Fixed form validation for previous step, hide tab depending on order status, added purchase_price field

This commit is contained in:
eeintech 2021-05-10 11:42:22 -04:00
parent 6857964c17
commit f0932040ee
7 changed files with 111 additions and 23 deletions

View File

@ -102,8 +102,9 @@ class FileManager:
] ]
self.OPTIONAL_HEADERS = [ self.OPTIONAL_HEADERS = [
'Unit_Price', 'Purchase_Price',
'Extended_Price', 'Reference',
'Notes',
] ]
# Update headers # Update headers

View File

@ -8,6 +8,8 @@ from __future__ import unicode_literals
from django import forms from django import forms
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from djmoney.forms.fields import MoneyField
from InvenTree.forms import HelperForm from InvenTree.forms import HelperForm
from .files import FileManager from .files import FileManager
@ -121,6 +123,7 @@ class MatchItem(forms.Form):
for row in row_data: for row in row_data:
# Navigate column data # Navigate column data
for col in row['data']: for col in row['data']:
# Create input for required headers # Create input for required headers
if col['column']['guess'] in file_manager.REQUIRED_HEADERS: if col['column']['guess'] in file_manager.REQUIRED_HEADERS:
# Set field name # Set field name
@ -156,11 +159,37 @@ class MatchItem(forms.Form):
# Set field select box # Set field select box
self.fields[field_name] = forms.ChoiceField( self.fields[field_name] = forms.ChoiceField(
choices=[('', '-' * 10)] + item_options, choices=[('', '-' * 10)] + item_options,
required=True, required=False,
widget=forms.Select(attrs={ widget=forms.Select(attrs={
'class': 'select bomselect', 'class': 'select bomselect',
}) })
) )
# Update initial selection # Update select box when match was found
if item_match: if item_match:
# Make it a required field
self.fields[field_name].required = True
# Update initial value
self.fields[field_name].initial = item_match.id self.fields[field_name].initial = item_match.id
# Optional entries
elif col['column']['guess'] in file_manager.OPTIONAL_HEADERS:
# Set field name
field_name = col['column']['guess'].lower() + '-' + str(row['index'])
# Get value
value = row.get(col['column']['guess'].lower(), '')
# Set field input box
if 'price' in col['column']['guess'].lower():
self.fields[field_name] = MoneyField(
label=_(col['column']['guess']),
default_currency='USD',
decimal_places=5,
max_digits=19,
required=False,
default_amount=value,
)
else:
self.fields[field_name] = forms.Input(
required=True,
widget=forms.Select(attrs={
})
)

View File

@ -191,6 +191,7 @@ class FileManagementFormView(MultiStepFormView):
# Set keys for item matching # Set keys for item matching
key_item_select = 'item_select' key_item_select = 'item_select'
key_quantity_select = 'quantity' key_quantity_select = 'quantity'
key_price_select = 'price'
def get_context_data(self, form, **kwargs): def get_context_data(self, form, **kwargs):
context = super().get_context_data(form=form, **kwargs) context = super().get_context_data(form=form, **kwargs)
@ -314,6 +315,19 @@ class FileManagementFormView(MultiStepFormView):
self.column_selections[col_name] = value self.column_selections[col_name] = value
def set_form_table_data(self, form=None): def set_form_table_data(self, form=None):
""" Set the form table data """
if self.column_names:
# Re-construct the column data
self.columns = []
for key in self.column_names:
header = ({
'name': key,
'guess': self.column_selections.get(key, ''),
})
self.columns.append(header)
if self.row_data: if self.row_data:
# Re-construct the row data # Re-construct the row data
self.rows = [] self.rows = []
@ -323,12 +337,12 @@ class FileManagementFormView(MultiStepFormView):
items = [] items = []
for col_idx in sorted(row.keys()): for col_idx in sorted(row.keys()):
value = row[col_idx] value = row[col_idx]
items.append(value) items.append(value)
self.rows.append({ self.rows.append({
'index': row_idx, 'index': row_idx,
'column': self.columns[row_idx],
'data': items, 'data': items,
'errors': {}, 'errors': {},
}) })
@ -370,17 +384,8 @@ class FileManagementFormView(MultiStepFormView):
row['item_select'] = self.key_item_select + '-' + str(row['index']) row['item_select'] = self.key_item_select + '-' + str(row['index'])
# Add quantity select field # Add quantity select field
row['quantity_select'] = self.key_quantity_select + '-' + str(row['index']) row['quantity_select'] = self.key_quantity_select + '-' + str(row['index'])
# Add price select field
if self.column_names: row['price_select'] = self.key_price_select + '-' + str(row['index'])
# Re-construct the column data
self.columns = []
for key in self.column_names:
header = ({
'name': key,
'guess': self.column_selections.get(key, ''),
})
self.columns.append(header)
def get_column_index(self, name): def get_column_index(self, name):
""" Return the index of the column with the given name. """ Return the index of the column with the given name.

View File

@ -48,7 +48,7 @@
</td> </td>
<td></td> <td></td>
<td> <td>
{{ row.index }} {% add row.index 1 %}
</td> </td>
<td> <td>
{% for field in form.visible_fields %} {% for field in form.visible_fields %}
@ -71,6 +71,12 @@
{% if row.errors.quantity %} {% if row.errors.quantity %}
<p class='help-inline'>{{ row.errors.quantity }}</p> <p class='help-inline'>{{ row.errors.quantity }}</p>
{% endif %} {% endif %}
{% elif item.column.guess == 'Purchase_Price' %}
{% for field in form.visible_fields %}
{% if field.name == row.price_select %}
{{ field }}
{% endif %}
{% endfor %}
{% else %} {% else %}
{{ item.cell }} {{ item.cell }}
{% endif %} {% endif %}

View File

@ -13,6 +13,7 @@
{% endblock %} {% endblock %}
{% block details %} {% block details %}
{% if order.status == PurchaseOrderStatus.PENDING and roles.purchase_order.change %}
<p>{% blocktrans with step=wizard.steps.step1 count=wizard.steps.count %}Step {{step}} of {{count}}{% endblocktrans %} <p>{% blocktrans with step=wizard.steps.step1 count=wizard.steps.count %}Step {{step}} of {{count}}{% endblocktrans %}
{% if description %}- {{ description }}{% endif %}</p> {% if description %}- {{ description }}{% endif %}</p>
@ -42,6 +43,11 @@
</form> </form>
{% endblock form_buttons_bottom %} {% endblock form_buttons_bottom %}
{% else %}
<div class='alert alert-danger alert-block' role='alert'>
{% trans "Order is already processed. Files cannot be uploaded." %}
</div>
{% endif %}
{% endblock details %} {% endblock details %}
{% block js_ready %} {% block js_ready %}

View File

@ -1,6 +1,7 @@
{% load i18n %} {% load i18n %}
{% load static %} {% load static %}
{% load inventree_extras %} {% load inventree_extras %}
{% load status_codes %}
<ul class='list-group'> <ul class='list-group'>
<li class='list-group-item'> <li class='list-group-item'>
@ -14,12 +15,14 @@
{% trans "Details" %} {% trans "Details" %}
</a> </a>
</li> </li>
{% if order.status == PurchaseOrderStatus.PENDING and roles.purchase_order.change %}
<li class='list-group-item {% if tab == "upload" %}active{% endif %}' title='{% trans "Upload File" %}'> <li class='list-group-item {% if tab == "upload" %}active{% endif %}' title='{% trans "Upload File" %}'>
<a href='{% url "po-upload" order.id %}'> <a href='{% url "po-upload" order.id %}'>
<span class='fas fa-file-upload'></span> <span class='fas fa-file-upload'></span>
{% trans "Upload File" %} {% trans "Upload File" %}
</a> </a>
</li> </li>
{% endif %}
<li class='list-group-item {% if tab == "received" %}active{% endif %}' title='{% trans "Received Stock Items" %}'> <li class='list-group-item {% if tab == "received" %}active{% endif %}' title='{% trans "Received Stock Items" %}'>
<a href='{% url "po-received" order.id %}'> <a href='{% url "po-received" order.id %}'>
<span class='fas fa-sign-in-alt'></span> <span class='fas fa-sign-in-alt'></span>

View File

@ -583,6 +583,7 @@ class PurchaseOrderUpload(FileManagementFormView):
_("Match Fields"), _("Match Fields"),
_("Match Supplier Parts"), _("Match Supplier Parts"),
] ]
key_price_select = 'purchase_price'
def get_order(self): def get_order(self):
""" Get order or return 404 """ """ Get order or return 404 """
@ -612,8 +613,9 @@ class PurchaseOrderUpload(FileManagementFormView):
q_idx = self.get_column_index('Quantity') q_idx = self.get_column_index('Quantity')
s_idx = self.get_column_index('Supplier_SKU') s_idx = self.get_column_index('Supplier_SKU')
m_idx = self.get_column_index('Manufacturer_MPN') m_idx = self.get_column_index('Manufacturer_MPN')
# p_idx = self.get_column_index('Unit_Price') p_idx = self.get_column_index('Purchase_Price')
# e_idx = self.get_column_index('Extended_Price') r_idx = self.get_column_index('Reference')
n_idx = self.get_column_index('Notes')
for row in self.rows: for row in self.rows:
@ -634,11 +636,10 @@ class PurchaseOrderUpload(FileManagementFormView):
try: try:
# Attempt to extract a valid quantity from the field # Attempt to extract a valid quantity from the field
quantity = Decimal(q_val) quantity = Decimal(q_val)
except (ValueError, InvalidOperation):
pass
# Store the 'quantity' value # Store the 'quantity' value
row['quantity'] = quantity row['quantity'] = quantity
except (ValueError, InvalidOperation):
pass
# Check if there is a column corresponding to "Supplier SKU" # Check if there is a column corresponding to "Supplier SKU"
if s_idx >= 0: if s_idx >= 0:
@ -670,8 +671,32 @@ class PurchaseOrderUpload(FileManagementFormView):
# If there is an exact match based on SKU or MPN, use that # If there is an exact match based on SKU or MPN, use that
row['item_match'] = exact_match_part row['item_match'] = exact_match_part
# Check if there is a column corresponding to "purchase_price"
if p_idx >= 0:
p_val = row['data'][p_idx]['cell']
if p_val:
# Delete commas
p_val = p_val.replace(',', '')
try:
# Attempt to extract a valid quantity from the field
purchase_price = Decimal(p_val)
# Store the 'purchase_price' value
row['purchase_price'] = purchase_price
except (ValueError, InvalidOperation):
pass
# Check if there is a column corresponding to "reference"
if r_idx >= 0:
pass
# Check if there is a column corresponding to "notes"
if n_idx >= 0:
pass
def done(self, form_list, **kwargs): def done(self, form_list, **kwargs):
""" Once all the data is in, process it to add SupplierPart items to the order """ """ Once all the data is in, process it to add PurchaseOrderLineItem instances to the order """
order = self.get_order() order = self.get_order()
@ -708,6 +733,18 @@ class PurchaseOrderUpload(FileManagementFormView):
# Update items # Update items
items[idx]['quantity'] = form_value items[idx]['quantity'] = form_value
if field == self.key_price_select:
if idx not in items:
# Insert into items
items.update({
idx: {
'purchase_price': form_value,
}
})
else:
# Update items
items[idx]['purchase_price'] = form_value
# Create PurchaseOrderLineItem instances # Create PurchaseOrderLineItem instances
for purchase_order_item in items.values(): for purchase_order_item in items.values():
try: try:
@ -718,6 +755,7 @@ class PurchaseOrderUpload(FileManagementFormView):
order=order, order=order,
part=supplier_part, part=supplier_part,
quantity=purchase_order_item['quantity'], quantity=purchase_order_item['quantity'],
purchase_price=purchase_order_item['purchase_price'],
) )
try: try:
purchase_order_line_item.save() purchase_order_line_item.save()