From de1eeee4eb7e44b6361b1a3a4f43222eea06c3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 28 Nov 2013 17:14:23 +0100 Subject: [PATCH 1/7] [FIX] payment_acquirer_paypal: data should be noupdate, otherwise each update erases the custom paypal account details bzr revid: tde@openerp.com-20131128161423-25thhf9xe9lgpn0i --- addons/payment_acquirer_paypal/data/paypal.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/payment_acquirer_paypal/data/paypal.xml b/addons/payment_acquirer_paypal/data/paypal.xml index f771c1a1ced..117a32dd39f 100644 --- a/addons/payment_acquirer_paypal/data/paypal.xml +++ b/addons/payment_acquirer_paypal/data/paypal.xml @@ -1,6 +1,6 @@ - + paypal @@ -10,7 +10,7 @@ dummy dummy dummy - dummy-Ud_oozfiDqqN3mUVLMmzPK71IZA3TM4taicUY2uaJYU1 + dummy From 27104e488808c83f4bdea921fa9248f5acc12206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 28 Nov 2013 17:15:16 +0100 Subject: [PATCH 2/7] [IMP] payment_acquirer: added company_id on the acquirer_model, to be able to know if the tx is domestic or international. Also added a fees field on the tx: should not be set by hand but by a specific acquirer. bzr revid: tde@openerp.com-20131128161516-mlu0z1v5bjpwzcrv --- addons/payment_acquirer/models/payment_acquirer.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/payment_acquirer/models/payment_acquirer.py b/addons/payment_acquirer/models/payment_acquirer.py index de61c77760c..b78021cea01 100644 --- a/addons/payment_acquirer/models/payment_acquirer.py +++ b/addons/payment_acquirer/models/payment_acquirer.py @@ -48,6 +48,7 @@ class PaymentAcquirer(osv.Model): _columns = { 'name': fields.char('Name', required=True), + 'company_id': fields.many2one('res.company', 'Company', required=True), 'message': fields.html('Message', help='Message displayed to help payment and validation'), 'view_template_id': fields.many2one('ir.ui.view', 'Form Button Template', required=True), 'env': fields.selection( @@ -58,8 +59,9 @@ class PaymentAcquirer(osv.Model): } _defaults = { - 'portal_published': True, + 'company_id': lambda self, cr, uid, obj, ctx=None: self.pool['res.users'].browse(cr, uid, uid).company_id.id, 'env': 'test', + 'portal_published': True, } def _check_required_if_provider(self, cr, uid, ids, context=None): @@ -198,6 +200,7 @@ class PaymentTransaction(osv.Model): 'amount': fields.float('Amount', required=True, help='Amount in cents', track_visibility='always'), + 'fees': fields.float('Fees', help='Fees amount; set by the system because depends on the acquirer'), 'currency_id': fields.many2one('res.currency', 'Currency', required=True), 'reference': fields.char('Order Reference', required=True), # duplicate partner / transaction data to store the values at transaction time From ad2bdf6d9411e8d53bf72cb4da484e60e88d6c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 28 Nov 2013 17:17:07 +0100 Subject: [PATCH 3/7] [IMP] payment_acquirer_paypal: added fees computation on paypal acquirer. paypal acquirer model: added paypal_fee_active and paypal_fee_* fields: fix and variable fees, for domestic and international transactions. updated views accordingly + cleaned paypal form view. updated tests updated form, adding handling input in the paypal button that is the input controlling the fees in the tx process. When creating a paypal tx, it dynamically computes fees. bzr revid: tde@openerp.com-20131128161707-ignhrlphts47wk72 --- .../views/payment_acquirer.xml | 58 +++++++++++-------- .../payment_acquirer_paypal/models/paypal.py | 50 +++++++++++++++- .../tests/test_paypal.py | 34 +++++++++++ .../views/payment_acquirer.xml | 32 +++++++--- .../payment_acquirer_paypal/views/paypal.xml | 4 ++ 5 files changed, 143 insertions(+), 35 deletions(-) diff --git a/addons/payment_acquirer/views/payment_acquirer.xml b/addons/payment_acquirer/views/payment_acquirer.xml index 916f4915e66..09c209f7dee 100644 --- a/addons/payment_acquirer/views/payment_acquirer.xml +++ b/addons/payment_acquirer/views/payment_acquirer.xml @@ -12,32 +12,41 @@ payment.acquirer
- - - - - - + +
@@ -84,6 +93,7 @@ + diff --git a/addons/payment_acquirer_paypal/models/paypal.py b/addons/payment_acquirer_paypal/models/paypal.py index 50b16d0e818..40c14ccbe36 100644 --- a/addons/payment_acquirer_paypal/models/paypal.py +++ b/addons/payment_acquirer_paypal/models/paypal.py @@ -27,6 +27,13 @@ class AcquirerPaypal(osv.Model): 'paypal_username': fields.char('Username', required_if_provider='paypal'), 'paypal_tx_url': fields.char('Transaction URL', required_if_provider='paypal'), 'paypal_use_ipn': fields.boolean('Use IPN'), + # Fees + 'paypal_fee_active': fields.boolean('Compute fees'), + 'paypal_fee_dom_fixed': fields.float('Fixed domestic fees'), + 'paypal_fee_dom_var': fields.float('Variable domestic fees (in percents)'), + 'paypal_fee_int_fixed': fields.float('Fixed international fees'), + 'paypal_fee_int_var': fields.float('Variable international fees (in percents)'), + # Server 2 server 'paypal_api_enabled': fields.boolean('Use Rest API'), 'paypal_api_username': fields.char('Rest API Username'), 'paypal_api_password': fields.char('Rest API Password'), @@ -35,11 +42,33 @@ class AcquirerPaypal(osv.Model): } _defaults = { - 'paypal_use_ipn': True, - 'paypal_api_enabled': False, 'paypal_tx_url': 'https://www.sandbox.paypal.com/cgi-bin/webscr', + 'paypal_use_ipn': True, + 'paypal_fee_active': False, + 'paypal_fee_dom_fixed': 0.35, + 'paypal_fee_dom_var': 3.4, + 'paypal_fee_int_fixed': 0.35, + 'paypal_fee_int_var': 3.9, + 'paypal_api_enabled': False, } + def paypal_compute_fees(self, cr, uid, id, amount, country_id, context=None): + """ Compute paypal fees. + + :param float amount: the amount to pay + :param integer country_id: an ID of a res.country, or None. This is + the customer's country, to be compared to + the acquirer company country. + :return float fees: computed fees + """ + acquirer = self.browse(cr, uid, id, context=context) + country = self.pool['res.country'].browse(cr, uid, country_id, context=context) + if country and acquirer.company_id.country_id.id == country.id: + fees = amount * (1 + acquirer.paypal_fee_dom_var / 100.0) + acquirer.paypal_fee_dom_fixed - amount + else: + fees = amount * (1 + acquirer.paypal_fee_int_var / 100.0) + acquirer.paypal_fee_int_fixed - amount + return fees + def paypal_form_generate_values(self, cr, uid, id, reference, amount, currency, partner_id=False, partner_values=None, tx_custom_values=None, context=None): if partner_values is None: partner_values = {} @@ -48,6 +77,11 @@ class AcquirerPaypal(osv.Model): partner = None if partner_id: partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context) + if partner: + country_id = partner.country_id.id + else: + country_ids = self.pool['res.country'].search(cr, uid, [('name', '=', partner_values.get('country_name'))], context=context) + country_id = country_ids and country_ids[0] or None tx_values = { 'cmd': '_xclick', 'business': acquirer.paypal_email_id, @@ -66,6 +100,8 @@ class AcquirerPaypal(osv.Model): 'notify_url': '%s' % urlparse.urljoin(base_url, PaypalController._notify_url), 'cancel_return': '%s' % urlparse.urljoin(base_url, PaypalController._cancel_url), } + if acquirer.paypal_fee_active: + tx_values['handling'] = '%.2f' % self.paypal_compute_fees(cr, uid, acquirer.id, amount, country_id, context=context) if tx_custom_values and tx_custom_values.get('return_url'): tx_values['custom'] = json.dumps({'return_url': '%s' % tx_custom_values.pop('return_url')}) if tx_custom_values: @@ -112,6 +148,16 @@ class TxPaypal(osv.Model): 'paypal_txn_type': fields.char('Transaction type'), } + # -------------------------------------------------- + # CRUD + # -------------------------------------------------- + + def paypal_create(self, cr, uid, values, context=None): + paypal = self.pool['payment.acquirer'].browse(cr, uid, values['acquirer_id'], context=context) + if paypal.paypal_fee_active: + values['fees'] = self.pool['payment.acquirer'].paypal_compute_fees(cr, uid, paypal.id, values.get('amount', 0.0), values.get('country_id'), context=context) + return values + # -------------------------------------------------- # FORM RELATED METHODS # -------------------------------------------------- diff --git a/addons/payment_acquirer_paypal/tests/test_paypal.py b/addons/payment_acquirer_paypal/tests/test_paypal.py index d3d9bfb7087..9b2c65272e6 100644 --- a/addons/payment_acquirer_paypal/tests/test_paypal.py +++ b/addons/payment_acquirer_paypal/tests/test_paypal.py @@ -95,6 +95,9 @@ class PaypalForm(PaypalCommon): def test_10_paypal_form_render(self): cr, uid, context = self.cr, self.uid, {} + # be sure not to do stupid things + paypal = self.payment_acquirer.browse(cr, uid, self.paypal_id, context) + self.assertEqual(paypal.env, 'test', 'test without test env') # ---------------------------------------- # Test: button direct rendering @@ -139,9 +142,40 @@ class PaypalForm(PaypalCommon): 'paypal: wrong value for form: received %s instead of %s' % (form_input.get('value'), form_values[form_input.get('name')]) ) + def test_11_paypal_form_with_fees(self): + cr, uid, context = self.cr, self.uid, {} + self.payment_acquirer.write(cr, uid, self.paypal_id, { + 'paypal_fee_active': True, + }, context) + + # be sure not to do stupid things + paypal = self.payment_acquirer.browse(self.cr, self.uid, self.paypal_id, None) + self.assertEqual(paypal.env, 'test', 'test without test env') + + # render the button + res = self.payment_acquirer.render( + cr, uid, self.paypal_id, + 'test_ref0', 12.50, self.currency_euro, + partner_id=None, + partner_values=self.buyer_values, + context=context) + + # check form result + handling_found = False + tree = objectify.fromstring(res) + self.assertEqual(tree.get('action'), 'https://www.sandbox.paypal.com/cgi-bin/webscr', 'paypal: wrong form POST url') + for form_input in tree.input: + if form_input.get('name') in ['handling']: + handling_found = True + self.assertEqual(form_input.get('value'), '0.84', 'paypal: wrong computed fees') + self.assertTrue(handling_found, 'paypal: paypal_fee_active did not add handling input in rendered form') + @mute_logger('openerp.addons.payment_acquirer_paypal.models.paypal', 'ValidationError') def test_20_paypal_form_management(self): cr, uid, context = self.cr, self.uid, {} + # be sure not to do stupid things + paypal = self.payment_acquirer.browse(cr, uid, self.paypal_id, context) + self.assertEqual(paypal.env, 'test', 'test without test env') # typical data posted by paypal after client has successfully paid paypal_post_data = { diff --git a/addons/payment_acquirer_paypal/views/payment_acquirer.xml b/addons/payment_acquirer_paypal/views/payment_acquirer.xml index d0d97cdfa12..8a6c36ac7b2 100644 --- a/addons/payment_acquirer_paypal/views/payment_acquirer.xml +++ b/addons/payment_acquirer_paypal/views/payment_acquirer.xml @@ -7,15 +7,29 @@ payment.acquirer - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/addons/payment_acquirer_paypal/views/paypal.xml b/addons/payment_acquirer_paypal/views/paypal.xml index 329714fb0a5..a6f401f6c3c 100644 --- a/addons/payment_acquirer_paypal/views/paypal.xml +++ b/addons/payment_acquirer_paypal/views/paypal.xml @@ -9,6 +9,10 @@ + + + + From 6564248f9678536e2786d8316b0aca1f876b6705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 28 Nov 2013 17:34:24 +0100 Subject: [PATCH 4/7] [CLEAN] payemnt_acquirer: moved some code for cleaning bzr revid: tde@openerp.com-20131128163424-0m42q8hnert8gemk --- .../models/payment_acquirer.py | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/addons/payment_acquirer/models/payment_acquirer.py b/addons/payment_acquirer/models/payment_acquirer.py index b78021cea01..a3f778d43fa 100644 --- a/addons/payment_acquirer/models/payment_acquirer.py +++ b/addons/payment_acquirer/models/payment_acquirer.py @@ -76,6 +76,13 @@ class PaymentAcquirer(osv.Model): (_check_required_if_provider, 'Required fields not filled', ['required for this provider']), ] + def get_form_action_url(self, cr, uid, id, context=None): + """ Returns the form action URL, for form-based acquirer implementations. """ + acquirer = self.browse(cr, uid, id, context=context) + if hasattr(self, '%s_get_form_action_url' % acquirer.name): + return getattr(self, '%s_get_form_action_url' % acquirer.name)(cr, uid, id, context=context) + return False + def render(self, cr, uid, id, reference, amount, currency, tx_id=None, partner_id=False, partner_values=None, tx_custom_values=None, context=None): """ Renders the form template of the given acquirer as a qWeb template. All templates should handle: @@ -118,13 +125,14 @@ class PaymentAcquirer(osv.Model): if partner_id: partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context) acquirer = self.browse(cr, uid, id, context=context) - method_name = '%s_form_generate_values' % (acquirer.name) - if tx_id and hasattr(self.pool['payment.transaction'], method_name): - method = getattr(self.pool['payment.transaction'], method_name) + # call _form_generate_values to update the tx dict with acqurier specific values + cust_method_name = '%s_form_generate_values' % (acquirer.name) + if tx_id and hasattr(self.pool['payment.transaction'], cust_method_name): + method = getattr(self.pool['payment.transaction'], cust_method_name) tx_values = method(cr, uid, tx_id, tx_custom_values, context=context) - elif hasattr(self, method_name): - method = getattr(self, method_name) + elif hasattr(self, cust_method_name): + method = getattr(self, cust_method_name) tx_values = method(cr, uid, id, reference, amount, currency, partner_id, partner_values, tx_custom_values, context=context) else: tx_values = tx_custom_values @@ -143,12 +151,6 @@ class PaymentAcquirer(osv.Model): # because render accepts view ids but not qweb -> need to find the xml_id return self.pool['ir.ui.view'].render(cr, uid, acquirer.view_template_id.xml_id, qweb_context, engine='ir.qweb', context=context) - def get_form_action_url(self, cr, uid, id, context=None): - acquirer = self.browse(cr, uid, id, context=context) - if hasattr(self, '%s_get_form_action_url' % acquirer.name): - return getattr(self, '%s_get_form_action_url' % acquirer.name)(cr, uid, id, context=context) - return False - class PaymentTransaction(osv.Model): """ Transaction Model. Each specific acquirer can extend the model by adding From 5ee3495ccbcf300d9bdbbcbaa6dfe677bab3dc61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 28 Nov 2013 18:08:12 +0100 Subject: [PATCH 5/7] [MOV] payment_acquirer: moved fees computation into generic computation. Now acquirer have access to a fees key in the tx_values they receive for generating the buttons. Fees are computed by calling _compute_fees. bzr revid: tde@openerp.com-20131128170812-1p3ipj85e1rvuf8l --- .../models/payment_acquirer.py | 54 +++++++++++++++---- .../payment_acquirer_paypal/models/paypal.py | 20 ++----- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/addons/payment_acquirer/models/payment_acquirer.py b/addons/payment_acquirer/models/payment_acquirer.py index a3f778d43fa..4fc92c7d891 100644 --- a/addons/payment_acquirer/models/payment_acquirer.py +++ b/addons/payment_acquirer/models/payment_acquirer.py @@ -83,9 +83,29 @@ class PaymentAcquirer(osv.Model): return getattr(self, '%s_get_form_action_url' % acquirer.name)(cr, uid, id, context=context) return False - def render(self, cr, uid, id, reference, amount, currency, tx_id=None, partner_id=False, partner_values=None, tx_custom_values=None, context=None): + def form_preprocess_values(self, cr, uid, id, reference, amount, currency_id, tx_id, partner_id, partner_values, tx_custom_values, context=None): + acquirer = self.browse(cr, uid, id, context=context) + tx_values = tx_custom_values + + # compute country + if partner_id: + partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context) + tx_values['country_id'] = partner.country_id.id + elif partner_values and partner_values.get('country_name'): + country_ids = self.pool['res.country'].search(cr, uid, [('name', '=', partner_values.get('country_name'))], context=context) + tx_values['country_id'] = country_ids and country_ids[0] or None + else: + tx_values['country_id'] = False + + # compute fees + if hasattr(self, '%s_compute_fees' % acquirer.name): + tx_values['fees'] = getattr(self, '%s_compute_fees' % acquirer.name)(cr, uid, id, amount, currency_id, tx_values.get('country_id'), context=None) + + return tx_values + + def render(self, cr, uid, id, reference, amount, currency_id, tx_id=None, partner_id=False, partner_values=None, tx_custom_values=None, context=None): """ Renders the form template of the given acquirer as a qWeb template. - All templates should handle: + All templates will receive: - acquirer: the payment.acquirer browse record - user: the current user browse record @@ -99,11 +119,11 @@ class PaymentAcquirer(osv.Model): in each provider, depending on the features it offers: - 'feedback_url': feedback URL, controler that manage answer of the acquirer - (without base url) + (without base url) -> FIXME - 'return_url': URL for coming back after payment validation (wihout - base url) - - 'cancel_url': URL if the client cancels the payment - - 'error_url': URL if there is an issue with the payment + base url) -> FIXME + - 'cancel_url': URL if the client cancels the payment -> FIXME + - 'error_url': URL if there is an issue with the payment -> FIXME - context: OpenERP context dictionary @@ -121,21 +141,25 @@ class PaymentAcquirer(osv.Model): """ if context is None: context = {} + if tx_custom_values is None: + tx_custom_values = {} partner = None if partner_id: partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context) acquirer = self.browse(cr, uid, id, context=context) + currency = self.pool['res.currency'].browse(cr, uid, currency_id, context=context) + + # pre-process values + tx_values = self.form_preprocess_values(cr, uid, id, reference, amount, currency, tx_id, partner_id, partner_values, tx_custom_values, context=context) # call _form_generate_values to update the tx dict with acqurier specific values cust_method_name = '%s_form_generate_values' % (acquirer.name) if tx_id and hasattr(self.pool['payment.transaction'], cust_method_name): method = getattr(self.pool['payment.transaction'], cust_method_name) - tx_values = method(cr, uid, tx_id, tx_custom_values, context=context) + tx_values = method(cr, uid, tx_id, tx_values, context=context) elif hasattr(self, cust_method_name): method = getattr(self, cust_method_name) - tx_values = method(cr, uid, id, reference, amount, currency, partner_id, partner_values, tx_custom_values, context=context) - else: - tx_values = tx_custom_values + tx_values = method(cr, uid, id, reference, amount, currency, partner_id, partner_values, tx_values, context=context) qweb_context = { 'acquirer': acquirer, @@ -230,12 +254,22 @@ class PaymentTransaction(osv.Model): } def create(self, cr, uid, values, context=None): + Acquirer = self.pool['payment.acquirer'] + if values.get('partner_id'): # @TDENOTE: not sure values.update(self.on_change_partner_id(cr, uid, None, values.get('partner_id'), context=context)['values']) # call custom create method if defined (i.e. ogone_create for ogone) if values.get('acquirer_id'): acquirer = self.pool['payment.acquirer'].browse(cr, uid, values.get('acquirer_id'), context=context) + + # compute fees + custom_method_name = '%s_compute_fees' % acquirer.name + if hasattr(Acquirer, custom_method_name): + values['fees'] = getattr(Acquirer, custom_method_name)( + cr, uid, acquirer.id, values.get('amount', 0.0), values.get('currency_id'), values.get('country_id'), context=None) + + # custom create custom_method_name = '%s_create' % acquirer.name if hasattr(self, custom_method_name): values.update(getattr(self, custom_method_name)(cr, uid, values, context=context)) diff --git a/addons/payment_acquirer_paypal/models/paypal.py b/addons/payment_acquirer_paypal/models/paypal.py index 40c14ccbe36..065dde95588 100644 --- a/addons/payment_acquirer_paypal/models/paypal.py +++ b/addons/payment_acquirer_paypal/models/paypal.py @@ -52,7 +52,7 @@ class AcquirerPaypal(osv.Model): 'paypal_api_enabled': False, } - def paypal_compute_fees(self, cr, uid, id, amount, country_id, context=None): + def paypal_compute_fees(self, cr, uid, id, amount, currency_id, country_id, context=None): """ Compute paypal fees. :param float amount: the amount to pay @@ -77,11 +77,7 @@ class AcquirerPaypal(osv.Model): partner = None if partner_id: partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context) - if partner: - country_id = partner.country_id.id - else: - country_ids = self.pool['res.country'].search(cr, uid, [('name', '=', partner_values.get('country_name'))], context=context) - country_id = country_ids and country_ids[0] or None + tx_values = { 'cmd': '_xclick', 'business': acquirer.paypal_email_id, @@ -101,7 +97,7 @@ class AcquirerPaypal(osv.Model): 'cancel_return': '%s' % urlparse.urljoin(base_url, PaypalController._cancel_url), } if acquirer.paypal_fee_active: - tx_values['handling'] = '%.2f' % self.paypal_compute_fees(cr, uid, acquirer.id, amount, country_id, context=context) + tx_values['handling'] = '%.2f' % tx_custom_values.pop('fees', 0.0) if tx_custom_values and tx_custom_values.get('return_url'): tx_values['custom'] = json.dumps({'return_url': '%s' % tx_custom_values.pop('return_url')}) if tx_custom_values: @@ -148,16 +144,6 @@ class TxPaypal(osv.Model): 'paypal_txn_type': fields.char('Transaction type'), } - # -------------------------------------------------- - # CRUD - # -------------------------------------------------- - - def paypal_create(self, cr, uid, values, context=None): - paypal = self.pool['payment.acquirer'].browse(cr, uid, values['acquirer_id'], context=context) - if paypal.paypal_fee_active: - values['fees'] = self.pool['payment.acquirer'].paypal_compute_fees(cr, uid, paypal.id, values.get('amount', 0.0), values.get('country_id'), context=context) - return values - # -------------------------------------------------- # FORM RELATED METHODS # -------------------------------------------------- From 7896d2e745e2f8be74aaa8943acdeb724056fae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 2 Dec 2013 16:59:41 +0100 Subject: [PATCH 6/7] [MOV] payment_acquirer: moved paypal_fee_* fields to fees_*, standard fields for an acquirer. bzr revid: tde@openerp.com-20131202155941-b8nbujgwf57fol2v --- .../models/payment_acquirer.py | 6 +++++ .../views/payment_acquirer.xml | 13 +++++++++-- .../payment_acquirer_paypal/models/paypal.py | 22 +++++++------------ .../tests/test_paypal.py | 4 ++-- .../views/payment_acquirer.xml | 11 ---------- 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/addons/payment_acquirer/models/payment_acquirer.py b/addons/payment_acquirer/models/payment_acquirer.py index 4fc92c7d891..101510501db 100644 --- a/addons/payment_acquirer/models/payment_acquirer.py +++ b/addons/payment_acquirer/models/payment_acquirer.py @@ -56,6 +56,12 @@ class PaymentAcquirer(osv.Model): string='Environment'), 'portal_published': fields.boolean('Visible in Portal', help="Make this payment acquirer available (Customer invoices, etc.)"), + # Fees + 'fees_active': fields.boolean('Compute fees'), + 'fees_dom_fixed': fields.float('Fixed domestic fees'), + 'fees_dom_var': fields.float('Variable domestic fees (in percents)'), + 'fees_int_fixed': fields.float('Fixed international fees'), + 'fees_int_var': fields.float('Variable international fees (in percents)'), } _defaults = { diff --git a/addons/payment_acquirer/views/payment_acquirer.xml b/addons/payment_acquirer/views/payment_acquirer.xml index 09c209f7dee..7377f4aedb3 100644 --- a/addons/payment_acquirer/views/payment_acquirer.xml +++ b/addons/payment_acquirer/views/payment_acquirer.xml @@ -17,11 +17,20 @@ - - + + + + + + + diff --git a/addons/payment_acquirer_paypal/models/paypal.py b/addons/payment_acquirer_paypal/models/paypal.py index 065dde95588..b2e15f4d894 100644 --- a/addons/payment_acquirer_paypal/models/paypal.py +++ b/addons/payment_acquirer_paypal/models/paypal.py @@ -27,12 +27,6 @@ class AcquirerPaypal(osv.Model): 'paypal_username': fields.char('Username', required_if_provider='paypal'), 'paypal_tx_url': fields.char('Transaction URL', required_if_provider='paypal'), 'paypal_use_ipn': fields.boolean('Use IPN'), - # Fees - 'paypal_fee_active': fields.boolean('Compute fees'), - 'paypal_fee_dom_fixed': fields.float('Fixed domestic fees'), - 'paypal_fee_dom_var': fields.float('Variable domestic fees (in percents)'), - 'paypal_fee_int_fixed': fields.float('Fixed international fees'), - 'paypal_fee_int_var': fields.float('Variable international fees (in percents)'), # Server 2 server 'paypal_api_enabled': fields.boolean('Use Rest API'), 'paypal_api_username': fields.char('Rest API Username'), @@ -44,11 +38,11 @@ class AcquirerPaypal(osv.Model): _defaults = { 'paypal_tx_url': 'https://www.sandbox.paypal.com/cgi-bin/webscr', 'paypal_use_ipn': True, - 'paypal_fee_active': False, - 'paypal_fee_dom_fixed': 0.35, - 'paypal_fee_dom_var': 3.4, - 'paypal_fee_int_fixed': 0.35, - 'paypal_fee_int_var': 3.9, + 'fees_active': False, + 'fees_dom_fixed': 0.35, + 'fees_dom_var': 3.4, + 'fees_int_fixed': 0.35, + 'fees_int_var': 3.9, 'paypal_api_enabled': False, } @@ -64,9 +58,9 @@ class AcquirerPaypal(osv.Model): acquirer = self.browse(cr, uid, id, context=context) country = self.pool['res.country'].browse(cr, uid, country_id, context=context) if country and acquirer.company_id.country_id.id == country.id: - fees = amount * (1 + acquirer.paypal_fee_dom_var / 100.0) + acquirer.paypal_fee_dom_fixed - amount + fees = amount * (1 + acquirer.fees_dom_var / 100.0) + acquirer.fees_dom_fixed - amount else: - fees = amount * (1 + acquirer.paypal_fee_int_var / 100.0) + acquirer.paypal_fee_int_fixed - amount + fees = amount * (1 + acquirer.fees_int_var / 100.0) + acquirer.fees_int_fixed - amount return fees def paypal_form_generate_values(self, cr, uid, id, reference, amount, currency, partner_id=False, partner_values=None, tx_custom_values=None, context=None): @@ -96,7 +90,7 @@ class AcquirerPaypal(osv.Model): 'notify_url': '%s' % urlparse.urljoin(base_url, PaypalController._notify_url), 'cancel_return': '%s' % urlparse.urljoin(base_url, PaypalController._cancel_url), } - if acquirer.paypal_fee_active: + if acquirer.fees_active: tx_values['handling'] = '%.2f' % tx_custom_values.pop('fees', 0.0) if tx_custom_values and tx_custom_values.get('return_url'): tx_values['custom'] = json.dumps({'return_url': '%s' % tx_custom_values.pop('return_url')}) diff --git a/addons/payment_acquirer_paypal/tests/test_paypal.py b/addons/payment_acquirer_paypal/tests/test_paypal.py index 9b2c65272e6..c29e605e1c8 100644 --- a/addons/payment_acquirer_paypal/tests/test_paypal.py +++ b/addons/payment_acquirer_paypal/tests/test_paypal.py @@ -145,7 +145,7 @@ class PaypalForm(PaypalCommon): def test_11_paypal_form_with_fees(self): cr, uid, context = self.cr, self.uid, {} self.payment_acquirer.write(cr, uid, self.paypal_id, { - 'paypal_fee_active': True, + 'fees_active': True, }, context) # be sure not to do stupid things @@ -168,7 +168,7 @@ class PaypalForm(PaypalCommon): if form_input.get('name') in ['handling']: handling_found = True self.assertEqual(form_input.get('value'), '0.84', 'paypal: wrong computed fees') - self.assertTrue(handling_found, 'paypal: paypal_fee_active did not add handling input in rendered form') + self.assertTrue(handling_found, 'paypal: fees_active did not add handling input in rendered form') @mute_logger('openerp.addons.payment_acquirer_paypal.models.paypal', 'ValidationError') def test_20_paypal_form_management(self): diff --git a/addons/payment_acquirer_paypal/views/payment_acquirer.xml b/addons/payment_acquirer_paypal/views/payment_acquirer.xml index 8a6c36ac7b2..6734b2fdcc5 100644 --- a/addons/payment_acquirer_paypal/views/payment_acquirer.xml +++ b/addons/payment_acquirer_paypal/views/payment_acquirer.xml @@ -19,17 +19,6 @@ - - - - - - - From 39e62670491083dd481eabe473bf740de955bb57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 2 Dec 2013 17:25:17 +0100 Subject: [PATCH 7/7] [FIX] paypal: correctly compute fees bzr revid: tde@openerp.com-20131202162517-39jdtg83l08yxdxm --- addons/payment_acquirer_paypal/models/paypal.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/payment_acquirer_paypal/models/paypal.py b/addons/payment_acquirer_paypal/models/paypal.py index b2e15f4d894..8bbd540372b 100644 --- a/addons/payment_acquirer_paypal/models/paypal.py +++ b/addons/payment_acquirer_paypal/models/paypal.py @@ -56,6 +56,8 @@ class AcquirerPaypal(osv.Model): :return float fees: computed fees """ acquirer = self.browse(cr, uid, id, context=context) + if not acquirer.fees_active: + return 0.0 country = self.pool['res.country'].browse(cr, uid, country_id, context=context) if country and acquirer.company_id.country_id.id == country.id: fees = amount * (1 + acquirer.fees_dom_var / 100.0) + acquirer.fees_dom_fixed - amount