Purpose
=======
Currently, it's not possible to activate a boolean on a non-editable list view without adding 2 buttons linked to a python method. These buttons aren't aligned and the result is not pretty.
This commit adds a new widget that allows to toggle a boolean record by record by clicking on the slider.
Before this fix, the field 'color' was hardcoded in the m2m_tags widget,
which means that:
- one couldn't specify another field (problem for custom models, with x_...)
- if the related model didn't have the field 'color', a warning was raised
by the server
Now, the color attribute needs to be specified on the widget options if one
wants to display colored tags.
If the color is not specified, the tags will be displayed in grey.
When an invisible x2many field is modified by an onchange, we had a
crash because the reset function did not return a deferred in that case.
This happens because the signature of _render in AbstractField allow for
an undefined return value, but the reset method should return a
deferred.
This was an issue for example in stock: editing the
pack_operation_product_ids one2many field in a stock.picking could
trigger an onchange on another invisible one2many (with no inline views).
When you receive an url with parameters
* auth_signup_token: uuid
* auth_login: login
those will be stored in the session and used
* when the user will want to sign up in order to be linked to the right
partner;
* when he logs in so he's sure to log in with the right account +
autofill is nice
This commit only adds the support, future commits will support its use.
In some situations, it would be desirable to be able to attempt a drag
and drop, without actually triggering the dropping action. As an
example, we would like to see whether dragging a new field in studio
ensures that a class 'o_web_studio_nearest_hook' be assigned. This can
only be tested *before* the new field is dropped.
This commit adds an optional argument 'disableDrop' to the
dragAndDrop method, and sets it by default to false. The dropping action
will then only be triggered if the aforementioned parameter is set to
false.
In some cases (onchange in a purchase order), the onchange can return a
domain for a field that is not in view. It should not be the case, but
it is really simple to protect the web client anyway.
Before this commit, the web client read the readonly in the modifiers,
and if no readonly was in the modifiers, it fell back to the field
property. But the field property was already taken into account in the
modifiers, so this was useless. And worse, in some case, it could cause
an issue. For example, a field with readonly=true, and readonly="0" in
the arch was considered readonly.
If the 'reload' action is triggered right after a view change, the
latter will only be effective if we refresh the page at the browser
level. To overcome this, we clear the cache every time the 'reload'
action is triggered.
The old code don't resize correctly if you use params in request.
because if '200' > 500 => return True
Now we force the casting to int to be sure to compare apple to apple.
before: /web/image/<id>?height=100 => don't return an image with height=100px
after: /web/image/<id>?height=100 => return now an image with height=100px
Previously, enabling some filters created a domain of which events
to display, but disabling all filters resulted in a domain of []
which, instead of showing no events at all, actually showed all events.
In saas-15, when an event had more than 3 attendees, it used to
show a '+' at the left of the avatars. This behavior was lost in
saas-16 where it became 'display 5 avatars max and that's it'.
This commit brings back the behavior of saas-15 and improves it
such that the '+' sign displays the number of additional attendees
whose avatars are not shown and displays it on the right.
Example for 7 attendees, '[]' representing an avatar:
saas-15: +[][][]
saas-16 before: [][][][][]
saas-16 now: [][][]+4
Before this commit, when whe loglevel was set to 2 in the mock server,
we simply logged the parameters in the console, then give the same
object to the _performRpc route. Most of the time, it is not an issue,
but nothing prevents the _performRpc route to modify the args object.
And this happens with the /create route, which is very confusing: when
we have a breakpoint/debugger in the mock rpc function in a test, we see
the correct arguments passed to the function. However, if we look at
the arguments in the console, after the end of the test, we see other
values (for all fields) in the args.args[0] object.
The solution is to simply deep copying everything, so any modification
in the mockserver will not affect the logged object.
In field_utils, the parse monetary method was remapped to parsefloat. In this commit, we add a specific parseMonetary method to handle currency specific formatting.
Onchange RPCs return an object that may contain a 'domain' key.
When it does, its value is an object whose keys are field names and
values are the new domain for the corresponding field.
Before this rev., the 'domain' key was totally ignored by the
BasicModel. This feature is used for example in the account.payment
form view (go to an open invoice, click on 'Register payment'): the
domain of field payment_method_id is updated by the onchanges (e.g.
when changing the journal_id). As the domain was ignored, it always
displayed all possible payment methods.
... when reading and writing on a record (especially inside lists).
Before this rev., the context sent when reading a record, and when
writing records inside lists (editable list views) wasn't correct.
This caused an issue in Sales > Products (variant activated) >
open a product with variants > click on variant prices > edit the
prices of a variant: the value wasn't saved correctly (because the
inverse function requires 'active_id' to be in the context and it
wasn't the case).
Fixes two issues in the test environment:
- for unset fields, the mockRead is supposed to return 0 (numerical
fields), empty array (x2many fields) or false (otherwise). Except
for the first case, it was returning undefined, and this might
cause crashes when evaluating contexts or domains.
- the mock environment allows overriding some global properties
like the session, for the test case only. Once the widget is
destroyed, those global properties are reset to their original
value. This wasn't working for models tests, because the destroy
function of the parent widget was never called. This could make
tests fail as they could have been impacted by other tests.
The test changed in this commit had a big issue: it did not properly
destroy the second form view that it created. Because of that, it was
still alive and could interact with other tests, such as the barcode
tests.
This is what happened:
1. var form was assigned to a form view
2. form was destroyed
3. in a try catch, form was reassigned to the result of createView, but
the evaluation of createView crashed (after creating a form view), so the
assignation was not done, and the var form was still pointing to the first
form view
4. form.destroy is called, which did nothing for the second form view.
There is no easy way to get the reference to the form view created by
createView without changing some other code, so we simply remove the
second part of the test, which was not particularly important.
The reference fields haven't been correctly implemented with the new views.
This commit restores their behaviour.
Note that an small improvement has been introduced in this commit.
Before saas-16, a `name_get` was done for each record (so 80 if the field
was displayed in a full list view), which is not optimal. The calls are now
batched by model (so one `name_get` by model appearing in the field values).
In the editable list, when pressing enter, the cursor goes to the next line and
the current row is saved.
This should not be the case for a textarea (i.e. in the FieldText widget). In
this particular case, we just want to continue editing the textarea.
With the new client web from v9, we start the new action before to destroy the old one.
When we switch from Apps (store) to Update and vice-versa, iframe was not loaded correctly.
In case of the Apps widget, we are binding event of the new iframe during the start,
and when it is ready, we destroy the old ifram and so unbind the listener of 'message.apps'.
Using a uniq id, we ensure to bind new event, and only unbind old event during the destroy.
The translate feature of widgets html and html_frame had been
broken by the new views refactoring. This commit restores it for
the html widget, and removes it completely for html_frame as it
wasn't working correctly before the new views anyway (moreover,
it had already been disabled for mass_mailing: de403dc1ab).
This commit also ensures that the changes are correctly saved for
the html_frame widget. Note that this widget still needs to be
converted to our new coding guidelines.
Before this commit, the discard confirm dialog was directly shown
without waiting for the write RPC. For instance, it the user clicked on 'Save'
after editing a record, and then directly clicked on another menu or on the
breadcrumb before the write RPC returned, the record was still considered
as dirty and thus the confirm dialog was displayed. We now wait for the RPC
to return before checking if the record is dirty, so that the confirm dialog
is only displayed when the record is actually dirty.
session.rpc should not be used anymore. The function '_rpc'
available on widgets should be used instead (with the correct
params).
Also, 'session' is no longer a widget attribute.
When the value of a many2one field with widget selection was unset,
it's value wasn't actually set to false in the BasicModel. It was
set to a virtual id like 'virtual_294' instead. This caused a
traceback when this value was sent to the server, obviously.
This was for example the case of the Register Payment form view
(accessible from a customer invoice), when the user selected a
payment journal, and then unselected it (the virtual id was then
sent to the onchange RPC).
The MonetaryField can be rendered with or without a currency. The
currency can change during the lifecyle of the widget (e.g.
currency field in the view, whose value is set by an onchange).
More precisely, the widget can be instantiated without currency,
then a change on another field can trigger an onchange which sets
the currency, and our monetary widget is re-rendered with a
currency.
Before this rev., this wasn't supported in edit mode because the
$el's root node was different if there were a currency or not
(it was an input if there were no currency, and a div containing
an input and a span otherwise). This root node being rendered only
once (at the creation of the widget), the widget wasn't re-rendered
correctly if the currency was suddenly set or unset.
This fix makes the widget behave uniformly whether or not there is
a currency, so now it is always a div containing an input (and
optionally a span if there is a currency).
A traceback occured when trying to create a BOM by going to
Inventory > Master Data > Products, on a product form view clicking
on the BOM stat button, and then on 'Create'.
This was a context problem: the context of the 'Products' action
was passed to the 'BOM' action without removing action specific
keys like 'default_*' or 'search_default_*'. For instance, it
contained a 'default_type' key, and as type is also a field of the
mrp.bom model, the python tried to interpret it, except that the
given value wasn't a correct value for mrp.bom.
When a button is clicked, we mix contexts coming from different
places to execute the new action. For some of them, we already
filtered out those action specific keys. This fix is simply to
make the piece of context adding the problematic keys pass though
the filter as well.
When x2many fields have to be evaluated in domains (e.g. ['id',
'in', some_x2many_field]), they must be evaluated as the list of
ids in the relation (whereas in contexts, they are evaluated as a
list of commands). Before this rev., they were always evaluated as
a list of commands.
Note that this didn't work neither before the new views.
Datapoints of the BasicModel store the data fetched from the
server and changes done (not saved yet) by the user. For x2many
fields, datapoints are of type 'list' and have a 'res_ids' key
containing the ids of all records in the relation. They also have a
'data' key containing datapoints of type 'record', representing the
records in the relation that have been fetched (with a limit set to
40 or 80 depending on the subview used). So basically, the length
of res_ids may be different than the length of data.
Before this rev., the changes in x2manys were saved under the key
'_changes' as a duplication of the content of 'data', i.e. same
list of datapoints of type 'record', modulo the changes done (it
contained the new records added and didn't contained the removed
records, whereas the 'data' remained unchanged). This didn't worked
at all when there were more records than the limit in the relation.
Indeed, when this happened, the commands to send to the server
couldn't be generated correctly.
This rev. modifies the way changes are stored in those datapoints.
Now, each change is stored as an operation. An operation could be
of type 'ADD', 'REMOVE', 'REMOVE_ALL' or 'UPDATE'. As before,
'data' remains unchanged and always keeps the datapoints of records
that have been fetched (the ones that are currently displayed in
the list or kanban subview). This way, commands can now be properly
computed.
This had a nice side-effect of fixing two other bugs linked to
x2manys.
First, when used in a context (e.g. {some_key: some_x2many_field}),
the value of some_x2many_field (i.e. a list of commands) was always
[] if the field was invisible="1" in the view, because it's
subrecords weren't fetched, and the generated commands were based
on them. Now, they are generated from the list of res_ids in the
relation, so it works fine.
Second, the x2many records are supposed to be sorted client-side,
after being read, and after each edition. This was working in the
first case, but not in the second. Now it's working even after
a record edition.
This rev. also correctly sets the 'parentID' and 'static' keys in
datapoints.
Finally, we also fixed the pager in x2manys as it was badly
displayed (small less tweaks).