mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add bulk delete for purchase order line items (#4452)
* add bulk delete for purchase order line items * bump API version * fix JS style * handle parts with no linked manufacturer part correctly * add unit test for purchase order line item bulk delete
This commit is contained in:
parent
abeb85cbb3
commit
106c238af5
@ -2,11 +2,14 @@
|
|||||||
|
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 99
|
INVENTREE_API_VERSION = 100
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
||||||
|
|
||||||
|
v100 -> 2023-03-04 : https://github.com/inventree/InvenTree/pull/4452
|
||||||
|
- Adds bulk delete of PurchaseOrderLineItems to API
|
||||||
|
|
||||||
v99 -> 2023-03-03 : https://github.com/inventree/InvenTree/pull/4445
|
v99 -> 2023-03-03 : https://github.com/inventree/InvenTree/pull/4445
|
||||||
- Adds sort by "responsible" to PurchaseOrderAPI
|
- Adds sort by "responsible" to PurchaseOrderAPI
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ class PurchaseOrderLineItemFilter(rest_filters.FilterSet):
|
|||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class PurchaseOrderLineItemList(APIDownloadMixin, ListCreateAPI):
|
class PurchaseOrderLineItemList(APIDownloadMixin, ListCreateDestroyAPIView):
|
||||||
"""API endpoint for accessing a list of PurchaseOrderLineItem objects.
|
"""API endpoint for accessing a list of PurchaseOrderLineItem objects.
|
||||||
|
|
||||||
- GET: Return a list of PurchaseOrder Line Item objects
|
- GET: Return a list of PurchaseOrder Line Item objects
|
||||||
|
@ -38,6 +38,22 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class='panel-content'>
|
<div class='panel-content'>
|
||||||
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
||||||
|
{% if roles.purchase_order.change %}
|
||||||
|
{% if order.is_pending or allow_extra_editing %}
|
||||||
|
<div class='btn-group' role='group'>
|
||||||
|
<!-- Multiple-select actions -->
|
||||||
|
<button id='multi-select-options' class='btn btn-primary dropdown-toggle' data-bs-toggle='dropdown'>
|
||||||
|
<span class='fas fa-tools'></span> <span class='caret'></span>
|
||||||
|
</button>
|
||||||
|
<ul class='dropdown-menu'>
|
||||||
|
<li><a class='dropdown-item' href='#' id='po-lines-bulk-delete' title='{% trans "Delete Line Items" %}'>
|
||||||
|
<span class='fas fa-trash-alt icon-red'></span> {% trans "Delete Line Items" %}
|
||||||
|
</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% include "filter_list.html" with id="purchase-order-lines" %}
|
{% include "filter_list.html" with id="purchase-order-lines" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -603,6 +603,26 @@ class PurchaseOrderLineItemTest(OrderTest):
|
|||||||
self.filter({'has_pricing': 1}, 0)
|
self.filter({'has_pricing': 1}, 0)
|
||||||
self.filter({'has_pricing': 0}, 5)
|
self.filter({'has_pricing': 0}, 5)
|
||||||
|
|
||||||
|
def test_po_line_bulk_delete(self):
|
||||||
|
"""Test that we can bulk delete multiple PurchaseOrderLineItems via the API."""
|
||||||
|
n = models.PurchaseOrderLineItem.objects.count()
|
||||||
|
|
||||||
|
self.assignRole('purchase_order.delete')
|
||||||
|
|
||||||
|
url = reverse('api-po-line-list')
|
||||||
|
|
||||||
|
# Try to delete a set of line items via their IDs
|
||||||
|
self.delete(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
'items': [1, 2],
|
||||||
|
},
|
||||||
|
expected_code=204,
|
||||||
|
)
|
||||||
|
|
||||||
|
# We should have 2 less PurchaseOrderLineItems after deletign them
|
||||||
|
self.assertEqual(models.PurchaseOrderLineItem.objects.count(), n - 2)
|
||||||
|
|
||||||
|
|
||||||
class PurchaseOrderDownloadTest(OrderTest):
|
class PurchaseOrderDownloadTest(OrderTest):
|
||||||
"""Unit tests for downloading PurchaseOrder data via the API endpoint."""
|
"""Unit tests for downloading PurchaseOrder data via the API endpoint."""
|
||||||
|
@ -914,6 +914,7 @@ function poLineItemFields(options={}) {
|
|||||||
// Returned prices are in increasing order of quantity
|
// Returned prices are in increasing order of quantity
|
||||||
if (response.length > 0) {
|
if (response.length > 0) {
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
|
var index = 0;
|
||||||
|
|
||||||
for (var idx = 0; idx < response.length; idx++) {
|
for (var idx = 0; idx < response.length; idx++) {
|
||||||
if (response[idx].quantity > quantity) {
|
if (response[idx].quantity > quantity) {
|
||||||
@ -2213,6 +2214,71 @@ function loadPurchaseOrderTable(table, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete the selected Purchase Order Line Items from the database
|
||||||
|
*/
|
||||||
|
function deletePurchaseOrderLineItems(items, options={}) {
|
||||||
|
|
||||||
|
function renderItem(item, opts={}) {
|
||||||
|
|
||||||
|
var part = item.part_detail;
|
||||||
|
var thumb = thumbnailImage(item.part_detail.thumbnail || item.part_detail.image);
|
||||||
|
var MPN = item.supplier_part_detail.manufacturer_part_detail ? item.supplier_part_detail.manufacturer_part_detail.MPN : '-';
|
||||||
|
|
||||||
|
var html = `
|
||||||
|
<tr>
|
||||||
|
<td>${thumb} ${part.full_name}</td>
|
||||||
|
<td>${part.description}</td>
|
||||||
|
<td>${item.supplier_part_detail.SKU}</td>
|
||||||
|
<td>${MPN}</td>
|
||||||
|
<td>${item.quantity}
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rows = '';
|
||||||
|
var ids = [];
|
||||||
|
|
||||||
|
items.forEach(function(item) {
|
||||||
|
rows += renderItem(item);
|
||||||
|
ids.push(item.pk);
|
||||||
|
});
|
||||||
|
|
||||||
|
var html = `
|
||||||
|
<div class='alert alert-block alert-danger'>
|
||||||
|
{% trans "All selected Line items will be deleted" %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class='table table-striped table-condensed'>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "Part" %}</th>
|
||||||
|
<th>{% trans "Description" %}</th>
|
||||||
|
<th>{% trans "SKU" %}</th>
|
||||||
|
<th>{% trans "MPN" %}</th>
|
||||||
|
<th>{% trans "Quantity" %}</th>
|
||||||
|
</tr>
|
||||||
|
${rows}
|
||||||
|
</table>
|
||||||
|
`;
|
||||||
|
|
||||||
|
constructForm('{% url "api-po-line-list" %}', {
|
||||||
|
method: 'DELETE',
|
||||||
|
multi_delete: true,
|
||||||
|
title: '{% trans "Delete selected Line items?" %}',
|
||||||
|
form_data: {
|
||||||
|
items: ids,
|
||||||
|
},
|
||||||
|
preFormContent: html,
|
||||||
|
onSuccess: function() {
|
||||||
|
// Refresh the table once the line items are deleted
|
||||||
|
$('#po-line-table').bootstrapTable('refresh');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a table displaying line items for a particular PurchasesOrder
|
* Load a table displaying line items for a particular PurchasesOrder
|
||||||
* @param {String} table - HTML ID tag e.g. '#table'
|
* @param {String} table - HTML ID tag e.g. '#table'
|
||||||
@ -2305,6 +2371,13 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Callback for bulk deleting mutliple lines
|
||||||
|
$('#po-lines-bulk-delete').off('click').on('click', function() {
|
||||||
|
var rows = getTableData(' #po-line-table');
|
||||||
|
|
||||||
|
deletePurchaseOrderLineItems(rows);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.allow_receive) {
|
if (options.allow_receive) {
|
||||||
@ -2569,6 +2642,13 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
linkButtonsToSelection(
|
||||||
|
table,
|
||||||
|
[
|
||||||
|
'#multi-select-options',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user