8000 [IMP] point_of_sale: real time syncing · odoo-dev/odoo@1952c76 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1952c76

Browse files
committed
[IMP] point_of_sale: real time syncing
We use the built-in listener of the related records to keep track of all of the changes. We then queue these changes and send them to the backend automatically. This means that the pos ui developer never needs to think about syncing their data to the server. It is done automatically. `sync_from_ui` is now removed. It performed a couple of actions: 1. Prepared the vals -> this is now done in `create` or `write` where needed 2. Performed side effects -> side effects are now moved in `action_pos_order_paid`, which is called by the client after validation. 3. It was used as a notifier -> modules that need to be notified of order creation and update can hook into `create` and `write`
1 parent be809ec commit 1952c76

File tree

98 files changed

+1133
-2275
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+1133
-2275
lines changed

addons/point_of_sale/models/pos_config.py

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from odoo.http import request
1111
from odoo.exceptions import AccessError, ValidationError, UserError
1212
from odoo.tools import SQL, convert
13-
from odoo.osv import expression
1413

1514
DEFAULT_LIMIT_LOAD_PRODUCT = 5000
1615
DEFAULT_LIMIT_LOAD_PARTNER = 100
@@ -205,36 +204,11 @@ def _get_default_tip_product(self):
205204
last_data_change = fields.Datetime(string='Last Write Date', readonly=True, compute='_compute_local_data_integrity', store=True)
206205
fallback_nomenclature_id = fields.Many2one('barcode.nomenclature', string="Fallback Nomenclature")
207206

208-
def notify_synchronisation(self, session_id, login_number, records={}):
209-
self.ensure_one()
210-
static_records = {}
211-
212-
for model, ids in records.items():
213-
static_records[model] = self.env[model]._read_pos_record(ids, self.id)
214-
215-
self._notify('SYNCHRONISATION', {
216-
'static_records': static_records,
217-
'session_id': session_id,
218-
'login_number': login_number,
219-
'records': records
220-
})
221-
222-
def read_config_open_orders(self, domain, record_ids):
223-
all_domain = expression.OR([domain, [('id', 'in', record_ids.get('pos.order')), ('config_id', '=', self.id)]])
224-
all_orders = self.env['pos.order'].search(all_domain)
225-
delete_record_ids = {}
226-
227-
for model, ids in record_ids.items():
228-
delete_record_ids[model] = [id for id in ids if not self.env[model].browse(id).exists()]
229-
230-
return {
231-
'dynamic_records': all_orders.filtered_domain(domain).read_pos_data([], self.id),
232-
'deleted_record_ids': delete_record_ids,
233-
}
234-
235207
@api.model
236208
def _load_pos_data_domain(self, data):
237-
return [('id', '=', data['pos.session'][0]['config_id'])]
209+
main_config = self.env['pos.config'].browse(data['pos.session'][0]['config_id'])
210+
other_configs = main_config._configs_that_share_data()
211+
return [('id', 'in', [main_config.id] + other_configs.ids)]
238212

239213
def _load_pos_data(self, data):
240214
domain = self._load_pos_data_domain(data)
@@ -248,6 +222,56 @@ def _post_read_pos_data(self, data):
248222
data[0]['_IS_VAT'] = self.env.company.country_id.id in self.env.ref("base.europe").country_ids.ids
249223
return super()._post_read_pos_data(data)
250224

225+
def _configs_that_share_data(self):
226+
self.ensure_one()
227+
return self.trusted_config_ids
228+
229+
def notify_data_chnage(self, queue, login_number):
230+
if not self:
231+
# No config is available to notify in certain scenarios (e.g., pre-display)
232+
return
233+
for config in self._configs_that_share_data() + self:
234+
config._notify('DATA_CHANGED', {'queue': queue, 'login_number': login_number, 'config_id': self.id})
235+
236+
def flush(self, queue, login_number):
237+
238+
def get_record(model, id):
239+
return self.env[model].search([('uuid', '=', id)], limit=1) if isinstance(id, str) else self.env[model].browse(id)
240+
241+
def replace_uuid_with_id(model, vals):
242+
def adapt_value(model, key, value):
243+
match self.env[model]._fields[key].type:
244+
case "many2one":
245+
return get_record(self.env[model]._fields[key].comodel_name, value).id
246+
case "many2many" | "one2many":
247+
return [(6, 0, [get_record(self.env[model]._fields[key].comodel_name, val).id for val in value])]
248+
case _:
249+
return value
250+
return {key: adapt_value(model, key, value) for key, value in vals.items()}
251+
252+
id_updates = {}
253+
254+
for [operation, *data] in queue:
255+
match operation:
256+
case "CREATE":
257+
model, vals = data
258+
new_record = self.env[model].create([replace_uuid_with_id(model, vals)])
259+
id_updates[vals['uuid']] = new_record.id
260+
case "UPDATE":
261+
model, id, vals = data
262+
record = get_record(model, id)
263+
record.write(replace_uuid_with_id(model, vals))
264+
case "DELETE":
265+
model, id = data
266+
record = get_record(model, id)
267+
if record.exists():
268+
record.unlink()
269+
case _:
270+
pass
271+
272+
self.notify_data_chnage(queue, login_number)
273+
return id_updates
274+
251275
@api.depends('payment_method_ids')
252276
def _compute_cash_control(self):
253277
for config in self:

0 commit comments

Comments
 (0)
0