cqs logics
Overview of Key Features
Tender Flow and Step Management
The tender process is divided into multiple steps, each with dynamic fetching and state updates based on query parameters like step and draft-id. It utilizes hooks for data fetching, state management, and error handling. Each step is handled by a dedicated function that fetches and updates the relevant data for that step.
Key Functionalities
Data Fetching and Step Handling
useEffect Hook
useEffect(() => { const draftId = searchParams.get("draft-id"); const stepParam = searchParams.get("step"); setDraftId(draftId); if (draftId) { fetchTenderData(draftId, stepParam); }}, [searchParams.get("draft-id"), procurementCategories, searchParams.get("step")]);-
Purpose: This
useEffecthook watches for changes in thedraft-idandstepquery parameters. It fetches tender data based on thedraft-idand proceeds with the relevant step usingfetchTenderData. -
Dependencies: It depends on
searchParams.get("draft-id"),searchParams.get("step"), andprocurementCategories.
fetchTenderData Function
const fetchTenderData = async (draftId: any, stepParam: any) => { try { const draftTender = await tenderService.getDraftTenderBySerialId(draftId); const { tender } = draftTender;
// Process steps based on stepParam if (stepParam === '1') { handleStepOne(tender); } else if (stepParam === '2') { await handleStepTwo(tender.process_id, tender); } // Further steps as needed... } catch (error) { console.error('Error fetching fetchTender:', error); }};- Purpose: This function fetches the tender details based on the provided
draftIdand determines the necessary action based on thestepParam. - Flow: Each step (
handleStepOne,handleStepTwo, etc.) updates the relevant state for the UI.
Handle Step Functions
Each step is handled by a dedicated function. Here’s an example for Step One:
const handleStepOne = async (tender: { description: string; title: string; industry: string; work_location: string; submission_deadline: string | null }) => { setStepOneLoader(true); const { description, title, industry, work_location, submission_deadline } = tender;
try { updateAdditionalData({ description, title, industry, work_location, submission_deadline: submission_deadline ? dayjs(submission_deadline, 'YYYY-MM-DD').toDate() : null, }); setStepOneLoader(false); } catch (error) { console.error("Error updating additional data", error); setStepOneLoader(false); }};- Purpose: It updates the UI state with the tender data for the first step. It also handles loading states to provide feedback during data fetching.
Handling Step Two (Procurement Categories & Templates)
const handleStepTwo = async (processId: any, tender: any) => { try { if (procurementCategories.length > 0) { setStepTwoLoader(true); const matchingProcess = procurementCategories.find((item: any) => item._id === processId);
if (matchingProcess) { const templateData = await templatesService.fetchTemplateByIdProcurementProcessId(matchingProcess._id); const matchingProcessEOI = templateData.find((item: any) => item.template_type === "eoi" || item.template_type === "Expression of Interest");
if (matchingProcessEOI) { setDynamicFieldsEOI(matchingProcessEOI); setFormDataEOI(tender.detailsEOI); setStepTwoLoader(false); } else { console.warn('No matching EOI template found.'); setStepTwoLoader(false); } } } } catch (error) { console.error('Error in handleStepTwo:', error); setStepTwoLoader(false); }};- Purpose: This function fetches template data based on the
processIdand updates relevant fields for step two, including the EOI template data.
Handle Step Three (Terms of Reference)
const handleStepThree = async (processId: any, tender: any) => { try { if (procurementCategories.length > 0) { const matchingProcess = procurementCategories.find((item: any) => item._id === processId);
if (matchingProcess) { const templateData = await templatesService.fetchTemplateByIdProcurementProcessId(matchingProcess._id); const matchingProcessTOR = templateData.find((item: any) => item.template_type === "tor" || item.template_type === "Terms of Reference");
setDynamicFieldsTOR(matchingProcessTOR); setFormData(tender.detailsTOR); setStepThreeLoader(false); } } } catch (error) { console.error('Error in handleStepThree:', error); setStepThreeLoader(false); }};- Purpose: Similar to Step Two, this function handles the fetching and setting of data for Step Three (Terms of Reference).
Final Submission
const submitFinal = async (fileNameToSend: any, fileNameToSend2: any) => { try { if (cqsProcurementProcess) { const embedding = await tenderService.summary_embedding({ description: cqsProcurementProcess.description, title: cqsProcurementProcess.title, industry: cqsProcurementProcess.industry, work_location: cqsProcurementProcess.work_location, submission_deadline: cqsProcurementProcess.submission_deadline, });
const updatedCqsProcurementProcess = { ...cqsProcurementProcess, gov_attachment: [fileNameToSend, fileNameToSend2], summary_embedding: embedding?.embedding || [], };
const createdTender = await tenderService.createTender(updatedCqsProcurementProcess); const dataToSend = { id: createdTender.serial_id, docs: [fileNameToSend, fileNameToSend2] };
await tenderService.createDoc(dataToSend); setShowSuccessMessage(true); router.push(`review-tender?tender-id=${createdTender.serial_id}`); } } catch (error) { console.error("Error in submitFinal:", error); toast.error("Error during tender submission."); }};- Purpose: Handles the final submission of the tender and associated files. It ensures that all data is uploaded and that the process moves to the review stage.
Key Components
-
TenderProgressBar: Displays the progress of the current tender process.
-
Dynamic Process Tabs: Renders different components based on the procurement process type (CQS, DSSP, RFQ). Example:
{currentTab === 0 && <AdditionalInfoFrom {...props} />}{currentTab === 1 && <DynamicConversionScreenEOITwo {...props} />}{currentTab === 2 && <DynamicConversionScreenTORTwo {...props} />}{currentTab === 3 && <SubmissionRequirements {...props} />}{currentTab === 3 && <ApproversAndEvaluators {...props} />}{currentTab === 3 && <SubmissionRequirementsForm {...props} />}{currentTab === 3 && <SubmissionRequirementsForm {...props} />}
Error Handling
-
Toast Notifications: Errors are handled gracefully with toast notifications, providing feedback for various errors like server issues or missing information.
-
Loading States: Throughout the tender process, loading states are managed to improve UX by showing loading indicators while data is being fetched or processed.
This documentation provides an overview of how your application manages the tender process, with step-by-step handling and dynamic updates to the UI and data flow.