mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-22 03:12:07 +02:00
19.0 vanilla
This commit is contained in:
parent
d1963a3c3a
commit
2d3ee4855a
7430 changed files with 2687981 additions and 2965473 deletions
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="payment.express_checkout" name="Payment Express Checkout">
|
||||
<!-- Parameters description:
|
||||
- reference_prefix: The custom prefix to compute the full transaction reference.
|
||||
- amount: The amount to pay.
|
||||
- minor_amount: The amount to pay in the minor units of its currency.
|
||||
- currency: The currency of the payment, as a `res.currency` record.
|
||||
- providers_sudo: The compatible providers, as a sudoed `payment.provider` recordset.
|
||||
- merchant_name: The merchant name.
|
||||
- payment_method_unknown_id: The ID of the "Unknown" payment method record, to use as
|
||||
the generic express checkout method.
|
||||
- payment_access_token: The access token used to authenticate the partner. Since this
|
||||
template is loaded in the shopping cart, this parameter is
|
||||
called `payment_access_token` to prevent mixing up with the
|
||||
`access_token` used for abandoned carts.
|
||||
- shipping_info_required: Whether the shipping information is required or not.
|
||||
- transaction_route: The route used to create a transaction when the user clicks Pay.
|
||||
- shipping_address_update_route: The route where available carriers are computed based
|
||||
on the (partial) shipping information available.
|
||||
Optional.
|
||||
- express_checkout_route: The route where the billing and shipping information are sent.
|
||||
- landing_route: The route the user is redirected to after the transaction.
|
||||
- payment_access_token: The access token used to authenticate the partner. Since this
|
||||
template is loaded in the shopping cart, this parameter is
|
||||
called `payment_access_token` to prevent mixing up with the
|
||||
`access_token` used for abandoned carts.
|
||||
-->
|
||||
<form name="o_payment_express_checkout_form" class="container"
|
||||
t-att-data-reference-prefix="reference_prefix"
|
||||
t-att-data-amount="amount"
|
||||
t-att-data-minor-amount="minor_amount"
|
||||
t-att-data-currency-id="currency and currency.id"
|
||||
t-att-data-currency-name="currency.name.lower()"
|
||||
t-att-data-merchant-name="merchant_name"
|
||||
t-att-data-partner-id="partner_id"
|
||||
t-att-data-payment-method-unknown-id="payment_method_unknown_id"
|
||||
t-att-data-access-token="payment_access_token"
|
||||
t-att-data-shipping-info-required="shipping_info_required"
|
||||
t-att-data-delivery-amount="delivery_amount"
|
||||
t-att-data-transaction-route="transaction_route"
|
||||
t-att-data-shipping-address-update-route="shipping_address_update_route"
|
||||
t-att-data-express-checkout-route="express_checkout_route"
|
||||
t-att-data-landing-route="landing_route"
|
||||
>
|
||||
<t t-set="provider_sudo" t-value="providers_sudo[:1]"/>
|
||||
<t t-set="express_checkout_form_xml_id"
|
||||
t-value="provider_sudo.express_checkout_form_view_id.xml_id"
|
||||
/>
|
||||
<t t-if="express_checkout_form_xml_id">
|
||||
<t t-call="{{express_checkout_form_xml_id}}"/>
|
||||
</t>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,546 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="payment.form" name="Payment Form">
|
||||
<!-- Form customization parameters:
|
||||
- mode: The operation mode of the form: `payment` or `validation`; default: `payment`.
|
||||
- allow_token_selection: Whether tokens can be selected for payment or assignation
|
||||
(through the `assign_token_route` parameter); default: `True`.
|
||||
- allow_token_deletion: Whether tokens can be deleted (archived); default: `False`.
|
||||
- default_token_id: The id of the token that should be pre-selected; default: `None`.
|
||||
- show_tokenize_input_mapping: For each provider, whether the tokenization checkbox is
|
||||
shown; used only in `payment` mode.
|
||||
- display_submit_button: Whether the submit button is displayed; default: `True`.
|
||||
- submit_button_label: The label of the submit button; default: 'Pay'/'Save'.
|
||||
-->
|
||||
<!-- Payment context:
|
||||
- reference_prefix: The custom prefix to compute the full transaction reference.
|
||||
- amount: The amount to pay.
|
||||
- currency: The currency of the payment, as a `res.currency` record.
|
||||
- partner_id: The id of the partner on behalf of whom the payment should be made.
|
||||
- providers_sudo: The compatible providers, as a sudoed `payment.provider` recordset.
|
||||
- payment_methods_sudo: The compatible payment methods, as a sudoed `payment.method`
|
||||
recordset.
|
||||
- tokens_sudo: The available payment tokens, as a sudoed `payment.token` recordset.
|
||||
- transaction_route: The route to call to create the transaction.
|
||||
- assign_token_route: The route to call to assign a new or existing token to a record.
|
||||
- landing_route: The route the user is redirected to after payment.
|
||||
- access_token: The access token used to authenticate the partner.
|
||||
-->
|
||||
<t t-set="mode" t-value="mode or 'payment'"/>
|
||||
<t t-set="allow_token_selection"
|
||||
t-value="True if allow_token_selection is None else allow_token_selection"
|
||||
/>
|
||||
<t t-set="allow_token_deletion" t-value="allow_token_deletion or False"/>
|
||||
<t t-set="selected_token_id"
|
||||
t-value="allow_token_selection and (default_token_id or tokens_sudo[:1].id)"
|
||||
/>
|
||||
<t t-set="selected_method_id"
|
||||
t-value="not selected_token_id
|
||||
and len(payment_methods_sudo) == 1
|
||||
and payment_methods_sudo[:1].id"
|
||||
/>
|
||||
<t t-set="collapse_payment_methods"
|
||||
t-value="tokens_sudo and allow_token_selection and payment_methods_sudo"
|
||||
/>
|
||||
<t t-set="display_submit_button"
|
||||
t-value="True if display_submit_button is None else display_submit_button"
|
||||
/>
|
||||
<t t-set="pay_label">Pay</t> <!-- Allow translating the label. -->
|
||||
<t t-set="save_label">Save</t> <!-- Allow translating the label. -->
|
||||
<t t-set="submit_button_label"
|
||||
t-value="submit_button_label or (pay_label if mode == 'payment' else save_label)"
|
||||
/>
|
||||
<form t-if="payment_methods_sudo or tokens_sudo" id="o_payment_form"
|
||||
class="o_payment_form"
|
||||
t-att-data-mode="mode"
|
||||
t-att-data-reference-prefix="reference_prefix"
|
||||
t-att-data-amount="amount"
|
||||
t-att-data-currency-id="currency and currency.id"
|
||||
t-att-data-partner-id="partner_id"
|
||||
t-att-data-transaction-route="transaction_route"
|
||||
t-att-data-assign-token-route="assign_token_route"
|
||||
t-att-data-landing-route="landing_route"
|
||||
t-att-data-access-token="access_token"
|
||||
>
|
||||
<div id="o_payment_form_options" class="d-flex flex-column gap-3">
|
||||
<!-- === Payment tokens === -->
|
||||
<div t-if="tokens_sudo">
|
||||
<!-- === Header === -->
|
||||
<h4 id="o_payment_tokens_heading">
|
||||
Your payment methods
|
||||
</h4>
|
||||
<!-- === Body === -->
|
||||
<ul class="list-group">
|
||||
<t t-foreach="tokens_sudo" t-as="token_sudo">
|
||||
<li name="o_payment_option"
|
||||
t-att-class="'list-group-item d-flex flex-column gap-2 py-3'
|
||||
+ (' o_outline' if allow_token_selection else '')"
|
||||
>
|
||||
<t t-call="payment.token_form">
|
||||
<t t-set="is_selected"
|
||||
t-value="token_sudo.id == selected_token_id"
|
||||
/>
|
||||
</t>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- === Payment methods === -->
|
||||
<div t-if="payment_methods_sudo"
|
||||
id="o_payment_methods"
|
||||
t-att-class="'collapse' if collapse_payment_methods else ''"
|
||||
>
|
||||
<!-- === Header === -->
|
||||
<p t-attf-class="mb-3 {{collapse_payment_methods and 'h5' or 'h4'}}">
|
||||
<t t-if="not collapse_payment_methods">Payment method</t>
|
||||
<t t-else="">Other payment methods</t>
|
||||
<t t-call="payment.availability_report_button"/>
|
||||
</p>
|
||||
<!-- === Body === -->
|
||||
<ul class="list-group">
|
||||
<t t-foreach="payment_methods_sudo" t-as="pm_sudo">
|
||||
<li name="o_payment_option"
|
||||
class="list-group-item d-flex flex-column gap-2 py-3 o_outline"
|
||||
>
|
||||
<t t-call="payment.method_form">
|
||||
<t t-set="is_selected"
|
||||
t-value="pm_sudo.id == selected_method_id"
|
||||
/>
|
||||
</t>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end flex-column flex-md-row gap-2 my-2">
|
||||
<!-- === Expand payment methods button === -->
|
||||
<button t-if="collapse_payment_methods"
|
||||
name="o_payment_expand_button"
|
||||
type="button"
|
||||
href="#o_payment_methods"
|
||||
class="btn btn-link"
|
||||
data-bs-toggle="collapse"
|
||||
>
|
||||
Choose another method <i class="oi oi-arrow-down"/>
|
||||
</button>
|
||||
<!-- === Submit button === -->
|
||||
<t t-if="display_submit_button" t-call="payment.submit_button"/>
|
||||
</div>
|
||||
<!-- === Availability report === -->
|
||||
<t t-call="payment.availability_report"/>
|
||||
</form>
|
||||
<t t-else="" t-call="payment.no_pms_available_warning"/>
|
||||
</template>
|
||||
|
||||
<template id="payment.token_form" name="Payment Token Form">
|
||||
<!-- Parameters description:
|
||||
- token_sudo: The token to display, as a sudoed `payment.token` recordset.
|
||||
- allow_token_selection: Whether tokens can be selected for payment or assignation (if
|
||||
the `assign_route` parameter is provided); default: `True`.
|
||||
- is_selected: Whether the radio button of the token should be checked.
|
||||
-->
|
||||
<t t-set="provider_sudo" t-value="token_sudo.provider_id"/>
|
||||
<t t-set="is_test" t-value="provider_sudo.state == 'test'"/>
|
||||
<t t-set="is_unpublished" t-value="not provider_sudo.is_published"/>
|
||||
<t t-set="inline_form_xml_id" t-value="provider_sudo.token_inline_form_view_id.xml_id"/>
|
||||
<div class="d-flex gap-3 align-items-start align-items-md-center">
|
||||
<!-- === Delete button === -->
|
||||
<button t-if="allow_token_deletion"
|
||||
name="o_payment_delete_token"
|
||||
t-att-class="'btn btn-link px-2 py-0 lh-lg z-1'
|
||||
+ (' d-none' if mode != 'validation' else '')"
|
||||
t-attf-data-linked-radio="o_payment_token_{{token_sudo.id}}"
|
||||
>
|
||||
<i class="fa fa-trash"
|
||||
title="Delete payment method"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
data-bs-delay="0"
|
||||
/>
|
||||
</button>
|
||||
<div class="row flex-column flex-md-row flex-grow-1 gap-lg-3 align-items-start
|
||||
align-items-md-center"
|
||||
>
|
||||
<div class="col col-lg-5">
|
||||
<div t-att-class="'form-check mb-0'
|
||||
+ (' ps-0' if not allow_token_selection else '')">
|
||||
<!-- === Radio button === -->
|
||||
<input t-attf-id="o_payment_token_{{token_sudo.id}}"
|
||||
name="o_payment_radio"
|
||||
type="radio"
|
||||
t-att-checked="is_selected"
|
||||
t-att-disabled="not allow_token_selection"
|
||||
t-att-class="'form-check-input'
|
||||
+ (' d-none' if not allow_token_selection else '')"
|
||||
data-payment-option-type="token"
|
||||
t-att-data-payment-option-id="token_sudo.id"
|
||||
t-att-data-provider-code="token_sudo.provider_id._get_code()"
|
||||
t-att-data-provider-id="token_sudo.provider_id.id"
|
||||
/>
|
||||
<div class="d-flex align-items-center flex-wrap gap-2">
|
||||
<!-- === Token label === -->
|
||||
<label t-out="token_sudo.payment_method_id.name"
|
||||
class="o_payment_option_label text-break"
|
||||
t-attf-for="o_payment_token_{{token_sudo.id}}"
|
||||
/>
|
||||
<div class="d-flex flex-nowrap gap-2">
|
||||
<!-- === "Unpublished" icon === -->
|
||||
<t t-if="is_unpublished" t-call="payment.form_icon">
|
||||
<t t-set="icon_name" t-value="'eye-slash'"/>
|
||||
<t t-set="color_name" t-value="'danger'"/>
|
||||
<t t-set="title">Unpublished</t>
|
||||
</t>
|
||||
<!-- === "Test mode" icon === -->
|
||||
<t t-if="is_test" t-call="payment.form_icon">
|
||||
<t t-set="icon_name" t-value="'exclamation-triangle'"/>
|
||||
<t t-set="color_name" t-value="'warning'"/>
|
||||
<t t-set="title">Test mode</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- === Token name (payment details) === -->
|
||||
<div class="col">
|
||||
<p t-out="token_sudo.display_name"
|
||||
t-att-class="'mb-0 small fw-bold text-break'
|
||||
+ (' ms-4 ms-md-0' if allow_token_selection else '')"
|
||||
/>
|
||||
</div>
|
||||
<!-- === Provider name (only for desktop and tablet) === -->
|
||||
<t t-set="hide_secured_by" t-value="False"/>
|
||||
<div class="col d-none d-md-block">
|
||||
<p name="o_payment_secured_by_desktop" t-att-class="'mb-0 small text-600'
|
||||
+ (' ms-4 ms-md-0' if allow_token_selection else '')
|
||||
+ (' d-none' if hide_secured_by else '')"
|
||||
>
|
||||
<span><i class="fa fa-lock"/> Secured by</span>
|
||||
<span t-out="dict(provider_sudo._fields['code']._description_selection(
|
||||
provider_sudo.env
|
||||
))[provider_sudo.code]"
|
||||
class="text-break"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- === Payment method logo === -->
|
||||
<div>
|
||||
<t t-call="payment.form_logo" logo_pm_sudo="token_sudo.payment_method_id"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- === Inline form === -->
|
||||
<div t-if="inline_form_xml_id"
|
||||
name="o_payment_inline_form"
|
||||
class="position-relative d-none"
|
||||
>
|
||||
<t t-call="{{inline_form_xml_id}}"/>
|
||||
</div>
|
||||
<!-- === Provider name (only for mobile) === -->
|
||||
<p name="o_payment_secured_by_mobile"
|
||||
t-att-class="'align-self-center d-block d-md-none mb-0 small text-600'
|
||||
+ (' d-none' if hide_secured_by else '')"
|
||||
>
|
||||
<span><i class="fa fa-lock"/> Secured by</span>
|
||||
<span t-out="dict(provider_sudo._fields['code']._description_selection(
|
||||
provider_sudo.env
|
||||
))[provider_sudo.code]"
|
||||
class="text-break"
|
||||
/>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template id="payment.method_form" name="Payment Method Form">
|
||||
<!-- Parameters description:
|
||||
- pm_sudo: The payment method to display, as a sudoed `payment.method` recordset.
|
||||
- is_selected: Whether the radio button of the payment method should be checked.
|
||||
-->
|
||||
<t t-set="provider_sudo"
|
||||
t-value="pm_sudo.provider_ids.filtered(lambda p: p in providers_sudo)[:1]"
|
||||
/>
|
||||
<t t-set="is_test" t-value="provider_sudo.state == 'test'"/>
|
||||
<t t-set="is_unpublished" t-value="not provider_sudo.is_published"/>
|
||||
<t t-set="pms_to_display_sudo" t-value="pm_sudo.brand_ids or pm_sudo"/>
|
||||
<t t-set="inline_form_xml_id" t-value="provider_sudo.inline_form_view_id.xml_id"/>
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-0 p-0"
|
||||
for="o_payment_radio"
|
||||
>
|
||||
<div class="form-check d-flex flex-grow-1 flex-wrap mb-0">
|
||||
<div class="d-flex justify-content-between align-items-center gap-2 flex-wrap w-100">
|
||||
<!-- === Radio button === -->
|
||||
<input t-attf-id="o_payment_method_{{pm_sudo.id}}"
|
||||
name="o_payment_radio"
|
||||
type="radio"
|
||||
t-att-checked="is_selected"
|
||||
class="form-check-input position-absolute mt-0"
|
||||
data-payment-option-type="payment_method"
|
||||
t-att-data-payment-option-id="pm_sudo.id"
|
||||
t-att-data-payment-method-code="pm_sudo.code"
|
||||
t-att-data-provider-id="provider_sudo.id"
|
||||
t-att-data-provider-code="provider_sudo._get_code()"
|
||||
t-att-data-provider-state="provider_sudo.state"
|
||||
/>
|
||||
<div class="d-flex gap-2 flex-grow-1 me-auto">
|
||||
<!-- === Method label === -->
|
||||
<label t-out="pm_sudo.name"
|
||||
class="o_payment_option_label mb-0 text-break"
|
||||
t-attf-for="o_payment_method_{{pm_sudo.id}}"
|
||||
/>
|
||||
<div class="d-flex flex-nowrap gap-2 mt-1">
|
||||
<!-- === "Unpublished" icon === -->
|
||||
<t t-if="is_unpublished" t-call="payment.form_icon">
|
||||
<t t-set="icon_name" t-value="'eye-slash'"/>
|
||||
<t t-set="color_name" t-value="'danger'"/>
|
||||
<t t-set="title">Unpublished</t>
|
||||
</t>
|
||||
<!-- === "Test mode" icon === -->
|
||||
<t t-if="is_test" t-call="payment.form_icon">
|
||||
<t t-set="icon_name" t-value="'exclamation-triangle'"/>
|
||||
<t t-set="color_name" t-value="'warning'"/>
|
||||
<t t-set="title">Test mode</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-1 flex-wrap d-flex">
|
||||
<!-- === Payment method logos === -->
|
||||
<t t-set="pm_index" t-value="0"/>
|
||||
<t t-foreach="pms_to_display_sudo" t-as="pm_to_display_sudo">
|
||||
<t t-if="pm_index < 4" t-call="payment.form_logo">
|
||||
<t t-set="logo_pm_sudo" t-value="pm_to_display_sudo"/>
|
||||
</t>
|
||||
<t t-set="pm_index" t-value="pm_index + 1"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- === Help message === -->
|
||||
<div t-if="not is_html_empty(provider_sudo.pre_msg)"
|
||||
class="w-100 mb-0 ms-4 small text-600"
|
||||
>
|
||||
<t t-out="provider_sudo.pre_msg"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- === Inline form === -->
|
||||
<div name="o_payment_inline_form" class="position-relative d-none">
|
||||
<t t-if="inline_form_xml_id and provider_sudo._should_build_inline_form(
|
||||
is_validation=mode == 'validation'
|
||||
)"
|
||||
t-call="{{inline_form_xml_id}}"
|
||||
>
|
||||
<t t-set="provider_id" t-value="provider_sudo.id"/>
|
||||
</t>
|
||||
<div class="d-flex flex-column flex-sm-row align-md-items-center justify-content-between
|
||||
gap-3 mt-2"
|
||||
>
|
||||
<!-- === Tokenization checkbox === -->
|
||||
<div t-if="mode == 'payment'
|
||||
and pm_sudo.support_tokenization
|
||||
and show_tokenize_input_mapping[provider_sudo.id]"
|
||||
name="o_payment_tokenize_container"
|
||||
class="o-checkbox form-check m-0"
|
||||
>
|
||||
<label>
|
||||
<input name="o_payment_tokenize_checkbox"
|
||||
type="checkbox"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<small class="text-600">Save my payment details</small>
|
||||
</label>
|
||||
</div>
|
||||
<!-- === Provider name === -->
|
||||
<t t-set="hide_secured_by" t-value="False"/>
|
||||
<p name="o_payment_secured_by"
|
||||
t-att-class="'align-self-end mb-0 mx-auto me-sm-0 small text-600'
|
||||
+ (' d-none' if hide_secured_by else '')"
|
||||
>
|
||||
<span><i class="fa fa-lock"/> Secured by</span>
|
||||
<span t-out="dict(provider_sudo._fields['code']._description_selection(
|
||||
provider_sudo.env
|
||||
))[provider_sudo.code]"
|
||||
class="text-break"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="payment.form_icon" name="Form Icon">
|
||||
<!-- Parameters description:
|
||||
- icon_name: The name of the FontAwesome icon.
|
||||
- color_name: The class name of the color (`warning`, `danger`...).
|
||||
- title: The title to display on hover.
|
||||
-->
|
||||
<i t-attf-class="fa fa-{{icon_name}} text-{{color_name}} position-relative z-1"
|
||||
t-att-title="title"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
data-bs-delay="0"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template id="payment.form_logo" name="Form Logo">
|
||||
<!-- Parameters description:
|
||||
- logo_pm_sudo: The payment method whose logo to display, as a sudoed `payment.method`
|
||||
record.
|
||||
-->
|
||||
<span t-field="logo_pm_sudo.image_payment_form"
|
||||
t-options="{'widget': 'image', 'alt-field': 'name'}"
|
||||
class="position-relative d-block rounded overflow-hidden z-1 shadow-sm"
|
||||
t-att-title="logo_pm_sudo.name"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
data-bs-delay="0"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template id="payment.submit_button" name="Submit Button">
|
||||
<!-- Parameters description:
|
||||
- label: The label of the submit button.
|
||||
-->
|
||||
<button name="o_payment_submit_button"
|
||||
type="submit"
|
||||
t-out="submit_button_label"
|
||||
class="btn btn-primary w-100 w-md-auto ms-auto px-5"
|
||||
disabled="true"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template id="payment.no_pms_available_warning">
|
||||
<div class="alert alert-warning mt-2">
|
||||
<div>
|
||||
<strong>No payment method available</strong>
|
||||
</div>
|
||||
<div t-if="request.env.is_system()" class="mt-2">
|
||||
<p t-if="providers_sudo">
|
||||
None is configured for:
|
||||
<t t-out="request.env.company.country_id.name"/>,
|
||||
<t t-out="request.env.company.currency_id.name"/>.
|
||||
</p>
|
||||
<p t-else="">
|
||||
No payment providers are configured.
|
||||
</p>
|
||||
<t
|
||||
t-set="onboarding_provider"
|
||||
t-value="request.env['res.config.settings'].sudo().new({}).onboarding_payment_module"
|
||||
/>
|
||||
<a
|
||||
t-if="onboarding_provider and not providers_sudo"
|
||||
name="start_payment_onboarding"
|
||||
href="/odoo/action-payment.action_start_payment_onboarding"
|
||||
role="button"
|
||||
class="btn btn-primary me-2"
|
||||
>
|
||||
ACTIVATE <t t-out="onboarding_provider.upper()"/>
|
||||
</a>
|
||||
<a
|
||||
t-if="availability_report"
|
||||
role="button"
|
||||
class="btn-link alert-warning me-2"
|
||||
data-bs-toggle="collapse"
|
||||
href="#payment_availability_report"
|
||||
>
|
||||
<strong><i class="fa fa-file-text"/> Show availability report</strong>
|
||||
</a>
|
||||
<a
|
||||
t-if="not providers_sudo"
|
||||
role="button"
|
||||
type="action"
|
||||
class="btn-link alert-warning me-2"
|
||||
href="/odoo/action-payment.action_payment_provider"
|
||||
>
|
||||
<strong><i class="oi oi-arrow-right"/> Payment Providers</strong>
|
||||
</a>
|
||||
<a
|
||||
t-else=""
|
||||
role="button"
|
||||
type="action"
|
||||
class="btn-link alert-warning"
|
||||
href="/odoo/action-payment.action_payment_method"
|
||||
>
|
||||
<strong><i class="oi oi-arrow-right"/> Payment Methods</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div t-else="" class="mt-2">
|
||||
If you believe that it is an error, please contact the website administrator.
|
||||
</div>
|
||||
</div>
|
||||
<!-- === Availability report === -->
|
||||
<t t-call="payment.availability_report"/>
|
||||
</template>
|
||||
|
||||
<template id="payment.availability_report_button">
|
||||
<a
|
||||
t-if="request.env.user._is_system() and availability_report"
|
||||
role="button"
|
||||
data-bs-toggle="collapse"
|
||||
href="#payment_availability_report"
|
||||
aria-expanded="false"
|
||||
aria-controls="payment_availability_report"
|
||||
>
|
||||
<i class="fa fa-bug"/>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<template id="payment.availability_report">
|
||||
<div
|
||||
t-if="request.env.user._is_system() and availability_report"
|
||||
id="payment_availability_report"
|
||||
class="collapse"
|
||||
>
|
||||
<h5> Availability report </h5>
|
||||
<h6 class="mt-3"> Payment providers </h6>
|
||||
<t t-call="payment.availability_report_records">
|
||||
<t t-set="records" t-value="availability_report.get('providers')"/>
|
||||
</t>
|
||||
<h6 class="mt-3"> Payment methods </h6>
|
||||
<t t-call="payment.availability_report_records">
|
||||
<t t-set="records" t-value="availability_report.get('payment_methods')"/>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="availability_report_records">
|
||||
<!-- Parameters description:
|
||||
- records: The records to list in the availability report, as a dict with the structure
|
||||
{record: {'available': bool, 'reason': str, supported_providers: list}}.
|
||||
-->
|
||||
<ul class="list-group">
|
||||
<t t-foreach="records" t-as="r">
|
||||
<t t-set="available" t-value="records[r]['available']"/>
|
||||
<li class="list-group-item ps-0">
|
||||
<div class="d-flex gap-2">
|
||||
<div class="ms-2">
|
||||
<i
|
||||
t-attf-class="fa fa-fw fa-{{'check-circle' if available else 'times-circle'}}"
|
||||
t-attf-style="color: {{'green' if available else 'red'}};"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="lead mb-0">
|
||||
<span class="fw-normal"><t t-out="r.name"/></span>
|
||||
<span class="text-muted">(ID: <t t-out="r.id"/>)</span>
|
||||
</p>
|
||||
<t t-if="not available">
|
||||
<p class="mb-0 fw-light">
|
||||
Reason: <t t-out="records[r]['reason']"/>
|
||||
</p>
|
||||
</t>
|
||||
<t t-if="r._name == 'payment.method' and 'supported_providers' in records[r]">
|
||||
<p class="mb-0 fw-light">
|
||||
Supported providers:
|
||||
<t t-foreach="records[r]['supported_providers']" t-as="p">
|
||||
<span t-attf-class="text-{{'success' if p[1] else 'danger'}}">
|
||||
<t t-out="p[0].name"/>
|
||||
</span>
|
||||
<t t-if="records[r]['supported_providers'][-1] != p">,</t>
|
||||
</t>
|
||||
</p>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="payment_icon_form" model="ir.ui.view">
|
||||
<field name="name">payment.icon.form</field>
|
||||
<field name="model">payment.icon</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment Icon">
|
||||
<sheet>
|
||||
<field name="image" widget="image" class="oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<h1><field name="name" placeholder="Name"/></h1>
|
||||
</div>
|
||||
<notebook>
|
||||
<page string="Providers list" name="providers">
|
||||
<field nolabel="1" name="provider_ids"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="payment_icon_tree" model="ir.ui.view">
|
||||
<field name="name">payment.icon.tree</field>
|
||||
<field name="model">payment.icon</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_payment_icon" model="ir.actions.act_window">
|
||||
<field name="name">Payment Icons</field>
|
||||
<field name="res_model">payment.icon</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a payment icon
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="payment_method_form" model="ir.ui.view">
|
||||
<field name="name">payment.method.form</field>
|
||||
<field name="model">payment.method</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment Method">
|
||||
<sheet>
|
||||
<field name="is_primary" invisible="True"/>
|
||||
<field name="image" widget="image" class="oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<h1><field name="name" placeholder="Name"/></h1>
|
||||
</div>
|
||||
<group>
|
||||
<field name="code" readonly="id" groups="base.group_no_one"/>
|
||||
<field name="primary_payment_method_id" invisible="is_primary"/>
|
||||
<field name="active"/>
|
||||
<label for="supported_country_ids"/>
|
||||
<div>
|
||||
<field name="supported_country_ids"
|
||||
class="oe_inline"
|
||||
widget="many2many_tags"
|
||||
readonly="1"
|
||||
/>
|
||||
<span class="oe_inline text-muted" invisible="supported_country_ids">
|
||||
All countries are supported.
|
||||
</span>
|
||||
</div>
|
||||
<label for="supported_currency_ids"/>
|
||||
<div>
|
||||
<field name="supported_currency_ids"
|
||||
class="oe_inline"
|
||||
widget="many2many_tags"
|
||||
readonly="1"
|
||||
/>
|
||||
<span class="oe_inline text-muted" invisible="supported_currency_ids">
|
||||
All currencies are supported.
|
||||
</span>
|
||||
</div>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Providers" name="providers">
|
||||
<field name="provider_ids" readonly="1">
|
||||
<list decoration-muted="state == 'disabled'" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Brands" name="brands" invisible="not is_primary">
|
||||
<field name="brand_ids"/>
|
||||
</page>
|
||||
<page string="Configuration"
|
||||
name="configuration"
|
||||
groups="base.group_no_one"
|
||||
>
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<i class="fa fa-exclamation-triangle"/> These properties are set to
|
||||
match the behavior of providers and that of their integration with
|
||||
Odoo regarding this payment method. Any change may result in errors
|
||||
and should be tested on a test database first.
|
||||
</div>
|
||||
<group>
|
||||
<field name="support_tokenization"/>
|
||||
<field name="support_manual_capture"/>
|
||||
<field name="support_express_checkout"/>
|
||||
<field name="support_refund" />
|
||||
<field name="supported_country_ids"
|
||||
widget="many2many_tags"
|
||||
placeholder="Select countries. Leave empty to allow any."
|
||||
/>
|
||||
<field name="supported_currency_ids"
|
||||
widget="many2many_tags"
|
||||
placeholder="Select currencies. Leave empty to allow any."
|
||||
/>
|
||||
<field name="provider_ids"
|
||||
string="Supported by"
|
||||
widget="many2many_tags"
|
||||
/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="payment_method_tree" model="ir.ui.view">
|
||||
<field name="name">payment.method.list</field>
|
||||
<field name="model">payment.method</field>
|
||||
<field name="arch" type="xml">
|
||||
<list multi_edit="True" decoration-muted="not active">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="active" widget="boolean_toggle"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="payment_method_kanban" model="ir.ui.view">
|
||||
<field name="name">payment.method.kanban</field>
|
||||
<field name="model">payment.method</field>
|
||||
<field name="priority">1</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="card" class="flex-row">
|
||||
<field name="name" class="fw-bolder"/>
|
||||
<field name="image" widget="image" class="ms-auto"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="payment_method_search" model="ir.ui.view">
|
||||
<field name="name">payment.method.search</field>
|
||||
<field name="model">payment.method</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name" string="Name"/>
|
||||
<filter name="available_pms"
|
||||
string="Available methods"
|
||||
domain="[('provider_ids.state', '!=', 'disabled')]"
|
||||
/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_payment_method" model="ir.actions.act_window">
|
||||
<field name="name">Payment Methods</field>
|
||||
<field name="res_model">payment.method</field>
|
||||
<field name="path">payment-methods</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="domain">[('is_primary', '=', True)]</field>
|
||||
<field name="context">{'active_test': False, 'search_default_available_pms': 1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No payment methods found for your payment providers.
|
||||
</p>
|
||||
<p>
|
||||
<a type="action" class="text-primary" name="%(payment.action_payment_provider)d">
|
||||
<i class="oi oi-arrow-right me-1"/> Configure a payment provider
|
||||
</a>
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,199 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Integration of a conditional "Manage payment methods" link in /my -->
|
||||
<template id="pay_meth_link" inherit_id="portal.portal_layout">
|
||||
<xpath expr="//div[hasclass('o_portal_my_details')]" position="inside">
|
||||
<t t-set="partner" t-value="request.env.user.partner_id"/>
|
||||
<t t-set="providers_allowing_tokenization"
|
||||
t-value="request.env['payment.provider'].sudo()._get_compatible_providers(request.env.company.id, partner.id, 0., force_tokenization=True, is_validation=True)"/>
|
||||
<t t-set="existing_tokens" t-value="partner.payment_token_ids + partner.commercial_partner_id.sudo().payment_token_ids"/>
|
||||
<!-- Only show the link if a token can be created or if one already exists -->
|
||||
<div t-if="providers_allowing_tokenization or existing_tokens"
|
||||
class='manage_payment_method mt16'>
|
||||
<a href="/my/payment_method">Manage payment methods</a>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Display of /payment/pay -->
|
||||
<template id="pay">
|
||||
<!-- Variables description:
|
||||
- 'partner_is_different' - Whether the partner logged in is the one making the payment
|
||||
-->
|
||||
<t t-call="portal.frontend_layout">
|
||||
<t t-set="page_title" t-value="'Payment'"/>
|
||||
<t t-set="additional_title"><t t-esc="page_title"/></t>
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<!-- Portal breadcrumb -->
|
||||
<t t-call="payment.portal_breadcrumb"/>
|
||||
<!-- Payment page -->
|
||||
<div class="row">
|
||||
<div class="col-lg-7">
|
||||
<div t-if="not amount" class="alert alert-info">
|
||||
There is nothing to pay.
|
||||
</div>
|
||||
<div t-elif="not currency" class="alert alert-warning">
|
||||
<strong>Warning</strong> The currency is missing or incorrect.
|
||||
</div>
|
||||
<div t-elif="not partner_id" class="alert alert-warning">
|
||||
<strong>Warning</strong> You must be logged in to pay.
|
||||
</div>
|
||||
<div t-elif="not providers and not tokens" 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 t-else="">
|
||||
<div t-if="partner_is_different" class="alert alert-warning">
|
||||
<strong>Warning</strong> Make sure your are logged in as the right partner before making this payment.
|
||||
</div>
|
||||
<t t-if="reference_prefix">
|
||||
<b>Reference:</b>
|
||||
<t t-esc="reference_prefix"/><br/>
|
||||
</t>
|
||||
<b>Amount:</b>
|
||||
<t t-esc="amount"
|
||||
t-options="{'widget': 'monetary', 'display_currency': currency}"/>
|
||||
<t t-call="payment.checkout"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Display of /my/payment_methods -->
|
||||
<template id="payment_methods" name="Payment Methods">
|
||||
<t t-call="portal.frontend_layout">
|
||||
<t t-set="page_title" t-value="'Payment Methods'"/>
|
||||
<t t-set="additional_title"><t t-esc="page_title"/></t>
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<!-- Portal breadcrumb -->
|
||||
<t t-call="payment.portal_breadcrumb"/>
|
||||
<!-- Manage page -->
|
||||
<div class="row">
|
||||
<div class="col-lg-7">
|
||||
<t t-if="providers or tokens" t-call="payment.manage"/>
|
||||
<div t-else="" class="alert alert-warning">
|
||||
<p><strong>No suitable payment provider could be found.</strong></p>
|
||||
<p>If you believe that it is an error, please contact the website administrator.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Display of /payment/status -->
|
||||
<template id="payment_status" name="Payment Status">
|
||||
<t t-call="portal.frontend_layout">
|
||||
<t t-set="page_title" t-value="'Payment Status'"/>
|
||||
<t t-set="additional_title"><t t-esc="page_title"/></t>
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<!-- Portal breadcrumb -->
|
||||
<t t-call="payment.portal_breadcrumb"/>
|
||||
<!-- Status page -->
|
||||
<div name="o_payment_status">
|
||||
<div name="o_payment_status_content"
|
||||
class="col-sm-6 offset-sm-3">
|
||||
<!-- The content is generated in JavaScript -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Display of /payment/confirmation -->
|
||||
<template id="confirm">
|
||||
<!-- Variables description:
|
||||
- 'tx' - The transaction to display
|
||||
-->
|
||||
<t t-call="portal.frontend_layout">
|
||||
<t t-set="page_title" t-value="'Payment Confirmation'"/>
|
||||
<t t-set="additional_title"><t t-esc="page_title"/></t>
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<!-- Portal breadcrumb -->
|
||||
<t t-call="payment.portal_breadcrumb"/>
|
||||
<!-- Confirmation page -->
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div>
|
||||
<t t-call="payment.transaction_status"/>
|
||||
<div class="mb-3 row">
|
||||
<label for="form_partner_name" class="col-md-3 col-form-label">
|
||||
From
|
||||
</label>
|
||||
<span name="form_partner_name"
|
||||
class="col-md-9 col-form-label"
|
||||
t-esc="tx.partner_name"/>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="mb-3 row">
|
||||
<label for="form_reference" class="col-md-3 col-form-label">
|
||||
Reference
|
||||
</label>
|
||||
<span name="form_reference"
|
||||
class="col-md-9 col-form-label"
|
||||
t-esc="tx.reference"/>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="mb-3 row">
|
||||
<label for="form_amount" class="col-md-3 col-form-label">
|
||||
Amount
|
||||
</label>
|
||||
<span name="form_amount"
|
||||
class="col-md-9 col-form-label"
|
||||
t-esc="tx.amount"
|
||||
t-options="{'widget': 'monetary', 'display_currency': tx.currency_id}"/>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-md-5 text-muted">
|
||||
Processed by <t t-esc="tx.provider_id.sudo().name"/>
|
||||
</div>
|
||||
<div class="col-md-4 offset-md-3 mt-2 ps-0">
|
||||
<a role="button"
|
||||
t-attf-class="btn btn-primary float-end"
|
||||
href="/my/home">
|
||||
<i class="fa fa-arrow-circle-right"/> Back to My Account
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Breadcrumb for the portal -->
|
||||
<template id="portal_breadcrumb">
|
||||
<!-- Variables description:
|
||||
- 'page_title' - The title of the breadcrumb item
|
||||
-->
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<ol class="breadcrumb mt8">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/my/home">
|
||||
<i class="fa fa-home"
|
||||
role="img"
|
||||
title="Home"
|
||||
aria-label="Home"/>
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item"><t t-esc="page_title"/></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -6,112 +6,109 @@
|
|||
<field name="model">payment.provider</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment provider">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<!-- Prevent considering the field readonly and thus allow writing on it. -->
|
||||
<field name="is_published" invisible="1"/>
|
||||
<field name="main_currency_id" invisible="1"/>
|
||||
<field name="support_fees" invisible="1"/>
|
||||
<field name="support_manual_capture" invisible="1"/>
|
||||
<field name="support_tokenization" invisible="1"/>
|
||||
<field name="support_express_checkout" invisible="1"/>
|
||||
<field name="module_id" invisible="1"/>
|
||||
<field name="module_state" invisible="1"/>
|
||||
<field name="module_to_buy" invisible="1"/>
|
||||
<field name="show_credentials_page" invisible="1"/>
|
||||
<field name="show_allow_express_checkout" invisible="1"/>
|
||||
<field name="show_allow_tokenization" invisible="1"/>
|
||||
<field name="show_payment_icon_ids" invisible="1"/>
|
||||
<field name="show_pre_msg" invisible="1"/>
|
||||
<field name="show_pending_msg" invisible="1"/>
|
||||
<field name="show_auth_msg" invisible="1"/>
|
||||
<field name="show_done_msg" invisible="1"/>
|
||||
<field name="show_cancel_msg" invisible="1"/>
|
||||
<field name="code" invisible="1"/>
|
||||
<sheet>
|
||||
<!-- === Stat Buttons === -->
|
||||
<div class="oe_button_box" name="button_box"
|
||||
attrs="{'invisible': [('module_state', '!=', 'installed')]}">
|
||||
invisible="module_state != 'installed'">
|
||||
<button name="action_toggle_is_published"
|
||||
attrs="{'invisible': [('is_published', '=', False)]}"
|
||||
invisible="not is_published"
|
||||
class="oe_stat_button"
|
||||
type="object"
|
||||
icon="fa-globe">
|
||||
<div class="o_stat_info o_field_widget">
|
||||
<span class="text-success">Published</span>
|
||||
<span class="o_stat_text text-success">Published</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="action_toggle_is_published"
|
||||
attrs="{'invisible': [('is_published', '=', True)]}"
|
||||
invisible="is_published"
|
||||
class="oe_stat_button"
|
||||
type="object"
|
||||
icon="fa-eye-slash">
|
||||
<div class="o_stat_info o_field_widget">
|
||||
<span class="text-danger">Unpublished</span>
|
||||
<span class="o_stat_text text-danger">Unpublished</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<field name="image_128" widget="image" class="oe_avatar"
|
||||
attrs="{'readonly': [('module_state', '!=', 'installed')]}"/>
|
||||
<widget name="web_ribbon" title="Disabled" bg_color="bg-danger" attrs="{'invisible': ['|', ('module_state', '!=', 'installed'), ('state', '!=', 'disabled')]}"/>
|
||||
<widget name="web_ribbon" title="Test Mode" bg_color="bg-warning" attrs="{'invisible': ['|', ('module_state', '!=', 'installed'), ('state', '!=', 'test')]}"/>
|
||||
readonly="module_state != 'installed'"/>
|
||||
<widget name="web_ribbon" title="Disabled" bg_color="text-bg-danger" invisible="module_state != 'installed' or state != 'disabled'"/>
|
||||
<widget name="web_ribbon" title="Test Mode" bg_color="text-bg-warning" invisible="module_state != 'installed' or state != 'test'"/>
|
||||
<div class="oe_title">
|
||||
<h1><field name="name" placeholder="Name"/></h1>
|
||||
<div attrs="{'invisible': ['|', ('module_state', '=', 'installed'), ('module_id', '=', False)]}">
|
||||
<a attrs="{'invisible': [('module_to_buy', '=', False)]}" href="https://odoo.com/pricing?utm_source=db&utm_medium=module" target="_blank" class="btn btn-info" role="button">Upgrade</a>
|
||||
<button attrs="{'invisible': [('module_to_buy', '=', True)]}" type="object" class="btn btn-primary" name="button_immediate_install" string="Install"/>
|
||||
<div invisible="module_state == 'installed' or not module_id">
|
||||
<a invisible="not module_to_buy" href="https://odoo.com/pricing?utm_source=db&utm_medium=module" target="_blank" class="btn btn-info" role="button">Upgrade</a>
|
||||
<button invisible="module_to_buy" type="object" class="btn btn-primary" name="button_immediate_install" string="Install"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="provider_creation_warning" attrs="{'invisible': [('id', '!=', False)]}" class="alert alert-warning" role="alert">
|
||||
<div id="provider_creation_warning" invisible="id" class="alert alert-warning" role="alert">
|
||||
<strong>Warning</strong> Creating a payment provider from the <em>CREATE</em> button is not supported.
|
||||
Please use the <em>Duplicate</em> action instead.
|
||||
</div>
|
||||
<group>
|
||||
<group name="payment_state" attrs="{'invisible': [('module_state', 'not in', ('installed', False))]}">
|
||||
<field name="code" groups="base.group_no_one" attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
<group name="payment_state" invisible="module_state not in ('installed', False)">
|
||||
<field name="code" groups="base.group_no_one" readonly="id"/>
|
||||
<field name="state" widget="radio"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options='{"no_open":True}'/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook attrs="{'invisible': ['&', ('module_id', '!=', False), ('module_state', '!=', 'installed')]}">
|
||||
<page string="Credentials" name="credentials" attrs="{'invisible': ['|', ('code', '=', 'none'), ('show_credentials_page', '=', False)]}">
|
||||
<notebook invisible="module_id and module_state != 'installed'">
|
||||
<page string="Credentials" name="credentials" invisible="code == 'none'">
|
||||
<group name="provider_credentials"/>
|
||||
</page>
|
||||
<page string="Configuration" name="configuration">
|
||||
<group name="provider_config">
|
||||
<group string="Payment Form" name="payment_form">
|
||||
<field name="display_as" placeholder="If not defined, the provider name will be used."/>
|
||||
<field name="payment_icon_ids" attrs="{'invisible': [('show_payment_icon_ids', '=', False)]}" widget="many2many_tags"/>
|
||||
<field name="allow_tokenization" attrs="{'invisible': ['|', ('support_tokenization', '=', False), ('show_allow_tokenization', '=', False)]}"/>
|
||||
<field name="capture_manually" attrs="{'invisible': [('support_manual_capture', '=', False)]}"/>
|
||||
<field name="allow_express_checkout" attrs="{'invisible': ['|', ('support_express_checkout', '=', False), ('show_allow_express_checkout', '=', False)]}"/>
|
||||
<field name="payment_method_ids"
|
||||
string="Payment Methods"
|
||||
domain="[('is_primary', '=', True)]"
|
||||
readonly="True"
|
||||
invisible="state == 'disabled'"
|
||||
widget="many2many_tags"
|
||||
/>
|
||||
<div colspan="2">
|
||||
<a type="object"
|
||||
name="action_view_payment_methods"
|
||||
class="btn btn-link"
|
||||
role="button"
|
||||
invisible="state == 'disabled'"
|
||||
>
|
||||
<i class="oi oi-fw o_button_icon oi-arrow-right"/>
|
||||
Enable Payment Methods
|
||||
</a>
|
||||
</div>
|
||||
<field name="allow_tokenization" invisible="not support_tokenization"/>
|
||||
<field name="capture_manually" invisible="not support_manual_capture"/>
|
||||
<field name="allow_express_checkout" invisible="not support_express_checkout"/>
|
||||
</group>
|
||||
<group string="Availability" name="availability">
|
||||
<field name="maximum_amount"/>
|
||||
<label for="available_currency_ids"/>
|
||||
<!-- Use `o_row` to allow placing a button next to the field in overrides. -->
|
||||
<div name="available_currencies" class="o_row">
|
||||
<field name="available_currency_ids"
|
||||
widget="many2many_tags"
|
||||
placeholder="Select currencies. Leave empty not to restrict any."
|
||||
options="{'no_create': True}"/>
|
||||
</div>
|
||||
<field name="available_country_ids"
|
||||
widget="many2many_tags"
|
||||
placeholder="Select countries. Leave empty to make available everywhere."
|
||||
options="{'no_open': True, 'no_create': True}"/>
|
||||
options="{'no_create': True}"/>
|
||||
</group>
|
||||
<group string="Payment Followup" name="payment_followup" invisible="1"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Fees" name="fees" attrs="{'invisible': [('support_fees', '=', False)]}">
|
||||
<group name="payment_fees">
|
||||
<field name="fees_active"/>
|
||||
<field name="fees_dom_fixed" attrs="{'invisible': [('fees_active', '=', False)]}"/>
|
||||
<field name="fees_dom_var" attrs="{'invisible': [('fees_active', '=', False)]}"/>
|
||||
<field name="fees_int_fixed" attrs="{'invisible': [('fees_active', '=', False)]}"/>
|
||||
<field name="fees_int_var" attrs="{'invisible': [('fees_active', '=', False)]}"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Messages"
|
||||
name="messages"
|
||||
attrs="{'invisible': [('module_id', '=', True), ('module_state', '!=', 'installed')]}">
|
||||
invisible="module_id and module_state != 'installed'">
|
||||
<group>
|
||||
<field name="pre_msg" attrs="{'invisible': [('show_pre_msg', '=', False)]}"/>
|
||||
<field name="pending_msg" attrs="{'invisible': [('show_pending_msg', '=', False)]}"/>
|
||||
<field name="auth_msg" attrs="{'invisible': ['|', ('support_manual_capture', '=', False), ('show_auth_msg', '=', False)]}"/>
|
||||
<field name="done_msg" attrs="{'invisible': [('show_done_msg', '=', False)]}"/>
|
||||
<field name="cancel_msg" attrs="{'invisible': [('show_cancel_msg', '=', False)]}"/>
|
||||
<field name="pre_msg"/>
|
||||
<field name="pending_msg"/>
|
||||
<field name="auth_msg" invisible="not support_manual_capture"/>
|
||||
<field name="done_msg"/>
|
||||
<field name="cancel_msg"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
|
@ -124,14 +121,14 @@
|
|||
<field name="name">payment.provider.list</field>
|
||||
<field name="model">payment.provider</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Payment Providers" create="false">
|
||||
<list string="Payment Providers" create="false">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="code" groups="base.group_no_one"/>
|
||||
<field name="state"/>
|
||||
<field name="available_country_ids" widget="many2many_tags" optional="hide"/>
|
||||
<field name="company_id" groups="base.group_multi_company" optional="show"/>
|
||||
</tree>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -139,57 +136,53 @@
|
|||
<field name="name">payment.provider.kanban</field>
|
||||
<field name="model">payment.provider</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban create="false" quick_create="false" class="o_kanban_dashboard">
|
||||
<field name="id"/>
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
<kanban create="false" quick_create="false">
|
||||
<field name="is_published"/>
|
||||
<field name="code"/>
|
||||
<field name="module_id"/>
|
||||
<field name="module_state"/>
|
||||
<field name="module_to_buy"/>
|
||||
<field name="color"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<t t-name="card" class="flex-row">
|
||||
<t t-set="installed" t-value="!record.module_id.value || (record.module_id.value && record.module_state.raw_value === 'installed')"/>
|
||||
<t t-set="to_buy" t-value="record.module_to_buy.raw_value === true"/>
|
||||
<t t-set="is_disabled" t-value="record.state.raw_value=='disabled'"/>
|
||||
<t t-set="is_published" t-value="record.is_published.raw_value === true"/>
|
||||
<t t-set="to_upgrade" t-value="!installed and to_buy"/>
|
||||
<div t-attf-class="oe_kanban_global_click" class="d-flex p-2">
|
||||
<div class="o_payment_provider_desc d-flex gap-2">
|
||||
<img type="open"
|
||||
t-att-src="kanban_image('payment.provider', 'image_128', record.id.raw_value)"
|
||||
class="mb-0 o_image_64_max"
|
||||
alt="provider"/>
|
||||
<div class="d-flex flex-column justify-content-between w-100">
|
||||
<div class="o_payment_kanban_info">
|
||||
<h4 class="mb-0"><t t-esc="record.name.value"/></h4>
|
||||
<t t-if="installed">
|
||||
<field name="state"
|
||||
widget="label_selection"
|
||||
options="{'classes': {'enabled': 'success', 'test': 'warning', 'disabled' : 'light'}}"/>
|
||||
<t t-if="!is_disabled">
|
||||
<span t-if="is_published and installed"
|
||||
class="badge text-bg-success ms-1">
|
||||
Published
|
||||
</span>
|
||||
<span t-if="!is_published and installed"
|
||||
class="badge text-bg-info ms-1">
|
||||
Unpublished
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
<span t-if="to_upgrade" class="badge text-bg-primary ms-1">Enterprise</span>
|
||||
</div>
|
||||
<div class="o_payment_kanban_button text-end">
|
||||
<button t-if="!installed and !selection_mode and !to_buy" type="object" class="btn btn-sm btn-primary float-end" name="button_immediate_install">Install</button>
|
||||
<button t-if="installed and is_disabled and !selection_mode" type="edit" class="btn btn-sm btn-secondary float-end">Activate</button>
|
||||
<button t-if="!installed and to_buy" href="https://odoo.com/pricing?utm_source=db&utm_medium=module" target="_blank" class="btn btn-sm btn-primary float-end">Upgrade</button>
|
||||
</div>
|
||||
</div>
|
||||
<aside>
|
||||
<field type="open"
|
||||
name="image_128" widget="image"
|
||||
class="mb-0 o_image_64_max"
|
||||
alt="provider"/>
|
||||
</aside>
|
||||
<main class="ms-2">
|
||||
<field name="name" class="mb-0 fw-bold fs-4"/>
|
||||
<field name="company_id" groups="base.group_multi_company" class="fs-6 text-muted mb-1"/>
|
||||
<div class="d-flex">
|
||||
<t t-if="installed">
|
||||
<field name="state"
|
||||
widget="label_selection"
|
||||
options="{'classes': {'enabled': 'success', 'test': 'warning', 'disabled' : 'light'}}"/>
|
||||
<t t-if="!is_disabled">
|
||||
<div>
|
||||
<span t-if="is_published"
|
||||
class="badge text-bg-success ms-1">
|
||||
Published
|
||||
</span>
|
||||
<span t-else=""
|
||||
class="badge text-bg-info ms-1">
|
||||
Unpublished
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<span t-if="to_upgrade" class="badge text-bg-primary">Enterprise</span>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<button t-if="!installed and !selection_mode and !to_buy" type="object" class="btn btn-sm btn-primary ms-auto" name="button_immediate_install">Install</button>
|
||||
<button t-if="installed and is_disabled and !selection_mode" type="open" class="btn btn-sm btn-secondary ms-auto">Activate</button>
|
||||
<button t-if="!installed and to_buy" href="https://odoo.com/pricing?utm_source=db&utm_medium=module" target="_blank" class="btn btn-sm btn-primary ms-auto">Upgrade</button>
|
||||
</footer>
|
||||
</main>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
|
|
@ -202,9 +195,17 @@
|
|||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name" string="provider" filter_domain="[('name', 'ilike', self)]"/>
|
||||
<field name="code"/>
|
||||
<field name="payment_method_ids"
|
||||
string="payment method"
|
||||
context="{'active_test': False}"
|
||||
filter_domain="[
|
||||
'|',
|
||||
('payment_method_ids.name', 'ilike', self),
|
||||
('payment_method_ids.code', 'ilike', self),
|
||||
]"
|
||||
/>
|
||||
<filter name="provider_installed" string="Installed" domain="[('module_state', '=', 'installed')]"/>
|
||||
<group expand="0" string="Group By">
|
||||
<group>
|
||||
<filter string="Provider" name="code" context="{'group_by': 'code'}"/>
|
||||
<filter string="State" name="state" context="{'group_by': 'state'}"/>
|
||||
<filter string="Company" name="company" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
|
||||
|
|
@ -216,11 +217,17 @@
|
|||
<record id="action_payment_provider" model="ir.actions.act_window">
|
||||
<field name="name">Payment Providers</field>
|
||||
<field name="res_model">payment.provider</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="path">payment-providers</field>
|
||||
<field name="view_mode">kanban,list,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new payment provider
|
||||
No providers available
|
||||
</p>
|
||||
<p class="fw-bold">To add a provider to the current company:</p>
|
||||
<ol class="text-start d-inline-block">
|
||||
<li>Toggle the main company in the company switcher.</li>
|
||||
<li>Install the provider you want to add.</li>
|
||||
</ol>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,460 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Checkout form -->
|
||||
<template id="checkout" name="Payment Checkout">
|
||||
<!-- Variables description:
|
||||
- 'providers' - The payment providers compatible with the current transaction
|
||||
- 'tokens' - The payment tokens of the current partner and payment providers
|
||||
- 'default_token_id' - The id of the token that should be pre-selected. Optional
|
||||
- 'fees_by_provider' - The dict of transaction fees for each provider. Optional
|
||||
- 'show_tokenize_input' - Whether the option to save the payment method is shown
|
||||
- 'reference_prefix' - The custom prefix to compute the full transaction reference
|
||||
- 'amount' - The amount to pay. Optional (sale_subscription)
|
||||
- 'currency' - The currency of the transaction, as a `res.currency` record
|
||||
- 'partner_id' - The id of the partner on behalf of whom the payment should be made
|
||||
- 'access_token' - The access token used to authenticate the partner.
|
||||
- 'transaction_route' - The route used to create a transaction when the user clicks Pay
|
||||
- 'landing_route' - The route the user is redirected to after the transaction
|
||||
- 'footer_template_id' - The template id for the submit button. Optional
|
||||
-->
|
||||
<form name="o_payment_checkout"
|
||||
class="o_payment_form mt-3 clearfix"
|
||||
t-att-data-reference-prefix="reference_prefix"
|
||||
t-att-data-amount="amount"
|
||||
t-att-data-currency-id="currency and currency.id"
|
||||
t-att-data-partner-id="partner_id"
|
||||
t-att-data-access-token="access_token"
|
||||
t-att-data-transaction-route="transaction_route"
|
||||
t-att-data-landing-route="landing_route"
|
||||
t-att-data-allow-token-selection="True">
|
||||
|
||||
<t t-set="provider_count" t-value="len(providers) if providers else 0"/>
|
||||
<t t-set="token_count" t-value="len(tokens) if tokens else 0"/>
|
||||
<!-- Check the radio button of the default token, if set, or of the first provider if
|
||||
it is the only payment option -->
|
||||
<t t-set="default_payment_option_id"
|
||||
t-value="default_token_id if default_token_id and token_count > 0
|
||||
else providers[0].id if provider_count == 1 and token_count == 0
|
||||
else None"/>
|
||||
<t t-set="fees_by_provider" t-value="fees_by_provider or dict()"/>
|
||||
<t t-set="footer_template_id"
|
||||
t-value="footer_template_id or 'payment.footer'"/>
|
||||
|
||||
<div class="card">
|
||||
<!-- === Providers === -->
|
||||
<t t-foreach="providers" t-as="provider">
|
||||
<div name="o_payment_option_card" class="card-body o_payment_option_card">
|
||||
<label>
|
||||
<!-- === Radio button === -->
|
||||
<!-- Only shown if linked to the only payment option -->
|
||||
<input name="o_payment_radio"
|
||||
type="radio"
|
||||
t-att-checked="provider.id == default_payment_option_id"
|
||||
t-att-class="'' if provider_count + token_count > 1 else 'd-none'"
|
||||
t-att-data-payment-option-id="provider.id"
|
||||
t-att-data-provider="provider.code"
|
||||
data-payment-option-type="provider"/>
|
||||
<!-- === Provider name === -->
|
||||
<span class="payment_option_name">
|
||||
<b t-esc="provider.display_as or provider.name"/>
|
||||
</span>
|
||||
<!-- === "Test Mode" badge === -->
|
||||
<span t-if="provider.state == 'test'"
|
||||
class="badge rounded-pill text-bg-warning ms-1">
|
||||
Test Mode
|
||||
</span>
|
||||
<!-- === "Unpublished" badge === -->
|
||||
<span t-if="not provider.is_published"
|
||||
class="badge rounded-pill text-bg-danger ms-1">
|
||||
Unpublished
|
||||
</span>
|
||||
<!-- === Extra fees badge === -->
|
||||
<t t-if="fees_by_provider.get(provider)">
|
||||
<span class="badge rounded-pill text-bg-secondary ms-1">
|
||||
+ <t t-esc="fees_by_provider.get(provider)"
|
||||
t-options="{'widget': 'monetary', 'display_currency': currency}"/>
|
||||
Fees
|
||||
</span>
|
||||
</t>
|
||||
</label>
|
||||
<!-- === Payment icon list === -->
|
||||
<t t-call="payment.icon_list"/>
|
||||
<!-- === Help message === -->
|
||||
<div t-if="not is_html_empty(provider.pre_msg)"
|
||||
t-out="provider.pre_msg"
|
||||
class="text-muted ms-3"/>
|
||||
</div>
|
||||
<!-- === Provider inline form === -->
|
||||
<div t-attf-id="o_payment_provider_inline_form_{{provider.id}}"
|
||||
name="o_payment_inline_form"
|
||||
class="card-footer px-3 d-none">
|
||||
<t t-if="provider.sudo()._should_build_inline_form(is_validation=False)">
|
||||
<t t-set="inline_form_xml_id"
|
||||
t-value="provider.sudo().inline_form_view_id.xml_id"/>
|
||||
<!-- === Inline form content (filled by provider) === -->
|
||||
<div t-if="inline_form_xml_id" class="clearfix">
|
||||
<t t-call="{{inline_form_xml_id}}">
|
||||
<t t-set="provider_id" t-value="provider.id"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<!-- === "Save my payment details" checkbox === -->
|
||||
<label t-if="show_tokenize_input[provider.id]">
|
||||
<input name="o_payment_save_as_token" type="checkbox"/>
|
||||
Save my payment details
|
||||
</label>
|
||||
</div>
|
||||
</t>
|
||||
<!-- === Tokens === -->
|
||||
<t t-foreach="tokens" t-as="token">
|
||||
<div name="o_payment_option_card" class="card-body o_payment_option_card">
|
||||
<label>
|
||||
<!-- === Radio button === -->
|
||||
<input name="o_payment_radio"
|
||||
type="radio"
|
||||
t-att-checked="token.id == default_payment_option_id"
|
||||
t-att-data-payment-option-id="token.id"
|
||||
t-att-data-provider="token.provider_code"
|
||||
data-payment-option-type="token"/>
|
||||
<!-- === Token name === -->
|
||||
<span class="payment_option_name" t-esc="token.display_name"/>
|
||||
<!-- === "V" check mark === -->
|
||||
<t t-call="payment.verified_token_checkmark"/>
|
||||
<!-- === "Fees" badge === -->
|
||||
<span t-if="fees_by_provider.get(token.provider_id)"
|
||||
class="badge rounded-pill text-bg-secondary ms-1">
|
||||
+ <t t-esc="fees_by_provider.get(token.provider_id)"
|
||||
t-options="{'widget': 'monetary', 'display_currency': currency}"/>
|
||||
Fees
|
||||
</span>
|
||||
<!-- === "Unpublished" badge === -->
|
||||
<span t-if="not token.provider_id.is_published" class="badge rounded-pill text-bg-danger ms-1">
|
||||
Unpublished
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<!-- === Token inline form === -->
|
||||
<div t-attf-id="o_payment_token_inline_form_{{token.id}}"
|
||||
name="o_payment_inline_form"
|
||||
class="card-footer d-none">
|
||||
<t t-set="token_inline_form_xml_id"
|
||||
t-value="token.sudo().provider_id.token_inline_form_view_id.xml_id"/>
|
||||
<!-- === Inline form content (filled by provider) === -->
|
||||
<div t-if="token_inline_form_xml_id" class="clearfix">
|
||||
<t t-call="{{token_inline_form_xml_id}}">
|
||||
<t t-set="token" t-value="token"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<!-- === "Pay" button === -->
|
||||
<t t-call="{{footer_template_id}}">
|
||||
<t t-set="label">Pay</t>
|
||||
<t t-set="icon_class" t-value="'fa-lock'"/>
|
||||
</t>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<!-- Manage (token create and deletion) form -->
|
||||
<template id="manage" name="Payment Manage">
|
||||
<!-- Variables description:
|
||||
- 'providers' - The payment providers supporting tokenization
|
||||
- 'tokens' - The set of payment tokens of the current partner
|
||||
- 'default_token_id' - The id of the token that should be pre-selected. Optional
|
||||
- 'reference_prefix' - The custom prefix to compute the full transaction reference
|
||||
- 'partner_id' - The id of the partner managing the tokens
|
||||
- 'access_token' - The access token used to authenticate the partner.
|
||||
- 'transaction_route' - The route used to create a validation transaction
|
||||
- 'assign_token_route' - The route to call to assign a token to a record. If set, it
|
||||
enables the token assignation mechanisms: creation of a new
|
||||
token through a refunded transaction and assignation of an
|
||||
existing token
|
||||
- 'landing_route' - The route the user is redirected to at then end of the flow
|
||||
- 'footer_template_id' - The template id for the submit button. Optional
|
||||
-->
|
||||
<form name="o_payment_manage"
|
||||
class="o_payment_form mt-3 clearfix"
|
||||
t-att-data-reference-prefix="reference_prefix"
|
||||
t-att-data-partner-id="partner_id"
|
||||
t-att-data-access-token="access_token"
|
||||
t-att-data-transaction-route="transaction_route"
|
||||
t-att-data-assign-token-route="assign_token_route"
|
||||
t-att-data-landing-route="landing_route"
|
||||
t-att-data-allow-token-selection="bool(assign_token_route)">
|
||||
<t t-set="provider_count" t-value="len(providers) if providers else 0"/>
|
||||
<t t-set="token_count" t-value="len(tokens) if tokens else 0"/>
|
||||
<t t-set="no_selectable_token" t-value="token_count == 0 or not assign_token_route"/>
|
||||
<t t-set="default_payment_option_id"
|
||||
t-value="default_token_id if default_token_id and token_count > 0
|
||||
else providers[0].id if provider_count == 1 and no_selectable_token
|
||||
else None"/>
|
||||
<t t-set="footer_template_id"
|
||||
t-value="footer_template_id or 'payment.footer'"/>
|
||||
<div class="card">
|
||||
<!-- === Providers === -->
|
||||
<t t-foreach="providers" t-as="provider">
|
||||
<div name="o_payment_option_card" class="card-body o_payment_option_card">
|
||||
<label>
|
||||
<!-- === Radio button === -->
|
||||
<!-- Only shown if linked to the only payment option -->
|
||||
<input name="o_payment_radio"
|
||||
type="radio"
|
||||
t-att-checked="provider.id == default_payment_option_id"
|
||||
t-att-class="'' if provider_count + token_count > 1 else 'd-none'"
|
||||
t-att-data-payment-option-id="provider.id"
|
||||
t-att-data-provider="provider.code"
|
||||
data-payment-option-type="provider"/>
|
||||
<!-- === Provider name === -->
|
||||
<span class="payment_option_name">
|
||||
<b t-esc="provider.display_as or provider.name"/>
|
||||
</span>
|
||||
<!-- === "Test Mode" badge === -->
|
||||
<span t-if="provider.state == 'test'"
|
||||
class="badge rounded-pill text-bg-warning"
|
||||
style="margin-left:5px">
|
||||
Test Mode
|
||||
</span>
|
||||
<!-- === "Unpublished" badge === -->
|
||||
<span t-if="not provider.is_published" class="badge rounded-pill text-bg-danger">
|
||||
Unpublished
|
||||
</span>
|
||||
</label>
|
||||
<!-- === Payment icon list === -->
|
||||
<t t-call="payment.icon_list"/>
|
||||
<!-- === Help message === -->
|
||||
<div t-if="not is_html_empty(provider.pre_msg)"
|
||||
t-out="provider.pre_msg"
|
||||
class="text-muted ms-3"/>
|
||||
</div>
|
||||
<!-- === Provider inline form === -->
|
||||
<t t-if="provider.sudo()._should_build_inline_form(is_validation=True)">
|
||||
<div t-attf-id="o_payment_provider_inline_form_{{provider.id}}"
|
||||
name="o_payment_inline_form"
|
||||
class="card-footer d-none">
|
||||
<t t-set="inline_form_xml_id"
|
||||
t-value="provider.sudo().inline_form_view_id.xml_id"/>
|
||||
<!-- === Inline form content (filled by provider) === -->
|
||||
<div t-if="inline_form_xml_id" class="clearfix">
|
||||
<t t-call="{{inline_form_xml_id}}">
|
||||
<t t-set="provider_id" t-value="provider.id"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<!-- === Tokens === -->
|
||||
<t t-foreach="tokens" t-as="token">
|
||||
<div name="o_payment_option_card" class="card-body o_payment_option_card">
|
||||
<label>
|
||||
<!-- === Radio button === -->
|
||||
<!-- Only shown if 'assign_token_route' is set -->
|
||||
<input name="o_payment_radio"
|
||||
type="radio"
|
||||
t-att-checked="token.id == default_payment_option_id"
|
||||
t-att-class="'' if bool(assign_token_route) else 'd-none'"
|
||||
t-att-data-payment-option-id="token.id"
|
||||
t-att-data-provider="token.provider_code"
|
||||
data-payment-option-type="token"/>
|
||||
<!-- === Token name === -->
|
||||
<span class="payment_option_name" t-esc="token.display_name"/>
|
||||
<!-- === "V" check mark === -->
|
||||
<t t-call="payment.verified_token_checkmark"/>
|
||||
<!-- === "Unpublished" badge === -->
|
||||
<span t-if="not token.provider_id.is_published and token.env.user._is_internal()"
|
||||
class="badge rounded-pill text-bg-danger ms-1">
|
||||
Unpublished
|
||||
</span>
|
||||
</label>
|
||||
<!-- === "Delete" token button === -->
|
||||
<button name="o_payment_delete_token"
|
||||
class="btn btn-primary btn-sm float-end">
|
||||
<i class="fa fa-trash"/> Delete
|
||||
</button>
|
||||
</div>
|
||||
<!-- === Token inline form === -->
|
||||
<div t-attf-id="o_payment_token_inline_form_{{token.id}}"
|
||||
name="o_payment_inline_form"
|
||||
class="card-footer d-none">
|
||||
<t t-set="token_inline_form_xml_id"
|
||||
t-value="token.sudo().provider_id.token_inline_form_view_id.xml_id"/>
|
||||
<!-- === Inline form content (filled by provider) === -->
|
||||
<div t-if="token_inline_form_xml_id" class="clearfix">
|
||||
<t t-call="{{token_inline_form_xml_id}}">
|
||||
<t t-set="token" t-value="token"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<!-- === "Save Payment Method" button === -->
|
||||
<t t-call="{{footer_template_id}}">
|
||||
<t t-set="label">Save Payment Method</t>
|
||||
<t t-set="icon_class" t-value="'fa-plus-circle'"/>
|
||||
</t>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<!-- Express Checkout form -->
|
||||
<template id="express_checkout" name="Payment Express Checkout">
|
||||
<!-- Variables description:
|
||||
- 'providers' - The payment providers compatible with the current transaction.
|
||||
- 'reference_prefix' - The custom prefix to compute the full transaction reference.
|
||||
- 'amount' - The amount to pay.
|
||||
- 'minor_amount' - The amount to pay in the minor units of its currency.
|
||||
- 'currency' - The currency of the transaction, as a `res.currency` record.
|
||||
- 'merchant_name' - The merchant name.
|
||||
- 'access_token' - The access token used to authenticate the partner.
|
||||
- 'shipping_info_required' - Whether the shipping information is required or not.
|
||||
- 'transaction_route' - The route used to create a transaction when the user clicks Pay.
|
||||
- 'shipping_address_update_route' - The route where available carriers are computed
|
||||
based on the (partial) shipping information
|
||||
available. Optional
|
||||
- 'express_checkout_route' - The route where the billing and shipping information are
|
||||
sent.
|
||||
- 'landing_route' - The route the user is redirected to after the transaction.
|
||||
-->
|
||||
<form name="o_payment_express_checkout_form" class="container"
|
||||
t-att-data-reference-prefix="reference_prefix"
|
||||
t-att-data-amount="amount"
|
||||
t-att-data-minor-amount="minor_amount"
|
||||
t-att-data-currency-id="currency and currency.id"
|
||||
t-att-data-currency-name="currency.name.lower()"
|
||||
t-att-data-merchant-name="merchant_name"
|
||||
t-att-data-partner-id="partner_id"
|
||||
t-att-data-access-token="payment_access_token"
|
||||
t-att-data-shipping-info-required="shipping_info_required"
|
||||
t-att-data-transaction-route="transaction_route"
|
||||
t-att-data-shipping-address-update-route="shipping_address_update_route"
|
||||
t-att-data-express-checkout-route="express_checkout_route"
|
||||
t-att-data-landing-route="landing_route">
|
||||
<t t-foreach="providers_sudo" t-as="provider_sudo">
|
||||
<t t-set="express_checkout_form_xml_id"
|
||||
t-value="provider_sudo.express_checkout_form_view_id.xml_id"/>
|
||||
<t t-if="express_checkout_form_xml_id">
|
||||
<t t-call="{{express_checkout_form_xml_id}}">
|
||||
<t t-set="provider_sudo" t-value="provider_sudo"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<!-- Expandable payment icon list -->
|
||||
<template id="icon_list" name="Payment Icon List">
|
||||
<ul class="payment_icon_list float-end list-inline" data-max-icons="3">
|
||||
<t t-set="icon_index" t-value="0"/>
|
||||
<t t-set="MAX_ICONS" t-value="3"/>
|
||||
<!-- === Icons === -->
|
||||
<!-- Only shown if in the first 3 icons -->
|
||||
<t t-foreach="provider.payment_icon_ids.filtered(lambda r: r.image_payment_form)" t-as="icon">
|
||||
<li t-attf-class="list-inline-item{{'' if (icon_index < MAX_ICONS) else ' d-none'}}">
|
||||
<span t-field="icon.image_payment_form"
|
||||
t-options="{'widget': 'image', 'alt-field': 'name'}"
|
||||
data-bs-toggle="tooltip"
|
||||
t-att-title="icon.name"/>
|
||||
</li>
|
||||
<t t-set="icon_index" t-value="icon_index + 1"/>
|
||||
</t>
|
||||
<t t-if="icon_index >= MAX_ICONS">
|
||||
<!-- === "show more" button === -->
|
||||
<!-- Only displayed if too many payment icons -->
|
||||
<li style="display:block;" class="list-inline-item">
|
||||
<span class="float-end more_option text-info">
|
||||
<a name="o_payment_icon_more"
|
||||
data-bs-toggle="tooltip"
|
||||
t-att-title="', '.join([icon.name for icon in provider.payment_icon_ids[MAX_ICONS:]])">
|
||||
show more
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<!-- === "show less" button === -->
|
||||
<!-- Only displayed when "show more" is clicked -->
|
||||
<li style="display:block;" class="list-inline-item d-none">
|
||||
<span class="float-end more_option text-info">
|
||||
<a name="o_payment_icon_less">show less</a>
|
||||
</span>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<!-- Verified token checkmark -->
|
||||
<template id="verified_token_checkmark" name="Payment Verified Token Checkmark">
|
||||
<t t-if="0" name="payment_demo_hook"/>
|
||||
<t t-else="">
|
||||
<i t-if="token.verified" class="fa fa-check text-success"
|
||||
title="This payment method has been verified by our system."
|
||||
role="img"
|
||||
aria-label="Ok"/>
|
||||
<i t-else="" class="fa fa-check text-muted"
|
||||
title="This payment method has not been verified by our system."
|
||||
role="img"
|
||||
aria-label="Not verified"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Generic footer for payment forms -->
|
||||
<template id="footer" name="Payment Footer">
|
||||
<!-- Variables description:
|
||||
- 'label' - The label for the submit button
|
||||
- 'icon_class' - The Font Awesome icon class (e.g. 'fa-lock') for the submit button
|
||||
-->
|
||||
<div class="float-end mt-2">
|
||||
<button name="o_payment_submit_button"
|
||||
type="submit"
|
||||
class="btn btn-primary btn-lg mb8 mt8"
|
||||
disabled="true"
|
||||
t-att-data-icon-class="icon_class">
|
||||
<i t-attf-class="fa {{icon_class}}"/> <t t-esc="label"/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Transaction status in portal -->
|
||||
<template id="transaction_status">
|
||||
<!-- Variables description:
|
||||
- 'tx' - The transaction whose status must be displayed
|
||||
-->
|
||||
<t t-if="tx.state == 'draft'">
|
||||
<t t-set="alert_style" t-value="'info'"/>
|
||||
<t t-set="status_message">
|
||||
<p>Your payment has not been processed yet.</p>
|
||||
</t>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'pending'">
|
||||
<t t-set="alert_style" t-value="'warning'"/>
|
||||
<t t-set="status_message" t-value="tx.provider_id.sudo().pending_msg"/>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'authorized'">
|
||||
<t t-set="alert_style" t-value="'success'"/>
|
||||
<t t-set="status_message" t-value="tx.provider_id.sudo().auth_msg"/>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'done'">
|
||||
<t t-set="alert_style" t-value="'success'"/>
|
||||
<t t-set="status_message" t-value="tx.provider_id.sudo().done_msg"/>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'cancel'">
|
||||
<t t-set="alert_style" t-value="'danger'"/>
|
||||
<t t-set="status_message" t-value="tx.provider_id.sudo().cancel_msg"/>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'error'">
|
||||
<t t-set="alert_style" t-value="'danger'"/>
|
||||
<t t-set="status_message">
|
||||
<p>An error occurred during the processing of your payment.</p>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-if="is_html_empty(status_message)" t-set="status_message" t-value="''"/>
|
||||
|
||||
<div t-if="status_message or tx.state_message"
|
||||
id="o_payment_status_alert"
|
||||
t-attf-class="alert alert-{{alert_style}} alert-dismissible">
|
||||
<button class="btn-close" data-bs-dismiss="alert" title="Dismiss"/>
|
||||
<t t-if="status_message" t-out="status_message"/>
|
||||
<t t-if="tx.state_message" t-out="tx.state_message"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
<field name="name">payment.token.form</field>
|
||||
<field name="model">payment.token</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment Tokens" create="false" editable="bottom">
|
||||
<form string="Payment Tokens" create="false" edit="false">
|
||||
<sheet>
|
||||
<field name="active" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
|
|
@ -14,10 +14,11 @@
|
|||
type="action" icon="fa-money" string="Payments">
|
||||
</button>
|
||||
</div>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
|
||||
<group>
|
||||
<group name="general_information">
|
||||
<field name="payment_details"/>
|
||||
<field name="payment_method_id"/>
|
||||
<field name="partner_id" />
|
||||
</group>
|
||||
<group name="technical_information">
|
||||
|
|
@ -35,13 +36,14 @@
|
|||
<field name="name">payment.token.list</field>
|
||||
<field name="model">payment.token</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Payment Tokens">
|
||||
<list string="Payment Tokens" create="false">
|
||||
<field name="payment_details"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="provider_id" readonly="1"/>
|
||||
<field name="provider_ref" readonly="1"/>
|
||||
<field name="payment_method_id"/>
|
||||
<field name="provider_id"/>
|
||||
<field name="provider_ref"/>
|
||||
<field name="company_id" groups="base.group_multi_company" optional="show"/>
|
||||
</tree>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -53,7 +55,7 @@
|
|||
<field name="partner_id"/>
|
||||
<separator/>
|
||||
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
|
||||
<group expand="1" string="Group By">
|
||||
<group>
|
||||
<filter string="Provider" name="provider_id" context="{'group_by': 'provider_id'}"/>
|
||||
<filter string="Partner" name="partner_id" context="{'group_by': 'partner_id'}"/>
|
||||
<filter string="Company" name="company" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
|
||||
|
|
@ -65,10 +67,11 @@
|
|||
<record id="action_payment_token" model="ir.actions.act_window">
|
||||
<field name="name">Payment Tokens</field>
|
||||
<field name="res_model">payment.token</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="path">payment-tokens</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new payment token
|
||||
There is no token created yet.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,17 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Payment Transactions" create="false" edit="false">
|
||||
<header>
|
||||
<button type="object" name="action_capture" states="authorized" string="Capture Transaction" class="oe_highlight"/>
|
||||
<button type="object" name="action_void" states="authorized" string="Void Transaction"
|
||||
<button type="object" name="action_capture" invisible="state != 'authorized'" string="Capture Transaction" class="oe_highlight"/>
|
||||
<button type="object" name="action_void" invisible="state != 'authorized'" string="Void Transaction"
|
||||
confirm="Are you sure you want to void the authorized transaction? This action can't be undone."/>
|
||||
<button
|
||||
string="Post-process"
|
||||
help="Run the post-processing step for this transaction."
|
||||
type="object"
|
||||
name="action_post_process"
|
||||
invisible="is_post_processed"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
|
@ -18,7 +26,7 @@
|
|||
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>
|
||||
</div>
|
||||
|
|
@ -26,18 +34,20 @@
|
|||
<group name="transaction_details">
|
||||
<field name="reference"/>
|
||||
<field name="source_transaction_id"
|
||||
attrs="{'invisible': [('source_transaction_id', '=', False)]}"/>
|
||||
invisible="not source_transaction_id"/>
|
||||
<field name="amount"/>
|
||||
<field name="fees" attrs="{'invisible': [('fees', '=', 0.0)]}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="payment_method_id"/>
|
||||
<field name="provider_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<!-- Used by some provider-specific views -->
|
||||
<field name="provider_code" invisible="1"/>
|
||||
<field name="provider_reference"/>
|
||||
<field name="token_id" attrs="{'invisible': [('token_id', '=', False)]}"/>
|
||||
<field name="token_id" invisible="not token_id"/>
|
||||
<field name="create_date"/>
|
||||
<field name="last_state_change"/>
|
||||
<field name="is_live"/>
|
||||
<field name="is_post_processed" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group name="transaction_partner">
|
||||
<field name="partner_id" widget="res_partner_many2one"/>
|
||||
|
|
@ -54,8 +64,10 @@
|
|||
<field name="partner_lang"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Message" attrs="{'invisible': [('state_message', '=', False)]}">
|
||||
<field name="state_message" nolabel="1" colspan="2"/>
|
||||
<separator string="Child transactions" invisible="not child_transaction_ids"/>
|
||||
<field name="child_transaction_ids" invisible="not child_transaction_ids"/>
|
||||
<group string="Message" invisible="not state_message">
|
||||
<field colspan="2" name="state_message" nolabel="1"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
|
|
@ -66,19 +78,20 @@
|
|||
<field name="name">payment.transaction.list</field>
|
||||
<field name="model">payment.transaction</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Payment Transactions" create="false">
|
||||
<list string="Payment Transactions" create="false">
|
||||
<field name="reference"/>
|
||||
<field name="create_date"/>
|
||||
<field name="payment_method_id"/>
|
||||
<field name="provider_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="partner_name"/>
|
||||
<!-- Needed to display the currency of the amounts -->
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="currency_id" column_invisible="True"/>
|
||||
<field name="amount"/>
|
||||
<field name="fees"/>
|
||||
<field name="state"/>
|
||||
<field name="company_id" groups="base.group_multi_company" optional="show"/>
|
||||
</tree>
|
||||
<field name="is_live" optional="hide"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -87,24 +100,14 @@
|
|||
<field name="model">payment.transaction</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_mobile" create="false">
|
||||
<field name="currency_id"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_content oe_kanban_global_click">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<strong><field name="reference"/></strong>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<span><field name="partner_name"/></span>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<span class="float-end">
|
||||
<field name="amount"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<t t-name="card">
|
||||
<div class="d-flex">
|
||||
<field name="reference" class="fw-bolder"/>
|
||||
<field name="amount" class="ms-auto"/>
|
||||
</div>
|
||||
<field name="partner_name"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
|
|
@ -120,20 +123,54 @@
|
|||
<field name="provider_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="partner_name"/>
|
||||
<group expand="1" string="Group By">
|
||||
<filter
|
||||
string="Production Environment"
|
||||
name="live_transactions"
|
||||
domain="[('is_live', '=', True)]"
|
||||
/>
|
||||
<group>
|
||||
<filter string="Provider" name="provider_id" context="{'group_by': 'provider_id'}"/>
|
||||
<filter string="Partner" name="partner_id" context="{'group_by': 'partner_id'}"/>
|
||||
<filter string="Status" name="state" context="{'group_by': 'state'}"/>
|
||||
<filter
|
||||
string="Production Environment"
|
||||
name="is_live"
|
||||
context="{'group_by': 'is_live'}"
|
||||
/>
|
||||
<filter string="Company" name="company" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="payment_transaction_graph" model="ir.ui.view">
|
||||
<field name="name">payment.transaction.graph</field>
|
||||
<field name="model">payment.transaction</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Payment Transactions">
|
||||
<field name="create_date" interval="month"/>
|
||||
<field name="state"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="payment_transaction_pivot" model="ir.ui.view">
|
||||
<field name="name">payment.transaction.pivot</field>
|
||||
<field name="model">payment.transaction</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Payment Transactions" display_quantity="1">
|
||||
<field name="create_date" interval="month" type="row"/>
|
||||
<field name="state" type="col"/>
|
||||
<field name="amount" type="measure"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_payment_transaction" model="ir.actions.act_window">
|
||||
<field name="name">Payment Transactions</field>
|
||||
<field name="res_model">payment.transaction</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="path">payment-transactions</field>
|
||||
<field name="view_mode">list,kanban,form,graph,pivot</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_neutral_face">
|
||||
There are no transactions to show
|
||||
|
|
@ -144,7 +181,7 @@
|
|||
<record id="action_payment_transaction_linked_to_token" model="ir.actions.act_window">
|
||||
<field name="name">Payment Transactions Linked To Token</field>
|
||||
<field name="res_model">payment.transaction</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="domain">[('token_id','=', active_id)]</field>
|
||||
<field name="context">{'create': False}</field>
|
||||
</record>
|
||||
|
|
|
|||
393
odoo-bringout-oca-ocb-payment/payment/views/portal_templates.xml
Normal file
393
odoo-bringout-oca-ocb-payment/payment/views/portal_templates.xml
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Display of /payment/pay -->
|
||||
<template id="payment.pay">
|
||||
<!-- Parameters description:
|
||||
- reference_prefix: The custom prefix to compute the full transaction reference.
|
||||
- amount: The amount to pay.
|
||||
- currency: The currency of the payment, as a `res.currency` record.
|
||||
- partner_id: The id of the partner on behalf of whom the payment should be made.
|
||||
- payment_methods_sudo: The compatible payment methods, as a sudoed `payment.method`
|
||||
recordset.
|
||||
- tokens_sudo: The available payment tokens, as a sudoed `payment.token` recordset.
|
||||
- availability_report: The availability report of providers and payment methods.
|
||||
- res_company: The company in which the payment if made (for the company logo).
|
||||
- company_mismatch: Whether the user should make the payment in another company.
|
||||
- expected_company: The record of the company that the user should switch to.
|
||||
- partner_is_different: Whether the partner logged in is the one making the payment.
|
||||
-->
|
||||
<t t-call="portal.frontend_layout">
|
||||
<t t-set="page_title">Payment</t>
|
||||
<t t-set="additional_title"><t t-esc="page_title"/></t>
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<!-- Portal breadcrumb -->
|
||||
<t t-call="payment.portal_breadcrumb"/>
|
||||
<!-- Payment page -->
|
||||
<div class="row justify-content-center my-3">
|
||||
<div class="col-lg-7">
|
||||
<div t-if="not amount" class="alert alert-info">
|
||||
There is nothing to pay.
|
||||
</div>
|
||||
<div t-elif="not currency" class="alert alert-warning">
|
||||
<strong>Warning</strong> The currency is missing or incorrect.
|
||||
</div>
|
||||
<div t-elif="not partner_id" class="alert alert-warning">
|
||||
<strong>Warning</strong> You must be logged in to pay.
|
||||
</div>
|
||||
<div t-elif="company_mismatch">
|
||||
<t t-call="payment.company_mismatch_warning"/>
|
||||
</div>
|
||||
<t t-else="">
|
||||
<div t-if="partner_is_different" class="alert alert-warning">
|
||||
<strong>Warning</strong> Make sure you are logged in as the
|
||||
correct partner before making this payment.
|
||||
</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'"/>
|
||||
<t t-set="label">Amount</t>
|
||||
<t t-set="value" t-value="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="reference_prefix"/>
|
||||
<t t-set="include_separator" t-value="True"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<t t-call="payment.form"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="payment.company_mismatch_warning" name="Company Mismatch Warning">
|
||||
<!-- Parameters description:
|
||||
- expected_company: The record of the company that the user should switch to.
|
||||
-->
|
||||
<div class="row mr16">
|
||||
<div class="alert alert-warning col-lg-12 ms-3 me-3" role="alert">
|
||||
<p>
|
||||
Please switch to company <t t-esc="expected_company.name"/> to make this
|
||||
payment.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Display of /my/payment_methods -->
|
||||
<template id="payment.payment_methods" name="Payment Methods">
|
||||
<t t-call="portal.frontend_layout">
|
||||
<t t-set="page_title">Payment Methods</t>
|
||||
<t t-set="additional_title"><t t-esc="page_title"/></t>
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<!-- Portal breadcrumb -->
|
||||
<t t-call="payment.portal_breadcrumb"/>
|
||||
<!-- Payment methods page -->
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-7">
|
||||
<t t-call="payment.form"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Display of /payment/status -->
|
||||
<template id="payment.payment_status" name="Payment Status">
|
||||
<t t-call="portal.frontend_layout">
|
||||
<t t-set="page_title">Payment Status</t>
|
||||
<t t-set="additional_title"><t t-esc="page_title"/></t>
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<!-- Portal breadcrumb -->
|
||||
<t t-call="payment.portal_breadcrumb"/>
|
||||
<!-- Payment status page -->
|
||||
<div class="row justify-content-center my-3">
|
||||
<div class="col-12 col-lg-8">
|
||||
<div t-if="payment_not_found" class="text-center">
|
||||
<p>Your payment is on its way!</p>
|
||||
<p>
|
||||
You should receive an email confirming your payment within a few
|
||||
minutes.
|
||||
</p>
|
||||
<p>Don't hesitate to contact us if you don't receive it.</p>
|
||||
</div>
|
||||
<div t-else="" name="o_payment_status">
|
||||
<t t-call="payment.state_header">
|
||||
<t t-set="is_processing" t-value="True"/>
|
||||
</t>
|
||||
<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'"/>
|
||||
<t t-set="label">Amount</t>
|
||||
<t t-set="value" t-value="tx.amount"/>
|
||||
<t t-set="options"
|
||||
t-value="{
|
||||
'widget': 'monetary',
|
||||
'display_currency': tx.currency_id,
|
||||
}"
|
||||
/>
|
||||
</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="tx.reference"/>
|
||||
<t t-set="include_separator" t-value="True"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Display of /payment/confirmation -->
|
||||
<template id="payment.confirm">
|
||||
<!-- Parameters description:
|
||||
- tx: The transaction to display.
|
||||
-->
|
||||
<t t-call="portal.frontend_layout">
|
||||
<t t-set="page_title">Payment Confirmation</t>
|
||||
<t t-set="additional_title"><t t-esc="page_title"/></t>
|
||||
<t t-set="show_pm" t-value="tx.payment_method_code != 'unknown'"/>
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<!-- Portal breadcrumb -->
|
||||
<t t-call="payment.portal_breadcrumb"/>
|
||||
<div class="row justify-content-center my-3">
|
||||
<div class="col-12 col-lg-7">
|
||||
<!-- Confirmation page -->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<t t-call="payment.state_header"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-att-class="'text-bg-light row row-cols-1 mx-0 mb-3 py-2 rounded'
|
||||
+ (' row-cols-md-4' if show_pm else ' row-cols-md-3')"
|
||||
>
|
||||
<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="tx.amount"/>
|
||||
<t t-set="options"
|
||||
t-value="{'widget': 'monetary', 'display_currency': tx.currency_id}"
|
||||
/>
|
||||
</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="tx.reference"/>
|
||||
<t t-set="include_separator" t-value="True"/>
|
||||
</t>
|
||||
<t t-if="tx.payment_method_code != 'unknown'">
|
||||
<t t-call="payment.summary_item">
|
||||
<t t-set="name" t-value="'method'"/>
|
||||
<t t-set="label">Payment Method</t>
|
||||
<t t-set="value" t-value="tx.payment_method_id.name"/>
|
||||
<t t-set="include_separator" t-value="True"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-call="payment.summary_item">
|
||||
<t t-set="name" t-value="'provider'"/>
|
||||
<t t-set="label">Processed by</t>
|
||||
<t t-set="value" t-value="tx.provider_id.sudo().name"/>
|
||||
<t t-set="include_separator" t-value="True"/>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col offset-md-3 ps-0">
|
||||
<a role="button" class="btn btn-primary float-end" href="/my/home">
|
||||
Go to my Account <i class="oi oi-arrow-right ms-2"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Breadcrumb for the portal -->
|
||||
<template id="payment.portal_breadcrumb">
|
||||
<!-- Parameters description:
|
||||
- page_title: The title of the breadcrumb item.
|
||||
-->
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<ol class="breadcrumb px-0 mt16">
|
||||
<li id="o_payment_portal_home" class="breadcrumb-item">
|
||||
<a href="/my/home">
|
||||
<i class="fa fa-home"
|
||||
role="img"
|
||||
title="Home"
|
||||
aria-label="Home"/>
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item"><t t-esc="page_title"/></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="payment.summary_item">
|
||||
<!-- Parameters description:
|
||||
- name: The summary item name that is suffixed to `o_payment_summary_` to create the id.
|
||||
- label: The label that is displayed.
|
||||
- value: The value of the summary item.
|
||||
- options: The widget options to set.
|
||||
- include_separator: Whether the summary item should be preceded by a separator.
|
||||
-->
|
||||
<t t-set="options" t-value="options or {'widget': 'string'}"/>
|
||||
<hr t-if="include_separator" class="d-md-none m-0 text-300 opacity-100"/>
|
||||
<div t-att-class="'col my-3 text-break'
|
||||
+ (' o_payment_summary_separator' if include_separator else '')"
|
||||
>
|
||||
<label t-attf-for="o_payment_summary_{{name}}"
|
||||
t-out="label"
|
||||
class="d-block small opacity-75"
|
||||
/>
|
||||
<span t-attf-id="o_payment_summary_{{name}}"
|
||||
t-out="value"
|
||||
t-options="options"
|
||||
class="fs-5 fw-bold"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="payment.state_header">
|
||||
<!-- Parameters description:
|
||||
- tx: The transaction whose status must be displayed.
|
||||
- is_processing: Whether the transaction is being processed.
|
||||
-->
|
||||
<t t-set="waiting_heading">
|
||||
<p>Please wait...</p>
|
||||
</t>
|
||||
<t t-set="tx_status_message" t-value="tx.provider_id.sudo()._get_status_message(tx.state)"/>
|
||||
<t t-if="tx.state == 'draft'">
|
||||
<t t-set="alert_style" t-value="'warning'"/>
|
||||
<t t-if="is_processing" t-set="status_heading" t-value="waiting_heading"/>
|
||||
<t t-set="status_message">
|
||||
<p>Your payment has not been processed yet.</p>
|
||||
</t>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'pending'">
|
||||
<t t-set="alert_style" t-value="'info'"/>
|
||||
<t t-if="is_processing" t-set="status_heading" t-value="waiting_heading"/>
|
||||
<t t-if="tx.operation == 'validation'" t-set="status_message">
|
||||
<p>Saving your payment method.</p>
|
||||
</t>
|
||||
<t t-else="" t-set="status_message" t-value="tx_status_message"/>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'authorized'">
|
||||
<t t-set="alert_style" t-value="'success'"/>
|
||||
<t t-if="is_processing" t-set="status_heading" t-value="waiting_heading"/>
|
||||
<t t-set="status_message" t-value="tx_status_message"/>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'done'">
|
||||
<t t-set="alert_style" t-value="'success'"/>
|
||||
<t t-if="not is_processing" t-set="status_heading">
|
||||
<p>Thank you!</p>
|
||||
</t>
|
||||
<t t-if="tx.operation == 'validation'" t-set="status_message">
|
||||
<p>Your payment method has been saved.</p>
|
||||
</t>
|
||||
<t t-else="" t-set="status_message" t-value="tx_status_message"/>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'cancel'">
|
||||
<t t-set="alert_style" t-value="'danger'"/>
|
||||
<t t-if="tx.operation == 'validation'" t-set="status_message">
|
||||
<p>The saving of your payment method has been canceled.</p>
|
||||
</t>
|
||||
<t t-else="" t-set="status_message" t-value="tx_status_message"/>
|
||||
</t>
|
||||
<t t-elif="tx.state == 'error'">
|
||||
<t t-set="alert_style" t-value="'danger'"/>
|
||||
<t t-if="tx.operation == 'validation'" t-set="status_message">
|
||||
<p class="mb-0">An error occurred while saving your payment method.</p>
|
||||
</t>
|
||||
<t t-else="" t-set="status_message">
|
||||
<p class="mb-0">An error occurred during the processing of your payment.</p>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-if="not status_message" t-set="status_message" t-value="''"/>
|
||||
<t t-set="o_payment_status_alert_class"
|
||||
t-value="'alert alert-'+ alert_style +' d-flex gap-3'"
|
||||
/>
|
||||
|
||||
<div t-if="status_heading or status_message or tx.state_message"
|
||||
name="o_payment_status_alert"
|
||||
t-attf-class="{{o_payment_status_alert_class}}"
|
||||
>
|
||||
<t t-set="alert_icon"
|
||||
t-value="'fa-cog fa-spin' if is_processing and alert_style != 'danger'
|
||||
else 'fa-check' if alert_style == 'success'
|
||||
else 'fa-info-circle' if alert_style == 'info'
|
||||
else 'fa-exclamation-triangle'"
|
||||
/>
|
||||
<div id="o_payment_status_icon">
|
||||
<i t-attf-class="fa {{alert_icon}}"/>
|
||||
</div>
|
||||
<div id="o_payment_status_message" class="w-100">
|
||||
<h5 t-if="status_heading" t-out="status_heading" class="alert-heading mb-0"/>
|
||||
<t t-if="status_message" t-out="status_message" class="mb-0"/>
|
||||
<t t-if="tx.state_message" t-out="tx.state_message" class="mb-0"/>
|
||||
</div>
|
||||
<a t-if="is_processing"
|
||||
t-att-href="tx.landing_route"
|
||||
class="alert-link ms-auto text-nowrap"
|
||||
>
|
||||
Skip <i class="oi oi-arrow-right ms-1 small"/>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- "Manage payment methods" card on /my -->
|
||||
<template id="portal_my_home_payment" name="Payment Methods" customize_show="True" inherit_id="portal.portal_my_home" priority="60">
|
||||
<xpath expr="//div[hasclass('o_portal_docs')]" position="before">
|
||||
<t t-set="portal_client_category_enable" t-value="True"/>
|
||||
</xpath>
|
||||
<div id="portal_client_category" position="inside">
|
||||
<t t-set="partner_sudo" t-value="request.env.user.partner_id"/>
|
||||
<t t-set="providers_sudo"
|
||||
t-value="request.env['payment.provider'].sudo()._get_compatible_providers(request.env.company.id, partner_sudo.id, 0., force_tokenization=True, is_validation=True)"/>
|
||||
<t t-set="methods_allowing_tokenization"
|
||||
t-value="request.env['payment.method'].sudo()._get_compatible_payment_methods(
|
||||
providers_sudo.ids,
|
||||
partner_sudo.id,
|
||||
force_tokenization=True,
|
||||
)"
|
||||
/>
|
||||
<t t-set="existing_tokens" t-value="partner_sudo.payment_token_ids + partner_sudo.commercial_partner_id.payment_token_ids"/>
|
||||
<t t-if="methods_allowing_tokenization or existing_tokens" t-call="portal.portal_docs_entry">
|
||||
<t t-set="icon" t-value="'/payment/static/img/payment-methods.svg'"/>
|
||||
<t t-set="title">Payment methods</t>
|
||||
<t t-set="text">Manage your payment methods</t>
|
||||
<t t-set="url" t-value="'/my/payment_method'"/>
|
||||
<t t-set="config_card" t-value="True"/>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -12,8 +12,8 @@
|
|||
<button type="action" class="oe_stat_button"
|
||||
icon="fa-credit-card-alt"
|
||||
name="%(payment.action_payment_token)d"
|
||||
context="{'search_default_partner_id': active_id, 'create': False, 'edit': False}"
|
||||
attrs="{'invisible': [('payment_token_count', '=', 0)]}">
|
||||
context="{'search_default_partner_id': id, 'create': False, 'edit': False}"
|
||||
invisible="payment_token_count == 0">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value">
|
||||
<field name="payment_token_count" widget="statinfo" nolabel="1"/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue