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