Functional checkpoint: add/delete related parts from template

This commit is contained in:
eeintech 2020-10-16 13:50:31 -05:00
parent 8579abb9c2
commit 34e4409e7f
5 changed files with 83 additions and 71 deletions

View File

@ -1254,25 +1254,32 @@ class Part(MPTTModel):
return self.get_descendants(include_self=False)
def fetch_related_parts(self):
""" Return all related parts """
def get_related_parts(self):
""" Return list of tuples for all related parts:
- first value is PartRelated object
- second value is matching Part object
"""
related_parts = []
parts_1 = self.related_parts_1.filter(part_1__id=self.pk)
related_parts_1 = self.related_parts_1.filter(part_1__id=self.pk)
parts_2 = self.related_parts_2.filter(part_2__id=self.pk)
related_parts_2 = self.related_parts_2.filter(part_2__id=self.pk)
for part in parts_1:
# Append
related_parts.append(part.part_2)
for related_part in related_parts_1:
# Add to related parts list
related_parts.append((related_part, related_part.part_2))
for part in parts_2:
# Append
related_parts.append(part.part_1)
for related_part in related_parts_2:
# Add to related parts list
related_parts.append((related_part, related_part.part_1))
return related_parts
@property
def related_count(self):
return len(self.get_related_parts())
def attach_file(instance, filename):
""" Function for storing a file for a PartAttachment
@ -1783,7 +1790,8 @@ class PartRelated(models.Model):
@classmethod
def create(cls, part_1, part_2):
''' Create PartRelated object '''
''' Create PartRelated object and relationship between two parts '''
related_part = cls()
related_part.create_relationship(part_1, part_2)
return related_part

View File

@ -18,7 +18,32 @@
</div>
</div>
<table class='table table-striped table-condensed related-table' id='table-related-part' data-toolbar='#button-bar'>
<table id='table-related-part' class='table table-condensed table-striped' data-toolbar='#button-toolbar'>
<thead>
<tr>
<th data-field='part' data-serachable='true'>{% trans "Part" %}</th>
</tr>
</thead>
<tbody>
{% for item in part.get_related_parts %}
{% with part_related=item.0 part=item.1 %}
<tr>
<td>
<a class='hover-icon'>
<img class='hover-img-thumb' src='{{ part.get_thumbnail_url }}'>
<img class='hover-img-large' src='{{ part.get_thumbnail_url }}'>
</a>
<a href='/part/{{ part.id }}/'>{{ part }}</a>
<div class='btn-group' style='float: right;'>
{% if roles.part.change %}
<button title='{% trans "Delete" %}' class='btn btn-default btn-glyph delete-related-part' url="{% url 'part-related-delete' part_related.id %}" type='button'><span class='fas fa-trash-alt icon-red'/></button>
{% endif %}
</div>
</td>
</tr>
{% endwith %}
{% endfor %}
</tbody>
</table>
@ -27,20 +52,24 @@
{% block js_ready %}
{{ block.super }}
loadPartRelatedTable($("#table-related-part"), {
url: "{% url 'api-part-list' %}",
params: {
part: {{ part.id }},
},
});
$('#table-related-part').inventreeTable({
});
$("#add-related-part").click(function() {
$("#add-related-part").click(function() {
launchModalForm("{% url 'part-related-create' %}", {
data: {
part: {{ part.id }},
},
reload: true,
});
});
});
$('.delete-related-part').click(function() {
var button = $(this);
launchModalForm(button.attr('url'), {
reload: true,
});
});
{% endblock %}

View File

@ -64,7 +64,7 @@
</li>
{% endif %}
<li{% ifequal tab 'related-parts' %} class="active"{% endifequal %}>
<a href="{% url 'part-related' part.id %}">{% trans "Related Parts" %} {% if part.related_count > 0 %}<span class="badge">{{ part.related_count }}</span>{% endif %}</a>
<a href="{% url 'part-related' part.id %}">{% trans "Related" %} {% if part.related_count > 0 %}<span class="badge">{{ part.related_count }}</span>{% endif %}</a>
</li>
<li{% ifequal tab 'attachments' %} class="active"{% endifequal %}>
<a href="{% url 'part-attachments' part.id %}">{% trans "Attachments" %} {% if part.attachment_count > 0 %}<span class="badge">{{ part.attachment_count }}</span>{% endif %}</a>

View File

@ -81,10 +81,8 @@ class PartRelatedCreate(AjaxCreateView):
ajax_template_name = "modal_form.html"
role_required = 'part.change'
# TODO: QuerySet should not show parts already related to object
def get_initial(self):
""" Point part_1 to parent part """
""" Set parent part as part_1 field """
initials = {}
@ -102,12 +100,30 @@ class PartRelatedCreate(AjaxCreateView):
""" 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
updated_choices = []
for choice in form.fields["part_2"].choices:
if choice[0] not in related_parts:
updated_choices.append(choice)
# Update choices for related part
form.fields['part_2'].choices = updated_choices
except KeyError:
pass
return form
def post_save(self):
@ -116,14 +132,9 @@ class PartRelatedCreate(AjaxCreateView):
form = self.get_form()
if form.is_valid():
print('form is valid!')
part_1 = form.cleaned_data['part_1']
part_2 = form.cleaned_data['part_2']
print(f'{part_1=}')
print(f'{part_2=}')
PartRelated.create(part_1, part_2)
@ -132,7 +143,6 @@ class PartRelatedDelete(AjaxDeleteView):
model = PartRelated
ajax_form_title = _("Delete Related Part")
ajax_template_name = "related_delete.html"
context_object_name = "related"
role_required = 'part.change'

View File

@ -163,41 +163,6 @@ function loadSimplePartTable(table, url, options={}) {
}
function loadPartRelatedTable(table, options={}) {
/* Load related parts table */
var columns = [
{
field: options.params['part'],
title: '{% trans 'Part' %}',
sortable: true,
sortName: 'name',
formatter: function(value, row, index, field) {
var name = '';
if (row.IPN) {
name += row.IPN + ' | ' + row.name;
} else {
name += row.name;
}
return renderLink(name, '/part/' + row.pk + '/');
}
}
];
$(table).inventreeTable({
sortName: 'part',
groupBy: false,
name: options.name || 'related_parts',
formatNoMatches: function() { return "{% trans "No parts found" %}"; },
columns: columns,
showColumns: true,
});
}
function loadParametricPartTable(table, options={}) {
/* Load parametric table for part parameters
*