mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-11-04 07:05:41 +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:
		@@ -141,6 +141,7 @@ export enum ApiEndpoints {
 | 
			
		||||
  sales_order_ship = 'order/so/:id/ship/',
 | 
			
		||||
  sales_order_complete = 'order/so/:id/complete/',
 | 
			
		||||
  sales_order_line_list = 'order/so-line/',
 | 
			
		||||
  sales_order_allocation_list = 'order/so-allocation/',
 | 
			
		||||
  sales_order_shipment_list = 'order/so/shipment/',
 | 
			
		||||
 | 
			
		||||
  return_order_list = 'order/ro/',
 | 
			
		||||
 
 | 
			
		||||
@@ -283,7 +283,7 @@ export default function BuildDetail() {
 | 
			
		||||
        label: t`Allocated Stock`,
 | 
			
		||||
        icon: <IconList />,
 | 
			
		||||
        content: build.pk ? (
 | 
			
		||||
          <BuildAllocatedStockTable buildId={build.pk} />
 | 
			
		||||
          <BuildAllocatedStockTable buildId={build.pk} showPartInfo allowEdit />
 | 
			
		||||
        ) : (
 | 
			
		||||
          <Skeleton />
 | 
			
		||||
        )
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,13 @@
 | 
			
		||||
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 {
 | 
			
		||||
  IconBookmarks,
 | 
			
		||||
  IconBuilding,
 | 
			
		||||
@@ -48,6 +56,7 @@ import {
 | 
			
		||||
  ViewBarcodeAction
 | 
			
		||||
} from '../../components/items/ActionDropdown';
 | 
			
		||||
import { PlaceholderPanel } from '../../components/items/Placeholder';
 | 
			
		||||
import { StylishText } from '../../components/items/StylishText';
 | 
			
		||||
import InstanceDetail from '../../components/nav/InstanceDetail';
 | 
			
		||||
import NavigationTree from '../../components/nav/NavigationTree';
 | 
			
		||||
import { PageDetail } from '../../components/nav/PageDetail';
 | 
			
		||||
@@ -76,6 +85,7 @@ import { useGlobalSettingsState } from '../../states/SettingsState';
 | 
			
		||||
import { useUserState } from '../../states/UserState';
 | 
			
		||||
import { BomTable } from '../../tables/bom/BomTable';
 | 
			
		||||
import { UsedInTable } from '../../tables/bom/UsedInTable';
 | 
			
		||||
import BuildAllocatedStockTable from '../../tables/build/BuildAllocatedStockTable';
 | 
			
		||||
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
 | 
			
		||||
import { AttachmentTable } from '../../tables/general/AttachmentTable';
 | 
			
		||||
import { PartParameterTable } from '../../tables/part/PartParameterTable';
 | 
			
		||||
@@ -84,6 +94,7 @@ import { PartVariantTable } from '../../tables/part/PartVariantTable';
 | 
			
		||||
import { RelatedPartTable } from '../../tables/part/RelatedPartTable';
 | 
			
		||||
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
 | 
			
		||||
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
 | 
			
		||||
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
 | 
			
		||||
import { SalesOrderTable } from '../../tables/sales/SalesOrderTable';
 | 
			
		||||
import { StockItemTable } from '../../tables/stock/StockItemTable';
 | 
			
		||||
import { TestStatisticsTable } from '../../tables/stock/TestStatisticsTable';
 | 
			
		||||
@@ -539,7 +550,43 @@ export default function PartDetail() {
 | 
			
		||||
        label: t`Allocations`,
 | 
			
		||||
        icon: <IconBookmarks />,
 | 
			
		||||
        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',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
import { t } from '@lingui/macro';
 | 
			
		||||
import { Grid, Skeleton, Stack } from '@mantine/core';
 | 
			
		||||
import {
 | 
			
		||||
  IconBook,
 | 
			
		||||
  IconBookmark,
 | 
			
		||||
  IconDots,
 | 
			
		||||
  IconInfoCircle,
 | 
			
		||||
  IconList,
 | 
			
		||||
@@ -49,6 +51,7 @@ import { apiUrl } from '../../states/ApiState';
 | 
			
		||||
import { useUserState } from '../../states/UserState';
 | 
			
		||||
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
 | 
			
		||||
import { AttachmentTable } from '../../tables/general/AttachmentTable';
 | 
			
		||||
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
 | 
			
		||||
import SalesOrderLineItemTable from '../../tables/sales/SalesOrderLineItemTable';
 | 
			
		||||
import SalesOrderShipmentTable from '../../tables/sales/SalesOrderShipmentTable';
 | 
			
		||||
 | 
			
		||||
@@ -272,6 +275,20 @@ export default function SalesOrderDetail() {
 | 
			
		||||
        icon: <IconTruckDelivery />,
 | 
			
		||||
        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',
 | 
			
		||||
        label: t`Build Orders`,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import { t } from '@lingui/macro';
 | 
			
		||||
import { Grid, Skeleton, Stack } from '@mantine/core';
 | 
			
		||||
import { Accordion, Grid, Skeleton, Stack } from '@mantine/core';
 | 
			
		||||
import {
 | 
			
		||||
  IconBookmark,
 | 
			
		||||
  IconBoxPadding,
 | 
			
		||||
@@ -33,6 +33,7 @@ import {
 | 
			
		||||
  ViewBarcodeAction
 | 
			
		||||
} from '../../components/items/ActionDropdown';
 | 
			
		||||
import { PlaceholderPanel } from '../../components/items/Placeholder';
 | 
			
		||||
import { StylishText } from '../../components/items/StylishText';
 | 
			
		||||
import InstanceDetail from '../../components/nav/InstanceDetail';
 | 
			
		||||
import NavigationTree from '../../components/nav/NavigationTree';
 | 
			
		||||
import { PageDetail } from '../../components/nav/PageDetail';
 | 
			
		||||
@@ -58,7 +59,9 @@ import {
 | 
			
		||||
} from '../../hooks/UseForm';
 | 
			
		||||
import { useInstance } from '../../hooks/UseInstance';
 | 
			
		||||
import { useUserState } from '../../states/UserState';
 | 
			
		||||
import BuildAllocatedStockTable from '../../tables/build/BuildAllocatedStockTable';
 | 
			
		||||
import { AttachmentTable } from '../../tables/general/AttachmentTable';
 | 
			
		||||
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
 | 
			
		||||
import InstalledItemsTable from '../../tables/stock/InstalledItemsTable';
 | 
			
		||||
import { StockItemTable } from '../../tables/stock/StockItemTable';
 | 
			
		||||
import StockItemTestResultTable from '../../tables/stock/StockItemTestResultTable';
 | 
			
		||||
@@ -268,6 +271,19 @@ export default function StockDetail() {
 | 
			
		||||
    );
 | 
			
		||||
  }, [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(() => {
 | 
			
		||||
    return [
 | 
			
		||||
      {
 | 
			
		||||
@@ -290,10 +306,44 @@ export default function StockDetail() {
 | 
			
		||||
        name: 'allocations',
 | 
			
		||||
        label: t`Allocations`,
 | 
			
		||||
        icon: <IconBookmark />,
 | 
			
		||||
        hidden:
 | 
			
		||||
          !stockitem?.part_detail?.salable &&
 | 
			
		||||
          !stockitem?.part_detail?.component,
 | 
			
		||||
        content: <PlaceholderPanel />
 | 
			
		||||
        hidden: !showSalesAlloctions && !showBuildAllocations,
 | 
			
		||||
        content: (
 | 
			
		||||
          <Accordion
 | 
			
		||||
            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',
 | 
			
		||||
 
 | 
			
		||||
@@ -164,17 +164,20 @@ export function StatusColumn({
 | 
			
		||||
  model,
 | 
			
		||||
  sortable,
 | 
			
		||||
  accessor,
 | 
			
		||||
  title
 | 
			
		||||
  title,
 | 
			
		||||
  hidden
 | 
			
		||||
}: {
 | 
			
		||||
  model: ModelType;
 | 
			
		||||
  sortable?: boolean;
 | 
			
		||||
  accessor?: string;
 | 
			
		||||
  hidden?: boolean;
 | 
			
		||||
  title?: string;
 | 
			
		||||
}) {
 | 
			
		||||
  return {
 | 
			
		||||
    accessor: accessor ?? 'status',
 | 
			
		||||
    sortable: sortable ?? true,
 | 
			
		||||
    title: title,
 | 
			
		||||
    hidden: hidden,
 | 
			
		||||
    render: TableStatusRenderer(model, accessor ?? 'status')
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -251,7 +251,16 @@ export function InvenTreeTable<T = any>({
 | 
			
		||||
    if (props.enableColumnSwitching == false) {
 | 
			
		||||
      return false;
 | 
			
		||||
    } 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]);
 | 
			
		||||
 | 
			
		||||
@@ -264,7 +273,9 @@ export function InvenTreeTable<T = any>({
 | 
			
		||||
 | 
			
		||||
  // Update column visibility when hiddenColumns change
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
        if (col.switchable ?? true) {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,12 @@ import { useTable } from '../../hooks/UseTable';
 | 
			
		||||
import { apiUrl } from '../../states/ApiState';
 | 
			
		||||
import { useUserState } from '../../states/UserState';
 | 
			
		||||
import { TableColumn } from '../Column';
 | 
			
		||||
import { LocationColumn, PartColumn } from '../ColumnRenderers';
 | 
			
		||||
import {
 | 
			
		||||
  LocationColumn,
 | 
			
		||||
  PartColumn,
 | 
			
		||||
  ReferenceColumn,
 | 
			
		||||
  StatusColumn
 | 
			
		||||
} from '../ColumnRenderers';
 | 
			
		||||
import { TableFilter } from '../Filter';
 | 
			
		||||
import { InvenTreeTable } from '../InvenTreeTable';
 | 
			
		||||
import { RowDeleteAction, RowEditAction } from '../RowActions';
 | 
			
		||||
@@ -21,12 +26,26 @@ import { RowDeleteAction, RowEditAction } from '../RowActions';
 | 
			
		||||
 * Render a table of allocated stock for a build.
 | 
			
		||||
 */
 | 
			
		||||
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 table = useTable('build-allocated-stock');
 | 
			
		||||
  const table = useTable('buildallocatedstock');
 | 
			
		||||
 | 
			
		||||
  const tableFilters: TableFilter[] = useMemo(() => {
 | 
			
		||||
    return [
 | 
			
		||||
@@ -40,14 +59,33 @@ export default function BuildAllocatedStockTable({
 | 
			
		||||
 | 
			
		||||
  const tableColumns: TableColumn[] = useMemo(() => {
 | 
			
		||||
    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',
 | 
			
		||||
        hidden: !showPartInfo,
 | 
			
		||||
        title: t`Part`,
 | 
			
		||||
        sortable: true,
 | 
			
		||||
        switchable: false,
 | 
			
		||||
        render: (record: any) => PartColumn(record.part_detail)
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        hidden: !showPartInfo,
 | 
			
		||||
        accessor: 'bom_reference',
 | 
			
		||||
        title: t`Reference`,
 | 
			
		||||
        sortable: true,
 | 
			
		||||
@@ -149,18 +187,21 @@ export default function BuildAllocatedStockTable({
 | 
			
		||||
        props={{
 | 
			
		||||
          params: {
 | 
			
		||||
            build: buildId,
 | 
			
		||||
            part_detail: true,
 | 
			
		||||
            part: partId,
 | 
			
		||||
            stock_item: stockId,
 | 
			
		||||
            build_detail: showBuildInfo ?? false,
 | 
			
		||||
            part_detail: showPartInfo ?? false,
 | 
			
		||||
            location_detail: true,
 | 
			
		||||
            stock_detail: true,
 | 
			
		||||
            supplier_detail: true
 | 
			
		||||
          },
 | 
			
		||||
          enableBulkDelete: user.hasDeleteRole(UserRoles.build),
 | 
			
		||||
          enableBulkDelete: allowEdit && user.hasDeleteRole(UserRoles.build),
 | 
			
		||||
          enableDownload: true,
 | 
			
		||||
          enableSelection: true,
 | 
			
		||||
          enableSelection: allowEdit && user.hasDeleteRole(UserRoles.build),
 | 
			
		||||
          rowActions: rowActions,
 | 
			
		||||
          tableFilters: tableFilters,
 | 
			
		||||
          modelField: 'stock_item',
 | 
			
		||||
          modelType: ModelType.stockitem
 | 
			
		||||
          modelField: modelField ?? 'stock_item',
 | 
			
		||||
          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
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user