[MOV] payment_transfer: rename to payment_custom

The module `payment_transfer` was originally meant to implement a
payment with Wire Transfer flow, which it does not exactly do since all
it does it making transactions follow the payment flow until their
`pending_msg` field's content is shown to the customer. Because of that,
other modules (`website_delivery_ups`, `website_sale_picking`) started
duplicating the base acquirer Wire Transfer to create new payment modes
such as Cash on Delivery and Pay in Store.

To better prepare for a proper dinstinction of the custom modes enabled
by other modules, this commit renames the module `payment_transfer` to
`payment_custom`.

The module `payment_transfer`'s `auto-install` key is also set to
`False` since we no longer want Wire Transfer to be the default payment
acquirer for new databases.

task-2853489

Part-of: odoo/odoo#99400
This commit is contained in:
Victor Feyens
2022-09-06 12:01:37 +02:00
parent 852c2a13ed
commit 5f41f15e6b
93 changed files with 123 additions and 96 deletions
@@ -245,8 +245,8 @@
<field name="sequence">30</field>
<field name="image_128"
type="base64"
file="payment_transfer/static/description/icon.png"/>
<field name="module_id" ref="base.module_payment_transfer"/>
file="payment_custom/static/description/icon.png"/>
<field name="module_id" ref="base.module_payment_custom"/>
</record>
</odoo>
@@ -42,7 +42,7 @@ class PaymentWizard(models.TransientModel):
def _get_manual_payment_acquirer(self, env=None):
if env is None:
env = self.env
module_id = env.ref('base.module_payment_transfer').id
module_id = env.ref('base.module_payment_custom').id
return env['payment.acquirer'].search([('module_id', '=', module_id),
('company_id', '=', env.company.id)], limit=1)
@@ -7,4 +7,4 @@ from odoo.addons.payment import reset_payment_acquirer
def uninstall_hook(cr, registry):
reset_payment_acquirer(cr, registry, 'transfer')
reset_payment_acquirer(cr, registry, 'custom')
@@ -1,18 +1,16 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Wire Transfer Payment Acquirer',
'name': 'Custom Payment Modes',
'version': '2.0',
'category': 'Accounting/Payment Acquirers',
'summary': 'Payment Acquirer: Wire Transfer Implementation',
'description': """Wire Transfer Payment Acquirer""",
'summary': 'Payment Acquirer: Custom payment modes',
'depends': ['payment'],
'data': [
'views/payment_custom_templates.xml',
'views/payment_views.xml',
'views/payment_transfer_templates.xml',
'data/payment_acquirer_data.xml',
],
'auto_install': True,
'assets': {
'web.assets_frontend': [
'payment_transfer/static/src/js/post_processing.js',
+18
View File
@@ -0,0 +1,18 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import pprint
from odoo.http import Controller, request, route
_logger = logging.getLogger(__name__)
class CustomController(Controller):
_process_url = '/payment/custom/process'
@route(_process_url, type='http', auth='public', methods=['POST'], csrf=False)
def custom_process_transaction(self, **post):
_logger.info("Handling custom processing with data:\n%s", pprint.pformat(post))
request.env['payment.transaction'].sudo()._handle_notification_data('custom', post)
return request.redirect('/payment/status')
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record id="payment.payment_acquirer_transfer" model="payment.acquirer">
<field name="provider">custom</field>
<field name="redirect_form_view_id" ref="redirect_form"/>
<!-- Clear the default value before recomputing the pending_msg -->
<field name="pending_msg" eval="False"/>
</record>
<function model="payment.acquirer"
name="_transfer_ensure_pending_msg_is_set"
eval="[[ref('payment.payment_acquirer_transfer')]]"/>
</odoo>
@@ -7,8 +7,8 @@ class PaymentAcquirer(models.Model):
_inherit = 'payment.acquirer'
provider = fields.Selection(
selection_add=[('transfer', "Wire Transfer")], default='transfer',
ondelete={'transfer': 'set default'})
selection_add=[('custom', "Custom")],
ondelete={'custom': 'set default'})
qr_code = fields.Boolean(
string="Enable QR Codes", help="Enable the use of QR-codes when paying by wire transfer.")
@@ -19,7 +19,7 @@ class PaymentAcquirer(models.Model):
:return: None
"""
super()._compute_view_configuration_fields()
self.filtered(lambda acq: acq.provider == 'transfer').update({
self.filtered(lambda acq: acq.provider == 'custom').update({
'show_credentials_page': False,
'show_payment_icon_ids': False,
'show_pre_msg': False,
@@ -27,23 +27,8 @@ class PaymentAcquirer(models.Model):
'show_cancel_msg': False,
})
@api.model_create_multi
def create(self, values_list):
""" Make sure to have a pending_msg set. """
# This is done here and not in a default to have access to all required values.
acquirers = super().create(values_list)
acquirers._transfer_ensure_pending_msg_is_set()
return acquirers
def write(self, values):
""" Make sure to have a pending_msg set. """
# This is done here and not in a default to have access to all required values.
res = super().write(values)
self._transfer_ensure_pending_msg_is_set()
return res
def _transfer_ensure_pending_msg_is_set(self):
for acquirer in self.filtered(lambda a: a.provider == 'transfer' and not a.pending_msg):
for acquirer in self.filtered(lambda a: a.provider == 'custom' and not a.pending_msg):
company_id = acquirer.company_id.id
# filter only bank accounts marked as visible
accounts = self.env['account.journal'].search([
@@ -5,7 +5,7 @@ import logging
from odoo import _, api, models
from odoo.exceptions import ValidationError
from odoo.addons.payment_transfer.controllers.main import TransferController
from odoo.addons.payment_custom.controllers.main import CustomController
_logger = logging.getLogger(__name__)
@@ -14,7 +14,7 @@ class PaymentTransaction(models.Model):
_inherit = 'payment.transaction'
def _get_specific_rendering_values(self, processing_values):
""" Override of payment to return Transfer-specific rendering values.
""" Override of payment to return custom-specific rendering values.
Note: self.ensure_one() from `_get_processing_values`
@@ -23,16 +23,16 @@ class PaymentTransaction(models.Model):
:rtype: dict
"""
res = super()._get_specific_rendering_values(processing_values)
if self.provider != 'transfer':
if self.provider != 'custom':
return res
return {
'api_url': TransferController._accept_url,
'api_url': CustomController._process_url,
'reference': self.reference,
}
def _get_tx_from_notification_data(self, provider, notification_data):
""" Override of payment to find the transaction based on transfer data.
""" Override of payment to find the transaction based on custom data.
:param str provider: The provider of the acquirer that handled the transaction
:param dict notification_data: The notification feedback data
@@ -41,11 +41,11 @@ class PaymentTransaction(models.Model):
:raise: ValidationError if the data match no transaction
"""
tx = super()._get_tx_from_notification_data(provider, notification_data)
if provider != 'transfer' or len(tx) == 1:
if provider != 'custom' or len(tx) == 1:
return tx
reference = notification_data.get('reference')
tx = self.search([('reference', '=', reference), ('provider', '=', 'transfer')])
tx = self.search([('reference', '=', reference), ('provider', '=', 'custom')])
if not tx:
raise ValidationError(
"Wire Transfer: " + _("No transaction found matching reference %s.", reference)
@@ -53,29 +53,29 @@ class PaymentTransaction(models.Model):
return tx
def _process_notification_data(self, notification_data):
""" Override of payment to process the transaction based on transfer data.
""" Override of payment to process the transaction based on custom data.
Note: self.ensure_one()
:param dict notification_data: The transfer data
:param dict notification_data: The custom data
:return: None
"""
super()._process_notification_data(notification_data)
if self.provider != 'transfer':
if self.provider != 'custom':
return
_logger.info(
"validated transfer payment for transaction with reference %s: set as pending",
"validated custom payment for transaction with reference %s: set as pending",
self.reference
)
self._set_pending()
def _log_received_message(self):
""" Override of payment to remove transfer acquirer from the recordset.
""" Override of `payment` to remove custom acquirers from the recordset.
:return: None
"""
other_provider_txs = self.filtered(lambda t: t.provider != 'transfer')
other_provider_txs = self.filtered(lambda t: t.provider != 'custom')
super(PaymentTransaction, other_provider_txs)._log_received_message()
def _get_sent_message(self):
@@ -85,7 +85,7 @@ class PaymentTransaction(models.Model):
:rtype: str
"""
message = super()._get_sent_message()
if self.provider == 'transfer':
if self.provider == 'custom':
message = _(
"The customer has selected %(acq_name)s to make the payment.",
acq_name=self.acquirer_id.name

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

@@ -1,4 +1,4 @@
odoo.define('payment_transfer.post_processing', require => {
odoo.define('payment_custom.post_processing', require => {
'use strict';
const paymentPostProcessing = require('payment.post_processing');
@@ -6,7 +6,7 @@ odoo.define('payment_transfer.post_processing', require => {
paymentPostProcessing.include({
/**
* Don't wait for the transaction to be confirmed before redirecting customers to the
* landing route because Wire Transfer transactions remain in the state 'pending' forever.
* landing route because custom transactions remain in the state 'pending' forever.
*
* @override method from `payment.post_processing`
* @param {Object} display_values_list - The post-processing values of the transactions
@@ -15,7 +15,7 @@ odoo.define('payment_transfer.post_processing', require => {
// In almost every case, there will be a single transaction to display. If there are
// more than one transaction, the last one will most likely be the one that counts. We
// use that one to redirect the user to the landing page.
if (display_values_list.length > 0 && display_values_list[0].provider === 'transfer') {
if (display_values_list.length > 0 && display_values_list[0].provider === 'custom') {
window.location = display_values_list[0].landing_route;
} else {
return this._super(...arguments);
@@ -7,9 +7,9 @@
</form>
</template>
<template id="transfer_transaction_status" inherit_id="payment.transaction_status">
<template id="custom_transaction_status" inherit_id="payment.transaction_status">
<xpath expr="//div[@id='o_payment_status_alert']" position="inside">
<t t-if="tx.acquirer_id.sudo().provider == 'transfer'">
<t t-if="tx.acquirer_id.sudo().provider == 'custom'">
<div t-if="tx.reference">
<strong>Communication: </strong><span t-esc="tx.reference"/>
</div>
@@ -2,18 +2,18 @@
<odoo>
<record id="payment_acquirer_form" model="ir.ui.view">
<field name="name">Wire Transfer Acquirer Form</field>
<field name="name">Custom Acquirer Form</field>
<field name="model">payment.acquirer</field>
<field name="inherit_id" ref="payment.payment_acquirer_form"/>
<field name="arch" type="xml">
<field name="capture_manually" position="after">
<field name="qr_code" attrs="{'invisible': [('provider', '!=', 'transfer')]}" />
<field name="qr_code" attrs="{'invisible': [('provider', '!=', 'custom')]}" />
</field>
<xpath expr="//group[@name='payment_followup']" position="attributes">
<group name="payment_followup" position="attributes">
<attribute name="attrs">
{'invisible': [('provider', '=', 'transfer')]}
{'invisible': [('provider', '=', 'custom')]}
</attribute>
</xpath>
</group>
</field>
</record>
@@ -1,19 +0,0 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import pprint
from odoo import http
from odoo.http import request
_logger = logging.getLogger(__name__)
class TransferController(http.Controller):
_accept_url = '/payment/transfer/feedback'
@http.route(_accept_url, type='http', auth='public', methods=['POST'], csrf=False)
def transfer_form_feedback(self, **post):
_logger.info("handling redirection from Transfer with data:\n%s", pprint.pformat(post))
request.env['payment.transaction'].sudo()._handle_notification_data('transfer', post)
return request.redirect('/payment/status')
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record id="payment.payment_acquirer_transfer" model="payment.acquirer">
<field name="provider">transfer</field>
<field name="state">enabled</field>
<field name="is_published">True</field>
<field name="redirect_form_view_id" ref="redirect_form"/>
<!-- Clear the default value to trigger the computation of the message -->
<field name="pending_msg" eval="False"/>
</record>
</odoo>
+1 -1
View File
@@ -39,7 +39,7 @@ class PaymentTransaction(models.Model):
sales_orders = record.sale_order_ids.filtered(lambda so: so.state in ['draft', 'sent'])
sales_orders.filtered(lambda so: so.state == 'draft').with_context(tracking_disable=True).write({'state': 'sent'})
if record.acquirer_id.provider == 'transfer':
if record.acquirer_id.provider == 'custom':
for so in record.sale_order_ids:
so.reference = record._compute_sale_order_reference(so)
# send order confirmation mail
@@ -9,6 +9,14 @@ from odoo.tests import tagged
class TestWEventBoothExhibitorCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal):
def test_register(self):
if self.env['ir.module.module']._get('payment_custom').state != 'installed':
self.skipTest("Transfer acquirer is not installed")
self.env.ref('payment.payment_acquirer_transfer').write({
'state': 'enabled',
'is_published': True,
})
self.browser_js(
'/event',
'odoo.__DEBUG__.services["web_tour.tour"].run("webooth_exhibitor_register")',
@@ -11,15 +11,20 @@ odoo.define("website_event_booth_sale_exhibitor.tour", function (require) {
trigger: '.btn-primary[href="/shop/confirm_order"]',
run: 'click',
}, {
content: 'Pay your order',
trigger: '.btn-primary[name="o_payment_submit_button"]',
run: 'click',
content: "Select `Wire Transfer` payment method",
trigger: '#payment_method label:contains("Wire Transfer")',
}, {
trigger: 'h3:contains("Please use the following transfer details")',
run: function () {},
}]
content: "Pay",
//Either there are multiple payment methods, and one is checked, either there is only one, and therefore there are no radio inputs
// extra_trigger: '#payment_method input:checked,#payment_method:not(:has("input:radio:visible"))',
trigger: 'button[name="o_payment_submit_button"]:visible:not(:disabled)',
}, {
content: "Last step",
trigger: '.oe_website_sale_tx_status:contains("Please use the following transfer details")',
timeout: 30000,
}];
}
});
});
});
@@ -14,6 +14,15 @@ class TestUi(HttpCaseWithUserDemo):
def setUp(self):
super().setUp()
if self.env['ir.module.module']._get('payment_custom').state != 'installed':
self.skipTest("Transfer acquirer is not installed")
self.env.ref('payment.payment_acquirer_transfer').write({
'state': 'enabled',
'is_published': True,
})
self.event_2 = self.env['event.event'].create({
'name': 'Conference for Architects TEST',
'user_id': self.env.ref('base.user_admin').id,
@@ -54,7 +63,6 @@ class TestUi(HttpCaseWithUserDemo):
'seats_max': 2,
}])
# flush event to ensure having tickets available in the tests
self.env.flush_all()
@@ -67,12 +67,33 @@ class TestUi(HttpCaseWithUserDemo):
self.start_tour(self.env['website'].get_client_action_url('/shop'), 'shop', login='admin')
def test_02_admin_checkout(self):
if self.env['ir.module.module']._get('payment_custom').state != 'installed':
self.skipTest("Transfer acquirer is not installed")
self.env.ref('payment.payment_acquirer_transfer').write({
'state': 'enabled',
'is_published': True,
})
self.start_tour("/", 'shop_buy_product', login="admin")
def test_03_demo_checkout(self):
if self.env['ir.module.module']._get('payment_custom').state != 'installed':
self.skipTest("Transfer acquirer is not installed")
self.env.ref('payment.payment_acquirer_transfer').write({
'state': 'enabled',
'is_published': True,
})
self.start_tour("/", 'shop_buy_product', login="demo")
def test_04_admin_website_sale_tour(self):
if self.env['ir.module.module']._get('payment_custom').state != 'installed':
self.skipTest("Transfer acquirer is not installed")
self.env.ref('payment.payment_acquirer_transfer').write({
'state': 'enabled',
'is_published': True,
})
tax_group = self.env['account.tax.group'].create({'name': 'Tax 15%'})
tax = self.env['account.tax'].create({
'name': 'Tax 15%',
+1 -1
View File
@@ -8,7 +8,7 @@
'description': """
Allows customers to pay for their orders at a shop, instead of paying online.
""",
'depends': ['website_sale_delivery', 'payment_transfer'],
'depends': ['website_sale_delivery', 'payment_custom'],
'data': [
'data/website_sale_picking_data.xml',
'views/res_config_settings_views.xml',
@@ -3,10 +3,10 @@
<record id="payment_acquirer_onsite" model="payment.acquirer">
<field name="name">Pay in store when picking the product</field>
<field name="provider">transfer</field>
<field name="provider">custom</field>
<field name="state">enabled</field>
<field name="is_onsite_acquirer">true</field>
<field name="redirect_form_view_id" ref="payment_transfer.redirect_form"/>
<field name="redirect_form_view_id" ref="payment_custom.redirect_form"/>
<field name="pending_msg" type="html">
<p>
<i>Your order has been saved.</i> Please come to the store to pay for your products
@@ -23,6 +23,7 @@ class PaymentAcquirer(models.Model):
if not onsite_carriers:
compatible_acquirers -= self.env.ref('website_sale_picking.payment_acquirer_onsite')
# FIXME MULTI COMPANY !!!
# Show onsite payment only if it is a physical product
order = self.env['sale.order'].browse(sale_order_id).exists()
if not any(product.type in ['consu', 'product'] for product in order.order_line.product_id):