feat: world-прайслист как заглушка для отсутствующих цен
Там, где для LOT нет цены в estimate/warehouse/competitor, подставляется цена из world-прайслиста. Такие ячейки в таблицах «Цена покупки»/«Цена продажи» подсвечиваются (amber), участвуют в «Итого» и убирают красную «*». В CSV-экспорте добавлена колонка «Заглушка (world)» с перечнем столбцов, где сработал фолбэк. Добавлены Tx-версии GetLatestLocalPricelistBySource/GetLocalPricesForLots, чтобы резолв прайслистов внутри транзакции не дедлочил single-connection пул. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
498cbf5490
commit
70a3ff255f
@@ -4126,8 +4126,15 @@ async function renderPricingTab() {
|
||||
estUnit: (pl && pl.estimate_price > 0) ? pl.estimate_price : 0,
|
||||
warehouseUnit: (pl && pl.warehouse_price > 0) ? pl.warehouse_price : null,
|
||||
competitorUnit: (pl && pl.competitor_price > 0) ? pl.competitor_price : null,
|
||||
estWorld: !!(pl && pl.estimate_from_world),
|
||||
whWorld: !!(pl && pl.warehouse_from_world),
|
||||
compWorld: !!(pl && pl.competitor_from_world),
|
||||
});
|
||||
|
||||
// Amber marker for world-fallback cells — must stay outside gray/green/red/blue
|
||||
// families since applyCustomPrice() strips those on vendor-price cells via regex.
|
||||
const WORLD_CLS = 'bg-amber-50 text-amber-700';
|
||||
|
||||
// ─── Build shared row data (unit prices for display, totals for math) ────
|
||||
// Each BOM row is exploded into per-LOT sub-rows; grouped by vendor PN via groupStart/groupSize.
|
||||
const cartQtyMap = {};
|
||||
@@ -4151,6 +4158,7 @@ async function renderPricingTab() {
|
||||
competitor: u.competitorUnit != null ? u.competitorUnit * item.quantity : null,
|
||||
vendorOrig: null, vendorOrigUnit: null, isEstOnly,
|
||||
groupStart: true, groupSize: 1,
|
||||
estWorld: u.estWorld, whWorld: u.whWorld, compWorld: u.compWorld,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -4189,6 +4197,7 @@ async function renderPricingTab() {
|
||||
est: u.estUnit > 0 ? u.estUnit * qty : 0,
|
||||
warehouse: u.warehouseUnit != null ? u.warehouseUnit * qty : null,
|
||||
competitor: u.competitorUnit != null ? u.competitorUnit * qty : null,
|
||||
estWorld: u.estWorld, whWorld: u.whWorld, compWorld: u.compWorld,
|
||||
});
|
||||
}
|
||||
allocs.forEach(a => {
|
||||
@@ -4201,6 +4210,7 @@ async function renderPricingTab() {
|
||||
est: u.estUnit > 0 ? u.estUnit * qty : 0,
|
||||
warehouse: u.warehouseUnit != null ? u.warehouseUnit * qty : null,
|
||||
competitor: u.competitorUnit != null ? u.competitorUnit * qty : null,
|
||||
estWorld: u.estWorld, whWorld: u.whWorld, compWorld: u.compWorld,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4212,6 +4222,7 @@ async function renderPricingTab() {
|
||||
est: 0, warehouse: null, competitor: null,
|
||||
vendorOrig, vendorOrigUnit, isEstOnly: false,
|
||||
groupStart: true, groupSize: 1,
|
||||
estWorld: false, whWorld: false, compWorld: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -4229,6 +4240,7 @@ async function renderPricingTab() {
|
||||
isEstOnly: false,
|
||||
groupStart: idx === 0,
|
||||
groupSize: idx === 0 ? groupSize : 0,
|
||||
estWorld: sub.estWorld, whWorld: sub.whWorld, compWorld: sub.compWorld,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4280,9 +4292,9 @@ async function renderPricingTab() {
|
||||
${pnDescHtml}
|
||||
<td class="px-3 py-1.5 text-xs ${borderTop}">${r.lotCell}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop}">${r.qty}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop}">${r.estUnit > 0 ? formatCurrency(r.estUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop}">${r.warehouseUnit != null ? formatCurrency(r.warehouseUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop}">${r.competitorUnit != null ? formatCurrency(r.competitorUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop} ${r.estWorld ? WORLD_CLS : ''}">${r.estUnit > 0 ? formatCurrency(r.estUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop} ${r.whWorld ? WORLD_CLS : ''}">${r.warehouseUnit != null ? formatCurrency(r.warehouseUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop} ${r.compWorld ? WORLD_CLS : ''}">${r.competitorUnit != null ? formatCurrency(r.competitorUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs pricing-vendor-price-buy ${borderTop} ${r.vendorOrigUnit == null ? 'text-gray-400' : ''}">${r.vendorOrigUnit != null ? formatCurrency(r.vendorOrigUnit) : '—'}</td>
|
||||
`;
|
||||
tbodyBuy.appendChild(tr);
|
||||
@@ -4332,9 +4344,9 @@ async function renderPricingTab() {
|
||||
${pnDescHtml}
|
||||
<td class="px-3 py-1.5 text-xs ${borderTop}">${r.lotCell}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop}">${r.qty}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop}">${saleEstUnit > 0 ? formatCurrency(saleEstUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop}">${saleWhUnit != null ? formatCurrency(saleWhUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop}">${saleCompUnit != null ? formatCurrency(saleCompUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop} ${r.estWorld ? WORLD_CLS : ''}">${saleEstUnit > 0 ? formatCurrency(saleEstUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop} ${r.whWorld ? WORLD_CLS : ''}">${saleWhUnit != null ? formatCurrency(saleWhUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs ${borderTop} ${r.compWorld ? WORLD_CLS : ''}">${saleCompUnit != null ? formatCurrency(saleCompUnit) : '—'}</td>
|
||||
<td class="px-3 py-1.5 text-right text-xs pricing-vendor-price-sale ${borderTop} text-gray-400">—</td>
|
||||
`;
|
||||
tbodySale.appendChild(tr);
|
||||
|
||||
Reference in New Issue
Block a user