Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Igce implementation summary #1551

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft

Igce implementation summary #1551

wants to merge 1 commit into from

Conversation

zachclark-ccpo
Copy link
Contributor

@zachclark-ccpo zachclark-ccpo commented Feb 22, 2023

Script overview

import exceljs, { Row, Worksheet } from "exceljs";
import { logger } from "../utils/logging";

import {
  FundingType,
  IndependentGovernmentCostEstimate,
  IPeriodEstimate,
  PeriodType,
} from "../models/document-generation";
import { INTERNAL_SERVER_ERROR } from "../utils/errors";
import { ApiBase64SuccessResponse, SuccessStatusCode } from "../utils/response";

export async function generateIGCEDocument(
  templatePath: string,
  payload: IndependentGovernmentCostEstimate
): Promise<ApiBase64SuccessResponse> {
  // Validation of periodsEstimate
  if (!payload.periodsEstimate && !payload.fundingDocument && !payload.surgeCapabilities) {
    return INTERNAL_SERVER_ERROR;
  }

Imports/validation, standard lambda function implementation. This function promises we return an ApiBase64SuccessResponse...

 // Set headers of API Response
  const headers = {
    "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "Content-Disposition": `attachment; filename=IndependentGovernmentCostEstimate.xlsx`,
  };

  return new ApiBase64SuccessResponse(buffer.toString("base64"), SuccessStatusCode.OK, headers);
}

... which is returned at the bottom of the function.

Lines 21-70

// Sort the base period and option periods
  const basePeriodLineItems = payload.periodsEstimate.filter((periodEstimate: IPeriodEstimate) => {
    return periodEstimate.period.periodType === PeriodType.BASE;
  });
  const optionPeriodsLineItems = payload.periodsEstimate
    .filter((periodEstimate: IPeriodEstimate) => {
      return periodEstimate.period.periodType === PeriodType.OPTION;
    })
    .sort((a, b) => a.period.optionOrder - b.period.optionOrder);

Sorting inputs of the periodsEstimate incoming JSON.

Example payload:

{
    "documentType": "INDEPENDENT_GOVERNMENT_COST_ESTIMATE",
    "templatePayload": {
        "fundingDocument": {
            "fundingType": "MIPR",
            "miprNumber": "MIPR123456789"
        },
        "periodsEstimate": [
            {
                "period": {
                    "periodType": "BASE",
                    "periodUnitCount": "5",
                    "periodUnit": "MONTH",
                    "optionOrder": "1"
                },
                "periodLineItems": [
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Security - Security Services",
                        "itemDescription": " Security Services Il2; entire duration",
                        "unitPrice": 600,
                        "quantity": 5,
                        "unit": "month"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Database - Instance #1",
                        "itemDescription": "3 x (TRANSACTIONAL, , TRANSFER_EXISTING, 20 vCPUs, 20 GB RAM, object storage: 10 GB)",
                        "unitPrice": 450,
                        "quantity": 5,
                        "unit": "month"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Networking - Cloud Service Provider (CSP) Network",
                        "itemDescription": "Cloud Service Provider (CSP) Il2; Entire duration",
                        "unitPrice": 300,
                        "quantity": 5,
                        "unit": "month"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Machine Learning - Specialized Applications",
                        "itemDescription": " Specialized Applications IL2; Base",
                        "unitPrice": 150,
                        "quantity": 5,
                        "unit": "month"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Edge Computing - Mobility",
                        "itemDescription": "Mobility - Man-portable Il6 ; Entire duration",
                        "unitPrice": 850,
                        "quantity": 5,
                        "unit": "month"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Networking - Hybrid Network",
                        "itemDescription": "Hybrid Network Il4 ; base & op2",
                        "unitPrice": 350,
                        "quantity": 5,
                        "unit": "month"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Edge Computing - Conditional Flag indicating military hardening",
                        "itemDescription": "Conditional Flag indicating IL2 ; Base and Op 1 ",
                        "unitPrice": 900,
                        "quantity": 5,
                        "unit": "month"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Security - Security Services",
                        "itemDescription": " Security Services Il6; Base",
                        "unitPrice": 650,
                        "quantity": 5,
                        "unit": "month"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Machine Learning - Specialized Tools",
                        "itemDescription": "Specialized Tools IL2; Entire duration",
                        "unitPrice": 100,
                        "quantity": 5,
                        "unit": "month"
                    }
                ]
            },
            {
                "period": {
                    "periodType": "OPTION",
                    "periodUnitCount": "10",
                    "periodUnit": "WEEK",
                    "optionOrder": "2"
                },
                "periodLineItems": [
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Machine Learning - Specialized Platform as a Service (PaaS)",
                        "itemDescription": "Specialized Platform as a Service IL5; Op1",
                        "unitPrice": 200,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Security - Security Services",
                        "itemDescription": " Security Services Il2; entire duration",
                        "unitPrice": 600,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Database - Instance #1",
                        "itemDescription": "3 x (TRANSACTIONAL, , TRANSFER_EXISTING, 20 vCPUs, 20 GB RAM, object storage: 10 GB)",
                        "unitPrice": 450,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Networking - Cloud Service Provider (CSP) Network",
                        "itemDescription": "Cloud Service Provider (CSP) Il2; Entire duration",
                        "unitPrice": 300,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Database - Instance #2",
                        "itemDescription": "1 x (GRAPH, , TRANSFER_EXISTING, 30 vCPUs, 30 GB RAM, object storage: 30 GB)",
                        "unitPrice": 500,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Edge Computing - Delivery",
                        "itemDescription": "Delivery - Pick-up IL5 ; Op 1 and op2",
                        "unitPrice": 1000,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Security - Custom Security",
                        "itemDescription": "Custom Security Il6 ; Op1 and Op2",
                        "unitPrice": 800,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Edge Computing - Mobility",
                        "itemDescription": "Mobility - Man-portable Il6 ; Entire duration",
                        "unitPrice": 850,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Security - CSP Cloud Security",
                        "itemDescription": "CSP Cloud Security IL4; Op1",
                        "unitPrice": 660,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Edge Computing - Conditional Flag indicating military hardening",
                        "itemDescription": "Conditional Flag indicating IL2 ; Base and Op 1 ",
                        "unitPrice": 900,
                        "quantity": 10,
                        "unit": "week"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Machine Learning - Specialized Tools",
                        "itemDescription": "Specialized Tools IL2; Entire duration",
                        "unitPrice": 100,
                        "quantity": 10,
                        "unit": "week"
                    }
                ]
            },
            {
                "period": {
                    "periodType": "OPTION",
                    "periodUnitCount": "300",
                    "periodUnit": "DAY",
                    "optionOrder": "3"
                },
                "periodLineItems": [
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Security - Security Services",
                        "itemDescription": " Security Services Il2; entire duration",
                        "unitPrice": 600,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Database - Instance #1",
                        "itemDescription": "3 x (TRANSACTIONAL, , TRANSFER_EXISTING, 20 vCPUs, 20 GB RAM, object storage: 10 GB)",
                        "unitPrice": 450,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Networking - Cloud Service Provider (CSP) Network",
                        "itemDescription": "Cloud Service Provider (CSP) Il2; Entire duration",
                        "unitPrice": 300,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Database - Instance #2",
                        "itemDescription": "1 x (GRAPH, , TRANSFER_EXISTING, 30 vCPUs, 30 GB RAM, object storage: 30 GB)",
                        "unitPrice": 500,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Edge Computing - Delivery",
                        "itemDescription": "Delivery - Pick-up IL5 ; Op 1 and op2",
                        "unitPrice": 1000,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Security - Custom Security",
                        "itemDescription": "Custom Security Il6 ; Op1 and Op2",
                        "unitPrice": 800,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Networking - Custom Network",
                        "itemDescription": "Custom Network Il6",
                        "unitPrice": 400,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Machine Learning - Specialized Software as a Service (SaaS)",
                        "itemDescription": "Specialized Software as a Service IL6; Op2",
                        "unitPrice": 250,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x003/x019 Cloud SECRET CLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Edge Computing - Mobility",
                        "itemDescription": "Mobility - Man-portable Il6 ; Entire duration",
                        "unitPrice": 850,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Security - Zero Trust/Permissive Trust Security",
                        "itemDescription": "Zero Trust/Permissive Trust IL5; Op2",
                        "unitPrice": 700,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Networking - Hybrid Network",
                        "itemDescription": "Hybrid Network Il4 ; base & op2",
                        "unitPrice": 350,
                        "quantity": 300,
                        "unit": "day"
                    },
                    {
                        "idiqClin": "x001/x017 Cloud UNCLASSIFIED",
                        "contractType": "T&M",
                        "dowTaskNumber": "TBD",
                        "serviceTitle": "Machine Learning - Specialized Tools",
                        "itemDescription": "Specialized Tools IL2; Entire duration",
                        "unitPrice": 100,
                        "quantity": 300,
                        "unit": "day"
                    }
                ]
            }
        ],
        "contractingShop": {
            "name": "DITCO"
        },
        "instructions": {
            "estimateDescription": "test",
            "assumptionsMade": "assumptions",
            "toolsUsed": "Prices previously paid on a same or similar contract",
            "informationSource": "info source",
            "previousEstimateComparison": "This is not a follow-on task order."
        },
        "surgeCapabilities": null
    }
}

The payload is sorted on the SNOW side, however we sort it again on the Lambda side for extra safety.

  // Set fundingDocumentNumber variable
  // Located at the top of each Period sheet
  let fundingDoc;
  let fundingDocumentNumber = "";
  if (payload.fundingDocument) {
    fundingDoc = payload.fundingDocument;
    switch (fundingDoc.fundingType) {
      case FundingType.FS_FORM:
        fundingDocumentNumber = `Order Number: ${fundingDoc.orderNumber} and GT&C Number: ${fundingDoc.gtcNumber}`;
        break;
      case FundingType.MIPR:
        fundingDocumentNumber = `MIPR Number: ${fundingDoc.miprNumber}`;
        break;
      default:
        fundingDocumentNumber = "";
    }
  }

Setting the fundingDocument number, this will be at the top of each page.

  // Set references for clin and contract drop down boxes
  // These references are on the CLIN Info Page, consist of x001/x017 Cloud UNCLASSIFIED and other CLINs
  const clinRangeString = `'CLIN Info'!$G$2:$G$9`;
  const contractRangeString = `'CLIN Info'!$H$2:$H$4`;

These ranges are on the CLIN Info page:
image

  // Determine unique CLINs from payload...
  // Sort them based on optionOrder
  const uniqueAndSorted = [...new Set(payload.periodsEstimate)].sort(
    (a, b) => a.period.optionOrder - b.period.optionOrder
  );

  // On the Summary sheet, contractCLINHelper will be used to fill
  // unique CLINs with associated contract type.
  const contractCLINHelper: Array<{ clin: string; contract: string }> = [];
  uniqueAndSorted.forEach(function (item) {
    item.periodLineItems.forEach(function (lineItem) {
      contractCLINHelper.push({ clin: lineItem.idiqClin.trim(), contract: lineItem.contractType });
    });
  });

Get the unique CLINs and contractType for a given period.

  // Sort CLINs on Summary Page alphabetically
  contractCLINHelper.sort((a, b) => a.clin.localeCompare(b.clin));
  const uniqueCLINwithContract = [...new Map(contractCLINHelper.map((item) => [item.clin, item])).values()];

Alphabetic sort of the CLINs.

###71-204

// Use Exceljs to generate the workbook
  const workbook = new exceljs.Workbook();
  await workbook.xlsx.readFile(templatePath);

Create the workbook (exceljs notation) from the template file.

  const summarySheet = workbook.getWorksheet("Summary");

getWorksheet on the Summary page, so we can use summarySheet later.

  /* Period sheet helper is used to get the specific cell reference ranges for the summary sheet
    that are generated during populatePeriodLineItems.
    Example output for periodSheetHelper: 
      { period: 'Base Period', cellRef: 'A41:I54' }
      { period: 'Option Period 1', cellRef: 'A28:I41' }
      { period: 'Option Period 2', cellRef: 'A28:I41' }
  */
  const periodSheetHelper: Array<{ period: string; cellRef: string }> = [];

periodSheetHelper stores the range of the summary calculations of each periodSheet:
image
If there are less than 20 items in the periodLineItems for a given period,
the range will always be the default:!A28:I41.

periodSheetHelper's stored summary ranges are used on the Summary sheet:
image

  // Populate Period sheets (Base and Option Periods)
  function populatePeriodLineItems(estimate: IPeriodEstimate): void {
    const { optionOrder, periodUnit, periodUnitCount, periodType } = estimate.period;
    const periodLineItems = estimate.periodLineItems;
    periodLineItems.sort((a, b) => a.idiqClin.localeCompare(b.idiqClin));
    // unique IDIQ Clins PER period sheet
    const uniqueIdiqClins = Array.from(new Set(periodLineItems.map((lineItem) => lineItem.idiqClin)));
    const periodSheetTopStartRow = 8; // On a Period Sheet, the first row is row 8 (see template)
    const periodSheetBottomStartRow = 28; // On a Period Sheet, the first row for the CLIN total calculations is 28
    let periodSheetName: string;

For each period in the periodEstimate object (see example payload above), go through the periodLine items
and write them to the correct periodSheet

    if (periodType === PeriodType.BASE) {
      periodSheetName = "Base Period";
    } else {
      periodSheetName = `Option Period ${optionOrder - 1}`;
      // optionOrder for Base Period is 1, optionOrder for Option Period 1 is 2, optionOrder for Option Period 2 is 3...
      // For determining periodSheetName we need to subtract 1 from the optionOrder of the estimate.period...
      // Old functionality had Base Period's optionOrder as null and Option Period 1 use optionOrder 1...
    }

Determine the sheet that we are currently writing to based on period...

    // Get the specific worksheet
    const periodSheet =
      periodType === PeriodType.BASE
        ? workbook.getWorksheet("Base Period")
        : workbook.getWorksheet(`Option Period ${optionOrder - 1}`);
    // Set Period of Performance and Funding Document Number
    // Located at the top of each Period Sheet
    const pop = `${periodUnitCount} ${periodUnit[0] + periodUnit.slice(1).toLowerCase()}(s)`;
    periodSheet.getCell("C2").value = pop;
    periodSheet.getCell("C3").value = fundingDocumentNumber;

Set static values into the specific cells (funding document number and pop.

    // Track number of Line Items in periodLineItems
    // 20 is the default number of rows built into the template
    // If there are more than 20 items in periodLineItems for a given period, we will need to use
    // duplicateRow to extend the space alotted for these items... using duplicateRow preserves formatting
    const initialUsableRows = 20;
    let numberOfRowsToAdd = 0;
    const numberOfItems = periodLineItems.length;
    if (numberOfItems > initialUsableRows) {
      // If there are more than 20 periodLineItems for a given period, add rows = to the difference
      numberOfRowsToAdd = numberOfItems - initialUsableRows;
      console.log("Number of rows to add: " + numberOfRowsToAdd);
      periodSheet.duplicateRow(26, numberOfRowsToAdd, true);
    }

20 rows is the template default. If there are more than 20 items in the periodLineItems, we need to add more rows.
We accomplish this with duplicateRow which preserves the template formatting.

    // Get lineItemRows
    const lineItemRows = periodSheet.getRows(periodSheetTopStartRow, numberOfItems);

Using excelJs's getRows (Get or create rows by 1-based index)...
We get the row (example row 1) and then set all cells in that row. numberOfItems is the number of cells to fill.

    // Fill each cell in the designated row with periodLineItems info
    lineItemRows?.forEach((row, index) => {
      // Set dropdown for the PeriodSheet cells column A (CLIN/CLIN Title/Classification Level)
      row.getCell("A").value = periodLineItems[index].idiqClin; // idiqClin
      row.getCell("A").dataValidation = {
        type: "list",
        allowBlank: false,
        formulae: [clinRangeString],
      };

.dataValidation allows use to set specific formulae

      // Set dropdown for the PeriodSheet cells column B (Contract)
      row.getCell("B").value = periodLineItems[index].contractType; // Contract Type
      row.getCell("B").dataValidation = {
        type: "list",
        allowBlank: false,
        formulae: [contractRangeString],
      };
      // Set specific values based on the the incomming periodLine items
      row.getCell("C").value = periodLineItems[index].dowTaskNumber; // "4.2.2.1.1";
      row.getCell("D").value = periodLineItems[index].serviceTitle; // "Compute";
      row.getCell("E").value = periodLineItems[index].itemDescription; // Description
      row.getCell("F").value = periodLineItems[index].unitPrice; // Unit Price
      row.getCell("G").value = periodLineItems[index].quantity; // Quantity
      row.getCell("H").value = periodLineItems[index].unit; // Unit

      // Set the total price forumla
      // Example value =F8*G8
      const totalPrice = `=F${row.number}*G${row.number}`;
      row.getCell("I").value = { formula: totalPrice, date1904: false };
      // date 1904 is required or exceljs will have an error generating the document
    });

Maps all the properties of an object in the periodLineItems array.
image
^This part.

    // Populate unique IDIQ CLIN items
    // Located on each Period Sheet (lower half)
    const periodIdiqClinLines = periodSheet.getRows(
      periodSheetBottomStartRow + numberOfRowsToAdd,
      uniqueIdiqClins.length
    );
    // For each IDIQ CLIN Line item
    periodIdiqClinLines?.forEach((row, index) => {
      row.getCell("A").value = uniqueIdiqClins[index];
      // Set formula for totalIdiqClinValue
      const totalIdiqClinValue = `=SUMIF($A${periodSheetTopStartRow}:$A$${
        periodSheetBottomStartRow + numberOfRowsToAdd - 1
      },"="&A$${row.number},'${periodSheetName}'!$I$${periodSheetTopStartRow}:$I$${
        periodSheetBottomStartRow + numberOfRowsToAdd
      })`;
      // Fill formula for the specified cell
      row.getCell("I").value = { formula: totalIdiqClinValue, date1904: false };
    });

Fills up the bottom of the periodSheet with unique CLINs

    // Set periodCellSummary caluclation, this is pushed to periodSheetHelper as cellRef, and used in the summary sheet
    const periodCellSummaryCalculation = `A${periodSheetBottomStartRow + numberOfRowsToAdd}:I${
      periodSheetBottomStartRow + numberOfRowsToAdd + 13
    }`;
    periodSheetHelper.push({ period: periodSheetName, cellRef: periodCellSummaryCalculation });

    // Set the formula for the Total Price of the period sheet (bottom right of table)
    const totalPeriodValueFormula = `=SUM(I${periodSheetBottomStartRow + numberOfRowsToAdd}:I${
      periodSheetBottomStartRow + numberOfRowsToAdd + 13
    })`;
    // Fill the formula for the Total price of the selected period sheet
    periodSheet.getCell(`I${periodSheetBottomStartRow + numberOfRowsToAdd + 14}`).value = {
      formula: totalPeriodValueFormula,
      date1904: false,
    };
  }

image

  // Use populatePeriodLine items on each item in the periodsEstimate array...
  // For each PeriodLineItem in the BASE Period, populatePeriodLineItems()
  basePeriodLineItems.forEach(populatePeriodLineItems);
  // For each PeriodLineItem in the OPTION Period, populatePeriodLineItems()
  optionPeriodsLineItems.forEach(populatePeriodLineItems);

Calling populatePeriodLineItems() on base and option periods.

211-295

 // Set summary page calculation cells
  const summaryRows = summarySheet.getRows(6, uniqueCLINwithContract.length);

6 is the starting point:
image
and we fill it for as many uniqueCLINs exist. In the example above it would be 2 unqiueCLINs.

  summaryRows?.forEach((row, index) => {
    row.getCell("A").dataValidation = {
      type: "list",
      allowBlank: false,
      formulae: [clinRangeString],
    };

Uses the clinRangeString, which is a reference to the CLIN Info sheet.

    row.getCell("A").value = uniqueCLINwithContract[index].clin;
    // CELL C is Contract
    row.getCell("C").dataValidation = {
      type: "list",
      allowBlank: false,
      formulae: [contractRangeString],
    };
    row.getCell("C").value = uniqueCLINwithContract[index].contract;

Uses the contractRangeString, which is a reference to the CLIN Info sheet.

    // CELL D is always Base Period
    const basePeriodCell = periodSheetHelper.find((obj) => {
      return obj.period === "Base Period";
    });

Using specific periodSheet helper to find the summary range for the period sheet.
image
In this example, the range for Base Period would be A28:I41

    const basePeriodCalc = `=IFERROR(VLOOKUP(A${row.number},'Base Period'!${basePeriodCell!.cellRef},9, FALSE),0)`;
    row.getCell("D").value = { formula: basePeriodCalc, date1904: false };
    // CELL E is always Option Period 1
    for (let i = 1; i <= 6; i++) {
      const optionPeriod = periodSheetHelper.find((obj) => {
        return obj.period === `Option Period ${i}`;
      });
      // Skip filling in any option periods that don't exist
      if (!optionPeriod) continue;
      const optionPeriodCalc = `=IFERROR(VLOOKUP(A${row.number},
        'Option Period ${i}'!${optionPeriod.cellRef},9, FALSE),0)`;
      // The base period is "D" and all option periods are offset from that
      const col = String.fromCharCode("D".charCodeAt(0) + i);
      console.log(col);
      row.getCell(col).value = { formula: optionPeriodCalc, date1904: false };
    }
  });

Populates the formula for each period sheet. If an IGCE has 3 periods (base, op1, op2), it would fill 3 cells.
Example formula output =IFERROR(VLOOKUP(A6,'Base Period'!A28:I41,9, FALSE),0)
This formula searches the periodsheet in the specific range for a the matching total CLIN (located at bottom of the periodSheet).

  // Set static Summary sheet cell values
  // Funding Document Number
  const summaryFundingDocCell = summarySheet.getCell("A3");
  summaryFundingDocCell.value = fundingDocumentNumber;

  // Surge Capabilities
  const surgeCapabilities = summarySheet.getCell("A23");
  surgeCapabilities.value = payload.surgeCapabilities / 100;

  // DITCO Fee / Contracting Shop Fee
  const contractingShopName = summarySheet.getCell("B26");
  const contractingShopFee = summarySheet.getCell("C26");
  if (payload.contractingShop.name === "OTHER") {
    contractingShopName.value = "Contracting Office Fee";
    if (payload.contractingShop.fee > 0) {
      const fee = (payload.contractingShop.fee / 100).toFixed(2); // round to 2 decimal places
      contractingShopFee.value = { formula: `=K24 *${fee}`, date1904: false };
    }
  } else if (payload.contractingShop.name === "DITCO") {
    contractingShopName.value = "DITCO Fee";
    contractingShopFee.value = { formula: `=K24 *.0225`, date1904: false };
  }
  // Grand Total With Fee
  const grandTotalWithFee = summarySheet.getCell("C27");
  grandTotalWithFee.value = { formula: `=C26 + K24`, date1904: false };
  // ^End of Summary sheet static cells

  // Set Instruction Sheet Cells
  const instructionSheet = workbook.getWorksheet("INSTRUCTIONS-MUST COMPLETE");
  const estimateMadeCell = instructionSheet.getCell("B11");
  estimateMadeCell.value = payload.instructions.estimateDescription;
  const infoToolsCell = instructionSheet.getCell("B12");
  infoToolsCell.value = payload.instructions.toolsUsed;
  const previousEstimate = instructionSheet.getCell("B13");
  previousEstimate.value = payload.instructions.previousEstimateComparison;

Setting static values.

  // Create a Buffer to store finished workbook
  const buffer = (await workbook.xlsx.writeBuffer()) as Buffer;
  logger.info("IGCE document generated");
  // Set headers of API Response
  const headers = {
    "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "Content-Disposition": `attachment; filename=IndependentGovernmentCostEstimate.xlsx`,
  };

  return new ApiBase64SuccessResponse(buffer.toString("base64"), SuccessStatusCode.OK, headers);
}

Convert the workbook into a buffer so it can be sent as a base64 string.

Added extra comments explaining igce implementation.
@sonarcloud
Copy link

sonarcloud bot commented Feb 22, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

100.0% 100.0% Coverage
0.0% 0.0% Duplication

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant