hr_payslip_line was inheriting from hr_payslip_rule which meant that we
were copying useless data from the rules on the lines (namely the
computation rules which are only used in _compute_rule on
hr_payslip_rule).
closesodoo/odoo#28711
Add a mixin that can be used to store a normalized version of the primary
email address of the parent model. The email_normalized field can
than be used on that model to search quickly on emails (by simple
comparison and not using time consuming regex anymore)
Apply the mail.address.mixin on blacklist mixin. So that every model
inheriting the blacklist.mixin will also inherit the address.mixin.
That simplify also the comparaison to - and the searches on - the
blacklist.
Use the email.normalized from mail.address.mixin to get always a normalized
email address in the unsubscribe link. That allows to simplify the search
on email address in the controllers -> Check blacklist, send feedback, etc..
This merge is linked to task ID 1896677
closesodoo/odoo#28205
_primary_email was an array to be able to use it directly in the
depends. Typically a 'depends' with a computed value (lambda) needs
an array. Otherwise, it will only take the first character of the
field name string.
By setting _primary_email as a string, the lambda should always get
an array. But it simplifies a lot the usage of the _primary_email.
also, having an array was confusing as we could think that more than
one field can be considered as the primary email. This is not the
goal hare. So having the _primary_email as a single string is more
'self describing'. Only one field should be the _primary_email.
To avoid sending mail to an opted-out mass_mailing_contact with email address
that is not strictly an email address (a <a@a.com> instead of a@a.com),
the the get_opt_out method must be adapted to use the email_normalized field,
as this method is only useful for that specific model.
Task ID : 1896677
Use the email_normalized from mail.address.mixin if available to get always
a normalized email address in the unsubscribe link. That allows to simplify
the search on email address in the controllers -> Check blacklist,
send feedback, etc..
Task ID 1896677
Apply the mail.address.mixin on blacklist mixin. So that every model
inheriting the blacklist.mixin will also inherit the address.mixin.
That simplify also the comparaison to - and the searches on - the
blacklist.
Task ID 1896677
This Mixin can be used to store a normalized version of the primary
email address of the parent model. The email_normalized field can
than be used on that model to search quickly on emails (by simple
comparison and not using time consuming regex anymore)
This commit will be usefull to simplify the email address comparison
in the blacklist mixin but also for any models storing non normalized
email address.
Task ID : 1896677
Rev. 7c3d5dc0 recently added new helpers to use in the tests, and
moved some existing helpers to testUtils sub groups (like .dom or
.mock).
This rev. adds a compatibility layer to ease forwardports.
closesodoo/odoo#28824
During the refactoring of the js test suite, in abf32b8b, the
click_everywhere test was inadvertently updated to use the helpers.
Some missing semi-colons were fixed too.
closesodoo/odoo#28820
This module only adds an action allowing to send some invitations to surveys to
leads. It is safer to go through the survey module especially that its use is
about to be improved.
Commit linked to task ID 1910982.
closesodoo/odoo#28801
Before this commit, when enabling a generic view from a specific website
context and that view already had a specific view for this website, the
view was duplicated again instead of writing on the already existing
specific one.
This is because we did not consider inactive views when checking if a
view that is being written already has a website-specific view.
closesodoo/odoo#28743
When using the media dialog, when uploading an image, the image list
refreshes itself properly. This was not the case for documents as it
was... refreshing the image list too instead of the document list. Also,
when uploading a document, it is supposed to be added in the page
directly and the media dialog is supposed to close. This feature was
broken for the same reason: the iframe system of both tabs which were
using the same name.
Bug introduced with https://github.com/odoo/odoo/commit/abde8bddf8ec45cf12aab59e95c330321158cfba
(even though is was technically wrong for the same reason before).
Closes https://github.com/odoo/odoo/pull/28722
On firefox if we do for example:
ALT+GR + [ALT+GRable ´ key]
Firefox may send keys "AltGr" and "Dead" instead of just "AltGr".
This was possibly causing caret to go a position too low when writing
speedily with diacritical marks.
opw-1903865
closes#28739
Before this commit:
When a coupon_program's coupon was giving a reward on a SO and then the
recompute was removing that reward (eg the SO did not met the requirements
anymore) the coupon would not be reset and would be lost.
Now:
If a coupon's reward got removed for some reason, the coupon got reset to a
valid state (`new`) so it can be used again.
Step to reproduce:
- Generate a coupon from a coupon program that needs requirements (eg $300)
- Add that coupon to a SO that has a total over $300
- Coupon is set as `used` and the reward is granted
- Remove some products to set the SO total below $300
- Recompute coupon, the reward is correctly removed but the coupon is still
set as `used` so it won't be usable again and is basically lost.
Closes#3062
Before this commit:
If a reward had been given on the SO with a coupon_program code and that the
program had requirements and that these requirements are not met anymore,
recomputing the SO would not remove the reward.
Now:
If the SO does not met the program requirements anymore, we remove the reward
Step to reproduce:
- Create a coupon_program with quantity or amount requirements (eg: $200)
- Generate a coupon for that program
- Add $200 worth of products (matching the program domain) in the SO
- Add the generated coupon to that SO
- You should get the reward as you have $200 in the SO
- Remove some products from the SO to go below $200
- Recompute coupons, the reward won't be removed
Closes#3062
Before this commit:
We would never unvalid a `next_order` program (and thus it's generated coupon)
Now:
We also retrieve applied `next_order` programs as we need to check if they are
still valid too
Step to reproduce:
- Create a program on `next_order` that require $300
- Add $300 worth of product on a SO
- Apply program, it will generate a coupon
- Make the SO total go below $300
- The generated coupon is still Valid and the client will receive that coupon
even if it is not supposed to anymore
Closes#3062
Before this commit, an `expired` generated coupon would be shown to the user.
Now we hide these `expired` coupons.
Note: An `expired` generated coupon might typically come from a SO that does
not meet a 'on_next_order' program anymore. So the generated coupon that
was set to `reserved` got canceled and set to `expired`.
Step to reproduce:
- Create a program oferring a product B on next order if you buy 2 product A
- Add 2 product A to cart, you then see the message that you got a coupon for
your next order
- Remove on product A, you still see the message even if the generated coupon
is now expired and not valid anymore.
Closes#3062
Before this commit:
1. We were checking if the rewards were in the SO even if it was 'next_order'
program.
2. We were deducing the rewards quantity for 'next_order' program when checking
if we had enough products to meet the program requirements.
Now:
1. We don't verify if the reward is on the SO if the program is 'next_order'
2. We don't deduce reward quantity when checking if enough products to meet the
program requirements if the program is 'next_order'
opw-1907211
Closes#3062
Before this commit:
Everytime the SO met a 'on_next_order' program requirements, a coupon would be
generated on that SO. Even if there was already a coupon for that program set to
'expired', for instance when the SO did not met the requirements anymore.
Now:
When the requirements are met, it checks that an `expired` coupon does not
already exist.
It it does, it will set that coupon back to `reserved` state.
Step to reproduce:
- Create a program on `next_order` with requirements, eg $300 amount
- Create a SO and add $300 worth of products
- Update promotion, a coupon is created and set to `reserved`
- Now update the SO to go below $300
- Update promotion, the coupon is set to `expired` as it should
- Update again the SO to meet the $300 requirements again
- Update promotion, a new `reserved` coupon is generated instead of updating
the state of the previous one from `expired` to `reserved`
Closes#3062
This optimizes the confirmation of a sale_order in the ecommerce by ~73%,
for a cart with 160 unique items, the processing time goes from
7m46s to 39s, which is roughly the same amount of processing time if the
module `sale_coupon` is not installed.
This optimization is achieved in two steps:
1. By validating promotional/discounted products in batch instead of
validating each product one at a time.
2. By performing an unlink() on invalid reward lines instead of sending
a delete command by writing to the one2many, as delete commands are not
(yet) performed in batch, which means record recomputation after every
delete.
opw-1893277
This PR fixes some miscellaneous issues:
- performance issue in read_progress_bar
- performance issue in activity view
- crash in ungrouped kanban view with progress bar
closesodoo/odoo#28715
The progressbar widget is not supposed to be displayed in non grouped
mode. Before this commit, this situation resulted in a traceback. For
example, if the user has an activity on the subscription model, and
tries to open it, it will open an ungrouped kanban view.
With this commit, we check first that the kanban view is in grouped
mode, before loading the progress bar data.
Fun fact: for the subscription model in odoo production database, the
get_activity_data rpc takes 36s, and transfer 420mb (non gzipped) of
data (when looking at all subscriptions).
The main reason for that is that the get_activity_data method create a
domain with all the res_ids (so, if you have 20k subscriptions, the
domain will look like (res_id, in, [...20k ids]). This domain is given
to read group, and the resulting groups (each with a domain key which
includes those res_ids) will be sent back to the web client.
As far as I can tell, the domain key is not used by the web client, so
we send (number of groups)*(number of records) of useless data.
This commit improves the situation in two different ways:
- we only generate the domain if there is a domain at the beginning.
This should greatly improve the performance when there is no current
domain
- we do not transfer the data to the web client
The tests have been detroyed while merging a refactoring for 12.0.
This commit reintroduces unit tests to checks each business cases from
"The Flow" into python tests.
closesodoo/odoo#28323
The read_progress_bar method is incredibly not efficient. It is also
wrong in other ways (for example, if 2 groups have same labels, there is
a collision). But let us talk about efficiency: it iterates on each
records on the domain, then, it computes some information. It is really
worse for selection fields: it performs a fields_get for each iteration.
This commit improves the situation by doing the fields_get only once.
Note that this is not the end of the story: this only has a small effect on
the performance of this method. It looks like there is a deeper issue in
some cases (kanban view for subscription, field 'activity_state')
Purpose : this commit improve various elements of the mass mailing interface :
- make recipients field in mass mailing form required and add "mass mailing contact" in selection
- new "Archive" button and color picker in dropdown menus of mailing lists and mailings
kanban views.
- various little improvements in labels
closesodoo/odoo#28497
After the Odoo package is built, the package.py script uses a Docker
image to test the package. After that python3-qrcode was added as a
dependency for the package in 2ff49c5f , it revealed some issues.
A missing cli parameter and a forgotten '&&' in the Dockerfile prevented
the installation of the depending packages.
Also, the script shebang was wrong by launching python2.
Finally, the fact that python3-xlwt is missing in Debian stretch was
highlighted. With this commit, the python3-xlwt is explicitly removed
from the dependencies and the documentation is updated accordingly.
closesodoo/odoo#28807
This rev. introduces robust helpers to use in the JS tests suite to
interact with DOM and components, and starts using them (almost)
everywhere.
All the helpers are exposed though testUtils.js.
There are 2 kinds of helpers:
1. Assertions
-------------
* assert.containsNone, containsN, containsOnce check that the DOM
(or a specific part of the DOM) contains a `selector`. It
generates a correct error message automatically.
ex: assert.notOk(form.$('button').hasClass('btn-primary'));
-> assert.doesNotHaveClass(form.$('button'), 'btn-primary');
* assert.isVisible, isNotVisible check that the DOM has an element
visible or not. They also check that the element is actually in
the DOM (before most tests didn't verify this).
* assert.hasClass, doesNotHaveClass, hasAttrVAlue, check specific
properties of a DOM element, and also validate that it is
applied on a single existing DOM element (before most tests
didn't verify this).
2. Utilities
------------
The goal of the utilities is to centralize the definition of many
standard components and interactions, ensuring that when we
refactor the JS framework, we do not need to change all the tests.
Existing mock utilities (addMockEnvironment, intercept, path,
patchDate, unpatch and fieldsViewGet) are moved to
'testUtils.mock.*'.
Existing DOM utilities are moved to 'testUtils.dom.*'.
New dom utilities are created for opendDatePicker, click,
clickFirst and clickLast. Helper `click` verifies that there is
exactly 1 element visible in the DOM you click on, `clickFirst`
and `clickLast` verify that there are more than one element on the
DOM.
ex: form.$('button').click();
-> testUtils.dom.click(form.$('button'));
New Form utilities: (testUtils.form.*)
clickEdit, clickSave, clickCreate, clickDiscard, all clicks on
the control panel buttons of the form.
`reload` reloads the form data.
New modal, graph, kanban and pivot utils (testUtils.pivot.*,
testUtils.kanban.*, etc.).
New fields utils: (testUtils.fields.*)
* editInput, editSelect: allow to change the value of a field,
using a selector to identify it. They validate that the input
exists and trigger the change event automatically.
* editAndTrigger: allow to modify a field and trigger specific
events after the value change
* many2one (testUtils.fields.many2one.*)
clickOpenDropdown, clickHighlightedItem, clickItem,
searchAndClickItem: use a field name instead of a selector and
do all the complex mechanism to open, filter and highlight
many2one fields.
Joint work with aab, dam, ged, mge, svs and vsc.
closesodoo/odoo#28784
This commit simply move code into the right file.
The goal is here to fit the guidelines and prepare
the module for some changes. This will ease the
reading of module code.
Task-1851286
closesodoo/odoo#28795
This rev. introduces robust helpers to use in the JS tests suite to
interact with DOM and components, and starts using them (almost)
everywhere.
All the helpers are exposed though testUtils.js.
There are 2 kinds of helpers:
1. Assertions
-------------
* assert.containsNone, containsN, containsOnce check that the DOM
(or a specific part of the DOM) contains a `selector`. It
generates a correct error message automatically.
ex: assert.strictEqual(form.$('.o_form_editable'), 1, "msg");
-> assert.containsOnce(form, '.o_form_editable');
* assert.isVisible, isNotVisible check that the DOM has an element
visible or not. They also check that the element is actually in
the DOM (before most tests didn't verify this).
* assert.hasClass, doesNotHaveClass, hasAttrVAlue, check specific
properties of a DOM element, and also validate that it is
applied on a single existing DOM element (before most tests
didn't verify this).
ex: assert.notOk(form.$('button').hasClass('btn-primary'));
-> assert.doesNotHaveClass(form.$('button'), 'btn-primary');
2. Utilities
------------
The goal of the utilities is to centralize the definition of many
standard components and interactions, ensuring that when we
refactor the JS framework, we do not need to change all the tests.
Existing mock utilities (addMockEnvironment, intercept, path,
patchDate, unpatch and fieldsViewGet) are moved to
'testUtils.mock.*'.
Existing DOM utilities are moved to 'testUtils.dom.*'.
New dom utilities are created for opendDatePicker, click,
clickFirst and clickLast. Helper `click` verifies that there is
exactly 1 element visible in the DOM you click on, `clickFirst`
and `clickLast` verify that there are more than one element on the
DOM.
ex: form.$('button').click();
-> testUtils.dom.click(form.$('button'));
New Form utilities: (testUtils.form.*)
clickEdit, clickSave, clickCreate, clickDiscard, all clicks on
the control panel buttons of the form.
`reload` reloads the form data.
New modal, graph, kanban and pivot utils (testUtils.pivot.*,
testUtils.kanban.*, etc.).
New fields utils: (testUtils.fields.*)
* editInput, editSelect: allow to change the value of a field,
using a selector to identify it. They validate that the input
exists and trigger the change event automatically.
* editAndTrigger: allow to modify a field and trigger specific
events after the value change
* many2one (testUtils.fields.many2one.*)
clickOpenDropdown, clickHighlightedItem, clickItem,
searchAndClickItem: use a field name instead of a selector and
do all the complex mechanism to open, filter and highlight
many2one fields.
Joint work with aab, dam, ged, mge, svs and vsc.
Before this rev., the mobile js tests suite was run on a desktop
like chrome-headless (1366x768). This can be a problem for this
suite which tests mobile behaviors and thus clicks on parts of the
interface that are only visible on small devices (thanks to scss
media queries).
This wasn't really a problem until now, because the test framework
allowed to click on invisible elements. But it's no longer the
case since the introduction of click helpers.