The ModelFieldSelector keeps an internal cache for the fields_get.
This cache needs to be cleared in the tests environment because
a model with the same name may be defined several times accross the
tests modules, but they may contain different fields.
This could also be a problem with studio: when a field is created,
the ModelFieldSelector cache must be cleared as well (in addition
to the data_manager one).
We thus introduce a new 'clear_cache' event on core.bus. When
triggered, the ModelFieldSelector and the data_manager clear their
respective cache.
We use this event in the test environment to ensure that the cache
is cleared at the end of each test using a mockEnvironment. This
rev. also fixes an infinite loop in the override of destroy() in
the mockEnvironment, which occured when both session and config
were specified in the params.
When the root node of the arch has attribute 'create' set to '0',
the generated DOM element must have classname 'o_cannot_create'.
This is used to correctly display the nocontent helper (when there
is no record).
Before this rev., the helper indicated that the user can click on
'Create' to create a new record, even if the create action was
disabled. This was for example the case in Point of Sale > Orders.
The problem occurred in form views with a many2one field, when the
user reproduced the following steps:
- type some text in the many2one
- click on 'Create ...' in the many2one dropdown to quick create
(name_create RPC) the record
- before the name_create returns, click on 'Save'.
When this happened, the record was saved before the many2one was
updated with its new value. So the record was incorrectly saved,
and the view was again dirty as soon as the name_create returned,
even if it was in 'readonly'. So after saving, a 'Changes will be
discarded' dialog opened when the user tried to leave the form.
We fix this issue by making the controller wait for the name_create
to return, and for the many2one to update its value, before saving.
This issue could also occur in list views.
The autofocus worked fine when switching from 'readonly' to 'edit',
but not when clicking on 'Create' from the multi-record view. This
was because in this case, we were trying to focus the field while
the view wasn't in the DOM yet. This rev. ensures that we wait for
the view to be appended to the DOM before trying to set the focus
on the default field.
Also ensures that the first visible field is correctly focused.
Before this rev., if the first field was invisible (or simply
not focusable), no field was focused.
Credit goes to @msh-odoo for the preliminary work.
The 'Add an item' button of one2many editable lists is deactivated
once clicked (since rev. f9a1241) to prevent concurrent record
creation. It is re-activated when the record has been created.
Unfortunately, it might happen that the record is actually not
created, so in this case the button is never re-activated.
This happens for example on the customer invoice form view, if
the user tries to add a line before selecting a partner.
This function should return a deferred, as indicated in the
docstring. However, in some cases, it doesn't. It then crashed
as the FieldX2Many tries to call done() on undefined.
This happens for instance on the customer invoice form view:
create a new record, select a partner, add a line, select a
product, directly click on the invoice date field (this will
trigger an onchange which will totally override the value of the
one2many). The FielX2Many calls setRowMode to switch the edited
row back to readonly, but this row doesn't exist anymore as the
one2many value has been overriden by the onchange, so setRowMode
wrongly returns nothing, and it crashes.
Suppose that a default_get returns the value [[6, 0, [1]] for an
x2many field (i.e. put id 1 in the relation). A read is performed
to fetch record of the comodel whose id is 1. Suppose that there
is another x2many field of the comodel. This x2many has to be
fetched (if not empty), and processed by the BasicModel (i.e. a
dataPoint must be created for it) as well.
Before this rev., the second x2many wasn't fetched nor processed,
and it produced a traceback for example in Expenses app, when
clicking on 'Submit to manager' from an expense form view.
Before this fix, if the start field is readonly, the user could not create
an event. With this commit, it is also ensured that the context sends the
right default values to the view
Previously, when an update operation was performed, the list of
ids in the x2many field was emptied beforehand.
It kinda worked in lots of cases where one would expect it to
fail because in thoses cases the widgets send link_to commands
along with the update one, thus re-adding the removed line.
Now the behavior is more consistent accross the board. We start
with the current list of ids and apply the requested changes.
Otherwise some changes can create rpc errors that are silently caught
and never seen as long as, out of (un)luck, the end result is the same.
Tests which need to create a server error can just simulate it using
the mockRPC mechanism.
When the user writes something in a Many2One input, after a short
delay, a name_search RPC is done with the value written in the
input, and results are displayed in a dropdown. Then, if the user
clicks on the input, the dropdown closes. If he clicks again, it
should do again a name_search RPC with the value of the input.
Before this rev., it was doing it with the empty string.
Suppose that we have a many2one which is set (has a value) in
a form view. Before this rev., if the user unset the value (by
erasing the input content in edit mode), and then reset the same
value, the input remained empty, and the old value wasn't actually
reset.
When creating a new record where the ´domain´ widget is set in the view
with an associated model but this model field has no value, an rpc
(search_count) was done on an unknown model, that causes a traceback.
To avoid this, the rpc is not done if the model is not set.
Keys 'graph_mode', 'graph_measure' and 'graph_groupbys' can be
specified in the context and must be used by the graph view to
determine the default mode, meadure and groupbys. Before this rev.,
those keys were simply ignored.
In some cases, the parentID was not properly set, which is a problem
when we need to evaluate the parent in a context.
Note: I also added a better error explanation in the mock server, to
make it better for the developper to see what is wrong.
In this commit, we improve the behaviour of quick creation in grouped kanban views. The issue was that the quick create widget was removed when the user click somewhere else, even if the user added some text. For example, the problem could be seen in the kanban view for the tasks.
In this commit, we simply keep it around if there is a non empty text.
Clicking multiple times on 'Create' (in main list views) or 'Add an
item' (in o2m lists) might create invalid rows (i.e. rows with
required fields unset).
Creating a new record requires two sequential RPCs: a default_get
and an onchange (only if there is an onchange of one of the
record's field). When clicking twice to create a new record, that
sequence of RPCs is done twice in parallel, after unselecting the
current row (i.e. saving it if it is valid). However, in both
cases, there is no line to unselect yet (as both operations are
done basically simultaneously). When the first onchange returns,
a first new record is added to the list. When the second returns,
the second one is added and takes the edition, leaving the first
one, invalid, in the list.
This rev. ensures this doesn't happen by preventing concurrent
record creation.
... before saving a line.
Suppose that we have an editable list with one required field
(e.g. many2one) with an onchange. We add a record and select a value
for the many2one. Before the onchange returns, we click again on
'Add an item'. If we don't wait for the onchange to return before
unselecting the row (i.e. before saving it), a confirm dialog asking
if the changes can be discarded opens, because the line isn't valid
yet. This could easily be reproduced on the sale_order form view,
with some throttling.
This rev. ensures that we wait for the onchange to return before
saving the line, and thus before creating a new line.
In a slightly too naive way, we apparently tried to improve the
parse_float method while rewriting the new views. This was done by
using a regexp to match all occurences of a thousand separator.
The way the regexp was built was fine, until the thousand separator is a
'.', which, if used as a regexp, matches all characters. Also, sadly,
'.' is not so rare as a thousand separator...
When a ´default_order´ is set on an embedded view for a x2many field,
the sort was only applied server-side, after saving the record. After
adding a record in a x2many, the records were thus not correctly sorted.
We reintroduce here the client-side sort after the x2many modification.
With the new views, the attribute autocomplete on input was no
longer supported. We simply reintroduce its support in this commit.
The basic attribute values are 'on' and 'off' but one may want to use a
random string.
Note that an input with type='password' is a special case: the autocomplete
attribute should always be set to 'new-password' to remove autocompletion
(autocomplete='off' doesn't actually remove the autocompletion).
When clicking on 'Save & New' in the form view dialog, a new default record
is created. The parent was not correctly set in this record, which causes an
error if `parent` was used in context.
Add support for value 'save' to attribute 'special' for buttons in
form view. This is useful for form views in dialogs. When clicked,
it saves the form view and closes the dialog (the default 'Save'
button doesn't close the dialog). Without this, the only way to
achieve that was to define a dummy python method and call it with
<button type="object" name="dummy_method"/>.
In view dialogs (e.g. click on the external button of a many2one
in edit mode), the attribute $buttons of the form controller is
undefined (the buttons are rendered by the dialog directly). The
code that (de)activate the buttons to prevent concurrent clicks
made the assumption that $buttons exist, so it crashed when it
doesn't.
For example: open a draft quotation, click on 'Confirm sale',
before this rev., the record was reloaded twice (each RPC done to
load the data was duplicated). This was actually tested, but the
tests didn't mock well the behavior of the ViewManager, so they
couldn't detect that those RPCs were done twice.
Suppose that there is a many2many list (non editable) in a form
view. When one of the many2many subrecords is edited (from the
form view in a dialog), it is saved directly when the user clicks
on 'Save' in the dialog.
Before this rev., if the user clicked on 'Save' in the main form
view after editing a m2m subrecord, a 'write' RPC was done, whereas
there were nothing left to save (as the subrecord had already been
saved).
Suppose that we have a form view with a one2many list (non
editable) containing a record. In edit mode, the user clicks on
that record to edit it in a form view (in a dialog). In this form
view, there is an x2many field that isn't in the list. Before this
rev., it crashed when the user clicked on 'Save' in the dialog
after editing the value of the x2many.
This was because the basic model didn't use the correct fieldsInfo
in that case (it use the fieldsInfo of the list view instead of the
one of the form view, and the x2many field isn't in the list).
Also ensures that the record is correctly saved even if editing the
x2many is the only change done, as this wasn't the case before.
In the list controller, some code to determine the active domain to
export was causing a crash. It was easy to see: just select all records
in a list view, then click on 'Export' in the sidebar.
Note that the data_export code is still quite old, and did evolve
organically. It does not conform to our new design principles, in
particular, the way component should communicate. But this is a task for
another day.
With the new views, the special attribute password was no longer
supported. We simply reintroduce in this commit proper support to
display password fields with *.
Note: we may want to display passwords with a static number of *, but
this requires some thoughts on the usability of the change. We simply
reintroduce the previous behaviour here.
The 'Expand All' feature was tested, but in the test environment
RPCs are mocked, and everything is synchronous (by default). So
even if the tests passed, the feature actually didn't work because
of a deferred (the reload deferred) that wasn't waited for.
Keys 'pivot_measures', 'pivot_col_groupby' and 'pivot_row_groupby'
can be specified in the context and are meant to be used by pivot
views to determine the initial measures and groupbys. Before this
rev., the new implementation of the pivot view simply ignored them..
Before this rev., the _mockReadGroup function only supported
grouping on one field, and if called with an array of fields of
length > 1, the remaining fields were ignored.
Grouping on several fields is now supported, and some tests had
to be adapted.
Before this commit, the save method in the basic model did not properly
react when the rpc fails. In that case, the returned deferred stayed
indefinitely in the 'pending' state. This is a big problem, because the
basic controller put that deferred in a mutex. As a result, every
subsequent operations (including field changes!) were indefinitely delayed.
To reproduce the issue, you can find any form view where some python
business logic will cause a fail in some cases. For example, create a
new inventory adjustement, click on 'Start inventory', then add a line
in the x2many with the same product as another line. Saving that record
will fail, but then, the form view is broken: no interaction will work.
Before this commit, row decorations were only computed at the initial
rendering for a list view, then never recomputed. Most of the time, it
is not an issue, but list view can be edited, and in that case, it may
be a problem. With this commit, we just override the confirmChange
method to recompute the various decorations.
Note that in bonus, decorations now works in realtime, when editing a
list view (in saas-15, they simply did not work when editing a record)
Also, we now use the same evaluation context as everything else in the
web client: the eval context from the record, not some custom handmade
context like before.
Eval contexts are not easy... They should be different when sent to the
server and when evaluated in the web client. In this commit, we fix
some small issues:
- when evaluated on the web client, x2manys should be a list of ids,
when sent to the server, it should be a list of commands
- dates should be converted to string
- always add current_date in the evaluation context, as a magic key (it
was previously only available in row decoration context evaluations)
With this commit, we just slightly improve list benchmarks, to make them
go through a wider variery of code.
Since we aim to use these benchmarks to track changes in performance
through various versions, it is useful to have a good version in
saas-16.
Before doing an onchange in a x2many, the basic model tries to evaluate
if the line is valid or not. In that computation, we used the
field.required property instead of using the required modifier. This
commit had to move the modifier handling from the BasicRenderer to the
BasicModel, in order to use it in the _isX2ManyValid method.