DigitalConsumer.FixMyGlass/src/helpers/page-prerequisites-helper.js
2026-03-10 09:17:03 -04:00

281 lines
11 KiB
JavaScript

import { debugLog } from "@/helpers/debug-log-helper.js";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
import { coverageStatus } from "@/constants/insurance";
import { applicationConfig } from "@/constants/application-config";
/**
* Logs the start of the page prerequisites check.
* Should be used on pages before the page prerequisites check is executed.
* @param {string} source - The source of the page prerequisites check.
* @param {boolean} preReqResult - The result of the page prerequisites check.
*/
export function logPagePrereqsStart(source, preReqResult) {
// prettier-ignore
{
debugLog(`--- ${source} pagePrereqs start ---`, null, !preReqResult);
}
}
/**
* Logs the end of the page prerequisites check.
* Should be used on pages after the page prerequisites check is executed.
* @param {string} source - The source of the page prerequisites check.
* @param {boolean} preReqResult - The result of the page prerequisites check.
*/
export function logPagePrereqsEnd(source, preReqResult) {
// prettier-ignore
{
debugLog(`--- ${source} pagePrereqs end ---`, null, !preReqResult);
}
}
/**
* Flushes the page prerequisites logs.
* @param {string} source - The source of the page prerequisites check. This is the page name most places.
* @param {boolean} preReqResult - The result of the page prerequisites check.
* @param {Array} logQueue - The queue of log functions.
*/
export function flushPagePrereqsLogs(source, preReqResult, logQueue) {
logPagePrereqsStart(source, preReqResult);
logQueue.forEach((fn) => fn());
logPagePrereqsEnd(source, preReqResult);
}
/**
* Pushes a log function to the log queue.
* @param {Array} logQueue - The queue of log functions.
* @param {Function} logFn - The log function to be executed.
*/
function queueLogging(logQueue, logFn) {
if (logQueue) {
logQueue.push(logFn);
}
}
/**
* Checks whether the service zip code information is valid for the order.
* Should be used on pages after service zip code collection is complete.
* Returns true if the zip code and zip code CTU are present on serviceLocation.
*/
export function hasServiceZipInfo(order, logQueue = null) {
const serviceLocation = order.serviceLocation;
const result = !!(serviceLocation.zipCode && serviceLocation.zipCodeCtu);
queueLogging(logQueue, () => {
// prettier-ignore
{
debugLog("hasServiceZipInfo:", result, !result);
debugLog("serviceLocation.zipCode:", serviceLocation.zipCode, !result);
debugLog("serviceLocation.zipCodeCtu:", serviceLocation.zipCodeCtu, !result);
debugLog("", null, !result);
}
});
return result;
}
/**
* Checks whether the service location information is valid for the appointment.
* Returns true if the required info is present for the chosen appointment type.
* For MOBILE: address, city, state, and zipCode must be present on serviceLocation.
* For INSHOP/DROPOFF: all provider address fields must be present.
*/
export function hasServiceLocationInfo(order, logQueue = null) {
const serviceLocation = order.serviceLocation;
const mobileReqs = !!(
serviceLocation.address &&
serviceLocation.city &&
serviceLocation.state &&
serviceLocation.zipCode
);
const providerLocation = serviceLocation.provider.address;
const dropOffInshopReqs = !!(
providerLocation.streetAddress &&
providerLocation.city &&
providerLocation.state &&
providerLocation.zipCode
);
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
const result = (isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);
queueLogging(logQueue, () => {
// prettier-ignore
{
debugLog("hasServiceLocationInfo mobileReqs:", mobileReqs, !result);
debugLog("serviceLocation.address:", serviceLocation.address, !result);
debugLog("serviceLocation.city:", serviceLocation.city, !result);
debugLog("serviceLocation.state:", serviceLocation.state, !result);
debugLog("serviceLocation.zipCode:", serviceLocation.zipCode, !result);
debugLog("dropOffInshopReqs:", dropOffInshopReqs, !result);
debugLog("providerLocation.streetAddress:", providerLocation.streetAddress, !result);
debugLog("providerLocation.city:", providerLocation.city, !result);
debugLog("providerLocation.state:", providerLocation.state, !result);
debugLog("providerLocation.zipCode:", providerLocation.zipCode, !result);
debugLog("", null, !result);
}
});
return result;
}
/**
* Checks whether the insurance information is valid for the order. To be used after all insurance info collection is complete.
* Returns true if cash selected or if insurance is selected and some insurance fields are present.
*/
export function hasInsuranceInfo(order, logQueue = null) {
const isInsurance = order.payment?.isInsurance;
const insuranceCoverageStatus = order.payment?.insuranceCoverage?.coverageStatus;
const currentDeductible = order.policy?.currentDeductible;
const parentAccountNumber = order.payment?.parentAccountNumber;
const policyNumber = order.policy?.policyNumber;
let result = false;
if (isInsurance !== null) {
if (isInsurance === false) {
result = true; // Cash selected - no need for policy number or parent account
} else {
const parentAccountNotCash =
parentAccountNumber !== applicationConfig.CASH_PARENT_ACCOUNT_NUMBER;
const hasPolicyNumber = !!policyNumber;
if (!parentAccountNotCash || !hasPolicyNumber) {
result = false;
} else if (
insuranceCoverageStatus === coverageStatus.VERIFIED &&
!(currentDeductible === 0 || currentDeductible > 0)
) {
result = false; // if coverageStatus is verified there must be a valid deductible also
} else {
result = true;
}
}
}
queueLogging(logQueue, () => {
// prettier-ignore
{
debugLog("hasInsuranceInfo:", result, !result);
if (isInsurance === true) {
debugLog("hasInsuranceInfo parentAccountNumber:", parentAccountNumber, !result);
debugLog("hasInsuranceInfo policyNumber:", policyNumber, !result);
}
if (insuranceCoverageStatus === coverageStatus.VERIFIED) {
debugLog("hasInsuranceInfo coverageStatus:", insuranceCoverageStatus, !result);
debugLog("hasInsuranceInfo currentDeductible:", currentDeductible, !result);
}
debugLog("", null, !result);
}
});
return result;
}
/**
* Checks whether the scheduling information is valid for the order.
* Should be used on pages after scheduling info collection is complete.
* Returns true if the required info is present for the chosen appointment type.
* For MOBILE: date, startTime, endTime, jobMaxMinutes, and jobMinMinutes must be present on schedule.
* For INSHOP/DROPOFF: all provider scheduling fields must be present.
*/
export function hasSchedulingInfo(order, logQueue = null) {
const schedule = order.schedule;
const result = !!(
schedule.date &&
schedule.startTime &&
schedule.endTime &&
schedule.jobMaxMinutes &&
schedule.jobMinMinutes
);
queueLogging(logQueue, () => {
// prettier-ignore
{
debugLog("hasSchedulingInfo:", result, !result);
debugLog("schedule.date:", schedule.date, !result);
debugLog("schedule.startTime:", schedule.startTime, !result);
debugLog("schedule.endTime:", schedule.endTime, !result);
debugLog("schedule.jobMaxMinutes:", schedule.jobMaxMinutes, !result);
debugLog("schedule.jobMinMinutes:", schedule.jobMinMinutes, !result);
debugLog("", null, !result);
}
});
return result;
}
/**
* Checks whether the customer information is valid for the order.
* Should be used on pages after customer info collection is complete.
* Returns true if the firstName, lastName, phoneNumber, and emailAddress are present on customer.
*/
export function hasCustomerInfo(order, logQueue = null) {
const customer = order.customer;
const result = !!(
customer.firstName &&
customer.lastName &&
customer.phoneNumber &&
customer.emailAddress
);
queueLogging(logQueue, () => {
// prettier-ignore
{
debugLog("hasCustomerInfo:", result, !result);
debugLog("customer.firstName:", customer.firstName, !result);
debugLog("customer.lastName:", customer.lastName, !result);
debugLog("customer.phoneNumber:", customer.phoneNumber, !result);
debugLog("customer.emailAddress:", customer.emailAddress, !result);
debugLog("", null, !result);
}
});
return result;
}
/**
* Checks whether the glass parts or repair information is valid for the order.
* Should be used on pages after glass parts or repair info collection is complete.
* Returns true if the isRepair is true or if the glassParts array is not empty.
*/
export function hasGlassPartsOrRepairInfo(order, logQueue = null) {
const isRepair = order.damage?.isRepair;
const glassParts = order.lineItems?.glassParts;
const hasGlassParts = glassParts != null && glassParts.length > 0;
const result = !!isRepair || hasGlassParts;
queueLogging(logQueue, () => {
// prettier-ignore
{
debugLog("hasGlassPartsOrRepairInfo:", result, !result);
debugLog("damage.isRepair:", isRepair, !result);
debugLog("lineItems.glassParts:", glassParts, !result);
debugLog("", null, !result);
}
});
return result;
}
/**
* Checks whether the payment method information is valid for the order.
* Should only be used on pages after payment method info collection is complete which is only the payment collection pages.
* Returns true if the isPia is true or if the piaType is set.
*/
export function hasPaymentMethodInfo(order, logQueue = null) {
const payment = order.payment;
const result = payment.isPia !== null && (payment.isPia || !!payment.piaType);
queueLogging(logQueue, () => {
// prettier-ignore
{
debugLog("hasPaymentMethodInfo:", result, !result);
debugLog("payment.isPia:", payment?.isPia, !result);
debugLog("payment.piaType:", payment?.piaType, !result);
debugLog("", null, !result);
}
});
return result;
}