- Add price_match column to SQLite, cached on order detail view
- Background backfill on startup checks all unchecked imported orders
- Extract _enrich_items_with_codmat() helper to deduplicate SKU enrichment
- Attention card now shows same nefacturate count as filter pill
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Period selector had both preset buttons (3/7/30 zile) and a dropdown
with overlapping options. Per plan Commit 6, preset buttons are the
single control: Azi / 3 zile / 7 zile / 30 zile / Custom. Visible
on all screen sizes with horizontal scroll on mobile.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The JS read pret_roa from order.price_check.items[idx] which doesn't
exist. The backend puts pret_roa and price_match directly on each item
in the items array. Fixed both desktop table and mobile view to read
from item.pret_roa and item.price_match instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SKUs with forward slashes (e.g. 0V2071/250159/250158) caused a 404
on /api/mappings/{sku}/prices because path separators in the SKU
were interpreted as URL path segments. Changed to query parameter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show a welcome card on the dashboard when no sync runs exist yet.
Guides new users: 1. Check Settings → 2. Start Sync → 3. Map SKUs.
Card auto-hides after first successful sync.
Cache-bust: dashboard.js?v=31, style.css?v=24
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consolidate Template CSV, Export CSV, Import CSV into a single
"Import/Export" dropdown. Keep "+ Adauga Mapare" and "Formular complet"
as prominent action buttons.
Cache-bust: mappings.js?v=13
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Default to showing problem orders (ERROR/SKIPPED) first. Imported
orders collapsed behind "X comenzi importate cu succes" toggle.
Reduces noise for operators scanning for issues.
Cache-bust: logs.js?v=14, style.css?v=23
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move Kit Pricing, Price Sync, and Dashboard Polling sections under a
collapsed "Setari avansate" toggle. Basic settings remain visible.
Tooltip warns: "Modificati doar la indicatia echipei tehnice."
Cache-bust: settings.js?v=9
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Change default period from 7 to 3 days. Add quick-select preset
buttons (3 zile / 7 zile / 30 zile) that sync with the dropdown.
Reduces noise for daily operators who only need recent orders.
Cache-bust: style.css?v=22, dashboard.js?v=30
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After saving a SKU mapping, check for SKIPPED orders containing that
SKU and show a floating banner with count + "Importa" button. Batch
retries up to 20 orders and shows result feedback.
Backend:
- get_skipped_orders_with_sku() in sqlite_service.py
- GET /api/orders/by-sku/{sku}/pending endpoint
- POST /api/orders/batch-retry endpoint (max 20, sequential)
Frontend:
- Auto-retry banner after quickMap save with batch import button
- Success/error feedback, auto-dismiss after 15s
Cache-bust: shared.js?v=19
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ability to re-import individual ERROR/SKIPPED orders directly from
the order detail modal. Downloads narrow date range from GoMag API,
finds the specific order, and re-runs import_single_order().
Backend:
- New retry_service.py with retry_single_order() — downloads order_date
±1 day from GoMag, finds order by number, imports via import_service
- Guard: blocks retry during active sync (_sync_lock check)
- POST /api/orders/{order_number}/retry endpoint
Frontend:
- "Reimporta" button in modal footer (visible only for ERROR/SKIPPED)
- Spinner during retry, success/error feedback with auto-refresh
Cache-bust: shared.js?v=18
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add invoice total comparison in the order detail modal. When an order
has been invoiced, shows whether the invoice total matches the order
total — green badge if OK, red badge with difference amount if not.
Backend: compute reconciliation (difference, match) from existing
invoice.total_cu_tva vs order_total in order_detail endpoint.
Frontend: reconciliation badge below invoice info in modal, hidden
when no invoice exists.
Cache-bust: shared.js?v=17
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a "Needs Attention" card above the orders table that surfaces:
- Import errors count (click → ERROR filter)
- Unmapped SKUs count (click → Missing SKUs page)
- Uninvoiced orders >3 days (click → UNINVOICED filter)
Shows green "Totul in ordine" when all metrics are zero.
Backend: add uninvoiced_old count to get_orders() and unresolved_skus
from get_dashboard_stats() to dashboard/orders API response.
Cache-bust: style.css?v=21, dashboard.js?v=29
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ROA price comparison to order detail modal — operators can now see
if GoMag prices match Oracle before invoicing. Eliminates the #1 risk
of invoicing with wrong prices.
Backend:
- New get_prices_for_order() in validation_service.py — batch Oracle
query with dual-policy routing (sales/production by cont 341/345),
PRETURI_CU_TVA handling, kit total calculation
- Extend GET /api/sync/order/{orderNumber} with per-item pret_roa and
order-level price_check summary
- GET /api/dashboard/orders returns price_match=null (lightweight)
Frontend:
- Modal: price check badge (green/red/grey), "Pret GoMag" + "Pret ROA"
columns, match dot per row, mismatch rows highlighted
- Dashboard: price dot column (₽) in orders table
- Mobile: inline mismatch indicator
Cache-bust: shared.js?v=16, dashboard.js?v=28
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bootstrap's .card sets color: var(--bs-body-color) which stays #212529 in
dark mode since we use data-theme="dark" not data-bs-theme. Added explicit
card dark override and color: var(--text-primary) on .flat-row.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mobile segmented control (7 buttons, 431px) overflowed 375px viewport.
Added overflow-x:auto on segmented containers and min-width:0 on
flex-grow child. Body scroll width now matches viewport.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bootstrap --bs-table-bg defaults to white, not overridden in dark mode.
Added --bs-table-bg: var(--surface) and explicit td background for odd
rows. Zebra now alternates #1E1E1E / #2A2A2A in dark mode.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DESIGN.md specifies box-shadow glow for SKIPPED status dots:
0 0 6px 2px rgba(202,138,4,0.3). Was missing from .dot-yellow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mobile segmented filter buttons used Bootstrap btn-primary (blue) for
active state. Per DESIGN.md two-accent system, state indicators use
amber. Added .seg-active class with --accent color.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move duplicated order detail modal logic from dashboard.js and logs.js
into a shared renderOrderDetailModal() function in shared.js. Move
modal HTML from dashboard.html and logs.html into base.html.
Shared functions: renderCodmatCell, orderStatusBadge, fmtCost, fmtNum,
computeDiscountSplit, renderReceipt. Both pages now call the shared
modal with page-specific quick map callbacks.
Net -152 lines. Logs page gains invoice info, TVA column, and receipt
footer that were previously dashboard-only.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove validation that blocked creating mappings when SKU matches an
existing CODMAT. Users need this for unit quantity conversion (e.g.,
website sells 50 units per SKU but ROA tracks 100, requiring
cantitate_roa=0.5).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Price=0 is a valid state for kit components in crm_politici_pret_art,
inserted automatically by the price sync system. Previously, the kit
validation treated pret=0 the same as missing, blocking orders from
importing even when all SKU mappings were correctly configured.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Existing 741 rows also updated via UPPER() on customer_name,
shipping_name, billing_name.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Kit discount: v_disc_amt is per-kit, not per-unit — remove division by
v_cantitate_web so discount lines compute correctly (e.g. -2 x 5 = -10).
Price sync: stop auto-inserting missing articles into price policies
(was inserting with wrong proc_tvav from GoMag). Log warning instead.
Kit detection: extend to single-component repackagings (cantitate_roa > 1)
in both PL/SQL package and price sync/validation services.
Add repackaging kit pricing test for separate_line and distributed modes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Join price policies directly into get_mappings() query so single-article
mappings display prices without extra API calls. Remove VAT percentage
from kit price display.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PACK_FACTURARE: use PTVA from COMENZI_ELEMENTE (NVL2) in adauga_articol_factura
instead of fetching PROC_TVAV from price list, fixing NULL SUMA for discount
lines with multiple TVA rates (11%, 21%).
sync.py: broaden direct SKU enrichment to all unmapped SKUs regardless of
mapping_status, fixing stale status edge cases.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix vat_included comparison: GoMag API returns int 1, not str "1",
causing all prices to be multiplied by TVA again (double TVA)
- Normalize vat_included to string in gomag_client at parse time
- Price sync now processes kit components individually by looking up
each component's CODMAT as standalone GoMag product
- Add _insert_component_price for components without existing Oracle price
- resolve_mapped_codmats: ROW_NUMBER dedup for CODMATs with multiple
NOM_ARTICOLE entries, prefer article with current stock
- pack_import_comenzi: merge_or_insert_articol to merge quantities when
same article appears from kit + individual on same order
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The export CSV button used a hardcoded /api/validate/missing-skus-csv path,
bypassing the IIS /gomag reverse proxy prefix. Also add changelog comments
to PACK_COMENZI and PACK_FACTURARE for the duplicate CODMAT discrimination.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
codmat_policy_map had CODMAT keys only, but build_articles_json looks
up by GoMag SKU — mapped articles like FRSETP250 never got per-article
id_pol, causing Oracle to use default sales policy and fail when price
exists only in production policy.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract the SKU mapping modal (HTML + JS) from dashboard, logs, and
missing_skus into a shared component in base.html + shared.js. All pages
now use the same compact layout with CODMAT/Cant. column headers.
- Fix missing_skus backdrop bug: event.stopPropagation() on icon click
prevents double modal open from <a> + <tr> event bubbling
- Shrink mappings addModal from modal-lg to regular size with compact layout
- Remove ~500 lines of duplicated modal HTML and JS across 4 pages
- Each page keeps a thin wrapper (openDashQuickMap, openLogsQuickMap,
openMapModal) that calls shared openQuickMap() with an onSave callback
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove leftover procent_pret input fields and validation from dashboard,
logs and missing_skus quick-map modals (missed in 9e5901a). Fix GoMag
Products API returning dict-keyed products instead of array, which caused
catalog price sync to find 0 products with SKU.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Oracle PL/SQL: kit pricing logic with Mode A (distributed discount) and
Mode B (separate discount line), dual policy support, PRETURI_CU_TVA flag
- Eliminate procent_pret from entire stack (Oracle, Python, JS, HTML)
- New settings: kit_pricing_mode, kit_discount_codmat, price_sync_enabled
- Settings UI: cards for Kit Pricing and Price Sync configuration
- Mappings UI: kit badges with lazy-loaded component prices from price list
- Price sync from orders: auto-update ROA prices when web prices differ
- Catalog price sync: new service to sync all GoMag product prices to ROA
- Kit component price validation: pre-check prices before import
- New endpoint GET /api/mappings/{sku}/prices for component price display
- New endpoints POST /api/price-sync/start, GET status, GET history
- DDL script 07_drop_procent_pret.sql (run after deploy confirmation)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace totals bar + VAT subtotals table with transport/discount as table
rows (with CODMAT from settings, proper VAT rate) and a single Total footer.
Right-align qty/price/TVA columns, thousands separator (ro-RO), discount
shown as qty=-1 price=positive.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace single-select gestiune dropdown with multi-select checkboxes.
Settings stores comma-separated IDs, Python builds IN clause with bind
variables, Oracle PL/SQL splits CSV via REGEXP_SUBSTR for stock lookup.
Empty selection = all warehouses (unchanged behavior).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add production pricing policy (id_pol_productie) for articles with cont 341/345,
smart discount VAT splitting across multiple rates, per-article id_pol support,
and mapped SKU price validation. Settings UI updated with new controls.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Search was hidden in card header — now inline with filters for better
discoverability. Compact refresh button to icon-only. On mobile, search
and period dropdown share the same row via flex.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reduces vertical space by eliminating the second row in the filter bar.
Search input is now next to the "Comenzi" title, hidden on mobile.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>