Browse Source

Improve (and fixes) the 'Open calling partner' function : better usability and less clicks

Update the description.
pull/26/head
Alexis de Lattre 13 years ago
parent
commit
8d0cc9c431
  1. 4
      asterisk_click2dial/__openerp__.py
  2. 87
      asterisk_click2dial/asterisk_click2dial.py
  3. 8
      asterisk_click2dial/res_partner_view.xml

4
asterisk_click2dial/__openerp__.py

@ -41,10 +41,10 @@ phone number is present in the partner addresses of OpenERP. Here is how it work
. 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. . 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.
. If it finds the name, it is set as the CallerID name of the call, so as to be presented on the IP phone of the user. . If it finds the name, it is set as the CallerID name of the call, so as to be presented on the IP phone of the user.
3) It adds a button "Open calling partner" in the menu "Sales > Address book" to open the partner form of the calling party in 2 clicks. Here is how it works :
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 . 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 . 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 and, if a record matches, it opens the form view of the corresponding partner.
. It searches the phone number of the calling party in the Partner addresses of OpenERP and, 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.
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 """, 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', 'author': 'Akretion',

87
asterisk_click2dial/asterisk_click2dial.py

@ -238,7 +238,7 @@ class asterisk_server(osv.osv):
sock.send(login_act.encode('ascii')) sock.send(login_act.encode('ascii'))
login_answer = self._parse_asterisk_answer(cr, uid, sock, context=context) login_answer = self._parse_asterisk_answer(cr, uid, sock, context=context)
if 'Response: Success' in login_answer: if 'Response: Success' in login_answer:
_logger.debug("Successful authentification to Asterisk : %s" % login_answer)
_logger.debug("Successful authentification to Asterisk :\n%s" % login_answer)
else: else:
raise osv.except_osv(_('Error :'), _("Authentification to Asterisk failed :\n%s" % login_answer)) raise osv.except_osv(_('Error :'), _("Authentification to Asterisk failed :\n%s" % login_answer))
@ -277,7 +277,7 @@ class asterisk_server(osv.osv):
status_answer = self._parse_asterisk_answer(cr, uid, sock, end_string='Event: StatusComplete', context=context) status_answer = self._parse_asterisk_answer(cr, uid, sock, end_string='Event: StatusComplete', context=context)
if 'Response: Success' in status_answer: if 'Response: Success' in status_answer:
_logger.debug('Successfull Status command : %s' % status_answer)
_logger.debug('Successfull Status command :\n%s' % status_answer)
else: else:
raise osv.except_osv(_('Error :'), _("Status command to Asterisk failed :\n%s" % status_answer)) raise osv.except_osv(_('Error :'), _("Status command to Asterisk failed :\n%s" % status_answer))
@ -285,7 +285,7 @@ class asterisk_server(osv.osv):
calling_party_number = False calling_party_number = False
status_answer_split = status_answer.split('\r\n\r\n') status_answer_split = status_answer.split('\r\n\r\n')
for event in status_answer_split: for event in status_answer_split:
string_match = 'Channel: ' + user.asterisk_chan_type + '/' + user.internal_number
string_match = 'BridgedChannel: ' + user.asterisk_chan_type + '/' + user.internal_number
if not string_match in event: if not string_match in event:
continue continue
event_split = event.split('\r\n') event_split = event.split('\r\n')
@ -301,9 +301,9 @@ class asterisk_server(osv.osv):
sock.send(('Action: Logoff\r\n\r\n').encode('ascii')) sock.send(('Action: Logoff\r\n\r\n').encode('ascii'))
logout_answer = self._parse_asterisk_answer(cr, uid, sock, context=context) logout_answer = self._parse_asterisk_answer(cr, uid, sock, context=context)
if 'Response: Goodbye' in logout_answer: if 'Response: Goodbye' in logout_answer:
_logger.debug('Successfull logout from Asterisk : %s' % logout_answer)
_logger.debug('Successfull logout from Asterisk :\n%s' % logout_answer)
else: else:
_logger.warning('Logout from Asterisk failed : %s' % logout_answer)
_logger.warning('Logout from Asterisk failed :\n%s' % logout_answer)
# we catch only network problems here # we catch only network problems here
except socket.error: except socket.error:
_logger.warning("Unable to connect to the Asterisk server '%s' IP '%s:%d'" % (ast_server.name, ast_server.ip_address, ast_server.port)) _logger.warning("Unable to connect to the Asterisk server '%s' IP '%s:%d'" % (ast_server.name, ast_server.ip_address, ast_server.port))
@ -315,6 +315,7 @@ class asterisk_server(osv.osv):
return True return True
elif method == "get_calling_number": elif method == "get_calling_number":
_logger.debug("Calling party number: %s" % calling_party_number)
return calling_party_number return calling_party_number
else: else:
@ -404,7 +405,7 @@ class res_partner_address(osv.osv):
''' '''
res = self.get_partner_from_phone_number(cr, uid, number, context=context) res = self.get_partner_from_phone_number(cr, uid, number, context=context)
if res: if res:
return res[1]
return res[2]
else: else:
return False return False
@ -425,11 +426,11 @@ class res_partner_address(osv.osv):
# We use a regexp on the phone field to remove non-digit caracters # We use a regexp on the phone field to remove non-digit caracters
if re.sub(r'\D', '', entry.phone).endswith(number): if re.sub(r'\D', '', entry.phone).endswith(number):
_logger.debug(u"Answer get_name_from_phone_number with name = %s" % entry.name) _logger.debug(u"Answer get_name_from_phone_number with name = %s" % entry.name)
return (entry.partner_id.id, entry.name)
return (entry.id, entry.partner_id.id, entry.name)
if entry.mobile: if entry.mobile:
if re.sub(r'\D', '', entry.mobile).endswith(number): if re.sub(r'\D', '', entry.mobile).endswith(number):
_logger.debug(u"Answer get_name_from_phone_number with name = %s" % entry.name) _logger.debug(u"Answer get_name_from_phone_number with name = %s" % entry.name)
return (entry.partner_id.id, entry.name)
return (entry.id, entry.partner_id.id, entry.name)
_logger.debug(u"No match for phone number %s" % number) _logger.debug(u"No match for phone number %s" % number)
return False return False
@ -439,12 +440,22 @@ res_partner_address()
class wizard_open_calling_partner(osv.osv_memory): class wizard_open_calling_partner(osv.osv_memory):
_name = "wizard.open.calling.partner" _name = "wizard.open.calling.partner"
_description = "Open calling partner"
_columns = {
'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', 'Partner address', help="Partner address related to the calling number"),
'partner_id': fields.many2one('res.partner', 'Partner', help="Partner related to the calling number"),
}
def open_calling_partner(self, cr, uid, ids, context=None):
_logger.debug(u"Start wizard 'open calling partner'")
def default_get(self, cr, uid, fields, context=None):
'''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')._connect_to_asterisk(cr, uid, method='get_calling_number', context=context) calling_number = self.pool.get('asterisk.server')._connect_to_asterisk(cr, uid, method='get_calling_number', context=context)
#To test the code without Asterisk server
#calling_number = "0141981242"
if calling_number: if calling_number:
res['calling_number'] = calling_number
# We match only on the end of the phone number # We match only on the end of the phone number
if len(calling_number) >= 9: if len(calling_number) >= 9:
number_to_search = calling_number[-9:len(calling_number)] number_to_search = calling_number[-9:len(calling_number)]
@ -452,7 +463,53 @@ class wizard_open_calling_partner(osv.osv_memory):
number_to_search = calling_number 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.address').get_partner_from_phone_number(cr, uid, number_to_search, context=context)
if partner: if partner:
_logger.debug("Found a partner corresponding to the calling party : '%s'" % partner[1])
res['partner_address_id'] = partner[0]
res['partner_id'] = partner[1]
else:
raise osv.except_osv(_('Error :'), _("Could not find a partner corresponding to the calling number '%s'" % calling_number))
else:
_logger.debug("Could not get the calling number from Asterisk.")
raise osv.except_osv(_('Error :'), _("Could not get the calling number from Asterisk. Check your setup and look at the OpenERP debug logs."))
return res
def open_filtered_object(self, cr, uid, ids, oerp_object, context=None):
'''Returns the action that opens the list view of the 'oerp_object'
given as argument filtered on the partner'''
# This module only depends on "base"
# and I don't want to add a dependancy on "sale" or "account"
# So I just check here that the model exists, to avoid a crash
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:
action = {
'name': oerp_object._description,
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': oerp_object._name,
'type': 'ir.actions.act_window',
'nodestroy': False, # close the pop-up wizard after action
'target': 'current',
'domain': [('partner_id', '=', partner[0])],
}
return action
else:
return False
def open_sale_orders(self, cr, uid, ids, context=None):
'''Function called by the related button of the wizard'''
return self.open_filtered_object(cr, uid, ids, self.pool.get('sale.order'), context=context)
def open_invoices(self, cr, uid, ids, context=None):
'''Function called by the related button of the wizard'''
return self.open_filtered_object(cr, uid, ids, self.pool.get('account.invoice'), context=context)
def open_partner(self, cr, uid, ids, context=None):
'''Function called by the related button of the wizard'''
partner = self.read(cr, uid, ids[0], ['partner_id'], context=context)['partner_id']
if partner:
action = { action = {
'name': 'Calling partner', 'name': 'Calling partner',
'view_type': 'form', 'view_type': 'form',
@ -465,11 +522,7 @@ class wizard_open_calling_partner(osv.osv_memory):
} }
return action return action
else: else:
_logger.debug("Could not find a partner corresponding to the calling number '%s'" % calling_number)
raise osv.except_osv(_('Error :'), _("Could not find a partner corresponding to the calling number '%s'" % calling_number))
else:
_logger.debug("Could not retrieve the calling number from Asterisk")
raise osv.except_osv(_('Error :'), _("Could not retrieve the calling number from Asterisk"))
return False
wizard_open_calling_partner() wizard_open_calling_partner()

8
asterisk_click2dial/res_partner_view.xml

@ -88,7 +88,13 @@
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Open calling partner"> <form string="Open calling partner">
<button name="open_calling_partner" icon="gtk-ok" string="Go" type="object" />
<field name="calling_number" readonly="1"/>
<field name="partner_address_id" readonly="1" />
<field name="partner_id" readonly="1" />
<newline />
<button name="open_partner" icon="gtk-go-forward" string="Partner form" type="object" />
<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" /> <button special="cancel" icon="gtk-cancel" string="Cancel" />
</form> </form>
</field> </field>

Loading…
Cancel
Save