Add dynamic filter for WC total spent
[MAILPOET-3227]
This commit is contained in:
@ -139,6 +139,8 @@ class DynamicSegments extends APIEndpoint {
|
||||
return WPFunctions::get()->__('Please fill all required values.', 'mailpoet');
|
||||
case InvalidFilterException::MISSING_NUMBER_OF_ORDERS_FIELDS:
|
||||
return WPFunctions::get()->__('Please select a type for the comparison, a number of orders and a number of days.', 'mailpoet');
|
||||
case InvalidFilterException::MISSING_TOTAL_SPENT_FIELDS:
|
||||
return WPFunctions::get()->__('Please select a type for the comparison, an amount and a number of days.', 'mailpoet');
|
||||
default:
|
||||
return WPFunctions::get()->__('An error occurred while saving data.', 'mailpoet');
|
||||
}
|
||||
|
@ -275,6 +275,7 @@ class ContainerConfigurator implements IContainerConfigurator {
|
||||
$container->autowire(\MailPoet\Segments\DynamicSegments\Filters\WooCommerceCategory::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Segments\DynamicSegments\Filters\WooCommerceNumberOfOrders::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Segments\DynamicSegments\Filters\WooCommerceProduct::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Segments\DynamicSegments\Filters\WooCommerceTotalSpent::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Segments\DynamicSegments\Filters\WooCommerceSubscription::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Segments\DynamicSegments\SegmentSaveController::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Segments\DynamicSegments\FilterDataMapper::class)->setPublic(true);
|
||||
|
@ -16,5 +16,6 @@ class InvalidFilterException extends InvalidStateException {
|
||||
const INVALID_EMAIL_ACTION = 8;
|
||||
const MISSING_VALUE = 9;
|
||||
const MISSING_NUMBER_OF_ORDERS_FIELDS = 10;
|
||||
const MISSING_TOTAL_SPENT_FIELDS = 11;
|
||||
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ use MailPoet\Segments\DynamicSegments\Filters\WooCommerceCategory;
|
||||
use MailPoet\Segments\DynamicSegments\Filters\WooCommerceNumberOfOrders;
|
||||
use MailPoet\Segments\DynamicSegments\Filters\WooCommerceProduct;
|
||||
use MailPoet\Segments\DynamicSegments\Filters\WooCommerceSubscription;
|
||||
use MailPoet\Segments\DynamicSegments\Filters\WooCommerceTotalSpent;
|
||||
|
||||
class FilterDataMapper {
|
||||
public function map(array $data = []): DynamicSegmentFilterData {
|
||||
@ -98,6 +99,13 @@ class FilterDataMapper {
|
||||
$filterData['number_of_orders_type'] = $data['number_of_orders_type'];
|
||||
$filterData['number_of_orders_count'] = $data['number_of_orders_count'];
|
||||
$filterData['number_of_orders_days'] = $data['number_of_orders_days'];
|
||||
} elseif ($data['action'] === WooCommerceTotalSpent::ACTION_TOTAL_SPENT) {
|
||||
if (!isset($data['total_spent_type']) || !isset($data['total_spent_amount']) || !isset($data['total_spent_days'])) {
|
||||
throw new InvalidFilterException('Missing required fields', InvalidFilterException::MISSING_TOTAL_SPENT_FIELDS);
|
||||
}
|
||||
$filterData['total_spent_type'] = $data['total_spent_type'];
|
||||
$filterData['total_spent_amount'] = $data['total_spent_amount'];
|
||||
$filterData['total_spent_days'] = $data['total_spent_days'];
|
||||
} else {
|
||||
throw new InvalidFilterException("Unknown action " . $data['action'], InvalidFilterException::MISSING_ACTION);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ use MailPoet\Segments\DynamicSegments\Filters\WooCommerceCategory;
|
||||
use MailPoet\Segments\DynamicSegments\Filters\WooCommerceNumberOfOrders;
|
||||
use MailPoet\Segments\DynamicSegments\Filters\WooCommerceProduct;
|
||||
use MailPoet\Segments\DynamicSegments\Filters\WooCommerceSubscription;
|
||||
use MailPoet\Segments\DynamicSegments\Filters\WooCommerceTotalSpent;
|
||||
use MailPoet\Segments\SegmentDependencyValidator;
|
||||
use MailPoetVendor\Doctrine\DBAL\Query\QueryBuilder;
|
||||
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||
@ -34,6 +35,9 @@ class FilterHandler {
|
||||
/** @var WooCommerceNumberOfOrders */
|
||||
private $wooCommerceNumberOfOrders;
|
||||
|
||||
/** @var WooCommerceTotalSpent */
|
||||
private $wooCommerceTotalSpent;
|
||||
|
||||
/** @var WooCommerceSubscription */
|
||||
private $wooCommerceSubscription;
|
||||
|
||||
@ -54,6 +58,7 @@ class FilterHandler {
|
||||
WooCommerceCategory $wooCommerceCategory,
|
||||
EmailOpensAbsoluteCountAction $emailOpensAbsoluteCount,
|
||||
WooCommerceNumberOfOrders $wooCommerceNumberOfOrders,
|
||||
WooCommerceTotalSpent $wooCommerceTotalSpent,
|
||||
WooCommerceSubscription $wooCommerceSubscription,
|
||||
SegmentDependencyValidator $segmentDependencyValidator
|
||||
) {
|
||||
@ -66,6 +71,7 @@ class FilterHandler {
|
||||
$this->entityManager = $entityManager;
|
||||
$this->segmentDependencyValidator = $segmentDependencyValidator;
|
||||
$this->emailOpensAbsoluteCount = $emailOpensAbsoluteCount;
|
||||
$this->wooCommerceTotalSpent = $wooCommerceTotalSpent;
|
||||
}
|
||||
|
||||
public function apply(QueryBuilder $queryBuilder, SegmentEntity $segment): QueryBuilder {
|
||||
@ -143,6 +149,8 @@ class FilterHandler {
|
||||
return $this->wooCommerceProduct->apply($queryBuilder, $filter);
|
||||
} elseif ($action === WooCommerceNumberOfOrders::ACTION_NUMBER_OF_ORDERS) {
|
||||
return $this->wooCommerceNumberOfOrders->apply($queryBuilder, $filter);
|
||||
} elseif ($action === WooCommerceTotalSpent::ACTION_TOTAL_SPENT) {
|
||||
return $this->wooCommerceTotalSpent->apply($queryBuilder, $filter);
|
||||
}
|
||||
return $this->wooCommerceCategory->apply($queryBuilder, $filter);
|
||||
default:
|
||||
|
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Segments\DynamicSegments\Filters;
|
||||
|
||||
use MailPoet\Entities\DynamicSegmentFilterEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoetVendor\Carbon\Carbon;
|
||||
use MailPoetVendor\Doctrine\DBAL\Query\QueryBuilder;
|
||||
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||
|
||||
class WooCommerceTotalSpent implements Filter {
|
||||
const ACTION_TOTAL_SPENT = 'totalSpent';
|
||||
|
||||
/** @var EntityManager */
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager) {
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function apply(QueryBuilder $queryBuilder, DynamicSegmentFilterEntity $filter): QueryBuilder {
|
||||
global $wpdb;
|
||||
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||
$filterData = $filter->getFilterData();
|
||||
$type = $filterData->getParam('total_spent_type');
|
||||
$amount = $filterData->getParam('total_spent_amount');
|
||||
$days = $filterData->getParam('total_spent_days');
|
||||
|
||||
$date = Carbon::now()->subDays($days);
|
||||
|
||||
$queryBuilder->innerJoin(
|
||||
$subscribersTable,
|
||||
$wpdb->postmeta,
|
||||
'postmeta',
|
||||
"postmeta.meta_key = '_customer_user' AND $subscribersTable.wp_user_id=postmeta.meta_value"
|
||||
)->leftJoin(
|
||||
'postmeta',
|
||||
$wpdb->posts,
|
||||
'posts',
|
||||
'posts.ID = postmeta.post_id AND posts.post_date >= :date' . $filter->getId() . ' AND postmeta.post_id NOT IN ( SELECT id FROM ' . $wpdb->posts . ' as p WHERE p.post_status IN ("wc-cancelled", "wc-failed"))'
|
||||
)->leftJoin(
|
||||
'posts',
|
||||
$wpdb->postmeta,
|
||||
'order_total',
|
||||
"posts.ID = order_total.post_id AND order_total.meta_key = '_order_total'"
|
||||
)->setParameter(
|
||||
'date' . $filter->getId(), $date->toDateTimeString()
|
||||
)->groupBy(
|
||||
'inner_subscriber_id'
|
||||
);
|
||||
|
||||
if ($type === '>') {
|
||||
$queryBuilder->having('SUM(order_total.meta_value) > :amount' . $filter->getId());
|
||||
} elseif ($type === '<') {
|
||||
$queryBuilder->having('SUM(order_total.meta_value) < :amount' . $filter->getId());
|
||||
}
|
||||
|
||||
$queryBuilder->setParameter('amount' . $filter->getId(), $amount);
|
||||
|
||||
return $queryBuilder;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user