mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
[PUI] Allocation Tables (#7836)
* Skeleton panel and placeholder tables * Implement build order allocation table * Refactor and repurpose existing table * Add allocations table to stock item page * Skeleton for <SalesOrderAllocationTable /> * Implement sales order allocation table(s)
This commit is contained in:
parent
dce6cf6b01
commit
90a918e6d2
@ -141,6 +141,7 @@ export enum ApiEndpoints {
|
|||||||
sales_order_ship = 'order/so/:id/ship/',
|
sales_order_ship = 'order/so/:id/ship/',
|
||||||
sales_order_complete = 'order/so/:id/complete/',
|
sales_order_complete = 'order/so/:id/complete/',
|
||||||
sales_order_line_list = 'order/so-line/',
|
sales_order_line_list = 'order/so-line/',
|
||||||
|
sales_order_allocation_list = 'order/so-allocation/',
|
||||||
sales_order_shipment_list = 'order/so/shipment/',
|
sales_order_shipment_list = 'order/so/shipment/',
|
||||||
|
|
||||||
return_order_list = 'order/ro/',
|
return_order_list = 'order/ro/',
|
||||||
|
@ -283,7 +283,7 @@ export default function BuildDetail() {
|
|||||||
label: t`Allocated Stock`,
|
label: t`Allocated Stock`,
|
||||||
icon: <IconList />,
|
icon: <IconList />,
|
||||||
content: build.pk ? (
|
content: build.pk ? (
|
||||||
<BuildAllocatedStockTable buildId={build.pk} />
|
<BuildAllocatedStockTable buildId={build.pk} showPartInfo allowEdit />
|
||||||
) : (
|
) : (
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Alert, Grid, Skeleton, Space, Stack, Text } from '@mantine/core';
|
import {
|
||||||
|
Accordion,
|
||||||
|
Alert,
|
||||||
|
Grid,
|
||||||
|
Skeleton,
|
||||||
|
Space,
|
||||||
|
Stack,
|
||||||
|
Text
|
||||||
|
} from '@mantine/core';
|
||||||
import {
|
import {
|
||||||
IconBookmarks,
|
IconBookmarks,
|
||||||
IconBuilding,
|
IconBuilding,
|
||||||
@ -48,6 +56,7 @@ import {
|
|||||||
ViewBarcodeAction
|
ViewBarcodeAction
|
||||||
} from '../../components/items/ActionDropdown';
|
} from '../../components/items/ActionDropdown';
|
||||||
import { PlaceholderPanel } from '../../components/items/Placeholder';
|
import { PlaceholderPanel } from '../../components/items/Placeholder';
|
||||||
|
import { StylishText } from '../../components/items/StylishText';
|
||||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||||
import NavigationTree from '../../components/nav/NavigationTree';
|
import NavigationTree from '../../components/nav/NavigationTree';
|
||||||
import { PageDetail } from '../../components/nav/PageDetail';
|
import { PageDetail } from '../../components/nav/PageDetail';
|
||||||
@ -76,6 +85,7 @@ import { useGlobalSettingsState } from '../../states/SettingsState';
|
|||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import { BomTable } from '../../tables/bom/BomTable';
|
import { BomTable } from '../../tables/bom/BomTable';
|
||||||
import { UsedInTable } from '../../tables/bom/UsedInTable';
|
import { UsedInTable } from '../../tables/bom/UsedInTable';
|
||||||
|
import BuildAllocatedStockTable from '../../tables/build/BuildAllocatedStockTable';
|
||||||
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
|
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
|
||||||
import { AttachmentTable } from '../../tables/general/AttachmentTable';
|
import { AttachmentTable } from '../../tables/general/AttachmentTable';
|
||||||
import { PartParameterTable } from '../../tables/part/PartParameterTable';
|
import { PartParameterTable } from '../../tables/part/PartParameterTable';
|
||||||
@ -84,6 +94,7 @@ import { PartVariantTable } from '../../tables/part/PartVariantTable';
|
|||||||
import { RelatedPartTable } from '../../tables/part/RelatedPartTable';
|
import { RelatedPartTable } from '../../tables/part/RelatedPartTable';
|
||||||
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
|
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
|
||||||
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
|
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
|
||||||
|
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
|
||||||
import { SalesOrderTable } from '../../tables/sales/SalesOrderTable';
|
import { SalesOrderTable } from '../../tables/sales/SalesOrderTable';
|
||||||
import { StockItemTable } from '../../tables/stock/StockItemTable';
|
import { StockItemTable } from '../../tables/stock/StockItemTable';
|
||||||
import { TestStatisticsTable } from '../../tables/stock/TestStatisticsTable';
|
import { TestStatisticsTable } from '../../tables/stock/TestStatisticsTable';
|
||||||
@ -539,7 +550,43 @@ export default function PartDetail() {
|
|||||||
label: t`Allocations`,
|
label: t`Allocations`,
|
||||||
icon: <IconBookmarks />,
|
icon: <IconBookmarks />,
|
||||||
hidden: !part.component && !part.salable,
|
hidden: !part.component && !part.salable,
|
||||||
content: <PlaceholderPanel />
|
content: (
|
||||||
|
<Accordion
|
||||||
|
multiple={true}
|
||||||
|
defaultValue={['buildallocations', 'salesallocations']}
|
||||||
|
>
|
||||||
|
{part.component && (
|
||||||
|
<Accordion.Item value="buildallocations" key="buildallocations">
|
||||||
|
<Accordion.Control>
|
||||||
|
<StylishText size="lg">{t`Build Order Allocations`}</StylishText>
|
||||||
|
</Accordion.Control>
|
||||||
|
<Accordion.Panel>
|
||||||
|
<BuildAllocatedStockTable
|
||||||
|
partId={part.pk}
|
||||||
|
modelField="build"
|
||||||
|
modelTarget={ModelType.build}
|
||||||
|
showBuildInfo
|
||||||
|
/>
|
||||||
|
</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
)}
|
||||||
|
{part.salable && (
|
||||||
|
<Accordion.Item value="salesallocations" key="salesallocations">
|
||||||
|
<Accordion.Control>
|
||||||
|
<StylishText size="lg">{t`Sales Order Allocations`}</StylishText>
|
||||||
|
</Accordion.Control>
|
||||||
|
<Accordion.Panel>
|
||||||
|
<SalesOrderAllocationTable
|
||||||
|
partId={part.pk}
|
||||||
|
modelField="order"
|
||||||
|
modelTarget={ModelType.salesorder}
|
||||||
|
showOrderInfo
|
||||||
|
/>
|
||||||
|
</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
)}
|
||||||
|
</Accordion>
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'bom',
|
name: 'bom',
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Grid, Skeleton, Stack } from '@mantine/core';
|
import { Grid, Skeleton, Stack } from '@mantine/core';
|
||||||
import {
|
import {
|
||||||
|
IconBook,
|
||||||
|
IconBookmark,
|
||||||
IconDots,
|
IconDots,
|
||||||
IconInfoCircle,
|
IconInfoCircle,
|
||||||
IconList,
|
IconList,
|
||||||
@ -49,6 +51,7 @@ import { apiUrl } from '../../states/ApiState';
|
|||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
|
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
|
||||||
import { AttachmentTable } from '../../tables/general/AttachmentTable';
|
import { AttachmentTable } from '../../tables/general/AttachmentTable';
|
||||||
|
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
|
||||||
import SalesOrderLineItemTable from '../../tables/sales/SalesOrderLineItemTable';
|
import SalesOrderLineItemTable from '../../tables/sales/SalesOrderLineItemTable';
|
||||||
import SalesOrderShipmentTable from '../../tables/sales/SalesOrderShipmentTable';
|
import SalesOrderShipmentTable from '../../tables/sales/SalesOrderShipmentTable';
|
||||||
|
|
||||||
@ -272,6 +275,20 @@ export default function SalesOrderDetail() {
|
|||||||
icon: <IconTruckDelivery />,
|
icon: <IconTruckDelivery />,
|
||||||
content: <SalesOrderShipmentTable orderId={order.pk} />
|
content: <SalesOrderShipmentTable orderId={order.pk} />
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'allocations',
|
||||||
|
label: t`Allocated Stock`,
|
||||||
|
icon: <IconBookmark />,
|
||||||
|
content: (
|
||||||
|
<SalesOrderAllocationTable
|
||||||
|
orderId={order.pk}
|
||||||
|
showPartInfo
|
||||||
|
allowEdit
|
||||||
|
modelField="item"
|
||||||
|
modelTarget={ModelType.stockitem}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'build-orders',
|
name: 'build-orders',
|
||||||
label: t`Build Orders`,
|
label: t`Build Orders`,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Grid, Skeleton, Stack } from '@mantine/core';
|
import { Accordion, Grid, Skeleton, Stack } from '@mantine/core';
|
||||||
import {
|
import {
|
||||||
IconBookmark,
|
IconBookmark,
|
||||||
IconBoxPadding,
|
IconBoxPadding,
|
||||||
@ -33,6 +33,7 @@ import {
|
|||||||
ViewBarcodeAction
|
ViewBarcodeAction
|
||||||
} from '../../components/items/ActionDropdown';
|
} from '../../components/items/ActionDropdown';
|
||||||
import { PlaceholderPanel } from '../../components/items/Placeholder';
|
import { PlaceholderPanel } from '../../components/items/Placeholder';
|
||||||
|
import { StylishText } from '../../components/items/StylishText';
|
||||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||||
import NavigationTree from '../../components/nav/NavigationTree';
|
import NavigationTree from '../../components/nav/NavigationTree';
|
||||||
import { PageDetail } from '../../components/nav/PageDetail';
|
import { PageDetail } from '../../components/nav/PageDetail';
|
||||||
@ -58,7 +59,9 @@ import {
|
|||||||
} from '../../hooks/UseForm';
|
} from '../../hooks/UseForm';
|
||||||
import { useInstance } from '../../hooks/UseInstance';
|
import { useInstance } from '../../hooks/UseInstance';
|
||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
|
import BuildAllocatedStockTable from '../../tables/build/BuildAllocatedStockTable';
|
||||||
import { AttachmentTable } from '../../tables/general/AttachmentTable';
|
import { AttachmentTable } from '../../tables/general/AttachmentTable';
|
||||||
|
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
|
||||||
import InstalledItemsTable from '../../tables/stock/InstalledItemsTable';
|
import InstalledItemsTable from '../../tables/stock/InstalledItemsTable';
|
||||||
import { StockItemTable } from '../../tables/stock/StockItemTable';
|
import { StockItemTable } from '../../tables/stock/StockItemTable';
|
||||||
import StockItemTestResultTable from '../../tables/stock/StockItemTestResultTable';
|
import StockItemTestResultTable from '../../tables/stock/StockItemTestResultTable';
|
||||||
@ -268,6 +271,19 @@ export default function StockDetail() {
|
|||||||
);
|
);
|
||||||
}, [stockitem, instanceQuery]);
|
}, [stockitem, instanceQuery]);
|
||||||
|
|
||||||
|
const showBuildAllocations = useMemo(() => {
|
||||||
|
// Determine if "build allocations" should be shown for this stock item
|
||||||
|
return (
|
||||||
|
stockitem?.part_detail?.component && // Must be a "component"
|
||||||
|
!stockitem?.sales_order && // Must not be assigned to a sales order
|
||||||
|
!stockitem?.belongs_to
|
||||||
|
); // Must not be installed into another item
|
||||||
|
}, [stockitem]);
|
||||||
|
|
||||||
|
const showSalesAlloctions = useMemo(() => {
|
||||||
|
return stockitem?.part_detail?.salable;
|
||||||
|
}, [stockitem]);
|
||||||
|
|
||||||
const stockPanels: PanelType[] = useMemo(() => {
|
const stockPanels: PanelType[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -290,10 +306,44 @@ export default function StockDetail() {
|
|||||||
name: 'allocations',
|
name: 'allocations',
|
||||||
label: t`Allocations`,
|
label: t`Allocations`,
|
||||||
icon: <IconBookmark />,
|
icon: <IconBookmark />,
|
||||||
hidden:
|
hidden: !showSalesAlloctions && !showBuildAllocations,
|
||||||
!stockitem?.part_detail?.salable &&
|
content: (
|
||||||
!stockitem?.part_detail?.component,
|
<Accordion
|
||||||
content: <PlaceholderPanel />
|
multiple={true}
|
||||||
|
defaultValue={['buildallocations', 'salesallocations']}
|
||||||
|
>
|
||||||
|
{showBuildAllocations && (
|
||||||
|
<Accordion.Item value="buildallocations" key="buildallocations">
|
||||||
|
<Accordion.Control>
|
||||||
|
<StylishText size="lg">{t`Build Order Allocations`}</StylishText>
|
||||||
|
</Accordion.Control>
|
||||||
|
<Accordion.Panel>
|
||||||
|
<BuildAllocatedStockTable
|
||||||
|
stockId={stockitem.pk}
|
||||||
|
modelField="build"
|
||||||
|
modelTarget={ModelType.build}
|
||||||
|
showBuildInfo
|
||||||
|
/>
|
||||||
|
</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
)}
|
||||||
|
{showSalesAlloctions && (
|
||||||
|
<Accordion.Item value="salesallocations" key="salesallocations">
|
||||||
|
<Accordion.Control>
|
||||||
|
<StylishText size="lg">{t`Sales Order Allocations`}</StylishText>
|
||||||
|
</Accordion.Control>
|
||||||
|
<Accordion.Panel>
|
||||||
|
<SalesOrderAllocationTable
|
||||||
|
stockId={stockitem.pk}
|
||||||
|
modelField="order"
|
||||||
|
modelTarget={ModelType.salesorder}
|
||||||
|
showOrderInfo
|
||||||
|
/>
|
||||||
|
</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
)}
|
||||||
|
</Accordion>
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'testdata',
|
name: 'testdata',
|
||||||
|
@ -164,17 +164,20 @@ export function StatusColumn({
|
|||||||
model,
|
model,
|
||||||
sortable,
|
sortable,
|
||||||
accessor,
|
accessor,
|
||||||
title
|
title,
|
||||||
|
hidden
|
||||||
}: {
|
}: {
|
||||||
model: ModelType;
|
model: ModelType;
|
||||||
sortable?: boolean;
|
sortable?: boolean;
|
||||||
accessor?: string;
|
accessor?: string;
|
||||||
|
hidden?: boolean;
|
||||||
title?: string;
|
title?: string;
|
||||||
}) {
|
}) {
|
||||||
return {
|
return {
|
||||||
accessor: accessor ?? 'status',
|
accessor: accessor ?? 'status',
|
||||||
sortable: sortable ?? true,
|
sortable: sortable ?? true,
|
||||||
title: title,
|
title: title,
|
||||||
|
hidden: hidden,
|
||||||
render: TableStatusRenderer(model, accessor ?? 'status')
|
render: TableStatusRenderer(model, accessor ?? 'status')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,16 @@ export function InvenTreeTable<T = any>({
|
|||||||
if (props.enableColumnSwitching == false) {
|
if (props.enableColumnSwitching == false) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return columns.some((col: TableColumn) => col.switchable ?? true);
|
return columns.some((col: TableColumn) => {
|
||||||
|
if (col.hidden == true) {
|
||||||
|
// Not a switchable column - is hidden
|
||||||
|
return false;
|
||||||
|
} else if (col.switchable == false) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [columns, props.enableColumnSwitching]);
|
}, [columns, props.enableColumnSwitching]);
|
||||||
|
|
||||||
@ -264,7 +273,9 @@ export function InvenTreeTable<T = any>({
|
|||||||
|
|
||||||
// Update column visibility when hiddenColumns change
|
// Update column visibility when hiddenColumns change
|
||||||
const dataColumns: any = useMemo(() => {
|
const dataColumns: any = useMemo(() => {
|
||||||
let cols = columns.map((col) => {
|
let cols = columns
|
||||||
|
.filter((col) => col?.hidden != true)
|
||||||
|
.map((col) => {
|
||||||
let hidden: boolean = col.hidden ?? false;
|
let hidden: boolean = col.hidden ?? false;
|
||||||
|
|
||||||
if (col.switchable ?? true) {
|
if (col.switchable ?? true) {
|
||||||
|
@ -12,7 +12,12 @@ import { useTable } from '../../hooks/UseTable';
|
|||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import { TableColumn } from '../Column';
|
import { TableColumn } from '../Column';
|
||||||
import { LocationColumn, PartColumn } from '../ColumnRenderers';
|
import {
|
||||||
|
LocationColumn,
|
||||||
|
PartColumn,
|
||||||
|
ReferenceColumn,
|
||||||
|
StatusColumn
|
||||||
|
} from '../ColumnRenderers';
|
||||||
import { TableFilter } from '../Filter';
|
import { TableFilter } from '../Filter';
|
||||||
import { InvenTreeTable } from '../InvenTreeTable';
|
import { InvenTreeTable } from '../InvenTreeTable';
|
||||||
import { RowDeleteAction, RowEditAction } from '../RowActions';
|
import { RowDeleteAction, RowEditAction } from '../RowActions';
|
||||||
@ -21,12 +26,26 @@ import { RowDeleteAction, RowEditAction } from '../RowActions';
|
|||||||
* Render a table of allocated stock for a build.
|
* Render a table of allocated stock for a build.
|
||||||
*/
|
*/
|
||||||
export default function BuildAllocatedStockTable({
|
export default function BuildAllocatedStockTable({
|
||||||
buildId
|
buildId,
|
||||||
|
stockId,
|
||||||
|
partId,
|
||||||
|
showBuildInfo,
|
||||||
|
showPartInfo,
|
||||||
|
allowEdit,
|
||||||
|
modelTarget,
|
||||||
|
modelField
|
||||||
}: {
|
}: {
|
||||||
buildId: number;
|
buildId?: number;
|
||||||
|
stockId?: number;
|
||||||
|
partId?: number;
|
||||||
|
showPartInfo?: boolean;
|
||||||
|
showBuildInfo?: boolean;
|
||||||
|
allowEdit?: boolean;
|
||||||
|
modelTarget?: ModelType;
|
||||||
|
modelField?: string;
|
||||||
}) {
|
}) {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable('build-allocated-stock');
|
const table = useTable('buildallocatedstock');
|
||||||
|
|
||||||
const tableFilters: TableFilter[] = useMemo(() => {
|
const tableFilters: TableFilter[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
@ -40,14 +59,33 @@ export default function BuildAllocatedStockTable({
|
|||||||
|
|
||||||
const tableColumns: TableColumn[] = useMemo(() => {
|
const tableColumns: TableColumn[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
|
ReferenceColumn({
|
||||||
|
accessor: 'build_detail.reference',
|
||||||
|
title: t`Build Order`,
|
||||||
|
switchable: false,
|
||||||
|
hidden: showBuildInfo != true
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
accessor: 'build_detail.title',
|
||||||
|
title: t`Description`,
|
||||||
|
hidden: showBuildInfo != true
|
||||||
|
},
|
||||||
|
StatusColumn({
|
||||||
|
accessor: 'build_detail.status',
|
||||||
|
model: ModelType.build,
|
||||||
|
title: t`Order Status`,
|
||||||
|
hidden: showBuildInfo != true
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
accessor: 'part',
|
accessor: 'part',
|
||||||
|
hidden: !showPartInfo,
|
||||||
title: t`Part`,
|
title: t`Part`,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
switchable: false,
|
switchable: false,
|
||||||
render: (record: any) => PartColumn(record.part_detail)
|
render: (record: any) => PartColumn(record.part_detail)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
hidden: !showPartInfo,
|
||||||
accessor: 'bom_reference',
|
accessor: 'bom_reference',
|
||||||
title: t`Reference`,
|
title: t`Reference`,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
@ -149,18 +187,21 @@ export default function BuildAllocatedStockTable({
|
|||||||
props={{
|
props={{
|
||||||
params: {
|
params: {
|
||||||
build: buildId,
|
build: buildId,
|
||||||
part_detail: true,
|
part: partId,
|
||||||
|
stock_item: stockId,
|
||||||
|
build_detail: showBuildInfo ?? false,
|
||||||
|
part_detail: showPartInfo ?? false,
|
||||||
location_detail: true,
|
location_detail: true,
|
||||||
stock_detail: true,
|
stock_detail: true,
|
||||||
supplier_detail: true
|
supplier_detail: true
|
||||||
},
|
},
|
||||||
enableBulkDelete: user.hasDeleteRole(UserRoles.build),
|
enableBulkDelete: allowEdit && user.hasDeleteRole(UserRoles.build),
|
||||||
enableDownload: true,
|
enableDownload: true,
|
||||||
enableSelection: true,
|
enableSelection: allowEdit && user.hasDeleteRole(UserRoles.build),
|
||||||
rowActions: rowActions,
|
rowActions: rowActions,
|
||||||
tableFilters: tableFilters,
|
tableFilters: tableFilters,
|
||||||
modelField: 'stock_item',
|
modelField: modelField ?? 'stock_item',
|
||||||
modelType: ModelType.stockitem
|
modelType: modelTarget ?? ModelType.stockitem
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
135
src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx
Normal file
135
src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
|
import { ModelType } from '../../enums/ModelType';
|
||||||
|
import { useTable } from '../../hooks/UseTable';
|
||||||
|
import { apiUrl } from '../../states/ApiState';
|
||||||
|
import { useUserState } from '../../states/UserState';
|
||||||
|
import { TableColumn } from '../Column';
|
||||||
|
import {
|
||||||
|
LocationColumn,
|
||||||
|
PartColumn,
|
||||||
|
ReferenceColumn,
|
||||||
|
StatusColumn
|
||||||
|
} from '../ColumnRenderers';
|
||||||
|
import { TableFilter } from '../Filter';
|
||||||
|
import { InvenTreeTable } from '../InvenTreeTable';
|
||||||
|
|
||||||
|
export default function SalesOrderAllocationTable({
|
||||||
|
partId,
|
||||||
|
stockId,
|
||||||
|
orderId,
|
||||||
|
showPartInfo,
|
||||||
|
showOrderInfo,
|
||||||
|
allowEdit,
|
||||||
|
modelTarget,
|
||||||
|
modelField
|
||||||
|
}: {
|
||||||
|
partId?: number;
|
||||||
|
stockId?: number;
|
||||||
|
orderId?: number;
|
||||||
|
showPartInfo?: boolean;
|
||||||
|
showOrderInfo?: boolean;
|
||||||
|
allowEdit?: boolean;
|
||||||
|
modelTarget?: ModelType;
|
||||||
|
modelField?: string;
|
||||||
|
}) {
|
||||||
|
const user = useUserState();
|
||||||
|
const table = useTable('salesorderallocations');
|
||||||
|
|
||||||
|
const tableFilters: TableFilter[] = useMemo(() => {
|
||||||
|
return [];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const tableColumns: TableColumn[] = useMemo(() => {
|
||||||
|
return [
|
||||||
|
ReferenceColumn({
|
||||||
|
accessor: 'order_detail.reference',
|
||||||
|
title: t`Sales Order`,
|
||||||
|
switchable: false,
|
||||||
|
hidden: showOrderInfo != true
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
accessor: 'order_detail.description',
|
||||||
|
title: t`Description`,
|
||||||
|
hidden: showOrderInfo != true
|
||||||
|
},
|
||||||
|
StatusColumn({
|
||||||
|
accessor: 'order_detail.status',
|
||||||
|
model: ModelType.salesorder,
|
||||||
|
title: t`Order Status`,
|
||||||
|
hidden: showOrderInfo != true
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
accessor: 'part',
|
||||||
|
hidden: showPartInfo != true,
|
||||||
|
title: t`Part`,
|
||||||
|
sortable: true,
|
||||||
|
switchable: false,
|
||||||
|
render: (record: any) => PartColumn(record.part_detail)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: 'quantity',
|
||||||
|
title: t`Allocated Quantity`,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: 'serial',
|
||||||
|
title: t`Serial Number`,
|
||||||
|
sortable: false,
|
||||||
|
switchable: true,
|
||||||
|
render: (record: any) => record?.item_detail?.serial
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: 'batch',
|
||||||
|
title: t`Batch Code`,
|
||||||
|
sortable: false,
|
||||||
|
switchable: true,
|
||||||
|
render: (record: any) => record?.item_detail?.batch
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: 'available',
|
||||||
|
title: t`Available Quantity`,
|
||||||
|
render: (record: any) => record?.item_detail?.quantity
|
||||||
|
},
|
||||||
|
LocationColumn({
|
||||||
|
accessor: 'location_detail',
|
||||||
|
switchable: true,
|
||||||
|
sortable: true
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const rowActions = useCallback(
|
||||||
|
(record: any) => {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
[user]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<InvenTreeTable
|
||||||
|
url={apiUrl(ApiEndpoints.sales_order_allocation_list)}
|
||||||
|
tableState={table}
|
||||||
|
columns={tableColumns}
|
||||||
|
props={{
|
||||||
|
params: {
|
||||||
|
part_detail: showPartInfo ?? false,
|
||||||
|
order_detail: showOrderInfo ?? false,
|
||||||
|
item_detail: true,
|
||||||
|
location_detail: true,
|
||||||
|
part: partId,
|
||||||
|
order: orderId,
|
||||||
|
stock_item: stockId
|
||||||
|
},
|
||||||
|
rowActions: rowActions,
|
||||||
|
tableFilters: tableFilters,
|
||||||
|
modelField: modelField ?? 'order',
|
||||||
|
modelType: modelTarget ?? ModelType.salesorder
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user