Testing what's literally just a native feature seems odd, but in this
case it's also way over-specified: Firefox's error message for the
conversion of a symbol to a number is
can't convert symbol to number
Before this commit, calling unpatch on an object that hasn't been
patched before crashed (before reaching the code that handles the
case by throwing an Error). This scenario is now properly handled.
This commit also defines specific Error classes for the patch and
unpatch faulty cases, so that they can be elegantly catched (in
tests for example).
closesodoo/odoo#68057
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
In tests, we might want to disable a specific patch for a specific
test (e.g. to remove a monkey patch done when another addon is
installed, to test the behavior of the current addon).
Before this commit, it was possible to unpatch at the beginning of
the test, but we couldn't re-patch when the test was over.
Feature required by task~2392303
* hr, hr_holidays, im_livechat, mail, snailmail, website,
website_livechat
This commit removes `patchMixin` and improve `utils.patch`.
`utils.patch` now supports native classes and has a new parameter
used to patch class members.
`utils.patch` is now used everywhere `patchMixin` was and it must
be used to patch classes.
closesodoo/odoo#65967
Related: odoo/enterprise#16278
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
Co-authored-by: ged-odoo <ged@odoo.com>
Before this commit, occurences of 'null', 'true' and 'false'
strings as autocomplete values in the search view were replaced
respectively by None, True and False.
Fixes#65743closesodoo/odoo#65958
X-original-commit: 885932ae8e31905e08b79141a445933b6afc9f15
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Before this commit, calling do_hide/do_show/do_toggle on a
widget that had been destroyed before being rendered crashed
(because this.$el was undefined).
Obviously, calling those methods in this situation is useless, but
with asynchronous code, it might happen that you call them in an
handler, and they have been destroyed meanwhile.
This commit checks if this.$el is set before accessing it to avoid
the crash.
closesodoo/odoo#65897
X-original-commit: 320c29f5b37d4f02b4d5f7b1b6ff64462b000c92
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
Before this commit, the `on_attach_callback` and `on_detach_callback`
callbacks are not called all the time on the `Dialog` widget when it's
attached/detached to the DOM. Relying on those callbacks could result in
unpredictable behaviours.
To be more precise, the `on_attach_callback` isn't executed on a regular
Dialog#open() call. But Dialog spawned by the ActionManager will execute
it.
This difference prevents from properly binding those callbacks later on
through an extend or include of the Dialog widget as we have no way to
know if they have already been called or not (e.g. which can result in
calling them twice).
This commit normalize this situation by ensuring that the
`on_attach_callback` and `on_detach_callback` callbacks are properly
called by the Dialog widget and allows any extension of this widget to
rely on them. Therefore the ActionManager is adapted accordingly.
opw-2438534
closesodoo/odoo#64794
X-original-commit: 036fc78103e3d8875a5a54c797e1ba0670d02272
Related: odoo/enterprise#15856
Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
Signed-off-by: Pierre Paridans <pparidans@users.noreply.github.com>
A string parameter 'order' has been added to the "sortBy" function of
the utils module to decide in which order the array should be sorted.
The default is 'asc'.
- avoid updating default position list in place
- ensure computed position takes into account enough margin with border
- fallback to requested position instead of bottom
Part of task-2270731
closesodoo/odoo#58370
X-original-commit: 3fad17421518732db2085c3eec596600cfe34f03
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Before this commit, any value could be added to registries and the class
needed to be overridden to assert that added values would answer to a
certain predicate.
Now, the registry can be instantiated with a given predicate function
that all added value must pass to be registered (default: all values
are accepted).
Existing implentations have been adapted:
- FieldRegistry
- FieldRegistryOwl.
*: web_editor
Do not display the backdrop element added by bootstrap in the body and
add a background on the modal to keep the same effect. The bootstrap
backdrop was probably useful for compatibility with <IE9 but is no
longer needed. This also avoids z-index issues because modals could be
opened in an element (e.g. the website #wrapwrap) whose stacking context
is different of the body one (where the backdrop is opened). This would
make the backdrop appears on top of the modal.
Part of https://github.com/odoo/odoo/pull/49142
Related to task-2229551
Co-authored-by: qsm-odoo <qsm@odoo.com>
This commit introduces a new utility function: 'groupBy'. It is
similar in API and result as the underscore method of the same
name.
X-original-commit: 834a1967161dc537cb2d5543314a062dbac08f9c
This commit adapts tests following recent changes on the helpers.
The main change is that addMockEnvironment (and all functions using
it) are now async, as they need to wait for services to be started.
The entries comming from the optional parameter 'mapping' passed at the
instantiation of a registry were never considered when returning the
registry keys or entries. This is no longer the case.
closesodoo/odoo#52768
X-original-commit: e094ddd0ffaf3357e64ca5941ffc2e0454c24ab7
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
Close can now be requested by children (slot content) with the event
`o-popover-close`. This feature is necessary if we want a "close" button inside
the popover itself, which is the case for mail.activity "Mark Done".
Clicking on the popover target now acts as a toggle, which is also a feature
that was expected from the previous popover implementation.
Add a specific class (`o_is_open`) when the popover is displayed to be able to
style its target depending on whether it is displayed or not.
Ensure computed position is whole number of pixels to prevent flicker issue on
Firefox.
Remove forced width to let the component grow with its content.
Add appropriate z-index to prevent overlap issue with the rest of our interface.
closesodoo/odoo#50850
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Add a "sortBy" helper to core utils. This function takes an array and
an optional criterion as arguments and returns a new array sorted
according to the given criterion.
Handling of escapes (`\`) was performed during evaluation rather than
parsing, so strings in the AST stored the escaped form (rather than
the proper one), and _formatAST had to mess around in order to try and
get it back into a semblance of relevance (especially as the AST would
store the escaped string without delimiters).
Fix: perform the escapes handling (aka normalisation) during
tokenization where it belongs. This means the AST formatter can now
just JSON.stringify the data. Until and unless we decide to produce a
cpython-compliant
repr (https://github.com/python/cpython/blob/0169d3003be3d072751dd14a5c84748ab63a249f/Objects/unicodeobject.c#L12902-L13006)
which is unlikely.
closesodoo/odoo#50236
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit implements a new way to monkey-patch ES6
classes (for instance, Owl Components).
Usage
-----
odoo.module('module.BaseClass', function (require) {
const patchMixin = require('web.patchMixin');
// Define your class as usual
class BaseClass {
constructor() {
this.foo = 'foo';
}
bar() {
console.log(this.foo);
}
}
// but export it like this to have a "patchable" version
return patchMixin(BaseClass);
});
odoo.module('module.Patch', function (require) {
// imports the "patchable" version
const BaseClass = require('module.BaseClass');
BaseClass.patch('key', T =>
class extends T {
constructor() {
super();
this.foo = 'patched foo';
}
bar() {
super.bar();
console.log('patched bar()');
}
}
);
});
odoo.module('module.instance', function (require) {
// imports the "patchable" version
const BaseClass = require('module.BaseClass');
const obj = new BaseClass();
obj.bar();
// if module.patch is loaded before this module the patch
// will be apply and calling obj.bar() will log:
// patched foo
// patched bar()
// You can unpatch a patchable class
BaseClass.unpatch('key');
});
Using bootstrap popover with owl is possible, but with a lot of
friction.
This commit adds a Popover element to ease developments that require
a popover. This component takes 2 props:
- position='bottom' (optional): 'top', 'bottom', 'left', 'right'
- title (optional)
Its usage requires setting an `opened` slot for the content of the
popover, whilst the 'trigger' of the popover uses the default slot.
E.g.
```xml
<Parent>
<Popover>
<t t-set="opened">
<p>You have opened the popover, congratulations!</p>
<button t-on-click='_handlerOnParent'>Dispatch cake</button>
</t>
<button class="btn btn-primary">Click me!</button>
</Popover>
</Parent>
```
Note that:
- only one popover can be opened at a time (opening a popover will
close any previously opened popover)
- `Popover` uses `Portal` under the hood, so events are propagated
correctly even though the popover is teleported elsewhere in the dom
(see example in this commit message with `_handlerOnParent`)
- `<Popover>` is registed as a global component in QWeb and does not
need to be added to a Component's subcomponents list
closesodoo/odoo#47710
Signed-off-by: Damien Bouvy (dbo) <dbo@odoo.com>
In JavaScript, the following computation introduces numerical errors:
```
Math.pow(10, -4) = 0.00009999999999999999
Math.pow(10, -5) = 0.000009999999999999999
```
In the context of `round_decimals`, such errors propagate to
`round_precision`, ultimately leading to inconsistencies between Python
and JS (see #47300 for detailed use case).
Instead of computing `Math.pow(10, decimals)`, we parse the scientific
notation to prevent such inaccuracies.
We also introduce tests in line with the Python tests.
opw-2205092
closesodoo/odoo#47694
X-original-commit: cb471897bfa08d1fee6a9f49e90d9c120e1733fc
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
This reverts commit d6b854306c.
The reverted commit introduced issues in patching class methods.
Introducing getters in the patch function is not actually compatible
with the original method patching.
Test for patch method is also introduced to guard patch from future
invalid modification that happened.
A more robust way of patching classes is now being developed.
closesodoo/odoo#47557
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
* modify client-side domain normalisation to error if the domain is
invalid (not enough terms / segments for the number of operators)
* add better error reporting to attrs / modifiers parsing
* add a few layered error augmentation to provide clearer context
e.g. "error: invalid domain <thing>" is helpful but "error while
parsing modifiers for field foo: modifier invisible: invalid domain
<thing>" is much more helpful
* rework _evalModifiers to deduplicate it in order to more easily
implement this contextual augmentation
* test that improper domains are properly found improper
* fix a bunch of incorrect attrs domains
* also removed an apparently undefined (& unused) "options" argument
to a _applyModifiers call
closesodoo/odoo#44642
Related: odoo/enterprise#8175
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Before this commit, the CSS rule handling the "activity" of the modals
(their z-index compared to the one of their backdrop) was global and would
interfere with front-end or custom modals which do not use the static Dialog
methods giving them the "active" class.
Now, the rule has been inverted: the z-index of a modal is only changed when
it is given an "inactive" class, thus only impacting the modals instantiated
via Dialog or Owl Dialog classes.
closesodoo/odoo#44067
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Before this commit: all dialogs would go through the static method (OwlDialog.hide)
when destroyed, regardless of wether they had been opened or not.
Now, only dialogs having an 'el' property set (= having been opened) will use
the 'hide' method.
Task 2170705
closesodoo/odoo#43124
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
New Owl component: Dialog. It does not rely on Bootstrap but behaves the same
and does not conflict with legacy dialogs.
To call this component, you need to define it in the XML parent template instead
of calling it in the JS file, and put a flag in the parent state to toggle the dialog.
Old dialog file has also been slightly updated to ensure compatibility between both
versions.
This commit also updates a list view test which did not wait for click events to
properly trigger and would cause the new dialog system to crash.
Before this commit, negative numbers are never rendered as human readable (e.g. 34000 -> 34k).
closesodoo/odoo#42789
Taskid: 2160790
X-original-commit: b51877c4c4c9d8cd873dd0205954fd807d62ee01
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Before this fix, a QUnit test was wrong (didn't parse)
After this fix, the test actually works and tests something.
closesodoo/odoo#41257
X-original-commit: 3818a7f0df754717a7379dc8341729b508a166be
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Conditional expressions were already parsed, but there was no support
for executing them (or stringifying them back though I'm not sure when
that's used).
closesodoo/odoo#40502
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This completes a commit that was made for the version saas-11.3 (12.0):
https://github.com/odoo/odoo/commit/1440c8be0337c89e3d67d6d93e614c269c8689f1
Indeed, the logic was implemented for the appendTo, prependTo, etc
methods but not for the attachTo...
This could solve unknown problems in stable versions as well but was
judged too risky to merge there. Indeed, if a real problem occurs in a
stable version because of this, the condition can be added to the
related widget individually.
The problem was found in master: during website edition, the public
widgets can be restarted if an element is edited... but sometimes the
public widgets may be restarted in the same JS stack execution. The
willStart method being async, the destroy method was called before
the start method. This does not lead not any known problem with our
current widgets but will create one for a new snippet being implemented.
closesodoo/odoo#39949
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Added an option in the Dialog class to give it a function to run
when it's closed by other ways than by its buttons.
Its default value is the "cancel" callback if given, or none.
Before this commit, there was no way to add any callback to run
when the modal wasn't closed by a button.
Now, when exiting the modal by other means (e.g.: "Escape" key),
it will run a given callback.
The main aim of the present refactoring is twofold:
- simplify the code that was largely complexified at the time of the
introduction of comparisons in the pivot view (Time Ranges menu),
- factorize the method expandHeader and _loadData that were too much complex.
Along the way, the pivot model structure has been simplified
and many tests have been added.
Performances in mobile mode have been improved by avoiding
unecessary operations due to useless column groupbys in that
mode.
It should now be easier to understand and modify the pivot view in future.
Co-Authored-By: Aaron Bohy <aab@odoo.com>
closesodoo/odoo#33615
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
math_utils is a small library that exports two
functions:
- cartesian: allows to compute the cartesian
products of any numbers of arrays
while preserving the internal
structures of their elements.
- sections: returns an array with all
the initial sections of the
array passed as parameter.
Add a new behavior to numeric fields, possibility to enter value manually or to use a simple arithmetic expression that will be evaluated.
Example: =20+3*2
In order for the computation of the arithmetic expression to be done, the value needs to starts with = and then an expression can be entered. We only support the basics mathematical operations + - * / ( ) ^
User locale and digits separator are taken into account. If the value entered can't be evaluated to a numeric, the field will be displayed in error.
closesodoo/odoo#34538
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit merges the following models
* account.invoice and account.move
* account.invoice.line and account.move.line
* account.voucher and account.move
* account.voucher.line and account.move.line
It was the opportunity for a big cleanup of the code, so it also restructures the whole account module, its different models/fields, the tests etc. for a better world and a better code readability.
==== Rationale ====
The rationale of this huge change is that we want journal entries / invoices to be easily edited, and changes reflected in the other model. It's a HUGE feature and very strategic for the fiduciary companies. For example, changing the account of a journal entry needs to be automatically reflected on the related invoice.
The same reasoning applies to sale/purchase vouchers.
==== Changes made in features =====
When creating an invoice, you are now creating a journal entry directly.
--> The object account.invoice no longer exists.
In the same fashion when creating an invoice line, you're now adding journal items directly in the journal entry representing the invoice. If this invoice line has some tax, it may create additional journal items as well.
--> The models account.invoice.line & account.invoice.tax no longer exist
Identically, when creating a sale/purchase receipt with its lines, you are now creating a journal entry directly and there's no more usability difference between encoding a receipt or an invoice.
--> The object account.voucher no longer exists.
--> The object account.voucher.line no longer exists.
--> The whole account_voucher module no longer exists.
Positive side-effects coming from these changes are
* draft invoices/bills/sale or purchase receipts now create a draft accounting entry. Validate these objects now simply post its journal entry. That means that draft invoices/bills/sale or purchase receipt can straightforwardly be included in reporting or budgets.
* opening a journal entry in form view will now always open the correct view: if it's a sale/purchase journal entry we will have a customer invoice/vendor bill view or a sale/purchase receipt view, whatever the menu we're coming from.
* code & business logic simplification. It is also condensed in a single place instead of being partially duplicated on invoices, vouchers and journal entries.
There should be no feature loss, except the one allowing to group multiple journal items together based on the same product during the invoice validation.
==== Changes made in models =====
* account.invoice: model removed. Instead, now use account.move with following mapping
field (account.invoice) field (account.move)
----------------------- --------------------
name invoice_payment_ref
number name
reference ref
comment narration
user_id invoice_user_id
amount_ total_company_signed amount_total_signed
residual amount_residual
state state + invoice_payment_state /!\ selection changed
date_invoice invoice_date
date_due invoice_date_due
sent invoice_sent
origin invoice_origin
payment_term_id invoice_payment_term_id
partner_bank_id invoice_partner_bank_id
incoterm_id invoice_incoterm_id
vendor_bill_id invoice_vendor_bill_id
source_email invoice_source_email
vendor_display_name invoice_vendor_display_name
invoice_icon invoice_vendor_icon
cash_rounding_id invoice_cash_rounding_id
sequence_number_next invoice_sequence_number_next
sequence_number_next_prefix invoice_sequence_number_next_prefix
'invoices' subset of account.move can be accessed by using the selection field 'type' or one of the many helpers like is_invoice()
* account.move: now has a valid state 'cancel' that has to be excluded from all business logic
* account.move: field 'amount' renamed into 'amount_total'
* account.move: field 'reverse_entry_id' renamed into 'reversed_entry_id'
* account.move.line: now has a field 'display_type' that has to be excluded from all business logic, in order to support invoice layouting
* account.invoice.line: model removed. Instead, now use account.move.line with following mapping
field (account.invoice.line) field (account.move.line)
---------------------------- -------------------------
invoice_id move_id
uom_id product_uom_id
invoice_line_tax_ids tax_ids
account_analytic_id analytic_account_id
'invoice lines' subset of all account.move.line from a journal entry can be accessed by using the boolean field 'exclude_from_invoice_tab'
* account.invoice.tax: model removed. Instead, now use account.move.line with following mapping
field (account.invoice.tax) field (account.move.line)
--------------------------- -------------------------
invoice_id move_id
account_analytic_id analytic_account_id
amount price_unit
base tax_base_amount
'tax lines' subset of all account.move.line from a journal entry can be accessed by using the relational field 'tax_line_id'
* account.invoice.confirm: model removed. Instead, now use the 'post()' function of account.move
* account.invoice.refund: model removed. Instead, now use account.move.reversal to reverse the entries with the same options as we had for invoices
* account.voucher: model removed. Instead, now use account.move of type in ['out_receipt', 'in_receipt]
* account.voucher.line: model removed. Instead, now use account.move.line
==== Changes made in functions ====
* on account.move, method _run_post_draft_to_post() renamed into _autopost_draft_entries()
* on account.move, method action_account_invoice_payment() renamed into action_invoice_register_payment()
* on account.move, method action_invoice_reconcile_to_check() renamed into action_open_matching_suspense_moves()
* on account.move, method _get_domain_edition_mode_available() renamed into _get_domain_matching_supsense_moves()
* on account.move, method _get_intrastat_country_id() renamed into _get_invoice_intrastat_country_id()
* on account.move.line, method _get_domain_for_edition_mode() renamed into _get_suspense_moves_domain()
* in account.bank.statement, contextual key 'edition_mode' renamed into 'suspense_moves_mode'
Was task 1917430
Widget class indirectly inherits from ParentedMixin (through
PropertiesMixin).
The Widget's children are destroyed in both the ParentedMixin and the
Widget's own destroy() method.
This commit prevents from trying to destroy already destroyed children
and specifically from looping again on those children (resulting into a
minor performance improvement).
closesodoo/odoo#32174
Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
It has been decided to use Chart.js instead of nvd3 to render charts.
In this commit the graph view has been largely rewritten to benefit
from the options offered by Chart.js.
Task ID: 1946138
The commit 6d3ada178f
aimed to solve problems occuring whith (single or
double) quotes when creating new custom filters.
Unfortunately, the point was missed and bugs were
still present. The present commit solves the
orginial problem satisfactorily.
There was also a problem in the management of
backslashes. Type '\\' in the search bar would
lead to a domain like
[('...', 'ilike', '\\\\\\\\\\\\\\\\')].
This has also been fixed. Note that it is
necessary to input "\\" if one is looking for a
backslash in db (as before).
A remark on the _formatAST function (py_utils.js):
We deescape only the chars `'`, `"`, and `\`
because it does not seem possible to produce a
string in the search view that would intend a
search for a line return or a tab for example.
A general remark:
Domains should always be in normalized form.
In that way they could be manipulated and combined
together without a tokenization/parsing!
closesodoo/odoo#29756
The formatting of very big numbers (like
1.0045e+22) was not handled adequately by
the function 'human_number' in web.utils.
For those numbers, it seems more appropriate
to use the scientific format. The only
difference introduced here is the following.
Beyond a magnitude of e+21, we represent the
numbers by themselves but we keep the
number of decimals provided as parameter
(or zero by default) and we remove useless
zero decimals like in the other cases.
For instance, 1.0045e+22 is replaced by 1e+22
instead of 1.00e+22 if ask 2 decimals of
precision (and by 1.005e+22 for 3 decimals).
We have also fixed a small bug occuring in the
previous version of the function: the symbol
'E' was never used. So by the past the above
number would have be represented as
10045000P and, even worse, 1.01e+45 by
1.012e+28P.
closesodoo/odoo#31140