Change logic abandone carts

This commit is contained in:
uryvskiy-dima 2022-12-29 20:53:23 +03:00
parent 878231a306
commit f5e5b15d56
4 changed files with 61 additions and 117 deletions

View file

@ -43,6 +43,11 @@ class RetailcrmCartUploader
*/
static $api;
/**
* @var string
*/
static $site;
/** @var \Context|\ContextCore */
static $context;
@ -56,12 +61,6 @@ class RetailcrmCartUploader
* @var array
*/
static $cartsIds;
/**
* @var array
*/
static $paymentTypes;
/**
* @var int
*/
@ -72,11 +71,6 @@ class RetailcrmCartUploader
*/
static $allowedUpdateInterval;
/**
* @var string
*/
static $syncStatus;
/**
* @var \DateTime
*/
@ -103,10 +97,8 @@ class RetailcrmCartUploader
{
static::$api = null;
static::$cartsIds = [];
static::$paymentTypes = [];
static::$syncDelay = 0;
static::$allowedUpdateInterval = 86400;
static::$syncStatus = '';
static::$now = new DateTimeImmutable();
static::$context = Context::getContext();
}
@ -116,7 +108,7 @@ class RetailcrmCartUploader
*/
public static function run()
{
if (!static::validateState()) {
if (null === static::$now || null === static::$api) {
return;
}
@ -147,33 +139,36 @@ class RetailcrmCartUploader
static::populateContextWithCart($cart);
$response = static::$api->ordersGet($cartExternalId);
RetailcrmLogger::writeDebug(__METHOD__, 'Test');
RetailcrmLogger::writeDebug(__METHOD__, $cart->getProducts());
$response = static::$api->cartsGet($cartExternalId, static::$site);
if ($response instanceof RetailcrmApiResponse) {
if (empty($response['order'])) {
if (empty($response['cart'])) {
// TODO
// Extract address from cart (if exists) and append to customer?
// Or maybe this customer will not order anything, so we don't need it's address...
static::$api->customersCreate(RetailcrmOrderBuilder::buildCrmCustomer(new Customer($cart->id_customer)));
$order = static::buildCartOrder($cart, $cartExternalId);
$crmCart = static::buildCrmCart($cart, $cartExternalId);
if (empty($order)) {
if (empty($crmCart)) {
continue;
}
if (false !== static::$api->ordersCreate($order)) {
if (false !== static::$api->cartsSet($crmCart, static::$site)) {
$cart->date_upd = date('Y-m-d H:i:s');
$cart->save();
}
} elseif (!empty($response['order']['externalId'])) {
$order = static::buildCartOrder($cart, $response['order']['externalId']);
} elseif (!empty($response['cart']['externalId'])) {
$crmCart = static::buildCrmCart($cart, $response['cart']['externalId']);
if (empty($order)) {
if (empty($crmCart)) {
continue;
}
if (false !== static::$api->ordersEdit($order)) {
if (false !== static::$api->ordersEdit($crmCart)) {
static::registerAbandonedCartSync($cart->id);
}
}
@ -252,25 +247,45 @@ class RetailcrmCartUploader
*
* @return array
*/
private static function buildCartOrder($cart, $cartExternalId)
private static function buildCrmCart($cart, $cartExternalId)
{
$order = [];
try {
$order = RetailcrmOrderBuilder::buildCrmOrderFromCart(
static::$api,
$cart,
$cartExternalId,
static::$paymentTypes[0],
static::$syncStatus
);
$crmCart = [
'externalId' => $cartExternalId,
'customer' => ['externalId' => $cart->id_customer],
'clearAt'=> null,
'createdAt' => $cart->date_add,
'droppedAt' => date('Y-m-d H:i:s'),
];
if (!empty($cart->date_upd)) {
$crmCart['updatedAt'] = $cart->date_upd;
}
$products = $cart->getProducts();
foreach ($products as $product) {
// Check variable products
$offers = Product::getProductAttributesIds($product['id_product']);
$crmCart['items'][] = [
'offer' => [
'externalId' => !empty($offers)
? $product['id_product'] . '#' . $product['id_product_attribute']
: $product['id_product']
],
'quantity'=> $product['cart_quantity'],
'price'=> $product['price'],
'createdAt'=> $product['date_add'],
];
}
} catch (Exception $exception) {
RetailcrmLogger::writeException(__METHOD__, $exception, null, true);
} catch (Error $exception) {
RetailcrmLogger::writeException(__METHOD__, $exception, null, true);
}
return $order;
return $crmCart;
}
/**
@ -354,24 +369,6 @@ class RetailcrmCartUploader
return $lastUploadDate < $lastUpdatedDate;
}
/**
* Returns false if inner state is not correct
*
* @return bool
*/
private static function validateState()
{
if (empty(static::$syncStatus)
|| (1 > count(static::$paymentTypes))
|| null === static::$now
|| !static::$api
) {
return false;
}
return true;
}
/**
* Backups current cart in context
*/

View file

@ -1180,67 +1180,6 @@ class RetailcrmOrderBuilder
);
}
/**
* Build array with order data for retailCRM from PrestaShop cart data
*
* @param \RetailcrmProxy|\RetailcrmApiClientV5 $api
* @param Cart $cart Cart with data
* @param string $externalId External ID for order
* @param string $paymentType Payment type (buildCrmOrder requires it)
* @param string $status Status for order
*
* @return array
*
* @throws \Exception
*/
public static function buildCrmOrderFromCart($api, $cart = null, $externalId = '', $paymentType = '', $status = '')
{
if (empty($cart) || empty($paymentType) || empty($status)) {
return [];
}
try {
$order = new Order();
$order->id_cart = $cart->id;
$order->id_customer = $cart->id_customer;
$order->id_address_delivery = $cart->id_address_delivery;
$order->id_address_invoice = $cart->id_address_invoice;
$order->id_currency = $cart->id_currency;
$order->id_carrier = $cart->id_carrier;
$order->total_discounts = $cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS);
$order->module = $paymentType;
$order->payment = $paymentType;
if (!empty($cart->id_carrier)) {
$order->total_shipping = $cart->getPackageShippingCost();
$order->total_shipping_tax_excl = $cart->getPackageShippingCost(null, false);
}
$orderBuilder = new RetailcrmOrderBuilder();
$orderData = $orderBuilder
->defaultLangFromConfiguration()
->setApi($api)
->setCmsOrder($order)
->setCmsCart($cart)
->setCmsCustomer(new Customer($cart->id_customer))
->buildOrderWithPreparedCustomer(true)
;
$orderData['externalId'] = $externalId;
$orderData['status'] = $status;
unset($orderData['payments']);
return RetailcrmTools::clearArray($orderData);
} catch (\InvalidArgumentException $exception) {
RetailcrmLogger::writeCaller(
'buildCrmOrderFromCart',
$exception->getMessage()
);
return [];
}
}
/**
* Builds retailCRM customer data from PrestaShop customer data
*

View file

@ -1220,10 +1220,16 @@ class RetailcrmApiClientV5
* @throws \RetailCrm\Exception\CurlException
* @throws \RetailCrm\Exception\InvalidJsonException
*/
public function cartsGet(string $customerId, string $site, string $by = 'externalId')
public function cartsGet($customerId, $site, $by = 'externalId')
{
$this->checkIdParameter($by);
if (empty($site)) {
throw new \InvalidArgumentException(
'Site must be set'
);
}
return $this->client->makeRequest(
sprintf('/customer-interaction/%s/cart/%s', $site, $customerId),
RetailcrmHttpClient::METHOD_GET,

View file

@ -70,14 +70,16 @@ class RetailcrmAbandonedCartsEvent extends RetailcrmAbstractEvent implements Ret
$api = RetailcrmTools::getApiClient();
if (empty($api)) {
if ($api === null) {
continue;
}
$reference = new RetailcrmReferences($api);
$site = $reference->getSite();
RetailcrmCartUploader::init();
RetailcrmCartUploader::$api = $api;
RetailcrmCartUploader::$paymentTypes = array_keys(json_decode(Configuration::get(RetailCRM::PAYMENT), true));
RetailcrmCartUploader::$syncStatus = Configuration::get(RetailCRM::SYNC_CARTS_STATUS);
RetailcrmCartUploader::$site = $site['code'] ?? '';
RetailcrmCartUploader::setSyncDelay(Configuration::get(RetailCRM::SYNC_CARTS_DELAY));
RetailcrmCartUploader::run();
}