diff --git a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx index 653a1df..d33f566 100644 --- a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx +++ b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx @@ -9,7 +9,7 @@ import { Step1PositionSelection } from './Step1PositionSelection/Step1PositionSe import { Step2CommercialOffers } from './Step2CommercialOffers/Step2CommercialOffers'; import { Step3ComparisonTable } from './Step3ComparisonTable/Step3ComparisonTable'; import { Step4Approval } from './Step4Approval/Step4Approval'; -import { buildColumnsFromSpOffers, buildSupplierColumnId, findColumnForRecord } from './utils/supplierColumns'; +import { buildColumnsFromSpOffers, buildSupplierColumnId, findColumnForRecord, findWinnerColumnId } from './utils/supplierColumns'; import { buildOffersFromSpRecords } from './utils/spOffers'; import { excludedItemsToFormData } from './utils/excludedColumns'; import { isUserInApprovalChain } from './utils/approvalAccess'; @@ -184,18 +184,26 @@ const CtCreateForm: React.FC = ({ context, userDisplayName, } } + // Preserve session suppliers and offers — SP data may be incomplete or stale vs. unsaved edits. + // Only use SP-derived data when session has none, or in review mode (always fresh). + const suppliers = withNoOfferSuppliers( + formData.suppliers.length === 0 ? [...spSuppliers, ...excluded.suppliers] : formData.suppliers, + noOfferFromSp, + ); + // Победитель обязателен для «Сохранить» на Шаге 3: без сессии берём его из шапки СТ, иначе + // в другом браузере пришлось бы выбирать заново. + const winnerColumnId = formData.recommendedSupplierId === undefined + ? findWinnerColumnId(suppliers, ct.winSupplierSpId) + : undefined; + updateFormData({ ct, approvalMatrix, // Preserve session selectedPositions — overwriting changes pos.id (Запросы ID → Позиции СТ ID), // which breaks edits keys built from buildOfferKey(sup.id, pos.id) in Step 3. ...(preferSp || formData.selectedPositions.length === 0 ? { selectedPositions: positions } : {}), - // Preserve session suppliers and offers — SP data may be incomplete or stale vs. unsaved edits. - // Only use SP-derived data when session has none, or in review mode (always fresh). - suppliers: withNoOfferSuppliers( - formData.suppliers.length === 0 ? [...spSuppliers, ...excluded.suppliers] : formData.suppliers, - noOfferFromSp, - ), + suppliers, + ...(winnerColumnId !== undefined ? { recommendedSupplierId: winnerColumnId } : {}), ...(preferSp || formData.offers.length === 0 ? { offers: [...offers, ...excluded.offers] } : {}), ...(formData.currencyRates.length === 0 && spCurrencyRates.length > 0 ? { currencyRates: spCurrencyRates } : {}), ...(uploadedKpFiles.length > 0 ? { uploadedKpFiles } : {}), diff --git a/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/ComparisonMatrix.tsx b/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/ComparisonMatrix.tsx index 04743b7..16307ab 100644 --- a/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/ComparisonMatrix.tsx +++ b/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/ComparisonMatrix.tsx @@ -8,6 +8,7 @@ import { SUPPLIER_STATUS_OPTIONS, getSubCols, formatKzt } from './matrixHelpers' import { UseAdataCheckResult } from './useAdataCheck'; import { AdataIndicator } from './AdataIndicator'; import { ExcludeSupplierDialog } from './ExcludeSupplierDialog'; +import { toggleWinner } from './step3Validation'; import styles from './Step3ComparisonTable.module.scss'; const FIXED_COLS = 3; // Наименование / Ед. изм. / Кол-во @@ -113,8 +114,9 @@ export function ComparisonMatrix({ matrix, currencyRates, isRestrictedView, adat <> diff --git a/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/Step3ComparisonTable.tsx b/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/Step3ComparisonTable.tsx index 8f0d4b1..fc9c0e3 100644 --- a/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/Step3ComparisonTable.tsx +++ b/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/Step3ComparisonTable.tsx @@ -56,7 +56,8 @@ export const Step3ComparisonTable: React.FC = ({ const matrix = useStep3Matrix({ service, formData, isReadOnly: !canEdit, onSave, onNext, onStepComplete }); const { isReadOnly, newSupplierName, newSupplierCurrency, setNewSupplierName, setNewSupplierCurrency, - handleAddSupplier, handleAddSupplierFromDatabase, translateUnits, setTranslateUnits, isSaving, saveError, setSaveError, handleSave, + handleAddSupplier, handleAddSupplierFromDatabase, translateUnits, setTranslateUnits, isSaving, saveError, setSaveError, + validateBeforeSave, handleSave, extraPositions, suppliersWithOffer, columnDisplayNames, allPositions, computedOffers, selectedSupplierId, excludedColumns, handleRestoreSupplier, } = matrix; @@ -242,7 +243,12 @@ export const Step3ComparisonTable: React.FC = ({