Сhanged the logic of working with abandoned carts (#208)

This commit is contained in:
Uryvskiy Dima 2023-01-26 12:55:52 +03:00 committed by GitHub
parent 96f62b5e7e
commit 5a899f6b2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 394 additions and 286 deletions

View File

@ -1,8 +1,8 @@
FROM php:7.1-fpm FROM php:7.2-fpm
RUN apt-get update RUN apt-get update
RUN apt-get install -y zlib1g-dev libpq-dev git libicu-dev libxml2-dev libpng-dev libjpeg-dev libmcrypt-dev libxslt-dev libfreetype6-dev \ RUN apt-get install -y zlib1g-dev libpq-dev git libicu-dev libxml2-dev libpng-dev libjpeg-dev libmcrypt-dev libxslt-dev libfreetype6-dev unzip\
&& docker-php-ext-configure intl \ && docker-php-ext-configure intl \
&& docker-php-ext-install intl \ && docker-php-ext-install intl \
&& docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
@ -11,15 +11,16 @@ RUN apt-get install -y zlib1g-dev libpq-dev git libicu-dev libxml2-dev libpng-de
&& docker-php-ext-install xml \ && docker-php-ext-install xml \
&& docker-php-ext-configure gd --with-png-dir=/usr/local/ --with-jpeg-dir=/usr/local/ --with-freetype-dir=/usr/local/ \ && docker-php-ext-configure gd --with-png-dir=/usr/local/ --with-jpeg-dir=/usr/local/ --with-freetype-dir=/usr/local/ \
&& docker-php-ext-install gd \ && docker-php-ext-install gd \
&& docker-php-ext-install mcrypt \
&& docker-php-ext-install bcmath \ && docker-php-ext-install bcmath \
&& docker-php-ext-install soap \ && docker-php-ext-install soap \
&& docker-php-ext-install xsl \ && docker-php-ext-install xsl \
&& docker-php-ext-install mbstring && docker-php-ext-install mbstring \
&& pecl install mcrypt-1.0.1 \
&& docker-php-ext-enable mcrypt
RUN apt-get install -y wget RUN apt-get install -y wget
RUN wget -O /usr/bin/phpunit https://phar.phpunit.de/phpunit-7.phar && chmod +x /usr/bin/phpunit RUN wget -O /usr/bin/phpunit https://phar.phpunit.de/phpunit-6.phar && chmod +x /usr/bin/phpunit
RUN curl --insecure https://getcomposer.org/composer.phar -o /usr/bin/composer && chmod +x /usr/bin/composer RUN curl --insecure https://getcomposer.org/composer.phar -o /usr/bin/composer && chmod +x /usr/bin/composer
# Set timezone # Set timezone

7
.env.dist Normal file
View File

@ -0,0 +1,7 @@
#PrestaShop git branch
BRANCH=1.7.4.4
#For version 1.7.x you need to use composer v1
COMPOSERV1=1
LOCAL_TEST=1

View File

@ -14,125 +14,33 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
- php-version: '5.6' - php-version: '7.1'
branch: '1.6.1.18' branch: '1.7.4.4'
phpunit-version: 'phpunit:5.7.23' composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.2'
branch: '1.7.4.4'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.7.6.9'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.2'
branch: '1.7.6.9'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.7.7.8'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.2'
branch: '1.7.7.8'
composerv1: 1
coverage: 1 coverage: 1
- php-version: '7.0'
branch: '1.6.1.18'
phpunit-version: 'phpunit:6.4.3' phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.6.1.18'
phpunit-version: 'phpunit:6.4.3'
- php-version: '5.6'
branch: '1.6.1.19'
phpunit-version: 'phpunit:5.7.23'
- php-version: '7.0'
branch: '1.6.1.19'
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.6.1.19'
phpunit-version: 'phpunit:6.4.3'
- php-version: '5.6'
branch: '1.6.1.20'
phpunit-version: 'phpunit:5.7.23'
- php-version: '7.0'
branch: '1.6.1.20'
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.6.1.20'
phpunit-version: 'phpunit:6.4.3'
- php-version: '5.6'
branch: '1.6.1.21'
phpunit-version: 'phpunit:5.7.23'
- php-version: '7.0'
branch: '1.6.1.21'
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.6.1.21'
phpunit-version: 'phpunit:6.4.3'
- php-version: '5.6'
branch: '1.6.1.22'
phpunit-version: 'phpunit:5.7.23'
- php-version: '7.0'
branch: '1.6.1.22'
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.6.1.22'
phpunit-version: 'phpunit:6.4.3'
- php-version: '5.6'
branch: '1.6.1.23'
phpunit-version: 'phpunit:5.7.23'
- php-version: '7.0'
branch: '1.6.1.23'
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.6.1.23'
phpunit-version: 'phpunit:6.4.3'
- php-version: '5.6'
branch: '1.6.1.24'
phpunit-version: 'phpunit:5.7.23'
- php-version: '7.0'
branch: '1.6.1.24'
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.6.1.24'
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.7.4.4'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.2'
branch: '1.7.4.4'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
# - php-version: '7.1'
# branch: '1.7.5.2'
# composerv1: 1
# phpunit-version: 'phpunit:6.4.3'
# - php-version: '7.2'
# branch: '1.7.5.2'
# composerv1: 1
# phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.7.6.9'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.2'
branch: '1.7.6.9'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.1'
branch: '1.7.7.8'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.2'
branch: '1.7.7.8'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
- php-version: '7.3'
branch: '1.7.7.8'
composerv1: 1
phpunit-version: 'phpunit:6.4.3'
# - php-version: '7.1'
# branch: '1.7.8.7'
# composerv1: 1
# phpunit-version: 'phpunit:6.4.3'
# - php-version: '7.2'
# branch: '1.7.8.7'
# composerv1: 1
# phpunit-version: 'phpunit:6.4.3'
services: services:
mysql: mysql:

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ upgrade/upgrade-*.php
!upgrade/upgrade-sample.php !upgrade/upgrade-sample.php
coverage.xml coverage.xml
.php-cs-fixer.cache .php-cs-fixer.cache
.env

View File

@ -1,3 +1,6 @@
## v3.5.0
* Реализована поддержка новой логики работы с брошенными корзинами.
## v3.4.14 ## v3.4.14
* Исправлен баг при передаче брошенных корзин. * Исправлен баг при передаче брошенных корзин.

View File

@ -31,19 +31,7 @@ ifeq ($(COMPOSERV1),1)
&& php -r "copy('https://getcomposer.org/download/1.10.17/composer.phar', 'composer.phar');" && php -r "copy('https://getcomposer.org/download/1.10.17/composer.phar', 'composer.phar');"
endif endif
setup_apache:
bash $(PRESTASHOP_DIR)/travis-scripts/setup-php-fpm.sh
echo "* Preparing Apache ..."
sudo a2enmod rewrite actions fastcgi alias
# Use default config
sudo cp -f $(PRESTASHOP_DIR)/tests/travis-ci-apache-vhost /etc/apache2/sites-available/000-default.conf
sudo sed -e "s?%PRESTASHOP_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/000-default.conf
sudo chmod 777 -R $(HOME)
# Starting Apache
sudo service apache2 restart
before_script: composer before_script: composer
mkdir coverage
ifneq ("$(wildcard $(PRESTASHOP_DIR)/travis-scripts/install-prestashop)","") ifneq ("$(wildcard $(PRESTASHOP_DIR)/travis-scripts/install-prestashop)","")
ifeq ($(COMPOSERV1),1) ifeq ($(COMPOSERV1),1)
cd $(PRESTASHOP_DIR) \ cd $(PRESTASHOP_DIR) \
@ -57,10 +45,15 @@ ifneq ("$(wildcard $(PRESTASHOP_DIR)/travis-scripts/install-prestashop)","")
&& bash travis-scripts/install-prestashop.sh && bash travis-scripts/install-prestashop.sh
endif endif
else else
mysql -u root -proot --port $(MYSQL_PORT) -e "DROP DATABASE IF EXISTS \`prestashop\`;"
rm -rf var/cache/* rm -rf var/cache/*
echo "* Installing PrestaShop, this may take a while ..."; echo "* Installing PrestaShop, this may take a while ...";
cd $(PRESTASHOP_DIR) && php install-dev/index_cli.php --language=en --country=fr --domain=localhost --db_server=127.0.0.1:$(MYSQL_PORT) --db_name=prestashop --db_user=root --db_create=1 --name=prestashop.unit.test --email=demo@prestashop.com --password=prestashop_demo
ifeq ($(LOCAL_TEST),1)
cd $(PRESTASHOP_DIR) && php install-dev/index_cli.php --db_server=db --db_user=root --db_create=1
else
mkdir coverage
cd $(PRESTASHOP_DIR) && php install-dev/index_cli.php --db_server=127.0.0.1:$(MYSQL_PORT) --db_user=root --db_create=1
endif
endif endif
fix-version-bugs: fix-version-bugs:
@ -73,9 +66,7 @@ ifeq ($(BRANCH), 1.7.4.4)
&& sed -i 's/$$install->installModules();/$$install->setTranslator(\\Context::getContext()->getTranslator());\n\t$$install->installModules();/g' tests/PrestaShopBundle/Utils/DatabaseCreator.php && sed -i 's/$$install->installModules();/$$install->setTranslator(\\Context::getContext()->getTranslator());\n\t$$install->installModules();/g' tests/PrestaShopBundle/Utils/DatabaseCreator.php
cat $(PRESTASHOP_DIR)/tests/PrestaShopBundle/Utils/DatabaseCreator.php | grep -A 3 -B 3 'install->installModules()' cat $(PRESTASHOP_DIR)/tests/PrestaShopBundle/Utils/DatabaseCreator.php | grep -A 3 -B 3 'install->installModules()'
endif endif
#ifeq ($(BRANCH), 1.7.5.2)
# cd $(PRESTASHOP_DIR) && php composer.phar require --dev friendsofphp/php-cs-fixer:2.16.0 --prefer-dist --no-interaction --no-progress --no-scripts
#endif
ifeq ($(BRANCH),$(filter $(BRANCH),1.7.6.9 1.7.7.8)) ifeq ($(BRANCH),$(filter $(BRANCH),1.7.6.9 1.7.7.8))
cd $(PRESTASHOP_DIR) \ cd $(PRESTASHOP_DIR) \
&& sed -i "s/SymfonyContainer::getInstance()->get('translator')/\\\\Context::getContext()->getTranslator()/g" classes/lang/DataLang.php && sed -i "s/SymfonyContainer::getInstance()->get('translator')/\\\\Context::getContext()->getTranslator()/g" classes/lang/DataLang.php
@ -103,3 +94,8 @@ endif
coverage: coverage:
wget https://phar.phpunit.de/phpcov-2.0.2.phar && php phpcov-2.0.2.phar merge coverage/ --clover coverage.xml wget https://phar.phpunit.de/phpcov-2.0.2.phar && php phpcov-2.0.2.phar merge coverage/ --clover coverage.xml
run_local_tests:
docker-compose up -d --build
docker exec app_test make before_script test
docker-compose down

View File

@ -28,6 +28,12 @@ Module allows integrate CMS Prestashop with [Simla.com](https://simla.com) ([Doc
You can customize your module behavior using [Custom Filters](doc/3.%20Customization/Filters.md) or [Custom Classes](doc/3.%20Customization/Classes.md) You can customize your module behavior using [Custom Filters](doc/3.%20Customization/Filters.md) or [Custom Classes](doc/3.%20Customization/Classes.md)
#### Local testing
To local testing:
* cp .env.dist .env
* make run_local_tests
#### Documentation #### Documentation
[Here](doc/README.md) you can find more information about module setup and workflow [Here](doc/README.md) you can find more information about module setup and workflow

View File

@ -1 +1 @@
3.4.14 3.5.0

View File

@ -1,25 +1,22 @@
version: '3' version: '3'
services: services:
app: app:
container_name: app_test
build: build:
context: ./.docker context: ./.docker
volumes: volumes:
- ./:/code - ./:/code
links: env_file:
- "mysql" - ./.env
depends_on:
- mysql
environment: environment:
- DB_NAME=presta - BRANCH=${BRANCH}
- DB_USER=presta links:
- DB_PASS=presta - db
- DB_HOST=presta depends_on:
mysql: - db
db:
image: mysql:5.7 image: mysql:5.7
environment: environment:
- MYSQL_DATABASE=presta - MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_USER=presta
- MYSQL_PASSWORD=presta
- MYSQL_ROOT_PASSWORD=root
ports: ports:
- "3306:3306" - "3306:3306"

View File

@ -43,6 +43,11 @@ class RetailcrmCartUploader
*/ */
static $api; static $api;
/**
* @var string
*/
static $site;
/** @var \Context|\ContextCore */ /** @var \Context|\ContextCore */
static $context; static $context;
@ -56,12 +61,6 @@ class RetailcrmCartUploader
* @var array * @var array
*/ */
static $cartsIds; static $cartsIds;
/**
* @var array
*/
static $paymentTypes;
/** /**
* @var int * @var int
*/ */
@ -72,11 +71,6 @@ class RetailcrmCartUploader
*/ */
static $allowedUpdateInterval; static $allowedUpdateInterval;
/**
* @var string
*/
static $syncStatus;
/** /**
* @var \DateTime * @var \DateTime
*/ */
@ -103,10 +97,8 @@ class RetailcrmCartUploader
{ {
static::$api = null; static::$api = null;
static::$cartsIds = []; static::$cartsIds = [];
static::$paymentTypes = [];
static::$syncDelay = 0; static::$syncDelay = 0;
static::$allowedUpdateInterval = 86400; static::$allowedUpdateInterval = 86400;
static::$syncStatus = '';
static::$now = new DateTimeImmutable(); static::$now = new DateTimeImmutable();
static::$context = Context::getContext(); static::$context = Context::getContext();
} }
@ -116,7 +108,7 @@ class RetailcrmCartUploader
*/ */
public static function run() public static function run()
{ {
if (!static::validateState()) { if (null === static::$now || null === static::$api) {
return; return;
} }
@ -130,7 +122,7 @@ class RetailcrmCartUploader
$cartExternalId = RetailcrmTools::getCartOrderExternalId($cart); $cartExternalId = RetailcrmTools::getCartOrderExternalId($cart);
$cartLastUpdateDate = null; $cartLastUpdateDate = null;
if (static::isGuestCart($cart) || static::isCartEmpty($cart)) { if (static::isGuestCart($cart)) {
continue; continue;
} }
@ -147,35 +139,40 @@ class RetailcrmCartUploader
static::populateContextWithCart($cart); static::populateContextWithCart($cart);
$response = static::$api->ordersGet($cartExternalId); $response = static::$api->cartGet($cart->id_customer, static::$site);
if ($response instanceof RetailcrmApiResponse) { if ($response instanceof RetailcrmApiResponse) {
if (empty($response['order'])) { $isExistExternalId = !empty($response['cart']['externalId']);
// 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); if (static::isCartEmpty($cart)) {
if ($isExistExternalId) {
static::$api->cartClear(
[
'clearedAt' => date('Y-m-d H:i:s'),
'customer' => ['externalId' => $cart->id_customer],
],
static::$site
);
}
if (empty($order)) {
continue; continue;
} }
if (false !== static::$api->ordersCreate($order)) { $crmCart = static::buildCrmCart($cart, $cartExternalId, $isExistExternalId);
if (empty($crmCart)) {
continue;
}
$response = static::$api->cartSet($crmCart, static::$site);
if ($response instanceof RetailcrmApiResponse && $response->isSuccessful()) {
if ($isExistExternalId) {
static::registerAbandonedCartSync($cart->id);
} else {
$cart->date_upd = date('Y-m-d H:i:s'); $cart->date_upd = date('Y-m-d H:i:s');
$cart->save(); $cart->save();
} }
} elseif (!empty($response['order']['externalId'])) {
$order = static::buildCartOrder($cart, $response['order']['externalId']);
if (empty($order)) {
continue;
}
if (false !== static::$api->ordersEdit($order)) {
static::registerAbandonedCartSync($cart->id);
}
} }
} }
} }
@ -247,30 +244,55 @@ class RetailcrmCartUploader
/** /**
* Build order for abandoned cart * Build order for abandoned cart
* *
* @param Cart|\CartCore $cart * @param Cart|CartCore $cart
* @param string $cartExternalId * @param string $cartExternalId
* @param bool $isExistExternalId
* *
* @return array * @return array
*/ */
private static function buildCartOrder($cart, $cartExternalId) private static function buildCrmCart($cart, string $cartExternalId, bool $isExistExternalId)
{ {
$order = [];
try { try {
$order = RetailcrmOrderBuilder::buildCrmOrderFromCart( $crmCart = [
static::$api, 'customer' => ['externalId' => $cart->id_customer],
$cart, 'clearAt' => null,
$cartExternalId, 'createdAt' => $cart->date_add,
static::$paymentTypes[0], ];
static::$syncStatus
); if (!$isExistExternalId) {
$crmCart['externalId'] = $cartExternalId . uniqid('_', true);
}
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'],
'createdAt' => $product['date_add'],
'price' => !empty($product['rate'])
? round($product['price'], 2) + (round($product['price'], 2) * $product['rate'] / 100)
: round($product['price'], 2),
];
}
} catch (Exception $exception) { } catch (Exception $exception) {
RetailcrmLogger::writeException(__METHOD__, $exception, null, true); RetailcrmLogger::writeException(__METHOD__, $exception, null, true);
} catch (Error $exception) { } catch (Error $exception) {
RetailcrmLogger::writeException(__METHOD__, $exception, null, true); RetailcrmLogger::writeException(__METHOD__, $exception, null, true);
} }
return $order; return $crmCart;
} }
/** /**
@ -354,24 +376,6 @@ class RetailcrmCartUploader
return $lastUploadDate < $lastUpdatedDate; 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 * 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 * Builds retailCRM customer data from PrestaShop customer data
* *

View File

@ -1207,6 +1207,90 @@ class RetailcrmApiClientV5
); );
} }
/**
* Get cart by id or externalId
*
* @param string $customerId order identificator
* @param string $site
* @param string $by (default: 'externalId')
*
* @return RetailcrmApiResponse
*
* @throws \InvalidArgumentException
* @throws \RetailCrm\Exception\CurlException
* @throws \RetailCrm\Exception\InvalidJsonException
*/
public function cartGet($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,
['by' => $by]
);
}
/**
* Create or update cart
*
* @param array $cart
* @param string $site
*
* @return RetailcrmApiResponse
*
* @throws \InvalidArgumentException
* @throws \RetailCrm\Exception\CurlException
* @throws \RetailCrm\Exception\InvalidJsonException
*/
public function cartSet(array $cart, string $site)
{
if (empty($site)) {
throw new \InvalidArgumentException(
'Site must be set'
);
}
return $this->client->makeRequest(
sprintf('/customer-interaction/%s/cart/set', $site),
RetailcrmHttpClient::METHOD_POST,
['cart' => json_encode($cart)]
);
}
/**
* Clear cart
*
* @param array $cart
* @param string $site
*
* @return RetailcrmApiResponse
*
* @throws \InvalidArgumentException
* @throws \RetailCrm\Exception\CurlException
* @throws \RetailCrm\Exception\InvalidJsonException
*/
public function cartClear(array $cart, string $site)
{
if (empty($site)) {
throw new \InvalidArgumentException(
'Site must be set'
);
}
return $this->client->makeRequest(
sprintf('/customer-interaction/%s/cart/clear', $site),
RetailcrmHttpClient::METHOD_POST,
['cart' => json_encode($cart)]
);
}
/** /**
* Returns filtered corporate customers list * Returns filtered corporate customers list
* *

View File

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

View File

@ -48,7 +48,7 @@ require_once dirname(__FILE__) . '/bootstrap.php';
class RetailCRM extends Module class RetailCRM extends Module
{ {
const VERSION = '3.4.14'; const VERSION = '3.5.0';
const API_URL = 'RETAILCRM_ADDRESS'; const API_URL = 'RETAILCRM_ADDRESS';
const API_KEY = 'RETAILCRM_API_TOKEN'; const API_KEY = 'RETAILCRM_API_TOKEN';

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,160 @@
<?php
/**
* MIT License
*
* Copyright (c) 2021 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2021 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
class RetailcrmCartUploaderTest extends RetailcrmTestCase
{
private $apiMock;
private $product;
protected function setUp()
{
parent::setUp();
$this->apiMock = $this->getApiMock(['cartGet', 'cartSet', 'cartClear']);
$catalog = new RetailcrmCatalog();
$data = $catalog->getData();
$this->product = $data[1]->current();
RetailcrmCartUploader::init();
RetailcrmCartUploader::$site = 'test';
RetailcrmCartUploader::setSyncDelay(Configuration::get(RetailCRM::SYNC_CARTS_DELAY));
}
public function testCreateCart()
{
$cart = $this->createCart(1);
$cart->updateQty(1, $this->product['id']);
$this->apiClientMock->expects($this->any())
->method('cartGet')
->willReturn(new RetailcrmApiResponse('200', json_encode(['cart' => []])))
;
$this->apiClientMock->expects($this->any())
->method('cartSet')
->willReturn(new RetailcrmApiResponse('200', json_encode(['success' => true])))
;
RetailcrmCartUploader::$api = $this->apiMock;
RetailcrmCartUploader::run();
$this->assertNotEquals(empty($cart->date_upd), true);
$this->assertInternalType('string', $cart->date_upd);
return $cart;
}
/**
* @depends testCreateCart
*/
public function testUpdateCart($cart)
{
$cart->updateQty(2, $this->product['id']);
$this->apiClientMock->expects($this->any())
->method('cartGet')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
[
'cart' => ['externalId' => $cart->id_customer],
]
)
)
)
;
$this->apiClientMock->expects($this->any())
->method('cartSet')
->willReturn(new RetailcrmApiResponse('200', json_encode(['success' => true])))
;
RetailcrmCartUploader::$api = $this->apiMock;
RetailcrmCartUploader::run();
$this->assertNotEquals(empty($cart->date_upd), true);
$this->assertInternalType('string', $cart->date_upd);
}
public function testClearCart()
{
$cart = $this->createCart(2);
$cartUpdate = $cart->date_upd;
$this->apiClientMock->expects($this->any())
->method('cartGet')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
[
'cart' => ['externalId' => $cart->id_customer],
]
)
)
)
;
$this->apiClientMock->expects($this->any())
->method('cartClear')
->willReturn(new RetailcrmApiResponse('200', json_encode(['success' => true])))
;
RetailcrmCartUploader::$api = $this->apiMock;
RetailcrmCartUploader::run();
$this->assertEquals($cartUpdate, $cart->date_upd);
$this->assertNotEquals(empty($cart->date_upd), true);
$this->assertInternalType('string', $cart->date_upd);
}
private function createCart(int $customerId)
{
$cart = new Cart();
$cart->id_lang = (int) Configuration::get('PS_LANG_DEFAULT');
$cart->id_customer = $customerId;
$cart->id_currency = 1;
$cart->save();
return $cart;
}
}