[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
This commit is contained in:
parent
27104e4888
commit
ad2bdf6d94
|
@ -12,32 +12,41 @@
|
|||
<field name="model">payment.acquirer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment Acquirer" version="7.0">
|
||||
<group name="acquirer_base">
|
||||
<field name="name"/>
|
||||
<field name="portal_published"/>
|
||||
<field name="env"/>
|
||||
<field name="message"/>
|
||||
<label for="view_template_id"/>
|
||||
<div>
|
||||
<field name="view_template_id" nolabel="1"/>
|
||||
<sheet>
|
||||
<group name="acquirer_base">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="company_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="portal_published"/>
|
||||
<field name="env"/>
|
||||
</group>
|
||||
</group>
|
||||
<group name="acquirer_display">
|
||||
<field name="message"/>
|
||||
<label for="view_template_id"/>
|
||||
<div>
|
||||
This is an HTML form template to submit a payment through this acquirer.
|
||||
The template will be rendered with qWeb, so it may use qWeb expressions.
|
||||
The qWeb evaluation context provides:
|
||||
<ul>
|
||||
<li>acquirer: payment.acquirer browse record</li>
|
||||
<li>user: current user browse record</li>
|
||||
<li>reference: the transaction reference number</li>
|
||||
<li>currency: the transaction currency browse record</li>
|
||||
<li>amount: the transaction amount, a float</li>
|
||||
<li>partner: the buyer partner browse record, not necessarily set</li>
|
||||
<li>partner_values: specific values about the buyer, for example coming from a shipping form</li>
|
||||
<li>tx_values: specific transaction values</li>
|
||||
<li>context: the current context dictionary</li>
|
||||
</ul>
|
||||
<field name="view_template_id" nolabel="1"/>
|
||||
<div>
|
||||
This is an HTML form template to submit a payment through this acquirer.
|
||||
The template will be rendered with qWeb, so it may use qWeb expressions.
|
||||
The qWeb evaluation context provides:
|
||||
<ul>
|
||||
<li>acquirer: payment.acquirer browse record</li>
|
||||
<li>user: current user browse record</li>
|
||||
<li>reference: the transaction reference number</li>
|
||||
<li>currency: the transaction currency browse record</li>
|
||||
<li>amount: the transaction amount, a float</li>
|
||||
<li>partner: the buyer partner browse record, not necessarily set</li>
|
||||
<li>partner_values: specific values about the buyer, for example coming from a shipping form</li>
|
||||
<li>tx_values: specific transaction values</li>
|
||||
<li>context: the current context dictionary</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -84,6 +93,7 @@
|
|||
<group>
|
||||
<field name="reference"/>
|
||||
<field name="amount"/>
|
||||
<field name="fees"/>
|
||||
<field name="currency_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="partner_name"/>
|
||||
|
|
|
@ -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
|
||||
# --------------------------------------------------
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -7,15 +7,29 @@
|
|||
<field name="model">payment.acquirer</field>
|
||||
<field name="inherit_id" ref="payment_acquirer.acquirer_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//group[@name="acquirer_base"]' position='after'>
|
||||
<group string="Paypal Details"
|
||||
attrs="{'invisible': [('name', '!=', 'paypal')]}">
|
||||
<field name="paypal_email_id"/>
|
||||
<field name="paypal_username"/>
|
||||
<field name="paypal_use_ipn"/>
|
||||
<field name="paypal_api_enabled"/>
|
||||
<field name="paypal_api_username"/>
|
||||
<field name="paypal_api_password"/>
|
||||
<xpath expr='//group[@name="acquirer_display"]' position='after'>
|
||||
<group attrs="{'invisible': [('name', '!=', 'paypal')]}">
|
||||
<group>
|
||||
<field name="paypal_email_id"/>
|
||||
<field name="paypal_username"/>
|
||||
<field name="paypal_use_ipn"/>
|
||||
<field name="paypal_api_enabled"/>
|
||||
<field name="paypal_api_username"
|
||||
attrs="{'invisible': [('paypal_api_enabled', '=', False)]}"/>
|
||||
<field name="paypal_api_password"
|
||||
attrs="{'invisible': [('paypal_api_enabled', '=', False)]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="paypal_fee_active"/>
|
||||
<field name="paypal_fee_dom_fixed"
|
||||
attrs="{'invisible': [('paypal_fee_active', '=', False)]}"/>
|
||||
<field name="paypal_fee_dom_var"
|
||||
attrs="{'invisible': [('paypal_fee_active', '=', False)]}"/>
|
||||
<field name="paypal_fee_int_fixed"
|
||||
attrs="{'invisible': [('paypal_fee_active', '=', False)]}"/>
|
||||
<field name="paypal_fee_int_var"
|
||||
attrs="{'invisible': [('paypal_fee_active', '=', False)]}"/>
|
||||
</group>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
<input type="hidden" name="item_name" t-att-value="tx_values['item_name']"/>
|
||||
<input type="hidden" name="item_number" t-att-value="tx_values['item_number']"/>
|
||||
<input type="hidden" name="amount" t-att-value="tx_values['amount']"/>
|
||||
<t t-if="'handling' in tx_values">
|
||||
<input type="hidden" name="handling" t-att-value="tx_values['handling']"/>
|
||||
</t>
|
||||
<input type="hidden" name="amount" t-att-value="tx_values['amount']"/>
|
||||
<input type="hidden" name="currency_code" t-att-value="tx_values['currency_code']"/>
|
||||
<!-- partner / address data -->
|
||||
<input type="hidden" name="address1" t-att-value="tx_values['address1']"/>
|
||||
|
|
Loading…
Reference in New Issue