2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 20:45:44 +00:00

Report printing refactor (#7074)

* Adds a new "generic" ReportTemplate model

* expose API endpoints

* Update model / migrations / serializer

* Add new mixin class to existing database models

* - Add detail view for report template
- Revert filters field behaviour

* Filter report list by provided item IDs

- Greatly simplify filtering logic compared to existing implemetation
- Expose to API schema

* Create data migration for converting *old* report templates

* Ignore internal reports for data migration

* Add report mixin to StockLocation model

* Provide model choices in admin interface

* Offload context data generation to the model classes

* Remove old report template models

* Refactor JS code in CUI

* Fix for API filtering

* Add data migration to delete old models

* Remove dead URL

* Updates

* Construct sample report templates on app start

* Bump API version

* Typo fix

* Fix incorrect context calls

* Add new LabelTemplate model

- ReportTemplate and LabelTemplate share common base
- Refactor previous migration

* Expose to admin interface

* Add in extra context from existing label models

* Add migration to create LabelTemplate instances from existing labels

* Add API endpoints for listing and updating LabelTemplate objects

* Adjust 'upload_to' path

* Refactor label printing

* Move default label templates

* Update API endpoints

* Update migrations

* Handle LookupError in migration

* Redirect the "label" API endpoint

* Add new model for handling result of template printing

* Refactor LabelPrinting mixin

* Unlink "labels" app entirely

* Fix typo

* Record 'plugin' used to generate a particular output

* Fix imports

* Generate label print response

- Still not good yet

* Refactoring label printing in CUI

* add "items" count to TemplateOutput model

* Fix for InvenTreeLabelSheetPlugin

* Remove old "label" app

* Make request object optional

* Fix filename generation

* Add help text for "model_type"

* Simplify TemplateTable

* Tweak TemplateTable

* Get template editor to display template data again

* Stringify template name

- Important, otherwise you get a TypeError instead of TemplateDoesNotExist

* Add hooks to reset plugin state

* fix context for StockLocation model

* Tweak log messages

* Fix incorrect serializer

* Cleanup TemplateTable

* Fix broken import

* Filter by target model type

* Remove manual file operations

* Update old migrations

- Remove references to functions that no longer exist

* Refactor asset / snippet uploading

* Update comments

* Retain original filename when editing templatese

* Cleanup

* Refactor model type filter to use new hook

* Add placeholder actions for printing labels and reports

* Improve hookiness

* Add new ReportOutput class

* Report printing works from PUI now!

* More inspired filename pattern for generated reports

* Fix template preview window

- Use new "output" response field across the board

* Remove outdated task

* Update data migration to use raw SQL

- If the 'labels' app is no longer available, this will fail
- So, use raw SQL instead

* Add more API endpoint defs

* Adds placeholder API endpoint for label printing

* Expose plugin field to the printing endpoint

* Adds plugin model type

* Hook to print labels

* Refactor action dropdown items

* Refactor report printing for CUI

* Refactor label print for CUI

- Still needs to handle custom printing options for plugin

* Fix migration

* Update ModelType dict

* playwright test fix

* Unit test fixes

* Fix model ruleset associations

* Fix for report.js

* Add support for "dynamic" fields in metadata.py

* Add in custom fields based on plugin

* Refactoring

* Reset plugin on form close

* Set custom timeout values

* Update migration

- Not atomic

* Cleanup

* Implement more printing actions

* Reduce timeout

* Unit test updates

* Fix part serializers

* Label printing works in CUI again

* js linting

* Update <ActionDropdown>

* Fix for label printing API endpoint

* Fix filterselectdrawer

* Improve button rendering

* Allow printing from StockLocationTable

* Add aria-labels to modal form fields

* Add test for printing stock item labels from table

* Add test for report printing

* Add unit testing for report template editing / preview

* Message refactor

* Refactor InvenTreeReportMixin class

* Update playwright test

* Update 'verbose_name' for a number of models

* Additional admin filtering

* Playwright test updates

* Run checks against new python lib branch

(temporary, will be reverted)

* remove old app reference

* fix testing ref

* fix app init

* remove old tests

* Revert custom target branch

* Expose label and report output objects to API

* refactor

* fix a few tests

* factor plugin_ref out

* fix options testing

* Update table field header

* re-enable full options testing

* fix missing plugin matching

* disable call assert

* Add custom related field for PluginConfig

- Uses 'key' rather than 'pk'
- Revert label print plugin to use slug

* Add support for custom pk field in metadata

* switch to labels for testing

* re-align report testing code

* disable version check

* fix url

* Implement lazy loading

* Allow blank plugin for printing

- Uses the builtin label printer if not specified

* Add printing actions for StockItem

* Fix for metadata helper

* Use key instead of pk in printing actions

* Support non-standard pk values in RelatedModelField

* pass context data to report serializers

* disable template / item discovery

* fix call

* Tweak unit test

* Run python checks against specific branch

* Add task for running docs server

- Option to compile schema as part of task

* Custom branch no longer needed

* Starting on documentation updates

* fix tests for reports

* fix label testing

* Update template context variables

* Refactor report context documentation

* Documentation cleanup

* Docs cleanup

* Include sample report files

* Fix links

* Link cleanup

* Integrate plugin example code into docs

* Code cleanup

* Fix type annotation

* Revert deleted variable

* remove templatetype

* remove unused imports

* extend context testing

* test if plg can print

* re-enable version check

* Update unit tests

* Fix test

* Adjust unit test

* Add debug statement to test

* Fix unit test

- Labels get printed against LabelTemplate items, duh

* Unit test update

* Unit test updates

* Test update

* Patch fix for <PartColumn> component

* Fix ReportSerialierBase class

- Re-initialize field options if not already set

* Fix unit test for sqlite

* Fix kwargs for non-blocking label printing

* Update playwright tests

* Tweak unit test

---------

Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
Oliver
2024-05-22 10:17:01 +10:00
committed by GitHub
parent d99b6ae81b
commit aa39582d89
217 changed files with 4507 additions and 6762 deletions

View File

@ -19,8 +19,11 @@ test('PUI - Pages - Index - Playground', async ({ page }) => {
.locator('div')
.first()
.click();
await page.getByLabel('Name *').fill(newPartName);
await page.getByLabel('Initial Stock Quantity *').fill('1');
// Set the "name"
await page.getByLabel('text-field-name').fill(newPartName);
await page.getByLabel('number-field-initial_stock.').fill('1');
await page
.getByLabel('Create Part')
.getByRole('button', { name: 'Cancel' })
@ -37,7 +40,7 @@ test('PUI - Pages - Index - Playground', async ({ page }) => {
// Create Stock Item
await page.getByRole('button', { name: 'Create Stock Item' }).click();
await page.locator('#react-select-25-input').fill('R_1K_0402_1');
await page.getByLabel('related-field-part').fill('R_1K_0402_1');
await page.getByText('R_1K_0402_1%').click();
await page
.getByLabel('Add Stock Item')

View File

@ -186,7 +186,8 @@ test('PUI - Admin', async ({ page }) => {
await page.getByRole('tab', { name: 'Custom Units' }).click();
await page.getByRole('tab', { name: 'Part Parameters' }).click();
await page.getByRole('tab', { name: 'Category Parameters' }).click();
await page.getByRole('tab', { name: 'Templates' }).click();
await page.getByRole('tab', { name: 'Label Templates' }).click();
await page.getByRole('tab', { name: 'Report Templates' }).click();
await page.getByRole('tab', { name: 'Plugins' }).click();
await page.getByRole('tab', { name: 'Machines' }).click();
});

View File

@ -0,0 +1,108 @@
import { test } from './baseFixtures.js';
import { baseUrl } from './defaults.js';
import { doQuickLogin } from './login.js';
/*
* Test for label printing.
* Select a number of stock items from the table,
* and print labels against them
*/
test('PUI - Label Printing', async ({ page }) => {
await doQuickLogin(page);
await page.goto(`${baseUrl}/stock/location/index/`);
await page.waitForURL('**/platform/stock/location/**');
await page.getByRole('tab', { name: 'Stock Items' }).click();
// Select some labels
await page.getByLabel('Select record 1', { exact: true }).click();
await page.getByLabel('Select record 2', { exact: true }).click();
await page.getByLabel('Select record 3', { exact: true }).click();
await page
.getByLabel('Stock Items')
.getByLabel('action-menu-printing-actions')
.click();
await page.getByLabel('action-menu-printing-actions-print-labels').click();
// Select plugin
await page.getByLabel('related-field-plugin').click();
await page.getByText('InvenTreeLabelSheet').click();
// Select label template
await page.getByLabel('related-field-template').click();
await page.getByText('InvenTree Stock Item Label (').click();
await page.waitForTimeout(100);
// Submit the form (second time should result in success)
await page.getByRole('button', { name: 'Submit' }).isEnabled();
await page.getByRole('button', { name: 'Submit' }).click();
await page.locator('#form-success').waitFor();
await page.getByText('Label printing completed').waitFor();
await page.context().close();
});
/*
* Test for report printing
* Navigate to a PurchaseOrder detail page,
* and print a report against it.
*/
test('PUI - Report Printing', async ({ page }) => {
await doQuickLogin(page);
await page.goto(`${baseUrl}/stock/location/index/`);
await page.waitForURL('**/platform/stock/location/**');
// Navigate to a specific PurchaseOrder
await page.getByRole('tab', { name: 'Purchasing' }).click();
await page.getByRole('cell', { name: 'PO0009' }).click();
// Select "print report"
await page.getByLabel('action-menu-printing-actions').click();
await page.getByLabel('action-menu-printing-actions-print-reports').click();
// Select template
await page.getByLabel('related-field-template').click();
await page.getByText('InvenTree Purchase Order').click();
await page.waitForTimeout(100);
// Submit the form (should result in success)
await page.getByRole('button', { name: 'Submit' }).isEnabled();
await page.getByRole('button', { name: 'Submit' }).click();
await page.locator('#form-success').waitFor();
await page.getByText('Report printing completed').waitFor();
await page.context().close();
});
test('PUI - Report Editing', async ({ page }) => {
await doQuickLogin(page, 'admin', 'inventree');
// Navigate to the admin center
await page.getByRole('button', { name: 'admin' }).click();
await page.getByRole('menuitem', { name: 'Admin Center' }).click();
await page.getByRole('tab', { name: 'Label Templates' }).click();
await page
.getByRole('cell', { name: 'InvenTree Stock Item Label (' })
.click();
// Generate preview
await page.getByLabel('split-button-preview-options-action').click();
await page
.getByLabel('split-button-preview-options-item-preview-save', {
exact: true
})
.click();
await page.getByRole('button', { name: 'Save & Reload' }).click();
await page.getByText('The preview has been updated').waitFor();
await page.context().close();
});

View File

@ -13,7 +13,9 @@ test('PUI - Stock', async ({ page }) => {
await page.getByRole('tab', { name: 'Stock Items' }).click();
await page.getByRole('cell', { name: '1551ABK' }).click();
await page.getByRole('tab', { name: 'Stock', exact: true }).click();
await page.waitForURL('**/platform/stock/**');
await page.getByRole('tab', { name: 'Stock Locations' }).click();
await page.getByRole('cell', { name: 'Electronics Lab' }).first().click();
await page.getByRole('tab', { name: 'Default Parts' }).click();
@ -78,11 +80,15 @@ test('PUI - Purchasing', async ({ page }) => {
.getByRole('button')
.click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByLabel('Address title *').waitFor();
await page.getByLabel('text-field-title').waitFor();
await page.getByLabel('text-field-line2').waitFor();
// Read the current value of the cell, to ensure we always *change* it!
const value = await page.getByLabel('Line 2').inputValue();
await page.getByLabel('Line 2').fill(value == 'old' ? 'new' : 'old');
const value = await page.getByLabel('text-field-line2').inputValue();
await page
.getByLabel('text-field-line2')
.fill(value == 'old' ? 'new' : 'old');
await page.getByRole('button', { name: 'Submit' }).isEnabled();