Commit Graph

68 Commits

Author SHA1 Message Date
Claude Agent
89c3d1d07f feat(partner): detect and resync partner mismatches on already-imported orders
Detects PF↔PJ transitions and CUI changes after import; auto-resyncs
uninvoiced orders (max 5/cycle) and shows visual alert for invoiced ones.
- SQLite: partner_mismatch column + batch helpers
- sync_service: detection loop + _resync_partner_for_order
- dashboard: red dot + attention card indicator
- modal: alert with contextual message and resync button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 16:19:26 +00:00
Claude Agent
bf194eb088 fix(price): remove baseprice detection, use directional price match
baseprice > price was wrongly treated as "quantity discount" — it's just
GoMag's promotional price. Now: price_gomag <= pret_roa is always OK,
only flag when GoMag charges MORE than ROA. Reset cached price_match
at startup for re-evaluation. Fix dashboard dot color for mismatches.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 20:41:54 +00:00
Claude Agent
057e62fc04 feat(price): detect quantity discounts via baseprice, show Disc. badge
GoMag sends baseprice (catalog price) alongside price (discounted).
When baseprice > price, the item is volume-discounted — skip ROA
price comparison and show amber "Disc." badge instead of false
mismatch. Strikethrough baseprice in price column for transparency.

Pipeline: parse baseprice → store in SQLite → skip in validation →
pass flag to frontend → render badge (desktop + mobile pill badge
with aria-label, opacity 0.6 for dark mode).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 17:06:37 +00:00
Claude Agent
0f817b2130 fix(address): normalize SECTORUL + etaj in addr_match, fix Oracle duplicate addrs
- _addr_match / addrMatch: add SECTORUL\s*\d* branch to strip sector
  number; add (?:\b|(?=\d)) to catch glued keywords (sc1, ap94);
  include etaj field in rStreet concat
- database.py: replace duplicate addr_match impl with import from sync_service
- import_service.py: short-circuit billing addr Oracle call when
  billing == shipping (avoids duplicate address creation)
- PL/SQL: normalize MUNICIPIUL BUCURESTI → BUCURESTI SECTORUL X before
  TIER 1; resolve id_localitate before search; TIER 1 now matches on
  id_loc instead of text locality
- Add scripts/cleanup_duplicate_addresses.sql for manual prod cleanup
- Add 5 new tests: sectorul, keyword+digit gluing, etaj, short-circuit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:48:49 +00:00
Claude Agent
ecde7fe440 feat(address): ROA address cache refresh — 8-field format + manual refresh endpoint
Phase 5 address format upgrade (pre-existing working tree changes):
- import_service: extend vadrese_parteneri query to 8 fields (strada/numar/bloc/scara/apart/etaj/localitate/judet); strip trailing city name from address string passed to Oracle
- sync_service: extend _addr_match to compare bloc/scara/apart in addition to strada/numar
- 05_pack_import_parteneri.pck: updated PL/SQL package

New: address cache refresh mechanism:
- sqlite_service: add get_order_address_ids(), update_order_address_cache() (targeted 3-column update, no ANAF fields touched), get_orders_with_address_ids()
- sync.py: POST /api/orders/{order_number}/refresh-address endpoint (404/422/503/200); batch Oracle address refresh in refresh_invoices (single IN roundtrip, per-order mismatch recomputed)
- UI: refresh button (⟳) in ADRESE modal header (base.html); refreshOrderAddress() with loading state + toast (dashboard.js v43); window._detailOrderNumber global (shared.js v32)
- tests: TestRefreshOrderAddress — 4 tests (404, 422, 503, 200 with 8-field assert)

Oracle prod fix applied directly: ADRESE_PARTENERI id_adresa=4116 STRADA VASILE→VASILE GOLDIS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:35:18 +00:00
Claude Agent
51910148ef refactor(ui): remove redundant price badge from order detail modal
Header diff badges already show price mismatches, making the Status-line
badge duplicative.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 16:11:49 +00:00
Claude Agent
9977ec28cf style(ui): remove glow from invoice dots in orders table
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 15:48:37 +00:00
Claude Agent
47fe7efd92 refactor(ui): move Factura column next to status dot in orders table
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 15:44:48 +00:00
Claude Agent
c8e3a4e8d1 refactor(ui): separate diff dots with distinct colors, align modal badges
Replace 2 combined dots with 4 individual dots per diff type:
- CUI/TVA (red), Denumire (orange), Adresa (blue), Pret (green)
- Remove redundant price column from dashboard table
- Add --compare design token (orange) for denomination mismatches
- Align modal badge colors with table dot colors (4 separate CSS classes)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 15:40:53 +00:00
Claude Agent
4bff1aada1 fix(anaf): deduplicate TVA/CUI badges, remove address from DIFFS filter
CUI adjustment (RO prefix change) already implies TVA mismatch, so
suppress redundant TVA badge when CUI badge is shown. Remove
address_mismatch from DIFFS pill count since it's not an ANAF difference.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 14:56:04 +00:00
Claude Agent
2b212b933e fix(anaf): show TVA badge only on GoMag vs ANAF mismatch
Previously the TVA badge/dot appeared whenever ANAF reported neplatitor.
Now it only appears when GoMag CUI prefix (RO=platitor) disagrees with
ANAF status — aligned across JS badges, red dots, SQL filter and count.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 14:49:30 +00:00
Claude Agent
31095c07f7 fix(address+ui): remove TIER 2 reuse, typed diff badges, false positive reduction
- Remove TIER 2 address lookup (county+city without street) from PL/SQL — creates
  new address when street differs instead of reusing wrong one
- Replace generic "N diferente" badge with typed micro-badges (CUI, Denumire, TVA,
  Adr. livr., Adr. fact., Preturi) with red/amber semantic colors
- Extend addrMatch() regex to strip full Romanian address words (STRADA, NUMAR, BLOC,
  COMUNA, SAT, MUNICIPIUL, etc.) — fixes "Strada X" vs "X" false positives
- Extend normalize_company_name() for II, PFA, INTREPRINDERE INDIVIDUALA legal forms
- Persist address_mismatch to SQLite so "Dif." filter includes address-only diffs
- Add red/amber indicator dots to desktop table and mobile list rows
- 12 unit tests for normalization and server-side address matching

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:28:57 +00:00
Claude Agent
e75d40fcde fix(address+ui): parse embedded AP/SC/ET from street + show PF partner name
Address parser: extract APARTAMENT/SCARA/ETAJ embedded in street text
(previously only NR and BLOC were extracted). Two-tier matching:
separator-required for short prefixes (avoids "APATEULUI" false-positive)
and direct-digit fallback for "ap14", "sc1", "et2" patterns.

UI: show denumire_roa for PF orders too, not just PJ.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:07:57 +00:00
Claude Agent
060b63bce9 style(design): FINDING-004 — add empty state for logs page
When no sync run is selected, the logs page was completely blank
below the controls. Added a guidance message with icon explaining
what to do. Hides automatically when a run is selected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:16:51 +00:00
Claude Agent
84c38e3641 style(ui): design polish + replace CUI badge with +RO/−RO
6 design review fixes: diff summary badge in modal header, PF indicator,
eFactura risk icon (octagon vs triangle for colorblind), aria labels,
extract .denom-mismatch CSS class, remove dead .addr-table CSS.

Replace vague "Corectat" badge with directional +RO (green, prefix added)
or −RO (orange, prefix removed). Kit items show "Kit" badge instead of
price match dot. Cache-bust shared.js v24, style.css v31.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:01:50 +00:00
Claude Agent
8b547f96de style(design): FINDING-002 — replace hardcoded color on triangle indicator
The billing/shipping diff triangle used inline style="color:#6b7280"
which doesn't adapt to dark mode. Now uses a CSS class with
var(--text-muted) for proper theming.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:21:13 +00:00
Claude Agent
e8b42088e3 fix(anaf-dedup): fix ANAF parsing, facturare addr, compact modal layout
- Fix ANAF API: extract CUI from date_generale (not top-level), fix
  notFound casing (capital F)
- Fix missing facturare address when same ID as livrare (copy instead
  of skip)
- Replace ANAF cache pre-population stub with real logic (3-month CUIs)
- Restructure order detail modal: inline 2-col GOMAG|ROA layout with
  compact address lines replacing collapsed sections
- Fix addrMatch() to use field-level comparison with Romanian
  abbreviation stripping (STR, NR, BL, SC, AP, ET, ETAJ, APART)
- Add dashboard "Diferente" filter pill for ANAF-adjusted orders
- Update e2e test for new modal structure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:07:37 +00:00
Claude Agent
2f593c30f6 feat(anaf-dedup): ANAF partner dedup + address fix + UI enrichment
Prevent partner duplicates via ANAF CUI verification and dual PL/SQL
search. Fix address matching with street-level comparison and diacritics
normalization. Show partner/address comparison in order detail modal.

- New anaf_service.py: batch ANAF API client with chunking, retry, cache
- PL/SQL: dual CUI search (bare/RO+bare/RO space+bare), 3-tier address
  search (street+city+id_loc → city+id_loc → create), strip_diacritics
  at storage for addresses and partner names
- SQLite: anaf_cache table, 12 new order columns for partner/address data
- import_service: cod_fiscal_override param, return partner/address from Oracle
- sync_service: ANAF batch integration, denomination mismatch detection,
  cache pre-population trigger
- Router: enriched order_detail with partner_info + addresses JSON
- UI: collapsible Detalii Partener + Adrese Comparativ sections in modal,
  auto-expand on mismatch, ANAF badges, mobile address cards
- Dashboard: address quality attention indicator
- New scan_duplicate_partners.py script for one-time duplicate audit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:36:52 +00:00
Claude Agent
3b9198d742 fix(scheduler): save interval change even when auto is disabled
updateSchedulerInterval() only saved when enabled=true, so changing
the dropdown with auto off was lost on refresh. Now always persists.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:07:47 +00:00
Claude Agent
aa9e580e1b fix(scheduler): prevent auto-enable with wrong interval on page load
Root cause: GET /api/sync/schedule returned interval_minutes=null when
scheduler was stopped, causing dropdown to stay on first HTML option
(1 min). Setting .value programmatically could trigger onchange, sending
a second PUT with interval=1 right after the user's intended interval.

- GET schedule falls back to DB/default (10 min) when scheduler is off
- Add _schedulerLoading flag to block onchange during loadSchedulerStatus
- Default interval 10 min everywhere (was 5 in backend)
- Cache bust dashboard.js v=33

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:57:22 +00:00
Claude Agent
6acb73b9ce fix(dashboard): cache ROA price status and align nefacturate counts
- 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>
2026-03-27 14:47:03 +00:00
Claude Agent
b2745a9a64 fix(flow): replace duplicate period dropdown with preset buttons
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>
2026-03-27 13:54:04 +00:00
Claude Agent
efb055c2be fix(qa): ISSUE-002 — ROA prices not showing in order detail modal
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>
2026-03-27 13:25:07 +00:00
Claude Agent
7e4bbabcae fix(qa): ISSUE-001 — SKU prices 404 for SKUs containing slashes
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>
2026-03-27 13:16:20 +00:00
Claude Agent
5a5ca63f92 feat(simplify): first-time guidance welcome card
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>
2026-03-27 12:42:40 +00:00
Claude Agent
d3d1905b18 feat(simplify): simplified logs view
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>
2026-03-27 12:42:29 +00:00
Claude Agent
4a589aafeb feat(flow): smart default view (3 days + preset buttons)
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>
2026-03-27 12:38:24 +00:00
Claude Agent
b52313faf6 feat(flow): map SKU + auto-retry consolidated banner
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>
2026-03-27 12:38:10 +00:00
Claude Agent
7a789b4fe7 feat(flow): retry failed orders
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>
2026-03-27 12:34:51 +00:00
Claude Agent
1b2b1d8b24 feat(safety): invoice reconciliation on order detail
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>
2026-03-27 12:30:21 +00:00
Claude Agent
a10a00aa4d feat(safety): needs attention card on dashboard
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>
2026-03-27 12:28:18 +00:00
Claude Agent
3bd0556f73 feat(safety): price comparison on order detail
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>
2026-03-27 12:25:02 +00:00
Claude Agent
aacca13b85 style(design): FINDING-001 — mobile segmented control uses amber accent
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>
2026-03-27 11:52:15 +00:00
Claude Agent
a8292c2ef2 style(design): migrate to DESIGN.md system
Full visual migration: Space Grotesk + DM Sans + JetBrains Mono fonts,
warm amber two-accent system (amber=state, blue=action), dark mode with
CSS vars + localStorage + FOUC prevention, mobile bottom nav (5 tabs),
full-width tables, error/skipped dot glow, ~13 hardcoded hex replaced
with CSS vars in 4 JS files, 5 new E2E tests.

Files: style.css (full rewrite), base.html (fonts, theme script, dark
toggle, bottom nav), settings.html (dark toggle card), dashboard.js,
logs.js, mappings.js, settings.js (color vars), 5 templates (bnav
active blocks), test_design_system_e2e.py (NEW).

Cache-bust: style.css?v=18, shared.js?v=14, dashboard.js?v=27,
logs.js?v=13, mappings.js?v=12, settings.js?v=8

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:36:07 +00:00
Claude Agent
c5757b8322 refactor(modal): extract order detail to shared.js
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>
2026-03-27 11:19:42 +00:00
Claude Agent
f07946b489 feat(dashboard): show article subtotal, discount, and transport in order detail receipt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:39:21 +00:00
Claude Agent
10c1afca01 feat: show prices for all mappings + remove VAT% display
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>
2026-03-20 23:15:26 +00:00
Claude Agent
327f0e6ea2 refactor(ui): unify mapping form into single shared component
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>
2026-03-19 23:21:43 +00:00
Claude Agent
952989d34b fix: remove procent_pret from quick-map modals, fix catalog price sync
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>
2026-03-19 22:53:36 +00:00
Claude Agent
9e5901a8fb feat(pricing): kit/pachet pricing with price list lookup, replace procent_pret
- 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>
2026-03-19 22:29:18 +00:00
Claude Agent
bedb93affe feat(dashboard): receipt-style order detail with inline transport and discount rows
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>
2026-03-19 18:44:56 +00:00
Claude Agent
c534a972a9 feat: multi-gestiune stock verification setting
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>
2026-03-18 16:15:40 +00:00
Claude Agent
695dafacd5 feat: dual pricing policies + discount VAT splitting
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>
2026-03-18 15:10:05 +00:00
Claude Agent
7dd39f9712 feat(order-detail): show CODMAT for direct SKUs + mapping validations
- Enrich order detail items with NOM_ARTICOLE data for direct SKUs
  (SKU=CODMAT) that have no ARTICOLE_TERTI entry
- Validate CODMAT exists in nomenclator before saving mapping (400)
- Block redundant self-mapping when SKU is already direct CODMAT (409)
- Show "direct" badge in CODMAT column for direct SKUs
- Show info alert in quick map modal for direct SKUs
- Display backend validation errors inline in modal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:10:20 +00:00
Claude Agent
7a2408e310 fix(import): resolve correct id_articol for duplicate CODMATs + gestiune setting
Unified id_articol selection logic in Python (resolve_codmat_ids) and PL/SQL
(resolve_id_articol): filters sters=0 AND inactiv=0, prefers article with
stock in configured gestiune, falls back to MAX(id_articol). Eliminates
mismatch where Python and PL/SQL could pick different id_articol for the
same CODMAT, causing ORA-20000 price-not-found errors.

- Add resolve_codmat_ids helper in validation_service.py (single batch query)
- Refactor validate_skus/validate_prices/ensure_prices to use it
- Add resolve_id_articol function in PL/SQL package body
- Add p_id_gestiune parameter to importa_comanda (spec + body)
- Add /api/settings/gestiuni endpoint and id_gestiune setting
- Add gestiune dropdown in settings UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:18:18 +00:00
Claude Agent
dafc2df0d4 feat(dashboard): auto-refresh after sync, configurable polling, extra filters
- Detect missed sync completions via last_run.run_id comparison
- Load polling interval from settings (dashboard_poll_seconds, default 5s)
- Add 1min/3min scheduler interval options
- Add 1zi/2zile period filter options
- New Dashboard settings card for polling interval

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:48:29 +00:00
Claude Agent
5e01fefd4c feat(sync): handle cancelled GoMag orders (status Anulata / statusId 7)
- Add web_status column to orders table (generic name for platform status)
- Filter cancelled orders during sync, record as CANCELLED in SQLite
- Soft-delete previously-imported cancelled orders in Oracle (if not invoiced)
- Add CANCELLED filter pill + badge in dashboard UI
- New soft_delete_order_in_roa() and mark_order_cancelled() functions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:50:38 +00:00
Claude Agent
8020b2d14b fix(dashboard): renderClientCell shows customer_name (partner) as primary
renderClientCell was showing shipping_name (person) instead of
customer_name (company/partner). Now shows customer_name with tooltip
for shipping person when different (e.g. company orders).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:28:35 +00:00
Claude Agent
172debdbdb fix(dashboard): show customer_name (partner) instead of shipping_name
Dashboard list was prioritizing shipping_name over customer_name,
so company orders showed the person instead of the company name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:25:56 +00:00
Claude Agent
5dfd795908 fix(sync): detect deleted orders and invoices in ROA
Previously, orders deleted from Oracle (sters=1) remained as IMPORTED
in SQLite, and deleted invoices kept stale cache data. Now the refresh
button and sync cycle re-verify all imported orders against Oracle:
- Deleted orders → marked DELETED_IN_ROA with cleared id_comanda
- Deleted invoices → invoice cache fields cleared
- New status badge for DELETED_IN_ROA in dashboard and logs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:18:36 +00:00