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:
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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):
|
||||
"""
|
||||
|
Reference in New Issue
Block a user