First pass at 'order parts' fom

- Select parts in modal form window
This commit is contained in:
Oliver Walters 2019-06-11 23:37:32 +10:00
parent 8e82488f70
commit bc05146e72
8 changed files with 171 additions and 4 deletions

View File

@ -170,7 +170,7 @@ class AjaxView(AjaxMixin, View):
"""
def post(self, request, *args, **kwargs):
return JsonResponse('', safe=False)
return self.renderJsonResponse(request)
def get(self, request, *args, **kwargs):

View File

@ -0,0 +1,44 @@
{% extends "modal_form.html" %}
{% block form %}
<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='part-table'>
<tr>
<th>Part</th>
<th>Supplier</th>
<th>Quantity</th>
<th></th>
</tr>
{% for part in parts %}
<tr>
<td>
{% include "hover_image.html" with image=part.image hover=False %}
{{ part.full_name }} <small><i>{{ part.description }}</i></small>
</td>
<td>
<select name="part_select_{{ item.part.id }}">
<option value=''>---------</option>
{% for supplier in part.supplier_parts.all %}
<option value="{{ supplier.id }}"{% if part.get_default_supplier and part.get_default_supplier.id == supplier.id %} selected="selected"{% endif %}>{{ supplier }}</option>
{% endfor %}
</select>
</td>
<td>
<input class='numberinput' min='0' value='{{ part.quantity_to_order }}' name='part_quantity_{{ part.id }}'/>
</td>
<td>
<button class='btn btn-default btn-remove' id='del_item_{{ part.id }}' title='Remove part' type='button'>
<span row='part_row_{{ item.part.id }}' onclick='removeOrderRow()' class='glyphicon glyphicon-small glyphicon-remove'></span>
</button>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@ -26,6 +26,8 @@ purchase_order_urls = [
url(r'^new/', views.PurchaseOrderCreate.as_view(), name='purchase-order-create'),
url(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'),
# Display detail view for a single purchase order
url(r'^(?P<pk>\d+)/', include(purchase_order_detail_urls)),

View File

@ -7,14 +7,17 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext as _
from django.views.generic import DetailView, ListView
from django.views.generic.edit import FormMixin
from django.forms import HiddenInput
from .models import PurchaseOrder, PurchaseOrderLineItem
from company.models import Company, SupplierPart
from stock.models import StockItem
from part.models import Part
from . import forms as order_forms
from InvenTree.views import AjaxCreateView, AjaxUpdateView
from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView
from InvenTree.helpers import str2bool
from InvenTree.status_codes import OrderStatus
@ -135,6 +138,96 @@ class PurchaseOrderIssue(AjaxUpdateView):
return self.renderJsonResponse(request, form, data)
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_select_parts.html'
# List of Parts we wish to order
parts = []
def get_context_data(self):
ctx = {}
print("Getting context data")
ctx['parts'] = self.get_parts()
return ctx
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[]')
print("Looking up parts from stock items:")
print(stock_id_list)
""" 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)
print("Parts:", part_ids)
# Create the list of parts
for id in part_ids:
try:
part = Part.objects.get(id=id)
except Part.DoesNotExist:
continue
self.parts.append(part)
return self.parts
def get(self, request, *args, **kwargs):
self.request = request
print("GET HERE")
print(request.GET)
self.get_parts()
return self.renderJsonResponse(request)
def post(self, request, *args, **kwargs):
self.request = request
print("POST here")
return self.renderJsonResponse(request)
class POLineItemCreate(AjaxCreateView):
""" AJAX view for creating a new PurchaseOrderLineItem object
"""

View File

@ -339,7 +339,7 @@ class Part(models.Model):
"""
if self.default_supplier:
return self.default_suppliers
return self.default_supplier
if self.supplier_count == 1:
return self.supplier_parts.first()
@ -410,6 +410,13 @@ class Part(models.Model):
return max(total, 0)
@property
def quantity_to_order(self):
""" Return the quantity needing to be ordered for this part. """
required = -1 * self.net_stock
return max(required, 0)
@property
def net_stock(self):
""" Return the 'net' stock. It takes into account:

View File

@ -237,6 +237,22 @@ function loadStockTable(table, options) {
$("#multi-item-move").click(function() {
stockAdjustment('move');
});
$("#multi-item-order").click(function() {
var selections = $("#stock-table").bootstrapTable("getSelections");
var stock = [];
selections.forEach(function(item) {
stock.push(item.pk);
});
launchModalForm("/order/purchase-order/order-parts/", {
data: {
stock: stock,
},
});
});
}

View File

@ -21,6 +21,8 @@
{% block pre_form_content %}
{% endblock %}
{% block form %}
<form method="post" action='' class='js-modal-form' enctype="multipart/form-data">
{% csrf_token %}
{% load crispy_forms_tags %}
@ -32,5 +34,7 @@
{% endblock %}
</form>
{% endblock %}
{% block post_form_content %}
{% endblock %}

View File

@ -9,7 +9,8 @@
<li><a href="#" id='multi-item-add' title='Add to selected stock items'>Add stock</a></li>
<li><a href="#" id='multi-item-remove' title='Remove from selected stock items'>Remove stock</a></li>
<li><a href="#" id='multi-item-stocktake' title='Stocktake selected stock items'>Count stock</a></li>
<li><a href='#' id='multi-item-move' title='Move selected stock items'>Move stock</a></li>
<li><a href='#' id='multi-item-move' title='Move selected stock items'>Move stock</a></li>
<li><a href='#' id='multi-item-order' title='Order selected items'>Order stock</a></li>
</ul>
</div>
</div>