Browse Source
Extract Asterisk-independant code (the widget="phone" + phone number reformatting) from the asterisk_click2dial module to a new base_phone module.
pull/7/head
Extract Asterisk-independant code (the widget="phone" + phone number reformatting) from the asterisk_click2dial module to a new base_phone module.
pull/7/head
Alexis de Lattre
11 years ago
27 changed files with 516 additions and 268 deletions
-
11asterisk_click2dial/__openerp__.py
-
66asterisk_click2dial/asterisk_click2dial.py
-
15asterisk_click2dial/asterisk_server_view.xml
-
4asterisk_click2dial/res_partner_view.xml
-
3asterisk_click2dial/wizard/__init__.py
-
73asterisk_click2dial/wizard/reformat_all_phonenumbers.py
-
32asterisk_click2dial_crm/__openerp__.py
-
31asterisk_click2dial_crm/asterisk_click2dial_crm.py
-
6asterisk_click2dial_crm/wizard/__init__.py
-
35asterisk_click2dial_crm/wizard/create_crm_phonecall.py
-
13asterisk_click2dial_crm/wizard/reformat_all_phonenumbers.py
-
43asterisk_click2dial_crm_claim/asterisk_click2dial_crm_claim.py
-
8asterisk_click2dial_crm_claim/wizard/open_calling_partner.py
-
13asterisk_click2dial_crm_claim/wizard/reformat_all_phonenumbers.py
-
8asterisk_click2dial_registration/__openerp__.py
-
23asterisk_click2dial_registration/asterisk_click2dial_registration.py
-
4asterisk_click2dial_registration/wizard/open_calling_partner.py
-
23base_phone/__init__.py
-
55base_phone/__openerp__.py
-
120base_phone/base_phone.py
-
50base_phone/res_partner_view.xml
-
0base_phone/static/lib/js/PhoneFormat.js
-
16base_phone/static/src/js/phone_widget.js
-
0base_phone/static/src/xml/phone.xml
-
22base_phone/wizard/__init__.py
-
100base_phone/wizard/reformat_all_phonenumbers.py
-
10base_phone/wizard/reformat_all_phonenumbers_view.xml
@ -1,73 +0,0 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Asterisk Click2dial module for OpenERP |
|||
# Copyright (C) 2012-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 |
|||
|
|||
_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 _extend_reformat_phonenumbers(self, cr, uid, context=None): |
|||
'''This function is designed to be inherited |
|||
to extend the functionnality to objects other than res.partner''' |
|||
res = { |
|||
self.pool['res.partner']: { |
|||
'allids': self.pool['res.partner'].search(cr, uid, ['|', ('active', '=', True), ('active', '=', False)], context=context), |
|||
'phonefields': ['phone', 'fax', 'mobile'], |
|||
'namefield': 'name', |
|||
} |
|||
} |
|||
return res |
|||
|
|||
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._extend_reformat_phonenumbers(cr, uid, context=context) |
|||
for obj, prop in toreformat_dict.items(): |
|||
for entry in obj.read(cr, uid, prop['allids'], [prop['namefield']] + prop['phonefields'], 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: |
|||
#raise orm.except_orm(_('Error :'), _("Problem on entry '%s'. Error message: %s" % (init_entry.get(prop['namefield']), e[1]))) |
|||
phonenumbers_not_reformatted += "Problem on %s '%s'. Error message: %s" % (obj._description, init_entry.get(prop['namefield']), e[1]) + "\n" |
|||
_logger.warning("Problem on %s '%s'. Error message: %s" % (obj._description, init_entry.get(prop['namefield']), e[1])) |
|||
continue |
|||
if any([init_entry.get(field) != entry.get(field) for field in prop['phonefields']]): |
|||
entry.pop('id') |
|||
entry.pop(prop['namefield']) |
|||
_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,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Base Module 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 |
@ -0,0 +1,55 @@ |
|||
# -*- 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': 'Extra Tools', |
|||
'license': 'AGPL-3', |
|||
'summary': 'Validate phone numbers', |
|||
'description': """ |
|||
Base Phone |
|||
========== |
|||
|
|||
This module validate phone numbers using the phonenumbers Python library, which is a port of the lib used in Android smartphones. It also adds tel: links on phone numbers. |
|||
|
|||
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'], |
|||
'external_dependencies': {'python': ['phonenumbers']}, |
|||
'data': [ |
|||
'res_partner_view.xml', |
|||
'wizard/reformat_all_phonenumbers_view.xml', |
|||
], |
|||
'js': [ |
|||
'static/src/js/*.js', |
|||
'static/lib/js/*.js', |
|||
], |
|||
'qweb': ['static/src/xml/*.xml'], |
|||
'images': [], |
|||
'installable': True, |
|||
'active': False, |
|||
} |
@ -0,0 +1,120 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Base Phone module for 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 |
|||
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', 'fax', 'mobile'], |
|||
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) |
|||
#print "user_countrycode=", user_countrycode |
|||
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)) |
|||
#print "res_parse=", res_parse |
|||
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 |
|||
|
|||
|
|||
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) |
@ -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,22 @@ |
|||
# -*- 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 |
@ -0,0 +1,100 @@ |
|||
# -*- 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 _extend_reformat_phonenumbers(self, cr, uid, context=None): |
|||
'''This function is designed to be inherited |
|||
to extend the functionnality to objects other than res.partner''' |
|||
res = { |
|||
self.pool['res.partner']: { |
|||
'allids': self.pool['res.partner'].search( |
|||
cr, uid, [ |
|||
'|', |
|||
('active', '=', True), |
|||
('active', '=', False) |
|||
], context=context), |
|||
'phonefields': ['phone', 'fax', 'mobile'], |
|||
'namefield': 'name', |
|||
} |
|||
} |
|||
return res |
|||
|
|||
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._extend_reformat_phonenumbers( |
|||
cr, uid, context=context) |
|||
for obj, prop in toreformat_dict.items(): |
|||
for entry in obj.read( |
|||
cr, uid, prop['allids'], |
|||
[prop['namefield']] + prop['phonefields'], |
|||
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: |
|||
phonenumbers_not_reformatted += \ |
|||
"Problem on %s '%s'. Error message: %s\n" % ( |
|||
obj._description, |
|||
init_entry.get(prop['namefield']), e[1]) |
|||
_logger.warning( |
|||
"Problem on %s '%s'. Error message: %s" % ( |
|||
obj._description, |
|||
init_entry.get(prop['namefield']), e[1])) |
|||
continue |
|||
if any( |
|||
[init_entry.get(field) |
|||
!= entry.get(field) for field |
|||
in prop['phonefields']]): |
|||
entry.pop('id') |
|||
entry.pop(prop['namefield']) |
|||
_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 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue