Skip to content

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 useEffect hook watches for changes in the draft-id and step query parameters. It fetches tender data based on the draft-id and proceeds with the relevant step using fetchTenderData.

  • Dependencies: It depends on searchParams.get("draft-id"), searchParams.get("step"), and procurementCategories.

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 draftId and determines the necessary action based on the stepParam.
  • 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 processId and 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.