mirror of
https://github.com/inventree/InvenTree.git
synced 2026-02-06 05:15:52 +00:00
Merge branch 'master' of https://github.com/inventree/InvenTree into matmair/issue6281
This commit is contained in:
@@ -11,6 +11,10 @@ v299 - 2025-01-10 : https://github.com/inventree/InvenTree/pull/6293
|
||||
- Removes a considerable amount of old auth endpoints
|
||||
- Introduces allauth based REST API
|
||||
|
||||
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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -796,10 +796,32 @@ class PurchaseOrder(TotalPriceMixin, Order):
|
||||
def receive_line_item(
|
||||
self, line, location, quantity, user, status=StockStatus.OK.value, **kwargs
|
||||
):
|
||||
"""Receive a line item (or partial line item) against this PurchaseOrder."""
|
||||
"""Receive a line item (or partial line item) against this PurchaseOrder.
|
||||
|
||||
Arguments:
|
||||
line: The PurchaseOrderLineItem to receive against
|
||||
location: The StockLocation to receive the item into
|
||||
quantity: The quantity to receive
|
||||
user: The User performing the action
|
||||
status: The StockStatus to assign to the item (default: StockStatus.OK)
|
||||
|
||||
Keyword Arguments:
|
||||
barch_code: Optional batch code for the new StockItem
|
||||
serials: Optional list of serial numbers to assign to the new StockItem(s)
|
||||
notes: Optional notes field for the StockItem
|
||||
packaging: Optional packaging field for the StockItem
|
||||
barcode: Optional barcode field for the StockItem
|
||||
|
||||
Raises:
|
||||
ValidationError: If the quantity is negative or otherwise invalid
|
||||
ValidationError: If the order is not in the 'PLACED' state
|
||||
"""
|
||||
# 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')
|
||||
|
||||
@@ -863,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