@@ -223,6 +224,16 @@ $("#edit-order").click(function() {
});
});
+$("#complete-order-shipments").click(function() {
+
+ completePendingShipments(
+ {{ order.pk }},
+ {
+ reload: true,
+ }
+ );
+});
+
$("#cancel-order").click(function() {
cancelSalesOrder(
diff --git a/InvenTree/templates/js/translated/forms.js b/InvenTree/templates/js/translated/forms.js
index d45a2de78c..9e1a7d154d 100644
--- a/InvenTree/templates/js/translated/forms.js
+++ b/InvenTree/templates/js/translated/forms.js
@@ -561,6 +561,11 @@ function constructFormBody(fields, options) {
insertPersistButton(options);
}
+ // Insert secondary buttons (if required)
+ if (options.buttons) {
+ insertSecondaryButtons(options);
+ }
+
// Display the modal
$(modal).modal('show');
@@ -650,6 +655,31 @@ function insertPersistButton(options) {
$(options.modal).find('#modal-footer-buttons').append(html);
}
+/*
+ * Add secondary buttons to the left of the close and submit buttons
+ * with callback functions
+ */
+function insertSecondaryButtons(options) {
+ for (var idx = 0; idx < options.buttons.length; idx++) {
+
+ var html = `
+
+ `;
+
+ $(options.modal).find('#modal-footer-secondary-buttons').append(html);
+
+ if (options.buttons[idx].onClick instanceof Function) {
+ // Copy callback reference to prevent errors if `idx` changes value before execution
+ var onclick_callback = options.buttons[idx].onClick;
+
+ $(options.modal).find(`#modal-form-${options.buttons[idx].name}`).click(function() {
+ onclick_callback(options);
+ });
+ }
+ }
+}
/*
* Extract all specified form values as a single object
diff --git a/InvenTree/templates/js/translated/modals.js b/InvenTree/templates/js/translated/modals.js
index 464006ae12..cc1212494d 100644
--- a/InvenTree/templates/js/translated/modals.js
+++ b/InvenTree/templates/js/translated/modals.js
@@ -75,6 +75,9 @@ function createNewModal(options={}) {
+
@@ -99,7 +102,7 @@ function createNewModal(options={}) {
$(modal_name).focus();
if (options.hideCloseButton) {
- $(modal_name).find('#modal-form-cancel').hide();
+ $(modal_name).find('#modal-form-close').hide();
}
if (options.preventSubmit || options.hideSubmitButton) {
diff --git a/InvenTree/templates/js/translated/order.js b/InvenTree/templates/js/translated/order.js
index 53dead4b60..0c21e368f1 100644
--- a/InvenTree/templates/js/translated/order.js
+++ b/InvenTree/templates/js/translated/order.js
@@ -24,6 +24,7 @@
cancelSalesOrder,
completePurchaseOrder,
completeShipment,
+ completePendingShipments,
createSalesOrder,
createSalesOrderShipment,
editPurchaseOrderLineItem,
@@ -69,7 +70,7 @@ function salesOrderShipmentFields(options={}) {
/*
* Complete a shipment
*/
-function completeShipment(shipment_id) {
+function completeShipment(shipment_id, options={}) {
// Request the list of stock items which will be shipped
inventreeGet(`/api/order/so/shipment/${shipment_id}/`, {}, {
@@ -126,28 +127,128 @@ function completeShipment(shipment_id) {
constructForm(`/api/order/so/shipment/${shipment_id}/ship/`, {
method: 'POST',
- title: '{% trans "Complete Shipment" %}',
+ title: `{% trans "Complete Shipment" %} ${shipment.reference}`,
fields: {
tracking_number: {},
},
preFormContent: html,
confirm: true,
confirmMessage: '{% trans "Confirm Shipment" %}',
+ buttons: options.buttons,
onSuccess: function(data) {
// Reload tables
$('#so-lines-table').bootstrapTable('refresh');
$('#pending-shipments-table').bootstrapTable('refresh');
$('#completed-shipments-table').bootstrapTable('refresh');
+
+ if (options.onSuccess instanceof Function) {
+ options.onSuccess(data);
+ }
},
- reload: true
+ reload: options.reload
});
}
});
}
+/*
+ * Launches a modal to mark all allocated pending shipments as complete
+ */
+function completePendingShipments(order_id, options={}) {
+ var pending_shipments = null;
+
+ // Request the list of stock items which will be shipped
+ inventreeGet(`/api/order/so/shipment/.*`,
+ {
+ order: order_id,
+ shipped: false
+ },
+ {
+ async: false,
+ success: function(shipments) {
+ pending_shipments = shipments;
+ }
+ }
+ );
+
+ var allocated_shipments = [];
+
+ for (var idx = 0; idx < pending_shipments.length; idx++) {
+ if (pending_shipments[idx].allocations.length > 0) {
+ allocated_shipments.push(pending_shipments[idx]);
+ }
+ }
+
+ if (allocated_shipments.length > 0) {
+ completePendingShipmentsHelper(allocated_shipments, 0, options);
+
+ } else {
+ html = `
+
+ `;
+
+ if (!pending_shipments.length) {
+ html += `
+ {% trans "No pending shipments found" %}
+ `;
+ } else {
+ html += `
+ {% trans "No stock items have been allocated to pending shipments" %}
+ `;
+ }
+
+ html += `
+