2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-01 11:10:54 +00:00

Merge remote-tracking branch 'inventree/master'

This commit is contained in:
Oliver Walters
2019-11-16 20:45:34 +11:00
10 changed files with 481 additions and 79 deletions

View File

@ -357,7 +357,7 @@ class StockItem(models.Model):
choices=StockStatus.items(),
validators=[MinValueValidator(0)])
notes = models.CharField(max_length=250, blank=True, help_text='Stock Item Notes')
notes = models.CharField(max_length=250, blank=True, help_text=_('Stock Item Notes'))
# If stock item is incoming, an (optional) ETA field
# expected_arrival = models.DateField(null=True, blank=True)

View File

@ -1,10 +1,11 @@
{% extends "stock/stock_app_base.html" %}
{% load static %}
{% load i18n %}
{% block content %}
<div class='row'>
<div class='col-sm-6'>
<h3>Stock Item Details</h3>
<h3>{% trans "Stock Item Details" %}</h3>
{% if item.serialized %}
<p><i>{{ item.part.full_name}} # {{ item.serial }}</i></p>
{% else %}
@ -47,11 +48,11 @@
</p>
{% if item.serialized %}
<div class='alert alert-block alert-info'>
This stock item is serialized - it has a unique serial number and the quantity cannot be adjusted.
{% trans "This stock item is serialized - it has a unique serial number and the quantity cannot be adjusted." %}
</div>
{% elif item.delete_on_deplete %}
<div class='alert alert-block alert-warning'>
This stock item will be automatically deleted when all stock is depleted.
{% trans "This stock item will be automatically deleted when all stock is depleted." %}
</div>
{% endif %}
</div>
@ -68,85 +69,85 @@
</tr>
{% if item.belongs_to %}
<tr>
<td>Belongs To</td>
<td>{% trans "Belongs To" %}</td>
<td><a href="{% url 'stock-item-detail' item.belongs_to.id %}">{{ item.belongs_to }}</a></td>
</tr>
{% elif item.location %}
<tr>
<td>Location</td>
<td>{% trans "Location" %}</td>
<td><a href="{% url 'stock-location-detail' item.location.id %}">{{ item.location.name }}</a></td>
</tr>
{% endif %}
{% if item.serialized %}
<tr>
<td>Serial Number</td>
<td>{% trans "Serial Number" %}</td>
<td>{{ item.serial }}</td>
</tr>
{% else %}
<tr>
<td>Quantity</td>
<td>{% trans "Quantity" %}</td>
<td>{{ item.quantity }}</td>
</tr>
{% endif %}
{% if item.batch %}
<tr>
<td>Batch</td>
<td>{% trans "Batch" %}</td>
<td>{{ item.batch }}</td>
</tr>
{% endif %}
{% if item.build %}
<tr>
<td>Build</td>
<td>{% trans "Build" %}</td>
<td><a href="{% url 'build-detail' item.build.id %}">{{ item.build }}</a></td>
</tr>
{% endif %}
{% if item.purchase_order %}
<tr>
<td>Purchase Order</td>
<td>{% trans "Purchase Order" %}</td>
<td><a href="{% url 'purchase-order-detail' item.purchase_order.id %}">{{ item.purchase_order }}</a></td>
</tr>
{% endif %}
{% if item.customer %}
<tr>
<td>Customer</td>
<td>{% trans "Customer" %}</td>
<td>{{ item.customer.name }}</td>
</tr>
{% endif %}
{% if item.URL %}
<tr>
<td>URL</td>
<td>{% trans "URL" %}</td>
<td><a href="{{ item.URL }}">{{ item.URL }}</a></td>
</tr>
{% endif %}
{% if item.supplier_part %}
<tr>
<td>Supplier</td>
<td>{% trans "Supplier" %}</td>
<td><a href="{% url 'company-detail' item.supplier_part.supplier.id %}">{{ item.supplier_part.supplier.name }}</a></td>
</tr>
<tr>
<td>Supplier Part</td>
<td>{% trans "Supplier Part" %}</td>
<td><a href="{% url 'supplier-part-detail' item.supplier_part.id %}">{{ item.supplier_part.SKU }}</a></td>
</tr>
{% endif %}
<tr>
<td>Last Updated</td>
<td>{% trans "Last Updated" %}</td>
<td>{{ item.updated }}</td>
</tr>
<tr>
<td>Last Stocktake</td>
<td>{% trans "Last Stocktake" %}</td>
{% if item.stocktake_date %}
<td>{{ item.stocktake_date }} <span class='badge'>{{ item.stocktake_user }}</span></td>
{% else %}
<td>No stocktake performed</td>
<td>{% trans "No stocktake performed" %}</td>
{% endif %}
</tr>
<tr>
<td>Status</td>
<td>{% trans "Status" %}</td>
<td>{{ item.get_status_display }}</td>
</tr>
{% if item.notes %}
<tr>
<td>Notes</td>
<td>{% trans "Notes" %}</td>
<td>{{ item.notes }}</td>
</tr>
{% endif %}
@ -155,7 +156,7 @@
</div>
<hr>
<h4>Stock Tracking Information</h4>
<h4>{% trans "Stock Tracking Information" %}</h4>
<div id='table-toolbar'>
<div class='btn-group'>
<button class='btn btn-success' type='button' title='New tracking entry' id='new-entry'>New Entry</button>

View File

@ -1,3 +1,5 @@
{% load i18n %}
{% block pre_form_content %}
{% endblock %}
@ -10,9 +12,13 @@
<table class='table table-condensed table-striped' id='stock-table'>
<tr>
<th>Stock Item</th>
<th>Location</th>
<th>{% trans "Stock Item" %}</th>
<th>{% trans "Location" %}</th>
{% if edit_quantity %}
<th>{{ stock_action_title }}</th>
{% else %}
<th>{% trans "Quantity" %}</th>
{% endif %}
<th></th>
</tr>
{% for item in stock_items %}
@ -21,6 +27,7 @@
{{ item.part.full_name }} <small><i>{{ item.part.description }}</i></small></td>
<td>{{ item.location.pathstring }}</td>
<td>
{% if edit_quantity %}
<input class='numberinput'
min='0'
{% if stock_action == 'take' or stock_action == 'move' %} max='{{ item.quantity }}' {% endif %}
@ -28,6 +35,10 @@
{% if item.error %}
<br><span class='help-inline'>{{ item.error }}</span>
{% endif %}
{% else %}
{{ item.new_quantity }}
<input type='hidden' name='stock-id-{{ item.id }}' value='{{ item.new_quantity }}'/>
{% endif %}
</td>
<td><button class='btn btn-default btn-remove' onclick='removeStockRow()' id='del-{{ item.id }}' title='Remove item' type='button'><span row='stock-row-{{ item.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span></button></td>
</tr>

View File

@ -256,6 +256,7 @@ class StockAdjust(AjaxView, FormMixin):
- Add items to stock
- Count items
- Move stock
- Delete stock items
"""
@ -337,10 +338,13 @@ class StockAdjust(AjaxView, FormMixin):
context['stock_items'] = self.stock_items
context['stock_action'] = self.stock_action
context['stock_action'] = self.stock_action.strip().lower()
context['stock_action_title'] = self.stock_action.capitalize()
# Quantity column will be read-only in some circumstances
context['edit_quantity'] = not self.stock_action == 'delete'
return context
def get_form(self):
@ -361,15 +365,16 @@ class StockAdjust(AjaxView, FormMixin):
self.stock_action = request.GET.get('action', '').lower()
# Pick a default action...
if self.stock_action not in ['move', 'count', 'take', 'add']:
if self.stock_action not in ['move', 'count', 'take', 'add', 'delete']:
self.stock_action = 'count'
# Choose the form title based on the action
titles = {
'move': 'Move Stock',
'count': 'Count Stock',
'take': 'Remove Stock',
'add': 'Add Stock'
'move': _('Move Stock Items'),
'count': _('Count Stock Items'),
'take': _('Remove From Stock'),
'add': _('Add Stock Items'),
'delete': _('Delete Stock Items')
}
self.ajax_form_title = titles[self.stock_action]
@ -383,7 +388,7 @@ class StockAdjust(AjaxView, FormMixin):
self.request = request
self.stock_action = request.POST.get('stock_action', 'invalid').lower()
self.stock_action = request.POST.get('stock_action', 'invalid').strip().lower()
# Update list of stock items
self.stock_items = self.get_POST_items()
@ -468,6 +473,9 @@ class StockAdjust(AjaxView, FormMixin):
elif self.stock_action == 'count':
return self.do_count()
elif self.stock_action == 'delete':
return self.do_delete()
else:
return 'No action performed'
@ -547,6 +555,23 @@ class StockAdjust(AjaxView, FormMixin):
n=count,
dest=destination.pathstring))
def do_delete(self):
""" Delete multiple stock items """
count = 0
# note = self.request.POST['note']
for item in self.stock_items:
# TODO - In the future, StockItems should not be 'deleted'
# TODO - Instead, they should be marked as "inactive"
item.delete()
count += 1
return _("Deleted {n} stock items".format(n=count))
class StockItemEdit(AjaxUpdateView):
"""