2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-09-18 08:31:33 +00:00

Reference fields (#3267)

* Adds a configurable 'reference pattern' to the IndexingReferenceMixin class

* Expand tests for reference_pattern validator:

- Prevent inclusion of illegal characters
- Prevent multiple groups of hash (#) characters
- Add unit tests

* Validator now checks for valid strftime formatter

* Adds build order reference pattern

* Adds function for creating a valid regex from the supplied pattern

- More unit tests
- Use it to validate BuildOrder reference field

* Refactoring the whole thing again - try using python string.format

* remove datetime-matcher from requirements.txt

* Add some more formatting helper functions

- Construct a regular expression from a format string
- Extract named values from a string, based on a format string

* Fix validator for build order reference field

* Adding unit tests for the new format string functionality

* Adds validation for reference fields

* Require the 'ref' format key as part of a valid reference pattern

* Extend format extraction to allow specification of integer groups

* Remove unused import

* Fix requirements

* Add method for generating the 'next' reference field for a model

* Fix function for generating next BuildOrder reference value

- A function is required as class methods cannot be used
- Simply wraps the existing class method

* Remove BUILDORDER_REFERENCE_REGEX setting

* Add unit test for build order reference field validation

* Adds unit testing for extracting integer values from a reference field

* Fix bugs from previous commit

* Add unit test for generation of default build order reference

* Add data migration for BuildOrder model

- Update reference field with old prefix
- Construct new pattern based on old prefix

* Adds unit test for data migration

- Check that the BuildOrder reference field is updated as expected

* Remove 'BUILDORDER_REFERENCE_PREFIX' setting

* Adds new setting for SalesOrder reference pattern

* Update method by which next reference value is generated

* Improved error handling in api_tester code

* Improve automated generation of order reference fields

- Handle potential errors
- Return previous reference if something goes wrong

* SalesOrder reference has now been updated also

- New reference pattern setting
- Updated default and validator for reference field
- Updated serializer and API
- Added unit tests

* Migrate the "PurchaseOrder" reference field to the new system

* Data migration for SalesOrder and PurchaseOrder reference fields

* Remove PURCHASEORDER_REFERENCE_PREFIX

* Remove references to SALESORDER_REFERENCE_PREFIX

* Re-add maximum value validation

* Bug fixes

* Improve algorithm for generating new reference

- Handle case where most recent reference does not conform to the reference pattern

* Fixes for 'order' unit tests

* Unit test fixes for order app

* More unit test fixes

* More unit test fixing

* Revert behaviour for "extract_int" clipping function

* Unit test value fix

* Prevent build order notification if we are importing records
This commit is contained in:
Oliver
2022-07-11 00:01:46 +10:00
committed by GitHub
parent 6133c745d7
commit 648faf4ed2
45 changed files with 1166 additions and 294 deletions

View File

@@ -94,23 +94,28 @@ class PurchaseOrderTest(OrderTest):
self.assertEqual(data['description'], 'Ordering some screws')
def test_po_reference(self):
"""Test that a reference with a too big / small reference is not possible."""
"""Test that a reference with a too big / small reference is handled correctly."""
# get permissions
self.assignRole('purchase_order.add')
url = reverse('api-po-list')
huge_number = 9223372036854775808
huge_number = "PO-92233720368547758089999999999999999"
self.post(
response = self.post(
url,
{
'supplier': 1,
'reference': huge_number,
'description': 'PO not created via the API',
'description': 'PO created via the API',
},
expected_code=201,
)
order = models.PurchaseOrder.objects.get(pk=response.data['pk'])
self.assertEqual(order.reference, 'PO-92233720368547758089999999999999999')
self.assertEqual(order.reference_int, 0x7fffffff)
def test_po_attachments(self):
"""Test the list endpoint for the PurchaseOrderAttachment model"""
url = reverse('api-po-attachment-list')
@@ -149,7 +154,7 @@ class PurchaseOrderTest(OrderTest):
url,
{
'supplier': 1,
'reference': '123456789-xyz',
'reference': 'PO-123456789',
'description': 'PO created via the API',
},
expected_code=201
@@ -177,19 +182,19 @@ class PurchaseOrderTest(OrderTest):
# Get detail info!
response = self.get(url)
self.assertEqual(response.data['pk'], pk)
self.assertEqual(response.data['reference'], '123456789-xyz')
self.assertEqual(response.data['reference'], 'PO-123456789')
# Try to alter (edit) the PurchaseOrder
response = self.patch(
url,
{
'reference': '12345-abc',
'reference': 'PO-12345',
},
expected_code=200
)
# Reference should have changed
self.assertEqual(response.data['reference'], '12345-abc')
self.assertEqual(response.data['reference'], 'PO-12345')
# Now, let's try to delete it!
# Initially, we do *not* have the required permission!
@@ -213,7 +218,7 @@ class PurchaseOrderTest(OrderTest):
self.post(
reverse('api-po-list'),
{
'reference': '12345678',
'reference': 'PO-12345678',
'supplier': 1,
'description': 'A test purchase order',
},
@@ -807,7 +812,7 @@ class SalesOrderTest(OrderTest):
url,
{
'customer': 4,
'reference': '12345',
'reference': 'SO-12345',
'description': 'Sales order',
},
expected_code=201
@@ -824,7 +829,7 @@ class SalesOrderTest(OrderTest):
url,
{
'customer': 4,
'reference': '12345',
'reference': 'SO-12345',
'description': 'Another sales order',
},
expected_code=400
@@ -834,19 +839,28 @@ class SalesOrderTest(OrderTest):
# Extract detail info for the SalesOrder
response = self.get(url)
self.assertEqual(response.data['reference'], '12345')
self.assertEqual(response.data['reference'], 'SO-12345')
# Try to alter (edit) the SalesOrder
# Initially try with an invalid reference field value
response = self.patch(
url,
{
'reference': '12345-a',
'reference': 'SO-12345-a',
},
expected_code=400
)
response = self.patch(
url,
{
'reference': 'SO-12346',
},
expected_code=200
)
# Reference should have changed
self.assertEqual(response.data['reference'], '12345-a')
self.assertEqual(response.data['reference'], 'SO-12346')
# Now, let's try to delete this SalesOrder
# Initially, we do not have the required permission
@@ -866,14 +880,29 @@ class SalesOrderTest(OrderTest):
"""Test that we can create a new SalesOrder via the API."""
self.assignRole('sales_order.add')
self.post(
reverse('api-so-list'),
url = reverse('api-so-list')
# Will fail due to invalid reference field
response = self.post(
url,
{
'reference': '1234566778',
'customer': 4,
'description': 'A test sales order',
},
expected_code=201
expected_code=400,
)
self.assertIn('Reference must match required pattern', str(response.data['reference']))
self.post(
url,
{
'reference': 'SO-12345',
'customer': 4,
'description': 'A better test sales order',
},
expected_code=201,
)
def test_so_cancel(self):