Report orientation (#5678)

* Add helper functions for report generation

* Add new fields to Report model:

- page_size (default = A4)
- landscape (default = False)

* Add migration for InvenTree reports

* Enable landscape printing
This commit is contained in:
Oliver 2023-10-09 13:25:53 +11:00 committed by GitHub
parent e9e505edd4
commit 6f2dca729d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 158 additions and 8 deletions

View File

@ -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': {

View File

@ -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

View File

@ -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'),
),
]

View File

@ -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

View File

@ -5,7 +5,7 @@
@page {
{% block page_style %}
{% block page_size %}
size: {{ default_page_size }};
size: {{ page_size }};
{% endblock %}
{% block page_margin %}
margin: 2cm;

View File

@ -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 |