diff --git a/sage_invoice/migrations/0002_alter_invoice_template_choice.py b/sage_invoice/migrations/0002_alter_invoice_template_choice.py new file mode 100644 index 0000000..609c0e0 --- /dev/null +++ b/sage_invoice/migrations/0002_alter_invoice_template_choice.py @@ -0,0 +1,32 @@ +# Generated by Django 5.1.2 on 2024-10-17 09:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("sage_invoice", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="invoice", + name="template_choice", + field=models.CharField( + choices=[ + ("quotation_1", "quotation_1"), + ("quotation_2", "quotation_2"), + ("quotation_3", "quotation_3"), + ("quotation_4", "quotation_4"), + ("receipt1", "receipt1"), + ("receipt2", "receipt2"), + ("receipt3", "receipt3"), + ], + db_comment="Template choice for the invoice", + help_text="The template you want for your invoice", + max_length=20, + verbose_name="Template choice", + ), + ), + ] diff --git a/sage_invoice/service/discovery.py b/sage_invoice/service/discovery.py index d7aed9b..84feb63 100644 --- a/sage_invoice/service/discovery.py +++ b/sage_invoice/service/discovery.py @@ -7,10 +7,10 @@ class JinjaTemplateDiscovery: def __init__(self): self.default_template_dir = "default_invoices" # inside package - self.custom_template_dir = ( + self.sage_template_dir = ( settings.SAGE_MODEL_TEMPLATE ) # custom templates folder name - self.custom_template_prefix = ( + self.sage_template_prefix = ( settings.SAGE_MODEL_PREFIX ) # custom template prefix @@ -29,12 +29,12 @@ def get_custom_templates(self): template_choices = [] for app_config in apps.get_app_configs(): template_dir = os.path.join( - app_config.path, "templates", self.custom_template_dir + app_config.path, "templates", self.sage_template_dir ) if os.path.exists(template_dir): template_choices.extend( self._find_templates_in_directory( - template_dir, self.custom_template_prefix + template_dir, self.sage_template_prefix ) ) return template_choices @@ -42,15 +42,17 @@ def get_custom_templates(self): def _find_templates_in_directory(self, directory, prefix=None): """ Helper method to find .jinja2 files in a directory, optionally filtering by - prefix. + prefix, and return the filenames without the .jinja2 extension. """ if not os.path.exists(directory): return [] templates = [] for filename in os.listdir(directory): - if filename.endswith(".jinja2") and ( - not prefix or filename.startswith(prefix) - ): + if filename.endswith(".jinja2") and (not prefix or filename.startswith(prefix)): templates.append(filename) - return templates + + # Remove the .jinja2 extension from the filenames + filenames = list(map(lambda x: x.replace('.jinja2', ''), templates)) + + return filenames diff --git a/sage_invoice/service/invoice_create.py b/sage_invoice/service/invoice_create.py index 4ccac28..4eff297 100644 --- a/sage_invoice/service/invoice_create.py +++ b/sage_invoice/service/invoice_create.py @@ -22,18 +22,16 @@ def __init__(self) -> None: Jinja2. """ logger.info("Initializing QuotationService") - self.template_discovery = JinjaTemplateDiscovery( - models_dir=getattr(settings, "SAGE_MODEL_TEMPLATE", "default_invoices") - ) + self.template_discovery = JinjaTemplateDiscovery() self.env = Environment( - loader=FileSystemLoader(self.template_discovery.models_dir), + loader=FileSystemLoader(self.template_discovery.sage_template_dir), autoescape=select_autoescape( ["html", "xml"] ), # Enable autoescape for HTML and XML templates ) logger.info( "Template discovery set to directory: %s", - self.template_discovery.models_dir, + self.template_discovery.sage_template_dir, ) def render_quotation(self, queryset: QuerySet) -> str: @@ -50,7 +48,7 @@ def render_quotation(self, queryset: QuerySet) -> str: """ logger.info("Rendering quotation") invoice = queryset.first() - context = self.render_contax(queryset) + context = self.render_context(queryset) is_receipt = invoice.receipt template_number = "".join(filter(str.isdigit, invoice.template_choice)) logger.info("Selected template number: %s", template_number) @@ -65,7 +63,7 @@ def render_quotation(self, queryset: QuerySet) -> str: return template.render(context) - def render_contax(self, queryset: QuerySet) -> Dict[str, Any]: + def render_context(self, queryset: QuerySet) -> Dict[str, Any]: """Prepare the context data for rendering a quotation. Args: diff --git a/sage_invoice/templates/quotation1.html b/sage_invoice/templates/quotation_1.html similarity index 100% rename from sage_invoice/templates/quotation1.html rename to sage_invoice/templates/quotation_1.html diff --git a/sage_invoice/templates/quotation2.html b/sage_invoice/templates/quotation_2.html similarity index 100% rename from sage_invoice/templates/quotation2.html rename to sage_invoice/templates/quotation_2.html diff --git a/sage_invoice/templates/quotation3.html b/sage_invoice/templates/quotation_3.html similarity index 100% rename from sage_invoice/templates/quotation3.html rename to sage_invoice/templates/quotation_3.html diff --git a/sage_invoice/templates/quotation4.html b/sage_invoice/templates/quotation_4.html similarity index 100% rename from sage_invoice/templates/quotation4.html rename to sage_invoice/templates/quotation_4.html diff --git a/sage_invoice/tests/test_service.py b/sage_invoice/tests/test_service.py index 064ee3e..6c91d8e 100644 --- a/sage_invoice/tests/test_service.py +++ b/sage_invoice/tests/test_service.py @@ -19,7 +19,7 @@ def test_init(self, mock_template_discovery): assert service.template_discovery == mock_template_discovery.return_value assert service.env is not None mock_template_discovery.assert_called_once_with( - models_dir="sage_invoice" # Default directory + sage_template_dir="sage_invoice" # Default directory ) @pytest.fixture @@ -90,13 +90,13 @@ def test_render_quotation_template_not_found(self, mock_get_template_path, invoi mock_get_template_path.assert_called_once() - def test_render_contax(self, invoice): + def test_render_context(self, invoice): # Test context generation for the invoice service = QuotationService() # Ensure contacts and other fields are handled correctly invoice.contacts = ["you@example.com", "1234567890"] - context = service.render_contax(invoice) + context = service.render_context(invoice) assert context["title"] == invoice.title assert context["tracking_code"] == invoice.tracking_code diff --git a/sage_invoice/views/invoice.py b/sage_invoice/views/invoice.py index 287fe51..6914501 100644 --- a/sage_invoice/views/invoice.py +++ b/sage_invoice/views/invoice.py @@ -32,14 +32,14 @@ def get_context_data(self, **kwargs): invoice_slug = self.kwargs.get("slug") invoice = Invoice.objects.filter(slug=invoice_slug).first() service = QuotationService() - rendered_content = service.render_contax(invoice) + rendered_content = service.render_context(invoice) context.update(rendered_content) # Dynamically choose the template based on invoice type and choice if invoice.receipt: - self.template_name = f"receipt{invoice.template_choice}.html" + self.template_name = f"{invoice.template_choice}.html" else: - self.template_name = f"quotation{invoice.template_choice}.html" + self.template_name = f"{invoice.template_choice}.html" return context @@ -79,7 +79,7 @@ def get(self, request, *args, **kwargs): continue service = QuotationService() - rendered_content = service.render_contax(invoice) + rendered_content = service.render_context(invoice) # Determine the template based on invoice type if invoice.receipt: