livrare website cu erp si crm
This commit is contained in:
parent
28773e3a72
commit
5c7bf7c295
257 changed files with 31929 additions and 0 deletions
300
erp_crm/INSTALL.md
Normal file
300
erp_crm/INSTALL.md
Normal 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue