From 2fe6776f4101f42b6072087700f0beb962f229cc Mon Sep 17 00:00:00 2001 From: David Graham Date: Tue, 28 Nov 2023 19:22:03 -0500 Subject: [PATCH] move quicker sign buttons to SignBtn folder add manifest service module for business logic related to the uniform hazardous waste manifest move api related web service modules to a subdirectory called APIs --- .../src/components/Manifest/ManifestForm.tsx | 23 ++---- .../Manifest/QuickerSign/QuickerSignForm.tsx | 25 +++++- .../HandlerSignBtn.spec.tsx} | 14 ++-- .../HandlerSignBtn.tsx} | 15 ++-- .../components/Manifest/QuickerSign/index.ts | 7 +- .../Manifest/QuickerSign/quickerSignSchema.ts | 22 ------ .../Manifest/Transporter/TransporterTable.tsx | 4 +- .../src/components/Manifest/manifestSchema.ts | 75 +++++------------- .../SyncManifestBtn/SyncManifestBtn.tsx | 2 +- client/src/services/{ => APIs}/UserApi.ts | 2 +- client/src/services/{ => APIs}/htApi.ts | 0 client/src/services/{ => APIs}/manifestApi.ts | 2 +- client/src/services/index.ts | 8 +- client/src/services/manifest/manifest.spec.ts | 76 +++++++++++++++++++ client/src/services/manifest/manifest.ts | 31 ++++++++ 15 files changed, 181 insertions(+), 125 deletions(-) rename client/src/components/Manifest/QuickerSign/{QuickerSignModalBtn.spec.tsx => SignBtn/HandlerSignBtn.spec.tsx} (89%) rename client/src/components/Manifest/QuickerSign/{QuickerSignModalBtn.tsx => SignBtn/HandlerSignBtn.tsx} (79%) delete mode 100644 client/src/components/Manifest/QuickerSign/quickerSignSchema.ts rename client/src/services/{ => APIs}/UserApi.ts (97%) rename client/src/services/{ => APIs}/htApi.ts (100%) rename client/src/services/{ => APIs}/manifestApi.ts (95%) create mode 100644 client/src/services/manifest/manifest.spec.ts create mode 100644 client/src/services/manifest/manifest.ts diff --git a/client/src/components/Manifest/ManifestForm.tsx b/client/src/components/Manifest/ManifestForm.tsx index 0229526b0..0e81b67d8 100644 --- a/client/src/components/Manifest/ManifestForm.tsx +++ b/client/src/components/Manifest/ManifestForm.tsx @@ -11,11 +11,11 @@ import { Alert, Button, Col, Form, Row } from 'react-bootstrap'; import { FormProvider, SubmitHandler, useFieldArray, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { toast } from 'react-toastify'; -import { manifestApi } from 'services/manifestApi'; +import { manifest, manifestApi } from 'services'; import { ContactForm, PhoneForm } from './Contact'; import { AddHandler, GeneratorForm, Handler } from './Handler'; import { Manifest, manifestSchema, ManifestStatus } from './manifestSchema'; -import { QuickerSignData, QuickerSignModal, QuickerSignModalBtn } from './QuickerSign'; +import { HandlerSignBtn, QuickerSignData, QuickerSignModal } from './QuickerSign'; import { Transporter, TransporterTable } from './Transporter'; import { EditWasteModal, WasteLineTable } from './WasteLine'; @@ -34,6 +34,7 @@ export interface ManifestContextType { setTsdfStateCode: React.Dispatch>; editWasteLineIndex?: number; setEditWasteLineIndex: React.Dispatch>; + signingSite?: string | undefined; } interface ManifestFormProps { @@ -51,6 +52,7 @@ export const ManifestContext = createContext({ setTsdfStateCode: () => {}, editWasteLineIndex: undefined, setEditWasteLineIndex: () => {}, + signingSite: undefined, }); /** @@ -138,7 +140,7 @@ export function ManifestForm({ const [showSignForm, setShowSignForm] = useState(false); const [quickerSignHandler, setQuickerSignHandler] = useState({ handler: undefined, - siteType: 'Generator', // ToDo initialize to undefined + siteType: 'Generator', }); const toggleQuickerSignShow = () => setShowSignForm(!showSignForm); const setupSign = (signContext: QuickerSignData) => { @@ -178,6 +180,7 @@ export function ManifestForm({ setTsdfStateCode: setTsdfStateCode, editWasteLineIndex: editWasteLine, setEditWasteLineIndex: setEditWasteLine, + signingSite: manifest.getNextSigner(manifestData), }} > @@ -389,7 +392,7 @@ export function ManifestForm({
- ) : generator && !showGeneratorForm ? ( - // If the form holds a value for generator, but they don't need to edit the - // generators values (allowed) then display the site details in a nice read only way <> @@ -409,16 +410,12 @@ export function ManifestForm({
) : showGeneratorForm ? ( - // Show the Handler form with current value for the generator - // The HandlerForm allows for fine-grained control over the handler inputs <>

Emergency Contact Information

) : ( - // default on a blank manifest, ask if they'd like to search for a generator to - // add, or if the user would like to manually enter the generator's info. <> - {/* List transporters */} - {/* Table Showing current Waste Lines included on the manifest */} - {/* Where The Tsdf information is added and displayed */} @@ -517,7 +511,7 @@ export function ManifestForm({
{/* Button to bring up the Quicker Sign modal*/} - - {/* Additional information for the manifest, such as reference information*/} diff --git a/client/src/components/Manifest/QuickerSign/QuickerSignForm.tsx b/client/src/components/Manifest/QuickerSign/QuickerSignForm.tsx index f5e83f4ca..8eb8f9231 100644 --- a/client/src/components/Manifest/QuickerSign/QuickerSignForm.tsx +++ b/client/src/components/Manifest/QuickerSign/QuickerSignForm.tsx @@ -2,7 +2,6 @@ import { faFileSignature } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { AxiosError } from 'axios'; import { Handler, RcraSiteType } from 'components/Manifest/manifestSchema'; -import { QuickerSignature } from 'components/Manifest/QuickerSign/quickerSignSchema'; import { Transporter } from 'components/Manifest/Transporter'; import { HtForm } from 'components/UI'; import React from 'react'; @@ -10,8 +9,30 @@ import { Button, Col, Container, Form, ListGroup, Row } from 'react-bootstrap'; import { SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { toast } from 'react-toastify'; -import { manifestApi } from 'services/manifestApi'; +import { manifestApi } from 'services'; import { selectUserName, useAppSelector } from 'store'; +import { z } from 'zod'; + +const siteType = z.enum(['Transporter', 'Generator', 'Tsdf', 'Broker']); +/** + * The EPA Quicker Sign schema + */ +const quickerSignatureSchema = z.object({ + siteId: z.string(), + siteType: siteType, + transporterOrder: z.number().optional(), + printedSignatureName: z.string(), + printedSignatureDate: z.string(), + manifestTrackingNumbers: z.string().array(), +}); + +const quickerSignDataSchema = z.object({ + handler: z.any(), + siteType: z.enum(['Generator', 'Transporter', 'Tsdf']), +}); + +export type QuickerSignData = z.infer; +export type QuickerSignature = z.infer; interface QuickerSignProps { mtn: Array; diff --git a/client/src/components/Manifest/QuickerSign/QuickerSignModalBtn.spec.tsx b/client/src/components/Manifest/QuickerSign/SignBtn/HandlerSignBtn.spec.tsx similarity index 89% rename from client/src/components/Manifest/QuickerSign/QuickerSignModalBtn.spec.tsx rename to client/src/components/Manifest/QuickerSign/SignBtn/HandlerSignBtn.spec.tsx index fb26128cb..5fa445284 100644 --- a/client/src/components/Manifest/QuickerSign/QuickerSignModalBtn.spec.tsx +++ b/client/src/components/Manifest/QuickerSign/SignBtn/HandlerSignBtn.spec.tsx @@ -1,5 +1,5 @@ import '@testing-library/jest-dom'; -import { QuickerSignModalBtn } from 'components/Manifest/QuickerSign/index'; +import { HandlerSignBtn } from 'components/Manifest/QuickerSign/index'; import React from 'react'; import { cleanup, renderWithProviders, screen } from 'test-utils'; import { createMockMTNHandler } from 'test-utils/fixtures'; @@ -13,11 +13,7 @@ describe('QuickerSignModalBtn', () => { test('renders', () => { const handler = createMockMTNHandler(); renderWithProviders( - undefined} - /> + undefined} /> ); expect(screen.getByRole('button')).toBeInTheDocument(); }); @@ -26,7 +22,7 @@ describe('QuickerSignModalBtn', () => { signed: true, }); renderWithProviders( - undefined} @@ -41,7 +37,7 @@ describe('QuickerSignModalBtn', () => { electronicSignaturesInfo: undefined, }); renderWithProviders( - undefined} @@ -73,7 +69,7 @@ describe('QuickerSignModalBtn', () => { signed: true, }); renderWithProviders( - undefined} diff --git a/client/src/components/Manifest/QuickerSign/QuickerSignModalBtn.tsx b/client/src/components/Manifest/QuickerSign/SignBtn/HandlerSignBtn.tsx similarity index 79% rename from client/src/components/Manifest/QuickerSign/QuickerSignModalBtn.tsx rename to client/src/components/Manifest/QuickerSign/SignBtn/HandlerSignBtn.tsx index d8163c638..b44bd64c4 100644 --- a/client/src/components/Manifest/QuickerSign/QuickerSignModalBtn.tsx +++ b/client/src/components/Manifest/QuickerSign/SignBtn/HandlerSignBtn.tsx @@ -1,8 +1,9 @@ import { faFeather } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { ManifestContext } from 'components/Manifest/ManifestForm'; import { Handler, RcraSiteType } from 'components/Manifest/manifestSchema'; import { RcraApiUserBtn } from 'components/Rcrainfo'; -import React from 'react'; +import React, { useContext } from 'react'; import { ButtonProps } from 'react-bootstrap'; import { siteByEpaIdSelector, useAppSelector } from 'store'; @@ -23,16 +24,18 @@ interface QuickerSignModalBtnProps extends ButtonProps { * The button will be disabled if siteId (the EPA ID number) is not provided * @constructor */ -export function QuickerSignModalBtn({ +export function HandlerSignBtn({ siteType, mtnHandler, handleClick, disabled, iconOnly = false, }: QuickerSignModalBtnProps) { - if (!useAppSelector(siteByEpaIdSelector(mtnHandler?.epaSiteId))) { - return <>; - } + const { signingSite } = useContext(ManifestContext); + if (!useAppSelector(siteByEpaIdSelector(mtnHandler?.epaSiteId))) return <>; + + if (mtnHandler?.epaSiteId !== signingSite) return <>; + return ( { @@ -40,7 +43,7 @@ export function QuickerSignModalBtn({ }} disabled={disabled} > - {iconOnly ? '' : 'Quicker Sign '} + {iconOnly ? '' : 'Sign '} ); diff --git a/client/src/components/Manifest/QuickerSign/index.ts b/client/src/components/Manifest/QuickerSign/index.ts index 90aef679f..8fef51e2b 100644 --- a/client/src/components/Manifest/QuickerSign/index.ts +++ b/client/src/components/Manifest/QuickerSign/index.ts @@ -1,7 +1,6 @@ -import { QuickerSignForm } from './QuickerSignForm'; +import { HandlerSignBtn } from 'components/Manifest/QuickerSign/SignBtn/HandlerSignBtn'; +import { QuickerSignature, QuickerSignData, QuickerSignForm } from './QuickerSignForm'; import { QuickerSignModal } from './QuickerSignModal'; -import { QuickerSignModalBtn } from './QuickerSignModalBtn'; -import { QuickerSignature, QuickerSignData } from './quickerSignSchema'; -export { QuickerSignForm, QuickerSignModal, QuickerSignModalBtn }; +export { QuickerSignForm, QuickerSignModal, HandlerSignBtn }; export type { QuickerSignature, QuickerSignData }; diff --git a/client/src/components/Manifest/QuickerSign/quickerSignSchema.ts b/client/src/components/Manifest/QuickerSign/quickerSignSchema.ts deleted file mode 100644 index 0744cb6ae..000000000 --- a/client/src/components/Manifest/QuickerSign/quickerSignSchema.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { z } from 'zod'; - -const siteType = z.enum(['Transporter', 'Generator', 'Tsdf', 'Broker']); -/** - * The EPA Quicker Sign schema - */ -const quickerSignatureSchema = z.object({ - siteId: z.string(), - siteType: siteType, - transporterOrder: z.number().optional(), - printedSignatureName: z.string(), - printedSignatureDate: z.string(), - manifestTrackingNumbers: z.string().array(), -}); - -const quickerSignDataSchema = z.object({ - handler: z.any(), - siteType: z.enum(['Generator', 'Transporter', 'Tsdf']), -}); - -export type QuickerSignData = z.infer; -export type QuickerSignature = z.infer; diff --git a/client/src/components/Manifest/Transporter/TransporterTable.tsx b/client/src/components/Manifest/Transporter/TransporterTable.tsx index d2e8007a6..5b23a73a5 100644 --- a/client/src/components/Manifest/Transporter/TransporterTable.tsx +++ b/client/src/components/Manifest/Transporter/TransporterTable.tsx @@ -3,7 +3,7 @@ import { faAngleRight, faCheck, faSignature } from '@fortawesome/free-solid-svg- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Transporter } from 'components/Manifest'; import { Manifest } from 'components/Manifest/manifestSchema'; -import { QuickerSignData, QuickerSignModalBtn } from 'components/Manifest/QuickerSign'; +import { HandlerSignBtn, QuickerSignData } from 'components/Manifest/QuickerSign'; import React, { useState } from 'react'; import { Accordion, Button, Card, Col, Row, Table, useAccordionButton } from 'react-bootstrap'; import { UseFieldArrayReturn } from 'react-hook-form'; @@ -67,7 +67,7 @@ function TransporterTable({ {readOnly ? ( - ; export const rcraSiteType = z.enum(['Generator', 'Tsdf', 'Transporter']); -/** - * The RCRAInfo/e-Manifest enum used to indicate site type - */ +/** The RCRAInfo/e-Manifest enum used to indicate site type*/ export type RcraSiteType = z.infer; export const paperSignatureSchema = z.object({ @@ -22,13 +17,9 @@ export const paperSignatureSchema = z.object({ export type PaperSignature = z.infer; -/** - * Schema for signer of a hazardous waste manifest - */ +/** Schema for signer of a hazardous waste manifest*/ const signerSchema = z.object({ - /** - * User's RCRAInfo username - */ + /** User's RCRAInfo username*/ userId: z.string().optional(), firstName: z.string().optional(), middleInitial: z.string().optional(), @@ -38,33 +29,22 @@ const signerSchema = z.object({ companyName: z.string().optional(), contactType: z.enum(['Email', 'Text', 'Voice']), }); -/** - * EPA's RCRAInfo electronic signature schema - */ +/** EPA's RCRAInfo electronic signature schema*/ export const electronicSignatureSchema = z.object({ signer: signerSchema.optional(), signatureDate: z.date().optional(), - /** - * Object representing metadata on a printable, human friendly, version of the manifest - * ToDo: see the USEPA/e-Manifest documentation on GitHub - */ + /**Object representing metadata on a printable, human friendly, version of the manifest */ humanReadableDocument: z.any().optional(), }); export const handlerSchema = rcraSite.extend({ paperSignatureInfo: paperSignatureSchema.optional(), electronicSignaturesInfo: electronicSignatureSchema.array().optional(), - /** - * Property on by back end to signify whether the handler has signed - */ + /**Haztrak specific Property to signify whether the handler has signed*/ signed: z.boolean().optional(), }); -/** - * The Handler extends the RcraSite schema and adds manifest specific data - */ + +/**The Handler extends the RcraSite schema and adds manifest specific data*/ export type Handler = z.infer; -/** - * The Signature that appears on paper versions of the manifest - */ export const transporterSchema = handlerSchema.extend({ order: z.number(), @@ -83,42 +63,24 @@ const manifestStatusEnum = z.enum([ 'MtnValidationFailed', ]); -/** - * Available statuses for a manifest as defined by EPA - */ +/** Available statuses for a manifest as defined by EPA*/ export type ManifestStatus = z.infer; -/** - * The Transporter type extends the Handler schema and adds transporter - * specific data, such as their order on the manifest - */ +/** The Manifest Transporter type extends the Handler schema*/ export type Transporter = z.infer; -/** - * A signer of a hazardous waste manifest - */ +/** A signer of a hazardous waste manifest*/ export type Signer = z.infer; -/** - * RCRAInfo electronic signature definition - */ +/** RCRAInfo electronic signature definition*/ export type ElectronicSignature = z.infer; export const manifestSchema = z .object({ manifestTrackingNumber: z.string().optional(), - /** - * The date-time the manifest was created in the e-Manifest system. - * Managed by EPA's systems. - */ + /** The date-time the manifest was created in the e-Manifest system, managed by EPA's systems.*/ createdDate: z.string().optional(), - /** - * The last date-time manifest was updated in the e-Manifest system. - * Managed by EPA's systems. - */ + /** The last date-time manifest was updated in the e-Manifest system, managed by EPA's systems.*/ updatedDate: z.string().optional(), - /** - * The date-time the hazardous waste shipment departed (was signed by) the generator. - * Managed by EPA's systems, but not present on pre-shipment manifests. - */ + /** The date-time the waste shipment departed the generator. Managed by EPA's systems*/ shippedDate: z.string().optional(), import: z.boolean().optional(), rejection: z.boolean().optional(), @@ -127,16 +89,13 @@ export const manifestSchema = z .optional() .transform((val) => { if (val === '' || val === undefined) { - // If empty string or undefined, return undefined return undefined; } else { return new Date(val).toISOString(); } }), status: manifestStatusEnum, - /** - * Whether the manifest is publicly available through EPA - */ + /** Whether the manifest is publicly available through EPA*/ isPublic: z.boolean().optional(), generator: handlerSchema.optional(), transporters: z.array(transporterSchema), diff --git a/client/src/components/Rcrainfo/buttons/SyncManifestBtn/SyncManifestBtn.tsx b/client/src/components/Rcrainfo/buttons/SyncManifestBtn/SyncManifestBtn.tsx index 052b12a37..6299349d8 100644 --- a/client/src/components/Rcrainfo/buttons/SyncManifestBtn/SyncManifestBtn.tsx +++ b/client/src/components/Rcrainfo/buttons/SyncManifestBtn/SyncManifestBtn.tsx @@ -4,7 +4,7 @@ import { AxiosError } from 'axios'; import { RcraApiUserBtn } from 'components/Rcrainfo/buttons/RcraApiUserBtn/RcraApiUserBtn'; import { useProgressTracker } from 'hooks'; import React, { useEffect, useState } from 'react'; -import { manifestApi } from 'services/manifestApi'; +import { manifestApi } from 'services'; import { addTask, updateTask, useAppDispatch } from 'store'; interface SyncManifestProps { diff --git a/client/src/services/UserApi.ts b/client/src/services/APIs/UserApi.ts similarity index 97% rename from client/src/services/UserApi.ts rename to client/src/services/APIs/UserApi.ts index 7656a27fa..67804a049 100644 --- a/client/src/services/UserApi.ts +++ b/client/src/services/APIs/UserApi.ts @@ -1,7 +1,7 @@ import { AxiosResponse } from 'axios'; import { HaztrakSite } from 'components/HaztrakSite'; -import { htApi } from 'services/htApi'; import { HaztrakModulePermissions, HaztrakUser, RcrainfoProfile, RcrainfoProfileSite } from 'store'; +import { htApi } from './htApi'; interface HaztrakOrgResponse { id: string; diff --git a/client/src/services/htApi.ts b/client/src/services/APIs/htApi.ts similarity index 100% rename from client/src/services/htApi.ts rename to client/src/services/APIs/htApi.ts diff --git a/client/src/services/manifestApi.ts b/client/src/services/APIs/manifestApi.ts similarity index 95% rename from client/src/services/manifestApi.ts rename to client/src/services/APIs/manifestApi.ts index 60eddd6a6..3ad145a67 100644 --- a/client/src/services/manifestApi.ts +++ b/client/src/services/APIs/manifestApi.ts @@ -1,8 +1,8 @@ import { AxiosResponse } from 'axios'; import { Manifest } from 'components/Manifest'; import { QuickerSignature } from 'components/Manifest/QuickerSign'; -import { htApi } from 'services/htApi'; import { TaskStatus } from 'store'; +import { htApi } from './htApi'; export const manifestApi = { /** Sign a manifest through the Haztrak Proxy endpoint */ diff --git a/client/src/services/index.ts b/client/src/services/index.ts index 9f7f7fb86..0f76efe72 100644 --- a/client/src/services/index.ts +++ b/client/src/services/index.ts @@ -1,4 +1,4 @@ -import { htApi } from 'services/htApi'; -import { UserApi } from 'services/UserApi'; - -export { htApi, UserApi }; +export { htApi } from 'services/APIs/htApi'; +export { UserApi } from 'services/APIs/UserApi'; +export { manifestApi } from 'services/APIs/manifestApi'; +export { manifest } from 'services/manifest/manifest'; diff --git a/client/src/services/manifest/manifest.spec.ts b/client/src/services/manifest/manifest.spec.ts new file mode 100644 index 000000000..0255c805f --- /dev/null +++ b/client/src/services/manifest/manifest.spec.ts @@ -0,0 +1,76 @@ +import { manifest } from 'services/manifest/manifest'; +import { + createMockManifest, + createMockMTNHandler, + createMockTransporter, +} from 'test-utils/fixtures'; +import { describe, expect, test } from 'vitest'; + +describe('manifest.getNextSigner', () => { + test('returns the the generator if scheduled and no generator signature present', () => { + // Arrange + const mockId = 'VATESTGEN001'; + const generator = createMockMTNHandler({ + epaSiteId: mockId, + electronicSignaturesInfo: [], + siteType: 'Generator', + }); + const mockManifest = createMockManifest({ + status: 'Scheduled', + generator, + }); + // Act + const result = manifest.getNextSigner(mockManifest); + // Assert + expect(result).toBe(mockId); + }); + test('returns the TSDF if ReadyForSignature', () => { + const mockId = 'VATESTTSDF001'; + const designatedFacility = createMockMTNHandler({ + epaSiteId: mockId, + electronicSignaturesInfo: [], + siteType: 'Tsdf', + }); + const mockManifest = createMockManifest({ + status: 'ReadyForSignature', + designatedFacility, + }); + const result = manifest.getNextSigner(mockManifest); + expect(result).toBe(mockId); + }); + test('returns the first transporter if "Scheduled" status and generator signed', () => { + const mockId = 'VATESTTRANS1'; + const mockTransporter = createMockTransporter({ + epaSiteId: mockId, + electronicSignaturesInfo: [], + siteType: 'Transporter', + }); + const generator = createMockMTNHandler({ + epaSiteId: mockId, + electronicSignaturesInfo: [ + { + signer: { firstName: 'John', lastName: 'Doe', contactType: 'Email' }, + }, + ], + siteType: 'Generator', + }); + const mockManifest = createMockManifest({ + status: 'Scheduled', + transporters: [mockTransporter], + generator, + }); + const result = manifest.getNextSigner(mockManifest); + expect(result).toBe(mockId); + }); + test.each(['NotAssigned', 'Pending', 'Corrected', 'Signed', 'UnderCorrection'])( + `returns undefined if status is %s`, + (status: string) => { + const mockManifest = createMockManifest({ + // @ts-ignore + status, + }); + const result = manifest.getNextSigner(mockManifest); + expect(result).toBe(undefined); + } + ); +}); diff --git a/client/src/services/manifest/manifest.ts b/client/src/services/manifest/manifest.ts new file mode 100644 index 000000000..f7f2d038f --- /dev/null +++ b/client/src/services/manifest/manifest.ts @@ -0,0 +1,31 @@ +import { Manifest } from 'components/Manifest'; + +export const manifest = { + /** Returns EPA ID of the next site that can sign on a manifest or undefined if not applicable. */ + getNextSigner(manifest: Partial | undefined): string | undefined { + if (manifest === undefined || manifest === null || manifest.status === undefined) { + return undefined; + } + if ( + manifest.status === 'Scheduled' && + !manifest.generator?.electronicSignaturesInfo?.[0]?.signer && + manifest.generator + ) { + return manifest.generator.epaSiteId; + } + if (manifest.status === 'Scheduled' && manifest.transporters?.length === 1) { + return manifest.transporters[0].epaSiteId; + } + if (manifest.status === 'InTransit' && manifest.transporters) { + for (const transporter of manifest.transporters) { + if (!transporter.electronicSignaturesInfo?.[0].signer) { + return transporter.epaSiteId; + } + } + } + if (manifest.status === 'ReadyForSignature' && manifest.designatedFacility) { + return manifest.designatedFacility.epaSiteId; + } + return undefined; + }, +};