pos_ui_optimization/models/pos_payment.py

54 lines
2.0 KiB
Python

# -*- coding: utf-8 -*-
from odoo import models, api
class PosPayment(models.Model):
_inherit = 'pos.payment'
@api.model_create_multi
def create(self, vals_list):
# 1. Extract and sort unique uuids to prevent deadlocks
uuids = []
for vals in vals_list:
if isinstance(vals, dict) and vals.get('uuid'):
uuids.append(vals['uuid'])
sorted_uuids = sorted(list(set(uuids)))
# 2. Acquire transaction-level PostgreSQL advisory locks on the sorted hashes of uuids
for uuid in sorted_uuids:
self.env.cr.execute("SELECT pg_advisory_xact_lock(hashtext(%s))", (uuid,))
# 3. Check which payments already exist in the database
existing_payments_map = {}
if sorted_uuids:
existing_payments = self.search([('uuid', 'in', sorted_uuids)])
for payment in existing_payments:
existing_payments_map[payment.uuid] = payment
# 4. Prepare values to create (only those that don't already exist)
final_payments_list = [None] * len(vals_list)
vals_to_create = []
create_indices = []
for i, vals in enumerate(vals_list):
uuid = vals.get('uuid') if isinstance(vals, dict) else None
if uuid and uuid in existing_payments_map:
final_payments_list[i] = existing_payments_map[uuid]
else:
vals_to_create.append(vals)
create_indices.append(i)
# 5. Create new payments
if vals_to_create:
created_payments = super(PosPayment, self).create(vals_to_create)
for idx, payment in zip(create_indices, created_payments):
final_payments_list[idx] = payment
# 6. Reconstruct and return the final combined recordset
final_payments = self.env['pos.payment']
for payment in final_payments_list:
if payment:
final_payments += payment
return final_payments