[IMP] account: align delivery and recipient adresses on invoices
Since 15.2, when creating an invoice containing both a recipient address and an invoice address, the addresses would both appear on the left, one after the other. This made reading difficult and the invoice unclear. Furthermore, the company address wasn't present by default on the invoice : it was only there if a layout had previously been selected. This PR: - reverts the behaviour of the company address, i.e. it appears even if no layout is (yet) selected ; - aligns the delivery and the recipient address on each side of the page when necessary, while not changing the outcome if a single address is given. Also displays a "title" above the addresses when necessary to make things clearer. task-2809240 related : https://github.com/odoo/enterprise/pull/27240 closes odoo/odoo#91487 X-original-commit: 1e745256fabbec4d6979180d8f792c99be463509 Related: odoo/enterprise#27383 Signed-off-by: Florian Gilbert <flg@odoo.com>
This commit is contained in:
@@ -141,4 +141,4 @@
|
||||
</div>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
||||
</odoo>
|
||||
|
||||
@@ -5,136 +5,168 @@
|
||||
<t t-call="web.external_layout">
|
||||
<t t-set="o" t-value="o.with_context(lang=lang)" />
|
||||
<t t-set="forced_vat" t-value="o.fiscal_position_id.foreign_vat"/> <!-- So that it appears in the footer of the report instead of the company VAT if it's set -->
|
||||
<t t-if="o.partner_shipping_id and (o.partner_shipping_id != o.partner_id)">
|
||||
<t t-set="information_block">
|
||||
<div groups="account.group_delivery_invoice_address" name="shipping_address_block">
|
||||
<strong>Shipping Address:</strong>
|
||||
<div t-field="o.partner_shipping_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
|
||||
<div class="row">
|
||||
<t t-if="o.partner_shipping_id and (o.partner_shipping_id != o.partner_id)">
|
||||
<div class="col-6">
|
||||
<t t-set="information_block">
|
||||
<div groups="account.group_delivery_invoice_address" name="shipping_address_block">
|
||||
<strong>Shipping Address:</strong>
|
||||
<div t-field="o.partner_shipping_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col-6" name="address_not_same_as_shipping">
|
||||
<t t-set="address">
|
||||
<address class="mb-0" t-field="o.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
|
||||
<div t-if="o.partner_id.vat">
|
||||
<t t-if="o.company_id.account_fiscal_country_id.vat_label" t-esc="o.company_id.account_fiscal_country_id.vat_label" id="inv_tax_id_label"/>
|
||||
<t t-else="">Tax ID</t>: <span t-field="o.partner_id.vat"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<div t-field="o.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' groups="account.group_delivery_invoice_address"/>
|
||||
<t t-set="address">
|
||||
<address t-field="o.partner_id" t-options='{"widget": "contact", "fields": ["address", "name", "vat"], "no_marker": True}' groups="!account.group_delivery_invoice_address"/>
|
||||
</t>
|
||||
<div class="page">
|
||||
<h2 class="mt-4">
|
||||
<span t-if="o.move_type == 'out_invoice' and o.state == 'posted'">Invoice</span>
|
||||
<span t-if="o.move_type == 'out_invoice' and o.state == 'draft'">Draft Invoice</span>
|
||||
<span t-if="o.move_type == 'out_invoice' and o.state == 'cancel'">Cancelled Invoice</span>
|
||||
<span t-if="o.move_type == 'out_refund'">Credit Note</span>
|
||||
<span t-if="o.move_type == 'in_refund'">Vendor Credit Note</span>
|
||||
<span t-if="o.move_type == 'in_invoice'">Vendor Bill</span>
|
||||
<span t-if="o.name != '/'" t-field="o.name"/>
|
||||
</h2>
|
||||
|
||||
<div id="informations" class="row mt-4 mb-4">
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.invoice_date" name="invoice_date">
|
||||
<strong>Invoice Date:</strong>
|
||||
<p class="m-0" t-field="o.invoice_date"/>
|
||||
<t t-elif="o.partner_shipping_id and (o.partner_shipping_id == o.partner_id)">
|
||||
<div class="offset-col-6 col-6" name="address_same_as_shipping">
|
||||
<t t-set="address">
|
||||
<address class="mb-0" t-field="o.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
|
||||
<div t-if="o.partner_id.vat">
|
||||
<t t-if="o.company_id.account_fiscal_country_id.vat_label" t-esc="o.company_id.account_fiscal_country_id.vat_label" id="inv_tax_id_label"/>
|
||||
<t t-else="">Tax ID</t>: <span t-field="o.partner_id.vat"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.invoice_date_due and o.move_type == 'out_invoice' and o.state == 'posted'" name="due_date">
|
||||
<strong>Due Date:</strong>
|
||||
<p class="m-0" t-field="o.invoice_date_due"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="offset-col-6 col-6" name="no_shipping">
|
||||
<t t-set="address">
|
||||
<address class="mb-0" t-field="o.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' groups="!account.group_delivery_invoice_address"/>
|
||||
<div t-if="o.partner_id.vat">
|
||||
<t t-if="o.company_id.account_fiscal_country_id.vat_label" t-esc="o.company_id.account_fiscal_country_id.vat_label" id="inv_tax_id_label"/>
|
||||
<t t-else="">Tax ID</t>: <span t-field="o.partner_id.vat"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.invoice_origin" name="origin">
|
||||
<strong>Source:</strong>
|
||||
<p class="m-0" t-field="o.invoice_origin"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<div class="page">
|
||||
<h2>
|
||||
<span t-if="o.move_type == 'out_invoice' and o.state == 'posted'">Invoice</span>
|
||||
<span t-if="o.move_type == 'out_invoice' and o.state == 'draft'">Draft Invoice</span>
|
||||
<span t-if="o.move_type == 'out_invoice' and o.state == 'cancel'">Cancelled Invoice</span>
|
||||
<span t-if="o.move_type == 'out_refund'">Credit Note</span>
|
||||
<span t-if="o.move_type == 'in_refund'">Vendor Credit Note</span>
|
||||
<span t-if="o.move_type == 'in_invoice'">Vendor Bill</span>
|
||||
<span t-if="o.name != '/'" t-field="o.name"/>
|
||||
</h2>
|
||||
|
||||
<div id="informations" class="row mt32 mb32">
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.invoice_date" name="invoice_date">
|
||||
<strong>Invoice Date:</strong>
|
||||
<p class="m-0" t-field="o.invoice_date"/>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.invoice_date_due and o.move_type == 'out_invoice' and o.state == 'posted'" name="due_date">
|
||||
<strong>Due Date:</strong>
|
||||
<p class="m-0" t-field="o.invoice_date_due"/>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.invoice_origin" name="origin">
|
||||
<strong>Source:</strong>
|
||||
<p class="m-0" t-field="o.invoice_origin"/>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.partner_id.ref" name="customer_code">
|
||||
<strong>Customer Code:</strong>
|
||||
<p class="m-0" t-field="o.partner_id.ref"/>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.ref" name="reference">
|
||||
<strong>Reference:</strong>
|
||||
<p class="m-0" t-field="o.ref"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.partner_id.ref" name="customer_code">
|
||||
<strong>Customer Code:</strong>
|
||||
<p class="m-0" t-field="o.partner_id.ref"/>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="o.ref" name="reference">
|
||||
<strong>Reference:</strong>
|
||||
<p class="m-0" t-field="o.ref"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<t t-set="display_discount" t-value="any(l.discount for l in o.invoice_line_ids)"/>
|
||||
<t t-set="display_discount" t-value="any(l.discount for l in o.invoice_line_ids)"/>
|
||||
|
||||
<table class="table table-sm o_main_table" name="invoice_line_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th name="th_description" class="text-left"><span>Description</span></th>
|
||||
<th name="th_quantity" class="text-right"><span>Quantity</span></th>
|
||||
<th name="th_priceunit" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}"><span>Unit Price</span></th>
|
||||
<th name="th_price_unit" t-if="display_discount" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
|
||||
<span>Disc.%</span>
|
||||
</th>
|
||||
<th name="th_taxes" t-attf-class="text-left {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}"><span>Taxes</span></th>
|
||||
<th name="th_subtotal" class="text-right">
|
||||
<span groups="account.group_show_line_subtotals_tax_excluded">Amount</span>
|
||||
<span groups="account.group_show_line_subtotals_tax_included">Total Price</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="invoice_tbody">
|
||||
<t t-set="current_subtotal" t-value="0"/>
|
||||
<t t-set="lines" t-value="o.invoice_line_ids.sorted(key=lambda l: (-l.sequence, l.date, l.move_name, -l.id), reverse=True)"/>
|
||||
|
||||
<t t-foreach="lines" t-as="line">
|
||||
<t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/>
|
||||
<t t-set="current_subtotal" t-value="current_subtotal + line.price_total" groups="account.group_show_line_subtotals_tax_included"/>
|
||||
|
||||
<tr t-att-class="'bg-200 font-weight-bold o_line_section' if line.display_type == 'line_section' else 'font-italic o_line_note' if line.display_type == 'line_note' else ''">
|
||||
<t t-if="not line.display_type" name="account_invoice_line_accountable">
|
||||
<td name="account_invoice_line_name"><span t-field="line.name" t-options="{'widget': 'text'}"/></td>
|
||||
<td class="text-right">
|
||||
<span t-field="line.quantity"/>
|
||||
<span t-field="line.product_uom_id" groups="uom.group_uom"/>
|
||||
</td>
|
||||
<td t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
|
||||
<span class="text-nowrap" t-field="line.price_unit"/>
|
||||
</td>
|
||||
<td t-if="display_discount" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
|
||||
<span class="text-nowrap" t-field="line.discount"/>
|
||||
</td>
|
||||
<td t-attf-class="text-left {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
|
||||
<span t-esc="', '.join(map(lambda x: (x.description or x.name), line.tax_ids))" id="line_tax_ids"/>
|
||||
</td>
|
||||
<td class="text-right o_price_total">
|
||||
<span class="text-nowrap" t-field="line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/>
|
||||
<span class="text-nowrap" t-field="line.price_total" groups="account.group_show_line_subtotals_tax_included"/>
|
||||
</td>
|
||||
</t>
|
||||
<t t-if="line.display_type == 'line_section'">
|
||||
<td colspan="99">
|
||||
<span t-field="line.name" t-options="{'widget': 'text'}"/>
|
||||
</td>
|
||||
<t t-set="current_section" t-value="line"/>
|
||||
<t t-set="current_subtotal" t-value="0"/>
|
||||
</t>
|
||||
<t t-if="line.display_type == 'line_note'">
|
||||
<td colspan="99">
|
||||
<span t-field="line.name" t-options="{'widget': 'text'}"/>
|
||||
</td>
|
||||
</t>
|
||||
<table class="table table-sm o_main_table" name="invoice_line_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th name="th_description" class="text-left"><span>Description</span></th>
|
||||
<th name="th_quantity" class="text-right"><span>Quantity</span></th>
|
||||
<th name="th_priceunit" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}"><span>Unit Price</span></th>
|
||||
<th name="th_price_unit" t-if="display_discount" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
|
||||
<span>Disc.%</span>
|
||||
</th>
|
||||
<th name="th_taxes" t-attf-class="text-left {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}"><span>Taxes</span></th>
|
||||
<th name="th_subtotal" class="text-right">
|
||||
<span groups="account.group_show_line_subtotals_tax_excluded">Amount</span>
|
||||
<span groups="account.group_show_line_subtotals_tax_included">Total Price</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="invoice_tbody">
|
||||
<t t-set="current_subtotal" t-value="0"/>
|
||||
<t t-set="lines" t-value="o.invoice_line_ids.sorted(key=lambda l: (-l.sequence, l.date, l.move_name, -l.id), reverse=True)"/>
|
||||
|
||||
<t t-if="current_section and (line_last or lines[line_index+1].display_type == 'line_section')">
|
||||
<tr class="is-subtotal text-right">
|
||||
<td colspan="99">
|
||||
<strong class="mr16">Subtotal</strong>
|
||||
<span
|
||||
t-esc="current_subtotal"
|
||||
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
|
||||
/>
|
||||
</td>
|
||||
<t t-foreach="lines" t-as="line">
|
||||
<t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/>
|
||||
<t t-set="current_subtotal" t-value="current_subtotal + line.price_total" groups="account.group_show_line_subtotals_tax_included"/>
|
||||
|
||||
<tr t-att-class="'bg-200 font-weight-bold o_line_section' if line.display_type == 'line_section' else 'font-italic o_line_note' if line.display_type == 'line_note' else ''">
|
||||
<t t-if="not line.display_type" name="account_invoice_line_accountable">
|
||||
<td name="account_invoice_line_name"><span t-field="line.name" t-options="{'widget': 'text'}"/></td>
|
||||
<td class="text-right">
|
||||
<span t-field="line.quantity"/>
|
||||
<span t-field="line.product_uom_id" groups="uom.group_uom"/>
|
||||
</td>
|
||||
<td t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
|
||||
<span class="text-nowrap" t-field="line.price_unit"/>
|
||||
</td>
|
||||
<td t-if="display_discount" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
|
||||
<span class="text-nowrap" t-field="line.discount"/>
|
||||
</td>
|
||||
<td t-attf-class="text-left {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
|
||||
<span t-esc="', '.join(map(lambda x: (x.description or x.name), line.tax_ids))" id="line_tax_ids"/>
|
||||
</td>
|
||||
<td class="text-right o_price_total">
|
||||
<span class="text-nowrap" t-field="line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/>
|
||||
<span class="text-nowrap" t-field="line.price_total" groups="account.group_show_line_subtotals_tax_included"/>
|
||||
</td>
|
||||
</t>
|
||||
<t t-if="line.display_type == 'line_section'">
|
||||
<td colspan="99">
|
||||
<span t-field="line.name" t-options="{'widget': 'text'}"/>
|
||||
</td>
|
||||
<t t-set="current_section" t-value="line"/>
|
||||
<t t-set="current_subtotal" t-value="0"/>
|
||||
</t>
|
||||
<t t-if="line.display_type == 'line_note'">
|
||||
<td colspan="99">
|
||||
<span t-field="line.name" t-options="{'widget': 'text'}"/>
|
||||
</td>
|
||||
</t>
|
||||
</tr>
|
||||
|
||||
<t t-if="current_section and (line_last or lines[line_index+1].display_type == 'line_section')">
|
||||
<tr class="is-subtotal text-right">
|
||||
<td colspan="99">
|
||||
<strong class="mr16">Subtotal</strong>
|
||||
<span
|
||||
t-esc="current_subtotal"
|
||||
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="clearfix mb-4">
|
||||
<div id="total" class="row">
|
||||
<div t-attf-class="#{'col-6' if report_type != 'html' else 'col-sm-7 col-md-6'} ml-auto">
|
||||
<table class="table table-sm" style="page-break-inside: avoid;">
|
||||
|
||||
<!--Tax totals-->
|
||||
<t t-set="tax_totals" t-value="json.loads(o.tax_totals_json)"/>
|
||||
<t t-call="account.document_tax_totals"/>
|
||||
<!--Tax totals-->
|
||||
<t t-set="tax_totals" t-value="json.loads(o.tax_totals_json)"/>
|
||||
<t t-call="account.document_tax_totals"/>
|
||||
|
||||
<!--Payments-->
|
||||
<t t-if="print_with_payments">
|
||||
@@ -157,10 +189,11 @@
|
||||
<span t-field="o.amount_residual"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -184,6 +217,24 @@
|
||||
<strong class="text-center">Scan me with your banking app.</strong><br/><br/>
|
||||
<img class="border border-dark rounded" t-att-src="qr_code_urls[o.id]"/>
|
||||
</p>
|
||||
<p t-if="o.invoice_payment_term_id" name="payment_term">
|
||||
<span t-field="o.invoice_payment_term_id.note"/>
|
||||
</p>
|
||||
<div t-if="not is_html_empty(o.narration)" name="comment">
|
||||
<span t-field="o.narration"/>
|
||||
</div>
|
||||
<p t-if="not is_html_empty(o.fiscal_position_id.note)" name="note">
|
||||
<span t-field="o.fiscal_position_id.note"/>
|
||||
</p>
|
||||
<p t-if="o.invoice_incoterm_id" name="incoterm">
|
||||
<strong>Incoterm: </strong><span t-field="o.invoice_incoterm_id.code"/> - <span t-field="o.invoice_incoterm_id.name"/>
|
||||
</p>
|
||||
<div id="qrcode" t-if="o.display_qr_code and o.amount_residual > 0">
|
||||
<p t-if="qr_code_urls.get(o.id)">
|
||||
<strong class="text-center">Scan me with your banking app.</strong><br/><br/>
|
||||
<img class="border border-dark rounded" t-att-src="qr_code_urls[o.id]"/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
<odoo>
|
||||
<template id="l10n_ca_report_invoice_document_inherit" inherit_id="account.report_invoice_document">
|
||||
<div t-field="o.partner_id" position="after">
|
||||
<t t-if="o.company_id.account_fiscal_country_id.code == 'CA' and o.partner_id.l10n_ca_pst" class="mt16">
|
||||
<div>PST: <span t-field="o.partner_id.l10n_ca_pst"/></div>
|
||||
</t>
|
||||
</div>
|
||||
<xpath expr="//div[hasclass('row')]//div[@name='address_not_same_as_shipping']//t[@t-set='address']" position="inside">
|
||||
<div>PST: <span t-field="o.partner_id.l10n_ca_pst"/></div>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('row')]//div[@name='address_same_as_shipping']//t[@t-set='address']" position="inside">
|
||||
<div>PST: <span t-field="o.partner_id.l10n_ca_pst"/></div>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('row')]//div[@name='no_shipping']//t[@t-set='address']" position="inside">
|
||||
<div>PST: <span t-field="o.partner_id.l10n_ca_pst"/></div>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
||||
@@ -441,6 +441,8 @@
|
||||
<div class="row">
|
||||
<div class="col-6" name="company_address">
|
||||
<span t-if="company.company_details" t-field="company.company_details"></span>
|
||||
<span t-else="" t-field="company.partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user