mirror of
https://github.com/inventree/InvenTree.git
synced 2025-09-23 11:00:18 +00:00
Add Expiry Date on Receive Line Item (#8867)
* Add expiry on line item receive from PO * add backend test * reset pre-commit * increment inventree api version * use None as default expiry date * check global setting STOCK_ENABLE_EXPIRY * check for default expiry in line item receive * use dayjs --------- Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 298
|
||||
INVENTREE_API_VERSION = 299
|
||||
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v299 - 2025-01-10 - https://github.com/inventree/InvenTree/pull/8867
|
||||
- Adds 'expiry_date' field to the PurchaseOrderReceive API endpoint
|
||||
- Adds 'default_expiry` field to the PartBriefSerializer, affecting API endpoints which use it
|
||||
|
||||
v298 - 2025-01-07 - https://github.com/inventree/InvenTree/pull/8848
|
||||
- Adds 'created_by' field to PurchaseOrder API endpoints
|
||||
- Adds 'created_by' field to SalesOrder API endpoints
|
||||
|
@@ -410,6 +410,7 @@ class PurchaseOrderReceive(PurchaseOrderContextMixin, CreateAPI):
|
||||
- supplier_part: pk value of the supplier part
|
||||
- quantity: quantity to receive
|
||||
- status: stock item status
|
||||
- expiry_date: stock item expiry date (optional)
|
||||
- location: destination for stock item (optional)
|
||||
- batch_code: the batch code for this stock item
|
||||
- serial_numbers: serial numbers for this stock item
|
||||
|
@@ -819,6 +819,9 @@ class PurchaseOrder(TotalPriceMixin, Order):
|
||||
# Extract optional batch code for the new stock item
|
||||
batch_code = kwargs.get('batch_code', '')
|
||||
|
||||
# Extract optional expiry date for the new stock item
|
||||
expiry_date = kwargs.get('expiry_date')
|
||||
|
||||
# Extract optional list of serial numbers
|
||||
serials = kwargs.get('serials')
|
||||
|
||||
@@ -882,6 +885,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
|
||||
purchase_order=self,
|
||||
status=status,
|
||||
batch=batch_code,
|
||||
expiry_date=expiry_date,
|
||||
packaging=packaging,
|
||||
serial=sn,
|
||||
purchase_price=unit_purchase_price,
|
||||
|
@@ -717,6 +717,7 @@ class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
|
||||
'quantity',
|
||||
'status',
|
||||
'batch_code',
|
||||
'expiry_date',
|
||||
'serial_numbers',
|
||||
'packaging',
|
||||
'note',
|
||||
@@ -765,6 +766,13 @@ class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
|
||||
allow_blank=True,
|
||||
)
|
||||
|
||||
expiry_date = serializers.DateField(
|
||||
label=_('Expiry Date'),
|
||||
help_text=_('Enter expiry date for incoming stock items'),
|
||||
required=False,
|
||||
default=None,
|
||||
)
|
||||
|
||||
serial_numbers = serializers.CharField(
|
||||
label=_('Serial Numbers'),
|
||||
help_text=_('Enter serial numbers for incoming stock items'),
|
||||
@@ -967,6 +975,7 @@ class PurchaseOrderReceiveSerializer(serializers.Serializer):
|
||||
status=item['status'],
|
||||
barcode=item.get('barcode', ''),
|
||||
batch_code=item.get('batch_code', ''),
|
||||
expiry_date=item.get('expiry_date', None),
|
||||
packaging=item.get('packaging', ''),
|
||||
serials=item.get('serials', None),
|
||||
notes=item.get('note', None),
|
||||
|
@@ -3,7 +3,7 @@
|
||||
import base64
|
||||
import io
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import date, datetime, timedelta
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import connection
|
||||
@@ -1061,12 +1061,20 @@ class PurchaseOrderReceiveTest(OrderTest):
|
||||
self.assertEqual(line_1.received, 0)
|
||||
self.assertEqual(line_2.received, 50)
|
||||
|
||||
one_week_from_today = date.today() + timedelta(days=7)
|
||||
|
||||
valid_data = {
|
||||
'items': [
|
||||
{'line_item': 1, 'quantity': 50, 'barcode': 'MY-UNIQUE-BARCODE-123'},
|
||||
{
|
||||
'line_item': 1,
|
||||
'quantity': 50,
|
||||
'expiry_date': one_week_from_today.strftime(r'%Y-%m-%d'),
|
||||
'barcode': 'MY-UNIQUE-BARCODE-123',
|
||||
},
|
||||
{
|
||||
'line_item': 2,
|
||||
'quantity': 200,
|
||||
'expiry_date': one_week_from_today.strftime(r'%Y-%m-%d'),
|
||||
'location': 2, # Explicit location
|
||||
'barcode': 'MY-UNIQUE-BARCODE-456',
|
||||
},
|
||||
@@ -1111,6 +1119,10 @@ class PurchaseOrderReceiveTest(OrderTest):
|
||||
self.assertEqual(stock_1.last().location.pk, 1)
|
||||
self.assertEqual(stock_2.last().location.pk, 2)
|
||||
|
||||
# Expiry dates should be set
|
||||
self.assertEqual(stock_1.last().expiry_date, one_week_from_today)
|
||||
self.assertEqual(stock_2.last().expiry_date, one_week_from_today)
|
||||
|
||||
# Barcodes should have been assigned to the stock items
|
||||
self.assertTrue(
|
||||
StockItem.objects.filter(barcode_data='MY-UNIQUE-BARCODE-123').exists()
|
||||
|
@@ -352,6 +352,7 @@ class PartBriefSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
||||
'barcode_hash',
|
||||
'category_default_location',
|
||||
'default_location',
|
||||
'default_expiry',
|
||||
'name',
|
||||
'revision',
|
||||
'full_name',
|
||||
|
Reference in New Issue
Block a user