From 8484c9fd74bb54acbf15cdcc438a40de2c4556c6 Mon Sep 17 00:00:00 2001 From: cubells Date: Wed, 5 Apr 2017 00:55:11 +0200 Subject: [PATCH] [MIG] crm_phone_call: Migrated to 10.0 (#138) * crm_phonecall module (#131) This module is the part extracted from Odoo v8 crm module from Odoo that allows to record phone calls. As it has been stripped off from Odoo v9, we add again the feature via this module. Migration scripts are also included to upgrade a v8 database via OpenUpgrade and don't lose your history. * [MIG] crm_phone_call: Migrated to 10.0 - FIX: Correct some lint errors * [MIG] crm_phone_call: Migrated to 10.0 --- crm_phonecall/README.rst | 59 ++ crm_phonecall/__init__.py | 7 + crm_phonecall/__manifest__.py | 27 + crm_phonecall/i18n/es.po | 707 ++++++++++++++++++ crm_phonecall/models/__init__.py | 7 + crm_phonecall/models/calendar.py | 15 + crm_phonecall/models/crm_phonecall.py | 276 +++++++ crm_phonecall/models/res_partner.py | 27 + crm_phonecall/report/__init__.py | 6 + crm_phonecall/report/crm_phonecall_report.py | 132 ++++ .../report/crm_phonecall_report_view.xml | 108 +++ crm_phonecall/security/crm_security.xml | 9 + crm_phonecall/security/ir.model.access.csv | 6 + crm_phonecall/static/description/icon.png | Bin 0 -> 9455 bytes crm_phonecall/tests/__init__.py | 6 + crm_phonecall/tests/test_crm_phonecall.py | 98 +++ crm_phonecall/views/crm_phonecall_view.xml | 317 ++++++++ crm_phonecall/views/res_partner_view.xml | 24 + crm_phonecall/wizard/__init__.py | 6 + .../wizard/crm_phonecall_to_phonecall.py | 94 +++ .../crm_phonecall_to_phonecall_view.xml | 35 + 21 files changed, 1966 insertions(+) create mode 100644 crm_phonecall/README.rst create mode 100644 crm_phonecall/__init__.py create mode 100644 crm_phonecall/__manifest__.py create mode 100644 crm_phonecall/i18n/es.po create mode 100644 crm_phonecall/models/__init__.py create mode 100644 crm_phonecall/models/calendar.py create mode 100644 crm_phonecall/models/crm_phonecall.py create mode 100644 crm_phonecall/models/res_partner.py create mode 100644 crm_phonecall/report/__init__.py create mode 100644 crm_phonecall/report/crm_phonecall_report.py create mode 100644 crm_phonecall/report/crm_phonecall_report_view.xml create mode 100644 crm_phonecall/security/crm_security.xml create mode 100644 crm_phonecall/security/ir.model.access.csv create mode 100644 crm_phonecall/static/description/icon.png create mode 100644 crm_phonecall/tests/__init__.py create mode 100644 crm_phonecall/tests/test_crm_phonecall.py create mode 100644 crm_phonecall/views/crm_phonecall_view.xml create mode 100644 crm_phonecall/views/res_partner_view.xml create mode 100644 crm_phonecall/wizard/__init__.py create mode 100644 crm_phonecall/wizard/crm_phonecall_to_phonecall.py create mode 100644 crm_phonecall/wizard/crm_phonecall_to_phonecall_view.xml diff --git a/crm_phonecall/README.rst b/crm_phonecall/README.rst new file mode 100644 index 00000000000..da5ba06f921 --- /dev/null +++ b/crm_phonecall/README.rst @@ -0,0 +1,59 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=============== +CRM phone calls +=============== + +* This module allows to manage phone calls in order to analyze them. + +Usage +===== + +To use this module, you need to: + +#. Go to *Sales > Phone Calls > Logged Calls > Create*. +#. If your user has *Show Scheduled Calls Menu* permission, you will see + scheduled calls menu too. +#. In any moment you can schedule another call, schedule a meeting or convert + call contact to opportunity. +#. Calls can be categorized and you can manage categories in *Sales > + Configuration > Leads & Opportunities > Phone Calls > Categories*. +#. Calls can be analyzed in *Sales > Reports > Phone Calls Analysis*. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/134/10.0 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smash it by providing detailed and welcomed +feedback. + +Credits +======= + +Contributors +------------ + +* Odoo S.A. +* Vicent Cubells + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/crm_phonecall/__init__.py b/crm_phonecall/__init__.py new file mode 100644 index 00000000000..f03a8710898 --- /dev/null +++ b/crm_phonecall/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models +from . import wizard +from . import report diff --git a/crm_phonecall/__manifest__.py b/crm_phonecall/__manifest__.py new file mode 100644 index 00000000000..ffdf6c70032 --- /dev/null +++ b/crm_phonecall/__manifest__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "CRM Phone Calls", + "version": "10.0.1.0.0", + "category": "Customer Relationship Management", + "author": "Odoo S.A., " + "Tecnativa, " + "Odoo Community Association (OCA)", + "website": "http://www.tecnativa.com", + "license": "AGPL-3", + "depends": [ + 'crm', + 'calendar', + ], + "data": [ + 'security/crm_security.xml', + 'security/ir.model.access.csv', + 'wizard/crm_phonecall_to_phonecall_view.xml', + 'views/crm_phonecall_view.xml', + 'views/res_partner_view.xml', + 'report/crm_phonecall_report_view.xml', + ], + 'installable': True, +} diff --git a/crm_phonecall/i18n/es.po b/crm_phonecall/i18n/es.po new file mode 100644 index 00000000000..bc81d359546 --- /dev/null +++ b/crm_phonecall/i18n/es.po @@ -0,0 +1,707 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * crm_phonecall +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-05-01 16:53+0000\n" +"PO-Revision-Date: 2017-05-01 16:53+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_nbr_cases +msgid "# of Cases" +msgstr "# de casos" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_form_view +msgid " min(s)" +msgstr " minuto(s)" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_form_view +msgid "Convert
To Opportunity
" +msgstr "Convertir
en oportunidad
" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_form_view +msgid "Schedule
A Meeting
" +msgstr "span>Planificar
una reunión" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_form_view +msgid "Schedule
Other Call
" +msgstr "Planificar
otra llamada
" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_action +msgid "Action" +msgstr "Acción" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_active +msgid "Active" +msgstr "Activa" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_user_id +msgid "Assign To" +msgstr "Asignar a" + +#. module: crm_phonecall +#: model:ir.filters,name:crm_phonecall.filter_crm_phonecall_sales_team +msgid "By Sales Team" +msgstr "Por equipo de ventas" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_name +msgid "Call Summary" +msgstr "Resumen de la llamada" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_name +msgid "Call summary" +msgstr "Resumen de la llamada" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_partners_form_crm_calls +msgid "Calls" +msgstr "Llamadas" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Calls Date by Month" +msgstr "Fechas de las llamadas por mes" + +#. module: crm_phonecall +#: selection:crm.phonecall,state:0 selection:crm.phonecall.report,state:0 +msgid "Cancelled" +msgstr "Cancelada" + +#. module: crm_phonecall +#: model:ir.ui.menu,name:crm_phonecall.menu_crm_case_phonecall-act +msgid "Categories" +msgstr "Categorias" + +#. module: crm_phonecall +#: model:ir.actions.act_window,help:crm_phonecall.crm_phonecall_categ_action +msgid "Click to add a new category." +msgstr "Pulse para añadir una categoría nueva" + +#. module: crm_phonecall +#: model:ir.actions.act_window,help:crm_phonecall.crm_case_categ_phone_incoming0 +msgid "Click to log the summary of a phone call." +msgstr "Pulse para registrar el resumen de una llamada." + +#. module: crm_phonecall +#: model:ir.actions.act_window,help:crm_phonecall.crm_case_categ_phone_outgoing0 +msgid "Click to schedule a call" +msgstr "Pulse para planificar una llamada" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_date_closed +msgid "Close Date" +msgstr "Fecha de cierre" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_date_closed +msgid "Closed" +msgstr "Cerrado" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_company_id +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_company_id +msgid "Company" +msgstr "Compañía" + +#. module: crm_phonecall +#: selection:crm.phonecall,state:0 +msgid "Confirmed" +msgstr "Confirmado" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_contact_name +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_partner_id +msgid "Contact" +msgstr "Contacto" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_form_view +msgid "Convert To Opportunity" +msgstr "Convertir en oportunidad" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_inbound_phone_tree_view +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_tree_view +msgid "Convert to Opportunity" +msgstr "Convertir en oportunidad" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_create_date +msgid "Create Date" +msgstr "Fecha de creación" + +#. module: crm_phonecall +#: model:ir.actions.act_window,help:crm_phonecall.crm_phonecall_categ_action +msgid "" +"Create specific phone call categories to better define the type of\n" +" calls tracked in the system." +msgstr "" +"Crear categorías específicas de llamadas para definir mejor el tipo\n" +" de las llamadas registradas en el sistema." + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_create_uid +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_create_date +msgid "Created on" +msgstr "Creado el" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Creation" +msgstr "Creación" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_create_date +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Creation Date" +msgstr "Fecha de creación" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Creation Month" +msgstr "Mes de creación" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Customer" +msgstr "Cliente" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_date +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_date +msgid "Date" +msgstr "Fecha" + +#. module: crm_phonecall +#: model:ir.filters,name:crm_phonecall.filter_crm_phonecall_delay_to_close +msgid "Delay To Close" +msgstr "Tiempo restante para el cierre" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_delay_close +msgid "Delay to close" +msgstr "Demora cierre" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_delay_open +msgid "Delay to open" +msgstr "Retraso de apertura" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_description +msgid "Description" +msgstr "Descripciòn" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_form_view +msgid "Description..." +msgstr "Descripción..." + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_display_name +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_display_name +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_display_name +msgid "Display Name" +msgstr "" + +#. module: crm_phonecall +#: selection:crm.phonecall.report,state:0 +msgid "Draft" +msgstr "Borrador" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_duration +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_duration +msgid "Duration" +msgstr "Duración" + +#. module: crm_phonecall +#: model:ir.model.fields,help:crm_phonecall.field_crm_phonecall_duration +msgid "Duration in minutes and seconds." +msgstr "Duración en minutos y segundos." + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_email_from +msgid "Email" +msgstr "Email" + +#. module: crm_phonecall +#: model:ir.model,name:crm_phonecall.model_calendar_event +msgid "Event" +msgstr "Evento" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Extended Filters..." +msgstr "Filtros extendidos..." + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Group By" +msgstr "Agrupar por" + +#. module: crm_phonecall +#: selection:crm.phonecall,state:0 selection:crm.phonecall.report,state:0 +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Held" +msgstr "Realizada" + +#. module: crm_phonecall +#: selection:crm.phonecall,priority:0 +#: selection:crm.phonecall.report,priority:0 +msgid "High" +msgstr "Alta" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_id +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_id +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_id +msgid "ID" +msgstr "Identificador" + +#. module: crm_phonecall +#: model:ir.actions.act_window,help:crm_phonecall.crm_case_categ_phone_incoming0 +msgid "" +"In order to follow up on the call, you can trigger a request for\n" +" another call, a meeting or an opportunity." +msgstr "" +"Para seguir una llamada, puede lanzar una petición para otra llamada,\n" +" una reunión o una oportunidad." + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_date_action_last +msgid "Last Action" +msgstr "Última acción" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall___last_update +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall___last_update +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report___last_update +msgid "Last Modified on" +msgstr "" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_write_uid +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_write_date +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_write_date +msgid "Last Updated on" +msgstr "" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_opportunity_id +msgid "Lead/Opportunity" +msgstr "Iniciativa/Oportunidad" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.phonecall_to_phonecall_view +msgid "Log Call" +msgstr "Registrar llamada" + +#. module: crm_phonecall +#: selection:crm.phonecall2phonecall,action:0 +msgid "Log a call" +msgstr "Registrar una llamada" + +#. module: crm_phonecall +#: model:ir.actions.act_window,name:crm_phonecall.crm_case_categ_phone_incoming0 +#: model:ir.ui.menu,name:crm_phonecall.menu_crm_case_phone_inbound +msgid "Logged Calls" +msgstr "Llamadas registradas" + +#. module: crm_phonecall +#: selection:crm.phonecall,priority:0 +#: selection:crm.phonecall.report,priority:0 +msgid "Low" +msgstr "Bajo" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_inbound_phone_tree_view +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_tree_view +msgid "Meeting" +msgstr "Reunión" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_partner_mobile +msgid "Mobile" +msgstr "Móvil" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Month" +msgstr "Mes" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Month of call" +msgstr "Mes de la llamada" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "My Phone Calls" +msgstr "Mis llamadas" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "My Phonecalls" +msgstr "Mis llamadas" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "My Sales Team(s)" +msgstr "Mis equipos de venta" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "My Team" +msgstr "Mi equipo" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "New Mail" +msgstr "Nuevo correo" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_date_action_next +msgid "Next Action" +msgstr "Siguiente acción" + +#. module: crm_phonecall +#: selection:crm.phonecall,priority:0 +#: selection:crm.phonecall.report,priority:0 +msgid "Normal" +msgstr "Normal" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Not Held" +msgstr "Pendiente" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_note +msgid "Note" +msgstr "Nota" + +#. module: crm_phonecall +#: model:ir.model.fields,help:crm_phonecall.field_crm_phonecall_report_delay_close +msgid "Number of Days to close the case" +msgstr "Número de días para cerrar el caso" + +#. module: crm_phonecall +#: model:ir.model.fields,help:crm_phonecall.field_crm_phonecall_report_delay_open +msgid "Number of Days to open the case" +msgstr "Número de días para abrir el caso" + +#. module: crm_phonecall +#: model:ir.actions.act_window,help:crm_phonecall.crm_case_categ_phone_outgoing0 +msgid "" +"Odoo allows you to easily define all the calls to be done\n" +" by your sales team and follow up based on their summary." +msgstr "" +"Odoo le permite definir fácilmente las llamadas a ser realizadas\n" +" por su equipo de ventas y seguirlas basadas en su resumen." + +#. module: crm_phonecall +#: model:ir.actions.act_window,help:crm_phonecall.crm_case_categ_phone_incoming0 +msgid "" +"Odoo allows you to log inbound calls on the fly to track the\n" +" history of the communication with a customer or to inform another\n" +" team member." +msgstr "" +"Odoo le permite registrar las llamadas entrantes sobre la marcha\n" +" para mantener el histórico de comunicación con un cliente o\n" +" informar a otro miembro del equipo." + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_date_open +msgid "Opened" +msgstr "Abierto" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_opening_date +msgid "Opening date" +msgstr "Fecha de apertura" + +#. module: crm_phonecall +#: model:ir.model,name:crm_phonecall.model_res_partner +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_partner_id +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_partner_id +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Partner" +msgstr "Cliente" + +#. module: crm_phonecall +#: selection:crm.phonecall,state:0 selection:crm.phonecall.report,state:0 +msgid "Pending" +msgstr "Pendiente" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_phone +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_partner_phone +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_form_view +msgid "Phone" +msgstr "Teléfono" + +#. module: crm_phonecall +#: code:addons/crm_phonecall/models/crm_phonecall.py:193 +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_form_view +#, python-format +msgid "Phone Call" +msgstr "Llamada" + +#. module: crm_phonecall +#: model:ir.actions.act_window,name:crm_phonecall.crm_case_categ_phone0 +#: model:ir.ui.menu,name:crm_phonecall.menu_crm_case_phone +#: model:ir.ui.menu,name:crm_phonecall.menu_crm_config_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_inbound_phone_tree_view +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_calendar_view +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_phone_tree_view +msgid "Phone Calls" +msgstr "Llamadas" + +#. module: crm_phonecall +#: model:ir.actions.act_window,name:crm_phonecall.crm_phonecall_report_action +#: model:ir.actions.act_window,name:crm_phonecall.crm_phonecall_report_action_team +#: model:ir.ui.menu,name:crm_phonecall.menu_report_crm_phonecalls_tree +msgid "Phone Calls Analysis" +msgstr "Análisis de llamadas" + +#. module: crm_phonecall +#: model:ir.filters,name:crm_phonecall.filter_crm_phonecall_phone_call_to_do +msgid "Phone Calls To Do" +msgstr "Llamadas por hacer" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Phone Calls that are assigned to me" +msgstr "Llamadas que están asignadas a mí" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_graph +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_pivot +msgid "Phone calls" +msgstr "Llamadas" + +#. module: crm_phonecall +#: model:ir.model,name:crm_phonecall.model_crm_phonecall_report +msgid "Phone calls by user" +msgstr "Llamadas por usuario" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Phone calls that are assigned to one of the sale teams I manage" +msgstr "" +"Las llamadas de teléfono están asignadas a uno de los equipos que yo " +"gestiono." + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Phone calls which are in closed state" +msgstr "Llamadas en estado cerrado" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Phone calls which are in draft and open state" +msgstr "Llamadas que están en estado borrador o abierto" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Phone calls which are in pending state" +msgstr "Llamadas con estado pendiente" + +#. module: crm_phonecall +#: model:ir.model,name:crm_phonecall.model_crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_calendar_event_phonecall_id +msgid "Phonecall" +msgstr "Llamada telefónica" + +#. module: crm_phonecall +#: model:ir.actions.act_window,name:crm_phonecall.crm_phonecall_categ_action +msgid "Phonecall Categories" +msgstr "Categorías de llamadas" + +#. module: crm_phonecall +#: model:ir.model,name:crm_phonecall.model_crm_phonecall2phonecall +msgid "Phonecall To Phonecall" +msgstr "Llamada telefónica a llamada telefónica" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_res_partner_phonecall_count +#: model:ir.model.fields,field_description:crm_phonecall.field_res_partner_phonecall_ids +#: model:ir.model.fields,field_description:crm_phonecall.field_res_users_phonecall_count +#: model:ir.model.fields,field_description:crm_phonecall.field_res_users_phonecall_ids +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Phonecalls" +msgstr "Llamadas telefónicas" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.phonecall_to_phonecall_view +msgid "Planned Date" +msgstr "Fecha planificada" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_priority +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_priority +msgid "Priority" +msgstr "Prioridad" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_user_id +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Responsible" +msgstr "Responsable" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_team_id +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_team_id +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Sales Team" +msgstr "Equipo de ventas" + +#. module: crm_phonecall +#: model:ir.model.fields,help:crm_phonecall.field_crm_phonecall_team_id +msgid "Sales team to which Case belongs to." +msgstr "Equipo de ventas al qual pertenece." + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Salesperson" +msgstr "Comercial" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.phonecall_to_phonecall_view +msgid "Schedule Call" +msgstr "Llamada planificada" + +#. module: crm_phonecall +#: model:ir.actions.act_window,name:crm_phonecall.phonecall_to_phonecall_act +#: model:ir.ui.view,arch_db:crm_phonecall.crm_case_inbound_phone_tree_view +msgid "Schedule Other Call" +msgstr "Planificar otra llamada" + +#. module: crm_phonecall +#: selection:crm.phonecall2phonecall,action:0 +msgid "Schedule a call" +msgstr "Planificar una llamada" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.phonecall_to_phonecall_view +msgid "Schedule/Log a Call" +msgstr "Planificar/registrar una llamada" + +#. module: crm_phonecall +#: model:ir.actions.act_window,name:crm_phonecall.crm_case_categ_phone_outgoing0 +#: model:ir.ui.menu,name:crm_phonecall.menu_crm_case_phone_outbound +msgid "Scheduled Calls" +msgstr "Llamadas planificadas" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Search" +msgstr "Buscar" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Search Phonecalls" +msgstr "Buscar llamadas telefónicas" + +#. module: crm_phonecall +#: model:res.groups,name:crm_phonecall.group_scheduled_calls +msgid "Show Scheduled Calls Menu" +msgstr "Mostrar el menú de llamadas programadas" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_state +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_state +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Status" +msgstr "Estado" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall2phonecall_tag_ids +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_tag_ids +msgid "Tags" +msgstr "Etiquetas" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_team_id +msgid "Team" +msgstr "Equipo" + +#. module: crm_phonecall +#: model:ir.model.fields,help:crm_phonecall.field_crm_phonecall_state +msgid "" +"The status is set to Confirmed, when a case is created.\n" +"When the call is over, the status is set to Held.\n" +"If the callis not applicable anymore, the status can be set to Cancelled." +msgstr "" +"El estado está establecido en Confirmado, cuando se crea un caso.\n" +"Cuando la llamada finaliza, el estado pasa a ser Retenido.\n" +"Si la llamada deja de ser aplicable, el estado pasará a ser Cancelado." + +#. module: crm_phonecall +#: model:ir.model.fields,help:crm_phonecall.field_crm_phonecall_email_from +msgid "These people will receive email." +msgstr "Estas personas recibirán un email." + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "To Do" +msgstr "Por hacer" + +#. module: crm_phonecall +#: selection:crm.phonecall.report,state:0 +#: model:ir.ui.view,arch_db:crm_phonecall.view_report_crm_phonecall_filter +msgid "Todo" +msgstr "Por hacer" + +#. module: crm_phonecall +#: model:ir.ui.view,arch_db:crm_phonecall.view_crm_case_phonecalls_filter +msgid "Unassigned" +msgstr "Sin asignar" + +#. module: crm_phonecall +#: model:ir.model.fields,field_description:crm_phonecall.field_crm_phonecall_report_user_id +msgid "User" +msgstr "Usuario" + +#. module: crm_phonecall +#: model:ir.actions.act_window,help:crm_phonecall.crm_case_categ_phone_outgoing0 +msgid "" +"You can use the import feature to massively import a new list of\n" +" prospects to qualify." +msgstr "" +"Puede usar la característica de importación para importar\n" +" masivamente una nueva lista de prospectos a calificar." diff --git a/crm_phonecall/models/__init__.py b/crm_phonecall/models/__init__.py new file mode 100644 index 00000000000..f5da41c1d14 --- /dev/null +++ b/crm_phonecall/models/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import crm_phonecall +from . import calendar +from . import res_partner diff --git a/crm_phonecall/models/calendar.py b/crm_phonecall/models/calendar.py new file mode 100644 index 00000000000..8632916b4a8 --- /dev/null +++ b/crm_phonecall/models/calendar.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2004-today OpenERP SA () +# Copyright (C) 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class CalendarEvent(models.Model): + _inherit = "calendar.event" + + phonecall_id = fields.Many2one( + comodel_name='crm.phonecall', + string='Phonecall', + ) diff --git a/crm_phonecall/models/crm_phonecall.py b/crm_phonecall/models/crm_phonecall.py new file mode 100644 index 00000000000..5df8ab80d1b --- /dev/null +++ b/crm_phonecall/models/crm_phonecall.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2004-today OpenERP SA () +# Copyright (C) 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from datetime import datetime +from odoo import api, fields, models, _ +from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT + + +class CrmPhonecall(models.Model): + """ Model for CRM phonecalls """ + _name = "crm.phonecall" + _description = "Phonecall" + _order = "id desc" + _inherit = ['mail.thread'] + + date_action_last = fields.Datetime( + string='Last Action', + readonly=True, + ) + date_action_next = fields.Datetime( + string='Next Action', + readonly=True, + ) + create_date = fields.Datetime( + string='Creation Date', + readonly=True, + ) + team_id = fields.Many2one( + comodel_name='crm.team', + string='Sales Team', + index=True, + help='Sales team to which Case belongs to.' + ) + user_id = fields.Many2one( + comodel_name='res.users', + string='Responsible', + default=lambda self: self.env.user, + ) + partner_id = fields.Many2one( + comodel_name='res.partner', + string='Contact', + ) + company_id = fields.Many2one( + comodel_name='res.company', + string='Company', + ) + description = fields.Text() + state = fields.Selection( + [('open', 'Confirmed'), + ('cancel', 'Cancelled'), + ('pending', 'Pending'), + ('done', 'Held') + ], + string='Status', + readonly=True, + track_visibility='onchange', + default='open', + help='The status is set to Confirmed, when a case is created.\n' + 'When the call is over, the status is set to Held.\n' + 'If the callis not applicable anymore, the status can be set ' + 'to Cancelled.') + email_from = fields.Char( + string='Email', + help="These people will receive email.") + date_open = fields.Datetime( + string='Opened', + readonly=True, + ) + name = fields.Char( + string='Call Summary', + required=True, + ) + active = fields.Boolean( + required=False, + default=True, + ) + duration = fields.Float(help='Duration in minutes and seconds.') + tag_ids = fields.Many2many( + comodel_name='crm.lead.tag', + relation='crm_phonecall_tag_rel', + column1='phone_id', + column2='tag_id', + string='Tags', + ) + partner_phone = fields.Char(string='Phone') + partner_mobile = fields.Char('Mobile') + priority = fields.Selection( + selection=[ + ('0', 'Low'), + ('1', 'Normal'), + ('2', 'High') + ], + string='Priority', + default='1', + ) + date_closed = fields.Datetime( + string='Closed', + readonly=True, + ) + date = fields.Datetime(default=fields.Datetime.now) + opportunity_id = fields.Many2one( + comodel_name='crm.lead', + string='Lead/Opportunity', + ) + + @api.onchange('partner_id') + def on_change_partner_id(self): + if self.partner_id: + self.partner_phone = self.partner_id.phone + self.partner_mobile = self.partner_id.mobile + + @api.multi + def write(self, values): + """ Override to add case management: open/close dates """ + if values.get('state'): + if values.get('state') == 'done': + values['date_closed'] = fields.datetime.now() + self.compute_duration() + elif values.get('state') == 'open': + values['date_open'] = fields.datetime.now() + values['duration'] = 0.0 + return super(CrmPhonecall, self).write(values) + + @api.multi + def compute_duration(self): + for phonecall in self: + if phonecall.duration <= 0: + duration = datetime.now() - datetime.strptime( + phonecall.date, DEFAULT_SERVER_DATETIME_FORMAT) + values = {'duration': duration.seconds / 60.0} + phonecall.write(values) + return True + + @api.multi + def schedule_another_phonecall(self, schedule_time, call_summary, + user_id=False, team_id=False, + tag_ids=False, action='schedule'): + """ + action :('schedule','Schedule a call'), ('log','Log a call') + """ + phonecall_dict = {} + for call in self: + if not team_id: + team_id = call.team_id.id or False + if not user_id: + user_id = call.user_id.id or False + if not schedule_time: + schedule_time = call.date + values = { + 'name': call_summary, + 'user_id': user_id or False, + 'description': call.description or False, + 'date': schedule_time, + 'team_id': team_id or False, + 'partner_id': call.partner_id.id or False, + 'partner_phone': call.partner_phone, + 'partner_mobile': call.partner_mobile, + 'priority': call.priority, + 'opportunity_id': call.opportunity_id.id or False, + } + if tag_ids: + values.update({'tag_ids': [(6, 0, [tag_ids])]}) + new_id = self.create(values) + if action == 'log': + call.write({'state': 'done'}) + phonecall_dict[call.id] = new_id + return phonecall_dict + + @api.onchange('opportunity_id') + def on_change_opportunity(self): + if self.opportunity_id: + self.team_id = self.opportunity_id.team_id.id + self.partner_phone = self.opportunity_id.phone + self.partner_mobile = self.opportunity_id.mobile + self.partner_id = self.opportunity_id.partner_id.id + self.tag_ids = self.opportunity_id.tag_ids.ids + + @api.multi + def redirect_phonecall_view(self): + model_data = self.env['ir.model.data'] + # Select the view + tree_view = model_data.get_object_reference( + 'crm_phonecall', 'crm_case_phone_tree_view') + form_view = model_data.get_object_reference( + 'crm_phonecall', 'crm_case_phone_form_view') + search_view = model_data.get_object_reference( + 'crm_phonecall', 'view_crm_case_phonecalls_filter') + value = {} + for call in self: + value = { + 'name': _('Phone Call'), + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'crm.phonecall', + 'res_id': call.id, + 'views': [ + (form_view and form_view[1] or False, 'form'), + (tree_view and tree_view[1] or False, 'tree'), + (False, 'calendar')], + 'type': 'ir.actions.act_window', + 'search_view_id': search_view and search_view[1] or False, + } + return value + + @api.multi + def convert_opportunity(self, opportunity_summary=False, partner_id=False, + planned_revenue=0.0, probability=0.0): + partner = self.env['res.partner'] + opportunity = self.env['crm.lead'] + opportunity_dict = {} + default_contact = False + for call in self: + if not partner_id: + partner_id = call.partner_id.id or False + if partner_id: + address_id = partner.address_get().get('contact', False) + if address_id: + default_contact = address_id.id + opportunity_id = opportunity.create({ + 'name': opportunity_summary or call.name, + 'planned_revenue': planned_revenue, + 'probability': probability, + 'partner_id': partner_id or False, + 'mobile': default_contact and default_contact.mobile, + 'team_id': call.team_id.id or False, + 'description': call.description or False, + 'priority': call.priority, + 'type': 'opportunity', + 'phone': call.partner_phone or False, + 'email_from': default_contact and default_contact.email, + 'tag_ids': [(6, 0, call.tag_ids.ids)], + }) + vals = { + 'partner_id': partner_id, + 'opportunity_id': opportunity_id.id, + 'state': 'done', + } + call.write(vals) + opportunity_dict[call.id] = opportunity_id + return opportunity_dict + + @api.multi + def action_make_meeting(self): + """ + Open meeting's calendar view to schedule a meeting on current + phonecall. + """ + partner_ids = [ + self.env['res.users'].browse(self.env.uid).partner_id.id] + res = {} + for phonecall in self: + if phonecall.partner_id and phonecall.partner_id.email: + partner_ids.append(phonecall.partner_id.id) + res = self.env['ir.actions.act_window'].for_xml_id( + 'calendar', 'action_calendar_event') + res['context'] = { + 'default_phonecall_id': phonecall.id, + 'default_partner_ids': partner_ids, + 'default_user_id': self.env.uid, + 'default_email_from': phonecall.email_from, + 'default_name': phonecall.name, + } + return res + + @api.multi + def action_button_convert2opportunity(self): + """ + Convert a phonecall into an opp and then redirect to the opp view. + """ + opportunity_dict = {} + for call in self: + opportunity_dict = call.convert_opportunity() + return opportunity_dict[call.id].redirect_opportunity_view() + return opportunity_dict diff --git a/crm_phonecall/models/res_partner.py b/crm_phonecall/models/res_partner.py new file mode 100644 index 00000000000..c91d90ec01e --- /dev/null +++ b/crm_phonecall/models/res_partner.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2004-today OpenERP SA () +# Copyright (C) 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + phonecall_ids = fields.One2many( + comodel_name='crm.phonecall', + inverse_name='partner_id', + string='Phonecalls', + ) + phonecall_count = fields.Integer( + compute='_compute_phonecall_count', + string="Phonecalls", + ) + + @api.multi + def _compute_phonecall_count(self): + for partner in self: + partner.phonecall_count = self.env[ + 'crm.phonecall'].search_count( + [('partner_id', '=', partner.id)]) diff --git a/crm_phonecall/report/__init__.py b/crm_phonecall/report/__init__.py new file mode 100644 index 00000000000..929bbda3d75 --- /dev/null +++ b/crm_phonecall/report/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Copyright 2004-2010 Tiny SPRL () +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import crm_phonecall_report diff --git a/crm_phonecall/report/crm_phonecall_report.py b/crm_phonecall/report/crm_phonecall_report.py new file mode 100644 index 00000000000..c62b4c06aef --- /dev/null +++ b/crm_phonecall/report/crm_phonecall_report.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# Copyright 2004-2010 Tiny SPRL () +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import tools +from odoo import api, fields, models + +AVAILABLE_STATES = [ + ('draft', 'Draft'), + ('open', 'Todo'), + ('cancel', 'Cancelled'), + ('done', 'Held'), + ('pending', 'Pending') +] + + +class CrmPhonecallReport(models.Model): + _name = "crm.phonecall.report" + _description = "Phone calls by user" + _auto = False + + user_id = fields.Many2one( + comodel_name='res.users', + string='User', + readonly=True, + ) + team_id = fields.Many2one( + comodel_name='crm.team', + string='Team', + readonly=True, + ) + priority = fields.Selection( + selection=[ + ('0', 'Low'), + ('1', 'Normal'), + ('2', 'High') + ], + string='Priority', + ) + nbr_cases = fields.Integer( + string='# of Cases', + readonly=True, + ) + state = fields.Selection( + AVAILABLE_STATES, + string='Status', + readonly=True, + ) + create_date = fields.Datetime( + string='Create Date', + readonly=True, + index=True, + ) + delay_close = fields.Float( + string='Delay to close', + digits=(16, 2), + readonly=True, + group_operator="avg", + help="Number of Days to close the case", + ) + duration = fields.Float( + string='Duration', + digits=(16, 2), + readonly=True, + group_operator="avg", + ) + delay_open = fields.Float( + string='Delay to open', + digits=(16, 2), + readonly=True, + group_operator="avg", + help="Number of Days to open the case", + ) + partner_id = fields.Many2one( + comodel_name='res.partner', + string='Partner', + readonly=True, + ) + company_id = fields.Many2one( + comodel_name='res.company', + string='Company', + readonly=True, + ) + opening_date = fields.Datetime( + readonly=True, + index=True, + ) + date_closed = fields.Datetime( + string='Close Date', + readonly=True, + index=True) + + def _select(self): + select_str = """ + select + id, + c.date_open as opening_date, + c.date_closed as date_closed, + c.state, + c.user_id, + c.team_id, + c.partner_id, + c.duration, + c.company_id, + c.priority, + 1 as nbr_cases, + c.create_date as create_date, + extract( + 'epoch' from ( + c.date_closed-c.create_date))/(3600*24) as delay_close, + extract( + 'epoch' from ( + c.date_open-c.create_date))/(3600*24) as delay_open + """ + return select_str + + def _from(self): + from_str = """ + from crm_phonecall c + """ + return from_str + + @api.model_cr + def init(self): + + tools.drop_view_if_exists(self._cr, self._table) + self._cr.execute(""" + create or replace view %s as ( + %s + %s + )""" % (self._table, self._select(), self._from())) diff --git a/crm_phonecall/report/crm_phonecall_report_view.xml b/crm_phonecall/report/crm_phonecall_report_view.xml new file mode 100644 index 00000000000..c5d907b03a3 --- /dev/null +++ b/crm_phonecall/report/crm_phonecall_report_view.xml @@ -0,0 +1,108 @@ + + + + + crm.phonecall.report.graph + crm.phonecall.report + + + + + + + + + + + crm.phonecall.report.pivot + crm.phonecall.report + + + + + + + + + + + + By Sales Team + crm.phonecall.report + [('state','=','done')] + + {'group_by': ['team_id'], 'col_group_by': [], 'measures': ['nbr_cases', 'duration']} + + + Delay To Close + crm.phonecall.report + [('state','=','done')] + + {'group_by': ['team_id'], 'col_group_by': [], 'measures': ['delay_close']} + + + Phone Calls To Do + crm.phonecall.report + [('state','in',('draft','open'))] + + {'group_by': ['team_id'], 'measures': ['nbr_cases']} + + + + crm.phonecall.report.select + crm.phonecall.report + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Phone Calls Analysis + crm.phonecall.report + form + pivot,graph + {} + [] + + + Phone Calls Analysis + crm.phonecall.report + form + pivot,graph + {'search_default_team_id': active_id} + [] + + + + diff --git a/crm_phonecall/security/crm_security.xml b/crm_phonecall/security/crm_security.xml new file mode 100644 index 00000000000..cf05858edd5 --- /dev/null +++ b/crm_phonecall/security/crm_security.xml @@ -0,0 +1,9 @@ + + + + + Show Scheduled Calls Menu + + + + diff --git a/crm_phonecall/security/ir.model.access.csv b/crm_phonecall/security/ir.model.access.csv new file mode 100644 index 00000000000..409d841f452 --- /dev/null +++ b/crm_phonecall/security/ir.model.access.csv @@ -0,0 +1,6 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,sales_team.group_sale_manager,1,1,1,1 +access_crm_phonecall,crm.phonecall,model_crm_phonecall,sales_team.group_sale_salesman,1,1,1,0 +access_crm_phonecall_report_user,crm.phonecall.report.user,model_crm_phonecall_report,sales_team.group_sale_salesman,1,0,0,0 +access_crm_phonecall_report_manager,crm.phonecall.report,model_crm_phonecall_report,sales_team.group_sale_manager,1,1,1,1 +access_crm_phonecall_partner_manager,crm.phonecall.partner.manager,model_crm_phonecall,base.group_partner_manager,1,1,1,1 diff --git a/crm_phonecall/static/description/icon.png b/crm_phonecall/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/crm_phonecall/tests/__init__.py b/crm_phonecall/tests/__init__.py new file mode 100644 index 00000000000..515aa00930b --- /dev/null +++ b/crm_phonecall/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Copyright 2004-2010 Tiny SPRL () +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_crm_phonecall diff --git a/crm_phonecall/tests/test_crm_phonecall.py b/crm_phonecall/tests/test_crm_phonecall.py new file mode 100644 index 00000000000..e371b4f35d9 --- /dev/null +++ b/crm_phonecall/tests/test_crm_phonecall.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.tests import common + + +class TestCrmPhoneCall(common.SavepointCase): + @classmethod + def setUpClass(cls): + super(TestCrmPhoneCall, cls).setUpClass() + cls.company = cls.env.ref('base.main_company') + partner_obj = cls.env['res.partner'] + cls.partner1 = partner_obj.create({ + 'name': 'Partner1', + 'phone': '123 456 789', + 'mobile': '123 456 789', + 'type': 'contact', + }) + cls.partner2 = partner_obj.create({ + 'name': 'Partner2', + 'phone': '789 654 321', + 'mobile': '789 654 321', + }) + cls.phonecall1 = cls.env['crm.phonecall'].create({ + 'name': 'Call #1 for test', + 'partner_id': cls.partner1.id, + }) + cls.opportunity1 = cls.env['crm.lead'].create({ + 'name': 'Opportunity #1', + 'phone': '12345', + 'mobile': '6789', + 'partner_id': cls.partner1.id, + }) + cls.opportunity2 = cls.env['crm.lead'].create({ + 'name': 'Opportunity #2', + 'phone': '2222', + 'mobile': '3333', + 'partner_id': cls.partner2.id, + }) + cls.tag = cls.env.ref('crm.categ_oppor1') + + def test_on_change_partner(self): + self.phonecall1.partner_id = self.partner2 + self.phonecall1.on_change_partner_id() + self.assertEqual(self.phonecall1.partner_phone, self.partner2.phone) + self.assertEqual(self.phonecall1.partner_mobile, self.partner2.mobile) + + self.assertFalse(self.phonecall1.date_closed) + self.phonecall1.state = 'done' + self.assertTrue(self.phonecall1.date_closed) + self.phonecall1.state = 'open' + self.assertEqual(self.phonecall1.duration, 0.0) + + def test_schedule_another_phonecall(self): + self.phonecall2 = self.phonecall1.schedule_another_phonecall( + schedule_time=False, + call_summary='Test schedule method', + action='schedule', + tag_ids=self.tag.id, + )[self.phonecall1.id] + self.assertEqual(self.phonecall2.id, self.phonecall1.id + 1) + self.assertEqual(self.phonecall1.state, 'open') + self.phonecall3 = self.phonecall1.schedule_another_phonecall( + schedule_time='2017-12-31 00:00:00', + call_summary='Test schedule method2', + action='log', + )[self.phonecall1.id] + self.assertEqual(self.phonecall3.id, self.phonecall1.id + 2) + self.assertEqual(self.phonecall1.state, 'done') + + result = self.phonecall2.redirect_phonecall_view() + self.assertEqual(result['res_id'], self.phonecall2.id) + + def test_on_change_opportunity(self): + self.phonecall1.opportunity_id = self.opportunity1 + self.phonecall1.on_change_opportunity() + self.assertEqual( + self.phonecall1.partner_phone, self.opportunity1.phone) + + def test_convert2opportunity(self): + result = self.phonecall1.action_button_convert2opportunity() + self.assertEqual(result['res_model'], 'crm.lead') + + def test_make_meeting(self): + result = self.phonecall1.action_make_meeting() + self.assertEqual( + result['context']['default_phonecall_id'], self.phonecall1.id) + + def test_wizard(self): + model_data = self.env['ir.model.data'] + wizard = self.env['crm.phonecall2phonecall'].with_context( + active_ids=self.phonecall1.ids, active_id=self.phonecall1.id, + ).create({}) + result = wizard.action_schedule() + search_view = model_data.get_object_reference( + 'crm_phonecall', 'view_crm_case_phonecalls_filter') + self.assertEqual(result['search_view_id'], search_view[1]) diff --git a/crm_phonecall/views/crm_phonecall_view.xml b/crm_phonecall/views/crm_phonecall_view.xml new file mode 100644 index 00000000000..8aa5ba7d2aa --- /dev/null +++ b/crm_phonecall/views/crm_phonecall_view.xml @@ -0,0 +1,317 @@ + + + + + Phonecall Categories + crm.lead.tag + form + + [] + + +

+ Click to add a new category. +

+ Create specific phone call categories to better define the type of + calls tracked in the system. +

+
+
+ + + + + CRM - Phone Calls Tree + crm.phonecall + + + + + + + + + +
+
+
+

+
+
+

+
+ + + + + + + +
+ + +
+ +
+
+ + + CRM - Logged Phone Calls Tree + crm.phonecall + + + + + + + + + + + + + + + + + + +
diff --git a/crm_phonecall/wizard/__init__.py b/crm_phonecall/wizard/__init__.py new file mode 100644 index 00000000000..3e208a9eb0f --- /dev/null +++ b/crm_phonecall/wizard/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Copyright 2004-2010 Tiny SPRL () +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import crm_phonecall_to_phonecall diff --git a/crm_phonecall/wizard/crm_phonecall_to_phonecall.py b/crm_phonecall/wizard/crm_phonecall_to_phonecall.py new file mode 100644 index 00000000000..bc73e8b2547 --- /dev/null +++ b/crm_phonecall/wizard/crm_phonecall_to_phonecall.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# Copyright 2004-2010 Tiny SPRL () +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + +import time + + +class CrmPhonecall2phonecall(models.TransientModel): + _name = 'crm.phonecall2phonecall' + _description = 'Phonecall To Phonecall' + + name = fields.Char( + string='Call summary', + required=True, + index=True, + ) + user_id = fields.Many2one( + comodel_name='res.users', + string="Assign To", + ) + contact_name = fields.Char( + string='Contact', + ) + phone = fields.Char() + tag_ids = fields.Many2many( + comodel_name='crm.lead.tag', + relation='crm_phonecall_tag_rel', + column1='phone_id', + column2='tag_id', + string='Tags', + ) + date = fields.Datetime() + team_id = fields.Many2one( + comodel_name='crm.team', + string='Sales Team' + ) + action = fields.Selection( + selection=[ + ('schedule', 'Schedule a call'), + ('log', 'Log a call') + ], + string='Action', + required=True, + ) + partner_id = fields.Many2one( + comodel_name='res.partner', + string="Partner", + ) + note = fields.Text() + + @api.multi + def action_schedule(self): + phonecall_obj = self.env['crm.phonecall'] + phonecalls = phonecall_obj.browse(self._context.get('active_ids', [])) + for this in self: + phonecalls.schedule_another_phonecall( + this.date, + this.name, + this.user_id.id, + this.team_id.id or False, + this.tag_ids.ids, + action=this.action, + ) + + return phonecalls.redirect_phonecall_view() + + @api.model + def default_get(self, fields): + """ + This function gets default values + + """ + res = super(CrmPhonecall2phonecall, self).default_get(fields) + res.update({ + 'action': 'schedule', + 'date': time.strftime('%Y-%m-%d %H:%M:%S') + }) + for phonecall in self.env['crm.phonecall'].browse( + self.env.context.get('active_id')): + if 'tag_ids' in fields: + res.update({'tag_ids': phonecall.tag_ids.ids}) + if 'user_id' in fields: + res.update({'user_id': phonecall.user_id.id}) + if 'team_id' in fields: + res.update({'team_id': phonecall.team_id.id}) + if 'partner_id' in fields: + res.update({'partner_id': phonecall.partner_id.id}) + for field in ('name', 'date'): + if field in fields: + res[field] = getattr(phonecall, field) + return res diff --git a/crm_phonecall/wizard/crm_phonecall_to_phonecall_view.xml b/crm_phonecall/wizard/crm_phonecall_to_phonecall_view.xml new file mode 100644 index 00000000000..27282c3ed6c --- /dev/null +++ b/crm_phonecall/wizard/crm_phonecall_to_phonecall_view.xml @@ -0,0 +1,35 @@ + + + + + crm.phonecall2phonecall.form + crm.phonecall2phonecall + +
+ + + + + + + + + +
+
+
+
+
+ + + Schedule Other Call + crm.phonecall2phonecall + form + form + + new + + +