fix(ct): поставщики без КП с шага 2 не попадают в таблицу сравнения
Они выводились на шаге 3 колонкой с нулевыми ценами, хотя сравнивать у них нечего. Остаются в списке шага 2 и в «Не получены КП»; ручной ввод цен сохранён за поставщиками, добавленными на самом шаге 3. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
-1
@@ -80,7 +80,6 @@ export function ComparisonMatrix({ matrix, currencyRates, isRestrictedView, adat
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles.supplierMetaRow}>
|
<div className={styles.supplierMetaRow}>
|
||||||
<AdataIndicator supplier={s} state={adata.adataMap[s.id]} onCheck={() => void adata.checkSupplier(s.id)} />
|
<AdataIndicator supplier={s} state={adata.adataMap[s.id]} onCheck={() => void adata.checkSupplier(s.id)} />
|
||||||
{s.isNoOffer && <span className={styles.noOfferTag}>Без КП</span>}
|
|
||||||
{currency !== 'KZT' && <span className={styles.currencyTag}>{currency}</span>}
|
{currency !== 'KZT' && <span className={styles.currencyTag}>{currency}</span>}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.supplierControlsRow}>
|
<div className={styles.supplierControlsRow}>
|
||||||
|
|||||||
+1
-1
@@ -74,7 +74,7 @@ export function MatrixRowView({ pos, posIndex, matrix, currencyRates, isRestrict
|
|||||||
}
|
}
|
||||||
|
|
||||||
const rate = isForeign ? (currencyRates.find(r => r.code === currency)?.rateToKzt ?? 1) : 1;
|
const rate = isForeign ? (currencyRates.find(r => r.code === currency)?.rateToKzt ?? 1) : 1;
|
||||||
const qty = item.quantity ?? ((s.isNoOffer || s.isExtraSupplier) && pos.quantity ? pos.quantity : undefined);
|
const qty = item.quantity ?? (s.isExtraSupplier && pos.quantity ? pos.quantity : undefined);
|
||||||
const price = item.pricePerUnit;
|
const price = item.pricePerUnit;
|
||||||
const totalInCurrency = (price ?? 0) * (qty ?? 0);
|
const totalInCurrency = (price ?? 0) * (qty ?? 0);
|
||||||
const priceKzt = (price ?? 0) * rate;
|
const priceKzt = (price ?? 0) * rate;
|
||||||
|
|||||||
-10
@@ -213,16 +213,6 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.noOfferTag {
|
|
||||||
font-size: 11px;
|
|
||||||
background: $danger-bg;
|
|
||||||
color: $danger;
|
|
||||||
padding: 1px 7px;
|
|
||||||
border-radius: 10px;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.deleteSupplierBtn {
|
.deleteSupplierBtn {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
|||||||
+9
-21
@@ -290,9 +290,13 @@ export function useStep3Matrix(args: UseStep3MatrixArgs) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const suppliersWithOffer = useMemo(() => [
|
const suppliersWithOffer = useMemo(() => [
|
||||||
...suppliers.map(s => ({ ...s, isExtraSupplier: false as const, isNoOffer: !s.hasOffer })),
|
// Поставщики без КП с Шага 2 (hasOffer:false) в таблицу сравнения не попадают — сравнивать
|
||||||
|
// у них нечего. Ручной ввод цен остаётся за поставщиками, добавленными на самом Шаге 3 (extras).
|
||||||
|
...suppliers
|
||||||
|
.filter(s => s.hasOffer !== false)
|
||||||
|
.map(s => ({ ...s, isExtraSupplier: false as const })),
|
||||||
...extraSuppliers.map(es => ({
|
...extraSuppliers.map(es => ({
|
||||||
id: es.id, name: es.name, hasOffer: true as const, isExtraSupplier: true as const, isNoOffer: false as const,
|
id: es.id, name: es.name, hasOffer: true as const, isExtraSupplier: true as const,
|
||||||
// spId/bin известны сразу для поставщиков, добавленных из «База данных поставщиков»
|
// spId/bin известны сразу для поставщиков, добавленных из «База данных поставщиков»
|
||||||
// (см. handleAddSupplierFromDatabase) — без этого useAdataCheck не увидит их БИН.
|
// (см. handleAddSupplierFromDatabase) — без этого useAdataCheck не увидит их БИН.
|
||||||
spId: es.spId, bin: es.bin,
|
spId: es.spId, bin: es.bin,
|
||||||
@@ -343,10 +347,10 @@ export function useStep3Matrix(args: UseStep3MatrixArgs) {
|
|||||||
const rate = currency !== 'KZT'
|
const rate = currency !== 'KZT'
|
||||||
? (currencyRates.find(r => r.code === currency)?.rateToKzt ?? 1)
|
? (currencyRates.find(r => r.code === currency)?.rateToKzt ?? 1)
|
||||||
: 1;
|
: 1;
|
||||||
// For noOffer/extra suppliers quantity may be undefined in edits (user only entered price).
|
// For extra suppliers quantity may be undefined in edits (user only entered price).
|
||||||
// Fall back to the position's own quantity so totalWithExtraKzt stays non-zero and the
|
// Fall back to the position's own quantity so totalWithExtraKzt stays non-zero and the
|
||||||
// offer is included in filteredComputed → persisted in offersForSession → restored on remount.
|
// offer is included in filteredComputed → persisted in offersForSession → restored on remount.
|
||||||
const posQtyFallback = (s.isNoOffer || s.isExtraSupplier) ? (pos.quantity || undefined) : undefined;
|
const posQtyFallback = s.isExtraSupplier ? (pos.quantity || undefined) : undefined;
|
||||||
items.forEach(item => result.push(computeOffer(
|
items.forEach(item => result.push(computeOffer(
|
||||||
{
|
{
|
||||||
...item,
|
...item,
|
||||||
@@ -694,20 +698,6 @@ export function useStep3Matrix(args: UseStep3MatrixArgs) {
|
|||||||
extraOfferIds[es.id] = offerId;
|
extraOfferIds[es.id] = offerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const noOfferSupSpIds: Record<string, number> = {};
|
|
||||||
const noOfferOfferIds: Record<string, number> = {};
|
|
||||||
for (const s of suppliers.filter(sup => !sup.hasOffer)) {
|
|
||||||
const hasData = computedOffers.some(o => o.supplierId === s.id && o.totalWithExtraKzt > 0);
|
|
||||||
if (!hasData) continue;
|
|
||||||
if (s.spId) {
|
|
||||||
noOfferSupSpIds[s.id] = s.spId;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const { spId, offerId } = await service.saveManualSupplierWithKp(s.name);
|
|
||||||
noOfferSupSpIds[s.id] = spId;
|
|
||||||
noOfferOfferIds[s.id] = offerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
const extraPosSpIds: Record<string, number> = {};
|
const extraPosSpIds: Record<string, number> = {};
|
||||||
for (const ep of extraPositions) {
|
for (const ep of extraPositions) {
|
||||||
if (ep.spId) {
|
if (ep.spId) {
|
||||||
@@ -735,7 +725,7 @@ export function useStep3Matrix(args: UseStep3MatrixArgs) {
|
|||||||
const offersToSave = computedOffers
|
const offersToSave = computedOffers
|
||||||
.filter(o => o.totalWithExtraKzt > 0)
|
.filter(o => o.totalWithExtraKzt > 0)
|
||||||
.map(o => {
|
.map(o => {
|
||||||
const supSpId = extraSupSpIds[o.supplierId] ?? noOfferSupSpIds[o.supplierId];
|
const supSpId = extraSupSpIds[o.supplierId];
|
||||||
const posSpId = extraPosSpIds[o.positionId];
|
const posSpId = extraPosSpIds[o.positionId];
|
||||||
const existingSup = suppliers.find(s => s.id === o.supplierId);
|
const existingSup = suppliers.find(s => s.id === o.supplierId);
|
||||||
const existingPos = selectedPositions.find(p => p.id === o.positionId);
|
const existingPos = selectedPositions.find(p => p.id === o.positionId);
|
||||||
@@ -761,7 +751,6 @@ export function useStep3Matrix(args: UseStep3MatrixArgs) {
|
|||||||
: (existingPos?.spId ? String(existingPos.spId) : o.positionId),
|
: (existingPos?.spId ? String(existingPos.spId) : o.positionId),
|
||||||
offerId: originalOffer?.offerId
|
offerId: originalOffer?.offerId
|
||||||
?? (extraOfferIds[o.supplierId] !== undefined ? String(extraOfferIds[o.supplierId]) : undefined)
|
?? (extraOfferIds[o.supplierId] !== undefined ? String(extraOfferIds[o.supplierId]) : undefined)
|
||||||
?? (noOfferOfferIds[o.supplierId] !== undefined ? String(noOfferOfferIds[o.supplierId]) : undefined)
|
|
||||||
?? (kpFileOfferId !== undefined ? String(kpFileOfferId) : undefined),
|
?? (kpFileOfferId !== undefined ? String(kpFileOfferId) : undefined),
|
||||||
...(kmVal !== undefined ? { deliveryDistanceKm: kmVal } : {}),
|
...(kmVal !== undefined ? { deliveryDistanceKm: kmVal } : {}),
|
||||||
};
|
};
|
||||||
@@ -784,7 +773,6 @@ export function useStep3Matrix(args: UseStep3MatrixArgs) {
|
|||||||
...suppliers.map(s => ({
|
...suppliers.map(s => ({
|
||||||
...s,
|
...s,
|
||||||
status: supplierStatuses[s.id] ?? s.status,
|
status: supplierStatuses[s.id] ?? s.status,
|
||||||
...(noOfferSupSpIds[s.id] !== undefined ? { spId: noOfferSupSpIds[s.id] } : {}),
|
|
||||||
})),
|
})),
|
||||||
// Move extras into suppliers (with React ID kept as `id` — required so formData.offers
|
// Move extras into suppliers (with React ID kept as `id` — required so formData.offers
|
||||||
// entries with React IDs still match sup.id on remount). Skip extras that are already in
|
// entries with React IDs still match sup.id on remount). Skip extras that are already in
|
||||||
|
|||||||
Reference in New Issue
Block a user