mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #2837 from SchrodingersGat/variant-tracking
Variant tracking
This commit is contained in:
commit
71b4c64e4d
@ -255,6 +255,9 @@ class StockHistoryCode(StatusCode):
|
|||||||
# Stock merging operations
|
# Stock merging operations
|
||||||
MERGED_STOCK_ITEMS = 45
|
MERGED_STOCK_ITEMS = 45
|
||||||
|
|
||||||
|
# Convert stock item to variant
|
||||||
|
CONVERTED_TO_VARIANT = 48
|
||||||
|
|
||||||
# Build order codes
|
# Build order codes
|
||||||
BUILD_OUTPUT_CREATED = 50
|
BUILD_OUTPUT_CREATED = 50
|
||||||
BUILD_OUTPUT_COMPLETED = 55
|
BUILD_OUTPUT_COMPLETED = 55
|
||||||
@ -294,6 +297,8 @@ class StockHistoryCode(StatusCode):
|
|||||||
|
|
||||||
MERGED_STOCK_ITEMS: _('Merged stock items'),
|
MERGED_STOCK_ITEMS: _('Merged stock items'),
|
||||||
|
|
||||||
|
CONVERTED_TO_VARIANT: _('Converted to variant'),
|
||||||
|
|
||||||
SENT_TO_CUSTOMER: _('Sent to customer'),
|
SENT_TO_CUSTOMER: _('Sent to customer'),
|
||||||
RETURNED_FROM_CUSTOMER: _('Returned from customer'),
|
RETURNED_FROM_CUSTOMER: _('Returned from customer'),
|
||||||
|
|
||||||
|
@ -1234,6 +1234,15 @@ class StockTrackingList(generics.ListAPIView):
|
|||||||
if not deltas:
|
if not deltas:
|
||||||
deltas = {}
|
deltas = {}
|
||||||
|
|
||||||
|
# Add part detail
|
||||||
|
if 'part' in deltas:
|
||||||
|
try:
|
||||||
|
part = Part.objects.get(pk=deltas['part'])
|
||||||
|
serializer = PartBriefSerializer(part)
|
||||||
|
deltas['part_detail'] = serializer.data
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
# Add location detail
|
# Add location detail
|
||||||
if 'location' in deltas:
|
if 'location' in deltas:
|
||||||
try:
|
try:
|
||||||
|
@ -718,6 +718,33 @@ class StockItem(MPTTModel):
|
|||||||
help_text=_('Select Owner'),
|
help_text=_('Select Owner'),
|
||||||
related_name='stock_items')
|
related_name='stock_items')
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def convert_to_variant(self, variant, user, notes=None):
|
||||||
|
"""
|
||||||
|
Convert this StockItem instance to a "variant",
|
||||||
|
i.e. change the "part" reference field
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not variant:
|
||||||
|
# Ignore null values
|
||||||
|
return
|
||||||
|
|
||||||
|
if variant == self.part:
|
||||||
|
# Variant is the same as the current part
|
||||||
|
return
|
||||||
|
|
||||||
|
self.part = variant
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
self.add_tracking_entry(
|
||||||
|
StockHistoryCode.CONVERTED_TO_VARIANT,
|
||||||
|
user,
|
||||||
|
deltas={
|
||||||
|
'part': variant.pk,
|
||||||
|
},
|
||||||
|
notes=_('Converted to part') + ': ' + variant.full_name,
|
||||||
|
)
|
||||||
|
|
||||||
def get_item_owner(self):
|
def get_item_owner(self):
|
||||||
"""
|
"""
|
||||||
Return the closest "owner" for this StockItem.
|
Return the closest "owner" for this StockItem.
|
||||||
|
@ -26,11 +26,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='panel-content'>
|
<div class='panel-content'>
|
||||||
<div id='table-toolbar'>
|
<div id='tracking-table-toolbar'>
|
||||||
<div class='btn-group'>
|
<div class='btn-group'>
|
||||||
|
{% include "filter_list.html" with id="stocktracking" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class='table table-condensed table-striped' id='track-table' data-toolbar='#table-toolbar'>
|
<table class='table table-condensed table-striped' id='track-table' data-toolbar='#tracking-table-toolbar'>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -342,7 +343,6 @@
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
loadStockTrackingTable($("#track-table"), {
|
loadStockTrackingTable($("#track-table"), {
|
||||||
params: {
|
params: {
|
||||||
ordering: '-date',
|
ordering: '-date',
|
||||||
|
@ -644,6 +644,16 @@ class StockItemConvert(AjaxUpdateView):
|
|||||||
|
|
||||||
return form
|
return form
|
||||||
|
|
||||||
|
def save(self, obj, form):
|
||||||
|
|
||||||
|
stock_item = self.get_object()
|
||||||
|
|
||||||
|
variant = form.cleaned_data.get('part', None)
|
||||||
|
|
||||||
|
stock_item.convert_to_variant(variant, user=self.request.user)
|
||||||
|
|
||||||
|
return stock_item
|
||||||
|
|
||||||
|
|
||||||
class StockLocationCreate(AjaxCreateView):
|
class StockLocationCreate(AjaxCreateView):
|
||||||
"""
|
"""
|
||||||
|
@ -2319,6 +2319,23 @@ function loadStockTrackingTable(table, options) {
|
|||||||
|
|
||||||
var cols = [];
|
var cols = [];
|
||||||
|
|
||||||
|
var filterTarget = '#filter-list-stocktracking';
|
||||||
|
|
||||||
|
var filterKey = 'stocktracking';
|
||||||
|
|
||||||
|
var filters = loadTableFilters(filterKey);
|
||||||
|
|
||||||
|
var params = options.params;
|
||||||
|
|
||||||
|
var original = {};
|
||||||
|
|
||||||
|
for (var k in params) {
|
||||||
|
original[k] = params[k];
|
||||||
|
filters[k] = params[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
setupFilterList(filterKey, table, filterTarget);
|
||||||
|
|
||||||
// Date
|
// Date
|
||||||
cols.push({
|
cols.push({
|
||||||
field: 'date',
|
field: 'date',
|
||||||
@ -2356,6 +2373,19 @@ function loadStockTrackingTable(table, options) {
|
|||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Part information
|
||||||
|
if (details.part) {
|
||||||
|
html += `<tr><th>{% trans "Part" %}</th><td>`;
|
||||||
|
|
||||||
|
if (details.part_detail) {
|
||||||
|
html += renderLink(details.part_detail.full_name, `/part/${details.part}/`);
|
||||||
|
} else {
|
||||||
|
html += `{% trans "Part information unavailable" %}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += `</td></tr>`;
|
||||||
|
}
|
||||||
|
|
||||||
// Location information
|
// Location information
|
||||||
if (details.location) {
|
if (details.location) {
|
||||||
|
|
||||||
@ -2493,27 +2523,10 @@ function loadStockTrackingTable(table, options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
// 2021-05-11 - Ability to edit or delete StockItemTracking entries is now removed
|
|
||||||
cols.push({
|
|
||||||
sortable: false,
|
|
||||||
formatter: function(value, row, index, field) {
|
|
||||||
// Manually created entries can be edited or deleted
|
|
||||||
if (false && !row.system) {
|
|
||||||
var bEdit = "<button title='{% trans 'Edit tracking entry' %}' class='btn btn-entry-edit btn-outline-secondary' type='button' url='/stock/track/" + row.pk + "/edit/'><span class='fas fa-edit'/></button>";
|
|
||||||
var bDel = "<button title='{% trans 'Delete tracking entry' %}' class='btn btn-entry-delete btn-outline-secondary' type='button' url='/stock/track/" + row.pk + "/delete/'><span class='fas fa-trash-alt icon-red'/></button>";
|
|
||||||
|
|
||||||
return "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>";
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
table.inventreeTable({
|
table.inventreeTable({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
queryParams: options.params,
|
queryParams: filters,
|
||||||
|
original: original,
|
||||||
columns: cols,
|
columns: cols,
|
||||||
url: options.url,
|
url: options.url,
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user