2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 03:26:45 +00:00

PO receive fix (#8423)

* Add "active" filter to PurchaseOrderLineItem.part field

* Fix for allocation serial numbers to incoming items

* Validate serial numbers per line item
This commit is contained in:
Oliver 2024-11-04 14:10:17 +11:00 committed by GitHub
parent c9079d9a0e
commit 4df42cd776
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 40 additions and 7 deletions

View File

@ -845,6 +845,20 @@ class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
except DjangoValidationError as e:
raise ValidationError({'serial_numbers': e.messages})
invalid_serials = []
# Check the serial numbers are valid
for serial in data['serials']:
try:
base_part.validate_serial_number(serial, raise_error=True)
except (ValidationError, DjangoValidationError):
invalid_serials.append(serial)
if len(invalid_serials) > 0:
msg = _('The following serial numbers already exist or are invalid')
msg += ': ' + ', '.join(invalid_serials)
raise ValidationError({'serial_numbers': msg})
return data

View File

@ -259,6 +259,7 @@ function poLineItemFields(options={}) {
part: {
icon: 'fa-shapes',
filters: {
active: true,
part_detail: true,
supplier_detail: true,
supplier: options.supplier,

View File

@ -237,6 +237,12 @@ function LineItemFormRow({
onClose: () => props.changeFn(props.idx, 'location', undefined)
});
// Is this a trackable part?
const trackable: boolean = useMemo(
() => record.part_detail?.trackable ?? false,
[record]
);
useEffect(() => {
if (!!record.destination) {
props.changeFn(props.idx, 'location', record.destination);
@ -303,6 +309,14 @@ function LineItemFormRow({
props.changeFn(props.idx, 'barcode', barcode);
}, [barcode]);
const batchToolTip: string = useMemo(() => {
if (trackable) {
return t`Assign Batch Code and Serial Numbers`;
} else {
return t`Assign Batch Code`;
}
}, [trackable]);
// Update location field description on state change
useEffect(() => {
if (!opened) {
@ -418,9 +432,7 @@ function LineItemFormRow({
size="sm"
onClick={() => batchHandlers.toggle()}
icon={<InvenTreeIcon icon="batch_code" />}
tooltip={t`Assign Batch Code${
record.trackable && ' and Serial Numbers'
}`}
tooltip={batchToolTip}
tooltipAlignment="top"
variant={batchOpen ? 'filled' : 'transparent'}
/>
@ -552,18 +564,20 @@ function LineItemFormRow({
fieldDefinition={{
field_type: 'string',
label: t`Batch Code`,
description: t`Enter batch code for received items`,
value: props.item.batch_code
}}
error={props.rowErrors?.batch_code?.message}
/>
<TableFieldExtraRow
visible={batchOpen && record.trackable}
visible={batchOpen && trackable}
onValueChange={(value) =>
props.changeFn(props.idx, 'serial_numbers', value)
}
fieldDefinition={{
field_type: 'string',
label: t`Serial numbers`,
label: t`Serial Numbers`,
description: t`Enter serial numbers for received items`,
value: props.item.serial_numbers
}}
error={props.rowErrors?.serial_numbers?.message}

View File

@ -302,6 +302,10 @@ export function PurchaseOrderLineItemTable({
);
}, [order, poStatus]);
const orderPlaced: boolean = useMemo(() => {
return order.status == poStatus.PLACED;
}, [order, poStatus]);
const rowActions = useCallback(
(record: any): RowAction[] => {
let received = (record?.received ?? 0) >= (record?.quantity ?? 0);
@ -370,10 +374,10 @@ export function PurchaseOrderLineItemTable({
icon={<IconSquareArrowRight />}
onClick={() => receiveLineItems.open()}
disabled={table.selectedRecords.length === 0}
hidden={!orderOpen || !user.hasChangeRole(UserRoles.purchase_order)}
hidden={!orderPlaced || !user.hasChangeRole(UserRoles.purchase_order)}
/>
];
}, [orderId, user, table, orderOpen]);
}, [orderId, user, table, orderOpen, orderPlaced]);
return (
<>