mirror of
https://github.com/inventree/InvenTree.git
synced 2025-10-24 01:47:39 +00:00
Merge branch 'master' into filtered-testing
This commit is contained in:
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Added much more detailed status information for machines to the API endpoint (including backend and frontend changes) in [#10381](https://github.com/inventree/InvenTree/pull/10381)
|
||||
- Added ability to partially complete and partially scrap build outputs in [#10499](https://github.com/inventree/InvenTree/pull/10499)
|
||||
- Added support for Redis ACL user-based authentication in [#10551](https://github.com/inventree/InvenTree/pull/10551)
|
||||
- Expose stock adjustment forms to the UI plugin context in [#10584](https://github.com/inventree/InvenTree/pull/10584)
|
||||
- Allow stock adjustments for "in production" items in [#10600](https://github.com/inventree/InvenTree/pull/10600)
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 408
|
||||
INVENTREE_API_VERSION = 409
|
||||
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v409 -> 2025-10-17 : https://github.com/inventree/InvenTree/pull/10601
|
||||
- Adds ability to filter StockList API by manufacturer part ID
|
||||
|
||||
v408 -> 2025-10-13: https://github.com/inventree/InvenTree/pull/10561
|
||||
- Allow search of assembly fields in BOM API endpoint
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import InvenTree.permissions
|
||||
import stock.serializers as StockSerializers
|
||||
from build.models import Build
|
||||
from build.serializers import BuildSerializer
|
||||
from company.models import Company, SupplierPart
|
||||
from company.models import Company, ManufacturerPart, SupplierPart
|
||||
from company.serializers import CompanySerializer
|
||||
from data_exporter.mixins import DataExportViewMixin
|
||||
from generic.states.api import StatusView
|
||||
@@ -553,6 +553,12 @@ class StockFilter(FilterSet):
|
||||
& Q(supplier_part__manufacturer_part__manufacturer=company)
|
||||
)
|
||||
|
||||
manufacturer_part = rest_filters.ModelChoiceFilter(
|
||||
label=_('Manufacturer Part'),
|
||||
queryset=ManufacturerPart.objects.all(),
|
||||
field_name='supplier_part__manufacturer_part',
|
||||
)
|
||||
|
||||
supplier = rest_filters.ModelChoiceFilter(
|
||||
label=_('Supplier'),
|
||||
queryset=Company.objects.filter(is_supplier=True),
|
||||
|
||||
@@ -1743,7 +1743,6 @@ class StockItem(
|
||||
self.belongs_to is None, # Not installed inside another StockItem
|
||||
self.customer is None, # Not assigned to a customer
|
||||
self.consumed_by is None, # Not consumed by a build
|
||||
not self.is_building, # Not part of an active build
|
||||
])
|
||||
|
||||
@property
|
||||
@@ -2221,7 +2220,6 @@ class StockItem(
|
||||
- The new item will have a different StockItem ID, while this will remain the same.
|
||||
"""
|
||||
# Run initial checks to test if the stock item can actually be "split"
|
||||
|
||||
allow_production = kwargs.get('allow_production', False)
|
||||
|
||||
# Cannot split a stock item which is in production
|
||||
@@ -2346,7 +2344,9 @@ class StockItem(
|
||||
'STOCK_ALLOW_OUT_OF_STOCK_TRANSFER', backup_value=False, cache=False
|
||||
)
|
||||
|
||||
if not allow_out_of_stock_transfer and not self.is_in_stock(check_status=False):
|
||||
if not allow_out_of_stock_transfer and not self.is_in_stock(
|
||||
check_status=False, check_in_production=False
|
||||
):
|
||||
raise ValidationError(_('StockItem cannot be moved as it is not in stock'))
|
||||
|
||||
if quantity <= 0:
|
||||
@@ -2362,7 +2362,7 @@ class StockItem(
|
||||
kwargs['notes'] = notes
|
||||
|
||||
# Split the existing StockItem in two
|
||||
self.splitStock(quantity, location, user, **kwargs)
|
||||
self.splitStock(quantity, location, user, allow_production=True, **kwargs)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -1554,7 +1554,7 @@ class StockAdjustmentItemSerializer(serializers.Serializer):
|
||||
)
|
||||
|
||||
if not allow_out_of_stock_transfer and not stock_item.is_in_stock(
|
||||
check_status=False, check_quantity=False
|
||||
check_status=False, check_quantity=False, check_in_production=False
|
||||
):
|
||||
raise ValidationError(_('Stock item is not in stock'))
|
||||
elif self.require_in_stock == False:
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
This file contains historical changelog information for the InvenTree UI components library.
|
||||
|
||||
### 0.7.0 - October 2025
|
||||
|
||||
Exposes stock adjustment forms to plugins, allowing plugins to adjust stock adjustments using the common InvenTree UI form components.
|
||||
|
||||
### 0.6.0 - September 2025
|
||||
|
||||
Updated underlying Mantine library versions.
|
||||
|
||||
### 0.5.0 - August 2025
|
||||
|
||||
This release updates the base `react` major version from `18.3.1` to `19.1.1`. This change may introduce breaking changes for plugins that rely on the InvenTree UI components library (plugin developers should test their plugins against this new version).
|
||||
|
||||
@@ -12,7 +12,12 @@ export { ModelType } from './enums/ModelType';
|
||||
export type { ModelDict } from './enums/ModelInformation';
|
||||
export { UserRoles, UserPermissions } from './enums/Roles';
|
||||
|
||||
export type { InvenTreePluginContext } from './types/Plugins';
|
||||
export type {
|
||||
InvenTreePluginContext,
|
||||
InvenTreeFormsContext,
|
||||
PluginVersion,
|
||||
StockAdjustmentFormsContext
|
||||
} from './types/Plugins';
|
||||
export type { RowAction, RowViewProps } from './types/Tables';
|
||||
|
||||
export type {
|
||||
@@ -25,6 +30,11 @@ export type {
|
||||
BulkEditApiFormModalProps
|
||||
} from './types/Forms';
|
||||
|
||||
export type {
|
||||
UseModalProps,
|
||||
UseModalReturn
|
||||
} from './types/Modals';
|
||||
|
||||
// Common utility functions
|
||||
export { apiUrl } from './functions/Api';
|
||||
export {
|
||||
|
||||
@@ -191,3 +191,11 @@ export interface ApiFormModalProps extends ApiFormProps {
|
||||
export interface BulkEditApiFormModalProps extends ApiFormModalProps {
|
||||
items: number[];
|
||||
}
|
||||
|
||||
export type StockOperationProps = {
|
||||
items?: any[];
|
||||
pk?: number;
|
||||
filters?: any;
|
||||
model: ModelType.stockitem | 'location' | ModelType.part;
|
||||
refresh: () => void;
|
||||
};
|
||||
|
||||
@@ -5,7 +5,11 @@ import type { AxiosInstance } from 'axios';
|
||||
import type { NavigateFunction } from 'react-router-dom';
|
||||
import type { ModelDict } from '../enums/ModelInformation';
|
||||
import type { ModelType } from '../enums/ModelType';
|
||||
import type { ApiFormModalProps, BulkEditApiFormModalProps } from './Forms';
|
||||
import type {
|
||||
ApiFormModalProps,
|
||||
BulkEditApiFormModalProps,
|
||||
StockOperationProps
|
||||
} from './Forms';
|
||||
import type { UseModalReturn } from './Modals';
|
||||
import type { RenderInstanceProps } from './Rendering';
|
||||
import type { SettingsStateProps } from './Settings';
|
||||
@@ -24,11 +28,24 @@ export interface PluginVersion {
|
||||
mantine: string;
|
||||
}
|
||||
|
||||
export type StockAdjustmentFormsContext = {
|
||||
addStock: (props: StockOperationProps) => UseModalReturn;
|
||||
assignStock: (props: StockOperationProps) => UseModalReturn;
|
||||
changeStatus: (props: StockOperationProps) => UseModalReturn;
|
||||
countStock: (props: StockOperationProps) => UseModalReturn;
|
||||
deleteStock: (props: StockOperationProps) => UseModalReturn;
|
||||
mergeStock: (props: StockOperationProps) => UseModalReturn;
|
||||
removeStock: (props: StockOperationProps) => UseModalReturn;
|
||||
transferStock: (props: StockOperationProps) => UseModalReturn;
|
||||
returnStock: (props: StockOperationProps) => UseModalReturn;
|
||||
};
|
||||
|
||||
export type InvenTreeFormsContext = {
|
||||
bulkEdit: (props: BulkEditApiFormModalProps) => UseModalReturn;
|
||||
create: (props: ApiFormModalProps) => UseModalReturn;
|
||||
delete: (props: ApiFormModalProps) => UseModalReturn;
|
||||
edit: (props: ApiFormModalProps) => UseModalReturn;
|
||||
stockActions: StockAdjustmentFormsContext;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@inventreedb/ui",
|
||||
"description": "UI components for the InvenTree project",
|
||||
"version": "0.6.0",
|
||||
"version": "0.7.0",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -24,14 +24,17 @@ export function BuiltinQueryCountWidgets(): DashboardWidgetProps[] {
|
||||
title: t`Subscribed Parts`,
|
||||
description: t`Show the number of parts which you have subscribed to`,
|
||||
modelType: ModelType.part,
|
||||
params: { starred: true }
|
||||
params: { starred: true, active: true }
|
||||
}),
|
||||
QueryCountDashboardWidget({
|
||||
label: 'sub-cat',
|
||||
title: t`Subscribed Categories`,
|
||||
description: t`Show the number of part categories which you have subscribed to`,
|
||||
modelType: ModelType.partcategory,
|
||||
params: { starred: true }
|
||||
params: {
|
||||
starred: true,
|
||||
top_level: 'none'
|
||||
}
|
||||
}),
|
||||
QueryCountDashboardWidget({
|
||||
label: 'invalid-bom',
|
||||
|
||||
@@ -18,6 +18,17 @@ import {
|
||||
type InvenTreePluginContext
|
||||
} from '@lib/types/Plugins';
|
||||
import { i18n } from '@lingui/core';
|
||||
import {
|
||||
useAddStockItem,
|
||||
useAssignStockItem,
|
||||
useChangeStockStatus,
|
||||
useCountStockItem,
|
||||
useDeleteStockItem,
|
||||
useMergeStockItem,
|
||||
useRemoveStockItem,
|
||||
useReturnStockItem,
|
||||
useTransferStockItem
|
||||
} from '../../forms/StockForms';
|
||||
import {
|
||||
useBulkEditApiFormModal,
|
||||
useCreateApiFormModal,
|
||||
@@ -60,7 +71,18 @@ export const useInvenTreeContext = () => {
|
||||
bulkEdit: useBulkEditApiFormModal,
|
||||
create: useCreateApiFormModal,
|
||||
delete: useDeleteApiFormModal,
|
||||
edit: useEditApiFormModal
|
||||
edit: useEditApiFormModal,
|
||||
stockActions: {
|
||||
addStock: useAddStockItem,
|
||||
assignStock: useAssignStockItem,
|
||||
changeStatus: useChangeStockStatus,
|
||||
countStock: useCountStockItem,
|
||||
deleteStock: useDeleteStockItem,
|
||||
mergeStock: useMergeStockItem,
|
||||
removeStock: useRemoveStockItem,
|
||||
transferStock: useTransferStockItem,
|
||||
returnStock: useReturnStockItem
|
||||
}
|
||||
}
|
||||
};
|
||||
}, [
|
||||
|
||||
@@ -37,7 +37,8 @@ import type {
|
||||
ApiFormAdjustFilterType,
|
||||
ApiFormFieldChoice,
|
||||
ApiFormFieldSet,
|
||||
ApiFormModalProps
|
||||
ApiFormModalProps,
|
||||
StockOperationProps
|
||||
} from '@lib/types/Forms';
|
||||
import {
|
||||
TableFieldExtraRow,
|
||||
@@ -711,6 +712,9 @@ function stockTransferFields(items: any[]): ApiFormFieldSet {
|
||||
|
||||
const records = Object.fromEntries(items.map((item) => [item.pk, item]));
|
||||
|
||||
// Extract all location values from the items
|
||||
const locations = [...new Set(items.map((item) => item.location))];
|
||||
|
||||
const fields: ApiFormFieldSet = {
|
||||
items: {
|
||||
field_type: 'table',
|
||||
@@ -739,6 +743,7 @@ function stockTransferFields(items: any[]): ApiFormFieldSet {
|
||||
]
|
||||
},
|
||||
location: {
|
||||
value: locations.length === 1 ? locations[0] : undefined,
|
||||
filters: {
|
||||
structural: false
|
||||
}
|
||||
@@ -1172,14 +1177,6 @@ function useStockOperationModal({
|
||||
});
|
||||
}
|
||||
|
||||
export type StockOperationProps = {
|
||||
items?: any[];
|
||||
pk?: number;
|
||||
filters?: any;
|
||||
model: ModelType.stockitem | 'location' | ModelType.part;
|
||||
refresh: () => void;
|
||||
};
|
||||
|
||||
export function useAddStockItem(props: StockOperationProps) {
|
||||
return useStockOperationModal({
|
||||
...props,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { UserRoles } from '@lib/index';
|
||||
import type { StockOperationProps } from '@lib/types/Forms';
|
||||
import type { UseModalReturn } from '@lib/types/Modals';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { type ReactNode, useMemo } from 'react';
|
||||
import type { ActionDropdownItem } from '../components/items/ActionDropdown';
|
||||
import { ActionDropdown } from '../components/items/ActionDropdown';
|
||||
import {
|
||||
type StockOperationProps,
|
||||
useAddStockItem,
|
||||
useAssignStockItem,
|
||||
useChangeStockStatus,
|
||||
@@ -54,8 +54,8 @@ export function useStockAdjustActions(
|
||||
// The available modals for stock adjustment actions
|
||||
const addStock = useAddStockItem(props.formProps);
|
||||
const assignStock = useAssignStockItem(props.formProps);
|
||||
const countStock = useCountStockItem(props.formProps);
|
||||
const changeStatus = useChangeStockStatus(props.formProps);
|
||||
const countStock = useCountStockItem(props.formProps);
|
||||
const deleteStock = useDeleteStockItem(props.formProps);
|
||||
const mergeStock = useMergeStockItem(props.formProps);
|
||||
const removeStock = useRemoveStockItem(props.formProps);
|
||||
|
||||
@@ -679,6 +679,7 @@ export default function BuildDetail() {
|
||||
<PrintingActions
|
||||
modelType={ModelType.build}
|
||||
items={[build.pk]}
|
||||
enableLabels
|
||||
enableReports
|
||||
/>,
|
||||
<OptionsActionDropdown
|
||||
|
||||
@@ -197,7 +197,7 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
|
||||
icon: <IconBuildingWarehouse />,
|
||||
hidden: !company?.is_manufacturer,
|
||||
content: company?.pk && (
|
||||
<ManufacturerPartTable params={{ manufacturer: company.pk }} />
|
||||
<ManufacturerPartTable manufacturerId={company.pk} />
|
||||
)
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@ import { Grid, Skeleton, Stack } from '@mantine/core';
|
||||
import {
|
||||
IconBuildingWarehouse,
|
||||
IconInfoCircle,
|
||||
IconList
|
||||
IconList,
|
||||
IconPackages
|
||||
} from '@tabler/icons-react';
|
||||
import { useMemo } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
@@ -42,6 +43,7 @@ import { useInstance } from '../../hooks/UseInstance';
|
||||
import { useUserState } from '../../states/UserState';
|
||||
import ManufacturerPartParameterTable from '../../tables/purchasing/ManufacturerPartParameterTable';
|
||||
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
|
||||
import { StockItemTable } from '../../tables/stock/StockItemTable';
|
||||
|
||||
export default function ManufacturerPartDetail() {
|
||||
const { id } = useParams();
|
||||
@@ -171,6 +173,20 @@ export default function ManufacturerPartDetail() {
|
||||
<Skeleton />
|
||||
)
|
||||
},
|
||||
{
|
||||
name: 'stock',
|
||||
label: t`Received Stock`,
|
||||
hidden: !user.hasViewRole(UserRoles.stock),
|
||||
icon: <IconPackages />,
|
||||
content: (
|
||||
<StockItemTable
|
||||
tableName='manufacturer-part-stock'
|
||||
params={{
|
||||
manufacturer_part: id
|
||||
}}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: 'suppliers',
|
||||
label: t`Suppliers`,
|
||||
@@ -194,7 +210,7 @@ export default function ManufacturerPartDetail() {
|
||||
model_id: manufacturerPart?.pk
|
||||
})
|
||||
];
|
||||
}, [manufacturerPart]);
|
||||
}, [user, manufacturerPart]);
|
||||
|
||||
const editManufacturerPartFields = useManufacturerPartFields();
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ import { UserRoles } from '@lib/enums/Roles';
|
||||
import { apiUrl } from '@lib/functions/Api';
|
||||
import { getDetailUrl } from '@lib/functions/Navigation';
|
||||
import { ActionButton } from '@lib/index';
|
||||
import type { ApiFormFieldSet } from '@lib/types/Forms';
|
||||
import type { ApiFormFieldSet, StockOperationProps } from '@lib/types/Forms';
|
||||
import AdminButton from '../../components/buttons/AdminButton';
|
||||
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
||||
import StarredToggleButton from '../../components/buttons/StarredToggleButton';
|
||||
@@ -80,10 +80,7 @@ import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';
|
||||
import { useApi } from '../../contexts/ApiContext';
|
||||
import { formatDecimal, formatPriceRange } from '../../defaults/formatters';
|
||||
import { usePartFields } from '../../forms/PartForms';
|
||||
import {
|
||||
type StockOperationProps,
|
||||
useFindSerialNumberForm
|
||||
} from '../../forms/StockForms';
|
||||
import { useFindSerialNumberForm } from '../../forms/StockForms';
|
||||
import {
|
||||
useApiFormModal,
|
||||
useCreateApiFormModal,
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function PartSupplierDetail({
|
||||
<StylishText size='lg'>{t`Manufacturers`}</StylishText>
|
||||
</Accordion.Control>
|
||||
<Accordion.Panel>
|
||||
<ManufacturerPartTable params={{ part: partId }} />
|
||||
<ManufacturerPartTable partId={partId} />
|
||||
</Accordion.Panel>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
|
||||
@@ -460,6 +460,7 @@ export default function PurchaseOrderDetail() {
|
||||
<PrintingActions
|
||||
modelType={ModelType.purchaseorder}
|
||||
items={[order.pk]}
|
||||
enableLabels
|
||||
enableReports
|
||||
/>,
|
||||
<OptionsActionDropdown
|
||||
|
||||
@@ -108,7 +108,7 @@ export default function PurchasingIndex() {
|
||||
name: 'manufacturer-parts',
|
||||
label: t`Manufacturer Parts`,
|
||||
icon: <IconBuildingWarehouse />,
|
||||
content: <ManufacturerPartTable params={{}} />
|
||||
content: <ManufacturerPartTable />
|
||||
}
|
||||
];
|
||||
}, [user, purchaseOrderView]);
|
||||
|
||||
@@ -458,6 +458,7 @@ export default function ReturnOrderDetail() {
|
||||
modelType={ModelType.returnorder}
|
||||
items={[order.pk]}
|
||||
enableReports
|
||||
enableLabels
|
||||
/>,
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Order Actions`}
|
||||
|
||||
@@ -516,6 +516,7 @@ export default function SalesOrderDetail() {
|
||||
modelType={ModelType.salesorder}
|
||||
items={[order.pk]}
|
||||
enableReports
|
||||
enableLabels
|
||||
/>,
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Order Actions`}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ModelType } from '@lib/enums/ModelType';
|
||||
import { UserRoles } from '@lib/enums/Roles';
|
||||
import { apiUrl } from '@lib/functions/Api';
|
||||
import { getDetailUrl } from '@lib/functions/Navigation';
|
||||
import type { StockOperationProps } from '@lib/types/Forms';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { Group, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { IconInfoCircle, IconPackages, IconSitemap } from '@tabler/icons-react';
|
||||
@@ -30,10 +31,7 @@ import { PageDetail } from '../../components/nav/PageDetail';
|
||||
import type { PanelType } from '../../components/panels/Panel';
|
||||
import { PanelGroup } from '../../components/panels/PanelGroup';
|
||||
import LocateItemButton from '../../components/plugins/LocateItemButton';
|
||||
import {
|
||||
type StockOperationProps,
|
||||
stockLocationFields
|
||||
} from '../../forms/StockForms';
|
||||
import { stockLocationFields } from '../../forms/StockForms';
|
||||
import { InvenTreeIcon } from '../../functions/icons';
|
||||
import {
|
||||
useDeleteApiFormModal,
|
||||
|
||||
@@ -33,6 +33,7 @@ import { ModelType } from '@lib/enums/ModelType';
|
||||
import { UserRoles } from '@lib/enums/Roles';
|
||||
import { apiUrl } from '@lib/functions/Api';
|
||||
import { getDetailUrl } from '@lib/functions/Navigation';
|
||||
import type { StockOperationProps } from '@lib/types/Forms';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { useBarcodeScanDialog } from '../../components/barcodes/BarcodeScanDialog';
|
||||
import AdminButton from '../../components/buttons/AdminButton';
|
||||
@@ -66,7 +67,6 @@ import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';
|
||||
import { useApi } from '../../contexts/ApiContext';
|
||||
import { formatCurrency, formatDecimal } from '../../defaults/formatters';
|
||||
import {
|
||||
type StockOperationProps,
|
||||
useFindSerialNumberForm,
|
||||
useStockFields,
|
||||
useStockItemSerializeFields
|
||||
|
||||
@@ -250,7 +250,10 @@ export default function InvenTreeTableHeader({
|
||||
<HoverCard
|
||||
position='bottom-end'
|
||||
withinPortal={true}
|
||||
disabled={!tableState.filterSet.activeFilters?.length}
|
||||
disabled={
|
||||
hasCustomFilters ||
|
||||
!tableState.filterSet.activeFilters?.length
|
||||
}
|
||||
>
|
||||
<HoverCard.Target>
|
||||
<Tooltip
|
||||
|
||||
@@ -12,10 +12,10 @@ import { UserRoles } from '@lib/enums/Roles';
|
||||
import { apiUrl } from '@lib/functions/Api';
|
||||
import { ActionButton } from '@lib/index';
|
||||
import type { TableFilter } from '@lib/types/Filters';
|
||||
import type { StockOperationProps } from '@lib/types/Forms';
|
||||
import type { TableColumn } from '@lib/types/Tables';
|
||||
import { IconCircleDashedCheck } from '@tabler/icons-react';
|
||||
import { useConsumeBuildItemsForm } from '../../forms/BuildForms';
|
||||
import type { StockOperationProps } from '../../forms/StockForms';
|
||||
import {
|
||||
useDeleteApiFormModal,
|
||||
useEditApiFormModal
|
||||
|
||||
@@ -248,6 +248,7 @@ export function BuildOrderTable({
|
||||
modelType: ModelType.build,
|
||||
enableSelection: true,
|
||||
enableReports: true,
|
||||
enableLabels: true,
|
||||
enableDownload: true
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -33,6 +33,7 @@ import { ModelType } from '@lib/enums/ModelType';
|
||||
import { UserRoles } from '@lib/enums/Roles';
|
||||
import { apiUrl } from '@lib/functions/Api';
|
||||
import type { TableFilter } from '@lib/types/Filters';
|
||||
import type { StockOperationProps } from '@lib/types/Forms';
|
||||
import type { TableColumn } from '@lib/types/Tables';
|
||||
import { StylishText } from '../../components/items/StylishText';
|
||||
import { useApi } from '../../contexts/ApiContext';
|
||||
@@ -43,7 +44,6 @@ import {
|
||||
useScrapBuildOutputsForm
|
||||
} from '../../forms/BuildForms';
|
||||
import {
|
||||
type StockOperationProps,
|
||||
useStockFields,
|
||||
useStockItemSerializeFields
|
||||
} from '../../forms/StockForms';
|
||||
|
||||
@@ -11,6 +11,7 @@ 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 type { TableFilter } from '@lib/types/Filters';
|
||||
import type { TableColumn } from '@lib/types/Tables';
|
||||
import { useManufacturerPartFields } from '../../forms/CompanyForms';
|
||||
import {
|
||||
@@ -32,9 +33,27 @@ import { InvenTreeTable } from '../InvenTreeTable';
|
||||
* Construct a table listing manufacturer parts
|
||||
*/
|
||||
export function ManufacturerPartTable({
|
||||
params
|
||||
}: Readonly<{ params: any }>): ReactNode {
|
||||
const table = useTable('manufacturerparts');
|
||||
manufacturerId,
|
||||
partId
|
||||
}: Readonly<{
|
||||
manufacturerId?: number;
|
||||
partId?: number;
|
||||
}>): ReactNode {
|
||||
const tableId: string = useMemo(() => {
|
||||
let tId = 'manufacturer-part';
|
||||
|
||||
if (manufacturerId) {
|
||||
tId += '-manufacturer';
|
||||
}
|
||||
|
||||
if (partId) {
|
||||
tId += '-part';
|
||||
}
|
||||
|
||||
return tId;
|
||||
}, [manufacturerId, partId]);
|
||||
|
||||
const table = useTable(tableId);
|
||||
|
||||
const user = useUserState();
|
||||
|
||||
@@ -42,7 +61,7 @@ export function ManufacturerPartTable({
|
||||
const tableColumns: TableColumn[] = useMemo(() => {
|
||||
return [
|
||||
PartColumn({
|
||||
switchable: 'part' in params
|
||||
switchable: !!partId
|
||||
}),
|
||||
{
|
||||
accessor: 'manufacturer',
|
||||
@@ -59,7 +78,7 @@ export function ManufacturerPartTable({
|
||||
DescriptionColumn({}),
|
||||
LinkColumn({})
|
||||
];
|
||||
}, [params]);
|
||||
}, [partId]);
|
||||
|
||||
const manufacturerPartFields = useManufacturerPartFields();
|
||||
|
||||
@@ -73,8 +92,8 @@ export function ManufacturerPartTable({
|
||||
fields: manufacturerPartFields,
|
||||
table: table,
|
||||
initialData: {
|
||||
manufacturer: params?.manufacturer,
|
||||
part: params?.part
|
||||
manufacturer: manufacturerId,
|
||||
part: partId
|
||||
}
|
||||
});
|
||||
|
||||
@@ -93,6 +112,24 @@ export function ManufacturerPartTable({
|
||||
table: table
|
||||
});
|
||||
|
||||
const tableFilters: TableFilter[] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
name: 'part_active',
|
||||
label: t`Active Part`,
|
||||
description: t`Show manufacturer parts for active internal parts.`,
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'manufacturer_active',
|
||||
label: t`Active Manufacturer`,
|
||||
active: !manufacturerId,
|
||||
description: t`Show manufacturer parts for active manufacturers.`,
|
||||
type: 'boolean'
|
||||
}
|
||||
];
|
||||
}, [manufacturerId]);
|
||||
|
||||
const tableActions = useMemo(() => {
|
||||
const can_add =
|
||||
user.hasAddRole(UserRoles.purchase_order) &&
|
||||
@@ -141,13 +178,15 @@ export function ManufacturerPartTable({
|
||||
columns={tableColumns}
|
||||
props={{
|
||||
params: {
|
||||
...params,
|
||||
part: partId,
|
||||
manufacturer: manufacturerId,
|
||||
part_detail: true,
|
||||
manufacturer_detail: true
|
||||
},
|
||||
enableDownload: true,
|
||||
rowActions: rowActions,
|
||||
tableActions: tableActions,
|
||||
tableFilters: tableFilters,
|
||||
modelType: ModelType.manufacturerpart
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -190,7 +190,8 @@ export function PurchaseOrderTable({
|
||||
modelType: ModelType.purchaseorder,
|
||||
enableSelection: true,
|
||||
enableDownload: true,
|
||||
enableReports: true
|
||||
enableReports: true,
|
||||
enableLabels: true
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -189,7 +189,8 @@ export function ReturnOrderTable({
|
||||
modelType: ModelType.returnorder,
|
||||
enableSelection: true,
|
||||
enableDownload: true,
|
||||
enableReports: true
|
||||
enableReports: true,
|
||||
enableLabels: true
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -12,11 +12,11 @@ import { ModelType } from '@lib/enums/ModelType';
|
||||
import { UserRoles } from '@lib/enums/Roles';
|
||||
import { apiUrl } from '@lib/functions/Api';
|
||||
import type { TableFilter } from '@lib/types/Filters';
|
||||
import type { StockOperationProps } from '@lib/types/Forms';
|
||||
import type { TableColumn } from '@lib/types/Tables';
|
||||
import { IconTruckDelivery } from '@tabler/icons-react';
|
||||
import { formatDate } from '../../defaults/formatters';
|
||||
import { useSalesOrderAllocationFields } from '../../forms/SalesOrderForms';
|
||||
import type { StockOperationProps } from '../../forms/StockForms';
|
||||
import {
|
||||
useBulkEditApiFormModal,
|
||||
useDeleteApiFormModal,
|
||||
|
||||
@@ -201,7 +201,8 @@ export function SalesOrderTable({
|
||||
modelType: ModelType.salesorder,
|
||||
enableSelection: true,
|
||||
enableDownload: true,
|
||||
enableReports: true
|
||||
enableReports: true,
|
||||
enableLabels: true
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -11,6 +11,7 @@ import { UserRoles } from '@lib/enums/Roles';
|
||||
import { apiUrl } from '@lib/functions/Api';
|
||||
import { getDetailUrl } from '@lib/functions/Navigation';
|
||||
import type { TableFilter } from '@lib/types/Filters';
|
||||
import type { StockOperationProps } from '@lib/types/Forms';
|
||||
import type { TableColumn } from '@lib/types/Tables';
|
||||
import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';
|
||||
import {
|
||||
@@ -18,10 +19,7 @@ import {
|
||||
formatDecimal,
|
||||
formatPriceRange
|
||||
} from '../../defaults/formatters';
|
||||
import {
|
||||
type StockOperationProps,
|
||||
useStockFields
|
||||
} from '../../forms/StockForms';
|
||||
import { useStockFields } from '../../forms/StockForms';
|
||||
import { InvenTreeIcon } from '../../functions/icons';
|
||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||
import { useStockAdjustActions } from '../../hooks/UseStockAdjustActions';
|
||||
|
||||
Reference in New Issue
Block a user