livrare website cu erp si crm

This commit is contained in:
DP Software services 2026-07-28 14:47:28 +03:00
parent 28773e3a72
commit 5c7bf7c295
257 changed files with 31929 additions and 0 deletions

300
erp_crm/INSTALL.md Normal file
View file

@ -0,0 +1,300 @@
# Instalare ERP/CRM DiDi de la 0
Ghid complet pentru a porni stack-ul ERPNext + DiDi custom de la o masina goala.
## Prerequisite
### Software pe host
```bash
docker --version # >= 24.0
docker compose version # >= v2
```
Toata logica de setup ruleaza IN containerul ERPNext prin `bench execute` pe
functiile din app-ul `didi_custom` — nu e nevoie de Python pe host.
### Resurse
- 4 GB RAM disponibili
- 10 GB spatiu disc
- Port 8080 liber (sau schimba ERPNEXT_PORT)
### Retea Docker
ERPNext-ul ruleaza pe reteaua `didi-network` (impartita cu website-ul). Creeaz-o:
```bash
docker network create didi-network 2>/dev/null || true
```
## Build automat (recomandat)
Ruleaza:
```bash
cd ~/erp_crm
bash build-from-zero.sh
```
Scriptul face urmatoarele (~5 min):
1. Verifica `docker network` si `.env`
2. Porneste containerele (`docker compose up -d`)
3. Asteapta MariaDB sa fie healthy
4. Configureaza Redis in `common_site_config.json`
5. Creeaza site-ul `didi-erp` cu ERPNext instalat
6. Instaleaza app-ul `didi_custom`
7. Creeaza Company `TOP CLOSSERS SRL` + plan de conturi RO + An Fiscal curent
8. Ruleaza setup-ul complet din `didi_custom` prin `bench execute`
(doctypes, campuri custom, CMS, items DIDI + user API, print format,
email, workspace + scurtaturi)
9. Build assets (`bench build`)
10. Verifica accesul HTTP
## Build manual (pas cu pas)
Daca preferi sa rulezi fiecare pas individual:
### Pas 1. Containere
```bash
cd ~/erp_crm
docker compose up -d
```
Asteapta ~30 secunde pana MariaDB e healthy:
```bash
docker compose ps
# Toate trebuie sa fie Up; mariadb cu (healthy)
```
### Pas 2. Configurare Redis
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench set-config -g redis_cache "redis://redis-cache:6379" &&
bench set-config -g redis_queue "redis://redis-queue:6379" &&
bench set-config -g redis_socketio "redis://redis-queue:6379"
'
```
### Pas 3. Creare site + instalare ERPNext
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench new-site didi-erp \
--mariadb-root-password <parola-root-db> \
--admin-password <parola-admin> \
--db-host mariadb \
--install-app erpnext
'
```
Dureaza ~3 minute.
### Pas 4. Fix MariaDB user pentru orice host
Userul DB creat de Frappe e restrictionat la host-ul curent. Pentru ca containerele cu workers/scheduler sa se conecteze, schimba la wildcard:
```bash
DB_NAME=$(docker exec didi-erpnext python3 -c "
import json
with open('/home/frappe/frappe-bench/sites/didi-erp/site_config.json') as f:
print(json.load(f)['db_name'])
")
DB_PWD=$(docker exec didi-erpnext python3 -c "
import json
with open('/home/frappe/frappe-bench/sites/didi-erp/site_config.json') as f:
print(json.load(f)['db_password'])
")
docker exec didi-mariadb mariadb -uroot -p<parola-root-db> -e "
DROP USER IF EXISTS '$DB_NAME'@'%';
CREATE USER '$DB_NAME'@'%' IDENTIFIED BY '$DB_PWD';
GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_NAME'@'%';
FLUSH PRIVILEGES;
"
```
### Pas 5. Instalare didi_custom
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
printf "frappe\nerpnext\ndidi_custom\n" > sites/apps.txt &&
env/bin/pip install -e apps/didi_custom &&
bench --site didi-erp install-app didi_custom
'
```
### Pas 6. Patch ERPNext (portal_users compatibility)
Frappe v15 are un bug minor cu campul `portal_users` pe Customer (referinta la modul lipsa). Patch:
```bash
docker exec didi-erpnext sed -i \
's|for portal_user in self.portal_users:|for portal_user in (getattr(self, "portal_users", None) or []):|' \
/home/frappe/frappe-bench/apps/erpnext/erpnext/selling/doctype/customer/customer.py
```
### Pas 7. Companie + plan de conturi Romania + An Fiscal
⚠️ **NU rula logica frappe cu `python3` pe host sau cu python-ul de sistem din
container** — esueaza tacut (frappe e instalat doar in venv-ul bench). Foloseste
`bench --site didi-erp execute <modul.functie>`.
```bash
BE='docker exec didi-erpnext bash -c'
# Warehouse Type "Transit" — cerut la crearea companiei, lipseste in instalarea curata
$BE 'cd /home/frappe/frappe-bench && bench --site didi-erp execute frappe.client.insert \
--kwargs "{\"doc\":{\"doctype\":\"Warehouse Type\",\"name\":\"Transit\"}}"' || true
# Company TOP CLOSSERS SRL (cu patch-uri country fixtures incluse in modul)
$BE 'cd /home/frappe/frappe-bench && bench --site didi-erp execute didi_custom.make_company_ro3.execute'
# Plan de conturi RO complet (447 conturi: TVA 4426/4427/4423/4424, venituri 704/707,
# default-uri companie, template TVA 21%)
$BE 'cd /home/frappe/frappe-bench && bench --site didi-erp execute didi_custom.setup_ro_coa.execute'
# An Fiscal curent — lipseste complet dupa instalarea curata; facturile pica fara el
YEAR=$(date +%Y)
$BE "cd /home/frappe/frappe-bench && bench --site didi-erp execute frappe.client.insert \
--kwargs '{\"doc\":{\"doctype\":\"Fiscal Year\",\"year\":\"$YEAR\",\"year_start_date\":\"$YEAR-01-01\",\"year_end_date\":\"$YEAR-12-31\"}}'"
# Price list implicit in RON
$BE 'cd /home/frappe/frappe-bench && bench --site didi-erp execute frappe.client.set_value \
--kwargs "{\"doctype\":\"Price List\",\"name\":\"Standard Selling\",\"fieldname\":\"currency\",\"value\":\"RON\"}"'
```
### Pas 8. Doctypes custom, campuri si continut CMS
```bash
for fn in didi_custom.setup_doctypes.execute \
didi_custom.integrations.migrations.setup_custom_fields.execute \
didi_custom.fix_sa.execute \
didi_custom.populate_content.execute; do
docker exec didi-erpnext bash -c "cd /home/frappe/frappe-bench && bench --site didi-erp execute $fn"
done
```
Creeaza: doctype-urile Service Agreement / Payment Log / Website Content, campurile
custom pe Customer / Sales Invoice / Lead (didi_user_id, iam_role, active_plan,
sales_invoice „Factura asociata" pe Service Agreement etc.) si continutul CMS.
### Pas 9. Integrare website, print format, email, workspace
```bash
for fn in didi_custom.setup_website_integration.execute \
didi_custom.setup_phase2_final.setup_print_format \
didi_custom.setup_website_integration.fix_print_format \
didi_custom.setup_email.execute \
didi_custom.setup_workspaces.execute \
didi_custom.setup_shortcuts.execute; do
docker exec didi-erpnext bash -c "cd /home/frappe/frappe-bench && bench --site didi-erp execute $fn"
done
```
- `setup_website_integration.execute` creeaza items DIDI, rolul „Website Integration"
(cu toate permisiunile read necesare validarii facturilor) si userul API
`website_api@didi-erp.local`**noteaza api_key/api_secret afisate**, intra in
`.env.production`-ul website-ului.
- `fix_print_format` repara print formatul „DiDi Invoice" si seteaza `host_name`
(altfel wkhtmltopdf da `HostNotFoundError` la logo).
- `setup_email.execute` configureaza contul SMTP „DiDi Outgoing" (Mailpit in test;
in productie se schimba doar host/port/credentiale in Email Account).
### Pas 10. Scripturile legacy (scripts/setup/) — NU se mai folosesc
Directorul `scripts/setup/` contine prima generatie de scripturi (rulate pe host).
Sunt pastrate doar ca referinta istorica — totul a fost mutat in module
`didi_custom` rulabile cu `bench execute` (pasii 7-9 de mai sus).
### Pas 11. Build assets + restart
```bash
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench build --force'
docker restart didi-erpnext
sleep 8
curl -s -o /dev/null -w "ERPNext: %{http_code}\n" http://localhost:8080
```
## Verificare instalare
Daca totul a mers, deschide http://localhost:8080:
- Login: `Administrator` / `admin`
- Sidebar trebuie sa contina: Home, Facturi, Clienti, CRM, Servicii, Plati, Contabilitate, Financial Reports, Website CMS
- Pagina `/app/customer` arata Customer-ul `Test User` (daca ai rulat seed)
Curl rapid de verificare:
```bash
# Login + verifica company
curl -s -c /tmp/c -X POST http://localhost:8080/api/method/login \
-d 'usr=Administrator&pwd=admin' && echo
curl -s -b /tmp/c http://localhost:8080/api/resource/Company | python3 -m json.tool
```
## Date de test (seed)
Pentru smoke testing dupa instalare:
```bash
bash seed-data.sh
```
Creeaza:
- 1 Customer (`Test User`)
- 3 Sales Invoices submitted + paid
- 1 Payment Log (Stripe simulat)
- 1 Service Agreement
## Probleme frecvente
### "Module Selling not found"
`installed_apps` global value nu contine `erpnext`. 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 restart didi-erpnext
```
### "wkhtmltopdf reported an error: HostNotFoundError"
`host_name` lipseste in Website Settings. Fix:
```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 restart didi-erpnext
```
### "Access denied for user '_xxxx'@'host'"
User DB are host limitat. Vezi Pas 4 mai sus pentru fix.
### Site ramane la 500 pe `/app/home`
`setup_complete` e 0 si lipsesc accounts. Treci prin Setup Wizard manual din browser, SAU re-ruleaza Pasul 7 + 8.
## Reset complet
Pentru a reseta totul si a porni de la 0:
```bash
cd ~/erp_crm
docker compose down -v # -v sterge volumele!
docker network rm didi-network 2>/dev/null
docker network create didi-network
bash build-from-zero.sh
```
ATENTIE: `down -v` sterge IREVERSIBIL toate datele din MariaDB. Faci backup intai daca ai date importante.