Browse Source
[ADD] Add base_phone module;it validates phone numbers using the *phonenumbers* Python library.
pull/38/head
[ADD] Add base_phone module;it validates phone numbers using the *phonenumbers* Python library.
pull/38/head
20 changed files with 1692 additions and 0 deletions
-
25base_phone/__init__.py
-
86base_phone/__openerp__.py
-
269base_phone/base_phone.py
-
18base_phone/base_phone_demo.xml
-
35base_phone/controller.py
-
273base_phone/i18n/base_phone.pot
-
273base_phone/i18n/fr.po
-
63base_phone/report_sxw_format.py
-
33base_phone/res_company_view.xml
-
50base_phone/res_partner_view.xml
-
40base_phone/res_users_view.xml
-
2base_phone/security/ir.model.access.csv
-
17base_phone/security/phone_security.xml
-
105base_phone/static/src/js/phone_widget.js
-
51base_phone/static/src/xml/phone.xml
-
23base_phone/wizard/__init__.py
-
129base_phone/wizard/number_not_found.py
-
55base_phone/wizard/number_not_found_view.xml
-
101base_phone/wizard/reformat_all_phonenumbers.py
-
44base_phone/wizard/reformat_all_phonenumbers_view.xml
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Base Phone module for OpenERP |
||||
|
# Copyright (C) 2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from . import base_phone |
||||
|
from . import wizard |
||||
|
from . import report_sxw_format |
||||
|
from . import controller |
@ -0,0 +1,86 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Base Phone module for OpenERP |
||||
|
# Copyright (C) 2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
|
||||
|
{ |
||||
|
'name': 'Base Phone', |
||||
|
'version': '0.1', |
||||
|
'category': 'Phone', |
||||
|
'license': 'AGPL-3', |
||||
|
'summary': 'Validate phone numbers', |
||||
|
'description': """ |
||||
|
Base Phone |
||||
|
========== |
||||
|
|
||||
|
This module validates phone numbers using the *phonenumbers* Python library, |
||||
|
which is a port of the library used in Android smartphones. For example, |
||||
|
if your user is linked to a French company and you update the form |
||||
|
view of a partner with a badly written French phone number |
||||
|
such as '01-55-42-12-42', Odoo will automatically update the phone number |
||||
|
to E.164 format '+33155421242' and display in the form view of the partner |
||||
|
the readable equivalent '+33 1 55 42 12 42'. |
||||
|
|
||||
|
This module also adds *tel:* links on phone numbers and *fax:* links on fax |
||||
|
numbers. If you have a softphone or a client software on your PC |
||||
|
that is associated with *tel:* links, the softphone should propose |
||||
|
you to dial the phone number when you click on such a link. |
||||
|
|
||||
|
This module also updates the format() function for reports |
||||
|
and adds 2 arguments : |
||||
|
|
||||
|
* *phone* : should be True for a phone number, False (default) otherwize. |
||||
|
* *phone_format* : it can have 3 possible values : |
||||
|
* *international* (default) : the report will display '+33 1 55 42 12 42' |
||||
|
* *national* : the report will display '01 55 42 12 42' |
||||
|
* *e164* : the report will display '+33155421242' |
||||
|
|
||||
|
For example, in the Sale Order report, to display the phone |
||||
|
number of the Salesman, you can write : o.user_id and o.user_id.phone |
||||
|
and format(o.user_id.phone, phone=True, phone_format='national') or '' |
||||
|
|
||||
|
This module is independant from the Asterisk connector. |
||||
|
|
||||
|
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> |
||||
|
for any help or question about this module. |
||||
|
""", |
||||
|
'author': 'Akretion', |
||||
|
'website': 'http://www.akretion.com/', |
||||
|
'depends': ['base', 'web'], |
||||
|
'external_dependencies': {'python': ['phonenumbers']}, |
||||
|
'data': [ |
||||
|
'security/phone_security.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
'res_partner_view.xml', |
||||
|
'res_company_view.xml', |
||||
|
'res_users_view.xml', |
||||
|
'wizard/reformat_all_phonenumbers_view.xml', |
||||
|
'wizard/number_not_found_view.xml', |
||||
|
], |
||||
|
'js': [ |
||||
|
'static/src/js/*.js', |
||||
|
'static/lib/js/*.js', |
||||
|
], |
||||
|
'qweb': ['static/src/xml/*.xml'], |
||||
|
'demo': ['base_phone_demo.xml'], |
||||
|
'images': [], |
||||
|
'installable': True, |
||||
|
'active': False, |
||||
|
} |
@ -0,0 +1,269 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Base Phone module for Odoo/OpenERP |
||||
|
# Copyright (C) 2010-2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from openerp.osv import orm, fields |
||||
|
from openerp.tools.translate import _ |
||||
|
import logging |
||||
|
# Lib for phone number reformating -> pip install phonenumbers |
||||
|
import phonenumbers |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class phone_common(orm.AbstractModel): |
||||
|
_name = 'phone.common' |
||||
|
|
||||
|
def generic_phonenumber_to_e164( |
||||
|
self, cr, uid, ids, field_from_to_seq, context=None): |
||||
|
result = {} |
||||
|
from_field_seq = [item[0] for item in field_from_to_seq] |
||||
|
for record in self.read(cr, uid, ids, from_field_seq, context=context): |
||||
|
result[record['id']] = {} |
||||
|
for fromfield, tofield in field_from_to_seq: |
||||
|
if not record.get(fromfield): |
||||
|
res = False |
||||
|
else: |
||||
|
try: |
||||
|
res = phonenumbers.format_number( |
||||
|
phonenumbers.parse(record.get(fromfield), None), |
||||
|
phonenumbers.PhoneNumberFormat.E164) |
||||
|
except Exception, e: |
||||
|
_logger.error( |
||||
|
"Cannot reformat the phone number '%s' to E.164 " |
||||
|
"format. Error message: %s" |
||||
|
% (record.get(fromfield), e)) |
||||
|
_logger.error( |
||||
|
"You should fix this number and run the wizard " |
||||
|
"'Reformat all phone numbers' from the menu " |
||||
|
"Settings > Configuration > Phones") |
||||
|
# If I raise an exception here, it won't be possible to |
||||
|
# install the module on a DB with bad phone numbers |
||||
|
res = False |
||||
|
result[record['id']][tofield] = res |
||||
|
return result |
||||
|
|
||||
|
def _generic_reformat_phonenumbers( |
||||
|
self, cr, uid, vals, |
||||
|
phonefields=[ |
||||
|
'phone', 'partner_phone', 'work_phone', 'fax', |
||||
|
'mobile', 'partner_mobile', 'mobile_phone', |
||||
|
], |
||||
|
context=None): |
||||
|
"""Reformat phone numbers in E.164 format i.e. +33141981242""" |
||||
|
if any([vals.get(field) for field in phonefields]): |
||||
|
user = self.pool['res.users'].browse(cr, uid, uid, context=context) |
||||
|
# country_id on res.company is a fields.function that looks at |
||||
|
# company_id.partner_id.addres(default).country_id |
||||
|
if user.company_id.country_id: |
||||
|
user_countrycode = user.company_id.country_id.code |
||||
|
else: |
||||
|
# We need to raise an exception here because, if we pass None |
||||
|
# as second arg of phonenumbers.parse(), it will raise an |
||||
|
# exception when you try to enter a phone number in |
||||
|
# national format... so it's better to raise the exception here |
||||
|
raise orm.except_orm( |
||||
|
_('Error:'), |
||||
|
_("You should set a country on the company '%s'") |
||||
|
% user.company_id.name) |
||||
|
for field in phonefields: |
||||
|
if vals.get(field): |
||||
|
init_value = vals.get(field) |
||||
|
try: |
||||
|
res_parse = phonenumbers.parse( |
||||
|
vals.get(field), user_countrycode) |
||||
|
except Exception, e: |
||||
|
raise orm.except_orm( |
||||
|
_('Error:'), |
||||
|
_("Cannot reformat the phone number '%s' to " |
||||
|
"international format. Error message: %s") |
||||
|
% (vals.get(field), e)) |
||||
|
vals[field] = phonenumbers.format_number( |
||||
|
res_parse, phonenumbers.PhoneNumberFormat.E164) |
||||
|
if init_value != vals[field]: |
||||
|
_logger.info( |
||||
|
"%s initial value: '%s' updated value: '%s'" |
||||
|
% (field, init_value, vals[field])) |
||||
|
return vals |
||||
|
|
||||
|
def get_name_from_phone_number( |
||||
|
self, cr, uid, presented_number, context=None): |
||||
|
'''Function to get name from phone number. Usefull for use from IPBX |
||||
|
to add CallerID name to incoming calls.''' |
||||
|
res = self.get_record_from_phone_number( |
||||
|
cr, uid, presented_number, context=context) |
||||
|
if res: |
||||
|
return res[2] |
||||
|
else: |
||||
|
return False |
||||
|
|
||||
|
def get_record_from_phone_number( |
||||
|
self, cr, uid, presented_number, context=None): |
||||
|
'''If it finds something, it returns (object name, ID, record name) |
||||
|
For example : ('res.partner', 42, u'Alexis de Lattre (Akretion)') |
||||
|
''' |
||||
|
if context is None: |
||||
|
context = {} |
||||
|
ctx_phone = context.copy() |
||||
|
ctx_phone['callerid'] = True |
||||
|
_logger.debug( |
||||
|
u"Call get_name_from_phone_number with number = %s" |
||||
|
% presented_number) |
||||
|
if not isinstance(presented_number, (str, unicode)): |
||||
|
_logger.warning( |
||||
|
u"Number '%s' should be a 'str' or 'unicode' but it is a '%s'" |
||||
|
% (presented_number, type(presented_number))) |
||||
|
return False |
||||
|
if not presented_number.isdigit(): |
||||
|
_logger.warning( |
||||
|
u"Number '%s' should only contain digits." % presented_number) |
||||
|
|
||||
|
user = self.pool['res.users'].browse(cr, uid, uid, context=context) |
||||
|
nr_digits_to_match_from_end = \ |
||||
|
user.company_id.number_of_digits_to_match_from_end |
||||
|
if len(presented_number) >= nr_digits_to_match_from_end: |
||||
|
end_number_to_match = presented_number[ |
||||
|
-nr_digits_to_match_from_end:len(presented_number)] |
||||
|
else: |
||||
|
end_number_to_match = presented_number |
||||
|
|
||||
|
phonefieldsdict = self._get_phone_fields(cr, uid, context=context) |
||||
|
phonefieldslist = [] |
||||
|
for objname, prop in phonefieldsdict.iteritems(): |
||||
|
if prop.get('get_name_sequence'): |
||||
|
phonefieldslist.append({objname: prop}) |
||||
|
phonefieldslist_sorted = sorted( |
||||
|
phonefieldslist, |
||||
|
key=lambda element: element.values()[0]['get_name_sequence']) |
||||
|
|
||||
|
for phonedict in phonefieldslist_sorted: |
||||
|
objname = phonedict.keys()[0] |
||||
|
prop = phonedict.values()[0] |
||||
|
phonefields = prop['phonefields'] |
||||
|
obj = self.pool[objname] |
||||
|
pg_search_number = str('%' + end_number_to_match) |
||||
|
_logger.debug( |
||||
|
"Will search phone and mobile numbers in %s ending with '%s'" |
||||
|
% (objname, end_number_to_match)) |
||||
|
domain = [] |
||||
|
for phonefield in phonefields: |
||||
|
domain.append((phonefield, 'like', pg_search_number)) |
||||
|
if len(phonefields) > 1: |
||||
|
domain = ['|'] * (len(phonefields) - 1) + domain |
||||
|
res_ids = obj.search(cr, uid, domain, context=context) |
||||
|
if len(res_ids) > 1: |
||||
|
_logger.warning( |
||||
|
u"There are several %s (IDS = %s) with a phone number " |
||||
|
"ending with '%s'. Taking the first one." |
||||
|
% (objname, res_ids, end_number_to_match)) |
||||
|
if res_ids: |
||||
|
name = obj.name_get( |
||||
|
cr, uid, res_ids[0], context=ctx_phone)[0][1] |
||||
|
res = (objname, res_ids[0], name) |
||||
|
_logger.debug( |
||||
|
u"Answer get_record_from_phone_number: (%s, %d, %s)" |
||||
|
% (res[0], res[1], res[2])) |
||||
|
return res |
||||
|
else: |
||||
|
_logger.debug( |
||||
|
u"No match on %s for end of phone number '%s'" |
||||
|
% (objname, end_number_to_match)) |
||||
|
return False |
||||
|
|
||||
|
def _get_phone_fields(self, cr, uid, context=None): |
||||
|
'''Returns a dict with key = object name |
||||
|
and value = list of phone fields''' |
||||
|
res = { |
||||
|
'res.partner': { |
||||
|
'phonefields': ['phone', 'mobile'], |
||||
|
'faxfields': ['fax'], |
||||
|
'get_name_sequence': 10, |
||||
|
}, |
||||
|
} |
||||
|
return res |
||||
|
|
||||
|
def click2dial(self, cr, uid, erp_number, context=None): |
||||
|
'''This function is designed to be overridden in IPBX-specific |
||||
|
modules, such as asterisk_click2dial''' |
||||
|
return {'dialed_number': erp_number} |
||||
|
|
||||
|
|
||||
|
class res_partner(orm.Model): |
||||
|
_name = 'res.partner' |
||||
|
_inherit = ['res.partner', 'phone.common'] |
||||
|
|
||||
|
def create(self, cr, uid, vals, context=None): |
||||
|
vals_reformated = self._generic_reformat_phonenumbers( |
||||
|
cr, uid, vals, context=context) |
||||
|
return super(res_partner, self).create( |
||||
|
cr, uid, vals_reformated, context=context) |
||||
|
|
||||
|
def write(self, cr, uid, ids, vals, context=None): |
||||
|
vals_reformated = self._generic_reformat_phonenumbers( |
||||
|
cr, uid, vals, context=context) |
||||
|
return super(res_partner, self).write( |
||||
|
cr, uid, ids, vals_reformated, context=context) |
||||
|
|
||||
|
def name_get(self, cr, uid, ids, context=None): |
||||
|
if context is None: |
||||
|
context = {} |
||||
|
if context.get('callerid'): |
||||
|
res = [] |
||||
|
if isinstance(ids, (int, long)): |
||||
|
ids = [ids] |
||||
|
for partner in self.browse(cr, uid, ids, context=context): |
||||
|
if partner.parent_id and partner.parent_id.is_company: |
||||
|
name = u'%s (%s)' % (partner.name, partner.parent_id.name) |
||||
|
else: |
||||
|
name = partner.name |
||||
|
res.append((partner.id, name)) |
||||
|
return res |
||||
|
else: |
||||
|
return super(res_partner, self).name_get( |
||||
|
cr, uid, ids, context=context) |
||||
|
|
||||
|
|
||||
|
class res_company(orm.Model): |
||||
|
_inherit = 'res.company' |
||||
|
|
||||
|
_columns = { |
||||
|
'number_of_digits_to_match_from_end': fields.integer( |
||||
|
'Number of Digits To Match From End', |
||||
|
help="In several situations, OpenERP will have to find a " |
||||
|
"Partner/Lead/Employee/... from a phone number presented by the " |
||||
|
"calling party. As the phone numbers presented by your phone " |
||||
|
"operator may not always be displayed in a standard format, " |
||||
|
"the best method to find the related Partner/Lead/Employee/... " |
||||
|
"in OpenERP is to try to match the end of the phone number in " |
||||
|
"OpenERP with the N last digits of the phone number presented " |
||||
|
"by the calling party. N is the value you should enter in this " |
||||
|
"field."), |
||||
|
} |
||||
|
|
||||
|
_defaults = { |
||||
|
'number_of_digits_to_match_from_end': 8, |
||||
|
} |
||||
|
|
||||
|
_sql_constraints = [( |
||||
|
'number_of_digits_to_match_from_end_positive', |
||||
|
'CHECK (number_of_digits_to_match_from_end > 0)', |
||||
|
"The value of the field 'Number of Digits To Match From End' must " |
||||
|
"be positive."), |
||||
|
] |
@ -0,0 +1,18 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright (C) 2014 Alexis de Lattre |
||||
|
@author Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
The licence is in the file __openerp__.py |
||||
|
--> |
||||
|
|
||||
|
<openerp> |
||||
|
<data noupdate="1"> |
||||
|
|
||||
|
<!-- I need a country on the company, because otherwize it raises an error --> |
||||
|
<record id="base.main_company" model="res.company"> |
||||
|
<field name="country_id" ref="base.fr"/> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,35 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Asterisk click2dial module for OpenERP |
||||
|
# Copyright (C) 2014 Alexis de Lattre (alexis@via.ecp.fr) |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
import openerp |
||||
|
|
||||
|
|
||||
|
class BasePhoneController(openerp.addons.web.http.Controller): |
||||
|
_cp_path = '/base_phone' |
||||
|
|
||||
|
@openerp.addons.web.http.jsonrequest |
||||
|
def click2dial(self, req, phone_number, click2dial_model, click2dial_id): |
||||
|
res = req.session.model('phone.common').click2dial( |
||||
|
phone_number, { |
||||
|
'click2dial_model': click2dial_model, |
||||
|
'click2dial_id': click2dial_id, |
||||
|
}) |
||||
|
return res |
@ -0,0 +1,273 @@ |
|||||
|
# Translation of OpenERP Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * base_phone |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: OpenERP Server 7.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2014-08-25 21:28+0000\n" |
||||
|
"PO-Revision-Date: 2014-08-25 21:28+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: base_phone |
||||
|
#: view:reformat.all.phonenumbers:0 |
||||
|
msgid "Cancel" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/base_phone.py:95 |
||||
|
#, python-format |
||||
|
msgid "Cannot reformat the phone number '%s' to international format. Error message: %s" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:34 |
||||
|
#, python-format |
||||
|
msgid "Click2dial started" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:46 |
||||
|
#, python-format |
||||
|
msgid "Click2dial successfull" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Close" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_res_company |
||||
|
msgid "Companies" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/wizard/number_not_found.py:85 |
||||
|
#, python-format |
||||
|
msgid "Create New Partner" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Create Partner with this Number" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Create or Update a Partner" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:number.not.found,current_partner_mobile:0 |
||||
|
msgid "Current Mobile" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:number.not.found,current_partner_phone:0 |
||||
|
msgid "Current Phone" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:31 |
||||
|
#, python-format |
||||
|
msgid "Dial" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:number.not.found,e164_number:0 |
||||
|
msgid "E.164 Number" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: help:number.not.found,e164_number:0 |
||||
|
msgid "E.164 equivalent of the calling number." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.users:0 |
||||
|
msgid "Email Preferences" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/base_phone.py:83 |
||||
|
#: code:addons/base_phone/base_phone.py:94 |
||||
|
#: code:addons/base_phone/wizard/number_not_found.py:99 |
||||
|
#, python-format |
||||
|
msgid "Error:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: selection:number.not.found,number_type:0 |
||||
|
msgid "Fixed" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:number.not.found,number_type:0 |
||||
|
msgid "Fixed/Mobile" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: help:res.company,number_of_digits_to_match_from_end:0 |
||||
|
msgid "In several situations, OpenERP will have to find a Partner/Lead/Employee/... from a phone number presented by the calling party. As the phone numbers presented by your phone operator may not always be displayed in a standard format, the best method to find the related Partner/Lead/Employee/... in OpenERP is to try to match the end of the phone number in OpenERP with the N last digits of the phone number presented by the calling party. N is the value you should enter in this field." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: selection:number.not.found,number_type:0 |
||||
|
msgid "Mobile" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Number Not Found" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Number converted to international format:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:47 |
||||
|
#, python-format |
||||
|
msgid "Number dialed:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_number_not_found |
||||
|
msgid "Number not found" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Number not found:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:res.company,number_of_digits_to_match_from_end:0 |
||||
|
msgid "Number of Digits To Match From End" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_res_partner |
||||
|
msgid "Partner" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/wizard/number_not_found.py:105 |
||||
|
#, python-format |
||||
|
msgid "Partner: %s" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.company:0 |
||||
|
msgid "Phone" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:res.groups,name:base_phone.group_callerid |
||||
|
msgid "Phone CallerID" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:reformat.all.phonenumbers,phonenumbers_not_reformatted:0 |
||||
|
msgid "Phone numbers that couldn't be reformatted" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:reformat.all.phonenumbers:0 |
||||
|
msgid "Phone numbers that couldn't be reformatted:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.actions.act_window,name:base_phone.reformat_all_phonenumbers_action |
||||
|
#: model:ir.ui.menu,name:base_phone.reformat_all_phonenumbers_menu |
||||
|
msgid "Reformat Phone Numbers" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_reformat_all_phonenumbers |
||||
|
#: view:reformat.all.phonenumbers:0 |
||||
|
msgid "Reformat all phone numbers" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/wizard/number_not_found.py:100 |
||||
|
#, python-format |
||||
|
msgid "Select the Partner to Update." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.ui.menu,name:base_phone.menu_config_phone |
||||
|
#: view:res.users:0 |
||||
|
msgid "Telephony" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.users:0 |
||||
|
msgid "Telephony Preferences" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: sql_constraint:res.company:0 |
||||
|
msgid "The value of the field 'Number of Digits To Match From End' must be positive." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:reformat.all.phonenumbers:0 |
||||
|
msgid "This wizard reformats the phone, mobile and fax numbers of all partners in standard international format e.g. +33141981242" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:35 |
||||
|
#, python-format |
||||
|
msgid "Unhook your ringing phone" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Update Partner with this Number" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: constraint:res.partner:0 |
||||
|
msgid "You cannot create recursive Partner hierarchies." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/base_phone.py:84 |
||||
|
#, python-format |
||||
|
msgid "You should set a country on the company '%s'" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_base_phone_installed |
||||
|
msgid "base.phone.installed" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.partner:0 |
||||
|
msgid "fax" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.partner:0 |
||||
|
msgid "phone" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_phone_common |
||||
|
msgid "phone.common" |
||||
|
msgstr "" |
||||
|
|
@ -0,0 +1,273 @@ |
|||||
|
# Translation of OpenERP Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * base_phone |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: OpenERP Server 7.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2014-08-25 21:29+0000\n" |
||||
|
"PO-Revision-Date: 2014-08-25 21:29+0000\n" |
||||
|
"Last-Translator: Alexis de Lattre <alexis.delattre@akretion.com>\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: base_phone |
||||
|
#: view:reformat.all.phonenumbers:0 |
||||
|
msgid "Cancel" |
||||
|
msgstr "Annuler" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/base_phone.py:95 |
||||
|
#, python-format |
||||
|
msgid "Cannot reformat the phone number '%s' to international format. Error message: %s" |
||||
|
msgstr "Impossible de reformatter le numéro de téléphone '%s' au format international. Message d'erreur : %s" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:34 |
||||
|
#, python-format |
||||
|
msgid "Click2dial started" |
||||
|
msgstr "Début du Click2dial" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:46 |
||||
|
#, python-format |
||||
|
msgid "Click2dial successfull" |
||||
|
msgstr "Click2dial réussi" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Close" |
||||
|
msgstr "Fermer" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_res_company |
||||
|
msgid "Companies" |
||||
|
msgstr "Sociétés" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/wizard/number_not_found.py:85 |
||||
|
#, python-format |
||||
|
msgid "Create New Partner" |
||||
|
msgstr "Créer un nouveau partenaire" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Create Partner with this Number" |
||||
|
msgstr "Créer un partenaire avec ce numéro" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Create or Update a Partner" |
||||
|
msgstr "Créer ou mettre à jour un partenaire" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:number.not.found,current_partner_mobile:0 |
||||
|
msgid "Current Mobile" |
||||
|
msgstr "Portable actuel" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:number.not.found,current_partner_phone:0 |
||||
|
msgid "Current Phone" |
||||
|
msgstr "Téléphone actuel" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:31 |
||||
|
#, python-format |
||||
|
msgid "Dial" |
||||
|
msgstr "Composer" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:number.not.found,e164_number:0 |
||||
|
msgid "E.164 Number" |
||||
|
msgstr "Numéro E.164" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: help:number.not.found,e164_number:0 |
||||
|
msgid "E.164 equivalent of the calling number." |
||||
|
msgstr "Equivalent au format E.164 du numéro appelant." |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.users:0 |
||||
|
msgid "Email Preferences" |
||||
|
msgstr "Préférences de messagerie électronique" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/base_phone.py:83 |
||||
|
#: code:addons/base_phone/base_phone.py:94 |
||||
|
#: code:addons/base_phone/wizard/number_not_found.py:99 |
||||
|
#, python-format |
||||
|
msgid "Error:" |
||||
|
msgstr "Erreur :" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: selection:number.not.found,number_type:0 |
||||
|
msgid "Fixed" |
||||
|
msgstr "Fixe" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:number.not.found,number_type:0 |
||||
|
msgid "Fixed/Mobile" |
||||
|
msgstr "Fixe/Portable" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: help:res.company,number_of_digits_to_match_from_end:0 |
||||
|
msgid "In several situations, OpenERP will have to find a Partner/Lead/Employee/... from a phone number presented by the calling party. As the phone numbers presented by your phone operator may not always be displayed in a standard format, the best method to find the related Partner/Lead/Employee/... in OpenERP is to try to match the end of the phone number in OpenERP with the N last digits of the phone number presented by the calling party. N is the value you should enter in this field." |
||||
|
msgstr "In several situations, OpenERP will have to find a Partner/Lead/Employee/... from a phone number presented by the calling party. As the phone numbers presented by your phone operator may not always be displayed in a standard format, the best method to find the related Partner/Lead/Employee/... in OpenERP is to try to match the end of the phone number in OpenERP with the N last digits of the phone number presented by the calling party. N is the value you should enter in this field." |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: selection:number.not.found,number_type:0 |
||||
|
msgid "Mobile" |
||||
|
msgstr "Portable" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Number Not Found" |
||||
|
msgstr "Numéro introuvable" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Number converted to international format:" |
||||
|
msgstr "Numéro converti au format international :" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:47 |
||||
|
#, python-format |
||||
|
msgid "Number dialed:" |
||||
|
msgstr "Numéro composé :" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_number_not_found |
||||
|
msgid "Number not found" |
||||
|
msgstr "Numéro introuvable" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Number not found:" |
||||
|
msgstr "Numéro introuvable :" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:res.company,number_of_digits_to_match_from_end:0 |
||||
|
msgid "Number of Digits To Match From End" |
||||
|
msgstr "Nombre de chiffres à faire correspondre en partant de la fin" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_res_partner |
||||
|
msgid "Partner" |
||||
|
msgstr "Partenaire" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/wizard/number_not_found.py:105 |
||||
|
#, python-format |
||||
|
msgid "Partner: %s" |
||||
|
msgstr "Partenaire : %s" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.company:0 |
||||
|
msgid "Phone" |
||||
|
msgstr "Téléphone" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:res.groups,name:base_phone.group_callerid |
||||
|
msgid "Phone CallerID" |
||||
|
msgstr "CallerID du téléphone" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: field:reformat.all.phonenumbers,phonenumbers_not_reformatted:0 |
||||
|
msgid "Phone numbers that couldn't be reformatted" |
||||
|
msgstr "Numéros de téléphone qui n'ont pas pu être reformatés" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:reformat.all.phonenumbers:0 |
||||
|
msgid "Phone numbers that couldn't be reformatted:" |
||||
|
msgstr "Numéros de téléphone qui n'ont pas pu être reformatés :" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.actions.act_window,name:base_phone.reformat_all_phonenumbers_action |
||||
|
#: model:ir.ui.menu,name:base_phone.reformat_all_phonenumbers_menu |
||||
|
msgid "Reformat Phone Numbers" |
||||
|
msgstr "Reformate les numéros de téléphone" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_reformat_all_phonenumbers |
||||
|
#: view:reformat.all.phonenumbers:0 |
||||
|
msgid "Reformat all phone numbers" |
||||
|
msgstr "Reformate tous les numéros de téléphone" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/wizard/number_not_found.py:100 |
||||
|
#, python-format |
||||
|
msgid "Select the Partner to Update." |
||||
|
msgstr "Selectionnez le partenaire à mettre à jour." |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.ui.menu,name:base_phone.menu_config_phone |
||||
|
#: view:res.users:0 |
||||
|
msgid "Telephony" |
||||
|
msgstr "Téléphonie" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.users:0 |
||||
|
msgid "Telephony Preferences" |
||||
|
msgstr "Préférences téléphoniques" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: sql_constraint:res.company:0 |
||||
|
msgid "The value of the field 'Number of Digits To Match From End' must be positive." |
||||
|
msgstr "The value of the field 'Number of Digits To Match From End' must be positive." |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:reformat.all.phonenumbers:0 |
||||
|
msgid "This wizard reformats the phone, mobile and fax numbers of all partners in standard international format e.g. +33141981242" |
||||
|
msgstr "Cet assistant reformate le numéro de téléphone fixe, portable et le fax de tous les partenaires au format standard international i.e. +33141981242" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#. openerp-web |
||||
|
#: code:addons/base_phone/static/src/js/phone_widget.js:35 |
||||
|
#, python-format |
||||
|
msgid "Unhook your ringing phone" |
||||
|
msgstr "Décrochez votre téléphone" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:number.not.found:0 |
||||
|
msgid "Update Partner with this Number" |
||||
|
msgstr "Mettre à jour le partenaire avec ce numéro" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: constraint:res.partner:0 |
||||
|
msgid "You cannot create recursive Partner hierarchies." |
||||
|
msgstr "You cannot create recursive Partner hierarchies." |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: code:addons/base_phone/base_phone.py:84 |
||||
|
#, python-format |
||||
|
msgid "You should set a country on the company '%s'" |
||||
|
msgstr "Vous devez renseigner un pays pour la société '%s'" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_base_phone_installed |
||||
|
msgid "base.phone.installed" |
||||
|
msgstr "base.phone.installed" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.partner:0 |
||||
|
msgid "fax" |
||||
|
msgstr "fax" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: view:res.partner:0 |
||||
|
msgid "phone" |
||||
|
msgstr "phone" |
||||
|
|
||||
|
#. module: base_phone |
||||
|
#: model:ir.model,name:base_phone.model_phone_common |
||||
|
msgid "phone.common" |
||||
|
msgstr "phone.common" |
||||
|
|
@ -0,0 +1,63 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Base Phone module for OpenERP |
||||
|
# Copyright (C) 2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from openerp.osv import orm |
||||
|
from openerp.report import report_sxw |
||||
|
import phonenumbers |
||||
|
|
||||
|
|
||||
|
class base_phone_installed(orm.AbstractModel): |
||||
|
'''When you use monkey patching, the code is executed when the module |
||||
|
is in the addons_path of the OpenERP server, even is the module is not |
||||
|
installed ! In order to avoid the side-effects it can create, |
||||
|
we create an AbstractModel inside the module and we test the |
||||
|
availability of this Model in the code of the monkey patching below. |
||||
|
At Akretion, we call this the "Guewen trick", in reference |
||||
|
to a trick used by Guewen Baconnier in the "connector" module. |
||||
|
''' |
||||
|
_name = "base.phone.installed" |
||||
|
|
||||
|
|
||||
|
format_original = report_sxw.rml_parse.format |
||||
|
|
||||
|
|
||||
|
def format( |
||||
|
self, text, oldtag=None, phone=False, phone_format='international'): |
||||
|
if self.pool.get('base.phone.installed') and phone and text: |
||||
|
# text should already be in E164 format, so we don't have |
||||
|
# to give a country code to phonenumbers.parse() |
||||
|
phone_number = phonenumbers.parse(text) |
||||
|
if phone_format == 'international': |
||||
|
res = phonenumbers.format_number( |
||||
|
phone_number, phonenumbers.PhoneNumberFormat.INTERNATIONAL) |
||||
|
elif phone_format == 'national': |
||||
|
res = phonenumbers.format_number( |
||||
|
phone_number, phonenumbers.PhoneNumberFormat.NATIONAL) |
||||
|
elif phone_format == 'e164': |
||||
|
res = phonenumbers.format_number( |
||||
|
phone_number, phonenumbers.PhoneNumberFormat.E164) |
||||
|
else: |
||||
|
res = text |
||||
|
else: |
||||
|
res = format_original(self, text, oldtag=oldtag) |
||||
|
return res |
||||
|
|
||||
|
report_sxw.rml_parse.format = format |
@ -0,0 +1,33 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright (C) 2014 Akretion (http://www.akretion.com/) |
||||
|
@author Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
The licence is in the file __openerp__.py |
||||
|
--> |
||||
|
|
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record id="view_company_form" model="ir.ui.view"> |
||||
|
<field name="name">base_phone.company.form</field> |
||||
|
<field name="model">res.company</field> |
||||
|
<field name="inherit_id" ref="base.view_company_form" /> |
||||
|
<field name="arch" type="xml"> |
||||
|
<group name="account_grp" position="after"> |
||||
|
<group name="phone" string="Phone"> |
||||
|
<field name="number_of_digits_to_match_from_end" /> |
||||
|
</group> |
||||
|
</group> |
||||
|
<field name="phone" position="attributes"> |
||||
|
<attribute name="widget">phone</attribute> |
||||
|
</field> |
||||
|
<field name="fax" position="attributes"> |
||||
|
<attribute name="widget">fax</attribute> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,50 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
Base Phone module for OpenERP |
||||
|
Copyright (C) 2010-2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
The licence is in the file __openerp__.py |
||||
|
--> |
||||
|
|
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record id="view_partner_simple_form" model="ir.ui.view"> |
||||
|
<field name="name">base.phone.res.partner.simplified.form</field> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="base.view_partner_simple_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="phone" position="attributes"> |
||||
|
<attribute name="widget">phone</attribute> |
||||
|
</field> |
||||
|
<field name="mobile" position="attributes"> |
||||
|
<attribute name="widget">phone</attribute> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="view_partner_form" model="ir.ui.view"> |
||||
|
<field name="name">base.phone.res.partner.form</field> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="base.view_partner_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//group/group/field[@name='phone']" position="attributes"> |
||||
|
<attribute name="widget">phone</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//group/group/field[@name='mobile']" position="attributes"> |
||||
|
<attribute name="widget">phone</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//group/group/field[@name='fax']" position="attributes"> |
||||
|
<attribute name="widget">fax</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//form[@string='Contact']/sheet/group/field[@name='phone']" position="attributes"> |
||||
|
<attribute name="widget">phone</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//form[@string='Contact']/sheet/group/field[@name='mobile']" position="attributes"> |
||||
|
<attribute name="widget">phone</attribute> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,40 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
Base Phone module for OpenERP |
||||
|
Copyright (C) 2010-2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
The licence is in the file __openerp__.py |
||||
|
--> |
||||
|
|
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record id="view_users_form" model="ir.ui.view"> |
||||
|
<field name="name">base_phone.res.users.telephony_tab</field> |
||||
|
<field name="model">res.users</field> |
||||
|
<field name="inherit_id" ref="base.view_users_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<notebook> |
||||
|
<page string="Telephony" name="phone" invisible="1" position="inside"> |
||||
|
<!-- Empty page, which will be used by other phone modules --> |
||||
|
<group name="phone-preferences" string="Telephony Preferences"> |
||||
|
</group> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="view_users_form_simple_modif" model="ir.ui.view"> |
||||
|
<field name="name">base_phone.user_preferences.view</field> |
||||
|
<field name="model">res.users</field> |
||||
|
<field name="inherit_id" ref="base.view_users_form_simple_modif" /> |
||||
|
<field name="arch" type="xml"> |
||||
|
<group string="Email Preferences" position="after"> |
||||
|
<group name="phone" string="Telephony Preferences" invisible="1"> |
||||
|
<!-- Empty group, that is used by other phone modules --> |
||||
|
</group> |
||||
|
</group> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,2 @@ |
|||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
||||
|
callerid_res_partner_read,Read access on res.partner,base.model_res_partner,group_callerid,1,0,0,0 |
@ -0,0 +1,17 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
Base Phone module for Odoo/OpenERP |
||||
|
Copyright (C) 2010-2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
The licence is in the file __openerp__.py |
||||
|
--> |
||||
|
|
||||
|
<openerp> |
||||
|
<data noupdate="1"> |
||||
|
|
||||
|
<!-- New group dedicated to the "Get CallerID name from OpenERP" feature --> |
||||
|
<record id="group_callerid" model="res.groups"> |
||||
|
<field name="name">Phone CallerID</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,105 @@ |
|||||
|
/* Base phone module for OpenERP |
||||
|
Copyright (C) 2013-2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
The licence is in the file __openerp__.py */ |
||||
|
|
||||
|
openerp.base_phone = function (instance) { |
||||
|
|
||||
|
var _t = instance.web._t; |
||||
|
|
||||
|
instance.base_phone.FieldPhone = instance.web.form.FieldChar.extend({ |
||||
|
template: 'FieldPhone', |
||||
|
initialize_content: function() { |
||||
|
this._super(); |
||||
|
var $button = this.$el.find('button'); |
||||
|
$button.click(this.on_button_clicked); |
||||
|
this.setupFocus($button); |
||||
|
}, |
||||
|
render_value: function() { |
||||
|
if (!this.get('effective_readonly')) { |
||||
|
this._super(); |
||||
|
} else { |
||||
|
var self = this; |
||||
|
var phone_num = this.get('value'); |
||||
|
//console.log('BASE_PHONE phone_num = %s', phone_num);
|
||||
|
if (phone_num) { |
||||
|
this.$el.find('a.oe_form_uri') |
||||
|
.attr('href', 'tel:' + phone_num) |
||||
|
.text(formatInternational('', phone_num) || ''); |
||||
|
} |
||||
|
if (phone_num && !this.options.dial_button_invisible) { |
||||
|
this.$el.find('#click2dial') |
||||
|
.text(phone_num && _t('Dial') || '') |
||||
|
.on('click', function(ev) { |
||||
|
self.do_notify( |
||||
|
_t('Click2dial started'), |
||||
|
_t('Unhook your ringing phone')); |
||||
|
var arg = { |
||||
|
'phone_number': phone_num, |
||||
|
'click2dial_model': self.view.dataset.model, |
||||
|
'click2dial_id': self.view.datarecord.id}; |
||||
|
self.rpc('/base_phone/click2dial', arg).done(function(r) { |
||||
|
//console.log('Click2dial r=%s', JSON.stringify(r));
|
||||
|
if (r === false) { |
||||
|
self.do_warn("Click2dial failed"); |
||||
|
} else if (typeof r === 'object') { |
||||
|
self.do_notify( |
||||
|
_t('Click2dial successfull'), |
||||
|
_t('Number dialed:') + ' ' + r.dialed_number); |
||||
|
if (r.action_model) { |
||||
|
var context = {}; |
||||
|
if (self.view.dataset.model == 'res.partner') { |
||||
|
context = { |
||||
|
'partner_id': self.view.datarecord.id}; |
||||
|
} |
||||
|
var action = { |
||||
|
name: r.action_name, |
||||
|
type: 'ir.actions.act_window', |
||||
|
res_model: r.action_model, |
||||
|
view_mode: 'form', |
||||
|
views: [[false, 'form']], |
||||
|
target: 'new', |
||||
|
context: context, |
||||
|
}; |
||||
|
instance.client.action_manager.do_action(action); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
on_button_clicked: function() { |
||||
|
location.href = 'tel:' + this.get('value'); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
instance.web.form.widgets.add('phone', 'instance.base_phone.FieldPhone'); |
||||
|
|
||||
|
instance.base_phone.FieldFax = instance.web.form.FieldChar.extend({ |
||||
|
template: 'FieldFax', |
||||
|
initialize_content: function() { |
||||
|
this._super(); |
||||
|
var $button = this.$el.find('button'); |
||||
|
$button.click(this.on_button_clicked); |
||||
|
this.setupFocus($button); |
||||
|
}, |
||||
|
render_value: function() { |
||||
|
if (!this.get('effective_readonly')) { |
||||
|
this._super(); |
||||
|
} else { |
||||
|
var fax_num = this.get('value'); |
||||
|
if (fax_num) { |
||||
|
this.$el.find('a.oe_form_uri') |
||||
|
.attr('href', 'fax:' + fax_num) |
||||
|
.text(formatInternational('', fax_num) || ''); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
on_button_clicked: function() { |
||||
|
location.href = 'fax:' + this.get('value'); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
instance.web.form.widgets.add('fax', 'instance.base_phone.FieldFax'); |
||||
|
|
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
Base phone module for OpenERP |
||||
|
Copyright (C) 2013-2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
The licence is in the file __openerp__.py |
||||
|
--> |
||||
|
|
||||
|
<templates id="template" xml:space="preserve"> |
||||
|
|
||||
|
<t t-name="FieldPhone"> |
||||
|
<span class="oe_form_field oe_form_field_email" t-att-style="widget.node.attrs.style"> |
||||
|
<t t-if="widget.get('effective_readonly')"> |
||||
|
<a href="#" class="oe_form_uri"/> |
||||
|
<!-- |
||||
|
You should add the following "<a .. />" in your IPBX-specific |
||||
|
module (such as asterisk_click2dial) via <t t-extend="FieldPhone"> |
||||
|
<a id="click2dial" href="#" class="oe_bold"/> |
||||
|
--> |
||||
|
</t> |
||||
|
<t t-if="!widget.get('effective_readonly')"> |
||||
|
<div> |
||||
|
<input type="text" |
||||
|
t-att-id="widget.id_for_label" |
||||
|
t-att-tabindex="widget.node.attrs.tabindex" |
||||
|
t-att-autofocus="widget.node.attrs.autofocus" |
||||
|
t-att-placeholder="widget.node.attrs.placeholder" |
||||
|
t-att-maxlength="widget.field.size" |
||||
|
/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</span> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="FieldFax"> |
||||
|
<span class="oe_form_field oe_form_field_email" t-att-style="widget.node.attrs.style"> |
||||
|
<a t-if="widget.get('effective_readonly')" href="#" class="oe_form_uri"/> |
||||
|
<t t-if="!widget.get('effective_readonly')"> |
||||
|
<div> |
||||
|
<input type="text" |
||||
|
t-att-id="widget.id_for_label" |
||||
|
t-att-tabindex="widget.node.attrs.tabindex" |
||||
|
t-att-autofocus="widget.node.attrs.autofocus" |
||||
|
t-att-placeholder="widget.node.attrs.placeholder" |
||||
|
t-att-maxlength="widget.field.size" |
||||
|
/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</span> |
||||
|
</t> |
||||
|
|
||||
|
</templates> |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Base Phone module for OpenERP |
||||
|
# Copyright (C) 2012-2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from . import reformat_all_phonenumbers |
||||
|
from . import number_not_found |
@ -0,0 +1,129 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Asterisk Click2dial module for OpenERP |
||||
|
# Copyright (C) 2010-2013 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from openerp.osv import orm, fields |
||||
|
from openerp.tools.translate import _ |
||||
|
import logging |
||||
|
import phonenumbers |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class number_not_found(orm.TransientModel): |
||||
|
_name = "number.not.found" |
||||
|
_description = "Number not found" |
||||
|
|
||||
|
_columns = { |
||||
|
'calling_number': fields.char( |
||||
|
'Calling Number', size=64, readonly=True, |
||||
|
help="Phone number of calling party that has been obtained " |
||||
|
"from Asterisk, in the format used by Asterisk (not E.164)."), |
||||
|
'e164_number': fields.char( |
||||
|
'E.164 Number', size=64, |
||||
|
help="E.164 equivalent of the calling number."), |
||||
|
'number_type': fields.selection( |
||||
|
[('phone', 'Fixed'), ('mobile', 'Mobile')], |
||||
|
'Fixed/Mobile', required=True), |
||||
|
'to_update_partner_id': fields.many2one( |
||||
|
'res.partner', 'Partner to Update', |
||||
|
help="Partner on which the phone number will be written"), |
||||
|
'current_partner_phone': fields.related( |
||||
|
'to_update_partner_id', 'phone', type='char', |
||||
|
relation='res.partner', string='Current Phone', readonly=True), |
||||
|
'current_partner_mobile': fields.related( |
||||
|
'to_update_partner_id', 'mobile', type='char', |
||||
|
relation='res.partner', string='Current Mobile', readonly=True), |
||||
|
} |
||||
|
|
||||
|
def default_get(self, cr, uid, fields_list, context=None): |
||||
|
res = super(number_not_found, self).default_get( |
||||
|
cr, uid, fields_list, context=context) |
||||
|
if not res: |
||||
|
res = {} |
||||
|
if res.get('calling_number'): |
||||
|
convert = self.pool['phone.common']._generic_reformat_phonenumbers( |
||||
|
cr, uid, {'phone': res.get('calling_number')}, context=context) |
||||
|
parsed_num = phonenumbers.parse(convert.get('phone')) |
||||
|
res['e164_number'] = phonenumbers.format_number( |
||||
|
parsed_num, phonenumbers.PhoneNumberFormat.INTERNATIONAL) |
||||
|
number_type = phonenumbers.number_type(parsed_num) |
||||
|
if number_type == 1: |
||||
|
res['number_type'] = 'mobile' |
||||
|
else: |
||||
|
res['number_type'] = 'phone' |
||||
|
return res |
||||
|
|
||||
|
def create_partner(self, cr, uid, ids, context=None): |
||||
|
'''Function called by the related button of the wizard''' |
||||
|
if context is None: |
||||
|
context = {} |
||||
|
wiz = self.browse(cr, uid, ids[0], context=context) |
||||
|
parsed_num = phonenumbers.parse(wiz.e164_number, None) |
||||
|
|
||||
|
context['default_%s' % wiz.number_type] = wiz.e164_number |
||||
|
action = { |
||||
|
'name': _('Create New Partner'), |
||||
|
'view_mode': 'form,tree,kanban', |
||||
|
'res_model': 'res.partner', |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'nodestroy': False, |
||||
|
'target': 'current', |
||||
|
'context': context, |
||||
|
} |
||||
|
return action |
||||
|
|
||||
|
def update_partner(self, cr, uid, ids, context=None): |
||||
|
wiz = self.browse(cr, uid, ids[0], context=context) |
||||
|
if not wiz.to_update_partner_id: |
||||
|
raise orm.except_orm( |
||||
|
_('Error:'), |
||||
|
_("Select the Partner to Update.")) |
||||
|
self.pool['res.partner'].write( |
||||
|
cr, uid, wiz.to_update_partner_id.id, |
||||
|
{wiz.number_type: wiz.e164_number}, context=context) |
||||
|
action = { |
||||
|
'name': _('Partner: %s' % wiz.to_update_partner_id.name), |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'res_model': 'res.partner', |
||||
|
'view_mode': 'form,tree,kanban', |
||||
|
'nodestroy': False, |
||||
|
'target': 'current', |
||||
|
'res_id': wiz.to_update_partner_id.id, |
||||
|
'context': context, |
||||
|
} |
||||
|
return action |
||||
|
|
||||
|
def onchange_to_update_partner( |
||||
|
self, cr, uid, ids, to_update_partner_id, context=None): |
||||
|
res = {'value': {}} |
||||
|
if to_update_partner_id: |
||||
|
to_update_partner = self.pool['res.partner'].browse( |
||||
|
cr, uid, to_update_partner_id, context=context) |
||||
|
res['value'].update({ |
||||
|
'current_partner_phone': to_update_partner.phone, |
||||
|
'current_partner_mobile': to_update_partner.mobile, |
||||
|
}) |
||||
|
else: |
||||
|
res['value'].update({ |
||||
|
'current_partner_phone': False, |
||||
|
'current_partner_mobile': False, |
||||
|
}) |
||||
|
return res |
@ -0,0 +1,55 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
Asterisk Click2dial module for OpenERP |
||||
|
Copyright (C) 2012-2013 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
The licence is in the file __openerp__.py |
||||
|
--> |
||||
|
|
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record id="number_not_found_form" model="ir.ui.view"> |
||||
|
<field name="name">number.not.found.form</field> |
||||
|
<field name="model">number.not.found</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Number Not Found" version="7.0"> |
||||
|
<div class="oe_title"> |
||||
|
<label string="Number not found:" for="calling_number"/> |
||||
|
<h1> |
||||
|
<field name="calling_number" /> |
||||
|
</h1> |
||||
|
<label string="Number converted to international format:" |
||||
|
for="e164_number"/> |
||||
|
<h2> |
||||
|
<field name="e164_number" /> |
||||
|
</h2> |
||||
|
<label for="number_type"/> |
||||
|
<h3> |
||||
|
<field name="number_type"/> |
||||
|
</h3> |
||||
|
</div> |
||||
|
<group colspan="4" col="2" name="create-update"> |
||||
|
<group name="partner" string="Create or Update a Partner" |
||||
|
colspan="1" col="2"> |
||||
|
<button name="create_partner" icon="gtk-new" colspan="2" |
||||
|
string="Create Partner with this Number" type="object"/> |
||||
|
<field name="to_update_partner_id" |
||||
|
on_change="onchange_to_update_partner(to_update_partner_id)"/> |
||||
|
<field name="current_partner_phone" widget="phone" |
||||
|
options="{'dial_button_invisible': True}"/> |
||||
|
<field name="current_partner_mobile" widget="phone" |
||||
|
options="{'dial_button_invisible': True}"/> |
||||
|
<button name="update_partner" icon="gtk-convert" colspan="2" |
||||
|
string="Update Partner with this Number" type="object"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<footer> |
||||
|
<button special="cancel" string="Close" class="oe_link"/> |
||||
|
</footer> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,101 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Base Phone module for OpenERP |
||||
|
# Copyright (C) 2012-2014 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from openerp.osv import orm, fields |
||||
|
import logging |
||||
|
|
||||
|
logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class reformat_all_phonenumbers(orm.TransientModel): |
||||
|
_name = "reformat.all.phonenumbers" |
||||
|
_description = "Reformat all phone numbers" |
||||
|
|
||||
|
_columns = { |
||||
|
'phonenumbers_not_reformatted': fields.text( |
||||
|
"Phone numbers that couldn't be reformatted"), |
||||
|
} |
||||
|
|
||||
|
def run_reformat_all_phonenumbers(self, cr, uid, ids, context=None): |
||||
|
logger.info('Starting to reformat all the phone numbers') |
||||
|
phonenumbers_not_reformatted = '' |
||||
|
toreformat_dict = self.pool['phone.common']._get_phone_fields( |
||||
|
cr, uid, context=context) |
||||
|
for objname, prop in toreformat_dict.iteritems(): |
||||
|
fields = [] |
||||
|
obj = self.pool[objname] |
||||
|
if prop.get('phonefields'): |
||||
|
fields += prop['phonefields'] |
||||
|
if prop.get('faxfields'): |
||||
|
fields += prop['faxfields'] |
||||
|
logger.info( |
||||
|
'Starting to reformat phone numbers on object %s ' |
||||
|
'(fields = %s)' % (objname, fields)) |
||||
|
# search if this object has an 'active' field |
||||
|
if obj._columns.get('active') or objname == 'hr.employee': |
||||
|
# hr.employee inherits from 'resource.resource' and |
||||
|
# 'resource.resource' has an active field |
||||
|
# As I don't know how to detect such cases, I hardcode it here |
||||
|
# If you know a better solution, please tell me |
||||
|
domain = ['|', ('active', '=', True), ('active', '=', False)] |
||||
|
else: |
||||
|
domain = [] |
||||
|
all_ids = obj.search(cr, uid, domain, context=context) |
||||
|
for entry in obj.read( |
||||
|
cr, uid, all_ids, fields, context=context): |
||||
|
init_entry = entry.copy() |
||||
|
# entry is _updated_ by the fonction |
||||
|
# _generic_reformat_phonenumbers() |
||||
|
try: |
||||
|
obj._generic_reformat_phonenumbers( |
||||
|
cr, uid, entry, context=context) |
||||
|
except Exception, e: |
||||
|
name = obj.name_get( |
||||
|
cr, uid, [init_entry['id']], context=context)[0][1] |
||||
|
phonenumbers_not_reformatted += \ |
||||
|
"Problem on %s '%s'. Error message: %s\n" % ( |
||||
|
obj._description, |
||||
|
name, e[1]) |
||||
|
logger.warning( |
||||
|
"Problem on %s '%s'. Error message: %s" % ( |
||||
|
obj._description, |
||||
|
name, e[1])) |
||||
|
continue |
||||
|
if any( |
||||
|
[init_entry.get(field) |
||||
|
!= entry.get(field) for field |
||||
|
in fields]): |
||||
|
entry.pop('id') |
||||
|
logger.info( |
||||
|
'[%s] Reformating phone number: FROM %s TO %s' % ( |
||||
|
obj._description, unicode(init_entry), |
||||
|
unicode(entry))) |
||||
|
obj.write( |
||||
|
cr, uid, init_entry['id'], entry, context=context) |
||||
|
if not phonenumbers_not_reformatted: |
||||
|
phonenumbers_not_reformatted = \ |
||||
|
'All phone numbers have been reformatted successfully.' |
||||
|
self.write( |
||||
|
cr, uid, ids[0], |
||||
|
{'phonenumbers_not_reformatted': phonenumbers_not_reformatted}, |
||||
|
context=context) |
||||
|
logger.info('End of the phone number reformatting wizard') |
||||
|
return True |
@ -0,0 +1,44 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
Base Phone module for OpenERP |
||||
|
Copyright (C) 2012-2013 Alexis de Lattre <alexis@via.ecp.fr> |
||||
|
The licence is in the file __openerp__.py |
||||
|
--> |
||||
|
|
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record id="reformat_all_phonenumbers_form" model="ir.ui.view"> |
||||
|
<field name="name">reformat_all_phonenumbers.form</field> |
||||
|
<field name="model">reformat.all.phonenumbers</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Reformat all phone numbers" version="7.0"> |
||||
|
<!-- TODO : add a "state" and display fields accordingly --> |
||||
|
<group name="main"> |
||||
|
<label string="This wizard reformats the phone, mobile and fax numbers of all partners in standard international format e.g. +33141981242" colspan="4"/> |
||||
|
<label colspan="4" string="Phone numbers that couldn't be reformatted:"/> |
||||
|
<field name="phonenumbers_not_reformatted" colspan="4" nolabel="1"/> |
||||
|
</group> |
||||
|
<footer> |
||||
|
<button name="run_reformat_all_phonenumbers" string="Reformat all phone numbers" type="object" class="oe_highlight"/> |
||||
|
<button special="cancel" string="Cancel" class="oe_link" /> |
||||
|
</footer> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="reformat_all_phonenumbers_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Reformat Phone Numbers</field> |
||||
|
<field name="res_model">reformat.all.phonenumbers</field> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="target">new</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Menu entry under Settings > Technical --> |
||||
|
<menuitem id="menu_config_phone" name="Telephony" parent="base.menu_custom"/> |
||||
|
|
||||
|
<menuitem id="reformat_all_phonenumbers_menu" action="reformat_all_phonenumbers_action" parent="menu_config_phone" sequence="100"/> |
||||
|
|
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue