2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 12:35:46 +00:00

Merge remote-tracking branch 'inventree/master' into drf-api-forms

This commit is contained in:
Oliver
2021-06-27 09:26:23 +10:00
43 changed files with 10592 additions and 8151 deletions

View File

@ -10,10 +10,17 @@ from django.utils.translation import ugettext_lazy as _
from mptt.fields import TreeNodeChoiceField
from djmoney.forms.fields import MoneyField
from InvenTree.forms import HelperForm
from InvenTree.fields import RoundingDecimalFormField
from InvenTree.fields import DatePickerFormField
from InvenTree.helpers import clean_decimal
from common.models import InvenTreeSetting
from common.forms import MatchItemForm
import part.models
from stock.models import StockLocation
@ -291,3 +298,37 @@ class EditSalesOrderAllocationForm(HelperForm):
'line',
'item',
'quantity']
class OrderMatchItemForm(MatchItemForm):
""" Override MatchItemForm fields """
def get_special_field(self, col_guess, row, file_manager):
""" Set special fields """
# set quantity field
if 'quantity' in col_guess.lower():
return forms.CharField(
required=False,
widget=forms.NumberInput(attrs={
'name': 'quantity' + str(row['index']),
'class': 'numberinput',
'type': 'number',
'min': '0',
'step': 'any',
'value': clean_decimal(row.get('quantity', '')),
})
)
# set price field
elif 'price' in col_guess.lower():
return MoneyField(
label=_(col_guess),
default_currency=InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY'),
decimal_places=5,
max_digits=19,
required=False,
default_amount=clean_decimal(row.get('purchase_price', '')),
)
# return default
return super().get_special_field(col_guess, row, file_manager)

View File

@ -17,8 +17,7 @@ from InvenTree.serializers import InvenTreeAttachmentSerializerField
from company.serializers import CompanyBriefSerializer, SupplierPartSerializer
from part.serializers import PartBriefSerializer
from stock.serializers import LocationBriefSerializer
from stock.serializers import StockItemSerializer, LocationSerializer
from stock.serializers import LocationBriefSerializer, StockItemSerializer, LocationSerializer
from .models import PurchaseOrder, PurchaseOrderLineItem
from .models import PurchaseOrderAttachment, SalesOrderAttachment

View File

@ -2,6 +2,7 @@
{% load inventree_extras %}
{% load i18n %}
{% load static %}
{% load crispy_forms_tags %}
{% block form_alert %}
{% if form.errors %}
@ -67,7 +68,7 @@
<td>
{% for field in form.visible_fields %}
{% if field.name == row.quantity %}
{{ field }}
{{ field|as_crispy_field }}
{% endif %}
{% endfor %}
{% if row.errors.quantity %}
@ -80,19 +81,19 @@
{% if item.column.guess == 'Purchase_Price' %}
{% for field in form.visible_fields %}
{% if field.name == row.purchase_price %}
{{ field }}
{{ field|as_crispy_field }}
{% endif %}
{% endfor %}
{% elif item.column.guess == 'Reference' %}
{% for field in form.visible_fields %}
{% if field.name == row.reference %}
{{ field }}
{{ field|as_crispy_field }}
{% endif %}
{% endfor %}
{% elif item.column.guess == 'Notes' %}
{% for field in form.visible_fields %}
{% if field.name == row.notes %}
{{ field }}
{{ field|as_crispy_field }}
{% endif %}
{% endfor %}
{% else %}

View File

@ -30,7 +30,9 @@ from stock.models import StockItem, StockLocation
from part.models import Part
from common.models import InvenTreeSetting
from common.forms import UploadFileForm, MatchFieldForm
from common.views import FileManagementFormView
from common.files import FileManager
from . import forms as order_forms
from part.views import PartPricing
@ -572,7 +574,28 @@ class SalesOrderShip(AjaxUpdateView):
class PurchaseOrderUpload(FileManagementFormView):
''' PurchaseOrder: Upload file, match to fields and parts (using multi-Step form) '''
class OrderFileManager(FileManager):
REQUIRED_HEADERS = [
'Quantity',
]
ITEM_MATCH_HEADERS = [
'Manufacturer_MPN',
'Supplier_SKU',
]
OPTIONAL_HEADERS = [
'Purchase_Price',
'Reference',
'Notes',
]
name = 'order'
form_list = [
('upload', UploadFileForm),
('fields', MatchFieldForm),
('items', order_forms.OrderMatchItemForm),
]
form_steps_template = [
'order/order_wizard/po_upload.html',
'order/order_wizard/match_fields.html',
@ -583,7 +606,6 @@ class PurchaseOrderUpload(FileManagementFormView):
_("Match Fields"),
_("Match Supplier Parts"),
]
# Form field name: PurchaseOrderLineItem field
form_field_map = {
'item_select': 'part',
'quantity': 'quantity',
@ -591,6 +613,7 @@ class PurchaseOrderUpload(FileManagementFormView):
'reference': 'reference',
'notes': 'notes',
}
file_manager_class = OrderFileManager
def get_order(self):
""" Get order or return 404 """
@ -598,6 +621,8 @@ class PurchaseOrderUpload(FileManagementFormView):
return get_object_or_404(PurchaseOrder, pk=self.kwargs['pk'])
def get_context_data(self, form, **kwargs):
""" Handle context data for order """
context = super().get_context_data(form=form, **kwargs)
order = self.get_order()
@ -708,26 +733,7 @@ class PurchaseOrderUpload(FileManagementFormView):
""" Once all the data is in, process it to add PurchaseOrderLineItem instances to the order """
order = self.get_order()
items = {}
for form_key, form_value in self.get_all_cleaned_data().items():
# Split key from row value
try:
(field, idx) = form_key.split('-')
except ValueError:
continue
if idx not in items:
# Insert into items
items.update({
idx: {
self.form_field_map[field]: form_value,
}
})
else:
# Update items
items[idx][self.form_field_map[field]] = form_value
items = self.get_clean_items()
# Create PurchaseOrderLineItem instances
for purchase_order_item in items.values():