mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Adds "shipped" field to SalesOrderLineItem
- This is an internal tracker of quantity of items shipped - Updated by the database logic (not by the user) - Keeps track of how many items have been shipped against a lineitem - Does not matter if the actual stock items are later removed from the database
This commit is contained in:
parent
c943b320e6
commit
8aed68a1d1
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 3.2.5 on 2021-11-26 12:06
|
||||||
|
|
||||||
|
import InvenTree.fields
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('order', '0056_alter_salesorderallocation_shipment'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='salesorderlineitem',
|
||||||
|
name='shipped',
|
||||||
|
field=InvenTree.fields.RoundingDecimalField(decimal_places=5, default=0, help_text='Shipped quantity', max_digits=15, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Shipped'),
|
||||||
|
),
|
||||||
|
]
|
62
InvenTree/order/migrations/0058_auto_20211126_1210.py
Normal file
62
InvenTree/order/migrations/0058_auto_20211126_1210.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Generated by Django 3.2.5 on 2021-11-26 12:10
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
from InvenTree.status_codes import SalesOrderStatus
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_shipped_quantity(apps, schema_editor):
|
||||||
|
"""
|
||||||
|
In migration 0057 we added a new field 'shipped' to the SalesOrderLineItem model.
|
||||||
|
|
||||||
|
This field is used to record the number of items shipped,
|
||||||
|
even if the actual stock items get deleted from the database.
|
||||||
|
|
||||||
|
For existing orders in the database, we calculate this as follows:
|
||||||
|
|
||||||
|
- If the order is "shipped" then we use the total quantity
|
||||||
|
- Otherwise, we use the "fulfilled" calculated quantity
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
StockItem = apps.get_model('stock', 'stockitem')
|
||||||
|
SalesOrderLineItem = apps.get_model('order', 'salesorderlineitem')
|
||||||
|
|
||||||
|
for item in SalesOrderLineItem.objects.all():
|
||||||
|
|
||||||
|
if item.order.status == SalesOrderStatus.SHIPPED:
|
||||||
|
item.shipped = item.quantity
|
||||||
|
else:
|
||||||
|
# Calculate total stock quantity of items allocated to this order?
|
||||||
|
items = StockItem.objects.filter(
|
||||||
|
sales_order=item.order,
|
||||||
|
part=item.part
|
||||||
|
)
|
||||||
|
|
||||||
|
q = sum([item.quantity for item in items])
|
||||||
|
|
||||||
|
item.shipped = q
|
||||||
|
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
|
||||||
|
def reverse_calculate_shipped_quantity(apps, schema_editor):
|
||||||
|
"""
|
||||||
|
Provided only for reverse migration compatibility.
|
||||||
|
This function does nothing.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('order', '0057_salesorderlineitem_shipped'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(
|
||||||
|
calculate_shipped_quantity,
|
||||||
|
reverse_code=reverse_calculate_shipped_quantity
|
||||||
|
)
|
||||||
|
]
|
@ -814,6 +814,7 @@ class SalesOrderLineItem(OrderLineItem):
|
|||||||
order: Link to the SalesOrder that this line item belongs to
|
order: Link to the SalesOrder that this line item belongs to
|
||||||
part: Link to a Part object (may be null)
|
part: Link to a Part object (may be null)
|
||||||
sale_price: The unit sale price for this OrderLineItem
|
sale_price: The unit sale price for this OrderLineItem
|
||||||
|
shipped: The number of items which have actually shipped against this line item
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -838,6 +839,14 @@ class SalesOrderLineItem(OrderLineItem):
|
|||||||
help_text=_('Unit sale price'),
|
help_text=_('Unit sale price'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
shipped = RoundingDecimalField(
|
||||||
|
verbose_name=_('Shipped'),
|
||||||
|
help_text=_('Shipped quantity'),
|
||||||
|
default=0,
|
||||||
|
max_digits=15, decimal_places=5,
|
||||||
|
validators=[MinValueValidator(0)]
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = [
|
unique_together = [
|
||||||
]
|
]
|
||||||
|
@ -555,6 +555,8 @@ class SOLineItemSerializer(InvenTreeModelSerializer):
|
|||||||
allocated = serializers.FloatField(source='allocated_quantity', read_only=True)
|
allocated = serializers.FloatField(source='allocated_quantity', read_only=True)
|
||||||
fulfilled = serializers.FloatField(source='fulfilled_quantity', read_only=True)
|
fulfilled = serializers.FloatField(source='fulfilled_quantity', read_only=True)
|
||||||
|
|
||||||
|
shipped = InvenTreeDecimalField(read_only=True)
|
||||||
|
|
||||||
sale_price = InvenTreeMoneySerializer(
|
sale_price = InvenTreeMoneySerializer(
|
||||||
allow_null=True
|
allow_null=True
|
||||||
)
|
)
|
||||||
@ -584,6 +586,7 @@ class SOLineItemSerializer(InvenTreeModelSerializer):
|
|||||||
'sale_price',
|
'sale_price',
|
||||||
'sale_price_currency',
|
'sale_price_currency',
|
||||||
'sale_price_string',
|
'sale_price_string',
|
||||||
|
'shipped',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user