diff --git a/InvenTree/common/forms.py b/InvenTree/common/forms.py index d884ca9d00..8a7a2a41ff 100644 --- a/InvenTree/common/forms.py +++ b/InvenTree/common/forms.py @@ -27,7 +27,7 @@ class SettingEditForm(HelperForm): ] -class UploadFile(forms.Form): +class UploadFileForm(forms.Form): """ Step 1 of FileManagementFormView """ file = forms.FileField( @@ -65,7 +65,7 @@ class UploadFile(forms.Form): return file -class MatchField(forms.Form): +class MatchFieldForm(forms.Form): """ Step 2 of FileManagementFormView """ def __init__(self, *args, **kwargs): @@ -98,7 +98,7 @@ class MatchField(forms.Form): self.fields[field_name].initial = col['guess'] -class MatchItem(forms.Form): +class MatchItemForm(forms.Form): """ Step 3 of FileManagementFormView """ def __init__(self, *args, **kwargs): @@ -179,5 +179,6 @@ class MatchItem(forms.Form): ) def get_special_field(self, col_guess, row, file_manager): - """ function to be overriden in inherited forms to add specific form settings """ + """ Function to be overriden in inherited forms to add specific form settings """ + return None diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py index c1ac20facd..92268d0023 100644 --- a/InvenTree/common/views.py +++ b/InvenTree/common/views.py @@ -118,7 +118,6 @@ class MultiStepFormView(SessionWizardView): form_steps_description: description for each form """ - form_list = [] form_steps_template = [] form_steps_description = [] file_manager = None @@ -176,11 +175,11 @@ class FileManagementFormView(MultiStepFormView): """ name = None - forms = { - 'upload': forms.UploadFile, - 'fields': forms.MatchField, - 'items': forms.MatchItem, - } + form_list = [ + ('upload', forms.UploadFileForm), + ('fields', forms.MatchFieldForm), + ('items', forms.MatchItemForm), + ] form_steps_description = [ _("Upload File"), _("Match Fields"), @@ -190,30 +189,18 @@ class FileManagementFormView(MultiStepFormView): extra_context_data = {} def __init__(self, *args, **kwargs): - """ initialize the FormView - Use the following syntax to override the forms that should be used in the steps: + """ Initialize the FormView """ - def __init__(self, *args, **kwargs): - self.forms['items'] = self.CustomMatchItem - return super().__init__(*args, **kwargs) - """ - # Construct form_list - self.form_list = [(key, value) for key, value in self.forms.items()] - - # perform all checks and inits for MultiStepFormView + # Perform all checks and inits for MultiStepFormView super().__init__(self, *args, **kwargs) # Check for file manager class if not hasattr(self, 'file_manager_class') and not issubclass(self.file_manager_class, FileManager): raise NotImplementedError('A subclass of a file manager class needs to be set!') - @classmethod - def get_initkwargs(cls, *args, **kwargs): - # Construct form_list - kwargs['form_list'] = [(key, value) for key, value in cls.forms.items()] - return super().get_initkwargs(*args, **kwargs) - def get_context_data(self, form=None, **kwargs): + """ Handle context data """ + if form is None: form = self.get_form() @@ -412,6 +399,7 @@ class FileManagementFormView(MultiStepFormView): 'data': data, 'errors': {}, } + self.rows.append(row) # In the item selection step: update row data with mapping to form fields diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py index 3973888e95..ceb633688a 100644 --- a/InvenTree/order/forms.py +++ b/InvenTree/order/forms.py @@ -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 @@ -285,3 +292,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) diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index fe62c19c95..9614f17020 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -15,7 +15,7 @@ from django.http import HttpResponseRedirect from django.utils.translation import ugettext_lazy as _ from django.views.generic import DetailView, ListView, UpdateView from django.views.generic.edit import FormMixin -from django.forms import HiddenInput, IntegerField, CharField, NumberInput +from django.forms import HiddenInput, IntegerField import logging from decimal import Decimal, InvalidOperation @@ -30,9 +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 common import forms as cm_forms from . import forms as order_forms from part.views import PartPricing @@ -44,8 +44,6 @@ from InvenTree.views import InvenTreeRoleMixin from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus, StockStatus -from djmoney.forms.fields import MoneyField - logger = logging.getLogger("inventree") @@ -576,38 +574,6 @@ class SalesOrderShip(AjaxUpdateView): class PurchaseOrderUpload(FileManagementFormView): ''' PurchaseOrder: Upload file, match to fields and parts (using multi-Step form) ''' - # overriden classes - class OrderMatchItem(cm_forms.MatchItem): - """ override MatchItem fields """ - def get_special_field(self, col_guess, row, file_manager): - """ set special field """ - # set quantity field - if 'quantity' in col_guess.lower(): - return CharField( - required=False, - widget=NumberInput(attrs={ - 'name': 'quantity' + str(row['index']), - 'class': 'numberinput', - 'type': 'number', - 'min': '0', - 'step': 'any', - 'value': self.clean_nbr(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=self.clean_nbr(row.get('price', '')), - ) - - # return default - return super().get_special_field(col_guess, row, file_manager) - class OrderFileManager(FileManager): REQUIRED_HEADERS = [ 'Quantity', @@ -625,6 +591,11 @@ class PurchaseOrderUpload(FileManagementFormView): ] 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', @@ -644,16 +615,14 @@ class PurchaseOrderUpload(FileManagementFormView): } file_manager_class = OrderFileManager - def __init__(self, *args, **kwargs): - self.forms['items'] = self.OrderMatchItem - return super().__init__(*args, **kwargs) - def get_order(self): """ Get order or return 404 """ 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()