Browse Source

Port to OpenERP 7.0

Add logo for the module asterisk_click2dial_crm
pull/7/head
Alexis de Lattre 12 years ago
parent
commit
df1d12e643
  1. 8
      asterisk_click2dial/__openerp__.py
  2. 44
      asterisk_click2dial/asterisk_click2dial.py
  3. 2
      asterisk_click2dial/asterisk_click2dial_demo.xml
  4. 4
      asterisk_click2dial/asterisk_server_view.xml
  5. 61
      asterisk_click2dial/res_partner_view.xml
  6. 28
      asterisk_click2dial/res_users_view.xml
  7. 4
      asterisk_click2dial/security/asterisk_server_security.xml
  8. 109
      asterisk_click2dial/wizard/open_calling_partner.py
  9. 32
      asterisk_click2dial/wizard/open_calling_partner_view.xml
  10. 28
      asterisk_click2dial/wizard/reformat_all_phonenumbers.py
  11. 11
      asterisk_click2dial_crm/asterisk_click2dial_crm.py
  12. BIN
      asterisk_click2dial_crm/static/src/img/icon.png
  13. 24
      asterisk_click2dial_crm/wizard/create_crm_phonecall.py
  14. 8
      asterisk_click2dial_crm/wizard/open_calling_partner_view.xml

8
asterisk_click2dial/__openerp__.py

@ -27,15 +27,15 @@
'license': 'AGPL-3',
'description': """This module adds 3 functionnalities :
1) It adds a 'dial' button in the partner address form view so that users can directly dial a phone number through Asterisk. This feature is usually known as 'click2dial'. Here is how it works :
. In OpenERP, the user clicks on the 'dial' button next to a phone number field in the partner address view.
1) It adds a 'dial' button in the partner form view so that users can directly dial a phone number through Asterisk. This feature is usually known as 'click2dial'. Here is how it works :
. In OpenERP, the user clicks on the 'dial' button next to a phone number field in the partner view.
. OpenERP connects to the Asterisk Manager Interface and Asterisk makes the user's phone ring.
. The user answers his own phone (if he doesn't, the process stops here).
. Asterisk dials the phone number found in OpenERP in place of the user.
. If the remote party answers, the user can talk to his correspondent.
2) It adds the ability to show the name of the calling party on the screen of your IP phone on incoming phone calls if the presented
phone number is present in the partner addresses of OpenERP. Here is how it works :
phone number is present in the partners of OpenERP. Here is how it works :
. On incoming phone calls, the Asterisk dialplan executes an AGI script "get_cid_name_timeout.sh".
. The "get_cid_name_timeout.sh" script calls the "get_cid_name.py" script with a short timeout.
. The "get_cid_name.py" script will make an XML-RPC request on the OpenERP server to try to find the name of the person corresponding to the phone number presented by the calling party.
@ -44,7 +44,7 @@ phone number is present in the partner addresses of OpenERP. Here is how it work
3) It adds a button "Open calling partner" in the menu "Sales > Address book" to get the partner corresponding to the calling party in one click. Here is how it works :
. When the user clicks on the "Open calling partner" button, OpenERP sends a query to the Asterisk Manager Interface to get a list of the current phone calls
. If it finds a phone call involving the user's phone, it gets the phone number of the calling party
. It searches the phone number of the calling party in the Partner addresses of OpenERP. If a record matches, it shows the name of the related Partner and proposes to open it, or open its related sale orders or invoices. If no record matches, it proposes to create a new Contact with the presented phone number as 'Phone' or 'Mobile' number or update an existing Contact.
. It searches the phone number of the calling party in the Partners of OpenERP. If a record matches, it shows the name of the related Partner and proposes to open it, or open its related sale orders or invoices. If no record matches, it proposes to create a new Contact with the presented phone number as 'Phone' or 'Mobile' number or update an existing Contact.
A detailed documentation for this module is available on the Akretion Web site : http://www.akretion.com/en/products-and-services/openerp-asterisk-voip-connector """,
'author': 'Akretion',

44
asterisk_click2dial/asterisk_click2dial.py

@ -299,8 +299,6 @@ class asterisk_server(osv.osv):
return calling_party_number
asterisk_server()
# Parameters specific for each user
class res_users(osv.osv):
@ -354,44 +352,43 @@ class res_users(osv.osv):
(_check_validity, "Error message in raise", ['resource', 'internal_number', 'callerid']),
]
res_users()
class res_partner_address(osv.osv):
_inherit = "res.partner.address"
class res_partner(osv.osv):
_inherit = "res.partner"
def _format_phonenumber_to_e164(self, cr, uid, ids, name, arg, context=None):
result = {}
for addr in self.read(cr, uid, ids, ['phone', 'mobile', 'fax'], context=context):
result[addr['id']] = {}
for partner in self.read(cr, uid, ids, ['phone', 'mobile', 'fax'], context=context):
result[partner['id']] = {}
for fromfield, tofield in [('phone', 'phone_e164'), ('mobile', 'mobile_e164'), ('fax', 'fax_e164')]:
if not addr.get(fromfield):
if not partner.get(fromfield):
res = False
else:
try:
res = phonenumbers.format_number(phonenumbers.parse(addr.get(fromfield), None), phonenumbers.PhoneNumberFormat.E164)
res = phonenumbers.format_number(phonenumbers.parse(partner.get(fromfield), None), phonenumbers.PhoneNumberFormat.E164)
except Exception, e:
_logger.error("Cannot reformat the phone number '%s' to E.164 format. Error message: %s" % (addr.get(fromfield), e))
_logger.error("Cannot reformat the phone number '%s' to E.164 format. Error message: %s" % (partner.get(fromfield), e))
_logger.error("You should fix this number and run the wizard 'Reformat all phone numbers' from the menu Settings > Configuration > Asterisk")
# If I raise an exception here, it won't be possible to install
# the module on a DB with bad phone numbers
#raise osv.except_osv(_('Error :'), _("Cannot reformat the phone number '%s' to E.164 format. Error message: %s" % (addr.get(fromfield), e)))
#raise osv.except_osv(_('Error :'), _("Cannot reformat the phone number '%s' to E.164 format. Error message: %s" % (partner.get(fromfield), e)))
res = False
result[addr['id']][tofield] = res
result[partner['id']][tofield] = res
#print "RESULT _format_phonenumber_to_e164", result
return result
_columns = {
'phone_e164': fields.function(_format_phonenumber_to_e164, type='char', size=64, string='Phone in E.164 format', readonly=True, multi="e164", store={
'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['phone'], 10),
'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['phone'], 10),
}),
'mobile_e164': fields.function(_format_phonenumber_to_e164, type='char', size=64, string='Mobile in E.164 format', readonly=True, multi="e164", store={
'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['mobile'], 10),
'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['mobile'], 10),
}),
'fax_e164': fields.function(_format_phonenumber_to_e164, type='char', size=64, string='Fax in E.164 format', readonly=True, multi="e164", store={
'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['fax'], 10),
'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['fax'], 10),
}),
}
@ -421,12 +418,12 @@ class res_partner_address(osv.osv):
def create(self, cr, uid, vals, context=None):
vals_reformated = self._reformat_phonenumbers(cr, uid, vals, context=context)
return super(res_partner_address, self).create(cr, uid, vals_reformated, 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._reformat_phonenumbers(cr, uid, vals, context=context)
return super(res_partner_address, self).write(cr, uid, ids, vals_reformated, context=context)
return super(res_partner, self).write(cr, uid, ids, vals_reformated, context=context)
def dial(self, cr, uid, ids, phone_field=['phone', 'phone_e164'], context=None):
@ -444,13 +441,13 @@ class res_partner_address(osv.osv):
def action_dial_phone(self, cr, uid, ids, context=None):
'''Function called by the button 'Dial' next to the 'phone' field
in the partner address view'''
in the partner view'''
return self.dial(cr, uid, ids, phone_field=['phone', 'phone_e164'], context=context)
def action_dial_mobile(self, cr, uid, ids, context=None):
'''Function called by the button 'Dial' next to the 'mobile' field
in the partner address view'''
in the partner view'''
return self.dial(cr, uid, ids, phone_field=['mobile', 'mobile_e164'], context=context)
@ -484,17 +481,15 @@ class res_partner_address(osv.osv):
res_ids = self.search(cr, uid, ['|', ('phone_e164', 'ilike', pg_seach_number), ('mobile_e164', 'ilike', pg_seach_number)], context=context)
# TODO : use is_number_match() of the phonenumber lib ?
if len(res_ids) > 1:
_logger.warning(u"There are several partners addresses (IDS = %s) with the same phone number %s" % (str(res_ids), number))
_logger.warning(u"There are several partners (IDS = %s) with the same phone number %s" % (str(res_ids), number))
if res_ids:
entry = self.read(cr, uid, res_ids[0], ['name', 'partner_id'], context=context)
entry = self.read(cr, uid, res_ids[0], ['name', 'parent_id'], context=context)
_logger.debug(u"Answer get_partner_from_phone_number with name = %s" % entry['name'])
return (entry['id'], entry['partner_id'] and entry['partner_id'][0] or False, entry['name'])
return (entry['id'], entry['parent_id'] and entry['parent_id'][0] or False, entry['name'])
else:
_logger.debug(u"No match for phone number %s" % number)
return False
res_partner_address()
# This module supports multi-company
class res_company(osv.osv):
@ -504,4 +499,3 @@ class res_company(osv.osv):
'asterisk_server_ids': fields.one2many('asterisk.server', 'company_id', 'Asterisk servers', help="List of Asterisk servers.")
}
res_company()

2
asterisk_click2dial/asterisk_click2dial_demo.xml

@ -21,11 +21,13 @@
</record>
<record id="base.user_root" model="res.users">
<field name="internal_number">11</field>
<field name="resource">11</field>
<field name="callerid">Administrator &lt;0141981242&gt;</field>
<field name="asterisk_server_id" ref="demo_ast_server"/>
</record>
<record id="base.user_demo" model="res.users">
<field name="internal_number">12</field>
<field name="resource">12</field>
<field name="callerid">Demo user &lt;0141984212&gt;</field>
<field name="asterisk_server_id" ref="demo_ast_server"/>
</record>

4
asterisk_click2dial/asterisk_server_view.xml

@ -74,8 +74,8 @@
<field name="context">{'asterisk_server_main_view': True}</field>
</record>
<!-- Menu entry under Settings > Configuration -->
<menuitem id="menu_asterisk_servers" name="Asterisk" parent="base.menu_config" groups="base.group_extended"/>
<!-- Menu entry under Settings > Technical -->
<menuitem id="menu_asterisk_servers" name="Asterisk" parent="base.menu_custom"/>
<menuitem action="action_asterisk_server" id="act_menu_ast_server" parent="menu_asterisk_servers" sequence="50"/>

61
asterisk_click2dial/res_partner_view.xml

@ -4,79 +4,64 @@
Copyright (C) 2010-2012 Alexis de Lattre <alexis@via.ecp.fr>
The licence is in the file __openerp__.py
Inherit partner_address views to add 'Dial' button next to 'phone'
Inherit partner views to add 'Dial' button next to 'phone'
and 'mobile' fields
-->
<openerp>
<data>
<record id="asterisk_res_partner_address_dial1" model="ir.ui.view">
<field name="name">asterisk.res.partner.address.dial1</field>
<field name="model">res.partner.address</field>
<record id="asterisk_res_partner_simplified_form_dial" model="ir.ui.view">
<field name="name">asterisk.res.partner.simplified.form.dial</field>
<field name="model">res.partner</field>
<field name="priority">15</field>
<field name="inherit_id" ref="base.view_partner_address_form1"/>
<field name="inherit_id" ref="base.view_partner_simple_form"/>
<field name="arch" type="xml">
<data>
<field name="phone" position="replace">
<group colspan="2" col="8">
<field name="phone" colspan="7" />
<button name="action_dial_phone" string="Dial" type="object"/>
<button name="action_dial_phone" string="Dial" type="object" attrs="{'invisible':[('phone','=',False)]}"/>
</group>
</field>
<field name="mobile" position="replace">
<group colspan="2" col="8">
<field name="mobile" colspan="7" />
<button name="action_dial_mobile" string="Dial" type="object"/>
<button name="action_dial_mobile" string="Dial" type="object" attrs="{'invisible':[('mobile','=',False)]}"/>
</group>
</field>
</data>
</field>
</record>
<record id="asterisk_res_partner_address_dial2" model="ir.ui.view">
<field name="name">asterisk.res.partner.address.dial2</field>
<field name="model">res.partner.address</field>
<record id="asterisk_res_partner_form_dial" model="ir.ui.view">
<field name="name">asterisk.res.partner.form.dial</field>
<field name="model">res.partner</field>
<field name="priority">15</field>
<field name="inherit_id" ref="base.view_partner_address_form2"/>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<data>
<field name="phone" position="replace">
<xpath expr="//group/group/field[@name='phone']" position="replace">
<group colspan="2" col="8">
<field name="phone" colspan="7" />
<button name="action_dial_phone" string="Dial" type="object"/>
<button name="action_dial_phone" string="Dial" type="object" attrs="{'invisible':[('phone','=',False)]}"/>
</group>
</field>
<field name="mobile" position="replace">
</xpath>
<xpath expr="//group/group/field[@name='mobile']" position="replace">
<group colspan="2" col="8">
<field name="mobile" colspan="7" />
<button name="action_dial_mobile" string="Dial" type="object"/>
<button name="action_dial_mobile" string="Dial" type="object" attrs="{'invisible':[('mobile','=',False)]}"/>
</group>
</field>
</data>
</field>
</record>
<record id="asterisk_res_partner_dial" model="ir.ui.view">
<field name="name">asterisk.res.partner.dial</field>
<field name="model">res.partner</field>
<field name="priority">15</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<data>
<field name="phone" position="replace">
</xpath>
<xpath expr="//form[@string='Contact']/div/group/field[@name='phone']" position="replace">
<group colspan="2" col="8">
<field name="phone" colspan="7" />
<button name="action_dial_phone" string="Dial" type="object"/>
<button name="action_dial_phone" string="Dial" type="object" attrs="{'invisible':[('phone','=',False)]}"/>
</group>
</field>
<field name="mobile" position="replace">
</xpath>
<xpath expr="//form[@string='Contact']/div/group/field[@name='mobile']" position="replace">
<group colspan="2" col="8">
<field name="mobile" colspan="7" />
<button name="action_dial_mobile" string="Dial" type="object"/>
<button name="action_dial_mobile" string="Dial" type="object" attrs="{'invisible':[('mobile','=',False)]}"/>
</group>
</field>
</data>
</xpath>
</field>
</record>

28
asterisk_click2dial/res_users_view.xml

@ -15,20 +15,22 @@
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<page string="User" position="after">
<page string="Telephony">
<separator string="Standard parameters" colspan="4"/>
<field name="asterisk_chan_type"/>
<field name="resource"/>
<field name="internal_number"/>
<field name="callerid"/>
<field name="asterisk_server_id"/>
<separator string="Optional parameters - for experts only, can be left empty" colspan="4"/>
<field name="dial_suffix"/>
<field name="alert_info"/>
<field name="variable"/>
<notebook>
<page string="Telephony" position="inside">
<group name="standard_params" string="Standard parameters">
<field name="asterisk_chan_type"/>
<field name="resource"/>
<field name="internal_number"/>
<field name="callerid"/>
<field name="asterisk_server_id"/>
</group>
<group name="optional_params" string="Optional parameters - for experts only, can be left empty">
<field name="dial_suffix"/>
<field name="alert_info"/>
<field name="variable"/>
</group>
</page>
</page>
</notebook>
</field>
</record>

4
asterisk_click2dial/security/asterisk_server_security.xml

@ -36,8 +36,8 @@
<!-- Only add the minimum rights to the "Asterisk CallerID" group -->
<record id="ir_model_access_asterisk_cid" model="ir.model.access">
<field name="model_id" ref="base.model_res_partner_address"/>
<field name="name" eval="&quot;&quot;&quot;res.partner.address_read&quot;&quot;&quot;"/>
<field name="model_id" ref="base.model_res_partner"/>
<field name="name" eval="&quot;&quot;&quot;res.partner_read&quot;&quot;&quot;"/>
<field name="group_id" ref="asterisk_click2dial.group_asterisk_cid"/>
<field name="perm_read" eval="1"/>
<field name="perm_write" eval="0"/>

109
asterisk_click2dial/wizard/open_calling_partner.py

@ -20,7 +20,6 @@
##############################################################################
from osv import osv, fields
# Lib required to open a socket (needed to communicate with Asterisk server)
import logging
# Lib to translate error messages
from tools.translate import _
@ -37,11 +36,11 @@ class wizard_open_calling_partner(osv.osv_memory):
# default_get (and thus connect to Asterisk) a second time when the user
# clicks on one of the buttons
'calling_number': fields.char('Calling number', size=30, help="Phone number of calling party that has been obtained from Asterisk."),
'partner_address_id': fields.many2one('res.partner.address', 'Contact name', help="Partner contact related to the calling number. If there is none and you want to update an existing partner"),
'partner_id': fields.many2one('res.partner', 'Partner', help="Partner related to the calling number."),
'to_update_partner_address_id': fields.many2one('res.partner.address', 'Contact to update', help="Partner contact on which the phone or mobile number will be written"),
'current_phone': fields.related('to_update_partner_address_id', 'phone', type='char', relation='res.partner.address', string='Current phone'),
'current_mobile': fields.related('to_update_partner_address_id', 'mobile', type='char', relation='res.partner.address', string='Current mobile'),
'partner_id': fields.many2one('res.partner', 'Partner name', help="Partner related to the calling number."),
'parent_partner_id': fields.many2one('res.partner', 'Parent partner', help="Parent Partner related to the calling number."),
'to_update_partner_id': fields.many2one('res.partner', 'Partner to update', help="Partner on which the phone or mobile number will be written"),
'current_phone': fields.related('to_update_partner_id', 'phone', type='char', relation='res.partner', string='Current phone'),
'current_mobile': fields.related('to_update_partner_id', 'mobile', type='char', relation='res.partner', string='Current mobile'),
}
@ -49,27 +48,28 @@ class wizard_open_calling_partner(osv.osv_memory):
'''Thanks to the default_get method, we are able to query Asterisk and
get the corresponding partner when we launch the wizard'''
res = {}
calling_number = self.pool.get('asterisk.server')._get_calling_number(cr, uid, context=context)
# calling_number = self.pool.get('asterisk.server')._get_calling_number(cr, uid, context=context)
#To test the code without Asterisk server
#calling_number = "0141981242"
calling_number = "0141981242"
if calling_number:
res['calling_number'] = calling_number
# We match only on the end of the phone number
# TODO : make this parameter configurable
if len(calling_number) >= 9:
number_to_search = calling_number[-9:len(calling_number)]
else:
number_to_search = calling_number
partner = self.pool.get('res.partner.address').get_partner_from_phone_number(cr, uid, number_to_search, context=context)
partner = self.pool.get('res.partner').get_partner_from_phone_number(cr, uid, number_to_search, context=context)
if partner:
res['partner_address_id'] = partner[0]
res['partner_id'] = partner[1]
res['partner_id'] = partner[0]
res['parent_partner_id'] = partner[1]
else:
res['partner_id'] = False
res['partner_address_id'] = False
res['to_update_partner_address_id'] = False
res['parent_partner_id'] = False
res['to_update_partner_id'] = False
else:
_logger.debug("Could not get the calling number from Asterisk.")
raise osv.except_osv(_('Error :'), _("Could not get the calling number from Asterisk. Are you currently on the phone ? If yes, check your setup and look at the OpenERP debug logs."))
raise osv.except_osv(_('Error :'), _("Could not get the calling number from Asterisk. Is your phone ringing or are you currently on the phone ? If yes, check your setup and look at the OpenERP debug logs."))
return res
@ -83,8 +83,9 @@ class wizard_open_calling_partner(osv.osv_memory):
if not self.pool.get('ir.model').search(cr, uid, [('model', '=', oerp_object._name)], context=context):
raise osv.except_osv(_('Error :'), _("The object '%s' is not found in your OpenERP database, probably because the related module is not installed." % oerp_object._description))
partner = self.read(cr, uid, ids[0], ['partner_id'], context=context)['partner_id']
if partner:
partner = self.read(cr, uid, ids[0], ['partner_id', 'parent_partner_id'], context=context)
partner_id_to_filter = partner['parent_partner_id'] and partner['parent_partner_id'][0] or (partner['partner_id'] and partner['partner_id'][0] or False)
if partner_id_to_filter:
action = {
'name': oerp_object._description,
'view_type': 'form',
@ -93,7 +94,7 @@ class wizard_open_calling_partner(osv.osv_memory):
'type': 'ir.actions.act_window',
'nodestroy': False, # close the pop-up wizard after action
'target': 'current',
'domain': [('partner_id', '=', partner[0])],
'domain': [('partner_id', '=', partner_id_to_filter)],
}
return action
else:
@ -110,22 +111,14 @@ class wizard_open_calling_partner(osv.osv_memory):
return self.open_filtered_object(cr, uid, ids, self.pool.get('account.invoice'), context=context)
def simple_open(self, cr, uid, ids, object_name='res.partner', context=None):
if object_name == 'res.partner':
field = 'partner_id'
label = 'Partner'
elif object_name == 'res.partner.address':
field = 'partner_address_id'
label = 'Contact'
else:
raise osv.except_osv(_('Error :'), "This object '%s' is not supported" % object_name)
def simple_open(self, cr, uid, ids, field='partner_id', context=None):
record_to_open = self.read(cr, uid, ids[0], [field], context=context)[field]
if record_to_open:
return {
'name': label,
'name': self.pool.get('res.partner')._description,
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': object_name,
'res_model': 'res.partner',
'type': 'ir.actions.act_window',
'nodestroy': False, # close the pop-up wizard after action
'target': 'current',
@ -137,15 +130,16 @@ class wizard_open_calling_partner(osv.osv_memory):
def open_partner(self, cr, uid, ids, context=None):
'''Function called by the related button of the wizard'''
return self.simple_open(cr, uid, ids, object_name='res.partner', context=context)
return self.simple_open(cr, uid, ids, field='partner_id', context=context)
def open_partner_address(self, cr, uid, ids, context=None):
# TODO
def open_parent_partner(self, cr, uid, ids, context=None):
'''Function called by the related button of the wizard'''
return self.simple_open(cr, uid, ids, object_name='res.partner.address', context=context)
return self.simple_open(cr, uid, ids, field='parent_partner_id', context=context)
def create_partner_address(self, cr, uid, ids, phone_type='phone', context=None):
def create_partner(self, cr, uid, ids, phone_type='phone', context=None):
'''Function called by the related button of the wizard'''
calling_number = self.read(cr, uid, ids[0], ['calling_number'], context=context)['calling_number']
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
@ -153,64 +147,67 @@ class wizard_open_calling_partner(osv.osv_memory):
# Convert the number to the international format
number_to_write = self.pool.get('asterisk.server')._convert_number_to_international_format(cr, uid, calling_number, ast_server, context=context)
new_partner_address_id = self.pool.get('res.partner.address').create(cr, uid, {phone_type: number_to_write}, context=context)
new_partner_id = self.pool.get('res.partner').create(cr, uid, {
'name': 'WRITE PARTNER NAME HERE',
phone_type: number_to_write,
}, context=context)
action = {
'name': 'Create new contact',
'name': 'Create new partner',
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'res.partner.address',
'res_model': 'res.partner',
'type': 'ir.actions.act_window',
'nodestroy': False,
'target': 'current',
'res_id': new_partner_address_id,
'res_id': new_partner_id,
}
return action
def create_partner_address_phone(self, cr, uid, ids, context=None):
return self.create_partner_address(cr, uid, ids, phone_type='phone', context=context)
def create_partner_phone(self, cr, uid, ids, context=None):
return self.create_partner(cr, uid, ids, phone_type='phone', context=context)
def create_partner_address_mobile(self, cr, uid, ids, context=None):
return self.create_partner_address(cr, uid, ids, phone_type='mobile', context=context)
def create_partner_mobile(self, cr, uid, ids, context=None):
return self.create_partner(cr, uid, ids, phone_type='mobile', context=context)
def update_partner_address(self, cr, uid, ids, phone_type='mobile', context=None):
def update_partner(self, cr, uid, ids, phone_type='mobile', context=None):
cur_wizard = self.browse(cr, uid, ids[0], context=context)
if not cur_wizard.to_update_partner_address_id:
raise osv.except_osv(_('Error :'), _("Select the contact to update."))
if not cur_wizard.to_update_partner_id:
raise osv.except_osv(_('Error :'), _("Select the partner to update."))
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
ast_server = self.pool.get('asterisk.server')._get_asterisk_server_from_user(cr, uid, user, context=context)
number_to_write = self.pool.get('asterisk.server')._convert_number_to_international_format(cr, uid, cur_wizard.calling_number, ast_server, context=context)
self.pool.get('res.partner.address').write(cr, uid, cur_wizard.to_update_partner_address_id.id, {phone_type: number_to_write}, context=context)
self.pool.get('res.partner').write(cr, uid, cur_wizard.to_update_partner_id.id, {phone_type: number_to_write}, context=context)
action = {
'name': 'Contact: ' + cur_wizard.to_update_partner_address_id.name,
'name': 'Partner: ' + cur_wizard.to_update_partner_id.name,
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'res.partner.address',
'res_model': 'res.partner',
'type': 'ir.actions.act_window',
'nodestroy': False,
'target': 'current',
'res_id': cur_wizard.to_update_partner_address_id.id
'res_id': cur_wizard.to_update_partner_id.id
}
return action
def update_partner_address_phone(self, cr, uid, ids, context=None):
return self.update_partner_address(cr, uid, ids, phone_type='phone', context=context)
def update_partner_phone(self, cr, uid, ids, context=None):
return self.update_partner(cr, uid, ids, phone_type='phone', context=context)
def update_partner_address_mobile(self, cr, uid, ids, context=None):
return self.update_partner_address(cr, uid, ids, phone_type='mobile', context=context)
def update_partner_mobile(self, cr, uid, ids, context=None):
return self.update_partner(cr, uid, ids, phone_type='mobile', context=context)
def onchange_to_update_partner_address(self, cr, uid, ids, to_update_partner_address_id, context=None):
def onchange_to_update_partner(self, cr, uid, ids, to_update_partner_id, context=None):
res = {}
res['value'] = {}
if to_update_partner_address_id:
to_update_partner_address = self.pool.get('res.partner.address').browse(cr, uid, to_update_partner_address_id, context=context)
res['value'].update({'current_phone': to_update_partner_address.phone,
'current_mobile': to_update_partner_address.mobile})
if to_update_partner_id:
to_update_partner = self.pool.get('res.partner').browse(cr, uid, to_update_partner_id, context=context)
res['value'].update({'current_phone': to_update_partner.phone,
'current_mobile': to_update_partner.mobile})
else:
res['value'].update({'current_phone': False, 'current_mobile': False})
return res

32
asterisk_click2dial/wizard/open_calling_partner_view.xml

@ -16,34 +16,30 @@
<field name="arch" type="xml">
<form string="Open calling partner">
<field name="calling_number" colspan="4"/>
<field name="partner_address_id" attrs="{'invisible':[('partner_address_id','=',False)]}"/>
<field name="partner_id" attrs="{'invisible':[('partner_address_id','=',False)]}" /> <!-- I want it visible when partner_address_id != False and partner_id = False, so that the user can see that this partner_address doesn't have a partner -->
<field name="partner_id" attrs="{'invisible':[('partner_id','=',False)]}"/>
<field name="parent_partner_id" attrs="{'invisible':[('partner_id','=',False)]}" /> <!-- I want it visible when partner_id != False and partner_id = False, so that the user can see that this partner doesn't have a parent partner -->
<newline />
<group colspan="4" attrs="{'invisible':[('partner_id','=',False)]}">
<group colspan="4" col="5" attrs="{'invisible':[('partner_id','=',False)]}">
<button name="open_partner" icon="gtk-go-forward" string="Partner form" type="object" />
<button name="open_parent_partner" icon="gtk-go-forward" string="Parent Partner form" type="object" attrs="{'invisible':[('parent_partner_id','=',False)]}"/>
<button name="open_sale_orders" icon="gtk-go-forward" string="Related sale orders" type="object" />
<button name="open_invoices" icon="gtk-go-forward" string="Related invoices" type="object" />
<button special="cancel" icon="gtk-cancel" string="Cancel" />
</group>
<!-- I display the button "Contact form" when the partner address exists but not the partner -->
<group colspan="4" attrs="{'invisible':['|', '&amp;', ('partner_address_id','!=',False), ('partner_id','!=',False), ('partner_address_id','=',False)]}">
<button name="open_partner_address" icon="gtk-go-forward" string="Contact form" type="object" colspan="2"/>
<button special="cancel" icon="gtk-cancel" string="Cancel" colspan="2"/>
</group>
<group attrs="{'invisible':[('partner_address_id','!=',False)]}" colspan="4" col="8">
<label string="No partner contact found in OpenERP with this number" colspan="8" />
<separator string="Create a new contact" colspan="8" />
<button name="create_partner_address_phone" icon="gtk-new" string="with calling number as phone" type="object" colspan="4"/>
<button name="create_partner_address_mobile" icon="gtk-new" string="with calling number as mobile" type="object" colspan="4"/>
<group attrs="{'invisible':[('partner_id','!=',False)]}" colspan="4" col="8">
<label string="No partner found in OpenERP with this number" colspan="8" />
<separator string="Create a new partner" colspan="8" />
<button name="create_partner_phone" icon="gtk-new" string="with calling number as phone" type="object" colspan="4"/>
<button name="create_partner_mobile" icon="gtk-new" string="with calling number as mobile" type="object" colspan="4"/>
<newline />
<separator string="Update an existing contact" colspan="8" />
<field name="to_update_partner_address_id" colspan="8" on_change="onchange_to_update_partner_address(to_update_partner_address_id)"/>
<separator string="Update an existing partner" colspan="8" />
<field name="to_update_partner_id" colspan="8" on_change="onchange_to_update_partner(to_update_partner_id)"/>
<field name="current_phone" colspan="6"/>
<button name="update_partner_address_phone" icon="gtk-convert" string="Update phone" type="object" colspan="2"/>
<button name="update_partner_phone" icon="gtk-convert" string="Update phone" type="object" colspan="2"/>
<field name="current_mobile" colspan="6"/>
<button name="update_partner_address_mobile" icon="gtk-convert" string="Update mobile" type="object" colspan="2"/>
<button name="update_partner_mobile" icon="gtk-convert" string="Update mobile" type="object" colspan="2"/>
<newline />
<button special="cancel" icon="gtk-cancel" string="Cancel" colspan="8" />
@ -62,7 +58,7 @@
<field name="target">new</field>
</record>
<menuitem id="menu_open_calling_partner_sales" parent="base.menu_address_book" action="action_open_calling_partner" sequence="50" />
<menuitem id="menu_open_calling_partner_sales" parent="base.menu_sales" action="action_open_calling_partner" sequence="50" />
</data>
</openerp>

28
asterisk_click2dial/wizard/reformat_all_phonenumbers.py

@ -35,27 +35,27 @@ class reformat_all_phonenumbers(osv.osv_memory):
def run_reformat_all_phonenumbers(self, cr, uid, ids, context=None):
addr_obj = self.pool.get('res.partner.address')
partner_obj = self.pool.get('res.partner')
phonefields = ['phone', 'fax', 'mobile']
_logger.info('Starting to reformat all the phone numbers')
all_addr_ids = addr_obj.search(cr, uid, ['|', ('active', '=', True), ('active', '=', False)], context=context)
all_partner_ids = partner_obj.search(cr, uid, ['|', ('active', '=', True), ('active', '=', False)], context=context)
phonenumbers_not_reformatted = ''
for addr in addr_obj.read(cr, uid, all_addr_ids, ['name'] + phonefields, context=context):
init_addr = addr.copy()
# addr is _updated_ by the fonction _reformat_phonenumbers()
for partner in partner_obj.read(cr, uid, all_partner_ids, ['name'] + phonefields, context=context):
init_partner = partner.copy()
# partner is _updated_ by the fonction _reformat_phonenumbers()
try:
addr_obj._reformat_phonenumbers(cr, uid, addr, context=context)
partner_obj._reformat_phonenumbers(cr, uid, partner, context=context)
except Exception, e:
#raise osv.except_osv(_('Error :'), _("Problem on partner contact '%s'. Error message: %s" % (init_addr.get('name'), e[1])))
phonenumbers_not_reformatted += "Problem on partner contact '%s'. Error message: %s" % (init_addr.get('name'), e[1]) + "\n"
_logger.warning("Problem on partner contact '%s'. Error message: %s" % (init_addr.get('name'), e[1]))
#raise osv.except_osv(_('Error :'), _("Problem on partner '%s'. Error message: %s" % (init_partner.get('name'), e[1])))
phonenumbers_not_reformatted += "Problem on partner '%s'. Error message: %s" % (init_partner.get('name'), e[1]) + "\n"
_logger.warning("Problem on partner '%s'. Error message: %s" % (init_partner.get('name'), e[1]))
continue
# Test if the phone numbers have been changed
if any([init_addr.get(field) != addr.get(field) for field in phonefields]):
addr.pop('id')
addr.pop('name')
_logger.info('Reformating phone number: FROM %s TO %s' % (unicode(init_addr), unicode(addr)))
addr_obj.write(cr, uid, init_addr['id'], addr, context=context)
if any([init_partner.get(field) != partner.get(field) for field in phonefields]):
partner.pop('id')
partner.pop('name')
_logger.info('Reformating phone number: FROM %s TO %s' % (unicode(init_partner), unicode(partner)))
partner_obj.write(cr, uid, init_partner['id'], partner, 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)

11
asterisk_click2dial_crm/asterisk_click2dial_crm.py

@ -26,8 +26,8 @@ from osv import osv, fields
# Lib to translate error messages
from tools.translate import _
class res_partner_address(osv.osv):
_inherit = "res.partner.address"
class res_partner(osv.osv):
_inherit = "res.partner"
def dial(self, cr, uid, ids, phone_field='phone', context=None):
'''
@ -37,9 +37,9 @@ class res_partner_address(osv.osv):
'''
if context is None:
context = {}
super(res_partner_address, self).dial(cr, uid, ids, phone_field=phone_field, context=context)
super(res_partner, self).dial(cr, uid, ids, phone_field=phone_field, context=context)
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
context['partner_address_id'] = ids[0]
context['partner_id'] = ids[0]
action_start_wizard = {
'name': 'Create phone call in CRM',
'type': 'ir.actions.act_window',
@ -55,7 +55,6 @@ class res_partner_address(osv.osv):
else:
return True
res_partner_address()
class res_users(osv.osv):
@ -72,5 +71,3 @@ class res_users(osv.osv):
'context_propose_creation_crm_call': True,
}
res_users()

BIN
asterisk_click2dial_crm/static/src/img/icon.png

After

Width: 100  |  Height: 100  |  Size: 16 KiB

24
asterisk_click2dial_crm/wizard/create_crm_phonecall.py

@ -31,10 +31,10 @@ class wizard_create_crm_phonecall(osv.osv_memory):
_name = "wizard.create.crm.phonecall"
def button_create_outgoing_phonecall(self, cr, uid, ids, context=None):
partner_address = self.pool.get('res.partner.address').browse(cr, uid, context.get('partner_address_id'), context=context)
return self._create_open_crm_phonecall(cr, uid, partner_address, crm_categ='Outbound', context=context)
partner = self.pool.get('res.partner').browse(cr, uid, context.get('partner_id'), context=context)
return self._create_open_crm_phonecall(cr, uid, partner, crm_categ='Outbound', context=context)
def _create_open_crm_phonecall(self, cr, uid, partner_address, crm_categ, context=None):
def _create_open_crm_phonecall(self, cr, uid, partner, crm_categ, context=None):
if context is None:
context = {}
crm_phonecall_obj = self.pool.get('crm.phonecall')
@ -42,12 +42,10 @@ class wizard_create_crm_phonecall(osv.osv_memory):
categ_ids = self.pool.get('crm.case.categ').search(cr, uid, [('name','=',crm_categ)], context={'lang': 'en_US'})
case_section_ids = self.pool.get('crm.case.section').search(cr, uid, [('member_ids', 'in', uid)], context=context)
values = {
'name': _('Call with') + ' ' + partner_address.name,
'partner_id': partner_address.partner_id and partner_address.partner_id.id or False,
'partner_address_id': partner_address.id,
'partner_phone': partner_address.phone,
'partner_contact': partner_address.name,
'partner_mobile': partner_address.mobile,
'name': _('Call with') + ' ' + partner.name,
'partner_id': partner.id or False,
'partner_phone': partner.phone,
'partner_mobile': partner.mobile,
'user_id': uid,
'categ_id': categ_ids and categ_ids[0] or False,
'section_id': case_section_ids and case_section_ids[0] or False,
@ -60,8 +58,8 @@ class wizard_create_crm_phonecall(osv.osv_memory):
crm_phonecall_id = crm_phonecall_obj.create(cr, uid, values, context=context)
return {
'name': partner_address.name,
'domain': [('partner_id', '=', partner_address.partner_id.id)],
'name': partner.name,
'domain': [('partner_id', '=', partner.id)],
'res_model': 'crm.phonecall',
'res_id': crm_phonecall_id,
'view_type': 'form',
@ -80,8 +78,8 @@ class wizard_open_calling_partner(osv.osv_memory):
def create_incoming_phonecall(self, cr, uid, ids, crm_categ, context=None):
'''Started by button on 'open calling partner wizard'''
partner_address = self.browse(cr, uid, ids[0], context=context).partner_address_id
action = self.pool.get('wizard.create.crm.phonecall')._create_open_crm_phonecall(cr, uid, partner_address, crm_categ='Inbound', context=context)
partner = self.browse(cr, uid, ids[0], context=context).partner_id
action = self.pool.get('wizard.create.crm.phonecall')._create_open_crm_phonecall(cr, uid, partner, crm_categ='Inbound', context=context)
return action
wizard_open_calling_partner()

8
asterisk_click2dial_crm/wizard/open_calling_partner_view.xml

@ -25,6 +25,14 @@
</field>
</record>
<!-- Move "Open calling partner" menu entry to "Phone calls" menu -->
<delete model="ir.ui.menu" id="asterisk_click2dial.menu_open_calling_partner_sales" />
<menuitem id="menu_open_calling_partner_phone"
parent="crm.menu_crm_case_phone"
action="asterisk_click2dial.action_open_calling_partner"
sequence="1" />
</data>
</openerp>
Loading…
Cancel
Save