19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:30:07 +01:00
parent ba20ce7443
commit 768b70e05e
2357 changed files with 1057103 additions and 712486 deletions

View file

@ -7,17 +7,20 @@
<field name="inherit_id" ref="account.view_account_journal_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='inbound_payment_method_line_ids']//field[@name='payment_account_id']" position="after">
<field name="payment_provider_state" invisible="1"/>
<field name="code" invisible="1"/>
<field name="payment_provider_id" options="{'no_open': True, 'no_create': True}" optional="hide" domain="[('code', '=', code)]"/>
<field name="code" column_invisible="True"/>
<field name="payment_provider_id"
options="{'no_open': True, 'no_create': True}"
optional="hide"
readonly="payment_provider_state in ('enabled', 'test')"/>
<field name="payment_provider_state" column_invisible="True"/>
<button name="action_open_provider_form"
type="object"
string="SETUP"
class="float-end btn-secondary"
attrs="{'invisible': [('payment_provider_id', '=', False)]}"
invisible="not payment_provider_id"
groups="base.group_system"/>
</xpath>
<xpath expr="//field[@name='inbound_payment_method_line_ids']/tree" position="attributes">
<xpath expr="//field[@name='inbound_payment_method_line_ids']/list" position="attributes">
<attribute name="decoration-muted">payment_provider_state == 'disabled'</attribute>
</xpath>
</field>

View file

@ -10,26 +10,30 @@
The user must capture/void the authorized transactions before registering a new payment.
-->
<xpath expr="//button[@id='account_invoice_payment_btn']" position="attributes">
<attribute name="attrs">{'invisible': ['|', '|', '|', ('state', '!=', 'posted'), ('payment_state', 'not in', ('partial', 'not_paid')), ('move_type', 'not in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt')), ('authorized_transaction_ids', '!=', [])]}</attribute>
<attribute name="invisible" separator="or" add="authorized_transaction_ids"/>
</xpath>
<xpath expr="//button[@id='account_invoice_payment_secondary_btn']" position="attributes">
<attribute name="invisible" separator="or" add="authorized_transaction_ids"/>
</xpath>
<xpath expr="//button[@id='account_invoice_payment_btn']" position="after">
<field name="authorized_transaction_ids" invisible="1"/>
<button name="payment_action_capture" type="object"
groups="account.group_account_invoice"
string="Capture Transaction" class="oe_highlight" data-hotkey="shift+g"
attrs="{'invisible': ['|', '|', ('move_type', 'not in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund')), ('state', '!=', 'posted'), ('authorized_transaction_ids', '=', [])]}"/>
invisible="move_type not in ('out_invoice', 'out_refund', 'in_invoice', 'in_refund') or state != 'posted' or not authorized_transaction_ids"/>
<button name="payment_action_void" type="object"
groups="account.group_account_invoice"
string="Void Transaction" data-hotkey="shift+v"
confirm="Are you sure you want to void the authorized transaction? This action can't be undone."
attrs="{'invisible': ['|', '|', ('move_type', 'not in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund')), ('state', '!=', 'posted'), ('authorized_transaction_ids', '=', [])]}"/>
invisible="move_type not in ('out_invoice', 'out_refund', 'in_invoice', 'in_refund') or state != 'posted' or not authorized_transaction_ids"/>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<field name="transaction_ids" invisible="1" />
<button name="action_view_payment_transactions" type="object"
groups="account.group_account_invoice"
class="oe_stat_button" icon="fa-money"
string="Payment Transaction"
attrs="{'invisible': [('transaction_ids', '=', [])]}" />
invisible="transaction_count == 0">
<field name="transaction_count" widget="statinfo" string="Payment Transaction"/>
</button>
</xpath>
</field>
</record>

View file

@ -5,10 +5,9 @@
id="payment_provider_menu"
parent="account.root_payment_menu"
sequence="10"/>
<menuitem action="payment.action_payment_icon"
id="payment_icon_menu"
<menuitem action="payment.action_payment_method"
id="payment_method_menu"
parent="account.root_payment_menu"
groups="base.group_no_one"
sequence="15"/>
<menuitem action="payment.action_payment_token"
id="payment_token_menu"

View file

@ -12,7 +12,7 @@
type="object"
string="Refund"
groups="account.group_account_invoice"
attrs="{'invisible': [('amount_available_for_refund', '&lt;=', 0)]}"
invisible="amount_available_for_refund &lt;= 0"
class="btn-secondary"/>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
@ -20,20 +20,21 @@
type="object"
class="oe_stat_button"
icon="fa-money"
attrs="{'invisible': [('refunds_count', '=', 0)]}">
invisible="refunds_count == 0">
<field name="refunds_count" widget="statinfo" string="Refunds"/>
</button>
</xpath>
<xpath expr='//group[2]' position="inside">
<field name="source_payment_id" attrs="{'invisible': [('source_payment_id', '=', False)]}"/>
<field name="payment_transaction_id" groups="base.group_no_one" attrs="{'invisible': [('use_electronic_payment_method', '!=', True)]}"/>
<field name="source_payment_id" invisible="not source_payment_id"/>
<field name="payment_transaction_id" groups="base.group_no_one" invisible="not use_electronic_payment_method"/>
</xpath>
<field name="payment_method_line_id" position="after">
<field name="payment_method_code" invisible="1"/>
<field name="suitable_payment_token_ids" invisible="1"/>
<field name="use_electronic_payment_method" invisible="1"/>
<field name="payment_token_id" options="{'no_create': True}"
attrs="{'invisible': [('use_electronic_payment_method', '!=', True)], 'readonly': [('state', '!=', 'draft')]}"/>
invisible="not use_electronic_payment_method"
readonly="state != 'draft'"/>
</field>
</field>
</record>

View file

@ -1,40 +1,131 @@
<odoo>
<template id="portal_my_invoices_payment" name="Payment on My Invoices" inherit_id="account.portal_my_invoices">
<xpath expr="//t[@t-call='portal.portal_table']/thead/tr/th[last()]" position="before">
<th></th>
<template id="portal_my_home_overdue_invoice" name="Portal layout: overdue invoices" inherit_id="portal.portal_breadcrumbs" priority="30">
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
<t t-if="page_name == 'overdue_invoices'">
<li t-attf-class="breadcrumb-item active">
<a t-attf-href="/my/invoices?{{ keep_query() }}">Invoices &amp; Bills</a>
</li>
<li class="breadcrumb-item active">
<t t-out="payment['reference']"/>
</li>
</t>
</xpath>
<xpath expr="//t[@t-foreach='invoices']/tr/td[last()]" position="before">
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="after">
<a t-if="page_name == 'invoice' and not invoice and filterby != 'bills' and overdue_invoice_count > 0"
class='btn btn-primary'
href='/my/invoices/overdue'>
Pay overdue
</a>
</xpath>
</template>
<template id="account_payment.portal_docs_entry" inherit_id="portal.portal_docs_entry">
<xpath expr="//a" position="inside">
<button
t-if="show_pay_overdue_invoices_button"
onclick="event.preventDefault(); window.location.href='/my/invoices/overdue'"
class="btn btn-secondary ms-auto">
Pay Now
</button>
</xpath>
</template>
<template id="portal_my_home_account_payment" name="Overdue invoices" customize_show="True" inherit_id="portal.portal_my_home" priority="20">
<xpath expr="//div[hasclass('o_portal_docs')]" position="before">
<t t-set="portal_alert_category_enable" t-value="True"/>
</xpath>
<div id="portal_alert_category" position="inside">
<t t-call="portal.portal_docs_entry">
<t t-set="bg_color" t-value="'alert alert-primary align-items-center'"/>
<t t-set="placeholder_count" t-value="'overdue_invoice_count'"/>
<t t-set="title">Invoices to pay</t>
<t t-set="url" t-value="'/my/invoices?filterby=overdue_invoices'"/>
<t t-set="show_count" t-value="True"/>
<t t-set="show_pay_overdue_invoices_button" t-value="True"/>
</t>
</div>
</template>
<template id="portal_overdue_invoices_page" name="Overdue payments">
<t t-call="portal.portal_layout">
<div class="row justify-content-center my-3">
<div class="col-lg-7">
<div class="text-bg-light row mx-0 rounded">
<t t-call="payment.summary_item">
<t t-set="name" t-value="'amount'"/>
<t t-set="label">Amount</t>
<t t-set="value" t-value="abs(payment['amount'])"/>
<t t-set="options"
t-value="{'widget': 'monetary', 'display_currency': currency}"/>
</t>
<t t-call="payment.summary_item">
<t t-set="name" t-value="'reference'"/>
<t t-set="label">Reference</t>
<t t-set="value" t-value="payment['reference']"/>
<t t-set="include_separator" t-value="True"/>
</t>
</div>
<div class="mt-4">
<t t-call="payment.form"/>
</div>
</div>
</div>
</t>
</template>
<template id="portal_my_invoices_payment" name="Payment on My Invoices" inherit_id="account.portal_my_invoices">
<xpath expr="//t[@t-call='portal.portal_table']//th[@name='amount_due']" position="after">
<th class="d-none d-lg-table-cell"/>
<th/>
</xpath>
<xpath expr="//t[@t-foreach='invoices']/tr/td[last()]" position="after">
<td class="d-none d-lg-table-cell text-center">
<t t-if="invoice_data.get('installment_state', False) in ('next', 'overdue')">
<span
t-attf-class="{{'text-danger' if invoice_data['installment_state'] == 'overdue' else ''}}"
t-out="invoice_data['next_amount_to_pay']"
t-options="{'widget': 'monetary', 'display_currency': invoice.currency_id}"
/>
<small
t-if="invoice_data['installment_state'] == 'next'"
class="o_portal_invoice_due_date"
t-att-datetime="invoice_data['next_due_date']"
/>
<small t-if="invoice_data['installment_state'] == 'overdue'" class="text-danger">
overdue
</small>
</t>
</td>
<td class="text-center">
<t t-set="tx_ids" t-value="invoice.transaction_ids.filtered(lambda tx: tx.state in ('pending', 'authorized'))"/>
<t t-set="pending_manual_txs" t-value="tx_ids.filtered(lambda tx: tx.state == 'pending' and tx.provider_code in ('none', 'custom'))"/>
<a t-if="invoice.state == 'posted' and invoice.payment_state in ('not_paid', 'partial') and invoice.amount_total and invoice.move_type == 'out_invoice' and (pending_manual_txs or not tx_ids or invoice.amount_paid &lt; invoice.amount_total)"
t-att-href="invoice.get_portal_url(anchor='portal_pay')" title="Pay Now" aria-label="Pay now" class="btn btn-sm btn-primary" role="button">
<a t-if="invoice._has_to_be_paid()"
t-att-href="invoice.get_portal_url(anchor='portal_pay', query_string='&amp;payment=True')"
title="Pay Now"
aria-label="Pay now"
class="btn btn-sm btn-primary"
role="button"
>
<i class="fa fa-arrow-circle-right"/><span class='d-none d-md-inline'> Pay Now</span>
</a>
</td>
</xpath>
<xpath expr="//t[@t-foreach='invoices']/tr/td[hasclass('tx_status')]" position="replace">
<t t-set="last_tx" t-value="invoice.get_portal_last_transaction()"/>
<td class="tx_status text-center">
<t t-if="invoice.state == 'posted' and invoice.payment_state in ('not_paid', 'partial') and (last_tx.state not in ['pending', 'authorized'] or (last_tx.state == 'pending' and last_tx.provider_code in ('none', 'custom')))">
<span class="badge rounded-pill text-bg-info"><i class="fa fa-fw fa-clock-o"></i><span class="d-none d-md-inline"> Waiting for Payment</span></span>
</t>
<t t-if="invoice.state == 'posted' and last_tx.state == 'authorized'">
<span class="badge rounded-pill text-bg-primary"><i class="fa fa-fw fa-check"/><span class="d-none d-md-inline"> Authorized</span></span>
</t>
<t t-if="invoice.state == 'posted' and last_tx.state == 'pending' and last_tx.provider_code not in ('none', 'custom')">
<span class="badge rounded-pill text-bg-warning"><span class="d-none d-md-inline"> Pending</span></span>
</t>
<t t-if="invoice.state == 'posted' and invoice.payment_state in ('paid', 'in_payment')">
<span class="badge rounded-pill text-bg-success"><i class="fa fa-fw fa-check"></i><span class="d-none d-md-inline"> Paid</span></span>
</t>
<t t-if="invoice.state == 'posted' and invoice.payment_state == 'reversed'">
<span class="badge rounded-pill text-bg-success"><i class="fa fa-fw fa-check"></i><span class="d-none d-md-inline"> Reversed</span></span>
</t>
<t t-if="invoice.state == 'cancel'">
<span class="badge rounded-pill text-bg-danger"><i class="fa fa-fw fa-remove"></i><span class="d-none d-md-inline"> Cancelled</span></span>
</t>
</td>
<xpath expr="//t[@name='invoice_status_posted']/span[1]" position="before">
<t t-set="tx_sudo" t-value="invoice.get_portal_last_transaction()"/>
</xpath>
<xpath expr="//span[@name='invoice_status_waiting_for_payment']" position="before">
<span t-elif="invoice.payment_state in ('not_paid', 'partial') and tx_sudo.state == 'authorized'"
class="badge rounded-pill text-bg-primary">
<i class="fa fa-fw fa-check"/>
<span class="d-none d-md-inline"> Authorized</span>
</span>
<span t-elif="invoice.payment_state in ('not_paid', 'partial') and tx_sudo.state == 'pending' and tx_sudo.provider_code not in ('none', 'custom')"
class="badge rounded-pill text-bg-warning">
<span class="d-none d-md-inline"> Pending</span>
</span>
<span t-elif="invoice.payment_state in ('paid', 'in_payment') and tx_sudo.state == 'done'" class="badge rounded-pill text-bg-success">
<i class="fa fa-fw fa-check"></i>
<span class="d-none d-md-inline"> Paid</span>
</span>
</xpath>
</template>
@ -43,18 +134,133 @@
<div class="modal fade" id="pay_with" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Pay with</h3>
<div class="modal-header pb-0">
<h3 class="modal-title">Pay</h3>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div t-if="providers or tokens" id="payment_method" class="text-start col-md-13">
<t t-call="payment.checkout"/>
<div t-if="company_mismatch">
<t t-call="payment.company_mismatch_warning"/>
</div>
<div t-else="" class="alert alert-warning">
<strong>No suitable payment option could be found.</strong><br/>
If you believe that it is an error, please contact the website administrator.
<div t-elif="installment_state in ('next', 'overdue') and amount_due != next_amount_to_pay" id="o_payment_installments_modal">
<div class="btn-group w-100" id="o_payment_tabs" role="tablist">
<button class="btn btn-outline-primary o_btn_payment_tab active"
id="o_payment_installments_tab"
data-bs-toggle="pill"
data-bs-target="#o_payment_installments"
type="button"
role="tab"
aria-controls="o_payment_installments"
aria-selected="true"
>
<strong>Installment</strong>
<br/>
<t
t-out="next_amount_to_pay"
t-options="{'widget': 'monetary', 'display_currency': currency}"
/>
</button>
<button class="btn btn-outline-primary o_btn_payment_tab"
id="o_payment_full_tab"
data-bs-toggle="pill"
data-bs-target="#o_payment_full"
type="button"
role="tab"
aria-controls="o_payment_full"
aria-selected="false"
>
<strong>Full Amount</strong><br/>
<t t-out="amount_due" t-options="{'widget': 'monetary', 'display_currency': currency}"/>
</button>
</div>
<div class="tab-content" id="o_payment_tabcontent">
<div t-if="payment_state == 'in_payment'" class="alert alert-danger mt-2">
A payment has already been made on this invoice, please make sure to not pay twice.
</div>
<div
class="tab-pane my-3 show active"
id="o_payment_installments"
role="tabpanel"
aria-labelledby="o_payment_installments_tab"
tabindex="0"
>
<div class="text-bg-light row row-cols-1 row-cols-md-2 mx-0 py-2 rounded">
<t t-call="payment.summary_item">
<t t-set="name" t-value="'amount_installment'"/>
<t t-set="label">Amount</t>
<t t-set="value" t-value="next_amount_to_pay"/>
<t t-set="options"
t-value="{'widget': 'monetary', 'display_currency': currency}"
/>
</t>
<t t-call="payment.summary_item">
<t t-set="name" t-value="'reference_installment'"/>
<t t-set="label">Reference</t>
<t t-set="value" t-value="next_payment_reference"/>
<t t-set="include_separator" t-value="True"/>
</t>
</div>
</div>
<div class="tab-pane my-3"
id="o_payment_full"
role="tabpanel"
aria-labelledby="o_payment_full_tab"
tabindex="0"
>
<div t-if="show_epd" class="alert alert-success">
Early Payment Discount of <span t-out="epd_discount_amount_currency" t-options="{'widget': 'monetary', 'display_currency': currency}"/> has been applied.
</div>
<div class="text-bg-light row row-cols-1 row-cols-md-2 mx-0 py-2 rounded">
<t t-call="payment.summary_item">
<t t-set="name" t-value="'amount_full'"/>
<t t-set="label">Amount</t>
<t t-set="value" t-value="amount_due"/>
<t t-set="options"
t-value="{'widget': 'monetary', 'display_currency': currency}"
/>
</t>
<t t-call="payment.summary_item">
<t t-set="name" t-value="'reference_full'"/>
<t t-set="label">Reference</t>
<t t-set="value" t-value="invoice_name"/>
<t t-set="include_separator" t-value="True"/>
</t>
</div>
</div>
<!-- set default amount as the max. amount due, the 'amount'
will be updated/set js-side depending the active tab -->
<t t-call="account_payment.form">
<t t-set="amount" t-value="amount_due"/>
</t>
</div>
</div>
<t t-else="">
<div t-if="show_epd" class="alert alert-success">
Early Payment Discount of <span t-out="epd_discount_amount_currency" t-options="{'widget': 'monetary', 'display_currency': currency}"/> has been applied.
</div>
<div t-if="payment_state == 'in_payment'" class="alert alert-danger">
A payment has already been made on this invoice, please make sure to not pay twice.
</div>
<div class="text-bg-light row row-cols-1 row-cols-md-2 mx-0 mb-3 py-2 rounded">
<t t-call="payment.summary_item">
<t t-set="name" t-value="'amount_full'"/>
<t t-set="label">Amount</t>
<t t-set="value" t-value="amount_due"/>
<t t-set="options"
t-value="{'widget': 'monetary', 'display_currency': currency}"
/>
</t>
<t t-call="payment.summary_item">
<t t-set="name" t-value="'reference_full'"/>
<t t-set="label">Reference</t>
<t t-set="value" t-value="next_payment_reference"/>
<t t-set="include_separator" t-value="True"/>
</t>
</div>
<t t-call="account_payment.form">
<t t-set="amount" t-value="amount_due"/>
</t>
</t>
</div>
</div>
</div>
@ -62,39 +268,56 @@
</div>
</template>
<template id="portal_invoice_page_inherit_payment" name="Payment on My Invoices" inherit_id="account.portal_invoice_page">
<xpath expr="//t[@t-call='portal.portal_record_sidebar']//div[hasclass('o_download_pdf')]" position="before">
<t t-set="tx_ids" t-value="invoice.transaction_ids.filtered(lambda tx: tx.state in ('pending', 'authorized'))"/>
<t t-set="pending_manual_txs" t-value="tx_ids.filtered(lambda tx: tx.state == 'pending' and tx.provider_code in ('none', 'custom'))"/>
<div class="d-grid">
<a href="#" t-if="invoice.state == 'posted' and invoice.payment_state in ('not_paid', 'partial') and invoice.amount_total and invoice.move_type == 'out_invoice' and (pending_manual_txs or not tx_ids or invoice.amount_paid &lt; invoice.amount_total)"
class="btn btn-primary mb-2" data-bs-toggle="modal" data-bs-target="#pay_with">
<i class="fa fa-fw fa-arrow-circle-right"/> Pay Now
</a>
<div t-if="tx_ids and not pending_manual_txs and not invoice.amount_residual and invoice.payment_state not in ('paid', 'in_payment')" class="alert alert-info py-1 mb-2" >
<i class="fa fa-fw fa-check-circle"/> Pending
</div>
<div t-if="invoice.payment_state in ('paid', 'in_payment')" class="alert alert-success py-1 mb-2" >
<i class="fa fa-fw fa-check-circle"/> Paid
<template id="portal_invoice_payment_paid" name="Invoice Paid">
<div class="modal fade" id="pay_with" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Pay Invoice</h3>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="alert alert-warning text-center" role="alert" t-out="invoice._get_online_payment_error()"/>
</div>
</div>
</div>
</div>
</template>
<template id="portal_invoice_page_inherit_payment" name="Payment on My Invoices" inherit_id="account.portal_invoice_page">
<xpath expr="//t[@t-call='portal.portal_record_sidebar']//h2[1]" position="after">
<t t-set="pending_txs" t-value="invoice.transaction_ids.filtered(lambda tx: tx.state in ('pending', 'authorized') and tx.provider_code not in ('none', 'custom'))"/>
<div name="invoice_paid_badge" t-if="invoice.currency_id.is_zero(invoice.amount_residual)" class="rounded text-bg-success fw-normal badge">
<i class="fa fa-fw fa-check-circle"/> Paid
</div>
<div t-if="invoice.payment_state == 'in_payment' and not invoice.currency_id.is_zero(invoice.amount_residual)" class="rounded text-bg-info fw-normal badge">
<i class="fa fa-fw fa-check-circle"/> Processing Payment
</div>
<div t-elif="pending_txs" class="rounded text-bg-info fw-normal badge">
<i class="fa fa-fw fa-check-circle"/> Pending
</div>
</xpath>
<xpath expr="//t[@t-call='portal.portal_record_sidebar']//div[hasclass('o_download_pdf')]" position="before">
<a t-if="invoice._has_to_be_paid()"
href="#"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#pay_with">
<i class="fa fa-fw fa-arrow-circle-right"/> Pay Now
</a>
</xpath>
<xpath expr="//div[@id='invoice_content']//div[hasclass('o_portal_html_view')]" position="before">
<t t-set="tx" t-value="invoice.get_portal_last_transaction()"/>
<div t-if="invoice.transaction_ids and invoice.amount_total and not success and not error and (invoice.payment_state != 'not_paid' or tx.state in ('pending', 'authorized'))"
<div t-if="invoice.get_portal_last_transaction() and invoice.amount_total and not success and not error and (invoice.payment_state != 'not_paid' or tx.state in ('pending', 'authorized'))"
class="o_account_payment_tx_status"
t-att-data-invoice-id="invoice.id">
<t t-call="payment.transaction_status"/>
<t t-call="payment.state_header"/>
</div>
<t t-set="tx_ids" t-value="invoice.transaction_ids.filtered(lambda tx: tx.state in ('authorized', 'done'))"/>
<div t-if="(invoice.amount_residual or not tx_ids) and invoice.state == 'posted' and invoice.payment_state in ('not_paid', 'partial') and invoice.amount_total" id="portal_pay">
<div t-if="invoice._has_to_be_paid()" id="portal_pay" t-att-data-payment="payment">
<t t-call="account_payment.portal_invoice_payment"/>
</div>
<div class="panel-body" t-if="existing_token">
<div class="offset-lg-3 col-lg-6">
<i class="fa fa-info"></i> You have credits card registered, you can log-in to be able to use them.
</div>
<div t-else="" id="portal_pay" t-att-data-payment="payment">
<t t-call="account_payment.portal_invoice_payment_paid"/>
</div>
</xpath>
</template>
@ -105,17 +328,17 @@
<t t-if="error == 'pay_invoice_invalid_doc'">
There was an error processing your payment: invalid invoice.
</t>
<t t-if="error == 'pay_invoice_invalid_token'">
<t t-elif="error == 'pay_invoice_invalid_token'">
There was en error processing your payment: invalid credit card ID.
</t>
<t t-if="error == 'pay_invoice_tx_fail'">
<t t-elif="error == 'pay_invoice_tx_fail'">
There was an error processing your payment: transaction failed.<br />
<t t-set="tx_id" t-value="invoice.get_portal_last_transaction()"/>
<t t-if="tx_id and tx_id.state_message">
<t t-esc="tx_id.state_message"/>
<t t-set="tx_sudo" t-value="invoice.get_portal_last_transaction()"/>
<t t-if="tx_sudo and tx_sudo.state_message">
<t t-out="tx_sudo.state_message"/>
</t>
</t>
<t t-if="error == 'pay_invoice_tx_token'">
<t t-elif="error == 'pay_invoice_tx_token'">
There was an error processing your payment: issue with credit card ID validation.
</t>
</xpath>
@ -125,10 +348,10 @@
inherit_id="account.portal_invoice_success">
<xpath expr="//a[hasclass('close')]" position="after">
<t t-if="success == 'pay_invoice'">
<t t-set="payment_tx_id" t-value="invoice.get_portal_last_transaction()"/>
<span t-if='payment_tx_id.provider_id.sudo().done_msg' t-out="payment_tx_id.provider_id.sudo().done_msg"/>
<div t-if="payment_tx_id.provider_id.sudo().pending_msg and payment_tx_id.provider_code == 'custom' and invoice.ref">
<b>Communication: </b><span t-esc='invoice.ref'/>
<t t-set="tx_sudo" t-value="invoice.get_portal_last_transaction()"/>
<span t-if="tx_sudo.provider_id.sudo().done_msg" t-out="tx_sudo.provider_id.sudo().done_msg"/>
<div t-if="tx_sudo.provider_id.sudo().pending_msg and tx_sudo.provider_code == 'custom' and invoice.ref">
<b>Communication: </b><span t-out='invoice.ref'/>
</div>
</t>
<t t-if="success == 'pay_invoice' and invoice.payment_state in ('paid', 'in_payment')">

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="account_payment.form" inherit_id="payment.form" name="Invoice Payment Form">
<xpath expr="//form[@id='o_payment_form']" position="attributes">
<attribute name="t-att-data-invoice-next-amount-to-pay">next_amount_to_pay</attribute>
<attribute name="t-att-data-invoice-amount-due">amount_due</attribute>
<attribute name="t-att-data-payment-reference">payment_reference</attribute>
</xpath>
</template>
</odoo>

View file

@ -14,7 +14,8 @@
<group name="payment_followup" position="inside">
<field name="journal_id"
context="{'default_type': 'bank'}"
attrs="{'required': [('state', '!=', 'disabled'), ('code', 'not in', ['none', 'custom'])]}"/>
required="state != 'disabled' and code not in ['none', 'custom']"/>
<field name="support_refund" groups="base.group_no_one"/>
</group>
</field>
</record>

View file

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Include account-related values in payment checkout form to pass them to the client -->
<template id="payment_checkout_inherit" inherit_id="payment.checkout">
<xpath expr="//form[@name='o_payment_checkout']" position="attributes">
<attribute name="t-att-data-invoice-id">invoice_id</attribute>
</xpath>
</template>
<!-- Include account-related values in payment manage form to pass them to the client -->
<template id="payment_manage_inherit" inherit_id="payment.manage">
<xpath expr="//form[@name='o_payment_manage']" position="attributes">
<attribute name="t-att-data-invoice-id">invoice_id</attribute>
</xpath>
</template>
</odoo>

View file

@ -9,7 +9,7 @@
<button name="action_view_refunds" position="before">
<button name="action_view_invoices" type="object"
class="oe_stat_button" icon="fa-money"
attrs="{'invisible': [('invoices_count', '=', 0)]}">
invisible="invoices_count == 0">
<field name="invoices_count" widget="statinfo" string="Invoice(s)"/>
</button>
</button>