feat: Se crea asistente para asignación de prospectos a operarios
This commit is contained in:
parent
1f52dcba26
commit
bc4833b3cf
@ -18,9 +18,10 @@ def register():
|
||||
prospect.ContactMethod,
|
||||
prospect.Prospect,
|
||||
prospect_trace.ProspectTrace,
|
||||
|
||||
prospect.AssignOperatorStart,
|
||||
module='sale_opportunity_management', type_='model')
|
||||
Pool.register(
|
||||
prospect.AssignOperator,
|
||||
module='sale_opportunity_management', type_='wizard')
|
||||
Pool.register(
|
||||
module='sale_opportunity_management', type_='report')
|
||||
|
39
prospect.py
39
prospect.py
@ -1,7 +1,9 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.wizard import Wizard, StateView, Button, StateTransition
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
from trytond.pyson import Eval, If
|
||||
from trytond.pool import Pool
|
||||
|
||||
|
||||
class Prospect(ModelSQL, ModelView):
|
||||
@ -41,6 +43,7 @@ class Prospect(ModelSQL, ModelView):
|
||||
self.state = 'assigned'
|
||||
else:
|
||||
self.state = 'unassigned'
|
||||
pass
|
||||
|
||||
|
||||
class ContactMethod(ModelSQL, ModelView):
|
||||
@ -72,3 +75,39 @@ class ContactMethod(ModelSQL, ModelView):
|
||||
contact_rec_name += ' [' + str(field) + '] '
|
||||
|
||||
return contact_rec_name
|
||||
|
||||
|
||||
class AssignOperatorStart(ModelView):
|
||||
'Inicio de asignación de operador'
|
||||
__name__ = 'sale.prospect.assign.start'
|
||||
|
||||
prospects_chunk = fields.Integer('Prospects chunk')
|
||||
operator = fields.Many2One('res.user', 'Operator')
|
||||
|
||||
|
||||
class AssignOperator(Wizard):
|
||||
'Asignar operador a prospecto'
|
||||
__name__ = 'sale.prospect.assign'
|
||||
|
||||
start = StateView(
|
||||
'sale.prospect.assign.start',
|
||||
'sale_opportunity_management.assign_start_view_form', [
|
||||
Button("Cancel", 'end', 'tryton-cancel'),
|
||||
Button("Assign", 'assign', 'tryton-ok', default=True)])
|
||||
|
||||
assign = StateTransition()
|
||||
|
||||
def transition_assign(self):
|
||||
pool = Pool()
|
||||
Prospect = pool.get('sale.prospect')
|
||||
|
||||
prospects = Prospect.search(
|
||||
[('state', '=', 'unassigned')],
|
||||
limit=self.start.prospects_chunk)
|
||||
|
||||
for prospect in prospects:
|
||||
prospect.assigned_operator = self.start.operator
|
||||
prospect.state = 'assigned'
|
||||
prospect.save()
|
||||
|
||||
return 'end'
|
||||
|
45
prospect.xml
45
prospect.xml
@ -7,7 +7,6 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="name">Prospects</field>
|
||||
<field name="res_model">sale.prospect</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="prospect_view_tree">
|
||||
<field name="model">sale.prospect</field>
|
||||
<field name="type">tree</field>
|
||||
@ -18,7 +17,6 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="type">form</field>
|
||||
<field name="name">prospect_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window.view" id="act_prospect_tree_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="prospect_view_tree"/>
|
||||
@ -29,19 +27,17 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="view" ref="prospect_view_form"/>
|
||||
<field name="act_window" ref="act_prospect_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_calls"
|
||||
sequence="10"
|
||||
id="menu_prospects_tree"
|
||||
action="act_prospect_tree"/>
|
||||
|
||||
<record model="ir.action.act_window" id="act_prospect_unassigned_tree">
|
||||
<record model="ir.action.act_window" id="act_prospect_unassigned_tree">
|
||||
<field name="name">Unassigned</field>
|
||||
<field name="res_model">sale.prospect</field>
|
||||
<field name="domain" eval="[('state', '=', 'unassigned')]" pyson="1"/>
|
||||
<field name="domain" eval="[('state', '=', 'unassigned')]" pyson="1"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="prospect_unassigned_view_tree">
|
||||
<field name="model">sale.prospect</field>
|
||||
<field name="type">tree</field>
|
||||
@ -52,7 +48,6 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="type">form</field>
|
||||
<field name="name">prospect_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window.view" id="act_prospect_unassigned_tree_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="prospect_unassigned_view_tree"/>
|
||||
@ -63,19 +58,17 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="view" ref="prospect_view_form"/>
|
||||
<field name="act_window" ref="act_prospect_unassigned_tree"/>
|
||||
</record>
|
||||
<menuitem
|
||||
parent="menu_prospects_tree"
|
||||
sequence="10"
|
||||
id="menu_prospects_unassigned_tree"
|
||||
action="act_prospect_unassigned_tree"/>
|
||||
|
||||
<menuitem
|
||||
parent="menu_prospects_tree"
|
||||
sequence="10"
|
||||
id="menu_prospects_unassigned_tree"
|
||||
action="act_prospect_unassigned_tree"/>
|
||||
|
||||
<record model="ir.action.act_window" id="act_prospect_assigned_tree">
|
||||
<record model="ir.action.act_window" id="act_prospect_assigned_tree">
|
||||
<field name="name">Assigned</field>
|
||||
<field name="res_model">sale.prospect</field>
|
||||
<field name="domain" eval="[('state', '=', 'assigned')]" pyson="1"/>
|
||||
<field name="domain" eval="[('state', '=', 'assigned')]" pyson="1"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="prospect_assigned_view_tree">
|
||||
<field name="model">sale.prospect</field>
|
||||
<field name="type">tree</field>
|
||||
@ -86,7 +79,6 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="type">form</field>
|
||||
<field name="name">prospect_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window.view" id="act_prospect_assigned_tree_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="prospect_assigned_view_tree"/>
|
||||
@ -97,18 +89,16 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="view" ref="prospect_view_form"/>
|
||||
<field name="act_window" ref="act_prospect_assigned_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_prospects_tree"
|
||||
sequence="10"
|
||||
id="menu_prospects_assigned_tree"
|
||||
action="act_prospect_assigned_tree"/>
|
||||
<menuitem
|
||||
parent="menu_prospects_tree"
|
||||
sequence="10"
|
||||
id="menu_prospects_assigned_tree"
|
||||
action="act_prospect_assigned_tree"/>
|
||||
|
||||
<record model="ir.action.act_window" id="act_contact_method_tree">
|
||||
<field name="name">Contact method</field>
|
||||
<field name="res_model">prospect.contact_method</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="contact_method_view_tree">
|
||||
<field name="model">prospect.contact_method</field>
|
||||
<field name="type">tree</field>
|
||||
@ -119,7 +109,6 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="type">form</field>
|
||||
<field name="name">contact_method_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window.view" id="act_contact_method_tree_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="contact_method_view_tree"/>
|
||||
@ -130,5 +119,11 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="view" ref="contact_method_view_form"/>
|
||||
<field name="act_window" ref="act_contact_method_tree"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="assign_start_view_form">
|
||||
<field name="model">sale.prospect.assign.start</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">assign_start_form</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
|
@ -42,50 +42,71 @@ El administrador deberá poder registrar los contactos de diferentes prospectos,
|
||||
|
||||
Crear prospecto::
|
||||
>>> Prospect = Model.get('sale.prospect')
|
||||
>>> prospect = Prospect()
|
||||
>>> prospect1 = Prospect()
|
||||
|
||||
>>> prospect.name = 'guchito S.A.S'
|
||||
>>> contact_method = prospect.contact_methods.new(value='31223425234', name='Roberto', job='Gerente R.H')
|
||||
>>> contact_method = prospect.contact_methods.new(contact_type='mobile', value='12345678910', name='Pancracia', job='Asistente administrativo')
|
||||
>>> contact_method = prospect.contact_methods.new(contact_type='mail', value='peralto@guchitos.org', name='Peralto', job='Administrador')
|
||||
>>> prospect1.name = 'guchito S.A.S'
|
||||
>>> contact_method = prospect1.contact_methods.new(value='31223425234', name='Roberto', job='Gerente R.H')
|
||||
>>> contact_method = prospect1.contact_methods.new(contact_type='mobile', value='12345678910', name='Pancracia', job='Asistente administrativo')
|
||||
>>> contact_method = prospect1.contact_methods.new(contact_type='mail', value='peralto@guchitos.org', name='Peralto', job='Administrador')
|
||||
|
||||
>>> City = Model.get('sale.city')
|
||||
>>> medellin, = City.find([('code', '=', 'CO-05001')])
|
||||
>>> prospect.city = medellin
|
||||
>>> prospect.save()
|
||||
>>> prospect1.city = medellin
|
||||
>>> prospect1.save()
|
||||
|
||||
Verificar estado final de creación de prospecto::
|
||||
>>> prospect.contact_methods
|
||||
>>> prospect1.contact_methods
|
||||
[proteus.Model.get('prospect.contact_method')(1), proteus.Model.get('prospect.contact_method')(2), proteus.Model.get('prospect.contact_method')(3)]
|
||||
>>> prospect.contact_methods[0].contact_type
|
||||
>>> prospect1.contact_methods[0].contact_type
|
||||
'mobile'
|
||||
>>> prospect.contact_methods[0].job
|
||||
>>> prospect1.contact_methods[0].job
|
||||
'Gerente R.H'
|
||||
>>> prospect.contact_methods[2].name
|
||||
>>> prospect1.contact_methods[2].name
|
||||
'Peralto'
|
||||
>>> prospect.contact_methods[2].value
|
||||
>>> prospect1.contact_methods[2].value
|
||||
'peralto@guchitos.org'
|
||||
|
||||
>>> prospect.city.code
|
||||
>>> prospect1.city.code
|
||||
'CO-05001'
|
||||
>>> prospect.department.code
|
||||
>>> prospect1.department.code
|
||||
'CO-05'
|
||||
>>> prospect.state
|
||||
>>> prospect1.state
|
||||
'unassigned'
|
||||
|
||||
Crear segundo prospecto::
|
||||
>>> prospect2 = Prospect()
|
||||
|
||||
>>> prospect2.name = 'Modernitus S.A.S'
|
||||
>>> contact_method = prospect2.contact_methods.new(value='3122390987', name='Pepe', job='Jefe de ventas')
|
||||
|
||||
>>> City = Model.get('sale.city')
|
||||
>>> bogota, = City.find([('code', '=', 'CO-11001')])
|
||||
>>> prospect2.city = bogota
|
||||
>>> prospect2.save()
|
||||
|
||||
Asignar operario a un prospecto::
|
||||
>>> User = Model.get('res.user')
|
||||
>>> user, = User.find([('name', '=', 'Administrator')])
|
||||
>>> prospect.assigned_operator = user
|
||||
|
||||
>>> prospect.assigned_operator.name
|
||||
.. >>> prospect1.assigned_operator = user
|
||||
|
||||
>>> assign = Wizard('sale.prospect.assign', [prospect1, prospect2])
|
||||
>>> assign.form.prospects_chunk = 2
|
||||
>>> assign.form.operator = user
|
||||
>>> assign.execute('assign')
|
||||
|
||||
>>> prospect1.assigned_operator.name
|
||||
'Administrator'
|
||||
>>> prospect.state
|
||||
>>> prospect1.state
|
||||
'assigned'
|
||||
>>> prospect2.assigned_operator.name
|
||||
'Administrator'
|
||||
>>> prospect2.state
|
||||
'assigned'
|
||||
|
||||
Remover operario asignado de un prospecto::
|
||||
>>> prospect.assigned_operator = None
|
||||
>>> prospect.state
|
||||
>>> prospect1.assigned_operator = None
|
||||
>>> prospect1.state
|
||||
'unassigned'
|
||||
|
||||
|
||||
@ -155,7 +176,7 @@ Crear seguimiento de prospecto::
|
||||
>>> ProspectTrace = Model.get('sale.prospect_trace')
|
||||
>>> prospect_trace = ProspectTrace()
|
||||
|
||||
>>> prospect_trace.prospect = prospect
|
||||
>>> prospect_trace.prospect = prospect1
|
||||
>>> prospect_trace.save()
|
||||
|
||||
>>> prospect_trace.prospect.name
|
||||
@ -215,10 +236,10 @@ Crear una llamada agendada previamente:
|
||||
'open'
|
||||
|
||||
Cuando se asigna prospecto sin método de contacto mobile, el contacto en el seguimiento es vacío::
|
||||
>>> prospect2 = Prospect()
|
||||
>>> prospect2.name = 'Sin celulares S.A.S'
|
||||
>>> contact_method = prospect2.contact_methods.new(contact_type='mail', value='felpucio@sincelulares.org', name='felpucio', job='Supervisor')
|
||||
>>> prospect2.save()
|
||||
>>> prospect3 = Prospect()
|
||||
>>> prospect3.name = 'Sin celulares S.A.S'
|
||||
>>> contact_method = prospect3.contact_methods.new(contact_type='mail', value='felpucio@sincelulares.org', name='felpucio', job='Supervisor')
|
||||
>>> prospect3.save()
|
||||
|
||||
>>> prospect_trace2 = ProspectTrace()
|
||||
>>> prospect_trace2.prospect = prospect2
|
||||
|
10
view/assign_start_form.xml
Normal file
10
view/assign_start_form.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="prospects_chunk"/>
|
||||
<field name="prospects_chunk"/>
|
||||
<newline/>
|
||||
<label name="operator"/>
|
||||
<field name="operator"/>
|
||||
</form>
|
Loading…
Reference in New Issue
Block a user