diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 55fac8b23a..a07697130c 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -50,6 +50,7 @@ import InvenTree.ready import InvenTree.tasks import InvenTree.validators import order.validators +import report.helpers from plugin import registry logger = logging.getLogger('inventree') @@ -1543,11 +1544,7 @@ class InvenTreeSetting(BaseInvenTreeSetting): 'name': _('Page Size'), 'description': _('Default page size for PDF reports'), 'default': 'A4', - 'choices': [ - ('A4', 'A4'), - ('Legal', 'Legal'), - ('Letter', 'Letter') - ], + 'choices': report.helpers.report_page_size_options, }, 'REPORT_ENABLE_TEST_REPORT': { diff --git a/InvenTree/report/helpers.py b/InvenTree/report/helpers.py new file mode 100644 index 0000000000..40d5c99665 --- /dev/null +++ b/InvenTree/report/helpers.py @@ -0,0 +1,31 @@ +"""Helper functions for report generation.""" + +import logging + +from django.utils.translation import gettext_lazy as _ + +logger = logging.getLogger('inventree') + + +def report_page_size_options(): + """Returns a list of page size options for PDF reports.""" + + return [ + ('A4', _('A4')), + ('Legal', _('Legal')), + ('Letter', _('Letter')), + ] + + +def report_page_size_default(): + """Returns the default page size for PDF reports.""" + + from common.models import InvenTreeSetting + + try: + page_size = InvenTreeSetting.get_setting('REPORT_DEFAULT_PAGE_SIZE', 'A4') + except Exception as exc: + logger.exception("Error getting default page size: %s", str(exc)) + page_size = 'A4' + + return page_size diff --git a/InvenTree/report/migrations/0021_auto_20231009_0144.py b/InvenTree/report/migrations/0021_auto_20231009_0144.py new file mode 100644 index 0000000000..442523b7cc --- /dev/null +++ b/InvenTree/report/migrations/0021_auto_20231009_0144.py @@ -0,0 +1,84 @@ +# Generated by Django 3.2.22 on 2023-10-09 01:44 + +from django.db import migrations, models +import report.helpers + + +class Migration(migrations.Migration): + + dependencies = [ + ('report', '0020_stocklocationreport'), + ] + + operations = [ + migrations.AddField( + model_name='billofmaterialsreport', + name='landscape', + field=models.BooleanField(default=False, help_text='Render report in landscape orientation', verbose_name='Landscape'), + ), + migrations.AddField( + model_name='billofmaterialsreport', + name='page_size', + field=models.CharField(default=report.helpers.report_page_size_default, help_text='Page size for PDF reports', max_length=20, verbose_name='Page Size'), + ), + migrations.AddField( + model_name='buildreport', + name='landscape', + field=models.BooleanField(default=False, help_text='Render report in landscape orientation', verbose_name='Landscape'), + ), + migrations.AddField( + model_name='buildreport', + name='page_size', + field=models.CharField(default=report.helpers.report_page_size_default, help_text='Page size for PDF reports', max_length=20, verbose_name='Page Size'), + ), + migrations.AddField( + model_name='purchaseorderreport', + name='landscape', + field=models.BooleanField(default=False, help_text='Render report in landscape orientation', verbose_name='Landscape'), + ), + migrations.AddField( + model_name='purchaseorderreport', + name='page_size', + field=models.CharField(default=report.helpers.report_page_size_default, help_text='Page size for PDF reports', max_length=20, verbose_name='Page Size'), + ), + migrations.AddField( + model_name='returnorderreport', + name='landscape', + field=models.BooleanField(default=False, help_text='Render report in landscape orientation', verbose_name='Landscape'), + ), + migrations.AddField( + model_name='returnorderreport', + name='page_size', + field=models.CharField(default=report.helpers.report_page_size_default, help_text='Page size for PDF reports', max_length=20, verbose_name='Page Size'), + ), + migrations.AddField( + model_name='salesorderreport', + name='landscape', + field=models.BooleanField(default=False, help_text='Render report in landscape orientation', verbose_name='Landscape'), + ), + migrations.AddField( + model_name='salesorderreport', + name='page_size', + field=models.CharField(default=report.helpers.report_page_size_default, help_text='Page size for PDF reports', max_length=20, verbose_name='Page Size'), + ), + migrations.AddField( + model_name='stocklocationreport', + name='landscape', + field=models.BooleanField(default=False, help_text='Render report in landscape orientation', verbose_name='Landscape'), + ), + migrations.AddField( + model_name='stocklocationreport', + name='page_size', + field=models.CharField(default=report.helpers.report_page_size_default, help_text='Page size for PDF reports', max_length=20, verbose_name='Page Size'), + ), + migrations.AddField( + model_name='testreport', + name='landscape', + field=models.BooleanField(default=False, help_text='Render report in landscape orientation', verbose_name='Landscape'), + ), + migrations.AddField( + model_name='testreport', + name='page_size', + field=models.CharField(default=report.helpers.report_page_size_default, help_text='Page size for PDF reports', max_length=20, verbose_name='Page Size'), + ), + ] diff --git a/InvenTree/report/models.py b/InvenTree/report/models.py index 66810490f7..4e6e1da7e1 100644 --- a/InvenTree/report/models.py +++ b/InvenTree/report/models.py @@ -18,6 +18,7 @@ import build.models import common.models import order.models import part.models +import report.helpers import stock.models from InvenTree.helpers import validateFilterString from InvenTree.helpers_model import get_base_url @@ -100,6 +101,13 @@ class ReportBase(models.Model): abstract = True + def __init__(self, *args, **kwargs): + """Initialize the particular report instance""" + + super().__init__(*args, **kwargs) + + self._meta.get_field('page_size').choices = report.helpers.report_page_size_options() + def save(self, *args, **kwargs): """Perform additional actions when the report is saved""" # Increment revision number @@ -185,6 +193,19 @@ class ReportBase(models.Model): editable=False, ) + page_size = models.CharField( + max_length=20, + default=report.helpers.report_page_size_default, + verbose_name=_('Page Size'), + help_text=_('Page size for PDF reports'), + ) + + landscape = models.BooleanField( + default=False, + verbose_name=_('Landscape'), + help_text=_('Render report in landscape orientation'), + ) + class ReportTemplateBase(MetadataMixin, ReportBase): """Reporting template model. @@ -203,6 +224,21 @@ class ReportTemplateBase(MetadataMixin, ReportBase): """Supply context data to the template for rendering.""" return {} + def get_report_size(self): + """Return the printable page size for this report""" + + try: + page_size_default = common.models.InvenTreeSetting.get_setting('REPORT_DEFAULT_PAGE_SIZE', 'A4') + except Exception: + page_size_default = 'A4' + + page_size = self.page_size or page_size_default + + if self.landscape: + page_size = page_size + ' landscape' + + return page_size + def context(self, request): """All context to be passed to the renderer.""" # Generate custom context data based on the particular report subclass @@ -211,7 +247,8 @@ class ReportTemplateBase(MetadataMixin, ReportBase): context['base_url'] = get_base_url(request=request) context['date'] = datetime.datetime.now().date() context['datetime'] = datetime.datetime.now() - context['default_page_size'] = common.models.InvenTreeSetting.get_setting('REPORT_DEFAULT_PAGE_SIZE') + context['page_size'] = self.get_report_size() + context['report_template'] = self context['report_description'] = self.description context['report_name'] = self.name context['report_revision'] = self.revision diff --git a/InvenTree/report/templates/report/inventree_report_base.html b/InvenTree/report/templates/report/inventree_report_base.html index 115af8d7b1..f20f0db9ce 100644 --- a/InvenTree/report/templates/report/inventree_report_base.html +++ b/InvenTree/report/templates/report/inventree_report_base.html @@ -5,7 +5,7 @@ @page { {% block page_style %} {% block page_size %} - size: {{ default_page_size }}; + size: {{ page_size }}; {% endblock %} {% block page_margin %} margin: 2cm; diff --git a/docs/docs/report/context_variables.md b/docs/docs/report/context_variables.md index 8a83ac1d31..7ec4bc21b3 100644 --- a/docs/docs/report/context_variables.md +++ b/docs/docs/report/context_variables.md @@ -15,7 +15,8 @@ Each report has access to a number of context variables by default. The followin | --- | --- | | date | Current date, represented as a Python datetime.date object | | datetime | Current datetime, represented as a Python datetime object | -| default_page_size | InvenTree default page size variable | +| page_size | The specified page size for this report, e.g. `A4` or `Letter landscape` | +| report_template | The report template model instance | | report_name | Name of the report template | | report_description | Description of the report template | | report_revision | Revision of the report template |