From f89e8f9df2c4ffaafc846082ac2b252c787e1e65 Mon Sep 17 00:00:00 2001
From: Damien Bouvy <dbo@odoo.com>
Date: Mon, 21 Sep 2015 12:17:08 +0200
Subject: [PATCH] [IMP] payment, website_sale, website_payment: unique
 reference on payment no longer prevent paying Payment transactions
 referenceis have a unique constraint which was problematic when a payment was
 cancelled from the acquirer's page. To stick the to DRY principle, I
 factorized a method that checks for existing references and happens a
 numerical suffix if necessary. This was already implemented in
 website_payment but was moved to payment and used in website_sale.

---
 addons/payment/models/payment_acquirer.py  |  8 ++++++++
 addons/website_payment/controllers/main.py |  6 +-----
 addons/website_sale/controllers/main.py    | 10 ++++------
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/addons/payment/models/payment_acquirer.py b/addons/payment/models/payment_acquirer.py
index 1e717d139a58..b46d38639520 100644
--- a/addons/payment/models/payment_acquirer.py
+++ b/addons/payment/models/payment_acquirer.py
@@ -419,6 +419,14 @@ class PaymentTransaction(osv.Model):
             }}
         return {}
 
+    def get_next_reference(self, cr, uid, reference, context=None):
+        ref_suffix = 1
+        init_ref = reference
+        while self.pool['payment.transaction'].search_count(cr, uid, [('reference', '=', reference)], context=context):
+            reference = init_ref + '-' + str(ref_suffix)
+            ref_suffix += 1
+        return reference
+
     # --------------------------------------------------
     # FORM RELATED METHODS
     # --------------------------------------------------
diff --git a/addons/website_payment/controllers/main.py b/addons/website_payment/controllers/main.py
index 39d659f3b24a..13c84313dbd4 100644
--- a/addons/website_payment/controllers/main.py
+++ b/addons/website_payment/controllers/main.py
@@ -41,11 +41,7 @@ class website_payment(http.Controller):
         acquirer = env['payment.acquirer'].with_context(submit_class='btn btn-primary pull-right',
                                                         submit_txt=_('Pay Now')).browse(acquirer_id)
         # auto-increment reference with a number suffix if the reference already exists
-        ref_suffix = 1
-        init_ref = reference
-        while request.env['payment.transaction'].sudo().search_count([('reference', '=', reference)]):
-            reference = init_ref + '-' + str(ref_suffix)
-            ref_suffix += 1
+        reference = request.env['payment.transaction'].get_next_reference(reference)
 
         partner_id = user.partner_id.id if user.partner_id.id != request.website.partner_id.id else False
 
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index c0f41b3e9435..9caf65e4c66d 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -727,18 +727,16 @@ class website_sale(http.Controller):
         values['errors'] = sale_order_obj._get_errors(cr, uid, order, context=context)
         values.update(sale_order_obj._get_website_data(cr, uid, order, context))
 
-        # fetch all registered payment means
-        # if tx:
-        #     acquirer_ids = [tx.acquirer_id.id]
-        # else:
         if not values['errors']:
+            # find an already existing transaction
+            tx = request.website.sale_get_transaction()
             acquirer_ids = payment_obj.search(cr, SUPERUSER_ID, [('website_published', '=', True), ('company_id', '=', order.company_id.id)], context=context)
             values['acquirers'] = list(payment_obj.browse(cr, uid, acquirer_ids, context=context))
             render_ctx = dict(context, submit_class='btn btn-primary', submit_txt=_('Pay Now'))
             for acquirer in values['acquirers']:
                 acquirer.button = payment_obj.render(
                     cr, SUPERUSER_ID, acquirer.id,
-                    order.name,
+                    tx and tx.reference or request.env['payment.transaction'].get_next_reference(order.name),
                     order.amount_total,
                     order.pricelist_id.currency_id.id,
                     values={
@@ -785,7 +783,7 @@ class website_sale(http.Controller):
                 'currency_id': order.pricelist_id.currency_id.id,
                 'partner_id': order.partner_id.id,
                 'partner_country_id': order.partner_id.country_id.id,
-                'reference': order.name,
+                'reference': request.env['payment.transaction'].get_next_reference(order.name),
                 'sale_order_id': order.id,
             }, context=context)
             request.session['sale_transaction_id'] = tx_id
-- 
GitLab