[FIX] pos_self_order,*: modifying the splash screen images

**Steps to reproduce**

- Open general settings of pos.
- Select/Create a Point of Sale that is kiosk to see the `Splash screens` field.
  - The field is pre-filled with 3 images.
- ISSUE: Try removing the images and save, they won't be removed.

**FIX**

- This is because of the `write` operation made from the `res.config.settings`
  model to the `pos.config`.
  - When removing an image, the field will be given `link` commands, linking the
    remaining images. This is wrong because it won't unlink the images that are
    deleted.

- To ensure the deletion, we reinterpret the command to the splash screen images
  field if the command comes from the res.config.settings.
  - We introduce a context called 'from_settings_view' such that it's set to
    true when the write is from the `res.config.settings` view.
  - And specific to the pos_self_order, we compute the items that should be
    unlinked and we append the unlink commands to the original set of commands
    for the splash screen field.

closes odoo/odoo#137819

Signed-off-by: Robin Heinz (rhe) <rhe@odoo.com>
This commit is contained in:
Joseph Caburnay
2023-10-11 17:02:03 +00:00
parent 47651d6c6b
commit d6c42bba00
3 changed files with 43 additions and 2 deletions
@@ -150,7 +150,7 @@ class ResConfigSettings(models.TransientModel):
# STEP: Finally, we write the value of 'pos' fields to 'pos_config_id'.
for pos_config_id, pos_fields_vals in pos_config_id_to_fields_vals_map.items():
pos_config = self.env['pos.config'].browse(pos_config_id)
pos_config.write(pos_fields_vals)
pos_config.with_context(from_settings_view=True).write(pos_fields_vals)
return result
+18 -1
View File
@@ -11,7 +11,7 @@ from werkzeug.urls import url_quote
from odoo.exceptions import UserError
from odoo.tools import image_to_base64
from odoo import api, fields, models, _, service
from odoo import api, fields, models, _, service, Command
from odoo.tools import file_open, split_every
@@ -153,6 +153,23 @@ class PosConfig(models.Model):
if (not vals.get('module_pos_restaurant') and not record.module_pos_restaurant) and vals.get('self_ordering_mode') == 'mobile':
vals['self_ordering_pay_after'] = 'each'
if 'self_ordering_image_home_ids' in vals and self.env.context.get('from_settings_view'):
linked_ids = set(record.self_ordering_image_home_ids.ids)
# Changes in the splash screen field always results to an array of link commands or a single set command.
# We inspect the commands to determine which attachments should be unlinked.
# We only care about the link command. We can consider set command as absolute as it will replace all.
for command in vals['self_ordering_image_home_ids']:
if command[0] == 4:
_id = command[1]
if _id in linked_ids:
linked_ids.remove(_id)
# Remaining items in linked_ids should be unlinked.
unlink_commands = [Command.unlink(_id) for _id in linked_ids]
vals['self_ordering_image_home_ids'] = unlink_commands + vals['self_ordering_image_home_ids']
return super().write(vals)
@api.depends("module_pos_restaurant")
@@ -70,3 +70,27 @@ class TestFrontendMobile(SelfOrderCommonTest):
result = response.json()
order_id = result['result']['id']
self.assertEqual(self.env['pos.order'].browse(order_id).fiscal_position_id.id, alternative_fp.id)
def test_properly_delete_splash_screen_images(self):
""" Simulate what is done from the res.config.settings view when removing an image. """
self.pos_config.write({
'self_ordering_image_home_ids': [
Command.clear(),
Command.create({'name': 'a1', 'datas': b'blob1234', 'mimetype': 'image/png'}),
Command.create({'name': 'a2', 'datas': b'blob2345', 'mimetype': 'image/png'}),
Command.create({'name': 'a3', 'datas': b'blob3456', 'mimetype': 'image/png'}),
]
})
linked_ids = self.pos_config.self_ordering_image_home_ids.ids
second_id = linked_ids[1]
# We'll unlink the second image and then save the settings.
# It will be a set of link commands for the images except the one we want to delete.
commands = [Command.link(id) for id in linked_ids if id != second_id]
self.pos_config.with_context(from_settings_view=True).write({
'self_ordering_image_home_ids': commands
})
self.assertTrue(second_id not in self.pos_config.self_ordering_image_home_ids.ids)