[Feature] External build order (#9312)

* Add BuildOrder reference to PurchaseOrderLineItem

* Add setting to enable / disable external build orders

* Fix for supplier part detail

* Update forms

* Filter build list by "external" status

* Add "external" attribute to BuildOrder

* Filter by external build when selecting against purchase order line item

* Add frontend elements

* Prevent creation of build outputs

* Tweak related model field

- Send filters when fetching initial data

* Fix migrations

* Fix some existing typos

* Add build info when receiving line items

* Logic fix

* Bump API version

* Updated relationship

* Add external orders tab for order

* Display table of external purchase orders against a build order

* Fix permissions

* Tweak field definition

* Add unit tests

* Tweak api_version.py

* Playwright testing

* Fix discrepancy in 'building' filter

* Add basic documentation

( more work required )

* Tweak docs macros

* Migration fix

* Adjust build page tabs

* Fix imports

* Fix broken import

* Update playywright tests

* Bump API version

* Handle DB issues

* Improve filter

* Cleaner code

* Fix column ordering bug

* Add filters to build output table

* Documentation

* Tweak unit test

* Add "scheduled_for_production" field

* Add helper function to part model

* Cleanup
This commit is contained in:
Oliver
2025-06-12 18:27:15 +10:00
committed by GitHub
parent 5915a1e13d
commit c6848b8e87
46 changed files with 864 additions and 157 deletions
+29 -1
View File
@@ -64,9 +64,14 @@ export function usePurchaseOrderLineItemFields({
orderId?: number;
create?: boolean;
}) {
const globalSettings = useGlobalSettingsState();
const [purchasePrice, setPurchasePrice] = useState<string>('');
const [autoPricing, setAutoPricing] = useState(true);
// Internal part information
const [part, setPart] = useState<any>({});
useEffect(() => {
if (autoPricing) {
setPurchasePrice('');
@@ -92,6 +97,9 @@ export function usePurchaseOrderLineItemFields({
active: true,
part_active: true
},
onValueChange: (value, record) => {
setPart(record?.part_detail ?? {});
},
adjustFilters: (adjust: ApiFormAdjustFilterType) => {
return {
...adjust.filters,
@@ -119,6 +127,14 @@ export function usePurchaseOrderLineItemFields({
destination: {
icon: <IconSitemap />
},
build_order: {
disabled: !part?.assembly,
filters: {
external: true,
outstanding: true,
part: part?.pk
}
},
notes: {
icon: <IconNotes />
},
@@ -127,12 +143,24 @@ export function usePurchaseOrderLineItemFields({
}
};
if (!globalSettings.isSet('BUILDORDER_EXTERNAL_BUILDS', false)) {
delete fields.build_order;
}
if (create) {
fields['merge_items'] = {};
}
return fields;
}, [create, orderId, supplierId, autoPricing, purchasePrice]);
}, [
create,
orderId,
part,
globalSettings,
supplierId,
autoPricing,
purchasePrice
]);
return fields;
}