department-of-veterans-affairs/vets-website

View on GitHub
src/applications/mhv-medications/util/pdfConfigs.js

Summary

Maintainability
F
4 days
Test Coverage
import {
  createNoDescriptionText,
  createOriginalFillRecord,
  dateFormat,
  processList,
  validateField,
  createVAPharmacyText,
} from './helpers';
import {
  pdfStatusDefinitions,
  pdfDefaultStatusDefinition,
  nonVAMedicationTypes,
} from './constants';

/**
 * @typedef {object} LiItem
 * @property {string} value
 */

/**
 * @typedef {object} Item
 * @property {string | undefined} title
 * @property {string | Array<LiItem>} value
 * @property {boolean | undefined} inline // false by default
 * @property {boolean | undefined} isRich // false by default; must be set to true if value is an array
 * @property {boolean | undefined} disablePageSplit // false by default
 * @property {boolean | undefined} noIndentation // false by default
 */

/**
 * @typedef {object} Section
 * @property {string | undefined} header
 * @property {Array<Item>} items
 * @property {string | undefined} headerSize // 'H4' by default
 */

/**
 * @typedef {Object} PdfConfigItem
 * @property {string | undefined} header
 * @property {boolean | undefined} sectionSeparators // false by default
 * @property {Object | undefined} sectionSeperatorOptions
 * @property {Array<Section>} sections
 */

/**
 * Return Non-VA prescription PDF list
 *
 * @returns {Array<PdfConfigItem>}
 */
export const buildNonVAPrescriptionPDFList = prescription => {
  return [
    {
      sections: [
        {
          items: [
            {
              title: 'Instructions',
              value: validateField(prescription.sig),
              inline: true,
            },
            {
              title: 'Reason for use',
              value: validateField(prescription.indicationForUse),
              inline: true,
            },
            {
              title: 'Status',
              value: validateField(prescription.dispStatus?.toString()),
              inline: true,
            },
            {
              value:
                'A VA provider added this medication record in your VA medical records. But this isn’t a prescription you filled through a VA pharmacy. You can’t request refills or manage this medication through this online tool.',
            },
            {
              title: 'Non-VA medications include these types:',
              value: nonVAMedicationTypes,
              inline: false,
            },
            {
              title: 'When you started taking this medication',
              value: dateFormat(prescription.dispensedDate, 'MMMM D, YYYY'),
              inline: true,
            },
            {
              title: 'Documented by',
              value: prescription.providerLastName
                ? `${
                    prescription.providerLastName
                  }, ${prescription.providerFirstName || ''}`
                : 'None noted',
              inline: true,
            },
            {
              title: 'Documented at this facility',
              value: validateField(prescription.facilityName),
              inline: true,
            },
            {
              title: 'Provider notes',
              value: validateField(
                (prescription.remarks ?? '') +
                  (prescription.disclaimer
                    ? ` ${prescription.disclaimer}`
                    : ''),
              ),
              inline: true,
            },
          ],
        },
      ],
    },
  ];
};

/**
 * Return prescriptions PDF list
 *
 * @returns {Array<PdfConfigItem>}
 */
export const buildPrescriptionsPDFList = prescriptions => {
  return prescriptions?.map(rx => {
    if (rx?.prescriptionSource === 'NV') {
      return {
        ...buildNonVAPrescriptionPDFList(rx)[0],
        header:
          rx.prescriptionName ||
          (rx.dispStatus === 'Active: Non-VA' ? rx.orderableItem : ''),
      };
    }

    return {
      header: rx.prescriptionName,
      sections: [
        {
          header: 'About your prescription',
          items: [
            {
              title: 'Last filled on',
              value: dateFormat(rx.dispensedDate, 'MMMM D, YYYY'),
              inline: true,
            },
            {
              title: 'Status',
              value: validateField(rx.dispStatus),
              inline: true,
            },
            {
              isRich: true,
              value:
                pdfStatusDefinitions[rx.refillStatus] ||
                pdfDefaultStatusDefinition,
            },
            {
              title: 'Refills left',
              value: validateField(rx.refillRemaining),
              inline: true,
            },
            {
              title: 'Request refills by this prescription expiration date',
              value: dateFormat(rx.expirationDate, 'MMMM D, YYYY'),
              inline: true,
            },
            {
              title: 'Prescription number',
              value: rx.prescriptionNumber,
              inline: true,
            },
            {
              title: 'Prescribed on',
              value: dateFormat(rx.orderedDate, 'MMMM D, YYYY'),
              inline: true,
            },
            {
              title: 'Prescribed by',
              value:
                (rx.providerFirstName && rx.providerLastName) || 'None noted',
              inline: true,
            },
            {
              title: 'Facility',
              value: validateField(rx.facilityName),
              inline: true,
            },
            {
              title: 'Pharmacy phone number',
              value: validateField(rx.phoneNumber),
              inline: true,
            },
          ],
        },
        {
          header: 'About this medication or supply',
          items: [
            {
              title: 'Instructions',
              value: validateField(rx.sig),
              inline: true,
            },
            {
              title: 'Reason for use',
              value: validateField(rx.indicationForUse),
              inline: true,
            },
            {
              title: 'Quantity',
              value: validateField(rx.quantity),
              inline: true,
            },
          ],
        },
      ],
    };
  });
};

/**
 * Return medication information PDF
 *
 * @returns {PdfConfigItem}
 */
export const buildMedicationInformationPDF = list => {
  const listOfHeaders = ['h2', 'h3'];
  const sections = [
    ...list
      .filter(listItem => listOfHeaders.includes(listItem.type))
      .map(listItem => {
        const object = { header: '', headerSize: 'H2', items: [] };
        object.header = listItem.text;
        const index = list.indexOf(listItem);
        const nextHeader = list
          .slice(index + 1)
          .find(i => listOfHeaders.includes(i.type));
        const nextIndex = nextHeader ? list.indexOf(nextHeader) : list.length;
        const subList = list.slice(index + 1, nextIndex);
        const isEndOfList = i => subList[i + 1]?.type !== 'li';
        let liArray = [];
        object.items = subList.flatMap((subItem, i) => {
          if (subItem.type === 'li') {
            liArray.push(subItem.text);
            if (isEndOfList(i)) {
              return {
                value: [
                  {
                    value: liArray,
                  },
                ],
                isRich: true,
                disablePageSplit: true,
              };
            }
            return [];
          }
          liArray = [];
          return [
            {
              value: subItem.text,
              noIndentation: true,
              disablePageSplit: true,
            },
          ];
        });
        return object;
      }),
  ];
  return {
    sectionSeparators: false,
    sections,
  };
};

/**
 * Return allergies PDF list
 *
 * @returns {Array<PdfConfigItem>}
 */
export const buildAllergiesPDFList = allergies => {
  return allergies.map(item => {
    return {
      header: item.name,
      sections: [
        {
          items: [
            {
              title: 'Date entered',
              value: validateField(item.date),
              inline: true,
            },
            {
              title: 'Signs and symptoms',
              value: processList(item.reaction),
              inline: true,
            },
            {
              title: 'Type of allergy',
              value: validateField(item.type),
              inline: true,
            },
            {
              title: 'Location',
              value: validateField(item.location),
              inline: true,
            },
            {
              title: 'Observed or historical',
              value: validateField(item.observedOrReported),
              inline: true,
            },
            {
              title: 'Provider notes',
              value: validateField(item.notes),
              inline: !item.notes,
            },
          ],
        },
      ],
    };
  });
};

/**
 * Return VA prescription PDF list
 *
 * @returns {Array<PdfConfigItem>}
 */
export const buildVAPrescriptionPDFList = prescription => {
  const refillHistory = [...(prescription?.rxRfRecords || [])];
  const originalFill = createOriginalFillRecord(prescription);
  refillHistory.push(originalFill);

  return [
    {
      header: 'About your prescription',
      sectionSeparators: false,
      sections: [
        {
          items: [
            {
              title: 'Last filled on',
              value: dateFormat(
                (prescription.rxRfRecords?.length &&
                  prescription.rxRfRecords[0].dispensedDate) ||
                  prescription.dispensedDate,
                'MMMM D, YYYY',
              ),
              inline: true,
            },
            {
              title: 'Status',
              value: validateField(prescription.dispStatus),
              inline: true,
            },
            {
              isRich: true,
              value:
                pdfStatusDefinitions[prescription.refillStatus] ||
                pdfDefaultStatusDefinition,
            },
            {
              title: 'Refills left',
              value: validateField(prescription.refillRemaining),
              inline: true,
            },
            {
              title: 'Request refills by this prescription expiration date',
              value: dateFormat(prescription.expirationDate, 'MMMM D, YYYY'),
              inline: true,
            },
            {
              title: 'Prescription number',
              value: prescription.prescriptionNumber,
              inline: true,
            },
            {
              title: 'Prescribed on',
              value: dateFormat(prescription.orderedDate, 'MMMM D, YYYY'),
              inline: true,
            },
            {
              title: 'Prescribed by',
              value: prescription.providerLastName
                ? `${
                    prescription.providerLastName
                  }, ${prescription.providerFirstName || ''}`
                : 'None noted',
              inline: true,
            },
            {
              title: 'Facility',
              value: validateField(prescription.facilityName),
              inline: true,
            },
            {
              title: 'Pharmacy phone number',
              value: validateField(prescription.phoneNumber),
              inline: true,
            },
          ],
        },
      ],
    },
    {
      header: 'About this medication or supply',
      sectionSeparators: false,
      sections: [
        {
          items: [
            {
              title: 'Instructions',
              value: validateField(prescription.sig),
              inline: true,
            },
            {
              title: 'Reason for use',
              value: validateField(prescription.indicationForUse),
              inline: true,
            },
            {
              title: 'Quantity',
              value: validateField(prescription.quantity),
              inline: true,
            },
          ],
        },
      ],
    },
    {
      header: 'Refill history',
      sectionSeparators: true,
      sectionSeperatorOptions: {
        spaceFromEdge: 16,
        linesAbove: 0,
        linesBelow: 1,
      },
      sections: [
        {
          items: refillHistory
            .map((entry, i) => {
              const { shape, color, backImprint, frontImprint } = entry;
              const index = refillHistory.length - i - 1;
              const phone =
                entry.cmopDivisionPhone || entry.dialCmopDivisionPhone;
              const hasValidDesc =
                shape?.trim() && color?.trim() && frontImprint?.trim();
              const description = hasValidDesc
                ? `* Shape: ${shape[0].toUpperCase()}${shape
                    .slice(1)
                    .toLowerCase()}
* Color: ${color[0].toUpperCase()}${color.slice(1).toLowerCase()}
* Front marking: ${frontImprint}
${backImprint ? `* Back marking: ${backImprint}` : ''}`
                : createNoDescriptionText(phone);
              return [
                {
                  value: [
                    {
                      value: `${
                        index === 0 ? 'First fill' : `Refill ${index}`
                      }`,
                      weight: 'bold',
                      itemSeperator: index !== refillHistory.length - 1,
                      itemSeperatorOptions: {
                        spaceFromEdge: 16,
                        linesAbove: 0.5,
                        linesBelow: 0.7,
                      },
                      font: 'Bitter-Bold',
                      paragraphGap: 4.75,
                    },
                  ],
                  isRich: true,
                },
                {
                  title: 'Medication description',
                  inline: false,
                },
                ...(hasValidDesc
                  ? [
                      {
                        title: 'Note',
                        value: `If the medication you’re taking doesn’t match this description, call ${createVAPharmacyText(
                          phone,
                        )}.`,
                        inline: true,
                      },
                    ]
                  : []),
                {
                  value: description,
                },
                {
                  title: `Filled by pharmacy on`,
                  value: entry?.dispensedDate
                    ? dateFormat(entry.dispensedDate)
                    : 'None noted',
                  inline: true,
                },
                {
                  title: `Shipped on`,
                  value: entry?.trackingList?.[0]?.completeDateTime
                    ? dateFormat(entry.trackingList[0].completeDateTime)
                    : 'None noted',
                  inline: true,
                },
              ];
            })
            .flat(),
        },
      ],
    },
  ];
};