Execute the barcode scanner method as side-effect method

Instead of going through the onchange machinery.
The intended usage of onchange methods is to update something on the
screen, without side-effects in the database, then let the user save
the form with the proposed changes.

Weirdly, the barcode scanner event triggers an onchange on the field
`_barcode_scanned`.

It doesn't work well with our use case, as the whole form is read-only
and we only care about having the barcode events doing side-effects on
the backend and displaying back the changes.

This particular onchange will then be executed as a normal method, with
side-effects. However, contrarily to other actions on the form, the
frontend does not reload the view after an onchange, as it relies on the
data returned back in the values. As we cannot know which values may
have been changed in the different implementations (location
destination, state, ...), the onchange returns a read with every field.
This commit is contained in:
Guewen Baconnier
2020-06-26 14:25:48 +02:00
committed by Hai Lang
parent 5fb25caed4
commit d1b7a6f47c
3 changed files with 17 additions and 7 deletions

View File

@@ -36,6 +36,20 @@ class VerticalLiftOperationBase(models.AbstractModel):
)
]
def onchange(self, values, field_name, field_onchange):
if field_name == "_barcode_scanned":
# _barcode_scanner is implemented (in the barcodes module) as an
# onchange, which is really annoying when we want it to act as a
# normal button and actually have side effect in the database
# (update line, go to the next step, ...). This override shorts the
# onchange call and calls the scanner method as a normal method.
self.on_barcode_scanned(values['_barcode_scanned'])
# We can't know which fields on_barcode_scanned changed, refresh
# everything.
return {"value": self.read()[0]}
else:
return super().onchange(values, field_name, field_onchange)
@api.depends()
def _compute_number_of_ops(self):
for record in self:
@@ -164,7 +178,7 @@ class VerticalLiftOperationTransfer(models.AbstractModel):
location_dest_id = fields.Many2one(
string="Destination",
related="current_move_line_id.location_dest_id",
readonly=True,
readonly=False,
)
# TODO add a glue addon with product_expiry to add the field

View File

@@ -11,15 +11,10 @@ class VerticalLiftOperationPick(models.Model):
def on_barcode_scanned(self, barcode):
self.ensure_one()
if not self.current_move_line_id or self.current_move_line_id == "done":
if not self.current_move_line_id or self.current_move_line_id.state == "done":
return
location = self.env["stock.location"].search([("barcode", "=", barcode)])
if location:
self.current_move_line_id.location_dest_id = location
# even if location_dest_id is a related, we need to set it, otherwise
# it's not refreshed on the view. We need both updates otherwise the
# line is not updated, probably because on_barcode_scanner is called
# in an onchange. (Even if the related is not readonly, tested.)
self.location_dest_id = location
self.operation_descr = _("Save")
else:

View File

@@ -140,6 +140,7 @@
<field
name="location_dest_id"
class="bg-primary o_shuttle_highlight"
readonly="1"
options="{'no_open': True}"
/>
</div>