fix: BOM — cart-LOT priority в дропдауне + корректный qtyMismatch при lot_qty_per_pn > 1
- filterAutocompleteBOM: LOT из текущего конфигуратора выводятся первыми с разделителем «── прочие ──», остальные — по popularity_score - qtyMismatch теперь сравнивает cartQty с pn_qty × lot_qty_per_pn во всех трёх местах рендера BOM-таблицы; «8 LOT = 1 PN» больше не даёт ложного жёлтого предупреждения Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1656,6 +1656,10 @@ function renderAutocomplete() {
|
||||
|
||||
// Build autocomplete items based on mode
|
||||
dropdown.innerHTML = autocompleteFiltered.map((comp, idx) => {
|
||||
if (comp.isDivider) {
|
||||
return `<div class="px-3 py-1 text-xs text-gray-400 border-t border-gray-200 select-none cursor-default" style="pointer-events:none">── прочие ──</div>`;
|
||||
}
|
||||
|
||||
let onmousedown;
|
||||
|
||||
if (autocompleteMode === 'section') {
|
||||
@@ -2039,14 +2043,24 @@ function showAutocompleteBOM(rowIdx, input) {
|
||||
|
||||
function filterAutocompleteBOM(rowIdx, search) {
|
||||
const searchLower = (search || '').toLowerCase();
|
||||
autocompleteFiltered = (window._bomAllComponents || allComponents).filter(c => {
|
||||
const cartLots = new Set(cart.map(i => i.lot_name));
|
||||
const all = (window._bomAllComponents || allComponents).filter(c => {
|
||||
const text = (c.lot_name + ' ' + (c.description || '')).toLowerCase();
|
||||
return text.includes(searchLower);
|
||||
}).sort((a, b) => {
|
||||
const popDiff = (b.popularity_score || 0) - (a.popularity_score || 0);
|
||||
if (popDiff !== 0) return popDiff;
|
||||
return a.lot_name.localeCompare(b.lot_name);
|
||||
});
|
||||
const inCart = all.filter(c => cartLots.has(c.lot_name))
|
||||
.sort((a, b) => a.lot_name.localeCompare(b.lot_name));
|
||||
const notInCart = all.filter(c => !cartLots.has(c.lot_name))
|
||||
.sort((a, b) => {
|
||||
const popDiff = (b.popularity_score || 0) - (a.popularity_score || 0);
|
||||
if (popDiff !== 0) return popDiff;
|
||||
return a.lot_name.localeCompare(b.lot_name);
|
||||
});
|
||||
if (inCart.length && notInCart.length) {
|
||||
autocompleteFiltered = [...inCart, {isDivider: true}, ...notInCart];
|
||||
} else {
|
||||
autocompleteFiltered = [...inCart, ...notInCart];
|
||||
}
|
||||
renderAutocomplete();
|
||||
}
|
||||
|
||||
@@ -2071,7 +2085,7 @@ function handleAutocompleteKeyBOM(event, rowIdx) {
|
||||
|
||||
function selectAutocompleteItemBOM(index, rowIdx) {
|
||||
const comp = autocompleteFiltered[index];
|
||||
if (!comp) return;
|
||||
if (!comp || comp.isDivider) return;
|
||||
const row = bomRows.find(r => r.source_row_index === rowIdx) || bomRows[rowIdx];
|
||||
if (!row) return;
|
||||
row.manual_lot = comp.lot_name;
|
||||
@@ -3209,7 +3223,7 @@ function _bomRawLotCell(rowIdx) {
|
||||
cart.forEach(item => { cartMap[item.lot_name] = item.quantity; });
|
||||
const isUnresolved = !map.resolved_lot || map.resolution_source === 'unresolved';
|
||||
const cartQty = map.resolved_lot ? (cartMap[map.resolved_lot] ?? null) : null;
|
||||
const qtyMismatch = cartQty !== null && cartQty !== map.quantity;
|
||||
const qtyMismatch = cartQty !== null && cartQty !== map.quantity * _getRowLotQtyPerPN(map);
|
||||
const notInCart = map.resolved_lot && cartQty === null;
|
||||
|
||||
if (isUnresolved) {
|
||||
@@ -3595,7 +3609,7 @@ function _renderBOMParsedTable() {
|
||||
const tr = document.createElement('tr');
|
||||
const isUnresolved = !row.resolved_lot || row.resolution_source === 'unresolved';
|
||||
const cartQty = row.resolved_lot ? (cartMap[row.resolved_lot] ?? null) : null;
|
||||
const qtyMismatch = cartQty !== null && cartQty !== row.quantity;
|
||||
const qtyMismatch = cartQty !== null && cartQty !== row.quantity * _getRowLotQtyPerPN(row);
|
||||
const notInCart = row.resolved_lot && cartQty === null;
|
||||
if (isUnresolved) unresolved++;
|
||||
if (qtyMismatch || notInCart) mismatches++;
|
||||
@@ -3662,7 +3676,7 @@ function _renderBOMRawTable() {
|
||||
else if (parsed) {
|
||||
const isUnresolved = !parsed.resolved_lot || parsed.resolution_source === 'unresolved';
|
||||
const cartQty = parsed.resolved_lot ? (cartMap[parsed.resolved_lot] ?? null) : null;
|
||||
const qtyMismatch = cartQty !== null && cartQty !== parsed.quantity;
|
||||
const qtyMismatch = cartQty !== null && cartQty !== parsed.quantity * _getRowLotQtyPerPN(parsed);
|
||||
const notInCart = parsed.resolved_lot && cartQty === null;
|
||||
if (isUnresolved) unresolved++;
|
||||
if (qtyMismatch || notInCart) mismatches++;
|
||||
|
||||
Reference in New Issue
Block a user