mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add a form/view/etc for BOM validation
This commit is contained in:
parent
c7f0d56be4
commit
e3a9a70678
@ -24,6 +24,21 @@ class PartImageForm(HelperForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BomValidateForm(HelperForm):
|
||||||
|
""" Simple confirmation form for BOM validation.
|
||||||
|
User is presented with a single checkbox input,
|
||||||
|
to confirm that the BOM for this part is valid
|
||||||
|
"""
|
||||||
|
|
||||||
|
validate = forms.BooleanField(required=False, initial=False, help_text='Confirm that the BOM is correct')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Part
|
||||||
|
fields = [
|
||||||
|
'validate'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class BomExportForm(HelperForm):
|
class BomExportForm(HelperForm):
|
||||||
|
|
||||||
# TODO - Define these choices somewhere else, and import them here
|
# TODO - Define these choices somewhere else, and import them here
|
||||||
|
@ -24,6 +24,7 @@ from django.contrib.auth.models import User
|
|||||||
from django.db.models.signals import pre_delete
|
from django.db.models.signals import pre_delete
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
from fuzzywuzzy import fuzz
|
from fuzzywuzzy import fuzz
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
@ -468,14 +469,16 @@ class Part(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def bom_count(self):
|
def bom_count(self):
|
||||||
|
""" Return the number of items contained in the BOM for this part """
|
||||||
return self.bom_items.count()
|
return self.bom_items.count()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def used_in_count(self):
|
def used_in_count(self):
|
||||||
|
""" Return the number of part BOMs that this part appears in """
|
||||||
return self.used_in.count()
|
return self.used_in.count()
|
||||||
|
|
||||||
def get_bom_hash(self):
|
def get_bom_hash(self):
|
||||||
""" Return a checksum hash for the BOM for this part.
|
""" Return a checksum hash for the BOM for this part.
|
||||||
Used to determine if the BOM has changed (and needs to be signed off!)
|
Used to determine if the BOM has changed (and needs to be signed off!)
|
||||||
|
|
||||||
For hash is calculated from the following fields of each BOM item:
|
For hash is calculated from the following fields of each BOM item:
|
||||||
@ -511,7 +514,7 @@ class Part(models.Model):
|
|||||||
- Saves the current date and the checking user
|
- Saves the current date and the checking user
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.bom_checksum = get_bom_hash()
|
self.bom_checksum = self.get_bom_hash()
|
||||||
self.bom_checked_by = user
|
self.bom_checked_by = user
|
||||||
self.bom_checked_date = datetime.now().date()
|
self.bom_checked_date = datetime.now().date()
|
||||||
|
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
<span class='caret'></span>
|
<span class='caret'></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class='dropdown-menu'>
|
<ul class='dropdown-menu'>
|
||||||
|
{% if part.is_bom_valid == False %}
|
||||||
|
<li><a href='#' id='validate-bom' title='Validate BOM'>Validate BOM</a></li>
|
||||||
|
{% endif %}
|
||||||
<li><a href='#' id='edit-bom' title='Edit BOM'>Edit BOM</a></li>
|
<li><a href='#' id='edit-bom' title='Edit BOM'>Edit BOM</a></li>
|
||||||
<li><a href='#' id='export-bom' title='Export BOM'>Export BOM</a></li>
|
<li><a href='#' id='export-bom' title='Export BOM'>Export BOM</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -87,6 +90,15 @@
|
|||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
|
$("#validate-bom").click(function() {
|
||||||
|
launchModalForm(
|
||||||
|
"{% url 'bom-validate' part.id %}",
|
||||||
|
{
|
||||||
|
reload: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
$("#edit-bom").click(function () {
|
$("#edit-bom").click(function () {
|
||||||
location.href = "{% url 'part-bom' part.id %}?edit=True";
|
location.href = "{% url 'part-bom' part.id %}?edit=True";
|
||||||
});
|
});
|
||||||
|
5
InvenTree/part/templates/part/bom_validate.html
Normal file
5
InvenTree/part/templates/part/bom_validate.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{% extends "modal_form.html" %}
|
||||||
|
|
||||||
|
{% block pre_form_content %}
|
||||||
|
Confirm that the Bill of Materials (BOM) is valid for:<br><i>{{ part.full_name }}</i>
|
||||||
|
{% endblock %}
|
@ -35,6 +35,7 @@ part_detail_urls = [
|
|||||||
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
|
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
|
||||||
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
|
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
|
||||||
url(r'^bom-export/?', views.BomDownload.as_view(), name='bom-export'),
|
url(r'^bom-export/?', views.BomDownload.as_view(), name='bom-export'),
|
||||||
|
url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'),
|
||||||
|
|
||||||
url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'),
|
url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'),
|
||||||
url(r'^attachments/?', views.PartDetail.as_view(template_name='part/attachments.html'), name='part-attachments'),
|
url(r'^attachments/?', views.PartDetail.as_view(template_name='part/attachments.html'), name='part-attachments'),
|
||||||
|
@ -331,12 +331,50 @@ class PartEdit(AjaxUpdateView):
|
|||||||
return form
|
return form
|
||||||
|
|
||||||
|
|
||||||
|
class BomValidate(AjaxUpdateView):
|
||||||
|
""" Modal form view for validating a part BOM """
|
||||||
|
|
||||||
|
model = Part
|
||||||
|
ajax_form_title = "Validate BOM"
|
||||||
|
ajax_template_name = 'part/bom_validate.html'
|
||||||
|
context_object_name = 'part'
|
||||||
|
form_class = part_forms.BomValidateForm
|
||||||
|
|
||||||
|
def get_context(self):
|
||||||
|
return {
|
||||||
|
'part': self.get_object(),
|
||||||
|
}
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
|
||||||
|
form = self.get_form()
|
||||||
|
|
||||||
|
return self.renderJsonResponse(request, form, context=self.get_context())
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
||||||
|
form = self.get_form()
|
||||||
|
part = self.get_object()
|
||||||
|
|
||||||
|
confirmed = str2bool(request.POST.get('validate', False))
|
||||||
|
|
||||||
|
if confirmed:
|
||||||
|
part.validate_bom(request.user)
|
||||||
|
else:
|
||||||
|
form.errors['validate'] = ['Confirm that the BOM is valid']
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'form_valid': confirmed
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.renderJsonResponse(request, form, data, context=self.get_context())
|
||||||
|
|
||||||
|
|
||||||
class BomExport(AjaxView):
|
class BomExport(AjaxView):
|
||||||
|
|
||||||
model = Part
|
model = Part
|
||||||
ajax_form_title = 'Export BOM'
|
ajax_form_title = 'Export BOM'
|
||||||
ajax_template_name = 'part/bom_export.html'
|
ajax_template_name = 'part/bom_export.html'
|
||||||
context_object_name = 'part'
|
|
||||||
form_class = part_forms.BomExportForm
|
form_class = part_forms.BomExportForm
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
@ -345,17 +383,6 @@ class BomExport(AjaxView):
|
|||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
form = self.form_class()
|
form = self.form_class()
|
||||||
|
|
||||||
"""
|
|
||||||
part = self.get_object()
|
|
||||||
|
|
||||||
context = {
|
|
||||||
'part': part
|
|
||||||
}
|
|
||||||
|
|
||||||
if request.is_ajax():
|
|
||||||
passs
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.renderJsonResponse(request, form)
|
return self.renderJsonResponse(request, form)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
Loading…
Reference in New Issue
Block a user