Repository: inventree/InvenTree

Issue:
calc price when adding new item to purchase / sales order
Suggest the price based on the price_breaks and quantity of the selected part automatically when:

- [x] purchase order item is added
- [x] sales order item is added



Discussion:

Resolving patch:
diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py
--- a/InvenTree/order/models.py
+++ b/InvenTree/order/models.py
@@ -223,7 +223,7 @@ def get_absolute_url(self):
         return reverse('po-detail', kwargs={'pk': self.id})
 
     @transaction.atomic
-    def add_line_item(self, supplier_part, quantity, group=True, reference=''):
+    def add_line_item(self, supplier_part, quantity, group=True, reference='', purchase_price=None):
         """ Add a new line item to this purchase order.
         This function will check that:
 
@@ -254,7 +254,12 @@ def add_line_item(self, supplier_part, quantity, group=True, reference=''):
             if matches.count() > 0:
                 line = matches.first()
 
-                line.quantity += quantity
+                # update quantity and price
+                quantity_new = line.quantity + quantity
+                line.quantity = quantity_new
+                supplier_price = supplier_part.get_price(quantity_new)
+                if line.purchase_price and supplier_price:
+                    line.purchase_price = supplier_price / quantity_new
                 line.save()
 
                 return
@@ -263,7 +268,9 @@ def add_line_item(self, supplier_part, quantity, group=True, reference=''):
             order=self,
             part=supplier_part,
             quantity=quantity,
-            reference=reference)
+            reference=reference,
+            purchase_price=purchase_price,
+        )
 
         line.save()
 
@@ -329,7 +336,7 @@ def is_complete(self):
         return self.pending_line_items().count() == 0
 
     @transaction.atomic
-    def receive_line_item(self, line, location, quantity, user, status=StockStatus.OK):
+    def receive_line_item(self, line, location, quantity, user, status=StockStatus.OK, purchase_price=None):
         """ Receive a line item (or partial line item) against this PO
         """
 
@@ -353,7 +360,8 @@ def receive_line_item(self, line, location, quantity, user, status=StockStatus.O
                 location=location,
                 quantity=quantity,
                 purchase_order=self,
-                status=status
+                status=status,
+                purchase_price=purchase_price,
             )
 
             stock.save()
diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py
--- a/InvenTree/order/views.py
+++ b/InvenTree/order/views.py
@@ -776,6 +776,7 @@ def receive_parts(self):
                 line.receive_quantity,
                 self.request.user,
                 status=line.status_code,
+                purchase_price=line.purchase_price,
             )
 
 
@@ -996,6 +997,14 @@ def post(self, request, *args, **kwargs):
                 part.order_supplier = supplier_part.id if supplier_part else None
                 part.order_quantity = quantity
 
+                # set supplier-price
+                if supplier_part:
+                    supplier_price = supplier_part.get_price(quantity)
+                    if supplier_price:
+                        part.purchase_price = supplier_price / quantity
+                if not hasattr(part, 'purchase_price'):
+                    part.purchase_price = None
+
                 self.parts.append(part)
 
                 if supplier_part is None:
@@ -1095,7 +1104,10 @@ def order_items(self):
                         sp=item.order_supplier))
                     continue
 
-                order.add_line_item(supplier_part, quantity)
+                # get purchase price
+                purchase_price = item.purchase_price
+
+                order.add_line_item(supplier_part, quantity, purchase_price=purchase_price)
 
 
 class POLineItemCreate(AjaxCreateView):


Test patch: