mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-17 04:25:42 +00:00
Merge branch 'master' of https://github.com/inventree/InvenTree into extend-build-order
This commit is contained in:
@ -11,11 +11,12 @@ from rest_framework import generics
|
||||
|
||||
from django.conf.urls import url, include
|
||||
|
||||
from InvenTree.api import AttachmentMixin
|
||||
from InvenTree.helpers import str2bool, isNull
|
||||
from InvenTree.status_codes import BuildStatus
|
||||
|
||||
from .models import Build, BuildItem
|
||||
from .serializers import BuildSerializer, BuildItemSerializer
|
||||
from .models import Build, BuildItem, BuildOrderAttachment
|
||||
from .serializers import BuildAttachmentSerializer, BuildSerializer, BuildItemSerializer
|
||||
|
||||
|
||||
class BuildList(generics.ListCreateAPIView):
|
||||
@ -228,14 +229,40 @@ class BuildItemList(generics.ListCreateAPIView):
|
||||
]
|
||||
|
||||
|
||||
build_item_api_urls = [
|
||||
url('^.*$', BuildItemList.as_view(), name='api-build-item-list'),
|
||||
]
|
||||
class BuildAttachmentList(generics.ListCreateAPIView, AttachmentMixin):
|
||||
"""
|
||||
API endpoint for listing (and creating) BuildOrderAttachment objects
|
||||
"""
|
||||
|
||||
queryset = BuildOrderAttachment.objects.all()
|
||||
serializer_class = BuildAttachmentSerializer
|
||||
|
||||
|
||||
class BuildAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMixin):
|
||||
"""
|
||||
Detail endpoint for a BuildOrderAttachment object
|
||||
"""
|
||||
|
||||
queryset = BuildOrderAttachment.objects.all()
|
||||
serializer_class = BuildAttachmentSerializer
|
||||
|
||||
|
||||
build_api_urls = [
|
||||
url(r'^item/', include(build_item_api_urls)),
|
||||
|
||||
# Attachments
|
||||
url(r'^attachment/', include([
|
||||
url(r'^(?P<pk>\d+)/', BuildAttachmentDetail.as_view(), name='api-build-attachment-detail'),
|
||||
url('^.*$', BuildAttachmentList.as_view(), name='api-build-attachment-list'),
|
||||
])),
|
||||
|
||||
# Build Items
|
||||
url(r'^item/', include([
|
||||
url('^.*$', BuildItemList.as_view(), name='api-build-item-list')
|
||||
])),
|
||||
|
||||
# Build Detail
|
||||
url(r'^(?P<pk>\d+)/', BuildDetail.as_view(), name='api-build-detail'),
|
||||
|
||||
# Build List
|
||||
url(r'^.*$', BuildList.as_view(), name='api-build-list'),
|
||||
]
|
||||
|
@ -15,7 +15,7 @@ from InvenTree.fields import DatePickerFormField
|
||||
|
||||
from InvenTree.status_codes import StockStatus
|
||||
|
||||
from .models import Build, BuildItem, BuildOrderAttachment
|
||||
from .models import Build, BuildItem
|
||||
|
||||
from stock.models import StockLocation, StockItem
|
||||
|
||||
@ -275,17 +275,3 @@ class EditBuildItemForm(HelperForm):
|
||||
'quantity',
|
||||
'install_into',
|
||||
]
|
||||
|
||||
|
||||
class EditBuildAttachmentForm(HelperForm):
|
||||
"""
|
||||
Form for creating / editing a BuildAttachment object
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = BuildOrderAttachment
|
||||
fields = [
|
||||
'build',
|
||||
'attachment',
|
||||
'comment'
|
||||
]
|
||||
|
@ -1,8 +1,13 @@
|
||||
# Generated by Django 3.2 on 2021-06-01 05:25
|
||||
|
||||
import logging
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
logger = logging.getLogger('inventree')
|
||||
|
||||
|
||||
def assign_bom_items(apps, schema_editor):
|
||||
"""
|
||||
Run through existing BuildItem objects,
|
||||
@ -13,7 +18,7 @@ def assign_bom_items(apps, schema_editor):
|
||||
BomItem = apps.get_model('part', 'bomitem')
|
||||
Part = apps.get_model('part', 'part')
|
||||
|
||||
print("Assigning BomItems to existing BuildItem objects")
|
||||
logger.info("Assigning BomItems to existing BuildItem objects")
|
||||
|
||||
count_valid = 0
|
||||
count_total = 0
|
||||
@ -41,7 +46,7 @@ def assign_bom_items(apps, schema_editor):
|
||||
pass
|
||||
|
||||
if count_total > 0:
|
||||
print(f"Assigned BomItem for {count_valid}/{count_total} entries")
|
||||
logger.info(f"Assigned BomItem for {count_valid}/{count_total} entries")
|
||||
|
||||
|
||||
def unassign_bom_items(apps, schema_editor):
|
||||
|
@ -60,6 +60,10 @@ class Build(MPTTModel):
|
||||
responsible: User (or group) responsible for completing the build
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def get_api_url():
|
||||
return reverse('api-build-list')
|
||||
|
||||
OVERDUE_FILTER = Q(status__in=BuildStatus.ACTIVE_CODES) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date())
|
||||
|
||||
class Meta:
|
||||
@ -1117,6 +1121,10 @@ class BuildItem(models.Model):
|
||||
quantity: Number of units allocated
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def get_api_url():
|
||||
return reverse('api-build-item-list')
|
||||
|
||||
def get_absolute_url(self):
|
||||
# TODO - Fix!
|
||||
return '/build/item/{pk}/'.format(pk=self.id)
|
||||
|
@ -10,13 +10,13 @@ from django.db.models import BooleanField
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from InvenTree.serializers import InvenTreeModelSerializer, UserSerializerBrief
|
||||
from InvenTree.serializers import InvenTreeModelSerializer, InvenTreeAttachmentSerializerField, UserSerializerBrief
|
||||
|
||||
from stock.serializers import StockItemSerializerBrief
|
||||
from stock.serializers import LocationSerializer
|
||||
from part.serializers import PartSerializer, PartBriefSerializer
|
||||
|
||||
from .models import Build, BuildItem
|
||||
from .models import Build, BuildItem, BuildOrderAttachment
|
||||
|
||||
|
||||
class BuildSerializer(InvenTreeModelSerializer):
|
||||
@ -148,3 +148,26 @@ class BuildItemSerializer(InvenTreeModelSerializer):
|
||||
'stock_item_detail',
|
||||
'quantity'
|
||||
]
|
||||
|
||||
|
||||
class BuildAttachmentSerializer(InvenTreeModelSerializer):
|
||||
"""
|
||||
Serializer for a BuildAttachment
|
||||
"""
|
||||
|
||||
attachment = InvenTreeAttachmentSerializerField(required=True)
|
||||
|
||||
class Meta:
|
||||
model = BuildOrderAttachment
|
||||
|
||||
fields = [
|
||||
'pk',
|
||||
'build',
|
||||
'attachment',
|
||||
'comment',
|
||||
'upload_date',
|
||||
]
|
||||
|
||||
read_only_fields = [
|
||||
'upload_date',
|
||||
]
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "build-attachment-create" %}',
|
||||
'{% url "api-build-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
build: {{ build.id }},
|
||||
@ -36,45 +36,49 @@ enableDragAndDrop(
|
||||
|
||||
// Callback for creating a new attachment
|
||||
$('#new-attachment').click(function() {
|
||||
launchModalForm(
|
||||
'{% url "build-attachment-create" %}',
|
||||
{
|
||||
reload: true,
|
||||
data: {
|
||||
build: {{ build.pk }},
|
||||
|
||||
constructForm('{% url "api-build-attachment-list" %}', {
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
build: {
|
||||
value: {{ build.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
method: 'POST',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
});
|
||||
});
|
||||
|
||||
// Callback for editing an attachment
|
||||
$("#attachment-table").on('click', '.attachment-edit-button', function() {
|
||||
var pk = $(this).attr('pk');
|
||||
loadAttachmentTable(
|
||||
'{% url "api-build-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
build: {{ build.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/build/attachment/${pk}/`;
|
||||
|
||||
var url = `/build/attachment/${pk}/edit/`;
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
|
||||
launchModalForm(
|
||||
url,
|
||||
{
|
||||
reload: true,
|
||||
constructForm(`/api/build/attachment/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Callback for deleting an attachment
|
||||
$("#attachment-table").on('click', '.attachment-delete-button', function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
var url = `/build/attachment/${pk}/delete/`;
|
||||
|
||||
launchModalForm(
|
||||
url,
|
||||
{
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$("#attachment-table").inventreeTable({});
|
||||
}
|
||||
);
|
||||
|
||||
{% endblock %}
|
||||
|
@ -36,12 +36,6 @@ build_urls = [
|
||||
url('^new/', views.BuildItemCreate.as_view(), name='build-item-create'),
|
||||
])),
|
||||
|
||||
url('^attachment/', include([
|
||||
url('^new/', views.BuildAttachmentCreate.as_view(), name='build-attachment-create'),
|
||||
url(r'^(?P<pk>\d+)/edit/', views.BuildAttachmentEdit.as_view(), name='build-attachment-edit'),
|
||||
url(r'^(?P<pk>\d+)/delete/', views.BuildAttachmentDelete.as_view(), name='build-attachment-delete'),
|
||||
])),
|
||||
|
||||
url(r'new/', views.BuildCreate.as_view(), name='build-create'),
|
||||
|
||||
url(r'^(?P<pk>\d+)/', include(build_detail_urls)),
|
||||
|
@ -12,7 +12,7 @@ from django.forms import HiddenInput
|
||||
from django.urls import reverse
|
||||
|
||||
from part.models import Part
|
||||
from .models import Build, BuildItem, BuildOrderAttachment
|
||||
from .models import Build, BuildItem
|
||||
from . import forms
|
||||
from stock.models import StockLocation, StockItem
|
||||
|
||||
@ -1058,88 +1058,3 @@ class BuildItemEdit(AjaxUpdateView):
|
||||
form.fields['install_into'].widget = HiddenInput()
|
||||
|
||||
return form
|
||||
|
||||
|
||||
class BuildAttachmentCreate(AjaxCreateView):
|
||||
"""
|
||||
View for creating a BuildAttachment
|
||||
"""
|
||||
|
||||
model = BuildOrderAttachment
|
||||
form_class = forms.EditBuildAttachmentForm
|
||||
ajax_form_title = _('Add Build Order Attachment')
|
||||
|
||||
def save(self, form, **kwargs):
|
||||
"""
|
||||
Add information on the user that uploaded the attachment
|
||||
"""
|
||||
|
||||
attachment = form.save(commit=False)
|
||||
attachment.user = self.request.user
|
||||
attachment.save()
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Added attachment')
|
||||
}
|
||||
|
||||
def get_initial(self):
|
||||
"""
|
||||
Get initial data for creating an attachment
|
||||
"""
|
||||
|
||||
initials = super().get_initial()
|
||||
|
||||
try:
|
||||
initials['build'] = Build.objects.get(pk=self.request.GET.get('build', -1))
|
||||
except (ValueError, Build.DoesNotExist):
|
||||
pass
|
||||
|
||||
return initials
|
||||
|
||||
def get_form(self):
|
||||
"""
|
||||
Hide the 'build' field if specified
|
||||
"""
|
||||
|
||||
form = super().get_form()
|
||||
|
||||
form.fields['build'].widget = HiddenInput()
|
||||
|
||||
return form
|
||||
|
||||
|
||||
class BuildAttachmentEdit(AjaxUpdateView):
|
||||
"""
|
||||
View for editing a BuildAttachment object
|
||||
"""
|
||||
|
||||
model = BuildOrderAttachment
|
||||
form_class = forms.EditBuildAttachmentForm
|
||||
ajax_form_title = _('Edit Attachment')
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
form.fields['build'].widget = HiddenInput()
|
||||
|
||||
return form
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Attachment updated')
|
||||
}
|
||||
|
||||
|
||||
class BuildAttachmentDelete(AjaxDeleteView):
|
||||
"""
|
||||
View for deleting a BuildAttachment
|
||||
"""
|
||||
|
||||
model = BuildOrderAttachment
|
||||
ajax_form_title = _('Delete Attachment')
|
||||
context_object_name = 'attachment'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'danger': _('Deleted attachment')
|
||||
}
|
||||
|
Reference in New Issue
Block a user