mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add new attechment functionality to new models
- Giving the ol' refactor tractor a fresh coat of paint
This commit is contained in:
parent
2369b40bbf
commit
366d4b2143
@ -8,6 +8,9 @@ from __future__ import unicode_literals
|
|||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
|
|
||||||
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
|
from rest_framework import filters
|
||||||
|
|
||||||
from rest_framework import permissions
|
from rest_framework import permissions
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
@ -41,6 +44,28 @@ class InfoView(AjaxView):
|
|||||||
return JsonResponse(data)
|
return JsonResponse(data)
|
||||||
|
|
||||||
|
|
||||||
|
class AttachmentMixin:
|
||||||
|
"""
|
||||||
|
Mixin for creating attachment objects,
|
||||||
|
and ensuring the user information is saved correctly.
|
||||||
|
"""
|
||||||
|
|
||||||
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
|
||||||
|
filter_backends = [
|
||||||
|
DjangoFilterBackend,
|
||||||
|
filters.OrderingFilter,
|
||||||
|
filters.SearchFilter,
|
||||||
|
]
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
""" Save the user information when a file is uploaded """
|
||||||
|
|
||||||
|
attachment = serializer.save()
|
||||||
|
attachment.user = self.request.user
|
||||||
|
attachment.save()
|
||||||
|
|
||||||
|
|
||||||
class ActionPluginView(APIView):
|
class ActionPluginView(APIView):
|
||||||
"""
|
"""
|
||||||
Endpoint for running custom action plugins.
|
Endpoint for running custom action plugins.
|
||||||
|
@ -12,6 +12,7 @@ from rest_framework import filters
|
|||||||
from django.conf.urls import url, include
|
from django.conf.urls import url, include
|
||||||
|
|
||||||
from InvenTree.helpers import str2bool
|
from InvenTree.helpers import str2bool
|
||||||
|
from InvenTree.api import AttachmentMixin
|
||||||
|
|
||||||
from part.models import Part
|
from part.models import Part
|
||||||
from company.models import SupplierPart
|
from company.models import SupplierPart
|
||||||
@ -200,7 +201,7 @@ class POLineItemDetail(generics.RetrieveUpdateAPIView):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class SOAttachmentList(generics.ListCreateAPIView):
|
class SOAttachmentList(generics.ListCreateAPIView, AttachmentMixin):
|
||||||
"""
|
"""
|
||||||
API endpoint for listing (and creating) a SalesOrderAttachment (file upload)
|
API endpoint for listing (and creating) a SalesOrderAttachment (file upload)
|
||||||
"""
|
"""
|
||||||
@ -208,12 +209,6 @@ class SOAttachmentList(generics.ListCreateAPIView):
|
|||||||
queryset = SalesOrderAttachment.objects.all()
|
queryset = SalesOrderAttachment.objects.all()
|
||||||
serializer_class = SOAttachmentSerializer
|
serializer_class = SOAttachmentSerializer
|
||||||
|
|
||||||
filter_backends = [
|
|
||||||
DjangoFilterBackend,
|
|
||||||
filters.OrderingFilter,
|
|
||||||
filters.SearchFilter,
|
|
||||||
]
|
|
||||||
|
|
||||||
filter_fields = [
|
filter_fields = [
|
||||||
'order',
|
'order',
|
||||||
]
|
]
|
||||||
@ -399,7 +394,7 @@ class SOLineItemDetail(generics.RetrieveUpdateAPIView):
|
|||||||
permission_classes = [permissions.IsAuthenticated]
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
|
||||||
|
|
||||||
class POAttachmentList(generics.ListCreateAPIView):
|
class POAttachmentList(generics.ListCreateAPIView, AttachmentMixin):
|
||||||
"""
|
"""
|
||||||
API endpoint for listing (and creating) a PurchaseOrderAttachment (file upload)
|
API endpoint for listing (and creating) a PurchaseOrderAttachment (file upload)
|
||||||
"""
|
"""
|
||||||
@ -407,12 +402,6 @@ class POAttachmentList(generics.ListCreateAPIView):
|
|||||||
queryset = PurchaseOrderAttachment.objects.all()
|
queryset = PurchaseOrderAttachment.objects.all()
|
||||||
serializer_class = POAttachmentSerializer
|
serializer_class = POAttachmentSerializer
|
||||||
|
|
||||||
filter_backends = [
|
|
||||||
DjangoFilterBackend,
|
|
||||||
filters.OrderingFilter,
|
|
||||||
filters.SearchFilter,
|
|
||||||
]
|
|
||||||
|
|
||||||
filter_fields = [
|
filter_fields = [
|
||||||
'order',
|
'order',
|
||||||
]
|
]
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
<table class='table table-striped table-condensed' data-toolbar='#attachment-buttons' id='attachment-table'>
|
<table class='table table-striped table-condensed' data-toolbar='#attachment-buttons' id='attachment-table'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-field='file' data-searchable='true'>{% trans "File" %}</th>
|
<th data-field='file' data-sortable='true' data-searchable='true'>{% trans "File" %}</th>
|
||||||
<th data-field='comment' data-searchable='true'>{% trans "Comment" %}</th>
|
<th data-field='comment' data-sortable='true' data-searchable='true'>{% trans "Comment" %}</th>
|
||||||
|
<th data-field='user' data-sortable='true' data-searchable='true'>{% trans "Uploaded" %}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -31,6 +32,10 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><a href='/media/{{ attachment.attachment }}'>{{ attachment.basename }}</a></td>
|
<td><a href='/media/{{ attachment.attachment }}'>{{ attachment.basename }}</a></td>
|
||||||
<td>{{ attachment.comment }}</td>
|
<td>{{ attachment.comment }}</td>
|
||||||
|
<td>
|
||||||
|
{% if attachment.upload_date %}{{ attachment.upload_date }}{% endif %}
|
||||||
|
{% if attachment.user %}<span class='badge'>{{ attachment.user.username }}</div>{% endif %}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class='btn-group' style='float: right;'>
|
<div class='btn-group' style='float: right;'>
|
||||||
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'po-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
|
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'po-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
{% include 'order/so_tabs.html' with tab='attachments' %}
|
{% include 'order/so_tabs.html' with tab='attachments' %}
|
||||||
|
|
||||||
<h4>{% trans "Sales Order Attachments" %}
|
<h4>{% trans "Sales Order Attachments" %}</h4>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
@ -21,8 +21,9 @@
|
|||||||
<table class='table table-striped table-condensed' data-toolbar='#attachment-buttons' id='attachment-table'>
|
<table class='table table-striped table-condensed' data-toolbar='#attachment-buttons' id='attachment-table'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-field='file' data-searchable='true'>{% trans "File" %}</th>
|
<th data-field='file' data-sortable='true' data-searchable='true'>{% trans "File" %}</th>
|
||||||
<th data-field='comment' data-searchable='true'>{% trans "Comment" %}</th>
|
<th data-field='comment' data-sortable='true' data-searchable='true'>{% trans "Comment" %}</th>
|
||||||
|
<th data-field='user' data-sortable='true' data-sortable='true' data-searchable='true'>{% trans "Uploaded" %}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -31,6 +32,10 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><a href='/media/{{ attachment.attachment }}'>{{ attachment.basename }}</a></td>
|
<td><a href='/media/{{ attachment.attachment }}'>{{ attachment.basename }}</a></td>
|
||||||
<td>{{ attachment.comment }}</td>
|
<td>{{ attachment.comment }}</td>
|
||||||
|
<td>
|
||||||
|
{% if attachment.upload_date %}{{ attachment.upload_date }}{% endif %}
|
||||||
|
{% if attachment.user %}<span class='badge'>{{ attachment.user.username }}</div>{% endif %}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class='btn-group' style='float: right;'>
|
<div class='btn-group' style='float: right;'>
|
||||||
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'so-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
|
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'so-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
|
||||||
|
@ -93,6 +93,10 @@ class PurchaseOrderAttachmentCreate(AjaxCreateView):
|
|||||||
ajax_form_title = _("Add Purchase Order Attachment")
|
ajax_form_title = _("Add Purchase Order Attachment")
|
||||||
ajax_template_name = "modal_form.html"
|
ajax_template_name = "modal_form.html"
|
||||||
|
|
||||||
|
def post_save(self, **kwargs):
|
||||||
|
self.object.user = self.request.user
|
||||||
|
self.object.save()
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
return {
|
return {
|
||||||
"success": _("Added attachment")
|
"success": _("Added attachment")
|
||||||
@ -133,6 +137,10 @@ class SalesOrderAttachmentCreate(AjaxCreateView):
|
|||||||
form_class = order_forms.EditSalesOrderAttachmentForm
|
form_class = order_forms.EditSalesOrderAttachmentForm
|
||||||
ajax_form_title = _('Add Sales Order Attachment')
|
ajax_form_title = _('Add Sales Order Attachment')
|
||||||
|
|
||||||
|
def post_save(self, **kwargs):
|
||||||
|
self.object.user = self.request.user
|
||||||
|
self.object.save()
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
return {
|
return {
|
||||||
'success': _('Added attachment')
|
'success': _('Added attachment')
|
||||||
|
@ -25,6 +25,7 @@ from . import serializers as part_serializers
|
|||||||
|
|
||||||
from InvenTree.views import TreeSerializer
|
from InvenTree.views import TreeSerializer
|
||||||
from InvenTree.helpers import str2bool, isNull
|
from InvenTree.helpers import str2bool, isNull
|
||||||
|
from InvenTree.api import AttachmentMixin
|
||||||
|
|
||||||
|
|
||||||
class PartCategoryTree(TreeSerializer):
|
class PartCategoryTree(TreeSerializer):
|
||||||
@ -106,7 +107,7 @@ class CategoryDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
queryset = PartCategory.objects.all()
|
queryset = PartCategory.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class PartAttachmentList(generics.ListCreateAPIView):
|
class PartAttachmentList(generics.ListCreateAPIView, AttachmentMixin):
|
||||||
"""
|
"""
|
||||||
API endpoint for listing (and creating) a PartAttachment (file upload).
|
API endpoint for listing (and creating) a PartAttachment (file upload).
|
||||||
"""
|
"""
|
||||||
@ -114,14 +115,6 @@ class PartAttachmentList(generics.ListCreateAPIView):
|
|||||||
queryset = PartAttachment.objects.all()
|
queryset = PartAttachment.objects.all()
|
||||||
serializer_class = part_serializers.PartAttachmentSerializer
|
serializer_class = part_serializers.PartAttachmentSerializer
|
||||||
|
|
||||||
permission_classes = [permissions.IsAuthenticated]
|
|
||||||
|
|
||||||
filter_backends = [
|
|
||||||
DjangoFilterBackend,
|
|
||||||
filters.OrderingFilter,
|
|
||||||
filters.SearchFilter,
|
|
||||||
]
|
|
||||||
|
|
||||||
filter_fields = [
|
filter_fields = [
|
||||||
'part',
|
'part',
|
||||||
]
|
]
|
||||||
|
@ -19,8 +19,9 @@
|
|||||||
<table class='table table-striped table-condensed' data-toolbar='#attachment-buttons' id='attachment-table'>
|
<table class='table table-striped table-condensed' data-toolbar='#attachment-buttons' id='attachment-table'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-field='file' data-searchable='true'>{% trans "File" %}</th>
|
<th data-field='file' data-sortable='true' data-searchable='true'>{% trans "File" %}</th>
|
||||||
<th data-field='comment' data-searchable='true'>{% trans "Comment" %}</th>
|
<th data-field='comment' data-sortable='true' data-searchable='true'>{% trans "Comment" %}</th>
|
||||||
|
<th data-field='user' data-sortable='true' data-searchable='true'>{% trans "Uploaded" %}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -29,6 +30,10 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><a href='/media/{{ attachment.attachment }}'>{{ attachment.basename }}</a></td>
|
<td><a href='/media/{{ attachment.attachment }}'>{{ attachment.basename }}</a></td>
|
||||||
<td>{{ attachment.comment }}</td>
|
<td>{{ attachment.comment }}</td>
|
||||||
|
<td>
|
||||||
|
{% if attachment.upload_date %}{{ attachment.upload_date }}{% endif %}
|
||||||
|
{% if attachment.user %}<span class='badge'>{{ attachment.user.username }}</div>{% endif %}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class='btn-group' style='float: right;'>
|
<div class='btn-group' style='float: right;'>
|
||||||
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'part-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
|
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'part-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
|
||||||
|
@ -74,6 +74,11 @@ class PartAttachmentCreate(AjaxCreateView):
|
|||||||
ajax_form_title = _("Add part attachment")
|
ajax_form_title = _("Add part attachment")
|
||||||
ajax_template_name = "modal_form.html"
|
ajax_template_name = "modal_form.html"
|
||||||
|
|
||||||
|
def post_save(self):
|
||||||
|
""" Record the user that uploaded the attachment """
|
||||||
|
self.object.user = self.request.user
|
||||||
|
self.object.save()
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
return {
|
return {
|
||||||
'success': _('Added attachment')
|
'success': _('Added attachment')
|
||||||
|
@ -29,6 +29,7 @@ from .serializers import StockItemAttachmentSerializer
|
|||||||
|
|
||||||
from InvenTree.views import TreeSerializer
|
from InvenTree.views import TreeSerializer
|
||||||
from InvenTree.helpers import str2bool, isNull
|
from InvenTree.helpers import str2bool, isNull
|
||||||
|
from InvenTree.api import AttachmentMixin
|
||||||
|
|
||||||
from decimal import Decimal, InvalidOperation
|
from decimal import Decimal, InvalidOperation
|
||||||
|
|
||||||
@ -645,7 +646,7 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class StockAttachmentList(generics.ListCreateAPIView):
|
class StockAttachmentList(generics.ListCreateAPIView, AttachmentMixin):
|
||||||
"""
|
"""
|
||||||
API endpoint for listing (and creating) a StockItemAttachment (file upload)
|
API endpoint for listing (and creating) a StockItemAttachment (file upload)
|
||||||
"""
|
"""
|
||||||
@ -653,22 +654,10 @@ class StockAttachmentList(generics.ListCreateAPIView):
|
|||||||
queryset = StockItemAttachment.objects.all()
|
queryset = StockItemAttachment.objects.all()
|
||||||
serializer_class = StockItemAttachmentSerializer
|
serializer_class = StockItemAttachmentSerializer
|
||||||
|
|
||||||
filter_backends = [
|
|
||||||
DjangoFilterBackend,
|
|
||||||
filters.OrderingFilter,
|
|
||||||
filters.SearchFilter,
|
|
||||||
]
|
|
||||||
|
|
||||||
filter_fields = [
|
filter_fields = [
|
||||||
'stock_item',
|
'stock_item',
|
||||||
]
|
]
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
|
||||||
|
|
||||||
attachment = serializer.save()
|
|
||||||
attachment.user = self.request.user
|
|
||||||
attachment.save()
|
|
||||||
|
|
||||||
|
|
||||||
class StockTrackingList(generics.ListCreateAPIView):
|
class StockTrackingList(generics.ListCreateAPIView):
|
||||||
""" API endpoint for list view of StockItemTracking objects.
|
""" API endpoint for list view of StockItemTracking objects.
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
<table class='table table-striped table-condensed' data-toolbar='#attachment-buttons' id='attachment-table'>
|
<table class='table table-striped table-condensed' data-toolbar='#attachment-buttons' id='attachment-table'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-field='file' data-searchable='true'>{% trans "File" %}</th>
|
<th data-field='file' data-sortable='true' data-searchable='true'>{% trans "File" %}</th>
|
||||||
<th data-field='comment' data-searchable='true'>{% trans "Comment" %}</th>
|
<th data-field='comment' data-sortable='true' data-searchable='true'>{% trans "Comment" %}</th>
|
||||||
<th data-field='user' data-searchable='true'>{% trans "Uploaded" %}</th>
|
<th data-field='user' data-sortable='true' data-searchable='true'>{% trans "Uploaded" %}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
Loading…
Reference in New Issue
Block a user