[RFR] base_changeset: adapt intercept of create to Odoo 14 cache changes

pull/2380/head
Stefan Rijnhart 2022-06-13 15:49:27 +02:00 committed by Miquel Raïch
parent d77f2a803e
commit 8557d1163f
5 changed files with 24 additions and 29 deletions

View File

@ -81,23 +81,7 @@ class Base(models.AbstractModel):
return result return result
for this, vals in zip(result, vals_list): for this, vals in zip(result, vals_list):
local_vals = self.env["record.changeset"].add_changeset( local_vals = self.env["record.changeset"].add_changeset(
# create a record-like object with empty values, this, vals, create=True
# but pass required many2one fields as those are
# most likely to be used in rule conditions
self.new(
{
field_name: value
for field_name, value in vals.items()
if field_name in self._fields
and self._fields[field_name].required
and isinstance(
self._fields[field_name],
fields.Many2one,
)
},
this,
),
vals,
) )
local_vals = { local_vals = {
key: value for key, value in local_vals.items() if vals[key] != value key: value for key, value in local_vals.items() if vals[key] != value

View File

@ -78,7 +78,7 @@ class RecordChangeset(models.Model):
self.with_context(skip_pending_status_check=True).mapped("change_ids").cancel() self.with_context(skip_pending_status_check=True).mapped("change_ids").cancel()
@api.model @api.model
def add_changeset(self, record, values): def add_changeset(self, record, values, create=False):
"""Add a changeset on a record """Add a changeset on a record
By default, when a record is modified by a user or by the By default, when a record is modified by a user or by the
@ -102,6 +102,9 @@ class RecordChangeset(models.Model):
:param values: the values being written on the record :param values: the values being written on the record
:type values: dict :type values: dict
:param create: in create mode, no check is made to see if the field
value consitutes a change.
:type creatie: boolean
:returns: dict of values that should be wrote on the record :returns: dict of values that should be wrote on the record
(fields with a 'Validate' or 'Never' rule are excluded) (fields with a 'Validate' or 'Never' rule are excluded)
@ -133,14 +136,20 @@ class RecordChangeset(models.Model):
if not rule or not rule._evaluate_expression(record): if not rule or not rule._evaluate_expression(record):
continue continue
if field in values: if field in values:
if not change_model._has_field_changed(record, field, values[field]): if not create and not change_model._has_field_changed(
record, field, values[field]
):
continue continue
change, pop_value = change_model._prepare_changeset_change( change, pop_value = change_model._prepare_changeset_change(
record, rule, field, values[field] record,
rule,
field,
values[field],
create=create,
) )
if pop_value: if pop_value:
write_values.pop(field) write_values.pop(field)
if not record.id: if create:
# overwrite with null value for new records # overwrite with null value for new records
write_values[field] = ( write_values[field] = (
# but create some default for required text fields # but create some default for required text fields
@ -159,7 +168,7 @@ class RecordChangeset(models.Model):
def _prepare_changeset_vals(self, changes, record, source): def _prepare_changeset_vals(self, changes, record, source):
has_company = "company_id" in self.env[record._name]._fields has_company = "company_id" in self.env[record._name]._fields
has_company = has_company and record.company_id has_company = has_company and record.company_id
company = record.company_id if has_company else self.env.user.company_id company = record.company_id if has_company else self.env.company
return { return {
# newly created records are passed as newid records with the id in ref # newly created records are passed as newid records with the id in ref
"res_id": record.id or record.id.ref, "res_id": record.id or record.id.ref,

View File

@ -338,7 +338,7 @@ class RecordChangesetChange(models.Model):
return value return value
@api.model @api.model
def _prepare_changeset_change(self, record, rule, field_name, value): def _prepare_changeset_change(self, record, rule, field_name, value, create=False):
"""Prepare data for a changeset change """Prepare data for a changeset change
It returns a dict of the values to write on the changeset change It returns a dict of the values to write on the changeset change
@ -364,7 +364,7 @@ class RecordChangesetChange(models.Model):
change["state"] = "cancel" change["state"] = "cancel"
pop_value = True # change never applied pop_value = True # change never applied
if change["state"] in ("cancel", "done"): if create or change["state"] in ("cancel", "done"):
# Normally the 'old' value is set when we use the 'apply' # Normally the 'old' value is set when we use the 'apply'
# button, but since we short circuit the 'apply', we # button, but since we short circuit the 'apply', we
# directly set the 'old' value here # directly set the 'old' value here
@ -372,7 +372,9 @@ class RecordChangesetChange(models.Model):
# get values ready to write as expected by the changeset # get values ready to write as expected by the changeset
# (for instance, a many2one is written in a reference # (for instance, a many2one is written in a reference
# field) # field)
origin_value = self._value_for_changeset(record, field_name) origin_value = self._value_for_changeset(
record, field_name, value=False if create else _NO_VALUE
)
change[old_field_name] = origin_value change[old_field_name] = origin_value
return change, pop_value return change, pop_value

View File

@ -79,9 +79,7 @@ class TestChangesetFlow(ChangesetTestCommon, TransactionCase):
"""Create a new partner with a changeset""" """Create a new partner with a changeset"""
new = ( new = (
self.env["res.partner"] self.env["res.partner"]
.with_context( .with_context(test_record_changeset=True)
test_record_changeset=True,
)
.create( .create(
{ {
"name": "partner", "name": "partner",
@ -90,6 +88,8 @@ class TestChangesetFlow(ChangesetTestCommon, TransactionCase):
} }
) )
) )
new._compute_changeset_ids()
new._compute_count_pending_changesets()
self.assertEqual(new.count_pending_changesets, 1) self.assertEqual(new.count_pending_changesets, 1)
self.assert_changeset( self.assert_changeset(
new, new,

View File

@ -34,4 +34,4 @@ class TestChangesetFlow(ChangesetTestCommon, TransactionCase):
] ]
) )
self.assertTrue(changeset) self.assertTrue(changeset)
self.assertFalse(changeset.sudo(user).search([("id", "=", changeset.id)])) self.assertFalse(changeset.with_user(user).search([("id", "=", changeset.id)]))