mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 21:25:42 +00:00 
			
		
		
		
	Fix for SalesOrderLineItem allocation calculation
Also function to render a progress bar
This commit is contained in:
		| @@ -47,7 +47,7 @@ | ||||
|     width: 100%; | ||||
|     left: 0px; | ||||
|     font-weight: bold; | ||||
|     font-size: 120%; | ||||
|     font-size: 110%; | ||||
| } | ||||
|  | ||||
| .progress-bar-inner { | ||||
|   | ||||
| @@ -78,6 +78,33 @@ function getImageUrlFromTransfer(transfer) { | ||||
|     return url; | ||||
| } | ||||
|  | ||||
| function makeProgressBar(value, maximum, opts) { | ||||
|     /* | ||||
|      * Render a progessbar! | ||||
|      *  | ||||
|      * @param value is the current value of the progress bar | ||||
|      * @param maximum is the maximum value of the progress bar | ||||
|      */ | ||||
|  | ||||
|     var options = opts || {}; | ||||
|  | ||||
|     value = parseFloat(value); | ||||
|     maximum = parseFloat(maximum); | ||||
|  | ||||
|     var percent = parseInt(value / maximum * 100); | ||||
|  | ||||
|     if (percent > 100) { | ||||
|         percent = 100; | ||||
|     } | ||||
|  | ||||
|     return ` | ||||
|         <div class='progress-bar'> | ||||
|             <div class='progress-bar progress-bar-inner' style='width: ${percent}%;'></div> | ||||
|             <div class='progress-bar-value'>${value} / ${maximum}</div> | ||||
|         </div> | ||||
|     `; | ||||
| } | ||||
|  | ||||
|  | ||||
| function enableDragAndDrop(element, url, options) { | ||||
|     /* Enable drag-and-drop file uploading for a given element. | ||||
|   | ||||
| @@ -19,9 +19,7 @@ import os | ||||
| from datetime import datetime | ||||
| from decimal import Decimal | ||||
|  | ||||
| from stock.models import StockItem | ||||
| from company.models import Company, SupplierPart | ||||
| from part.models import Part | ||||
|  | ||||
| from InvenTree.fields import RoundingDecimalField | ||||
| from InvenTree.helpers import decimal2string | ||||
| @@ -372,7 +370,7 @@ class SalesOrderLineItem(OrderLineItem): | ||||
|  | ||||
|     order = models.ForeignKey(SalesOrder, on_delete=models.CASCADE, related_name='lines', help_text=_('Sales Order')) | ||||
|  | ||||
|     part = models.ForeignKey(Part, on_delete=models.SET_NULL, related_name='sales_order_line_items', null=True, help_text=_('Part'), limit_choices_to={'salable': True}) | ||||
|     part = models.ForeignKey('part.Part', on_delete=models.SET_NULL, related_name='sales_order_line_items', null=True, help_text=_('Part'), limit_choices_to={'salable': True}) | ||||
|  | ||||
|     def allocated_quantity(self): | ||||
|         """ Return the total stock quantity allocated to this LineItem. | ||||
| @@ -380,6 +378,6 @@ class SalesOrderLineItem(OrderLineItem): | ||||
|         This is a summation of the quantity of each attached StockItem | ||||
|         """ | ||||
|  | ||||
|         query = self.stock_items.aggregate(allocated=Coalesce(Sum('stock_item__quantity'), Decimal(0))) | ||||
|         query = self.stock_items.aggregate(allocated=Coalesce(Sum('quantity'), Decimal(0))) | ||||
|  | ||||
|         return query['allocated'] | ||||
|   | ||||
| @@ -72,12 +72,7 @@ $("#so-lines-table").inventreeTable({ | ||||
|             field: 'quantity', | ||||
|             title: 'Quantity', | ||||
|             formatter: function(value, row, index, field) { | ||||
|                 return ` | ||||
|                 <div class='progress-bar'> | ||||
|                     <div class='progress-bar progress-bar-inner' style='width: 50%;'></div> | ||||
|                     <div class='progress-bar-value'>${row.allocated} / ${row.quantity}</div> | ||||
|                 </div> | ||||
|                 `; | ||||
|                 return makeProgressBar(row.allocated, row.quantity); | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|   | ||||
| @@ -29,6 +29,7 @@ from InvenTree.models import InvenTreeTree | ||||
| from InvenTree.fields import InvenTreeURLField | ||||
|  | ||||
| from part.models import Part | ||||
| from order.models import PurchaseOrder, SalesOrderLineItem | ||||
|  | ||||
|  | ||||
| class StockLocation(InvenTreeTree): | ||||
| @@ -262,6 +263,20 @@ class StockItem(MPTTModel): | ||||
|             # TODO - Find a test than can be perfomed... | ||||
|             pass | ||||
|  | ||||
|         try: | ||||
|             # If this StockItem is assigned to a SalesOrderLineItem, | ||||
|             # the "Part" that the line item references is the same as the part that THIS references | ||||
|             if self.sales_order is not None: | ||||
|  | ||||
|                 if self.sales_order.part == None: | ||||
|                     raise ValidationError({'sales_order': _('Stock item cannot be assigned to a LineItem which does not reference a part')}) | ||||
|                  | ||||
|                 if not self.sales_order.part == self.part: | ||||
|                     raise ValidationError({'sales_order': _('Stock item does not reference the same part object as the LineItem')}) | ||||
|  | ||||
|         except SalesOrderLineItem.DoesNotExist: | ||||
|             pass | ||||
|  | ||||
|         if self.belongs_to and self.belongs_to.pk == self.pk: | ||||
|             raise ValidationError({ | ||||
|                 'belongs_to': _('Item cannot belong to itself') | ||||
| @@ -347,7 +362,7 @@ class StockItem(MPTTModel): | ||||
|     ) | ||||
|  | ||||
|     purchase_order = models.ForeignKey( | ||||
|         'order.PurchaseOrder', | ||||
|         PurchaseOrder, | ||||
|         on_delete=models.SET_NULL, | ||||
|         related_name='stock_items', | ||||
|         blank=True, null=True, | ||||
| @@ -355,7 +370,7 @@ class StockItem(MPTTModel): | ||||
|     ) | ||||
|  | ||||
|     sales_order = models.ForeignKey( | ||||
|         'order.SalesOrderLineItem', | ||||
|         SalesOrderLineItem, | ||||
|         on_delete=models.SET_NULL, | ||||
|         related_name='stock_items', | ||||
|         null=True) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user