From e91d7417858a1b7fa31a47daf1d80f276c763b4f Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 16 Aug 2024 15:53:07 +1000 Subject: [PATCH] Build output table (#7898) - Display "allocated items" quantity --- .../src/tables/build/BuildOutputTable.tsx | 78 +++++++++++++++++-- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/tables/build/BuildOutputTable.tsx b/src/frontend/src/tables/build/BuildOutputTable.tsx index 873f550a69..3274109a4c 100644 --- a/src/frontend/src/tables/build/BuildOutputTable.tsx +++ b/src/frontend/src/tables/build/BuildOutputTable.tsx @@ -2,7 +2,7 @@ import { t } from '@lingui/macro'; import { Group, Text } from '@mantine/core'; import { IconCircleCheck, IconCircleX } from '@tabler/icons-react'; import { useQuery } from '@tanstack/react-query'; -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { api } from '../../App'; import { ActionButton } from '../../components/buttons/ActionButton'; @@ -76,10 +76,40 @@ export default function BuildOutputTable({ build }: { build: any }) { return (testTemplates?.length ?? 0) > 0; }, [partId, testTemplates]); + // Fetch the "tracked" BOM items associated with the partId + const { data: trackedItems } = useQuery({ + queryKey: ['trackeditems', buildId], + queryFn: async () => { + if (!buildId || buildId < 0) { + return []; + } + + return api + .get(apiUrl(ApiEndpoints.build_line_list), { + params: { + build: buildId, + tracked: true + } + }) + .then((response) => response.data) + .catch(() => []); + } + }); + + const hasTrackedItems: boolean = useMemo(() => { + return (trackedItems?.length ?? 0) > 0; + }, [trackedItems]); + + // Ensure base table data is updated correctly + useEffect(() => { + table.refreshTable(); + }, [hasTrackedItems, hasRequiredTests]); + // Format table records const formatRecords = useCallback( (records: any[]): any[] => { records?.forEach((record: any, index: number) => { + // Test result information, per record let results: TestResultOverview[] = []; let passCount: number = 0; @@ -105,11 +135,34 @@ export default function BuildOutputTable({ build }: { build: any }) { records[index].passCount = passCount; records[index].results = results; + + // Stock allocation information, per record + let fullyAllocatedCount: number = 0; + + // Iterate through each tracked item + trackedItems?.forEach((item: any) => { + let allocated = 0; + + // Find all allocations which match the build output + let allocations = item.allocations.filter( + (allocation: any) => (allocation.install_into = record.pk) + ); + + allocations.forEach((allocation: any) => { + allocated += allocation.quantity; + }); + + if (allocated >= item.bom_item_detail.quantity) { + fullyAllocatedCount += 1; + } + }); + + records[index].fullyAllocated = fullyAllocatedCount; }); return records; }, - [partId, testTemplates] + [partId, buildId, testTemplates, trackedItems] ); const buildOutputFields = useBuildOrderOutputFields({ build: build }); @@ -282,10 +335,16 @@ export default function BuildOutputTable({ build }: { build: any }) { accessor: 'allocations', sortable: false, switchable: false, - title: t`Allocated Items`, + hidden: !hasTrackedItems, + title: t`Allocated Lines`, render: (record: any) => { - // TODO: Implement this! - return '-'; + return ( + + ); } }, { @@ -327,7 +386,14 @@ export default function BuildOutputTable({ build }: { build: any }) { } } ]; - }, [buildId, partId, testTemplates]); + }, [ + buildId, + partId, + hasRequiredTests, + hasTrackedItems, + testTemplates, + trackedItems + ]); return ( <>