54 lines
2.0 KiB
Python
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
|