2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-08-06 20:11:37 +00:00

[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

View File

@@ -3,6 +3,7 @@ import { test } from '../baseFixtures.ts';
import {
activateCalendarView,
clearTableFilters,
clickOnRowMenu,
getRowFromCell,
loadTab,
navigate,
@@ -65,7 +66,7 @@ test('Build Order - Basic Tests', async ({ browser }) => {
await loadTab(page, 'Attachments');
await loadTab(page, 'Notes');
await loadTab(page, 'Incomplete Outputs');
await loadTab(page, 'Line Items');
await loadTab(page, 'Required Stock');
await loadTab(page, 'Allocated Stock');
// Check for expected text in the table
@@ -373,3 +374,53 @@ test('Build Order - Duplicate', async ({ browser }) => {
await page.getByText('Pending').first().waitFor();
});
// Tests for external build orders
test('Build Order - External', async ({ browser }) => {
const page = await doCachedLogin(browser, { url: 'manufacturing/index/' });
await loadTab(page, 'Build Orders');
// Filter to show only external builds
await clearTableFilters(page);
await setTableChoiceFilter(page, 'External', 'Yes');
await page.getByRole('cell', { name: 'BO0026' }).waitFor();
await page.getByRole('cell', { name: 'BO0025' }).click();
await page
.locator('span')
.filter({ hasText: /^External$/ })
.waitFor();
await loadTab(page, 'Allocated Stock');
await loadTab(page, 'Incomplete Outputs');
await page
.getByText('This build order is fulfilled by an external purchase order')
.waitFor();
await loadTab(page, 'External Orders');
await page.getByRole('cell', { name: 'PO0016' }).click();
await loadTab(page, 'Attachments');
await loadTab(page, 'Received Stock');
await loadTab(page, 'Line Items');
const cell = await page.getByRole('cell', {
name: '002.01-PCBA',
exact: true
});
await clickOnRowMenu(cell);
await page.getByRole('menuitem', { name: 'Receive line item' }).waitFor();
await page.getByRole('menuitem', { name: 'Duplicate' }).waitFor();
await page.getByRole('menuitem', { name: 'Edit' }).waitFor();
await page.getByRole('menuitem', { name: 'View Build Order' }).click();
// Wait for navigation back to build order detail page
await page.getByText('Build Order: BO0025', { exact: true }).waitFor();
// Let's look at BO0026 too
await navigate(page, 'manufacturing/build-order/26/details');
await loadTab(page, 'External Orders');
await page.getByRole('cell', { name: 'PO0017' }).waitFor();
await page.getByRole('cell', { name: 'PO0018' }).waitFor();
});