mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +00:00 
			
		
		
		
	More refactoring
This commit is contained in:
		| @@ -362,6 +362,17 @@ class AjaxCreateView(AjaxMixin, CreateView): | ||||
|         form = self.get_form() | ||||
|         return self.renderJsonResponse(request, form) | ||||
|  | ||||
|     def do_save(self, form): | ||||
|         """ | ||||
|         Method for actually saving the form to the database. | ||||
|         Default implementation is very simple, | ||||
|         but can be overridden if required. | ||||
|         """ | ||||
|  | ||||
|         self.object = form.save() | ||||
|  | ||||
|         return self.object | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|         """ Responds to form POST. Validates POST data and returns status info. | ||||
|  | ||||
| @@ -385,13 +396,17 @@ class AjaxCreateView(AjaxMixin, CreateView): | ||||
|             'form_valid': valid | ||||
|         } | ||||
|  | ||||
|         # Add in any extra class data | ||||
|         for value, key in enumerate(self.get_data()): | ||||
|             data[key] = value | ||||
|  | ||||
|         if valid: | ||||
|  | ||||
|             # Perform (optional) pre-save step | ||||
|             self.pre_save(None, self.form) | ||||
|  | ||||
|             # Save the object to the database | ||||
|             self.object = self.form.save() | ||||
|             self.do_save(self.form) | ||||
|  | ||||
|             # Perform (optional) post-save step | ||||
|             self.post_save(self.object, self.form) | ||||
| @@ -425,6 +440,17 @@ class AjaxUpdateView(AjaxMixin, UpdateView): | ||||
|          | ||||
|         return self.renderJsonResponse(request, self.get_form(), context=self.get_context_data()) | ||||
|  | ||||
|     def do_save(self, form): | ||||
|         """ | ||||
|         Method for updating the object in the database. | ||||
|         Default implementation is very simple, | ||||
|         but can be overridden if required. | ||||
|         """ | ||||
|  | ||||
|         self.object = form.save() | ||||
|  | ||||
|         return self.object | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|         """ Respond to POST request. | ||||
|  | ||||
| @@ -453,13 +479,17 @@ class AjaxUpdateView(AjaxMixin, UpdateView): | ||||
|             'form_valid': valid | ||||
|         } | ||||
|  | ||||
|         # Add in any extra class data | ||||
|         for value, key in enumerate(self.get_data()): | ||||
|             data[key] = value | ||||
|  | ||||
|         if valid: | ||||
|  | ||||
|             # Perform (optional) pre-save step | ||||
|             self.pre_save(self.object, form) | ||||
|  | ||||
|             # Save the updated objec to the database | ||||
|             obj = form.save() | ||||
|             obj = self.do_save(form) | ||||
|  | ||||
|             # Perform (optional) post-save step | ||||
|             self.post_save(obj, form) | ||||
|   | ||||
| @@ -60,30 +60,25 @@ class BuildCancel(AjaxUpdateView): | ||||
|     form_class = forms.CancelBuildForm | ||||
|     role_required = 'build.change' | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|         """ Handle POST request. Mark the build status as CANCELLED """ | ||||
|     def validate(self, build, form, **kwargs): | ||||
|  | ||||
|         build = self.get_object() | ||||
|         confirm = str2bool(form.cleaned_data.get('confirm_cancel', False)) | ||||
|  | ||||
|         form = self.get_form() | ||||
|  | ||||
|         valid = form.is_valid() | ||||
|  | ||||
|         confirm = str2bool(request.POST.get('confirm_cancel', False)) | ||||
|  | ||||
|         if confirm: | ||||
|             build.cancelBuild(request.user) | ||||
|         else: | ||||
|         if not confirm: | ||||
|             form.add_error('confirm_cancel', _('Confirm build cancellation')) | ||||
|             valid = False | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': valid, | ||||
|     def post_save(self, build, form, **kwargs): | ||||
|         """ | ||||
|         Cancel the build. | ||||
|         """ | ||||
|  | ||||
|         build.cancelBuild(self.request.user) | ||||
|  | ||||
|     def get_data(self): | ||||
|         return { | ||||
|             'danger': _('Build was cancelled') | ||||
|         } | ||||
|  | ||||
|         return self.renderJsonResponse(request, form, data=data) | ||||
|  | ||||
|  | ||||
| class BuildAutoAllocate(AjaxUpdateView): | ||||
|     """ View to auto-allocate parts for a build. | ||||
|   | ||||
| @@ -209,6 +209,7 @@ class PurchaseOrder(Order): | ||||
|  | ||||
|         line.save() | ||||
|  | ||||
|     @transaction.atomic | ||||
|     def place_order(self): | ||||
|         """ Marks the PurchaseOrder as PLACED. Order must be currently PENDING. """ | ||||
|  | ||||
| @@ -217,6 +218,7 @@ class PurchaseOrder(Order): | ||||
|             self.issue_date = datetime.now().date() | ||||
|             self.save() | ||||
|  | ||||
|     @transaction.atomic | ||||
|     def complete_order(self): | ||||
|         """ Marks the PurchaseOrder as COMPLETE. Order must be currently PLACED. """ | ||||
|  | ||||
| @@ -225,10 +227,16 @@ class PurchaseOrder(Order): | ||||
|             self.complete_date = datetime.now().date() | ||||
|             self.save() | ||||
|  | ||||
|     def can_cancel(self): | ||||
|         return self.status not in [ | ||||
|             PurchaseOrderStatus.PLACED, | ||||
|             PurchaseOrderStatus.PENDING | ||||
|         ] | ||||
|  | ||||
|     def cancel_order(self): | ||||
|         """ Marks the PurchaseOrder as CANCELLED. """ | ||||
|  | ||||
|         if self.status in [PurchaseOrderStatus.PLACED, PurchaseOrderStatus.PENDING]: | ||||
|         if self.can_cancel(): | ||||
|             self.status = PurchaseOrderStatus.CANCELLED | ||||
|             self.save() | ||||
|  | ||||
| @@ -377,6 +385,16 @@ class SalesOrder(Order): | ||||
|  | ||||
|         return True | ||||
|  | ||||
|     def can_cancel(self): | ||||
|         """ | ||||
|         Return True if this order can be cancelled | ||||
|         """ | ||||
|  | ||||
|         if not self.status == SalesOrderStatus.PENDING: | ||||
|             return False | ||||
|  | ||||
|         return True | ||||
|  | ||||
|     @transaction.atomic | ||||
|     def cancel_order(self): | ||||
|         """ | ||||
| @@ -386,7 +404,7 @@ class SalesOrder(Order): | ||||
|         - Delete any StockItems which have been allocated | ||||
|         """ | ||||
|  | ||||
|         if not self.status == SalesOrderStatus.PENDING: | ||||
|         if not self.can_cancel(): | ||||
|             return False | ||||
|  | ||||
|         self.status = SalesOrderStatus.CANCELLED | ||||
|   | ||||
| @@ -404,29 +404,19 @@ class PurchaseOrderCancel(AjaxUpdateView): | ||||
|     form_class = order_forms.CancelPurchaseOrderForm | ||||
|     role_required = 'purchase_order.change' | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|         """ Mark the PO as 'CANCELLED' """ | ||||
|  | ||||
|         order = self.get_object() | ||||
|         form = self.get_form() | ||||
|  | ||||
|         confirm = str2bool(request.POST.get('confirm', False)) | ||||
|  | ||||
|         valid = False | ||||
|     def validate(self, order, form, **kwargs): | ||||
|          | ||||
|         confirm = str2bool(form.cleaned_data.get('confirm', False)) | ||||
|  | ||||
|         if not confirm: | ||||
|             form.add_error('confirm', _('Confirm order cancellation')) | ||||
|         else: | ||||
|             valid = True | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': valid | ||||
|         } | ||||
|         if not order.can_cancel(): | ||||
|             form.add_error(None, _('Order cannot be cancelled')) | ||||
|  | ||||
|         if valid: | ||||
|             order.cancel_order() | ||||
|     def post_save(self, order, form, **kwargs): | ||||
|  | ||||
|         return self.renderJsonResponse(request, form, data) | ||||
|         order.cancel_order() | ||||
|  | ||||
|  | ||||
| class SalesOrderCancel(AjaxUpdateView): | ||||
| @@ -438,30 +428,19 @@ class SalesOrderCancel(AjaxUpdateView): | ||||
|     form_class = order_forms.CancelSalesOrderForm | ||||
|     role_required = 'sales_order.change' | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|     def validate(self, order, form, **kwargs): | ||||
|  | ||||
|         order = self.get_object() | ||||
|         form = self.get_form() | ||||
|  | ||||
|         confirm = str2bool(request.POST.get('confirm', False)) | ||||
|  | ||||
|         valid = False | ||||
|         confirm = str2bool(form.cleaned_data.get('confirm', False)) | ||||
|  | ||||
|         if not confirm: | ||||
|             form.add_error('confirm', _('Confirm order cancellation')) | ||||
|         else: | ||||
|             valid = True | ||||
|  | ||||
|         if valid: | ||||
|             if not order.cancel_order(): | ||||
|                 form.add_error(None, _('Could not cancel order')) | ||||
|                 valid = False | ||||
|         if not order.can_cancel(): | ||||
|             form.add_error(None, _('Order cannot be cancelled')) | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': valid, | ||||
|         } | ||||
|     def post_save(self, order, form, **kwargs): | ||||
|  | ||||
|         return self.renderJsonResponse(request, form, data) | ||||
|         order.cancel_order() | ||||
|  | ||||
|  | ||||
| class PurchaseOrderIssue(AjaxUpdateView): | ||||
| @@ -473,30 +452,22 @@ class PurchaseOrderIssue(AjaxUpdateView): | ||||
|     form_class = order_forms.IssuePurchaseOrderForm | ||||
|     role_required = 'purchase_order.change' | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|         """ Mark the purchase order as 'PLACED' """ | ||||
|     def validate(self, order, form, **kwargs): | ||||
|  | ||||
|         order = self.get_object() | ||||
|         form = self.get_form() | ||||
|  | ||||
|         confirm = str2bool(request.POST.get('confirm', False)) | ||||
|  | ||||
|         valid = False | ||||
|         confirm = str2bool(form.cleaned_data.get('confirm', False)) | ||||
|  | ||||
|         if not confirm: | ||||
|             form.add_error('confirm', _('Confirm order placement')) | ||||
|         else: | ||||
|             valid = True | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': valid, | ||||
|     def post_save(self, order, form, **kwargs): | ||||
|  | ||||
|         order.place_order() | ||||
|  | ||||
|     def get_data(self): | ||||
|         return { | ||||
|             'success': _('Purchase order issued') | ||||
|         } | ||||
|  | ||||
|         if valid: | ||||
|             order.place_order() | ||||
|  | ||||
|         return self.renderJsonResponse(request, form, data) | ||||
|  | ||||
|  | ||||
| class PurchaseOrderComplete(AjaxUpdateView): | ||||
|     """ View for marking a PurchaseOrder as complete. | ||||
| @@ -517,24 +488,22 @@ class PurchaseOrderComplete(AjaxUpdateView): | ||||
|  | ||||
|         return ctx | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|     def validate(self, order, form, **kwargs): | ||||
|  | ||||
|         confirm = str2bool(request.POST.get('confirm', False)) | ||||
|         confirm = str2bool(form.cleaned_data.get('confirm', False)) | ||||
|  | ||||
|         if confirm: | ||||
|             po = self.get_object() | ||||
|             po.status = PurchaseOrderStatus.COMPLETE | ||||
|             po.save() | ||||
|         if not confirm: | ||||
|             form.add_error('confirm', _('Confirm order completion')) | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': confirm | ||||
|     def post_save(self, order, form, **kwargs): | ||||
|  | ||||
|         order.complete_order() | ||||
|  | ||||
|     def get_data(self): | ||||
|         return { | ||||
|             'success': _('Purchase order completed') | ||||
|         } | ||||
|  | ||||
|         form = self.get_form() | ||||
|  | ||||
|         return self.renderJsonResponse(request, form, data) | ||||
|  | ||||
|  | ||||
| class SalesOrderShip(AjaxUpdateView): | ||||
|     """ View for 'shipping' a SalesOrder """ | ||||
|     form_class = order_forms.ShipSalesOrderForm | ||||
| @@ -1117,52 +1086,21 @@ class POLineItemCreate(AjaxCreateView): | ||||
|     ajax_form_title = _('Add Line Item') | ||||
|     role_required = 'purchase_order.add' | ||||
|  | ||||
|     def post(self, request, *arg, **kwargs): | ||||
|     def validate(self, item, form, **kwargs): | ||||
|  | ||||
|         self.request = request | ||||
|         order = form.cleaned_data.get('order', None) | ||||
|  | ||||
|         form = self.get_form() | ||||
|         part = form.cleaned_data.get('part', None) | ||||
|  | ||||
|         valid = form.is_valid() | ||||
|         if not part: | ||||
|             form.add_error('part', _('Supplier part must be specified')) | ||||
|  | ||||
|         # Extract the SupplierPart ID from the form | ||||
|         part_id = form['part'].value() | ||||
|  | ||||
|         # Extract the Order ID from the form | ||||
|         order_id = form['order'].value() | ||||
|  | ||||
|         try: | ||||
|             order = PurchaseOrder.objects.get(id=order_id) | ||||
|         except (ValueError, PurchaseOrder.DoesNotExist): | ||||
|             order = None | ||||
|             form.add_error('order', _('Invalid Purchase Order')) | ||||
|             valid = False | ||||
|  | ||||
|         try: | ||||
|             sp = SupplierPart.objects.get(id=part_id) | ||||
|  | ||||
|             if order is not None: | ||||
|                 if not sp.supplier == order.supplier: | ||||
|                     form.add_error('part', _('Supplier must match for Part and Order')) | ||||
|                     valid = False | ||||
|  | ||||
|         except (SupplierPart.DoesNotExist, ValueError): | ||||
|             valid = False | ||||
|             form.add_error('part', _('Invalid SupplierPart selection')) | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': valid, | ||||
|         } | ||||
|  | ||||
|         if valid: | ||||
|             self.object = form.save() | ||||
|  | ||||
|             data['pk'] = self.object.pk | ||||
|             data['text'] = str(self.object) | ||||
|         else: | ||||
|             self.object = None | ||||
|          | ||||
|         return self.renderJsonResponse(request, form, data,) | ||||
|         if part and order: | ||||
|             if not part.supplier == order.supplier: | ||||
|                 form.add_error( | ||||
|                     'part', | ||||
|                     _('Supplier must match for Part and Order') | ||||
|                 ) | ||||
|  | ||||
|     def get_form(self): | ||||
|         """ Limit choice options based on the selected order, etc | ||||
|   | ||||
| @@ -1133,6 +1133,31 @@ class Part(MPTTModel): | ||||
|  | ||||
|             bom_item.save() | ||||
|  | ||||
|     @transaction.atomic | ||||
|     def copy_parameters_from(self, other, **kwargs): | ||||
|          | ||||
|         clear = kwargs.get('clear', True) | ||||
|  | ||||
|         if clear: | ||||
|             self.get_parameters().delete() | ||||
|  | ||||
|         for parameter in other.get_parameters.all(): | ||||
|  | ||||
|             # If this part already has a parameter pointing to the same template, | ||||
|             # delete that parameter from this part first! | ||||
|  | ||||
|             try: | ||||
|                 existing = PartParameter.objects.get(part=self, template=parameter.template) | ||||
|                 existing.delete() | ||||
|             except (PartParameter.DoesNotExist): | ||||
|                 pass | ||||
|  | ||||
|             parameter.part = self | ||||
|             parameter.pk = None | ||||
|  | ||||
|             parameter.save() | ||||
|  | ||||
|     @transaction.atomic | ||||
|     def deepCopy(self, other, **kwargs): | ||||
|         """ Duplicates non-field data from another part. | ||||
|         Does not alter the normal fields of this part, | ||||
| @@ -1156,15 +1181,8 @@ class Part(MPTTModel): | ||||
|  | ||||
|         # Copy the parameters data | ||||
|         if kwargs.get('parameters', True): | ||||
|             # Get template part parameters | ||||
|             parameters = other.get_parameters() | ||||
|             # Copy template part parameters to new variant part | ||||
|             for parameter in parameters: | ||||
|                 PartParameter.create(part=self, | ||||
|                                      template=parameter.template, | ||||
|                                      data=parameter.data, | ||||
|                                      save=True) | ||||
|  | ||||
|             self.copy_parameters_from(other) | ||||
|          | ||||
|         # Copy the fields that aren't available in the duplicate form | ||||
|         self.salable = other.salable | ||||
|         self.assembly = other.assembly | ||||
|   | ||||
| @@ -371,6 +371,8 @@ class MakePartVariant(AjaxCreateView): | ||||
|         initials = model_to_dict(part_template) | ||||
|         initials['is_template'] = False | ||||
|         initials['variant_of'] = part_template | ||||
|         initials['bom_copy'] = InvenTreeSetting.get_setting('PART_COPY_BOM') | ||||
|         initials['parameters_copy'] = InvenTreeSetting.get_seting('PART_COPY_PARAMETERS') | ||||
|  | ||||
|         return initials | ||||
|  | ||||
| @@ -906,23 +908,21 @@ class BomValidate(AjaxUpdateView): | ||||
|  | ||||
|         return self.renderJsonResponse(request, form, context=self.get_context()) | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|     def validate(self, part, form, **kwargs): | ||||
|  | ||||
|         form = self.get_form() | ||||
|         part = self.get_object() | ||||
|         confirm = str2bool(form.cleaned_data.get('validate', False)) | ||||
|  | ||||
|         confirmed = str2bool(request.POST.get('validate', False)) | ||||
|  | ||||
|         if confirmed: | ||||
|             part.validate_bom(request.user) | ||||
|         else: | ||||
|         if not confirm: | ||||
|             form.add_error('validate', _('Confirm that the BOM is valid')) | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': confirmed | ||||
|         } | ||||
|     def post_save(self, part, form, **kwargs): | ||||
|  | ||||
|         return self.renderJsonResponse(request, form, data, context=self.get_context()) | ||||
|         part.validate_bom(self.request.user) | ||||
|  | ||||
|     def get_data(self): | ||||
|         return { | ||||
|             'success': _('Validated Bill of Materials') | ||||
|         } | ||||
|  | ||||
|  | ||||
| class BomUpload(InvenTreeRoleMixin, FormView): | ||||
|   | ||||
| @@ -1126,6 +1126,20 @@ class StockItem(MPTTModel): | ||||
|  | ||||
|         return s | ||||
|  | ||||
|     @transaction.atomic | ||||
|     def clear_test_results(self, **kwargs): | ||||
|         """ | ||||
|         Remove all test results | ||||
|         """ | ||||
|  | ||||
|         # All test results | ||||
|         results = self.test_results.all() | ||||
|  | ||||
|         # TODO - Perhaps some filtering options supplied by kwargs? | ||||
|  | ||||
|         results.delete() | ||||
|  | ||||
|  | ||||
|     def getTestResults(self, test=None, result=None, user=None): | ||||
|         """ | ||||
|         Return all test results associated with this StockItem. | ||||
|   | ||||
| @@ -245,32 +245,28 @@ class StockItemAssignToCustomer(AjaxUpdateView): | ||||
|     form_class = StockForms.AssignStockItemToCustomerForm | ||||
|     role_required = 'stock.change' | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|     def validate(self, item, form, **kwargs): | ||||
|  | ||||
|         customer = request.POST.get('customer', None) | ||||
|         customer = form.cleaned_data.get('customer', None) | ||||
|  | ||||
|         if not customer: | ||||
|             form.add_error('customer', _('Customer must be specified')) | ||||
|  | ||||
|     def post_save(self, item, form, **kwargs): | ||||
|         """ | ||||
|         Assign the stock item to the customer. | ||||
|         """ | ||||
|  | ||||
|         customer = form.cleaned_data.get('customer', None) | ||||
|  | ||||
|         if customer: | ||||
|             try: | ||||
|                 customer = Company.objects.get(pk=customer) | ||||
|             except (ValueError, Company.DoesNotExist): | ||||
|                 customer = None | ||||
|  | ||||
|         if customer is not None: | ||||
|             stock_item = self.get_object() | ||||
|  | ||||
|             item = stock_item.allocateToCustomer( | ||||
|             item = item.allocateToCustomer( | ||||
|                 customer, | ||||
|                 user=request.user | ||||
|                 user=self.request.user | ||||
|             ) | ||||
|  | ||||
|             item.clearAllocations() | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': True, | ||||
|         } | ||||
|  | ||||
|         return self.renderJsonResponse(request, self.get_form(), data) | ||||
|  | ||||
|  | ||||
| class StockItemReturnToStock(AjaxUpdateView): | ||||
|     """ | ||||
| @@ -283,30 +279,25 @@ class StockItemReturnToStock(AjaxUpdateView): | ||||
|     form_class = StockForms.ReturnStockItemForm | ||||
|     role_required = 'stock.change' | ||||
|  | ||||
|     def post(self, request, *args, **kwargs): | ||||
|     def validate(self, item, form, **kwargs): | ||||
|  | ||||
|         location = request.POST.get('location', None) | ||||
|         location = form.cleaned_data.get('location', None) | ||||
|  | ||||
|         if not location: | ||||
|             form.add_error('location', _('Specify a valid location')) | ||||
|  | ||||
|     def post_save(self, item, form, **kwargs): | ||||
|  | ||||
|         location = form.cleaned_data.get('location', None) | ||||
|  | ||||
|         if location: | ||||
|             try: | ||||
|                 location = StockLocation.objects.get(pk=location) | ||||
|             except (ValueError, StockLocation.DoesNotExist): | ||||
|                 location = None | ||||
|             item.returnFromCustomer(location, self.request.user) | ||||
|  | ||||
|         if location: | ||||
|             stock_item = self.get_object() | ||||
|  | ||||
|             stock_item.returnFromCustomer(location, request.user) | ||||
|         else: | ||||
|             raise ValidationError({'location': _("Specify a valid location")}) | ||||
|  | ||||
|         data = { | ||||
|             'form_valid': True, | ||||
|             'success': _("Stock item returned from customer") | ||||
|     def get_data(self): | ||||
|         return { | ||||
|             'success': _('Stock item returned from customer') | ||||
|         } | ||||
|  | ||||
|         return self.renderJsonResponse(request, self.get_form(), data) | ||||
|  | ||||
|  | ||||
| class StockItemSelectLabels(AjaxView): | ||||
|     """ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user