PURPOSE
All unassigned leads should be assigned to teams as soon as possible to ease
lead analysis.
Purpose of assign thresholds is to ensure sales people receive at least this
amount of leads within 30 days, counting lost and won leads. Giving them leads
regularly is also one goal of automatic assign.
SPECIFICATIONS: TEAM ALLOCATION
Team assignment has to be updated as we may have team domains that overlap.
We therefore remove maximum number of leads to allocate to teams. Instead all
available unassigned leads are allocated within teams.
- Solution: assign all available leads and not a count based on team's
capacity. This notably reverts the main goal of odoo/odoo@6df2f0cfc0
(see odoo/odoo#48422)
This assignment process is done proportionally to the team capacity. It is
computed as the sum of each member's maximum assignment counter. This means
that with a team having twice as much sale capacity than another team sharing
the same domain: first team should receive about 2/3 of leads while the second
one should receive the remaining 1/3.
- Solution: assign lead one by one. Choose a team randomly using a weighted
random algorithm, based on team's members capacity.
SPECIFICATIONS: MEMBER ASSIGN
Counting every lead whatever its state may lead to an inconvenient situation.
Moreover salespersons may opt-out from assign by setting their max capacity
to 0, for example when going on holidays.
When doing that lead assignment is not smooth and getting back to a full
pipe may take several days. To solve that issue a compensation is added in
assignment quota done to sales people. Salespersons having few leads will
get a boost in assign as soon as they get back in assign process. When being
near maximum compensation is nearing 0 and daily quota is given.
PERFORMANCE
During team assignation, assigning lead one by one may cause performance issue.
Since PLS is computed at each flush, so we want to flush after a bunch of lead.
To solve that we obviously need to not commit at each assignation but
also avoid to search for duplicate at each assignation, that why the
search for duplicates is done at the beginning of the process and stored
in memory.
LINKS
Task ID-2444908 (assign fixes)
Task ID-2489951 (assign process improvements)
COM PR odoo/odoo#70172
X-original-commit: 83f72711e7affa8b0ad997b9ee262326e9577d54
When running the cron is should assign leads based on its frequency. If cron
runs once every day, work_days given to sub methods should be 1. If it runs
more than once day it should be less than 1. We therefore remove the *2
multiplier and support fraction of days.
As assign process will soon change, assigning more strictly compared to
salespersons capacity will not be an issue anymore. Assign process is best
designed to run every few hours (~4 times / day) or each few days. Code and
work_days are updated accordingly.
LINKS
Task ID-2444908 (assign fixes)
Task ID-2489951 (assign process improvements)
COM PR odoo/odoo#70172
X-original-commit: c59ba43d1e9eb0c016b9a113c9475dec28fa413b
Automatic assignment is performed on leads that are unassigned and not won
nor lost. This commit fixes the condition that should be based only on
stage being set to a stage with ``is_won`` being True.
Current code fails with won unassigned leads that are assigned even if it
should not. This happens rarely as won leads have probably been taken care
of. However having the right condition ensure filtering won and lost leads
is not correctly done.
Followup of odoo/odoo@5016b47a06 (see odoo/odoo#48422)
LINKS
Task ID-2444908 (assign fixes)
Task ID-2489951 (assign process improvements)
COM PR odoo/odoo#70172
X-original-commit: d9fe86ec2ca6459a34b31e65c0702d8a80a7ec61
Co-authored-by: Thibault François <tfr@odoo.com>
Co-authored-by: Thibault Delavallée <tde@odoo.com>
PURPOSE
Purpose is to try to reduce friction between searches in loops, team assign
on leads and unlink during merge process that unlink leads and forces flush
/ cache reset, as well as PLS computation.
SPECIFICATIONS
During team assignment setting team on leads one lead at a time may cause
performance issue. As PLS is computed at each flush we want to flush after
a bunch of lead. For that purpose we need to avoid too much commits and
also avoid to search for duplicate at each assignation.
We therefore perform the search for duplicates before going into allocation
and use a cache through loops to ease using pre-fetched information.
Unlinking duplicates at each iteration is also sub efficient as it causes
recomputation or invalidation. We therefore aggregate all duplicates to
unlink and unlink them in the main team-based loop instead of the sub loop
that is lead-based.
LINKS
Task ID-2444908 (assign fixes)
Task ID-2489951 (assign process improvements)
COM PR odoo/odoo#70172
X-original-commit: c5310102210fb9afc6ab786f4c8f6eaf5aee59bb
Co-authored-by: Thibault François <tfr@odoo.com>
Co-authored-by: Thibault Delavallée <tde@odoo.com>
New leads are automatically assigned to sales team and salesman during assign
process. Some of those leads are duplicates of existing opportunities. If a
new lead is merged into an existing opportunity, the opportunity is the master
data and the lead is duplicated. However the opportunity should keep its sales
team and not be assigned to the team being under automatic assign.
Before this commit, the merge was forcing the crm team to the 'current' team
during auto assignment and thus it was changing the team of the opportunity.
In this commit we now assign team to lead to merge before the merge and do
not force the crm team during merge process.
LINKS
Task ID-2444908 (assign fixes)
Task ID-2489951 (assign process improvements)
COM PR odoo/odoo#70172
X-original-commit: 356a55053eb1cc49ae6eed0e58338cff08eddc42
PURPOSE
Goal of ``assignment_max`` is to make sure sales receives this amount of leads
within 30 days. Counting lost or won leads is therefore necessary to effectively
count all leads received those last 30 days.
SPECIFICATIONS
Change ``lead_month_count`` computation to take into account archived and won
leads. We consider now that goal of ``assignment_max`` is to make sure sales
people receive this amount of leads within the 30 days at max.
This allows to avoid archiving leads to get a new batch of leads to handle.
Also done leads should be counted as it is part of the month job.
LINKS
Task ID-2444908 (assign fixes)
Task ID-2489951 (assign process improvements)
COM PR odoo/odoo#70172
X-original-commit: 23feb1a467e0a441eb775be26c96af697d74506f
Change domain of ``_get_lead_duplicates``: lost and not win lead currently
means lead with a probability != 0 and != 100. This is not always accurate as
you may have a lead with 100% win probability but that is still not won.
Instead search for active lead and with stage_id.is_won = False .
LINKS
Task ID-2444908 (assign fixes)
Task ID-2489951 (assign process improvements)
COM PR odoo/odoo#70172
X-original-commit: 31e8d3cf03025085b5ae9db67536a1110bf3e484
This commit contains two main preparatory changes in tests
* 1) lead_month_count will be changed to count lost lead as well. So
archiving leads before running the test doesn't reset the counter.
Lead needs to be unlinked in order to make tests reproducible;
* 2) assertMemberAssign checked the validity of the team domain. Normally
all lead assigned to the member should match the domain of its team.
This assert is not always verified since we force the team after a
merge of duplicated leads. Final merged lead may not match team domain
anymore as final properties depend on all merged leads.
Some tests are also added :
* add tests for master lead team_id and user_id values when merging leads
in assign process;
* add tests using email_normalized check in duplicate finding to ensure that
normalized emails are used for duplicates and not only exact match;
* add tests for won / lost inclusion in ``_get_lead_duplicates``, as well
as different between probability=100 and stage.is_won = True . This is
going to change in upcoming commits, hence some test to highlight it;
* add tests counting existing leads for assignment purpose;
* add tests for assignment_max maximum leads allocation as well as max=0
meaning salesperson is opt-outed from assign;
* add tests for default user / team / stage computation for leads;
* add tests about leads taken into account in assign process (currently
failing with won unassigned leads);
We also add some flush to ensure some fields notably related to probabilities
are flushed before counting queries.
LINKS
Task ID-2444908 (assign fixes)
Task ID-2489951 (assign process improvements)
COM PR odoo/odoo#70172
X-original-commit: bd3444085974f4e12287c2f5da4fb33308cd6180
Co-authored-by: Thibault François <tfr@odoo.com>
Co-authored-by: Thibault Delavallée <tde@odoo.com>
If country is updated on a record inheriting from mail.thread.phone
its sanitized number should be computed again. Indeed without this
trigger it is not computed and may lead to inconsistencies between
phone numbers and sanitized number.
Task ID-2528169
closesodoo/odoo#70734
X-original-commit: odoo/odoo@d00b291167
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Currently phone_sanitized computation on lead model works only if crm_sms
is installed. Indeed an override of ``_phone_get_number_fields`` is missing.
However ``_sms_get_number_fields`` coming with ``crm_sms`` and its ``sms``
dependency hides the issue as those modules are auto-install. However if
``crm_sms`` is uninstalled phone_sanitized is not correctly computed anymore.
Task ID-2528169
Oversight of odoo/odoo#45315
X-Original-Commit: odoo/odoo@45ae2922e5
Regarding of the `display_default_code` context value, `display_name` is
supposed to return the product code or not, eg:
> product.display_name
> '[FURN_6666] Acoustic Bloc Screens'
> product.with_context(display_default_code=False).display_name
> 'Acoustic Bloc Screens'
But since the context was not considered when accessing this field, it would
always return the cached value, which was set from the first time that field
was read, with the `display_default_code` value used at that time.
tl;dr: `display_name` was ignoring the context once cached.
One of the critical issue was that internal code were displayed on the eshop
cart (not the eshop itself), see `name_short`.
task-2517830
closesodoo/odoo#70739
X-original-commit: b5b4d38adf1f3960cda21b795a26e67b978b2901
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Signed-off-by: Romain Derie <rdeodoo@users.noreply.github.com>
It seems some ppl are sharing the same bank account accross multiple journals.
issues:
2527148
2527994
2527894
...
closesodoo/odoo#70704
X-original-commit: 9b3506523659b06440b46664eeb83952cc30694e
Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com>
Currently, none of the classes derived from Interface use `super`. If
it's added, for example by adding this to `SocketInterface`:
```
def __init__(self):
super().__init__()
```
, a deprecation warning will appear in Python 3.6 and 3.7:
```
2021-04-30 13:14:25,000 24736 WARNING ? py.warnings: /home/pi/odoo/addons/hw_drivers/iot_handlers/interfaces/SocketInterface.py:11: DeprecationWarning: class not set defining 'SocketInterface' as <class 'SocketInterface.py.SocketInterface'>. Was classcell propagated to type.new?
class SocketInterface(Interface):
```
In Python 3.8 this is no longer a warning and becomes a `RuntimeError`.
The reason this happens is that `InterfaceMetaClass` caches the results
of the `__new__` calls it does in `interfaces`. CPython's data model
specifies that when calling `__new__`, the cell for `__class__` needs to
be passed along to the parent class: https://docs.python.org/3/reference/datamodel.html#creating-the-class-object .
See https://docs.python.org/3/c-api/cell.html for a definition of what
a cell is.
Because of the caching, this doesn't happen when `__new__` is called
multiple times for the same class. In the case of the `SocketInterface`
example, `__new__` is called twice: first when it's imported directly by
`load_iot_handlers` (https://github.com/odoo/odoo/blob/841c016913a87133bf7257c62ae5f6bf7d99e06d/addons/hw_drivers/main.py#L81)
and second when `IngenicoDriver` imports it. The `__class__` cell is
different each time in that case. With the caching present, this means
the second cell isn't propagated correctly, resulting in the warning /
error.
After `load_iot_handlers` has finished, the `Manager`'s `run` method
iterates over `interfaces`, instantiating and starting the loaded
classes. Because of this, simply removing the caching appears to be
sufficient to avoid the issue while keeping the end result the same.
This issue was encountered while forward-porting a V13 PR, which adds a
`super` use to `SocketInterface`. The issue didn't occur in V13, because
the metaclass doesn't have a cache there.
I found a second problem resulting from the caching. I had noticed that
the `socket_devices` dict the `IngenicoDriver` had access to did not
have the same contents as the one the `SocketInterface` was operating
on. This means that whenever you called the `disconnect` function on the
`IngenicoDriver`, which deletes its entry from `socket_devices`, it will
always fail. The bluetooth driver seems to be impacted by the same.
It turns out the reason for that is how downloaded modules get loaded in
`load_iot_handlers`. That logic (using `exec_module`) doesn't actually
import the module, it just executes the code (registering the interfaces
and drivers as a side-effect). This means the module doesn't get cached
in sys.modules. That means that when another module (`IngenicoDriver`)
imports that same module (`SocketInterface`), Python will execute the
entire contents again, in this case effectively replacing socket_devices
with a new dict, which `IngenicoDriver` gets a reference to, while the
`SocketInterface` thread that runs is still using the old reference to
the original dict. Meaning the two are out of sync. See
https://docs.python.org/3/reference/import.html#the-module-cache for
details on how the import caching works.
The reason the classes get out of sync is because the metaclass doesn't
update interfaces when the second actual import happens, so the
`SocketInterface` class that gets instantiated holds a reference to the
old `socket_devices` dict. Removing the caching removes that problem as
well. If there's no caching, both the `SocketInterface` class and
`IngenicoDriver` will hold a reference to the same instance of
`socket_devices`.
X-original-commit: edffdd10f3ceb3826bf8897f93fa8290d7fce1ec
This commit was originally part of a larger commit related to an
Ingenico double connection deadlock bugfix in V13, but in V14 most of
the related code has moved to enterprise. When a driver thread is
running, calling `disconnect` on it will delete it from iot_devices. If
the driver thread gets added to iot_devices in the Interface thread
after starting it, this means there is a tiny window of time where
`disconnect` could be called and the thread wouldn't be in iot_devices
yet, resulting in an exception. This change puts the driver thread in
iot_devices before starting it, avoiding that scenario and the need to
check in `disconnect` for that happening.
X-original-commit: 6c24d30c3910e67ed751327d1554e2e8cf5e958b
In database with front end, there are lot of bad query like this:
bad query: UPDATE "website_visitor" SET "timezone"='Europe/Paris',"write_uid"=116,"write_date"=(now() at time zone 'UTC') WHERE id IN (15414)
closesodoo/odoo#70709
Error: Could not serialize access due to concurrent update
X-original-commit: d0db984990679a63714ca62e6b605d94af7d5c28
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
When purchase order line is removed, related stock moves procure method stays as "Advanced" which doesn't allow reservation from stock
closesodoo/odoo#70708
X-original-commit: 17d0d1bc6294578e035e29a550a7e90ae7ef2f5f
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
A product with single novariant attribute is normally not shown.
But in the configurator modal it was shown and then added in the product
description when doing exactly the same scenario (add the product) than
without the configurator.
With this changeset, we add is_single attribute and only add a no_create
variant if it is not a single value or a custom value.
opw-2494331
closesodoo/odoo#70700
X-original-commit: 9bd32f2a36eae1713753bf7a5a1aee3b5c51a97a
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
- outerText is a non-standard feature. It is not
supported by firefox and should not be used. This
commit replaced it by value.
- The design of the industry selection screen had
a misalignment flaw on firefox. This commit fixed
it.
- The industry selection used a <i/> element instead
of an <input/>.
closesodoo/odoo#70694
X-original-commit: 2dbbb4e38d603cbb5956fa61040a9497f60c3349
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Co-authored-by: Stefano Rigano <sri@odoo.com>
Use `frozendict` for dicts that often remain empty on models, like
_inherits and _depends, and also make `frozendict` more compact in
memory.
On a registry with 296 modules, this saves 635 kilobytes of memory,
which is about 6% of the registry's memory footprint.
closesodoo/odoo#70402
Related: odoo/enterprise#18142
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This makes the union of many dicts into a single dict.
On a registry with 296 modules, this saves 300 kilobytes of memory,
which is about 3% of the registry's memory footprint.
This keeps field.__dict__ as small as possible.
On a registry with 296 modules, this saves 40 kilobytes of memory,
which is about 0.35% of the registry's memory footprint.
This mainly keeps field.related's type consistent.
On a registry with 296 modules, this saves 325 kilobytes of memory,
which is about 3% of the registry's memory footprint.
This avoids a call to __init__() which no longer has access to the
model's class' parent classes, and was not even correct...
closesodoo/odoo#70400
Related: odoo/enterprise#18141
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
The base classes of models in the registry are modified when models are
extended by inheritance. But modifying cls.__bases__ is a costly
operation, so we manage to do it once per model when loading a registry.
Our benchmark consists in loading a registry with 296 modules. The net
time to load the registry is 25% smaller. In other words, the registry
loads 25% faster. Note that the time does not include the time to load
modules themselves, which does not change.
This commit makes few changes in the event tour as
listed below:
* Remove the step asking user to save the event, as the next step is
redirecting to the website which already triggers a save
* Make the tip for website redirection appeaer in edit mode also
* Fix a typo ("registering" instead of "registrating")
* Instead of having to go to a specific stage, moving to any stage is
now enough for going to next step
taskID-2446215
closesodoo/odoo#70682
X-original-commit: 203499216c657631b39b6ddc9560a1daaf20a862
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Acronyms:
SRL : receivable lines in the session's account move that balances
the receivable lines in the session's invoices
IRL : receivable lines of the invoices in the pos session
When closing a pos session, a single account move is created to capture
all the transactions, but, invoices are kept (each is an account move).
During the construction of this single account move, SRLs are
reconciled with IRLs.
Prior to this commit, when closing a pos session, SRLs are grouped
by `property_account_receivable_id` of the partners in the invoices.
Because of this, SRLs are blind of the partners that they are linked
to. This causes issues on tracking the 'due' in the partners that are
invoiced using the pos application.
To fix the issue, we now group the SRLs by partner before reconciling
them the the IRLs.
Same concept is employed for receivable lines generated from split
cash payments, we also assigned partner to them if applicable.
closesodoo/odoo#70662
X-original-commit: 861612baf57caa67afb32ab904fb8aa26a353dd7
Signed-off-by: agr-odoo <agr-odoo@users.noreply.github.com>
Let's make use of Many2oneReference as a better tool to link the model and the id.
closesodoo/odoo#70518
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
What are the steps to reproduce your issue ?
1. From the product form, go to the website version, edit it to add tabs
2. Using studio, add the field "Description for website" to a tab of the notebook
3. Save, click Edit, go to the tab that has the field
What is currently happening ?
Traceback:
form_renderer.js:258 Uncaught (in promise) TypeError: Cannot read property 'querySelector' of undefined
at Class.setLocalState (form_renderer.js:258)
at Class.setLocalState (form_editor.js:131)
at Class.prototype.<computed> [as setLocalState] (class.js:90)
at view_editor_manager.js:184
What are you expecting to happen ?
Correctly add product description without tracebacks
Why is this happening ?
Because the number of tab is not equal to the number of pages
How to fix the bug ?
Before accessing the element, check if it exists
opw-2378743
closesodoo/odoo#70670
X-original-commit: 96564dd64bdbd426ae87444fd75a822074a37fc0
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
Signed-off-by: Achraf <abz-odoo@users.noreply.github.com>
Add a retry button to enable the user to try and resend multiple emails at once,
purpose is to allow users to easily send back multiple emails which crashed for
a "one-shot" reason instead of asking them to resubmit them one by one.
Task-2492990
closesodoo/odoo#69880
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
- set correct decoration-info attribute on purchase.order tree view, replacing unexisting states ('wait','confirmed') by existing ones ('draft','sent')
- Move the decoration-info from tree line to name field to comply with the new display standards
closesodoo/odoo#70158
Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
Steps to reproduce the bug:
- Let's consider a company in $
- Let's consider two sales taxes T1 (10% included) and T2 (0%)
- Define a fiscal position FP that maps T1 to T2
- Define a product P with T1, price = 11$ and available in the shop
- Define a pricelist PL in € such as 1€ = 2$, show discount to customer and discount P with 50%
- Define a portal user PU with FP and PL
- Log with PU
- Add P in the cart
Bug:
The unit price of P was 2,75€ instead of 2,5€ and the discounted price was 10€ instead of 5€
PS: Before adding P in the cart, the correct unit price and discounted price were displayed.
opw:2472528
closesodoo/odoo#69745
X-original-commit: 5e414d80dd5faf0b90d62dbccc1e6237099ac8db
Signed-off-by: Simon Goffin (sig) <sig@openerp.com>
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
When we get the values to embed to pdf, these values can be False if
there is no edi attachment on the account_move so try to assign something
to 'values' will fail.
Now there is a check before assignment.
opw-2526280
closesodoo/odoo#70629
X-original-commit: e1659f8a9041d409d0d303a7c12342b2e73675c7
Signed-off-by: Josse Colpaert <jco@openerp.com>
Before, each time the name of a slide was modified then a new link
tracker was created.
After discussion, we agreed to remove the automatic creation of link
tracker and let the user creates it manually if he really wants one.
The slides already have a lot of statistics that can be used without
the need of a link tracker.
task-2511961
closesodoo/odoo#69734
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Before this commit, It was not possible to customize Picking values.
With this commit, we add a new method which Prepares to Picking values.
closesodoo/odoo#70494
Signed-off-by: Rémy Voet <ryv-odoo@users.noreply.github.com>
Bug
===
1. Create an event which allows track proposal
2. Follow it and subscribe to "New Track"
3. Log in in incognito and submit a proposal
The email is not sent, because it's sent as the public user, which has
no email address set. And so it the 2 system parameters
<mail.catchall.domain> and <mail.default.from> are not set, we can not
know which email address used to send the email.
Note that this bug also occurs if you create a track with a user without
an email address set.
Task 2510181
closesodoo/odoo#70627
X-original-commit: 45ffab08a7c1dacc70d331077198f92884b53646
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Currently, empty help content are not properly added so in this
task add the proper help content on several menu and add module
field service in community.
So in this commit done the below changes:
- Task form view: change the tooltip of the sale_line_id field
- Change the empty help content in below menu:
- reporting > tasks analysis
- Configuration > Stages
- Project > Reporting > Project Costs and Revenues
- base: The industry_fsm module should show up under Apps in community,
with the usual 'upgrade' button
closesodoo/odoo#68940
Taskid: 2465012
Related: odoo/upgrade#2369
Related: odoo/enterprise#17548
Signed-off-by: LTU-Odoo <IT-Ideas@users.noreply.github.com>
Bug
===
The registration users should be able to read the event tickets.
Allow the registration users to see unpublished event record on website
(Jitsi room, sponsors, track...).
Task 2506148
closesodoo/odoo#70615
X-original-commit: 3eef17203661919a067a4f0d8d99c2b3b6fcf233
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
The button plan of in the manufacturing order tree view doesn't
confirm correctly the draft MO selected (but only the related moves).
task-2479111
closesodoo/odoo#70608
X-original-commit: ef9515611ac96368eae14fc941bca15e3724557a
Signed-off-by: Rémy Voet <ryv-odoo@users.noreply.github.com>
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>