remove dead code

This commit is contained in:
Oliver Walters 2022-05-03 17:33:03 +10:00
parent f0e8e32c8a
commit 96c5a8252c
7 changed files with 31 additions and 524 deletions

View File

@ -1,85 +0,0 @@
{% extends "modal_form.html" %}
{% load inventree_extras %}
{% load i18n %}
{% block form %}
{% default_currency as currency %}
{% settings_value 'PART_SHOW_PRICE_IN_FORMS' as show_price %}
<h4>
{% trans "Step 1 of 2 - Select Part Suppliers" %}
</h4>
{% if parts|length > 0 %}
<div class='alert alert-info alert-block' role='alert'>
{% trans "Select suppliers" %}
</div>
{% else %}
<div class='alert alert-warning alert-block' role='alert'>
{% trans "No purchaseable parts selected" %}
</div>
{% endif %}
<form method="post" action='' class='js-modal-form' enctype="multipart/form-data">
{% csrf_token %}
{% load crispy_forms_tags %}
<input type='hidden' name='form_step' value='select_parts'/>
<table class='table table-condensed table-striped' id='order-wizard-part-table'>
<tr>
<th>{% trans "Part" %}</th>
<th colspan='2'>{% trans "Select Supplier" %}</th>
<th>{% trans "Quantity" %}</th>
<th></th>
</tr>
{% for part in parts %}
<tr id='part_row_{{ part.id }}'>
<td>
{% include "hover_image.html" with image=part.image hover=False %}
{{ part.full_name }} <small><em>{{ part.description }}</em></small>
</td>
<td>
<button class='btn btn-outline-secondary btn-create' onClick='newSupplierPartFromOrderWizard()' id='new_supplier_part_{{ part.id }}' part='{{ part.pk }}' title='{% trans "Create new supplier part" %}' type='button'>
<span part='{{ part.pk }}' class='fas fa-plus-circle'></span>
</button>
</td>
<td>
<div class='control-group'>
<div class='controls'>
<select class='select' id='id_supplier_part_{{ part.id }}' name="part-supplier-{{ part.id }}">
<option value=''>---------</option>
{% for supplier in part.supplier_parts.all %}
<option value="{{ supplier.id }}"{% if part.order_supplier == supplier.id %} selected="selected"{% endif %}>
{% if show_price %}
{% call_method supplier 'get_price' part.order_quantity as price %}
{% if price != None %}{% include "price.html" with price=price %}{% else %}{% trans 'No price' %}{% endif %} -
{% endif %}
{{ supplier }}
</option>
{% endfor %}
</select>
</div>
{% if not part.order_supplier %}
<span class='help-inline'>{% blocktrans with name=part.name %}Select a supplier for <em>{{name}}</em>{% endblocktrans %}</span>
{% endif %}
</div>
</td>
<td>
<div class='control-group'>
<div class='controls'>
<input class='numberinput' type='number' min='0' value='{% decimal part.order_quantity %}' name='part-quantity-{{ part.id }}'/>
</div>
</div>
</td>
<td>
<button class='btn btn-outline-secondary btn-remove' onclick='removeOrderRowFromOrderWizard()' id='del_item_{{ part.id }}' title='{% trans "Remove part" %}' type='button'>
<span row='part_row_{{ part.id }}' class='fas fa-trash-alt icon-red'></span>
</button>
</td>
</tr>
{% endfor %}
</table>
</form>
{% endblock %}

View File

@ -1,77 +0,0 @@
{% extends "modal_form.html" %}
{% load i18n %}
{% block form %}
<h4>
{% trans "Step 2 of 2 - Select Purchase Orders" %}
</h4>
<div class='alert alert-info alert-block' role='alert'>
{% trans "Select existing purchase orders, or create new orders." %}
</div>
<form method='post' action='' class='js-modal-form' enctype='multipart/form-data'>
{% csrf_token %}
{% load crispy_forms_tags %}
<input type='hidden' name='form_step' value='select_purchase_orders'/>
{% for supplier in suppliers %}
{% for item in supplier.order_items %}
<input type='hidden' name='part-supplier-{{ item.id }}' value='{{ item.order_supplier }}'/>
<input type='hidden' name='part-quantity-{{ item.id }}' value='{{ item.order_quantity }}'/>
{% endfor %}
{% endfor %}
<table class='table table-condensed table-striped' id='order-wizard-po-table'>
<tr>
<th>{% trans "Supplier" %}</th>
<th>{% trans "Items" %}</th>
<th colspan='2'>{% trans "Select Purchase Order" %}</th>
</tr>
{% for supplier in suppliers %}
<tr id='suppier_row_{{ supplier.id }}'>
<td>
{% include 'hover_image.html' with image=supplier.image hover=False %}
{{ supplier.name }}
</td>
<td>{{ supplier.order_items|length }}</td>
<td>
<button
class='btn btn-outline-secondary btn-create'
id='new_po_{{ supplier.id }}'
title='{% blocktrans with name=supplier.name %}Create new purchase order for {{name}}{% endblocktrans %}'
type='button'
supplierid='{{ supplier.id }}'
onclick='newPurchaseOrderFromOrderWizard()'>
<span supplierid='{{ supplier.id }}' class='fas fa-plus-circle'></span>
</button>
</td>
<td>
<div class='control-group'>
<div class='controls'>
<select
class='select'
id='id-purchase-order-{{ supplier.id }}'
name='purchase-order-{{ supplier.id }}'>
<option value=''>---------</option>
{% for order in supplier.pending_purchase_orders %}
<option value='{{ order.id }}'{% if supplier.selected_purchase_order == order.id %} selected='selected'{% endif %}>
{{ order }}
</option>
{% endfor %}
</select>
</div>
{% if not supplier.selected_purchase_order %}
<span class='help-inline'>{% blocktrans with name=supplier.name %}Select a purchase order for {{name}}{% endblocktrans %}</span>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</table>
</form>
{% endblock %}

View File

@ -23,7 +23,6 @@ purchase_order_detail_urls = [
purchase_order_urls = [
re_path(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'),
re_path(r'^pricing/', views.LineItemPricing.as_view(), name='line-pricing'),
# Display detail view for a single purchase order

View File

@ -448,346 +448,6 @@ class PurchaseOrderExport(AjaxView):
return DownloadFile(filedata, filename)
class OrderParts(AjaxView):
""" View for adding various SupplierPart items to a Purchase Order.
SupplierParts can be selected from a variety of 'sources':
- ?supplier_parts[]= -> Direct list of SupplierPart objects
- ?parts[]= -> List of base Part objects (user must then select supplier parts)
- ?stock[]= -> List of StockItem objects (user must select supplier parts)
- ?build= -> A Build object (user must select parts, then supplier parts)
"""
ajax_form_title = _("Order Parts")
ajax_template_name = 'order/order_wizard/select_parts.html'
role_required = [
'part.view',
'purchase_order.change',
]
# List of Parts we wish to order
parts = []
suppliers = []
def get_context_data(self):
ctx = {}
ctx['parts'] = sorted(self.parts, key=lambda part: int(part.order_quantity), reverse=True)
ctx['suppliers'] = self.suppliers
return ctx
def get_data(self):
""" enrich respone json data """
data = super().get_data()
# if in selection-phase, add a button to update the prices
if getattr(self, 'form_step', 'select_parts') == 'select_parts':
data['buttons'] = [{'name': 'update_price', 'title': _('Update prices')}] # set buttons
data['hideErrorMessage'] = '1' # hide the error message
return data
def get_suppliers(self):
""" Calculates a list of suppliers which the user will need to create PurchaseOrders for.
This is calculated AFTER the user finishes selecting the parts to order.
Crucially, get_parts() must be called before get_suppliers()
"""
suppliers = {}
for supplier in self.suppliers:
supplier.order_items = []
suppliers[supplier.name] = supplier
for part in self.parts:
supplier_part_id = part.order_supplier
try:
supplier = SupplierPart.objects.get(pk=supplier_part_id).supplier
except SupplierPart.DoesNotExist:
continue
if supplier.name not in suppliers:
supplier.order_items = []
# Attempt to auto-select a purchase order
orders = PurchaseOrder.objects.filter(supplier=supplier, status__in=PurchaseOrderStatus.OPEN)
if orders.count() == 1:
supplier.selected_purchase_order = orders.first().id
else:
supplier.selected_purchase_order = None
suppliers[supplier.name] = supplier
suppliers[supplier.name].order_items.append(part)
self.suppliers = [suppliers[key] for key in suppliers.keys()]
def get_parts(self):
""" Determine which parts the user wishes to order.
This is performed on the initial GET request.
"""
self.parts = []
part_ids = set()
# User has passed a list of stock items
if 'stock[]' in self.request.GET:
stock_id_list = self.request.GET.getlist('stock[]')
""" Get a list of all the parts associated with the stock items.
- Base part must be purchaseable.
- Return a set of corresponding Part IDs
"""
stock_items = StockItem.objects.filter(
part__purchaseable=True,
id__in=stock_id_list)
for item in stock_items:
part_ids.add(item.part.id)
# User has passed a single Part ID
elif 'part' in self.request.GET:
try:
part_id = self.request.GET.get('part')
part = Part.objects.get(id=part_id)
part_ids.add(part.id)
except Part.DoesNotExist:
pass
# User has passed a list of part ID values
elif 'parts[]' in self.request.GET:
part_id_list = self.request.GET.getlist('parts[]')
parts = Part.objects.filter(
purchaseable=True,
id__in=part_id_list)
for part in parts:
part_ids.add(part.id)
# User has provided a Build ID
elif 'build' in self.request.GET:
build_id = self.request.GET.get('build')
try:
build = Build.objects.get(id=build_id)
parts = build.required_parts
for part in parts:
# If ordering from a Build page, ignore parts that we have enough of
if part.quantity_to_order <= 0:
continue
part_ids.add(part.id)
except Build.DoesNotExist:
pass
# Create the list of parts
for id in part_ids:
try:
part = Part.objects.get(id=id)
# Pre-fill the 'order quantity' value
part.order_quantity = part.quantity_to_order
default_supplier = part.get_default_supplier()
if default_supplier:
part.order_supplier = default_supplier.id
else:
part.order_supplier = None
except Part.DoesNotExist:
continue
self.parts.append(part)
def get(self, request, *args, **kwargs):
self.request = request
self.get_parts()
return self.renderJsonResponse(request)
def post(self, request, *args, **kwargs):
""" Handle the POST action for part selection.
- Validates each part / quantity / supplier / etc
Part selection form contains the following fields for each part:
- supplier-<pk> : The ID of the selected supplier
- quantity-<pk> : The quantity to add to the order
"""
self.request = request
self.parts = []
self.suppliers = []
# Any errors for the part selection form?
part_errors = False
supplier_errors = False
# Extract part information from the form
for item in self.request.POST:
if item.startswith('part-supplier-'):
pk = item.replace('part-supplier-', '')
# Check that the part actually exists
try:
part = Part.objects.get(id=pk)
except (Part.DoesNotExist, ValueError):
continue
supplier_part_id = self.request.POST[item]
quantity = self.request.POST.get('part-quantity-' + str(pk), 0)
# Ensure a valid supplier has been passed
try:
supplier_part = SupplierPart.objects.get(id=supplier_part_id)
except (SupplierPart.DoesNotExist, ValueError):
supplier_part = None
# Ensure a valid quantity is passed
try:
quantity = int(quantity)
# Eliminate lines where the quantity is zero
if quantity == 0:
continue
except ValueError:
quantity = part.quantity_to_order
part.order_supplier = supplier_part.id if supplier_part else None
part.order_quantity = quantity
# set supplier-price
if supplier_part:
supplier_price = supplier_part.get_price(quantity)
if supplier_price:
part.purchase_price = supplier_price / quantity
if not hasattr(part, 'purchase_price'):
part.purchase_price = None
self.parts.append(part)
if supplier_part is None:
part_errors = True
elif quantity < 0:
part_errors = True
elif item.startswith('purchase-order-'):
# Which purchase order is selected for a given supplier?
pk = item.replace('purchase-order-', '')
# Check that the Supplier actually exists
try:
supplier = Company.objects.get(id=pk)
except Company.DoesNotExist:
# Skip this item
continue
purchase_order_id = self.request.POST[item]
# Ensure that a valid purchase order has been passed
try:
purchase_order = PurchaseOrder.objects.get(pk=purchase_order_id)
except (PurchaseOrder.DoesNotExist, ValueError):
purchase_order = None
supplier.selected_purchase_order = purchase_order.id if purchase_order else None
self.suppliers.append(supplier)
if supplier.selected_purchase_order is None:
supplier_errors = True
form_step = request.POST.get('form_step')
# Map parts to suppliers
self.get_suppliers()
valid = False
if form_step == 'select_parts':
# No errors? and the price-update button was not used to submit? Proceed to PO selection form
if part_errors is False and 'act-btn_update_price' not in request.POST:
self.ajax_template_name = 'order/order_wizard/select_pos.html'
self.form_step = 'select_purchase_orders' # set step (important for get_data)
else:
self.ajax_template_name = 'order/order_wizard/select_parts.html'
elif form_step == 'select_purchase_orders':
self.ajax_template_name = 'order/order_wizard/select_pos.html'
valid = part_errors is False and supplier_errors is False
# Form wizard is complete! Add items to purchase orders
if valid:
self.order_items()
data = {
'form_valid': valid,
'success': _('Ordered {n} parts').format(n=len(self.parts))
}
return self.renderJsonResponse(self.request, data=data)
@transaction.atomic
def order_items(self):
""" Add the selected items to the purchase orders. """
for supplier in self.suppliers:
# Check that the purchase order does actually exist
try:
order = PurchaseOrder.objects.get(pk=supplier.selected_purchase_order)
except PurchaseOrder.DoesNotExist:
logger.critical('Could not add items to purchase order {po} - Order does not exist'.format(po=supplier.selected_purchase_order))
continue
for item in supplier.order_items:
# Ensure that the quantity is valid
try:
quantity = int(item.order_quantity)
if quantity <= 0:
continue
except ValueError:
logger.warning("Did not add part to purchase order - incorrect quantity")
continue
# Check that the supplier part does actually exist
try:
supplier_part = SupplierPart.objects.get(pk=item.order_supplier)
except SupplierPart.DoesNotExist:
logger.critical("Could not add part '{part}' to purchase order - selected supplier part '{sp}' does not exist.".format(
part=item,
sp=item.order_supplier))
continue
# get purchase price
purchase_price = item.purchase_price
order.add_line_item(supplier_part, quantity, purchase_price=purchase_price)
class LineItemPricing(PartPricing):
""" View for inspecting part pricing information """

View File

@ -1532,13 +1532,18 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
var pk = $(this).attr('pk');
launchModalForm('{% url "order-parts" %}', {
data: {
parts: [
pk,
]
inventreeGet(
`/api/part/${pk}/`,
{},
{
success: function(part) {
orderParts(
[part],
{}
);
}
});
}
);
});
// Callback for 'build' button

View File

@ -3290,13 +3290,18 @@ function loadSalesOrderLineItemTable(table, options={}) {
$(table).find('.button-buy').click(function() {
var pk = $(this).attr('pk');
launchModalForm('{% url "order-parts" %}', {
data: {
parts: [
pk
],
},
});
inventreeGet(
`/api/part/${pk}/`,
{},
{
success: function(part) {
orderParts(
[part],
{}
);
}
}
);
});
// Callback for displaying price

View File

@ -2043,17 +2043,17 @@ function loadStockTable(table, options) {
$('#multi-item-order').click(function() {
var selections = $(table).bootstrapTable('getSelections');
var stock = [];
var parts = [];
selections.forEach(function(item) {
stock.push(item.pk);
var part = item.part_detail;
if (part) {
parts.push(part);
}
});
launchModalForm('/order/purchase-order/order-parts/', {
data: {
stock: stock,
},
});
orderParts(parts, {});
});
$('#multi-item-set-status').click(function() {