309 lines
7.7 KiB
Markdown
309 lines
7.7 KiB
Markdown
# Operare ERP/CRM DiDi
|
|
|
|
Ghid pentru administrare zilnica: backup, restart, log-uri, troubleshooting.
|
|
|
|
## Comenzi uzuale
|
|
|
|
### Status containere
|
|
|
|
```bash
|
|
docker compose ps
|
|
docker stats --no-stream # CPU/RAM realtime
|
|
```
|
|
|
|
### Restart serviciu
|
|
|
|
```bash
|
|
# Doar ERPNext (cel mai des)
|
|
docker compose restart erpnext
|
|
|
|
# Toate
|
|
docker compose restart
|
|
|
|
# Restart cu rebuild image
|
|
docker compose up -d --build erpnext
|
|
```
|
|
|
|
### Log-uri
|
|
|
|
```bash
|
|
# Container ERPNext (gunicorn + nginx)
|
|
docker compose logs -f erpnext
|
|
|
|
# Worker job-uri background
|
|
docker compose logs -f queue-short
|
|
docker compose logs -f queue-long
|
|
docker compose logs -f scheduler
|
|
|
|
# Fisier de log Frappe (in container)
|
|
docker exec didi-erpnext tail -f /home/frappe/frappe-bench/sites/didi-erp/logs/web.log
|
|
docker exec didi-erpnext tail -f /home/frappe/logs/database.log
|
|
```
|
|
|
|
### Bench (CLI Frappe)
|
|
|
|
```bash
|
|
# Cache + cache static
|
|
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp clear-cache'
|
|
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp clear-website-cache'
|
|
|
|
# Migrate (dupa update Frappe sau didi_custom)
|
|
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp migrate'
|
|
|
|
# Rebuild assets (CSS/JS)
|
|
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench build --force'
|
|
|
|
# Reset Administrator password
|
|
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp set-admin-password admin'
|
|
|
|
# Console Python interactiv
|
|
docker exec -it didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp console'
|
|
```
|
|
|
|
## Backup
|
|
|
|
### Backup automat zilnic (recomandare cron)
|
|
|
|
Adauga in crontab (`crontab -e`):
|
|
|
|
```cron
|
|
# Backup zilnic la 02:00, retentie 14 zile
|
|
0 2 * * * ~/erp_crm/bin/backup.sh
|
|
```
|
|
|
|
Continut `bin/backup.sh` (creeaza-l):
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -e
|
|
DATE=$(date +%Y%m%d_%H%M%S)
|
|
BACKUP_DIR=/var/backups/didi-erp
|
|
mkdir -p $BACKUP_DIR
|
|
|
|
# DB dump
|
|
docker exec didi-mariadb mariadb-dump -uroot -p<parola-root-db> --all-databases \
|
|
| gzip > $BACKUP_DIR/db-$DATE.sql.gz
|
|
|
|
# Files (uploaded attachments)
|
|
docker run --rm \
|
|
-v didi-data-layer_erpnext-sites:/data \
|
|
-v $BACKUP_DIR:/backup \
|
|
alpine tar czf /backup/sites-$DATE.tar.gz /data
|
|
|
|
# Retention: keep last 14 days
|
|
find $BACKUP_DIR -mtime +14 -delete
|
|
echo "Backup OK: $DATE"
|
|
```
|
|
|
|
### Backup manual (Frappe-managed)
|
|
|
|
ERPNext are propriu mecanism de backup:
|
|
|
|
```bash
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench &&
|
|
bench --site didi-erp backup --with-files
|
|
'
|
|
# Fisierele apar in: sites/didi-erp/private/backups/
|
|
```
|
|
|
|
Copy local:
|
|
|
|
```bash
|
|
docker cp didi-erpnext:/home/frappe/frappe-bench/sites/didi-erp/private/backups/ ./backups-$(date +%Y%m%d)
|
|
```
|
|
|
|
## Restore din backup
|
|
|
|
```bash
|
|
# 1. Copiaza fisierele in container
|
|
docker cp ./backups-20260525 didi-erpnext:/tmp/restore
|
|
|
|
# 2. Restore
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench &&
|
|
bench --site didi-erp restore /tmp/restore/db-XXXXXX.sql.gz \
|
|
--with-public-files /tmp/restore/files-XXXXXX.tar \
|
|
--with-private-files /tmp/restore/private-files-XXXXXX.tar \
|
|
--mariadb-root-password <parola-root-db>
|
|
'
|
|
```
|
|
|
|
## Update / upgrade
|
|
|
|
### Update didi_custom (app-ul nostru)
|
|
|
|
Dupa ce modifici cod in `didi_custom/`:
|
|
|
|
```bash
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench &&
|
|
bench --site didi-erp migrate
|
|
'
|
|
```
|
|
|
|
Daca ai modificat doctype:
|
|
|
|
```bash
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench &&
|
|
bench --site didi-erp execute "frappe.model.sync.sync_for" --kwargs "{\"app\":\"didi_custom\"}"
|
|
'
|
|
```
|
|
|
|
### Upgrade ERPNext (major version)
|
|
|
|
NU recomandat fara o copie test. Procedura:
|
|
|
|
1. Backup complet
|
|
2. Edit `docker-compose.yml`: `ERPNEXT_VERSION=v16` (cand apare)
|
|
3. `docker compose pull`
|
|
4. `docker compose up -d`
|
|
5. `bench --site didi-erp migrate`
|
|
6. Test extensiv
|
|
|
|
## Monitorizare
|
|
|
|
### Health checks
|
|
|
|
```bash
|
|
# HTTP
|
|
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080
|
|
|
|
# DB
|
|
docker exec didi-mariadb mariadb -uroot -p<parola-root-db> -e "SELECT 1"
|
|
|
|
# Redis
|
|
docker exec didi-redis-cache redis-cli ping
|
|
docker exec didi-redis-queue redis-cli ping
|
|
|
|
# Background workers (verifica heartbeat)
|
|
docker exec didi-redis-queue redis-cli KEYS 'rq:worker:*'
|
|
```
|
|
|
|
### Email queue
|
|
|
|
```bash
|
|
docker exec didi-mariadb mariadb -u_xxx -pxxx didi_db -e "
|
|
SELECT status, COUNT(*) FROM \`tabEmail Queue\` GROUP BY status;
|
|
"
|
|
|
|
# Flush manual
|
|
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp execute frappe.email.queue.flush'
|
|
|
|
# Trimitere imediata (bypass queue)
|
|
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp send-email --send-now'
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Site nu raspunde / 500
|
|
|
|
```bash
|
|
# 1. Log-uri
|
|
docker compose logs --tail 100 erpnext
|
|
|
|
# 2. Restart curat
|
|
docker exec didi-redis-cache redis-cli FLUSHALL
|
|
docker exec didi-redis-queue redis-cli FLUSHALL
|
|
docker compose restart erpnext
|
|
|
|
# 3. Daca tot nu merge, verifica DB conexiune
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench && bench --site didi-erp doctor
|
|
'
|
|
```
|
|
|
|
### Workers nu proceseaza job-uri
|
|
|
|
```bash
|
|
# Status workers
|
|
docker exec didi-redis-queue redis-cli LRANGE "rq:queue:short" 0 -1 | head
|
|
docker exec didi-redis-queue redis-cli LRANGE "rq:queue:long" 0 -1 | head
|
|
|
|
# Restart workers
|
|
docker compose restart queue-short queue-long queue-default
|
|
```
|
|
|
|
### "Module Selling not found" sau alte module standard
|
|
|
|
`installed_apps` din DB e dezsincronizat. Fix:
|
|
|
|
```bash
|
|
DB=$(docker exec didi-erpnext cat /home/frappe/frappe-bench/sites/didi-erp/site_config.json | python3 -c "import sys,json; print(json.load(sys.stdin)['db_name'])")
|
|
|
|
docker exec didi-mariadb mariadb -uroot -p<parola-root-db> $DB -e "
|
|
UPDATE tabDefaultValue SET defvalue='[\"frappe\",\"erpnext\",\"didi_custom\"]' WHERE defkey='installed_apps';
|
|
"
|
|
docker exec didi-redis-cache redis-cli FLUSHALL
|
|
docker compose restart erpnext
|
|
```
|
|
|
|
### PDF nu se genereaza ("HostNotFoundError")
|
|
|
|
```bash
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench &&
|
|
bench --site didi-erp set-config -g host_name "http://didi-erpnext:8080"
|
|
'
|
|
docker compose restart erpnext
|
|
```
|
|
|
|
### Workspace cu titlu romanesc nu se gaseste
|
|
|
|
URL-urile Frappe sunt slug-ificate. Diacriticele se pierd. Pune titlul fara diacritice in DB:
|
|
|
|
```sql
|
|
UPDATE tabWorkspace SET title='Plati' WHERE name='Plati';
|
|
```
|
|
|
|
## Scenarii de operare
|
|
|
|
### Adaugare user admin nou
|
|
|
|
```bash
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench &&
|
|
bench --site didi-erp add-user nume.user@clossers.com \
|
|
--first-name Nume \
|
|
--last-name User \
|
|
--password parolaTemp123 \
|
|
--add-system-manager
|
|
'
|
|
```
|
|
|
|
### Schimbare email From-name (SendGrid)
|
|
|
|
```bash
|
|
# Update Email Account
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench &&
|
|
bench --site didi-erp execute "frappe.db.set_value" --kwargs "{\"doctype\":\"Email Account\", \"docname\":\"DiDi Outgoing\", \"fieldname\":\"email_id\", \"value\":\"office@clossers.com\"}"
|
|
'
|
|
docker compose restart erpnext
|
|
```
|
|
|
|
### Sterge factura emisa (anulare)
|
|
|
|
ERPNext nu permite delete pe `docstatus=1`. Trebuie cancel + delete:
|
|
|
|
```bash
|
|
docker exec didi-erpnext bash -c '
|
|
cd /home/frappe/frappe-bench &&
|
|
bench --site didi-erp execute "frappe.client.cancel" --kwargs "{\"doctype\":\"Sales Invoice\", \"name\":\"DIDI-INV-2026-00001\"}"
|
|
'
|
|
```
|
|
|
|
Apoi din UI sterge documentul anulat.
|
|
|
|
## SLA si severitati (conform contract)
|
|
|
|
| Severitate | Definitie | Timp raspuns | Timp rezolvare |
|
|
|------------|-----------|--------------|----------------|
|
|
| Critica | Sistemul nu functioneaza / plati nefunctionale | 4 ore | 24 ore |
|
|
| Majora | Functionalitate importanta afectata | 8 ore | 3 zile lucratoare |
|
|
| Minora | Probleme cosmetice / minore | 24 ore | 10 zile lucratoare |
|
|
|
|
Canal tichete: office@clossers.com (sau sistem helpdesk dedicat la productie).
|
|
|
|
Program suport: zile lucratoare 09:00 - 18:00.
|