Some tests sometimes require some more queries to be finished.
Task ID-2444908
closesodoo/odoo#65379
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
When merging leads final priority is currently the one of the lead considered
as the master lead. This is based on ``_sort_by_confidence_level`` who sorts
on confidence but not on priority.
We think final priority should be the highest one from merged leads. Indeed
if a top priority lead is merged into a low priority one we should not loose
the priority information. It is better to keep the final lead with an high
priority and let salesmen move it downwards.
LINKS
Task ID-2446759 (lead merge priority field management)
Task ID-2446883 (query counters fix)
PR odoo/odoo#65016
Purpose of this commit is to make clearer how final opportunity value are
computed or chosen when merging leads. Functionally nothing should change
with this commit.
LINKS
Task ID-2446759 (lead merge priority field management)
Task ID-2446883 (query counters fix)
PR odoo/odoo#65016
Purpose is to test internals of lead merge method, notably about values
of final opportunity. That way we ensure future changes will be reflected
in tests and regressions will be avoided.
LINKS
Task ID-2446759 (lead merge priority field management)
Task ID-2446883 (query counters fix)
PR odoo/odoo#65016
Purpose is to split assign tests related to results (leads being assigned,
with deduplication, compared to team and member domains) from tests related
to performance (query counters).
Assign process is a random process: randomizing teams leads to searching,
assigning and de-duplicating leads in various order. As a lot of search
are implied during assign process query counters may vary from run to run.
"Heavy" performance test included here ranged from 6K to 6.3K queries. Either
we set high counters maximum which makes those tests less useful. Either we
avoid random if possible which is what we decided to do by setting the seed
of random in tests.
SPECIFICATIONS
For results oriented tests remove query counters. Those tests should simply
ensure results of assign process, notably that even with random choice between
team and users we always have leads assigned with right domain and counts.
For performance oriented tests using query counters set random seed to have
a reproducible scenario and have less random in query counters.
LINKS
Task ID-2446759 (lead merge priority field management)
Task ID-2446883 (query counters fix)
PR odoo/odoo#65016
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 clean
SPECIFICATIONS
Set _check_company_auto on lead model to enable automatic company check when
updating company_id field.
Add a company check on user_id field to ensure user and lead company match.
Also add a company check on team_id to ensure team and lead company match.
Add a dynamic domain to be used in form view to limit available users to set
on leads to those matching domain.
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
Compute default team id for sales related documents. Note that this method is
not called by default_get as it takes some additional parameters and is meant
to be called by other default methods. Heuristic (when multiple match: take
first sequence ordered)
1- any of my teams (member OR responsible) matching domain
2- any of my teams (member OR responsible)
3- default from context
4- any team matching my company and domain
5- any team matching my company
Note: ResPartner.team_id field is explicitly not taken into account. We think
this field causes a lot of noises compared to its added value. Think notably:
team not in responsible teams, team company not matching responsible or lead
company, asked domain not matching, ...
We also improve various places where sale team is computed on sales documents.
Purpose is to try to use same heuristic as much as possible in various
team_id fields.
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
Currently when assignment runs all free leads are allocated to teams. They
are then assigned to members according to their capacity. This means that
no lead is kept free. If assignment is performed on a subset of teams this
means that other teams have no free lead anymore.
During assignment evaluate which teams still need to receive leads. This is
based on team maximum capacity. We consider a team should receive twice its
capacity as leads. That way members will receive leads and can pick some leads
in team unassigned pool of leads.
e.g. a team has a total of capacity of 90 leads / month among its 3 members.
When running a daily assignment process, an equivalent of twice this running
time is assigned to members (see previous commits). It leads to assignment
of (90 / 30) * 2 = 6 leads. Twice this count is allocated to the team aka
12 leads. Remaining leads will be allocated in next assignment run or are
available for manual assign.
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
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
PURPOSE
Prepare sales team membership and lead assignment improvements by
reorganizing and cleaning some code bits.
SPECIFICATIONS
Tools methods should be private by default to indicate those are not part of
official convert or merge API for leads. In this commit we make convert and
merge tool methods private, keeping only main API methods public.
LINKS
Task ID-2428882
Prepares Task ID-2086889
COM PR odoo/odoo#64196
ENT PT odoo/enterprise#15610
With a recent commit[1], we fixed the issue of false warning while changing
the partner on lead. But that fix ignored the fact that the lead has an
automatic formatting that may lead to false warning.
Right way to detect a phone number change is
* lead phone is different from partner phone;
* lead formatted phone is different from partner formatted phone;
If those two conditions are met we are quite sure numbers are different and
not only differs in their formatting.
In this commit we also fix inverse of phone number. When updating lead phone
value we have to use the same heuristic to update partner phone value. That
was we avoid unnecessary partner update when only formatting differs.
Tests are added to ensure new behavior and that ribbon message is effectively
trig erred with correct content.
LINKS
Task ID-2390287
[1] - https://github.com/odoo/odoo/commit/d29862c1de6208f7fdb7c8104afe0d35241d130bclosesodoo/odoo#63521
X-original-commit: 5154f40544e7913f7bcd0ff73f034d111700f580
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Co-authored-by: Ijas Ahammed <ija@odoo.com>
Co-authored-by: Thibault Delavallée <tde@odoo.com>
When you mark an crm.lead as "won" using the "mark as won" button, the user
will be shown a rainbowman under certain conditions. This happens notably
when you win your first lead.
This commit fixes the 'ir.actions.act_window_close' model to allow the
'effect' key within its readable fields (even if it's not a real field) which
is in turn picked up by the web client to display the infamous rainbowman.
At the same time, we add the tour that is testing the rainbowman of the crm app
in the test suite, since it was missing and never actually executed by the CI.
Some fixes were also necessary to make the test run properly.
Task ID-2394745
closesodoo/odoo#63259
X-original-commit: 47079f67f586adf45da15fc98dbc81571f7a9100
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
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>
When we clear the configuration parameter crm.pls_fields unlink method is
called. In order to have a correct dynamic compute based on this parameter
we need to re-evaluate the depends. This is done by overriding unlink of
ir.config_parameter, like already done at create and write.
Task-2196200
closesodoo/odoo#61293
X-original-commit: d04cc4df4ec28816aeb6d1d7c7fc0e547fd13fa5
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Problem
-------
Sales people can have restriction on partner they can see
Private addresses, multi company, ....
When they convert a lead to opportunity, it's currently possible
that the wizard will find and link a partner that the current user
cannot see.
Solution
--------
Field that are now computed store field, that were previously
normal field with onchange, should not be computed as sudo
to respect the record rule
closesodoo/odoo#59957
X-original-commit: 182fa38d7f28a92e7171c4ee3a42c8f73217b765
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
To investigate a bit. Sometimes a few extra queries are generated.
Task ID-2359847
closesodoo/odoo#59869
X-original-commit: 36bb56a5e9704c76e84960ec84588524b52406f8
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Handle salesmen allows to assign responsible to leads using a round robin like
algorithm. Currently a write on each lead is done to update its team and
responsible, even if number of leads is far greater than number of available
users to assign.
Current implementation can be simplified by doing one write per sales person
to assign on its batch of leads, or a single write if no salesmen has to be
assigned.
Performance counter on a mass convert wizard on 50 leads show that we gain
about 9% of queries (125 on 1471) with this simple optimization.
Task ID-2351604
PR #59084closesodoo/odoo#59324
X-original-commit: 973a2998666813ca4fbe90f1b486c1b18091c4e7
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Purpose of this commit is to
* move tests about mass management of leads (mass assignment + mass convert
wizards) in its own file to ease writing of tests;
* add some performance tests :
* performance for assignment;
* performance for convert wizard in mass mode;
Task ID-2351604
PR #59084
X-original-commit: 950dd491bc4b680e0bcfab83815313e909a3c282
The method _compute_probability has a dynamic depends, that depends on the
crm.pls_fields config parameter. When installing the DB, the depends is
evaluated. If the config parameter is modified afterwards, the depends is not
re-evaluated as the registry is not rebuilt.
The result is that when modifying the config parameter, if an optional
pls_field's value is modified on a record, the compute won't be triggered, as
that pls_field is not in the compute's depends.
This commit force to re-setup the registry after a modification (or the
creation) of the crm.pls_fields config parameter, in order to force the
depends of the _compute_probability method to be updated.
Task ID: 2341829
closesodoo/odoo#58165
X-original-commit: e95afbedc18d198454c7f66b523c4cafb19a4066
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Signed-off-by: David Beguin <dbeguin@users.noreply.github.com>
Setting a lead to won or lost should not impact others leads' probability
until they are modified.
Tests have been added to ensure that.
Task ID: 2254543
closesodoo/odoo#57681
X-original-commit: 7edc12e366659d226d56197e09bd65d17c80bd2f
Signed-off-by: Toufik Benjaa (tbe) <tbe@odoo.com>
Signed-off-by: David Beguin <dbeguin@users.noreply.github.com>
PURPOSE
Avoid automatic partner finding and update on lead to erase too much data.
RATIONALE
On crm.lead, the address fields, email_from and phone, are computed field
since saas-13.3 based on the partner_id. Previously they were synchronized
with an onchange on partner_id which was never triggered during automatic
flows on the lead.
Now computed field are triggered each time the partner_id is written.
Problems
- If someone uses the mass conversion with the action "Use existing partner
or create", the partner is found for each lead with the method
_find_matching_partner. This method can find any partner with a name that
contains the lead name, the lead contact_name or partner name. It can find
wrong partner. Previously, only the partner was changed and the contact
information remained on the lead. Now, all the information are erased with
the wrong partner information.
- If at creation all the address information are set and the partner_id
as well, the address field from the partner won't be synchronized.
The lead will end up with the address information we forced.
During the conversion to opportunity, the partner_id defined on the
lead, will be written again. It will trigger the synchronization
of the address field on the lead. Those info can be incomplete or wrong
You will end up with a data loss.
SPECIFICATIONS
Tell _find_matching_partner to match partner only based on exact email address
in the case of mass convert. Avoid fuzzy matching based on name likeliness.
During opportunity conversion, don't write the partner_id if the partner is
already the one set on the lead.
LINKS
Task ID-2316828
PR #55825
X-original-commit eed0a31e1e2c428c94dae4703c9575534a49ec1d
X-original-PR #55194closesodoo/odoo#55838
X-original-commit: e82b5a92f44709592b25fa66d9555d64abef1ec9
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
PURPOSE
Distinguish synchronization of partner values on lead: address fields (all
or none), classic fields (propagate if set) and special cases (names-alike).
SPECIFICATIONS
Follow up of https://github.com/odoo/odoo/commit/f8179007f9aa662be7318edeb18426ea1c906c15
Context: many fields are now synchronized from the partner_id: address fields
as well as other contact fields. A first commit 9c9f477f04e8f4ee9b18092fe894890c2ab31b58 kept the value
from the lead if the value from the partner was empty. This lead to mixed
address fields.
A second commit fixed that behavior f8179007f9aa662be7318edeb18426ea1c906c15 by taking the value from
the partner only when it was set.
Problem: This erases too much information.
```
>>> lead.partner_name
'testtest'
>>> partner_id.name
'testtest@mailinator.com'
>>> partner_id.parent_id
res.partner()
>>> partner_id.is_company
False
>>> lead.write({'partner_id': partner_id.id})
>>> lead.partner_name
False
```
We indeed need a consistent address but for the other fields we want to keep
the maximum of data.
SOLUTION
For the address fields, take all the values from the partner if one of the
address fields is defined, otherwise keep the information defined on the lead.
For all the other fields keep the lead information if the partner information
is empty.
LINKS
Task ID-2316828
PR #55825
X-original-commit https://github.com/odoo/odoo/pull/55194/commits/f53fba6663a34e8e6b13354dde3dc225f5814de3
X-original-PR #55194
X-original-commit: b136df8530279a54c9be96beeea9bdda01643000
Followup of 9c9f477f04e8f4ee9b18092fe894890c2ab31b58 and f8179007f9aa662be7318edeb18426ea1c906c15
In some cases (notably event_crm addon in 13.4) a country record is propagated
instead of a country ID; converting as write values ensure we always deal with
IDs in all cases.
Also add some tests to cover more test cases. Notably phone and email behavior
in 13.3 compared to other fields. For example phone is kept is partner's phone
is void. It may leads to inconsistencies (partner US, Belgian phone number).
We think it is better to keep values and let salesmen change them than
voiding values customer gave.
PR #55390
Task ID-2311981
closesodoo/odoo#55412
X-original-commit: a26735f516e48acb77e234862e17e29be71d7d1d
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Consider a lead with valid email and/or phone. Some process assign a partner
to it, like mass convert. This partner has no email and/or phone. We should
not void lead values for email and/or phone, as this is information loss.
This is a followup of 89ca89ca92 . Test cases are added to try to
avoid future regressions.
Task ID 2311981
PR #54619
X-original-commit: 0b69d98cf4cbd2c99d7c3fb510e324f49652eea5
FIXUP of 9c9f477f04e8f4ee9b18092fe894890c2ab31b58
[FIX] crm_lead: do not erase computed field based on partner
Don't erase the field on the lead if you emptied the field partner_id
but erase them if you select a partner_id that have empty value
for the corresponding field
otherwise you end up with mixed address field.
Make an exception for the phone and the email_from
Keep the value from the lead if the partner_id has no value
for those field
X-original-commit: ed3979f84e65ebfa9534f12196a8fa41cade8370
Issue:
When you write partner_id = False on a lead
it erase all the values computed based on the res.partner
this lead to data loss during the conversion to opportunies
by the lead assignation process
Solution:
Revert to v13.0 behavior, don't erase the value
of the address, phone, email when the partner is set to
False
+ Fix typo in method name
X-original-commit: 21db6cf93fea7d07ec4a8655fc6030a177abc36f
RATIONALE
Activities are a way to organize our daily pipe. Notably in a sales pipeline
salesmen may have multiple leads with activities to perform in the next few
days. We would like to be able to have a list view displaying a list of leads
with "my" deadline, and to order leads based on this field.
PURPOSE
As activities are linked to records through a one2many and as my activities
are only a subset of those activities, it is impossible to store a field
on lead model. Indeed it would depend on the current user which makes storing
it impossible.
However ordering on a column in list view asks for a stored field. As it is
not possible, this commit proposes to hijack the web client and search of lead
model in order to allow it.
SPECIFICATIONS
Introduce a activity_date_deadline_my field, computed and searchable that
behaves like activity_date_deadline. It is filtered on current user activities
instead of being global to the record activities. "My" deadline is the earliest
deadline of my activities, even in the past.
Ordering through web client calls search_read with an order parameter set.
Search_read then calls search. In this commit we therefore override search
to intercept a search without count with an order on activity_date_deadline_my.
In that case we do the search in two steps.
First step: fill with deadline-based results
* Perform a read_group on my activities to get a mapping lead_id / deadline
Remember date_deadline is required, we always have a value for it. Only
the earliest deadline per lead is kept.
* Search leads linked to those activities that also match the asked domain
and order from the original search request.
* Results of that search will be at the top of returned results. Use limit
None because we have to search all leads linked to activities as ordering
on deadline is done in post processing.
* Reorder them according to deadline asc or desc depending on original
search ordering. Finally take only a subset of those leads to fill with
results matching asked offset / limit.
Second step: fill with other results. If first step does not gives results
enough to match offset and limit parameters we fill with a search on other
leads. We keep the asked domain and ordering while filtering out already
scanned leads to keep a coherent results.
All other search and search_read are left untouched by this commit to avoid
side effects. Search_count is not affected by this commit.
As web client order availability is simply based on field being stored we
have to allow hijacking its value. A new option 'allow_order' is added that
display the order icon in list view column headers. It allows calling
search_read with an order based on the column but nothing more. Using it
on a not-stored field will give a warning log and ORM ignores it by default.
LIMITATIONS
At least following limitations apply
* search on "my activities" gives a list of ids that is used for searching
and ordering. It means that having too much activities on a given user can
result in poor performances.
-> we consider that activities assigned to a given user should be kept
under control. Leads with activities for a given user should be a small
subset of leads without activities.
* ordering on activity_date_deadline_my always put those records on the top
(deadline asc or desc) whatever the actual ordering of order items given
to search. This is done to avoid complex implementation where deadline
would be used to order records within groups ordered by another field.
-> for example: order = 'priority DESC, activity_date_deadline_my ASC'
actually behaves like 'activity_date_deadline_my ASC, priority DESC'.
WARNING
This implementation is a hack. It has been done by professionals. Do not try
to do it at home.
More seriously this is hackish and should be avoided. IN our case we consider
that the use of activities in sales pipeline is mainly driven by "my activities
deadline", which is not necessarily the case with longer processes like tasks.
Moreover user tests tend to show that this feature could be interesting. It
will improve quality of Odoo CRM and its adoption by improving its daily
use. A framework solution has to be found. Until this is done we keep this
hack and hope it is not duplicated in other applications.
LINKS
Task ID 2276011
Prepares Task ID 2243124 (My activities in CRM)
PR #52232
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
PURPOSE
Get rid of email / phone behavior on lead that is hard to understand: if
and contact is set fields are readonly, if not they are editable.
SPECIFICATIONS
We want to be able to edit them if a partner is set. If we write on the
email/phone of the lead, it should write on the partner (and vice-versa).
Even a Falsy value is propagated to the customer. Reason is that if you update
a contact information, it should be available for all other records. Setting
a void value probably means you want to stop contacting this contact. This is
now also propagated.
SIDE NOTE: MOBILE FIELD
Mobile field is a bit different. Main phone contact field is phone, and is
placed in the main contact section of the lead view. Mobile is under a more
technical / detailled tab and is not completely synchronized with the partner.
Like zip, city or country, changing partner updates lead information but
changing lead values does not propagate those to the customer. Those fields
can be used for deal-specific information if needed.
Statistics: 5k crm.lead use mobile for 80k active records which means it is
a "lesser field".
LINKS
Task ID 2207636
PR odoo/odoo#48395
Upgrade PR odoo/upgrade#1025
PURPOSE
Prepare enhancements of sales team membership.
SPECIFICATIONS
Purpose of this commit is to prepare modifications in sales team management
notably by cleaning sales team tests. We also move some data preparation in
sales team. It allows to rely on some common data while doing sales team
then crm tests.
LINKS
Task ID 2086889 (sales team enhancements)
Task ID 2234698 (preparation lint)
Community PR odoo/odoo#49520
PURPOSE
Try to move from onchange / default_get to stored editable computed fields.
Behavior should be the same (computed or set by user), with support of
create / write / onchange field update without additional code.
SPECIFICATIONS
Update classic fields updated in some cases by onchange and/or default methods
by fields with store=True, readonly=False. It means their value comes either
from manual user input, either from trigger based computation.
Remove onchange and default_get when possible, leading to an unique computation
method and clearing fields definition.
Also clean some fields definition inconsistencies, notably required fields
that should instead be correctly computed or default that have no real meaning.
SPECIFIATIONS: CONSTRAINT USER_ID / TEAM_ID
In this commit we also remove all the better implementations of "not really a
constraint" constraint about user_id and team_id. Indeed as this is a computed
field normally we should not have to call the onchange manually, even through
a hackish call to a falsy constraint (see fdc8749, 222cca2, 4e8ebc7 ). You are
all inferior to SM team.
SPECIFIATIONS: DATE_OPEN
Assignment field, namely ``date_open``, has a random definition as it seems
linked to assignation, with several behaviors intended
* ce39ca8a97 : reset only when going from
no salesman to a salesman (aka, keep assignation when changing)
* 8e540558ee: reset when changing salesman
We choose to keep first implementation as it seems a bugfix broken again
by second commit. It will also replace the ``assign_date`` defined in
``website_crm_score`` module.
SIDE EFFECTS
Several side effects occur with this commit. Indeed behavior is not always
exactly the same, notably as code rewriting allowed to fix some issues,
incoherent behavior or was simply not able to achieve exactly the same
result. Notably
* at lead creation: default probability is the one coming from PLS and not
0.0 anymore, since field is already computed. Synchronization with PLS
still works the same way (change probability, you are out of syn);
* various user_id / team_id combinations notably in convert / merge wizards
may change, notably we do not reset team_id if user_id is reset. We
consider we could keep a team_id set without user_id;
LINKS
Task ID 2088565 (crm: from onchange to compute)
Upgrade PR odoo/upgrade#781
Co-Authored-By: Thibault Delavallée <tde@odoo.com>
Co-Authored-By: Florent Lejoly <fle@odoo.com>
SPECIFICATIONS
Improve heuristic used to find lead to convert duplicates
* check email_normalized instead of email_from, as it may contain formatted
emails. Normalized email are sanitized and normalized version of emails
and ease comparisons;
* use lead email if its customer has no email;
* if no email is available but a customer is set, use it anyway;
This notably reverts 2917b38f28 . Indeed no reason has been found why
this fix is necessary.
LINKS
Task ID 2088565 (crm: from onchange to compute)
SPECIFICATIONS 1: FORCE_ASSIGNATION
Move and rename force_assignation in convert wizard. Purpose is to move the
force_assignation field from mass convert wizard to its base convert wizard
used through _inherit. It allows to avoid relying on context propagation in
some methods. This field is also renamed as assignation as other meaning in
English.
SPECIFICATIONS 2: OPPORTUNITY_IDS
Improve search of duplicate by always ensuring duplicated are computed using
active_test. Also add the active_test on the field as otherwise computed
results are actually not visible to the user.
Generic opportunity_ids field is also renamed to better indicated it is used
to store duplicates and avoid thinking it holds data related to batch convert
or merge.
LINKS
Task ID 2088565 (crm: from onchange to compute)
Upgrade PR odoo/upgrade#781
PURPOSE
As CRM is going to be updated (onchange -> compute, code improvements, better
management of sales teams) cleaning and improving code is a necessary first
step.
SPECIFICATIONS
Purpose of this commit is to rewrite code located and/or used in convert or
merge wizards. Indeed it holds unnecessary variables, dictionaries manipulation
that hides the real business flow, badly named variables, unclear methods, ...
Logic of those wizards seem quite simple but is hidden behind a wall of
bloated code.
Notably for wizards
* try to set explicit arguments in methods;
* less use of context values, replaced by arguments when possible;
* try to make better use of lead2opportunity wizard in its mass wizard that
inherit from it, notably by correctly calling super;
Notably for tools
* ``get_duplicated_leads`` was just a shortcut to ``_get_duplicated_leads_by
_emails``;
* ``_get_duplicated_leads_by_emails`` is renamed to ``_get_lead_duplicates``
because email is not the only way of finding duplicates;
* try to make better use of record sets instead of propagating ids, notably
for partner. For example input of ``_get_lead_duplicates`` or output of
``_find_matching_partner``;
* ``_create_lead_partner`` rename to ``_create_customer``, and its sub
method ``_create_lead_partner_data`` to ``_prepare_customer_values``;
* ``handle_partner_assignation`` was difficult as its use is not documented
and its docstring was not updated. Parameter have been renamed to be more
explicit about what it does. Method is renamed to ``handle_partner_
assignment`` as assignation has other meaning in English;
* ``allocate_salesman`` is renamed to ``handle_salesmen_assignment`` to match
the partner assignement and code is slightly cleaned;
No functional change should occur with this commit. Tests have been gradually
added to try to ensure behavior does not change.
LINKS
Task ID 2088565 (crm: from onchange to compute)
PURPOSE
As CRM is going to be updated (onchange -> compute, code improvements, better
management of sales teams) ensuring data integrity in tests is necessary to
avoid having hidden issues or tests difficult to debug.
LINKS
Task ID 2088565 (crm: from onchange to compute)
PURPOSE
As CRM is going to be updated (onchange -> compute, code improvements, better
management of sales teams) cleaning and improving code is a necessary first
step.
SPECIFICATIONS
Add tests. Amazing. Notably about matching partner / duplicate based on email
as there is some weird behavior.
closesodoo/odoo#45477
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Following changes needing ir.model.access on transient models too.
Remove groups declaration on the action to move it to ir.model.access
when possible.
Rules are strict by default with no unlink access by default and high
priviledge asked. Adaptations may be needed later.
Write access is given as a wizard may need to be modified in case the
action triggers an error and the user has to correct a value
account*: use account.group_account_user for all transient by default
remove account.print.journal relic
stock*: use stock.group_stock_user by default
survey: survey user can send invitations
mail: allow any employee to execute wizards
additional verifications are made to ensure they are executed
only on the documents the user has access to you
give portal access to mail.compose.message as portal still does
some actions like posting messages on the forum
add ir.rule to avoid reading somebody else messages
increase the query count because of undeterminist count
crm: saleman for lead2opp, manager for massmailing
partner manager for actions linked to partners
avoid a write in test_lead_lost
sms: any employee can send sms
mrp: mrp user can execute wizards
give unlink access as making write during do_produce operation
base_import: employees can import files
delivery: stock user can deliver
event_sale: sale user can configure the wizards
event user inherit from sale rights
gamification: employee can give badge
google_service: resolve FIXME
hr: add specific rights
manager can set a plan according to group on button
anyone who can write on an employee can register a departure
hr_expense: set rights based on buttons
hr_holidays: an approver can make a summary report
hr_recruitment: recruiter can refuse a candidate
hr_timesheet: can use the wizard if can create a timesheet
l10n_eu_service: managers can create fiscal positions
mass_mailing: same group as on mass.mailing.list
membership: accountant can create invoice from membership
payment: accountant can create a link
as the source is an account.move
keep the payment.acquirer.onboarding.wizard to system user
only as it is called during company configuration
point_of_sale: PoS manager only can use wizards
never create closing_balance_confirm_wizard records
product_expiry: stock user has rights on stock.picking
product_margin: access from accounting menus
repair: same rules as for above models
sale: set ir.rule for self wizard only
add rule from model introduced in payment to add salesman group
sale_crm: saleman can create a quotation from a lead
sale_coupon: any saleman can generate coupon
add self ir.rule
sale_product_configurator: salesman can select product variants
snailmail: employee can send letters
website: designers can write on website
website_crm_partner_assign: same rule as group on action
website_sale: sale ACL as for payment.acquirer.onboarding.wizard
website_slides: anyone can send invitation
base: base.language.*: allow employee (cf lang_install)
change.password.user: can not read change password wizard of
other users
test.*: no access is needed
Courtesy of Damien Bouvy, William Andre and Antoine Prieëls for review
of acl
PURPOSE
As crm will soon evolve (onchange -> compute, code improvements, better
management of sales teams) cleaning and improving tests is necessary to avoid
regressions.
SPECIFICATIONS
This wizard has no tests at all. Even if it not really complex it is better
to have some tests ensuring at least marking a lead as lost with a reason
correctly updates it.
LINKS
Task ID 2180521 (add tests for crm wizards)
Task ID 2056759 (remove crm.partner.binding mixin)
Task ID 2088565 (crm onchange -> compute)
Community PR odoo/odoo#43473
PURPOSE
As crm will soon evolve (onchange -> compute, code improvements, better
management of sales teams) cleaning and improving tests is necessary to avoid
regressions.
SPECIFICATIONS
Improve and clean tests about leads and opportunities merge.
Some strange behaviors spotted :
* user_id / team_id interaction is somehow unclear;
* probability is not taken into account in confidence level, which is very
very strange;
LINKS
Task ID 2180521 (add tests for crm wizards)
Task ID 2056759 (remove crm.partner.binding mixin)
Task ID 2088565 (crm onchange -> compute)
Community PR odoo/odoo#43473
PURPOSE
As crm will soon evolve (onchange -> compute, code improvements, better
management of sales teams) cleaning and improving tests is necessary to avoid
regressions.
SPECIFICATIONS
After ff6b35f759 that added some first tests, this commit will add more tests
notably about convert wizards.
Notably
* add tests for crm.lead2opportunity.partner wizard, notably options about
action (do nothing, exist or create partner), as well as some corner cases
like stage update, lost leads, ...
* rewrite and improve tests about crm.lead2opportunity.partner.mass, aka the
mass converted wizard that implements some random behavior on top of the
crm.lead2opportunity.partner wizard;
Some strange behaviors spotted
* partner action works on lost leads, but not the convert;
* user_id / team_id / stage_id coherency is not enforced during convert
as it relies mainly on onchanges that are not called;
LINKS
Task ID 2180521 (add tests for crm wizards)
Task ID 2056759 (remove crm.partner.binding mixin)
Task ID 2088565 (crm onchange -> compute)
Community PR odoo/odoo#43473
Try to understand a bit this code with comments. Some unnecessary code is
removed, and some parameters are added to try to understand the various flows,
but main purpose is to understand that mighty spaghetti, not destroy it.
LINKS
Side effect of Task ID 2056759 (remove crm.partner.binding mixin)
Side effect of Task ID 2088565 (crm onchange -> compute)
Community PR #43127
Enterprise PR odoo/enterpreise#7656
Related: odoo/enterprise#7656
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
PURPOSE
As crm will soon evolve (onchange -> compute, code improvements, addition of
new features) cleaning and improving tests is necessary to help avoid issues.
SPECIFICATIONS
In this commit we add tests for the lead 2 opportunity converters. Indeed
it is strange that such a critical wizard has so few tests. Notably the
use of single-lead / multi-lead mode is more tested, allowing to see that
code is somewhat oldish.
LINKS
Side effect of Task ID 2056759 (remove crm.partner.binding mixin)
Side effect of Task ID 2088565 (crm onchange -> compute)
Community PR #43127
Enterprise PR odoo/enterprise#7656
Purpose of this commit is to clean a bit crm tests, notably lessening data
created in tests and removing / improving some low level tests. As we are
about to remove onchange / default and replace them by editable computed
fields it is easier to clean some tests and data beforehand.
This commit is a preliminary cleaning coming from task 2088565 about CRM
onchange to compute methods update.
LINKS
Task ID 2088565
Community PR #42344
Enterprise PR odoo/enterprise#7403
Related: odoo/enterprise#7403
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
PURPOSE
Add some improvements in mail gateway: remove private discussion, improve
bounce management, allow resetting bounce counters, improve automatic set or
reset of blacklists and ease mass mailing inheritance.
SPECIFICATIONS
Parsing email values: make message_parse effectively prepare all required
values for later processing
* update message_parse to add some more data directly in parsed dictionary
and avoid having to parse value again in later processing and computation.
* notably recipients computation is now done directly in parsing. It
includes email check and reconstruction using tools methods. That way
routing just has to handle those values and not compute part of them;
* from and cc are correctly managed with parsed and cleaned (sanitized)
versions in dictionary;
* remove all code decoding message header and replace them by fetching
the parsed value instead;
* filter parsed values before calling message_post to ensure right values
are given to it instead of having to manage them in message_post. Indeed
caller has to give the right input;
* make parsing sub-methods (extract payload, post process payload) have
a dictionary as input and output to always manage a dictionary of values
through the parsing methods and update their namespace;
Routing: remove deprecated code parts
* remove use of email_references regex. Indeed emails are routed using their
messageId and not the regex anymore since several versions [1];
* clean some unnecessary variables;
* simplify variable type input, like message_parse accepts only valid
email.message instances and to avoid several decode / encode. Tests are
updated accordingly;
Update docstrings of those methods.
LINKS
Related to task 1893155
Linked to PR #33340
[1] See df037e2959 and 0028c42136