diff options
| -rw-r--r-- | addons/portal/__init__.py | 2 | ||||
| -rw-r--r-- | addons/portal/__openerp__.py | 2 | ||||
| -rw-r--r-- | addons/portal/acquirer.py | 96 | ||||
| -rw-r--r-- | addons/portal/acquirer_view.xml | 67 | ||||
| -rw-r--r-- | addons/portal/portal_data.xml | 24 | ||||
| -rw-r--r-- | addons/portal/security/ir.model.access.csv | 2 | ||||
| -rw-r--r-- | addons/portal/static/src/css/portal.css | 60 |
7 files changed, 252 insertions, 1 deletions
diff --git a/addons/portal/__init__.py b/addons/portal/__init__.py index 2bfc6df0d96..0045a557a49 100644 --- a/addons/portal/__init__.py +++ b/addons/portal/__init__.py @@ -22,6 +22,6 @@ import portal import mail_mail import wizard - +import acquirer # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal/__openerp__.py b/addons/portal/__openerp__.py index 66a736c6048..4f37a2205d7 100644 --- a/addons/portal/__openerp__.py +++ b/addons/portal/__openerp__.py @@ -49,8 +49,10 @@ very handy when used in combination with the module 'share'. 'portal_view.xml', 'wizard/portal_wizard_view.xml', 'wizard/share_wizard_view.xml', + 'acquirer_view.xml', ], 'demo': ['portal_demo.xml'], + 'css': ['static/src/css/portal.css'], 'installable': True, } diff --git a/addons/portal/acquirer.py b/addons/portal/acquirer.py new file mode 100644 index 00000000000..922a341b679 --- /dev/null +++ b/addons/portal/acquirer.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Business Applications +# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +import logging +from urllib import quote as quote + +from openerp.osv import osv, fields +from openerp.tools import ustr +from openerp.tools.translate import _ + +_logger = logging.getLogger(__name__) +try: + from mako.template import Template as MakoTemplate +except ImportError: + _logger.warning("payment_acquirer: mako templates not available, payment acquirer will not work!") + + +class acquirer(osv.Model): + _name = 'portal.payment.acquirer' + _description = 'Online Payment Acquirer' + + _columns = { + 'name': fields.char('Name', required=True), + 'form_template': fields.text('Payment form template (HTML)', translate=True), + 'visible': fields.boolean('Visible', help="Whether this payment acquirer is currently displayed in portal forms"), + } + + _default = { + 'visible': True, + } + + def render(self, cr, uid, id, object, reference, currency, amount, context=None, **kwargs): + """ Renders the form template of the given acquirer as a mako template """ + if not isinstance(id, (int,long)): + id = id[0] + this = self.browse(cr, uid, id) + if context is None: + context = {} + try: + i18n_kind = _(object._description) # may fail to translate, but at least we try + template = ustr(this.form_template) + result = MakoTemplate(template).render_unicode(object=object, + reference=reference, + currency=currency, + amount=amount, + kind=i18n_kind, + quote=quote, + # context kw would clash with mako internals + ctx=context, + format_exceptions=True) + result = result.strip() + if result == u'False': + result = u'' + return result + except Exception: + _logger.exception("failed to render mako template value for payment.acquirer %s: %r", this.name, template) + return + + def _wrap_payment_block(self, cr, uid, html_block, context=None): + payment_header = _('Pay safely online:') + result = """<div class="payment_acquirers"> + <span class="payment_header">%s</span> + %%s + </div>""" % payment_header + return result % html_block + + def render_payment_block(self, cr, uid, object, reference, currency, amount, context=None, **kwargs): + """ Renders all visible payment acquirer forms for the given rendering context, and + return them wrapped in an appropriate HTML block, ready for direct inclusion + in an OpenERP v7 form view """ + acquirer_ids = self.search(cr, uid, [('visible', '=', True)]) + if not acquirer_ids: + return + html_forms = [] + for this in self.browse(cr, uid, acquirer_ids): + html_forms.append(this.render(object, reference, currency, amount, context=context, **kwargs)) + html_block = '\n'.join(html_forms) + return self._wrap_payment_block(cr, uid, html_block, context=context) diff --git a/addons/portal/acquirer_view.xml b/addons/portal/acquirer_view.xml new file mode 100644 index 00000000000..0e88d47f758 --- /dev/null +++ b/addons/portal/acquirer_view.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + <record id="acquirer_form" model="ir.ui.view"> + <field name="model">portal.payment.acquirer</field> + <field name="arch" type="xml"> + <form string="Payment Acquirer" version="7.0"> + <group col="1"> + <div class="oe_title"> + <label for="name" class="oe_edit_only"/><h1><field name="name"/></h1> + <div class="oe_edit_only"><field name="visible"/><label for="visible"/></div> + </div> + <group string="Form Template"> + <div> + <p> + This is an HTML form template to submit a payment through this acquirer. + The template will be rendered through mako, so it may use normal mako expressions. + The mako evaluation context provides: + <ul> + <li>reference: the reference number of the document to pay</li> + <li>kind: the kind of document on which the payment form is rendered (translated to user language, e.g. "Invoice")</li> + <li>currency: the currency record in which the document is issued (e.g. currency.name could be EUR)</li> + <li>amount: the total amount to pay, as a float</li> + <li>object: the document on which the payment form is rendered (usually an invoice or sale order record)</li> + <li>quote(): a method to quote special string character to make them suitable for inclusion in a URL</li> + <li>cr: the current database cursor</li> + <li>uid: the current user id</li> + <li>ctx: the current context dictionary</li> + </ul> + If the template renders to an empty result in a certain context it will be ignored, as if it was inactive. + </p> + </div> + <field name="form_template" nolabel="1" colspan="2"/> + </group> + </group> + </form> + </field> + </record> + <record id="acquirer_list" model="ir.ui.view"> + <field name="model">portal.payment.acquirer</field> + <field name="arch" type="xml"> + <tree string="Payment Acquirers"> + <field name="name"/> + <field name="visible"/> + </tree> + </field> + </record> + <record id="acquirer_search" model="ir.ui.view"> + <field name="model">portal.payment.acquirer</field> + <field name="arch" type="xml"> + <search> + <field name="name"/> + </search> + </field> + </record> + + <record model="ir.actions.act_window" id="action_acquirer_list"> + <field name="name">Payment Acquirers</field> + <field name="res_model">portal.payment.acquirer</field> + </record> + + <menuitem id="menu_acquirers" parent="portal_menu" action="action_acquirer_list"/> + <menuitem id="menu_acquirers2" parent="menu_acquirers" action="action_acquirer_list"/> + <menuitem id="menu_acquirers3" parent="menu_acquirers2" action="action_acquirer_list"/> + + </data> +</openerp> diff --git a/addons/portal/portal_data.xml b/addons/portal/portal_data.xml index 90a570bc1d5..89e62c8d48e 100644 --- a/addons/portal/portal_data.xml +++ b/addons/portal/portal_data.xml @@ -27,6 +27,30 @@ <field name="res_id" ref="company_jobs"/> <field name="view_mode">form</field> </record> + + + <record id="paypal_acquirer" model="portal.payment.acquirer"> + <field name="name">Paypal</field> + <field name="form_template"><![CDATA[ +% if object.company_id.paypal_account: +<% +kind = quote(kind.title()) +comp_name = quote(object.company_id.name) +ref = quote(reference) +paypal_account = quote(object.company_id.paypal_account) +amount = quote(str(object.amount_total)) +cur_code = quote(currency.name) +paypal_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=%s%%20%s%%20%s" \ + "&invoice=%s&amount=%s&currency_code=%s&button_subtype=services&no_note=1" \ + "&bn=OpenERP_Portal_PayNow_%s" % \ + (paypal_account,comp_name,kind,ref,ref,amount,cur_code,cur_code) +%> +<a style="margin-left: 120px;" href="${paypal_url}"> + <img class="oe_edi_paypal_button" src="https://www.paypal.com/en_US/i/btn/btn_paynowCC_LG.gif"/> +</a> +% endif + ]]></field> + </record> </data> </openerp> diff --git a/addons/portal/security/ir.model.access.csv b/addons/portal/security/ir.model.access.csv index 9202c7f4087..b6d932bf7ee 100644 --- a/addons/portal/security/ir.model.access.csv +++ b/addons/portal/security/ir.model.access.csv @@ -4,3 +4,5 @@ access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0, access_res_partner_address,res.partner_address,base.model_res_partner_address,portal.group_portal,1,0,0,0 access_res_partner_category,res.partner_category,base.model_res_partner_category,portal.group_portal,1,0,0,0 access_res_partner_title,res.partner_title,base.model_res_partner_title,portal.group_portal,1,0,0,0 +access_acquirer,portal.payment.acquirer,portal.model_portal_payment_acquirer,,1,0,0,0 +access_acquirer_all,portal.payment.acquirer,portal.model_portal_payment_acquirer,base.group_system,1,1,1,1 diff --git a/addons/portal/static/src/css/portal.css b/addons/portal/static/src/css/portal.css new file mode 100644 index 00000000000..02d0d44e6b3 --- /dev/null +++ b/addons/portal/static/src/css/portal.css @@ -0,0 +1,60 @@ + +.openerp .oe_application .oe_form_sheetbg { + /* Establish a stacking context on top of which the + payment_acquirers::before element can be positioned */ + position: relative; + z-index: 0; +} + +.openerp .payment_acquirers { + margin: -40px 0 -32px -24px; + position: relative; + padding: 10px 15px; + right: -153px; + + background: #729FCF; + background-image: -webkit-gradient(linear, left top, left bottom, from(#729FCF), to(#3465A4)); + background-image: -webkit-linear-gradient(top, #729FCF, #3465A4); + background-image: -moz-linear-gradient(top, #729FCF, #3465A4); + background-image: -ms-linear-gradient(top, #729FCF, #3465A4); + background-image: -o-linear-gradient(top, #729FCF, #3465A4); + background-image: linear-gradient(to bottom, #729FCF, #3465A4); + border-bottom: 1px solid #043574; + + -webkit-box-shadow: 0 4px 20px rgba(0, 0, 0, 0.45); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.45); +} + +.openerp .payment_acquirers::after { + content: " "; + display: block; + width: 10px; + height: 20px; + position: absolute; + bottom: 0; + right: 1px; + + margin-bottom: -6px; + background: #043574; + + -webkit-transform: skewY(-45deg); + -moz-transform: skewY(-45deg); + -ms-transform: skewY(-45deg); + -o-transform: skewY(-45deg); + transform: skewY(-45deg); + + -webkit-box-shadow: inset 1px -1px 2px black, -1px 1px 3px black; + box-shadow: inset 1px -1px 2px black, -1px 1px 3px black; + + /* push it under all its siblings, just on top of its root + in the z-index stack: div.oe_form_sheetbg */ + z-index: -1; +} + +.openerp .payment_acquirers .payment_header { + font-weight: bold; + font-size: 110%; + padding-right: 15px; + color: white; + text-shadow: 0 1px 1px #729FCF, 0 -1px 1px #3465A4; +}
\ No newline at end of file |
