Fix for SalesOrderLineItem allocation calculation

Also function to render a progress bar
This commit is contained in:
Oliver Walters 2020-04-21 16:45:44 +10:00
parent a1376eeb9e
commit 89ede3e103
5 changed files with 48 additions and 13 deletions

View File

@ -47,7 +47,7 @@
width: 100%;
left: 0px;
font-weight: bold;
font-size: 120%;
font-size: 110%;
}
.progress-bar-inner {

View File

@ -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.

View File

@ -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']

View File

@ -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);
}
},
{

View File

@ -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)