fix(sync): prevent kit/bax price sync from overwriting individual CRM prices

Three code paths could overwrite CRM list prices with wrong values when
web unit (50 buc) differs from ROA unit (100 buc):

- price_sync_service: kit path now skips components that have their own
  ARTICOLE_TERTI mapping (individual path handles them with correct ÷0.5)
- validation_service: sync_prices_from_order now skips bax SKUs
  (cantitate_roa > 1) in addition to multi-component kits
- pack_import_comenzi: skip negative kit discount (markup), ROUND prices
  to nzecimale_pretv decimals

Also adds:
- SQL script for 6 ARTICOLE_TERTI mappings (cantitate_roa=0.5) for cup
  articles where web=50buc, ROA=100buc/set
- Oracle schema reference documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-03-25 19:05:49 +00:00
parent f315aad14c
commit 47b5723f92
5 changed files with 195 additions and 6 deletions

122
docs/oracle-schema-notes.md Normal file
View File

@@ -0,0 +1,122 @@
# Oracle Schema Notes — MARIUSM_AUTO
Reference pentru tabelele, procedurile și relațiile Oracle descoperite în debugging.
## Tabele comenzi
### COMENZI
| Coloană | Tip | Notă |
|---|---|---|
| ID_COMANDA | NUMBER (PK) | Auto-generated |
| COMANDA_EXTERNA | VARCHAR2 | Nr. comandă GoMag (ex: 481588552) |
| DATA_COMANDA | DATE | |
| ID_PART | NUMBER | FK → NOM_PARTENERI |
| PROC_DISCOUNT | NUMBER(10,4) | Discount procentual pe comandă (setat 0 la import) |
| STERS | NUMBER | Soft-delete flag |
### COMENZI_ELEMENTE
| Coloană | Tip | Notă |
|---|---|---|
| ID_COMANDA_ELEMENT | NUMBER (PK) | Auto-generated |
| ID_COMANDA | NUMBER | FK → COMENZI |
| ID_ARTICOL | NUMBER | FK → NOM_ARTICOLE |
| ID_POL | NUMBER | FK → CRM_POLITICI_PRETURI |
| PRET | NUMBER(14,3) | Preț per unitate (cu/fără TVA per PRET_CU_TVA flag) |
| CANTITATE | NUMBER(14,3) | Cantitate (negativă pentru discount lines) |
| DISCOUNT_UNITAR | NUMBER(20,4) | Default 0 |
| PTVA | NUMBER | Procentul TVA (11, 21, etc.) |
| PRET_CU_TVA | NUMBER(1) | 1 = prețul include TVA |
| STERS | NUMBER | Soft-delete flag |
**Discount lines**: qty negativă, pret pozitiv. Ex: qty=-1, pret=51.56 → scade 51.56 din total.
## Tabele facturare
### VANZARI
| Coloană | Tip | Notă |
|---|---|---|
| ID_VANZARE | NUMBER (PK) | |
| NUMAR_ACT | NUMBER | Număr factură (nract) |
| SERIE_ACT | VARCHAR2 | Serie factură |
| TIP | NUMBER | 3=factură pe bază de comandă, 1=factură simplă |
| ID_COMANDA | NUMBER | FK → COMENZI (pentru TIP=3) |
| ID_PART | NUMBER | FK → NOM_PARTENERI |
| TOTAL_FARA_TVA | NUMBER | Total calculat de pack_facturare |
| TOTAL_TVA | NUMBER | |
| TOTAL_CU_TVA | NUMBER | |
| DIFTOTFTVA | NUMBER | Diferența față de totalul trimis de client ROAFACTUARE |
| DIFTOTTVA | NUMBER | |
| STERS | NUMBER | |
### VANZARI_DETALII
| Coloană | Tip | Notă |
|---|---|---|
| **ID_VANZARE_DET** | NUMBER (PK) | ⚠ NU `id_detaliu`! |
| ID_VANZARE | NUMBER | FK → VANZARI |
| ID_ARTICOL | NUMBER | FK → NOM_ARTICOLE |
| CANTITATE | NUMBER | |
| PRET | NUMBER | Preț de vânzare |
| PRET_ACHIZITIE | NUMBER | |
| PROC_TVAV | NUMBER | Coeficient TVA (1.21, 1.11, etc.) |
| ID_GESTIUNE | NUMBER | NULL pentru discount lines |
| CONT | VARCHAR2 | '371', NULL pentru discount lines |
| STERS | NUMBER | |
## Tabele prețuri
### CRM_POLITICI_PRETURI
| Coloană | Tip | Notă |
|---|---|---|
| ID_POL | NUMBER (PK) | ID politică de preț |
| PRETURI_CU_TVA | NUMBER | 1 = prețurile includ TVA |
### CRM_POLITICI_PRET_ART
| Coloană | Tip | Notă |
|---|---|---|
| ID_POL | NUMBER | FK → CRM_POLITICI_PRETURI |
| ID_ARTICOL | NUMBER | FK → NOM_ARTICOLE |
| PRET | NUMBER | Preț de listă (cu/fără TVA per PRETURI_CU_TVA din politică) |
| PROC_TVAV | NUMBER | Coeficient TVA |
Politici folosite: id_pol=39 (vânzare), id_pol=65 (transport).
### ARTICOLE_TERTI
| Coloană | Tip | Notă |
|---|---|---|
| SKU | VARCHAR2 | SKU din magazin web (GoMag) |
| CODMAT | VARCHAR2 | CODMAT în ROA (FK → NOM_ARTICOLE.CODMAT) |
| CANTITATE_ROA | NUMBER | Conversie: 1 web unit = X ROA units |
| ACTIV | NUMBER | |
| STERS | NUMBER | |
**cantitate_roa semnificații**:
- `1` → 1:1 (unitate identică web/ROA)
- `0.5` → 1 web unit (50 buc) = 0.5 ROA set (100 buc). Price sync: `pret_web / 0.5`
- `10` → bax 1000buc = 10 seturi ROA (100 buc). Kit pricing activ.
- `22.5` → bax 2250buc = 22.5 seturi ROA (100 buc). Kit pricing activ.
## Proceduri cheie
### PACK_COMENZI.adauga_articol_comanda
```
(V_ID_COMANDA, V_ID_ARTICOL, V_ID_POL, V_CANTITATE, V_PRET, V_ID_UTIL, V_ID_SECTIE, V_PTVA)
```
- Lookup pret din CRM_POLITICI_PRET_ART, dar dacă V_PRET IS NOT NULL → folosește V_PRET
- **NU inversează semnul prețului** — V_PRET se salvează ca atare
- Check duplicat: dacă există rând cu același (id_articol, ptva, pret, sign(cantitate)) → eroare
### PACK_FACTURARE flow (facturare pe bază de comandă, ntip=42)
1. `cursor_comanda` → citește COMENZI_ELEMENTE, filtrează `SIGN(A.CANTITATE) * (A.CANTITATE - NVL(D.CANTITATE, 0)) > 0`
2. `cursor_gestiuni_articol` → verifică stoc per articol
3. `initializeaza_date_factura` → setează sesiune facturare
4. `adauga_articol_factura` (×N) → inserează în VANZARI_DETALII_TEMP
5. `scrie_factura2` → procesează temp, contabilizează
6. `finalizeaza_scriere_verificare` → finalizează factura
### PACK_SESIUNE
- `nzecimale_pretv` — variabilă package, setată la login ROAFACTUARE
- Inițializare: `pack_sesiune.getoptiunefirma(USER, 'PPRETV')` = **2** (pe MARIUSM_AUTO)
- **Nu e setată** în context server-side (import comenzi) → folosim `getoptiunefirma` direct
### OPTIUNI (tabel configurare)
- Coloane: `VARNAME`, `VARVALUE` (⚠ NU `cod`/`valoare`)