2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-01 11:10:54 +00:00

Add new global setting to control auto-upload of test reports (#3137)

* Add new global setting to control auto-upload of test reports

* Adds callback to attach a copy of the test report when printing

* Fix for all attachment API endpoints

- The AttachmentMixin must come first!
- User was not being set, as the custom 'perform_create' function was never called

* Remove duplicated UserSerializer

* display uploading user in attachment table

* Add unit test to check the test report is automatically uploaded
This commit is contained in:
Oliver
2022-06-06 15:20:41 +10:00
committed by GitHub
parent 2b1d8f5b79
commit a066fcc909
18 changed files with 116 additions and 80 deletions

View File

@ -1,6 +1,7 @@
"""API functionality for the 'report' app"""
from django.core.exceptions import FieldError, ValidationError
from django.core.files.base import ContentFile
from django.http import HttpResponse
from django.template.exceptions import TemplateDoesNotExist
from django.urls import include, path, re_path
@ -15,7 +16,7 @@ import common.models
import InvenTree.helpers
import order.models
import part.models
from stock.models import StockItem
from stock.models import StockItem, StockItemAttachment
from .models import (BillOfMaterialsReport, BuildReport, PurchaseOrderReport,
SalesOrderReport, TestReport)
@ -158,6 +159,18 @@ class PartReportMixin:
class ReportPrintMixin:
"""Mixin for printing reports."""
def report_callback(self, object, report, request):
"""Callback function for each object/report combination.
Allows functionality to be performed before returning the consolidated PDF
Arguments:
object: The model instance to be printed
report: The individual PDF file object
request: The request instance associated with this print call
"""
...
def print(self, request, items_to_print):
"""Print this report template against a number of pre-validated items."""
if len(items_to_print) == 0:
@ -182,12 +195,16 @@ class ReportPrintMixin:
report.object_to_print = item
report_name = report.generate_filename(request)
output = report.render(request)
# Run report callback for each generated report
self.report_callback(item, output, request)
try:
if debug_mode:
outputs.append(report.render_as_string(request))
else:
outputs.append(report.render(request))
outputs.append(output)
except TemplateDoesNotExist as e:
template = str(e)
if not template:
@ -326,6 +343,22 @@ class StockItemTestReportPrint(generics.RetrieveAPIView, StockItemReportMixin, R
queryset = TestReport.objects.all()
serializer_class = TestReportSerializer
def report_callback(self, item, report, request):
"""Callback to (optionally) save a copy of the generated report"""
if common.models.InvenTreeSetting.get_setting('REPORT_ATTACH_TEST_REPORT'):
# Construct a PDF file object
pdf = report.get_document().write_pdf()
pdf_content = ContentFile(pdf, "test_report.pdf")
StockItemAttachment.objects.create(
attachment=pdf_content,
stock_item=item,
user=request.user,
comment=_("Test report")
)
def get(self, request, *args, **kwargs):
"""Check if valid stock item(s) have been provided."""
items = self.get_items()

View File

@ -9,9 +9,9 @@ from django.urls import reverse
import report.models as report_models
from build.models import Build
from common.models import InvenTreeUserSetting
from common.models import InvenTreeSetting, InvenTreeUserSetting
from InvenTree.api_tester import InvenTreeAPITestCase
from stock.models import StockItem
from stock.models import StockItem, StockItemAttachment
class ReportTest(InvenTreeAPITestCase):
@ -141,15 +141,28 @@ class TestReportTest(ReportTest):
# Now print with a valid StockItem
item = StockItem.objects.first()
response = self.get(url, {'item': item.pk})
response = self.get(url, {'item': item.pk}, expected_code=200)
# Response should be a StreamingHttpResponse (PDF file)
self.assertEqual(type(response), StreamingHttpResponse)
headers = response.headers
self.assertEqual(headers['Content-Type'], 'application/pdf')
# By default, this should *not* have created an attachment against this stockitem
self.assertFalse(StockItemAttachment.objects.filter(stock_item=item).exists())
# Change the setting, now the test report should be attached automatically
InvenTreeSetting.set_setting('REPORT_ATTACH_TEST_REPORT', True, None)
response = self.get(url, {'item': item.pk}, expected_code=200)
headers = response.headers
self.assertEqual(headers['Content-Type'], 'application/pdf')
# Check that a report has been uploaded
attachment = StockItemAttachment.objects.filter(stock_item=item).first()
self.assertIsNotNone(attachment)
class BuildReportTest(ReportTest):
"""Unit test class for the BuildReport model"""