You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
2.6 KiB

  1. # Copyright 2017 Jairo Llopis <jairo.llopis@tecnativa.com>
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  3. from odoo import api, models
  4. class Base(models.AbstractModel):
  5. _inherit = "base"
  6. @api.model
  7. def load(self, fields, data):
  8. """Try to identify rows by other pseudo-unique keys.
  9. It searches for rows that have no XMLID specified, and gives them
  10. one if any :attr:`~.field_ids` combination is found. With a valid
  11. XMLID in place, Odoo will understand that it must *update* the
  12. record instead of *creating* a new one.
  13. """
  14. # We only need to patch this call if there are usable rules for it
  15. if self.env["base_import.match"]._usable_rules(self._name, fields):
  16. newdata = list()
  17. # Data conversion to ORM format
  18. import_fields = list(map(models.fix_import_export_id_paths, fields))
  19. converted_data = self._convert_records(
  20. self._extract_records(import_fields, data)
  21. )
  22. # Mock Odoo to believe the user is importing the ID field
  23. if "id" not in fields:
  24. fields.append("id")
  25. import_fields.append(["id"])
  26. # Needed to match with converted data field names
  27. clean_fields = [f[0] for f in import_fields]
  28. for dbid, xmlid, record, info in converted_data:
  29. row = dict(zip(clean_fields, data[info["record"]]))
  30. match = self
  31. if xmlid:
  32. # Skip rows with ID, they do not need all this
  33. row["id"] = xmlid
  34. newdata.append(tuple(row[f] for f in clean_fields))
  35. continue
  36. elif dbid:
  37. # Find the xmlid for this dbid
  38. match = self.browse(dbid)
  39. else:
  40. # Store records that match a combination
  41. match = self.env["base_import.match"]._match_find(self, record, row)
  42. # Give a valid XMLID to this row if a match was found
  43. # To generate externals IDS.
  44. match.export_data(fields)
  45. ext_id = match.get_external_id()
  46. row["id"] = ext_id[match.id] if match else row.get("id", "")
  47. # Store the modified row, in the same order as fields
  48. newdata.append(tuple(row[f] for f in clean_fields))
  49. # We will import the patched data to get updates on matches
  50. data = newdata
  51. # Normal method handles the rest of the job
  52. return super(Base, self).load(fields, data)