[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:
@@ -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',
|
||||
@@ -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>
|
||||
+4
-19
@@ -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([
|
||||
+14
-14
@@ -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 |
+3
-3
@@ -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);
|
||||
+2
-2
@@ -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>
|
||||
+5
-5
@@ -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>
|
||||
@@ -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")',
|
||||
|
||||
+12
-7
@@ -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%',
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user