import {bidFirmIssues} from './bidFirmFields.js'; import {sourceRows,bidSourceOptions,bidSourceSnapshot,restoreBidPrices} from './bidSource.js'; import {selectBidLots} from './bidLots.js'; import {bidTotal,bidAmount,validateBidRows} from './bidValidation.js'; import {bidTypeForForm,bidValidityForForm} from './bidTerms.js'; import {documentKey,preparationBlockers} from './preparationChecks.js'; import {preparationDeadlineProblem} from './preparationDeadline.js'; import {tenderDateKey} from './tenderCalendar.js'; // Saved draft diagnostics only. A clean summary still requires live output checks. export function preparationSummary(tender,vault,now=new Date()) { const draft=tender.bidDraft || {},analysis=draft.analysisSource || {},issues=[]; const add=(target,text)=>issues.push({target,text}); const deadline=preparationDeadlineProblem(tender,now); if(deadline)add('source',deadline); const documents=[...new Map([...(analysis.documentChecklist || []),...(draft.manualDocuments || [])].map(d=>[documentKey(d),d])).values()]; const itemSource=draft.itemSource || {},partial=draft.partialBid || {enabled:false,source:'',selected:[],assignments:{}}; const options=bidSourceOptions(tender,analysis,itemSource),rows=sourceRows(tender,analysis,options.selected || 'tender'); const selection=selectBidLots(rows,partial); const snapshot=JSON.stringify([bidSourceSnapshot(tender,{...analysis,documentChecklist:documents},rows),partial,itemSource,options.signature]); if(draft.reviewedSource!==snapshot)add('source','Resmi kaynak karşılaştırması gerekli.'); if(analysis.sourceReview?.status==='partial')add('analysis','Analiz kısmi; kaynak kontrolünü tamamlayın.'); if(options.needsSelection)add('itemSource','Resmi cetvele uygun kalem listesini seçin.'); for(const issue of bidFirmIssues(draft.firma))add(`firm:${issue.k}`,issue.message); const type=bidTypeForForm(tender.aciklama,analysis.procurementTerms?.bidType),bidType=draft.teklifTuru || type.type || ''; if(!['birim','goturu'].includes(bidType)||type.status==='conflict'||(type.type&&type.type!==bidType))add('bidType','Teklif türünü doğrulayın.'); const validity=bidValidityForForm(tender.aciklama,analysis.procurementTerms?.bidValidity),days=Number(draft.gecerlilikGun || validity.days || ''); if(!Number.isInteger(days)||days<=0||validity.status==='conflict'||(validity.days&&daysadd('lots',text)); const prices=restoreBidPrices(draft),priced=selection.rows.map(row=>({...row,birimFiyat:prices[row.priceKey]})); if(bidType==='birim') { if(!priced.length)add('pricing','Resmi teklif kalemleri eksik.'); priced.forEach((row,i)=>{if(validateBidRows([row]).length)add(`price:${row.priceKey}`,`${i+1}. kalemin miktar, birim veya fiyatını tamamlayın.`);}); if(priced.length&&!validateBidRows(priced).length&&bidTotal(priced)===null)add('pricing','Genel toplam geçersiz veya hesaplama sınırını aşıyor.'); } if(bidType==='goturu'&&bidAmount(draft.goturuBedel)===null)add('lumpSum','Toplam teklif bedelini kontrol edin.'); const checkedVault={...vault,documents:Array.isArray(vault?.documents) ? vault.documents : [],deadlineDate:tenderDateKey(tender),tenderIkn:tender.ikn}; const documentIssues=preparationBlockers([],documents,draft.checks,checkedVault); preparationBlockers(selection.rows,documents,draft.checks,checkedVault).forEach(text=>add('checks',text)); return {issues,documentIssues,owner:tender.atananPersonel || 'Atanmadı',next:issues[0] || {target:'source',text:'Dosyayı açıp son kontrolleri yapın.'}}; }