Related parts are now created via the API

This commit is contained in:
Oliver 2021-11-25 14:23:27 +11:00
parent 2065c05519
commit 68f7887379
5 changed files with 19 additions and 125 deletions

View File

@ -157,20 +157,6 @@ class BomMatchItemForm(MatchItemForm):
return super().get_special_field(col_guess, row, file_manager)
class CreatePartRelatedForm(HelperForm):
""" Form for creating a PartRelated object """
class Meta:
model = PartRelated
fields = [
'part_1',
'part_2',
]
labels = {
'part_2': _('Related Part'),
}
class SetPartCategoryForm(forms.Form):
""" Form for setting the category of multiple Part objects """

View File

@ -759,11 +759,25 @@
);
$("#add-related-part").click(function() {
launchModalForm("{% url 'part-related-create' %}", {
data: {
part: {{ part.id }},
constructForm('{% url "api-part-related-list" %}', {
method: 'POST',
fields: {
part_1: {
hidden: true,
value: {{ part.pk }},
},
part_2: {
label: '{% trans "Related Part" %}',
filters: {
exclude_related: {{ part.pk }},
}
}
},
reload: true,
title: '{% trans "Add Related Part" %}',
onSuccess: function() {
$('#related-parts-table').bootstrapTable('refresh');
}
});
});

View File

@ -145,36 +145,6 @@ class PartDetailTest(PartViewTestCase):
self.assertIn('streaming_content', dir(response))
class PartRelatedTests(PartViewTestCase):
def test_valid_create(self):
""" test creation of a related part """
# Test GET view
response = self.client.get(reverse('part-related-create'), {'part': 1},
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(response.status_code, 200)
# Test POST view with valid form data
response = self.client.post(reverse('part-related-create'), {'part_1': 1, 'part_2': 2},
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertContains(response, '"form_valid": true', status_code=200)
# Try to create the same relationship with part_1 and part_2 pks reversed
response = self.client.post(reverse('part-related-create'), {'part_1': 2, 'part_2': 1},
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertContains(response, '"form_valid": false', status_code=200)
# Try to create part related to itself
response = self.client.post(reverse('part-related-create'), {'part_1': 1, 'part_2': 1},
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertContains(response, '"form_valid": false', status_code=200)
# Check final count
n = PartRelated.objects.all().count()
self.assertEqual(n, 1)
class PartQRTest(PartViewTestCase):
""" Tests for the Part QR Code AJAX view """

View File

@ -12,10 +12,6 @@ from django.conf.urls import url, include
from . import views
part_related_urls = [
url(r'^new/?', views.PartRelatedCreate.as_view(), name='part-related-create'),
url(r'^(?P<pk>\d+)/delete/?', views.PartRelatedDelete.as_view(), name='part-related-delete'),
]
sale_price_break_urls = [
url(r'^new/', views.PartSalePriceBreakCreate.as_view(), name='sale-price-break-create'),
@ -96,9 +92,6 @@ part_urls = [
# Part category
url(r'^category/', include(category_urls)),
# Part related
url(r'^related-parts/', include(part_related_urls)),
# Part price breaks
url(r'^sale-price/', include(sale_price_break_urls)),

View File

@ -30,7 +30,7 @@ import io
from rapidfuzz import fuzz
from decimal import Decimal, InvalidOperation
from .models import PartCategory, Part, PartRelated
from .models import PartCategory, Part
from .models import PartParameterTemplate
from .models import PartCategoryParameterTemplate
from .models import BomItem
@ -85,75 +85,6 @@ class PartIndex(InvenTreeRoleMixin, ListView):
return context
class PartRelatedCreate(AjaxCreateView):
""" View for creating a new PartRelated object
- The view only makes sense if a Part object is passed to it
"""
model = PartRelated
form_class = part_forms.CreatePartRelatedForm
ajax_form_title = _("Add Related Part")
ajax_template_name = "modal_form.html"
def get_initial(self):
""" Set parent part as part_1 field """
initials = {}
part_id = self.request.GET.get('part', None)
if part_id:
try:
initials['part_1'] = Part.objects.get(pk=part_id)
except (Part.DoesNotExist, ValueError):
pass
return initials
def get_form(self):
""" Create a form to upload a new PartRelated
- Hide the 'part_1' field (parent part)
- Display parts which are not yet related
"""
form = super(AjaxCreateView, self).get_form()
form.fields['part_1'].widget = HiddenInput()
try:
# Get parent part
parent_part = self.get_initial()['part_1']
# Get existing related parts
related_parts = [related_part[1].pk for related_part in parent_part.get_related_parts()]
# Build updated choice list excluding
# - parts already related to parent part
# - the parent part itself
updated_choices = []
for choice in form.fields["part_2"].choices:
if (choice[0] not in related_parts) and (choice[0] != parent_part.pk):
updated_choices.append(choice)
# Update choices for related part
form.fields['part_2'].choices = updated_choices
except KeyError:
pass
return form
class PartRelatedDelete(AjaxDeleteView):
""" View for deleting a PartRelated object """
model = PartRelated
ajax_form_title = _("Delete Related Part")
context_object_name = "related"
# Explicit role requirement
role_required = 'part.change'
class PartSetCategory(AjaxUpdateView):
""" View for settings the part category for multiple parts at once """