From 7cc56f9904ac3a3f4023a798aa7f5d5fed0f522e Mon Sep 17 00:00:00 2001 From: billkhiz Date: Wed, 18 Mar 2026 15:22:58 +0000 Subject: [PATCH] Simplify bill and invoice detail card templates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Collapse 4 near-identical status blocks (draft, review, approved, paid) into a single unified block with conditional CSS classes. This removes ~90 lines of duplicated markup while preserving all visual behaviour. Changes: - card_bill.html: 219 → 155 lines (-29%) - card_invoice.html: 203 → 155 lines (-24%) - New: components/accrual_icon.html (shared accrual status icon) Also fixes: - Unclosed

tags in dashboard accrual section - Missing {% trans %} tags on several user-facing strings - Duplicate id attributes on footer action buttons Addresses #250 --- .../bills/includes/card_bill.html | 149 ++++++----------- .../components/accrual_icon.html | 6 + .../invoice/includes/card_invoice.html | 152 +++++++----------- 3 files changed, 113 insertions(+), 194 deletions(-) create mode 100644 django_ledger/templates/django_ledger/components/accrual_icon.html diff --git a/django_ledger/templates/django_ledger/bills/includes/card_bill.html b/django_ledger/templates/django_ledger/bills/includes/card_bill.html index 338d85d1..b95dd892 100644 --- a/django_ledger/templates/django_ledger/bills/includes/card_bill.html +++ b/django_ledger/templates/django_ledger/bills/includes/card_bill.html @@ -18,26 +18,19 @@

{{ bill.vendor.address_1 }}

Past Due: {{ bill.date_due | timesince }} ago

{% endif %} - {% if bill.accrue %} -

Is Accrued: {% icon 'ant-design:check-circle-filled' 24 %} - {% else %} -

Accrue: - {% icon 'maki:roadblock-11' 24 %} - {% endif %} -

You Still Owe: +

{% trans 'Is Accrued' %}: + {% include 'django_ledger/components/accrual_icon.html' with is_accrued=bill.accrue %} +

+

{% trans 'You Still Owe' %}: {% currency_symbol %}{{ bill.get_amount_open | currency_format }}

-

Amount Paid: {% currency_symbol %}{{ bill.amount_paid | currency_format }}

-

Progressed: {{ bill.get_progress | percentage }}


+

{% trans 'Amount Paid' %}: {% currency_symbol %}{{ bill.amount_paid | currency_format }}

+

{% trans 'Progressed' %}: {{ bill.get_progress | percentage }}


{{ bill.get_progress | percentage }} - - {# MARK AS PAID MODAL #} {% modal_action bill 'get' entity_slug %} - + {% elif style == 'bill-detail' %}
@@ -62,61 +56,50 @@

- {% if bill.is_draft %} -

{% trans 'This bill is' %} {{ bill.get_bill_status_display }}

-

{% trans 'Amount Due' %}: - - {% currency_symbol %}{{ bill.amount_due | currency_format }} - -

-

{% trans 'Due Date' %}: - {{ bill.date_due | timeuntil }} + + {# Status heading — colour varies by state #} + {% if bill.is_paid %} +

+ {% elif bill.is_approved %} +

+ {% elif bill.is_draft or bill.is_review %} +

+ {% else %} +

+ {% endif %} + {% if bill.is_draft or bill.is_review or bill.is_approved or bill.is_paid %} + {% trans 'This bill is' %} {{ bill.get_bill_status_display }} + {% else %} + {{ bill.get_bill_status_display | upper }} + {% endif %} +

+ + {# Amount — show amount due or amount paid depending on state #} + {% if bill.is_paid %} +

{% trans 'Amount Paid' %}: + {% currency_symbol %}{{ bill.amount_paid | currency_format }}

-

{% trans 'Is Accrued' %}: - {% if bill.accrue %} - {% icon 'ant-design:check-circle-filled' 24 %} - {% else %} - {% icon 'maki:roadblock-11' 24 %} - {% endif %} +

{% trans 'Paid Date' %}: + {{ bill.date_paid | date }}

- {% elif bill.is_review %} -

{% trans 'This bill is' %} {{ bill.get_bill_status_display }}

+ {% elif bill.is_draft or bill.is_review or bill.is_approved %}

{% trans 'Amount Due' %}: - - {% currency_symbol %}{{ bill.amount_due | currency_format }} - + {% currency_symbol %}{{ bill.amount_due | currency_format }}

{% trans 'Due Date' %}: {{ bill.date_due | timeuntil }}

{% trans 'Is Accrued' %}: - {% if bill.accrue %} - {% icon 'ant-design:check-circle-filled' 24 %} - {% else %} - {% icon 'maki:roadblock-11' 24 %} - {% endif %} + {% include 'django_ledger/components/accrual_icon.html' with is_accrued=bill.accrue %}

- {% if bill.xref %} -

{% trans 'External Ref' %}: {{ bill.xref }}

- {% endif %} - - {% elif bill.is_approved %} -

{% trans 'This bill is' %} {{ bill.get_bill_status_display }}

-

{% trans 'Amount Due' %}: - - {% currency_symbol %}{{ bill.amount_due | currency_format }} - -

-

{% trans 'Due Date' %}: - {{ bill.date_due | timeuntil }} -

-

{% trans 'Is Accrued' %}: - {% if bill.accrue %} - {% icon 'ant-design:check-circle-filled' 24 %} - {% else %} - {% icon 'maki:roadblock-11' 24 %} - {% endif %} + {% else %} +

{% trans 'Bill Amount' %}: + {% currency_symbol %}{{ bill.amount_due | currency_format }}

+ {% endif %} + + {# Progress bar — only for approved bills with partial payment #} + {% if bill.is_approved %}

{% trans 'Amount Paid' %}: {% currency_symbol %}{{ bill.amount_paid | currency_format }}

{% trans 'Progressed' %}: {{ bill.get_progress | percentage }}


@@ -125,96 +108,64 @@

{% tr max="100"> {{ bill.get_progress | percentage }} - {% if bill.xref %} -

{% trans 'External Ref' %}: {{ bill.xref }}

- {% endif %} - {% elif bill.is_paid %} -

{% trans 'This bill is' %} {{ bill.get_bill_status_display }}

-

{% trans 'Amount Paid' %}: - - {% currency_symbol %}{{ bill.amount_paid | currency_format }} - -

-

{% trans 'Paid Date' %}: - {{ bill.date_paid | date }} - {% if bill.xref %} -

{% trans 'External Ref' %}: {{ bill.xref }}

- {% endif %} - {% else %} -

Bill Amount: - {% currency_symbol %}{{ bill.amount_due | currency_format }} -

-

{{ bill.get_bill_status_display | upper }}

{% endif %} + + {# External reference — shown for review and approved states #} + {% if bill.xref and not bill.is_draft %} +

{% trans 'External Ref' %}: {{ bill.xref }}

+ {% endif %} +
+ + {# Action footer — each button shown only when the action is available #}
- {# UPDATE BUTTON #} {% trans 'Update' %} - {# MARK DRAFT #} {% if bill.can_draft %} {% trans 'Mark as Draft' %} - {# MARK AS DRAFT MODAL #} {% modal_action_v2 bill bill.get_mark_as_draft_url bill.get_mark_as_draft_message bill.get_mark_as_draft_html_id %} {% endif %} - {# MARK REVIEW #} {% if bill.can_review %} {% trans 'Mark as Review' %} - {# MARK AS REVIEW MODAL #} {% modal_action_v2 bill bill.get_mark_as_review_url bill.get_mark_as_review_message bill.get_mark_as_review_html_id %} {% endif %} - {# MARK APPROVED #} {% if bill.can_approve %} {% trans 'Mark as Approved' %} - {# MARK AS APPROVED MODAL #} {% modal_action_v2 bill bill.get_mark_as_approved_url bill.get_mark_as_approved_message bill.get_mark_as_approved_html_id %} {% endif %} - {# MARK PAID #} {% if bill.can_pay %} {% trans 'Mark as Paid' %} - {# MARK AS PAID MODAL #} {% modal_action_v2 bill bill.get_mark_as_paid_url bill.get_mark_as_paid_message bill.get_mark_as_paid_html_id %} {% endif %} - {# VOID BUTTON #} {% if bill.can_void %} {% trans 'Void' %} - {# MARK AS VOID MODAL #} {% modal_action_v2 bill bill.get_mark_as_void_url bill.get_mark_as_void_message bill.get_mark_as_void_html_id %} {% endif %} - {# CANCEL BUTTON #} {% if bill.can_cancel %} {% trans 'Cancel' %} - {# MARK AS VOID MODAL #} {% modal_action_v2 bill bill.get_mark_as_canceled_url bill.get_mark_as_canceled_message bill.get_mark_as_canceled_html_id %} {% endif %}
{% endif %} {% else %} - {# CREATE BILL CARD #}
{% icon "ic:baseline-add-circle-outline" 48 %}

{% trans 'New Bill' %}

{% endif %} - \ No newline at end of file + diff --git a/django_ledger/templates/django_ledger/components/accrual_icon.html b/django_ledger/templates/django_ledger/components/accrual_icon.html new file mode 100644 index 00000000..7968cd5c --- /dev/null +++ b/django_ledger/templates/django_ledger/components/accrual_icon.html @@ -0,0 +1,6 @@ +{% load django_ledger %} +{% if is_accrued %} + {% icon 'ant-design:check-circle-filled' 24 %} +{% else %} + {% icon 'maki:roadblock-11' 24 %} +{% endif %} diff --git a/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html b/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html index b65afd7b..02af460a 100644 --- a/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html +++ b/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html @@ -7,7 +7,8 @@

{% icon "bi:cash-stack" 16 %} - {% trans 'Invoice' %}

+ {% trans 'Invoice' %} +

{{ invoice.customer.customer_name }}

{{ invoice.customer.address_1 }}

{% if not invoice.is_past_due %} @@ -16,17 +17,13 @@

{{ invoice.customer.address_1 }}

Past Due: {{ invoice.date_due | timesince }} ago

{% endif %} - {% if invoice.accrue %} -

Accrue: {% icon 'ant-design:check-circle-filled' 24 %} - {% else %} -

Accrue: - {% icon 'maki:roadblock-11' 24 %} - {% endif %} -

Owed to You: +

{% trans 'Is Accrued' %}: + {% include 'django_ledger/components/accrual_icon.html' with is_accrued=invoice.accrue %} +

+

{% trans 'Owed to You' %}: {% currency_symbol %}{{ invoice.get_amount_open | currency_format }}

-

Amount Paid: {% currency_symbol %}{{ invoice.amount_paid | currency_format }}

-

Progressed: {{ invoice.get_progress | percentage }}


+

{% trans 'Amount Paid' %}: {% currency_symbol %}{{ invoice.amount_paid | currency_format }}

+

{% trans 'Progressed' %}: {{ invoice.get_progress | percentage }}


{{ invoice.get_progress | percentage }} @@ -44,70 +41,60 @@

{{ invoice.customer.address_1 }}

{% endif %}
+ {% elif style == 'invoice-detail' %}

- - {% icon 'uil:bill' 36 %} - {% trans 'Invoice Info' %}

+ {% icon 'uil:bill' 36 %} + {% trans 'Invoice Info' %} +
- {% if invoice.is_draft %} -

{% trans 'This invoice is' %} {{ invoice.get_invoice_status_display }}

-

{% trans 'Amount Due' %}: - - {% currency_symbol %}{{ invoice.amount_due | currency_format }} - -

-

{% trans 'Due Date' %}: - {{ invoice.date_due | timeuntil }} + + {# Status heading — colour varies by state #} + {% if invoice.is_paid %} +

+ {% elif invoice.is_approved %} +

+ {% elif invoice.is_draft or invoice.is_review %} +

+ {% else %} +

+ {% endif %} + {% if invoice.is_draft or invoice.is_review or invoice.is_approved or invoice.is_paid %} + {% trans 'This invoice is' %} {{ invoice.get_invoice_status_display }} + {% else %} + {{ invoice.get_invoice_status_display | upper }} + {% endif %} +

+ + {# Amount — show amount due or amount paid depending on state #} + {% if invoice.is_paid %} +

{% trans 'Amount Paid' %}: + {% currency_symbol %}{{ invoice.amount_paid | currency_format }}

-

{% trans 'Is Accrued' %}: - {% if invoice.accrue %} - {% icon 'ant-design:check-circle-filled' 24 %} - {% else %} - {% icon 'maki:roadblock-11' 24 %} - {% endif %} +

{% trans 'Paid Date' %}: + {{ invoice.date_paid | date }}

- {% elif invoice.is_review %} -

{% trans 'This invoice is' %} {{ invoice.get_invoice_status_display }}

+ {% elif invoice.is_draft or invoice.is_review or invoice.is_approved %}

{% trans 'Amount Due' %}: - - {% currency_symbol %}{{ invoice.amount_due | currency_format }} - + {% currency_symbol %}{{ invoice.amount_due | currency_format }}

{% trans 'Due Date' %}: {{ invoice.date_due | timeuntil }}

{% trans 'Is Accrued' %}: - {% if invoice.accrue %} - {% icon 'ant-design:check-circle-filled' 24 %} - {% else %} - {% icon 'maki:roadblock-11' 24 %} - {% endif %} + {% include 'django_ledger/components/accrual_icon.html' with is_accrued=invoice.accrue %}

- {% if invoice.xref %} -

{% trans 'External Ref' %}: {{ invoice.xref }}

- {% endif %} - - {% elif invoice.is_approved %} -

{% trans 'This invoice is' %} {{ invoice.get_invoice_status_display }}

-

{% trans 'Amount Due' %}: - - {% currency_symbol %}{{ invoice.amount_due | currency_format }} - -

-

{% trans 'Due Date' %}: - {{ invoice.date_due | timeuntil }} -

-

{% trans 'Is Accrued' %}: - {% if invoice.accrue %} - {% icon 'ant-design:check-circle-filled' 24 %} - {% else %} - {% icon 'maki:roadblock-11' 24 %} - {% endif %} + {% else %} +

{% trans 'Invoice Amount' %}: + {% currency_symbol %}{{ invoice.amount_due | currency_format }}

+ {% endif %} + + {# Progress bar — only for approved invoices with partial payment #} + {% if invoice.is_approved %}

{% trans 'Amount Paid' %}: {% currency_symbol %}{{ invoice.amount_paid | currency_format }}

{% trans 'Progressed' %}: {{ invoice.get_progress | percentage }}


@@ -116,77 +103,53 @@

{% tr max="100"> {{ invoice.get_progress | percentage }} - {% elif invoice.is_paid %} -

{% trans 'This invoice is' %} {{ invoice.get_invoice_status_display }}

-

{% trans 'Amount Paid' %}: - - {% currency_symbol %}{{ invoice.amount_paid | currency_format }} - -

-

{% trans 'Paid Date' %}: - {{ invoice.date_paid | date }} - {% else %} -

Invoice Amount: - {% currency_symbol %}{{ invoice.amount_due | currency_format }} -

-

{{ invoice.get_invoice_status_display | upper }}

{% endif %} + + {# External reference — shown for review and approved states #} + {% if invoice.xref and not invoice.is_draft %} +

{% trans 'External Ref' %}: {{ invoice.xref }}

+ {% endif %} +
+ + {# Action footer — each button shown only when the action is available #}
{% trans 'Update' %} - {# MARK DRAFT #} {% if invoice.can_draft %} {% trans 'Mark as Draft' %} - {# MARK AS DRAFT MODAL #} {% modal_action_v2 invoice invoice.get_mark_as_draft_url invoice.get_mark_as_draft_message invoice.get_mark_as_draft_html_id %} {% endif %} - {# MARK REVIEW #} {% if invoice.can_review %} {% trans 'Mark as Review' %} - {# MARK AS REVIEW MODAL #} {% modal_action_v2 invoice invoice.get_mark_as_review_url invoice.get_mark_as_review_message invoice.get_mark_as_review_html_id %} {% endif %} - {# MARK APPROVED #} {% if invoice.can_approve %} {% trans 'Approve' %} - {# MARK AS APPROVED MODAL #} + class="card-footer-item has-text-success has-text-centered">{% trans 'Approve' %} {% modal_action_v2 invoice invoice.get_mark_as_approved_url invoice.get_mark_as_approved_message invoice.get_mark_as_approved_html_id %} {% endif %} - {# MARK PAID #} {% if invoice.can_pay %} {% trans 'Mark as Paid' %} - {# MARK AS PAID MODAL #} + class="card-footer-item has-text-success has-text-centered">{% trans 'Mark as Paid' %} {% modal_action_v2 invoice invoice.get_mark_as_paid_url invoice.get_mark_as_paid_message invoice.get_mark_as_paid_html_id %} {% endif %} - {# MARK VOID #} {% if invoice.can_void %} {% trans 'Void' %} - {# MARK AS PAID MODAL #} + class="card-footer-item has-text-danger has-text-centered">{% trans 'Void' %} {% modal_action_v2 invoice invoice.get_mark_as_void_url invoice.get_mark_as_void_message invoice.get_mark_as_void_html_id %} {% endif %} - {# MARK CANCELED #} {% if invoice.can_cancel %} {% trans 'Cancel' %} - {# MARK AS PAID MODAL #} {% modal_action_v2 invoice invoice.get_mark_as_canceled_url invoice.get_mark_as_canceled_message invoice.get_mark_as_canceled_html_id %} {% endif %}
@@ -200,4 +163,3 @@

{%

{% trans 'New Invoice' %}

{% endif %} -