From d2f6c48acb88ec8f49dd54b39f9133b69492d30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jakes=CC=8C?= Date: Wed, 9 Oct 2019 11:08:24 +0200 Subject: [PATCH] Prevent tracking WooCommerce purchases multiple times [MAILPOET-2446] --- lib/Models/StatisticsWooCommercePurchases.php | 10 +++++++--- lib/Statistics/Track/WooCommercePurchases.php | 4 ++-- .../Statistics/Track/WooCommercePurchasesTest.php | 11 +++++++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/Models/StatisticsWooCommercePurchases.php b/lib/Models/StatisticsWooCommercePurchases.php index d983b0afa0..cb9c2076dd 100644 --- a/lib/Models/StatisticsWooCommercePurchases.php +++ b/lib/Models/StatisticsWooCommercePurchases.php @@ -16,9 +16,13 @@ use WC_Order; class StatisticsWooCommercePurchases extends Model { public static $_table = MP_STATISTICS_WOOCOMMERCE_PURCHASES_TABLE; - static function createOrUpdateByClickAndOrder(StatisticsClicks $click, WC_Order $order) { - $statistics = self::where('click_id', $click->id) - ->where('order_id', $order->get_id()) + static function createOrUpdateByClickDataAndOrder(StatisticsClicks $click, WC_Order $order) { + // search by subscriber and newsletter IDs (instead of click itself) to avoid duplicities + // when a new click from the subscriber appeared since last tracking for given newsletter + // (this will keep the originally tracked click - likely the click that led to the order) + $statistics = self::where('order_id', $order->get_id()) + ->where('subscriber_id', $click->subscriber_id) + ->where('newsletter_id', $click->newsletter_id) ->findOne(); if (!$statistics) { diff --git a/lib/Statistics/Track/WooCommercePurchases.php b/lib/Statistics/Track/WooCommercePurchases.php index 656909370f..a0e882dffd 100644 --- a/lib/Statistics/Track/WooCommercePurchases.php +++ b/lib/Statistics/Track/WooCommercePurchases.php @@ -38,7 +38,7 @@ class WooCommercePurchases { $processed_newsletter_ids_map = []; $order_email_clicks = $this->getClicks($order->get_billing_email(), $from, $to); foreach ($order_email_clicks as $click) { - StatisticsWooCommercePurchases::createOrUpdateByClickAndOrder($click, $order); + StatisticsWooCommercePurchases::createOrUpdateByClickDataAndOrder($click, $order); $processed_newsletter_ids_map[$click->newsletter_id] = true; } @@ -52,7 +52,7 @@ class WooCommercePurchases { if (isset($processed_newsletter_ids_map[$click->newsletter_id])) { continue; // do not track click for newsletters that were already tracked by order email } - StatisticsWooCommercePurchases::createOrUpdateByClickAndOrder($click, $order); + StatisticsWooCommercePurchases::createOrUpdateByClickDataAndOrder($click, $order); } } diff --git a/tests/integration/Statistics/Track/WooCommercePurchasesTest.php b/tests/integration/Statistics/Track/WooCommercePurchasesTest.php index 26833d82aa..ed4dddb949 100644 --- a/tests/integration/Statistics/Track/WooCommercePurchasesTest.php +++ b/tests/integration/Statistics/Track/WooCommercePurchasesTest.php @@ -138,6 +138,17 @@ class WooCommercePurchasesTest extends \MailPoetTest { expect(count(StatisticsWooCommercePurchases::findMany()))->equals(1); } + function testItTracksPaymentOnlyOnceWhenNewClickAppears() { + $this->createClick($this->link, $this->subscriber, 5); + $order_mock = $this->createOrderMock($this->subscriber->email); + $woocommerce_purchases = new WooCommercePurchases($this->createWooCommerceHelperMock($order_mock), $this->cookies); + $woocommerce_purchases->trackPurchase($order_mock->get_id()); + + $this->createClick($this->link, $this->subscriber, 1); + $woocommerce_purchases->trackPurchase($order_mock->get_id()); + expect(count(StatisticsWooCommercePurchases::findMany()))->equals(1); + } + function testItDoesNotTrackPaymentWhenClickTooOld() { $this->createClick($this->link, $this->subscriber, 20); $order_mock = $this->createOrderMock($this->subscriber->email);