summaryrefslogtreecommitdiff
path: root/odoo/fields.py
AgeCommit message (Collapse)Author
2021-05-31[FIX] core: origin of main record in onchangeHEAD14.0Raphael Collet
When invoking onchange() on a line in a one2many field, the inverse many2one field is given as a dict of values. Those values are the ones of the "container" record in the form view, and they include the "id" of the container record. The method onchange() instantiates the container record as a new record with the given values. Fix the code to set the expected "origin" of that record to the record with the given "id". closes odoo/odoo#71474 X-original-commit: ebfb5d90fd4ff65ee1d2fc73faf8f9eaa18f4521 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-05-19[FIX] core: computed editable one2many field with a domainRaphael Collet
Manually adding a line should not trigger the computation of the field, just like modifying the line fields that occur in the field's domain. In other words, the dependencies of the field should be limited to the ones declared on field or its compute method. closes odoo/odoo#71027 X-original-commit: 9000a50582db827ff12acdecf8ef91749122452d Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-02-26[FIX] core: convert_to_write() of x2many field with new recordsRaphael Collet
When comparing the values of a new record with its origin, x2many fields are always different because we compare new records with real records. For instance, converting the value of a one2many field where lines have a many2many field always returns update commands for the many2many field. closes odoo/odoo#66937 X-original-commit: 03a4137cc3fa398dbd0cb214dc5472a083ae33b8 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-02-15[FIX] core: flush domain before searching for records in many2many fieldRaphael Collet
This guarantees the cache consistency of the many2many field values. X-original-commit: 74e188197e560897e13f7666d385a45ed7ca6f90
2021-02-05[FIX] core: writing on one2many field on new recordRaphael Collet
When using command "6" (SET), the one2many field's inverse was not assigned on the lines. closes odoo/odoo#65656 X-original-commit: 330b885c4fd8570429d1cc4b59db1be00c26507b Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-02-06[FIX] core: fix adding a field related to Binary or x2manyIvan Yelizariev
such fields have store=True, but they don't exist in table. --- https://github.com/odoo/odoo/pull/65232#issuecomment-773298323 https://github.com/odoo/odoo/commit/02417290191c22c9c99e6dc96a572c21f38e64f1 closes odoo/odoo#65665 X-original-commit: 2eee717ded0fc702b431f7fe784dc62438aa5603 Signed-off-by: Raphael Collet (rco) <rco@openerp.com> Signed-off-by: Ivan Yelizariev // IEL <yelizariev@users.noreply.github.com>
2021-02-05[FIX] base: query company dependant as superuserMartin Trigaux
When retrieving company dependant values, the computed domain called search_multi method of ir.property as normal user. Since odoo/odoo@8f578637076d4b65 ir.property records are no longer readable by a normal classical user. To reproduce: Add a domain using a company_dependant field e.g. on res.partner, with purchase installed, modify the parent_id field in form view to <field name="parent_id" ... domain="[('property_purchase_currency_id','=',property_purchase_currency_id)]" /> When clicking on the parent_id with a low priviledge user, an access-right error is raised, as the user doesn't have access to ir.property records Fixes odoo/odoo#65450 closes odoo/odoo#65552 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2021-02-02[FIX] core: initialize new stored related field via SQLIvan Yelizariev
Filling the new column in SQL is dramatically faster than doing it via the ORM, which iterates over all the records in the table. The test case is creating a related field for 100+ records with distinct values. Setting the field's value was taking more than 100 queries. It now takes 3 queries. task-2449313 opw-2380445 opw-2389376 https://github.com/odoo/enterprise/pull/15910 closes odoo/odoo#65421 X-original-commit: 82644c3ea20f7b5748f92ce4d0f4585335995d29 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-01-15[FIX] odoo/fields.py: fix removing translations on writing ''Ivan Yelizariev
cache_value could be empty string rather than None. I'm not sure why it was different before. STEPS: * install an app that adds menu Products (e.g. Sales) * activate second language and switch to it * create new product, set some value to field description ("Internal Notes"), save * click edit, remove description, save BEFORE: the value is not removed AFTER: value is empty, translations are removed closes odoo/odoo#64591 X-original-commit: 32465251e19efe63d2015b799b8de9b4e8db438f Signed-off-by: Ivan Yelizariev // IEL <yelizariev@users.noreply.github.com>
2021-01-08[FIX] core: avoid access error when flushingRaphael Collet
This takes a former patch one step further. Assume you recompute a field on two records, and the computation assigns the first record but not the second one. Before this patch, the recomputation process was accessing the field on both records. When accessing the first record, both records are recomputed, and the value of the first one is found in cache. When accessing the second record, no recomputation is made (it has been done already), and the cache is empty. The field is thus fetched from database, and this crashes because of insufficient access rights. This scenario was causing some obscure nondeterministic crashes in tests. The nondeterminism comes from the choice of the environment for flushing (it should not be in superuser mode); the order of records in the set to compute; the order in which records are assigned in the compute method; the fact that the compute method should assign some records and some not. The fix consists in adding a method that processes pending computations, without doing anything special for unassigned records. The method is used in field accessors (__get__ and mapped) and in method recompute(). The access error is gone because the recomputation no longer tries to get the value of a field to compute. closes odoo/odoo#64250 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-12-18[FIX] core: marking and traversing computed fields before modificationRaphael Collet
This fixes an issue that occurs when marking fields to compute in the following situation: - it occurs before the actual modification, - a relational field is marked to compute, - the same field is traversed to inverse some dependency. When the marking occurs after the modification, the traversal of the field should actually recompute the field. However, if the marking occurs before the modification, the inversion of dependencies must be based on the current value of the field. This is the case with method unlink(): we call method modified() to mark the fields that currently depend on the records to be deleted, and the fields must be computed only after the deletion! X-original-commit: 3a6ac95ddf6a8719aa714a83fc339ba838c3811d
2020-12-02[FIX] core: invalidation of computed editable field in one2manyLaurent Smet
This fixes the issue introduced by revision fd50ba9fb838067fab0b920470cf79b9c94d785c The way computed fields are invalidated depends on the order of the dict passed as a parameter to method onchange(). This causes some unexpected behavior when dealing with computed editable fields: the user loses the value in that field because of the onchange. Explanation: during the onchange, the modified field is cached by record._update_cache(changed_values, validate=True) If the field is a one2many, 'value' contains an update command for each modified line. Because of 'validate=True', the assignment triggers field computations on the lines, which are already handled by another call to onchange(). In case anything on the parent model modifies some line, the whole one2many values are returned to the user, and accidentally recomputed fields show up in the interface. closes odoo/odoo#62060 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-12-02[FIX] core: document cache miss behavior in Field.__get__Raphael Collet
2020-11-25[FIX] core: allow writing to delegated m2o fields on recordsAdrian Torres
Before this commit, it was impossible to write to a delegated m2o field if the length of the recordset was greater than 1. The reason was because the special case for delegated fields inside fields.Many2one.convert_to_cache would check for `record.id` which is a bit misleading, since record can be greater than one. The solution is to check whether any of the records are real records instead, as if all of the records are NewRecords, then the parent is a NewRecord too. Fixes #62069 closes odoo/odoo#62321 X-original-commit: fd211958a28d886626552ec976253f9f9267dacf Signed-off-by: Raphael Collet (rco) <rco@openerp.com> Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
2020-11-17[FIX] core: avoid access error when flushingRaphael Collet
This patch guarantees that computed fields with `compute_sudo=True` do not cause access errors when fetched from database. This fixes a non-deterministic access error upon `commit`, where fields are recomputed and flushed with some random environment. The method `recompute` performs its duty by accessing the fields to recompute. The compute method of a field is called but does not assign it. As the field is not in cache, its value is read from database. However, as the latter is not done in superuser mode, it may cause some access error. closes odoo/odoo#61820 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-11-09[FIX] core: use 'x_name' as _rec_name only on custom modelsRaphael Collet
This fixes a very obscure bug that happens on workers serving multiple databases. Consider two databases A and B with the same model M, that does not have a field 'name', but has a custom field 'x_name' only on database A. The bug can be reproduced with the module 'account' and its model 'account.register.payments'. Assume the server loads a registry for database A. In that registry, the model M uses 'x_name' as its _rec_name, and the field 'display_name' on model M determines its dependencies to be the field 'x_name'. Now assume the server load a registry for database B. In that registry, the model M has no _rec_name. However, an optimization reuses the field 'display_name' for the model M on the registry of A. The field's attribute 'depends' is equal to the tuple ('x_name',). When the ORM tries to resolve the field's dependencies, it does not find the field 'x_name' on M and crashes. In order to avoid this situation, we forbid the usage of 'x_name' as _rec_name on non-custom models. OPW 2349238 closes odoo/odoo#61531 X-original-commit: 731e676fa8a9f7bdc6a66056c124c3b39a0800ad Signed-off-by: Olivier Dony (odo) <odo@openerp.com> Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-10-21[FIX] core: validation of field parametersRaphael Collet
The feature was actually not working as expected. It has been fixed, and a test now ensures it does work as expected. This commit also fixes some invalid parameters, hopefully nothing critical. closes odoo/odoo#60402 Related: odoo/enterprise#14273 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-10-13[FIX] core: assignment of binary field on new record with originRaphael Collet
The assignment of a binary field on a new record with origin did actually modify the attachment storing the value of the field on the origin record! The fix is simply to avoid messing up with attachments when updating new records. closes odoo/odoo#59918 X-original-commit: 6778c4c10fa68c46bde6fae176f547f905e9c02f Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-10-13[FIX] core: assignment of size to new recordsRaphael Collet
Upon onchange, the web client sends unchanged image fields on one2many lines as "bin size" values, while changed image fields are sent as their full value. As the value is not base64-encoded, the assignment of that value crashes. Fix it by making assignment on new records not crash when decoding the image: the value is simply not assigned to the field. In the situation described above, the record being assigned is a new record with a real record as origin. Because the field is actually not assigned, its value is implicitly the value of the field on the origin record, which is consistent with the fact that the field was not modified in the form. X-original-commit: 4442d6f0f29a2bf6e992515cd535c88215855a36
2020-10-02[FIX] core: cache consistency of one2many field with computed inverseXavier-Do
Consider a one2many field with a corresponding many2one field that is computed. After modifying the many2one field's dependencies, the cached value of the one2many field is inconsistent until the many2one field has been recomputed. Therefore, one has to force the computation of the many2one field before accessing the cached value of the one2many field. closes odoo/odoo#59031 X-original-commit: b9201ebdd65eaabab9257cf97c58410681783fa6 Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com> Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-09-28[FIX] core: compute on batches of maximum PREFETCH_MAX recordsRaphael Collet
Calling a compute method on 1M records inevitably brings a worst case in cache prefetching: the code that determines which records to fetch has time complexity O(N²). We avoid this situation by calling the compute method on maximum 1K records. Each computed batch has a "prefetch set" of maximum 1K records too, which avoids the worst-case scenario above. closes odoo/odoo#58647 X-original-commit: 0b1aa660b1d94fe46dea09670b875f2d81ca36a3 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-09-21[FIX] core: always evaluate field.depends upon setupRaphael Collet
This is necessary when a field's dependencies are given by a callable. This functionality was broken with the support for an explicit parameter `depends` in the fields' definition, because the implementation could not distinguish between the field parameter `depends` and the `depends` evaluated from compute functions. The fix consists in storing the field parameter `depends` into `field._depends`, and the result of the setup into `field.depends`. closes odoo/odoo#58127 X-original-commit: d4d7925d69c9a37f099ddd3a8929004f17e162eb Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-09-17[FIX] core: non-stored binary fields should have attachment=FalseRaphael Collet
This prevents some code (in controllers) to retrieve an attachment for a field that is not stored, as the code only relies on `field.attachment`. This also makes the field definition more consistent. closes odoo/odoo#57969 X-original-commit: 13397943d9e953815ae5ce9b01ce812a92903361 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-08-21[IMP] core: error message for computed field left unassignedRaphael Collet
Non-stored readonly computed fields must be assigned by compute method. Make the error message more explicit. closes odoo/odoo#56269 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-08-20[FIX] core: first onchange on new one2many lineRaphael Collet
Consider models `M` and `L`, with a one2many field `M.l_ids` with inverse `L.m_id`. Consider also a computed field `L.foo` that depends on `L.m_id`. The field `L.foo` is not computed correctly by `onchange` on a new line in the form view of `M`: its value is forced to `False` because it has no default, and is not recomputed by `onchange` since the field `L.m_id` is never triggered an `onchange`. Modify the method `onchange` to not force fields without a default to `False`, and return all fields.
2020-08-17[FIX] base: docstring typoRémi Rahir
closes odoo/odoo#55983 X-original-commit: edacc0fc920e27b9759408887762fcba284ee391 Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
2020-08-17[IMP] core: clarify making fields inaccessibleXavier Morel
* add a constant to `fields` for that purpose * add a test to ensure that it works as expected * fix the formatter so it handles the pattern correctly
2020-07-20[FIX] core: update of one2many field on new record with originRaphael Collet
When setting the inverse many2one field on a record, the record is not removed from its inverse relation if the field's current value is not in cache. Fix this by setting the field's value in cache before updating. closes odoo/odoo#54711 X-original-commit: df12c85816dfa59f298c3e6a077bd88e4b7aa6a6 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-07-16[FIX] core: mapped() does not prefetch as expectedAdrian Torres
Before this commit, calling `mapped()` on a relational field of a single record inside a for loop does not correctly propagate the prefetch ids from the bigger recordset down to the record inside the loop: [rec.line_ids.mapped('name') for rec in recs] To be more precise, `recs` correctly propagates prefetching information down to `rec.line_ids`, but method `mapped()` does not pass it along to the record that triggers the prefetching. This resulted in one query per record in `recs`, so if `recs` were a 1000 records recordset, at least 1000 queries would be necessary. With this commit, the `mapped()` function correctly propagates the `_prefetch_ids` of the larger recordset (`rec.line_ids`) so that the prefetching works properly and the 1000 queries are brought down to 1. This commit is a followup on #42611. closes odoo/odoo#54565 X-original-commit: 0e97053fee36c0c76b70cb94be5340c3144b178b Signed-off-by: Raphael Collet (rco) <rco@openerp.com> Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
2020-07-16[FIX] core: update of one2many field on new record with originRaphael Collet
An onchange method can remove an existing line from a one2many field of a new record with command 2, such as: move.line_ids = [(2, <NewId origin=42>), ...] The processing of the command 2 above incorrectly tries to remove the new line from the origin record, instead of the new record. closes odoo/odoo#54545 X-original-commit: 7d138a445acbd9f2e122d9c30ca81877bae6a245 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-06-23[FIX] orm: don't log errors on constraint failure unless necessaryAdrian Torres
Given an scenario in which a field F of model M is defined in module X as `required=True` and is extended by another module Y as `required=False` in a database with data not satisfying the original constraint: During an upgrade of base the original constraint will be re-applied on the data (and fail) even though it is no longer necessary because module Y relaxes the NOT NULL constraint. This failure in and of itself is non-blocking, the upgrade will go through but an error and a warning are logged anyway which are not problematic either except in the case of automated testing infrastructure (such as runbot), because of this it would be best if these errors would not be logged at all unless we're 100% sure that the constraint that was applied is not relaxed downstream. With this commit, the `finalize_constraints` method will verify that the constraint is applicable (field is required) before re-applying the NOT NULL constraint. opw-2269220 closes odoo/odoo#53529 X-original-commit: f09f4826fbdd1a547503c51a3cfad71285312c49 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-06-17[FIX] core: make `state` special case overridableXavier Morel
`state` was special cased in `copy_data` such that it would always be reset to its default value if it had one. While this special case can be useful (maybe) and is certainly ingrained in odoo, having it not be overridable can be problematic. Move the special case to the fields, so it's possible to explicitly mark state fields as copy. closes odoo/odoo#53113 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-06-11[FIX] core: do not compute a field on a mix of new and real recordsRaphael Collet
This fix looks like good practice to avoid confusing developers when writing compute methods for fields, and should not be necessary. But it actually fixes an extremely obscure bug in the computation of the field `sale.order.invoice_status` when dealing with timesheets (module sale_timesheet_enterprise). The bug seems triggered by the fact that the field is computed on both a given sales order and a new record with that sales order as origin. X-original-commit: f9c128c6f567dfaab5cfb0080e4fdc847942911a
2020-05-26[IMP] *: make ir.property methods privateMartin Trigaux
Should only interact with them via python code in a controlled environment, no direct call with RPC
2020-05-14[IMP] doc: Image field documentationVictor Feyens
It was considered important to precise that image fields without limitations weren't checked at all and could therefore contain non image content (and precise some other things on Image fields). Forward-port of #51200 closes odoo/odoo#51259 Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
2020-05-14[FIX] core: selection override with str or callableRaphael Collet
If the original field is defined with a selection list, overrides with method or methods names fall back on the list. closes odoo/odoo#51232 X-original-commit: 272ba8d2238d1d1b87f47b114b55e6eed25314a8 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-05-13[FIX] base: default check_company domain.Victor Feyens
The supported case of check_company on `res_company` model fields was not considered when specifying a default domain on `check_company=True` fields. closes odoo/odoo#48674 Nb: It is already correctly supported in the `_check_company()` method. Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-05-08[FIX] core: partial unlink in recordsetRaphael Collet
The following loop crashes on the second iteration: for record in records: record.display_name # access non-stored computed field record.unlink() # delete record The cache has been invalidated by `unlink` on the first iteration, so the field is computed. The computation is done on the whole recordset, which fails with a `MissingError` because of the first record. The fix is to retry the recomputation on the single record in this case. closes odoo/odoo#50910 X-original-commit: 7f33ebf528b1415452ce549e3329c3fe89be0ad8 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-05-06[FIX] core: unexpected cache invalidation when updating one2manyRaphael Collet
When setting a many2one field, the corresponding one2many fields are updated in cache. When such a one2many field has a domain, the evaluation of the domain may require to fetch some fields from the database. If the `towrite` cache has not been updated yet, the many2one field is overridden by the database value. Fix by setting the `towrite` cache before updating inverse fields. closes odoo/odoo#50788 X-original-commit: c1ebfe05a66cfebc7ced36e25db5f6ff4bfb2d46 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-04-30[FIX] core: improve cache consistency of translated fieldsRaphael Collet
X-original-commit: 7460d65387edd9d8578e048da6ee634ef6a2e71e Co-authored-by: Christophe Simonis <chs@odoo.com>
2020-04-18[FIX] fields: screwing up cache when rounding monetary valueRaphael Collet
Consider a sales order with a single line. Edit the sales order: remove the line, and add another line with the same subtotal. When saving, the total of the sales order is 0.0. Here is the explanation: the form view performs a `write` on the sales order, and modifies the lines with a command `2` (remove line) and a command `0` (create line). After deleting the first order line, the cache is emptied, and a call to `flush()` forces the recomputation of the total. The value is computed to be 0, and assigned to the field. The assignment converts the value for the cache, without prefetching the currency field (optimization), and puts 0.0 in cache. The assignment then converts the value for the database, which prefetches most fields on the sales order: the cache is now inconsistent and contains the old value V, while the database is then updated with 0.0. After creating the new order line, the total is once again recomputed. Its value is V, and because the cache also contains that value, no update is performed to the database, which remains at 0.0! The fix consists in avoiding the prefetching of fields when accessing the currency field to round a monetary value. opw-2223134 closes odoo/odoo#49741 X-original-commit: 048ea2f20a0a2fa6d629cbe262cbbe765248d36f Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-04-08[IMP] base: remove redundant base64 back and forth in attachmentsXavier Morel
* add a `raw` computed field, though only update some of base to use it (addons for which that makes sense can be migrated progressively) * avoid working with base64 data when it's possible to work with the actual data * improve datas (base64 encoded content): should depend on bin_size closes odoo/odoo#47212 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-04-07[FIX] fields: add support for parameter `invisible` (actually used)Raphael Collet
2020-04-07[IMP] fields: add validation of parameter namesRaphael Collet
2020-04-07[IMP] base: document all field types.Victor Feyens
closes odoo/odoo#49135 X-original-commit: cc653d3f1a49e2b7b2cc0ec833097bd7cf3528a1 Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
2020-04-03[FIX] core: add NOT NULL constraints in post-initRaphael Collet
The method `_init_column` for the field `alias_id` of `mail.alias.mixin` requires the reflection of models, because `mail.alias` records have a many2one field to `ir.model`. The actual initialization of the column is thus performed in post-init phase (after reflection). Therefore, the NOT NULL constraint cannot be added right away. X-original-commit: 2e3400f149ce4ed4c00bc49a519f58993b49bc51
2020-04-03[IMP] core: add/update foreign keys in batchRaphael Collet
This greatly reduces the number of queries to add foreign keys (notably for many2one fields). This saves 6.5% of the total installation time. X-original-commit: 13a2666b4da09fc0ec7608a974dadde45f76fd7a
2020-04-03[IMP] core: create/drop indexes all at onceRaphael Collet
Reduce the number of queries to create and drop indexes. This saves 1.5% of the total installation time. X-original-commit: 0e1e480da9d971575feba64038c4fa518ebe102b
2020-04-03[IMP] core: compute field_computed lazilyRaphael Collet
This is a simple refactoring. X-original-commit: 634775bff6d9eba9d4548cc801071a942895a719
2020-04-03[IMP] core: compute field triggers lazily on registryRaphael Collet
This saves 2% of the total installation time. X-original-commit: 6a0028f91944b1d9e4eac026e86ca249ef5bc7ee