Skip to content

Commit cd26f42

Browse files
authored
Merge pull request #206 from Kit/fix-exclude-orders-with-no-email
Sync Past Orders: Exclude Orders with no Email Address
2 parents 32518d7 + 5825288 commit cd26f42

11 files changed

+175
-32
lines changed

includes/class-ckwc-order.php

+22-7
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ public function get_orders_not_sent_to_convertkit() {
675675
switch ( get_option( 'woocommerce_custom_orders_table_enabled' ) ) {
676676
case 'no':
677677
// Query CPT.
678-
// We can't use WC_Order_Quey with a meta_query when HPOS is disabled:
678+
// We can't use WC_Order_Query with a meta_query when HPOS is disabled:
679679
// https://github.com/woocommerce/woocommerce/pull/47457.
680680
$query = new WP_Query(
681681
array(
@@ -686,12 +686,18 @@ public function get_orders_not_sent_to_convertkit() {
686686
// Only include Orders that do not match the Purchase Data Event integration setting.
687687
'post_status' => $post_statuses,
688688

689-
// Only include Orders that do not have a ConvertKit Purchase Data ID.
689+
// Only include Orders that do not have a ConvertKit Purchase Data ID
690+
// and have an email address.
690691
'meta_query' => array(
691692
array(
692693
'key' => 'ckwc_purchase_data_id',
693694
'compare' => 'NOT EXISTS',
694695
),
696+
array(
697+
'key' => '_billing_email',
698+
'value' => '',
699+
'compare' => '!=',
700+
),
695701
),
696702

697703
// Only return Order IDs.
@@ -713,22 +719,31 @@ public function get_orders_not_sent_to_convertkit() {
713719
$query = new WC_Order_Query(
714720
array(
715721
// Return posts of type `shop_order`.
716-
'type' => 'shop_order',
717-
'limit' => -1,
722+
'type' => 'shop_order',
723+
'limit' => -1,
718724

719725
// Only include Orders that do not match the Purchase Data Event integration setting.
720-
'status' => $post_statuses,
726+
'status' => $post_statuses,
721727

722728
// Only include Orders that do not have a ConvertKit Purchase Data ID.
723-
'meta_query' => array(
729+
'meta_query' => array(
724730
array(
725731
'key' => 'ckwc_purchase_data_id',
726732
'compare' => 'NOT EXISTS',
727733
),
728734
),
729735

736+
// Only include Orders that have an email address.
737+
'field_query' => array(
738+
array(
739+
'field' => 'billing_email',
740+
'value' => '',
741+
'compare' => '!=',
742+
),
743+
),
744+
730745
// Only return Order IDs.
731-
'return' => 'ids',
746+
'return' => 'ids',
732747
)
733748
);
734749

tests/_support/Helper/Acceptance/WooCommerce.php

+52-3
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,29 @@ public function setupWooCommercePlugin($I)
9191
}
9292

9393
/**
94-
* Helper method to setup HPOS in WooCommerce.
94+
* Helper method to enable HPOS in WooCommerce.
9595
*
96-
* @since 1.6.6
96+
* @since 1.9.3
9797
*
9898
* @param AcceptanceTester $I AcceptanceTester.
9999
*/
100-
public function setupWooCommerceHPOS($I)
100+
public function enableWooCommerceHPOS($I)
101101
{
102102
$I->haveOptionInDatabase('woocommerce_custom_orders_table_enabled', 'yes');
103103
}
104104

105+
/**
106+
* Helper method to disable HPOS in WooCommerce.
107+
*
108+
* @since 1.9.3
109+
*
110+
* @param AcceptanceTester $I AcceptanceTester.
111+
*/
112+
public function disableWooCommerceHPOS($I)
113+
{
114+
$I->haveOptionInDatabase('woocommerce_custom_orders_table_enabled', 'no');
115+
}
116+
105117
/**
106118
* Helper method to setup WooCommerce's checkout page to use the
107119
* legacy [woocommerce_shortcode].
@@ -428,6 +440,43 @@ public function wooCommerceRefundOrder($I, $orderID, $amount)
428440
$I->waitForElementVisible('abbr.refund_by');
429441
}
430442

443+
/**
444+
* Refunds the given Order ID.
445+
*
446+
* @since 1.9.3
447+
*
448+
* @param AcceptanceTester $I Acceptance Tester.
449+
* @param int|string $orderID WooCommerce Order ID.
450+
* @param string $newEmailAddress New Email Address.
451+
*/
452+
public function wooCommerceChangeOrderEmailAddress($I, $orderID, $newEmailAddress = '')
453+
{
454+
// We perform the order status change by editing the Order as a WordPress Administrator would,
455+
// so that WooCommerce triggers its actions and filters that our integration hooks into.
456+
$I->loginAsAdmin();
457+
458+
// If the Order ID contains dashes, it's prefixed by the Custom Order Numbers Plugin.
459+
if (strpos($orderID, '-') !== false) {
460+
$orderIDParts = explode('-', $orderID);
461+
$orderID = $orderIDParts[ count($orderIDParts) - 1 ];
462+
}
463+
464+
// Load order edit screen.
465+
$I->amOnAdminPage('post.php?post=' . $orderID . '&action=edit');
466+
467+
// Change the email address.
468+
$I->click('a.edit_address:first-child');
469+
$I->waitForElementVisible('#_billing_email');
470+
471+
// Update email address.
472+
$I->submitForm(
473+
'div.wrap > form',
474+
[
475+
'_billing_email' => $newEmailAddress,
476+
]
477+
);
478+
}
479+
431480
/**
432481
* Creates a 'Simple product' in WooCommerce that can be used for tests.
433482
*

tests/acceptance/purchase-data/PurchaseDataCest.php

-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ public function _before(AcceptanceTester $I)
1919
// Activate Plugin.
2020
$I->activateWooCommerceAndConvertKitPlugins($I);
2121

22-
// Enable HPOS.
23-
$I->setupWooCommerceHPOS($I);
24-
2522
// Activate Custom Order Numbers, so that we can prefix Order IDs with
2623
// an environment-specific string.
2724
$I->activateThirdPartyPlugin($I, 'custom-order-numbers-for-woocommerce');

tests/acceptance/subscribe/SubscribeCheckoutBlockOnOrderProcessingEventCest.php

-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ public function _before(AcceptanceTester $I)
2020
// Activate Plugin.
2121
$I->activateWooCommerceAndConvertKitPlugins($I);
2222

23-
// Enable HPOS.
24-
$I->setupWooCommerceHPOS($I);
25-
2623
// Setup WooCommerce Plugin.
2724
$I->setupWooCommercePlugin($I);
2825

tests/acceptance/subscribe/SubscribeOnOrderCompletedEventCest.php

-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ public function _before(AcceptanceTester $I)
1919
// Activate Plugin.
2020
$I->activateWooCommerceAndConvertKitPlugins($I);
2121

22-
// Enable HPOS.
23-
$I->setupWooCommerceHPOS($I);
24-
2522
// Setup WooCommerce Plugin.
2623
$I->setupWooCommercePlugin($I);
2724

tests/acceptance/subscribe/SubscribeOnOrderPendingPaymentEventCest.php

-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ public function _before(AcceptanceTester $I)
1919
// Activate Plugin.
2020
$I->activateWooCommerceAndConvertKitPlugins($I);
2121

22-
// Enable HPOS.
23-
$I->setupWooCommerceHPOS($I);
24-
2522
// Setup WooCommerce Plugin.
2623
$I->setupWooCommercePlugin($I);
2724

tests/acceptance/subscribe/SubscribeOnOrderProcessingEventCest.php

-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ public function _before(AcceptanceTester $I)
2020
// Activate Plugin.
2121
$I->activateWooCommerceAndConvertKitPlugins($I);
2222

23-
// Enable HPOS.
24-
$I->setupWooCommerceHPOS($I);
25-
2623
// Setup WooCommerce Plugin.
2724
$I->setupWooCommercePlugin($I);
2825

tests/acceptance/sync-past-orders/SyncPastOrdersCLICest.php

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public function _before(AcceptanceTester $I)
1818
// Activate Plugin.
1919
$I->activateWooCommerceAndConvertKitPlugins($I);
2020

21+
// Disable HPOS.
22+
$I->disableWooCommerceHPOS($I);
23+
2124
// Setup WooCommerce Plugin.
2225
$I->setupWooCommercePlugin($I);
2326

tests/acceptance/sync-past-orders/SyncPastOrdersCest.php

+52-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public function _before(AcceptanceTester $I)
1818
// Activate Plugin.
1919
$I->activateWooCommerceAndConvertKitPlugins($I);
2020

21+
// Disable HPOS.
22+
$I->disableWooCommerceHPOS($I);
23+
2124
// Setup WooCommerce Plugin.
2225
$I->setupWooCommercePlugin($I);
2326

@@ -166,6 +169,50 @@ public function testSyncPastOrderExcludesRefunds(AcceptanceTester $I)
166169
$I->dontSeeElementInDOM('a#ckwc_sync_past_orders');
167170
}
168171

172+
/**
173+
* Test that no button is displayed on the Integration Settings screen
174+
* when:
175+
* - the Integration is enabled,
176+
* - valid API credentials are specified,
177+
* - a WooCommerce Order exists, that has no email address.
178+
*
179+
* @since 1.9.3
180+
*
181+
* @param AcceptanceTester $I Tester.
182+
*/
183+
public function testSyncPastOrderExcludesOrdersWithNoEmailAddress(AcceptanceTester $I)
184+
{
185+
// Delete all existing WooCommerce Orders from the database.
186+
$I->wooCommerceDeleteAllOrders($I);
187+
188+
// Create Product and Checkout for this test, not sending the Order
189+
// to ConvertKit.
190+
$result = $I->wooCommerceCreateProductAndCheckoutWithConfig(
191+
$I,
192+
[
193+
'send_purchase_data' => false,
194+
]
195+
);
196+
197+
// Login as the Administrator.
198+
$I->loginAsAdmin();
199+
200+
// Load Settings screen.
201+
$I->loadConvertKitSettingsScreen($I);
202+
203+
// Confirm that the Sync Past Order button is displayed.
204+
$I->seeElementInDOM('a#ckwc_sync_past_orders');
205+
206+
// Remove the email address from the Order.
207+
$I->wooCommerceChangeOrderEmailAddress($I, $result['order_id'], '');
208+
209+
// Load Settings screen.
210+
$I->loadConvertKitSettingsScreen($I);
211+
212+
// Confirm that no Sync Past Order button is displayed.
213+
$I->dontSeeElementInDOM('a#ckwc_sync_past_orders');
214+
}
215+
169216
/**
170217
* Test that a button is displayed on the Integration Settings screen
171218
* when:
@@ -232,8 +279,8 @@ public function testSyncPastOrder(AcceptanceTester $I)
232279
$I->seeInSource('Enable Kit integration');
233280

234281
// Confirm that the Transaction ID is stored in the Order's metadata.
235-
$I->wooCommerceOrderMetaKeyAndValueExist($I, $postID, 'ckwc_purchase_data_sent', 'yes', true);
236-
$I->wooCommerceOrderMetaKeyAndValueExist($I, $postID, 'ckwc_purchase_data_id', $purchaseDataID, true);
282+
$I->wooCommerceOrderMetaKeyAndValueExist($I, $postID, 'ckwc_purchase_data_sent', 'yes');
283+
$I->wooCommerceOrderMetaKeyAndValueExist($I, $postID, 'ckwc_purchase_data_id', $purchaseDataID);
237284
}
238285

239286
/**
@@ -276,7 +323,7 @@ public function testSyncPastOrderCreatedInPreviousPluginVersion(AcceptanceTester
276323

277324
// Remove the Transaction ID metadata in the Order, as if it were sent
278325
// by 1.4.2 or older.
279-
$I->wooCommerceOrderDeleteMeta($I, $postID, 'ckwc_purchase_data_id', true);
326+
$I->wooCommerceOrderDeleteMeta($I, $postID, 'ckwc_purchase_data_id');
280327

281328
// Login as the Administrator.
282329
$I->loginAsAdmin();
@@ -306,8 +353,8 @@ public function testSyncPastOrderCreatedInPreviousPluginVersion(AcceptanceTester
306353
$I->seeElementInDOM('a.cancel[disabled]');
307354

308355
// Confirm that the Transaction ID is stored in the Order's metadata.
309-
$I->wooCommerceOrderMetaKeyAndValueExist($I, $postID, 'ckwc_purchase_data_sent', 'yes', true);
310-
$I->wooCommerceOrderMetaKeyAndValueExist($I, $postID, 'ckwc_purchase_data_id', $purchaseDataID, true);
356+
$I->wooCommerceOrderMetaKeyAndValueExist($I, $postID, 'ckwc_purchase_data_sent', 'yes');
357+
$I->wooCommerceOrderMetaKeyAndValueExist($I, $postID, 'ckwc_purchase_data_id', $purchaseDataID);
311358
}
312359

313360
/**

tests/acceptance/sync-past-orders/SyncPastOrdersHPOSCLICest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function _before(AcceptanceTester $I)
2020
$I->activateWooCommerceAndConvertKitPlugins($I);
2121

2222
// Enable HPOS.
23-
$I->setupWooCommerceHPOS($I);
23+
$I->enableWooCommerceHPOS($I);
2424

2525
// Setup WooCommerce Plugin.
2626
$I->setupWooCommercePlugin($I);

tests/acceptance/sync-past-orders/SyncPastOrdersHPOSCest.php

+45-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function _before(AcceptanceTester $I)
2020
$I->activateWooCommerceAndConvertKitPlugins($I);
2121

2222
// Enable HPOS.
23-
$I->setupWooCommerceHPOS($I);
23+
$I->enableWooCommerceHPOS($I);
2424

2525
// Setup WooCommerce Plugin.
2626
$I->setupWooCommercePlugin($I);
@@ -170,6 +170,50 @@ public function testSyncPastOrderExcludesRefunds(AcceptanceTester $I)
170170
$I->dontSeeElementInDOM('a#ckwc_sync_past_orders');
171171
}
172172

173+
/**
174+
* Test that no button is displayed on the Integration Settings screen
175+
* when:
176+
* - the Integration is enabled,
177+
* - valid API credentials are specified,
178+
* - a WooCommerce Order exists, that has no email address.
179+
*
180+
* @since 1.9.3
181+
*
182+
* @param AcceptanceTester $I Tester.
183+
*/
184+
public function testSyncPastOrderExcludesOrdersWithNoEmailAddress(AcceptanceTester $I)
185+
{
186+
// Delete all existing WooCommerce Orders from the database.
187+
$I->wooCommerceDeleteAllOrders($I);
188+
189+
// Create Product and Checkout for this test, not sending the Order
190+
// to ConvertKit.
191+
$result = $I->wooCommerceCreateProductAndCheckoutWithConfig(
192+
$I,
193+
[
194+
'send_purchase_data' => false,
195+
]
196+
);
197+
198+
// Login as the Administrator.
199+
$I->loginAsAdmin();
200+
201+
// Load Settings screen.
202+
$I->loadConvertKitSettingsScreen($I);
203+
204+
// Confirm that the Sync Past Order button is displayed.
205+
$I->seeElementInDOM('a#ckwc_sync_past_orders');
206+
207+
// Remove the email address from the Order.
208+
$I->wooCommerceChangeOrderEmailAddress($I, $result['order_id'], '');
209+
210+
// Load Settings screen.
211+
$I->loadConvertKitSettingsScreen($I);
212+
213+
// Confirm that no Sync Past Order button is displayed.
214+
$I->dontSeeElementInDOM('a#ckwc_sync_past_orders');
215+
}
216+
173217
/**
174218
* Test that a button is displayed on the Integration Settings screen
175219
* when:

0 commit comments

Comments
 (0)