diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py index bae7a0d8f9c..ac2f79b56f1 100644 --- a/addons/email_template/wizard/mail_compose_message.py +++ b/addons/email_template/wizard/mail_compose_message.py @@ -41,6 +41,21 @@ def _reopen(self, res_id, model): class mail_compose_message(osv.TransientModel): _inherit = 'mail.compose.message' + def default_get(self, cr, uid, fields, context=None): + """ + """ + if context is None: + context = {} + res = super(mail_compose_message, self).default_get(cr, uid, fields, context=context) + if context.get('default_template_id'): + res.update( + self.onchange_template_id( + cr, uid, [], context['default_template_id'], res.get('composition_mode'), + res.get('model'), res.get('res_id'), context=context + )['value'] + ) + return res + _columns = { 'template_id': fields.many2one('email.template', 'Use template', select=True), 'partner_to': fields.char('To (Partner IDs)', diff --git a/addons/event/__openerp__.py b/addons/event/__openerp__.py index 9ff7a6dc47d..ad01e28f199 100644 --- a/addons/event/__openerp__.py +++ b/addons/event/__openerp__.py @@ -39,7 +39,7 @@ Key Features * Use emails to automatically confirm and send acknowledgements for any event registration """, 'author': 'OpenERP SA', - 'depends': ['base_setup', 'board', 'email_template'], + 'depends': ['base_setup', 'board', 'email_template', 'marketing'], 'data': [ 'security/event_security.xml', 'security/ir.model.access.csv', diff --git a/addons/event/event.py b/addons/event/event.py index 6b5c3ebdf07..daf2b2aa982 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -41,7 +41,6 @@ class event_type(osv.osv): 'default_registration_max': 0, } - class event_event(osv.osv): """Event""" _name = 'event.event' @@ -179,7 +178,7 @@ class event_event(osv.osv): _visibility_selection = lambda self, *args, **kwargs: self._get_visibility_selection(*args, **kwargs) _columns = { - 'name': fields.char('Name', size=64, required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}), + 'name': fields.char('Event Name', size=64, required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}), 'user_id': fields.many2one('res.users', 'Responsible User', readonly=False, states={'done': [('readonly', True)]}), 'type': fields.many2one('event.type', 'Type of Event', readonly=False, states={'done': [('readonly', True)]}), 'register_max': fields.integer('Maximum Registrations', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )", readonly=True, states={'draft': [('readonly', False)]}), @@ -202,14 +201,12 @@ class event_event(osv.osv): 'email_registration_id' : fields.many2one('email.template','Registration Confirmation Email', help='This field contains the template of the mail that will be automatically sent each time a registration for this event is confirmed.'), 'email_confirmation_id' : fields.many2one('email.template','Event Confirmation Email', help="If you set an email template, each participant will receive this email announcing the confirmation of the event."), 'reply_to': fields.char('Reply-To Email', size=64, readonly=False, states={'done': [('readonly', True)]}, help="The email address of the organizer is likely to be put here, with the effect to be in the 'Reply-To' of the mails sent automatically at event or registrations confirmation. You can also put the email address of your mail gateway if you use one."), - 'main_speaker_id': fields.many2one('res.partner','Main Speaker', readonly=False, states={'done': [('readonly', True)]}, help="Speaker who will be giving speech at the event."), 'address_id': fields.many2one('res.partner','Location', readonly=False, states={'done': [('readonly', True)]}), 'street': fields.related('address_id','street',type='char',string='Street'), 'street2': fields.related('address_id','street2',type='char',string='Street2'), 'state_id': fields.related('address_id','state_id',type='many2one', relation="res.country.state", string='State'), 'zip': fields.related('address_id','zip',type='char',string='zip'), 'city': fields.related('address_id','city',type='char',string='city'), - 'speaker_confirmed': fields.boolean('Speaker Confirmed', readonly=False, states={'done': [('readonly', True)]}), 'country_id': fields.related('address_id', 'country_id', type='many2one', relation='res.country', string='Country', readonly=False, states={'done': [('readonly', True)]}, store=True), 'description': fields.html( @@ -220,6 +217,9 @@ class event_event(osv.osv): 'is_subscribed' : fields.function(_subscribe_fnc, type="boolean", string='Subscribed'), 'visibility': fields.selection(_visibility_selection, 'Privacy / Visibility', select=True, required=True), + 'organizer_id': fields.many2one('res.partner', "Organizer"), + 'phone': fields.related('organizer_id', 'phone', type='char', string='Phone'), + 'email': fields.related('organizer_id', 'email', type='char', string='Email'), } _defaults = { 'state': 'draft', diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml index e1ea6e95af9..40be13c6b28 100644 --- a/addons/event/event_view.xml +++ b/addons/event/event_view.xml @@ -9,13 +9,7 @@ tree,form,calendar,graph {'search_default_event_id': active_id, 'default_event_id': active_id} - - - - + @@ -52,8 +46,9 @@ event.type form - - + + + @@ -63,11 +58,11 @@
+
@@ -76,18 +71,19 @@
- + + + - + @@ -102,10 +98,6 @@
- - - - @@ -175,7 +167,6 @@ - @@ -323,7 +314,7 @@ context="{'search_default_partner_id': [active_id], 'default_partner_id': active_id}" view_type="form"/> - + @@ -460,7 +451,7 @@ diff --git a/addons/event/report/report_event_registration.py b/addons/event/report/report_event_registration.py index 0e33e892432..b529d6ef029 100644 --- a/addons/event/report/report_event_registration.py +++ b/addons/event/report/report_event_registration.py @@ -44,7 +44,6 @@ class report_event_registration(osv.osv): 'user_id': fields.many2one('res.users', 'Event Responsible', readonly=True), 'user_id_registration': fields.many2one('res.users', 'Register', readonly=True), 'name_registration': fields.char('Participant / Contact Name',size=45, readonly=True), - 'speaker_id': fields.many2one('res.partner', 'Speaker', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True), } _order = 'event_date desc' @@ -64,7 +63,6 @@ class report_event_registration(osv.osv): r.user_id AS user_id_registration, r.name AS name_registration, e.company_id AS company_id, - e.main_speaker_id AS speaker_id, to_char(e.date_begin, 'YYYY-MM-DD') AS event_date, to_char(e.date_begin, 'YYYY') AS year, to_char(e.date_begin, 'MM') AS month, @@ -91,7 +89,6 @@ class report_event_registration(osv.osv): e.user_id, event_state, e.company_id, - e.main_speaker_id, year, month, e.register_max, diff --git a/addons/event_moodle/__openerp__.py b/addons/event_moodle/__openerp__.py deleted file mode 100644 index fdfb793b494..00000000000 --- a/addons/event_moodle/__openerp__.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - - -{ - 'name': 'Event Moodle', - 'version': '0.1', - 'category': 'Tools', - 'description': """ -Configure your moodle server. -============================= - -With this module you are able to connect your OpenERP with a moodle platform. -This module will create courses and students automatically in your moodle platform -to avoid wasting time. -Now you have a simple way to create training or courses with OpenERP and moodle. - -STEPS TO CONFIGURE: -------------------- - -1. Activate web service in moodle. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ->site administration >plugins >web services >manage protocols activate the xmlrpc web service - - ->site administration >plugins >web services >manage tokens create a token - - ->site administration >plugins >web services >overview activate webservice - - -2. Create confirmation email with login and password. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We strongly suggest you to add those following lines at the bottom of your event -confirmation email to communicate the login/password of moodle to your subscribers. - - -........your configuration text....... - -**URL:** your moodle link for exemple: http://openerp.moodle.com - -**LOGIN:** ${object.moodle_username} - -**PASSWORD:** ${object.moodle_user_password} -""", - 'author': 'OpenERP SA', - 'depends': ['event'], - 'data': [ - 'wizard_moodle.xml', - 'event_view.xml', - 'security/ir.model.access.csv' - ], - 'demo': [], - 'test': [], - 'installable': True, - 'auto_install': False, - 'images': ['images/token.png','images/enable_webservice.png','images/active_xmlrpc.png'], -} -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/event_moodle/event_moodle.py b/addons/event_moodle/event_moodle.py deleted file mode 100644 index 44d2de4bdd5..00000000000 --- a/addons/event_moodle/event_moodle.py +++ /dev/null @@ -1,286 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2012 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -from openerp.osv import fields, osv -import xmlrpclib -import string -import time -import random -from random import sample -from openerp.tools.translate import _ - -class event_moodle(osv.osv): - _name = 'event.moodle.config.wiz' - _columns = { - 'moodle_username' : fields.char('Moodle Username', 128, help="You can also connect with your username that you define when you create a token"), - 'moodle_password' : fields.char('Moodle Password', 128), - 'moodle_token' : fields.char('Moodle Token', 128, help="Put your token that you created in your moodle server"), - 'server_moodle': fields.char('Moodle Server', 128, required=True,help="URL where you have your moodle server. For exemple: 'http://127.0.0.1' or 'http://localhost'"), - 'url': fields.char('URL to Moodle Server', size=256, help="The url that will be used for the connection with moodle in xml-rpc"), - } - - _order = 'create_date desc' - - _defaults = { - 'server_moodle': 'http://127.0.0.1', - } - - def configure_moodle(self, cr, uid, ids, context=None): - url = self.make_url(cr, uid, ids, context=context) - self.write(cr, uid, ids, {'url': url}) - return {'type': 'ir.actions.act_window_close'} - - def find(self, cr, uid, context=None): - """ - Find the config wizard containing the configuration and raise and error if none is available. - """ - moodle_config_wiz_ids = self.search(cr, uid, [], context=context) - if not moodle_config_wiz_ids: - raise osv.except_osv(_('Error!'),_("First configure your moodle connection.")) - return moodle_config_wiz_ids[0] - - def make_url(self, cr, uid, ids, context=None): - """ - create the good url with the information of the configuration - @return url for moodle connexion - """ - def _encode_password(password): - for i in range(len(password)): - x = password[i] - if x not in string.ascii_letters + string.digits: - unicode_car = (hex(ord(x))) - hex_car = '%'+str(unicode_car[2:]) - password = password.replace(x,hex_car) - return password - url="" - config_moodle = self.browse(cr, uid, ids[0], context=context) - if config_moodle.moodle_username and config_moodle.moodle_password: - #connexion with password and username - password = _encode_password(config_moodle.moodle_password) - url = config_moodle.server_moodle + '/moodle/webservice/xmlrpc/simpleserver.php?wsusername=' + config_moodle.moodle_username + '&wspassword=' + password - if config_moodle.moodle_token: - #connexion with token - url = config_moodle.server_moodle + '/moodle/webservice/xmlrpc/server.php?wstoken=' + config_moodle.moodle_token - return url - - def create_moodle_user(self, cr, uid, id, dic_user, context=None): - """ - create a moodle user - @param dic_user : is a list of dictonnaries with the moodle information - @return a liste of dictonaries with the create user id - """ - #connect to moodle - url = self.browse(cr, uid, id, context=context).url - sock = xmlrpclib.ServerProxy(url) - #add user in moodle and return list of id and username - return sock.core_user_create_users(dic_user) - - def create_moodle_courses(self, cr, uid, id, courses, context=None): - """ - create a mmodle course - @param courses : is a list of dictionaries with the moodle course information - @return a list of dictionaries with the create course id - """ - #connect to moodle - url = self.browse(cr, uid, id, context=context).url - if not url: - raise osv.except_osv(_('Error!'),_("You must configure your moodle connection.")) - sock = xmlrpclib.ServerProxy(url) - return sock.core_course_create_courses(courses) - - def moodle_enrolled(self, cr, uid, id, enrolled, context=None): - """ - this method is used to match a course with users - @param enrolled : list of dictonaries with the course id and the user id - """ - #connect to moodle - url = self.browse(cr, uid, id, context=context).url - sock = xmlrpclib.ServerProxy(url) - #add enrolled in moodle - sock.enrol_manual_enrol_users(enrolled) - - def create_password(self): - """ - create a random password - """ - rand = string.ascii_letters + string.digits - length = 8 - passwd = ''.join(sample(rand, length)) - passwd = passwd + '+' - return passwd - - def check_email(self, email): - - """ - check if email is correct - """ - if email: - if (email.count('@') != 1 and email.count('.') < 1): - raise osv.except_osv(_('Error!'),_("Your email '%s' is wrong.") % (email)) - - def make_username(self, username, response_courses): - """ - create a moodle username with a random number for the uniqueness - @return the moodle username - """ - if username: - #remove space in the name - username = username.replace(" ","_") - #give an user name - name_user = username + "%d" % (response_courses,) + "%d" % (random.randint(1,999999),) - else: - name_user = "moodle_" + "%d" % (response_courses,) + "%d" % (random.randint(1,999999),) - return name_user - - -class event_event(osv.osv): - _inherit = "event.event" - - _columns={ - 'moodle_id': fields.integer('Moodle ID', help='The identifier of this event in Moodle'), - } - - def check_registration_limits(self, cr, uid, ids, context=None): - """ - create moodle courses ,users and match them when an event is confirmed - if the event_registration is not confirmed then it doesn t nothing - """ - res = super(event_event, self).check_registration_limits(cr, uid, ids, context=context) - moodle_pool = self.pool.get('event.moodle.config.wiz') - moodle_config_wiz_id = moodle_pool.find(cr, uid, context=context) - list_users=[] - userid = [] - for event in self.browse(cr, uid, ids, context=context): - #moodle use time() to store the date - date = time.strptime(event.date_begin, '%Y-%m-%d %H:%M:%S') - date = int (time.mktime(date)) - #create the dict of values to create the course in Moodle - dic_courses= [{ - 'fullname': event.name, - 'shortname': '', - 'startdate': date, - 'summary': event.note, - 'categoryid':1, #the category hardcoded is 'Miscellaneous' - }] - #create a course in moodle and keep the id - response_courses = moodle_pool.create_moodle_courses(cr, uid, moodle_config_wiz_id, dic_courses, context=context) - self.write(cr, uid, event.id, {'moodle_id': response_courses[0]['id']}) - - moodle_uids = [] - for registration in event.registration_ids: - if registration.state == 'open': - #enroll the registration in Moodle as it is confirmed - if not registration.moodle_uid: - #create a dictionary for an user - name_user = moodle_pool.make_username(registration.name, response_courses[0]['id']) - moodle_pool.check_email(registration.email) - passwd = moodle_pool.create_password() - dic_users={ - 'username' : name_user, - 'password' : passwd, - 'city' : registration.city, - 'firstname' : registration.name , - 'lastname': '', - 'email': registration.email - } - #create the user in moodle - response_user = moodle_pool.create_moodle_user(cr, uid, moodle_config_wiz_id, [dic_users], context=context) - for user in response_user: - self.pool.get('event.registration').write(cr,uid,[registration.id],{'moodle_uid': user['id'], 'moodle_user_password': passwd, 'moodle_username': name_user}) - moodle_uids.append(user['id']) - else: - moodle_uids.append(registration.moodle_uid) - - #link the course with users - enrolled = [] - for moodle_user in moodle_uids: - enrolled.append({ - 'roleid' :'5', #mark as 'Student' - 'userid' : moodle_user, - 'courseid' :response_courses[0]['id'] - }) - moodle_pool.moodle_enrolled(cr, uid, moodle_config_wiz_id, enrolled, context=context) - return res - - -class event_registration(osv.osv): - - _inherit = "event.registration" - - _columns={ - 'moodle_user_password': fields.char('Password for Moodle User', 128), - 'moodle_username': fields.char('Moodle Username', 128), - 'moodle_uid': fields.integer('Moodle User ID'), - } - - def confirm_registration(self, cr, uid, ids, context=None): - """ - create a user and match to a course if the event is already confirmed - """ - res = super(event_registration, self).confirm_registration(cr, uid, ids, context=context) - moodle_pool = self.pool.get('event.moodle.config.wiz') - moodle_config_wiz_id = moodle_pool.find(cr, uid, context=context) - for register in self.browse(cr, uid, ids, context=context): - if register.event_id.state == 'confirm' and register.event_id.moodle_id: - if not register.moodle_uid: - #create the user in moodle - name_user = moodle_pool.make_username(register.name, register.event_id.moodle_id) - moodle_pool.check_email(register.email) - passwd = moodle_pool.create_password() - dic_users = [{ - 'username': name_user, - 'password': passwd, - 'city': register.city, - 'firstname': register.name, - 'lastname': '', #we could make a split of the register.name on ' ' but it would be inaccurate, so it seems better to let it empty as it's not really useful - 'email': register.email, - }] - response_user = moodle_pool.create_moodle_user(cr, uid, moodle_config_wiz_id, dic_users, context=context) - #write in database the password and the username - moodle_user_id = response_user[0]['id'] - self.pool.get('event.registration').write(cr, uid, ids, {'moodle_uid': moodle_user_id, 'moodle_user_password': passwd, 'moodle_username': name_user}) - else: - moodle_user_id = register.moodle_uid - enrolled=[{ - 'roleid': '5', #mark as student - 'userid': moodle_user_id, - 'courseid': register.event_id.moodle_id - }] - moodle_pool.moodle_enrolled(cr, uid, moodle_config_wiz_id, enrolled, context=context) - return res - - def onchange_moodle_name(self, cr, uid, ids, moodle_username, context=None): - """ - This onchange receive as parameter a username moddle and will fill the moodle_uid and password fields if existing records with this username are found - @param moodle_username: the existing moodle username - """ - res = {} - reg_ids = self.search(cr, uid, [('moodle_username', '=', moodle_username)], order='create_date desc', context=context) - if reg_ids: - reg = self.browse(cr, uid, reg_ids[0], context=context) - res = {'value' :{ - 'moodle_uid': reg.moodle_uid, - 'name': reg.name, - 'email':reg.email, - 'phone':reg.phone, - 'city': reg.city, - 'street': reg.street}} - return res diff --git a/addons/event_moodle/event_view.xml b/addons/event_moodle/event_view.xml deleted file mode 100644 index 252e805a6ab..00000000000 --- a/addons/event_moodle/event_view.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - event.moodle.registration - event.registration - - - - - - - - - - - - - - - - - - event.moodle.event - event.event - - - - - - - - - - - - - diff --git a/addons/event_moodle/i18n/cs.po b/addons/event_moodle/i18n/cs.po deleted file mode 100644 index 6621ffd35e0..00000000000 --- a/addons/event_moodle/i18n/cs.po +++ /dev/null @@ -1,185 +0,0 @@ -# Czech translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-03-31 16:48+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Czech \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:37+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "" diff --git a/addons/event_moodle/i18n/de.po b/addons/event_moodle/i18n/de.po deleted file mode 100644 index c1cbb8d8f56..00000000000 --- a/addons/event_moodle/i18n/de.po +++ /dev/null @@ -1,198 +0,0 @@ -# German translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-10 08:39+0000\n" -"Last-Translator: Thorsten Vocks (OpenBig.org) \n" -"Language-Team: German \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:37+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Anbindung mit Benutzer und Passwort" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"URL Ihres Moodle Servers. Zum Beispiel: 'http://127.0.0.1' oder " -"'http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Passwort für Moodle Benutzer" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Moodle Passwort" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Ihre EMail #%s' ist falsch." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Verbindungstoken" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"Der einfachste Weg für eine OpenERP Verbindung zu einem Moodle Server ist " -"der Erstellung eines 'Tokens' in Moodle. Dieser wird dann eingesetzt, um " -"OpenERP als vertrauenswürdige Anwendung zu authentifizieren." - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "URL des Moodle Servers" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" -"Die url die benutzt wird, um eine Verbindung zu moodle via xml-rpc " -"herzustellen" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Veranstaltung Anmeldung" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" -"Ein anderer Ansatz ist die Erstellung eines Benutzers für OpenERP in Moodle " -"zu erstellen. Wenn Sie dieses bevorzugen, sollte natürlich sicher gestellt " -"werden, dass ausreichende Zugriffsrechte erteilt werden." - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "Moodle Benutzer ID" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Moodle Server" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Moodle ID" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Server" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Fehler !" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Sie müssen zuerst Ihre Moodle Verbindung konfigurieren." - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Moodle Benutzername" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Konfigurieren Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Moodle Token" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" -"Sie können sich ebenso mit Ihrem Benutzernamen, den Sie bei der Token " -"Erstellung erzeugt haben, anmelden." - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "Die Identifizierung Ihrer Veranstaltung in Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "Tragen Sie den in Moodle erstellten Token ein" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Moodle Konfiguration" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "oder" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Konfigurieren Sie zuerst Ihre Moodle Verbindung" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Anwenden" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Abbrechen" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Veranstaltung" diff --git a/addons/event_moodle/i18n/es.po b/addons/event_moodle/i18n/es.po deleted file mode 100644 index ccbed7ef575..00000000000 --- a/addons/event_moodle/i18n/es.po +++ /dev/null @@ -1,194 +0,0 @@ -# Spanish translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-12 20:43+0000\n" -"Last-Translator: lambdasoftware \n" -"Language-Team: Spanish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Conexión con nombre de usuario y contraseña" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"Dirección (URL) de su servidor moodle. Por ejemplo: 'http://127.0.0.1' o " -"'http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Contraseña del usuario Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Contraseña de Moodle" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Su email '%s' es erróneo." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Conexión con testigo (token)" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"La manera más sencilla para conectar OpenERP con el servidor moodle es crear " -"un 'token' en Moodle. Esto permitirá autenticar a OpenERP como una " -"aplicación de confianza." - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "Dirección (URL) al servidor de Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "Dirección que se usará para conectar con moodle a través de xml-rpc" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Registro de eventos" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" -"Otro enfoque es crear un usuario para OpenERP en Moodle. Si lo hace, " -"asegúrese de que el usuario tiene los permisos adecuados." - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "ID del usario Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Servidor Moodle" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "ID de Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Servidor" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "¡Error!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Debe configurar la conexión con moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Nombre de usuario Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Configurar Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Testigo (Token) de Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" -"También puede conectarse con el nombre de usuario que definió cuando creó el " -"token" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "Identificador de este evento en Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "Ponga el token que ha creado en su servidor moodle" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Configuración de Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "o" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Configure primero su conexion moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Aplicar" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Cancelar" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Evento" diff --git a/addons/event_moodle/i18n/event_moodle.pot b/addons/event_moodle/i18n/event_moodle.pot deleted file mode 100644 index 1bae5a8dcd2..00000000000 --- a/addons/event_moodle/i18n/event_moodle.pot +++ /dev/null @@ -1,175 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * event_moodle -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0alpha\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-21 17:05+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "URL where you have your moodle server. For exemple: 'http://127.0.0.1' or 'http://localhost'" -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "The easiest way to connect OpenERP with a moodle server is to create a 'token' in Moodle. It will be used to authenticate OpenERP as a trustable application." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Another approach is to create a user for OpenERP in Moodle. If you do so, make sure that this user has appropriate access rights." -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "You can also connect with your username that you define when you create a token" -msgstr "" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "" - diff --git a/addons/event_moodle/i18n/fr.po b/addons/event_moodle/i18n/fr.po deleted file mode 100644 index 387fa94bea7..00000000000 --- a/addons/event_moodle/i18n/fr.po +++ /dev/null @@ -1,194 +0,0 @@ -# French translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-21 13:44+0000\n" -"Last-Translator: Julius \n" -"Language-Team: French \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:37+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Connexion avec identifiant et mot de passe" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"L'Url de votre serveur Moodle. Par exemple : 'http://127.0.0.1' ou " -"http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Mot de passe de l'utilisateur Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Mot de passe Moodle" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Votre email '%s' est incorrect" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Connexion avec une session d'authentification (Token)" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"La manière la plus simple de se connecter à OpenERP avec un serveur moodle " -"est de créer une session d'authentification (token). Ceci permet " -"d'authentifier OpenERP comme une application de confiance" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "URL du serveur Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "L'url qui sera utilisé pour la connexion de Moodle en xml-rpc" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Inscription à l'événement" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" -"Une autre approche est de créer un utilisateur pour OpenERP sur Moodle. Si " -"vous faîtes cela, vérifier que l'utilisateur a des droits d'accés appropriés" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "Identifiant de l'utilisateur Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Serveur Moodle" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Identifiant Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Serveur" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Erreur !" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Vous devez configurer votre connexion moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Nom de l'utilisateur Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Configurer Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Session d'authentification (Token)" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" -"Vous pouvez aussi vous connecter avec votre identifiant que vous avez défini " -"lors de la création d'un Token" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Configuration Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "ou" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Première configuration de votre connexion Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Annuler" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Évènement" diff --git a/addons/event_moodle/i18n/hr.po b/addons/event_moodle/i18n/hr.po deleted file mode 100644 index 2759988dca2..00000000000 --- a/addons/event_moodle/i18n/hr.po +++ /dev/null @@ -1,185 +0,0 @@ -# Croatian translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-09 20:12+0000\n" -"Last-Translator: Goran Kliska \n" -"Language-Team: Croatian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Lozinka za Moodle korisnika" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Moodle lozinka" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Vaša email adresa '%s' nije ispravna." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "URL Moodle poslužitelja" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Moodle poslužitelj" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Moodle ID" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Poslužitelj" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Greška!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Moodle korisničko ime" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Moodle postavke" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Moodle token" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "ili" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Primjeni" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Odustani" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Event" diff --git a/addons/event_moodle/i18n/hu.po b/addons/event_moodle/i18n/hu.po deleted file mode 100644 index b092c30b3b4..00000000000 --- a/addons/event_moodle/i18n/hu.po +++ /dev/null @@ -1,197 +0,0 @@ -# Hungarian translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-02-28 08:28+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Hungarian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:37+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Csatlakozás felhasználónévvel és jelszóval" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"A moodle tanulási környezet szerver helyének URL elérési útja. Pédául: " -"'http://127.0.0.1' or 'http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Jelszó a Moodle tanulási környezet felhasználónak" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Moodle tanulási környezeti jelszó" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Az '%s' e-mailje hibás." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Szimbólum tokennel való belépés" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"A legkönnyebb kapcsolódási lehetőség Moodle szerverrel az OpenERP " -"rendszerhez úgy, hogy egy szimbólum 'tokent' hoz A Moodle-n. Ezt az OpenERP " -"hitelesítésére lesz használva mint hitelesített alkalmazás." - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "URL a Moodle szerverhez" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" -"Ezt az url elérési útat az xml-rpc fogja használni a Moodle tanulási " -"környezet csatlakozására" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Rendezvény regisztráció" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" -"Másik lehetőség, hogy az OpenERP felhasználót a moodle tanulási környezetből " -"állítja be. Ha így tesz, akkor győződjön meg, hogy ennek a felhasználónak " -"megfelelő elérési jogosultságai vannak." - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "Moodle tanulási környezet felhasználó ID azonosítója" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Moodle szerver" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Moodle ID azonosító" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Szerver" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Hiba!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Be kell állítani a Moodle tanulási környezet csatlakozást." - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Moodle tanulási környezet felhasználó" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Moodle tanulási környezet beállítása" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Moodle tanulási környezet Token" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" -"A token létrehozásakor létrehozott felhasználó nevével is kapcsolódhat" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "Ennek az eseménynek az azonosítójaa moodle tanulási környezetben" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" -"Tegye ide a tokent amit a Moodle tanulási környezet szerveren létrehozott" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Moodle tanulási környezet beállítás" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "vagy" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Előszőr állítsa be a Moodle tanulási környezet csatlakozást" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Alkalmaz" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Mégsem" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Esemény" diff --git a/addons/event_moodle/i18n/mk.po b/addons/event_moodle/i18n/mk.po deleted file mode 100644 index 750bafb5462..00000000000 --- a/addons/event_moodle/i18n/mk.po +++ /dev/null @@ -1,194 +0,0 @@ -# Macedonian translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-03-08 14:43+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Macedonian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:37+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Конекција со корисничко име и лозинка" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"URl адресата на вашиот moodle сервер. На пример, 'http://127.0.0.1' или " -"'http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Лозинка за Moodle корисник" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Moodle лозинка" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Вашата е-пошта '%s' е погрешна." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Конекција со токен" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"Најлесен начин да се поврзете на OpenERP со moodle сервер е да креирате " -"'токен' во Moodle. Тој ќе се користи за да се идентификува OpenERP како " -"доверлива апликација." - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "URL на Moodle Сервер" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "URL која ќе се користи за конекција со moodle во xml-rpc" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Регистрација на настан" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" -"Другиот начин е да се креира корисник за OpenERP во Moodle. Доколку го " -"направите тоа, погрижете се овој корисник да ги има сите права за пристап." - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "ID на Moodle корисник" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Moodle Сервер" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Moodle ID" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Сервер" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Грешка!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Мора да ја конфигурирате вашата moodle конекција." - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Moodle корисничко име" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Конфигурирај Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Moodle Токен" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" -"Можете да се конектирате со вашето корисничко име што го дефинирате кога " -"креирате токен" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "Идентификувач на овој настан во Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "Ставете го токенот кој го креиравте во вашиот Moodle сервер" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Moodle Конфигурација" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "или" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Најпрво конфигурирајте ја вашата moodle конекција." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Примени" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Откажи" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Настан" diff --git a/addons/event_moodle/i18n/mn.po b/addons/event_moodle/i18n/mn.po deleted file mode 100644 index 512eecce92a..00000000000 --- a/addons/event_moodle/i18n/mn.po +++ /dev/null @@ -1,185 +0,0 @@ -# Mongolian translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-02-06 09:39+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Mongolian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Хэрэглэгчийн нэр ба нууц үгтэй холболт" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Moodle хэрэглэгчийн нууц үг" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Moodle нууц үг" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Таны емайл '%s' буруу байна." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "Moodle серверийн URL" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Үйл явдлын бүртгэл" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "Moodle хэрэглэгч ID" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Moodle Сервер" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Moodle ID" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Сервер" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Алдаа гарлаа!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Moodle хэрэглэгчийн нэр" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Moodle тохиргоо" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Moodle тасалбар" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Moodle тохиргоо" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "эсвэл" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Эхлээд moodleхолболтыг тохируул" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Ашиглах" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Цуцлах" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Үйл ажиллагаа" diff --git a/addons/event_moodle/i18n/nl.po b/addons/event_moodle/i18n/nl.po deleted file mode 100644 index eb794e9d1c6..00000000000 --- a/addons/event_moodle/i18n/nl.po +++ /dev/null @@ -1,185 +0,0 @@ -# Dutch translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-11-30 20:02+0000\n" -"Last-Translator: Erwin van der Ploeg (BAS Solutions) \n" -"Language-Team: Dutch \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:37+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Connectie met gebruikersnaam en wachtwoord." - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Wachtwoord voor Moodle gebruiker" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Moodle wachtwoord" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Uwr email '%s' is fout." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Connectie met een token" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "URL van Moodle Server" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Evenementregistratie" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "Moodle User ID" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Moodle Server" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Moodle ID" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Server" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Fout!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Moodle gebruikersnaam" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Moodle instellen" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Moodle Token" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Moodle instellingen" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "of" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Stel eerst uw Moodle connectie in." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Toepassen" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Annuleren" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Evenement" diff --git a/addons/event_moodle/i18n/pt.po b/addons/event_moodle/i18n/pt.po deleted file mode 100644 index 72df6577c6d..00000000000 --- a/addons/event_moodle/i18n/pt.po +++ /dev/null @@ -1,187 +0,0 @@ -# Portuguese translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-01-04 17:35+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Portuguese \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Ligação com nome de utilizador e senha" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"Endereço onde tem o seu servidor moodle. Por exemplo: 'http://127.0.0.1' ou " -"'http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Senha para o utilizador Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Senha Moodle" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "O seu email '%s' está errado." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "Endereço para o servidor Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "O endereço que será usado para a ligação com o moodle em xml-rpc" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Servidor Moodle" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Servidor" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Erro!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Tem que configurar a sua ligação ao moodle." - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Configurar Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Configuração Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Primeiro configure a sua ligação ao moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Aplicar" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Cancelar" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Evento" diff --git a/addons/event_moodle/i18n/pt_BR.po b/addons/event_moodle/i18n/pt_BR.po deleted file mode 100644 index 94a7220d015..00000000000 --- a/addons/event_moodle/i18n/pt_BR.po +++ /dev/null @@ -1,195 +0,0 @@ -# Brazilian Portuguese translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-24 18:29+0000\n" -"Last-Translator: Fábio Martinelli - http://zupy.com.br " -"\n" -"Language-Team: Brazilian Portuguese \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Conectar com usuário e senha" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"URL aonde está configurado o servidor moodle. Por exemplo 'http://127.0.0.1' " -"ou 'http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Senha para o Usuário Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Senha Moodle" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Seu email '%s' está errado." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Conectar com um Token" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"A maneira mais fácil de conectar o OpenERP com um servidor moodle é criar um " -"token no Moodle. Ele será usado para autenticar o OpenERP como uma aplicação " -"confiável." - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "URL para o Servidor Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "A url que será usada para a conexão do moodle em xml-rpc" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Inscrição no Evento" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" -"Outra maneira é criar um usuário para o OpenERP no Moodle. Se você fizer " -"dessa forma, tenha certeza de que este usuário possui os direitos de acesso " -"apropriados." - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "ID do Usuário no Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Servidor Moodle" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "ID Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Servidor" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Erro!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Você precisa configurar sua conexão ao moodle." - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Usuário Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Configurar Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Token Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" -"Você também pode conectar com o usuário que você definiu ao criar um token" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "O identificador deste evento no Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "Coloque o token que você criou no seu servidor moodle" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Configuracão do Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "ou" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Primeiro configure sua conexão do Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Aplicar" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Cancelar" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Evento" diff --git a/addons/event_moodle/i18n/ro.po b/addons/event_moodle/i18n/ro.po deleted file mode 100644 index 56a9d877616..00000000000 --- a/addons/event_moodle/i18n/ro.po +++ /dev/null @@ -1,195 +0,0 @@ -# Romanian translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-01-23 21:24+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Romanian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Conectare cu numele de utilizator si parola" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "wiz.config.eveniment.moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"URL-ul unde aveti serverul moodle. De exemplu: 'http://127.0.0.1' or " -"'http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Parola pentru Utilizatorul Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Parola Moodle" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Email-ul dumneavoastra '%s' este gresit." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Conectare cu un Simbol" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"Cel mai usor mod de conectare a lui OpenERP cu un server moodle este sa " -"creati un 'simbol' in Moodle. Va fi folosit pentru a autentifica OpenERP " -"drept o aplicatie de incredere." - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "URL catre Serverul Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "Url-ul care va fi folosit pentru conectarea cu moodle in xml-rpc" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Inregistrarea Evenimentelor" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" -"O alta abordare este sa creati un utilizator pentru OpenERP in Moodle. Daca " -"faceti acest lucru, asigurati-va ca acest utilizator are drepturi de acces " -"adecvate." - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "ID Utilizator Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Server Moodle" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "ID Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Server" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Eroare!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Trebuie sa configurati conexiunea moodle." - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Nume de utilizator Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Configureaza Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Simbol Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" -"De asemenea, puteti sa va conectati cu numele de utilizator pe care il " -"definiti atunci cand creati un simbol" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "Identificatorul acestui eveniment in Moodle" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "Puneti simbolul pe care l-ati creat in serverul moodle" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Configurare Moodle" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "sau" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Mai intai configurati-va conexiunea moodle." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Aplica" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Anuleaza" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Eveniment" diff --git a/addons/event_moodle/i18n/ru.po b/addons/event_moodle/i18n/ru.po deleted file mode 100644 index b42a84a023b..00000000000 --- a/addons/event_moodle/i18n/ru.po +++ /dev/null @@ -1,185 +0,0 @@ -# Russian translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-11-13 05:19+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Russian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-14 05:23+0000\n" -"X-Generator: Launchpad (build 16820)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "" diff --git a/addons/event_moodle/i18n/sl.po b/addons/event_moodle/i18n/sl.po deleted file mode 100644 index f6aba48c1ff..00000000000 --- a/addons/event_moodle/i18n/sl.po +++ /dev/null @@ -1,185 +0,0 @@ -# Slovenian translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-01-26 12:20+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Slovenian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Registracija dogodka" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Strežnik" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Napaka!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "ali" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Uporabi" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "Prekliči" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Dogodek" diff --git a/addons/event_moodle/i18n/tr.po b/addons/event_moodle/i18n/tr.po deleted file mode 100644 index 55ab0120d94..00000000000 --- a/addons/event_moodle/i18n/tr.po +++ /dev/null @@ -1,193 +0,0 @@ -# Turkish translation for openobject-addons -# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-02-04 14:05+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Turkish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "Kullanıcı adı ve parola ile bağlanma" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "etkinlik.moodle.yapılanma.sih" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"Moodle sunucunuzun bulunduğu URL. Örneğin: 'http://127.0.0.1' or " -"'http://localhost'" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Moodle kullanıcı parolası" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Moodle Parolası" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "Epostanız '%s' yanlıştır." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "Andaç ile bağlanma" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"OpenERP ye bir moodle sunucusu ile en kolay bağlanma yolu Moodle da bir " -"'andaç' oluşturmaktır. OpenERP nin güvenilir bir uygulama olduğunu " -"doğrulamak için kullanılacaktır." - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "Moodle Sunucusu için URL" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "xml-rpc de moodle ile bağlanmak için kullanılacak url." - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "Etkinlik Kaydı" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "" -"Diğer bir yaklaşım Moodle da OpenERP için bir kullanıcı oluşturmaktır. Böyle " -"yaparsanız, bu kullanıcının uygun izinlerinin olduğundan emin olun." - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "Moodle Kullanıcı ID" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Moodle Sunucusu" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Moodle ID" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "Sunucu" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "Hata!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "Moodle bağlantınızı yapılandırmalısınız." - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Moodle Kullanıcı Adı" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "Moodle Yapılandır" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Moodle Andaçı" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "" -"Bir andaç oluştururken tanımladığınız kullanıcı adınızla da bağlanabilirsiniz" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "Moodle da bu etkinliğin kimliği" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "Moodle sunucusunda oluşturduğunuz andaçı koyun" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Modle Yapılandırması" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "ya da" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "Önce moodle bağlantınızı yapılandırın." - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "Uygula" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "İptal" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "Etkinlik" diff --git a/addons/event_moodle/i18n/zh_CN.po b/addons/event_moodle/i18n/zh_CN.po deleted file mode 100644 index 006004b929e..00000000000 --- a/addons/event_moodle/i18n/zh_CN.po +++ /dev/null @@ -1,188 +0,0 @@ -# Chinese (Simplified) translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-30 00:29+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Chinese (Simplified) \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:38+0000\n" -"X-Generator: Launchpad (build 16761)\n" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with username and password" -msgstr "用户名和密码的链接" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_moodle_config_wiz -msgid "event.moodle.config.wiz" -msgstr "event.moodle.config.wiz" - -#. module: event_moodle -#: help:event.moodle.config.wiz,server_moodle:0 -msgid "" -"URL where you have your moodle server. For exemple: 'http://127.0.0.1' or " -"'http://localhost'" -msgstr "" -"你的 moodle 服务器的URL。\r\n" -"例如:“http://127.0.0.1”或“http://localhost”" - -#. module: event_moodle -#: field:event.registration,moodle_user_password:0 -msgid "Password for Moodle User" -msgstr "Moodle用户密码" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_password:0 -msgid "Moodle Password" -msgstr "Moodle 密码" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Your email '%s' is wrong." -msgstr "你的邮件 '%s' 是错误的" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Connection with a Token" -msgstr "用 令牌 链接" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"The easiest way to connect OpenERP with a moodle server is to create a " -"'token' in Moodle. It will be used to authenticate OpenERP as a trustable " -"application." -msgstr "" -"用Moodle服务器连接OpenERP的最简单的方法是创建一个“标记”在Moodle。将使用它作为可信赖的应用程序中进行身份验证OpenERP的。" - -#. module: event_moodle -#: field:event.moodle.config.wiz,url:0 -msgid "URL to Moodle Server" -msgstr "Moodle 服务器的URL" - -#. module: event_moodle -#: help:event.moodle.config.wiz,url:0 -msgid "The url that will be used for the connection with moodle in xml-rpc" -msgstr "XML-RPC中的URL将被用于连接与Moodle" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_registration -msgid "Event Registration" -msgstr "事件记录" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "" -"Another approach is to create a user for OpenERP in Moodle. If you do so, " -"make sure that this user has appropriate access rights." -msgstr "在moodle中创建一个Openerp用户的其它方法。如果你这样做了,确实这用户有适当的访问权限。" - -#. module: event_moodle -#: field:event.registration,moodle_uid:0 -msgid "Moodle User ID" -msgstr "Moodle 用户ID" - -#. module: event_moodle -#: field:event.moodle.config.wiz,server_moodle:0 -msgid "Moodle Server" -msgstr "Moodle 服务器" - -#. module: event_moodle -#: field:event.event,moodle_id:0 -msgid "Moodle ID" -msgstr "Moodle ID" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Server" -msgstr "服务器" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#: code:addons/event_moodle/event_moodle.py:105 -#: code:addons/event_moodle/event_moodle.py:137 -#, python-format -msgid "Error!" -msgstr "错误!" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:105 -#, python-format -msgid "You must configure your moodle connection." -msgstr "你必须配置你的 Moodle 链接" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_username:0 -#: field:event.registration,moodle_username:0 -msgid "Moodle Username" -msgstr "Moodle 用户名" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -#: model:ir.actions.act_window,name:event_moodle.configure_moodle -msgid "Configure Moodle" -msgstr "配置 Moodle" - -#. module: event_moodle -#: field:event.moodle.config.wiz,moodle_token:0 -msgid "Moodle Token" -msgstr "Moodle 令牌" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_username:0 -msgid "" -"You can also connect with your username that you define when you create a " -"token" -msgstr "当你创建了一个令牌,你也能用你定义的用户名链接。" - -#. module: event_moodle -#: help:event.event,moodle_id:0 -msgid "The identifier of this event in Moodle" -msgstr "该事件在 Moodle 中的标识" - -#. module: event_moodle -#: help:event.moodle.config.wiz,moodle_token:0 -msgid "Put your token that you created in your moodle server" -msgstr "把你的令牌 放在你的服务器中" - -#. module: event_moodle -#: model:ir.ui.menu,name:event_moodle.wizard_moodle -msgid "Moodle Configuration" -msgstr "Moodle 配置" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "or" -msgstr "或" - -#. module: event_moodle -#: code:addons/event_moodle/event_moodle.py:57 -#, python-format -msgid "First configure your moodle connection." -msgstr "第一次配置的你moodle连接" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Apply" -msgstr "应用" - -#. module: event_moodle -#: view:event.moodle.config.wiz:0 -msgid "Cancel" -msgstr "取消" - -#. module: event_moodle -#: model:ir.model,name:event_moodle.model_event_event -msgid "Event" -msgstr "事件" diff --git a/addons/event_moodle/security/ir.model.access.csv b/addons/event_moodle/security/ir.model.access.csv deleted file mode 100644 index 93a9252162d..00000000000 --- a/addons/event_moodle/security/ir.model.access.csv +++ /dev/null @@ -1,3 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_event_moodle,event.moodle.admin,model_event_moodle_config_wiz,event.group_event_manager,1,1,1,1 -access_event_moodle_user,event.moodle.usr,model_event_moodle_config_wiz,event.group_event_user,0,0,0,0 diff --git a/addons/event_moodle/wizard_moodle.xml b/addons/event_moodle/wizard_moodle.xml deleted file mode 100644 index ef8af01ec3b..00000000000 --- a/addons/event_moodle/wizard_moodle.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - moodle.config.wizard.form - event.moodle.config.wiz - - - - - - - - -
-
- -
-
- - - Configure Moodle - event.moodle.config.wiz - - form - form - new - - - - - - open - - - - -
-
diff --git a/addons/event_sale/event_sale.py b/addons/event_sale/event_sale.py index 2d409453682..09e67382188 100644 --- a/addons/event_sale/event_sale.py +++ b/addons/event_sale/event_sale.py @@ -118,9 +118,6 @@ class event_event(osv.osv): _columns = { 'event_ticket_ids': fields.one2many('event.event.ticket', "event_id", "Event Ticket"), - 'organizer_id': fields.many2one('res.partner', "Organizer"), - 'phone': fields.related('organizer_id', 'phone', type='char', string='Phone'), - 'email': fields.related('organizer_id', 'email', type='char', string='Email'), 'register_max': fields.function(_get_register_max, string='Maximum Registrations', help="The maximum registration level is equal to the sum of the maximum registration of event ticket." + diff --git a/addons/event_sale/event_sale_view.xml b/addons/event_sale/event_sale_view.xml index ee71820ff30..33bd7d7469e 100644 --- a/addons/event_sale/event_sale_view.xml +++ b/addons/event_sale/event_sale_view.xml @@ -57,9 +57,6 @@
- - - diff --git a/addons/event_moodle/__init__.py b/addons/payment_acquirer/__init__.py similarity index 86% rename from addons/event_moodle/__init__.py rename to addons/payment_acquirer/__init__.py index 2814f9d514b..d95d47860af 100644 --- a/addons/event_moodle/__init__.py +++ b/addons/payment_acquirer/__init__.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). +# Copyright (C) 2013-Today OpenERP SA (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -19,7 +19,4 @@ # ############################################################################## -import event_moodle - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - +import models diff --git a/addons/payment_acquirer/__openerp__.py b/addons/payment_acquirer/__openerp__.py new file mode 100644 index 00000000000..4102c4fe276 --- /dev/null +++ b/addons/payment_acquirer/__openerp__.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +{ + 'name': 'Payment Acquirer', + 'category': 'Hidden', + 'summary': 'Payment Acquirer Base Module', + 'version': '1.0', + 'description': """Payment Acquirer Base Module""", + 'author': 'OpenERP SA', + 'depends': ['mail'], + 'data': [ + 'views/payment_acquirer.xml', + 'security/ir.model.access.csv', + ], + 'installable': True, +} diff --git a/addons/payment_acquirer/doc/changelog.rst b/addons/payment_acquirer/doc/changelog.rst new file mode 100644 index 00000000000..d0c24af384d --- /dev/null +++ b/addons/payment_acquirer/doc/changelog.rst @@ -0,0 +1,9 @@ +.. _changelog: + +Changelog +========= + +`trunk (saas-3)` +---------------- + +- Module creation \ No newline at end of file diff --git a/addons/payment_acquirer/doc/index.rst b/addons/payment_acquirer/doc/index.rst new file mode 100644 index 00000000000..85028ed0d3e --- /dev/null +++ b/addons/payment_acquirer/doc/index.rst @@ -0,0 +1,14 @@ +Payment module documentation +============================ + +Payment documentation topics +'''''''''''''''''''''''''''' + + +Changelog +''''''''' + +.. toctree:: + :maxdepth: 1 + + changelog.rst diff --git a/addons/payment_acquirer/models/__init__.py b/addons/payment_acquirer/models/__init__.py new file mode 100644 index 00000000000..da51c9c1854 --- /dev/null +++ b/addons/payment_acquirer/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import payment_acquirer diff --git a/addons/payment_acquirer/models/payment_acquirer.py b/addons/payment_acquirer/models/payment_acquirer.py new file mode 100644 index 00000000000..69a026cba81 --- /dev/null +++ b/addons/payment_acquirer/models/payment_acquirer.py @@ -0,0 +1,292 @@ +# -*- coding: utf-'8' "-*-" + +from openerp.osv import osv, fields + +import logging + +_logger = logging.getLogger(__name__) + + +class ValidationError(ValueError): + """ Used for value error when validating transaction data coming from acquirers. """ + pass + + +class PaymentAcquirer(osv.Model): + """ Acquirer Model. Each specific acquirer can extend the model by adding + its own fields. Using the required_if_provider='' attribute on fields + it is possible to have required fields that depend on a specific acquirer. + + Each acquirer has a link to an ir.ui.view record that is a template of + a button used to display the payment form. See examples in ``payment_acquirer_ogone`` + and ``payment_acquirer_paypal`` modules. + + Methods that should be added in an acquirer-specific implementation: + + - ``_form_generate_values(self, cr, uid, id, reference, amount, currency, + partner_id=False, partner_values=None, tx_custom_values=None, context=None)``: + method that generates the values used to render the form button template. + - ``_get_form_action_url(self, cr, uid, id, context=None):``: method + that returns the url of the button form. It is used for example in + ecommerce application, if you want to repost some data to the acquirer. + + Each acquirer should also define controllers to handle communication between + OpenERP and the acquirer. It generally consists in return urls given to the + button form and that the acquirer uses to send the customer back after the + transaction, with transaction details given as a POST request. + """ + _name = 'payment.acquirer' + _description = 'Payment Acquirer' + + _columns = { + 'name': fields.char('Name', 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( + [('test', 'Test'), ('prod', 'Production')], + string='Environment'), + 'portal_published': fields.boolean('Visible in Portal', + help="Make this payment acquirer available (Customer invoices, etc.)"), + } + + _defaults = { + 'portal_published': True, + 'env': 'test', + } + + def _check_required_if_provider(self, cr, uid, ids, context=None): + """ If the field has 'required_if_provider=""' attribute, then it + required if record.name is . """ + for acquirer in self.browse(cr, uid, ids, context=context): + if any(c for c, f in self._all_columns.items() if getattr(f.column, 'required_if_provider', None) == acquirer.name and not acquirer[c]): + return False + return True + + _constraints = [ + (_check_required_if_provider, 'Required fields not filled', ['required for this provider']), + ] + + 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: + + - acquirer: the payment.acquirer browse record + - user: the current user browse record + - currency: currency browse record + - amount: amount of the transaction + - reference: reference of the transaction + - partner: the current partner browse record, if any (not necessarily set) + - partner_values: a dictionary of partner-related values + - tx_custom_values: a dictionary of transaction related values that depends + on the acquirer. Some specific keys should be managed + in each provider, depending on the features it offers: + + - 'feedback_url': feedback URL, controler that manage answer of the acquirer + (without base url) + - '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 + + - context: OpenERP context dictionary + + :param string reference: the transaction reference + :param float amount: the amount the buyer has to pay + :param res.currency browse record currency: currency + :param int tx_id: id of a transaction; if set, bypasses all other given + values and only render the already-stored transaction + :param res.partner browse record partner_id: the buyer + :param dict partner_values: a dictionary of values for the buyer (see above) + :param dict tx_custom_values: a dictionary of values for the transction + that is given to the acquirer-specific method + generating the form values + :param dict context: OpenERP context + """ + if context is None: + context = {} + 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) + 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) + tx_values = method(cr, uid, tx_id, tx_custom_values, context=context) + elif hasattr(self, method_name): + method = getattr(self, 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 + + qweb_context = { + 'acquirer': acquirer, + 'user': self.pool.get("res.users").browse(cr, uid, uid, context=context), + 'reference': reference, + 'amount': amount, + 'currency': currency, + 'partner': partner, + 'partner_values': partner_values, + 'tx_values': tx_values, + 'context': context, + } + # 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 + its own fields. + + Methods that should be added in an acquirer-specific implementation: + + - ``_form_generate_values(self, cr, uid, id, tx_custom_values=None, + context=None)``: method that generates the values used to render the + form button template. + + Methods that can be added in an acquirer-specific implementation: + + - ``_create``: method receiving values used when creating a new + transaction and that returns a dictionary that will update those values. + This method can be used to tweak some transaction values. + + Methods defined for convention, depending on your controllers: + + - ``_form_feedback(self, cr, uid, data, context=None)``: method that + handles the data coming from the acquirer after the transaction. It will + generally receives data posted by the acquirer after the transaction. + """ + _name = 'payment.transaction' + _description = 'Payment Transaction' + _inherit = ['mail.thread'] + _order = 'id desc' + _rec_name = 'reference' + + _columns = { + 'date_create': fields.datetime('Creation Date', readonly=True, required=True), + 'date_validate': fields.datetime('Validation Date'), + 'acquirer_id': fields.many2one( + 'payment.acquirer', 'Acquirer', + required=True, + ), + 'type': fields.selection( + [('server2server', 'Server To Server'), ('form', 'Form')], + string='Type', required=True), + 'state': fields.selection( + [('draft', 'Draft'), ('pending', 'Pending'), + ('done', 'Done'), ('error', 'Error'), + ('cancel', 'Canceled') + ], 'Status', required=True, + track_visiblity='onchange'), + 'state_message': fields.text('Message', + help='Field used to store error and/or validation messages for information'), + # payment + 'amount': fields.float('Amount', required=True, + help='Amount in cents', + track_visibility='always'), + '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 + 'partner_id': fields.many2one('res.partner', 'Partner'), + 'partner_name': fields.char('Partner Name'), + 'partner_lang': fields.char('Lang'), + 'partner_email': fields.char('Email'), + 'partner_zip': fields.char('Zip'), + 'partner_address': fields.char('Address'), + 'partner_city': fields.char('City'), + 'partner_country_id': fields.many2one('res.country', 'Country'), + 'partner_phone': fields.char('Phone'), + 'partner_reference': fields.char('Buyer Reference'), + } + + _sql_constraints = [ + ('reference_uniq', 'UNIQUE(reference)', 'The payment transaction reference must be unique!'), + ] + + _defaults = { + 'date_create': fields.datetime.now, + 'type': 'form', + 'state': 'draft', + 'partner_lang': 'en_US', + } + + def create(self, cr, uid, values, context=None): + 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) + 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)) + + return super(PaymentTransaction, self).create(cr, uid, values, context=context) + + def on_change_partner_id(self, cr, uid, ids, partner_id, context=None): + if partner_id: + partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context) + values = { + 'partner_name': partner.name, + 'partner_lang': partner.lang, + 'partner_email': partner.email, + 'partner_zip': partner.zip, + 'partner_address': ' '.join((partner.street or '', partner.street2 or '')).strip(), + 'partner_city': partner.city, + 'partner_country_id': partner.country_id.id, + 'partner_phone': partner.phone, + } + else: + values = { + 'partner_name': False, + 'partner_lang': 'en_US', + 'partner_email': False, + 'partner_zip': False, + 'partner_address': False, + 'partner_city': False, + 'partner_country_id': False, + 'partner_phone': False, + } + return {'values': values} + + # -------------------------------------------------- + # FORM RELATED METHODS + # -------------------------------------------------- + + def form_feedback(self, cr, uid, data, acquirer_name, context=None): + invalid_parameters, tx = None, None + + tx_find_method_name = '_%s_form_get_tx_from_data' % acquirer_name + if hasattr(self, tx_find_method_name): + tx = getattr(self, tx_find_method_name)(cr, uid, data, context=context) + + invalid_param_method_name = '_%s_form_get_invalid_parameters' % acquirer_name + if hasattr(self, invalid_param_method_name): + invalid_parameters = getattr(self, invalid_param_method_name)(cr, uid, tx, data, context=context) + + if invalid_parameters: + _error_message = '%s: incorrect tx data:\n' % (acquirer_name) + for item in invalid_parameters: + _error_message += '\t%s: received %s instead of %s\n' % (item[0], item[1], item[2]) + _logger.error(_error_message) + return False + + feedback_method_name = '_%s_form_validate' % acquirer_name + if hasattr(self, feedback_method_name): + return getattr(self, feedback_method_name)(cr, uid, tx, data, context=context) + + return True + + # -------------------------------------------------- + # SERVER2SERVER RELATED METHODS + # -------------------------------------------------- + + def create_s2s(self, cr, uid, tx_values, cc_values, context=None): + tx_id = self.create(cr, uid, tx_values, context=context) + return tx_id diff --git a/addons/payment_acquirer/security/ir.model.access.csv b/addons/payment_acquirer/security/ir.model.access.csv new file mode 100644 index 00000000000..18f98939472 --- /dev/null +++ b/addons/payment_acquirer/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +payment_acquirer_all,payment.acquirer.all,model_payment_acquirer,,1,0,0,0 +payment_acquirer_user,payment.acquirer.user,model_payment_acquirer,base.group_user,1,1,1,0 +payment_acquirer_system,payment.acquirer.system,model_payment_acquirer,base.group_system,1,1,1,1 +payment_transaction_all,payment.transaction.all,model_payment_transaction,,1,1,1,0 +payment_transaction_user,payment.transaction.user,model_payment_transaction,base.group_user,1,1,1,0 +payment_transaction_system,payment.transaction.system,model_payment_transaction,base.group_system,1,1,1,1 \ No newline at end of file diff --git a/addons/payment_acquirer/static/description/icon.png b/addons/payment_acquirer/static/description/icon.png new file mode 100644 index 00000000000..51e33ac6ddf Binary files /dev/null and b/addons/payment_acquirer/static/description/icon.png differ diff --git a/addons/payment_acquirer/tests/__init__.py b/addons/payment_acquirer/tests/__init__.py new file mode 100644 index 00000000000..5c193a07c8d --- /dev/null +++ b/addons/payment_acquirer/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import common diff --git a/addons/payment_acquirer/tests/common.py b/addons/payment_acquirer/tests/common.py new file mode 100644 index 00000000000..5c915f80cbf --- /dev/null +++ b/addons/payment_acquirer/tests/common.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +from openerp.tests import common + + +class PaymentAcquirerCommon(common.TransactionCase): + + def setUp(self): + super(PaymentAcquirerCommon, self).setUp() + self.payment_acquirer = self.registry('payment.acquirer') + self.payment_transaction = self.registry('payment.transaction') + + self.currency_euro_id = self.registry('res.currency').search( + self.cr, self.uid, [('name', '=', 'EUR')], limit=1)[0] + self.currency_euro = self.registry('res.currency').browse( + self.cr, self.uid, self.currency_euro_id) + country_belgium_id = self.registry('res.country').search( + self.cr, self.uid, [('code', 'like', 'BE')], limit=1)[0] + + # dict partner values + self.buyer_values = { + 'name': 'Norbert Buyer', + 'lang': 'en_US', + 'email': 'norbert.buyer@example.com', + 'street': 'Huge Street', + 'street2': '2/543', + 'phone': '0032 12 34 56 78', + 'city': 'Sin City', + 'zip': '1000', + 'country_id': country_belgium_id, + 'country_name': 'Belgium', + } + + # test partner + self.buyer_id = self.registry('res.partner').create( + self.cr, self.uid, { + 'name': 'Norbert Buyer', + 'lang': 'en_US', + 'email': 'norbert.buyer@example.com', + 'street': 'Huge Street', + 'street2': '2/543', + 'phone': '0032 12 34 56 78', + 'city': 'Sin City', + 'zip': '1000', + 'country_id': country_belgium_id, + } + ) diff --git a/addons/payment_acquirer/views/payment_acquirer.xml b/addons/payment_acquirer/views/payment_acquirer.xml new file mode 100644 index 00000000000..916f4915e66 --- /dev/null +++ b/addons/payment_acquirer/views/payment_acquirer.xml @@ -0,0 +1,150 @@ + + + + + + + + acquirer.form + payment.acquirer + +
+ + + + + + +
+
+
+ + + payment.acquirer + + + + + + + + + + + payment.acquirer + + + + + + + + + Payment Acquirers + payment.acquirer + form + tree,form + + + + + + payment.transaction + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+
+ + + payment.transaction + + + + + + + + + + + + + payment.transaction + + + + + + + + + + + + Payment Transactions + payment.transaction + form + tree,form + + + + +
+
diff --git a/addons/payment_acquirer_ogone/__init__.py b/addons/payment_acquirer_ogone/__init__.py new file mode 100644 index 00000000000..dde6f25c728 --- /dev/null +++ b/addons/payment_acquirer_ogone/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2013-Today OpenERP SA (). +# +# 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 . +# +############################################################################## + +import models +import controllers diff --git a/addons/payment_acquirer_ogone/__openerp__.py b/addons/payment_acquirer_ogone/__openerp__.py new file mode 100644 index 00000000000..2c7b5076981 --- /dev/null +++ b/addons/payment_acquirer_ogone/__openerp__.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +{ + 'name': 'Ogone Payment Acquirer', + 'category': 'Hidden', + 'summary': 'Payment Acquirer: Ogone Implementation', + 'version': '1.0', + 'description': """Ogone Payment Acquirer""", + 'author': 'OpenERP SA', + 'depends': ['payment_acquirer'], + 'data': [ + 'views/ogone.xml', + 'views/payment_acquirer.xml', + 'data/ogone.xml', + ], + 'installable': True, +} diff --git a/addons/payment_acquirer_ogone/controllers/__init__.py b/addons/payment_acquirer_ogone/controllers/__init__.py new file mode 100644 index 00000000000..bbd183e955b --- /dev/null +++ b/addons/payment_acquirer_ogone/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import main diff --git a/addons/payment_acquirer_ogone/controllers/main.py b/addons/payment_acquirer_ogone/controllers/main.py new file mode 100644 index 00000000000..69307fcc181 --- /dev/null +++ b/addons/payment_acquirer_ogone/controllers/main.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +import logging +import pprint + +from openerp.addons.web import http +from openerp.addons.web.http import request +from openerp.addons.website.models import website + +_logger = logging.getLogger(__name__) + + +class OgoneController(http.Controller): + _accept_url = '/payment/ogone/test/accept' + _decline_url = '/payment/ogone/test/decline' + _exception_url = '/payment/ogone/test/exception' + _cancel_url = '/payment/ogone/test/cancel' + + @website.route([ + '/payment/ogone/accept', '/payment/ogone/test/accept', + '/payment/ogone/decline', '/payment/ogone/test/decline', + '/payment/ogone/exception', '/payment/ogone/test/exception', + '/payment/ogone/cancel', '/payment/ogone/test/cancel', + ], type='http', auth='admin') + def ogone_form_feedback(self, **post): + _logger.info('Ogone: entering form_feedback with post data %s', pprint.pformat(post)) # debug + cr, uid, context = request.cr, request.uid, request.context + request.registry['payment.transaction'].ogone_form_feedback(cr, uid, post, context) + return request.redirect(post.pop('return_url', '/')) diff --git a/addons/payment_acquirer_ogone/data/__init__.py b/addons/payment_acquirer_ogone/data/__init__.py new file mode 100644 index 00000000000..349d8f668e8 --- /dev/null +++ b/addons/payment_acquirer_ogone/data/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import ogone diff --git a/addons/payment_acquirer_ogone/data/ogone.py b/addons/payment_acquirer_ogone/data/ogone.py new file mode 100644 index 00000000000..3a2500ee24b --- /dev/null +++ b/addons/payment_acquirer_ogone/data/ogone.py @@ -0,0 +1,497 @@ +# -*- coding: utf-8 -*- + +OGONE_ERROR_MAP = { + '0020001001': "Authorization failed, please retry", + '0020001002': "Authorization failed, please retry", + '0020001003': "Authorization failed, please retry", + '0020001004': "Authorization failed, please retry", + '0020001005': "Authorization failed, please retry", + '0020001006': "Authorization failed, please retry", + '0020001007': "Authorization failed, please retry", + '0020001008': "Authorization failed, please retry", + '0020001009': "Authorization failed, please retry", + '0020001010': "Authorization failed, please retry", + '0030001999': "Our payment system is currently under maintenance, please try later", + '0050001005': "Expiry date error", + '0050001007': "Requested Operation code not allowed", + '0050001008': "Invalid delay value", + '0050001010': "Input date in invalid format", + '0050001013': "Unable to parse socket input stream", + '0050001014': "Error in parsing stream content", + '0050001015': "Currency error", + '0050001016': "Transaction still posted at end of wait", + '0050001017': "Sync value not compatible with delay value", + '0050001019': "Transaction duplicate of a pre-existing transaction", + '0050001020': "Acceptation code empty while required for the transaction", + '0050001024': "Maintenance acquirer differs from original transaction acquirer", + '0050001025': "Maintenance merchant differs from original transaction merchant", + '0050001028': "Maintenance operation not accurate for the original transaction", + '0050001031': "Host application unknown for the transaction", + '0050001032': "Unable to perform requested operation with requested currency", + '0050001033': "Maintenance card number differs from original transaction card number", + '0050001034': "Operation code not allowed", + '0050001035': "Exception occurred in socket input stream treatment", + '0050001036': "Card length does not correspond to an acceptable value for the brand", + '0050001036': "Card length does not correspond to an acceptable value for the brand", + '0050001068': "A technical problem occurred, please contact helpdesk", + '0050001069': "Invalid check for CardID and Brand", + '0050001070': "A technical problem occurred, please contact helpdesk", + '0050001116': "Unknown origin IP", + '0050001117': "No origin IP detected", + '0050001118': "Merchant configuration problem, please contact support", + '10001001': "Communication failure", + '10001002': "Communication failure", + '10001003': "Communication failure", + '10001004': "Communication failure", + '10001005': "Communication failure", + '20001001': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001002': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001003': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001004': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001005': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001006': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001007': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001008': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001009': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001010': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001101': "A technical problem occurred, please contact helpdesk", + '20001105': "We received an unknown status for the transaction. We will contact your acquirer and update the status of the transaction within one working day. Please check the status later.", + '20001111': "A technical problem occurred, please contact helpdesk", + '20002001': "Origin for the response of the bank can not be checked", + '20002002': "Beneficiary account number has been modified during processing", + '20002003': "Amount has been modified during processing", + '20002004': "Currency has been modified during processing", + '20002005': "No feedback from the bank server has been detected", + '30001001': "Payment refused by the acquirer", + '30001002': "Duplicate request", + '30001010': "A technical problem occurred, please contact helpdesk", + '30001011': "A technical problem occurred, please contact helpdesk", + '30001012': "Card black listed - Contact acquirer", + '30001015': "Your merchant's acquirer is temporarily unavailable, please try later or choose another payment method.", + '30001051': "A technical problem occurred, please contact helpdesk", + '30001054': "A technical problem occurred, please contact helpdesk", + '30001057': "Your merchant's acquirer is temporarily unavailable, please try later or choose another payment method.", + '30001058': "Your merchant's acquirer is temporarily unavailable, please try later or choose another payment method.", + '30001060': "Aquirer indicates that a failure occured during payment processing", + '30001070': "RATEPAY Invalid Response Type (Failure)", + '30001071': "RATEPAY Missing Mandatory status code field (failure)", + '30001072': "RATEPAY Missing Mandatory Result code field (failure)", + '30001073': "RATEPAY Response parsing Failed", + '30001090': "CVC check required by front end and returned invalid by acquirer", + '30001091': "ZIP check required by front end and returned invalid by acquirer", + '30001092': "Address check required by front end and returned as invalid by acquirer.", + '30001100': "Unauthorized buyer's country", + '30001101': "IP country <> card country", + '30001102': "Number of different countries too high", + '30001103': "unauthorized card country", + '30001104': "unauthorized ip address country", + '30001105': "Anonymous proxy", + '30001110': "If the problem persists, please contact Support, or go to paysafecard's card balance page (https://customer.cc.at.paysafecard.com/psccustomer/GetWelcomePanelServlet?language=en) to see when the amount reserved on your card will be available again.", + '30001120': "IP address in merchant's black list", + '30001130': "BIN in merchant's black list", + '30001131': "Wrong BIN for 3xCB", + '30001140': "Card in merchant's card blacklist", + '30001141': "Email in blacklist", + '30001142': "Passenger name in blacklist", + '30001143': "Card holder name in blacklist", + '30001144': "Passenger name different from owner name", + '30001145': "Time to departure too short", + '30001149': "Card Configured in Card Supplier Limit for another relation (CSL)", + '30001150': "Card not configured in the system for this customer (CSL)", + '30001151': "REF1 not allowed for this relationship (Contract number", + '30001152': "Card/Supplier Amount limit reached (CSL)", + '30001153': "Card not allowed for this supplier (Date out of contract bounds)", + '30001154': "You have reached the usage limit allowed", + '30001155': "You have reached the usage limit allowed", + '30001156': "You have reached the usage limit allowed", + '30001157': "Unauthorized IP country for itinerary", + '30001158': "email usage limit reached", + '30001159': "Unauthorized card country/IP country combination", + '30001160': "Postcode in highrisk group", + '30001161': "generic blacklist match", + '30001162': "Billing Address is a PO Box", + '30001180': "maximum scoring reached", + '30001997': "Authorization canceled by simulation", + '30001998': "A technical problem occurred, please try again.", + '30001999': "Your merchant's acquirer is temporarily unavailable, please try later or choose another payment method.", + '30002001': "Payment refused by the financial institution", + '30002001': "Payment refused by the financial institution", + '30021001': "Call acquirer support call number.", + '30022001': "Payment must be approved by the acquirer before execution.", + '30031001': "Invalid merchant number.", + '30041001': "Retain card.", + '30051001': "Authorization declined", + '30071001': "Retain card - special conditions.", + '30121001': "Invalid transaction", + '30131001': "Invalid amount", + '30131002': "You have reached the total amount allowed", + '30141001': "Invalid card number", + '30151001': "Unknown acquiring institution.", + '30171001': "Payment method cancelled by the buyer", + '30171002': "The maximum time allowed is elapsed.", + '30191001': "Try again later.", + '30201001': "A technical problem occurred, please contact helpdesk", + '30301001': "Invalid format", + '30311001': "Unknown acquirer ID.", + '30331001': "Card expired.", + '30341001': "Suspicion of fraud.", + '30341002': "Suspicion of fraud (3rdMan)", + '30341003': "Suspicion of fraud (Perseuss)", + '30341004': "Suspicion of fraud (ETHOCA)", + '30381001': "A technical problem occurred, please contact helpdesk", + '30401001': "Invalid function.", + '30411001': "Lost card.", + '30431001': "Stolen card, pick up", + '30511001': "Insufficient funds.", + '30521001': "No Authorization. Contact the issuer of your card.", + '30541001': "Card expired.", + '30551001': "Invalid PIN.", + '30561001': "Card not in authorizer's database.", + '30571001': "Transaction not permitted on card.", + '30581001': "Transaction not allowed on this terminal", + '30591001': "Suspicion of fraud.", + '30601001': "The merchant must contact the acquirer.", + '30611001': "Amount exceeds card ceiling.", + '30621001': "Restricted card.", + '30631001': "Security policy not respected.", + '30641001': "Amount changed from ref. trn.", + '30681001': "Tardy response.", + '30751001': "PIN entered incorrectly too often", + '30761001': "Card holder already contesting.", + '30771001': "PIN entry required.", + '30811001': "Message flow error.", + '30821001': "Authorization center unavailable", + '30831001': "Authorization center unavailable", + '30901001': "Temporary system shutdown.", + '30911001': "Acquirer unavailable.", + '30921001': "Invalid card type for acquirer.", + '30941001': "Duplicate transaction", + '30961001': "Processing temporarily not possible", + '30971001': "A technical problem occurred, please contact helpdesk", + '30981001': "A technical problem occurred, please contact helpdesk", + '31011001': "Unknown acceptance code", + '31021001': "Invalid currency", + '31031001': "Acceptance code missing", + '31041001': "Inactive card", + '31051001': "Merchant not active", + '31061001': "Invalid expiration date", + '31071001': "Interrupted host communication", + '31081001': "Card refused", + '31091001': "Invalid password", + '31101001': "Plafond transaction (majoré du bonus) dépassé", + '31111001': "Plafond mensuel (majoré du bonus) dépassé", + '31121001': "Plafond centre de facturation dépassé", + '31131001': "Plafond entreprise dépassé", + '31141001': "Code MCC du fournisseur non autorisé pour la carte", + '31151001': "Numéro SIRET du fournisseur non autorisé pour la carte", + '31161001': "This is not a valid online banking account", + '32001004': "A technical problem occurred, please try again.", + '34011001': "Bezahlung mit RatePAY nicht möglich.", + '39991001': "A technical problem occurred, please contact the helpdesk of your acquirer", + '40001001': "A technical problem occurred, please try again.", + '40001002': "A technical problem occurred, please try again.", + '40001003': "A technical problem occurred, please try again.", + '40001004': "A technical problem occurred, please try again.", + '40001005': "A technical problem occurred, please try again.", + '40001006': "A technical problem occurred, please try again.", + '40001007': "A technical problem occurred, please try again.", + '40001008': "A technical problem occurred, please try again.", + '40001009': "A technical problem occurred, please try again.", + '40001010': "A technical problem occurred, please try again.", + '40001011': "A technical problem occurred, please contact helpdesk", + '40001012': "Your merchant's acquirer is temporarily unavailable, please try later or choose another payment method.", + '40001013': "A technical problem occurred, please contact helpdesk", + '40001016': "A technical problem occurred, please contact helpdesk", + '40001018': "A technical problem occurred, please try again.", + '40001019': "Sorry, an error occurred during processing. Please retry the operation (use back button of the browser). If problem persists, contact your merchant's helpdesk.", + '40001020': "Sorry, an error occurred during processing. Please retry the operation (use back button of the browser). If problem persists, contact your merchant's helpdesk.", + '40001050': "A technical problem occurred, please contact helpdesk", + '40001133': "Authentication failed, the signature of your bank access control server is incorrect", + '40001134': "Authentication failed, please retry or cancel.", + '40001135': "Authentication temporary unavailable, please retry or cancel.", + '40001136': "Technical problem with your browser, please retry or cancel", + '40001137': "Your bank access control server is temporary unavailable, please retry or cancel", + '40001998': "Temporary technical problem. Please retry a little bit later.", + '50001001': "Unknown card type", + '50001002': "Card number format check failed for given card number.", + '50001003': "Merchant data error", + '50001004': "Merchant identification missing", + '50001005': "Expiry date error", + '50001006': "Amount is not a number", + '50001007': "A technical problem occurred, please contact helpdesk", + '50001008': "A technical problem occurred, please contact helpdesk", + '50001009': "A technical problem occurred, please contact helpdesk", + '50001010': "A technical problem occurred, please contact helpdesk", + '50001011': "Brand not supported for that merchant", + '50001012': "A technical problem occurred, please contact helpdesk", + '50001013': "A technical problem occurred, please contact helpdesk", + '50001014': "A technical problem occurred, please contact helpdesk", + '50001015': "Invalid currency code", + '50001016': "A technical problem occurred, please contact helpdesk", + '50001017': "A technical problem occurred, please contact helpdesk", + '50001018': "A technical problem occurred, please contact helpdesk", + '50001019': "A technical problem occurred, please contact helpdesk", + '50001020': "A technical problem occurred, please contact helpdesk", + '50001021': "A technical problem occurred, please contact helpdesk", + '50001022': "A technical problem occurred, please contact helpdesk", + '50001023': "A technical problem occurred, please contact helpdesk", + '50001024': "A technical problem occurred, please contact helpdesk", + '50001025': "A technical problem occurred, please contact helpdesk", + '50001026': "A technical problem occurred, please contact helpdesk", + '50001027': "A technical problem occurred, please contact helpdesk", + '50001028': "A technical problem occurred, please contact helpdesk", + '50001029': "A technical problem occurred, please contact helpdesk", + '50001030': "A technical problem occurred, please contact helpdesk", + '50001031': "A technical problem occurred, please contact helpdesk", + '50001032': "A technical problem occurred, please contact helpdesk", + '50001033': "A technical problem occurred, please contact helpdesk", + '50001034': "A technical problem occurred, please contact helpdesk", + '50001035': "A technical problem occurred, please contact helpdesk", + '50001036': "Card length does not correspond to an acceptable value for the brand", + '50001037': "Purchasing card number for a regular merchant", + '50001038': "Non Purchasing card for a Purchasing card merchant", + '50001039': "Details sent for a non-Purchasing card merchant, please contact helpdesk", + '50001040': "Details not sent for a Purchasing card transaction, please contact helpdesk", + '50001041': "Payment detail validation failed", + '50001042': "Given transactions amounts (tax,discount,shipping,net,etc…) do not compute correctly together", + '50001043': "A technical problem occurred, please contact helpdesk", + '50001044': "No acquirer configured for this operation", + '50001045': "No UID configured for this operation", + '50001046': "Operation not allowed for the merchant", + '50001047': "A technical problem occurred, please contact helpdesk", + '50001048': "A technical problem occurred, please contact helpdesk", + '50001049': "A technical problem occurred, please contact helpdesk", + '50001050': "A technical problem occurred, please contact helpdesk", + '50001051': "A technical problem occurred, please contact helpdesk", + '50001052': "A technical problem occurred, please contact helpdesk", + '50001053': "A technical problem occurred, please contact helpdesk", + '50001054': "Card number incorrect or incompatible", + '50001055': "A technical problem occurred, please contact helpdesk", + '50001056': "A technical problem occurred, please contact helpdesk", + '50001057': "A technical problem occurred, please contact helpdesk", + '50001058': "A technical problem occurred, please contact helpdesk", + '50001059': "A technical problem occurred, please contact helpdesk", + '50001060': "A technical problem occurred, please contact helpdesk", + '50001061': "A technical problem occurred, please contact helpdesk", + '50001062': "A technical problem occurred, please contact helpdesk", + '50001063': "Card Issue Number does not correspond to range or not present", + '50001064': "Start Date not valid or not present", + '50001066': "Format of CVC code invalid", + '50001067': "The merchant is not enrolled for 3D-Secure", + '50001068': "The card number or account number (PAN) is invalid", + '50001069': "Invalid check for CardID and Brand", + '50001070': "The ECI value given is either not supported, or in conflict with other data in the transaction", + '50001071': "Incomplete TRN demat", + '50001072': "Incomplete PAY demat", + '50001073': "No demat APP", + '50001074': "Authorisation too old", + '50001075': "VERRes was an error message", + '50001076': "DCP amount greater than authorisation amount", + '50001077': "Details negative amount", + '50001078': "Details negative quantity", + '50001079': "Could not decode/decompress received PARes (3D-Secure)", + '50001080': "Received PARes was an erereor message from ACS (3D-Secure)", + '50001081': "Received PARes format was invalid according to the 3DS specifications (3D-Secure)", + '50001082': "PAReq/PARes reconciliation failure (3D-Secure)", + '50001084': "Maximum amount reached", + '50001087': "The transaction type requires authentication, please check with your bank.", + '50001090': "CVC missing at input, but CVC check asked", + '50001091': "ZIP missing at input, but ZIP check asked", + '50001092': "Address missing at input, but Address check asked", + '50001095': "Invalid date of birth", + '50001096': "Invalid commodity code", + '50001097': "The requested currency and brand are incompatible.", + '50001111': "Data validation error", + '50001113': "This order has already been processed", + '50001114': "Error pre-payment check page access", + '50001115': "Request not received in secure mode", + '50001116': "Unknown IP address origin", + '50001117': "NO IP address origin", + '50001118': "Pspid not found or not correct", + '50001119': "Password incorrect or disabled due to numbers of errors", + '50001120': "Invalid currency", + '50001121': "Invalid number of decimals for the currency", + '50001122': "Currency not accepted by the merchant", + '50001123': "Card type not active", + '50001124': "Number of lines don't match with number of payments", + '50001125': "Format validation error", + '50001126': "Overflow in data capture requests for the original order", + '50001127': "The original order is not in a correct status", + '50001128': "missing authorization code for unauthorized order", + '50001129': "Overflow in refunds requests", + '50001130': "Error access to original order", + '50001131': "Error access to original history item", + '50001132': "The Selected Catalog is empty", + '50001133': "Duplicate request", + '50001134': "Authentication failed, please retry or cancel.", + '50001135': "Authentication temporary unavailable, please retry or cancel.", + '50001136': "Technical problem with your browser, please retry or cancel", + '50001137': "Your bank access control server is temporary unavailable, please retry or cancel", + '50001150': "Fraud Detection, Technical error (IP not valid)", + '50001151': "Fraud detection : technical error (IPCTY unknown or error)", + '50001152': "Fraud detection : technical error (CCCTY unknown or error)", + '50001153': "Overflow in redo-authorisation requests", + '50001170': "Dynamic BIN check failed", + '50001171': "Dynamic country check failed", + '50001172': "Error in Amadeus signature", + '50001174': "Card Holder Name is too long", + '50001175': "Name contains invalid characters", + '50001176': "Card number is too long", + '50001177': "Card number contains non-numeric info", + '50001178': "Card Number Empty", + '50001179': "CVC too long", + '50001180': "CVC contains non-numeric info", + '50001181': "Expiration date contains non-numeric info", + '50001182': "Invalid expiration month", + '50001183': "Expiration date must be in the future", + '50001184': "SHA Mismatch", + '50001205': "Missing mandatory fields for billing address.", + '50001206': "Missing mandatory field date of birth.", + '50001207': "Missing required shopping basket details.", + '50001208': "Missing social security number", + '50001209': "Invalid country code", + '50001210': "Missing yearly salary", + '50001211': "Missing gender", + '50001212': "Missing email", + '50001213': "Missing IP address", + '50001214': "Missing part payment campaign ID", + '50001215': "Missing invoice number", + '50001216': "The alias must be different than the card number", + '60000001': "account number unknown", + '60000003': "not credited dd-mm-yy", + '60000005': "name/number do not correspond", + '60000007': "account number blocked", + '60000008': "specific direct debit block", + '60000009': "account number WKA", + '60000010': "administrative reason", + '60000011': "account number expired", + '60000012': "no direct debit authorisation given", + '60000013': "debit not approved", + '60000014': "double payment", + '60000018': "name/address/city not entered", + '60001001': "no original direct debit for revocation", + '60001002': "payer’s account number format error", + '60001004': "payer’s account at different bank", + '60001005': "payee’s account at different bank", + '60001006': "payee’s account number format error", + '60001007': "payer’s account number blocked", + '60001008': "payer’s account number expired", + '60001009': "payee’s account number expired", + '60001010': "direct debit not possible", + '60001011': "creditor payment not possible", + '60001012': "payer’s account number unknown WKA-number", + '60001013': "payee’s account number unknown WKA-number", + '60001014': "impermissible WKA transaction", + '60001015': "period for revocation expired", + '60001017': "reason for revocation not correct", + '60001018': "original run number not numeric", + '60001019': "payment ID incorrect", + '60001020': "amount not numeric", + '60001021': "amount zero not permitted", + '60001022': "negative amount not permitted", + '60001023': "payer and payee giro account number", + '60001025': "processing code (verwerkingscode) incorrect", + '60001028': "revocation not permitted", + '60001029': "guaranteed direct debit on giro account number", + '60001030': "NBC transaction type incorrect", + '60001031': "description too large", + '60001032': "book account number not issued", + '60001034': "book account number incorrect", + '60001035': "payer’s account number not numeric", + '60001036': "payer’s account number not eleven-proof", + '60001037': "payer’s account number not issued", + '60001039': "payer’s account number of DNB/BGC/BLA", + '60001040': "payee’s account number not numeric", + '60001041': "payee’s account number not eleven-proof", + '60001042': "payee’s account number not issued", + '60001044': "payee’s account number unknown", + '60001050': "payee’s name missing", + '60001051': "indicate payee’s bank account number instead of 3102", + '60001052': "no direct debit contract", + '60001053': "amount beyond bounds", + '60001054': "selective direct debit block", + '60001055': "original run number unknown", + '60001057': "payer’s name missing", + '60001058': "payee’s account number missing", + '60001059': "restore not permitted", + '60001060': "bank’s reference (navraaggegeven) missing", + '60001061': "BEC/GBK number incorrect", + '60001062': "BEC/GBK code incorrect", + '60001087': "book account number not numeric", + '60001090': "cancelled on request", + '60001091': "cancellation order executed", + '60001092': "cancelled instead of bended", + '60001093': "book account number is a shortened account number", + '60001094': "instructing party account number not identical with payer", + '60001095': "payee unknown GBK acceptor", + '60001097': "instructing party account number not identical with payee", + '60001099': "clearing not permitted", + '60001101': "payer’s account number not spaces", + '60001102': "PAN length not numeric", + '60001103': "PAN length outside limits", + '60001104': "track number not numeric", + '60001105': "track number not valid", + '60001106': "PAN sequence number not numeric", + '60001107': "domestic PAN not numeric", + '60001108': "domestic PAN not eleven-proof", + '60001109': "domestic PAN not issued", + '60001110': "foreign PAN not numeric", + '60001111': "card valid date not numeric", + '60001112': "book period number (boekperiodenr) not numeric", + '60001113': "transaction number not numeric", + '60001114': "transaction time not numeric", + '60001115': "transaction no valid time", + '60001116': "transaction date not numeric", + '60001117': "transaction no valid date", + '60001118': "STAN not numeric", + '60001119': "instructing party’s name missing", + '60001120': "foreign amount (bedrag-vv) not numeric", + '60001122': "rate (verrekenkoers) not numeric", + '60001125': "number of decimals (aantaldecimalen) incorrect", + '60001126': "tariff (tarifering) not B/O/S", + '60001127': "domestic costs (kostenbinnenland) not numeric", + '60001128': "domestic costs (kostenbinnenland) not higher than zero", + '60001129': "foreign costs (kostenbuitenland) not numeric", + '60001130': "foreign costs (kostenbuitenland) not higher than zero", + '60001131': "domestic costs (kostenbinnenland) not zero", + '60001132': "foreign costs (kostenbuitenland) not zero", + '60001134': "Euro record not fully filled in", + '60001135': "Client currency incorrect", + '60001136': "Amount NLG not numeric", + '60001137': "Amount NLG not higher than zero", + '60001138': "Amount NLG not equal to Amount", + '60001139': "Amount NLG incorrectly converted", + '60001140': "Amount EUR not numeric", + '60001141': "Amount EUR not greater than zero", + '60001142': "Amount EUR not equal to Amount", + '60001143': "Amount EUR incorrectly converted", + '60001144': "Client currency not NLG", + '60001145': "rate euro-vv (Koerseuro-vv) not numeric", + '60001146': "comma rate euro-vv (Kommakoerseuro-vv) incorrect", + '60001147': "acceptgiro distributor not valid", + '60001148': "Original run number and/or BRN are missing", + '60001149': "Amount/Account number/ BRN different", + '60001150': "Direct debit already revoked/restored", + '60001151': "Direct debit already reversed/revoked/restored", + '60001153': "Payer’s account number not known", +} + +DATA_VALIDATION_ERROR = '50001111' + + +def retryable(error): + return error in [ + '0020001001', '0020001002', '0020001003', '0020001004', '0020001005', + '0020001006', '0020001007', '0020001008', '0020001009', '0020001010', + '30001010', '30001011', '30001015', + '30001057', '30001058', + '30001998', '30001999', + #'30611001', # amount exceeds card limit + '30961001', + '40001001', '40001002', '40001003', '40001004', '40001005', + '40001006', '40001007', '40001008', '40001009', '40001010', + '40001012', + '40001018', '40001019', '40001020', + '40001134', '40001135', '40001136', '40001137', + #'50001174', # cardholder name too long + ] diff --git a/addons/payment_acquirer_ogone/data/ogone.xml b/addons/payment_acquirer_ogone/data/ogone.xml new file mode 100644 index 00000000000..51f67114b1f --- /dev/null +++ b/addons/payment_acquirer_ogone/data/ogone.xml @@ -0,0 +1,17 @@ + + + + + + ogone + + test + dummy + dummy + dummy + tINY4Yv14789gUix1130 + tINYj885Tfvd4P471464 + + + + diff --git a/addons/payment_acquirer_ogone/doc/changelog.rst b/addons/payment_acquirer_ogone/doc/changelog.rst new file mode 100644 index 00000000000..d0c24af384d --- /dev/null +++ b/addons/payment_acquirer_ogone/doc/changelog.rst @@ -0,0 +1,9 @@ +.. _changelog: + +Changelog +========= + +`trunk (saas-3)` +---------------- + +- Module creation \ No newline at end of file diff --git a/addons/payment_acquirer_ogone/doc/index.rst b/addons/payment_acquirer_ogone/doc/index.rst new file mode 100644 index 00000000000..85028ed0d3e --- /dev/null +++ b/addons/payment_acquirer_ogone/doc/index.rst @@ -0,0 +1,14 @@ +Payment module documentation +============================ + +Payment documentation topics +'''''''''''''''''''''''''''' + + +Changelog +''''''''' + +.. toctree:: + :maxdepth: 1 + + changelog.rst diff --git a/addons/payment_acquirer_ogone/models/__init__.py b/addons/payment_acquirer_ogone/models/__init__.py new file mode 100644 index 00000000000..349d8f668e8 --- /dev/null +++ b/addons/payment_acquirer_ogone/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import ogone diff --git a/addons/payment_acquirer_ogone/models/ogone.py b/addons/payment_acquirer_ogone/models/ogone.py new file mode 100644 index 00000000000..b06505c1cdd --- /dev/null +++ b/addons/payment_acquirer_ogone/models/ogone.py @@ -0,0 +1,408 @@ +# -*- coding: utf-'8' "-*-" + +from hashlib import sha1 +import logging +from lxml import etree, objectify +from pprint import pformat +import time +from urllib import urlencode +import urllib2 +import urlparse + +from openerp.addons.payment_acquirer.models.payment_acquirer import ValidationError +from openerp.addons.payment_acquirer_ogone.controllers.main import OgoneController +from openerp.addons.payment_acquirer_ogone.data import ogone +from openerp.osv import osv, fields +from openerp.tools import float_round + +_logger = logging.getLogger(__name__) + + +class PaymentAcquirerOgone(osv.Model): + _inherit = 'payment.acquirer' + + def _get_ogone_urls(self, cr, uid, ids, name, args, context=None): + """ Ogone URLS: + + - standard order: POST address for form-based + + @TDETODO: complete me + """ + res = {} + for acquirer in self.browse(cr, uid, ids, context=context): + qualif = acquirer.env + res[acquirer.id] = { + 'ogone_standard_order_url': 'https://secure.ogone.com/ncol/%s/orderstandard.asp' % qualif, + 'ogone_direct_order_url': 'https://secure.ogone.com/ncol/%s/orderdirect.asp' % qualif, + 'ogone_direct_query_url': 'https://secure.ogone.com/ncol/%s/querydirect.asp' % qualif, + 'ogone_afu_agree_url': 'https://secure.ogone.com/ncol/%s/AFU_agree.asp' % qualif, + } + return res + + _columns = { + 'ogone_pspid': fields.char( + 'PSPID', required_if_provider='ogone'), + 'ogone_userid': fields.char( + 'API User id', required_if_provider='ogone'), + 'ogone_password': fields.char( + 'Password', required_if_provider='ogone'), + 'ogone_shakey_in': fields.char( + 'SHA Key IN', size=32, required_if_provider='ogone'), + 'ogone_shakey_out': fields.char( + 'SHA Key OUT', size=32, required_if_provider='ogone'), + # store ogone contact URLs -> not necessary IMHO + 'ogone_standard_order_url': fields.function( + _get_ogone_urls, type='char', multi='_get_ogone_urls', + string='Stanrd Order URL (form)'), + 'ogone_direct_order_url': fields.function( + _get_ogone_urls, type='char', multi='_get_ogone_urls', + string='Direct Order URL (2)'), + 'ogone_direct_query_url': fields.function( + _get_ogone_urls, type='char', multi='_get_ogone_urls', + string='Direct Query URL'), + 'ogone_afu_agree_url': fields.function( + _get_ogone_urls, type='char', multi='_get_ogone_urls', + string='AFU Agree URL'), + } + + def _ogone_generate_shasign(self, acquirer, inout, values): + """ Generate the shasign for incoming or outgoing communications. + + :param browse acquirer: the payment.acquirer browse record. It should + have a shakey in shaky out + :param string inout: 'in' (openerp contacting ogone) or 'out' (ogone + contacting openerp). In this last case only some + fields should be contained (see e-Commerce basic) + :param dict values: transaction values + + :return string: shasign + """ + assert inout in ('in', 'out') + assert acquirer.name == 'ogone' + key = getattr(acquirer, 'ogone_shakey_' + inout) + + def filter_key(key): + if inout == 'in': + return True + else: + keys = "ORDERID CURRENCY AMOUNT PM ACCEPTANCE STATUS CARDNO ALIAS ED CN TRXDATE PAYID NCERROR BRAND ECI IP COMPLUS".split() + return key.upper() in keys + + items = sorted((k.upper(), v) for k, v in values.items()) + sign = ''.join('%s=%s%s' % (k, v, key) for k, v in items if v and filter_key(k)) + shasign = sha1(sign).hexdigest() + return shasign + + def ogone_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 = {} + base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') + acquirer = self.browse(cr, uid, id, context=context) + partner = None + if partner_id: + partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context) + tx_values = { + 'PSPID': acquirer.ogone_pspid, + 'ORDERID': reference, + 'AMOUNT': '%d' % int(float_round(amount, 2) * 100), + 'CURRENCY': currency and currency.name or 'EUR', + 'LANGUAGE': partner and partner.lang or partner_values.get('lang', ''), + 'CN': partner and partner.name or partner_values.get('name', ''), + 'EMAIL': partner and partner.email or partner_values.get('email', ''), + 'OWNERZIP': partner and partner.zip or partner_values.get('zip', ''), + 'OWNERADDRESS': partner and ' '.join((partner.street or '', partner.street2 or '')).strip() or ' '.join((partner_values.get('street', ''), partner_values.get('street2', ''))).strip(), + 'OWNERTOWN': partner and partner.city or partner_values.get('city', ''), + 'OWNERCTY': partner and partner.country_id and partner.country_id.name or partner_values.get('country_name', ''), + 'OWNERTELNO': partner and partner.phone or partner_values.get('phone', ''), + 'ACCEPTURL': '%s' % urlparse.urljoin(base_url, OgoneController._accept_url), + 'DECLINEURL': '%s' % urlparse.urljoin(base_url, OgoneController._decline_url), + 'EXCEPTIONURL': '%s' % urlparse.urljoin(base_url, OgoneController._exception_url), + 'CANCELURL': '%s' % urlparse.urljoin(base_url, OgoneController._cancel_url), + } + if tx_custom_values and tx_custom_values.get('return_url'): + tx_values['PARAMPLUS'] = 'return_url=%s' % tx_custom_values.pop('return_url') + if tx_custom_values: + tx_values.update(tx_custom_values) + shasign = self._ogone_generate_shasign(acquirer, 'in', tx_values) + tx_values['SHASIGN'] = shasign + return tx_values + + def ogone_get_form_action_url(self, cr, uid, id, context=None): + acquirer = self.browse(cr, uid, id, context=context) + return acquirer.ogone_standard_order_url + + +class PaymentTxOgone(osv.Model): + _inherit = 'payment.transaction' + # ogone status + _ogone_valid_tx_status = [5, 9] + _ogone_wait_tx_status = [41, 50, 51, 52, 55, 56, 91, 92, 99] + _ogone_pending_tx_status = [46] # 3DS HTML response + _ogone_cancel_tx_status = [1] + + _columns = { + 'ogone_3ds': fields.dummy('3ds Activated'), + 'ogone_3ds_html': fields.html('3DS HTML'), + 'ogone_feedback_model': fields.char(), + 'ogone_feedback_eval': fields.char(), + 'ogone_complus': fields.char('Complus'), + 'ogone_payid': fields.char('PayID', help='Payment ID, generated by Ogone') + } + + # -------------------------------------------------- + # FORM RELATED METHODS + # -------------------------------------------------- + + def ogone_form_generate_values(self, cr, uid, id, tx_custom_values=None, context=None): + """ Ogone-specific value generation for rendering a transaction-based + form button. """ + tx = self.browse(cr, uid, id, context=context) + + tx_data = { + 'LANGUAGE': tx.partner_lang, + 'CN': tx.partner_name, + 'EMAIL': tx.partner_email, + 'OWNERZIP': tx.partner_zip, + 'OWNERADDRESS': tx.partner_address, + 'OWNERTOWN': tx.partner_city, + 'OWNERCTY': tx.partner_country_id and tx.partner_country_id.name or '', + 'OWNERTELNO': tx.partner_phone, + } + if tx_custom_values: + tx_data.update(tx_custom_values) + return self.pool['payment.acquirer'].ogone_form_generate_values( + cr, uid, tx.acquirer_id.id, + tx.reference, tx.amount, tx.currency_id, + tx_custom_values=tx_data, + context=context + ) + + def _ogone_form_get_tx_from_data(self, cr, uid, data, context=None): + """ Given a data dict coming from ogone, verify it and find the related + transaction record. """ + reference, pay_id, shasign = data.get('orderID'), data.get('PAYID'), data.get('SHASIGN') + if not reference or not pay_id or not shasign: + error_msg = 'Ogone: received data with missing reference (%s) or pay_id (%s) or shashign (%s)' % (reference, pay_id, shasign) + _logger.error(error_msg) + raise ValidationError(error_msg) + + # find tx -> @TDENOTE use paytid ? + tx_ids = self.search(cr, uid, [('reference', '=', reference)], context=context) + if not tx_ids or len(tx_ids) > 1: + error_msg = 'Ogone: received data for reference %s' % (reference) + if not tx_ids: + error_msg += '; no order found' + else: + error_msg += '; multiple order found' + _logger.error(error_msg) + raise ValidationError(error_msg) + tx = self.pool['payment.transaction'].browse(cr, uid, tx_ids[0], context=context) + + # verify shasign + shasign_check = self.pool['payment.acquirer']._ogone_generate_shasign(tx.acquirer_id, 'out', data) + if shasign_check.upper() != shasign.upper(): + error_msg = 'Ogone: invalid shasign, received %s, computed %s, for data %s' % (shasign, shasign_check, data) + _logger.error(error_msg) + raise ValidationError(error_msg) + + return tx + + def ogone_form_feedback(self, cr, uid, data, context=None): + tx = self._ogone_form_get_tx_from_data(cr, uid, data, context) + if not tx: + raise ValidationError('Ogone: feedback: tx not found') + if tx.state == 'done': + _logger.warning('Ogone: trying to validate an already validated tx (ref %s' % tx.reference) + return False + + status = int(data.get('STATUS', '0')) + if status in self._ogone_valid_tx_status: + tx.write({ + 'state': 'done', + 'date_validate': data['TRXDATE'], + 'ogone_payid': data['PAYID'], + }) + return True + elif status in self._ogone_cancel_tx_status: + tx.write({ + 'state': 'cancel', + }) + elif status in self._ogone_pending_tx_status: + tx.write({ + 'state': 'pending', + }) + else: + error = 'Ogone: feedback error: %(error_str)s\n\n%(error_code)s: %(error_msg)s' % { + 'error_str': data.get('NCERROR'), + 'error_code': data.get('NCERRORPLUS'), + 'error_msg': ogone.OGONE_ERROR_MAP.get(data.get('NCERRORPLUS')), + } + _logger.info(error) + tx.write({'state': 'error', 'state_message': error}) + return False + + # -------------------------------------------------- + # S2S RELATED METHODS + # -------------------------------------------------- + + def ogone_s2s_create_alias(self, cr, uid, id, values, context=None): + """ Purpose: create an alias via batch """ + tx = self.browse(cr, uid, id, context=context) + assert tx.type == 'server2server', 'Calling s2s dedicated method for a %s acquirer' % tx.type + alias = 'OPENERP-%d-%d' % (tx.partner_id.id, tx.id) + + expiry_date = '%s%s' % (values['expiry_date_mm'], values['expiry_date_yy'][2:]) + line = 'ADDALIAS;%(alias)s;%(holder_name)s;%(number)s;%(expiry_date)s;%(brand)s;%(pspid)s' + line = line % dict(values, alias=alias, expiry_date=expiry_date, pspid=tx.acquirer_id.ogone_pspid) + + tx_data = { + 'FILE_REFERENCE': 'OPENERP-NEW-ALIAS-%s' % time.time(), # something unique, + 'TRANSACTION_CODE': 'ATR', + 'OPERATION': 'SAL', + 'NB_PAYMENTS': 1, # even if we do not actually have any payment, ogone want it to not be 0 + 'FILE': line, + 'REPLY_TYPE': 'XML', + 'PSPID': tx.acquirer_id.ogone_pspid, + 'USERID': tx.acquirer_id.ogone_userid, + 'PSWD': tx.acquirer_id.ogone_password, + 'PROCESS_MODE': 'CHECKANDPROCESS', + } + + request = urllib2.Request(tx.acquirer_id.ogone_afu_agree_url, urlencode(tx_data)) + result = urllib2.urlopen(request).read() + + try: + tree = objectify.fromstring(result) + except etree.XMLSyntaxError: + _logger.exception('Invalid xml response from ogone') + return None + + error_code = error_str = None + if hasattr(tree, 'PARAMS_ERROR'): + error_code = tree.NCERROR.text + error_str = 'PARAMS ERROR: %s' % (tree.PARAMS_ERROR.text or '',) + else: + node = tree.FORMAT_CHECK + error_node = getattr(node, 'FORMAT_CHECK_ERROR', None) + if error_node is not None: + error_code = error_node.NCERROR.text + error_str = 'CHECK ERROR: %s' % (error_node.ERROR.text or '',) + + if error_code: + error_msg = ogone.OGONE_ERROR_MAP.get(error_code) + error = '%s\n\n%s: %s' % (error_str, error_code, error_msg) + _logger.error(error) + raise Exception(error) # TODO specific exception + + tx.write({'partner_reference': alias}) + return True + + def ogone_s2s_generate_values(self, cr, uid, id, custom_values, context=None): + tx = self.browse(cr, uid, id, context=context) + tx_data = { + 'PSPID': tx.acquirer_id.ogone_pspid, + 'USERID': tx.acquirer_id.ogone_userid, + 'PSWD': tx.acquirer_id.ogone_password, + 'OrderID': tx.reference, + 'amount': '%d' % int(float_round(tx.amount, 2) * 100), # tde check amount or str * 100 ? + 'CURRENCY': tx.currency_id.name, + 'LANGUAGE': tx.partner_lang, + 'OPERATION': 'SAL', + 'ECI': 2, # Recurring (from MOTO) + 'ALIAS': tx.partner_reference, + 'RTIMEOUT': 30, + } + if custom_values.get('ogone_cvc'): + tx_data['CVC'] = custom_values.get('ogone_cvc') + if custom_values.pop('ogone_3ds', None): + tx_data.update({ + 'FLAG3D': 'Y', # YEAH!! + }) + if custom_values.get('ogone_complus'): + tx_data['COMPLUS'] = custom_values.get('ogone_complus') + if custom_values.get('ogone_accept_url'): + pass + + shasign = self.pool['payment.acquirer']._ogone_generate_shasign(tx.acquirer_id, 'in', tx_data) + tx_data['SHASIGN'] = shasign + return tx_data + + def ogone_s2s_feedback(self, cr, uid, data, context=None): + pass + + def ogone_s2s_execute(self, cr, uid, id, values, context=None): + tx = self.browse(cr, uid, id, context=context) + + tx_data = self.ogone_s2s_generate_values(cr, uid, id, values, context=context) + _logger.info('Generated Ogone s2s data %s', pformat(tx_data)) # debug + + request = urllib2.Request(tx.acquirer_id.ogone_direct_order_url, urlencode(tx_data)) + result = urllib2.urlopen(request).read() + _logger.info('Contacted Ogone direct order; result %s', result) # debug + + tree = objectify.fromstring(result) + payid = tree.get('PAYID') + + query_direct_data = dict( + PSPID=tx.acquirer_id.ogone_pspid, + USERID=tx.acquirer_id.ogone_userid, + PSWD=tx.acquirer_id.ogone_password, + ID=payid, + ) + query_direct_url = 'https://secure.ogone.com/ncol/%s/querydirect.asp' % (tx.acquirer_id.env,) + + tries = 2 + tx_done = False + tx_status = False + while not tx_done or tries > 0: + try: + tree = objectify.fromstring(result) + except etree.XMLSyntaxError: + # invalid response from ogone + _logger.exception('Invalid xml response from ogone') + raise + + # see https://secure.ogone.com/ncol/paymentinfos1.asp + VALID_TX = [5, 9] + WAIT_TX = [41, 50, 51, 52, 55, 56, 91, 92, 99] + PENDING_TX = [46] # 3DS HTML response + # other status are errors... + + status = tree.get('STATUS') + if status == '': + status = None + else: + status = int(status) + + if status in VALID_TX: + tx_status = True + tx_done = True + + elif status in PENDING_TX: + html = str(tree.HTML_ANSWER) + tx_data.update(ogone_3ds_html=html.decode('base64')) + tx_status = False + tx_done = True + + elif status in WAIT_TX: + time.sleep(1500) + + request = urllib2.Request(query_direct_url, urlencode(query_direct_data)) + result = urllib2.urlopen(request).read() + _logger.debug('Contacted Ogone query direct; result %s', result) + + else: + error_code = tree.get('NCERROR') + if not ogone.retryable(error_code): + error_str = tree.get('NCERRORPLUS') + error_msg = ogone.OGONE_ERROR_MAP.get(error_code) + error = 'ERROR: %s\n\n%s: %s' % (error_str, error_code, error_msg) + _logger.info(error) + raise Exception(error) + + tries = tries - 1 + + if not tx_done and tries == 0: + raise Exception('Cannot get transaction status...') + + return tx_status diff --git a/addons/payment_acquirer_ogone/static/description/icon.png b/addons/payment_acquirer_ogone/static/description/icon.png new file mode 100644 index 00000000000..4151a633c79 Binary files /dev/null and b/addons/payment_acquirer_ogone/static/description/icon.png differ diff --git a/addons/payment_acquirer_ogone/static/src/img/ogone_logo.png b/addons/payment_acquirer_ogone/static/src/img/ogone_logo.png new file mode 100644 index 00000000000..89e0ef6816f Binary files /dev/null and b/addons/payment_acquirer_ogone/static/src/img/ogone_logo.png differ diff --git a/addons/payment_acquirer_ogone/static/src/img/ogone_logo_plain.gif b/addons/payment_acquirer_ogone/static/src/img/ogone_logo_plain.gif new file mode 100644 index 00000000000..e7833ec3b6d Binary files /dev/null and b/addons/payment_acquirer_ogone/static/src/img/ogone_logo_plain.gif differ diff --git a/addons/payment_acquirer_ogone/tests/__init__.py b/addons/payment_acquirer_ogone/tests/__init__.py new file mode 100644 index 00000000000..6607b8cf6cd --- /dev/null +++ b/addons/payment_acquirer_ogone/tests/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from . import test_ogone + +checks = [ + test_ogone, +] diff --git a/addons/payment_acquirer_ogone/tests/test_ogone.py b/addons/payment_acquirer_ogone/tests/test_ogone.py new file mode 100644 index 00000000000..245cef73007 --- /dev/null +++ b/addons/payment_acquirer_ogone/tests/test_ogone.py @@ -0,0 +1,233 @@ +# -*- coding: utf-8 -*- + +from openerp.addons.payment_acquirer.models.payment_acquirer import ValidationError +from openerp.addons.payment_acquirer.tests.common import PaymentAcquirerCommon +from openerp.addons.payment_acquirer_ogone.controllers.main import OgoneController +from openerp.tools import mute_logger + +from lxml import objectify +# import requests +import time +import urlparse + + +class OgonePayment(PaymentAcquirerCommon): + + def setUp(self): + super(OgonePayment, self).setUp() + cr, uid = self.cr, self.uid + + self.base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url') + model, self.ogone_view_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'payment_acquirer_ogone', 'ogone_acquirer_button') + + # create a new ogone account + self.ogone_id = self.payment_acquirer.create( + cr, uid, { + 'name': 'ogone', + 'env': 'test', + 'view_template_id': self.ogone_view_id, + 'ogone_pspid': 'dummy', + 'ogone_userid': 'dummy', + 'ogone_password': 'dummy', + 'ogone_shakey_in': 'tINY4Yv14789gUix1130', + 'ogone_shakey_out': 'tINYj885Tfvd4P471464', + }) + self.ogone_url = self.payment_acquirer._get_ogone_urls(cr, uid, [self.ogone_id], None, None)[self.ogone_id]['ogone_standard_order_url'] + + def test_00_ogone_acquirer(self): + ogone = self.payment_acquirer.browse(self.cr, self.uid, self.ogone_id, None) + self.assertEqual(ogone.env, 'test', 'test without test env') + + def test_10_ogone_form_render(self): + cr, uid, context = self.cr, self.uid, {} + + # ---------------------------------------- + # Test: button direct rendering + shasign + # ---------------------------------------- + + form_values = { + 'PSPID': 'dummy', + 'ORDERID': 'test_ref0', + 'AMOUNT': '1', + 'CURRENCY': 'EUR', + 'LANGUAGE': 'en_US', + 'CN': 'Norbert Buyer', + 'EMAIL': 'norbert.buyer@example.com', + 'OWNERZIP': '1000', + 'OWNERADDRESS': 'Huge Street 2/543', + 'OWNERCTY': 'Belgium', + 'OWNERTOWN': 'Sin City', + 'OWNERTELNO': '0032 12 34 56 78', + 'SHASIGN': '815f67b8ff70d234ffcf437c13a9fa7f807044cc', + 'ACCEPTURL': '%s' % urlparse.urljoin(self.base_url, OgoneController._accept_url), + 'DECLINEURL': '%s' % urlparse.urljoin(self.base_url, OgoneController._decline_url), + 'EXCEPTIONURL': '%s' % urlparse.urljoin(self.base_url, OgoneController._exception_url), + 'CANCELURL': '%s' % urlparse.urljoin(self.base_url, OgoneController._cancel_url), + } + + # render the button + res = self.payment_acquirer.render( + cr, uid, self.ogone_id, + 'test_ref0', 0.01, self.currency_euro, + partner_id=None, + partner_values=self.buyer_values, + context=context) + + # check form result + tree = objectify.fromstring(res) + self.assertEqual(tree.get('action'), 'https://secure.ogone.com/ncol/test/orderstandard.asp', 'ogone: wrong form POST url') + for form_input in tree.input: + if form_input.get('name') in ['submit']: + continue + self.assertEqual( + form_input.get('value'), + form_values[form_input.get('name')], + 'ogone: wrong value for form: received %s instead of %s' % (form_input.get('value'), form_values[form_input.get('name')]) + ) + + # ---------------------------------------- + # Test2: button using tx + validation + # ---------------------------------------- + + # create a new draft tx + tx_id = self.payment_transaction.create( + cr, uid, { + 'amount': 0.01, + 'acquirer_id': self.ogone_id, + 'currency_id': self.currency_euro_id, + 'reference': 'test_ref0', + 'partner_id': self.buyer_id, + }, context=context + ) + # render the button + res = self.payment_acquirer.render( + cr, uid, self.ogone_id, + 'should_be_erased', 0.01, self.currency_euro, + tx_id=tx_id, + partner_id=None, + partner_values=self.buyer_values, + context=context) + + # check form result + tree = objectify.fromstring(res) + self.assertEqual(tree.get('action'), 'https://secure.ogone.com/ncol/test/orderstandard.asp', 'ogone: wrong form POST url') + for form_input in tree.input: + if form_input.get('name') in ['submit']: + continue + self.assertEqual( + form_input.get('value'), + form_values[form_input.get('name')], + 'ogone: wrong value for form input %s: received %s instead of %s' % (form_input.get('name'), form_input.get('value'), form_values[form_input.get('name')]) + ) + + @mute_logger('openerp.addons.payment_acquirer_ogone.models.ogone', 'ValidationError') + def test_20_ogone_form_management(self): + cr, uid, context = self.cr, self.uid, {} + + # typical data posted by ogone after client has successfully paid + ogone_post_data = { + 'orderID': u'test_ref_2', + 'STATUS': u'9', + 'CARDNO': u'XXXXXXXXXXXX0002', + 'PAYID': u'25381582', + 'CN': u'Norbert Buyer', + 'NCERROR': u'0', + 'TRXDATE': u'11/15/13', + 'IP': u'85.201.233.72', + 'BRAND': u'VISA', + 'ACCEPTANCE': u'test123', + 'currency': u'EUR', + 'amount': u'1.95', + 'SHASIGN': u'7B7B0ED9CBC4A85543A9073374589033A62A05A5', + 'ED': u'0315', + 'PM': u'CreditCard' + } + + # should raise error about unknown tx + with self.assertRaises(ValidationError): + self.payment_transaction.ogone_form_feedback(cr, uid, ogone_post_data, context=context) + + # create tx + tx_id = self.payment_transaction.create( + cr, uid, { + 'amount': 1.95, + 'acquirer_id': self.ogone_id, + 'currency_id': self.currency_euro_id, + 'reference': 'test_ref_2', + 'partner_name': 'Norbert Buyer', + }, context=context + ) + # validate it + self.payment_transaction.ogone_form_feedback(cr, uid, ogone_post_data, context=context) + # check state + tx = self.payment_transaction.browse(cr, uid, tx_id, context=context) + self.assertEqual(tx.state, 'done', 'ogone: validation did not put tx into done state') + self.assertEqual(tx.ogone_payid, ogone_post_data.get('PAYID'), 'ogone: validation did not update tx payid') + + # reset tx + tx.write({'state': 'draft', 'date_validate': False, 'ogone_payid': False}) + + # now ogone post is ok: try to modify the SHASIGN + ogone_post_data['SHASIGN'] = 'a4c16bae286317b82edb49188d3399249a784691' + with self.assertRaises(ValidationError): + self.payment_transaction.ogone_form_feedback(cr, uid, ogone_post_data, context=context) + + # simulate an error + ogone_post_data['STATUS'] = 2 + ogone_post_data['SHASIGN'] = 'a4c16bae286317b82edb49188d3399249a784691' + self.payment_transaction.ogone_form_feedback(cr, uid, ogone_post_data, context=context) + # check state + tx = self.payment_transaction.browse(cr, uid, tx_id, context=context) + self.assertEqual(tx.state, 'error', 'ogone: erroneous validation did not put tx into error state') + + def test_30_ogone_s2s(self): + test_ref = 'test_ref_%.15f' % time.time() + cr, uid, context = self.cr, self.uid, {} + + # create a new draft tx + tx_id = self.payment_transaction.create( + cr, uid, { + 'amount': 0.01, + 'acquirer_id': self.ogone_id, + 'currency_id': self.currency_euro_id, + 'reference': test_ref, + 'partner_id': self.buyer_id, + 'type': 'server2server', + }, context=context + ) + + # create an alias + res = self.payment_transaction.ogone_s2s_create_alias( + cr, uid, tx_id, { + 'expiry_date_mm': '01', + 'expiry_date_yy': '2015', + 'holder_name': 'Norbert Poilu', + 'number': '4000000000000002', + 'brand': 'VISA', + }, context=context) + + # check an alias is set, containing at least OPENERP + tx = self.payment_transaction.browse(cr, uid, tx_id, context=context) + self.assertIn('OPENERP', tx.partner_reference, 'ogone: wrong partner reference after creating an alias') + + res = self.payment_transaction.ogone_s2s_execute(cr, uid, tx_id, {}, context=context) + # print res + + +# { +# 'orderID': u'reference', +# 'STATUS': u'9', +# 'CARDNO': u'XXXXXXXXXXXX0002', +# 'PAYID': u'24998692', +# 'CN': u'Norbert Poilu', +# 'NCERROR': u'0', +# 'TRXDATE': u'11/05/13', +# 'IP': u'85.201.233.72', +# 'BRAND': u'VISA', +# 'ACCEPTANCE': u'test123', +# 'currency': u'EUR', +# 'amount': u'1.95', +# 'SHASIGN': u'EFDC56879EF7DE72CCF4B397076B5C9A844CB0FA', +# 'ED': u'0314', +# 'PM': u'CreditCard' +# } diff --git a/addons/payment_acquirer_ogone/views/ogone.xml b/addons/payment_acquirer_ogone/views/ogone.xml new file mode 100644 index 00000000000..f71f92197f0 --- /dev/null +++ b/addons/payment_acquirer_ogone/views/ogone.xml @@ -0,0 +1,49 @@ + + + + + + + + diff --git a/addons/payment_acquirer_ogone/views/payment_acquirer.xml b/addons/payment_acquirer_ogone/views/payment_acquirer.xml new file mode 100644 index 00000000000..8ec958a5351 --- /dev/null +++ b/addons/payment_acquirer_ogone/views/payment_acquirer.xml @@ -0,0 +1,41 @@ + + + + + + acquirer.form.ogone + payment.acquirer + + + + + + + + + + + + + + + + acquirer.transaction.form.ogone + payment.transaction + + + + + + + + + + + + + + + diff --git a/addons/payment_acquirer_paypal/__init__.py b/addons/payment_acquirer_paypal/__init__.py new file mode 100644 index 00000000000..dde6f25c728 --- /dev/null +++ b/addons/payment_acquirer_paypal/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2013-Today OpenERP SA (). +# +# 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 . +# +############################################################################## + +import models +import controllers diff --git a/addons/payment_acquirer_paypal/__openerp__.py b/addons/payment_acquirer_paypal/__openerp__.py new file mode 100644 index 00000000000..d7ba75d0a7b --- /dev/null +++ b/addons/payment_acquirer_paypal/__openerp__.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +{ + 'name': 'Paypal Payment Acquirer', + 'category': 'Hidden', + 'summary': 'Payment Acquirer: Paypal Implementation', + 'version': '1.0', + 'description': """Paypal Payment Acquirer""", + 'author': 'OpenERP SA', + 'depends': ['payment_acquirer'], + 'data': [ + 'views/paypal.xml', + 'views/payment_acquirer.xml', + 'data/paypal.xml', + ], + 'installable': True, +} diff --git a/addons/payment_acquirer_paypal/controllers/__init__.py b/addons/payment_acquirer_paypal/controllers/__init__.py new file mode 100644 index 00000000000..bbd183e955b --- /dev/null +++ b/addons/payment_acquirer_paypal/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import main diff --git a/addons/payment_acquirer_paypal/controllers/main.py b/addons/payment_acquirer_paypal/controllers/main.py new file mode 100644 index 00000000000..09321631db0 --- /dev/null +++ b/addons/payment_acquirer_paypal/controllers/main.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2013-Today OpenERP SA (). +# +# 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 . +# +############################################################################## + +from openerp.addons.web import http +from openerp.addons.web.http import request +# from openerp.addons.payment_acquirer.models.payment_acquirer import ValidationError +from openerp.addons.website.models import website + +import logging +import requests +from urllib import urlencode + +_logger = logging.getLogger(__name__) + + +class PaypalController(http.Controller): + _notify_url = '/payment/paypal/ipn/' + _return_url = '/payment/paypal/dpn/' + _cancel_url = '/payment/paypal/cancel/' + + @website.route([ + '/payment/paypal/ipn/', + ], type='http', auth='public') + def paypal_ipn(self, **post): + print 'Entering paypal_ipn with post', post + # step 1: return an empty HTTP 200 response -> will be done at the end by returning '' + + # step 2: POST the complete, unaltered message back to Paypal (preceded by cmd=_notify-validate), with same encoding + paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr" + post_url = '%s?cmd=_notify-validate&%s' % (paypal_url, urlencode(post)) + resp = requests.post(post_url) + print '\tReceived response', resp, resp.text + + # step 3: paypal send either VERIFIED or INVALID (single word) + if resp.text == 'VERIFIED': + _logger.info('Paypal: received verified IPN') + cr, uid, context = request.cr, request.uid, request.context + payment_transaction = request.registry['payment.transaction'] + res = payment_transaction.paypal_form_feedback(cr, uid, post, context=context) + print '\tValidation result', res + elif resp.text == 'INVALID': + _logger.warning('Paypal: received invalid IPN with post %s' % post) + else: + _logger.warning('Paypal: received unrecognized IPN with post %s' % post) + + return '' + + @website.route([ + '/payment/paypal/dpn', + ], type='http', auth="public") + def paypal_dpn(self, **post): + """ TODO + """ + cr, uid, context = request.cr, request.uid, request.context + print 'Entering paypal_dpn with post', post + + # step 1: return an empty HTTP 200 response -> will be done at the end by returning '' + + # step 2: POST the complete, unaltered message back to Paypal (preceded by cmd=_notify-validate), with same encoding + paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr" + post_url = '%s?cmd=_notify-validate&%s' % (paypal_url, urlencode(post)) + resp = requests.post(post_url) + print '\tReceived response', resp, resp.text + + # step 3: paypal send either VERIFIED or INVALID (single word) + if resp.text == 'VERIFIED': + _logger.info('Paypal: received verified IPN') + cr, uid, context = request.cr, request.uid, request.context + payment_transaction = request.registry['payment.transaction'] + res = payment_transaction.paypal_form_feedback(cr, uid, post, context=context) + print '\tValidation result', res + elif resp.text == 'INVALID': + _logger.warning('Paypal: received invalid IPN with post %s' % post) + else: + _logger.warning('Paypal: received unrecognized IPN with post %s' % post) + + return_url = post.pop('return_url', '/') + print 'return_url', return_url + return request.redirect(return_url) + + @website.route([ + '/payment/paypal/cancel', + ], type='http', auth="public") + def paypal_cancel(self, **post): + """ TODO + """ + cr, uid, context = request.cr, request.uid, request.context + print 'Entering paypal_cancel with post', post + + return_url = post.pop('return_url', '/') + print 'return_url', return_url + return request.redirect(return_url) diff --git a/addons/payment_acquirer_paypal/data/paypal.xml b/addons/payment_acquirer_paypal/data/paypal.xml new file mode 100644 index 00000000000..eac0b78bb72 --- /dev/null +++ b/addons/payment_acquirer_paypal/data/paypal.xml @@ -0,0 +1,15 @@ + + + + + + paypal + + test + https://www.sandbox.paypal.com/cgi-bin/webscr + dummy + dummy + + + + diff --git a/addons/payment_acquirer_paypal/doc/changelog.rst b/addons/payment_acquirer_paypal/doc/changelog.rst new file mode 100644 index 00000000000..d0c24af384d --- /dev/null +++ b/addons/payment_acquirer_paypal/doc/changelog.rst @@ -0,0 +1,9 @@ +.. _changelog: + +Changelog +========= + +`trunk (saas-3)` +---------------- + +- Module creation \ No newline at end of file diff --git a/addons/payment_acquirer_paypal/doc/index.rst b/addons/payment_acquirer_paypal/doc/index.rst new file mode 100644 index 00000000000..85028ed0d3e --- /dev/null +++ b/addons/payment_acquirer_paypal/doc/index.rst @@ -0,0 +1,14 @@ +Payment module documentation +============================ + +Payment documentation topics +'''''''''''''''''''''''''''' + + +Changelog +''''''''' + +.. toctree:: + :maxdepth: 1 + + changelog.rst diff --git a/addons/payment_acquirer_paypal/models/__init__.py b/addons/payment_acquirer_paypal/models/__init__.py new file mode 100644 index 00000000000..a1fe670f56f --- /dev/null +++ b/addons/payment_acquirer_paypal/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import paypal diff --git a/addons/payment_acquirer_paypal/models/paypal.py b/addons/payment_acquirer_paypal/models/paypal.py new file mode 100644 index 00000000000..a908ac34e2d --- /dev/null +++ b/addons/payment_acquirer_paypal/models/paypal.py @@ -0,0 +1,191 @@ +# -*- coding: utf-'8' "-*-" + +from openerp.addons.payment_acquirer.models.payment_acquirer import ValidationError +from openerp.addons.payment_acquirer_paypal.controllers.main import PaypalController +from openerp.osv import osv, fields +from openerp.tools.float_utils import float_compare + +import logging +import urlparse + +_logger = logging.getLogger(__name__) + + +class AcquirerPaypal(osv.Model): + _inherit = 'payment.acquirer' + + _columns = { + 'paypal_email_id': fields.char('Email ID', required_if_provider='paypal'), + 'paypal_username': fields.char('Username', required_if_provider='paypal'), + 'paypal_password': fields.char('Password'), + 'paypal_signature': fields.char('Signature'), + 'paypal_tx_url': fields.char('Transaction URL', required_if_provider='paypal'), + 'paypal_use_dpn': fields.boolean('Use DPN'), + 'paypal_use_ipn': fields.boolean('Use IPN'), + } + + _defaults = { + 'paypal_use_dpn': True, + 'paypal_use_ipn': True, + 'paypal_tx_url': 'https://www.sandbox.paypal.com/cgi-bin/webscr', + } + + 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 = {} + base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') + acquirer = self.browse(cr, uid, id, context=context) + partner = None + if partner_id: + partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context) + tx_values = { + 'cmd': '_xclick', + 'business': acquirer.paypal_email_id, + 'item_name': reference, + 'item_number': reference, + 'amount': amount, + 'currency_code': currency and currency.name or 'EUR', + 'address1': partner and ' '.join((partner.street or '', partner.street2 or '')).strip() or ' '.join((partner_values.get('street', ''), partner_values.get('street2', ''))).strip(), + 'city': partner and partner.city or partner_values.get('city', ''), + 'country': partner and partner.country_id and partner.country_id.name or partner_values.get('country_name', ''), + 'email': partner and partner.email or partner_values.get('email', ''), + 'zip': partner and partner.zip or partner_values.get('zip', ''), + 'first_name': partner and partner.name or partner_values.get('name', '').split()[-1:], + 'last_name': partner and partner.name or partner_values.get('name', '').split()[:-1], + 'return': '%s' % urlparse.urljoin(base_url, PaypalController._return_url), + 'notify_url': '%s' % urlparse.urljoin(base_url, PaypalController._notify_url), + 'cancel_return': '%s' % urlparse.urljoin(base_url, PaypalController._cancel_url), + } + if tx_custom_values and tx_custom_values.get('return_url'): + tx_values['custom'] = 'return_url=%s' % tx_custom_values.pop('return_url') + if tx_custom_values: + tx_values.update(tx_custom_values) + return tx_values + + def paypal_get_form_action_url(self, cr, uid, id, context=None): + acquirer = self.browse(cr, uid, id, context=context) + return acquirer.paypal_tx_url + + +class TxPaypal(osv.Model): + _inherit = 'payment.transaction' + + _columns = { + 'paypal_txn_id': fields.char('Transaction ID'), + 'paypal_txn_type': fields.char('Transaction type'), + } + + # -------------------------------------------------- + # FORM RELATED METHODS + # -------------------------------------------------- + + def paypal_form_generate_values(self, cr, uid, id, tx_custom_values=None, context=None): + tx = self.browse(cr, uid, id, context=context) + + tx_data = { + 'item_name': tx.name, + 'first_name': tx.partner_name and tx.partner_name.split()[-1:], + 'last_name': tx.partner_name and tx.partner_name.split()[:-1], + 'email': tx.partner_email, + 'zip': tx.partner_zip, + 'address1': tx.partner_address, + 'city': tx.partner_city, + 'country': tx.partner_country_id and tx.partner_country_id.name or '', + } + if tx_custom_values: + tx_data.update(tx_custom_values) + return self.pool['payment.acquirer'].paypal_form_generate_values( + cr, uid, tx.acquirer_id.id, + tx.reference, tx.amount, tx.currency_id, + tx_custom_values=tx_data, + context=context + ) + + def _paypal_get_tx_from_data(self, cr, uid, data, context=None): + reference, txn_id = data.get('item_number'), data.get('txn_id') + if not reference or not txn_id: + error_msg = 'Paypal: received data with missing reference (%s) or txn_id (%s)' % (reference, txn_id) + _logger.error(error_msg) + raise ValidationError(error_msg) + + # find tx -> @TDENOTE use txn_id ? + tx_ids = self.pool['payment.transaction'].search(cr, uid, [('reference', '=', reference)], context=context) + if not tx_ids or len(tx_ids) > 1: + error_msg = 'Paypal: received data for reference %s' % (reference) + if not tx_ids: + error_msg += '; no order found' + else: + error_msg += '; multiple order found' + _logger.error(error_msg) + raise ValidationError(error_msg) + tx = self.pool['payment.transaction'].browse(cr, uid, tx_ids[0], context=context) + + return tx + + def paypal_form_feedback(self, cr, uid, data, context=None): + invalid_parameters = [] + + # get tx + tx = self._paypal_get_tx_from_data(cr, uid, data, context=context) + + if data.get('notify_version')[0] != '2.6': + _logger.warning( + 'Received a notification from Paypal with version %s instead of 2.6. This could lead to issues when managing it.' % + data.get('notify_version') + ) + if data.get('test_ipn'): + _logger.warning( + 'Received a notification from Paypal using sandbox' + ), + # check what is buyed + if float_compare(float(data.get('mc_gross', '0.0')), tx.amount, 2) != 0: + invalid_parameters.append(('mc_gross', tx.amount)) + if data.get('mc_currency') != tx.currency_id.name: + invalid_parameters.append(('mc_currency', tx.currency_id.name)) + # if parameters.get('payment_fee') != tx.payment_fee: + # invalid_parameters.append(('payment_fee', tx.payment_fee)) + # if parameters.get('quantity') != tx.quantity: + # invalid_parameters.append(('mc_currency', tx.quantity)) + # if parameters.get('shipping') != tx.shipping: + # invalid_parameters.append(('shipping', tx.shipping)) + # check buyer + # if parameters.get('payer_id') != tx.payer_id: + # invalid_parameters.append(('mc_gross', tx.payer_id)) + # if parameters.get('payer_email') != tx.payer_email: + # invalid_parameters.append(('payer_email', tx.payer_email)) + # check seller + # if parameters.get('receiver_email') != tx.receiver_email: + # invalid_parameters.append(('receiver_email', tx.receiver_email)) + # if parameters.get('receiver_id') != tx.receiver_id: + # invalid_parameters.append(('receiver_id', tx.receiver_id)) + + if invalid_parameters: + _warn_message = 'The following transaction parameters are incorrect:\n' + for item in invalid_parameters: + _warn_message += '\t%s: received %s instead of %s\n' % (item, data.get(item[0]), item[1]) + _logger.warning(_warn_message) + return False + + status = data.get('payment_status', 'Pending') + if status in ['Completed', 'Processed']: + tx.write({ + 'state': 'done', + 'txn_id': data['txn_id'], + 'date_validate': data.get('payment_date', fields.datetime.now()), + 'paypal_txn_type': data.get('express_checkout') + }) + return True + elif status in ['Pending', 'Expired']: + tx.write({ + 'state': 'pending', + 'txn_id': data['txn_id'], + }) + return True + else: + error = 'Paypal: feedback error' + _logger.info(error) + tx.write({ + 'state': 'error', + 'state_message': error + }) + return False diff --git a/addons/payment_acquirer_paypal/static/description/icon.png b/addons/payment_acquirer_paypal/static/description/icon.png new file mode 100644 index 00000000000..35528a10508 Binary files /dev/null and b/addons/payment_acquirer_paypal/static/description/icon.png differ diff --git a/addons/payment_acquirer_paypal/static/src/img/paypal_logo.png b/addons/payment_acquirer_paypal/static/src/img/paypal_logo.png new file mode 100644 index 00000000000..4803ff5d1ef Binary files /dev/null and b/addons/payment_acquirer_paypal/static/src/img/paypal_logo.png differ diff --git a/addons/payment_acquirer_paypal/tests/__init__.py b/addons/payment_acquirer_paypal/tests/__init__.py new file mode 100644 index 00000000000..6a46df50be2 --- /dev/null +++ b/addons/payment_acquirer_paypal/tests/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from . import test_paypal + +checks = [ + test_paypal, +] diff --git a/addons/payment_acquirer_paypal/tests/test_paypal.py b/addons/payment_acquirer_paypal/tests/test_paypal.py new file mode 100644 index 00000000000..266c97d6b3b --- /dev/null +++ b/addons/payment_acquirer_paypal/tests/test_paypal.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Business Applications +# Copyright (c) 2012-TODAY OpenERP S.A. +# +# 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 . +# +############################################################################## + +from openerp.addons.payment_acquirer.tests.common import PaymentAcquirerCommon +from openerp.osv.orm import except_orm + +from lxml import objectify +# import requests +# import urlparse + + +class BasicPayment(PaymentAcquirerCommon): + + def test_10_paypal_basic(self): + pass + + def test_11_paypal_form(self): + cr, uid = self.cr, self.uid + context = {} + base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url') + # ogone_url = self.payment_acquirer._get_ogone_urls(cr, uid, [ogone_id], None, None)[ogone_id]['ogone_standard_order_url'] + + model, paypal_view_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'payment_acquirer_paypal', 'paypal_acquirer_button') + + # forgot some mandatory fields: should crash + with self.assertRaises(except_orm): + paypal_id = self.payment_acquirer.create( + cr, uid, { + 'name': 'paypal', + 'env': 'test', + 'view_template_id': paypal_view_id, + 'paypal_email_id': 'tde+paypal-facilitator@openerp.com', + }, context=context + ) + # tde+buyer@openerp.com + + # create a new paypal account + paypal_id = self.payment_acquirer.create( + cr, uid, { + 'name': 'paypal', + 'env': 'test', + 'view_template_id': paypal_view_id, + 'paypal_email_id': 'dummy', + 'paypal_username': 'dummy', + }, context=context + ) + # verify acquirer data + paypal = self.payment_acquirer.browse(cr, uid, paypal_id, context) + self.assertEqual(paypal.env, 'test', 'test without test env') + + # render the button + res = self.payment_acquirer.render( + cr, uid, paypal_id, + 'test_ref0', 0.01, self.currency_euro, + partner_id=None, + partner_values=self.buyer_values, + context=context) + # print res + + # # check some basic paypal methods + # res = self.payment_transaction.validate_paypal_notification( + # cr, uid, + # 'http://localhost/payment?mc_gross=19.95&protection_eligibility=Eligible&address_status=confirmed&payer_id=LPLWNMTBWMFAY&tax=0.00&address_street=1+Main+St&payment_date=20%3A12%3A59+Jan+13%2C+2009+PST&payment_status=Completed&charset=windows-1252&address_zip=95131&first_name=Test&mc_fee=0.88&address_country_code=US&address_name=Test+User¬ify_version=2.6&custom=&payer_status=verified&address_country=United+States&address_city=San+Jose&quantity=1&verify_sign=AtkOfCXbDm2hu0ZELryHFjY-Vb7PAUvS6nMXgysbElEn9v-1XcmSoGtf&payer_email=gpmac_1231902590_per%40paypal.com&txn_id=61E67681CH3238416&payment_type=instant&last_name=User&address_state=CA&receiver_email=gpmac_1231902686_biz%40paypal.com&payment_fee=0.88&receiver_id=S8XGHLYDW9T3S&txn_type=express_checkout&item_name=&mc_currency=USD&item_number=&residence_country=US&test_ipn=1&handling_amount=0.00&transaction_subject=&payment_gross=19.95&shipping=0.00') + # self.assertEqual(res, False, 'payment: paypal validation on a txn_id that does not exists should return False') + + # txn_id = self.payment_transaction.create( + # cr, uid, { + # 'amount': 0.01, + # 'acquirer_id': paypal_id, + # 'currency_id': currency_id, + # 'reference': 'test_reference', + # 'paypal_txn_id': '61E67681CH3238416', + # }, context=context + # ) + # res = self.payment_transaction.validate_paypal_notification( + # cr, uid, + # 'http://localhost/payment?mc_gross=19.95&protection_eligibility=Eligible&address_status=confirmed&payer_id=LPLWNMTBWMFAY&tax=0.00&address_street=1+Main+St&payment_date=20%3A12%3A59+Jan+13%2C+2009+PST&payment_status=Completed&charset=windows-1252&address_zip=95131&first_name=Test&mc_fee=0.88&address_country_code=US&address_name=Test+User¬ify_version=2.6&custom=&payer_status=verified&address_country=United+States&address_city=San+Jose&quantity=1&verify_sign=AtkOfCXbDm2hu0ZELryHFjY-Vb7PAUvS6nMXgysbElEn9v-1XcmSoGtf&payer_email=gpmac_1231902590_per%40paypal.com&txn_id=61E67681CH3238416&payment_type=instant&last_name=User&address_state=CA&receiver_email=gpmac_1231902686_biz%40paypal.com&payment_fee=0.88&receiver_id=S8XGHLYDW9T3S&txn_type=express_checkout&item_name=&mc_currency=USD&item_number=&residence_country=US&test_ipn=1&handling_amount=0.00&transaction_subject=&payment_gross=19.95&shipping=0.00') + # print res + + # # user pays using Paypal + # resp = self.payment_transaction.create_paypal_command( + # cr, uid, cmd='_xclick', parameters={ + # 'business': 'tdelavallee-facilitator@gmail.com', + # 'amount': 50, + # 'item_name': 'test_item', + # 'quantity': 1, + # 'currency_code': 'USD', + # 'return': 'http://www.example.com', + # }) + # print resp + # print resp.url + # print resp.text + + # self.payment_transaction.validate(cr, uid, [tx_id], context=context) + +# { +# 'protection_eligibility': u'Ineligible', +# 'last_name': u'Poilu', +# 'txn_id': u'08D73520KX778924N', +# 'receiver_email': u'tde+paypal-facilitator@openerp.com', +# 'payment_status': u'Pending', +# 'payment_gross': u'', +# 'tax': u'0.00', +# 'residence_country': u'FR', +# 'address_state': u'Alsace', +# 'payer_status': u'verified', +# 'txn_type': u'web_accept', +# 'address_street': u'Av. de la Pelouse, 87648672 Mayet', +# 'handling_amount': u'0.00', +# 'payment_date': u'03:21:19 Nov 18, 2013 PST', +# 'first_name': u'Norbert', +# 'item_name': u'test_ref_0', +# 'address_country': u'France', +# 'charset': u'windows-1252', +# 'custom': u'', +# 'notify_version': u'3.7', +# 'address_name': u'Norbert Poilu', +# 'pending_reason': u'multi_currency', +# 'item_number': u'test_ref_0', +# 'receiver_id': u'DEG7Z7MYGT6QA', +# 'transaction_subject': u'', +# 'business': u'tde+paypal-facilitator@openerp.com', +# 'test_ipn': u'1', +# 'payer_id': u'VTDKRZQSAHYPS', +# 'verify_sign': u'An5ns1Kso7MWUdW4ErQKJJJ4qi4-AVoiUf-3478q3vrSmqh08IouiYpM', +# 'address_zip': u'75002', +# 'address_country_code': u'FR', +# 'address_city': u'Paris', +# 'address_status': u'unconfirmed', +# 'mc_currency': u'EUR', +# 'shipping': u'0.00', +# 'payer_email': u'tde+buyer@openerp.com', +# 'payment_type': u'instant', +# 'mc_gross': u'1.95', +# 'ipn_track_id': u'866df2ccd444b', +# 'quantity': u'1' +# } diff --git a/addons/payment_acquirer_paypal/views/payment_acquirer.xml b/addons/payment_acquirer_paypal/views/payment_acquirer.xml new file mode 100644 index 00000000000..ae89253545c --- /dev/null +++ b/addons/payment_acquirer_paypal/views/payment_acquirer.xml @@ -0,0 +1,40 @@ + + + + + + acquirer.form.paypal + payment.acquirer + + + + + + + + + + + + + + + + acquirer.transaction.form.paypal + payment.transaction + + + + + + + + + + + + + + + diff --git a/addons/payment_acquirer_paypal/views/paypal.xml b/addons/payment_acquirer_paypal/views/paypal.xml new file mode 100644 index 00000000000..9515e0a12a2 --- /dev/null +++ b/addons/payment_acquirer_paypal/views/paypal.xml @@ -0,0 +1,40 @@ + + + + + + + + diff --git a/addons/payment_acquirer_transfer/__init__.py b/addons/payment_acquirer_transfer/__init__.py new file mode 100644 index 00000000000..dde6f25c728 --- /dev/null +++ b/addons/payment_acquirer_transfer/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2013-Today OpenERP SA (). +# +# 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 . +# +############################################################################## + +import models +import controllers diff --git a/addons/payment_acquirer_transfer/__openerp__.py b/addons/payment_acquirer_transfer/__openerp__.py new file mode 100644 index 00000000000..45293e4f84a --- /dev/null +++ b/addons/payment_acquirer_transfer/__openerp__.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +{ + 'name': 'Transfer Payment Acquirer', + 'category': 'Hidden', + 'summary': 'Payment Acquirer: Transfer Implementation', + 'version': '1.0', + 'description': """Transfer Payment Acquirer""", + 'author': 'OpenERP SA', + 'depends': ['payment_acquirer'], + 'data': [ + 'views/transfer.xml', + 'data/transfer.xml', + ], + 'installable': True, +} diff --git a/addons/payment_acquirer_transfer/controllers/__init__.py b/addons/payment_acquirer_transfer/controllers/__init__.py new file mode 100644 index 00000000000..bbd183e955b --- /dev/null +++ b/addons/payment_acquirer_transfer/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import main diff --git a/addons/payment_acquirer_transfer/controllers/main.py b/addons/payment_acquirer_transfer/controllers/main.py new file mode 100644 index 00000000000..6d0a7c1fa6f --- /dev/null +++ b/addons/payment_acquirer_transfer/controllers/main.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +import logging +import pprint + +from openerp.addons.web import http +from openerp.addons.web.http import request +from openerp.addons.website.models import website + +_logger = logging.getLogger(__name__) + + +class OgoneController(http.Controller): + _accept_url = '/payment/transfer/feedback' + + @website.route([ + '/payment/transfer/feedback', + ], type='http', auth='admin') + def transfer_form_feedback(self, **post): + cr, uid, context = request.cr, request.uid, request.context + _logger.info('Beginning form_feedback with post data %s', pprint.pformat(post)) # debug + request.registry['payment.transaction'].form_feedback(cr, uid, post, 'transfer', context) + return request.redirect(post.pop('return_url', '/')) diff --git a/addons/payment_acquirer_transfer/data/transfer.xml b/addons/payment_acquirer_transfer/data/transfer.xml new file mode 100644 index 00000000000..ce6e56be57d --- /dev/null +++ b/addons/payment_acquirer_transfer/data/transfer.xml @@ -0,0 +1,16 @@ + + + + + + transfer + + test + + Please use the account 001-002-003 to make the payment.

]]> +
+
+ +
+
diff --git a/addons/payment_acquirer_transfer/doc/changelog.rst b/addons/payment_acquirer_transfer/doc/changelog.rst new file mode 100644 index 00000000000..d0c24af384d --- /dev/null +++ b/addons/payment_acquirer_transfer/doc/changelog.rst @@ -0,0 +1,9 @@ +.. _changelog: + +Changelog +========= + +`trunk (saas-3)` +---------------- + +- Module creation \ No newline at end of file diff --git a/addons/payment_acquirer_transfer/doc/index.rst b/addons/payment_acquirer_transfer/doc/index.rst new file mode 100644 index 00000000000..85028ed0d3e --- /dev/null +++ b/addons/payment_acquirer_transfer/doc/index.rst @@ -0,0 +1,14 @@ +Payment module documentation +============================ + +Payment documentation topics +'''''''''''''''''''''''''''' + + +Changelog +''''''''' + +.. toctree:: + :maxdepth: 1 + + changelog.rst diff --git a/addons/payment_acquirer_transfer/models/__init__.py b/addons/payment_acquirer_transfer/models/__init__.py new file mode 100644 index 00000000000..da51c9c1854 --- /dev/null +++ b/addons/payment_acquirer_transfer/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import payment_acquirer diff --git a/addons/payment_acquirer_transfer/models/payment_acquirer.py b/addons/payment_acquirer_transfer/models/payment_acquirer.py new file mode 100644 index 00000000000..2f72214e4e6 --- /dev/null +++ b/addons/payment_acquirer_transfer/models/payment_acquirer.py @@ -0,0 +1,53 @@ +# -*- coding: utf-'8' "-*-" + +from openerp.addons.payment_acquirer.models.payment_acquirer import ValidationError +from openerp.osv import osv +from openerp.tools.float_utils import float_compare + +import logging +import pprint + +_logger = logging.getLogger(__name__) + + +class TransferPaymentAcquirer(osv.Model): + _inherit = 'payment.acquirer' + + def transfer_get_form_action_url(self, cr, uid, id, context=None): + return '/payment/transfer/feedback' + + +class TransferPaymentTransaction(osv.Model): + _inherit = 'payment.transaction' + + def _transfer_form_get_tx_from_data(self, cr, uid, data, context=None): + reference, amount, currency_name = data.get('reference'), data.get('amount'), data.get('currency_name') + tx_ids = self.search( + cr, uid, [ + ('reference', '=', reference), + ], context=context) + + if not tx_ids or len(tx_ids) > 1: + error_msg = 'received data for reference %s' % (pprint.pformat(reference)) + if not tx_ids: + error_msg += '; no order found' + else: + error_msg += '; multiple order found' + _logger.error(error_msg) + raise ValidationError(error_msg) + + return self.browse(cr, uid, tx_ids[0], context=context) + + def _transfer_form_get_invalid_parameters(self, cr, uid, tx, data, context=None): + invalid_parameters = [] + + if float_compare(float(data.get('amount', '0.0')), tx.amount, 2) != 0: + invalid_parameters.append(('amount', data.get('amount'), '%.2f' % tx.amount)) + if data.get('currency') != tx.currency_id.name: + invalid_parameters.append(('currency', data.get('currency'), tx.currency_id.name)) + + return invalid_parameters + + def _transfer_form_validate(self, cr, uid, tx, data, context=None): + _logger.info('Validated transfer payment for tx %s: set as pending' % (tx.reference)) + return tx.write({'state': 'pending'}) diff --git a/addons/payment_acquirer_transfer/static/description/icon.png b/addons/payment_acquirer_transfer/static/description/icon.png new file mode 100644 index 00000000000..183937ed9ce Binary files /dev/null and b/addons/payment_acquirer_transfer/static/description/icon.png differ diff --git a/addons/payment_acquirer_transfer/views/transfer.xml b/addons/payment_acquirer_transfer/views/transfer.xml new file mode 100644 index 00000000000..af5c6fcef0f --- /dev/null +++ b/addons/payment_acquirer_transfer/views/transfer.xml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/addons/product/product.py b/addons/product/product.py index 3220d695239..a3fdcae11ac 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -642,6 +642,7 @@ class product_product(osv.osv): _table = "product_product" _inherits = {'product.template': 'product_tmpl_id'} _inherit = ['mail.thread'] + _inherit = ['mail.thread'] _order = 'default_code,name_template' _columns = { 'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'), @@ -839,9 +840,7 @@ class product_product(osv.osv): context=context) def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): - if context is None: - context = {} - if context and context.get('search_default_categ_id', False): + if context and context.get('search_default_categ_id'): args.append((('categ_id', 'child_of', context['search_default_categ_id']))) return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count) diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 351b55fdcfc..7003082a739 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -306,8 +306,6 @@ class project_issue(osv.Model): } def set_priority(self, cr, uid, ids, priority, *args): - """Set lead priority - """ return self.write(cr, uid, ids, {'priority' : priority}) def set_high_priority(self, cr, uid, ids, *args): diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 03f83f412ca..d38b4b948b6 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -48,42 +48,14 @@ class Website(openerp.addons.web.controllers.main.Home): @website.route('/pagenew/', type='http', auth="user") def pagenew(self, path, noredirect=NOPE): - module = 'website' - # completely arbitrary max_length - idname = slugify(path, max_length=50) - - request.cr.execute('SAVEPOINT pagenew') - imd = request.registry['ir.model.data'] - view = request.registry['ir.ui.view'] - view_model, view_id = imd.get_object_reference( - request.cr, request.uid, 'website', 'default_page') - newview_id = view.copy( - request.cr, request.uid, view_id, context=request.context) - newview = view.browse( - request.cr, request.uid, newview_id, context=request.context) - newview.write({ - 'arch': newview.arch.replace("website.default_page", - "%s.%s" % (module, idname)), - 'name': path, - 'page': True, - }) - # Fuck it, we're doing it live + web = request.registry['website'] try: - imd.create(request.cr, request.uid, { - 'name': idname, - 'module': module, - 'model': 'ir.ui.view', - 'res_id': newview_id, - 'noupdate': True - }, context=request.context) + path = web.new_page(request.cr, request.uid, path, request.context) except psycopg2.IntegrityError: logger.exception('Unable to create ir_model_data for page %s', path) request.cr.execute('ROLLBACK TO SAVEPOINT pagenew') return werkzeug.exceptions.InternalServerError() - else: - request.cr.execute('RELEASE SAVEPOINT pagenew') - - url = "/page/%s" % idname + url = "/page/" + path if noredirect is not NOPE: return werkzeug.wrappers.Response(url, mimetype='text/plain') return werkzeug.utils.redirect(url) @@ -112,7 +84,7 @@ class Website(openerp.addons.web.controllers.main.Home): @website.route(['/website/snippets'], type='json', auth="public") def snippets(self): - return request.website.render('website.snippets') + return request.website._render('website.snippets') @website.route('/page/', type='http', auth="public", multilang=True) def page(self, page, **opt): diff --git a/addons/website/models/ir_qweb.py b/addons/website/models/ir_qweb.py index 6e33742803d..6f72c2e4ce7 100644 --- a/addons/website/models/ir_qweb.py +++ b/addons/website/models/ir_qweb.py @@ -10,7 +10,6 @@ import cStringIO import datetime import itertools import logging -import re import urllib2 import urlparse @@ -216,18 +215,19 @@ class Image(orm.AbstractModel): source_element, t_att, g_att, qweb_context, context=context) def record_to_html(self, cr, uid, field_name, record, column, options=None, context=None): - cls = '' - if 'class' in options: - cls = ' class="%s"' % werkzeug.utils.escape(options['class']) + if options is None: options = {} + classes = ['img', 'img-responsive'] + options.get('class', '').split() - return '' % ( - cls, record._model._name, field_name, record.id) + return '' % ( + ' '.join(itertools.imap(werkzeug.utils.escape, classes)), + record._model._name, + field_name, record.id) def from_html(self, cr, uid, model, column, element, context=None): url = element.find('img').get('src') url_object = urlparse.urlsplit(url) - query = urlparse.parse_qs(url_object.query) + query = dict(urlparse.parse_qsl(url_object.query)) if url_object.path == '/website/image' and query['model'] == 'ir.attachment': attachment = self.pool['ir.attachment'].browse( cr, uid, int(query['id']), context=context) diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 478b6a97ec9..3bd49c32aed 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -3,6 +3,7 @@ import fnmatch import functools import inspect import logging +import psycopg2 import math import itertools import traceback @@ -21,6 +22,7 @@ from openerp.tools.safe_eval import safe_eval from openerp.addons.web import http from openerp.addons.web.http import request, LazyResponse +from ..utils import slugify logger = logging.getLogger(__name__) @@ -117,6 +119,34 @@ class website(osv.osv): } public_user = None + def new_page(self, cr, uid, name, template='website.default_page', ispage=True, context=None): + context=context or {} + # completely arbitrary max_length + idname = slugify(name, max_length=50) + + cr.execute('SAVEPOINT pagenew') + imd = self.pool.get('ir.model.data') + view = self.pool.get('ir.ui.view') + + module, tmp_page = template.split('.') + view_model, view_id = imd.get_object_reference(cr, uid, module, tmp_page) + + newview_id = view.copy(cr, uid, view_id, context=context) + newview = view.browse(cr, uid, newview_id, context=context) + newview.write({ + 'arch': newview.arch.replace(template, "%s.%s" % (module, idname)), + 'name': name, + 'page': ispage, + }) + imd.create(cr, uid, { + 'name': idname, + 'module': module, + 'model': 'ir.ui.view', + 'res_id': newview_id, + 'noupdate': True + }, context=context) + cr.execute('RELEASE SAVEPOINT pagenew') + return "%s.%s" % (module, idname) def get_public_user(self, cr, uid, context=None): if not self.public_user: @@ -473,7 +503,7 @@ class website(osv.osv): 'range': range, 'template': template, } - return request.website.render("website.kanban_contain", values) + return request.website._render("website.kanban_contain", values) def kanban_col(self, cr, uid, ids, model, domain, page, template, step, orderby, context=None): html = "" @@ -508,6 +538,7 @@ class website_menu(osv.osv): _defaults = { 'url': '', 'sequence': 0, + 'new_window': False, } _parent_store = True _parent_order = 'sequence, name' @@ -515,7 +546,7 @@ class website_menu(osv.osv): def get_menu(self, cr, uid, website_id, context=None): root_domain = [('parent_id', '=', False)] # ('website_id', '=', website_id), - menu_ids = self.search(cr, uid, root_domain, context=context) + menu_ids = self.search(cr, uid, root_domain, order='id', context=context) menu = self.browse(cr, uid, menu_ids, context=context) return menu[0] diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index 68e40e9118b..f10cb6f52e0 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -1,3 +1,4 @@ +@charset "utf-8"; /* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY * * css for editor buttons, openerp widget included in the website and other @@ -434,7 +435,6 @@ ul.nav-stacked > li > a { .oe_dark { background: #eff8f8; background: rgba(100, 200, 200, 0.14); - background-image: none !important; -webkit-box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset; -moz-box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset; box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset; @@ -442,20 +442,17 @@ ul.nav-stacked > li > a { .oe_black { background-color: rgba(0, 0, 0, 0.9); - background-image: none !important; } .oe_green { background-color: rgba(0, 128, 0, 0.8); - background-image: none !important; } .oe_red { background-color: rgba(255, 0, 0, 0.8); - background-image: none !important; } -.oe_custom_bg { +.oe_img_bg { height: 100%; background-size: 100%; } diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass index ec992256d6e..932f46a1912 100644 --- a/addons/website/static/src/css/website.sass +++ b/addons/website/static/src/css/website.sass @@ -328,17 +328,13 @@ ul.nav-stacked > li > a .oe_dark background: #eff8f8 background: rgba(100, 200, 200, 0.14) - background-image: none !important +box-shadow(0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset) .oe_black background-color: rgba(0, 0, 0, 0.9) - background-image: none !important .oe_green background-color: rgba(0, 128, 0, 0.8) - background-image: none !important .oe_red background-color: rgba(255, 0, 0, 0.8) - background-image: none !important -.oe_custom_bg +.oe_img_bg height: 100% - background-size: 100% + background-size: 100% \ No newline at end of file diff --git a/addons/website/static/src/img/bglink.png b/addons/website/static/src/img/bglink.png new file mode 100644 index 00000000000..e25f81c8414 Binary files /dev/null and b/addons/website/static/src/img/bglink.png differ diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index feb8e403c54..cee4409240d 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -30,8 +30,8 @@ function link_dialog(editor) { return new website.editor.RTELinkDialog(editor).appendTo(document.body); } - function image_dialog(editor) { - return new website.editor.RTEImageDialog(editor).appendTo(document.body); + function image_dialog(editor, image) { + return new website.editor.RTEImageDialog(editor, image).appendTo(document.body); } // only enable editors manually @@ -53,7 +53,7 @@ && !element.data('cke-realelement') && !element.isReadOnly() && (element.data('oe-model') !== 'ir.ui.view')) { - image_dialog(editor); + image_dialog(editor, element); return; } @@ -69,13 +69,9 @@ }, null, null, 500); var previousSelection; - editor.on('selectionChange', function (evt) { - var selected = evt.data.path.lastElement; - if (previousSelection) { - // cleanup previous selection - $(previousSelection).next().remove(); - previousSelection = null; - } + $(editor.element.$).on('mouseenter', 'img', function () { + if (previousSelection) { return; } + var selected = new CKEDITOR.dom.element(this); if (!selected.is('img') || selected.data('cke-realelement') || selected.isReadOnly() @@ -84,26 +80,46 @@ } // display button - var $el = $(previousSelection = selected.$); + var $el = $((previousSelection = selected).$); var $btn = $('') .insertAfter($el) .click(function (e) { e.preventDefault(); e.stopPropagation(); - image_dialog(editor); + image_dialog(editor, selected); }); var position = $el.position(); + // http://bugs.jquery.com/ticket/5445#comment:6 + // if the image has margin: x auto for centering, FF & IE + // will report top/left as the "correct" value and + // marginTop/marginLeft at "0px", webkit browsers will + // report top/left as 0-ish and set marginTop and + // marginLeft + var image_top = position.top + parseInt($el.css('marginTop'), 10); + var image_left = position.left + parseInt($el.css('marginLeft'), 10); $btn.css({ position: 'absolute', - top: $el.height() / 2 + position.top - $btn.outerHeight() / 2, - left: $el.width() / 2 + position.left - $btn.outerWidth() / 2, + top: $el.height() / 2 + image_top - $btn.outerHeight() / 2, + left: $el.width() / 2 + image_left - $btn.outerWidth() / 2, }); + $el.css('opacity', 0.75); + }).on('mouseleave', 'img', function (e) { + var $previous = $(previousSelection.$); + var $button = $previous.next('button'); + $button.css('visibility', 'hidden'); + var el = document.elementFromPoint(e.clientX, e.clientY); + $button.css('visibility', ''); + if (el === this) { return; } + $button.remove(); + $previous.css('opacity', ''); + previousSelection = null; }); editor.on('destroy', function (evt) { - if (previousSelection) { - $('.image-edit-button').remove(); - } + if (!previousSelection) { return; } + $('.image-edit-button') + .prev().css('opacity', '').end() + .remove(); }); //noinspection JSValidateTypes @@ -202,6 +218,154 @@ } }); + CKEDITOR.plugins.add('linkstyle', { + requires: 'panelbutton,floatpanel', + init: function (editor) { + var label = "Link Style"; + + editor.ui.add('LinkStyle', CKEDITOR.UI_PANELBUTTON, { + label: label, + title: label, + icon: '/website/static/src/img/bglink.png', + modes: { wysiwyg: true }, + editorFocus: true, + panel: { + css: '/website/static/lib/bootstrap/css/bootstrap.css', + attributes: { 'role': 'listbox', 'aria-label': label }, + }, + + types: { + 'btn-default': _t("Basic"), + 'btn-primary': _t("Primary"), + 'btn-success': _t("Success"), + 'btn-info': _t("Info"), + 'btn-warning': _t("Warning"), + 'btn-danger': _t("Danger"), + }, + sizes: { + 'btn-xs': _t("Extra Small"), + 'btn-sm': _t("Small"), + '': _t("Default"), + 'btn-lg': _t("Large") + }, + + onRender: function () { + var self = this; + editor.on('selectionChange', function (e) { + var path = e.data.path, el; + + if (!(e = path.contains('a')) || e.isReadOnly()) { + self.disable(); + return; + } + + self.enable(); + }); + // no hook where button is available, so wait + // "some time" after render. + setTimeout(function () { + self.disable(); + }, 0) + }, + enable: function () { + this.setState(CKEDITOR.TRISTATE_OFF); + }, + disable: function () { + this.setState(CKEDITOR.TRISTATE_DISABLED); + }, + + onOpen: function () { + var link = get_selected_link(editor); + var id = this._.id; + var block = this._.panel._.panel._.blocks[id]; + var $root = $(block.element.$); + $root.find('button').removeClass('active').removeProp('disabled'); + + // enable buttons matching link state + for (var type in this.types) { + if (!this.types.hasOwnProperty(type)) { continue; } + if (!link.hasClass(type)) { continue; } + + $root.find('button[data-type=types].' + type) + .addClass('active'); + } + var found; + for (var size in this.sizes) { + if (!this.sizes.hasOwnProperty(size)) { continue; } + if (!size || !link.hasClass(size)) { continue; } + found = true; + $root.find('button[data-type=sizes].' + size) + .addClass('active'); + } + if (!found && link.hasClass('btn')) { + $root.find('button[data-type="sizes"][data-set-class=""]') + .addClass('active'); + } + }, + + onBlock: function (panel, block) { + var self = this; + block.autoSize = true; + + var html = ['
']; + html.push('
'); + _(this.types).each(function (label, key) { + html.push(_.str.sprintf( + '', + key, key, label)); + }); + html.push('
'); + html.push('
'); + _(this.sizes).each(function (label, key) { + html.push(_.str.sprintf( + '', + key, key, label)); + }); + html.push('
'); + html.push(''); + html.push('
'); + + block.element.setHtml(html.join(' ')); + var $panel = $(block.element.$); + $panel.on('click', 'button', function () { + self.clicked(this); + }); + }, + clicked: function (button) { + editor.focus(); + editor.fire('saveSnapshot'); + + var $button = $(button), + $link = $(get_selected_link(editor).$); + if (!$link.hasClass('btn')) { + $link.addClass('btn btn-default'); + } + switch($button.data('type')) { + case 'reset': + $link.removeClass('btn') + .removeClass(_.keys(this.types).join(' ')) + .removeClass(_.keys(this.sizes).join(' ')); + break; + case 'types': + $link.removeClass(_.keys(this.types).join(' ')) + .addClass($button.data('set-class')); + break; + case 'sizes': + $link.removeClass(_.keys(this.sizes).join(' ')) + .addClass($button.data('set-class')); + } + this._.panel.hide(); + + editor.fire('saveSnapshot'); + }, + + }); + } + }); + CKEDITOR.plugins.add('oeref', { requires: 'widget', @@ -224,157 +388,6 @@ } }); - CKEDITOR.plugins.add('bootstrapcombo', { - requires: 'richcombo', - - init: function (editor) { - var config = editor.config; - - editor.ui.addRichCombo('BootstrapLinkCombo', { - // default title - label: "Links", - // hover - title: "Link styling", - toolbar: 'styles,10', - allowedContent: ['a'], - - panel: { - css: [ - '/website/static/lib/bootstrap/css/bootstrap.css', - CKEDITOR.skin.getPath( 'editor' ) - ].concat( config.contentsCss ), - multiSelect: true, - }, - - types: { - 'basic': 'btn-default', - 'primary': 'btn-primary', - 'success': 'btn-success', - 'info': 'btn-info', - 'warning': 'btn-warning', - 'danger': 'btn-danger', - }, - - sizes: { - 'large': 'btn-lg', - 'default': '', - 'small': 'btn-sm', - 'extra small': 'btn-xs', - }, - - init: function () { - this.add('', 'Reset'); - this.startGroup("Types"); - for(var type in this.types) { - if (!this.types.hasOwnProperty(type)) { continue; } - var cls = this.types[type]; - var el = _.str.sprintf( - '%s', - cls, type); - this.add(type, el); - } - this.startGroup("Sizes"); - for (var size in this.sizes) { - if (!this.sizes.hasOwnProperty(size)) { continue; } - cls = this.sizes[size]; - - el = _.str.sprintf( - '%s', - cls, size); - this.add(size, el); - } - this.commit(); - }, - onRender: function () { - var self = this; - editor.on('selectionChange', function (e) { - var path = e.data.path, el; - - if (!(el = path.contains('a'))) { - self.element = null; - self.disable(); - return; - } - - self.enable(); - // This is crap, but getting the currently selected - // element from within onOpen absolutely does not - // work, so store the "current" element in the - // widget instead - self.element = el; - }); - setTimeout(function () { - // Because I can't find any normal hook where the - // bloody button's bloody element is available - self.disable(); - }, 0); - }, - onOpen: function () { - this.showAll(); - this.unmarkAll(); - - for(var val in this.types) { - if (!this.types.hasOwnProperty(val)) { continue; } - var cls = this.types[val]; - if (!this.element.hasClass(cls)) { continue; } - - this.mark(val); - break; - } - - var found; - for(val in this.sizes) { - if (!this.sizes.hasOwnProperty(val)) { continue; } - cls = this.sizes[val]; - if (!cls || !this.element.hasClass(cls)) { continue; } - - found = true; - this.mark(val); - break; - } - if (!found && this.element.hasClass('btn')) { - this.mark('default'); - } - }, - onClick: function (value) { - editor.focus(); - editor.fire('saveShapshot'); - - // basic btn setup - var el = this.element; - if (!el.hasClass('btn')) { - el.addClass('btn'); - el.addClass('btn-default'); - } - - if (!value) { - this.setClass(this.types); - this.setClass(this.sizes); - el.removeClass('btn'); - } else if (value in this.types) { - this.setClass(this.types, value); - } else if (value in this.sizes) { - this.setClass(this.sizes, value); - } - - editor.fire('saveShapshot'); - }, - setClass: function (classMap, value) { - var element = this.element; - _(classMap).each(function (cls) { - if (!cls) { return; } - element.removeClass(cls); - }.bind(this)); - - var cls = classMap[value]; - if (cls) { - element.addClass(cls); - } - } - }); - }, - }); - var editor = new website.EditorBar(); var $body = $(document.body); editor.prependTo($body).then(function () { @@ -788,7 +801,7 @@ fillEmptyBlocks: false, filebrowserImageUploadUrl: "/website/attach", // Support for sharedSpaces in 4.x - extraPlugins: 'sharedspace,customdialogs,tablebutton,oeref,bootstrapcombo', + extraPlugins: 'sharedspace,customdialogs,tablebutton,oeref,linkstyle', // Place toolbar in controlled location sharedSpaces: { top: 'oe_rte_toolbar' }, toolbar: [{ @@ -800,7 +813,7 @@ "Superscript", "TextColor", "BGColor", "RemoveFormat" ]},{ name: 'span', items: [ - "Link", "Blockquote", "BulletedList", + "Link", "LinkStyle", "Blockquote", "BulletedList", "NumberedList", "Indent", "Outdent" ]},{ name: 'justify', items: [ @@ -810,7 +823,7 @@ "Image", "TableButton" ]},{ name: 'styles', items: [ - "Styles", "BootstrapLinkCombo" + "Styles" ]} ], // styles dropdown in toolbar @@ -1182,26 +1195,30 @@ }, }); website.editor.RTEImageDialog = website.editor.ImageDialog.extend({ - init: function () { - this._super.apply(this, arguments); + init: function (editor, image) { + this._super(editor); + + this.element = image; this.on('start', this, this.proxy('started')); this.on('save', this, this.proxy('saved')); }, started: function (holder) { - var selection = this.editor.getSelection(); - var el = selection && selection.getSelectedElement(); - this.element = null; - - if (el && el.is('img')) { - this.element = el; - _(this.image_styles).each(function (style) { - if (el.hasClass(style)) { - holder.style = style; - } - }); - holder.url = el.getAttribute('src'); + if (!this.element) { + var selection = this.editor.getSelection(); + this.element = selection && selection.getSelectedElement(); } + + var el = this.element; + if (!el || !el.is('img')) { + return; + } + _(this.image_styles).each(function (style) { + if (el.hasClass(style)) { + holder.style = style; + } + }); + holder.url = el.getAttribute('src'); }, saved: function (data) { var element, editor = this.editor; diff --git a/addons/website/static/src/js/website.menu.js b/addons/website/static/src/js/website.menu.js index 40551b2dd75..b3554b9e7c5 100644 --- a/addons/website/static/src/js/website.menu.js +++ b/addons/website/static/src/js/website.menu.js @@ -5,15 +5,12 @@ website.menu = {}; website.add_template_file('/website/static/src/xml/website.menu.xml'); - var globalEditor; - website.EditorBar.include({ events: _.extend({}, website.EditorBar.prototype.events, { 'click a[data-action="edit-structure"]': 'editStructure', }), editStructure: function () { var self = this; - globalEditor = self; var context = website.get_context(); openerp.jsonRpc('/web/dataset/call_kw', 'call', { model: 'website.menu', @@ -24,7 +21,6 @@ }, }).then(function (menu) { var result = new website.menu.EditMenuDialog(menu).appendTo(document.body); - self.trigger('tour:menu_editor_dialog_ready'); return result; }); }, @@ -171,7 +167,6 @@ $link_text.focus(); }); }); - globalEditor.trigger('tour:new_menu_entry_dialog_ready'); return result; }, save: function () { @@ -192,7 +187,6 @@ } }, destroy: function () { - globalEditor.trigger('tour:new_menu_entry_dialog_closed'); this._super.apply(this, arguments); }, }); diff --git a/addons/website/static/src/js/website.snippets.animation.js b/addons/website/static/src/js/website.snippets.animation.js index 7277f80ba95..34edfe9d259 100644 --- a/addons/website/static/src/js/website.snippets.animation.js +++ b/addons/website/static/src/js/website.snippets.animation.js @@ -82,7 +82,7 @@ var self = this; var speed = parseFloat(self.$target.attr("data-scroll-background-ratio") || 0); - if (speed == 1) { + if (speed === 1 || this.$target.css("background-image") === "none") { this.$target.css("background-attachment", "fixed").css("background-position", "0px 0px"); return; } else { @@ -101,7 +101,7 @@ } else { offset = - self.$target.offset().top * speed; } - self.$target.attr("data-scroll-background-offset", offset); + self.$target.attr("data-scroll-background-offset", offset > 0 ? 0 : offset); $(window).scroll(); }; img.src = this.$target.css("background-image").replace(/url\(['"]*|['"]*\)/g, ""); diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 7d7aade081f..a4f51c6ab39 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -77,6 +77,7 @@ hack_to_add_snippet_id(); }); + website.snippet.styles = {}; website.snippet.selector = []; website.snippet.BuildingBlock = openerp.Widget.extend({ template: 'website.snippets', @@ -138,22 +139,19 @@ }, fetch_snippet_templates: function () { var self = this; - this.style_templates = {}; openerp.jsonRpc("/website/snippets", 'call', {}) .then(function (html) { var $html = $(html); - var $styles = $html.find("#snippet_styles"); - $styles.find("> [data-snippet-id]").each(function () { + var $styles = $html.find("[data-snippet-style-id]"); + $styles.each(function () { var $style = $(this); - var snipped_id = $style.data('snippet-id'); - self.style_templates[snipped_id] = { - 'snipped-id' : snipped_id, + var style_id = $style.data('snippet-style-id'); + website.snippet.styles[style_id] = { + 'snippet-style-id' : style_id, 'selector': $style.data('selector'), - 'class': $style.data("class"), - 'label': $style.find(".oe_snippet_label").text(), - 'group': $style.find(".oe_snippet_group").text() + '$el': $style, }; }); $styles.addClass("hidden"); @@ -529,13 +527,212 @@ }); + website.snippet.styleRegistry = {}; + website.snippet.StyleEditor = openerp.Class.extend({ + // initialisation (don't overwrite) + init: function (parent, $target, snippet_id) { + this.parent = parent; + this.$target = $target; + var styles = this.$target.data("snippet-style-ids") || {}; + styles[snippet_id] = this; + this.$target.data("snippet-style-ids", styles); + this.$overlay = this.$target.data('overlay'); + this['snippet-style-id'] = snippet_id; + this.$el = website.snippet.styles[snippet_id].$el.find(">li").clone(); + + this.required = this.$el.data("required"); + + this.set_active(); + this.$el.find('li[data-class] a').on('mouseover mouseout click', _.bind(this._mouse, this)); + this.$target.on('snippet-style-reset', _.bind(this.set_active, this)); + + this.start(); + }, + _mouse: function (event) { + var self = this; + + if (event.type === 'mouseout') { + if (!this.over) return; + this.over = false; + } else if (event.type === 'click') { + this.over = false; + }else { + this.over = true; + } + + var $prev, $next; + if (event.type === 'mouseout') { + $prev = $(event.currentTarget).parent(); + $next = this.$el.find("li[data-class].active"); + } else { + $prev = this.$el.find("li[data-class].active"); + $next = $(event.currentTarget).parent(); + } + if (!$prev.length) { + $prev = false; + } + if ($prev && $prev[0] === $next[0]) { + $next = false; + if (this.required) { + return; + } + } + + var np = {'$next': $next, '$prev': $prev}; + + if (event.type === 'click') { + setTimeout(function () { + self.set_active(); + self.$target.trigger("snippet-style-change", [self, np]); + },0); + this.select(event, {'$next': $next, '$prev': $prev}); + } else { + setTimeout(function () { + self.$target.trigger("snippet-style-preview", [self, np]); + },0); + this.preview(event, np); + } + }, + // start is call just after the init + start: function () { + }, + /* select + * called when a user select an item + * variables: np = {$next, $prev} + * $next is false if they are no next item selected + * $prev is false if they are no previous item selected + */ + select: function (event, np) { + var self = this; + // add or remove html class + if (np.$prev) { + this.$target.removeClass(np.$prev.data('class' || "")); + } + if (np.$next) { + this.$target.addClass(np.$next.data('class') || ""); + } + }, + /* preview + * called when a user is on mouse over or mouse out of an item + * variables: np = {$next, $prev} + * $next is false if they are no next item selected + * $prev is false if they are no previous item selected + */ + preview: function (event, np) { + var self = this; + + // add or remove html class + if (np.$prev) { + this.$target.removeClass(np.$prev.data('class') || ""); + } + if (np.$next) { + this.$target.addClass(np.$next.data('class') || ""); + } + }, + /* set_active + * select and set item active or not (add highlight item and his parents) + * called before start + */ + set_active: function () { + var self = this; + this.$el.find('li').removeClass("active"); + var $active = this.$el.find('li[data-class]') + .filter(function () { + var $li = $(this); + return ($li.data('class') && self.$target.hasClass($li.data('class'))); + }) + .first() + .addClass("active"); + this.$el.find('li:has(li[data-class].active)').addClass("active"); + } + }); + + + website.snippet.styleRegistry['size'] = website.snippet.StyleEditor.extend({ + select: function(event, np) { + this._super(event, np); + this.parent.parent.cover_target(this.$overlay, this.$target); + }, + preview: function (event, np) { + this._super(event, np); + this.parent.parent.cover_target(this.$overlay, this.$target); + } + }); + + website.snippet.styleRegistry.background = website.snippet.StyleEditor.extend({ + _get_bg: function () { + return this.$target.css("background-image").replace(/url\(['"]*|['"]*\)|^none$/g, ""); + }, + _set_bg: function (src) { + this.$target.css("background-image", src && src !== "" ? 'url(' + src + ')' : ""); + }, + start: function () { + this._super(); + var src = this._get_bg(); + this.$el.find("li[data-class].active.oe_custom_bg").data("src", src); + }, + select: function(event, np) { + var self = this; + this._super(event, np); + if (np.$next) { + if (np.$next.hasClass("oe_custom_bg")) { + var editor = new website.editor.ImageDialog(); + editor.on('start', self, function (o) {o.url = np.$prev && np.$prev.data("src") || "";}); + editor.on('save', self, function (o) { + self._set_bg(o.url); + np.$next.data("src", o.url); + self.$target.trigger("snippet-style-change", [self, np]); + }); + editor.on('cancel', self, function () { + if (!np.$prev || np.$prev.data("src") === "") { + np.$next.removeClass('active'); + self.$target.removeClass(np.$next.data("class")); + self.$target.trigger("snippet-style-change", [self, np]); + } + }); + editor.appendTo($('body')); + } else { + this._set_bg(np.$next.data("src")); + } + } else { + this._set_bg(false); + } + }, + preview: function (event, np) { + this._super(event, np); + if (np.$next) { + this._set_bg(np.$next.data("src")); + } + }, + set_active: function () { + var self = this; + var bg = self.$target.css("background-image"); + this.$el.find('li').removeClass("active"); + var $active = this.$el.find('li[data-class]') + .filter(function () { + var $li = $(this); + return ($li.data('src') && bg.indexOf($li.data('src')) >= 0) || + (!$li.data('src') && self.$target.hasClass($li.data('class'))); + }) + .first(); + if (!$active.length) { + $active = this.$target.css("background-image") !== 'none' ? + this.$el.find('li[data-class].oe_custom_bg') : + this.$el.find('li[data-class=""]'); + } + $active.addClass("active"); + this.$el.find('li:has(li[data-class].active)').addClass("active"); + } + }); + + website.snippet.editorRegistry = {}; website.snippet.Editor = openerp.Class.extend({ - init: function (parent, dom, force_snippet_id) { + init: function (parent, dom) { this.parent = parent; this.$target = $(dom); this.$overlay = this.$target.data('overlay'); - this.snippet_id = force_snippet_id || this.$target.data("snippet-id"); + this.snippet_id = this.$target.data("snippet-id"); this._readXMLData(); this.load_style_options(); this.get_parent_block(); @@ -652,90 +849,21 @@ }, load_style_options: function () { - if (this.$target.data('snippetStyles')) { - return; - } - var self = this; var $styles = this.$overlay.find('.oe_options'); var $ul = $styles.find('ul:first'); - _.each(this.parent.style_templates, function (val) { + _.each(website.snippet.styles, function (val) { if (!self.parent.dom_filter(val.selector).is(self.$target)) { return; } - var $li = $("
  • ").data(val); - $li.append($('').text(val.label)); - if (self.$target.hasClass( val.class )) { - $li.addClass("active"); - } - - if (val.group.length) { - var $group = $ul.find("li.dropdown-submenu").filter(function () { - return $("a:first", this).text() === val.group; - }); - if (!$group.length) { - $group = $('