Files
odoo_source/addons/account/views/report_invoice.xml
T
Pouya Malekinejad eb23c0c9d5 [IMP] *: unify contact widget usage with VAT
The contact widget supports displaying VAT but it was added manually in the reports after contact. This commit fixes this behavior and results in fewer code and an easier way for the l10n modules which may modify VAT display.

closes odoo/odoo#83733

Related: odoo/enterprise#25195
Signed-off-by: Laurent Smet <las@odoo.com>
2022-03-24 13:57:11 +01:00

289 lines
18 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="report_invoice_document">
<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>
</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"/>
</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>
<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>
</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>
</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"/>
<!--Payments-->
<t t-if="print_with_payments">
<t t-if="o.payment_state != 'invoicing_legacy'">
<t t-set="payments_vals" t-value="o.sudo()._get_reconciled_info_JSON_values()"/>
<t t-foreach="payments_vals" t-as="payment_vals">
<tr>
<td>
<i class="oe_form_field text-right oe_payment_label">Paid on <t t-esc="payment_vals['date']" t-options='{"widget": "date"}'/></i>
</td>
<td class="text-right">
<span t-esc="payment_vals['amount']" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
</td>
</tr>
</t>
<t t-if="len(payments_vals) > 0">
<tr class="border-black">
<td><strong>Amount Due</strong></td>
<td class="text-right">
<span t-field="o.amount_residual"/>
</td>
</tr>
</t>
</t>
</t>
</table>
</div>
</div>
</div>
<p t-if="o.move_type in ('out_invoice', 'in_refund') and o.payment_reference" name="payment_communication">
Please use the following communication for your payment : <b><span t-field="o.payment_reference"/></b>
</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>
</t>
</template>
<template id="document_tax_totals">
<!--
Generic template to display tax totals in pdf reports.
Used by invoices, SO and PO.
ARGUMENTS:
- tax_totals: dict in the form generated by account.move's _get_tax_totals.
-->
<t t-foreach="tax_totals['subtotals']" t-as="subtotal">
<tr class="border-black o_subtotal">
<td><strong t-esc="subtotal['name']"/></td>
<td class="text-right">
<span
t-att-class="oe_subtotal_footer_separator"
t-esc="subtotal['formatted_amount']"
/>
</td>
</tr>
<t t-set="subtotal_to_show" t-value="subtotal['name']"/>
<t t-call="account.tax_groups_totals"/>
</t>
<!--Total amount with all taxes-->
<tr class="border-black o_total">
<td><strong>Total</strong></td>
<td class="text-right">
<span t-esc="tax_totals['formatted_amount_total']"/>
</td>
</tr>
</template>
<template id="tax_groups_totals">
<!--
Generic template to display a list of tax groups with the related amounts.
ARGUMENTS:
- tax_totals: dict in the form generated by account.move's _get_tax_totals.
- subtotal_to_show: The subtotal we need to render the groups from
-->
<t t-foreach="tax_totals['groups_by_subtotal'][subtotal_to_show]" t-as="amount_by_group">
<tr>
<t t-if="len(tax_totals['groups_by_subtotal'][subtotal_to_show]) > 1">
<td>
<span t-esc="amount_by_group['tax_group_name']"/>
<span class="text-nowrap"> on
<t t-esc="amount_by_group['formatted_tax_group_base_amount']"/>
</span>
</td>
<td class="text-right o_price_total">
<span class="text-nowrap" t-esc="amount_by_group['formatted_tax_group_amount']"/>
</td>
</t>
<t t-else="">
<td><span class="text-nowrap" t-esc="amount_by_group['tax_group_name']"/></td>
<td class="text-right o_price_total">
<span class="text-nowrap" t-esc="amount_by_group['formatted_tax_group_amount']" />
</td>
</t>
</tr>
</t>
</template>
<template id="report_invoice">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-set="lang" t-value="o.partner_id.lang"/>
<t t-if="o._get_name_invoice_report() == 'account.report_invoice_document'"
t-call="account.report_invoice_document" t-lang="lang"/>
</t>
</t>
</template>
<template id="report_invoice_with_payments">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-set="lang" t-value="o.partner_id.lang"/>
<t t-set="print_with_payments" t-value="True"/>
<t t-if="o._get_name_invoice_report() == 'account.report_invoice_document'"
t-call="account.report_invoice_document" t-lang="lang"/>
</t>
</t>
</template>
<!--We need to create the following empty report template for the action report
"action_account_original_vendor_bill" to work. The action is merging the
original vendor bill(s) that were used to create the vendor bill(s) into one PDF. -->
<template id="report_original_vendor_bill">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<div class="article" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')"></div>
</t>
</t>
</template>
</data>
</odoo>