mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
"Validate BOM" now uses the API also
This commit is contained in:
parent
70f9a0fe13
commit
2c0da25cbc
@ -474,6 +474,56 @@ class PartCopyBOM(generics.CreateAPIView):
|
||||
return ctx
|
||||
|
||||
|
||||
class PartValidateBOM(generics.RetrieveUpdateAPIView):
|
||||
"""
|
||||
API endpoint for 'validating' the BOM for a given Part
|
||||
"""
|
||||
|
||||
class BOMValidateSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Part
|
||||
fields = [
|
||||
'checksum',
|
||||
'valid',
|
||||
]
|
||||
|
||||
checksum = serializers.CharField(
|
||||
read_only=True,
|
||||
source='bom_checksum',
|
||||
)
|
||||
|
||||
valid = serializers.BooleanField(
|
||||
write_only=True,
|
||||
default=False,
|
||||
label=_('Valid'),
|
||||
help_text=_('Validate entire Bill of Materials'),
|
||||
)
|
||||
|
||||
def validate_valid(self, valid):
|
||||
if not valid:
|
||||
raise ValidationError(_('This option must be selected'))
|
||||
|
||||
queryset = Part.objects.all()
|
||||
|
||||
serializer_class = BOMValidateSerializer
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
|
||||
part = self.get_object()
|
||||
|
||||
partial = kwargs.pop('partial', False)
|
||||
|
||||
serializer = self.get_serializer(part, data=request.data, partial=partial)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
part.validate_bom(request.user)
|
||||
|
||||
return Response({
|
||||
'checksum': part.bom_checksum,
|
||||
})
|
||||
|
||||
|
||||
class PartDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
""" API endpoint for detail view of a single Part object """
|
||||
|
||||
@ -1605,8 +1655,11 @@ part_api_urls = [
|
||||
# Endpoint for extra serial number information
|
||||
url(r'^serial-numbers/', PartSerialNumberDetail.as_view(), name='api-part-serial-number-detail'),
|
||||
|
||||
# Endpoint for duplicating a BOM
|
||||
url(r'^copy-bom/', PartCopyBOM.as_view(), name='api-part-copy-bom'),
|
||||
# Endpoint for duplicating a BOM for the specific Part
|
||||
url(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'),
|
||||
|
||||
# Endpoint for validating a BOM for the specific Part
|
||||
url(r'^bom-validate/', PartValidateBOM.as_view(), name='api-part-bom-validate'),
|
||||
|
||||
# Part detail endpoint
|
||||
url(r'^.*$', PartDetail.as_view(), name='api-part-detail'),
|
||||
|
@ -55,21 +55,6 @@ class PartImageDownloadForm(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, label=_('validate'), help_text=_('Confirm that the BOM is correct'))
|
||||
|
||||
class Meta:
|
||||
model = Part
|
||||
fields = [
|
||||
'validate'
|
||||
]
|
||||
|
||||
|
||||
class BomMatchItemForm(MatchItemForm):
|
||||
""" Override MatchItemForm fields """
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
{% extends "modal_form.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block pre_form_content %}
|
||||
{% blocktrans with part.full_name as part %}Confirm that the Bill of Materials (BOM) is valid for:<br><em>{{ part }}</em>{% endblocktrans %}
|
||||
|
||||
<div class='alert alert-warning alert-block'>
|
||||
{% trans 'This will validate each line in the BOM.' %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -609,12 +609,10 @@
|
||||
});
|
||||
|
||||
$("#validate-bom").click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'bom-validate' part.id %}",
|
||||
{
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
|
||||
validateBom({{ part.id }}, {
|
||||
reload: true
|
||||
});
|
||||
});
|
||||
|
||||
$("#download-bom").click(function () {
|
||||
|
@ -35,7 +35,6 @@ part_detail_urls = [
|
||||
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
|
||||
url(r'^bom-export/?', views.BomExport.as_view(), name='bom-export'),
|
||||
url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'),
|
||||
url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'),
|
||||
|
||||
url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'),
|
||||
|
||||
|
@ -694,48 +694,6 @@ class PartImageSelect(AjaxUpdateView):
|
||||
return self.renderJsonResponse(request, form, data)
|
||||
|
||||
|
||||
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 validate(self, part, form, **kwargs):
|
||||
|
||||
confirm = str2bool(form.cleaned_data.get('validate', False))
|
||||
|
||||
if not confirm:
|
||||
form.add_error('validate', _('Confirm that the BOM is valid'))
|
||||
|
||||
def save(self, part, form, **kwargs):
|
||||
"""
|
||||
Mark the BOM as validated
|
||||
"""
|
||||
|
||||
part.validate_bom(self.request.user)
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Validated Bill of Materials')
|
||||
}
|
||||
|
||||
|
||||
class BomUpload(InvenTreeRoleMixin, FileManagementFormView):
|
||||
""" View for uploading a BOM file, and handling BOM data importing.
|
||||
|
||||
|
@ -207,6 +207,11 @@ function showApiError(xhr, url) {
|
||||
title = '{% trans "Error 404: Resource Not Found" %}';
|
||||
message = '{% trans "The requested resource could not be located on the server" %}';
|
||||
break;
|
||||
// Method not allowed
|
||||
case 405:
|
||||
title = '{% trans "Error 405: Method Not Allowed" %}';
|
||||
message = '{% trans "HTTP method not allowed at URL" %}';
|
||||
break;
|
||||
// Timeout
|
||||
case 408:
|
||||
title = '{% trans "Error 408: Timeout" %}';
|
||||
|
@ -40,6 +40,7 @@
|
||||
loadStockPricingChart,
|
||||
partStockLabel,
|
||||
toggleStar,
|
||||
validateBom,
|
||||
*/
|
||||
|
||||
/* Part API functions
|
||||
@ -429,9 +430,34 @@ function toggleStar(options) {
|
||||
}
|
||||
|
||||
|
||||
/* Validate a BOM */
|
||||
function validateBom(part_id, options={}) {
|
||||
|
||||
var html = `
|
||||
<div class='alert alert-block alert-success'>
|
||||
{% trans "Validating the BOM will mark each line item as valid" %}
|
||||
</div>
|
||||
`;
|
||||
|
||||
constructForm(`/api/part/${part_id}/bom-validate/`, {
|
||||
method: 'PUT',
|
||||
fields: {
|
||||
valid: {},
|
||||
},
|
||||
preFormContent: html,
|
||||
title: '{% trans "Validate Bill of Materials" %}',
|
||||
reload: options.reload,
|
||||
onSuccess: function(response) {
|
||||
showMessage('{% trans "Validated Bill of Materials" %}');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* Duplicate a BOM */
|
||||
function duplicateBom(part_id, options={}) {
|
||||
constructForm(`/api/part/${part_id}/copy-bom/`, {
|
||||
|
||||
constructForm(`/api/part/${part_id}/bom-copy/`, {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
part: {
|
||||
|
Loading…
Reference in New Issue
Block a user