Commit Graph

8 Commits

Author SHA1 Message Date
Mikhail Chusavitin
f73e3d144d Vendor mapping: wildcard ignore patterns, bulk CSV import, multi-lot qty
- Add glob pattern support (* and ?) for ignore rules stored in
  qt_vendor_partnumber_seen (is_pattern flag, migration 041)
- Pattern matching applied in stock/competitor import, partnumber book
  snapshot, and vendor mappings list (Go-side via NormalizeKey)
- BulkUpsertMappings: replace N+1 loop with two batch SQL upserts,
  validating all lots in a single query (~1500 queries → 3-4)
- CSV import: multi-lot per PN via repeated rows, optional qty column
- CSV export: updated column format vendor;partnumber;lot_name;qty;description;ignore;notes
- UI: ignore patterns section with add/delete, import progress feedback
- Update bible-local/vendor-mapping.md with new CSV format

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 09:41:48 +03:00
Mikhail Chusavitin
df14da2265 Improve pricing modal performance and charting 2026-03-17 12:37:58 +03:00
Mikhail Chusavitin
df5be91353 Improve performance on poor connections: local assets, gzip, caching
- Replace Tailwind CDN (~350KB) with purged local CSS (~22KB)
- Replace htmx unpkg CDN with local static file
- Add Gzip middleware (standard library, sync.Pool) for all responses
- Add Cache-Control: public, max-age=3600 for /static/* assets
- Reduce status polling interval from 5s to 30s
- Add scripts/build-css.sh for CSS regeneration after template changes
- Document in bible-local/operations.md and history.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 14:51:21 +03:00
Mikhail Chusavitin
c53c484bde Replace competitor discount with price_uplift; stock pricelist detail UI
- Drop `expected_discount_pct`, add `price_uplift DECIMAL(8,4) DEFAULT 1.3`
  to `qt_competitors` (migration 040); formula: effective_price = price / uplift
- Extend `LoadLotMetrics` to return per-PN qty map (`pnQtysByLot`)
- Add virtual fields `CompetitorNames`, `PriceSpreadPct`, `PartnumberQtys`
  to `PricelistItem`; populate via `enrichWarehouseItems` / `enrichCompetitorItems`
- Competitor quotes filtered to qty > 0 before lot resolution
- New "stock layout" on pricelist detail page for warehouse/competitor:
  Partnumbers column (PN + qty, only qty>0), Поставщик column, no Настройки/Доступно
- Spread badge ±N% shown next to price for competitor rows
- Bible updated: pricelist.md, history.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 12:58:41 +03:00
Mikhail Chusavitin
ec182abe99 Competitor pricelist: aggregate all competitors, rebuild without re-import
- Add GetLatestQuotesAllCompetitors() repo method: latest quote per
  (competitor_id, partnumber) across all active competitors
- Add RebuildPricelist() service method: loads all quotes, applies each
  competitor's discount, aggregates with weighted_median per lot,
  creates single combined competitor pricelist
- Add POST /api/competitors/pricelist handler + route
- JS: "Создать прайслист" on competitor tab calls new endpoint instead
  of the generic one that required explicit items

This allows recreating the competitor pricelist after new lot mappings
are added, without requiring a new file upload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 08:17:44 +03:00
Mikhail Chusavitin
f48615e8a9 Modularize Go files, extract JS to static, implement competitor pricelists
Go refactoring:
- Split handlers/pricing.go (2446→291 lines) into 5 focused files
- Split services/stock_import.go (1334→~400 lines) into stock_mappings.go + stock_parse.go
- Split services/sync/service.go (1290→~250 lines) into 3 files

JS extraction:
- Move all inline <script> blocks to web/static/js/ (6 files)
- Templates reduced: admin_pricing 2873→521, lot 1531→304, vendor_mappings 1063→169, etc.

Competitor pricelists (migrations 033-039):
- qt_competitors + partnumber_log_competitors tables
- Excel import with column mapping, dedup, bulk insert
- p/n→lot resolution via weighted_median, discount applied
- Unmapped p/ns written to qt_vendor_partnumber_seen
- Quote counts (unique/total) shown on /admin/competitors
- price_method="weighted_median", price_period_days=0 stored explicitly

Fix price_method/price_period_days for warehouse items:
- warehouse: weighted_avg, period=0
- competitor: weighted_median, period=0
- Removes misleading DB defaults (was: median/90)

Update bible: architecture.md, pricelist.md, history.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 07:44:10 +03:00
005478ac6b refactor to MariaDB-only runtime and simplify PriceForge 2026-02-07 21:42:26 +03:00
20309d1f0e Fork from QuoteForge → PriceForge
Renamed module path git.mchus.pro/mchus/quoteforge → git.mchus.pro/mchus/priceforge,
renamed package quoteforge → priceforge, moved binary from cmd/qfs to cmd/pfs.
2026-02-07 21:42:26 +03:00