diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 458696b75c..89a285cf60 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -135,7 +135,7 @@ class PartAttachmentDelete(AjaxDeleteView): model = PartAttachment ajax_form_title = _("Delete Part Attachment") - ajax_template_name = "part/attachment_delete.html" + ajax_template_name = "attachment_delete.html" context_object_name = "attachment" def get_data(self): diff --git a/InvenTree/stock/admin.py b/InvenTree/stock/admin.py index e233908ec7..86099cdbac 100644 --- a/InvenTree/stock/admin.py +++ b/InvenTree/stock/admin.py @@ -8,7 +8,7 @@ from import_export.resources import ModelResource from import_export.fields import Field import import_export.widgets as widgets -from .models import StockLocation, StockItem +from .models import StockLocation, StockItem, StockItemAttachment from .models import StockItemTracking from build.models import Build @@ -108,6 +108,11 @@ class StockItemAdmin(ImportExportModelAdmin): list_display = ('part', 'quantity', 'location', 'status', 'updated') +class StockAttachmentAdmin(admin.ModelAdmin): + + list_display = ('stock_item', 'attachment', 'comment') + + class StockTrackingAdmin(ImportExportModelAdmin): list_display = ('item', 'date', 'title') @@ -115,3 +120,4 @@ class StockTrackingAdmin(ImportExportModelAdmin): admin.site.register(StockLocation, LocationAdmin) admin.site.register(StockItem, StockItemAdmin) admin.site.register(StockItemTracking, StockTrackingAdmin) +admin.site.register(StockItemAttachment, StockAttachmentAdmin) diff --git a/InvenTree/stock/forms.py b/InvenTree/stock/forms.py index fef6ecc7a5..a4578440cb 100644 --- a/InvenTree/stock/forms.py +++ b/InvenTree/stock/forms.py @@ -13,7 +13,21 @@ from mptt.fields import TreeNodeChoiceField from InvenTree.helpers import GetExportFormats from InvenTree.forms import HelperForm -from .models import StockLocation, StockItem, StockItemTracking +from .models import StockLocation, StockItem, StockItemTracking, StockItemAttachment + + +class EditStockItemAttachmentForm(HelperForm): + """ + Form for creating / editing a StockItemAttachment object + """ + + class Meta: + model = StockItemAttachment + fields = [ + 'stock_item', + 'attachment', + 'comment' + ] class EditStockLocationForm(HelperForm): diff --git a/InvenTree/stock/migrations/0036_stockitemattachment.py b/InvenTree/stock/migrations/0036_stockitemattachment.py new file mode 100644 index 0000000000..946f6251b0 --- /dev/null +++ b/InvenTree/stock/migrations/0036_stockitemattachment.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.5 on 2020-05-06 23:36 + +import InvenTree.models +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0035_auto_20200502_2308'), + ] + + operations = [ + migrations.CreateModel( + name='StockItemAttachment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('attachment', models.FileField(help_text='Select file to attach', upload_to=InvenTree.models.rename_attachment)), + ('comment', models.CharField(help_text='File comment', max_length=100)), + ('stock_item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='stock.StockItem')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index f514eea3da..ecfbf751c9 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -6,6 +6,8 @@ Stock database model definitions # -*- coding: utf-8 -*- from __future__ import unicode_literals +import os + from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError from django.urls import reverse @@ -27,7 +29,7 @@ from datetime import datetime from InvenTree import helpers from InvenTree.status_codes import StockStatus -from InvenTree.models import InvenTreeTree +from InvenTree.models import InvenTreeTree, InvenTreeAttachment from InvenTree.fields import InvenTreeURLField from part import models as PartModels @@ -935,6 +937,21 @@ def before_delete_stock_item(sender, instance, using, **kwargs): StockItem.objects.rebuild() +class StockItemAttachment(InvenTreeAttachment): + """ + Model for storing file attachments against a StockItem object. + """ + + def getSubdir(self): + return os.path.join("stock_files", str(self.stock_item.id)) + + stock_item = models.ForeignKey( + StockItem, + on_delete=models.CASCADE, + related_name='attachments' + ) + + class StockItemTracking(models.Model): """ Stock tracking entry - breacrumb for keeping track of automated stock transactions diff --git a/InvenTree/part/templates/part/attachment_delete.html b/InvenTree/stock/templates/stock/attachment_delete.html similarity index 100% rename from InvenTree/part/templates/part/attachment_delete.html rename to InvenTree/stock/templates/stock/attachment_delete.html diff --git a/InvenTree/stock/templates/stock/item_attachments.html b/InvenTree/stock/templates/stock/item_attachments.html new file mode 100644 index 0000000000..6aeff554d0 --- /dev/null +++ b/InvenTree/stock/templates/stock/item_attachments.html @@ -0,0 +1,82 @@ +{% extends "stock/item_base.html" %} + +{% load static %} +{% load i18n %} + +{% block details %} + +{% include "stock/tabs.html" with tab='attachments' %} + +
{% trans "File" %} | +{% trans "Comment" %} | ++ |
---|---|---|
{{ attachment.basename }} | +{{ attachment.comment }} | +
+
+
+
+
+ |
+