diff --git a/InvenTree/InvenTree/api_version.py b/InvenTree/InvenTree/api_version.py
index 01e2fda972..0867ef8b0c 100644
--- a/InvenTree/InvenTree/api_version.py
+++ b/InvenTree/InvenTree/api_version.py
@@ -2,11 +2,15 @@
# InvenTree API version
-INVENTREE_API_VERSION = 145
+INVENTREE_API_VERSION = 147
"""
Increment this API version number whenever there is a significant change to the API that any clients need to know about
+v147 -> 2023-11-04: https://github.com/inventree/InvenTree/pull/5860
+ - Adds "completed_lines" field to SalesOrder API endpoint
+ - Adds "completed_lines" field to PurchaseOrder API endpoint
+
v146 -> 2023-11-02: https://github.com/inventree/InvenTree/pull/5822
- Extended SSO Provider endpoint to contain if a provider is configured
- Adds API endpoints for Email Address model
diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py
index b4825ce1a9..939123b660 100644
--- a/InvenTree/order/serializers.py
+++ b/InvenTree/order/serializers.py
@@ -29,8 +29,8 @@ from InvenTree.serializers import (InvenTreeAttachmentSerializer,
InvenTreeModelSerializer,
InvenTreeMoneySerializer)
from InvenTree.status_codes import (PurchaseOrderStatusGroups,
- ReturnOrderStatus, SalesOrderStatusGroups,
- StockStatus)
+ ReturnOrderLineStatus, ReturnOrderStatus,
+ SalesOrderStatusGroups, StockStatus)
from part.serializers import PartBriefSerializer
from users.serializers import OwnerSerializer
@@ -58,6 +58,9 @@ class AbstractOrderSerializer(serializers.Serializer):
# Number of line items in this order
line_items = serializers.IntegerField(read_only=True)
+ # Number of completed line items (this is an annotated field)
+ completed_lines = serializers.IntegerField(read_only=True)
+
# Human-readable status text (read-only)
status_text = serializers.CharField(source='get_status_display', read_only=True)
@@ -107,6 +110,7 @@ class AbstractOrderSerializer(serializers.Serializer):
'target_date',
'description',
'line_items',
+ 'completed_lines',
'link',
'project_code',
'project_code_detail',
@@ -211,6 +215,10 @@ class PurchaseOrderSerializer(TotalPriceMixin, AbstractOrderSerializer, InvenTre
"""
queryset = AbstractOrderSerializer.annotate_queryset(queryset)
+ queryset = queryset.annotate(
+ completed_lines=SubqueryCount('lines', filter=Q(quantity__lte=F('received')))
+ )
+
queryset = queryset.annotate(
overdue=Case(
When(
@@ -743,10 +751,15 @@ class SalesOrderSerializer(TotalPriceMixin, AbstractOrderSerializer, InvenTreeMo
"""Add extra information to the queryset.
- Number of line items in the SalesOrder
+ - Number of completed line items in the SalesOrder
- Overdue status of the SalesOrder
"""
queryset = AbstractOrderSerializer.annotate_queryset(queryset)
+ queryset = queryset.annotate(
+ completed_lines=SubqueryCount('lines', filter=Q(quantity__lte=F('shipped')))
+ )
+
queryset = queryset.annotate(
overdue=Case(
When(
@@ -1503,6 +1516,10 @@ class ReturnOrderSerializer(AbstractOrderSerializer, TotalPriceMixin, InvenTreeM
"""Custom annotation for the serializer queryset"""
queryset = AbstractOrderSerializer.annotate_queryset(queryset)
+ queryset = queryset.annotate(
+ completed_lines=SubqueryCount('lines', filter=~Q(outcome=ReturnOrderLineStatus.PENDING.value))
+ )
+
queryset = queryset.annotate(
overdue=Case(
When(
diff --git a/src/frontend/src/components/renderers/StatusRenderer.tsx b/src/frontend/src/components/renderers/StatusRenderer.tsx
index f3a97ccf5d..bcd1359f8a 100644
--- a/src/frontend/src/components/renderers/StatusRenderer.tsx
+++ b/src/frontend/src/components/renderers/StatusRenderer.tsx
@@ -1,4 +1,4 @@
-import { Badge, MantineSize } from '@mantine/core';
+import { Badge, Center, MantineSize } from '@mantine/core';
import { colorMap } from '../../defaults/backendMappings';
import { useServerApiState } from '../../states/ApiState';
@@ -99,5 +99,8 @@ export const StatusRenderer = ({
export function TableStatusRenderer(
type: ModelType
): ((record: any) => any) | undefined {
- return (record: any) => StatusRenderer({ status: record.status, type: type });
+ return (record: any) =>
+ record.status && (
+
{StatusRenderer({ status: record.status, type: type })}
+ );
}
diff --git a/src/frontend/src/components/tables/ColumnRenderers.tsx b/src/frontend/src/components/tables/ColumnRenderers.tsx
new file mode 100644
index 0000000000..bad1d3621b
--- /dev/null
+++ b/src/frontend/src/components/tables/ColumnRenderers.tsx
@@ -0,0 +1,134 @@
+/**
+ * Common rendering functions for table column data.
+ */
+import { t } from '@lingui/macro';
+
+import { ProgressBar } from '../items/ProgressBar';
+import { ModelType } from '../render/ModelType';
+import { RenderOwner } from '../render/User';
+import { TableStatusRenderer } from '../renderers/StatusRenderer';
+import { TableColumn } from './Column';
+import { ProjectCodeHoverCard } from './TableHoverCard';
+
+export function DescriptionColumn(): TableColumn {
+ return {
+ accessor: 'description',
+ title: t`Description`,
+ sortable: false,
+ switchable: true
+ };
+}
+
+export function LinkColumn(): TableColumn {
+ return {
+ accessor: 'link',
+ title: t`Link`,
+ sortable: false
+ // TODO: Custom URL hyperlink renderer?
+ };
+}
+
+export function LineItemsProgressColumn(): TableColumn {
+ return {
+ accessor: 'line_items',
+ title: t`Line Items`,
+ sortable: true,
+ render: (record: any) => (
+
+ )
+ };
+}
+
+export function ProjectCodeColumn(): TableColumn {
+ return {
+ accessor: 'project_code',
+ title: t`Project Code`,
+ sortable: true,
+ render: (record: any) => (
+
+ )
+ };
+}
+
+export function StatusColumn(model: ModelType) {
+ return {
+ accessor: 'status',
+ sortable: true,
+ title: t`Status`,
+ render: TableStatusRenderer(model)
+ };
+}
+
+export function ResponsibleColumn(): TableColumn {
+ return {
+ accessor: 'responsible',
+ title: t`Responsible`,
+ sortable: true,
+ render: (record: any) =>
+ record.responsible && RenderOwner({ instance: record.responsible_detail })
+ };
+}
+
+export function TargetDateColumn(): TableColumn {
+ return {
+ accessor: 'target_date',
+ title: t`Target Date`,
+ sortable: true
+ // TODO: custom renderer which alerts user if target date is overdue
+ };
+}
+
+export function CreationDateColumn(): TableColumn {
+ return {
+ accessor: 'creation_date',
+ title: t`Creation Date`,
+ sortable: true
+ };
+}
+
+export function ShipmentDateColumn(): TableColumn {
+ return {
+ accessor: 'shipment_date',
+ title: t`Shipment Date`,
+ sortable: true
+ };
+}
+
+export function CurrencyColumn({
+ accessor,
+ title,
+ currency,
+ currency_accessor,
+ sortable
+}: {
+ accessor: string;
+ title?: string;
+ currency?: string;
+ currency_accessor?: string;
+ sortable?: boolean;
+}): TableColumn {
+ return {
+ accessor: accessor,
+ title: title ?? t`Currency`,
+ sortable: sortable ?? true,
+ render: (record: any) => {
+ let value = record[accessor];
+ let currency_key = currency_accessor ?? `${accessor}_currency`;
+ currency = currency ?? record[currency_key];
+
+ // TODO: A better render which correctly formats money values
+ return `${value} ${currency}`;
+ }
+ };
+}
+
+export function TotalPriceColumn(): TableColumn {
+ return CurrencyColumn({
+ accessor: 'total_price',
+ title: t`Total Price`
+ });
+}
diff --git a/src/frontend/src/components/tables/TableHoverCard.tsx b/src/frontend/src/components/tables/TableHoverCard.tsx
index 03499f585d..b43f134e7a 100644
--- a/src/frontend/src/components/tables/TableHoverCard.tsx
+++ b/src/frontend/src/components/tables/TableHoverCard.tsx
@@ -1,3 +1,4 @@
+import { t } from '@lingui/macro';
import { Divider, Group, HoverCard, Stack, Text } from '@mantine/core';
import { IconInfoCircle } from '@tabler/icons-react';
import { ReactNode } from 'react';
@@ -21,6 +22,10 @@ export function TableHoverCard({
return value;
}
+ if (Array.isArray(extra) && extra.length == 0) {
+ return value;
+ }
+
return (
@@ -42,3 +47,18 @@ export function TableHoverCard({
);
}
+
+/**
+ * Custom hovercard for displaying projectcode detail in a table
+ */
+export function ProjectCodeHoverCard({ projectCode }: { projectCode: any }) {
+ return projectCode ? (
+
+ ) : (
+ '-'
+ );
+}
diff --git a/src/frontend/src/components/tables/build/BuildOrderTable.tsx b/src/frontend/src/components/tables/build/BuildOrderTable.tsx
index b39b2a85c3..950961e81d 100644
--- a/src/frontend/src/components/tables/build/BuildOrderTable.tsx
+++ b/src/frontend/src/components/tables/build/BuildOrderTable.tsx
@@ -1,22 +1,22 @@
import { t } from '@lingui/macro';
-import { Text } from '@mantine/core';
-import { useCallback, useMemo } from 'react';
+import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
-import { buildOrderFields } from '../../../forms/BuildForms';
-import { openCreateApiForm } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
-import { AddItemButton } from '../../buttons/AddItemButton';
import { ThumbnailHoverCard } from '../../images/Thumbnail';
import { ProgressBar } from '../../items/ProgressBar';
import { ModelType } from '../../render/ModelType';
-import { RenderOwner, RenderUser } from '../../render/User';
-import { TableStatusRenderer } from '../../renderers/StatusRenderer';
+import { RenderUser } from '../../render/User';
import { TableColumn } from '../Column';
-import { TableFilter } from '../Filter';
+import {
+ CreationDateColumn,
+ ProjectCodeColumn,
+ ResponsibleColumn,
+ StatusColumn,
+ TargetDateColumn
+} from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
-import { TableHoverCard } from '../TableHoverCard';
/**
* Construct a list of columns for the build order table
@@ -66,47 +66,15 @@ function buildOrderTableColumns(): TableColumn[] {
/>
)
},
- {
- accessor: 'status',
- sortable: true,
- title: t`Status`,
-
- render: TableStatusRenderer(ModelType.build)
- },
- {
- accessor: 'project_code',
- title: t`Project Code`,
- sortable: true,
- // TODO: Hide this if project code is not enabled
- render: (record: any) => {
- let project = record.project_code_detail;
-
- return project ? (
- {project.description}}
- />
- ) : (
- '-'
- );
- }
- },
+ StatusColumn(ModelType.build),
+ ProjectCodeColumn(),
{
accessor: 'priority',
title: t`Priority`,
sortable: true
},
- {
- accessor: 'creation_date',
- sortable: true,
- title: t`Created`
- },
- {
- accessor: 'target_date',
- sortable: true,
- title: t`Target Date`
- },
+ CreationDateColumn(),
+ TargetDateColumn(),
{
accessor: 'completion_date',
sortable: true,
@@ -120,14 +88,7 @@ function buildOrderTableColumns(): TableColumn[] {
)
},
- {
- accessor: 'responsible',
- sortable: true,
- title: t`Responsible`,
- render: (record: any) => (
-
- )
- }
+ ResponsibleColumn()
];
}
diff --git a/src/frontend/src/components/tables/general/CompanyTable.tsx b/src/frontend/src/components/tables/general/CompanyTable.tsx
index 77908caea4..97ec95c5c7 100644
--- a/src/frontend/src/components/tables/general/CompanyTable.tsx
+++ b/src/frontend/src/components/tables/general/CompanyTable.tsx
@@ -6,6 +6,7 @@ import { useNavigate } from 'react-router-dom';
import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail';
+import { DescriptionColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
/**
@@ -42,11 +43,7 @@ export function CompanyTable({
);
}
},
- {
- accessor: 'description',
- title: t`Description`,
- sortable: false
- },
+ DescriptionColumn(),
{
accessor: 'website',
title: t`Website`,
diff --git a/src/frontend/src/components/tables/part/PartCategoryTable.tsx b/src/frontend/src/components/tables/part/PartCategoryTable.tsx
index c2c7ad55ed..4688ea498d 100644
--- a/src/frontend/src/components/tables/part/PartCategoryTable.tsx
+++ b/src/frontend/src/components/tables/part/PartCategoryTable.tsx
@@ -5,6 +5,7 @@ import { useNavigate } from 'react-router-dom';
import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { TableColumn } from '../Column';
+import { DescriptionColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
/**
@@ -23,11 +24,7 @@ export function PartCategoryTable({ params = {} }: { params?: any }) {
sortable: true,
switchable: false
},
- {
- accessor: 'description',
- title: t`Description`,
- sortable: false
- },
+ DescriptionColumn(),
{
accessor: 'pathstring',
title: t`Path`,
diff --git a/src/frontend/src/components/tables/part/PartTable.tsx b/src/frontend/src/components/tables/part/PartTable.tsx
index 49221ce43a..fe35844af9 100644
--- a/src/frontend/src/components/tables/part/PartTable.tsx
+++ b/src/frontend/src/components/tables/part/PartTable.tsx
@@ -8,6 +8,7 @@ import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail';
import { TableColumn } from '../Column';
+import { DescriptionColumn, LinkColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter';
import { InvenTreeTable, InvenTreeTableProps } from '../InvenTreeTable';
import { TableHoverCard } from '../TableHoverCard';
@@ -42,11 +43,7 @@ function partTableColumns(): TableColumn[] {
sortable: true,
title: t`Units`
},
- {
- accessor: 'description',
- title: t`Description`,
- sortable: true
- },
+ DescriptionColumn(),
{
accessor: 'category',
title: t`Category`,
@@ -155,10 +152,7 @@ function partTableColumns(): TableColumn[] {
return '-- price --';
}
},
- {
- accessor: 'link',
- title: t`Link`
- }
+ LinkColumn()
];
}
diff --git a/src/frontend/src/components/tables/purchasing/PurchaseOrderLineItemTable.tsx b/src/frontend/src/components/tables/purchasing/PurchaseOrderLineItemTable.tsx
index bd264a1ba8..c3d2746172 100644
--- a/src/frontend/src/components/tables/purchasing/PurchaseOrderLineItemTable.tsx
+++ b/src/frontend/src/components/tables/purchasing/PurchaseOrderLineItemTable.tsx
@@ -12,6 +12,13 @@ import { useUserState } from '../../../states/UserState';
import { ActionButton } from '../../buttons/ActionButton';
import { AddItemButton } from '../../buttons/AddItemButton';
import { Thumbnail } from '../../images/Thumbnail';
+import { RenderStockLocation } from '../../render/Stock';
+import {
+ CurrencyColumn,
+ LinkColumn,
+ TargetDateColumn,
+ TotalPriceColumn
+} from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
import {
RowDeleteAction,
@@ -112,8 +119,8 @@ export function PurchaseOrderLineItemTable({
sortable: true,
switchable: false,
render: (record: any) => {
- let part = record?.part_detail;
let supplier_part = record?.supplier_part_detail ?? {};
+ let part = record?.part_detail ?? supplier_part?.part_detail ?? {};
let extra = [];
if (supplier_part.pack_quantity_native != 1) {
@@ -127,8 +134,7 @@ export function PurchaseOrderLineItemTable({
extra.push(
- {t`Total Quantity`}: {total}
- {part.units}
+ {t`Total Quantity`}: {total} {part?.units}
);
}
@@ -158,7 +164,6 @@ export function PurchaseOrderLineItemTable({
{
accessor: 'pack_quantity',
sortable: false,
-
title: t`Pack Quantity`,
render: (record: any) => record?.supplier_part_detail?.pack_quantity
},
@@ -166,7 +171,8 @@ export function PurchaseOrderLineItemTable({
accessor: 'SKU',
title: t`Supplier Code`,
switchable: false,
- sortable: true
+ sortable: true,
+ render: (record: any) => record?.supplier_part_detail?.SKU
},
{
accessor: 'supplier_link',
@@ -183,43 +189,26 @@ export function PurchaseOrderLineItemTable({
render: (record: any) =>
record?.supplier_part_detail?.manufacturer_part_detail?.MPN
},
-
- {
+ CurrencyColumn({
accessor: 'purchase_price',
- title: t`Unit Price`,
- sortable: true
-
- // TODO: custom renderer
- },
- {
- accessor: 'total_price',
- title: t`Total Price`,
- sortable: true
-
- // TODO: custom renderer
- },
- {
- accessor: 'target_date',
- title: t`Target Date`,
- sortable: true
- },
+ title: t`Unit Price`
+ }),
+ TotalPriceColumn(),
+ TargetDateColumn(),
{
accessor: 'destination',
title: t`Destination`,
- sortable: false
-
- // TODO: Custom renderer
+ sortable: false,
+ render: (record: any) =>
+ record.destination
+ ? RenderStockLocation({ instance: record.destination_detail })
+ : '-'
},
{
accessor: 'notes',
title: t`Notes`
},
- {
- accessor: 'link',
- title: t`Link`
-
- // TODO: custom renderer
- }
+ LinkColumn()
];
}, [orderId, user]);
diff --git a/src/frontend/src/components/tables/purchasing/PurchaseOrderTable.tsx b/src/frontend/src/components/tables/purchasing/PurchaseOrderTable.tsx
index a0343358c1..63c0c60faa 100644
--- a/src/frontend/src/components/tables/purchasing/PurchaseOrderTable.tsx
+++ b/src/frontend/src/components/tables/purchasing/PurchaseOrderTable.tsx
@@ -6,7 +6,16 @@ import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail';
import { ModelType } from '../../render/ModelType';
-import { StatusRenderer } from '../../renderers/StatusRenderer';
+import {
+ CreationDateColumn,
+ DescriptionColumn,
+ LineItemsProgressColumn,
+ ProjectCodeColumn,
+ ResponsibleColumn,
+ StatusColumn,
+ TargetDateColumn,
+ TotalPriceColumn
+} from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
/**
@@ -30,11 +39,9 @@ export function PurchaseOrderTable({ params }: { params?: any }) {
title: t`Reference`,
sortable: true,
switchable: false
+ // TODO: Display extra information if order is overdue
},
- {
- accessor: 'description',
- title: t`Description`
- },
+ DescriptionColumn(),
{
accessor: 'supplier__name',
title: t`Supplier`,
@@ -55,54 +62,13 @@ export function PurchaseOrderTable({ params }: { params?: any }) {
accessor: 'supplier_reference',
title: t`Supplier Reference`
},
- {
- accessor: 'project_code',
- title: t`Project Code`
-
- // TODO: Custom project code formatter
- },
- {
- accessor: 'status',
- title: t`Status`,
- sortable: true,
-
- render: (record: any) =>
- StatusRenderer({
- status: record.status,
- type: ModelType.purchaseorder
- })
- },
- {
- accessor: 'creation_date',
- title: t`Created`
-
- // TODO: Custom date formatter
- },
- {
- accessor: 'target_date',
- title: t`Target Date`
-
- // TODO: Custom date formatter
- },
- {
- accessor: 'line_items',
- title: t`Line Items`,
- sortable: true
- },
- {
- accessor: 'total_price',
- title: t`Total Price`,
- sortable: true
-
- // TODO: Custom money formatter
- },
- {
- accessor: 'responsible',
- title: t`Responsible`,
- sortable: true
-
- // TODO: custom 'owner' formatter
- }
+ LineItemsProgressColumn(),
+ StatusColumn(ModelType.purchaseorder),
+ ProjectCodeColumn(),
+ CreationDateColumn(),
+ TargetDateColumn(),
+ TotalPriceColumn(),
+ ResponsibleColumn()
];
}, []);
diff --git a/src/frontend/src/components/tables/purchasing/SupplierPartTable.tsx b/src/frontend/src/components/tables/purchasing/SupplierPartTable.tsx
index be206a9400..e3e1276885 100644
--- a/src/frontend/src/components/tables/purchasing/SupplierPartTable.tsx
+++ b/src/frontend/src/components/tables/purchasing/SupplierPartTable.tsx
@@ -14,6 +14,7 @@ import { useUserState } from '../../../states/UserState';
import { AddItemButton } from '../../buttons/AddItemButton';
import { Thumbnail } from '../../images/Thumbnail';
import { TableColumn } from '../Column';
+import { DescriptionColumn, LinkColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard';
@@ -63,11 +64,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
title: t`Supplier Part`,
sortable: true
},
- {
- accessor: 'description',
- title: t`Description`,
- sortable: false
- },
+ DescriptionColumn(),
{
accessor: 'manufacturer',
@@ -128,13 +125,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
);
}
},
- {
- accessor: 'link',
- title: t`Link`,
- sortable: false
-
- // TODO: custom link renderer?
- },
+ LinkColumn(),
{
accessor: 'note',
title: t`Notes`,
diff --git a/src/frontend/src/components/tables/sales/ReturnOrderTable.tsx b/src/frontend/src/components/tables/sales/ReturnOrderTable.tsx
index 18f298d8ba..41bf78762a 100644
--- a/src/frontend/src/components/tables/sales/ReturnOrderTable.tsx
+++ b/src/frontend/src/components/tables/sales/ReturnOrderTable.tsx
@@ -6,7 +6,15 @@ import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail';
import { ModelType } from '../../render/ModelType';
-import { TableStatusRenderer } from '../../renderers/StatusRenderer';
+import {
+ CreationDateColumn,
+ DescriptionColumn,
+ LineItemsProgressColumn,
+ ProjectCodeColumn,
+ ResponsibleColumn,
+ StatusColumn,
+ TargetDateColumn
+} from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
export function ReturnOrderTable({ params }: { params?: any }) {
@@ -26,10 +34,7 @@ export function ReturnOrderTable({ params }: { params?: any }) {
accessor: 'reference',
title: t`Return Order`,
sortable: true
- },
- {
- accessor: 'description',
- title: t`Description`
+ // TODO: Display extra information if order is overdue
},
{
accessor: 'customer__name',
@@ -51,24 +56,17 @@ export function ReturnOrderTable({ params }: { params?: any }) {
accessor: 'customer_reference',
title: t`Customer Reference`
},
+ DescriptionColumn(),
+ LineItemsProgressColumn(),
+ StatusColumn(ModelType.returnorder),
+ ProjectCodeColumn(),
+ CreationDateColumn(),
+ TargetDateColumn(),
+ ResponsibleColumn(),
{
- accessor: 'project_code',
- title: t`Project Code`
-
- // TODO: Custom formatter
- },
- {
- accessor: 'status',
- title: t`Status`,
- sortable: true,
-
- render: TableStatusRenderer(ModelType.returnorder)
+ accessor: 'total_cost',
+ title: t`Total Cost`
}
- // TODO: Creation date
- // TODO: Target date
- // TODO: Line items
- // TODO: Responsible
- // TODO: Total cost
];
}, []);
diff --git a/src/frontend/src/components/tables/sales/SalesOrderTable.tsx b/src/frontend/src/components/tables/sales/SalesOrderTable.tsx
index 48cce5cc95..fdda8670d7 100644
--- a/src/frontend/src/components/tables/sales/SalesOrderTable.tsx
+++ b/src/frontend/src/components/tables/sales/SalesOrderTable.tsx
@@ -6,7 +6,16 @@ import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail';
import { ModelType } from '../../render/ModelType';
-import { TableStatusRenderer } from '../../renderers/StatusRenderer';
+import {
+ CreationDateColumn,
+ DescriptionColumn,
+ LineItemsProgressColumn,
+ ProjectCodeColumn,
+ ShipmentDateColumn,
+ StatusColumn,
+ TargetDateColumn,
+ TotalPriceColumn
+} from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
export function SalesOrderTable({ params }: { params?: any }) {
@@ -27,10 +36,7 @@ export function SalesOrderTable({ params }: { params?: any }) {
title: t`Sales Order`,
sortable: true,
switchable: false
- },
- {
- accessor: 'description',
- title: t`Description`
+ // TODO: Display extra information if order is overdue
},
{
accessor: 'customer__name',
@@ -52,25 +58,14 @@ export function SalesOrderTable({ params }: { params?: any }) {
accessor: 'customer_reference',
title: t`Customer Reference`
},
- {
- accessor: 'project_code',
- title: t`Project Code`
-
- // TODO: Custom formatter
- },
- {
- accessor: 'status',
- title: t`Status`,
- sortable: true,
-
- render: TableStatusRenderer(ModelType.salesorder)
- }
-
- // TODO: Creation date
- // TODO: Target date
- // TODO: Shipment date
- // TODO: Line items
- // TODO: Total price
+ DescriptionColumn(),
+ LineItemsProgressColumn(),
+ StatusColumn(ModelType.salesorder),
+ ProjectCodeColumn(),
+ CreationDateColumn(),
+ TargetDateColumn(),
+ ShipmentDateColumn(),
+ TotalPriceColumn()
];
}, []);
diff --git a/src/frontend/src/components/tables/settings/ProjectCodeTable.tsx b/src/frontend/src/components/tables/settings/ProjectCodeTable.tsx
index 7715b938b8..8b7270828f 100644
--- a/src/frontend/src/components/tables/settings/ProjectCodeTable.tsx
+++ b/src/frontend/src/components/tables/settings/ProjectCodeTable.tsx
@@ -11,6 +11,7 @@ import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { AddItemButton } from '../../buttons/AddItemButton';
import { TableColumn } from '../Column';
+import { DescriptionColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
@@ -27,11 +28,7 @@ export function ProjectCodeTable() {
sortable: true,
title: t`Project Code`
},
- {
- accessor: 'description',
- sortable: false,
- title: t`Description`
- }
+ DescriptionColumn()
];
}, []);
diff --git a/src/frontend/src/components/tables/stock/StockItemTable.tsx b/src/frontend/src/components/tables/stock/StockItemTable.tsx
index 397d40a480..1e15bf3b10 100644
--- a/src/frontend/src/components/tables/stock/StockItemTable.tsx
+++ b/src/frontend/src/components/tables/stock/StockItemTable.tsx
@@ -7,8 +7,8 @@ import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail';
import { ModelType } from '../../render/ModelType';
-import { TableStatusRenderer } from '../../renderers/StatusRenderer';
import { TableColumn } from '../Column';
+import { StatusColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter';
import { RowAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard';
@@ -150,14 +150,7 @@ function stockItemTableColumns(): TableColumn[] {
);
}
},
- {
- accessor: 'status',
- sortable: true,
-
- filter: true,
- title: t`Status`,
- render: TableStatusRenderer(ModelType.stockitem)
- },
+ StatusColumn(ModelType.stockitem),
{
accessor: 'batch',
sortable: true,
diff --git a/src/frontend/src/components/tables/stock/StockLocationTable.tsx b/src/frontend/src/components/tables/stock/StockLocationTable.tsx
index 06ee99cd5a..52f2299b03 100644
--- a/src/frontend/src/components/tables/stock/StockLocationTable.tsx
+++ b/src/frontend/src/components/tables/stock/StockLocationTable.tsx
@@ -6,6 +6,7 @@ import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
import { YesNoButton } from '../../items/YesNoButton';
import { TableColumn } from '../Column';
+import { DescriptionColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
/**
@@ -23,10 +24,7 @@ export function StockLocationTable({ params = {} }: { params?: any }) {
title: t`Name`,
switchable: false
},
- {
- accessor: 'description',
- title: t`Description`
- },
+ DescriptionColumn(),
{
accessor: 'pathstring',
title: t`Path`,