diff --git a/InvenTree/company/forms.py b/InvenTree/company/forms.py index 079e871b84..506133df00 100644 --- a/InvenTree/company/forms.py +++ b/InvenTree/company/forms.py @@ -6,13 +6,12 @@ Django Forms for interacting with Company app from __future__ import unicode_literals from InvenTree.forms import HelperForm -from InvenTree.fields import InvenTreeMoneyField, RoundingDecimalFormField +from InvenTree.fields import RoundingDecimalFormField from django.utils.translation import ugettext_lazy as _ import django.forms from .models import Company -from .models import SupplierPart from .models import SupplierPriceBreak @@ -34,67 +33,6 @@ class CompanyImageDownloadForm(HelperForm): ] -class EditSupplierPartForm(HelperForm): - """ Form for editing a SupplierPart object """ - - field_prefix = { - 'link': 'fa-link', - 'SKU': 'fa-hashtag', - 'note': 'fa-pencil-alt', - } - - single_pricing = InvenTreeMoneyField( - label=_('Single Price'), - help_text=_('Single quantity price'), - decimal_places=4, - max_digits=19, - required=False, - ) - - manufacturer = django.forms.ChoiceField( - required=False, - help_text=_('Select manufacturer'), - choices=[], - ) - - MPN = django.forms.CharField( - required=False, - help_text=_('Manufacturer Part Number'), - max_length=100, - label=_('MPN'), - ) - - class Meta: - model = SupplierPart - fields = [ - 'part', - 'supplier', - 'SKU', - 'manufacturer', - 'MPN', - 'description', - 'link', - 'note', - 'single_pricing', - # 'base_cost', - # 'multiple', - 'packaging', - ] - - def get_manufacturer_choices(self): - """ Returns tuples for all manufacturers """ - empty_choice = [('', '----------')] - - manufacturers = [(manufacturer.id, manufacturer.name) for manufacturer in Company.objects.filter(is_manufacturer=True)] - - return empty_choice + manufacturers - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.fields['manufacturer'].choices = self.get_manufacturer_choices() - - class EditPriceBreakForm(HelperForm): """ Form for creating / editing a supplier price break """ diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index d8ea32ee15..3b731381b8 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -9,9 +9,7 @@ import os from django.utils.translation import ugettext_lazy as _ from django.core.validators import MinValueValidator -from django.core.exceptions import ValidationError from django.db import models -from django.db.utils import IntegrityError from django.db.models import Sum, Q, UniqueConstraint from django.apps import apps diff --git a/InvenTree/company/templates/company/detail.html b/InvenTree/company/templates/company/detail.html index 9c9e836c70..18e85718cb 100644 --- a/InvenTree/company/templates/company/detail.html +++ b/InvenTree/company/templates/company/detail.html @@ -378,22 +378,27 @@ {% endif %} $("#multi-part-delete").click(function() { - var selections = $("#part-table").bootstrapTable("getSelections"); + var selections = $("#supplier-part-table").bootstrapTable("getSelections"); - var parts = []; + var requests = []; - selections.forEach(function(item) { - parts.push(item.pk); - }); - - var url = "{% url 'supplier-part-delete' %}" - - launchModalForm(url, { - data: { - parts: parts, - }, - reload: true, - }); + showQuestionDialog( + '{% trans "Delete Supplier Parts?" %}', + '{% trans "All selected supplier parts will be deleted" %}', + { + accept: function() { + selections.forEach(function(part) { + var url = `/api/company/part/${part.pk}/`; + + requests.push(inventreeDelete(url)); + }); + + $.when.apply($, requests).then(function() { + $('#supplier-part-table').bootstrapTable('refresh'); + }); + } + } + ); }); $("#multi-part-order").click(function() { diff --git a/InvenTree/company/templates/company/manufacturer_part.html b/InvenTree/company/templates/company/manufacturer_part.html index 12b869ca72..bc6d4d5960 100644 --- a/InvenTree/company/templates/company/manufacturer_part.html +++ b/InvenTree/company/templates/company/manufacturer_part.html @@ -194,18 +194,25 @@ $("#supplier-part-delete").click(function() { var selections = $("#supplier-table").bootstrapTable("getSelections"); - var parts = []; + var requests = []; - selections.forEach(function(item) { - parts.push(item.pk); - }); - - launchModalForm("{% url 'supplier-part-delete' %}", { - data: { - parts: parts, - }, - reload: true, - }); + showQuestionDialog( + '{% trans "Delete Supplier Parts?" %}', + '{% trans "All selected supplier parts will be deleted" %}', + { + accept: function() { + selections.forEach(function(part) { + var url = `/api/company/part/${part.pk}/`; + + requests.push(inventreeDelete(url)); + }); + + $.when.apply($, requests).then(function() { + reloadSupplierPartTable(); + }); + } + } + ); }); $("#multi-parameter-delete").click(function() { diff --git a/InvenTree/company/templates/company/supplier_part.html b/InvenTree/company/templates/company/supplier_part.html index c3c2f89aa7..f751665e56 100644 --- a/InvenTree/company/templates/company/supplier_part.html +++ b/InvenTree/company/templates/company/supplier_part.html @@ -327,21 +327,21 @@ $('#order-part, #order-part2').click(function() { }); $('#edit-part').click(function () { - launchModalForm( - "{% url 'supplier-part-edit' part.id %}", - { - reload: true - } - ); + + editSupplierPart({{ part.pk }}, { + onSuccess: function() { + location.reload(); + } + }); }); $('#delete-part').click(function() { - launchModalForm( - "{% url 'supplier-part-delete' %}?part={{ part.id }}", - { - redirect: "{% url 'company-detail' part.supplier.id %}" + + deleteSupplierPart({{ part.pk }}, { + onSuccess: function() { + window.location.href = "{% url 'company-detail' part.supplier.id %}"; } - ); + }); }); attachNavCallbacks({ diff --git a/InvenTree/company/templates/company/supplier_part_create.html b/InvenTree/company/templates/company/supplier_part_create.html deleted file mode 100644 index 21c23f9075..0000000000 --- a/InvenTree/company/templates/company/supplier_part_create.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends "modal_form.html" %} - -{% load i18n %} - -{% block pre_form_content %} -{{ block.super }} - -{% if part %} -
- {% include "hover_image.html" with image=part.image %} - {{ part.full_name}} -
- {{ part.description }} -
-{% endif %} - -{% endblock %} \ No newline at end of file diff --git a/InvenTree/company/templates/company/supplier_part_delete.html b/InvenTree/company/templates/company/supplier_part_delete.html deleted file mode 100644 index 40d9ce42de..0000000000 --- a/InvenTree/company/templates/company/supplier_part_delete.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "modal_delete_form.html" %} -{% load i18n %} - -{% block pre_form_content %} -{% trans "Are you sure you want to delete the following Supplier Parts?" %} - -
-{% endblock %} - -{% block form_data %} - -{% for part in parts %} - - - - - - - -{% endfor %} -
- {% include "hover_image.html" with image=part.part.image %} - {{ part.part.full_name }} - - {% include "hover_image.html" with image=part.supplier.image %} - {{ part.supplier.name }} - - {{ part.SKU }} -
- -{% endblock %} \ No newline at end of file diff --git a/InvenTree/company/test_views.py b/InvenTree/company/test_views.py index bb796a0763..89968081c3 100644 --- a/InvenTree/company/test_views.py +++ b/InvenTree/company/test_views.py @@ -10,9 +10,6 @@ from django.urls import reverse from django.contrib.auth import get_user_model from django.contrib.auth.models import Group -from .models import ManufacturerPart -from .models import SupplierPart - class CompanyViewTestBase(TestCase): diff --git a/InvenTree/company/urls.py b/InvenTree/company/urls.py index b983a6483b..901e7f7089 100644 --- a/InvenTree/company/urls.py +++ b/InvenTree/company/urls.py @@ -35,14 +35,6 @@ manufacturer_part_urls = [ ])), ] -supplier_part_detail_urls = [ - url(r'^edit/?', views.SupplierPartEdit.as_view(), name='supplier-part-edit'), - +supplier_part_urls = [ url('^.*$', views.SupplierPartDetail.as_view(template_name='company/supplier_part.html'), name='supplier-part-detail'), ] - -supplier_part_urls = [ - url(r'delete/', views.SupplierPartDelete.as_view(), name='supplier-part-delete'), - - url(r'^(?P\d+)/', include(supplier_part_detail_urls)), -] diff --git a/InvenTree/company/views.py b/InvenTree/company/views.py index cf683ffb90..f3a9af7628 100644 --- a/InvenTree/company/views.py +++ b/InvenTree/company/views.py @@ -10,31 +10,22 @@ from django.utils.translation import ugettext_lazy as _ from django.views.generic import DetailView, ListView from django.urls import reverse -from django.forms import HiddenInput from django.core.files.base import ContentFile -from moneyed import CURRENCIES - from PIL import Image import requests import io -from InvenTree.views import AjaxCreateView, AjaxUpdateView, AjaxDeleteView -from InvenTree.helpers import str2bool +from InvenTree.views import AjaxUpdateView from InvenTree.views import InvenTreeRoleMixin from .models import Company from .models import ManufacturerPart from .models import SupplierPart -from part.models import Part -from .forms import EditSupplierPartForm from .forms import CompanyImageDownloadForm -import common.models -import common.settings - class CompanyIndex(InvenTreeRoleMixin, ListView): """ View for displaying list of companies @@ -231,134 +222,3 @@ class SupplierPartDetail(DetailView): ctx = super().get_context_data(**kwargs) return ctx - - -class SupplierPartEdit(AjaxUpdateView): - """ Update view for editing SupplierPart """ - - model = SupplierPart - context_object_name = 'part' - form_class = EditSupplierPartForm - ajax_template_name = 'modal_form.html' - ajax_form_title = _('Edit Supplier Part') - - def save(self, supplier_part, form, **kwargs): - """ Process ManufacturerPart data """ - - manufacturer = form.cleaned_data.get('manufacturer', None) - MPN = form.cleaned_data.get('MPN', None) - kwargs = {'manufacturer': manufacturer, - 'MPN': MPN, - } - supplier_part.save(**kwargs) - - def get_form(self): - form = super().get_form() - - supplier_part = self.get_object() - - # Hide Manufacturer fields - form.fields['manufacturer'].widget = HiddenInput() - form.fields['MPN'].widget = HiddenInput() - - # It appears that hiding a MoneyField fails validation - # Therefore the idea to set the value before hiding - if form.is_valid(): - form.cleaned_data['single_pricing'] = supplier_part.unit_pricing - # Hide the single-pricing field (only for creating a new SupplierPart!) - form.fields['single_pricing'].widget = HiddenInput() - - return form - - def get_initial(self): - """ Fetch data from ManufacturerPart """ - - initials = super(SupplierPartEdit, self).get_initial().copy() - - supplier_part = self.get_object() - - if supplier_part.manufacturer_part: - if supplier_part.manufacturer_part.manufacturer: - initials['manufacturer'] = supplier_part.manufacturer_part.manufacturer.id - initials['MPN'] = supplier_part.manufacturer_part.MPN - - return initials - - -class SupplierPartDelete(AjaxDeleteView): - """ Delete view for removing a SupplierPart. - - SupplierParts can be deleted using a variety of 'selectors'. - - - ?part= -> Delete a single SupplierPart object - - ?parts=[] -> Delete a list of SupplierPart objects - - """ - - success_url = '/supplier/' - ajax_template_name = 'company/supplier_part_delete.html' - ajax_form_title = _('Delete Supplier Part') - - role_required = 'purchase_order.delete' - - parts = [] - - def get_context_data(self): - ctx = {} - - ctx['parts'] = self.parts - - return ctx - - def get_parts(self): - """ Determine which SupplierPart object(s) the user wishes to delete. - """ - - self.parts = [] - - # User passes a single SupplierPart ID - if 'part' in self.request.GET: - try: - self.parts.append(SupplierPart.objects.get(pk=self.request.GET.get('part'))) - except (ValueError, SupplierPart.DoesNotExist): - pass - - elif 'parts[]' in self.request.GET: - - part_id_list = self.request.GET.getlist('parts[]') - - self.parts = SupplierPart.objects.filter(id__in=part_id_list) - - def get(self, request, *args, **kwargs): - self.request = request - self.get_parts() - - return self.renderJsonResponse(request, form=self.get_form()) - - def post(self, request, *args, **kwargs): - """ Handle the POST action for deleting supplier parts. - """ - - self.request = request - self.parts = [] - - for item in self.request.POST: - if item.startswith('supplier-part-'): - pk = item.replace('supplier-part-', '') - - try: - self.parts.append(SupplierPart.objects.get(pk=pk)) - except (ValueError, SupplierPart.DoesNotExist): - pass - - confirm = str2bool(self.request.POST.get('confirm_delete', False)) - - data = { - 'form_valid': confirm, - } - - if confirm: - for part in self.parts: - part.delete() - - return self.renderJsonResponse(self.request, data=data, form=self.get_form()) diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html index 77de5deceb..f5eee0cdfa 100644 --- a/InvenTree/part/templates/part/detail.html +++ b/InvenTree/part/templates/part/detail.html @@ -817,18 +817,25 @@ var selections = $("#supplier-part-table").bootstrapTable("getSelections"); - var parts = []; + var requests = []; - selections.forEach(function(item) { - parts.push(item.pk); - }); - - launchModalForm("{% url 'supplier-part-delete' %}", { - data: { - parts: parts, - }, - reload: true, - }); + showQuestionDialog( + '{% trans "Delete Supplier Parts?" %}', + '{% trans "All selected supplier parts will be deleted" %}', + { + accept: function() { + selections.forEach(function(part) { + var url = `/api/company/part/${part.pk}/`; + + requests.push(inventreeDelete(url)); + }); + + $.when.apply($, requests).then(function() { + reloadSupplierPartTable(); + }); + } + } + ); }); loadSupplierPartTable(