2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 20:45:44 +00:00

Adds API endpoint to delete build outputs

This commit is contained in:
Oliver
2022-02-10 00:46:26 +11:00
parent 18ac1ceebe
commit 96af074365
6 changed files with 253 additions and 13 deletions

View File

@ -245,6 +245,7 @@ class BuildOutputComplete(generics.CreateAPIView):
ctx = super().get_serializer_context()
ctx['request'] = self.request
ctx['to_complete'] = True
try:
ctx['build'] = Build.objects.get(pk=self.kwargs.get('pk', None))
@ -254,6 +255,29 @@ class BuildOutputComplete(generics.CreateAPIView):
return ctx
class BuildOutputDelete(generics.CreateAPIView):
"""
API endpoint for deleting multiple build outputs
"""
queryset = Build.objects.none()
serializer_class = build.serializers.BuildOutputDeleteSerializer
def get_serializer_context(self):
ctx = super().get_serializer_context()
ctx['request'] = self.request
try:
ctx['build'] = Build.objects.get(pk=self.kwargs.get('pk', None))
except:
pass
return ctx
class BuildFinish(generics.CreateAPIView):
"""
API endpoint for marking a build as finished (completed)
@ -432,6 +456,7 @@ build_api_urls = [
url(r'^(?P<pk>\d+)/', include([
url(r'^allocate/', BuildAllocate.as_view(), name='api-build-allocate'),
url(r'^complete/', BuildOutputComplete.as_view(), name='api-build-output-complete'),
url(r'^delete-outputs/', BuildOutputDelete.as_view(), name='api-build-output-delete'),
url(r'^finish/', BuildFinish.as_view(), name='api-build-finish'),
url(r'^unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'),
url(r'^.*$', BuildDetail.as_view(), name='api-build-detail'),

View File

@ -708,7 +708,7 @@ class Build(MPTTModel, ReferenceIndexingMixin):
self.save()
@transaction.atomic
def deleteBuildOutput(self, output):
def delete_output(self, output):
"""
Remove a build output from the database:

View File

@ -141,6 +141,9 @@ class BuildOutputSerializer(serializers.Serializer):
build = self.context['build']
# As this serializer can be used in multiple contexts, we need to work out why we are here
to_complete = self.context.get('to_complete', False)
# The stock item must point to the build
if output.build != build:
raise ValidationError(_("Build output does not match the parent build"))
@ -153,9 +156,11 @@ class BuildOutputSerializer(serializers.Serializer):
if not output.is_building:
raise ValidationError(_("This build output has already been completed"))
# The build output must have all tracked parts allocated
if not build.isFullyAllocated(output):
raise ValidationError(_("This build output is not fully allocated"))
if to_complete:
# The build output must have all tracked parts allocated
if not build.isFullyAllocated(output):
raise ValidationError(_("This build output is not fully allocated"))
return output
@ -165,6 +170,50 @@ class BuildOutputSerializer(serializers.Serializer):
]
class BuildOutputDeleteSerializer(serializers.Serializer):
"""
DRF serializer for deleting (cancelling) one or more build outputs
"""
class Meta:
fields = [
'outputs',
]
outputs = BuildOutputSerializer(
many=True,
required=True,
)
def validate(self, data):
data = super().validate(data)
outputs = data.get('outputs', [])
if len(outputs) == 0:
raise ValidationError(_("A list of build outputs must be provided"))
return data
def save(self):
"""
'save' the serializer to delete the build outputs
"""
data = self.validated_data
outputs = data.get('outputs', [])
build = self.context['build']
with transaction.atomic():
for item in outputs:
output = item['output']
build.delete_output(output)
class BuildOutputCompleteSerializer(serializers.Serializer):
"""
DRF serializer for completing one or more build outputs

View File

@ -243,13 +243,16 @@
<!-- Build output actions -->
<div class='btn-group'>
<button id='output-options' class='btn btn-primary dropdown-toiggle' type='button' data-bs-toggle='dropdown' title='{% trans "Output Actions" %}'>
<button id='output-options' class='btn btn-primary dropdown-toggle' type='button' data-bs-toggle='dropdown' title='{% trans "Output Actions" %}'>
<span class='fas fa-tools'></span> <span class='caret'></span>
</button>
<ul class='dropdown-menu'>
<li><a class='dropdown-item' href='#' id='multi-output-complete' title='{% trans "Complete selected items" %}'>
<li><a class='dropdown-item' href='#' id='multi-output-complete' title='{% trans "Complete selected build outputs" %}'>
<span class='fas fa-check-circle icon-green'></span> {% trans "Complete outputs" %}
</a></li>
<li><a class='dropdown-item' href='#' id='multi-output-delete' title='{% trans "Delete selected build outputs" %}'>
<span class='fas fa-trash-alt icon-red'></span> {% trans "Delete outputs" %}
</a></li>
</ul>
</div>
{% include "filter_list.html" with id='incompletebuilditems' %}
@ -372,6 +375,7 @@ inventreeGet(
[
'#output-options',
'#multi-output-complete',
'#multi-output-delete',
]
);
@ -393,6 +397,24 @@ inventreeGet(
);
});
$('#multi-output-delete').click(function() {
var outputs = $('#build-output-table').bootstrapTable('getSelections');
deleteBuildOutputs(
build_info.pk,
outputs,
{
success: function() {
// Reload the "in progress" table
$('#build-output-table').bootstrapTable('refresh');
// Reload the "completed" table
$('#build-stock-table').bootstrapTable('refresh');
}
}
)
});
{% endif %}
{% if build.active and build.has_untracked_bom_items %}