diff --git a/DESIGN.md b/DESIGN.md index 0375821..baa1511 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -97,6 +97,10 @@ Every admin tool is blue. This one uses amber — reads as "operational" and "at --cancelled: #78716C; --cancelled-light: #F5F5F4; + + --compare: #EA580C; + --compare-light: #FFF7ED; + --compare-text: #9A3412; } ``` @@ -140,6 +144,10 @@ Strategy: invert surfaces, reduce accent saturation ~15%, keep semantic colors r --cancelled: #78716C; --cancelled-light: rgba(120,113,108,0.15); + + --compare: #EA580C; + --compare-light: rgba(234,88,12,0.15); + --compare-text: #FB923C; } ``` diff --git a/api/app/static/css/style.css b/api/app/static/css/style.css index c738698..0f23445 100644 --- a/api/app/static/css/style.css +++ b/api/app/static/css/style.css @@ -48,6 +48,10 @@ --cancelled: #78716C; --cancelled-light: #F5F5F4; + --compare: #EA580C; + --compare-light: #FFF7ED; + --compare-text: #9A3412; + /* Border radius */ --radius-sm: 4px; --radius-md: 8px; @@ -93,6 +97,10 @@ --cancelled: #78716C; --cancelled-light: rgba(120,113,108,0.15); + + --compare: #EA580C; + --compare-light: rgba(234,88,12,0.15); + --compare-text: #FB923C; } /* Dark mode overrides for elements with hardcoded colors */ @@ -1179,7 +1187,9 @@ tr.mapping-deleted td { /* Diff-type badges (reuses .anaf-badge sizing per DESIGN.md type scale minimum) */ .diff-badge { display:inline-block; font-family:var(--font-body); font-size:12px; font-weight:500; padding:2px 8px; border-radius:9999px; margin-left:4px; vertical-align:middle; } .diff-badge-anaf { background:var(--error-light); color:var(--error-text); } -.diff-badge-info { background:var(--warning-light); color:var(--warning-text); } +.diff-badge-denumire { background:var(--compare-light); color:var(--compare-text); } +.diff-badge-addr { background:var(--info-light); color:var(--info-text); } +.diff-badge-price { background:var(--success-light); color:var(--success-text); } /* ── Compact order detail layout ──────────────── */ .detail-col-label { diff --git a/api/app/static/js/dashboard.js b/api/app/static/js/dashboard.js index 206c0ee..bece68a 100644 --- a/api/app/static/js/dashboard.js +++ b/api/app/static/js/dashboard.js @@ -358,7 +358,7 @@ async function loadDashOrders() { const orders = data.orders || []; if (orders.length === 0) { - tbody.innerHTML = 'Nicio comanda'; + tbody.innerHTML = 'Nicio comanda'; } else { tbody.innerHTML = orders.map(o => { const dateStr = fmtDate(o.order_date); @@ -368,13 +368,12 @@ async function loadDashOrders() { ${statusDot(o.status)} ${dateStr} ${renderClientCell(o)} - ${esc(o.order_number)}${(o.anaf_cod_fiscal_adjusted===1||o.anaf_denumire_mismatch===1||(o.cod_fiscal_gomag&&o.anaf_platitor_tva!==null&&o.anaf_cod_fiscal_adjusted!==1&&(/^RO/i.test(o.cod_fiscal_gomag)!==(o.anaf_platitor_tva===1))))?'':''}${(o.address_mismatch===1||o.price_match===false)?'':''} + ${esc(o.order_number)}${diffDots(o)} ${o.items_count || 0} ${fmtCost(o.delivery_cost)} ${fmtCost(o.discount_total)} ${orderTotal} ${invoiceDot(o)} - ${priceDot(o)} `; }).join(''); } @@ -394,14 +393,11 @@ async function loadDashOrders() { } const name = o.customer_name || o.shipping_name || o.billing_name || '\u2014'; const totalStr = o.order_total ? Number(o.order_total).toFixed(2) : ''; - const anafDiffDot = (o.anaf_cod_fiscal_adjusted===1||o.anaf_denumire_mismatch===1||(o.cod_fiscal_gomag&&o.anaf_platitor_tva!==null&&o.anaf_cod_fiscal_adjusted!==1&&(/^RO/i.test(o.cod_fiscal_gomag)!==(o.anaf_platitor_tva===1)))) ? '' : ''; - const addrDiffDot = o.address_mismatch===1 ? '' : ''; - const priceMismatch = o.price_match === false ? ' ' : ''; return `
${statusDot(o.status)} ${dateFmt} ${esc(name)} - x${o.items_count || 0}${totalStr ? ' · ' + anafDiffDot + addrDiffDot + priceMismatch + '' + totalStr + '' : ''} + x${o.items_count || 0}${totalStr ? ' · ' + diffDots(o, true) + '' + totalStr + '' : ''}
`; }).join(''); } @@ -500,10 +496,22 @@ function statusLabelText(status) { } } -function priceDot(order) { - if (order.price_match === true) return ''; - if (order.price_match === false) return ''; - return ''; +function diffDots(o, mobile) { + const sz = mobile ? 6 : 7; + const ml = mobile ? 'margin-right:2px' : 'margin-left:3px'; + let d = ''; + const s = `display:inline-block;width:${sz}px;height:${sz}px;border-radius:50%;${ml};vertical-align:middle`; + if (o.anaf_cod_fiscal_adjusted===1 || + (o.cod_fiscal_gomag && o.anaf_platitor_tva!==null && o.anaf_cod_fiscal_adjusted!==1 && + (/^RO/i.test(o.cod_fiscal_gomag)!==(o.anaf_platitor_tva===1)))) + d += ``; + if (o.anaf_denumire_mismatch===1) + d += ``; + if (o.address_mismatch===1) + d += ``; + if (o.price_match===false) + d += ``; + return d; } function invoiceDot(order) { diff --git a/api/app/static/js/shared.js b/api/app/static/js/shared.js index fe54de4..ec09dc0 100644 --- a/api/app/static/js/shared.js +++ b/api/app/static/js/shared.js @@ -1019,15 +1019,15 @@ function _renderHeaderInfo(order) { orderNumEl.parentNode.querySelectorAll('.diff-badge').forEach(b => b.remove()); const badges = []; if (isPJ && pi.anaf_cod_fiscal_adjusted) badges.push({label:'CUI', cls:'diff-badge-anaf', aria:'CUI ajustat conform ANAF'}); - if (isPJ && pi.anaf_denumire_mismatch) badges.push({label:'Denumire', cls:'diff-badge-anaf', aria:'Denumire diferita fata de ANAF'}); + if (isPJ && pi.anaf_denumire_mismatch) badges.push({label:'Denumire', cls:'diff-badge-denumire', aria:'Denumire diferita fata de ANAF'}); if (isPJ && !pi.anaf_cod_fiscal_adjusted && pi.anaf_platitor_tva !== null && pi.anaf_platitor_tva !== undefined) { const gomagImpliesPlatitor = pi.cod_fiscal_gomag && /^RO/i.test(pi.cod_fiscal_gomag); const anafPlatitor = pi.anaf_platitor_tva === 1; if (gomagImpliesPlatitor !== anafPlatitor) badges.push({label:'TVA', cls:'diff-badge-anaf', aria: anafPlatitor ? 'Platitor TVA conform ANAF (GoMag fara RO)' : 'Neplatitor TVA conform ANAF (GoMag cu RO)'}); } - if (addr && addr.livrare_roa && !addrMatch(addr.livrare_gomag, addr.livrare_roa)) badges.push({label:'Adr. livr.', cls:'diff-badge-info', aria:'Adresa livrare diferita'}); - if (addr && addr.facturare_roa && !addrMatch(addr.facturare_gomag, addr.facturare_roa)) badges.push({label:'Adr. fact.', cls:'diff-badge-info', aria:'Adresa facturare diferita'}); - if (order.price_check && order.price_check.mismatches > 0) badges.push({label:'Preturi (' + order.price_check.mismatches + ')', cls:'diff-badge-info', aria:'Preturi diferite: ' + order.price_check.mismatches}); + if (addr && addr.livrare_roa && !addrMatch(addr.livrare_gomag, addr.livrare_roa)) badges.push({label:'Adr. livr.', cls:'diff-badge-addr', aria:'Adresa livrare diferita'}); + if (addr && addr.facturare_roa && !addrMatch(addr.facturare_gomag, addr.facturare_roa)) badges.push({label:'Adr. fact.', cls:'diff-badge-addr', aria:'Adresa facturare diferita'}); + if (order.price_check && order.price_check.mismatches > 0) badges.push({label:'Preturi (' + order.price_check.mismatches + ')', cls:'diff-badge-price', aria:'Preturi diferite: ' + order.price_check.mismatches}); let insertAfter = orderNumEl; badges.forEach(b => { const el = document.createElement('span'); diff --git a/api/app/templates/base.html b/api/app/templates/base.html index 3730c0a..7961bb5 100644 --- a/api/app/templates/base.html +++ b/api/app/templates/base.html @@ -19,7 +19,7 @@ {% set rp = request.scope.get('root_path', '') %} - + @@ -161,7 +161,7 @@ - + + {% endblock %}