mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +00:00 
			
		
		
		
	Remove references to old setting (#8018)
* Remove references to old setting - Now offloaded to plugins * Remove REPORT_ENABLE_TEST_REPORT setting * Cleanup * Add new boolean setting to control whether reports are attached automatically * Attach generated report to model instance * Update unit testing * Bump API version
This commit is contained in:
		| @@ -1,13 +1,16 @@ | ||||
| """InvenTree API version information.""" | ||||
|  | ||||
| # InvenTree API version | ||||
| INVENTREE_API_VERSION = 250 | ||||
| INVENTREE_API_VERSION = 251 | ||||
|  | ||||
| """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" | ||||
|  | ||||
|  | ||||
| INVENTREE_API_TEXT = """ | ||||
|  | ||||
| v251 - 2024-09-06 : https://github.com/inventree/InvenTree/pull/8018 | ||||
|     - Adds "attach_to_model" field to the ReporTemplate model | ||||
|  | ||||
| v250 - 2024-09-04 : https://github.com/inventree/InvenTree/pull/8069 | ||||
|     - Fixes 'revision' field definition in Part serializer | ||||
|  | ||||
|   | ||||
| @@ -1704,20 +1704,6 @@ class InvenTreeSetting(BaseInvenTreeSetting): | ||||
|             'default': 'A4', | ||||
|             'choices': report.helpers.report_page_size_options, | ||||
|         }, | ||||
|         'REPORT_ENABLE_TEST_REPORT': { | ||||
|             'name': _('Enable Test Reports'), | ||||
|             'description': _('Enable generation of test reports'), | ||||
|             'default': True, | ||||
|             'validator': bool, | ||||
|         }, | ||||
|         'REPORT_ATTACH_TEST_REPORT': { | ||||
|             'name': _('Attach Test Reports'), | ||||
|             'description': _( | ||||
|                 'When printing a Test Report, attach a copy of the Test Report to the associated Stock Item' | ||||
|             ), | ||||
|             'default': False, | ||||
|             'validator': bool, | ||||
|         }, | ||||
|         'SERIAL_NUMBER_GLOBALLY_UNIQUE': { | ||||
|             'name': _('Globally Unique Serials'), | ||||
|             'description': _('Serial numbers for stock items must be globally unique'), | ||||
|   | ||||
| @@ -228,9 +228,6 @@ class SettingsTest(InvenTreeTestCase): | ||||
|         report_size_obj = InvenTreeSetting.get_setting_object( | ||||
|             'REPORT_DEFAULT_PAGE_SIZE' | ||||
|         ) | ||||
|         report_test_obj = InvenTreeSetting.get_setting_object( | ||||
|             'REPORT_ENABLE_TEST_REPORT' | ||||
|         ) | ||||
|  | ||||
|         # check settings base fields | ||||
|         self.assertEqual(instance_obj.name, 'Server Instance Name') | ||||
| @@ -260,7 +257,6 @@ class SettingsTest(InvenTreeTestCase): | ||||
|  | ||||
|         # check setting_type | ||||
|         self.assertEqual(instance_obj.setting_type(), 'string') | ||||
|         self.assertEqual(report_test_obj.setting_type(), 'boolean') | ||||
|         self.assertEqual(stale_days.setting_type(), 'integer') | ||||
|  | ||||
|         # check as_int | ||||
| @@ -269,9 +265,6 @@ class SettingsTest(InvenTreeTestCase): | ||||
|             instance_obj.as_int(), 'InvenTree' | ||||
|         )  # not an int -> return default | ||||
|  | ||||
|         # check as_bool | ||||
|         self.assertEqual(report_test_obj.as_bool(), True) | ||||
|  | ||||
|         # check to_native_value | ||||
|         self.assertEqual(stale_days.to_native_value(), 0) | ||||
|  | ||||
|   | ||||
| @@ -350,6 +350,15 @@ class ReportPrint(GenericAPIView): | ||||
|  | ||||
|                 output = template.render(instance, request) | ||||
|  | ||||
|                 if template.attach_to_model: | ||||
|                     # Attach the generated report to the model instance | ||||
|                     data = output.get_document().write_pdf() | ||||
|                     instance.create_attachment( | ||||
|                         attachment=ContentFile(data, report_name), | ||||
|                         comment=_('Report saved at time of printing'), | ||||
|                         upload_user=request.user, | ||||
|                     ) | ||||
|  | ||||
|                 # Provide generated report to any interested plugins | ||||
|                 for plugin in registry.with_mixin('report'): | ||||
|                     try: | ||||
|   | ||||
| @@ -0,0 +1,23 @@ | ||||
| # Generated by Django 4.2.15 on 2024-09-05 23:18 | ||||
|  | ||||
| from django.db import migrations, models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ('report', '0027_alter_labeltemplate_model_type_and_more'), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name='labeltemplate', | ||||
|             name='attach_to_model', | ||||
|             field=models.BooleanField(default=False, help_text='Save report output as an attachment against linked model instance when printing', verbose_name='Attach to Model on Print'), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='reporttemplate', | ||||
|             name='attach_to_model', | ||||
|             field=models.BooleanField(default=False, help_text='Save report output as an attachment against linked model instance when printing', verbose_name='Attach to Model on Print'), | ||||
|         ), | ||||
|     ] | ||||
| @@ -163,6 +163,14 @@ class ReportTemplateBase(MetadataMixin, InvenTree.models.InvenTreeModel): | ||||
|         editable=False, | ||||
|     ) | ||||
|  | ||||
|     attach_to_model = models.BooleanField( | ||||
|         default=False, | ||||
|         verbose_name=_('Attach to Model on Print'), | ||||
|         help_text=_( | ||||
|             'Save report output as an attachment against linked model instance when printing' | ||||
|         ), | ||||
|     ) | ||||
|  | ||||
|     def generate_filename(self, context, **kwargs): | ||||
|         """Generate a filename for this report.""" | ||||
|         template_string = Template(self.filename_pattern) | ||||
|   | ||||
| @@ -42,6 +42,7 @@ class ReportSerializerBase(InvenTreeModelSerializer): | ||||
|             'filename_pattern', | ||||
|             'enabled', | ||||
|             'revision', | ||||
|             'attach_to_model', | ||||
|         ] | ||||
|  | ||||
|     template = InvenTreeAttachmentSerializerField(required=True) | ||||
|   | ||||
| @@ -555,8 +555,16 @@ class TestReportTest(PrintTestMixins, ReportTest): | ||||
|         template = ReportTemplate.objects.filter( | ||||
|             enabled=True, model_type='stockitem' | ||||
|         ).first() | ||||
|  | ||||
|         self.assertIsNotNone(template) | ||||
|  | ||||
|         # Ensure that the 'attach_to_model' attribute is initially False | ||||
|         template.attach_to_model = False | ||||
|         template.save() | ||||
|         template.refresh_from_db() | ||||
|  | ||||
|         self.assertFalse(template.attach_to_model) | ||||
|  | ||||
|         url = reverse(self.print_url) | ||||
|  | ||||
|         # Try to print without providing a valid StockItem | ||||
| @@ -568,18 +576,37 @@ class TestReportTest(PrintTestMixins, ReportTest): | ||||
|         # Now print with a valid StockItem | ||||
|         item = StockItem.objects.first() | ||||
|  | ||||
|         n = item.attachments.count() | ||||
|  | ||||
|         response = self.post( | ||||
|             url, {'template': template.pk, 'items': [item.pk]}, expected_code=201 | ||||
|         ) | ||||
|  | ||||
|         # There should be a link to the generated PDF | ||||
|         self.assertEqual(response.data['output'].startswith('/media/report/'), True) | ||||
|         self.assertTrue(response.data['output'].startswith('/media/report/')) | ||||
|         self.assertTrue(response.data['output'].endswith('.pdf')) | ||||
|  | ||||
|         # By default, this should *not* have created an attachment against this stockitem | ||||
|         self.assertEqual(n, item.attachments.count()) | ||||
|         self.assertFalse( | ||||
|             Attachment.objects.filter(model_id=item.pk, model_type='stockitem').exists() | ||||
|         ) | ||||
|  | ||||
|         # Now try again, but attach the generated PDF to the StockItem | ||||
|         template.attach_to_model = True | ||||
|         template.save() | ||||
|  | ||||
|         response = self.post( | ||||
|             url, {'template': template.pk, 'items': [item.pk]}, expected_code=201 | ||||
|         ) | ||||
|  | ||||
|         # A new attachment should have been created | ||||
|         self.assertEqual(n + 1, item.attachments.count()) | ||||
|         attachment = item.attachments.order_by('-pk').first() | ||||
|  | ||||
|         # The attachment should be a PDF | ||||
|         self.assertTrue(attachment.attachment.name.endswith('.pdf')) | ||||
|  | ||||
|     def test_mdl_build(self): | ||||
|         """Test the Build model.""" | ||||
|         self.run_print_test(Build, 'build', label=False) | ||||
|   | ||||
| @@ -54,19 +54,15 @@ | ||||
| </div> | ||||
| {% endif %} | ||||
| <!-- Document / label menu --> | ||||
| {% if test_report_enabled or labels_enabled %} | ||||
| <div class='btn-group' role='group'> | ||||
|     <button id='document-options' title='{% trans "Printing actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'><span class='fas fa-print'></span> <span class='caret'></span></button> | ||||
|     <ul class='dropdown-menu' role='menu'> | ||||
|         {% if labels_enabled %} | ||||
|         <li><a class='dropdown-item' href='#' id='print-label'><span class='fas fa-tag'></span> {% trans "Print Label" %}</a></li> | ||||
|         {% endif %} | ||||
|         {% if test_report_enabled %} | ||||
|         <li><a class='dropdown-item' href='#' id='stock-test-report'><span class='fas fa-file-pdf'></span> {% trans "Test Report" %}</a></li> | ||||
|         {% endif %} | ||||
|         <li><a class='dropdown-item' href='#' id='stock-test-report'><span class='fas fa-file-pdf'></span> {% trans "Print Report" %}</a></li> | ||||
|     </ul> | ||||
| </div> | ||||
| {% endif %} | ||||
|  | ||||
| <!-- Stock adjustment menu --> | ||||
| {% if user_owns_item %} | ||||
|   | ||||
| @@ -18,8 +18,6 @@ | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_DEFAULT_PAGE_SIZE" icon="fa-print" %} | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_DEBUG_MODE" icon="fa-laptop-code" %} | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_LOG_ERRORS" icon="fa-exclamation-circle" %} | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE_TEST_REPORT" icon="fa-vial" %} | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_ATTACH_TEST_REPORT" icon="fa-file-upload" %} | ||||
|     </tbody> | ||||
| </table> | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
|  | ||||
| {% plugins_enabled as plugins_enabled %} | ||||
| {% settings_value 'BARCODE_ENABLE' as barcodes %} | ||||
| {% settings_value 'REPORT_ENABLE_TEST_REPORT' as test_report_enabled %} | ||||
| {% settings_value 'RETURNORDER_ENABLED' as return_order_enabled %} | ||||
| {% settings_value "REPORT_ENABLE" as report_enabled %} | ||||
| {% settings_value "SERVER_RESTART_REQUIRED" as server_restart_required %} | ||||
|   | ||||
| @@ -21,6 +21,12 @@ export default function ReportTemplateTable() { | ||||
|             modelRenderer: (instance: any) => ( | ||||
|               <YesNoButton value={instance.landscape} /> | ||||
|             ) | ||||
|           }, | ||||
|           attach_to_model: { | ||||
|             label: t`Attach to Model`, | ||||
|             modelRenderer: (instance: any) => ( | ||||
|               <YesNoButton value={instance.attach_to_model} /> | ||||
|             ) | ||||
|           } | ||||
|         } | ||||
|       }} | ||||
|   | ||||
| @@ -161,9 +161,7 @@ export default function SystemSettings() { | ||||
|               'REPORT_ENABLE', | ||||
|               'REPORT_DEFAULT_PAGE_SIZE', | ||||
|               'REPORT_DEBUG_MODE', | ||||
|               'REPORT_LOG_ERRORS', | ||||
|               'REPORT_ENABLE_TEST_REPORT', | ||||
|               'REPORT_ATTACH_TEST_REPORT' | ||||
|               'REPORT_LOG_ERRORS' | ||||
|             ]} | ||||
|           /> | ||||
|         ) | ||||
|   | ||||
							
								
								
									
										7
									
								
								tasks.py
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								tasks.py
									
									
									
									
									
								
							| @@ -1184,7 +1184,7 @@ def frontend_build(c): | ||||
|  | ||||
|  | ||||
| @task | ||||
| def frontend_dev(c): | ||||
| def frontend_server(c): | ||||
|     """Start frontend development server. | ||||
|  | ||||
|     Args: | ||||
| @@ -1447,7 +1447,7 @@ def clear_generated(c): | ||||
| development = Collection( | ||||
|     delete_data, | ||||
|     docs_server, | ||||
|     frontend_dev, | ||||
|     frontend_server, | ||||
|     gunicorn, | ||||
|     import_fixtures, | ||||
|     schema, | ||||
| @@ -1458,6 +1458,7 @@ development = Collection( | ||||
|     test_translations, | ||||
|     translate, | ||||
| ) | ||||
|  | ||||
| internal = Collection( | ||||
|     clean_settings, | ||||
|     clear_generated, | ||||
| @@ -1474,6 +1475,7 @@ internal = Collection( | ||||
|     translate_stats, | ||||
|     worker, | ||||
| ) | ||||
|  | ||||
| ns = Collection( | ||||
|     backup, | ||||
|     export_records, | ||||
| @@ -1490,5 +1492,6 @@ ns = Collection( | ||||
|     version, | ||||
|     wait, | ||||
| ) | ||||
|  | ||||
| ns.add_collection(development, 'dev') | ||||
| ns.add_collection(internal, 'int') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user