Смысл красной подсветки итогов сменился с «цены есть не для всех позиций» на «часть суммы посчитана по ценам-заглушкам world» — оформлено отдельной записью в decision log. Журнал решений добавлен в оглавление bible-local. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.8 KiB
2.8 KiB
Decision: world pricelist as a fallback stub for missing prices
Date: 2026-07-10 Status: active
Context
Four pricelist source values sync from the server: estimate, warehouse, competitor,
world. Only the first three were ever read — world synced into local_pricelists /
local_pricelist_items but nothing consumed it, so LOTs with no warehouse/competitor price
showed as "—" in the "Ценообразование" tab, which also broke the "Итого" coverage (red "*").
Decision
world is a fallback stub, applied per-column, only when the native price for that column
is missing or ≤ 0:
- Resolution order per column: native source price →
worldprice → still missing. - Applies to all three Buy columns (Estimate, Склад, Конкуренты), the Sale table (same unit prices, multiplied by the existing sale coefficients), and CSV export.
- A world-fallback price counts toward "Итого" like a native price (closes the red "*" gap).
- UI marks only the specific cell that used a fallback, with
bg-amber-50 text-amber-700(amber was chosen becauseapplyCustomPrice()stripsgray/green/red/bluetext-color classes via regex on vendor-price cells — amber survives that). - CSV keeps price values untouched (no suffixes) and adds one trailing comment column,
"Заглушка (world)", listing which columns used the fallback per row (e.g.
world: Stock, Конкуренты), always present regardless of export options so column counts stay aligned across header/rows/summary. worldis resolved independently in each call site (quote.goCalculatePriceLevels,export.goresolvePricingTotals) via "explicit ID → latest active → latest local", same pattern as the other three sources. It is intentionally NOT added tolevelBySource/ResolvedPricelistIDsas a fourth on-screen level.NormalizePricelistSource("world")returnsPricelistSourceWorld, notestimate— it must not collapse into the estimate source.
Consequences
PriceLevelsItem(APIPOST /api/quote/price-levels) carries three new bools:estimate_from_world,warehouse_from_world,competitor_from_world.price_missingon that endpoint only lists a source when BOTH the native and theworldprice are unavailable.- No new config-level column (e.g.
world_pricelist_id) — world always resolves to "latest activeworldpricelist," not a per-configuration pin. - If no
worldpricelist exists locally, behavior is unchanged (missing prices stay "—", no error). - How the footer totals surface this fallback is decided separately in 2026-07-24-pricing-total-world-share.md; membership of world LOTs in the configurator's LOT set is decided in 2026-07-24-component-universe-world-union.md.