Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions numigi_test_crm_louarmassi/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Technical test ODOO - CRM
==========================
This module add custom features on CRM module

.. contents:: Table of Contents

Context
-------
Custom development on crm and website_crm modules, no configuration will be required after the installation of this module

Overview
--------
A new field is created on crm team form view containing all email addresses of the team members,separated by commas


.. image:: static/description/team_emails.png

When the team manager is selected on the team form, it will be automatically added to the team members


.. image:: static/description/team_leader.png

Three new teams will be created after the module installation


.. image:: static/description/teams.png


In the CRM configurator, these two fields will be enabled by default: leads, Incoming emails.


.. image:: static/description/crm_setting_default.png


A cron is created to send a notification to the associated members if an opportunity has not progressed beyond the draft stage for more than 10 days.


.. image:: static/description/notify_member_cron.png


On all views of leads and opportunities, the “Expected Revenue” field will be visible only to the Sales Administrator group.

On the crm Contact Form from the website, the created lead is assigned to the default Team(Équipe de vente).


Contributors
------------

The `Numigi <https://numigi.com/r/home>`_ team is the contributor to this project.
13 changes: 13 additions & 0 deletions numigi_test_crm_louarmassi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# © Numigi (tm) and all its contributors (https://numigi.com/r/home)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import models

Check warning on line 4 in numigi_test_crm_louarmassi/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/__init__.py#L4

'.models' imported but unused (F401)

from odoo import api, fields, SUPERUSER_ID, _

Check warning on line 6 in numigi_test_crm_louarmassi/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/__init__.py#L6

'odoo.fields' imported but unused (F401)


def crm_refresh_res_setting(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})

# Recalculate computed fields of res.config.setting
env["res.config.settings"].search([]).write({})
23 changes: 23 additions & 0 deletions numigi_test_crm_louarmassi/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# © Numigi (tm) and all its contributors (https://numigi.com/r/home)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

{

Check notice on line 4 in numigi_test_crm_louarmassi/__manifest__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/__manifest__.py#L4

Statement seems to have no effect
"name": "Numigi crm test",
"version": "1.0.0",
"author": "Youness LOUARMASSI",
"maintainer": "Numigi",
"license": "LGPL-3",
"category": "Other",
"summary": "Custom development on CRM module",
"depends": ["crm", "website_crm"],
"data": [
"security/crm_security.xml",
"data/crm_data.xml",
"data/mail_data.xml",
"data/service_cron.xml",
"views/crm_team_views.xml",
"views/crm_lead_views.xml",
],
"installable": True,
"post_init_hook": "crm_refresh_res_setting",
}
29 changes: 29 additions & 0 deletions numigi_test_crm_louarmassi/data/crm_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="crm_team_technical_support" model="crm.team">
<field name="name">Équipe Support Technique</field>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="crm_team_sales" model="crm.team">
<field name="name">Équipe ventes</field>
<field name="company_id" ref="base.main_company"/>
<field name="use_leads" eval="True"/>

</record>
<record id="crm_team_sav" model="crm.team">
<field name="name">Équipe SAV</field>
<field name="alias_contact">partners</field>
<field name="company_id" ref="base.main_company"/>
</record>

<record id="crm_generate_lead_from_alias" model="ir.config_parameter">
<field name="key">crm.generate_lead_from_alias</field>
<field name="value">True</field>
</record>

<record id="website_crm_form_default_team" model="res.config.settings">
<field name="crm_default_team_id" ref="numigi_test_crm_louarmassi.crm_team_sales"/>
</record>
</data>
</odoo>
25 changes: 25 additions & 0 deletions numigi_test_crm_louarmassi/data/mail_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" ?>
<odoo>
<data noupdate="1">
<!--Email template -->
<record id="email_template_notify_members" model="mail.template">
<field name="name">Notify team members</field>
<field name="model_id" ref="crm.model_crm_lead"/>
<field name="subject">${object.company_id.name} | Suivi opportunité</field>
<field name="email_from">${(object.company_id.email or user.email) | safe}</field>
<field name="email_to">${object.team_id.emails | safe}</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px; font-size: 13px;">
Bonjour,<br/>
<br/>
Merci de donner une suite à cette opportunité <a href="${object.get_access_link()}">${object.name}</a>.<br/>
<br/>
Cordialement.
</p>

</div>
</field>
</record>
</data>
</odoo>
14 changes: 14 additions & 0 deletions numigi_test_crm_louarmassi/data/service_cron.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Notify the sales team members if a lead still has draft state more than 10 days -->
<record id="ir_cron_auto_notify_lead_state" model="ir.cron">
<field name="name">Notify crm team members</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="model_id" ref="crm.model_crm_lead"/>
<field name="code">model._notify_members()</field>
<field name="state">code</field>
</record>
</odoo>
5 changes: 5 additions & 0 deletions numigi_test_crm_louarmassi/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# © Numigi (tm) and all its contributors (https://numigi.com/r/home)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import crm_team

Check warning on line 4 in numigi_test_crm_louarmassi/models/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/models/__init__.py#L4

'.crm_team' imported but unused (F401)
from . import crm_lead

Check warning on line 5 in numigi_test_crm_louarmassi/models/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/models/__init__.py#L5

'.crm_lead' imported but unused (F401)
40 changes: 40 additions & 0 deletions numigi_test_crm_louarmassi/models/crm_lead.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# © Numigi (tm) and all its contributors (https://numigi.com/r/home)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from odoo import api, fields, models, _

Check warning on line 4 in numigi_test_crm_louarmassi/models/crm_lead.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/models/crm_lead.py#L4

'odoo._' imported but unused (F401)

Check warning on line 4 in numigi_test_crm_louarmassi/models/crm_lead.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/models/crm_lead.py#L4

Unused _ imported from odoo
from _datetime import timedelta
from werkzeug.urls import url_join


class Lead(models.Model):
_inherit = "crm.lead"

expected_revenue = fields.Monetary(groups="sales_team.group_sale_manager")

@api.model
def _notify_members(self):
template = self.env.ref(
"numigi_test_crm_louarmassi.email_template_notify_members", raise_if_not_found=False
)
new_leads = self._get_draft_leads_10days()
for lead in new_leads:
template.send_mail(lead.id, force_send=True)

@api.model
def _get_draft_leads_10days(self):
stage_new = self.env.ref("crm.stage_lead1")
date_before_10days = fields.Datetime.now() - timedelta(days=10)
lead_domain = [
("type", "=", "opportunity"),
("stage_id", "=", stage_new.id),
("date_last_stage_update", "<=", date_before_10days),
("team_id", "!=", False),
]
new_leads = self.search(lead_domain)
return new_leads

def get_access_link(self):
self.ensure_one()
web_base_url = self.get_base_url()
access_link = url_join(web_base_url, f"/web#id={self.id}&model=crm.lead&view_type=form")
return access_link
21 changes: 21 additions & 0 deletions numigi_test_crm_louarmassi/models/crm_team.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# © Numigi (tm) and all its contributors (https://numigi.com/r/home)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from odoo import api, fields, models, _

Check warning on line 4 in numigi_test_crm_louarmassi/models/crm_team.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/models/crm_team.py#L4

'odoo._' imported but unused (F401)

Check warning on line 4 in numigi_test_crm_louarmassi/models/crm_team.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/models/crm_team.py#L4

Unused _ imported from odoo


class Team(models.Model):
_inherit = "crm.team"

emails = fields.Char("Emails", compute="_compute_emails")

@api.depends("member_ids.email")
def _compute_emails(self):
for team in self:
members_email = [member.email for member in team.member_ids if member.email]
team.emails = ",".join(members_email)

@api.onchange("user_id")
def onchange_user_id(self):
if self.user_id:
self.member_ids = [(4, self.user_id.id)]
11 changes: 11 additions & 0 deletions numigi_test_crm_louarmassi/security/crm_security.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>

<odoo>
<data>
<record model="res.groups" id="base.group_user">
<field name="implied_ids" eval="[
(4, ref('crm.group_use_lead'))
]"/>
</record>
</data>
</odoo>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions numigi_test_crm_louarmassi/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# © Numigi (tm) and all its contributors (https://numigi.com/r/home)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import test_crm_team

Check warning on line 4 in numigi_test_crm_louarmassi/tests/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/tests/__init__.py#L4

'.test_crm_team' imported but unused (F401)
56 changes: 56 additions & 0 deletions numigi_test_crm_louarmassi/tests/test_crm_team.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# © Numigi (tm) and all its contributors (https://numigi.com/r/home)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from datetime import date, timedelta

Check warning on line 4 in numigi_test_crm_louarmassi/tests/test_crm_team.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/tests/test_crm_team.py#L4

'datetime.date' imported but unused (F401)

Check warning on line 4 in numigi_test_crm_louarmassi/tests/test_crm_team.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/tests/test_crm_team.py#L4

Unused date imported from datetime
from odoo import fields
from odoo.tests.common import tagged, users

Check warning on line 6 in numigi_test_crm_louarmassi/tests/test_crm_team.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/tests/test_crm_team.py#L6

'odoo.tests.common.tagged' imported but unused (F401)

Check warning on line 6 in numigi_test_crm_louarmassi/tests/test_crm_team.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

numigi_test_crm_louarmassi/tests/test_crm_team.py#L6

Unused tagged imported from odoo.tests.common
from odoo.tests.common import Form
from odoo.addons.crm.tests.common import TestCrmCommon


class TestCrmTeam(TestCrmCommon):
@classmethod
def setUpClass(cls):
super(TestCrmTeam, cls).setUpClass()
cls.opport_1 = cls.env["crm.lead"].create(
{
"name": "Nibbler Spacecraft Request",
"type": "opportunity",
"user_id": cls.user_sales_leads.id,
"team_id": cls.sales_team_1.id,
"partner_id": False,
"contact_name": "Amy Wong",
"email_from": "amy.wong@test.example.com",
"country_id": cls.env.ref("base.us").id,
"stage_id": cls.env.ref("crm.stage_lead1").id,
}
)

def test_crm_team_emails(self):
"""Test Emails field containing all email addresses of team members,
separated by commas."""
field_emails = self.sales_team_1.emails.split(",")
member_emails = [member.email for member in self.sales_team_1.member_ids if member.email]
self.assertEqual(field_emails, member_emails)

def test_crm_team_manager(self):
"""Test if a team manager is also a team member"""
team_form = Form(self.sales_team_1)
team_form.user_id = self.user_sales_manager
self.assertIn(team_form.user_id, team_form.member_ids)

def test_draft_leads_10days(self):
self.opport_1.write(
{
"date_last_stage_update": fields.Datetime.now() - timedelta(days=11),
}
)
draft_before_10days_leads = self.env["crm.lead"]._get_draft_leads_10days()
self.assertIn(self.opport_1, draft_before_10days_leads)
self.opport_1.write(
{
"date_last_stage_update": fields.Datetime.now() - timedelta(days=9),
}
)
draft_before_10days_leads = self.env["crm.lead"]._get_draft_leads_10days()
self.assertNotIn(self.opport_1, draft_before_10days_leads)
25 changes: 25 additions & 0 deletions numigi_test_crm_louarmassi/views/crm_lead_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0"?>
<odoo>
<record id="crm_lead_view_form" model="ir.ui.view">
<field name="name">crm.lead.form.numigi</field>
<field name="model">crm.lead</field>
<field name="inherit_id" ref="crm.crm_lead_view_form"/>
<field name="arch" type="xml">
<xpath expr="//h2[1]" position="attributes">
<attribute name="groups">sales_team.group_sale_manager</attribute>
</xpath>
</field>
</record>

<record id="crm_case_kanban_view_leads" model="ir.ui.view">
<field name="name">crm.lead.kanban.lead.numigi</field>
<field name="model">crm.lead</field>
<field name="priority" eval="10"/>
<field name="inherit_id" ref="crm.crm_case_kanban_view_leads"/>
<field name="arch" type="xml">
<xpath expr="//t[@t-name='kanban-box']/div[1]/div[2]/div[2]" position="attributes">
<attribute name="groups">sales_team.group_sale_manager</attribute>
</xpath>
</field>
</record>
</odoo>
17 changes: 17 additions & 0 deletions numigi_test_crm_louarmassi/views/crm_team_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="sales_team_form_view_in_crm_test" model="ir.ui.view">
<field name="name">crm.team.form.inherit.test</field>
<field name="model">crm.team</field>
<field name="inherit_id" ref="sales_team.crm_team_view_form"/>
<field name="priority">20</field>
<field name="arch" type="xml">
<field name="alias_contact" position="after">
<field name="emails" />
</field>
</field>
</record>

</data>
</odoo>