2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

Include location detail in build output table (#8923)

* Include location detail in build output table

* Raise validation error if trying to split an in-production item
This commit is contained in:
Oliver 2025-01-21 01:41:13 +11:00 committed by GitHub
parent 2575c7276c
commit 68d3620bb2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 29 additions and 11 deletions

View File

@ -1985,9 +1985,18 @@ class StockItem(
Returns: Returns:
The new StockItem object The new StockItem object
Raises:
ValidationError: If the stock item cannot be split
- The provided quantity will be subtracted from this item and given to the new one. - The provided quantity will be subtracted from this item and given to the new one.
- 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"
# Cannot split a stock item which is in production
if self.is_building:
raise ValidationError(_('Stock item is currently in production'))
notes = kwargs.get('notes', '') notes = kwargs.get('notes', '')
# Do not split a serialized part # Do not split a serialized part

View File

@ -1565,18 +1565,18 @@ class StockAdjustmentItemSerializer(serializers.Serializer):
help_text=_('StockItem primary key value'), help_text=_('StockItem primary key value'),
) )
def validate_pk(self, pk): def validate_pk(self, stock_item: StockItem) -> StockItem:
"""Ensure the stock item is valid.""" """Ensure the stock item is valid."""
allow_out_of_stock_transfer = get_global_setting( allow_out_of_stock_transfer = get_global_setting(
'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 pk.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
): ):
raise ValidationError(_('Stock item is not in stock')) raise ValidationError(_('Stock item is not in stock'))
return pk return stock_item
quantity = serializers.DecimalField( quantity = serializers.DecimalField(
max_digits=15, decimal_places=5, min_value=Decimal(0), required=True max_digits=15, decimal_places=5, min_value=Decimal(0), required=True

View File

@ -667,13 +667,15 @@ export default function StockDetail() {
}); });
const stockActions = useMemo(() => { const stockActions = useMemo(() => {
const inStock = // Can this stock item be transferred to a different location?
const canTransfer =
user.hasChangeRole(UserRoles.stock) && user.hasChangeRole(UserRoles.stock) &&
!stockitem.sales_order && !stockitem.sales_order &&
!stockitem.belongs_to && !stockitem.belongs_to &&
!stockitem.customer && !stockitem.customer &&
!stockitem.consumed_by && !stockitem.consumed_by;
!stockitem.is_building;
const isBuilding = stockitem.is_building;
const serial = stockitem.serial; const serial = stockitem.serial;
const serialized = const serialized =
@ -704,7 +706,7 @@ export default function StockDetail() {
{ {
name: t`Count`, name: t`Count`,
tooltip: t`Count stock`, tooltip: t`Count stock`,
hidden: serialized || !inStock, hidden: serialized || !canTransfer || isBuilding,
icon: ( icon: (
<InvenTreeIcon icon='stocktake' iconProps={{ color: 'blue' }} /> <InvenTreeIcon icon='stocktake' iconProps={{ color: 'blue' }} />
), ),
@ -715,7 +717,7 @@ export default function StockDetail() {
{ {
name: t`Add`, name: t`Add`,
tooltip: t`Add Stock`, tooltip: t`Add Stock`,
hidden: serialized || !inStock, hidden: serialized || !canTransfer || isBuilding,
icon: <InvenTreeIcon icon='add' iconProps={{ color: 'green' }} />, icon: <InvenTreeIcon icon='add' iconProps={{ color: 'green' }} />,
onClick: () => { onClick: () => {
stockitem.pk && addStockItem.open(); stockitem.pk && addStockItem.open();
@ -724,7 +726,11 @@ export default function StockDetail() {
{ {
name: t`Remove`, name: t`Remove`,
tooltip: t`Remove Stock`, tooltip: t`Remove Stock`,
hidden: serialized || !inStock || stockitem.quantity <= 0, hidden:
serialized ||
!canTransfer ||
isBuilding ||
stockitem.quantity <= 0,
icon: <InvenTreeIcon icon='remove' iconProps={{ color: 'red' }} />, icon: <InvenTreeIcon icon='remove' iconProps={{ color: 'red' }} />,
onClick: () => { onClick: () => {
stockitem.pk && removeStockItem.open(); stockitem.pk && removeStockItem.open();
@ -733,7 +739,7 @@ export default function StockDetail() {
{ {
name: t`Transfer`, name: t`Transfer`,
tooltip: t`Transfer Stock`, tooltip: t`Transfer Stock`,
hidden: !inStock, hidden: !canTransfer,
icon: ( icon: (
<InvenTreeIcon icon='transfer' iconProps={{ color: 'blue' }} /> <InvenTreeIcon icon='transfer' iconProps={{ color: 'blue' }} />
), ),
@ -745,8 +751,10 @@ export default function StockDetail() {
name: t`Serialize`, name: t`Serialize`,
tooltip: t`Serialize stock`, tooltip: t`Serialize stock`,
hidden: hidden:
!inStock || !canTransfer ||
isBuilding ||
serialized || serialized ||
stockitem?.quantity != 1 ||
stockitem?.part_detail?.trackable != true, stockitem?.part_detail?.trackable != true,
icon: <InvenTreeIcon icon='serial' iconProps={{ color: 'blue' }} />, icon: <InvenTreeIcon icon='serial' iconProps={{ color: 'blue' }} />,
onClick: () => { onClick: () => {

View File

@ -575,6 +575,7 @@ export default function BuildOutputTable({
props={{ props={{
params: { params: {
part_detail: true, part_detail: true,
location_detail: true,
tests: true, tests: true,
is_building: true, is_building: true,
build: buildId build: buildId