Browse Source

[FIX] connector_voicent

pull/191/head
Maxime Chambreuil 6 years ago
parent
commit
d02d51a685
  1. 12
      connector_voicent/__manifest__.py
  2. 4
      connector_voicent/data/ir_cron.xml
  3. 32
      connector_voicent/examples/prototype.py
  4. 2
      connector_voicent/examples/voicent.csv
  5. 52
      connector_voicent/examples/voicent.py
  6. 3
      connector_voicent/models/__init__.py
  7. 111
      connector_voicent/models/backend_voicent.py
  8. 109
      connector_voicent/models/backend_voicent_call_line.py
  9. 18
      connector_voicent/models/backend_voicent_time_line.py
  10. 17
      connector_voicent/models/queue_job.py
  11. 4
      connector_voicent/models/res_partner.py
  12. 6
      connector_voicent/readme/CONFIGURATION.rst
  13. 3
      connector_voicent/readme/ROADMAP.rst
  14. 4
      connector_voicent/readme/USAGE.rst
  15. 8
      connector_voicent/security/ir.model.access.csv
  16. BIN
      connector_voicent/static/description/icon.png
  17. 13
      connector_voicent/tests/test_backend_voicent.py
  18. 18
      connector_voicent/view/queue_job_view.xml
  19. 47
      connector_voicent/views/backend_voicent.xml
  20. 76
      connector_voicent/views/backend_voicent_call_line.xml
  21. 10
      connector_voicent/views/res_partner.xml

12
connector_voicent/__manifest__.py

@ -7,9 +7,7 @@
'version': '12.0.1.0.0',
'category': 'Connector',
'license': 'AGPL-3',
'summary': """This module allows you to connect Odoo with Voicent
(https://www.voicent.com) and is meant to be extended to integrate
Odoo records and processes with phone calls made by Voicent.""",
'summary': """Connect Odoo with Voicent""",
"author": "Open Source Integrators, "
"Odoo Community Association (OCA)",
"website": "https://github.com/OCA/connector-telephony",
@ -18,10 +16,10 @@
],
'data': [
'security/ir.model.access.csv',
'data/check_the_voicent_status.xml',
'view/res_partner.xml',
'view/backend_voicent.xml',
'view/queue_job_view.xml',
'data/ir_cron.xml',
'views/res_partner.xml',
'views/backend_voicent_call_line.xml',
'views/backend_voicent.xml',
],
'installable': True,
'maintainers': [

4
connector_voicent/data/check_the_voicent_status.xml → connector_voicent/data/ir_cron.xml

@ -2,7 +2,7 @@
<odoo>
<record id="fetch_check_the_voicent_status" model="ir.cron">
<field name="name">Fetch check the Voicent status</field>
<field name="name">Voicent: Update the next call</field>
<field name="model_id" ref="model_backend_voicent"/>
<field eval="True" name="active"/>
<field name="user_id" ref="base.user_root"/>
@ -11,7 +11,7 @@
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field name="state">code</field>
<field name="code">model._run_check_the_voicent_status()</field>
<field name="code">model._run_update_next_call()</field>
</record>
</odoo>

32
connector_voicent/examples/prototype.py

@ -1,32 +0,0 @@
# Copyright (C) 2019 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# Simple message
import voicent
v = voicent.Voicent()
phoneno = "6024275632"
reqid = v.callText(phoneno, "Hello, This is a test of the autodialer.", "1")
status = v.callStatus(reqid)
# Using Campaign in 2 steps
v = voicent.Voicent()
filepath = "/home/mchambreuil/odoo/pvm/voicent.csv"
listname = "Test"
leadsrc_id = v.importCampaign(listname, filepath)
res = v.runCampaign(listname)
v.checkStatus(res['leadsrc_id'])
# Using Campaign in 1 step with TTS
v = voicent.Voicent()
filepath = "/home/mchambreuil/odoo/pvm/voicent.csv"
res = v.importAndRunCampaign(filepath, "tts", "Hello, This is a test. Bye")
status = v.checkStatus(res['camp_id'])
# Using Campaign in 1 step with Template
v = voicent.Voicent()
filepath = "/home/mchambreuil/odoo/pvm/voicent.csv"
res = v.importAndRunCampaign(filepath, "template", "Test")
status = v.checkStatus(res['camp_id'])

2
connector_voicent/examples/voicent.csv

@ -1,2 +0,0 @@
Name,Phone
Maxime Chambreuil,6024275632

52
connector_voicent/examples/voicent.py

@ -4,16 +4,21 @@
#
# Documentation available at https://voicent.com/developer/docs/camp-api/
import ast
import csv
import ntpath
import os
import requests
import ast
class Voicent():
def __init__(self, host="localhost", port="8155"):
def __init__(self, host="localhost", port="8155", callerid="000000000",
line="1"):
self.host_ = host
self.port_ = port
self.callerid_ = callerid
self.line_ = line
def postToGateway(self, urlstr, params, files=None):
url = "http://" + self.host_ + ":" + self.port_ + urlstr
@ -22,11 +27,11 @@ class Voicent():
def getReqId(self, rcstr):
index1 = rcstr.find("[ReqId=")
if (index1 == -1):
if index1 == -1:
return ""
index1 += 7
index2 = rcstr.find("]", index1)
if (index2 == -1):
if index2 == -1:
return ""
return rcstr[index1:index2]
@ -132,9 +137,9 @@ class Voicent():
'CAMP_NAME': 'Test',
'listname': listname,
'phonecols': 'Phone',
'lines': '4',
'lines': self.line_,
'calldisps': '',
'callerid': '+18884728568',
'callerid': self.callerid_,
}
res = self.postToGateway(urlstr, params)
return ast.literal_eval(res)
@ -146,16 +151,17 @@ class Voicent():
# Parameters for importing the campaign
'importfile': ntpath.basename(filepath),
'importfilepath': filepath,
'mergeopt': 'skip',
# 'profile': 'Test',
'mod': 'cus',
'row1': 1,
'leadsrcname': 'Test',
'leadsrcname': 'Odoo Voicent Connector',
# Parameters for running the campaign
'CAMP_NAME': 'Test',
'CAMP_NAME': 'Odoo Voicent Connector',
'phonecols': 'Phone',
'lines': '4',
'lines': self.line_,
'calldisps': '',
'callerid': '+18884728568',
'callerid': self.callerid_,
# Parameters for Autodialer
'msgtype': msgtype,
'msginfo': msginfo,
@ -166,22 +172,34 @@ class Voicent():
res = self.postToGateway(urlstr, params, files)
return ast.literal_eval(res)
def checkStatus(self, leadsrc_id):
def checkStatus(self, camp_id):
urlstr = "/ocall/campapi"
params = {
'action': 'campstats',
'leadsrc_id': leadsrc_id
'camp_id': camp_id
}
res = self.postToGateway(urlstr, params)
return ast.literal_eval(res)
def exportResult(self, camp_id, filename, extracols):
def exportResult(self, camp_id, filename, extracols=None):
urlstr = "/ocall/campapi"
params = {
'action': 'exportcamp',
'camp_id_id': camp_id,
'f': filename,
'camp_id': camp_id,
'f': 'webapps/ROOT/assets/global/' + filename,
'extracols': extracols
}
res = self.postToGateway(urlstr, params)
return ast.literal_eval(res)
res = ast.literal_eval(self.postToGateway(urlstr, params))
if res.get('status') == 'OK':
url = 'http://' + self.host_ + ':' + self.port_ + \
'/assets/global/' + filename
res2 = requests.get(url)
with open(filename, 'wb') as local_file:
local_file.write(res2.content)
local_file.close()
reader = csv.DictReader(open(filename, 'r'))
os.remove(filename)
for row in reader:
return row
else:
return res

3
connector_voicent/models/__init__.py

@ -1,5 +1,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import res_partner
from . import backend_voicent_call_line
from . import backend_voicent_time_line
from . import backend_voicent
from . import queue_job

111
connector_voicent/models/backend_voicent.py

@ -7,58 +7,46 @@ from odoo import api, fields, models
from datetime import datetime, timedelta
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
from pytz import timezone
from ..examples import voicent
class BackendVoicent(models.Model):
_name = 'backend.voicent'
_description = 'Voicent Backend'
_inherit = ['connector.backend']
_rec_name = 'host'
host = fields.Char(
string='Host',
required=True,
)
port = fields.Integer(
string='Port',
required=True,
)
next_call = fields.Datetime(
string='Next Call',
copy=False,
)
name = fields.Char(string='Name', required=True)
host = fields.Char(string='Host', default='localhost', required=True)
port = fields.Integer(string='Port', default='8155', required=True)
callerid = fields.Char(string='Caller ID', required=True)
line = fields.Integer(string='Number of lines', required=True)
next_call = fields.Datetime(string='Next Call', copy=False)
call_line_ids = fields.One2many(
string='Call Lines',
comodel_name='backend.voicent.call.line',
inverse_name='backend_id',
)
inverse_name='backend_id')
time_line_ids = fields.One2many(
string='Call Times',
comodel_name='backend.voicent.time.line',
inverse_name='backend_id',
)
is_active = fields.Boolean('Is Active')
inverse_name='backend_id')
active = fields.Boolean('Active', default=True)
@api.model
def _run_check_the_voicent_status(self):
''' This method is called from a cron job. '''
def _run_update_next_call(self):
""" This method is called from a cron job. """
cr_time_list = []
is_next_day = False
backend_voicent_rec = self.search([('is_active', '=', True)])
for backend_voicent in backend_voicent_rec:
backends = self.search([('active', '=', True)])
for backend in backends:
current_dt = datetime.now(timezone('UTC'))
user_tz = timezone(
self.env.context.get('tz') or self.env.user.tz or 'UTC')
dt_value = current_dt.astimezone(user_tz)
convt_dt_strf = dt_value.strftime(
DEFAULT_SERVER_DATETIME_FORMAT)
convt_dt_strf = dt_value.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
convt_dt = datetime.strptime(
convt_dt_strf,
DEFAULT_SERVER_DATETIME_FORMAT)
current_time = convt_dt.strftime("%H:%M")
for time_line_rec in backend_voicent.time_line_ids:
for time_line_rec in backend.time_line_ids:
hours, minutes = divmod(abs(time_line_rec.time) * 60, 60)
minutes = round(minutes)
if minutes == 60:
@ -67,64 +55,25 @@ class BackendVoicent(models.Model):
line_time = '%02d:%02d' % (hours, minutes)
cr_time_list.append(line_time)
cr_time_list = sorted(cr_time_list)
next_call = datetime.now()
for each_time_entry in cr_time_list:
if each_time_entry > current_time and not is_next_day:
next_call = False
for time_entry in cr_time_list:
if time_entry > current_time:
next_call = datetime.now().replace(
hour=int(each_time_entry.split(':')[0]),
minute=int(each_time_entry.split(':')[1]))
is_next_day = True
if cr_time_list and not is_next_day:
hour=int(time_entry.split(':')[0]),
minute=int(time_entry.split(':')[1]),
second=0)
break
if not next_call:
next_call = datetime.now().replace(
hour=int(cr_time_list[0].split(':')[0]),
minute=int(cr_time_list[0].split(':')[1])) + timedelta(
days=1)
next_call_tz = timezone(self.env.context.get(
'tz') or self.env.user.tz).localize(next_call, is_dst=False)
minute=int(cr_time_list[0].split(':')[1]),
second=0) + timedelta(
days=0)
next_call_tz = timezone(self.env.context.get('tz') or
self.env.user.tz).localize(next_call,
is_dst=False)
next_call_utc = next_call_tz.astimezone(timezone('UTC'))
next_call_utc = datetime.strptime(
fields.Datetime.to_string(next_call_utc),
DEFAULT_SERVER_DATETIME_FORMAT)
backend_voicent.next_call = fields.Datetime.to_string(
next_call_utc)
class BackendVoicentTimeLine(models.Model):
_name = 'backend.voicent.time.line'
_description = 'Voicent Backend Time Line'
name = fields.Char(
string='Name',
required=True,
)
time = fields.Float(
string='Time',
copy=False,
)
backend_id = fields.Many2one(
string='Backend',
comodel_name='backend.voicent',
ondelete='set null',
)
class BackendVoicentCallLine(models.Model):
_name = 'backend.voicent.call.line'
_description = 'Voicent Backend Call Line'
name = fields.Char(
string='Name',
required=True,
)
applies_on = fields.Selection(
string='Applies on',
selection=[],
)
voicent_app = fields.Char(
string='Voicent App',
)
backend_id = fields.Many2one(
string='Backend',
comodel_name='backend.voicent',
ondelete='set null',
)
backend.next_call = fields.Datetime.to_string(next_call_utc)

109
connector_voicent/models/backend_voicent_call_line.py

@ -0,0 +1,109 @@
# Copyright (C) 2019 Open Source Integrators
# <https://www.opensourceintegrators.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
VOICENT_CONTACT_COLUMNS = [('First Name', 'First Name (Required)'),
('Last Name', 'Last Name'),
('Business', 'Business'),
('Phone', 'Phone (Required)'),
('Email', 'Email'),
('Category', 'Category'),
('Assigned To', 'Assigned To'),
('Contact Status', 'Contact Status'),
('Lead Source', 'Lead Source'),
('Other', 'Other')]
VOICENT_REPLY = [('availableagents', 'Available Agents'),
('callback', 'Callback'),
('campid', 'Campaign ID'),
('campname', 'Campaign Name'),
('campsize', 'Campaign Size'),
('connected', 'Connected'),
('dnc', 'Contact DNC'),
('nophone', 'Contact No Phone'),
('disc', 'Disc. Number'),
('dropped', 'Dropped'),
('failed', 'Failed'),
('fax', 'Fax'),
('info', 'Info'),
('in', 'Interested'),
('lines', 'Lines'),
('linebusy', 'Line Busy'),
('live', 'Live Answer'),
('machine', 'Machine Answer'),
('made', 'Made'),
('maxlines', 'Max Lines'),
('noact', 'No Activity'),
('noanswer', 'No Answer'),
('notin', 'Not Interested'),
('notes', 'Notes'),
('optout', 'Opt Out'),
('serverr', 'Service Error'),
('status', 'Status'),
('totalagents', 'Total Agents'),
('wit', 'Wit')]
MSGTYPE = [('audio', 'Audio'),
('ivr', 'IVR'),
('survey', 'Survey'),
('template', 'Template'),
('tts', 'Text-To-Speech')]
class BackendVoicentCallLine(models.Model):
_name = 'backend.voicent.call.line'
_description = 'Voicent Backend Call Line'
name = fields.Char(string='Name', required=True)
sequence = fields.Integer(string='Sequence', default=0)
applies_on = fields.Selection(string='Applies on', selection=[])
msgtype = fields.Selection(MSGTYPE, string='Message Type', required=True)
msginfo = fields.Char(string='Message Info')
backend_id = fields.Many2one(
string='Backend',
comodel_name='backend.voicent',
ondelete='set null')
reply_ids = fields.One2many('backend.voicent.call.line.reply', 'line_id',
string="Replies")
contact_ids = fields.One2many('backend.voicent.call.line.contact',
'line_id',
string="Contact Info")
class BackendVoicentCallLineContact(models.Model):
_name = 'backend.voicent.call.line.contact'
_description = 'Columns of the CSV file to provide the contact list'
_order = 'sequence'
name = fields.Selection(VOICENT_CONTACT_COLUMNS, string='Voicent Field',
required=True)
other = fields.Char(string='Other')
sequence = fields.Integer(string='Sequence', default=0)
field_domain = fields.Char(string='Odoo Field',
required=True)
default_value = fields.Char(string='Default Value', required=True)
line_id = fields.Many2one(
string='Call Line',
comodel_name='backend.voicent.call.line',
ondelete='set null')
class BackendVoicentCallLineReply(models.Model):
_name = 'backend.voicent.call.line.reply'
_description = 'Reply to a Voicent Call'
name = fields.Char(string='Name', required=True)
line_id = fields.Many2one(
string='Call Line',
comodel_name='backend.voicent.call.line',
ondelete='set null')
reply_field = fields.Selection(VOICENT_REPLY, string="Voicent Reply Field",
required=True)
reply_value = fields.Char(string="Voicent Reply Value", required=True)
action_id = fields.Many2one('ir.actions.server', string="Server Action",
required=True,
help="""If the Voicent reply field is equal to
the Voicent reply value, the server action is
executed.""")

18
connector_voicent/models/backend_voicent_time_line.py

@ -0,0 +1,18 @@
# Copyright (C) 2019 Open Source Integrators
# <https://www.opensourceintegrators.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class BackendVoicentTimeLine(models.Model):
_name = 'backend.voicent.time.line'
_description = 'Voicent Backend Time Line'
_order = 'time'
name = fields.Char(string='Name', required=True)
time = fields.Float(string='Time', copy=False)
backend_id = fields.Many2one(
string='Backend',
comodel_name='backend.voicent',
ondelete='set null')

17
connector_voicent/models/queue_job.py

@ -1,17 +0,0 @@
# Copyright (C) 2019 Open Source Integrators
# <https://www.opensourceintegrators.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class QueueJob(models.Model):
""" Job status and result """
_inherit = 'queue.job'
call_line_id = fields.Many2one(
'backend.voicent.call.line', 'Call Line',
)
voicent_campaign = fields.Text(
'Campaign ID',
)

4
connector_voicent/models/res_partner.py

@ -8,6 +8,4 @@ from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
can_call = fields.Boolean(
string='Accepts Calls',
)
can_call = fields.Boolean(string='Accepts Voicent Calls', default=True)

6
connector_voicent/readme/CONFIGURATION.rst

@ -0,0 +1,6 @@
#. Go to Settings > Users & Companies > Users
#. Select the filter "Inactive Users" only
#. Select the user "OdooBot"
#. Click on "Edit"
#. Go to the tab "Preferences"
#. Set the timezone

3
connector_voicent/readme/ROADMAP.rst

@ -0,0 +1,3 @@
* On the backend, replace the 'Applies On' selection list with a Many2one to ir.model.fields
* On the backend call line contact, use the domain widget to select the field
* Update the voicent library on Pypi with examples/voicent.py

4
connector_voicent/readme/USAGE.rst

@ -1,4 +1,6 @@
#. Go to Connectors > Backends > Voicent Backends
#. Create a new Voicent Backend with the host and port
#. Create a new Voicent Backend with the host, port, the caller ID and the number of lines
#. Create Call Lines to determine when (which stage in the process) calls are added to the queue
#. Create Contact Info to create the structure of the CSV file to send to Voicent
#. Create Replies to determine what to do based on the replies (see example below)
#. Create Time Line to determine when (what time) calls are made

8
connector_voicent/security/ir.model.access.csv

@ -1,4 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_backend_voicent,access_backend_voicent,model_backend_voicent,base.group_user,1,1,1,1
access_backend_voicent_call_line,access_backend_voicent_call_line,model_backend_voicent_call_line,base.group_user,1,1,1,1
access_backend_voicent_time_line,access_backend_voicent_time_line,model_backend_voicent_time_line,base.group_user,1,1,1,1
access_backend_voicent,access_backend_voicent,model_backend_voicent,connector.group_connector_manager,1,1,1,1
access_backend_voicent_call_line,access_backend_voicent_call_line,model_backend_voicent_call_line,connector.group_connector_manager,1,1,1,1
access_backend_voicent_call_line_reply,access_backend_voicent_call_line_reply,model_backend_voicent_call_line_reply,connector.group_connector_manager,1,1,1,1
access_backend_voicent_call_line_contact,access_backend_voicent_call_line_contact,model_backend_voicent_call_line_contact,connector.group_connector_manager,1,1,1,1
access_backend_voicent_time_line,access_backend_voicent_time_line,model_backend_voicent_time_line,connector.group_connector_manager,1,1,1,1

BIN
connector_voicent/static/description/icon.png

Before

Width: 128  |  Height: 128  |  Size: 9.2 KiB

After

Width: 210  |  Height: 76  |  Size: 22 KiB

13
connector_voicent/tests/test_backend_voicent.py

@ -10,15 +10,18 @@ class TestBackendVoicent(TransactionCase):
def setUp(self):
super(TestBackendVoicent, self).setUp()
self.backend_voicent_model = self.env['backend.voicent']
self.backend_voicent_id = self.backend_voicent_model.create(
{'host': 'localhost',
{'name': 'Test',
'host': 'localhost',
'port': '8155',
'is_active': True,
'callerid': '0000000000',
'line': '1',
'active': True,
'call_line_ids': [(0, 0,
{'name': 'call 1',
'applies_on': False,
'voicent_app': 'App'})],
'msgtype': 'tts',
'msginfo': 'Hello World!'})],
'time_line_ids': [(0, 0, {'name': 'Call Time 1',
'time': 10.0}),
(0, 0, {'name': 'Call Time 2',
@ -31,4 +34,4 @@ class TestBackendVoicent(TransactionCase):
def test_run_check_the_voicent_status(self):
"""To call the scheduler method."""
self.backend_voicent_id._run_check_the_voicent_status()
self.backend_voicent_id._run_update_next_call()

18
connector_voicent/view/queue_job_view.xml

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_queue_job_form_inherit_voicent" model="ir.ui.view">
<field name="name">queue.job.form.inherit.voicent</field>
<field name="model">queue.job</field>
<field name="inherit_id" ref="queue_job.view_queue_job_form"/>
<field name="arch" type="xml">
<xpath expr="//group[1]" position="after">
<group string="Connector Voicent">
<field name="call_line_id"/>
<field name="voicent_campaign"/>
</group>
</xpath>
</field>
</record>
</odoo>

47
connector_voicent/view/backend_voicent.xml → connector_voicent/views/backend_voicent.xml

@ -1,15 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="backend_voicent_tree_view" model="ir.ui.view">
<field name="name">backend.voicent.tree.view</field>
<field name="model">backend.voicent</field>
<field name="arch" type="xml">
<tree string="Voicent Backend">
<tree string="Voicent Backends">
<field name="name"/>
<field name="host"/>
<field name="port"/>
<field name="next_call"/>
<field name="is_active"/>
<field name="callerid"/>
<field name="line"/>
<field name="next_call" groups="base.group_no_one"/>
<field name="active"/>
</tree>
</field>
</record>
@ -20,18 +22,33 @@
<field name="arch" type="xml">
<form string="Voicent Backend">
<sheet>
<div class="oe_button_box" position="inside">
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
<field name="active" widget="boolean_button" options="{&quot;terminology&quot;: &quot;archive&quot;}"/>
</button>
</div>
<div class="oe_title">
<h1><field name="name" class="field_name" placeholder="Name of the backend..."/></h1>
</div>
<group>
<field name="host"/>
<field name="port"/>
<field name="is_active"/>
<group>
<field name="host"/>
<field name="port"/>
</group>
<group>
<field name="callerid"/>
<field name="line"/>
</group>
</group>
<notebook>
<page string="Call Lines">
<field name="call_line_ids">
<tree string="Call Lines" editable="top">
<tree string="Call Lines">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="applies_on"/>
<field name="voicent_app"/>
<field name="msgtype"/>
<field name="msginfo"/>
</tree>
</field>
</page>
@ -43,6 +60,14 @@
</tree>
</field>
</page>
<page string="Debug" groups="base.group_no_one">
<group>
<group id="debug-left">
<field name="next_call"/>
</group>
<group id="debug-right"/>
</group>
</page>
</notebook>
</sheet>
</form>
@ -56,7 +81,9 @@
<search string="Voicent Backend">
<field name="host"/>
<field name="port"/>
<field name="is_active"/>
<field name="callerid"/>
<filter string="Archived" name="inactive"
domain="[('active', '=', False)]"/>
</search>
</field>
</record>

76
connector_voicent/views/backend_voicent_call_line.xml

@ -0,0 +1,76 @@
<odoo>
<record id="backend_voicent_call_line_tree_view" model="ir.ui.view">
<field name="name">backend.voicent.call.line.tree.view</field>
<field name="model">backend.voicent.call.line</field>
<field name="arch" type="xml">
<tree string="Voicent Backend Call Lines">
<field name="name"/>
<field name="applies_on"/>
<field name="msgtype"/>
<field name="msginfo"/>
</tree>
</field>
</record>
<record id="backend_voicent_call_line_form_view" model="ir.ui.view">
<field name="name">backend.voicent.call.line.form.view</field>
<field name="model">backend.voicent.call.line</field>
<field name="arch" type="xml">
<form string="Voicent Backend Call Line">
<sheet>
<div class="oe_title">
<h1><field name="name" class="field_name" placeholder="Name of the call line..."/></h1>
</div>
<group>
<group id="main-left">
<field name="applies_on"/>
<field name="msgtype"/>
<field name="msginfo"/>
</group>
<group id="main-right">
</group>
</group>
<notebook>
<page string="Contact Info">
<field name="contact_ids">
<tree string="Contacts">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="other"/>
<field name="field_domain"/>
<field name="default_value"/>
</tree>
<form>
<field name="name"/>
<group>
<group>
<field name="other"/>
<field name="field_domain"
placeholder="partner_id.name or partner_id.phone"/>
</group>
<group>
<field name="sequence"/>
<field name="default_value"/>
</group>
</group>
</form>
</field>
</page>
<page string="Replies">
<field name="reply_ids">
<tree string="Replies" editable="top">
<field name="name"/>
<field name="reply_field" string="If"/>
<field name="reply_value" string="contains"/>
<field name="action_id" string="Then, execute"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
</odoo>

10
connector_voicent/view/res_partner.xml → connector_voicent/views/res_partner.xml

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_res_partner_form" model="ir.ui.view">
@ -6,11 +5,10 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//h1//field[@name='name']/.." position="after">
<group attrs="{'invisible': [('is_company', '=', True)]}">
<field name="can_call"/>
</group>
</xpath>
<field name="user_ids" position="before">
<field name="can_call"
attrs="{'invisible': [('is_company', '=', True)]}"/>
</field>
</field>
</record>
Loading…
Cancel
Save