diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index 2b3c6747ed..5824b584c9 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,12 +1,15 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 377 +INVENTREE_API_VERSION = 378 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v378 -> 2025-08-01 : https://github.com/inventree/InvenTree/pull/10111 + - Adds "scheduled_to_build" annotated field to BuildLine serializer + v377 -> 2025-08-01 : https://github.com/inventree/InvenTree/pull/10109 - Allow email records to be deleted via the API diff --git a/src/backend/InvenTree/build/serializers.py b/src/backend/InvenTree/build/serializers.py index 628c7d1ee5..2bca90ef52 100644 --- a/src/backend/InvenTree/build/serializers.py +++ b/src/backend/InvenTree/build/serializers.py @@ -1308,6 +1308,7 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali # Annotated fields 'allocated', 'in_production', + 'scheduled_to_build', 'on_order', 'available_stock', 'available_substitute_stock', @@ -1438,13 +1439,12 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali ) # Annotated (calculated) fields - - # Total quantity of allocated stock allocated = serializers.FloatField(label=_('Allocated Stock'), read_only=True) - on_order = serializers.FloatField(label=_('On Order'), read_only=True) - in_production = serializers.FloatField(label=_('In Production'), read_only=True) + scheduled_to_build = serializers.FloatField( + label=_('Scheduled to Build'), read_only=True + ) external_stock = serializers.FloatField(read_only=True, label=_('External Stock')) available_stock = serializers.FloatField(read_only=True, label=_('Available Stock')) @@ -1464,6 +1464,7 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali - available: Total stock available for allocation against this build line - on_order: Total stock on order for this build line - in_production: Total stock currently in production for this build line + - scheduled_to_build: Total stock scheduled to be built for this build line Arguments: queryset: The queryset to annotate @@ -1573,7 +1574,10 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali # Annotate the "in_production" quantity queryset = queryset.annotate( - in_production=part.filters.annotate_in_production_quantity(reference=ref) + in_production=part.filters.annotate_in_production_quantity(reference=ref), + scheduled_to_build=part.filters.annotate_scheduled_to_build_quantity( + reference=ref + ), ) # Annotate the "on_order" quantity diff --git a/src/frontend/src/tables/ColumnRenderers.tsx b/src/frontend/src/tables/ColumnRenderers.tsx index e10c19ab48..155a2a8097 100644 --- a/src/frontend/src/tables/ColumnRenderers.tsx +++ b/src/frontend/src/tables/ColumnRenderers.tsx @@ -19,7 +19,11 @@ import type { TableColumn, TableColumnProps } from '@lib/types/Tables'; import { Thumbnail } from '../components/images/Thumbnail'; import { TableStatusRenderer } from '../components/render/StatusRenderer'; import { RenderOwner, RenderUser } from '../components/render/User'; -import { formatCurrency, formatDate } from '../defaults/formatters'; +import { + formatCurrency, + formatDate, + formatDecimal +} from '../defaults/formatters'; import { useGlobalSettingsState, useUserSettingsState @@ -212,6 +216,16 @@ export function BooleanColumn(props: TableColumn): TableColumn { }; } +export function DecimalColumn(props: TableColumn): TableColumn { + return { + render: (record: any) => { + const value = resolveItem(record, props.accessor ?? ''); + return formatDecimal(value); + }, + ...props + }; +} + export function DescriptionColumn(props: TableColumnProps): TableColumn { return { accessor: 'description', diff --git a/src/frontend/src/tables/build/BuildAllocatedStockTable.tsx b/src/frontend/src/tables/build/BuildAllocatedStockTable.tsx index fc75257b44..9ce710ce25 100644 --- a/src/frontend/src/tables/build/BuildAllocatedStockTable.tsx +++ b/src/frontend/src/tables/build/BuildAllocatedStockTable.tsx @@ -10,7 +10,6 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import { ModelType } from '@lib/enums/ModelType'; import { UserRoles } from '@lib/enums/Roles'; import { apiUrl } from '@lib/functions/Api'; -import { formatDecimal } from '@lib/functions/Formatting'; import type { TableFilter } from '@lib/types/Filters'; import type { TableColumn } from '@lib/types/Tables'; import type { StockOperationProps } from '../../forms/StockForms'; @@ -22,6 +21,7 @@ import { useStockAdjustActions } from '../../hooks/UseStockAdjustActions'; import { useTable } from '../../hooks/UseTable'; import { useUserState } from '../../states/UserState'; import { + DecimalColumn, LocationColumn, PartColumn, ReferenceColumn, @@ -131,19 +131,16 @@ export default function BuildAllocatedStockTable({ switchable: true, render: (record: any) => record?.stock_item_detail?.batch }, - { + DecimalColumn({ accessor: 'available', - title: t`Available Quantity`, - render: (record: any) => - formatDecimal(record?.stock_item_detail?.quantity) - }, - { + title: t`Available Quantity` + }), + DecimalColumn({ accessor: 'quantity', title: t`Allocated Quantity`, sortable: true, - switchable: false, - render: (record: any) => formatDecimal(record?.quantity) - }, + switchable: false + }), LocationColumn({ accessor: 'location_detail', switchable: true, diff --git a/src/frontend/src/tables/build/BuildLineTable.tsx b/src/frontend/src/tables/build/BuildLineTable.tsx index faf0c17b8f..f3cf15d992 100644 --- a/src/frontend/src/tables/build/BuildLineTable.tsx +++ b/src/frontend/src/tables/build/BuildLineTable.tsx @@ -42,6 +42,7 @@ import { useTable } from '../../hooks/UseTable'; import { useUserState } from '../../states/UserState'; import { BooleanColumn, + DecimalColumn, DescriptionColumn, LocationColumn, PartColumn @@ -445,6 +446,26 @@ export default function BuildLineTable({ switchable: false, render: renderAvailableColumn }, + { + accessor: 'in_production', + render: (record: any) => { + if (record.scheduled_to_build > 0) { + return ( + + ); + } else { + return record.part_detail?.is_assembly ? 0 : '-'; + } + } + }, + DecimalColumn({ + accessor: 'on_order', + defaultVisible: false + }), { accessor: 'allocated', switchable: false, diff --git a/src/frontend/src/tables/general/ExtraLineItemTable.tsx b/src/frontend/src/tables/general/ExtraLineItemTable.tsx index bb0c7b5b8c..36dca53759 100644 --- a/src/frontend/src/tables/general/ExtraLineItemTable.tsx +++ b/src/frontend/src/tables/general/ExtraLineItemTable.tsx @@ -12,7 +12,7 @@ import type { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import type { UserRoles } from '@lib/enums/Roles'; import { apiUrl } from '@lib/functions/Api'; import type { TableColumn } from '@lib/types/Tables'; -import { formatCurrency, formatDecimal } from '../../defaults/formatters'; +import { formatCurrency } from '../../defaults/formatters'; import { extraLineItemFields } from '../../forms/CommonForms'; import { useCreateApiFormModal, @@ -21,7 +21,12 @@ import { } from '../../hooks/UseForm'; import { useTable } from '../../hooks/UseTable'; import { useUserState } from '../../states/UserState'; -import { DescriptionColumn, LinkColumn, NoteColumn } from '../ColumnRenderers'; +import { + DecimalColumn, + DescriptionColumn, + LinkColumn, + NoteColumn +} from '../ColumnRenderers'; import { InvenTreeTable } from '../InvenTreeTable'; export default function ExtraLineItemTable({ @@ -47,11 +52,10 @@ export default function ExtraLineItemTable({ switchable: false }, DescriptionColumn({}), - { + DecimalColumn({ accessor: 'quantity', - switchable: false, - render: (record: any) => formatDecimal(record.quantity) - }, + switchable: false + }), { accessor: 'price', title: t`Unit Price`, diff --git a/src/frontend/src/tables/purchasing/SupplierPartTable.tsx b/src/frontend/src/tables/purchasing/SupplierPartTable.tsx index 3cebdb000d..0d7c74f92a 100644 --- a/src/frontend/src/tables/purchasing/SupplierPartTable.tsx +++ b/src/frontend/src/tables/purchasing/SupplierPartTable.tsx @@ -12,7 +12,6 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import { ModelType } from '@lib/enums/ModelType'; import { UserRoles } from '@lib/enums/Roles'; import { apiUrl } from '@lib/functions/Api'; -import { formatDecimal } from '@lib/index'; import type { TableFilter } from '@lib/types/Filters'; import type { TableColumn } from '@lib/types/Tables'; import { useSupplierPartFields } from '../../forms/CompanyForms'; @@ -26,6 +25,7 @@ import { useUserState } from '../../states/UserState'; import { BooleanColumn, CompanyColumn, + DecimalColumn, DescriptionColumn, LinkColumn, NoteColumn, @@ -90,11 +90,10 @@ export function SupplierPartTable({ switchable: true, defaultVisible: false }), - { + DecimalColumn({ accessor: 'in_stock', - sortable: true, - render: (record: any) => formatDecimal(record.in_stock) - }, + sortable: true + }), { accessor: 'packaging', sortable: true, diff --git a/src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx b/src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx index e2eb0bca0d..084aa3eeb7 100644 --- a/src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx +++ b/src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx @@ -29,7 +29,7 @@ import type { TableFilter } from '@lib/types/Filters'; import type { TableColumn } from '@lib/types/Tables'; import { RenderPart } from '../../components/render/Part'; import OrderPartsWizard from '../../components/wizards/OrderPartsWizard'; -import { formatCurrency, formatDecimal } from '../../defaults/formatters'; +import { formatCurrency } from '../../defaults/formatters'; import { useBuildOrderFields } from '../../forms/BuildForms'; import { useAllocateToSalesOrderForm, @@ -45,6 +45,7 @@ import { useTable } from '../../hooks/UseTable'; import { useUserState } from '../../states/UserState'; import { DateColumn, + DecimalColumn, DescriptionColumn, LinkColumn, PartColumn @@ -102,11 +103,10 @@ export default function SalesOrderLineItemTable({ sortable: false, switchable: true }, - { + DecimalColumn({ accessor: 'quantity', - sortable: true, - render: (record: any) => formatDecimal(record.quantity) - }, + sortable: true + }), { accessor: 'sale_price', render: (record: any) =>