diff --git a/__init__.py b/__init__.py
index 5fc9b58edc..bd0f5a4067 100644
--- a/__init__.py
+++ b/__init__.py
@@ -17,6 +17,7 @@ def register():
account.PaymentBraintreeRefund,
account.PaymentBraintreeAccount,
account.PaymentBraintreeCustomer,
+ account.PaymentBraintreeCustomerIdentical,
account.PaymentBraintreeCustomerPaymentMethodDeleteAsk,
party.Party,
party.PartyReceptionDirectDebit,
diff --git a/account.py b/account.py
index 7665fd2ade..c45ed2749b 100644
--- a/account.py
+++ b/account.py
@@ -7,6 +7,7 @@ import uuid
import braintree
from braintree.exceptions import GatewayTimeoutError, TooManyRequestsError
from braintree.exceptions.braintree_error import BraintreeError
+from sql import Literal
from trytond.cache import Cache
from trytond.config import config
@@ -21,6 +22,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval
from trytond.report import Report
+from trytond.tools import sql_pairing
from trytond.transaction import Transaction
from trytond.url import http_host
from trytond.wizard import (
@@ -916,6 +918,13 @@ class PaymentBraintreeCustomer(
'invisible': ~Eval('braintree_error_message'),
})
+ identical_customers = fields.Many2Many(
+ 'account.payment.braintree.customer.identical',
+ 'source', 'target', "Identical Customers", readonly=True,
+ states={
+ 'invisible': ~Eval('identical_customers'),
+ })
+
_payment_methods_cache = Cache(
'account_payment_braintree_customer.payment_methods',
duration=config.getint(
@@ -1146,6 +1155,34 @@ class PaymentBraintreeCustomer(
self._payment_methods_cache.clear()
+class PaymentBraintreeCustomerIdentical(ModelSQL):
+ "Braintree Customer Identical"
+ __name__ = 'account.payment.braintree.customer.identical'
+ source = fields.Many2One('account.payment.braintree.customer', "Source")
+ target = fields.Many2One('account.payment.braintree.customer', "Target")
+
+ @classmethod
+ def table_query(cls):
+ pool = Pool()
+ Customer = pool.get('account.payment.braintree.customer')
+ source = Customer.__table__()
+ target = Customer.__table__()
+ return (
+ source
+ .join(target, condition=(
+ source.braintree_customer_id
+ == target.braintree_customer_id))
+ .select(
+ Literal(0).as_('create_uid'),
+ source.create_date.as_('create_date'),
+ Literal(None).as_('write_uid'),
+ Literal(None).as_('write_date'),
+ sql_pairing(source.id, target.id).as_('id'),
+ source.id.as_('source'),
+ target.id.as_('target'),
+ where=source.id != target.id))
+
+
class PaymentBraintreeCustomerPaymentMethodDelete(Wizard):
"Delete Customer Payment Method"
__name__ = 'account.payment.braintree.customer.payment_method.delete'
diff --git a/party.py b/party.py
index f15f2fff78..6c3f6ed4dc 100644
--- a/party.py
+++ b/party.py
@@ -13,6 +13,13 @@ class Party(metaclass=PoolMeta):
braintree_customers = fields.One2Many(
'account.payment.braintree.customer', 'party', "Braintree Customers")
+ def _payment_identical_parties(self):
+ parties = super()._payment_identical_parties()
+ for customer in self.braintree_customers:
+ for other_customer in customer.identical_customers:
+ parties.add(other_customer.party)
+ return parties
+
@classmethod
def write(cls, *args):
pool = Pool()
diff --git a/view/customer_form.xml b/view/customer_form.xml
index aef591631b..aaab2cff57 100644
--- a/view/customer_form.xml
+++ b/view/customer_form.xml
@@ -21,4 +21,6 @@ this repository contains the full copyright notices and license terms. -->
+
+