mirror of
https://github.com/inventree/InvenTree.git
synced 2026-05-12 04:28:45 +00:00
Block SO allocation until tests pass (#11915)
* Add new global setting * Check item before allocating * add unit test
This commit is contained in:
@@ -234,3 +234,4 @@ The following [global settings](../settings/global.md) are available for sales o
|
|||||||
{{ globalsetting("SALESORDER_EDIT_COMPLETED_ORDERS") }}
|
{{ globalsetting("SALESORDER_EDIT_COMPLETED_ORDERS") }}
|
||||||
{{ globalsetting("SALESORDER_SHIP_COMPLETE") }}
|
{{ globalsetting("SALESORDER_SHIP_COMPLETE") }}
|
||||||
{{ globalsetting("SALESORDER_SHIPMENT_REQUIRES_CHECK") }}
|
{{ globalsetting("SALESORDER_SHIPMENT_REQUIRES_CHECK") }}
|
||||||
|
{{ globalsetting("SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS")}}
|
||||||
|
|||||||
@@ -910,6 +910,14 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
|
|||||||
'default': False,
|
'default': False,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
},
|
},
|
||||||
|
'SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS': {
|
||||||
|
'name': _('Block Incomplete Item Tests'),
|
||||||
|
'description': _(
|
||||||
|
'Prevent allocation of stock items to sales orders if required item tests are incomplete'
|
||||||
|
),
|
||||||
|
'default': False,
|
||||||
|
'validator': bool,
|
||||||
|
},
|
||||||
'PURCHASEORDER_REFERENCE_PATTERN': {
|
'PURCHASEORDER_REFERENCE_PATTERN': {
|
||||||
'name': _('Purchase Order Reference Pattern'),
|
'name': _('Purchase Order Reference Pattern'),
|
||||||
'description': _(
|
'description': _(
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import order.models
|
|||||||
import part.filters as part_filters
|
import part.filters as part_filters
|
||||||
import stock.models
|
import stock.models
|
||||||
import stock.serializers
|
import stock.serializers
|
||||||
|
from common.settings import get_global_setting
|
||||||
from company.serializers import (
|
from company.serializers import (
|
||||||
AddressBriefSerializer,
|
AddressBriefSerializer,
|
||||||
CompanyBriefSerializer,
|
CompanyBriefSerializer,
|
||||||
@@ -1663,6 +1664,15 @@ class SalesOrderShipmentAllocationItemSerializer(serializers.Serializer):
|
|||||||
stock_item = data['stock_item']
|
stock_item = data['stock_item']
|
||||||
quantity = data['quantity']
|
quantity = data['quantity']
|
||||||
|
|
||||||
|
if get_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS'):
|
||||||
|
if (
|
||||||
|
stock_item.hasRequiredTests()
|
||||||
|
and not stock_item.passedAllRequiredTests()
|
||||||
|
):
|
||||||
|
raise ValidationError({
|
||||||
|
'stock_item': _('Stock item has not passed all required tests')
|
||||||
|
})
|
||||||
|
|
||||||
if stock_item.serialized and quantity != 1:
|
if stock_item.serialized and quantity != 1:
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'quantity': _('Quantity must be 1 for serialized stock item')
|
'quantity': _('Quantity must be 1 for serialized stock item')
|
||||||
@@ -1853,6 +1863,14 @@ class SalesOrderSerialAllocationSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
stock_item = items[0]
|
stock_item = items[0]
|
||||||
|
|
||||||
|
if get_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS'):
|
||||||
|
if (
|
||||||
|
stock_item.hasRequiredTests()
|
||||||
|
and not stock_item.passedAllRequiredTests()
|
||||||
|
):
|
||||||
|
serials_unavailable.add(str(serial))
|
||||||
|
continue
|
||||||
|
|
||||||
if not stock_item.in_stock:
|
if not stock_item.in_stock:
|
||||||
serials_unavailable.add(str(serial))
|
serials_unavailable.add(str(serial))
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -2404,6 +2404,43 @@ class SalesOrderAllocateTest(OrderTest):
|
|||||||
assert_subset=True,
|
assert_subset=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_block_on_required_tests(self):
|
||||||
|
"""Test the SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS setting."""
|
||||||
|
from part.models import PartTestTemplate
|
||||||
|
|
||||||
|
line = self.order.lines.first()
|
||||||
|
part = line.part
|
||||||
|
|
||||||
|
# Make this a testable part
|
||||||
|
part.testable = True
|
||||||
|
part.save()
|
||||||
|
|
||||||
|
# Create a required test
|
||||||
|
PartTestTemplate.objects.create(
|
||||||
|
part=part, test_name='A required test', required=True
|
||||||
|
)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'items': [
|
||||||
|
{
|
||||||
|
'line_item': line.pk,
|
||||||
|
'stock_item': part.stock_items.last().pk,
|
||||||
|
'quantity': line.quantity,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
set_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS', True)
|
||||||
|
|
||||||
|
response = self.post(self.url, data, expected_code=400)
|
||||||
|
self.assertIn(
|
||||||
|
'Stock item has not passed all required tests', str(response.data)
|
||||||
|
)
|
||||||
|
|
||||||
|
set_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS', False)
|
||||||
|
|
||||||
|
response = self.post(self.url, data, expected_code=201)
|
||||||
|
|
||||||
|
|
||||||
class ReturnOrderTests(InvenTreeAPITestCase):
|
class ReturnOrderTests(InvenTreeAPITestCase):
|
||||||
"""Unit tests for ReturnOrder API endpoints."""
|
"""Unit tests for ReturnOrder API endpoints."""
|
||||||
|
|||||||
@@ -336,7 +336,8 @@ export default function SystemSettings() {
|
|||||||
'SALESORDER_DEFAULT_SHIPMENT',
|
'SALESORDER_DEFAULT_SHIPMENT',
|
||||||
'SALESORDER_EDIT_COMPLETED_ORDERS',
|
'SALESORDER_EDIT_COMPLETED_ORDERS',
|
||||||
'SALESORDER_SHIP_COMPLETE',
|
'SALESORDER_SHIP_COMPLETE',
|
||||||
'SALESORDER_SHIPMENT_REQUIRES_CHECK'
|
'SALESORDER_SHIPMENT_REQUIRES_CHECK',
|
||||||
|
'SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS'
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<GlobalSettingList
|
<GlobalSettingList
|
||||||
|
|||||||
Reference in New Issue
Block a user