mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	Merge pull request #3043 from maksimstojkovic/fr-2986-shipment-page-action
Complete Allocated Pending Orders from SO Page Actions Menu
This commit is contained in:
		| @@ -57,6 +57,7 @@ src="{% static 'img/blank_image.png' %}" | ||||
|     <ul class='dropdown-menu' role='menu'> | ||||
|         <li><a class='dropdown-item' href='#' id='edit-order'><span class='fas fa-edit icon-green'></span> {% trans "Edit order" %}</a></li> | ||||
|         {% if order.status == SalesOrderStatus.PENDING %} | ||||
|         <li><a class='dropdown-item' href='#' id='complete-order-shipments'><span class='fas fa-truck'></span> {% trans "Complete Shipments" %}</a></li> | ||||
|         <li><a class='dropdown-item' href='#' id='cancel-order'><span class='fas fa-times-circle icon-red'></span> {% trans "Cancel order" %}</a></li> | ||||
|         {% endif %} | ||||
|     </ul> | ||||
| @@ -223,6 +224,16 @@ $("#edit-order").click(function() { | ||||
|     }); | ||||
| }); | ||||
|  | ||||
| $("#complete-order-shipments").click(function() { | ||||
|  | ||||
|     completePendingShipments( | ||||
|         {{ order.pk }}, | ||||
|         { | ||||
|             reload: true, | ||||
|         } | ||||
|     ); | ||||
| }); | ||||
|  | ||||
| $("#cancel-order").click(function() { | ||||
|  | ||||
|     cancelSalesOrder( | ||||
|   | ||||
| @@ -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 = ` | ||||
|         <button type="button" class="btn btn-outline-secondary" id="modal-form-${options.buttons[idx].name}"> | ||||
|             ${options.buttons[idx].title} | ||||
|         </button> | ||||
|         `; | ||||
|  | ||||
|         $(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 | ||||
|   | ||||
| @@ -75,6 +75,9 @@ function createNewModal(options={}) { | ||||
|                     </div> | ||||
|                     <span class='flex-item' style='flex-grow: 1;'></span> | ||||
|                     <h4><span id='modal-progress-spinner' class='fas fa-circle-notch fa-spin' style='display: none;'></span></h4> | ||||
|                     <div id='modal-footer-secondary-buttons'> | ||||
|                         <!-- Extra secondary buttons can be inserted here --> | ||||
|                     </div> | ||||
|                     <button type='button' class='btn btn-secondary' id='modal-form-close' data-bs-dismiss='modal'>{% trans "Cancel" %}</button> | ||||
|                     <button type='button' class='btn btn-${submitClass}' id='modal-form-submit'>{% trans "Submit" %}</button> | ||||
|                 </div> | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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,25 +127,125 @@ 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 = ` | ||||
|         <div class='alert alert-block alert-danger'> | ||||
|         `; | ||||
|  | ||||
|         if (!pending_shipments.length) { | ||||
|             html += ` | ||||
|             {% trans "No pending shipments found" %} | ||||
|             `; | ||||
|         } else { | ||||
|             html += ` | ||||
|             {% trans "No stock items have been allocated to pending shipments" %} | ||||
|             `; | ||||
|         } | ||||
|          | ||||
|         html += ` | ||||
|         </div> | ||||
|         `; | ||||
|  | ||||
|         constructForm(`/api/order/so/shipment/0/ship/`, { | ||||
|             method: 'POST', | ||||
|             title: '{% trans "Complete Shipments" %}', | ||||
|             preFormContent: html, | ||||
|             onSubmit: function(fields, options) { | ||||
|                 handleFormSuccess(fields, options); | ||||
|             }, | ||||
|             closeText: 'Close', | ||||
|             hideSubmitButton: true, | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Recursive helper for opening shipment completion modals | ||||
|  */ | ||||
| function completePendingShipmentsHelper(shipments, shipment_idx, options={}) { | ||||
|     if (shipment_idx < shipments.length) { | ||||
|         completeShipment(shipments[shipment_idx].pk, | ||||
|             { | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         name: 'skip', | ||||
|                         title: `{% trans "Skip" %}`, | ||||
|                         onClick: function(form_options) { | ||||
|                             if (form_options.modal) { | ||||
|                                 $(form_options.modal).modal('hide'); | ||||
|                             } | ||||
|  | ||||
|                             completePendingShipmentsHelper(shipments, shipment_idx + 1, options); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 onSuccess: function(data) { | ||||
|                     completePendingShipmentsHelper(shipments, shipment_idx + 1, options); | ||||
|                 }, | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|     } else if (options.reload) { | ||||
|         location.reload(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Launches a modal form to mark a PurchaseOrder as "complete" | ||||
|  */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user