2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-29 20:16:44 +00:00

Merge pull request #2710 from SchrodingersGat/duplicate-order-lines

Adds "duplicate line item" button to orders
This commit is contained in:
Oliver 2022-03-04 07:44:27 +11:00 committed by GitHub
commit cb76b13eb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 158 additions and 44 deletions

View File

@ -16,10 +16,11 @@ from rest_framework.response import Response
from company.models import SupplierPart from company.models import SupplierPart
from InvenTree.filters import InvenTreeOrderingFilter from InvenTree.filters import InvenTreeOrderingFilter
from InvenTree.helpers import str2bool from InvenTree.helpers import str2bool, DownloadFile
from InvenTree.api import AttachmentMixin from InvenTree.api import AttachmentMixin
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus
from order.admin import POLineItemResource
import order.models as models import order.models as models
import order.serializers as serializers import order.serializers as serializers
from part.models import Part from part.models import Part
@ -370,6 +371,34 @@ class POLineItemList(generics.ListCreateAPIView):
return queryset return queryset
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
# Check if we wish to export the queried data to a file
export_format = request.query_params.get('export', None)
if export_format:
export_format = str(export_format).strip().lower()
if export_format in ['csv', 'tsv', 'xls', 'xlsx']:
dataset = POLineItemResource().export(queryset=queryset)
filedata = dataset.export(export_format)
filename = f"InvenTree_PurchaseOrderData.{export_format}"
return DownloadFile(filedata, filename)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
filter_backends = [ filter_backends = [
rest_filters.DjangoFilterBackend, rest_filters.DjangoFilterBackend,
filters.SearchFilter, filters.SearchFilter,

View File

@ -152,32 +152,16 @@
{% if order.status == PurchaseOrderStatus.PENDING %} {% if order.status == PurchaseOrderStatus.PENDING %}
$('#new-po-line').click(function() { $('#new-po-line').click(function() {
var fields = poLineItemFields({
order: {{ order.pk }},
supplier: {{ order.supplier.pk }},
{% if order.supplier.currency %}
currency: '{{ order.supplier.currency }}',
{% endif %}
});
constructForm('{% url "api-po-line-list" %}', { constructForm('{% url "api-po-line-list" %}', {
fields: { fields: fields,
order: {
value: {{ order.pk }},
hidden: true,
},
part: {
filters: {
part_detail: true,
supplier_detail: true,
supplier: {{ order.supplier.pk }},
},
},
quantity: {},
reference: {},
purchase_price: {},
purchase_price_currency: {
{% if order.supplier.currency %}
value: '{{ order.supplier.currency }}',
{% endif %}
},
target_date: {},
destination: {},
notes: {},
},
method: 'POST', method: 'POST',
title: '{% trans "Add Line Item" %}', title: '{% trans "Add Line Item" %}',
onSuccess: function() { onSuccess: function() {

View File

@ -221,29 +221,19 @@
}, },
}); });
function reloadTable() {
$("#so-lines-table").bootstrapTable("refresh");
}
$("#new-so-line").click(function() { $("#new-so-line").click(function() {
var fields = soLineItemFields({
order: {{ order.pk }},
});
constructForm('{% url "api-so-line-list" %}', { constructForm('{% url "api-so-line-list" %}', {
fields: { fields: fields,
order: {
value: {{ order.pk }},
hidden: true,
},
part: {},
quantity: {},
reference: {},
sale_price: {},
sale_price_currency: {},
target_date: {},
notes: {},
},
method: 'POST', method: 'POST',
title: '{% trans "Add Line Item" %}', title: '{% trans "Add Line Item" %}',
onSuccess: reloadTable, onSuccess: function() {
$("#so-lines-table").bootstrapTable("refresh");
},
}); });
}); });

View File

@ -281,6 +281,65 @@ function createPurchaseOrder(options={}) {
} }
/* Construct a set of fields for the SalesOrderLineItem form */
function soLineItemFields(options={}) {
var fields = {
order: {
hidden: true,
},
part: {},
quantity: {},
reference: {},
sale_price: {},
sale_price_currency: {},
target_date: {},
notes: {},
};
if (options.order) {
fields.order.value = options.order;
}
return fields;
}
/* Construct a set of fields for the PurchaseOrderLineItem form */
function poLineItemFields(options={}) {
var fields = {
order: {
hidden: true,
},
part: {
filters: {
part_detail: true,
supplier_detail: true,
supplier: options.supplier,
}
},
quantity: {},
reference: {},
purchase_price: {},
purchase_price_currency: {},
target_date: {},
destination: {},
notes: {},
};
if (options.order) {
fields.order.value = options.order;
}
if (options.currency) {
fields.purchase_price_currency.value = options.currency;
}
return fields;
}
function removeOrderRowFromOrderWizard(e) { function removeOrderRowFromOrderWizard(e) {
/* Remove a part selection from an order form. */ /* Remove a part selection from an order form. */
@ -293,6 +352,7 @@ function removeOrderRowFromOrderWizard(e) {
$('#' + row).remove(); $('#' + row).remove();
} }
function newSupplierPartFromOrderWizard(e) { function newSupplierPartFromOrderWizard(e) {
/* Create a new supplier part directly from an order form. /* Create a new supplier part directly from an order form.
* Launches a secondary modal and (if successful), * Launches a secondary modal and (if successful),
@ -991,10 +1051,36 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
var target = options.filter_target || '#filter-list-purchase-order-lines'; var target = options.filter_target || '#filter-list-purchase-order-lines';
setupFilterList('purchaseorderlineitem', $(table), target); setupFilterList('purchaseorderlineitem', $(table), target, {download: true});
function setupCallbacks() { function setupCallbacks() {
if (options.allow_edit) { if (options.allow_edit) {
// Callback for "duplicate" button
$(table).find('.button-line-duplicate').click(function() {
var pk = $(this).attr('pk');
inventreeGet(`/api/order/po-line/${pk}/`, {}, {
success: function(data) {
var fields = poLineItemFields({
supplier: options.supplier,
});
constructForm('{% url "api-po-line-list" %}', {
method: 'POST',
fields: fields,
data: data,
title: '{% trans "Duplicate Line Item" %}',
onSuccess: function(response) {
$(table).bootstrapTable('refresh');
}
});
}
});
});
// Callback for "edit" button
$(table).find('.button-line-edit').click(function() { $(table).find('.button-line-edit').click(function() {
var pk = $(this).attr('pk'); var pk = $(this).attr('pk');
@ -1022,6 +1108,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
}); });
}); });
// Callback for "delete" button
$(table).find('.button-line-delete').click(function() { $(table).find('.button-line-delete').click(function() {
var pk = $(this).attr('pk'); var pk = $(this).attr('pk');
@ -1270,6 +1357,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
} }
if (options.allow_edit) { if (options.allow_edit) {
html += makeIconButton('fa-clone', 'button-line-duplicate', pk, '{% trans "Duplicate line item" %}');
html += makeIconButton('fa-edit icon-blue', 'button-line-edit', pk, '{% trans "Edit line item" %}'); html += makeIconButton('fa-edit icon-blue', 'button-line-edit', pk, '{% trans "Edit line item" %}');
html += makeIconButton('fa-trash-alt icon-red', 'button-line-delete', pk, '{% trans "Delete line item" %}'); html += makeIconButton('fa-trash-alt icon-red', 'button-line-delete', pk, '{% trans "Delete line item" %}');
} }
@ -2449,6 +2537,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
html += makeIconButton('fa-dollar-sign icon-green', 'button-price', pk, '{% trans "Calculate price" %}'); html += makeIconButton('fa-dollar-sign icon-green', 'button-price', pk, '{% trans "Calculate price" %}');
} }
html += makeIconButton('fa-clone', 'button-duplicate', pk, '{% trans "Duplicate line item" %}');
html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line item" %}'); html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line item" %}');
var delete_disabled = false; var delete_disabled = false;
@ -2480,6 +2569,28 @@ function loadSalesOrderLineItemTable(table, options={}) {
// Configure callback functions once the table is loaded // Configure callback functions once the table is loaded
function setupCallbacks() { function setupCallbacks() {
// Callback for duplicating line items
$(table).find('.button-duplicate').click(function() {
var pk = $(this).attr('pk');
inventreeGet(`/api/order/so-line/${pk}/`, {}, {
success: function(data) {
var fields = soLineItemFields();
constructForm('{% url "api-so-line-list" %}', {
method: 'POST',
fields: fields,
data: data,
title: '{% trans "Duplicate Line Item" %}',
onSuccess: function(response) {
$(table).bootstrapTable('refresh');
}
});
}
});
});
// Callback for editing line items // Callback for editing line items
$(table).find('.button-edit').click(function() { $(table).find('.button-edit').click(function() {
var pk = $(this).attr('pk'); var pk = $(this).attr('pk');