Merge branch 'master' of github.com:inventree/InvenTree into multi_part_forms

This commit is contained in:
eeintech 2021-05-06 11:30:08 -04:00
commit 005063aad6
30 changed files with 4420 additions and 3792 deletions

View File

@ -74,7 +74,7 @@ def validate_build_order_reference(value):
match = re.search(pattern, value) match = re.search(pattern, value)
if match is None: if match is None:
raise ValidationError(_('Reference must match pattern') + f" '{pattern}'") raise ValidationError(_('Reference must match pattern {pattern}').format(pattern=pattern))
def validate_purchase_order_reference(value): def validate_purchase_order_reference(value):
@ -88,7 +88,7 @@ def validate_purchase_order_reference(value):
match = re.search(pattern, value) match = re.search(pattern, value)
if match is None: if match is None:
raise ValidationError(_('Reference must match pattern') + f" '{pattern}'") raise ValidationError(_('Reference must match pattern {pattern}').format(pattern=pattern))
def validate_sales_order_reference(value): def validate_sales_order_reference(value):
@ -102,7 +102,7 @@ def validate_sales_order_reference(value):
match = re.search(pattern, value) match = re.search(pattern, value)
if match is None: if match is None:
raise ValidationError(_('Reference must match pattern') + f" '{pattern}'") raise ValidationError(_('Reference must match pattern {pattern}').format(pattern=pattern))
def validate_tree_name(value): def validate_tree_name(value):

View File

@ -158,6 +158,8 @@ $('#view-calendar').click(function() {
$("#build-order-calendar").show(); $("#build-order-calendar").show();
$("#view-list").show(); $("#view-list").show();
calendar.render();
}); });
$("#view-list").click(function() { $("#view-list").click(function() {

View File

@ -202,7 +202,7 @@ class CompanyImageDownloadFromURL(AjaxUpdateView):
# Check for valid response code # Check for valid response code
if not response.status_code == 200: if not response.status_code == 200:
form.add_error('url', f"{_('Invalid response')}: {response.status_code}") form.add_error('url', _('Invalid response: {code}').format(code=response.status_code))
return return
response.raw.decode_content = True response.raw.decode_content = True

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -223,7 +223,7 @@ class PurchaseOrder(Order):
return reverse('po-detail', kwargs={'pk': self.id}) return reverse('po-detail', kwargs={'pk': self.id})
@transaction.atomic @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. """ Add a new line item to this purchase order.
This function will check that: This function will check that:
@ -254,7 +254,12 @@ class PurchaseOrder(Order):
if matches.count() > 0: if matches.count() > 0:
line = matches.first() 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() line.save()
return return
@ -263,7 +268,9 @@ class PurchaseOrder(Order):
order=self, order=self,
part=supplier_part, part=supplier_part,
quantity=quantity, quantity=quantity,
reference=reference) reference=reference,
purchase_price=purchase_price,
)
line.save() line.save()
@ -329,7 +336,7 @@ class PurchaseOrder(Order):
return self.pending_line_items().count() == 0 return self.pending_line_items().count() == 0
@transaction.atomic @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 """ Receive a line item (or partial line item) against this PO
""" """
@ -353,13 +360,14 @@ class PurchaseOrder(Order):
location=location, location=location,
quantity=quantity, quantity=quantity,
purchase_order=self, purchase_order=self,
status=status status=status,
purchase_price=purchase_price,
) )
stock.save() stock.save()
text = _("Received items") text = _("Received items")
note = f"{_('Received')} {quantity} {_('items against order')} {str(self)}" note = _('Received {n} items against order {name}').format(n=quantity, name=str(self))
# Add a new transaction note to the newly created stock item # Add a new transaction note to the newly created stock item
stock.addTransactionNote(text, user, note) stock.addTransactionNote(text, user, note)

View File

@ -146,6 +146,8 @@ $('#view-calendar').click(function() {
$("#purchase-order-calendar").show(); $("#purchase-order-calendar").show();
$("#view-list").show(); $("#view-list").show();
calendar.render();
}); });
$("#view-list").click(function() { $("#view-list").click(function() {

View File

@ -144,6 +144,8 @@ $('#view-calendar').click(function() {
$("#sales-order-calendar").show(); $("#sales-order-calendar").show();
$("#view-list").show(); $("#view-list").show();
calendar.render();
}); });
$("#view-list").click(function() { $("#view-list").click(function() {

View File

@ -1183,6 +1183,7 @@ class PurchaseOrderReceive(AjaxUpdateView):
line.receive_quantity, line.receive_quantity,
self.request.user, self.request.user,
status=line.status_code, status=line.status_code,
purchase_price=line.purchase_price,
) )
@ -1403,6 +1404,14 @@ class OrderParts(AjaxView):
part.order_supplier = supplier_part.id if supplier_part else None part.order_supplier = supplier_part.id if supplier_part else None
part.order_quantity = quantity 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) self.parts.append(part)
if supplier_part is None: if supplier_part is None:
@ -1502,7 +1511,10 @@ class OrderParts(AjaxView):
sp=item.order_supplier)) sp=item.order_supplier))
continue 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): class POLineItemCreate(AjaxCreateView):
@ -1802,7 +1814,7 @@ class SalesOrderAssignSerials(AjaxView, FormMixin):
except StockItem.DoesNotExist: except StockItem.DoesNotExist:
self.form.add_error( self.form.add_error(
'serials', 'serials',
_('No matching item for serial') + f" '{serial}'" _('No matching item for serial {serial}').format(serial=serial)
) )
continue continue
@ -1812,7 +1824,7 @@ class SalesOrderAssignSerials(AjaxView, FormMixin):
if not stock_item.in_stock: if not stock_item.in_stock:
self.form.add_error( self.form.add_error(
'serials', 'serials',
f"'{serial}' " + _("is not in stock") _('{serial} is not in stock').format(serial=serial)
) )
continue continue
@ -1820,7 +1832,7 @@ class SalesOrderAssignSerials(AjaxView, FormMixin):
if stock_item.is_allocated(): if stock_item.is_allocated():
self.form.add_error( self.form.add_error(
'serials', 'serials',
f"'{serial}' " + _("already allocated to an order") _('{serial} already allocated to an order').format(serial=serial)
) )
continue continue

View File

@ -91,7 +91,7 @@
{% if part.salable and roles.sales_order.view %} {% if part.salable and roles.sales_order.view %}
<li class='list-group-item {% if tab == "sales-prices" %}active{% endif %}' title='{% trans "Sales Price Information" %}'> <li class='list-group-item {% if tab == "sales-prices" %}active{% endif %}' title='{% trans "Sales Price Information" %}'>
<a href='{% url "part-sale-prices" part.id %}'> <a href='{% url "part-sale-prices" part.id %}'>
<span class='menu-tab-icon fas fa-dollar-sign'></span> <span class='menu-tab-icon fas fa-dollar-sign' style='width: 20px;'></span>
{% trans "Sale Price" %} {% trans "Sale Price" %}
</a> </a>
</li> </li>

View File

@ -2,7 +2,7 @@
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
{% block menubar %}} {% block menubar %}
{% include 'part/navbar.html' with tab='sales-prices' %} {% include 'part/navbar.html' with tab='sales-prices' %}
{% endblock %} {% endblock %}

View File

@ -884,7 +884,7 @@ class PartImageDownloadFromURL(AjaxUpdateView):
# Check for valid response code # Check for valid response code
if not response.status_code == 200: if not response.status_code == 200:
form.add_error('url', f"{_('Invalid response')}: {response.status_code}") form.add_error('url', _('Invalid response: {code}').format(code=response.status_code))
return return
response.raw.decode_content = True response.raw.decode_content = True

View File

@ -198,7 +198,7 @@ class StockItem(MPTTModel):
if add_note: if add_note:
note = f"{_('Created new stock item for')} {str(self.part)}" note = _('Created new stock item for {part}').format(part=str(self.part))
# This StockItem is being saved for the first time # This StockItem is being saved for the first time
self.addTransactionNote( self.addTransactionNote(
@ -613,7 +613,7 @@ class StockItem(MPTTModel):
item.addTransactionNote( item.addTransactionNote(
_("Assigned to Customer"), _("Assigned to Customer"),
user, user,
notes=_("Manually assigned to customer") + " " + customer.name, notes=_("Manually assigned to customer {name}").format(name=customer.name),
system=True system=True
) )
@ -626,9 +626,9 @@ class StockItem(MPTTModel):
""" """
self.addTransactionNote( self.addTransactionNote(
_("Returned from customer") + f" {self.customer.name}", _("Returned from customer {name}").format(name=self.customer.name),
user, user,
notes=_("Returned to location") + f" {location.name}", notes=_("Returned to location {loc}").format(loc=location.name),
system=True system=True
) )
@ -789,7 +789,7 @@ class StockItem(MPTTModel):
# Add a transaction note to the other item # Add a transaction note to the other item
stock_item.addTransactionNote( stock_item.addTransactionNote(
_('Installed into stock item') + ' ' + str(self.pk), _('Installed into stock item {pk}').format(str(self.pk)),
user, user,
notes=notes, notes=notes,
url=self.get_absolute_url() url=self.get_absolute_url()
@ -797,7 +797,7 @@ class StockItem(MPTTModel):
# Add a transaction note to this item # Add a transaction note to this item
self.addTransactionNote( self.addTransactionNote(
_('Installed stock item') + ' ' + str(stock_item.pk), _('Installed stock item {pk}').format(str(stock_item.pk)),
user, notes=notes, user, notes=notes,
url=stock_item.get_absolute_url() url=stock_item.get_absolute_url()
) )
@ -821,7 +821,7 @@ class StockItem(MPTTModel):
# Add a transaction note to the parent item # Add a transaction note to the parent item
self.belongs_to.addTransactionNote( self.belongs_to.addTransactionNote(
_("Uninstalled stock item") + ' ' + str(self.pk), _("Uninstalled stock item {pk}").format(pk=str(self.pk)),
user, user,
notes=notes, notes=notes,
url=self.get_absolute_url(), url=self.get_absolute_url(),
@ -840,7 +840,7 @@ class StockItem(MPTTModel):
# Add a transaction note! # Add a transaction note!
self.addTransactionNote( self.addTransactionNote(
_('Uninstalled into location') + ' ' + str(location), _('Uninstalled into location {loc}').formaT(loc=str(location)),
user, user,
notes=notes, notes=notes,
url=url url=url
@ -966,7 +966,7 @@ class StockItem(MPTTModel):
if len(existing) > 0: if len(existing) > 0:
exists = ','.join([str(x) for x in existing]) exists = ','.join([str(x) for x in existing])
raise ValidationError({"serial_numbers": _("Serial numbers already exist") + ': ' + exists}) raise ValidationError({"serial_numbers": _("Serial numbers already exist: {exists}").format(exists=exists)})
# Create a new stock item for each unique serial number # Create a new stock item for each unique serial number
for serial in serials: for serial in serials:
@ -1074,7 +1074,7 @@ class StockItem(MPTTModel):
new_stock.addTransactionNote( new_stock.addTransactionNote(
_("Split from existing stock"), _("Split from existing stock"),
user, user,
f"{_('Split')} {helpers.normalize(quantity)} {_('items')}" _('Split {n} items').format(n=helpers.normalize(quantity))
) )
# Remove the specified quantity from THIS stock item # Remove the specified quantity from THIS stock item
@ -1131,10 +1131,10 @@ class StockItem(MPTTModel):
return True return True
msg = f"{_('Moved to')} {str(location)}"
if self.location: if self.location:
msg += f" ({_('from')} {str(self.location)})" msg = _("Moved to {loc_new} (from {loc_old})").format(loc_new=str(location), loc_old=str(self.location))
else:
msg = _('Moved to {loc_new}').format(loc_new=str(location))
self.location = location self.location = location
@ -1202,9 +1202,7 @@ class StockItem(MPTTModel):
if self.updateQuantity(count): if self.updateQuantity(count):
n = helpers.normalize(count) text = _('Counted {n} items').format(n=helpers.normalize(count))
text = f"{_('Counted')} {n} {_('items')}"
self.addTransactionNote( self.addTransactionNote(
text, text,
@ -1237,8 +1235,7 @@ class StockItem(MPTTModel):
if self.updateQuantity(self.quantity + quantity): if self.updateQuantity(self.quantity + quantity):
n = helpers.normalize(quantity) text = _('Added {n} items').format(n=helpers.normalize(quantity))
text = f"{_('Added')} {n} {_('items')}"
self.addTransactionNote( self.addTransactionNote(
text, text,
@ -1268,8 +1265,7 @@ class StockItem(MPTTModel):
if self.updateQuantity(self.quantity - quantity): if self.updateQuantity(self.quantity - quantity):
q = helpers.normalize(quantity) text = _('Removed {n1} items').format(n1=helpers.normalize(quantity))
text = f"{_('Removed')} {q} {_('items')}"
self.addTransactionNote(text, self.addTransactionNote(text,
user, user,

View File

@ -65,7 +65,7 @@ def manage(c, cmd, pty=False):
cmd - django command to run cmd - django command to run
""" """
c.run('cd {path} && python3 manage.py {cmd}'.format( c.run('cd "{path}" && python3 manage.py {cmd}'.format(
path=managePyDir(), path=managePyDir(),
cmd=cmd cmd=cmd
), pty=pty) ), pty=pty)
@ -185,7 +185,7 @@ def translate(c):
""" """
# Translate applicable .py / .html / .js files # Translate applicable .py / .html / .js files
manage(c, "makemessages --all -e py,html,js") manage(c, "makemessages --all -e py,html,js --no-wrap")
manage(c, "compilemessages") manage(c, "compilemessages")
path = os.path.join('InvenTree', 'script', 'translation_stats.py') path = os.path.join('InvenTree', 'script', 'translation_stats.py')