As this is a many2one, it should end with an ``_id`` suffix. Otherwise we
may think this is a char field, which was probably the case at one point.
Task-2671709
Part-of: odoo/odoo#78648
Purpose
=======
When merging multiple leads, we want to move the followers to the
destination lead if they posted a message in the last 30 days.
A message will be added in the merge note to know which followers have
been added.
Task-2447721
PR odoo/odoo#75742
Purpose
=======
Add more fields when we merge multiple leads to be sure not lose
valuable information.
Specifications
==============
Those fields are propagated to the destination if the value on the
destination is Falsy
- referred
- color
- recurring_revenue
- recurring_plan
- function
- lang_id
- date_deadline
- reveal_id
- lead_mining_request_id
- reveal_ip
- reveal_iap_credits
- reveal_rule_id
- event_lead_rule_id
- event_id
The "lost_reason" field is propagated to the destination only if it's
lost (otherwise, it makes no sense to have a lost reason on a non-lost
lead).
The field "iap_enrich_done" is set to True if at least one lead has been
enriched.
We also keep the sum of all the lead tags (and remove any potential
duplicates).
The address is taken from the lead with the most non-empty address
fields (sorted by highest rank if multiple lead have the same amount
of non-empty fields).
Task-2447721
PR odoo/odoo#75742
Jinja as a templating engine was problematic in differents respect:
- introduce external dependency to Odoo (less controll)
- add another templating mechanism in the stack
- specific feature in qweb cannot be reused
- difficulty in rendering easily editable templates
- more knowledge required with no betterment
By replacing jinja with qweb we can now build tools to edit a qweb
that will work with the previously jinja encoded document
(essentially `mail.template` records).
There is a catch however. Some email fields (eg. email_to) used jinja
syntax for rendering dynamic variables (ie. ${object.something} and
${object.something_that_should_not_be_escaped | safe}).
We still want user to use dynamic variables for some char fields (eg.
subject, from, to, ...). We made a new rendering engine called
"inline_template" that will render an expression enclosed by `{{` and
`}}`.
To be able to edit the templates from the backend interface, a
plugin to the Odoo editor has been made for seamlessly edit the
document.
This qweb plugin includes:
- make dynamic variables (eg. `<t t-out="variable"/>`) not editable
(for preventing the user to shoot himself in the foot)
- group and hide related logical branching (ie. t-if, t-elif, and t-else)
in order to see only one at once
- a floating select input to switch visibility of a particular logical
branching
Task-27033
X-original-commit: odoo/odoo@68182baff4
Part-of: odoo/odoo#77377
Use a template for merge post messages and clean how fields are displayed,
notably by fixing the display format, and the field order.
Indeed, previously posted lead merge message contained all fields in an
alphabetical order, even ones that had empty values, which is not very user
friendly in terms of display.
Now, the displayed fields are determined and ordered by sections, which greatly
improves understanding the various information.
Please note however, that it has the downside of not including all fields
anymore.
The merged leads information are included in a "read more/read less" enabled
block using the "data-o-mail-quote" feature to get a nice rendering and avoid
cluttering the Odoo chatter UI.
Within the sent mail however, the full text is directly visible when viewing
through a mail client.
Task-2451164
closesodoo/odoo#75946
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Co-authored-by: Aurélien Warnon <awa@odoo.com>
Before this commit, editing a mail.activity with the "meeting" category would
open a modal form for the mail.activity, which did not make much sense.
When editing a mail.activity that is linked to a calendar.event, you will now
jump on the calendar view to edit the related event, which is much more
convenient.
In addition, when scheduling such an activity, the "Edit" button in the chatter
is renamed to "Reschedule", to show the user that he will land on the calendar
view.
Furthermore, trying to delete an activity that is linked to a meeting will now
prompt a confirmation dialog warning the user that the meeting will be deleted
as well.
Finally, we moved the 'phonecall' activity category from the 'voip' module
(enterprise) to the base 'mail' module.
Scheduling a phonecall activity will let the user choose if he wants to:
- Simply save the activity, which will schedule a regular mail.activity
- Open the calendar to create a related calendar.event
Used typically when you want your colleagues to see that you are busy in your
calendar during this call.
Task-2486126
ENT PR odoo/enterprise#20431
UPG PR odoo/upgrade#2775closesodoo/odoo#75530
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Co-authored-by: Aurélien Warnon <awa@odoo.com>
Following the removal of read access on ir.model (odoo/odoo#69120),
the mail.activity.type model was not accessible to non-admin users due
to the res_model_id many2one field.
Before this commit, a project user could not access the Activity Type
menu.
Convert it to a selection field with the selection values being
computed in sudo.
closesodoo/odoo#74981
Related: odoo/enterprise#20214
Related: odoo/upgrade#2734
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Taking advantage of the new action_opportunity_forecast for crm leads to
create a dedicated ir_actions.xml file to store all server/client actions.
Task-ID: 2243913
PR odoo/odoo#69380
Add a new submenu "Forecast" in "Reporting" for CRM
The Forecast shows 4 views:
1. Kanban
2. Graph
3. Pivot
4. List
Objective
Shows the short term forecast for opportunities (crm_lead) based on their
expected closing (date_deadline) and have an overview of the prorated
revenues for each period (defaults to month).
Implementation
1. Kanban
- the progressbar is using the prorated_revenue
- the forecast_field is date_deadline
- the default groupby is date_deadline
2.3. Graph, Pivot
- the measure defaults to the prorated_revenue
- the row defaults to date_deadline
4. List
- shows the prorated_revenue
The special filter "Forecast" is defined to be used by the
forecastModelExtension (JS). (define the forecast_filter context key)
The forecast_field context key is defined in the action to be used by the
forecastModelExtension and the forecastService (JS).
The demo data for opportunities is updated to spread date_deadline over 4 months
Enable drag&drop and quickCreate features for the kanban view with the use of
the allow_group_range_value <field> xml attribute
Add a "Won" flag for the forecast view to better distinguish opportunities that
need to be worked on
Test tour
Task-ID: 2243913
PR odoo/odoo#69380
ENT PR odoo/enterprise#18547
GLOBAL PURPOSE
Ability to have salesmen belonging to several sales team is a core requirement
of CRM. It is therefore moved from website_crm_score to crm along with cleaning
and behavior improvement. Automatic lead assignment is also moved and cleaned.
SPECIFICATIONS
Move sales team automatic lead assignment from website_crm_score (enterprise)
directly into sales_team. Some cleaning and renaming is performed while moving
the code as it is old fashioned.
Scoring feature is removed completely from lead assignment. Indeed we consider
PLS is a better feature and provides more accurate results.
Minimal scoring specific field on team is removed. Indeed it can also be
integrated directly into domains linked to a sales team as this is a field
directly available on lead using ``probability``. It allows to reduce fields
of team model and move all logic in the team's domain itself.
Overall behavior as been kept as close as possible from the original one.
Purpose is to avoid too much undesired changes between versions.
In this commit we also add tests for automatic lead assignment.
ASSIGNMENT PROCESS DESCRIPTION
1- LEAD TO TEAM ALLOCATION
Allocate leads to teams given by self. This method sets ``team_id`` field
on lead records that are unassigned (no team and no responsible). No
salesperson is assigned in this process. Its purpose is simply to allocate
leads within teams.
Heuristic of this method is the following:
* first we randomize all teams;
* then for each team
* find unassigned leads, aka leads being
* without team, without user -> not assigned;
* not in a won stage, and not having False/0 (lost) or 100 (won)
probability) -> live leads;
* if set, a delay after creation can be applied (see BUNDLE_HOURS_DELAY)
parameter explanations here below;
* keep only leads matching the team's assignment domain (empty means
everything);
* assign maximum BUNDLE_SIZE leads to the team, then move to the next team.
This is done to ensure every team will have leads enough to fill its
capacity based on its domain;
* when setting a team on leads, leads belonging to the current batch
are also merged. Purpose is to clean database and avoid assigning
duplicates to same or different teams;
* for all teams that still have capacity (aka: a search on unassigned
available leads with team domain still give results), do another
assignment round. Each round teams are randomized so that team order
is not always the same;
Note that leads are assigned in batch meaning a team could receive leads that
could better fit another team. However this heuristics is based on hypothesis
that team domains do not overlap. Indeed if a company has several teams they
will probably target separate market segments: country-based, customer type or
size, ... Having several teams using same assignment domain could lead to less
fairness in assignment process but this should not be the target use case of this
heuristic.
Leads are allocated by batch. This can be configured using a config parameter.
Batch size depends on cron frequency, lead pipeline size and members assignment
maximum. Finding an optimal heuristic for this parameter is not easy as it
depends on internal processes and organization. Higher batch size leads to
better performances when running automatic assignment. It can also give unfair
results if teams domain overlap or if pipeline is not big enough to fill all
teams capacity.
2- LEAD TO MEMBER ASSIGN
Main processing method to assign leads to sales team members. It also converts
them into opportunities. Its main purpose is therefore to distribute team
workload on its members based on their capacity.
Preparation
* prepare lead domain for each member. It is done using a logical AND with
team's domain and member's domain. Member domains further restricts team
domain;
* prepare a set of available leads for each member by searching for leads
matching domain with a sufficient limit to ensure all members will receive
leads;
* prepare a weighted population sample. Population are members that should
receive leads. Initial weight is the number of leads to assign to that
specific member. This is minimum value between
* remaining this month: assignment_max - number of lead already assigned
this month;
* days-based assignment: assignment_max with a ratio based on ``work_days``
* e.g. Michel Poilvache (max: 30 - currently assigned: 15) limit
for 2 work days: min(30-15, 30/15) -> 2 leads assigned
* e.g. Michel Tartopoil (max: 30 - currently assigned: 26) limit
for 10 work days: min(30-26, 30/3) -> 4 leads assigned
Assign process then follows the following heuristic
* take a weighted random choice in population;
* find first available (not yet assigned) lead in its lead set;
* if found:
* convert it into an opportunity and assign member as salesperson;
* lessen member's weight so that other members have an higher
probability of being picked up next;
* if not found: consider this member is out of assignment process,
remove it from population so that it is not picked up anymore;
Assignment is performed one lead at a time for fairness purpose. Indeed members
may have overlapping domains within a given team. To ensure some fairness in
process once a member receives a lead, a new choice is performed with updated
weights. This is not optimal from performance point of view but increases
probability leads are correctly distributed within the team.
LINKS
Task ID-2086889 (main task)
Task ID-2357969 (scoring migration task)
Community PR odoo/odoo#48422
Enterprise PR odoo/enterprise#499
Upgrade PR odoo/upgrade#996
GLOBAL PURPOSE
Ability to have salesmen belonging to several sales team is a core requirement
of CRM. It is therefore moved from website_crm_score to crm along with cleaning
and behavior improvement. Automatic lead assignment is also moved and cleaned.
SPECIFICATIONS: MODEL CLEANING
In this commit we improve team member model to make it more usable and
aligned with current Odoo views and usability.
This commit contains notably
* add some related fields on the user: phone, mobile, company, email;
* rename "team_user_domain" to "assignment_domain";
* rename "maximum_user_leads" to "assignment_max";
* improve member views globally;
We also introduce dynamic domain computation for users and teams when seeing
team members. This allows to limit selection of users or teams depending
on already existing configuration. Purpose is to avoid having people trying
to create wrong configuration (duplicates, ...) and receiving error messages.
Also
* clean some data and demo about teams and members;
* fix some views glitches;
* improve views: add some fields in search views, improve wording of
fields or actions, ... globally improve usability and US as well as
feedback given to users;
* group sales team members by team by default as it help getting an
overview of team members distribution;
* update tests to create team members instead of writing directly on m2m
towards users;
SPECIFICATIONS: SALE_TEAM_ID FIELD ON RES.USERS
In this commit we also rewrite sale_team_id field of res.users. Previously in
crm it was simply a many2one field linking to a crm.team. It was used to compute
team membership as a standard many2one / one2many relationship. In enterprise
module ``website_crm_score`` this field was set as a related on first user
teams. Indeed scoring changed relationship between users and teams to a
many2many.
This field is now directly a computed many2one field that links to the
"main" team of the user even in multi memberships mode. As memberships can
now be de-activated we changed this field to a computed stored field. It is
based on oldest active membership of user. That way default team of documents
will be the user's oldest team considered as its "main team".
SPECIFICATIONS: LEAD_ALL_ASSIGNED_MONTH_COUNT
Improve crm_team ``lead_all_assigned_month_count`` field computation. It is
now simply the sum of assigned leads of team members. Differences may
happen if a lead in teamA is assigned to an user working in teamB. This should
not happen if team / user is correctly set at lead level which is generally
the case. However if that happens, old field counted it. New field will not
count it as it is not directly linked to a team's member.
SPECIFICATIONS: DEMO DATA
Make crm.lead demo data coherent with user_id / team_id . As demo data should
be using a mono-membership behavior for users and teams, we have to ensure
user_id and team_id effectively matches. It allows to have coherent reporting
and assignment demo flows.
Also avoid having Odoobot responsible of leads. Instead of undefined user_id
and team_id leading to Odoobot being responsible of some leads, force it
to be False. Those demo data allow to test automatic assignment of lead
LINKS
Task ID-2086889 (main task)
Task ID-2357969 (scoring migration task)
Community PR odoo/odoo#48422
Enterprise PR odoo/enterprise#499
Upgrade PR odoo/upgrade#996
GLOBAL PURPOSE
Ability to have salesmen belonging to several sales team is a core requirement
of CRM. It is therefore moved from website_crm_score to crm along with cleaning
and behavior improvement. Automatic lead assignment is also moved and cleaned.
SPECIFICIATIONS
Move sales team membership model from website_crm_score (enterprise) directly
into sales_team. It allows to have the base requirements to correctly handle
mono and multi sales team for salesperson.
Membership is modeled using a decorated many2many relationship. Members of
a sales team are res.users. Subscriptions are crm.team.member linking a team
and an user. It is a rename of team.user model coming from website_crm_score
as well as some other relational fields renaming.
Part of old team.user model is moved directly to sales team, part of it to
crm module (notably assignment limits). Its support will be improved in the
upcoming commits. Assignment related fields will be cleaned and used when
moving assignment directly into CRM.
LINKS
Task ID-2086889 (main task)
Task ID-2357969 (scoring migration task)
Community PR odoo/odoo#48422
Enterprise PR odoo/enterprise#499
Upgrade PR odoo/upgrade#996996
PURPOSE
Remove the alias setting option because it is a weird and hackish way to
proceed. We would prefer users to configure their alias through sales teams.
Improve alias configuration on teams.
RATIONALE
"Incoming Emails" option has many flaws
* it creates collision when you try to set an alias that is already used
and it is not easy to find them back;
* it has no default value (no sales team, no type, ...) and works through the
'owner' field. This is set with the admin on activation of the feature
which is not correct. The admin is potentially not a salesperson. If you
set the field to blank, you get leads without team and without assigned
responsible.
* this alias is not team-bound which thus asks the question: in which team
should the lead ever go? To the first team? Why?
All this make it seem way healthier to handle this through the Sales Team.
=> By default, we'll already have one working with an alias.
If users really want a global lead alias it can be setup manually through
alias menu in configuration. Shortcut and default alias in crm are removed
but feature is still doable if requested.
SPECIFICATIONS
Remove the s "Incoming emails" setting that allows to setup a global alias for
leads / opportunities with a default value being 'contact'. Also remove related
alias data as it has no use anymore.
LINKS
Task ID-2414079
Sort of follow-up of Task ID-2373095.
COM PR odoo/odoo#63160
UPG PR odoo/upgrade#2017
Crm holds a blank template that adds no real value. Its purpose was to
give a base for salesmen to perform a mass mailing on leads. Using a template
and its action menu entry it was possible to launch a mail composer in
mass mail mode on leads.
However template itself is not necessary. Same goal can be achieved with
a standard action. As template was blank and creating noise we can remove
it and simplify available templates.
LINKS
Task ID-2375767
COM PR odoo/odoo#61814
ENT PR odoo/enterprise#14775
UPG PR odoo/upgrade#1936
PURPOSE
Clean organization of templates in odoo apps: mail.template records in data,
qweb templates (views) used directly in code, notably using post with view.
Purpose is to ease future improvements in posting based on templates.
SPECIFICATIONS
* move those templates in their own file to ease their discovering and
maintenance;
* put them into data (as those are not views even if it contains qweb)
* guidelines are now :
-> Qweb templates should be in data/mail_templates.xml;
-> mail.template records should be in data/mail_template_data.xml;
* put their declaration in no update when not done if template has no
technical code or complex dependency on underlying code;
* move found mail data (mail.message.subtype or mail.activity.type) records
in a mail_data file that should contain only "core" records linked to mail;
LINKS
Task ID-2375767
COM PR odoo/odoo#61814
ENT PR odoo/enterprise#14775
UPG PR odoo/upgrade#1936
The purpose is to ease the onboarding for the default CRM settings.
Now, we do not include any field by default and tags become an option
in the choice of fields apply to the computation.
task-2196200
closesodoo/odoo#48124
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
In this commit we remove the warning logger when not being able to format
a phone number. Indeed this does not indicate there was a real issue.
It simply indicates that either the phone number is not parsable or not
matching given country format.
It happens in a lot of situation that phone numbers are not valid: bad
encoding, country mismatch due to {lead, task, ticket} / partner not always
being the same, ... This should not raise a server warning.
When using frontend SMS composer for phone number, a warning is displayed
to the user telling the number is probably incorrect. This is considered
as sufficient from UX point of view as it warns users. We do not think
we should warn admins that some data is incoherent in database.
This commit also
* Revert "[FIX] crm: avoid linking demo leads with an unrelated partner"
This reverts commit 2c94c4c81ffa171158586cd64828d27c537cd1d6
-> having "invalid" data should be a valid use case of real life
* Revert "[FIX] crm: get correct country for phone validation"
This reverts commit a58f9fc154c038d72031b281e2bec2c0fc2915ba
-> country of a lead comes from its partner if set but can be different.
Same for phone numbers. Values on a lead after a compute are considered
as complete. Sales persons could effectively have incoherent data on their
form view but that is the result of what has been encoded.
Task ID-2325228
X-original-commit: cecc4ca6f02e599e193c3fa688bfcbd02ac0580b
Using this partner will copy his phone number on the lead.
However, the lead and the partner don't have the same country, which
will lead to ad invalid phone number (for the lead country).
It avoids a warning emitted by the `phone_validator` module, while
browsing the lead.
closesodoo/odoo#58352
X-original-commit: 2c94c4c81ffa171158586cd64828d27c537cd1d6
Signed-off-by: Christophe Simonis <chs@odoo.com>
Purpose
=======
Get rid of the cron.
Always have an up to date frequency table to compute lead probability.
Clean PLS code and ensure to remove unnecessary code
Specifications
==============
Disable the cron:
- Increment won and lost count for lead PLS params from frequency table at
each won/lost
- The complete set of leads won't be recomputed anymore every day
- A lead probability will only be recomputed if one of the PLS parameter will
be modified (stage_id, team_id + the ones checked in settings)
- No more onboarding phase : as frequency table is always up to date and only
the modified leads are recomputed, we can drop this. (So even on onboarding,
winning or losing a lead won't impact other leads, except the ones we modify
manually afterwards)
- Add an button to force the recompute of all the lead probabilities
(kind of reset) in the settings.
The cron has been disabled by default.
Users can know choose to reactivate it if they want to continue updating their
lead probabilities on a daily basis.
Code have been reorganised for better structure and understanding.
Some code parts have been factorised to be usable in both Live Increment and
Full Rebuild mode.
In this commit, we also update probabilities using only computes
Before this commit, _update_probability was called during write and create,
to ensure both probability and automated_probability were correct. That was
necessary because of onchanges and readonly field (automated_probability
was not given to the write method while saving after a change on the lead).
After this commit, we use the force_save tag on the readonly field
automated_probability. So we ensure that write always receives the new
automated_probability value and everything can be handled directly by the
compute. Also, we force the lead to start in automated probability mode.
So when creating a new lead, both probability and automated probability are
computed and aligned.
Finally, when winning a lead, we ensure that both probabilities are aligned
(=100), so that if user take the lead back to a previous stage, the
probabilities are correctly recomputed, and the lead will not be stuck to
100%.
Also, this commit applies some fix and minor changes listed here under:
- Ensure to have always positive frequencies
- Fix lost counts for team not set in pls computation
- optimise set_won : write only once per values
Finally, include tag in frequency table even if less than 50 occurences:
Due to refactoring in which we increment frequency table at each won/lost
instead of rebuilding the frequency table each day, the tags are never added
in frequency table.
This is due to the 50 occurence conditions that avoid to create the frequency
if we have less than 50 won or lost for a tag.
After this commit, we include the tag_ids in the frequency table, no matter
the number of occurences. But, during the PLS computation, we skip the tag
frequencies if the number of occurences for this tag is under 50.
This allows to have a complete vision on the tag frequencies, even for
small number of occurences.
Task ID : 2254543
X-original-commit: cd291b79eb2d2df80899867263ec71438ab8fe87
Right now on few business objects (like leads, invoices, tasks, helpdesk
tickets etc) creation message contains
* subtype description;
* generic creation message;
This looks like multiple creation message on chatter after creation of the
record as you generally have "Task Created - Task created" (subtype description
then generic message).
This happens when we provide custom subtype on creation by by overriding
`_creation_subtype` method.
This commit fixes the issue by only using provided creation subtype and
removing default body. If creation subtype is not provided default creation
message is posted as before.
In this commit we also fix subtype for Lead/Opportunity creation and make
it generic ('Lead/Opportunity created') to avoid inconsistent behavior.
Finally some cleaning is made in method naming. Semi followup of 92e9e84b63
LINKS
Task ID-2288458
PR odoo/odoo#56631
PR odoo/enterprise#12707closesodoo/odoo#56688
X-original-commit: 2ebbeb4b5443c6405dd9a3b202a1eee9c5c67ebb
Related: odoo/enterprise#12728
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
PURPOSE
Allow users to configure contract recurrences and Monthly Recurring Revenues
on Opportunities they're trying to close. One short revenues are not sufficient
to cover real life use cases of CRM revenu analysis.
SPECIFICATIONS
Adds an option in the settings to activate the recurring revenue feature.
This feature is set on an opportunity to indicate a revenue that could be
perceived over time. This time indicator is set by the crm.recurring.plan
model in which the number of months is determined.
By default some plans are added in data. When using plans, revenues are
computed across the plan months.
LINKS
Task ID-2283052
odoo/odoo#54194odoo/enterprise#12423odoo/upgrade#1463
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
PURPOSE
Link field name with their content.
SPECIFICATIONS
This commit changes the field name "expected_revenue" into "prorated_revenue"
and the field name "planned_revenue" into "expected_revenue".
Indeed content of those fields evolved since their first naming. Their content
is not what the field name indicates. Better rename those fields to understand
code flow inside CRM.
LINKS
Task ID-2283052
odoo/odoo#54194odoo/enterprise#12423odoo/upgrade#1463
PURPOSE
Review the tips and digest layout design to make sure they have a WOW effect
and increase trial conversion/retention.
SPECIFICATIONS
“Did you know Odoo has built-in lead mining?”
“Opportunity win rate is predicted with AI”
“Manage your pipeline”
“Do not waste time recording user's data”
“Turn a selection of opportunities into a map”
See code for specifications.
LINKS
Task ID-2274264
COM PR: odoo/odoo#53580
ENT PR: odoo/enterprise#1139
X-original-commit: 93c7aa19397ae7a25e88e760f44d24a0b4f0dd9a
This commit sets 'info' alias on the default sales team and sets 'admin' as a
default user for the same. After a long debate on default alias configuration
"it will work on SaaS and other people will be careful when deploying" won.
Task ID-2284840
closesodoo/odoo#54943
X-original-commit: 46d616643ba684596b709cd7e65536781dfa5d51
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
PURPOSE
Make digest email and tips more appealing. The goals of these tips are
* to encourage the adoption of other apps (Did you know ?);
* to make Odoo look more fun (Fun tips and tricks, young and dynamic style);
* to show social proof and increase trust (emphasis on already existing
projects / customers to);
SPECIFICATIONS
Improve existing tips to be more inlined with new digest styling.
Add new tips, notably
* use lead enrichment;
* use lead mining;
LINKS
Task ID 2197417
PR odoo/odoo#51619
Co-Authored-By: Elisabeth Dickinson <edi@odoo.com>
Co-Authored-By: Thibault Delavallée <tde@odoo.com>
PURPOSE
Prepare enhancements of sales team membership.
SPECIFICATIONS
Lint crm data and demo, notably about sales team and file organization.
Also move crm menu entries declaration in a single file and remove some
menu entries not imported anymore.
LINKS
Task ID 2086889 (sales team enhancements)
Task ID 2234698 (preparation lint)
Community PR odoo/odoo#49520
As the crm.lead.tags model shall be used in CRM and/or Sales apps,
it has been moved to the sales_team module, which is a depedency
of the CRM and Sales apps.
As these tags becomes more generic than just "lead tags", the model
has been renamed from crm.lead.tags to crm.tags.
Tags on sale orders were already present but not visible. They are
now visible in the "Other Info" section, and optionally in sale order
tree views.
When a quotation is created from an opportunity (CRM app), existing tags
are populated from the opportunity to the sale order (Sales app).
Views and demo data of several modules have been updated accordingly.
Task ID 2191276
PURPOSE
Ease edition of digest tips by adding a name.
SPECIFICATIONS
Add a name on digest tips. Even if technical and not send to customers it
allows to see them at a glance in list view without having to guess their
content.
LINKS
Task ID 2214325
Com PR odoo/odoo#47416
Related: odoo/upgrade#933
Related: odoo/enterprise#9167
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Purpose: Replace user's role by partner in the chatter of lead.
Currently the discussion in the chatter of the lead is incorrect as both
are users.The message is sent by user to demo user instead of partner.
This commit fixes the behavior by setting the author of mail message to
partner instead of user and if there is no partner selected then the message
is sent by the contact email.
Task 2180228
closesodoo/odoo#44253
Closes: https://github.com/odoo/odoo/pull/44253
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Update demo data on leads to make more senses
with the utm fields, tags and the lead itself.
task-2189667
closesodoo/odoo#44832
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
* Code cleanup
* Avoid a safe evaluation of the field value when loading those records.
closesodoo/odoo#44883
Related: odoo/enterprise#8283
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
Add new activity type 'Email with Template' for demo purpose and add a mail
template for it.
task-1887986
closesodoo/odoo#38944
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
When there are only few leads, marking a lead as won or lost changes
a lot the won/lost repartition. For onboarding purpose, the cron is launched
if the threshold PLS config param is not reached.
When the number of lead in the database reaches the PLS threshold,
the config parameter is set to 0 to avoid the useless check
of the number of lead in the dabase in the future
Task ID: 2044539
PR #37413
This commit
- removes probability default value in order to activate
Bayes predictive lead scoring by default
- set the default pls start date to today - 8 days
to include all demo data in PLS computation
Task ID: 2044539
PR #37413
This commit applies multiples things:
- Fix PLS settings that were not loaded correctly (was not using technical field names)
- Add data for PLS settings to check all optional fields and set the start date.
- use null value instead of empty for phone and email state fields to lessen the DB storage
- set pls start date required
Task ID: 2044539
PR #37413
As part of the back2basics, the stage messages were modified to be clearer
* when an opportunity is lost previously 2 separated messages where
created in the chatter (one for the reason, one for the active state)
now, one message is created with both infos;
* new message when an opportunity is restored;
There where also some fixes to typos, and an the probability of a lead
to be successful received a new title "estimated by Odoo".
Task 2026297
closesodoo/odoo#35308
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Since introduction of website_visitor,
we don't need to identifiy the lead with a lead_id cookie.
The visitor is identified and if a lead is created with the
contact form, the lead is created and linked to the visitor.
To avoid losing data, each time a visitor send a contact form,
it creates a new lead. All those leads are linked between them
via the website_visitor.
As the website_visitor already has the lang set on itself,
there is no reason to keep the lang_id of crm_lead at enterprise
side. So that lang_id on crm.lead has been moved to community.
This commit is directly linked to another one in enterprise
See https://github.com/odoo/enterprise/pull/4834 to get more details.
Task ID : 2028059
PR #34624
This commit improves the ux in CRM by changing a few things:
- Restore the use_leads and use_quotations fields
along with their features as they were in 12.0.
- Hide the email alias if use_upportunities and use_leads
are unchecked.
- Show a link to the general settings instead of the alias_domain
if no alias_domain has been configured.
- fixes the "unassigned lead(s)" link so that
it redirects the user to the actually unassigned leads
Task: #1962182
PR: #32372
This new Predictive Lead Scoring (aka PLS) replaces the stage based probability mechanism.
It uses Naive Bayes probability computation theorem.
The lead probability is now computated automatically based on multiple criteria (= frequency fields).
Some are mandatory and will always be used, some are optional and can be activated
in the settings.
- Mandatory fields :
- team_id
- stage_id
- tag_ids
- Optional fields :
- email_state (validity of the email_from field: correct / incorrect or empty if email_from is empty)
- phone_state (validity of the phone field !! not the mobile one !!: correct / incorrect or empty if phone is empty)
- country_id
- state_id
- source_id (UTM Source)
PLS uses a start date to consider only the lead created after that date to generate the frequency table
and to recompute the lead probability. This date is also configurable in the CRM settings.
Default start date is date.todays() (at module install).
The settings for PLS are NOT company related :
PLS Fields = Many2many to a model that store only the fields allowed for PLS computation.
PLS Start Date = Date
As Date and Many2many fields are not allowed for config_parameters,
Char fields are used to store the configuration
and Date and m2m fields are used to ease the configuration by the user in the config panel.
Date and m2m fields are both computed fields based on their corresponding Char fields.
Char field for Date store a strigified date.
char field for Many2many store a comma separated string which is a list of activated fields.
Each mandatory field is used in a specific way
- Team_id : the frequency table is split for every team_id, plus once for leads that don't have a team_id.
Considering Lead A from Team 1 and Lead B from Team 2.
Even if Lead A and Lead B have the exact same attributes (country, phone, email,stage, ...),
their probability will most likely not be the same.
That's because each teams compute their leads' probability based on their own won/lost leads.
- Stage_id : if no optional fields are activated and if there is no tag on the lead,
this will make PLS work quite the same way as it was working with removed stage based probability,
as only the stage will count in the computation.
But here, instead of fixing manually the probability for each stage,
this stage related probability is automatically computed based on past experience (won and lost leads).
- Tag_ids : each tag is considered separatelly, as if the lead had only one tag.
(no link between tag on same lead is made). To avoid that a tag take to much importance if his subset is too
small, we include the tag frequencies in the frequency table only if at least 50 won or lost leads had this tag.
The frequency table is a table where all won and lost leads are aggregated by fields
(mandatory or optional if activated). For each team_id / field couple, we store the number of
won and lost leads that has that fields values.
For example: Lead A is assigned to team 1 and client comes from France and has been won.
If we consider only this lead A, the frequency table will looks like :
id | variable | value | won_count | lost_count | team_id
--------+-------------+-------+-----------+------------+---------
1 country_id FR 1 0 1
To computed the probability of a lead, we get all the records for the frequency table
that match all fields (per team_id) and we compute a won score and a lost score.
The probability is computed and normalized based on those scores
- P = S(Won) / (S(Won) + S(Lost))
Considering two variables A and B :
- S(Won) ∝ P(A∩B | Won)*P(Won) = P(A|Won) * P(B|Won) * P(Won)
- S(Lost) ∝ P(A∩B | Lost)*P(Lost) = P(A|Lost) * P(B|Lost) * P(Lost)
To overcome the 'zero frequency problem',
we do not start at 0 for the won or lost count for each variable / value combination.
It suggested to start at 1, but to avoid that a small subset take to much weight compared to
a larger one, we start at 0.1.
For example :
If we start at 1 : If team 1 has few records from France,
it can get high probability to win even if every lead where lost.
variable | value | won_count | lost_count | team_id | Probability
-------------+-------+-----------+------------+---------+-------------
country_id FR 1 7 1 0.125
country_id FR 198 7306 2 0.0263
If we start at 0.1 :
variable | value | won_count | lost_count | team_id | Probability
-------------+-------+-----------+------------+---------+-------------
country_id FR 0.1 6.1 1 0.0161
country_id FR 197.1 7305.1 2 0.0263
The more we have records for each couple, the more the computation become precise.
The allow the user to decide himself which probability should be set on the lead,
a manual probabiltiy system has been implemented using 2 stored fields + 1 computed field :
- probability (stored): Probability set on the lead, can be set manually in the lead form.
- automated_probability (stored): Probability computed by PLS.
- is_automated_probability (computed): If both previous fields are equal, the probability is considered
as automatic. and each time the automated_probability is updated, the probability is aligned.
If both are not equal, the probability is considered as manual. The automated_probability is still
updated but the probability is not aligned. The user can reset the probability in automatic mode
by clicking on the estimated probability displayed in edit mode in the lead form.
probability and automated_probability are not computed fields as they are manually computed at write and create.
The computation is triggered if one of the activated frequency fields is modified or set.
To trigger also the computation when modifying the lead values on the lead views (form and kanban),
_onchange methods have been added for each frequency field.
Also, a cron has been added to run every day to rebuild the frequency table and to recompute all active
and pending leads (not won nor lost) probability.
Task ID : 1925439
PR #33589
remove rerun cron on action lost and won
This commit prepares the next Predictive Lead Scoring (aka PLS) ones.
With the new PLS implementation, stage based probablility is not relevant anymore
as the probability will be computed based on multiple criteria
following the Naive Bayes probabilist theorem.
To determine if the stage is a won stage, a new 'won_stage' boolean field replaces
the old probability field that is now removed.
won_stage = True is equivalent to stage.probability = 100.
Task ID : 1925439
PR #33589
This commit removes the field `datas_fname` from `ir.attachment` as
it was unnecessary and most of the time the duplicate of `name` or
`url`.
Task #1909865closesodoo/odoo#32976
Signed-off-by: Martin Geubelle (mge) <mge@openerp.com>
The user can delete teams created during the installation of the Sale
Team module, both CRM and Sale modify those teams but the way they
modify the teams doesn't take their deletion into account.
This reverts commit 30a848bffb to replace
post_init_hooks by `forcecreate=False` in the datas.
closesodoo/odoo#32742
Signed-off-by: Christophe Simonis <chs@odoo.com>
The user can delete teams created during the installation of the Sale
Team module, both CRM and Sale modify those teams but the way they
modify the teams doesn't take their deletion into account.
opw-1962297
closesodoo/odoo#32412
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>