Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions templates/_shared/document_type.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,16 @@
{% endmacro %}

{#
Settlement lines for a final invoice, as <div> rows.
Settlement lines for a final invoice, or a reminder for one, as <div> rows.

`line` and `amount` name the template's own classes for a totals row and its
amount cell, so each skin keeps its own typography.
The gross amount leaves out a reminder fee, which templates list after the
deductions. `line` and `amount` name the template's own classes for a totals
row and its amount cell, so each skin keeps its own typography.
#}
{% macro settlement_lines_div(invoice, deposit_deductions, line="totals-line", amount="totals-amount", label="totals-label") %}
<div class="{{ line }}">
<span class="{{ label }}">{{ _("Gross") }}</span>
<span class="{{ amount }}">{{ invoice.total | as_currency }}</span>
<span class="{{ amount }}">{{ (invoice.sum + invoice.VAT_total) | as_currency }}</span>
</div>
{%- for dep in deposit_deductions %}
<div class="{{ line }} deposit-deduction">
Expand All @@ -73,7 +74,7 @@
{% macro settlement_lines_table(invoice, deposit_deductions, label="totals-label", value="totals-value") %}
<tr>
<td class="{{ label }}">{{ _("Gross") }}</td>
<td class="{{ value }}">{{ invoice.total | as_currency }}</td>
<td class="{{ value }}">{{ (invoice.sum + invoice.VAT_total) | as_currency }}</td>
</tr>
{%- for dep in deposit_deductions %}
<tr class="deposit-deduction">
Expand Down
2 changes: 1 addition & 1 deletion templates/invoice-bold/invoice.html
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,13 @@
<span class="totals-amount">{{ invoice.VAT_total | as_currency }}</span>
</div>
{% endif %}
{% if is_final or deposit_deductions %}{{ doc.settlement_lines_div(invoice, deposit_deductions) }}{% endif %}
{% if is_reminder and invoice.reminder_fee %}
<div class="totals-line">
<span class="totals-label">{{ _("Reminder Fee") }}</span>
<span class="totals-amount">{{ invoice.reminder_fee | as_currency }}</span>
</div>
{% endif %}
{% if is_final %}{{ doc.settlement_lines_div(invoice, deposit_deductions) }}{% endif %}
<div class="total-due">
<span class="totals-label">{{ doc.amount_due_label(is_deposit, is_final) }}</span>
<span class="totals-amount">{{ remaining_balance | as_currency }}</span>
Expand Down
2 changes: 1 addition & 1 deletion templates/invoice-grayshades/invoice.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ <h1 class="invoice-title">{{ _("Invoice No.") }} {{ invoice.number }}{% if is_de
<td class="totals-value">{{ invoice.VAT_total | as_currency }}</td>
</tr>
{% endif %}
{% if is_final or deposit_deductions %}{{ doc.settlement_lines_table(invoice, deposit_deductions) }}{% endif %}
{% if is_reminder and invoice.reminder_fee %}
<tr>
<td class="totals-label">{{ _("Reminder Fee") }}</td>
<td class="totals-value">{{ invoice.reminder_fee | as_currency }}</td>
</tr>
{% endif %}
{% if is_final %}{{ doc.settlement_lines_table(invoice, deposit_deductions) }}{% endif %}
<tr class="total-due-row">
<td class="totals-label"><strong>{{ doc.amount_due_label(is_deposit, is_final) }} (€)</strong></td>
<td class="totals-value"><strong>{{ remaining_balance | as_currency }}</strong></td>
Expand Down
2 changes: 1 addition & 1 deletion templates/invoice-minimal/invoice.html
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,13 @@
<span class="totals-value">{{ invoice.VAT_total | as_currency }}</span>
</div>
{% endif %}
{% if is_final or deposit_deductions %}{{ doc.settlement_lines_div(invoice, deposit_deductions, amount="totals-value") }}{% endif %}
{% if is_reminder and invoice.reminder_fee %}
<div class="totals-line">
<span class="totals-label">{{ _("Reminder Fee") }}</span>
<span class="totals-value">{{ invoice.reminder_fee | as_currency }}</span>
</div>
{% endif %}
{% if is_final %}{{ doc.settlement_lines_div(invoice, deposit_deductions, amount="totals-value") }}{% endif %}
<div class="divider"></div>
<div class="totals-line total-due">
<span class="totals-label">{{ doc.amount_due_label(is_deposit, is_final) }}</span>
Expand Down
2 changes: 1 addition & 1 deletion templates/invoice-modern/invoice.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@
<span class="totals-amount">{{ invoice.VAT_total | as_currency }}</span>
</div>
{% endif %}
{% if is_final or deposit_deductions %}{{ doc.settlement_lines_div(invoice, deposit_deductions) }}{% endif %}
{% if is_reminder and invoice.reminder_fee %}
<div class="totals-line">
<span class="totals-label">{{ _("Reminder Fee") }}</span>
<span class="totals-amount">{{ invoice.reminder_fee | as_currency }}</span>
</div>
{% endif %}
{% if is_final %}{{ doc.settlement_lines_div(invoice, deposit_deductions) }}{% endif %}
<div class="totals-rule"></div>
<div class="totals-line total-due">
<span class="totals-label">{{ doc.amount_due_label(is_deposit, is_final) }}</span>
Expand Down
30 changes: 11 additions & 19 deletions tuttle/app/invoicing/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,19 @@ class InvoicingDataSource(SQLModelDataSourceMixin):
def __init__(self):
super().__init__()

def get_invoices_for_project(self, project_id) -> IntentResult[List[Invoice]]:
"""TODO Get all invoices associated with a given project
@staticmethod
def _hydrate(entities, _depth: int = 2):
"""Also load the settlement that a reminder of a final invoice restates.

Returns:
IntentResult:
was_intent_successful : bool
data : list[Invoice] was_intent_successful else None
log_message : str if an error or exception occurs
exception : Exception if an exception occurs
Its figures come from the final invoice at the head of its reminder
chain and from the deposits deducted there, which the generic
hydration does not reach.
"""
try:
return IntentResult(
was_intent_successful=False,
log_message="NotImplementedError @InvoicingDataSource.get_invoices_for_project",
)
except Exception as e:
return IntentResult(
was_intent_successful=False,
log_message=f"Exception raised @TimeTrackingDataSource.get_invoices_for_project {e.__class__.__name__}",
exception=e,
)
SQLModelDataSourceMixin._hydrate(entities, _depth)
for invoice in entities:
if isinstance(invoice, Invoice) and invoice.is_reminder:
# Reading the deductions walks the chain and loads what they need.
invoice.deposit_deductions

def get_invoice_by_id(self, invoice_id: int) -> IntentResult[Optional[Invoice]]:
"""Fetch a single invoice by primary key."""
Expand Down
Loading
Loading