Somehow followup of dbb6cfdbf8 . Purpose is
to use formataddr from tools instead of manually handcrafting the full
email address format. Indeed the tools one correctly encapsulates and
format name and email.
Task ID 2068986
When Lead is duplicated, `stage_id` should not be copied for obvious reason.
Indeed it should go through the pipeline again, with probably and stage_id
being freshly computed again.
closesodoo/odoo#37927
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Before this commit it was not possible to enrich leads manually as
only a cron enriches leads. It is considered as sub optimal since people
would like to do it manually on some leads and not activate it only for
all leads, using a cron.
After this commit an option is added in CRM settings to choose the type of
enrichment: either manual, either automatic.
In manual mode, a button appears on the lead to enrich if certain conditions
are met (email_adress present, not already enriched,...). It also deactivates
the enrich cron.
In automatic mode, the button on lead is not displayed and the cron is
activated.
A config parameter is defined in CRM as it is requested to be able to configure
it directly in CRM without having to first install the app then configure
it. A post install hook to synchronize cron status with config parameter
is therefore required.
FP/AJU request
Task 2075817
closesodoo/odoo#37367
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
when runnning the PLS cron, only the automated probability was updated
with the new values.
But dissociating probability and automated probability
(for the leads that were in auto mode), breaks the autom mode and set
implicitelly the mode to manual.
(as probability and automated_probability are not equal anymore).
This commit update also the probability only in the case both fields were equal before
the cron process.
Task ID: 2044539
PR #37413
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
If the stage is set to won, automated probability should = 100%
Without forcing it, it should be the case as all lead at stage won
have been won. (thanks Captain Obvious!)
But if a user mark as lost a lead that is at won stage, it will reduce the
probability of the won stage.
Also, if the cron didn't run recently, it could be that the autmomated probability
will give the same result than in previous stage (if no lead have been won at all).
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
Since it appears that email validation feature from Flanker v0.9.0
is completelly broken (the lib explodes when calling
address.validate_address('some@address.xxx')), Flanker is then removed
and email validation will be done only using the email_normalize method.
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
Indeed since a lot of cleaning has happened, notably merging lead and
opportunity views and actions cleaning, let us have a real name for
that main action instead of a bad and error-prone name.
Task 2070287
closesodoo/odoo#36676
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
In order to prepare the send mail to visitor that are linked to leads,
getting lead by confidence level must be factorised to avoid code duplicates.
Task ID: 2056080
PR #36290
PURPOSE
Allow auto install of all SMS-based feature. Move partner onchange formatting
directly inside phone validation.
SPECIFICATIONS
Move the onchange on the phone field of contact model directly inside phone
validation to have it available in all SMS based applications.
LINKS
Task 2061765
PURPOSE
Allow the user to enrich a lead based on the domain of the email address of
the client.
SPECIFICATIONS
Following fields will be populated if found using clearbit and if they are
not yet populated :
* description
* partner_name
* reveal_id
* website
* street, street2, zip, city, country_id, state_id
* phone (using the first number found in clearbit)
* mobile (using the second number found in clearbit, else the same as phone)
A message will also be logged in the chatter.
If no data is found using clearbit no credit is used and a message will be
logged. If the user has no credits he will be redirected to buy credits for
the service.
It is possible to enrich using the 'enrich' action in listview or with a
cron that will run every hour on leads not older than 1 hour.
Add a "Lead Enrichment" setting in CRM installing lead enrichment.
LINKS
Task 193185
closesodoo/odoo#36419
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
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>
This branch is the combination of several optimizations in the ORM:
* store field values once in the cache: the cache reflects more
faithfully the database, only fields that explicitly depend on the
context have an extra indirection in the cache;
* delay recomputations by default: use method `recompute` to explicitly
flush out pending recomputations;
* delay updates in method `write`: updates are stored in a data
structure that can be flushed efficiently to the database with method
`flush` (which also flush out recomputations);
* make method `modified` take advantage of inverse fields to inverse
dependencies;
* filter records by evaluating a domain on records in Python;
* a computed field with `readonly=False` behaves like a normal field
with an onchange method;
* computed fields are computed in superuser mode by default.
Work done by Toufik Ben Jaa, Raphael Collet, Denis Ledoux and Fabien
Pinckaers.
closesodoo/odoo#35659
Signed-off-by: Denis Ledoux <beledouxdenis@users.noreply.github.com>
When redirecting to record, the wrong 'form' view will sometimes be
loaded. A 'hack' has been done in crm_lead.py to redirect the user to
the relevant 'form' view based on the value of the 'type' field.
However, this solution is not clean as it does not solve all cases
(multiple crm.lead records loaded from the activity systray, reloading
the page after redirection, etc.)
Goal of this task is to solve those issues by merging crm.lead.form.lead and
crm.lead.form.opportunity form views. That way multi records actions will
always display the relevant information according to record type.
Note: Here some fields used as a twice in the form view just to stay
close to the current design. Still few things which are not possible
here for 'lead' and 'opportunity', that is
* A dynamic 'placeholder' on 'name' field.
* A 'domain' on 'partner_id' field.
* A 'widget' on 'probability' field.
Task 47118
closesodoo/odoo#32248
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
In this commit useless code is removed
* method 'close_dialog' and 'edit_dialog' from crm.lead;
* actions: crm_opportunity_report_action_graph,
create_opportunity_simplified, crm_lead_action_activities,
merge_opportunity_act;
* views: view_create_opportunity_simplified
Indeed this is dead code and can be removed to clean a bit module.
Task 47118
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
When the many2xxx field relates to a model where company_id is required, set
this domain [('company_id','=',company_id.id)]
When the company_id field of the related model is not required, set this domain
['|',('company_id','=',company_id.id),('company_id','=',False)]
When setting the domain on a field which is in the treeview of a xxx2many field
evaluate against the company_id of the 'parent'.
Some constraints have been added on sereval models. Take a look at the complete
specification for more details.
TaskID: 2024446
Closes: #35266
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
Module module_crm_phone_validation and its checkbox from py and xml file
because the module crm_phone_validation is moved to module crm since f60825b439 .
Also moved label of phone_international_format to help directly inside settings
view in order to have a nice looking configuration page.
Task 2036270
closesodoo/odoo#35377
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This attribute is misleading as it is insufficient to correctly upgrade
the database. It only renames the column in the database, but other
operations are needed, like updating the corresponding `ir.model.fields`
record (and its xmlid). The default values and the translations are also
lost during the upgrade.
Moreover, this feature was misused. It was:
- left on fields during multiple versions.
- used on reports (SQL views). This would be ok if the feature was
complete, but, as is, it was useless.
- kept unchanged after a second renaming of the field (which can happen
versions later the first rename).
- used, even when the meaning of the field changed. i.e. the field
`archived` has been renamed to the classic `active`, but the value
in the database should be switched.
The following models are already using big images, or they might need big images
in the future:
- partner
- hr employee
- shop category
- lunch product
- gamification badge and karma rank
PR: #34925
PURPOSE
This commit removes the mass_mailing.campaign model. Instead of having a fully
fledged model, we will simply inherit utm.campaign. We will also add relevant
statistics on utm campaign model in order to use it in various applications.
SPECIFICATIONS
This commit adds leads/generated statistics in the kanban and
the form view of the utm campaign.
Kanban and form views will now display the number of leads and
opportunities generated with the campaign
TaskID: 2002029
PR: #34452
Now we can deselect all the optional fields to compute the predictive
lead scoring.
Task 2028666
closesodoo/odoo#34614
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Commit f60825b439 moved phone validation addition on res.partner model
from a specific module to crm directly. However the inherit from the validation
mixin class was forgotten, leading to a crash when changing phone from the UI.
closesodoo/odoo#34545
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
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 moves phone validation from bridge module to crm directly.
This commit prepares the PLS feature (see next commits).
PLS needs the phone state to evaluate the probability to closes a lead.
So as crm will depend of phone_validation, the content of the bridge
module is moved in crm module.
Task ID : 1925439
PR #33589
- Have two crm teams with the same team leader, and without team members
(team1, team2 as instance).
- Create a new lead, add as Salesperson the team leader, and as Sales
team the second previously created team (team2).
- Save the new lead.
Before this commit, when we save the lead, the sales team will change,
to set the default sales team for the chosen Salesperson, in this case
team1.
opw-2005924
closesodoo/odoo#33898
Signed-off-by: Simon Goffin (sig) <sig@openerp.com>
In order to be consistent with Lead Generation, we need to use Industry tags instead of technology tags.
In addition, we reduce the number of tags to keep only the relevant ones.
Task ID: 1941555
closesodoo/odoo#33434
Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
Purpose of this commit is to clean notification process: calls, methods
API, method name, variable propagation.
Contains notably
* simplify API of methods used to group recipients when sending notification
emails;
* improve and rename methods used in email notification process;
* move some methods on model itself as non mail thread records could be
mass-mailed and _notify_email_headers could be called on other records;
Related to task 1943901
Linked to PR #32404
Message post should always be called on a record (ensure_one). That way we
ensure posting a message is always done in a record's context with right
values computed (reply_to, followers, ...)
Message_notify can be called on record or on mail_thread and must have
partner_ids. It is based on the recently modified user_notification mechanism
and allow to notify a partner on a record or just to push him a message
(aka, not linked to a record).
Small performance improvement
* browse recipients instead of search in _notify_email_recipients;
* todo in future optimizations: mayybe be improve by searching on ids
and is_blacklist immediately;
Related to task 1943901
Linked to PR #32404
Purpose of this commit is to clean some bits of code, notably calls to
message_post/log as well as notification methods. It will ease performance
improvement work.
Small optimization: account: read content after extension check
Parameter cleaning
* use message log with kwargs instead of args;
* remove message post after hook useless parameters;
* remove _notify_email_recipients useless message parameter;
* remove message_notify useless send_after_commit parameters;
* remove message post params matching default values;
Other improvements
* remove message_post commands support for partners and channels;
* only calls message_post with ids list for channels and partners. We
don't support mix of ids and command anymore to simplify code;
* remove support of private discussion in mail.thread adding partners
as recipients, as there is no use anymore;
Related to task 1943901
Linked to PR #32404
The goal is to be coherent with the user property.
Actually, company_id and company_ids on the environment are no fields.
Calling env.company_id returns a browse record, not an id.
This commit changes the method _get_default_team_id so that it removes
the xmlid reference to the default team. Instead, we will now use
the team sequence (with default team's sequence being set as 1)
and falling back to the next team with the highest sequence if the
default team got deleted.
Therefore, teams will now be ordered by sequence instead of name,
allowing the users to reorder their teams as they see fit
This commit also removes useless sudo when searching teams
Task: #1962182
PR: #32372
wip
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
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
Multi is the default api for methods, it is not necessary to explicitly
decorate methods with it, adds clutter and most people use it because
they see that the rest of the code uses it.
Done with `find . -type f -name '*.py' | xargs sed -i '/@api.multi/d'`
Purpose
=======
Some formviews are useless since there are so few relevant fields https://nimb.ws/1EdMV7
For instance, to create a new lost reason the user is forced to:
1. Hit create
2. Type in the name of the record
3. Hit save
4. Go back to the treeview
While he could simply type them away in an editable treeview.
The goal of this task is to allow for creation/edition of records in such models
directly from the treeview.
Specification
=============
Modify tree views from a given list of models for which the
treeview has to be made editable bottom.
If not specified otherwise, the content treeview should stay the same.
If a field is readonly/required/etc. in the formview, it should be in the
editable treeview as well.
Relabeling has to be done of the field itself, not in the view.
TaskID: 2026126
closesodoo/odoo#34577
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
Purpose
=======
Parentheses in the label of units of measure sometimes make
reading needlessly uncomfortable.
Specification
=============
Remove parentheses in the name of every standard uom.uom and hardcoded
occurence on views/field names.
TaskID: 2030444
closesodoo/odoo#34492
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>