13 Commits

Author SHA1 Message Date
Rodia
a4fe42e15a Update tryton.cfg 2023-12-04 23:51:05 -05:00
d1ad40203b Merge pull request 'fix: al crear mecanismo de contacto desde prospecto no se actualiza correctamente en seguimiento de prospecto' (#77) from NoSeActualizaContactMethodEnProspectTrace_#76 into 6.8
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Se replica error en las pruebas y se soluciona con un on_change
2023-10-20 16:19:03 -05:00
9c368809f9 fix: al crear mecanismo de contacto desde prospecto no se actualiza correctamente en seguimiento de prospecto
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
2023-10-20 15:27:51 -05:00
e40991de02 feat: Se agregan dominios de vista de prospectos
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-22 10:39:10 -05:00
b8ba775733 chore(Tipificación del cliente): Se hacen traducciones
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-21 19:28:19 -05:00
336a266578 chore: Se hace visible rating en vista de arbol de prospectos
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-21 19:13:29 -05:00
22fb3736a7 chore(Agendación de tarea): Se agregan traducciones faltantes
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-21 19:08:24 -05:00
5cc7ef011d feat: Se agrega tipificación del cliente, closed #70
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-19 17:10:13 -05:00
72ae0cfa22 feat: Se hace posible agregar y modificar métodos de contactos desde seguimiento de prospectos, closed #72
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-19 15:56:21 -05:00
0b7d15f35b feat(Programación de tareas): Se agregan traducciones, #71
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-19 12:19:49 -05:00
8a0aa29368 feat: Se agregan estados a la vista de tareas pendientes, #71
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-19 11:57:29 -05:00
f71e6f4671 feat: Se implementa en las pruebas cierre de tarea pendientes
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-09-19 11:47:31 -05:00
cf874db55f chore(Task): se extrae clase a otro archivo, #71 2023-09-19 11:24:49 -05:00
14 changed files with 210 additions and 38 deletions

View File

@@ -14,8 +14,8 @@ def register():
Pool.register(
user.User,
pending_call.PendingCall,
pending_call.PendingTask,
call.Call,
call.PendingTask,
department.Department,
city.City,
prospect.ContactMethod,

43
call.py
View File

@@ -1,7 +1,6 @@
from trytond.model import ModelSQL, ModelView, fields
from trytond.pyson import Eval
from datetime import date
from .selections.interest import Interest
from .selections.call_types import CallTypes
from .selections.call_results import CallResults
@@ -47,3 +46,43 @@ class Call(ModelSQL, ModelView):
@classmethod
def default_date(cls):
return date.today()
class PendingTask(ModelSQL, ModelView):
'Tarea a realizar a un seguimiento de prospecto'
__name__ = "sale.pending_task"
description = fields.Text(
'Description', required=True,
states={
'readonly': Eval('state') == 'done'
})
state = fields.Selection(
[('pending', 'Pending'),
('done', 'Done')],
'State')
prospect_trace = fields.Many2One(
'sale.prospect_trace', 'Prospect trace',
required=True, readonly=True)
@classmethod
def __setup__(cls):
super(PendingTask, cls).__setup__()
cls._buttons.update({
'close_task': {
'invisible': Eval('state') == 'done'
}
})
@classmethod
@ModelView.button
def close_task(cls, tasks):
for task in tasks:
task.state = 'done'
task.save()
@classmethod
def default_state(cls):
return 'pending'

View File

@@ -99,11 +99,37 @@ this repository contains the full copyright notices and license terms. -->
<field name="view" ref="pending_task_view_form"/>
<field name="act_window" ref="act_pending_task_tree"/>
</record>
<record model="ir.action.act_window.domain" id="act_task_domain_pending">
<field name="name">Pending</field>
<field name="sequence" eval="10"/>
<field name="domain" eval="[('state', '=', 'pending')]" pyson="1"/>
<field name="count" eval="True"/>
<field name="act_window" ref="act_pending_task_tree"/>
</record>
<record model="ir.action.act_window.domain" id="act_task_domain_done">
<field name="name">Done</field>
<field name="sequence" eval="20"/>
<field name="domain" eval="[('state', '=', 'done')]" pyson="1"/>
<field name="count" eval="True"/>
<field name="act_window" ref="act_pending_task_tree"/>
</record>
<record model="ir.action.act_window.domain" id="act_task_domain_all">
<field name="name">All</field>
<field name="sequence" eval="9999"/>
<field name="domain"/>
<field name="count" eval="True"/>
<field name="act_window" ref="act_pending_task_tree"/>
</record>
<menuitem
parent="menu_calls"
sequence="60"
id="menu_pending_tasks"
action="act_pending_task_tree"
icon="tryton-graph"/>
<record model="ir.model.button" id="close_task_button">
<field name="name">close_task</field>
<field name="string">Close task</field>
<field name="model" search="[('model', '=', 'sale.pending_task')]"/>
</record>
</data>
</tryton>

View File

@@ -2,10 +2,6 @@
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:res.user,user_admin:"
msgid "Is Admin"
msgstr "Es Administrador"
msgctxt "model:res.group,name:group_prospect"
msgid "Prospects"
msgstr "Prospectos"
@@ -30,6 +26,10 @@ msgctxt "model:res.group,name:group_prospect_trace_admin"
msgid "Traces Administrator"
msgstr "Administración de Seguimientos"
msgctxt "field:res.user,user_admin:"
msgid "Is Admin"
msgstr "Es Administrador"
msgctxt "field:sale.prospect_trace,prospect:"
msgid "Prospect"
msgstr "Prospecto"
@@ -76,7 +76,11 @@ msgstr "Unidad de negocio"
msgctxt "view:sale.prospect:"
msgid "Contact methods"
msgstr "Metodos de contacto"
msgstr "Métodos de contacto"
msgctxt "view:sale.prospect:"
msgid "About prospect"
msgstr "Tipificación del prospecto"
msgctxt "field:sale.prospect,contact_methods:"
msgid "Contact methods"
@@ -102,6 +106,14 @@ msgctxt "field:sale.prospect,prospect_trace:"
msgid "Prospect trace"
msgstr "Seguimiento de prospecto"
msgctxt "field:sale.prospect,rating:"
msgid "Rating (1-5)"
msgstr "Calificación (1-5)"
msgctxt "field:sale.prospect,comments:"
msgid "Comments"
msgstr "Comentarios"
msgctxt "field:sale.call,date:"
msgid "Date"
msgstr "Fecha"
@@ -226,6 +238,21 @@ msgctxt "field:sale.prospect_trace.make_call.ask,datetime:"
msgid "Date time"
msgstr "Fecha y hora"
msgctxt "field:sale.pending_task,description:"
msgid "Description"
msgstr "Descripción"
msgctxt "field:sale.pending_task,prospect_trace:"
msgid "Prospect trace"
msgstr "Seguimiento de prospecto"
msgctxt "field:sale.prospect_trace.make_call.start,schedule_task:"
msgid "Schedule task?"
msgstr "¿Agendar tarea?"
msgctxt "field:sale.prospect_trace.make_call.ask_task,task_description:"
msgid "Task description"
msgstr "Descripción de la tarea"
msgctxt "selection:sale.prospect,business_unit:"
msgid "Brigade"
@@ -259,6 +286,10 @@ msgctxt "selection:prospect.contact_method,contact_type:"
msgid "Mail"
msgstr "Correo electrónico"
msgctxt "selection:sale.prospect,rating:"
msgid "None"
msgstr "Sin calificación"
msgctxt "selection:sale.prospect.assign.start,business_unit:"
msgid "Brigade"
msgstr "Brigada"
@@ -387,6 +418,11 @@ msgctxt "selection:sale.call,call_business_unit:"
msgid "Equipment"
msgstr "Equipos"
msgctxt "selection:sale.prospect_trace.make_call.start,schedule_task:"
msgid "Yes"
msgstr "Si"
msgctxt "model:ir.ui.menu,name:menu_calls"
msgid "Calls"
msgstr "Llamadas"
@@ -419,6 +455,10 @@ msgctxt "model:ir.ui.menu,name:menu_reassign_by_prospect_wizard"
msgid "Reassign by prospect"
msgstr "Reasignar por prospecto"
msgctxt "model:ir.ui.menu,name:menu_pending_tasks"
msgid "Pending tasks"
msgstr "Tareas pendientes"
msgctxt "model:ir.model.button,string:schedule_call_wizard_button"
msgid "Schedule call"
@@ -436,6 +476,10 @@ msgctxt "model:ir.model.button,string:reopen_trace_button"
msgid "Reopen trace"
msgstr "Reabrir seguimiento"
msgctxt "model:ir.model.button,string:close_task_button"
msgid "Close task"
msgstr "Cerrar tarea"
msgctxt "wizard_button:sale.prospect_trace.make_call,start,end:"
msgid "Cancel"
@@ -451,7 +495,7 @@ msgstr "Cancelar"
msgctxt "wizard_button:sale.prospect_trace.make_call,ask,schedule_call:"
msgid "Schedule call"
msgstr "Agendar"
msgstr "Agendar llamada"
msgctxt "wizard_button:sale.prospect_trace.schedule,start,end:"
msgid "Cancel"
@@ -459,7 +503,15 @@ msgstr "Cancelar"
msgctxt "wizard_button:sale.prospect_trace.schedule,start,schedule:"
msgid "Schedule"
msgstr "Agendar"
msgstr "Agendar llamada"
msgctxt "wizard_button:sale.prospect_trace.make_call,ask_task,end:"
msgid "Cancel"
msgstr "Cancelar"
msgctxt "wizard_button:sale.prospect_trace.make_call,ask_task,schedule_task:"
msgid "Schedule task"
msgstr "Agendar tarea"
msgctxt "wizard_button:sale.prospect.assign,start,end:"
msgid "Cancel"
@@ -513,6 +565,19 @@ msgctxt "model:ir.action.act_window.domain,name:act_prospect_domain_assigned"
msgid "Assigned"
msgstr "Asignado"
msgctxt "model:ir.action.act_window.domain,name:act_task_domain_pending"
msgid "Pending"
msgstr "Pendiente"
msgctxt "model:ir.action.act_window.domain,name:act_task_domain_done"
msgid "Done"
msgstr "Completado"
msgctxt "model:ir.action.act_window.domain,name:act_task_domain_all"
msgid "All"
msgstr "Todo"
msgctxt "model:ir.action,name:schedule_call_wizard"
msgid "Schedule call"
msgstr "Agendar llamada"

View File

@@ -12,18 +12,3 @@ class PendingCall(ModelSQL, ModelView):
def get_rec_name(self, name):
if self.date:
return str(self.date)
class PendingTask(ModelSQL, ModelView):
'Tarea pendiente a un seguimiento de prospecto'
__name__ = "sale.pending_task"
description = fields.Text('Description', required=True)
done = fields.Boolean('Done')
prospect_trace = fields.Many2One(
'sale.prospect_trace', 'Prospect trace',
required=True, readonly=True)
@classmethod
def default_done(cls):
return False

View File

@@ -1,12 +1,12 @@
# 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.model import ModelSQL, ModelView, fields, DeactivableMixin
from trytond.pyson import Eval, If
from trytond.pool import Pool
class Prospect(ModelSQL, ModelView):
class Prospect(ModelSQL, ModelView, DeactivableMixin):
'Prospecto'
__name__ = 'sale.prospect'
_rec_name = 'name'
@@ -38,10 +38,24 @@ class Prospect(ModelSQL, ModelView):
prospect_trace = fields.Many2One('sale.prospect_trace', 'Prospect trace')
rating = fields.Selection(
[(None, None),
('1', '1'),
('2', '2'),
('3', '3'),
('4', '4'),
('5', '5')], 'Rating (1-5)')
comments = fields.Text('Comments')
@classmethod
def default_state(cls):
return 'unassigned'
@fields.depends('prospect_trace', 'contact_methods')
def on_change_contact_methods(self):
for contact in self.contact_methods:
contact.prospect_trace = self.prospect_trace
@fields.depends('city', 'department')
def on_change_city(self):
if self.city:

View File

@@ -21,6 +21,9 @@ this repository contains the full copyright notices and license terms. -->
<record model="ir.action.act_window" id="act_prospect_tree">
<field name="name">Prospects</field>
<field name="domain"
eval="[If(Eval('context', {}).get('user_admin', None), (), ('assigned_operator', '=', Eval('_user')))]"
pyson="1"/>
<field name="res_model">sale.prospect</field>
</record>
<record model="ir.ui.view" id="prospect_view_tree">

View File

@@ -24,8 +24,8 @@ class ProspectTrace(ModelSQL, ModelView):
'Business unit', states=_states
)
prospect_contacts = fields.One2Many(
'prospect.contact_method', 'prospect_trace', 'Prospect contacts',
states=_states)
'prospect.contact_method', 'prospect_trace',
'Prospect contacts', required=True)
prospect_city = fields.Many2One('sale.city', 'City',
states=_states)
@@ -49,6 +49,11 @@ class ProspectTrace(ModelSQL, ModelView):
], 'State',
states=_states)
@fields.depends('prospect_contacts', 'prospect')
def on_change_prospect_contacts(self):
for contact in self.prospect_contacts:
contact.prospect = self.prospect
@classmethod
def __setup__(cls):
super(ProspectTrace, cls).__setup__()

View File

@@ -31,7 +31,7 @@ this repository contains the full copyright notices and license terms. -->
</record>
<record model="ir.action.act_window" id="act_prospect_trace_tree">
<field name="name">Prospect Traces</field>
<field name="domain"
<field name="domain"
eval="[If(Eval('context', {}).get('user_admin', None), (), ('prospect_assigned_operator', '=', Eval('_user')))]"
pyson="1"/>
<field name="res_model">sale.prospect_trace</field>

View File

@@ -95,6 +95,10 @@ Crear tercer prospecto::
>>> prospect3.business_unit = 'optics'
>>> prospect3.save()
Asignar tipificación a un prospecto
>>> prospect3.rating = '1'
>>> prospect3.comments = 'Calificación al cliente'
------------------------------------
Asignación de prospectos a operarios
------------------------------------
@@ -192,6 +196,11 @@ Verificar creación de seguimiento de prospecto::
>>> prospect_trace.prospect_contacts
[proteus.Model.get('prospect.contact_method')(1), proteus.Model.get('prospect.contact_method')(2), proteus.Model.get('prospect.contact_method')(3)]
Agregar un método de contacto desde el seguimiento de prospecto::
>>> contact_method_ = prospect_trace.prospect_contacts.new(value='31231231212', name='Carlos', job='Supervisor')
>>> contact_method_.prospect
proteus.Model.get('sale.prospect')(1)
Crear llamadas a un seguimiento de prospecto::
>>> make_call = Wizard('sale.prospect_trace.make_call', [prospect_trace])
@@ -265,7 +274,7 @@ Crear una llamada agendada previamente::
>>> prospect_trace.state
'open'
Hacer llamada y programar tarea
Hacer llamada y programar tarea::
>>> make_call = Wizard('sale.prospect_trace.make_call', [prospect_trace])
>>> make_call.form.description = 'Prospect told me to send him an email'
>>> make_call.form.interest = '3'
@@ -282,6 +291,13 @@ Hacer llamada y programar tarea
>>> task
proteus.Model.get('sale.pending_task')(1)
>>> task.state
'pending'
>>> task.click('close_task')
>>> task.state
'done'
Hacer llamada y cerrar venta (Seguimiento de prospecto)::
>>> make_call = Wizard('sale.prospect_trace.make_call', [prospect_trace])
>>> make_call.form.description = 'Closed sale'
@@ -349,8 +365,14 @@ Crear un usuario de rol administrador::
>>> admin.user_admin == True
True
Agregar un nuevo método de contacto desde prospecto
>>> contact_method = prospect1.contact_methods.new(value='0000000000', name='Nuevo', job='Puesto increíble')
>>> prospect1.save()
>>> prospect1.contact_methods[-1].value
'0000000000'
>>> prospect_trace.prospect_contacts[-1].value
'0000000000'
--------
Reportes

View File

@@ -1,5 +1,5 @@
[tryton]
version=6.8.0
version=7.0.0
depends:
ir
res

View File

@@ -4,4 +4,5 @@ this repository contains the full copyright notices and license terms. -->
<tree>
<field name="prospect_trace" expand="1"/>
<field name="description" expand="1"/>
<button name="close_task"/>
</tree>

View File

@@ -22,13 +22,24 @@ this repository contains the full copyright notices and license terms. -->
<page string="Contact methods" id="contact_methods">
<field name="contact_methods" colspan="2"/>
</page>
<page string="About prospect" id="contact_methods">
<label name="rating"/>
<field name="rating"/>
<newline/>
<label name="comments"/>
<field name="comments"/>
</page>
</notebook>
<newline/>
<group col="4" id="stated">
<label name="assigned_operator"/>
<field name="assigned_operator"/>
<label name="state"/>
<field name="state"/>
<group col="6" colspan="5" id="footer" yalign="0">
<label name="assigned_operator"/>
<field name="assigned_operator"/>
<label name="state"/>
<field name="state"/>
<group col="-1" colspan="1" id="checkboxes">
<label name="active"/>
<field name="active" xexpand="0" width="25"/>
</group>
</group>
</form>

View File

@@ -7,4 +7,5 @@ this repository contains the full copyright notices and license terms. -->
<field name="department" expand="1"/>
<field name="city" expand="1"/>
<field name="assigned_operator" expand="1"/>
<field name="rating" expand="1"/>
</tree>