diff --git a/src/frontend/src/forms/PurchaseOrderForms.tsx b/src/frontend/src/forms/PurchaseOrderForms.tsx
index 50824f9a13..d60bb0c36d 100644
--- a/src/frontend/src/forms/PurchaseOrderForms.tsx
+++ b/src/frontend/src/forms/PurchaseOrderForms.tsx
@@ -349,11 +349,11 @@ function LineItemFormRow({
}>) {
// Barcode Modal state
const [opened, { open, close }] = useDisclosure(false, {
- onClose: () => props.changeFn(props.idx, 'barcode', undefined)
+ onClose: () => props.changeFn(props.rowId, 'barcode', undefined)
});
const [locationOpen, locationHandlers] = useDisclosure(false, {
- onClose: () => props.changeFn(props.idx, 'location', undefined)
+ onClose: () => props.changeFn(props.rowId, 'location', undefined)
});
// Is this a trackable part?
@@ -366,7 +366,7 @@ function LineItemFormRow({
useEffect(() => {
if (!!record.destination) {
- props.changeFn(props.idx, 'location', record.destination);
+ props.changeFn(props.rowId, 'location', record.destination);
locationHandlers.open();
}
}, [record.destination]);
@@ -376,7 +376,7 @@ function LineItemFormRow({
isEnabled: () => batchOpen,
onGenerate: (value: any) => {
if (value) {
- props.changeFn(props.idx, 'batch_code', value);
+ props.changeFn(props.rowId, 'batch_code', value);
}
}
});
@@ -388,19 +388,19 @@ function LineItemFormRow({
const [packagingOpen, packagingHandlers] = useDisclosure(false, {
onClose: () => {
- props.changeFn(props.idx, 'packaging', undefined);
+ props.changeFn(props.rowId, 'packaging', undefined);
}
});
const [noteOpen, noteHandlers] = useDisclosure(false, {
onClose: () => {
- props.changeFn(props.idx, 'note', undefined);
+ props.changeFn(props.rowId, 'note', undefined);
}
});
const [batchOpen, batchHandlers] = useDisclosure(false, {
onClose: () => {
- props.changeFn(props.idx, 'batch_code', undefined);
+ props.changeFn(props.rowId, 'batch_code', undefined);
},
onOpen: () => {
// Generate a new batch code
@@ -413,7 +413,7 @@ function LineItemFormRow({
const [serialOpen, serialHandlers] = useDisclosure(false, {
onClose: () => {
- props.changeFn(props.idx, 'serial_numbers', undefined);
+ props.changeFn(props.rowId, 'serial_numbers', undefined);
},
onOpen: () => {
// Generate new serial numbers
@@ -423,7 +423,7 @@ function LineItemFormRow({
quantity: props.item.quantity
});
} else {
- props.changeFn(props.idx, 'serial_numbers', undefined);
+ props.changeFn(props.rowId, 'serial_numbers', undefined);
}
}
});
@@ -434,20 +434,20 @@ function LineItemFormRow({
const defaultExpiry = record.part_detail?.default_expiry;
if (defaultExpiry !== undefined && defaultExpiry > 0) {
props.changeFn(
- props.idx,
+ props.rowId,
'expiry_date',
dayjs().add(defaultExpiry, 'day').format('YYYY-MM-DD')
);
}
},
onClose: () => {
- props.changeFn(props.idx, 'expiry_date', undefined);
+ props.changeFn(props.rowId, 'expiry_date', undefined);
}
});
// Status value
const [statusOpen, statusHandlers] = useDisclosure(false, {
- onClose: () => props.changeFn(props.idx, 'status', undefined)
+ onClose: () => props.changeFn(props.rowId, 'status', undefined)
});
// Barcode value
@@ -456,7 +456,7 @@ function LineItemFormRow({
// Change form value when state is altered
useEffect(() => {
- props.changeFn(props.idx, 'barcode', barcode);
+ props.changeFn(props.rowId, 'barcode', barcode);
}, [barcode]);
// Update location field description on state change
@@ -591,7 +591,7 @@ function LineItemFormRow({
nextValue = Number.isFinite(parsed) ? parsed : '';
}
- props.changeFn(props.idx, 'quantity', nextValue);
+ props.changeFn(props.rowId, 'quantity', nextValue);
serialNumberGenerator.update({
quantity: nextValue === '' ? undefined : nextValue
});
@@ -690,7 +690,7 @@ function LineItemFormRow({
- props.removeFn(props.idx)} />
+ props.removeFn(props.rowId)} />
{locationOpen && (
@@ -709,7 +709,7 @@ function LineItemFormRow({
structural: false
},
onValueChange: (value) => {
- props.changeFn(props.idx, 'location', value);
+ props.changeFn(props.rowId, 'location', value);
},
description: locationDescription,
value: props.item.location,
@@ -731,7 +731,7 @@ function LineItemFormRow({
tooltip={t`Store at default location`}
onClick={() =>
props.changeFn(
- props.idx,
+ props.rowId,
'location',
record.part_detail?.default_location ??
record.part_detail?.category_default_location
@@ -745,7 +745,11 @@ function LineItemFormRow({
icon={}
tooltip={t`Store at line item destination `}
onClick={() =>
- props.changeFn(props.idx, 'location', record.destination)
+ props.changeFn(
+ props.rowId,
+ 'location',
+ record.destination
+ )
}
tooltipAlignment='top'
/>
@@ -758,7 +762,7 @@ function LineItemFormRow({
tooltip={t`Store with already received stock`}
onClick={() =>
props.changeFn(
- props.idx,
+ props.rowId,
'location',
record.destination_detail.pk
)
@@ -774,7 +778,7 @@ function LineItemFormRow({
{
- props.changeFn(props.idx, 'batch_code', value);
+ props.changeFn(props.rowId, 'batch_code', value);
}}
fieldName='batch_code'
fieldDefinition={{
@@ -788,7 +792,7 @@ function LineItemFormRow({
- props.changeFn(props.idx, 'serial_numbers', value)
+ props.changeFn(props.rowId, 'serial_numbers', value)
}
fieldName='serial_numbers'
fieldDefinition={{
@@ -806,7 +810,7 @@ function LineItemFormRow({
- props.changeFn(props.idx, 'expiry_date', value)
+ props.changeFn(props.rowId, 'expiry_date', value)
}
fieldName='expiry_date'
fieldDefinition={{
@@ -820,7 +824,9 @@ function LineItemFormRow({
)}
props.changeFn(props.idx, 'packaging', value)}
+ onValueChange={(value) =>
+ props.changeFn(props.rowId, 'packaging', value)
+ }
fieldName='packaging'
fieldDefinition={{
field_type: 'string',
@@ -833,7 +839,7 @@ function LineItemFormRow({
visible={statusOpen}
defaultValue={10}
fieldName='status'
- onValueChange={(value) => props.changeFn(props.idx, 'status', value)}
+ onValueChange={(value) => props.changeFn(props.rowId, 'status', value)}
fieldDefinition={{
field_type: 'choice',
api_url: apiUrl(ApiEndpoints.stock_status),
@@ -845,7 +851,7 @@ function LineItemFormRow({
props.changeFn(props.idx, 'note', value)}
+ onValueChange={(value) => props.changeFn(props.rowId, 'note', value)}
fieldDefinition={{
field_type: 'string',
label: t`Note`
@@ -874,13 +880,20 @@ export function useReceiveLineItems(props: LineItemsForm) {
[]
);
- const records = Object.fromEntries(
- props.items.map((item) => [item.pk, item])
- );
+ const records = useMemo(() => {
+ return Object.fromEntries(props.items.map((item) => [item.pk, item]));
+ }, [props.items]);
- const filteredItems = props.items.filter(
- (elem) => elem.quantity !== elem.received
- );
+ const filteredItems = useMemo(() => {
+ return props.items
+ .filter((elem) => elem.quantity !== elem.received)
+ .map((elem) => {
+ return {
+ id: elem.pk,
+ ...elem
+ };
+ });
+ }, [props.items]);
const fields: ApiFormFieldSet = useMemo(() => {
return {
@@ -890,8 +903,9 @@ export function useReceiveLineItems(props: LineItemsForm) {
},
items: {
field_type: 'table',
- value: filteredItems.map((elem, idx) => {
+ value: filteredItems.map((elem) => {
return {
+ id: elem.pk,
line_item: elem.pk,
location: elem.destination ?? elem.destination_detail?.pk ?? null,
quantity: elem.quantity - elem.received,
@@ -914,7 +928,7 @@ export function useReceiveLineItems(props: LineItemsForm) {
props={row}
record={record}
statuses={stockStatusCodes}
- key={record.pk}
+ key={row.rowId}
/>
);
},
@@ -933,7 +947,7 @@ export function useReceiveLineItems(props: LineItemsForm) {
}
}
};
- }, [filteredItems, props, stockStatusCodes]);
+ }, [filteredItems, records, props, stockStatusCodes]);
return useCreateApiFormModal({
...props.formProps,