mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
implemeting document search on deal id instead of uprn
This commit is contained in:
parent
a0b12673f3
commit
c7a5780877
10 changed files with 138 additions and 103 deletions
|
|
@ -5,22 +5,25 @@ import { uploadedFiles } from "@/app/db/schema/uploaded_files";
|
|||
|
||||
export async function GET(req: Request) {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const dealIdParam = searchParams.get("dealId");
|
||||
const uprnParam = searchParams.get("uprn");
|
||||
const landlordPropertyIdParam = searchParams.get("landlordPropertyId");
|
||||
|
||||
if (!uprnParam && !landlordPropertyIdParam) {
|
||||
if (!dealIdParam && !uprnParam && !landlordPropertyIdParam) {
|
||||
return NextResponse.json(
|
||||
{ error: "uprn or landlordPropertyId is required" },
|
||||
{ error: "dealId, uprn, or landlordPropertyId is required" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// Prefer UPRN — it's more selective and avoids an OR full-table scan.
|
||||
// Only fall back to landlordPropertyId when no UPRN is available.
|
||||
const condition = uprnParam
|
||||
? eq(uploadedFiles.uprn, BigInt(uprnParam))
|
||||
: eq(uploadedFiles.landlordPropertyId, landlordPropertyIdParam!);
|
||||
// Prefer dealId — reliable even when UPRN is missing from the deal.
|
||||
// Fall back to UPRN, then landlordPropertyId.
|
||||
const condition = dealIdParam
|
||||
? eq(uploadedFiles.hubsotDealId, dealIdParam)
|
||||
: uprnParam
|
||||
? eq(uploadedFiles.uprn, BigInt(uprnParam))
|
||||
: eq(uploadedFiles.landlordPropertyId, landlordPropertyIdParam!);
|
||||
|
||||
const rows = await db
|
||||
.select({
|
||||
|
|
|
|||
|
|
@ -663,8 +663,7 @@ export default function ContractorUploadModal({ deal, portfolioId, onClose, docS
|
|||
|
||||
{/* ── Measure Select ── */}
|
||||
{phase === "measure-select" && (() => {
|
||||
const uprn = deal.uprn ?? null;
|
||||
const docStatus = uprn ? docStatusMap?.[uprn] : undefined;
|
||||
const docStatus = docStatusMap?.[deal.dealId];
|
||||
const measureProgressMap = new Map(
|
||||
(docStatus?.measureProgress ?? []).map((m) => [m.measureName, m]),
|
||||
);
|
||||
|
|
@ -779,8 +778,7 @@ export default function ContractorUploadModal({ deal, portfolioId, onClose, docS
|
|||
|
||||
{/* ── Phase 2: Classify ── */}
|
||||
{phase === "classify" && (() => {
|
||||
const uprn = deal.uprn ?? null;
|
||||
const docStatus = uprn ? docStatusMap?.[uprn] : undefined;
|
||||
const docStatus = docStatusMap?.[deal.dealId];
|
||||
const measureProgressMap = new Map(
|
||||
(docStatus?.measureProgress ?? []).map((m) => [m.measureName, m]),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ type InstallStatusFilter = "all" | "none" | "hasDocs" | "partial" | "complete";
|
|||
|
||||
interface DocumentTableProps {
|
||||
data: ClassifiedDeal[];
|
||||
onOpenDrawer: (uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void;
|
||||
onOpenDrawer: (dealId: string, uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void;
|
||||
docStatusMap: DocStatusMap;
|
||||
portfolioId: string;
|
||||
userCapability: PortfolioCapabilityType;
|
||||
|
|
@ -67,7 +67,7 @@ export default function DocumentTable({ data, onOpenDrawer, docStatusMap, portfo
|
|||
|
||||
const filteredData = useMemo(() => {
|
||||
return data.filter((d) => {
|
||||
const status = d.uprn ? docStatusMap[d.uprn] : undefined;
|
||||
const status = docStatusMap[d.dealId];
|
||||
|
||||
if (retroAssessmentFilter !== "all") {
|
||||
if (retroAssessmentFilter === "none" && !(!status || !status.hasSurveyDocs)) return false;
|
||||
|
|
@ -115,7 +115,7 @@ export default function DocumentTable({ data, onOpenDrawer, docStatusMap, portfo
|
|||
const header = "Address,Landlord ID,Retrofit Assessment Status,Install Docs Status";
|
||||
const body = rows
|
||||
.map((row) => {
|
||||
const status = row.original.uprn ? docStatusMap[row.original.uprn] : undefined;
|
||||
const status = docStatusMap[row.original.dealId];
|
||||
const retroStatus = status?.isSurveyComplete
|
||||
? "Complete"
|
||||
: status?.hasSurveyDocs
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ function InstallDocsBadge({ status }: { status: DocStatus | undefined }) {
|
|||
}
|
||||
|
||||
export function createDocumentTableColumns(
|
||||
onOpenDrawer: (uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void,
|
||||
onOpenDrawer: (dealId: string, uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void,
|
||||
docStatusMap: DocStatusMap = {},
|
||||
onUpload?: (deal: ClassifiedDeal) => void,
|
||||
): ColumnDef<ClassifiedDeal>[] {
|
||||
|
|
@ -138,14 +138,14 @@ export function createDocumentTableColumns(
|
|||
{
|
||||
id: "retroAssessmentStatus",
|
||||
accessorFn: (row) => {
|
||||
const status = row.uprn ? docStatusMap[row.uprn] : undefined;
|
||||
const status = docStatusMap[row.dealId];
|
||||
if (status?.isSurveyComplete) return 2;
|
||||
if (status?.hasSurveyDocs) return 1;
|
||||
return 0;
|
||||
},
|
||||
header: ({ column }) => <SortableHeader label="Retrofit Assessment Docs" column={column as any} />,
|
||||
cell: ({ row }) => {
|
||||
const status = row.original.uprn ? docStatusMap[row.original.uprn] : undefined;
|
||||
const status = docStatusMap[row.original.dealId];
|
||||
return <RetroAssessmentBadge status={status} />;
|
||||
},
|
||||
enableHiding: false,
|
||||
|
|
@ -155,7 +155,7 @@ export function createDocumentTableColumns(
|
|||
{
|
||||
id: "installDocs",
|
||||
accessorFn: (row) => {
|
||||
const status = row.uprn ? docStatusMap[row.uprn] : undefined;
|
||||
const status = docStatusMap[row.dealId];
|
||||
const s = status?.installStatus ?? "none";
|
||||
if (s === "all") return 3;
|
||||
if (s === "partial") return 2;
|
||||
|
|
@ -164,7 +164,7 @@ export function createDocumentTableColumns(
|
|||
},
|
||||
header: ({ column }) => <SortableHeader label="Install Docs" column={column as any} />,
|
||||
cell: ({ row }) => {
|
||||
const status = row.original.uprn ? docStatusMap[row.original.uprn] : undefined;
|
||||
const status = docStatusMap[row.original.dealId];
|
||||
return <InstallDocsBadge status={status} />;
|
||||
},
|
||||
enableHiding: false,
|
||||
|
|
@ -177,8 +177,7 @@ export function createDocumentTableColumns(
|
|||
<span className="text-xs font-semibold uppercase tracking-wide text-gray-500">Docs</span>
|
||||
),
|
||||
cell: ({ row }) => {
|
||||
const uprn = row.original.uprn ?? "";
|
||||
const status = uprn ? docStatusMap[uprn] : undefined;
|
||||
const status = docStatusMap[row.original.dealId];
|
||||
|
||||
let icon: React.ReactNode;
|
||||
let className: string;
|
||||
|
|
@ -201,6 +200,7 @@ export function createDocumentTableColumns(
|
|||
<button
|
||||
onClick={() =>
|
||||
onOpenDrawer(
|
||||
row.original.dealId,
|
||||
row.original.uprn,
|
||||
row.original.landlordPropertyId,
|
||||
row.original.dealname,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ export default function LiveTracker({
|
|||
// ── Document drawer (used by PropertyTable) ──────────────────────────
|
||||
const [drawerState, setDrawerState] = useState<DocumentDrawerState>({
|
||||
open: false,
|
||||
dealId: null,
|
||||
uprn: null,
|
||||
landlordPropertyId: null,
|
||||
dealname: null,
|
||||
|
|
@ -100,11 +101,12 @@ export default function LiveTracker({
|
|||
};
|
||||
|
||||
const handleOpenDrawer = (
|
||||
dealId: string,
|
||||
uprn: string | null,
|
||||
landlordPropertyId: string | null,
|
||||
dealname: string | null,
|
||||
) => {
|
||||
setDrawerState({ open: true, uprn, landlordPropertyId, dealname });
|
||||
setDrawerState({ open: true, dealId, uprn, landlordPropertyId, dealname });
|
||||
};
|
||||
|
||||
if (!totalDeals) {
|
||||
|
|
@ -404,15 +406,17 @@ export default function LiveTracker({
|
|||
{/* ── Document drawer ────────────────────────────────────────────── */}
|
||||
<PropertyDrawer
|
||||
open={drawerState.open}
|
||||
dealId={drawerState.dealId}
|
||||
uprn={drawerState.uprn}
|
||||
landlordPropertyId={drawerState.landlordPropertyId}
|
||||
dealname={drawerState.dealname}
|
||||
docStatus={
|
||||
drawerState.uprn ? docStatusMap[drawerState.uprn] : undefined
|
||||
drawerState.dealId ? docStatusMap[drawerState.dealId] : undefined
|
||||
}
|
||||
onClose={() =>
|
||||
setDrawerState({
|
||||
open: false,
|
||||
dealId: null,
|
||||
uprn: null,
|
||||
landlordPropertyId: null,
|
||||
dealname: null,
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ function DocumentRow({ doc, showMeasure }: { doc: PropertyDocument; showMeasure?
|
|||
// -----------------------------------------------------------------------
|
||||
interface PropertyDrawerProps {
|
||||
open: boolean;
|
||||
dealId?: string | null;
|
||||
uprn: string | null;
|
||||
landlordPropertyId: string | null;
|
||||
dealname: string | null;
|
||||
|
|
@ -169,22 +170,24 @@ interface PropertyDrawerProps {
|
|||
|
||||
export default function PropertyDrawer({
|
||||
open,
|
||||
dealId,
|
||||
uprn,
|
||||
landlordPropertyId,
|
||||
dealname,
|
||||
docStatus,
|
||||
onClose,
|
||||
}: PropertyDrawerProps) {
|
||||
const canQuery = !!(uprn || landlordPropertyId);
|
||||
const canQuery = !!(dealId || uprn || landlordPropertyId);
|
||||
const {
|
||||
data: fetchedDocuments = [],
|
||||
isFetching,
|
||||
isError,
|
||||
} = useQuery({
|
||||
queryKey: ["property-documents", uprn, landlordPropertyId],
|
||||
queryKey: ["property-documents", dealId, uprn, landlordPropertyId],
|
||||
queryFn: async () => {
|
||||
const params = new URLSearchParams();
|
||||
if (uprn) params.set("uprn", uprn);
|
||||
if (dealId) params.set("dealId", dealId);
|
||||
else if (uprn) params.set("uprn", uprn);
|
||||
else if (landlordPropertyId)
|
||||
params.set("landlordPropertyId", landlordPropertyId);
|
||||
const res = await fetch(
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ type RemovalFilter = "all" | "pending_removal" | "removed" | "pending_re_additio
|
|||
|
||||
interface PropertyTableProps {
|
||||
data: ClassifiedDeal[];
|
||||
onOpenDrawer: (uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void;
|
||||
onOpenDrawer: (dealId: string, uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void;
|
||||
onOpenDetail?: (deal: ClassifiedDeal) => void;
|
||||
showDocuments?: boolean;
|
||||
docStatusMap?: DocStatusMap;
|
||||
|
|
@ -128,7 +128,7 @@ export default function PropertyTable({ data, onOpenDrawer, onOpenDetail, showDo
|
|||
}
|
||||
if (docFilter !== "all") {
|
||||
result = result.filter((d) => {
|
||||
const status = d.uprn ? docStatusMap[d.uprn] : undefined;
|
||||
const status = docStatusMap[d.dealId];
|
||||
if (docFilter === "none") return !status || !status.hasSurveyDocs;
|
||||
if (docFilter === "has_docs") return !!status?.hasSurveyDocs;
|
||||
if (docFilter === "incomplete") return !!status?.hasSurveyDocs && !status.isSurveyComplete;
|
||||
|
|
|
|||
|
|
@ -42,10 +42,10 @@ function SortableHeader({
|
|||
// -----------------------------------------------------------------------
|
||||
// Column factory — takes onOpenDrawer so the Documents button can trigger it
|
||||
// showDocuments controls whether the Docs action column is included
|
||||
// docStatusMap provides per-UPRN document status for status indicators
|
||||
// docStatusMap provides per-deal document status for status indicators
|
||||
// -----------------------------------------------------------------------
|
||||
export function createPropertyTableColumns(
|
||||
onOpenDrawer: (uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void,
|
||||
onOpenDrawer: (dealId: string, uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void,
|
||||
showDocuments: boolean = false,
|
||||
docStatusMap: DocStatusMap = {},
|
||||
onOpenDetail?: (deal: ClassifiedDeal) => void,
|
||||
|
|
@ -291,8 +291,7 @@ export function createPropertyTableColumns(
|
|||
<span className="text-xs font-semibold uppercase tracking-wide text-gray-500">Docs</span>
|
||||
),
|
||||
cell: ({ row }) => {
|
||||
const uprn = row.original.uprn ?? "";
|
||||
const status = uprn ? docStatusMap[uprn] : undefined;
|
||||
const status = docStatusMap[row.original.dealId];
|
||||
const isComplete = status?.isSurveyComplete;
|
||||
const hasDocs = status?.hasSurveyDocs;
|
||||
|
||||
|
|
@ -315,7 +314,7 @@ export function createPropertyTableColumns(
|
|||
|
||||
return (
|
||||
<button
|
||||
onClick={() => onOpenDrawer(row.original.uprn, row.original.landlordPropertyId, row.original.dealname)}
|
||||
onClick={() => onOpenDrawer(row.original.dealId, row.original.uprn, row.original.landlordPropertyId, row.original.dealname)}
|
||||
className={className}
|
||||
>
|
||||
{icon}
|
||||
|
|
|
|||
|
|
@ -225,95 +225,122 @@ export default async function LiveReportingPage(props: {
|
|||
if (state !== "none") removalStatusByDeal[row.hubspotDealId] = state;
|
||||
}
|
||||
|
||||
// Fetch survey document status for all properties
|
||||
const uprnList = deals
|
||||
// Fetch document status for all deals — two-phase strategy:
|
||||
// Phase 1: query by dealId (reliable even when UPRN is missing from hubspot_deal_data)
|
||||
// Phase 2: UPRN fallback only for deals that returned no results in phase 1
|
||||
const docsByDealId = new Map<string, Array<{ fileType: string; measureName: string | null }>>();
|
||||
|
||||
if (dealIds.length > 0) {
|
||||
const phase1Rows = await db
|
||||
.select({
|
||||
hubsotDealId: uploadedFiles.hubsotDealId,
|
||||
fileType: uploadedFiles.fileType,
|
||||
measureName: uploadedFiles.measureName,
|
||||
})
|
||||
.from(uploadedFiles)
|
||||
.where(inArray(uploadedFiles.hubsotDealId, dealIds));
|
||||
|
||||
for (const row of phase1Rows) {
|
||||
if (!row.hubsotDealId || row.fileType === null) continue;
|
||||
if (!docsByDealId.has(row.hubsotDealId)) docsByDealId.set(row.hubsotDealId, []);
|
||||
docsByDealId.get(row.hubsotDealId)!.push({ fileType: row.fileType, measureName: row.measureName });
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 2: for deals with no docs from phase 1 that have a UPRN, try UPRN lookup
|
||||
const dealsWithoutDocs = deals.filter((d) => !docsByDealId.has(d.dealId));
|
||||
const fallbackUprns = dealsWithoutDocs
|
||||
.map((d) => d.uprn)
|
||||
.filter((u): u is string => !!u)
|
||||
.map((u) => {
|
||||
try { return BigInt(u); } catch { return null; }
|
||||
})
|
||||
.map((u) => { try { return BigInt(u); } catch { return null; } })
|
||||
.filter((u): u is bigint => u !== null);
|
||||
|
||||
let docStatusMap: DocStatusMap = {};
|
||||
|
||||
if (uprnList.length > 0) {
|
||||
const docRows = await db
|
||||
if (fallbackUprns.length > 0) {
|
||||
const phase2Rows = await db
|
||||
.select({
|
||||
uprn: uploadedFiles.uprn,
|
||||
fileType: uploadedFiles.fileType,
|
||||
measureName: uploadedFiles.measureName,
|
||||
})
|
||||
.from(uploadedFiles)
|
||||
.where(inArray(uploadedFiles.uprn, uprnList));
|
||||
.where(inArray(uploadedFiles.uprn, fallbackUprns));
|
||||
|
||||
// Group docs by UPRN
|
||||
const docsByUprn = new Map<string, Array<{ fileType: string; measureName: string | null }>>();
|
||||
for (const row of docRows) {
|
||||
// Map phase 2 UPRN results back to dealId
|
||||
const uprnToDealId = new Map<string, string>(
|
||||
dealsWithoutDocs
|
||||
.filter((d) => d.uprn)
|
||||
.map((d) => {
|
||||
try { return [String(BigInt(d.uprn!)), d.dealId] as [string, string]; } catch { return null; }
|
||||
})
|
||||
.filter((e): e is [string, string] => e !== null),
|
||||
);
|
||||
|
||||
for (const row of phase2Rows) {
|
||||
if (row.uprn === null || row.fileType === null) continue;
|
||||
const key = String(row.uprn);
|
||||
if (!docsByUprn.has(key)) docsByUprn.set(key, []);
|
||||
docsByUprn.get(key)!.push({ fileType: row.fileType, measureName: row.measureName });
|
||||
const dealId = uprnToDealId.get(String(row.uprn));
|
||||
if (!dealId) continue;
|
||||
if (!docsByDealId.has(dealId)) docsByDealId.set(dealId, []);
|
||||
docsByDealId.get(dealId)!.push({ fileType: row.fileType, measureName: row.measureName });
|
||||
}
|
||||
}
|
||||
|
||||
// Build measures lookup from deals (uprn → approved measures, falling back to proposed)
|
||||
const measuresByUprn = new Map<string, string[]>();
|
||||
for (const deal of deals) {
|
||||
if (deal.uprn) {
|
||||
const key = String(deal.uprn);
|
||||
const approved = approvalsByDeal[deal.dealId] ?? [];
|
||||
const measures = approved.length > 0
|
||||
? approved
|
||||
: (deal.proposedMeasures ?? "").split(",").map((m: string) => m.trim()).filter(Boolean);
|
||||
measuresByUprn.set(key, measures);
|
||||
}
|
||||
}
|
||||
// Build measures lookup by dealId (approved measures, falling back to proposed)
|
||||
const measuresByDealId = new Map<string, string[]>();
|
||||
for (const deal of deals) {
|
||||
const approved = approvalsByDeal[deal.dealId] ?? [];
|
||||
const measures = approved.length > 0
|
||||
? approved
|
||||
: (deal.proposedMeasures ?? "").split(",").map((m: string) => m.trim()).filter(Boolean);
|
||||
measuresByDealId.set(deal.dealId, measures);
|
||||
}
|
||||
|
||||
for (const [uprn, docs] of docsByUprn) {
|
||||
const surveyDocs = docs.filter((d) => SURVEY_ALL_DOC_TYPES.has(d.fileType));
|
||||
const installDocs = docs.filter((d) => !SURVEY_ALL_DOC_TYPES.has(d.fileType));
|
||||
const surveyTypeSet = new Set(surveyDocs.map((d) => d.fileType));
|
||||
// Build docStatusMap keyed by dealId
|
||||
const docStatusMap: DocStatusMap = {};
|
||||
|
||||
const measures = measuresByUprn.get(uprn) ?? [];
|
||||
for (const [dealId, docs] of docsByDealId) {
|
||||
const surveyDocs = docs.filter((d) => SURVEY_ALL_DOC_TYPES.has(d.fileType));
|
||||
const installDocs = docs.filter((d) => !SURVEY_ALL_DOC_TYPES.has(d.fileType));
|
||||
const surveyTypeSet = new Set(surveyDocs.map((d) => d.fileType));
|
||||
|
||||
// Compute per-measure document progress against the requirements matrix
|
||||
const measureProgress: MeasureDocProgress[] = measures.map((measureName) => {
|
||||
const required = getRequiredDocs(measureName);
|
||||
const docsForMeasure = installDocs.filter((d) => d.measureName === measureName);
|
||||
const uploadedTypeSet = new Set(docsForMeasure.map((d) => d.fileType));
|
||||
const uploaded = required.filter((r) => uploadedTypeSet.has(r));
|
||||
return {
|
||||
measureName,
|
||||
required,
|
||||
uploaded,
|
||||
isComplete: uploaded.length === required.length,
|
||||
uploadedCount: uploaded.length,
|
||||
requiredCount: required.length,
|
||||
};
|
||||
});
|
||||
const measures = measuresByDealId.get(dealId) ?? [];
|
||||
|
||||
let installStatus: DocStatus["installStatus"] = "none";
|
||||
if (installDocs.length > 0) {
|
||||
if (measures.length === 0) {
|
||||
installStatus = "hasDocs";
|
||||
} else {
|
||||
installStatus = measureProgress.every((m) => m.isComplete)
|
||||
? "all"
|
||||
: measureProgress.some((m) => m.uploadedCount > 0)
|
||||
? "partial"
|
||||
: "none";
|
||||
}
|
||||
}
|
||||
|
||||
const status: DocStatus = {
|
||||
presentSurveyTypes: Array.from(surveyTypeSet),
|
||||
hasSurveyDocs: surveyDocs.length > 0,
|
||||
isSurveyComplete: EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES.every((t) => surveyTypeSet.has(t)),
|
||||
hasInstallDocs: installDocs.length > 0,
|
||||
installStatus,
|
||||
measureProgress,
|
||||
// Compute per-measure document progress against the requirements matrix
|
||||
const measureProgress: MeasureDocProgress[] = measures.map((measureName) => {
|
||||
const required = getRequiredDocs(measureName);
|
||||
const docsForMeasure = installDocs.filter((d) => d.measureName === measureName);
|
||||
const uploadedTypeSet = new Set(docsForMeasure.map((d) => d.fileType));
|
||||
const uploaded = required.filter((r) => uploadedTypeSet.has(r));
|
||||
return {
|
||||
measureName,
|
||||
required,
|
||||
uploaded,
|
||||
isComplete: uploaded.length === required.length,
|
||||
uploadedCount: uploaded.length,
|
||||
requiredCount: required.length,
|
||||
};
|
||||
docStatusMap[uprn] = status;
|
||||
});
|
||||
|
||||
let installStatus: DocStatus["installStatus"] = "none";
|
||||
if (installDocs.length > 0) {
|
||||
if (measures.length === 0) {
|
||||
installStatus = "hasDocs";
|
||||
} else {
|
||||
installStatus = measureProgress.every((m) => m.isComplete)
|
||||
? "all"
|
||||
: measureProgress.some((m) => m.uploadedCount > 0)
|
||||
? "partial"
|
||||
: "none";
|
||||
}
|
||||
}
|
||||
|
||||
docStatusMap[dealId] = {
|
||||
presentSurveyTypes: Array.from(surveyTypeSet),
|
||||
hasSurveyDocs: surveyDocs.length > 0,
|
||||
isSurveyComplete: EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES.every((t) => surveyTypeSet.has(t)),
|
||||
hasInstallDocs: installDocs.length > 0,
|
||||
installStatus,
|
||||
measureProgress,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -275,10 +275,11 @@ export type DocStatus = {
|
|||
measureProgress: MeasureDocProgress[]; // one entry per proposed measure
|
||||
};
|
||||
|
||||
export type DocStatusMap = Record<string, DocStatus>; // keyed by UPRN string
|
||||
export type DocStatusMap = Record<string, DocStatus>; // keyed by dealId string
|
||||
|
||||
export type DocumentDrawerState = {
|
||||
open: boolean;
|
||||
dealId: string | null;
|
||||
uprn: string | null;
|
||||
landlordPropertyId: string | null;
|
||||
dealname: string | null;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue