Merge lp:~openerp-dev/openobject-addons/trunk-paypal-transaction-fees-sgo into lp:openobject-addons

Proposed by Sanjay Gohel (Open ERP)
Status: Needs review
Proposed branch: lp:~openerp-dev/openobject-addons/trunk-paypal-transaction-fees-sgo
Merge into: lp:openobject-addons
Diff against target: 389 lines (+182/-27)
11 files modified
account/edi/invoice.py (+2/-0)
account/project/wizard/account_analytic_chart_view.xml (+5/-2)
account/res_config_view.xml (+12/-11)
portal/acquirer.py (+46/-12)
portal/acquirer_view.xml (+1/-0)
portal/portal_data.xml (+1/-0)
portal_sale/portal_sale.py (+15/-0)
portal_sale/res_config.py (+58/-1)
portal_sale/res_config_view.xml (+36/-1)
portal_sale/security/portal_security.xml (+4/-0)
sale/edi/sale_order.py (+2/-0)
To merge this branch: bzr merge lp:~openerp-dev/openobject-addons/trunk-paypal-transaction-fees-sgo
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+163107@code.launchpad.net

This proposal supersedes a proposal from 2013-05-01.

Description of the change

Hello,

  Have done all improvement related paypal transaction fees given in specification.

 - Add a new paypal section under the 'eInvoicing & Payments' and all details related paypal in this section.
 - Add checkbox named ‘Charge Paypal fees to customers’ under paypal account.
 - Add fields below this check box which is visible after checked for domestic and international charges of paypal.
 - Display fees in paypal widget shown on invoice and sale order which comes after calculation based on domestic and international
 - And also added shipping and handling in paypal url.
- when country is not defined in company help for this field's will be changed

Thanks.

To post a comment you must log in.
8700. By Sanjay Gohel (Open ERP)

[IMP]improve string for international paypal charges help. and changed string where needed

8701. By Sanjay Gohel (Open ERP)

[IMP]Improve code

8702. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk'

8703. By Sanjay Gohel (Open ERP)

[IMP]improve string

8704. By Sanjay Gohel (Open ERP)

[IMP]onchange of company paypal fees country changed

8705. By Sanjay Gohel (Open ERP)

[IMP]improve string of percntage fee help

8706. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8707. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8708. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8709. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8710. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8711. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8712. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

Unmerged revisions

8712. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8711. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8710. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8709. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8708. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8707. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8706. By Sanjay Gohel (Open ERP)

[MERGE]sync with trunk

8705. By Sanjay Gohel (Open ERP)

[IMP]improve string of percntage fee help

8704. By Sanjay Gohel (Open ERP)

[IMP]onchange of company paypal fees country changed

8703. By Sanjay Gohel (Open ERP)

[IMP]improve string

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account/edi/invoice.py'
2--- account/edi/invoice.py 2012-12-17 14:43:06 +0000
3+++ account/edi/invoice.py 2013-07-22 07:17:28 +0000
4@@ -263,6 +263,7 @@
5 res = dict.fromkeys(ids, False)
6 for inv in self.browse(cr, uid, ids, context=context):
7 if inv.type == 'out_invoice' and inv.company_id.paypal_account:
8+ paypal_fees = self.pool.get('portal.payment.acquirer').compute_paypal_fees(cr, uid, inv, inv.currency_id, inv.residual, context=context)
9 params = {
10 "cmd": "_xclick",
11 "business": inv.company_id.paypal_account,
12@@ -273,6 +274,7 @@
13 "button_subtype": "services",
14 "no_note": "1",
15 "bn": "OpenERP_Invoice_PayNow_" + inv.currency_id.name,
16+ "handling": paypal_fees
17 }
18 res[inv.id] = "https://www.paypal.com/cgi-bin/webscr?" + urlencode(params)
19 return res
20
21=== modified file 'account/project/wizard/account_analytic_chart_view.xml'
22--- account/project/wizard/account_analytic_chart_view.xml 2012-11-29 22:26:45 +0000
23+++ account/project/wizard/account_analytic_chart_view.xml 2013-07-22 07:17:28 +0000
24@@ -13,8 +13,11 @@
25 <button string="Cancel" class="oe_link" special="cancel"/>
26 </header>
27 <group string="Select the Period for Analysis" col="4">
28- <field name="from_date"/>
29- <field name="to_date"/>
30+ <label for="from_date" class="oe_inline"/>
31+ <div>
32+ <field name="from_date" class="oe_inline"/>
33+ <field name="to_date" class="oe_inline"/>
34+ </div>
35 <label string="(Keep empty to open the current situation)" colspan="4"/>
36 </group>
37 </form>
38
39=== modified file 'account/res_config_view.xml'
40--- account/res_config_view.xml 2013-04-11 10:46:43 +0000
41+++ account/res_config_view.xml 2013-07-22 07:17:28 +0000
42@@ -226,21 +226,22 @@
43 </div>
44 </div>
45 </group>
46+ <group name="paypal">
47+ <label for="id" string="Paypal"/>
48+ <div>
49+ <label for="paypal_account"/>
50+ <field name="paypal_account" placeholder="e.g. sales@openerp.com" class="oe_inline"/>
51+ </div>
52+ </group>
53 <separator string="Bank &amp; Cash"/>
54 <group name="bank_cash">
55 <label for="id" string="Configuration"/>
56 <div>
57- <div>
58- <label for="company_footer"/>
59- <button name="open_company_form" type="object"
60- string="Configure your company bank accounts" icon="gtk-go-forward"
61- class="oe_inline oe_link"/>
62- <field name="company_footer"/>
63- </div>
64- <div>
65- <label for="paypal_account"/>
66- <field name="paypal_account" placeholder="e.g. sales@openerp.com" class="oe_inline"/>
67- </div>
68+ <label for="company_footer"/>
69+ <button name="open_company_form" type="object"
70+ string="Configure your company bank accounts" icon="gtk-go-forward"
71+ class="oe_inline oe_link"/>
72+ <field name="company_footer"/>
73 </div>
74 </group>
75 <separator name="analytic_account" string="Analytic Accounting" invisible="1"/>
76
77=== modified file 'portal/acquirer.py'
78--- portal/acquirer.py 2012-11-30 09:45:01 +0000
79+++ portal/acquirer.py 2013-07-22 07:17:28 +0000
80@@ -47,7 +47,7 @@
81 'visible': True,
82 }
83
84- def render(self, cr, uid, id, object, reference, currency, amount, context=None, **kwargs):
85+ def render(self, cr, uid, id, object, reference, currency, amount, fees=False, context=None, **kwargs):
86 """ Renders the form template of the given acquirer as a mako template """
87 if not isinstance(id, (int,long)):
88 id = id[0]
89@@ -60,6 +60,7 @@
90 reference=reference,
91 currency=currency,
92 amount=amount,
93+ fees=fees,
94 kind=i18n_kind,
95 quote=quote,
96 # context kw would clash with mako internals
97@@ -70,26 +71,40 @@
98 _logger.exception("failed to render mako template value for payment.acquirer %s: %r", this.name, this.form_template)
99 return
100
101- def _wrap_payment_block(self, cr, uid, html_block, amount, currency, context=None):
102+ def _wrap_payment_block(self, cr, uid, html_block, amount, currency, fees=False, context=None):
103 if not html_block:
104 link = '#action=account.action_account_config'
105- payment_header = _('You can finish the configuration in the <a href="%s">Bank&Cash settings</a>') % link
106+ payment_header = _('You can finish the configuration in the <a href="%s">eInvoicing &amp; Payments</a>') % link
107 amount = _('No online payment acquirers configured')
108+ fees_str = _('')
109+ fees_amount = ''
110 group_ids = self.pool.get('res.users').browse(cr, uid, uid, context=context).groups_id
111 if any(group.is_portal for group in group_ids):
112 return ''
113 else:
114 payment_header = _('Pay safely online')
115+ fees_str = _('Fees: ')
116 amount_str = float_repr(amount, self.pool.get('decimal.precision').precision_get(cr, uid, 'Account'))
117 currency_str = currency.symbol or currency.name
118 amount = u"%s %s" % ((currency_str, amount_str) if currency.position == 'before' else (amount_str, currency_str))
119- result = """<div class="payment_acquirers">
120- <div class="payment_header">
121- <div class="payment_amount">%s</div>
122- %s
123- </div>
124- %%s
125- </div>""" % (amount, payment_header)
126+ fees_amount = u"%s %s" % ((currency_str, fees) if currency.position == 'before' else (fees, currency_str))
127+ if fees:
128+ result = """<div class="payment_acquirers">
129+ <div class="payment_header">
130+ <div class="payment_amount">%s</div>
131+ <div>%s %s</div>
132+ %s
133+ </div>
134+ %%s
135+ </div>""" % (amount, fees_str, fees_amount, payment_header)
136+ else:
137+ result = """<div class="payment_acquirers">
138+ <div class="payment_header">
139+ <div class="payment_amount">%s</div>
140+ %s
141+ </div>
142+ %%s
143+ </div>""" % (amount, payment_header)
144 return result % html_block
145
146 def render_payment_block(self, cr, uid, object, reference, currency, amount, context=None, **kwargs):
147@@ -100,9 +115,28 @@
148 if not acquirer_ids:
149 return
150 html_forms = []
151+ paypal_fees = self.compute_paypal_fees(cr, uid, object, currency, amount, context=context)
152 for this in self.browse(cr, uid, acquirer_ids):
153- content = this.render(object, reference, currency, amount, context=context, **kwargs)
154+ content = this.render(object, reference, currency, amount, fees=paypal_fees, context=context, **kwargs)
155 if content:
156 html_forms.append(content)
157 html_block = '\n'.join(filter(None,html_forms))
158- return self._wrap_payment_block(cr, uid, html_block, amount, currency, context=context)
159+ return self._wrap_payment_block(cr, uid, html_block, amount, currency, fees=paypal_fees, context=context)
160+
161+ def compute_paypal_fees(self, cr, uid, object, currency, amount, context=None):
162+ group_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal_sale', 'group_paypal_fees_on_customer')[1]
163+ group_check_total = self.pool.get('res.groups').browse(cr, uid, group_id, context=context)
164+ charge = 0.00
165+ if group_check_total and uid in [x.id for x in group_check_total.users]:
166+ if object.partner_id.country_id.id == object.company_id.country_id.id or not object.partner_id.country_id.id or not object.company_id.country_id.id:
167+ per_fee = object.company_id.domestic_fee * 0.01
168+ fix_fee = object.company_id.domestic_fixed_fee
169+ charge = (per_fee * amount + fix_fee) / (1 - per_fee)
170+ else:
171+ per_fee = object.company_id.international_fee * 0.01
172+ fix_fee = object.company_id.international_fixed_fee
173+ charge = (per_fee * amount + fix_fee) / (1 - per_fee)
174+ total_charges = float_repr(charge, self.pool.get('decimal.precision').precision_get(cr, uid, 'Account'))
175+ return total_charges
176+ else:
177+ return charge
178\ No newline at end of file
179
180=== modified file 'portal/acquirer_view.xml'
181--- portal/acquirer_view.xml 2012-12-21 16:48:08 +0000
182+++ portal/acquirer_view.xml 2013-07-22 07:17:28 +0000
183@@ -19,6 +19,7 @@
184 <ul>
185 <li>reference: the reference number of the document to pay</li>
186 <li>kind: the kind of document on which the payment form is rendered (translated to user language, e.g. "Invoice")</li>
187+ <li>handling: the total international/domestic fees to pay, as a float</li>
188 <li>currency: the currency record in which the document is issued (e.g. currency.name could be EUR)</li>
189 <li>amount: the total amount to pay, as a float</li>
190 <li>object: the document on which the payment form is rendered (usually an invoice or sales order record)</li>
191
192=== modified file 'portal/portal_data.xml'
193--- portal/portal_data.xml 2012-12-21 16:48:08 +0000
194+++ portal/portal_data.xml 2013-07-22 07:17:28 +0000
195@@ -96,6 +96,7 @@
196 <input type="hidden" name="item_name" value="${object.company_id.name} ${kind.title()} ${reference}"/>
197 <input type="hidden" name="amount" value="${amount}"/>
198 <input type="hidden" name="currency_code" value="${currency.name}"/>
199+ <input type="hidden" name="handling" value="${fees}"/>
200 <input type="image" name="submit" src="https://www.paypal.com/en_US/i/btn/btn_paynowCC_LG.gif"/>
201 </form>
202 % endif
203
204=== modified file 'portal_sale/portal_sale.py'
205--- portal_sale/portal_sale.py 2013-05-06 09:49:55 +0000
206+++ portal_sale/portal_sale.py 2013-07-22 07:17:28 +0000
207@@ -129,3 +129,18 @@
208 if p.id not in order.message_follower_ids:
209 so_obj.message_subscribe(cr, uid, [mail.res_id], [p.id], context=context)
210 return super(mail_mail, self)._postprocess_sent_message(cr, uid, mail=mail, context=context)
211+
212+class res_company(osv.osv):
213+ _inherit = "res.company"
214+ _columns = {
215+ 'domestic_fee': fields.float('Percentage fee', help="Percentage fee charged by Paypal on each transaction. The percentage fee is applied before the fixed fee on the total amount of the invoice."),
216+ 'domestic_fixed_fee': fields.float('Fixed fee', help="Fixed fee charged by Paypal on each transaction."),
217+ 'international_fee': fields.float('Percentage fee', help="Percentage fee charged by Paypal on each transaction. The percentage fee is applied before the fixed fee on the total amount of the invoice."),
218+ 'international_fixed_fee': fields.float('Fixed fee', help="Fixed fee charged by Paypal on each transaction."),
219+ }
220+ _defaults = {
221+ 'domestic_fee': 2.90,
222+ 'domestic_fixed_fee': 0.30,
223+ 'international_fee': 3.90,
224+ 'international_fixed_fee': 0.30
225+ }
226
227=== modified file 'portal_sale/res_config.py'
228--- portal_sale/res_config.py 2012-11-13 16:44:35 +0000
229+++ portal_sale/res_config.py 2013-07-22 07:17:28 +0000
230@@ -21,6 +21,10 @@
231
232 from openerp.osv import fields, osv
233
234+from lxml import etree
235+from openerp import tools
236+from openerp.tools.translate import _
237+
238 class sale_portal_config_settings(osv.TransientModel):
239 _inherit = 'account.config.settings'
240
241@@ -29,4 +33,57 @@
242 implied_group='portal_sale.group_payment_options',
243 help="Show online payment options on Sale Orders and Customer Invoices to employees. "
244 "If not checked, these options are only visible to portal users."),
245- }
246\ No newline at end of file
247+ 'group_paypal_fees_on_customer': fields.boolean('Charge Paypal fees to customers',
248+ implied_group='portal_sale.group_paypal_fees_on_customer',
249+ help="Check this box if you want to charge the transaction fees to your customers when they pay with Paypal. "
250+ "An additional line will appear on the Paypal payment form with the amount of the fee."),
251+ 'domestic_fee': fields.related('company_id', 'domestic_fee', type='float', string='Percentage fee',
252+ help="Percentage fee charged by Paypal on each transaction. The percentage fee is applied before the fixed fee on the total amount of the invoice."),
253+ 'domestic_fixed_fee': fields.related('company_id', 'domestic_fixed_fee', type='float', string='Fixed fee',
254+ help="Fixed fee charged by Paypal on each transaction"),
255+ 'international_fee': fields.related('company_id', 'international_fee', type='float', string='Percentage fee',
256+ help="Percentage fee charged by Paypal on each transaction. The percentage fee is applied before the fixed fee on the total amount of the invoice."),
257+ 'international_fixed_fee': fields.related('company_id', 'international_fixed_fee', type='float', string='Fixed fee',
258+ help="Fixed fee charged by Paypal on each transaction"),
259+ 'is_country': fields.boolean('If country in company',readonly=True),
260+ 'country_name_dmstc': fields.char("Country name for domestic help",size=128,readonly=True),
261+ 'country_name_intrntl': fields.char("Country name for international help",size=128,readonly=True),
262+ }
263+
264+ def onchange_company_id(self, cr, uid, ids, company_id, context=None):
265+ vals = super(sale_portal_config_settings, self).onchange_company_id(cr, uid, ids, company_id, context=None)
266+ company = self.pool.get('res.company').browse(cr, uid, company_id, context=context)
267+ if company.country_id:
268+ vals['value'].update({
269+ 'is_country':True,
270+ 'country_name_dmstc':company.country_id.name,
271+ 'country_name_intrntl':company.country_id.name,
272+ })
273+ else:
274+ vals['value'].update({
275+ 'is_country':False,
276+ })
277+ vals['value'].update({
278+ 'domestic_fee': company.domestic_fee,
279+ 'domestic_fixed_fee': company.domestic_fixed_fee,
280+ 'international_fee': company.international_fee,
281+ 'international_fixed_fee': company.international_fixed_fee,
282+ })
283+ return vals
284+
285+ def open_current_company(self, cr, uid, ids, context=None):
286+ """ open Company's view """
287+ mod_obj = self.pool.get('ir.model.data')
288+ config = self.browse(cr, uid, ids[0], context=context)
289+ dummy, form_view = mod_obj.get_object_reference(cr, uid, 'base', 'view_company_form')
290+ return {
291+ 'name': _('Company'),
292+ 'view_type': 'form',
293+ 'view_mode': 'form',
294+ 'res_model': 'res.company',
295+ 'res_id': int(config.company_id.id),
296+ 'view_id': False,
297+ 'views': [(form_view or False, 'form'),
298+ (False, 'calendar'), (False, 'graph')],
299+ 'type': 'ir.actions.act_window',
300+ }
301
302=== modified file 'portal_sale/res_config_view.xml'
303--- portal_sale/res_config_view.xml 2012-11-13 16:44:35 +0000
304+++ portal_sale/res_config_view.xml 2013-07-22 07:17:28 +0000
305@@ -7,13 +7,48 @@
306 <field name="model">account.config.settings</field>
307 <field name="inherit_id" ref="account.view_account_config_settings"/>
308 <field name="arch" type="xml">
309- <xpath expr="//group[@name='bank_cash']/div" version="7.0" position="inside">
310+ <xpath expr="//group[@name='paypal']/div" version="7.0" position="inside">
311 <div>
312 <field name="group_payment_options" class="oe_inline"/>
313 <label for="group_payment_options"/>
314 <button name='%(portal.action_acquirer_list)d' type="action"
315 string="Configure payment acquiring methods" class="oe_link"/>
316 </div>
317+ <div>
318+ <field name="group_paypal_fees_on_customer" class="oe_inline"/>
319+ <label for="group_paypal_fees_on_customer"/>
320+ </div>
321+ <field name="is_country" invisible="1"/>
322+ <div attrs="{'invisible': [('group_paypal_fees_on_customer','=',False)]}">
323+ <p name="help_domestic">Fees for domestic transactions (per transaction).</p>
324+ <p attrs="{'invisible': [('is_country','=',False)]}">These fees will be applied to any Paypal payment
325+ where the customer’s country on the invoice is <field name="country_name_dmstc"/></p>
326+
327+ <p attrs="{'invisible': [('is_country','=',True)]}">These fees will be applied to any Paypal payment
328+ where the customer’s country on the invoice is the same as the country in your <button name="open_current_company" type="object" class="oe_link" string="company's address"/></p>
329+ <div>
330+ <label for="domestic_fee"/>
331+ <field name="domestic_fee" class="oe_inline" attrs="{'required': [('group_paypal_fees_on_customer','=',True)]}"/><b>%%</b>
332+ </div>
333+ <div>
334+ <label for="domestic_fixed_fee"/>
335+ <field name="domestic_fixed_fee" class="oe_inline" widget='monetary' options="{'currency_field': 'currency_id'}" attrs="{'required': [('group_paypal_fees_on_customer','=',True)]}"/>
336+ </div>
337+ <p name="help_international">Fees for international transactions (per transaction).</p>
338+ <p attrs="{'invisible': [('is_country','=',False)]}">These fees will be applied to any Paypal payment where
339+ the customer’s country on the invoice is different from <field name="country_name_intrntl"/></p>
340+
341+ <p attrs="{'invisible': [('is_country','=',True)]}">These fees will be applied to any Paypal payment where the customer’s country
342+ on the invoice is different from the country in your <button name="open_current_company" type="object" class="oe_link" string="company's address"/></p>
343+ <div>
344+ <label for="international_fee"/>
345+ <field name="international_fee" class="oe_inline" attrs="{'required': [('group_paypal_fees_on_customer','=',True)]}"/><b>%%</b>
346+ </div>
347+ <div>
348+ <label for="international_fixed_fee"/>
349+ <field name="international_fixed_fee" class="oe_inline" widget='monetary' options="{'currency_field': 'currency_id'}" attrs="{'required': [('group_paypal_fees_on_customer','=',True)]}"/>
350+ </div>
351+ </div>
352 </xpath>
353 </field>
354 </record>
355
356=== modified file 'portal_sale/security/portal_security.xml'
357--- portal_sale/security/portal_security.xml 2012-11-29 22:26:45 +0000
358+++ portal_sale/security/portal_security.xml 2013-07-22 07:17:28 +0000
359@@ -9,6 +9,10 @@
360 on Sale Orders and Customer Invoices. These options are meant for customers who are accessing
361 their documents through the portal.</field>
362 </record>
363+ <record id="group_paypal_fees_on_customer" model="res.groups">
364+ <field name="name">Advance Paypal Payment Options</field>
365+ <field name="category_id" ref="base.module_category_hidden"/>
366+ </record>
367 <!-- Make the payment_options group implied for all portal users -->
368 <record id="portal.group_portal" model="res.groups">
369 <field name="implied_ids" eval="[(4,ref('group_payment_options'))]"/>
370
371=== modified file 'sale/edi/sale_order.py'
372--- sale/edi/sale_order.py 2012-12-17 14:43:06 +0000
373+++ sale/edi/sale_order.py 2013-07-22 07:17:28 +0000
374@@ -186,6 +186,7 @@
375 for order in self.browse(cr, uid, ids, context=context):
376 if order.order_policy in ('prepaid', 'manual') and \
377 order.company_id.paypal_account and order.state != 'draft':
378+ paypal_fees = self.pool.get('portal.payment.acquirer').compute_paypal_fees(cr, uid, order, order.pricelist_id.currency_id, order.amount_total, context=context)
379 params = {
380 "cmd": "_xclick",
381 "business": order.company_id.paypal_account,
382@@ -196,6 +197,7 @@
383 "button_subtype": "services",
384 "no_note": "1",
385 "bn": "OpenERP_Order_PayNow_" + order.pricelist_id.currency_id.name,
386+ "handling": paypal_fees
387 }
388 res[order.id] = "https://www.paypal.com/cgi-bin/webscr?" + urlencode(params)
389 return res

Subscribers

People subscribed via source and target branches

to all changes: