fix(work-orders): keep completion freeze on live registry edits

This commit is contained in:
Arthur Bassi 2026-09-10 18:47:32 -03:00
parent 1809694973
commit c7aec49f05
20 changed files with 208 additions and 59 deletions

View file

@ -46,7 +46,7 @@ export function CompDocDetailsSection({
<CompDocDetailRow <CompDocDetailRow
icon={MapPin} icon={MapPin}
label="Site Code" label="Site Code"
value={`${row.site} · Amazon.com Services LLC`} value={`${site.code} · Amazon.com Services LLC`}
/> />
<CompDocEditableRow <CompDocEditableRow
label="Address" label="Address"

View file

@ -43,7 +43,7 @@ export function CompDocPreviewDocument({
isGenerated={isGenerated} isGenerated={isGenerated}
generatedAt={generatedAt} generatedAt={generatedAt}
/> />
<CompDocPreviewVendorSafety row={row} /> <CompDocPreviewVendorSafety site={site} />
<CompDocPreviewProcedureNotes pm={row.pm} notes={notes} /> <CompDocPreviewProcedureNotes pm={row.pm} notes={notes} />
</div> </div>
<div <div

View file

@ -72,10 +72,10 @@ export function CompDocPreviewServiceInfo({
margin: "2px 0", margin: "2px 0",
}} }}
> >
Site ID — {row.site} Site ID — {site.code}
</Text> </Text>
<Text as="p" style={{ fontSize: 13, color: "#161E38", margin: "2px 0" }}> <Text as="p" style={{ fontSize: 13, color: "#161E38", margin: "2px 0" }}>
Amazon.com Services LLC {row.site} Amazon.com Services LLC {site.code}
</Text> </Text>
<Text as="p" style={{ fontSize: 13, color: "#58595B", margin: "2px 0" }}> <Text as="p" style={{ fontSize: 13, color: "#58595B", margin: "2px 0" }}>
{site.street}, {site.street},

View file

@ -73,10 +73,10 @@ export function CompDocPreviewSummary({
margin: "2px 0", margin: "2px 0",
}} }}
> >
Site ID — {row.site} Site ID — {site.code}
</Text> </Text>
<Text variant="body" sx={{ fontSize: 13, color: "#161E38", margin: "2px 0" }}> <Text variant="body" sx={{ fontSize: 13, color: "#161E38", margin: "2px 0" }}>
Amazon.com Services LLC {row.site} Amazon.com Services LLC {site.code}
</Text> </Text>
<Text variant="body" sx={{ fontSize: 13, color: "#58595B", margin: "2px 0" }}> <Text variant="body" sx={{ fontSize: 13, color: "#58595B", margin: "2px 0" }}>
{site.street}, {site.street},
@ -88,8 +88,8 @@ export function CompDocPreviewSummary({
<Text variant="body" sx={{ fontSize: 13, color: "#161E38", margin: "14px 0 6px" }}> <Text variant="body" sx={{ fontSize: 13, color: "#161E38", margin: "14px 0 6px" }}>
<span style={{ fontWeight: 700 }}>Vendor / Technician:&nbsp;</span> <span style={{ fontWeight: 700 }}>Vendor / Technician:&nbsp;</span>
{row.tech || "—"} {site.tech || "—"}
{row.company ? ` · ${row.company}` : ""} {site.company ? ` · ${site.company}` : ""}
</Text> </Text>
</> </>
); );

View file

@ -1,18 +1,18 @@
import { Text } from "@/components/ui/text"; import { Text } from "@/components/ui/text";
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row"; import type { CompDocSiteInfo } from "@/domain/work-orders/types/completion-doc";
import { SAFETY_BULLETS } from "@/domain/work-orders/utils/completion-doc-procedures"; import { SAFETY_BULLETS } from "@/domain/work-orders/utils/completion-doc-procedures";
type CompDocPreviewVendorSafetyProps = { type CompDocPreviewVendorSafetyProps = {
row: WorkOrderTableRow; site: CompDocSiteInfo;
}; };
export function CompDocPreviewVendorSafety({ row }: CompDocPreviewVendorSafetyProps) { export function CompDocPreviewVendorSafety({ site }: CompDocPreviewVendorSafetyProps) {
return ( return (
<> <>
<Text as="p" style={{ fontSize: 13, color: "#161E38", margin: "14px 0 6px" }}> <Text as="p" style={{ fontSize: 13, color: "#161E38", margin: "14px 0 6px" }}>
<span style={{ fontWeight: 700 }}>Vendor / Technician:&nbsp;</span> <span style={{ fontWeight: 700 }}>Vendor / Technician:&nbsp;</span>
{row.tech || "—"} {site.tech || "—"}
{row.company ? ` · ${row.company}` : ""} {site.company ? ` · ${site.company}` : ""}
</Text> </Text>
<ul style={{ listStyle: "disc", paddingLeft: 18, margin: "8px 0 0" }}> <ul style={{ listStyle: "disc", paddingLeft: 18, margin: "8px 0 0" }}>

View file

@ -100,8 +100,9 @@ export function useCompDocDialog({
setEditDateCompleted, setEditDateCompleted,
}); });
const company = effectiveCompany(info);
const amazonRep = effectivePoc(info).contacts[0]?.name || ""; const amazonRep = effectivePoc(info).contacts[0]?.name || "";
const seaRep = effectiveCompany(info).contactName || ""; const seaRep = company.contactName || "";
const cfg = DOC_STATE_CFG[docState]; const cfg = DOC_STATE_CFG[docState];
const isNotRequired = docState === "not-required"; const isNotRequired = docState === "not-required";
const isGenerated = docState === "generated" || Boolean(signOffAttachment); const isGenerated = docState === "generated" || Boolean(signOffAttachment);
@ -114,6 +115,9 @@ export function useCompDocDialog({
dateCompleted: editDateCompleted, dateCompleted: editDateCompleted,
amazonRep, amazonRep,
seaRep, seaRep,
siteCode: site.code,
tech: company.contactName || "",
company: company.name || "",
}; };
const { persist, syncDateIfChanged, refreshAuthoritativeState, handleSaveDraft, handleGenerate } = const { persist, syncDateIfChanged, refreshAuthoritativeState, handleSaveDraft, handleGenerate } =

View file

@ -16,6 +16,7 @@ import { formatApptRange, parseApptTime } from "@/domain/work-orders/utils/wizar
import { import {
effectiveCompany, effectiveCompany,
effectivePoc, effectivePoc,
effectiveSite,
} from "@/domain/work-orders/utils/effective-completion-snapshot"; } from "@/domain/work-orders/utils/effective-completion-snapshot";
import { DocBadge } from "./slide-over-doc-badge"; import { DocBadge } from "./slide-over-doc-badge";
import { SlideOverInfoTabAssignedField } from "./slide-over-info-tab-assigned-field"; import { SlideOverInfoTabAssignedField } from "./slide-over-info-tab-assigned-field";
@ -71,10 +72,11 @@ function SlideOverCompletedSite({
sites: LocationOption[]; sites: LocationOption[];
}) { }) {
const primaryPoc = poc.contacts[0]; const primaryPoc = poc.contacts[0];
const frozenSite = effectiveSite(source);
return ( return (
<SiteCell <SiteCell
value={source.site} value={frozenSite?.code ?? source.site}
location={source.location} location={frozenSite?.label ?? source.location}
locationId={source.locationId} locationId={source.locationId}
pocName={primaryPoc?.name ?? ""} pocName={primaryPoc?.name ?? ""}
pocPhone={primaryPoc?.phone ?? ""} pocPhone={primaryPoc?.phone ?? ""}
@ -82,10 +84,11 @@ function SlideOverCompletedSite({
additionalContacts={poc.contacts.slice(1).map((contact) => ({ additionalContacts={poc.contacts.slice(1).map((contact) => ({
name: contact.name ?? "", name: contact.name ?? "",
phone: contact.phone ?? "", phone: contact.phone ?? "",
notes: contact.notes ?? "",
}))} }))}
sites={sites} sites={sites}
viewOnly viewOnly
frozenSite={source.frozenSite} frozenSite={frozenSite}
onSave={() => undefined} onSave={() => undefined}
/> />
); );

View file

@ -98,21 +98,31 @@ export function VendorDialogBody({
<div> <div>
<FieldLabel>Technician (optional)</FieldLabel> <FieldLabel>Technician (optional)</FieldLabel>
<WizardFieldSelect {frozenCompany != null ? (
value={selectedKey} <div className={DLG_INPUT_CLS} style={DLG_INPUT_STYLE}>
placeholder={selectedCompany ? "Select technician …" : "Pick a company first"} {frozenCompany.contactName?.trim() || tech || "—"}
disabled={!selectedCompany} </div>
icon={ ) : (
<Wrench size={14} className="shrink-0" style={{ color: "var(--color-text-muted)" }} /> <WizardFieldSelect
} value={selectedKey}
searchPlaceholder="Search technician…" placeholder={selectedCompany ? "Select technician …" : "Pick a company first"}
options={technicianOptions.map((option) => ({ disabled={!selectedCompany}
key: option.key, icon={
label: option.name, <Wrench
}))} size={14}
onPick={onPick} className="shrink-0"
/> style={{ color: "var(--color-text-muted)" }}
{companyVendorForAdd != null && ( />
}
searchPlaceholder="Search technician…"
options={technicianOptions.map((option) => ({
key: option.key,
label: option.name,
}))}
onPick={onPick}
/>
)}
{frozenCompany == null && companyVendorForAdd != null && (
<div className="mt-2"> <div className="mt-2">
<VendorDialogAddTechnician <VendorDialogAddTechnician
companyName={anchorCompanyName} companyName={anchorCompanyName}

View file

@ -77,8 +77,8 @@ export function VendorDialog({
technicianOptions={form.technicianOptions} technicianOptions={form.technicianOptions}
anchorCompanyName={form.anchorCompanyName} anchorCompanyName={form.anchorCompanyName}
companyVendorForAdd={viewOnly ? undefined : (form.companyVendor ?? undefined)} companyVendorForAdd={viewOnly ? undefined : (form.companyVendor ?? undefined)}
tech={form.selected?.name ?? form.t} tech={frozenCompany?.contactName ?? form.selected?.name ?? form.t}
phone={form.phone} phone={frozenCompany?.phone ?? form.phone}
notes={form.notes} notes={form.notes}
resolvedCompany={form.resolvedCompany} resolvedCompany={form.resolvedCompany}
selectedVendor={form.selectedVendor} selectedVendor={form.selectedVendor}

View file

@ -4,6 +4,7 @@ import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-ta
import { applyAssignedToTableSave } from "@/domain/work-orders/utils/work-order-feedback-toasts"; import { applyAssignedToTableSave } from "@/domain/work-orders/utils/work-order-feedback-toasts";
import { isWorkOrderCompletionSurfaceReadOnly } from "@/domain/work-orders/utils/work-order-lock"; import { isWorkOrderCompletionSurfaceReadOnly } from "@/domain/work-orders/utils/work-order-lock";
import { import {
effectiveAdditionalContacts,
effectivePoc, effectivePoc,
effectiveSite, effectiveSite,
} from "@/domain/work-orders/utils/effective-completion-snapshot"; } from "@/domain/work-orders/utils/effective-completion-snapshot";
@ -69,10 +70,7 @@ export function WoTableRowCells({
pocName={primaryPoc?.name ?? ""} pocName={primaryPoc?.name ?? ""}
pocPhone={primaryPoc?.phone ?? ""} pocPhone={primaryPoc?.phone ?? ""}
pocNotes={poc.notes ?? ""} pocNotes={poc.notes ?? ""}
additionalContacts={poc.contacts.slice(1).map((contact) => ({ additionalContacts={effectiveAdditionalContacts(row)}
name: contact.name ?? "",
phone: contact.phone ?? "",
}))}
sites={sites} sites={sites}
q={search} q={search}
viewOnly={viewOnly} viewOnly={viewOnly}

View file

@ -105,8 +105,9 @@ export function useCompDocDialog({
setEditAddress(value); setEditAddress(value);
}; };
const company = effectiveCompany(row);
const amazonRep = effectivePoc(row).contacts[0]?.name || ""; const amazonRep = effectivePoc(row).contacts[0]?.name || "";
const seaRep = effectiveCompany(row).contactName || ""; const seaRep = company.contactName || "";
const cfg = DOC_STATE_CFG[docState]; const cfg = DOC_STATE_CFG[docState];
const isNotRequired = docState === "not-required"; const isNotRequired = docState === "not-required";
const isGenerated = docState === "generated"; const isGenerated = docState === "generated";
@ -120,6 +121,9 @@ export function useCompDocDialog({
dateCompleted: editDateCompleted, dateCompleted: editDateCompleted,
amazonRep, amazonRep,
seaRep, seaRep,
siteCode: site.code,
tech: company.contactName || "",
company: company.name || "",
}; };
const previewSite = useMemo( const previewSite = useMemo(

View file

@ -314,6 +314,7 @@ function readFrozenPoc(item: Record<string, unknown>): WorkOrderFrozenPoc | unde
? rawContacts.map(asRecord).map((contact) => ({ ? rawContacts.map(asRecord).map((contact) => ({
name: readString(contact, "name", "Name"), name: readString(contact, "name", "Name"),
phone: readString(contact, "phone", "Phone"), phone: readString(contact, "phone", "Phone"),
notes: readString(contact, "notes", "Notes"),
})) }))
: []; : [];
return { return {

View file

@ -14,6 +14,9 @@ export interface DocFields {
dateCompleted: string; dateCompleted: string;
amazonRep: string; amazonRep: string;
seaRep: string; seaRep: string;
siteCode: string;
tech: string;
company: string;
} }
export type DocState = "draft" | "generated" | "not-required"; export type DocState = "draft" | "generated" | "not-required";
@ -31,12 +34,15 @@ export interface CompletionDocStateConfig {
} }
export interface CompDocSiteInfo { export interface CompDocSiteInfo {
code: string;
street: string; street: string;
city: string; city: string;
state: string; state: string;
zip: string; zip: string;
label: string; label: string;
fullAddress: string; fullAddress: string;
tech: string;
company: string;
} }
export type CompDocSaveStatus = Exclude<CompletionDocStatus, "">; export type CompDocSaveStatus = Exclude<CompletionDocStatus, "">;

View file

@ -38,7 +38,7 @@ export type WorkOrderFrozenCompany = {
}; };
export type WorkOrderFrozenPoc = { export type WorkOrderFrozenPoc = {
contacts: { name?: string; phone?: string }[]; contacts: { name?: string; phone?: string; notes?: string }[];
notes?: string; notes?: string;
}; };

View file

@ -75,11 +75,11 @@ export function buildDocHtml(
<div class="rule"></div> <div class="rule"></div>
<h1>${esc(serviceTitle(row).toUpperCase())}</h1> <h1>${esc(serviceTitle(row).toUpperCase())}</h1>
<p style="margin:2px 0;" class="wo">WO# ${esc(row.woNumber)}</p> <p style="margin:2px 0;" class="wo">WO# ${esc(row.woNumber)}</p>
<p style="margin:14px 0 0;">Site ID — ${esc(row.site)}</p> <p style="margin:14px 0 0;">Site ID — ${esc(fields.siteCode)}</p>
<p style="margin:2px 0;">Amazon.com Services LLC ${esc(row.site)}</p> <p style="margin:2px 0;">Amazon.com Services LLC ${esc(fields.siteCode)}</p>
<p style="margin:2px 0;" class="muted">${esc(fields.street)},</p> <p style="margin:2px 0;" class="muted">${esc(fields.street)},</p>
<p style="margin:2px 0;" class="muted">${esc(cityStateZip)}</p> <p style="margin:2px 0;" class="muted">${esc(cityStateZip)}</p>
<p style="margin:14px 0 4px;"><b>Vendor / Technician:</b> ${esc(row.tech || "—")}${row.company ? ` &middot; ${esc(row.company)}` : ""}</p> <p style="margin:14px 0 4px;"><b>Vendor / Technician:</b> ${esc(fields.tech || "—")}${fields.company ? ` &middot; ${esc(fields.company)}` : ""}</p>
<ul style="padding-left:20px;">${safety}</ul> <ul style="padding-left:20px;">${safety}</ul>
${completedBlock} ${completedBlock}
<h3 style="margin:16px 0 4px;">${esc(proc.heading)}:</h3> <h3 style="margin:16px 0 4px;">${esc(proc.heading)}:</h3>

View file

@ -1,20 +1,53 @@
import type { Location } from "@/domain/locations/types/location"; import type { Location } from "@/domain/locations/types/location";
import type { CompDocSiteInfo } from "@/domain/work-orders/types/completion-doc"; import type { CompDocSiteInfo } from "@/domain/work-orders/types/completion-doc";
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row"; import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
import { effectiveSite } from "@/domain/work-orders/utils/effective-completion-snapshot"; import {
effectiveCompany,
effectiveSite,
} from "@/domain/work-orders/utils/effective-completion-snapshot";
type CompDocAddress = Pick<
CompDocSiteInfo,
"street" | "city" | "state" | "zip" | "label" | "fullAddress"
>;
type CompDocIdentityRow = Pick<WorkOrderTableRow, "site" | "location" | "status" | "frozenSite"> &
Partial<Pick<WorkOrderTableRow, "company" | "tech" | "techPhone" | "frozenCompany">>;
function buildLabel(city?: string, state?: string): string { function buildLabel(city?: string, state?: string): string {
return [city, state].filter(Boolean).join(", "); return [city, state].filter(Boolean).join(", ");
} }
function toCompDocSite(street: string, city: string, state: string, zip: string): CompDocSiteInfo { function toCompDocAddress(
street: string,
city: string,
state: string,
zip: string,
): CompDocAddress {
const label = buildLabel(city, state); const label = buildLabel(city, state);
const fullAddress = [street, label, zip].filter(Boolean).join(", ") || "—"; const fullAddress = [street, label, zip].filter(Boolean).join(", ") || "—";
return { street, city, state, zip, label, fullAddress }; return { street, city, state, zip, label, fullAddress };
} }
function resolveLiveLocationSite(location: Location): CompDocSiteInfo { function withCompDocIdentity(address: CompDocAddress, row: CompDocIdentityRow): CompDocSiteInfo {
return toCompDocSite( const frozen = effectiveSite(row);
const company = effectiveCompany({
status: row.status,
company: row.company ?? "",
tech: row.tech ?? "",
techPhone: row.techPhone ?? "",
frozenCompany: row.frozenCompany,
});
return {
...address,
code: frozen?.code ?? row.site,
tech: company.contactName ?? "",
company: company.name ?? "",
};
}
function resolveLiveLocationSite(location: Location): CompDocAddress {
return toCompDocAddress(
location.address ?? "", location.address ?? "",
location.city ?? "", location.city ?? "",
location.state ?? "", location.state ?? "",
@ -22,30 +55,33 @@ function resolveLiveLocationSite(location: Location): CompDocSiteInfo {
); );
} }
function resolveRowLocationSite(row: Pick<WorkOrderTableRow, "location">): CompDocSiteInfo { function resolveRowLocationSite(row: Pick<WorkOrderTableRow, "location">): CompDocAddress {
const locationParts = row.location.split(",").map((part) => part.trim()); const locationParts = row.location.split(",").map((part) => part.trim());
const city = locationParts[0] ?? ""; const city = locationParts[0] ?? "";
const state = locationParts[1] ?? ""; const state = locationParts[1] ?? "";
const label = buildLabel(city, state); const label = buildLabel(city, state);
const street = row.location && !label ? row.location : ""; const street = row.location && !label ? row.location : "";
return toCompDocSite(street, city, state, ""); return toCompDocAddress(street, city, state, "");
} }
export function resolveCompDocSite( export function resolveCompDocSite(
row: Pick<WorkOrderTableRow, "site" | "location" | "status" | "frozenSite">, row: CompDocIdentityRow,
location?: Location | null, location?: Location | null,
): CompDocSiteInfo { ): CompDocSiteInfo {
const frozen = effectiveSite(row); const frozen = effectiveSite(row);
if (frozen != null) { if (frozen != null) {
return toCompDocSite( return withCompDocIdentity(
frozen.address ?? "", toCompDocAddress(
frozen.city ?? "", frozen.address ?? "",
frozen.state ?? "", frozen.city ?? "",
frozen.zip ?? "", frozen.state ?? "",
frozen.zip ?? "",
),
row,
); );
} }
if (location?.address || location?.city) { if (location?.address || location?.city) {
return resolveLiveLocationSite(location); return withCompDocIdentity(resolveLiveLocationSite(location), row);
} }
return resolveRowLocationSite(row); return withCompDocIdentity(resolveRowLocationSite(row), row);
} }

View file

@ -1,3 +1,4 @@
import type { WorkOrderAdditionalContact } from "@/domain/work-orders/types/work-order-additional-contact";
import type { import type {
WorkOrderFrozenCompany, WorkOrderFrozenCompany,
WorkOrderFrozenPoc, WorkOrderFrozenPoc,
@ -48,8 +49,20 @@ export function effectivePoc(row: PocSnapshotRow): WorkOrderFrozenPoc {
...(row.additionalContacts ?? []).map((contact) => ({ ...(row.additionalContacts ?? []).map((contact) => ({
name: contact.name, name: contact.name,
phone: contact.phone, phone: contact.phone,
notes: contact.notes,
})), })),
], ],
notes: row.pocNotes, notes: row.pocNotes,
}; };
} }
export function effectiveAdditionalContacts(row: PocSnapshotRow): WorkOrderAdditionalContact[] {
if (row.status === "Completed" && row.frozenPoc != null) {
return row.frozenPoc.contacts.slice(1).map((contact) => ({
name: contact.name ?? "",
phone: contact.phone ?? "",
notes: contact.notes ?? "",
}));
}
return row.additionalContacts ?? [];
}

View file

@ -1,5 +1,6 @@
import { render, screen } from "@testing-library/react"; import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { VendorDialogBody } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-body";
import { VendorDialogCompanyCard } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-company-card"; import { VendorDialogCompanyCard } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-company-card";
import type { VendorDropdownItem } from "@/domain/work-orders/types/work-order"; import type { VendorDropdownItem } from "@/domain/work-orders/types/work-order";
@ -48,4 +49,42 @@ describe("VendorDialogCompanyCard completion snapshot", () => {
expect(screen.getByText("200 Vendor Ave, Chicago, IL, 60602")).toBeInTheDocument(); expect(screen.getByText("200 Vendor Ave, Chicago, IL, 60602")).toBeInTheDocument();
expect(screen.queryByText("900 Live St")).not.toBeInTheDocument(); expect(screen.queryByText("900 Live St")).not.toBeInTheDocument();
}); });
it("shows the frozen technician instead of a renamed live roster contact", () => {
render(
<VendorDialogBody
selectedCompany="Frozen Vendor"
companyOptions={[{ key: "Frozen Vendor", label: "Frozen Vendor" }]}
selectedKey={String(LIVE_VENDOR.id)}
technicianOptions={[
{
key: String(LIVE_VENDOR.id),
label: LIVE_VENDOR.contactName,
name: LIVE_VENDOR.contactName,
company: LIVE_VENDOR.companyName,
phone: "",
vendor: LIVE_VENDOR,
},
]}
anchorCompanyName="Frozen Vendor"
companyVendorForAdd={LIVE_VENDOR}
tech="Frozen Tech"
phone="111"
notes=""
resolvedCompany="Frozen Vendor"
selectedVendor={LIVE_VENDOR}
frozenCompany={{ name: "Frozen Vendor", contactName: "Frozen Tech", phone: "111" }}
saveError={null}
onCompanyPick={() => undefined}
onPick={() => undefined}
onPhoneChange={() => undefined}
onNotesChange={() => undefined}
onTechnicianCreated={() => undefined}
/>,
);
expect(screen.getAllByText("Frozen Tech").length).toBeGreaterThan(0);
expect(screen.queryByText("Live Contact")).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: /\+ add technician/i })).not.toBeInTheDocument();
});
}); });

View file

@ -8,12 +8,16 @@ describe("resolveCompDocSite", () => {
site: "BK5", site: "BK5",
location: "Live City, WI", location: "Live City, WI",
status: "Completed", status: "Completed",
company: "Live Co",
tech: "Live Tech",
frozenSite: { frozenSite: {
code: "FROZEN",
address: "100 Frozen Ave", address: "100 Frozen Ave",
city: "Chicago", city: "Chicago",
state: "IL", state: "IL",
zip: "60601", zip: "60601",
}, },
frozenCompany: { name: "Frozen Co", contactName: "Frozen Tech" },
}, },
{ {
address: "900 Live St", address: "900 Live St",
@ -24,12 +28,15 @@ describe("resolveCompDocSite", () => {
); );
expect(result).toEqual({ expect(result).toEqual({
code: "FROZEN",
street: "100 Frozen Ave", street: "100 Frozen Ave",
city: "Chicago", city: "Chicago",
state: "IL", state: "IL",
zip: "60601", zip: "60601",
label: "Chicago, IL", label: "Chicago, IL",
fullAddress: "100 Frozen Ave, Chicago, IL, 60601", fullAddress: "100 Frozen Ave, Chicago, IL, 60601",
tech: "Frozen Tech",
company: "Frozen Co",
}); });
}); });

View file

@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { import {
effectiveAdditionalContacts,
effectiveCompany, effectiveCompany,
effectivePoc, effectivePoc,
effectiveSite, effectiveSite,
@ -61,15 +62,42 @@ describe("effective completion snapshot", () => {
pocName: "Live POC", pocName: "Live POC",
pocPhone: "222", pocPhone: "222",
pocNotes: "live", pocNotes: "live",
additionalContacts: [{ name: "Backup", phone: "333" }], additionalContacts: [{ name: "Backup", phone: "333", notes: "gate hours" }],
}), }),
).toEqual({ ).toEqual({
contacts: [ contacts: [
{ name: "Live POC", phone: "222" }, { name: "Live POC", phone: "222" },
{ name: "Backup", phone: "333" }, { name: "Backup", phone: "333", notes: "gate hours" },
], ],
notes: "live", notes: "live",
}); });
expect(
effectiveAdditionalContacts({
status: "Scheduled",
pocName: "Live POC",
pocPhone: "222",
pocNotes: "live",
additionalContacts: [{ name: "Backup", phone: "333", notes: "gate hours" }],
}),
).toEqual([{ name: "Backup", phone: "333", notes: "gate hours" }]);
});
it("keeps extra-contact notes on the open work-order path", () => {
expect(
effectiveAdditionalContacts({
status: "Scheduled",
pocName: "Primary",
pocPhone: "111",
pocNotes: "",
additionalContacts: [{ name: "Backup", phone: "333", notes: "gate hours" }],
frozenPoc: {
contacts: [
{ name: "Frozen", phone: "000" },
{ name: "Frozen Extra", phone: "999", notes: "ignored while open" },
],
},
}),
).toEqual([{ name: "Backup", phone: "333", notes: "gate hours" }]);
}); });
it("treats missing additional contacts as an empty live contact list", () => { it("treats missing additional contacts as an empty live contact list", () => {