diff --git a/asterisk_click2dial/__openerp__.py b/asterisk_click2dial/__openerp__.py
index d4524ac..b787b5d 100644
--- a/asterisk_click2dial/__openerp__.py
+++ b/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.
. 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
. 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 """,
'author': 'Akretion',
diff --git a/asterisk_click2dial/asterisk_click2dial.py b/asterisk_click2dial/asterisk_click2dial.py
index 9f015e5..d197da1 100644
--- a/asterisk_click2dial/asterisk_click2dial.py
+++ b/asterisk_click2dial/asterisk_click2dial.py
@@ -238,7 +238,7 @@ class asterisk_server(osv.osv):
sock.send(login_act.encode('ascii'))
login_answer = self._parse_asterisk_answer(cr, uid, sock, context=context)
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:
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)
if 'Response: Success' in status_answer:
- _logger.debug('Successfull Status command : %s' % status_answer)
+ _logger.debug('Successfull Status command :\n%s' % status_answer)
else:
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
status_answer_split = status_answer.split('\r\n\r\n')
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:
continue
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'))
logout_answer = self._parse_asterisk_answer(cr, uid, sock, context=context)
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:
- _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
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))
@@ -315,6 +315,7 @@ class asterisk_server(osv.osv):
return True
elif method == "get_calling_number":
+ _logger.debug("Calling party number: %s" % calling_party_number)
return calling_party_number
else:
@@ -404,7 +405,7 @@ class res_partner_address(osv.osv):
'''
res = self.get_partner_from_phone_number(cr, uid, number, context=context)
if res:
- return res[1]
+ return res[2]
else:
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
if re.sub(r'\D', '', entry.phone).endswith(number):
_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 re.sub(r'\D', '', entry.mobile).endswith(number):
_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)
return False
@@ -439,12 +440,22 @@ res_partner_address()
class wizard_open_calling_partner(osv.osv_memory):
_name = "wizard.open.calling.partner"
-
-
- def open_calling_partner(self, cr, uid, ids, context=None):
- _logger.debug(u"Start 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 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)
+ #To test the code without Asterisk server
+ #calling_number = "0141981242"
if calling_number:
+ res['calling_number'] = calling_number
# We match only on the end of the phone number
if len(calling_number) >= 9:
number_to_search = calling_number[-9:len(calling_number)]
@@ -452,24 +463,66 @@ class wizard_open_calling_partner(osv.osv_memory):
number_to_search = calling_number
partner = self.pool.get('res.partner.address').get_partner_from_phone_number(cr, uid, number_to_search, context=context)
if partner:
- _logger.debug("Found a partner corresponding to the calling party : '%s'" % partner[1])
- action = {
- 'name': 'Calling partner',
- 'view_type': 'form',
- 'view_mode': 'form,tree',
- 'res_model': 'res.partner',
- 'type': 'ir.actions.act_window',
- 'nodestroy': False, # close the pop-up wizard after action
- 'target': 'current',
- 'res_id': [partner[0]],
- }
- return action
+ res['partner_address_id'] = partner[0]
+ res['partner_id'] = partner[1]
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"))
+ _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 = {
+ 'name': 'Calling partner',
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'res.partner',
+ 'type': 'ir.actions.act_window',
+ 'nodestroy': False, # close the pop-up wizard after action
+ 'target': 'current',
+ 'res_id': [partner[0]],
+ }
+ return action
+ else:
+ return False
wizard_open_calling_partner()
diff --git a/asterisk_click2dial/res_partner_view.xml b/asterisk_click2dial/res_partner_view.xml
index ea60044..a2f3b2a 100644
--- a/asterisk_click2dial/res_partner_view.xml
+++ b/asterisk_click2dial/res_partner_view.xml
@@ -88,7 +88,13 @@
form