Commit Graph
30 Commits
Author SHA1 Message Date
Xavier Morel 9ebbfdac73 [FIX] *: incorrect translations markings
Fixes a large number of cases where strings are translated then
formatted, instead of letting `_()` do the formatting internally,
which allows it to recover from incorrect translations (missing,
broken, or extra placeholders).

Also

- removes translation markers entirely when there's nothing to
  translate e.g. `_("%s - %s")` is not useful
- fixes a few messes which lead to only partial translatability
  (DRY is generally a bad idea when translations are involved, even
  more so when you don't make the variable part translatable)
- fixes a few nearby issues noticed at the same time
- replaces a few `"%s"` by `%r`, which should automatically quote
  strings relatively appropriately
- fixes translated strings which use `\` to escape a newline (in order
  to fill-paragraph): `\` escapes only the newline, if the
  continuation string is indented this results in a bunch of spaces
  ending in the string to translate, which is pretty garbage for the
  translator, using implicit concatenation works much better

Note: some of the updates revert f-string parameters to %, because
babel (2.9) apparently has trouble with f-strings and blows up trying
to extract them.

Not in scope:

Helping translators fix translatable strings e.g. any translation
string with more than one placeholder probably should use keyword
placeholders

- Provides more context / data to the translator to make sense of the
  sentence.
- Allows reordering the translated terms, which can be necessary
  depending on the sentence and language.

closes odoo/odoo#139314

Related: odoo/enterprise#49311
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-10-23 16:45:09 +00:00
Adrien Widart (awt) f41c3b1d9e [FIX] base: rollback if broken transaction while importing
Suppose a user who has CRM module and wants to import some leads
thanks to this CSV file:
```csv
name,recurring_plan
Coca-Cola,Plan01
SAP,Plan02
```
And, because the recurring plans are not yet created on his database,
he enables the option "Create new values" for that field. An error
will occur and here is the only info the user will have:
> current transaction is aborted, commands ignored until end of
> transaction block

When importing, we convert the data encoded by the user ([1]). To do
so, we convert the provided values, field by field ([2]). Since
`recurring_plan` is a `many2one` field, we go (through
`_str_to_many2one`) in `db_id_for`. In this method, we `name_search`
the record and then, if it does not exist and if the feature is
enabled, we `name_create` it ([3]).

Back to the above use case. We start with the first line and there is
not any recurring plan called "Plan01" so we try to create it. But
here is the issue: we only have a name to create the record although
there is another required field: `number_of_months`. Therefore, it
leads to a `NotNullViolation` error. This error is caught (see [3])
and, later in the same method, we will raise a `ValueError`. This
error will be caught by one of the except in [2]: we will save the
error and will then  continue with the convertion of next values.
However, because of the `NotNullViolation`, the current SQL
transaction is broken. As a result, while trying to convert the
second line of the file, we will `name_search` "Plan02" and it will
simply lead to a `InFailedSqlTransaction`

[1]
https://github.com/odoo/odoo/blob/f3d7fdce608f692ecb08498ee158edf9dfbced5e/odoo/models.py#L1170-L1182
[2]
https://github.com/odoo/odoo/blob/b80d4294a000e748677a3a0c1849140bf46ddbe8/odoo/addons/base/models/ir_fields.py#L117-L118
[3]
https://github.com/odoo/odoo/blob/b80d4294a000e748677a3a0c1849140bf46ddbe8/odoo/addons/base/models/ir_fields.py#L472-L475

sentry-3969379125

closes odoo/odoo#132897

X-original-commit: 28373b9d261a48154b233fbbd895880680b0aed0
Signed-off-by: Adrien Widart (awt) <awt@odoo.com>
2023-08-24 18:38:17 +02:00
Rémy Voet (ryv) 3c62ca1eb9 [REM] core: remove name_get API
Rationale
=========

Since v8, the `display_name` field is present on all models. By default,
`display_name` uses `name_get` which has pretty much the same purpose
(return record name used by the web client). Gradually, many (backend)
developers (and the ORM: https://github.com/odoo/odoo/commit/6da1c3ac4c036eac289597602976538e243cb939)
started using `display_name` (more convenient than
`record.name_get()[0][1]`) but it still had the `name_get` override.
It becomes more complex than necessary and poeple start to misunderstand
the two (and sometimes override both, leading to inconstiencies between
`display_name`/`name_get`).

To simplify the ORM and the API, we decided to keep only one of them,
the `display_name` field:
- It is much more convenient from a backend point of view
(`record.name_get()[0][1]` vs `record.display_name`)
- It is cached during the same transaction (and invalidated if
its dependencies change)
- It can be overridden like any other compute field (override
`_compute_display_name` with any extra dependencies)
- `name_get` is replaced by `read(['display_name'])`
(API perceptive), which can actually be more efficient
(if `display_name`'s depends are correct, the ORM will only fetch the
fields it needs instead of every prefetchable field)

Changes
=======

- Deprecates `name_get` for the v17 and based the method on
`display_name` (the opposite of before)
- Converts all usage of `name_get`
- Overrides of `name_get` are now overrides of `_compute_display_name`
- For `res.partner`, rename the field store `display_name` into
`complete_name` because `display_name` context-dependent and it makes
no sense to have a compute store that is context-dependent.
- Previously, it was possible to return multiple names for the same
record with `name_get`, but it was tricky and most of the usage of
this `name_get` didn't take this into account. The only example of
this is the `name_get` of `product.product`
(now use `", ".join(<names>)`).

Part-of: odoo/odoo#122085
2023-06-28 17:41:19 +02:00
Mohit Beniwal 7e84ec87b1 [FIX] base: prevent error while uploading record of type properties
This error occurs when user import records having value in 'properties' column
which is of datatype, 'properties' and while trying to get attribute from
getattr to get value of converter it is getting default value None. That's why
this error is produced, 'NoneType' object is not callable.

Steps to reproduce:
1) Install 'CRM' module.
2) Open 'CRM' module and in it click on 'List' view.
3) Open any record and add value for field 'Add a property'.
4) Export that records.
5) Now click on 'Favourites' > 'Import records'.
6) Now click on 'UPLOAD FILE' button > upload that exported file.
7) Now click on 'TEST' button, error will be generated.

By applying this, user will be able to import record of datatype
'properties'.

Sentry-4128524668

closes odoo/odoo#126609

X-original-commit: b80d4294a000e748677a3a0c1849140bf46ddbe8
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
2023-06-28 09:59:54 +02:00
Ivan Yelizariev 44ccc0dd83 [FIX] core: support export/import for json fields
New class `fields.Json` is introduced in v16. The feature lacks some converting
methods for export/import. This commit fills the gap.

Example: field `line_ids/analytic_distribution` in `account.move` (Invoices)

opw-3056669

closes odoo/odoo#105973

X-original-commit: abbe2e002c0125ecb83a1ab3ee80acf3f43e3cb6
Signed-off-by: Ivan Elizaryev (iel) <iel@odoo.com>
2022-11-18 12:58:09 +01:00
william eaa2e3b452 [FIX] base: import related field with name containing %
To reproduce, import and invoice containing one line with a tax of
i.e. `21%` on it.

Because the message is recursively expanded to follow the relation of
the field, the interpolation symbol needs to be escaped every time.
Otherwise the message will contain something like
> No matching record found for name '21%' in field '%(field)s/Taxes'

Where `'21%'` will try to be mistakenly interpolated.

X-original-commit: ceb3ce3030b47baa2aca128d364a823becb173ab
Part-of: odoo/odoo#104764
2022-11-02 22:20:40 +01:00
Rémy Voet (ryv) f66fa9433f [MOV] core,base: move logic of O2MIdMapper
O2MIdMapper Class inherit of 'base' Model to change the behavior of
`create`.
Because it is in base and the `_import_current_module` is set in
models.py, move it at the end of create in models.py.

closes odoo/odoo#99550

Related: odoo/enterprise#33063
Signed-off-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
2022-11-02 15:34:30 +01:00
ef00294e71 [IMP] core: store translated fields as JSONB columns
Translated fields no longer use the model ir.translation.  Instead they store
all their values as JSON, and store them into JSONB columns in the model's
table.  The field's column value is either NULL or a JSON dict mapping language
codes to text (the field's value in the corresponding language), and must
contain an entry for key 'en_US' (as it is used as a fallback for all other
languages).  Empty text is allowed in translation values, but not NULL.

Here are examples for a field with translate=True:

    NULL
    {"en_US": "Foo"}
    {"en_US": "Foo", "fr_FR": "Bar", "nl_NL": "Baz"}
    {"en_US": "Foo", "fr_FR": "", "nl_NL": "Baz"}

Like before, writing False to the field makes it NULL, i.e., False in all
languages.  However, writing "" to the field makes its value empty in the
current language, but does not discard the values in the other languages.

Here are examples for a field with translate=xml_translate:

    NULL
    {"en_US": "<div>Foo<p>Bar</p></div>", "fr_FR": "<div>Fou<p>Barre</p></div>"}

Change for callable(translate) fields: one can now write any value in any
language on such a field.  The new value will be adapted in all languages, based
on the mapping of terms between languages in the old values.  Basically the
structure of the value must remain the same in all languages, like before.

Reading a translated field is now both simpler and faster than the former
implementation.  We fetch the value of the field in the current language by
coalescing its value with the 'en_US' value of the field:

    SELECT id, COALESCE(name->>'fr_FR', name->>'en_US') AS name ...

The raw cache of the field contains either None or a dict which is conceptually
a subset of the JSON value in database (except for missing languages).  For the
sake of simplicity, most cache operations deal with the dict and return the text
value in the current language.

Trigram indexes have been adapted to the new storing strategy, and should enable
to search in any language.  Before this change, only the source value of the
field ('en_US') could be indexed.

Computed stored translated fields are not supported by the framework, because of
the complexity of the computation itself: the field would need to be computed in
all active languages.  We chose to not provide any hook to compute a field in
all languages at once, and the framework always invokes a compute method once to
recompute it.

Code translations are no longer stored into the database.  They become static,
and are extracted from the PO files when needed.  The worker simply uses a cache
with extracted code translations for performance.  This is reasonable, since
fr_FR code translations for all modules takes around 2MB of memory, and the
cache can be shared among all registries in the worker.  Changing code
translations requires to update the corresponding PO file and reloading the
worker(s).

Performance summary:
 (+) reading 'model' translated fields is faster
 (+) reading 'model_terms' translated fields is much faster (no need to inject
     translations into the source value)
 (+) searching translated fields with operator 'ilike' is much faster when the
     field is indexed with 'trigram'
 (+) updating translated fields requires less ORM flushing
 (-) importing translations from PO files is 2x slower

Some extra fixes:
 - make field 'name' of ir.actions.actions translated; because of the PG
   inheritance, this is necessary to make the column definition consistent in
   all models that inherit from ir.actions.actions.
 - add some backend API for the web/website client for editing translations
 - move methods get_field_string() to model ir.model.fields
 - move _load_module_terms to model ir.module.module
 - adapt tests in test_impex, test_new_api
 - because env.lang is injected into SQL queries, its returned value is
   now guaranteed to correspond to a valid active language or None
 - remove wizard to insert missing translations (no longer makes sense)

task-id: 2081307

Co-authored-by: Fabien Pinckaers <fp@openerp.com>
Co-authored-by: Raphael Collet <rco@odoo.com>
2022-09-15 22:37:50 +02:00
Abdelouahab (abla) 5bc83b046a [FIX] base : fix importing file with special character
To reproduce
============

for example on accounting, attempt to import a record from excel containing a special character like `%`.
Gets error stating the system doesn't support these

Purpose
=======

the issue is caused by misfromatted error string :
https://github.com/odoo/odoo/blob/b859d78c3d56526f44fbdd9ce5e84d34cf8a0a35/odoo/addons/base/models/ir_fields.py#L410-L411

Specification
=============

to solve the issue use :
`str(value).replace('%', '%%')`

opw-2838573

closes odoo/odoo#96336

X-original-commit: eb0152d4c5ec38c33ccc5381d1277543354e3456
Signed-off-by: abla001 <abla@odoo.com>
2022-07-19 21:22:09 +02:00
Xavier Morel bdc9d9d369 [FIX] core; base: lots of docstrings
* add configuration for `flake8[flake8-rst-docstring]`
* enable docstring-related checks
* fix invalid docstrings in odoo's core & `base`
* fix a few more bits (mostly missing or incorrect `:param:` info
  fields) are out of scope for the lint but my editor catches

closes odoo/odoo#74604

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2021-12-09 14:36:58 +00:00
Nikunj LadavaandMohammed Shekha 662ecf4e20 [IMP] base_import: improve import wizard preview
PURPOSE

Improve import wizard as followup of recent improvements.

SPECIFICATIONS

Preview lines

  - make the preview lines more visible
    - set font-weight: 500 on o_import_header_name
    - remove the text-muted class from the data preview line

  - allow the user to preview the first 5 non-empty values
    - when hovering on the data preview span, display a tooltip with the first
    5 non-empty values of the file column (with 'Preview' as the tooltip title)

  - In the 'when a value cannot be matched' dropdown:
    add a new 'skip record' option for the following field types: boolean,
    many2one, many2many, selection
    add a new 'set empty' for the following field types: many2one, many2many,
    selection hide this option if the field is required

When a value cannot be matched:
  the 'skip record' option will make sure that lines with an unmatched value
  will not be imported (i.e. skipped at import)
  the 'set empty' option will set the field value to False when the value
  cannot be matched

  - Restore colored background on alert boxes by removing some css rules

Task-2504343

closes odoo/odoo#73713

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Co-authored-by: Mohammed Shekha <msh@odoo.com>
2021-09-02 12:57:13 +00:00
Xavier Morel 7ac3a391a1 [FIX] core: don't break import on files triggering UnicodeEncodeError
The import logging (ish) assumes that if an exception has at least 2
args the second arg is metadata added by the callee.

As it turns out, `UnicodeEncodeError` has *five* arguments, none of
which is added by us. So if encoding something fails during the
process (e.g. because the file contains a lone surrogate, which leads
to the database insert failing when psycopg2 tries to encode the query
to UTF8), then the `_log` function itself will fail, yielding a very
unhelpful error of:

   dictionary update sequence element #0 has length 1; 2 is required

(because we tried to update a dict using a string).

This issue occurs only during *field conversion* and most fields have
no need to interact with the database (so don't need to encode the
value, which is what fails), however it is a problem when the invalid
string is used as a record name to look for (e.g. an m2o).

Further improve the experience by converting the UnicodeEncodeError to
a ValueError using the stringified UEE: `_log` assumes the first
argument to the exception is an error message of some sort, but for
UnicodeError subclasses it's just the encoding involved in the
error (here `utf-8`), which doesn't really serve as an error message.

Stringifying the exception generates a complete error message which is
quite a bit more helpful.

Specific update notes:

* avoid modifying the exception in-place, doesn't seem useful
* not sure why `field_name` was added as part of the augmentation
  rather than up-front when `record` is created

Issue 2480064

closes odoo/odoo#72517

X-original-commit: 6c3c500929cd463cd3a1749f4ede8f3a8afd5748
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2021-06-22 09:33:43 +00:00
David Beguin c483f59b37 [REF] base_import: revamp import module
Purpose
=======

Propose an import tool that is more intuitive and allows more import options to
ease the import.

Specifications
==============

Update upload import file screen
--------------------------------

- Relabel import welcome screen
	- relabel the 'load file' button to 'upload file'
	- relabel the first (bold) line of the helper to 'Upload an Excel or CSV
	file to import'

- Move all import options in a left panel

- Invert rows and columns in the mapping view
	- One row for each column (header) to map in the imported file
	- Columns: File Column / Odoo Field / If a match cannot be found / Comments

Left panel details
------------------

The sidepanel to the left of the mapping view is composed as followed:
- Imported File
	- Import file name
	- Sheet: Dropdown to select the sheet in the file if there are more than 1.
	- 'use first row as header' checkbox: like the existing option, defines
	whether the first row of the file should be considered as the header.
	True by default. If False, display the first value only under 'File Column'
	(see above)
- Formatting: only available if the file is a .csv
	- list every option that already existed in previous import implementation.
- Batch Import
	- is only available in debug moide and if the file exceeds the batch limit
	- Batch limit : 2000
	- Allow to define the threshold and the batch size.
- Help
	- Download Template link
	- Go to FAQ link
- Advanced
	- Track history during import. (same as existing functionallity)
	- Show Fields of relation fields. (same as existing functionallity)

Columns details
---------------

- File Column:
	- Contains the column headers of the import file and the first non-empty
	value of the column as a 'subtitle' (in grey italic)
	- If 'use first row as header' is False, only display the first column value
	(without the grey italic)

- Odoo Field:
	- Contains dropdowns to the fields of the current model
	- Required fields are diplayed in bold in the dropdown
	- Icon: In the front of the field label, the field type (char, many2one,..)
	is indicated by an icon.
	- Tooltip: when hovering a field, display a tooltip with the following
	information: field label, technical name, type, related model (if any)
	- Placeholder: If no field is selected, display the placeholder
	'To import, select a field...' in text-warning bold (i.e. orange)
	- Allow clear: there is a close (fa-times) icon at the end of the dropdown
	body to remove the Odoo field (and prevent import of this column)
	- Multi Mapping: when setting a field already matched to another column,
	unset it from the 'old' column (NB: exception made for char/text fields)

- Comments:
	- Contains feedback from the system to the user, either import
	errors/warnings or any additional details (multi mapping comments,...)
	- For many2many field, display in related comment cell the following:
	"To import multiple values, separate them by a comma".
	- If there is an import error for a specific field, the error will be
	displayed in the comment cell of the related field.
	- If there is a mapping error, mapping options are displayed under the
	error div to let the user choose the best option to fix that error.

Import errors management
------------------------

- Errors/warnings that can be matched to a specific field are displayed as
alert-danger/warning in the corresponding 'Comments' cell of the field.
- For 'no match found' errors, if X values couldn't be found,
display an unique error box will all the errors.
	- Values beyond the first three are folded under a 'More' button.
	- No changes on the 'See possible values' button.
- If an unmatched value is present in one row only, display :
	'<value> at row X (<name of the row if the name field is matched>)'
- If an unmatched value is multiple rows, display:
	'<value> at multiple rows'
- Errors/warnings/infos that cannot be matched to specific field are displayed
above the mapping listview. Global errors are not regrouped by error types to
avoid too much code complexy just to handle the rare times where multiple errors
of same types cannot be linked to a specific mapped field.

BaseImportError class have been introduced to ease the formatting of the various
exceptions that can occur during the import.

After testing the import, display the following above the mapping table:
- No warning/error:
	'Everything seems valid' (alert-info)
- At least one error:
	'The file contains blocking errors (see below)' (alert-error)
- At least one warning but no error:
	'The file contains non-blocking warning (see below)' (alert-warning)

Mapping options
---------------

Mapping options are only displayed after testing or importing the file,
if there are import errors. The goal is to have a clean interface and to guide
the user step by step. The import process can therefore be a bit longer as it
needs to import -> choose solution for errors -> re-import but that is easier
for users to learn and understand this reworked import tool.

Possible values when a value cannot be matched:
- For many2one / many2many fields:
	- Prevent import: (selected by default) not finding a match is blocking the
	import
	- Skip unknown values: values that cannot be matched will be skipped.
	(hidden if the field is required)
	- Create new values: Create records for values that cannot be matched
- For selection fields:
	- Prevent import (selected by default)
	- Skip unknown values: (hidden if the field is required)
	- Set to <first value>: if cannot be matched, set it to <first value>
	- Set to <second value>
	- Set to <third value>
	- etc.
- For boolean fields:
	- Prevent Import (selected by default)
	- Set to True
	- Set to False
	Note: With this rework, boolean warnings where the system assumes the
	replacement value in case of matching error is removed and is replaced by a
	blocking error. The user now has to choose the value to set.

"Prevent import" is the default behaviour when testing or importing.

Automatic mapping proposal
---------------------------

When loading a file, an automated mapping is directly proposed to the user,
based on word distance (see below), and on mapping created on previous
imports.
- Priority is given for mapping created on previous imports, skip fuzzy mapping.
	- a distance of -1 is used to ensure priority during duplicates removal .
	- In case multiple headers are mapped on the same field, if the mapped field
	is already taken by another header, use fuzzy mapping instead.
- If no previous mapping for that header on that model, try an exact match on
every field id and field name of the model. (distance = 0)
- If no match is found, fuzzy mapping is applied (word distance).
The fuzzy mapping is executed only on the most likely fields (see below).
- Remove duplicates: keep the header-field couple that has the smallest
distance. In case of equality, keep the first.

Automatic mapping is therefore optimised for previous mapping or exact match,
as fuzzy mapping requires heaviest treatment. This is intended to prioritise the
import of files based on import templates.

Most likely fields
------------------

When parsing the import file, each header is analysed to guess what type of data
the column contains. For example, ff the column contains float, we suppose that
that header will most likely be matched on float or monetary fields.
The most likely fields are a subset of the model's fields that match the
header types.

Most likely fields are used for the fuzzy mapping, to propose the user a field
mapping based on the header types, if an exact match could not be found.

Most likely fields are also listed under "Suggested fields" in the mapping
dropdown in "Odoo Field" column of the import tool.
For now on, every fields (no mather their type) can be matched to any header,
but we prioritise the most likely fields. This way, we don't constrain the
mapping possibility based on what we suppose the user would do, but we instead
guide suggest the user the most likely mapping solutions.

Word distance mapping
----------------------------

In order to improve the mapping configuration, if an exact match cannot be found
between the file column and one of the odoo field:
- Use Word distance:
	Word distance return a indice between 0 and 1.
		- 0: exact match
		- 1: completely different
	- A: First try on field['name']
	- B: Then on field['string']
	- Keep the minimal distance between A and B for each odoo_field
	- C: Keep the field that has the minimal distance.
	- Match the column to the field by default if C['distance'] < 0.3.
	Note: 0.3 has been chosen to ensure proximity but still having a little
	error margin.

Multi mapping
-------------

When multiple file columns are matched to the same char/text/many2many field,
display the following alert-info box in the "Comments" column of the related
fields:

	"Those columns will be concatenated in field <field label>"

Multi mapping rule :
	- If it is a char field, separate the concatenated values by a space
	- If it is a text field, separate the concatenated values by a line break
	- If it is a many2many field, separate the concatenated values by a comma

Various improvements
--------------------

- During Import (or Test), the first waiting message displayed has been modified
to 'Importing...' or 'Testing...'. The progress (x record imported/tested) is
only displayed after the first batch of record have been imported/tested.
- Ease matching for Selection field: use case insensitive comparaison instead
of exact match.
- Add filename to import wizard.
- Add placeholder to search input of field mapping dropdown.

Tests have been adapted accordingly.

Links
=====

Task ID: 2352241

closes odoo/odoo#61948

Related: odoo/enterprise#17246
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2021-04-02 11:17:31 +00:00
Raphael Collet f2d4ba6890 [FIX] core: imports with one2many lines with dangling external ids
Consider a model M with a one2many field with comodel L, such that
deleting records in M cascade-deletes records in L.  Import a bunch of
records in M with one2many lines having specific external ids.  Delete
the imported records: the database cascade-deletes the corresponding
lines, but the lines' external ids are not deleted.  Now re-import the
same records: this crashes, because the import process finds the lines'
external ids and tries to update the deleted lines!

The fix consists in checking that an external id's record actually
exists.  The existence check was removed for performance reasons by
https://github.com/odoo/odoo/pull/26496.  We reintroduce it by resolving
the external id with a join on the model's name, which checks the
record's existence faster than an extra query.  This patch allows to
re-create the imported records' lines.

Another patch is necessary to actually update the external ids that
refer to deleted records, otherwise they remain dangling, and importing
the same records again duplicates the lines, because their external ids
do not match any existing record.

OPW 2409649

closes odoo/odoo#63318

X-original-commit: 0322febbea2cfd2d2fd7aedc42ef03632b17c967
Related: odoo/enterprise#15285
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-12-14 11:29:21 +00:00
Julien Castiaux 90b52d144a [REF] base: Use Command helper for x2many
Task: 2366606
2020-11-30 10:16:09 +00:00
Anh Thao Pham (pta) cea6cb7183 [FIX] base: fix create option of import for Many2one in One2many
- Install Inventory
- Create an excel file with the following values :
--------------------------------------------------------------------------------------------------------------------------------------------------------
location_id               | location_dest_id | Operation Type / database ID | Stock moves / product | Stock moves / unit of measure | Stock moves / name
--------------------------------------------------------------------------------------------------------------------------------------------------------
Partner Locations/Vendors | WH/Stock         | 1                            | Non existent product  | Units                         | Test
--------------------------------------------------------------------------------------------------------------------------------------------------------
- Go to Inventory > Operations > Transfers and import the file
- Check the "Create if doesn't exist" option for "Stock moves / Product" and click on "TEST" button
Import fails because Product does not exist and is not created.

"name_create_enabled_fields" is used in frontend to store which fields have to be created if they don't exist.
The issue comes from the fact that the keys used in "name_create_enabled_fields" contain
the full path to the related field (i.e. move_lines/product_id), but only the final field name is used
when checking "name_create_enabled_fields" in the backend (i.e. product_id).

The prefix from the keys in "name_create_enabled_fields" should be removed when parsing fields from One2many.

opw-2282087

X-original-commit: fadce5c117e3a14ec659cf0accee85502214120d
2020-07-31 14:44:58 +00:00
Martin Trigaux ba244cef01 [IMP] *: replace to new _() syntax
Using a few regex like
\((_\(.*%s.*)(\) % )([\w\[\]][\w .\[\]\(\)'"]*)\)
($1, $3))

Old syntax is still compatible but starts the migration to the new
syntax that catches error.
2020-06-18 13:03:34 +02:00
Xavier Morel 6b2dfcc8b0 [IMP] core: batching during import
By default importing is batched (or at least attempted to), however
because the import is functionally sequential it's possible for a
record to refer to a previously imported record of the same batch.

When records are referenced by xid this is easy, we can just keep
track of all the xids we *should* have created so far and when trying
to look up a xid if it's one of those flush all pending
creations (otherwise assume it's some other unrelated xid which
already exists in the system).

For "name_search" lookups however this is more complicated, so we'd
just flush the entire thing.

This, then, is an issue when importing records with an m2o which
is *generally* looked up by "name" rather than xid e.g. when importing
partners it's more likely the "state" will be specified by
name (e.g. AZ or Arizona) than xid (base.state_us_3 lol), because it
means more or less every line will be flushed, defeating all batching
and slowing down the import.

To fix this, allow passing *model names* to flush (not just xids), and
try to collate all the models we could be creating (or updating)
records for in the process of importing. If we see a name_search on
one of these models flush, otherwise don't because we couldn't have
impacted the search.

Task 1951307

While at it, f2a1618758 removed all
usage of model_load_save, but left the creation of the savepoint
itself.

The InternalError check should be left in place to catch things like
conversion issues which put the tnx in an invalid state (only invalid
states should trigger an InternalError according to psycopg's errors
documentation).

closes odoo/odoo#49289

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-05-28 11:40:35 +00:00
Jinal PatelandMohammed Shekha 8f8c93b68a [IMP] base: display full name of the field in import warning
Before this change, if an error occurs while trying to match / import
a sub-field e.g. order_line/product_id, only the name of the top-level
field is showing when displaying the error e.g. "Order Line", which
lacks precision and makes understanding and fixing the issue more
complicated.

After this change, the entire field path should be displayed, e.g.
"Order Line / Product" in the example above.

Task-1906700

closes odoo/odoo#33031

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Co-authored-by: Mohammed Shekha <msh@odoo.com>
2020-03-23 11:51:30 +00:00
Wolfgang Taferner 5ac04570f1 [ADD] base: allow importing new O2M values with an xid
When importing an O2M value (sub-record), rather than raising an error
if the value has a xid set (foo_ids/id) and the xid does not exist in
the database, re-insert the xid as the "id" field of the sub-record,
then re-extract it at creation (the ORM will have ignored it) and
associate it with the newly created record.

Advantages:

* keeps o2m creation in the proper order during import (sub-records
  remain created after the parent) meaning o2ms with a required parent
  can take advantage of the feature
* avoids breaking batching when creating the objects
* no new command or smuggling through an existing command

closes odoo/odoo#35995

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2019-11-04 08:11:51 +00:00
Nans Lefebvre 0ce6eea5bd [FIX] ir_fields: import many2one_reference fields
Since a many2one_reference is simply an int, we can defer
_str_to_many2one_reference to _str_to_integer.

Note that to really validate the integer, we need the model_field of the
field, which should be stored in the record's values.
To get this information, _extract_records would have to be modified.

For the reported use-case, it does not matter as the create of the
message record checks for the existence of the related record,
so the validation works as expected.

Better support for this type of fields would be to allow for
import/export of xml_ids, which would avoid the need for the model.

opw 2087353

closes odoo/odoo#39601

X-original-commit: 77f616e9359272b2598d414672cffbc06cee2a33
Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
2019-10-30 15:50:18 +00:00
Goffin Simon f520ee8f7b [FIX] odoo: Import data with falsy many2one fields
Steps to reproduce:

- Export a partner with country set to False, using EXCELL
- Try to import it with the xls file

Bug:

It raised: "No matching record found for name 'False' in field 'Country' at row 2"

opw:2080376

closes odoo/odoo#38379

X-original-commit: 01caf1e44f653a8e9bf5edd583bc2421905d9464
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
2019-10-10 11:28:09 +00:00
Yannick Tivisse 58b3557d6d [IMP] base_import: Improve import general UX (back2basics)
Purpose
=======

Improve error management UX on import.

TaskID: 2049992

closes odoo/odoo#35804

Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
2019-08-20 12:23:08 +00:00
Hiral Bhavsar 3cd7ed07a2 [IMP] *: remove 'view_type' on window actions.
The old tree views don't really exist anymore, this odd pseudo-flag to
dispatch between "list" and "tree" tree views has no reason to remain.

Task 1937686

closes odoo/odoo#31243

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2019-06-17 11:34:17 +00:00
Adrian Torres 52f5528cfb [REF] *: replace deprecated pycompat helpers for builtins
This commit replaces calls to pycompat helpers that were intended for
python 2 <-> python 3 interoperability for python 3 builtins, as python
2 is no longer officially supported by Odoo.

This includes:
    * calls to imap/izip/ifilter replaced by map/zip/filter
    * uses of text_type replaced by str
    * uses of unichr replaced by chr
    * calls to implements_to_string, implements_iterator removed
    * string_types and integer_types replaced by str, int respectively
    * calls to to_native replaced by calls to to_text

This is done in preparation to the removal of these deprecated helpers
in the following commit.
2018-11-29 09:28:17 +00:00
Nimesh Jethva 7eea263f36 [IMP]base_*: Improvement in model description
Purpose of this commit is to give description more "business oriented"
because those descriptions appears in Odoo Studio which is supposed to be used by end users, not only by developers.

Related Task ID : 37311
2018-09-21 11:45:15 +02:00
Xavier Morel edb34ee27a [IMP] base: avoid ref() in conversion of M2O/M2M
A proper ref() call implies an exists(), which isn't that expensive
but piles up over a few thousand calls.

The partner import test case trigger 7394 calls to exists, for a total
of ~6% runtime (and under 2% for the actual xid lookup).
2018-09-11 16:43:55 +02:00
Mohammed Shekha 8fbadb9575 [ADD] base_import: debug option to create M2O/M2M records
Adds a checkbox to import columns (in debug mode) allowing a user to
create records M2O and M2M records not found (via name_search).

Task ID: 1850633

* uses a context key to avoid altering basically all the import callstack
* attempted to lift the creation in the `_str_to_*` functions and create
  m2m via commands, but that doesn't really work out
2018-08-16 11:10:35 +02:00
Raphael Collet d5b687a48f [REF] models: import records in batch
Create new methods on `BaseModel` to create records with given xml ids in
batch.  Those methods replace the methods `_update` and `_update_dummy` of
model 'ir.model.data', which are now deprecated.

Adapt XML and CSV import code to create records in batch.
2018-07-24 16:58:14 +02:00
Thibault Delavallée 1fbc29a641 [MOV] base: move ir_* models into models/ 2017-11-27 11:15:03 +01:00