mirror of
https://github.com/inventree/InvenTree.git
synced 2026-05-28 11:59:23 +00:00
Offload order completion tasks
This commit is contained in:
@@ -849,24 +849,17 @@ class PurchaseOrder(TotalPriceMixin, Order):
|
|||||||
|
|
||||||
Order must be currently PLACED.
|
Order must be currently PLACED.
|
||||||
"""
|
"""
|
||||||
if self.status == PurchaseOrderStatus.PLACED:
|
if self.status != PurchaseOrderStatus.PLACED:
|
||||||
self.status = PurchaseOrderStatus.COMPLETE.value
|
return
|
||||||
self.complete_date = InvenTree.helpers.current_date()
|
|
||||||
|
|
||||||
self.save()
|
# Schedule the order completion task, which will perform the necessary stock movements and other related actions
|
||||||
|
InvenTree.tasks.offload_task(
|
||||||
|
order.tasks.complete_purchase_order, self.pk, group='purchase_order'
|
||||||
|
)
|
||||||
|
|
||||||
unique_parts = set()
|
self.status = PurchaseOrderStatus.COMPLETE.value
|
||||||
|
self.complete_date = InvenTree.helpers.current_date()
|
||||||
# Schedule pricing update for any referenced parts
|
self.save()
|
||||||
for line in self.lines.all().prefetch_related('part__part'):
|
|
||||||
# Ensure we only check 'unique' parts
|
|
||||||
if line.part and line.part.part:
|
|
||||||
unique_parts.add(line.part.part)
|
|
||||||
|
|
||||||
for part in unique_parts:
|
|
||||||
part.schedule_pricing_update(create=True, refresh=False)
|
|
||||||
|
|
||||||
trigger_event(PurchaseOrderEvents.COMPLETED, id=self.pk)
|
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def issue_order(self):
|
def issue_order(self):
|
||||||
@@ -1584,20 +1577,15 @@ class SalesOrder(TotalPriceMixin, Order):
|
|||||||
if not self.can_complete(**kwargs):
|
if not self.can_complete(**kwargs):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Offload task to process the shipment lines
|
||||||
|
InvenTree.tasks.offload_task(
|
||||||
|
order.tasks.complete_sales_order, self.pk, group='sales_order'
|
||||||
|
)
|
||||||
|
|
||||||
bypass_shipped = InvenTree.helpers.str2bool(
|
bypass_shipped = InvenTree.helpers.str2bool(
|
||||||
get_global_setting('SALESORDER_SHIP_COMPLETE')
|
get_global_setting('SALESORDER_SHIP_COMPLETE')
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update line items
|
|
||||||
for line in self.lines.all():
|
|
||||||
# Mark any "virtual" parts as shipped at this point
|
|
||||||
if line.part and line.part.virtual and line.shipped != line.quantity:
|
|
||||||
line.shipped = line.quantity
|
|
||||||
line.save()
|
|
||||||
|
|
||||||
if line.part:
|
|
||||||
line.part.schedule_pricing_update(create=True)
|
|
||||||
|
|
||||||
if bypass_shipped or self.status == SalesOrderStatus.SHIPPED:
|
if bypass_shipped or self.status == SalesOrderStatus.SHIPPED:
|
||||||
self.status = SalesOrderStatus.COMPLETE.value
|
self.status = SalesOrderStatus.COMPLETE.value
|
||||||
else:
|
else:
|
||||||
@@ -1608,9 +1596,6 @@ class SalesOrder(TotalPriceMixin, Order):
|
|||||||
self.shipment_date = InvenTree.helpers.current_date()
|
self.shipment_date = InvenTree.helpers.current_date()
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
trigger_event(SalesOrderEvents.COMPLETED, id=self.pk)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -3459,19 +3444,23 @@ class TransferOrder(Order):
|
|||||||
if not self.can_complete(raise_error=True, **kwargs):
|
if not self.can_complete(raise_error=True, **kwargs):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.status == TransferOrderStatus.ISSUED:
|
if self.status != TransferOrderStatus.ISSUED:
|
||||||
for allocation in self.allocations():
|
return
|
||||||
# execute each transfer
|
|
||||||
allocation.complete_allocation(user)
|
|
||||||
|
|
||||||
self.status = TransferOrderStatus.COMPLETE.value
|
# Offload task to perform the transfer of each allocated stock item
|
||||||
self.complete_date = InvenTree.helpers.current_date()
|
InvenTree.tasks.offload_task(
|
||||||
|
order.tasks.complete_transfer_order,
|
||||||
|
self.pk,
|
||||||
|
user.pk if user else None,
|
||||||
|
group='transfer_order',
|
||||||
|
)
|
||||||
|
|
||||||
self.save()
|
self.status = TransferOrderStatus.COMPLETE.value
|
||||||
|
self.complete_date = InvenTree.helpers.current_date()
|
||||||
|
|
||||||
trigger_event(TransferOrderEvents.COMPLETED, id=self.pk)
|
self.save()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def complete_order(self, user, **kwargs):
|
def complete_order(self, user, **kwargs):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import common.notifications
|
|||||||
import InvenTree.helpers_model
|
import InvenTree.helpers_model
|
||||||
import order.models
|
import order.models
|
||||||
from InvenTree.tasks import ScheduledTask, scheduled_task
|
from InvenTree.tasks import ScheduledTask, scheduled_task
|
||||||
from order.events import PurchaseOrderEvents, SalesOrderEvents
|
from order.events import PurchaseOrderEvents, SalesOrderEvents, TransferOrderEvents
|
||||||
from order.status_codes import (
|
from order.status_codes import (
|
||||||
PurchaseOrderStatusGroups,
|
PurchaseOrderStatusGroups,
|
||||||
ReturnOrderStatusGroups,
|
ReturnOrderStatusGroups,
|
||||||
@@ -273,3 +273,56 @@ def complete_sales_order_shipment(
|
|||||||
|
|
||||||
# Trigger event signalling that the shipment has been completed
|
# Trigger event signalling that the shipment has been completed
|
||||||
trigger_event(SalesOrderEvents.SHIPMENT_COMPLETE, id=shipment.pk)
|
trigger_event(SalesOrderEvents.SHIPMENT_COMPLETE, id=shipment.pk)
|
||||||
|
|
||||||
|
|
||||||
|
@tracer.start_as_current_span('complete_purchase_order')
|
||||||
|
def complete_purchase_order(order_id: int):
|
||||||
|
"""Run completion tasks for a PurchaseOrder that has just been marked as complete."""
|
||||||
|
po = order.models.PurchaseOrder.objects.get(pk=order_id)
|
||||||
|
|
||||||
|
unique_parts = set()
|
||||||
|
|
||||||
|
# Schedule pricing update for any referenced parts
|
||||||
|
for line in po.lines.all().prefetch_related('part__part'):
|
||||||
|
# Ensure we only check 'unique' parts
|
||||||
|
if line.part and line.part.part:
|
||||||
|
unique_parts.add(line.part.part)
|
||||||
|
|
||||||
|
for part in unique_parts:
|
||||||
|
part.schedule_pricing_update(create=True, refresh=False)
|
||||||
|
|
||||||
|
trigger_event(PurchaseOrderEvents.COMPLETED, id=order_id)
|
||||||
|
|
||||||
|
# Trigger event signalling that the purchase order has been completed
|
||||||
|
trigger_event(PurchaseOrderEvents.COMPLETE, id=order_id)
|
||||||
|
|
||||||
|
|
||||||
|
@tracer.start_as_current_span('complete_sales_order')
|
||||||
|
def complete_sales_order(order_id: int):
|
||||||
|
"""Run completion tasks for a SalesOrder that has just been marked as complete."""
|
||||||
|
so = order.models.SalesOrder.objects.get(pk=order_id)
|
||||||
|
|
||||||
|
# Update line items
|
||||||
|
for line in so.lines.all():
|
||||||
|
# Mark any "virtual" parts as shipped at this point
|
||||||
|
if line.part and line.part.virtual and line.shipped != line.quantity:
|
||||||
|
line.shipped = line.quantity
|
||||||
|
line.save()
|
||||||
|
|
||||||
|
if line.part:
|
||||||
|
line.part.schedule_pricing_update(create=True)
|
||||||
|
|
||||||
|
trigger_event(SalesOrderEvents.COMPLETED, id=order_id)
|
||||||
|
|
||||||
|
|
||||||
|
@tracer.start_as_current_span('complete_transfer_order')
|
||||||
|
def complete_transfer_order(order_id: int, user_id: int):
|
||||||
|
"""Run completion tasks for a TransferOrder that has just been marked as complete."""
|
||||||
|
transfer_order = order.models.TransferOrder.objects.get(pk=order_id)
|
||||||
|
user = User.objects.filter(pk=user_id).first() if user_id else None
|
||||||
|
|
||||||
|
for allocation in transfer_order.allocations():
|
||||||
|
# execute each transfer
|
||||||
|
allocation.complete_allocation(user)
|
||||||
|
|
||||||
|
trigger_event(TransferOrderEvents.COMPLETED, id=order_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user