1
0
mirror of synced 2024-11-24 22:16:13 +03:00

Merge pull request #13 from iyzoer/master

v2.3.0
This commit is contained in:
Alex Lushpai 2018-08-21 11:16:07 +03:00 committed by GitHub
commit 0ed0795be4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 1366 additions and 637 deletions

9
CHACNGELOG.md Normal file
View File

@ -0,0 +1,9 @@
## 2018-08-21 v.2.3.0
* Добавлены консольные команды для выгрузки архива клиентов и заказов
* Обработка данных для формирования структуры перед отправкой вынесена в сервисы
* Теперь при ручной выгрузке заказов из админки не нужно сохранять номера заказов
* ICML каталог теперь формируется для каждого сайта
* При формировании каталога выгружаются выбранные атрибуты товаров
* Улучшена выгрузка товаров в заказе (теперь учитываются конфигурируемые товары)
* Добавлены переводы на русский и испанский языки
* Из обработки истории удален менеджер объектов

View File

@ -29,8 +29,4 @@ By default ICML file is being generated by module every 4 hours. You can find fi
composer require retailcrm/api-client-php ~5.0
```
2) Unpack the archive with the module into the `app/code/Retailcrm/Retailcrm` directory.
3) Change `app/etc/config.php` file by adding `'Retailcrm_Retailcrm' => 1` line into `modules` array
This module is compatible with Magento up to version 2.2.3

View File

@ -33,11 +33,6 @@ Magento module
composer require retailcrm/api-client-php ~5.0
```
2) Распакуйте архив с модулем в директорию "app/code/Retailcrm/Retailcrm".
3) В файле "app/etc/config.php" в массив `modules` добавьте элемент `'Retailcrm_Retailcrm' => 1`
В конфигурационный файл `composer.json` вашего проекта будет добавлена библиотека [retailcrm/api-client-php](https://github.com/retailcrm/api-client-php), которая будет установлена в директорию `vendor/`.

View File

@ -1 +1 @@
2.2.0
2.3.0

View File

@ -0,0 +1,8 @@
<?php
namespace Retailcrm\Retailcrm\Api;
interface CustomerManagerInterface
{
public function process(\Magento\Customer\Model\Customer $customer);
}

View File

@ -0,0 +1,8 @@
<?php
namespace Retailcrm\Retailcrm\Api;
interface OrderManagerInterface
{
public function process(\Magento\Sales\Model\Order $order);
}

View File

@ -55,7 +55,7 @@ class Button extends \Magento\Config\Block\System\Config\Form\Field
)->setData(
[
'id' => 'order_button',
'label' => __('Run'),
'label' => __('Send'),
]
);

View File

@ -20,6 +20,7 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
*/
protected $_fieldRenderer;
private $objectFactory;
private $paymentConfig;
private $client;
@ -29,10 +30,12 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
\Magento\Framework\View\Helper\Js $jsHelper,
\Magento\Payment\Model\Config $paymentConfig,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Magento\Framework\DataObjectFactory $objectFactory,
array $data = []
) {
$this->paymentConfig = $paymentConfig;
$this->client = $client;
$this->objectFactory = $objectFactory;
parent::__construct($context, $authSession, $jsHelper, $data);
}
@ -61,7 +64,7 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = new \Magento\Framework\DataObject(['showInDefault' => 1, 'showInWebsite' => 1]);
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 1]);
}
return $this->_dummyElement;
@ -70,7 +73,11 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$htmlError = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$html .= $this->_getHeaderHtml($element);
if ($this->client->isConfigured()) {

View File

@ -20,6 +20,7 @@ class Shipping extends \Magento\Config\Block\System\Config\Form\Fieldset
*/
protected $_fieldRenderer;
private $objectFactory;
private $shippingConfig;
private $client;
@ -29,10 +30,12 @@ class Shipping extends \Magento\Config\Block\System\Config\Form\Fieldset
\Magento\Framework\View\Helper\Js $jsHelper,
\Magento\Shipping\Model\Config $shippingConfig,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Magento\Framework\DataObjectFactory $objectFactory,
array $data = []
) {
$this->shippingConfig = $shippingConfig;
$this->client = $client;
$this->objectFactory = $objectFactory;
parent::__construct($context, $authSession, $jsHelper, $data);
}
@ -61,7 +64,7 @@ class Shipping extends \Magento\Config\Block\System\Config\Form\Fieldset
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = new \Magento\Framework\DataObject(['showInDefault' => 1, 'showInWebsite' => 1]);
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 1]);
}
return $this->_dummyElement;
@ -76,7 +79,11 @@ class Shipping extends \Magento\Config\Block\System\Config\Form\Fieldset
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$htmlError = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$html .= $this->_getHeaderHtml($element);
if ($this->client->isConfigured()) {

View File

@ -20,6 +20,7 @@ class Site extends \Magento\Config\Block\System\Config\Form\Fieldset
*/
protected $_fieldRenderer;
private $objectFactory;
private $client;
public function __construct(
@ -27,9 +28,11 @@ class Site extends \Magento\Config\Block\System\Config\Form\Fieldset
\Magento\Backend\Model\Auth\Session $authSession,
\Magento\Framework\View\Helper\Js $jsHelper,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Magento\Framework\DataObjectFactory $objectFactory,
array $data = []
) {
$this->client = $client;
$this->objectFactory = $objectFactory;
parent::__construct($context, $authSession, $jsHelper, $data);
}
@ -58,7 +61,7 @@ class Site extends \Magento\Config\Block\System\Config\Form\Fieldset
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = new \Magento\Framework\DataObject(['showInDefault' => 1, 'showInWebsite' => 0]);
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 0]);
}
return $this->_dummyElement;
@ -73,7 +76,10 @@ class Site extends \Magento\Config\Block\System\Config\Form\Fieldset
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$htmlError = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$html .= $this->_getHeaderHtml($element);
if ($this->client->isConfigured()) {
@ -145,7 +151,7 @@ class Site extends \Magento\Config\Block\System\Config\Form\Fieldset
'select',
[
'name' => 'groups[' . $fieldset->getId() . '][fields][default][value]',
'label' => 'Default site',
'label' => __('Default site'),
'value' => isset($data) ? $data : '',
'values' => $this->getValues(),
'inherit' => isset($data['inherit']) ? $data['inherit'] : '',

View File

@ -20,6 +20,7 @@ class Sites extends \Magento\Config\Block\System\Config\Form\Fieldset
*/
protected $_fieldRenderer;
private $objectFactory;
private $storeManager;
private $client;
@ -29,11 +30,12 @@ class Sites extends \Magento\Config\Block\System\Config\Form\Fieldset
\Magento\Framework\View\Helper\Js $jsHelper,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Magento\Framework\DataObjectFactory $objectFactory,
array $data = []
) {
$this->storeManager = $storeManager;
$this->client = $client;
$this->objectFactory = $objectFactory;
parent::__construct($context, $authSession, $jsHelper, $data);
}
@ -61,7 +63,7 @@ class Sites extends \Magento\Config\Block\System\Config\Form\Fieldset
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = new \Magento\Framework\DataObject(['showInDefault' => 1, 'showInWebsite' => 0]);
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 0]);
}
return $this->_dummyElement;
@ -76,7 +78,10 @@ class Sites extends \Magento\Config\Block\System\Config\Form\Fieldset
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$htmlError = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$html .= $this->_getHeaderHtml($element);
if ($this->client->isConfigured()) {

View File

@ -20,6 +20,7 @@ class Status extends \Magento\Config\Block\System\Config\Form\Fieldset
*/
protected $_fieldRenderer;
private $objectFactory;
private $statusCollection;
private $client;
@ -29,10 +30,12 @@ class Status extends \Magento\Config\Block\System\Config\Form\Fieldset
\Magento\Framework\View\Helper\Js $jsHelper,
\Magento\Sales\Model\ResourceModel\Order\Status\Collection $statusCollection,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Magento\Framework\DataObjectFactory $objectFactory,
array $data = []
) {
$this->statusCollection = $statusCollection;
$this->client = $client;
$this->objectFactory = $objectFactory;
parent::__construct($context, $authSession, $jsHelper, $data);
}
@ -61,7 +64,7 @@ class Status extends \Magento\Config\Block\System\Config\Form\Fieldset
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = new \Magento\Framework\DataObject(['showInDefault' => 1, 'showInWebsite' => 1]);
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 1]);
}
return $this->_dummyElement;
@ -70,11 +73,15 @@ class Status extends \Magento\Config\Block\System\Config\Form\Fieldset
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$htmlError = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$html .= $this->_getHeaderHtml($element);
if ($this->client->isConfigured()) {
$statuses = $this->statusCollection->toOptionArray();;
$statuses = $this->statusCollection->toOptionArray();
foreach ($statuses as $code => $status) {
$html .= $this->_getFieldHtml($element, $status);

View File

@ -0,0 +1,117 @@
<?php
namespace Retailcrm\Retailcrm\Console\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Magento\Customer\Model\ResourceModel\Customer\Collection;
use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory;
class CustomersExport extends Command
{
/**
* @var CollectionFactory
*/
private $customerCollectionFactory;
/**
* @var Collection
*/
private $collection;
private $appState;
private $api;
private $helper;
private $serviceCustomer;
public function __construct(
CollectionFactory $customerCollectionFactory,
\Magento\Framework\App\State $appState,
\Retailcrm\Retailcrm\Helper\Proxy $api,
\Retailcrm\Retailcrm\Helper\Data $helper,
\Retailcrm\Retailcrm\Model\Service\Customer $serviceCustomer
) {
$this->appState = $appState;
$this->api = $api;
$this->helper = $helper;
$this->customerCollectionFactory = $customerCollectionFactory;
$this->serviceCustomer = $serviceCustomer;
parent::__construct();
}
protected function configure()
{
$this->setName('retailcrm:customers:export')
->setDescription('Upload archive customers to retailCRM from Magento')
->addArgument('from', InputArgument::OPTIONAL, 'Beginning order number')
->addArgument('to', InputArgument::OPTIONAL, 'End order number');
parent::configure();
}
/**
* Upload customers to retailCRM
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @throws \Exception
*
* @return boolean
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);
$arguments = $input->getArguments();
$this->collection = $this->customerCollectionFactory->create();
$this->collection->addAttributeToSelect('*');
if ($arguments['from'] !== null && $arguments['to'] !== null) {
$this->collection->addAttributeToFilter(
[
[
'attribute' => 'entity_id',
'from' => $arguments['from']
],
[
'attribute' => 'entity_id',
'to' => $arguments['to']
]
]
);
}
$customers = $this->collection->getItems();
if (empty($customers)) {
$output->writeln('<comment>Customers not found</comment>');
return false;
}
/** @var \Magento\Customer\Model\Customer $customer */
foreach ($customers as $customer) {
$ordersToCrm[$customer->getStore()->getId()][] = $this->serviceCustomer->process($customer);
}
foreach ($ordersToCrm as $storeId => $ordersStore) {
$chunked = array_chunk($ordersStore, 50);
unset($ordersStore);
foreach ($chunked as $chunk) {
$this->api->setSite($this->helper->getSite($storeId));
$this->api->customersUpload($chunk);
time_nanosleep(0, 250000000);
}
unset($chunked);
}
$output->writeln('<info>Uploading customers finished</info>');
return true;
}
}

View File

@ -0,0 +1,103 @@
<?php
namespace Retailcrm\Retailcrm\Console\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
class OrdersExport extends Command
{
private $orderRepository;
private $searchCriteriaBuilder;
private $appState;
private $serviceOrder;
private $api;
private $helper;
public function __construct(
\Magento\Sales\Model\OrderRepository $orderRepository,
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
\Magento\Framework\App\State $appState,
\Retailcrm\Retailcrm\Model\Service\Order $serviceOrder,
\Retailcrm\Retailcrm\Helper\Proxy $api,
\Retailcrm\Retailcrm\Helper\Data $helper
) {
$this->orderRepository = $orderRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->appState = $appState;
$this->serviceOrder = $serviceOrder;
$this->api = $api;
$this->helper = $helper;
parent::__construct();
}
protected function configure()
{
$this->setName('retailcrm:orders:export')
->setDescription('Upload archive orders to retailCRM from Magento')
->addArgument('from', InputArgument::OPTIONAL, 'Beginning order number')
->addArgument('to', InputArgument::OPTIONAL, 'End order number');
parent::configure();
}
/**
* Upload orders to retailCRM
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @throws \Exception
*
* @return boolean
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);
$arguments = $input->getArguments();
if ($arguments['from'] !== null && $arguments['to'] !== null) {
$searchCriteria = $this->searchCriteriaBuilder
->addFilter('increment_id', $arguments['from'], 'from')
->addFilter('increment_id', $arguments['to'], 'to')
->create();
} else {
$searchCriteria = $this->searchCriteriaBuilder->create();
}
$resultSearch = $this->orderRepository->getList($searchCriteria);
$orders = $resultSearch->getItems();
if (empty($orders)) {
$output->writeln('<comment>Orders not found</comment>');
return false;
}
/** @var \Magento\Sales\Model\Order $order */
foreach ($orders as $order) {
$ordersToCrm[$order->getStore()->getId()][] = $this->serviceOrder->process($order);
}
foreach ($ordersToCrm as $storeId => $ordersStore) {
$chunked = array_chunk($ordersStore, 50);
unset($ordersStore);
foreach ($chunked as $chunk) {
$this->api->setSite($this->helper->getSite($storeId));
$this->api->ordersUpload($chunk);
time_nanosleep(0, 250000000);
}
unset($chunked);
}
$output->writeln('<info>Uploading orders finished</info>');
return true;
}
}

View File

@ -4,28 +4,36 @@ namespace Retailcrm\Retailcrm\Controller\Adminhtml\System\Config;
class Button extends \Magento\Backend\App\Action
{
/**
* @var \Psr\Log\LoggerInterface
*/
private $logger;
private $order;
private $jsonFactory;
/**
* @param \Magento\Backend\App\Action\Context $context
* @param \Psr\Log\LoggerInterface $logger
* @param \Retailcrm\Retailcrm\Model\Order\OrderNumber $order
* @param \Magento\Framework\Controller\Result\JsonFactory $jsonFactory
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Psr\Log\LoggerInterface $logger,
\Retailcrm\Retailcrm\Model\Order\OrderNumber $order
\Retailcrm\Retailcrm\Model\Order\OrderNumber $order,
\Magento\Framework\Controller\Result\JsonFactory $jsonFactory
) {
$this->order = $order;
$this->logger = $logger;
$this->jsonFactory = $jsonFactory;
parent::__construct($context);
}
/**
* Upload selected orders
*
* @return \Magento\Framework\Controller\Result\Json
*/
public function execute()
{
$this->order->exportOrderNumber();
$numbers = $this->getRequest()->getParam('numbers');
$result = $this->order->exportOrderNumber($numbers);
$resultJson = $this->jsonFactory->create();
return $resultJson->setData($result);
}
}

View File

@ -6,17 +6,24 @@ class Icml
{
private $logger;
private $icml;
private $storeManager;
public function __construct(
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Retailcrm\Retailcrm\Model\Icml\Icml $icml
\Retailcrm\Retailcrm\Model\Icml\Icml $icml,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->logger = $logger;
$this->icml = $icml;
$this->storeManager = $storeManager;
}
public function execute()
{
$this->icml->generate();
$websites = $this->storeManager->getWebsites();
foreach ($websites as $website) {
$this->icml->generate($website);
}
}
}

View File

@ -23,6 +23,13 @@ class Data extends AbstractHelper
parent::__construct($context);
}
public function getGeneralSettings($setting = null)
{
return $setting === null
? $this->getConfigValue(self::XML_PATH_RETAILCRM . 'general')
: $this->getConfigValue(self::XML_PATH_RETAILCRM . 'general/' . $setting);
}
public function getConfigValue($field, $storeId = null)
{
return $this->scopeConfig->getValue(
@ -32,11 +39,6 @@ class Data extends AbstractHelper
);
}
public function getGeneralConfig($code, $storeId = null)
{
return $this->getConfigValue(self::XML_PATH_RETAILCRM . $code, $storeId);
}
/**
* Get site code
*

View File

@ -78,11 +78,11 @@ class ApiUrl extends \Magento\Framework\App\Config\Value
$response = $api->availableVersions();
if ($response === false) {
throw new \Magento\Framework\Exception\ValidatorException(__('Verify that the data entered is correct'));
throw new \Magento\Framework\Exception\ValidatorException(__('Make sure that the entered data is correct'));
} elseif (!$response->isSuccessful() && $response['errorMsg'] == $api->getErrorText('errorApiKey')) {
throw new \Magento\Framework\Exception\ValidatorException(__('Invalid CRM api key'));
throw new \Magento\Framework\Exception\ValidatorException(__('Incorrect API key'));
} elseif (isset($response['errorMsg']) && $response['errorMsg'] == $api->getErrorText('errorAccount')) {
throw new \Magento\Framework\Exception\ValidatorException(__('Invalid CRM api url'));
throw new \Magento\Framework\Exception\ValidatorException(__('Incorrect URL of retailCRM'));
}
return true;

View File

@ -73,14 +73,16 @@ class ApiVersion extends \Magento\Framework\App\Config\Value
if ($response->isSuccessful()) {
$availableVersions = $response['versions'];
} else {
throw new \Magento\Framework\Exception\ValidatorException(__('Invalid CRM url or api key'));
throw new \Magento\Framework\Exception\ValidatorException(__('Incorrect URL of retailCRM or API key'));
}
if (isset($availableVersions)) {
if (in_array($apiVersions[$apiVersion], $availableVersions)) {
$this->setValue($this->getValue());
} else {
throw new \Magento\Framework\Exception\ValidatorException(__('Selected api version forbidden'));
throw new \Magento\Framework\Exception\ValidatorException(
__('The selected API version is unavailable')
);
}
}
}

View File

@ -19,14 +19,11 @@ class Exchange
private $cacheTypeList;
private $order;
private $orderManagement;
private $eventManager;
private $objectManager;
private $orderInterface;
private $storeManager;
private $regionFactory;
public function __construct(
\Magento\Framework\App\ObjectManager $objectManager,
\Retailcrm\Retailcrm\Helper\Data $helper,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Config\Model\ResourceModel\Config $resourceConfig,
@ -40,7 +37,6 @@ class Exchange
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Sales\Api\Data\OrderInterface $orderInterface,
\Magento\Sales\Api\OrderManagementInterface $orderManagement,
\Magento\Framework\Event\Manager $eventManager,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Magento\Sales\Model\Order $order,
\Magento\Store\Model\StoreManagerInterface $storeManager,
@ -61,8 +57,6 @@ class Exchange
$this->cacheTypeList = $cacheTypeList;
$this->orderInterface = $orderInterface;
$this->orderManagement = $orderManagement;
$this->eventManager = $eventManager;
$this->objectManager = $objectManager;
$this->order = $order;
$this->storeManager = $storeManager;
$this->regionFactory = $regionFactory;

View File

@ -10,49 +10,57 @@ class Icml
private $shop;
private $manager;
private $category;
private $product;
private $storeManager;
private $StockState;
private $configurable;
private $config;
private $dirList;
private $ddFactory;
private $resourceModelProduct;
private $searchCriteriaBuilder;
private $productRepository;
public function __construct(
\Magento\Store\Model\StoreManagerInterface $manager,
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $product,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\CatalogInventory\Api\StockStateInterface $StockState,
\Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurable,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\DomDocument\DomDocumentFactory $ddFactory,
\Magento\Framework\Filesystem\DirectoryList $dirList
\Magento\Framework\Filesystem\DirectoryList $dirList,
\Magento\Catalog\Model\ResourceModel\Product $resourceModelProduct,
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
\Magento\Catalog\Model\ProductRepository $productRepository
) {
$this->configurable = $configurable;
$this->StockState = $StockState;
$this->storeManager = $storeManager;
$this->product = $product;
$this->category = $categoryCollectionFactory;
$this->manager = $manager;
$this->config = $config;
$this->ddFactory = $ddFactory;
$this->dirList = $dirList;
$this->resourceModelProduct = $resourceModelProduct;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->productRepository = $productRepository;
}
/**
* Generate icml catelog
*
* @param \Magento\Store\Model\Website $website
*
* @return void
*/
public function generate()
public function generate($website)
{
$this->shop = $this->manager->getStore()->getId();
$this->shop = $website;
$string = '<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="'.date('Y-m-d H:i:s').'">
<shop>
<name>'.$this->manager->getStore()->getName().'</name>
<name>' . $website->getName() . '</name>
<categories/>
<offers/>
</shop>
@ -79,8 +87,7 @@ class Icml
$this->addOffers();
$this->dd->saveXML();
$shopCode = $this->manager->getStore()->getCode();
$this->dd->save($this->dirList->getRoot() . '/retailcrm_' . $shopCode . '.xml');
$this->dd->save($this->dirList->getRoot() . '/retailcrm_' . $website->getCode() . '.xml');
}
/**
@ -226,22 +233,22 @@ class Icml
{
$offers = [];
$collection = $this->product->create();
$collection->addFieldToFilter('visibility', 4);//catalog, search visible
$collection->addAttributeToSelect('*');
$picUrl = $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$customAdditionalAttributes = $this->config->getValue('retailcrm/Misc/attributes_to_export_into_icml');
$criteria = $this->searchCriteriaBuilder
->addFilter('website_id', $this->shop->getId(), 'eq')
->create();
$collection = $this->productRepository->getList($criteria);
$customAdditionalAttributes = $this->config->getValue('retailcrm/catalog/attributes_to_export_into_icml');
foreach ($collection as $product) {
foreach ($collection->getItems() as $product) {
if ($product->getTypeId() == 'simple') {
$offers[] = $this->buildOffer($product);
$offers[] = $this->buildOffer($product, $customAdditionalAttributes);
}
if ($product->getTypeId() == 'configurable') {
$associated_products = $this->getAssociatedProducts($product);
foreach ($associated_products as $associatedProduct) {
$offers[] = $this->buildOffer($product, $associatedProduct);
$offers[] = $this->buildOffer($product, $customAdditionalAttributes, $associatedProduct);
}
}
}
@ -253,14 +260,17 @@ class Icml
* Build offer array
*
* @param object $product
* @param $customAdditionalAttributes
* @param object $associatedProduct
*
* @return array $offer
*/
private function buildOffer($product, $associatedProduct = null)
private function buildOffer($product, $customAdditionalAttributes, $associatedProduct = null)
{
$offer = [];
$picUrl = $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$store = $this->shop->getDefaultStore() ? $this->shop->getDefaultStore() : $this->storeManager->getStore();
$picUrl = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$offer['id'] = $associatedProduct === null ? $product->getId() : $associatedProduct->getId();
$offer['productId'] = $product->getId();
@ -276,7 +286,7 @@ class Icml
$offer['initialPrice'] = $associatedProduct === null
? $product->getFinalPrice()
: $associatedProduct->getFinalPrice();
$offer['url'] = $product->getProductUrl();
$offer['url'] = $product->getUrlInStore();
if ($associatedProduct === null) {
$offer['picture'] = $picUrl . 'catalog/product' . $product->getImage();
@ -294,7 +304,7 @@ class Icml
? $product->getAttributeText('manufacturer')
: $associatedProduct->getAttributeText('manufacturer');
$offer['params'] = $this->getOfferParams($product, $associatedProduct);
$offer['params'] = $this->getOfferParams($product, $customAdditionalAttributes, $associatedProduct);
return $offer;
}
@ -303,59 +313,35 @@ class Icml
* Get parameters offers
*
* @param object $product
* @param $customAdditionalAttributes
* @param object $associatedProduct
*
* @return array $params
*/
private function getOfferParams($product, $associatedProduct = null)
private function getOfferParams($product, $customAdditionalAttributes, $associatedProduct = null)
{
$params = [];
if ($associatedProduct !== null) {
if ($associatedProduct->getResource()->getAttribute('color')) {
$colorAttribute = $associatedProduct->getResource()->getAttribute('color');
$color = $colorAttribute->getSource()->getOptionText($associatedProduct->getColor());
if (!$customAdditionalAttributes) {
return $params;
}
if (isset($color)) {
$attributes = explode(',', $customAdditionalAttributes);
foreach ($attributes as $attributeCode) {
$attribute = $this->resourceModelProduct->getAttribute($attributeCode);
$attributeValue = $associatedProduct
? $associatedProduct->getData($attributeCode)
: $product->getData($attributeCode);
$attributeText = $attribute->getSource()->getOptionText($attributeValue);
if ($attribute && $attributeValue) {
$params[] = [
'name' => 'Color',
'code' => 'color',
'value' => $color
'name' => $attribute->getDefaultFrontendLabel(),
'code' => $attributeCode,
'value' => $attributeText ? $attributeText : $attributeValue
];
}
if ($associatedProduct->getResource()->getAttribute('size')) {
$sizeAttribute = $associatedProduct->getResource()->getAttribute('size');
$size = $sizeAttribute->getSource()->getOptionText($associatedProduct->getSize());
}
if (isset($size)) {
$params[] = [
'name' => 'Size',
'code' => 'size',
'value' => $size
];
}
}
$article = $associatedProduct === null ? $product->getSku() : $associatedProduct->getSku();
if (!empty($article)) {
$params[] = [
'name' => 'Article',
'code' => 'article',
'value' => $article
];
}
$weight = $associatedProduct === null ? $product->getWeight() : $associatedProduct->getWeight();
if (!empty($weight)) {
$params[] = [
'name' => 'Weight',
'code' => 'weight',
'value' => $weight
];
}
return $params;

View File

@ -11,15 +11,18 @@ class Customer implements \Magento\Framework\Event\ObserverInterface
private $registry;
private $customer;
private $helper;
private $serviceCustomer;
public function __construct(
\Magento\Framework\Registry $registry,
Helper $helper,
ApiClient $api
ApiClient $api,
\Retailcrm\Retailcrm\Model\Service\Customer $serviceCustomer
) {
$this->api = $api;
$this->helper = $helper;
$this->registry = $registry;
$this->serviceCustomer = $serviceCustomer;
$this->customer = [];
}
@ -31,17 +34,8 @@ class Customer implements \Magento\Framework\Event\ObserverInterface
return false;
}
$data = $observer->getEvent()->getCustomer();
$this->customer = [
'externalId' => $data->getId(),
'email' => $data->getEmail(),
'firstName' => $data->getFirstname(),
'patronymic' => $data->getMiddlename(),
'lastName' => $data->getLastname(),
'createdAt' => date('Y-m-d H:i:s', strtotime($data->getCreatedAt()))
];
$customer = $observer->getEvent()->getCustomer();
$this->customer = $this->serviceCustomer->process($customer);
$response = $this->api->customersEdit($this->customer);
if ($response === false) {
@ -49,7 +43,7 @@ class Customer implements \Magento\Framework\Event\ObserverInterface
}
if (!$response->isSuccessful() && $response->errorMsg == $this->api->getErrorText('errorNotFound')) {
$this->api->setSite($this->helper->getSite($data->getStore()));
$this->api->setSite($this->helper->getSite($customer->getStore()));
$this->api->customersCreate($this->customer);
}

View File

@ -4,41 +4,37 @@ namespace Retailcrm\Retailcrm\Model\Observer;
use Magento\Framework\Event\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
use RetailCrm\Retailcrm\Helper\Data as Helper;
use Retailcrm\Retailcrm\Helper\Data as Helper;
class OrderCreate implements \Magento\Framework\Event\ObserverInterface
{
protected $api;
protected $config;
protected $logger;
protected $helper;
private $registry;
private $product;
private $order;
private $serviceOrder;
/**
* Constructor
*
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\Registry $registry
* @param \Retailcrm\Retailcrm\Model\Logger\Logger $logger
* @param \Magento\Catalog\Model\ProductRepository $product
* @param \Retailcrm\Retailcrm\Model\Service\Order $serviceOrder
* @param Helper $helper
* @param ApiClient $api
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\Registry $registry,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Magento\Catalog\Model\ProductRepository $product,
\Retailcrm\Retailcrm\Model\Service\Order $serviceOrder,
Helper $helper,
ApiClient $api
) {
$this->logger = $logger;
$this->config = $config;
$this->registry = $registry;
$this->product = $product;
$this->serviceOrder = $serviceOrder;
$this->helper = $helper;
$this->api = $api;
$this->order = [];
@ -60,101 +56,18 @@ class OrderCreate implements \Magento\Framework\Event\ObserverInterface
}
$order = $observer->getEvent()->getOrder();
$this->api->setSite($this->helper->getSite($order->getStore()));
if ($this->existsInCrm($order->getId()) === true) {
return false;
}
$addressObj = $order->getBillingAddress();
$shippingCode = $this->getShippingCode($order->getShippingMethod());
$this->order = [
'externalId' => $order->getId(),
'number' => $order->getRealOrderId(),
'createdAt' => $order->getCreatedAt(),
'lastName' => $order->getCustomerLastname()
? $order->getCustomerLastname()
: $addressObj->getLastname(),
'firstName' => $order->getCustomerFirstname()
? $order->getCustomerFirstname()
: $addressObj->getFirstname(),
'patronymic' => $order->getCustomerMiddlename()
? $order->getCustomerMiddlename()
: $addressObj->getMiddlename(),
'email' => $order->getCustomerEmail(),
'phone' => $addressObj->getTelephone(),
'status' => $this->config->getValue('retailcrm/retailcrm_status/' . $order->getStatus()),
'items' => $this->getOrderItems($order),
'delivery' => [
'code' => $this->config->getValue('retailcrm/retailcrm_shipping/' . $shippingCode),
'cost' => $order->getShippingAmount(),
'address' => [
'index' => $addressObj->getData('postcode'),
'city' => $addressObj->getData('city'),
'street' => $addressObj->getData('street'),
'region' => $addressObj->getData('region'),
'text' => trim(
',',
implode(
',',
[
$addressObj->getData('postcode'),
$addressObj->getData('city'),
$addressObj->getData('street'),
]
)
)
]
]
];
if ($addressObj->getData('country_id')) {
$this->order['countryIso'] = $addressObj->getData('country_id');
}
if ($this->api->getVersion() == 'v4') {
$this->order['paymentType'] = $this->config->getValue(
'retailcrm/retailcrm_payment/' . $order->getPayment()->getMethodInstance()->getCode()
);
$this->order['discount'] = abs($order->getDiscountAmount());
} elseif ($this->api->getVersion() == 'v5') {
$this->order['discountManualAmount'] = abs($order->getDiscountAmount());
$payment = [
'type' => $this->config->getValue(
'retailcrm/retailcrm_payment/' . $order->getPayment()->getMethodInstance()->getCode()
),
'externalId' => $order->getId(),
'order' => [
'externalId' => $order->getId(),
]
];
if ($order->getBaseTotalDue() == 0) {
$payment['status'] = 'paid';
}
$this->order['payments'][] = $payment;
}
if (trim($this->order['delivery']['code']) == '') {
unset($this->order['delivery']['code']);
}
if (isset($this->order['paymentType']) && trim($this->order['paymentType']) == '') {
unset($this->order['paymentType']);
}
if (trim($this->order['status']) == '') {
unset($this->order['status']);
}
$billingAddress = $order->getBillingAddress();
$this->order = $this->serviceOrder->process($order);
$this->setCustomer(
$order,
$addressObj
$billingAddress
);
Helper::filterRecursive($this->order);
@ -168,9 +81,9 @@ class OrderCreate implements \Magento\Framework\Event\ObserverInterface
/**
* @param $order
* @param $addressObj
* @param $billingAddress
*/
private function setCustomer($order, $addressObj)
private function setCustomer($order, $billingAddress)
{
if ($order->getCustomerIsGuest() == 1) {
$customer = $this->getCustomerByEmail($order->getCustomerEmail());
@ -191,9 +104,9 @@ class OrderCreate implements \Magento\Framework\Event\ObserverInterface
'email' => $order->getCustomerEmail()
];
if ($addressObj->getTelephone()) {
if ($billingAddress->getTelephone()) {
$preparedCustomer['phones'][] = [
'number' => $addressObj->getTelephone()
'number' => $billingAddress->getTelephone()
];
}
@ -204,62 +117,6 @@ class OrderCreate implements \Magento\Framework\Event\ObserverInterface
}
}
/**
* Get order products
*
* @param object $order
*
* @return array $items
*/
private function getOrderItems($order)
{
$items = [];
foreach ($order->getAllItems() as $item) {
if ($item->getProductType() == "simple") {
$price = $item->getPrice();
if ($price == 0) {
$magentoProduct = $this->product->getById($item->getProductId());
$price = $magentoProduct->getPrice();
}
$product = [
'productId' => $item->getProductId(),
'productName' => $item->getName(),
'quantity' => $item->getQtyOrdered(),
'initialPrice' => $price,
'offer' => [
'externalId' => $item->getProductId()
]
];
unset($magentoProduct);
unset($price);
$items[] = $product;
}
}
return $items;
}
/**
* Get shipping code
*
* @param string $string
*
* @return string
*/
public function getShippingCode($string)
{
$split = array_values(explode('_', $string));
$length = count($split);
$prepare = array_slice($split, 0, $length/2);
return implode('_', $prepare);
}
/**
* Check exists order or customer in CRM
*

View File

@ -4,7 +4,7 @@ namespace Retailcrm\Retailcrm\Model\Observer;
use Magento\Framework\Event\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
use RetailCrm\Retailcrm\Helper\Data as Helper;
use Retailcrm\Retailcrm\Helper\Data as Helper;
class OrderUpdate implements \Magento\Framework\Event\ObserverInterface
{

View File

@ -2,36 +2,41 @@
namespace Retailcrm\Retailcrm\Model\Order;
use RetailCrm\Retailcrm\Helper\Data as Helper;
use Retailcrm\Retailcrm\Helper\Data as Helper;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
use Retailcrm\Retailcrm\Model\Observer\OrderCreate;
class OrderNumber extends OrderCreate
class OrderNumber
{
private $salesOrder;
private $orderService;
private $helper;
private $api;
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\Registry $registry,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Magento\Catalog\Model\ProductRepository $product,
Helper $helper,
ApiClient $api,
\Retailcrm\Retailcrm\Model\Service\Order $orderService,
\Magento\Sales\Api\Data\OrderInterface $salesOrder
) {
$this->api = $api;
$this->helper = $helper;
$this->salesOrder = $salesOrder;
parent::__construct($config, $registry, $logger, $product, $helper, $api);
$this->orderService = $orderService;
}
public function exportOrderNumber()
/**
* @param string $orderNumbers
*
* @return array
*/
public function exportOrderNumber($orderNumbers)
{
$ordernumber = $this->config->getValue('retailcrm/Load/number_order');
$ordersId = explode(",", $ordernumber);
$ordersId = explode(",", $orderNumbers);
$orders = [];
foreach ($ordersId as $id) {
$magentoOrder = $this->salesOrder->load($id);
$orders[$magentoOrder->getStore()->getId()][] = $this->prepareOrder($magentoOrder);
$orders[$magentoOrder->getStore()->getId()][] = $this->orderService->process($magentoOrder);
}
foreach ($orders as $storeId => $ordersStore) {
@ -40,106 +45,22 @@ class OrderNumber extends OrderCreate
foreach ($chunked as $chunk) {
$this->api->setSite($this->helper->getSite($storeId));
$this->api->ordersUpload($chunk);
$response = $this->api->ordersUpload($chunk);
/** @var \RetailCrm\Response\ApiResponse $response */
if (!$response->isSuccessful()) {
return [
'success' => false,
'error' => $response->getErrorMsg()
];
}
time_nanosleep(0, 250000000);
}
unset($chunked);
}
return true;
}
public function prepareOrder($magentoOrder)
{
$items = [];
$addressObj = $magentoOrder->getBillingAddress();
foreach ($magentoOrder->getAllItems() as $item) {
if ($item->getProductType() == "simple") {
$price = $item->getPrice();
if ($price == 0) {
$magentoProduct = $this->productRepository->getById($item->getProductId());
$price = $magentoProduct->getPrice();
}
$product = [
'productId' => $item->getProductId(),
'productName' => $item->getName(),
'quantity' => $item->getQtyOrdered(),
'initialPrice' => $price,
'offer' => [
'externalId'=>$item->getProductId()
]
];
unset($magentoProduct);
unset($price);
$items[] = $product;
}
}
$ship = $this->getShippingCode($magentoOrder->getShippingMethod());
$preparedOrder = [
'externalId' => $magentoOrder->getRealOrderId(),
'number' => $magentoOrder->getRealOrderId(),
'createdAt' => date('Y-m-d H:i:s'),
'lastName' => $magentoOrder->getCustomerLastname(),
'firstName' => $magentoOrder->getCustomerFirstname(),
'patronymic' => $magentoOrder->getCustomerMiddlename(),
'email' => $magentoOrder->getCustomerEmail(),
'phone' => $addressObj->getTelephone(),
'paymentType' => $this->config->getValue(
'retailcrm/Payment/' . $magentoOrder->getPayment()->getMethodInstance()->getCode()
),
'status' => $this->config->getValue('retailcrm/Status/'.$magentoOrder->getStatus()),
'discount' => abs($magentoOrder->getDiscountAmount()),
'items' => $items,
'delivery' => [
'code' => $this->config->getValue('retailcrm/Shipping/'.$ship),
'cost' => $magentoOrder->getShippingAmount(),
'address' => [
'index' => $addressObj->getData('postcode'),
'city' => $addressObj->getData('city'),
'country' => $addressObj->getData('country_id'),
'street' => $addressObj->getData('street'),
'region' => $addressObj->getData('region'),
'text' => trim(
',',
implode(
',',
[
$addressObj->getData('postcode'),
$addressObj->getData('city'),
$addressObj->getData('street'),
]
)
)
]
]
];
if (trim($preparedOrder['delivery']['code']) == '') {
unset($preparedOrder['delivery']['code']);
}
if (trim($preparedOrder['paymentType']) == '') {
unset($preparedOrder['paymentType']);
}
if (trim($preparedOrder['status']) == '') {
unset($preparedOrder['status']);
}
if ($magentoOrder->getCustomerIsGuest() == 0) {
$preparedOrder['customer']['externalId'] = $magentoOrder->getCustomerId();
}
$this->logger->writeDump($preparedOrder, 'OrderNumber');
return Helper::filterRecursive($preparedOrder);
return ['success' => true];
}
}

View File

@ -0,0 +1,111 @@
<?php
namespace Retailcrm\Retailcrm\Model\Service;
use Retailcrm\Retailcrm\Api\CustomerManagerInterface;
class Customer implements CustomerManagerInterface
{
private $helper;
/**
* Customer constructor.
*
* @param \Retailcrm\Retailcrm\Helper\Data $helper
*/
public function __construct(
\Retailcrm\Retailcrm\Helper\Data $helper
) {
$this->helper = $helper;
}
/**
* Process customer
*
* @param \Magento\Customer\Model\Customer $customer
*
* @return array $preparedCustomer
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function process(\Magento\Customer\Model\Customer $customer)
{
$preparedCustomer = [
'externalId' => $customer->getId(),
'email' => $customer->getEmail(),
'firstName' => $customer->getFirstname(),
'patronymic' => $customer->getMiddlename(),
'lastName' => $customer->getLastname(),
'createdAt' => $customer->getCreatedAt()
];
$address = $this->getAddress($customer);
$phones = $this->getPhones($customer);
if ($address) {
$preparedCustomer['address'] = $address;
}
if ($phones) {
$preparedCustomer['phones'] = $this->getPhones($customer);
}
if ($this->helper->getGeneralSettings('api_version') == 'v5') {
if ($customer->getGender()) {
$preparedCustomer['sex'] = $customer->getGender() == 1 ? 'male' : 'female';
}
$preparedCustomer['birthday'] = $customer->getDob();
}
return $preparedCustomer;
}
private function getAddress(\Magento\Customer\Model\Customer $customer)
{
$billingAddress = $customer->getDefaultBillingAddress();
if ($billingAddress) {
$address = [
'index' => $billingAddress->getData('postcode'),
'countryIso' => $billingAddress->getData('country_id'),
'region' => $billingAddress->getData('region'),
'city' => $billingAddress->getData('city'),
'street' => $billingAddress->getData('street'),
'text' => sprintf(
'%s %s %s %s',
$billingAddress->getData('postcode'),
$billingAddress->getData('region'),
$billingAddress->getData('city'),
$billingAddress->getData('street')
)
];
return $address;
}
return false;
}
/**
* Set customer phones
*
* @param \Magento\Customer\Model\Customer $customer
*
* @return array $phones
*/
private function getPhones(\Magento\Customer\Model\Customer $customer)
{
$addresses = $customer->getAddressesCollection();
$phones = [];
if (!empty($addresses)) {
foreach ($addresses as $address) {
$phone = [];
$phone['number'] = $address->getTelephone();
$phones[] = $phone;
}
}
return $phones;
}
}

176
src/Model/Service/Order.php Normal file
View File

@ -0,0 +1,176 @@
<?php
namespace Retailcrm\Retailcrm\Model\Service;
use \Retailcrm\Retailcrm\Helper\Data as Helper;
class Order implements \Retailcrm\Retailcrm\Api\OrderManagerInterface
{
private $productRepository;
private $config;
private $helper;
private $configurableProduct;
public function __construct(
\Magento\Catalog\Model\ProductRepository $productRepository,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableProduct,
Helper $helper
) {
$this->productRepository = $productRepository;
$this->config = $config;
$this->helper = $helper;
$this->configurableProduct = $configurableProduct;
}
/**
* Process order
*
* @param \Magento\Sales\Model\Order $order
*
* @return mixed
*/
public function process(\Magento\Sales\Model\Order $order)
{
$items = $order->getAllItems();
$products = $this->addProducts($items);
$billingAddress = $order->getBillingAddress();
$shippingAddress = $order->getShippingAddress();
$shipping = $this->getShippingCode($order->getShippingMethod());
$preparedOrder = [
'externalId' => $order->getId(),
'number' => $order->getRealOrderId(),
'createdAt' => $order->getCreatedAt(),
'lastName' => $order->getCustomerLastname(),
'firstName' => $order->getCustomerFirstname(),
'patronymic' => $order->getCustomerMiddlename(),
'email' => $order->getCustomerEmail(),
'phone' => $billingAddress->getTelephone(),
'status' => $this->config->getValue('retailcrm/retailcrm_status/' . $order->getStatus()),
'items' => $products,
'delivery' => [
'code' => $this->config->getValue('retailcrm/retailcrm_shipping/' . $shipping),
'cost' => $order->getShippingAmount(),
'address' => [
'index' => $shippingAddress->getData('postcode'),
'city' => $shippingAddress->getData('city'),
'countryIso' => $shippingAddress->getData('country_id'),
'street' => $shippingAddress->getData('street'),
'region' => $shippingAddress->getData('region'),
'text' => trim(
',',
implode(
',',
[
$shippingAddress->getData('postcode'),
$shippingAddress->getData('city'),
$shippingAddress->getData('street'),
]
)
)
]
]
];
if ($billingAddress->getData('country_id')) {
$preparedOrder['countryIso'] = $billingAddress->getData('country_id');
}
if ($this->helper->getGeneralSettings('api_version') == 'v4') {
$preparedOrder['discount'] = abs($order->getDiscountAmount());
$preparedOrder['paymentType'] = $this->config->getValue(
'retailcrm/retailcrm_payment/' . $order->getPayment()->getMethodInstance()->getCode()
);
} elseif ($this->helper->getGeneralSettings('api_version') == 'v5') {
$preparedOrder['discountManualAmount'] = abs($order->getDiscountAmount());
$payment = [
'type' => $this->config->getValue(
'retailcrm/retailcrm_payment/' . $order->getPayment()->getMethodInstance()->getCode()
),
'externalId' => $order->getId(),
'order' => [
'externalId' => $order->getId(),
]
];
if ($order->getBaseTotalDue() == 0) {
$payment['status'] = 'paid';
}
$preparedOrder['payments'][] = $payment;
}
if ($order->getCustomerIsGuest() == 0) {
$preparedOrder['customer']['externalId'] = $order->getCustomerId();
}
return Helper::filterRecursive($preparedOrder);
}
/**
* Get shipping code
*
* @param string $string
*
* @return string
*/
public function getShippingCode($string)
{
$split = array_values(explode('_', $string));
$length = count($split);
$prepare = array_slice($split, 0, $length/2);
return implode('_', $prepare);
}
/**
* Add products in order array
*
* @param $items
*
* @return array
*/
protected function addProducts($items)
{
$products = [];
foreach ($items as $item) {
if ($item->getProductType() == 'configurable') {
$attributesInfo = $item->getProductOptions()['attributes_info'];
$attributes = [];
foreach ($attributesInfo as $attributeInfo) {
$attributes[$attributeInfo['option_id']] = $attributeInfo['option_value'];
}
$product = $this->configurableProduct->getProductByAttributes($attributes, $item->getProduct());
} else {
$product = $item->getProduct();
}
$price = $item->getPrice();
if ($price == 0) {
$magentoProduct = $this->productRepository->getById($item->getProductId());
$price = $magentoProduct->getPrice();
}
$resultProduct = [
'productName' => $item->getName(),
'quantity' => $item->getQtyOrdered(),
'initialPrice' => $price,
'offer' => [
'externalId' => $product ? $product->getId() : ''
]
];
unset($magentoProduct);
unset($price);
$products[] = $resultProduct;
}
return $products;
}
}

View File

@ -17,7 +17,13 @@ class Attribute implements \Magento\Framework\Option\ArrayInterface
public function toOptionArray()
{
$types = ['text', 'multiselect', 'decimal'];
$types = [
'text',
'decimal',
'boolean',
'select',
'price'
];
$attributes = $this->entityType->loadByCode('catalog_product')->getAttributeCollection();
$attributes->addFieldToFilter('frontend_input', $types);
@ -26,7 +32,7 @@ class Attribute implements \Magento\Framework\Option\ArrayInterface
foreach ($attributes as $attr) {
if ($attr->getFrontendLabel()) {
$result[] = [
'value' => $attr->getAttributeId(),
'value' => $attr->getAttributeCode(),
'label' => $attr->getFrontendLabel(),
'title' => $attr->getAttributeCode()
];

View File

@ -17,6 +17,7 @@ class FieldsetTest extends \PHPUnit\Framework\TestCase
protected $form;
protected $testElementId = 'test_element_id';
protected $testFieldSetCss = 'test_fieldset_css';
protected $objectFactory;
public function setUp()
{
@ -26,7 +27,7 @@ class FieldsetTest extends \PHPUnit\Framework\TestCase
$escaperMock = $this->createMock(\Magento\Framework\Escaper::class);
$formElementMock = $this->createMock(\Magento\Framework\Data\Form\Element\Select::class);
$factoryMock->expects($this->any())->method('create')->willReturn($formElementMock);
$this->objectFactory = $this->objectManager->getObject(\Magento\Framework\DataObjectFactory::class);
$formElementMock->expects($this->any())->method('setRenderer')->willReturn($formElementMock);
$elementCollection = $this->objectManager->getObject(\Magento\Framework\Data\Form\Element\Collection::class);
@ -88,13 +89,17 @@ class FieldsetTest extends \PHPUnit\Framework\TestCase
$this->urlModelMock = $this->createMock(\Magento\Backend\Model\Url::class);
$this->layoutMock = $this->createMock(\Magento\Framework\View\Layout::class);
$this->groupMock = $this->createMock(\Magento\Config\Model\Config\Structure\Element\Group::class);
$this->groupMock->expects($this->any())->method('getFieldsetCss')->will($this->returnValue($this->testFieldSetCss));
$this->groupMock->expects($this->any())->method('getFieldsetCss')
->will($this->returnValue($this->testFieldSetCss));
$this->context = $this->createMock(\Magento\Backend\Block\Context::class);
$this->context->expects($this->any())->method('getRequest')->willReturn($this->requestMock);
$this->context->expects($this->any())->method('getUrlBuilder')->willReturn($this->urlModelMock);
$this->layoutMock->expects($this->any())->method('getBlockSingleton')->willReturn($rendererMock);
$this->helperMock = $this->createMock(\Magento\Framework\View\Helper\Js::class);
$this->form = $this->createPartialMock(\Magento\Config\Block\System\Config\Form::class, ['getElements', 'getRequest']);
$this->form = $this->createPartialMock(
\Magento\Config\Block\System\Config\Form::class,
['getElements', 'getRequest']
);
$this->form->expects($this->any())->method('getElements')->willReturn($elementCollection);
$this->form->expects($this->any())->method('getRequest')->willReturn($this->requestMock);
}

View File

@ -51,7 +51,8 @@ class PaymentTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
'data' => ['group' => $this->groupMock],
'client' => $client,
'paymentConfig' => $paymentConfig,
'context' => $this->context
'context' => $this->context,
'objectFactory' => $this->objectFactory
];
$payment = $this->objectManager->getObject(
@ -68,7 +69,10 @@ class PaymentTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$expected = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$expected = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$this->assertContains($expected, $html);
}
}
@ -76,11 +80,13 @@ class PaymentTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
protected function getTestActiveMethods()
{
$payment = $this->getMockBuilder(\Magento\Payment\Model\MethodInterface::class)
->setMethods(['getData'])
->disableOriginalConstructor()
->getMockForAbstractClass();
$payment->expects($this->any())
->method('getTitle')
->method('getData')
->with('title')
->willReturn('Test Payment');
return ['test_payment' => $payment];

View File

@ -51,7 +51,8 @@ class ShippingTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
'data' => ['group' => $this->groupMock],
'client' => $client,
'shippingConfig' => $shippingConfig,
'context' => $this->context
'context' => $this->context,
'objectFactory' => $this->objectFactory
];
$shipping = $this->objectManager->getObject(
@ -68,12 +69,15 @@ class ShippingTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$expected = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$expected = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$this->assertContains($expected, $html);
}
}
protected function getTestActiveCarriers()
private function getTestActiveCarriers()
{
$shipping = $this->getMockBuilder(\Magento\Shipping\Model\Carrier\AbstractCarrierInterface::class)
->disableOriginalConstructor()

View File

@ -42,7 +42,8 @@ class SiteTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
'jsHelper' => $this->helperMock,
'data' => ['group' => $this->groupMock],
'client' => $client,
'context' => $this->context
'context' => $this->context,
'objectFactory' => $this->objectFactory
];
$site = $this->objectManager->getObject(
@ -59,7 +60,10 @@ class SiteTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$expected = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$expected = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$this->assertContains($expected, $html);
}
}

View File

@ -54,7 +54,8 @@ class SitesTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
'data' => ['group' => $this->groupMock],
'client' => $client,
'storeManager' => $storeManager,
'context' => $this->context
'context' => $this->context,
'objectFactory' => $this->objectFactory
];
$sites = $this->objectManager->getObject(
@ -71,12 +72,15 @@ class SitesTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$expected = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$expected = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$this->assertContains($expected, $html);
}
}
protected function getTestStores()
private function getTestStores()
{
$store = $this->getMockBuilder(\Magento\Store\Model\Store::class)
->disableOriginalConstructor()

View File

@ -51,7 +51,8 @@ class StatusTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
'data' => ['group' => $this->groupMock],
'client' => $client,
'statusCollection' => $statusCollection,
'context' => $this->context
'context' => $this->context,
'objectFactory' => $this->objectFactory
];
$status = $this->objectManager->getObject(
@ -68,12 +69,15 @@ class StatusTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$expected = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$expected = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$this->assertContains($expected, $html);
}
}
protected function getTestStatuses()
private function getTestStatuses()
{
$status = [
'label' => 'Test Status',

View File

@ -1,6 +1,6 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Observer;
namespace Retailcrm\Retailcrm\Test\Unit\Model\Observer;
class CustomerTest extends \PHPUnit\Framework\TestCase
{
@ -12,6 +12,7 @@ class CustomerTest extends \PHPUnit\Framework\TestCase
private $mockCustomer;
private $unit;
private $helper;
private $mockServiceCustomer;
public function setUp()
{
@ -46,21 +47,22 @@ class CustomerTest extends \PHPUnit\Framework\TestCase
$this->mockCustomer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class)
->disableOriginalConstructor()
->setMethods([
'getId',
'getEmail',
'getFirstname',
'getMiddlename',
'getLastname',
'getStore'
])
->getMock();
$this->mockServiceCustomer = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Service\Customer::class)
->disableOriginalConstructor()
->getMock();
$this->mockServiceCustomer->expects($this->any())->method('process')->willReturn($this->getCustomerTestData());
$this->helper = $this->createMock(\Retailcrm\Retailcrm\Helper\Data::class);
$this->unit = new \Retailcrm\Retailcrm\Model\Observer\Customer(
$this->registry,
$this->helper,
$this->mockApi
$this->mockApi,
$this->mockServiceCustomer
);
}
@ -73,8 +75,6 @@ class CustomerTest extends \PHPUnit\Framework\TestCase
$isSuccessful,
$isConfigured
) {
$testData = $this->getAfterSaveCustomerTestData();
// mock Response
$this->mockResponse->expects($this->any())
->method('isSuccessful')
@ -95,27 +95,6 @@ class CustomerTest extends \PHPUnit\Framework\TestCase
->method('isConfigured')
->willReturn($isConfigured);
// mock Customer
$this->mockCustomer->expects($this->any())
->method('getId')
->willReturn($testData['id']);
$this->mockCustomer->expects($this->any())
->method('getEmail')
->willReturn($testData['email']);
$this->mockCustomer->expects($this->any())
->method('getFirstname')
->willReturn($testData['firstname']);
$this->mockCustomer->expects($this->any())
->method('getMiddlename')
->willReturn($testData['middlename']);
$this->mockCustomer->expects($this->any())
->method('getLastname')
->willReturn($testData['lastname']);
$store = $this->createMock(\Magento\Store\Model\Store::class);
$this->mockCustomer->expects($this->any())
@ -142,25 +121,24 @@ class CustomerTest extends \PHPUnit\Framework\TestCase
$this->assertArrayHasKey('lastName', $this->unit->getCustomer());
$this->assertArrayHasKey('patronymic', $this->unit->getCustomer());
$this->assertArrayHasKey('createdAt', $this->unit->getCustomer());
$this->assertInstanceOf(\RetailCrm\Retailcrm\Model\Observer\Customer::class, $customerObserver);
$this->assertInstanceOf(\Retailcrm\Retailcrm\Model\Observer\Customer::class, $customerObserver);
} else {
$this->assertEmpty($this->unit->getCustomer());
}
}
/**
* Get test customer data
*
* @return array
*/
private function getAfterSaveCustomerTestData()
private function getCustomerTestData()
{
return [
'id' => 1,
'externalId' => 1,
'email' => 'test@mail.com',
'firstname' => 'TestFirstname',
'lastname' => 'Testlastname',
'middlename' => 'Testmiddlename'
'firstName' => 'TestFirstname',
'lastName' => 'Testlastname',
'patronymic' => 'Testmiddlename',
'createdAt' => \date('Y-m-d H:i:s')
];
}

View File

@ -7,20 +7,19 @@ namespace Retailcrm\Retailcrm\Test\Unit\Observer;
*/
class OrderCreateTest extends \PHPUnit\Framework\TestCase
{
private $config;
private $unit;
private $mockEvent;
private $mockObserver;
private $registry;
private $mockRegistry;
private $mockApi;
private $mockOrder;
private $mockItem;
private $mockStore;
private $mockBillingAddress;
private $mockResponse;
private $mockPayment;
private $mockPaymentMethod;
private $logger;
private $mockLogger;
private $mockServiceOrder;
private $mockHelper;
public function setUp()
{
@ -47,60 +46,18 @@ class OrderCreateTest extends \PHPUnit\Framework\TestCase
->setMethods(['getOrder'])
->getMock();
$this->config = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
->getMockForAbstractClass();
$this->logger = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Logger\Logger::class)
$this->mockLogger = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Logger\Logger::class)
->disableOriginalConstructor()
->getMock();
$this->registry = $this->getMockBuilder(\Magento\Framework\Registry::class)
$this->mockRegistry = $this->getMockBuilder(\Magento\Framework\Registry::class)
->disableOriginalConstructor()
->getMock();
$this->mockOrder = $this->getMockBuilder(\Magento\Sales\Order::class)
->setMethods([
'getId',
'getRealOrderId',
'getCreatedAt',
'getStore',
'getBillingAddress',
'getShippingMethod',
'getCustomerId',
'getCustomerLastname',
'getCustomerFirstname',
'getCustomerMiddlename',
'getCustomerEmail',
'getShippingAmount',
'getDiscountAmount',
'getPayment',
'getBaseTotalDue',
'getCustomerIsGuest',
'getAllItems',
'getStatus'
])
->getMock();
$this->mockPayment = $this->getMockBuilder(\Magento\Sales\Model\Order\Payment::class)
->setMethods(['getMethodInstance'])
$this->mockOrder = $this->getMockBuilder(\Magento\Sales\Model\Order::class)
->disableOriginalConstructor()
->getMock();
$this->mockPaymentMethod = $this->getMockBuilder(\Magento\Payment\Model\MethodInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->mockItem = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
->disableOriginalConstructor()
->setMethods([
'getPrice',
'getProductId',
'getName',
'getQtyOrdered',
'getProductType'
])
->getMock();
$this->mockStore = $this->getMockBuilder(\Magento\Store\Model\Store::class)
->disableOriginalConstructor()
->setMethods(['getCode'])
@ -116,18 +73,19 @@ class OrderCreateTest extends \PHPUnit\Framework\TestCase
->setMethods(['isSuccessful'])
->getMock();
$product = $this->getMockBuilder(\Magento\Catalog\Model\ProductRepository::class)
$this->mockServiceOrder = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Service\Order::class)
->disableOriginalConstructor()
->getMock();
$helper = $this->createMock(\Retailcrm\Retailcrm\Helper\Data::class);
$this->mockHelper = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->unit = new \Retailcrm\Retailcrm\Model\Observer\OrderCreate(
$this->config,
$this->registry,
$this->logger,
$product,
$helper,
$this->mockRegistry,
$this->mockLogger,
$this->mockServiceOrder,
$this->mockHelper,
$this->mockApi
);
}
@ -206,27 +164,6 @@ class OrderCreateTest extends \PHPUnit\Framework\TestCase
->method('getCode')
->willReturn(1);
// order item mock set data
$this->mockItem->expects($this->any())
->method('getProductType')
->willReturn('simple');
$this->mockItem->expects($this->any())
->method('getPrice')
->willReturn(999.99);
$this->mockItem->expects($this->any())
->method('getProductId')
->willReturn(10);
$this->mockItem->expects($this->any())
->method('getName')
->willReturn('Product name');
$this->mockItem->expects($this->any())
->method('getQtyOrdered')
->willReturn(3);
// order mock set data
$this->mockOrder->expects($this->any())
->method('getId')
@ -236,68 +173,10 @@ class OrderCreateTest extends \PHPUnit\Framework\TestCase
->method('getBillingAddress')
->willReturn($this->mockBillingAddress);
$this->mockOrder->expects($this->any())
->method('getShippingMethod')
->willReturn($testData['order.shippingMethod']);
$this->mockOrder->expects($this->any())
->method('getStore')
->willReturn($this->mockStore);
$this->mockOrder->expects($this->any())
->method('getRealOrderId')
->willReturn($testData['order.realOrderId']);
$this->mockOrder->expects($this->any())
->method('getCreatedAt')
->willReturn(date('Y-m-d H:i:s'));
$this->mockOrder->expects($this->any())
->method('getCustomerLastname')
->willReturn($testData['order.customerLastname']);
$this->mockOrder->expects($this->any())
->method('getCustomerFirstname')
->willReturn($testData['order.customerFirstname']);
$this->mockOrder->expects($this->any())
->method('getCustomerMiddlename')
->willReturn($testData['order.customerMiddlename']);
$this->mockOrder->expects($this->any())
->method('getCustomerEmail')
->willReturn($testData['order.customerEmail']);
$this->mockOrder->expects($this->any())
->method('getAllItems')
->willReturn($testData['order.allItems']);
$this->mockOrder->expects($this->any())
->method('getStatus')
->willReturn($testData['order.status']);
$this->mockOrder->expects($this->any())
->method('getCustomerIsGuest')
->willReturn($customerIsGuest);
$this->mockOrder->expects($this->any())
->method('getCustomerId')
->willReturn(1);
$this->mockOrder->expects($this->any())
->method('getPayment')
->willReturn($this->mockPayment);
// mock Payment Method
$this->mockPaymentMethod->expects($this->any())
->method('getCode')
->willReturn($testData['order.paymentMethod']);
// mock Payment
$this->mockPayment->expects($this->any())
->method('getMethodInstance')
->willReturn($this->mockPaymentMethod);
// mock Event
$this->mockEvent->expects($this->any())
->method('getOrder')
@ -308,6 +187,8 @@ class OrderCreateTest extends \PHPUnit\Framework\TestCase
->method('getEvent')
->willReturn($this->mockEvent);
$this->mockServiceOrder->expects($this->any())->method('process')
->willReturn($this->getOrderTestData($apiVersion, $customerIsGuest));
$orderCreateObserver = $this->unit->execute($this->mockObserver);
if ($isConfigured && !$isSuccessful) {
@ -320,7 +201,7 @@ class OrderCreateTest extends \PHPUnit\Framework\TestCase
$this->assertArrayHasKey('patronymic', $this->unit->getOrder());
$this->assertArrayHasKey('email', $this->unit->getOrder());
$this->assertArrayHasKey('phone', $this->unit->getOrder());
// $this->assertArrayHasKey('status', $this->unit->getOrder());
$this->assertArrayHasKey('status', $this->unit->getOrder());
$this->assertArrayHasKey('items', $this->unit->getOrder());
$this->assertArrayHasKey('delivery', $this->unit->getOrder());
@ -336,6 +217,67 @@ class OrderCreateTest extends \PHPUnit\Framework\TestCase
}
}
private function getOrderTestData($apiVersion, $customerIsGuest)
{
$order = [
'countryIso' => 'RU',
'externalId' => 1,
'number' => '000000001',
'status' => 'new',
'phone' => '890000000000',
'email' => 'test@gmail.com',
'createdAt' => date('Y-m-d H:i:s'),
'lastName' => 'Test',
'firstName' => 'Test',
'patronymic' => 'Tests',
'items' => [
[
'productName' => 'Test product',
'quantity' => 2,
'initialPrice' => 1.000,
'offer' => [
'externalId' => 1
]
]
],
'delivery' => [
'code' => 'test',
'cost' => '100',
'address' => [
'index' => '111111',
'city' => 'Moscow',
'countryIso' => 'RU',
'street' => 'Test street',
'region' => 'Test region',
'text' => '111111, Moscow, Test region, Test street'
]
]
];
if ($apiVersion == 'v5') {
$order['discountManualAmount'] = 0;
$payment = [
'type' => 'test',
'externalId' => 1,
'order' => [
'externalId' => 1,
],
'status' => 'paid'
];
$order['payments'][] = $payment;
} else {
$order['paymentType'] = 'test';
$order['discount'] = 0;
}
if ($customerIsGuest == 0) {
$order['customer']['externalId'] = 1;
}
return $order;
}
/**
* Get test order data
*
@ -376,25 +318,6 @@ class OrderCreateTest extends \PHPUnit\Framework\TestCase
return $testData['order.billingAddress']['data'][$dataKey];
}
public function getCallbackDataClasses($class)
{
$helper = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$logger = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Logger\Logger::class)
->disableOriginalConstructor()
->getMock();
if ($class == '\Retailcrm\Retailcrm\Helper\Data') {
return $helper;
}
if ($class == '\Retailcrm\Retailcrm\Model\Logger\Logger') {
return $logger;
}
}
public function dataProviderOrderCreate()
{
return [

View File

@ -0,0 +1,191 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Model\Service;
class CustomerTest extends \PHPUnit\Framework\TestCase
{
private $mockData;
private $mockCustomer;
private $unit;
public function setUp()
{
$this->mockData = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->mockCustomer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class)
->disableOriginalConstructor()
->setMethods([
'getId',
'getEmail',
'getFirstname',
'getMiddlename',
'getLastname',
'getStore',
'getGender',
'getDob',
'getDefaultBillingAddress',
'getAddressesCollection'
])
->getMock();
}
/**
* @param $apiVersion
*
* @dataProvider dataProvider
*/
public function testProcess($apiVersion)
{
$mockAddress = $this->getMockBuilder(\Magento\Customer\Model\Address::class)
->disableOriginalConstructor()
->setMethods([
'getData',
'getTelephone'
])
->getMock();
$mockAddress->expects($this->any())
->method('getData')
->with(
$this->logicalOr(
$this->equalTo('postcode'),
$this->equalTo('country_id'),
$this->equalTo('region'),
$this->equalTo('city'),
$this->equalTo('street')
)
)
->will($this->returnCallback([$this, 'getCallbackDataAddress']));
$mockAddress->expects($this->any())
->method('getTelephone')
->willReturn('000-00-00');
$this->mockData->expects($this->any())
->method('getGeneralSettings')
->with('api_version')
->willReturn($apiVersion);
$testData = $this->getAfterSaveCustomerTestData();
// mock Customer
$this->mockCustomer->expects($this->any())
->method('getId')
->willReturn($testData['id']);
$this->mockCustomer->expects($this->any())
->method('getEmail')
->willReturn($testData['email']);
$this->mockCustomer->expects($this->any())
->method('getFirstname')
->willReturn($testData['firstname']);
$this->mockCustomer->expects($this->any())
->method('getMiddlename')
->willReturn($testData['middlename']);
$this->mockCustomer->expects($this->any())
->method('getLastname')
->willReturn($testData['lastname']);
$this->mockCustomer->expects($this->any())
->method('getGender')
->willReturn($testData['gender']);
$this->mockCustomer->expects($this->any())
->method('getDob')
->willReturn($testData['birthday']);
$this->mockCustomer->expects($this->any())
->method('getDefaultBillingAddress')
->willReturn($mockAddress);
$this->mockCustomer->expects($this->any())
->method('getAddressesCollection')
->willReturn([$mockAddress]);
$this->unit = new \Retailcrm\Retailcrm\Model\Service\Customer(
$this->mockData
);
$result = $this->unit->process($this->mockCustomer);
$this->assertNotEmpty($result);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('externalId', $result);
$this->assertNotEmpty($result['externalId']);
$this->assertEquals($this->getAfterSaveCustomerTestData()['id'], $result['externalId']);
$this->assertArrayHasKey('email', $result);
$this->assertNotEmpty($result['email']);
$this->assertEquals($this->getAfterSaveCustomerTestData()['email'], $result['email']);
$this->assertArrayHasKey('firstName', $result);
$this->assertNotEmpty($result['firstName']);
$this->assertEquals($this->getAfterSaveCustomerTestData()['firstname'], $result['firstName']);
$this->assertArrayHasKey('lastName', $result);
$this->assertNotEmpty($result['lastName']);
$this->assertEquals($this->getAfterSaveCustomerTestData()['lastname'], $result['lastName']);
$this->assertArrayHasKey('patronymic', $result);
$this->assertNotEmpty($result['patronymic']);
$this->assertEquals($this->getAfterSaveCustomerTestData()['middlename'], $result['patronymic']);
if ($apiVersion == 'v5') {
$this->assertArrayHasKey('birthday', $result);
$this->assertNotEmpty($result['birthday']);
$this->assertEquals($this->getAfterSaveCustomerTestData()['birthday'], $result['birthday']);
$this->assertArrayHasKey('sex', $result);
$this->assertNotEmpty($result['sex']);
$this->assertEquals('male', $result['sex']);
}
}
public function getCallbackDataAddress($dataKey)
{
$address = [
'postcode' => 'test-index',
'country_id' => 'US',
'region' => 'test-region',
'city' => 'test-city',
'street' => 'test-street'
];
return $address[$dataKey];
}
/**
* Get test customer data
*
* @return array
*/
private function getAfterSaveCustomerTestData()
{
return [
'id' => 1,
'email' => 'test@mail.com',
'firstname' => 'TestFirstname',
'lastname' => 'Testlastname',
'middlename' => 'Testmiddlename',
'birthday' => '1990-01-01',
'gender' => 1
];
}
/**
* Data provider
*
* @return array
*/
public function dataProvider()
{
return [
[
'api_version' => 'v4',
],
[
'api_version' => 'v5'
]
];
}
}

View File

@ -0,0 +1,232 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Model\Service;
class OrderTest extends \PHPUnit\Framework\TestCase
{
private $mockProductRepository;
private $mockHelper;
private $mockConfig;
private $mockConfigurableProduct;
private $mockOrder;
private $unit;
public function setUp()
{
$this->mockProductRepository = $this->getMockBuilder(\Magento\Catalog\Model\ProductRepository::class)
->disableOriginalConstructor()
->getMock();
$this->mockConfigurableProduct = $this->getMockBuilder(
\Magento\ConfigurableProduct\Model\Product\Type\Configurable::class
)->disableOriginalConstructor()->getMock();
$this->mockHelper = $this->createMock(\Retailcrm\Retailcrm\Helper\Data::class);
$this->mockConfig = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
->getMockForAbstractClass();
$this->mockOrder = $this->getMockBuilder(\Magento\Sales\Model\Order::class)
->disableOriginalConstructor()
->getMock();
$this->unit = new \Retailcrm\Retailcrm\Model\Service\Order(
$this->mockProductRepository,
$this->mockConfig,
$this->mockConfigurableProduct,
$this->mockHelper
);
}
/**
* @dataProvider dataProvider
*
* @param $productType
* @param $customerIsGuest
* @param $apiVersion
*/
public function testProcess($productType, $customerIsGuest, $apiVersion)
{
$this->mockHelper->expects($this->any())->method('getGeneralSettings')
->with('api_version')->willReturn($apiVersion);
$this->mockConfig->expects($this->any())->method('getValue')
->with($this->logicalOr(
$this->equalTo('retailcrm/retailcrm_status/processing'),
$this->equalTo('retailcrm/retailcrm_payment/checkmo'),
$this->equalTo('retailcrm/retailcrm_shipping/flatrate')
))->will($this->returnCallback([$this, 'getCallbackDataConfig']));
$mockProduct = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
->disableOriginalConstructor()
->getMock();
$mockProduct->expects($this->any())->method('getId')->willReturn(1);
$mockItem = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
->disableOriginalConstructor()
->getMock();
$mockItem->expects($this->any())->method('getProductType')->willReturn($productType);
$mockItem->expects($this->any())->method('getProductOptions')
->willReturn([
'attributes_info' => [
[
'option_id' => 1,
'option_value' => 1
]
]
]);
$mockItem->expects($this->any())->method('getProduct')->willReturn($mockProduct);
$mockItem->expects($this->any())->method('getPrice')->willReturn(100.000);
$mockItem->expects($this->any())->method('getName')->willReturn('Test product');
$mockItem->expects($this->any())->method('getQtyOrdered')->willReturn(2);
$mockConfigurableProduct = $this->getMockBuilder(
\Magento\ConfigurableProduct\Model\Product\Type\Configurable::class
)
->disableOriginalConstructor()
->getMock();
$mockConfigurableProduct->expects($this->any())->method('getProductByAttributes')->willReturn($mockProduct);
$mockShippingAddress = $this->getMockBuilder(\Magento\Sales\Model\Order\Address::class)
->disableOriginalConstructor()
->setMethods(['getData'])
->getMock();
$mockShippingAddress->expects($this->any())
->method('getData')
->with($this->logicalOr(
$this->equalTo('city'),
$this->equalTo('region'),
$this->equalTo('street'),
$this->equalTo('postcode'),
$this->equalTo('country_id')
))
->will($this->returnCallback([$this, 'getCallbackDataAddress']));
$mockBillingAddress = $this->getMockBuilder(\Magento\Sales\Model\Order\Address::class)
->disableOriginalConstructor()
->setMethods(['getTelephone'])
->getMock();
$mockBillingAddress->expects($this->any())->method('getTelephone')->willReturn('89000000000');
$mockPaymentMethod = $this->getMockBuilder(\Magento\Payment\Model\MethodInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$mockPaymentMethod->expects($this->any())->method('getCode')->willReturn('checkmo');
$mockPayment = $this->getMockBuilder(\Magento\Sales\Model\Order\Payment::class)
->setMethods(['getMethodInstance'])
->disableOriginalConstructor()
->getMock();
$mockPayment->expects($this->any())->method('getMethodInstance')->willReturn($mockPaymentMethod);
$this->mockOrder->expects($this->any())->method('getAllItems')->willReturn([$mockItem]);
$this->mockOrder->expects($this->any())->method('getBillingAddress')->willReturn($mockBillingAddress);
$this->mockOrder->expects($this->any())->method('getShippingAddress')->willReturn($mockShippingAddress);
$this->mockOrder->expects($this->any())->method('getShippingMethod')->willReturn('flatrate_flatrate');
$this->mockOrder->expects($this->any())->method('getId')->willReturn(1);
$this->mockOrder->expects($this->any())->method('getRealOrderId')->willReturn('000000001');
$this->mockOrder->expects($this->any())->method('getCreatedAt')->willReturn(date('Y-m-d H:i:s'));
$this->mockOrder->expects($this->any())->method('getCustomerLastname')->willReturn('Test');
$this->mockOrder->expects($this->any())->method('getCustomerFirstname')->willReturn(date('Test'));
$this->mockOrder->expects($this->any())->method('getCustomerMiddlename')->willReturn(date('Test'));
$this->mockOrder->expects($this->any())->method('getCustomerEmail')->willReturn('test@mail.com');
$this->mockOrder->expects($this->any())->method('getStatus')->willReturn('processing');
$this->mockOrder->expects($this->any())->method('getShippingAmount')->willReturn(100);
$this->mockOrder->expects($this->any())->method('getDiscountAmount')->willReturn(0);
$this->mockOrder->expects($this->any())->method('getPayment')->willReturn($mockPayment);
$this->mockOrder->expects($this->any())->method('getBaseTotalDue')->willReturn(0);
$this->mockOrder->expects($this->any())->method('getCustomerIsGuest')->willReturn($customerIsGuest);
$this->mockOrder->expects($this->any())->method('getCustomerId')->willReturn(1);
$resultOrder = $this->unit->process($this->mockOrder);
$this->assertNotEmpty($resultOrder);
$this->assertArrayHasKey('externalId', $resultOrder);
$this->assertArrayHasKey('number', $resultOrder);
$this->assertArrayHasKey('createdAt', $resultOrder);
$this->assertArrayHasKey('lastName', $resultOrder);
$this->assertArrayHasKey('firstName', $resultOrder);
$this->assertArrayHasKey('patronymic', $resultOrder);
$this->assertArrayHasKey('email', $resultOrder);
$this->assertArrayHasKey('phone', $resultOrder);
$this->assertArrayHasKey('items', $resultOrder);
$this->assertArrayHasKey('delivery', $resultOrder);
if ($apiVersion == 'v5') {
$this->assertArrayHasKey('payments', $resultOrder);
} else {
$this->assertArrayHasKey('paymentType', $resultOrder);
}
}
public function getCallbackDataConfig($key)
{
$data = [
'retailcrm/retailcrm_status/processing' => 'new',
'retailcrm/retailcrm_payment/checkmo' => 'test',
'retailcrm/retailcrm_shipping/flatrate' => 'test'
];
return $data[$key];
}
public function dataProvider()
{
return [
[
'product_type' => 'simple',
'customer_is_guest' => 1,
'api_version' => 'v4'
],
[
'product_type' => 'configurable',
'customer_is_guest' => 1,
'api_version' => 'v4'
],
[
'product_type' => 'simple',
'customer_is_guest' => 0,
'api_version' => 'v4'
],
[
'product_type' => 'configurable',
'customer_is_guest' => 0,
'api_version' => 'v4'
],
[
'product_type' => 'simple',
'customer_is_guest' => 1,
'api_version' => 'v5'
],
[
'product_type' => 'configurable',
'customer_is_guest' => 1,
'api_version' => 'v5'
],
[
'product_type' => 'simple',
'customer_is_guest' => 0,
'api_version' => 'v5'
],
[
'product_type' => 'configurable',
'customer_is_guest' => 0,
'api_version' => 'v5'
]
];
}
public function getCallbackDataAddress($dataKey)
{
$address = [
'city' => 'Moscow',
'region' => 'Moscow',
'street' => 'Test street',
'postcode' => '111111',
'country_id' => 'RU'
];
return $address[$dataKey];
}
}

View File

@ -6,72 +6,62 @@
</tab>
<section id="retailcrm" translate="label" sortOrder="130" showInDefault="1" showInWebsite="1" showInStore="1">
<class>separator-top</class>
<label>Setting</label>
<label>Settings</label>
<tab>retailcrm</tab>
<resource>Retailcrm_Retailcrm::retailcrm_configuration</resource>
<group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General Configuration</label>
<label>Main settings</label>
<field id="api_url" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>API URL</label>
<comment>https://YourCrmName.retailcrm.ru</comment>
<backend_model>Retailcrm\Retailcrm\Model\Config\Backend\ApiUrl</backend_model>
</field>
<field id="api_key" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>API Key</label>
<comment>To generate an API Key, log in to RetailCRM then select Admin > Integration > API Keys</comment>
<label>API key</label>
<comment>You can create an API key in the administration section of retailCRM</comment>
</field>
<field id="api_version" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>API Version</label>
<label>API version</label>
<source_model>Retailcrm\Retailcrm\Model\Setting\ApiVersions</source_model>
<backend_model>Retailcrm\Retailcrm\Model\Config\Backend\ApiVersion</backend_model>
</field>
</group>
<group id="Misc" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Misc</label>
<group id="catalog" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Catalogue settings</label>
<field id="attributes_to_export_into_icml" translate="label" type="multiselect" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Attributes to export into icml</label>
<comment>Attributes to export into icml</comment>
<label>Attributes for uploading to ICML</label>
<comment>Select attributes which will be uploaded to ICML</comment>
<source_model>Retailcrm\Retailcrm\Model\Setting\Attribute</source_model>
</field>
</group>
<group id="shipping" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Shipping</label>
<label>Delivery types</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Shipping</frontend_model>
</group>
<group id="payment" translate="label comment" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment method</label>
<label>Payment types</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Payment</frontend_model>
</group>
<group id="status" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Order Status</label>
<label>Order statuses</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Status</frontend_model>
</group>
<group id="Load" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Order Load</label>
<group id="load" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Uploading orders</label>
<field id="number_order" translate="label" type="text" sortOrder="6" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Order number</label>
<comment>Enter your order number, separated by commas</comment>
<comment>Enter order numbers separated by a comma for uploading</comment>
</field>
<field id="button_order" translate="label comment" type="button" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Button</frontend_model>
</field>
</group>
<group id="site" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Site</label>
<label>Setting the store by default</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Site</frontend_model>
</group>
<group id="sites" translate="label" type="select" sortOrder="70" showInDefault="0" showInWebsite="1" showInStore="0">
<label>Sites</label>
<label>Setting the stores correspondence</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Sites</frontend_model>
</group>
</section>

View File

@ -8,4 +8,12 @@
<argument name="pathVersion" xsi:type="const">Retailcrm\Retailcrm\Api\ConfigManagerInterface::API_VERSION_PATH</argument>
</arguments>
</type>
<type name="Magento\Framework\Console\CommandList">
<arguments>
<argument name="commands" xsi:type="array">
<item name="orders_export_command" xsi:type="object">Retailcrm\Retailcrm\Console\Command\OrdersExport</item>
<item name="customers_export_command" xsi:type="object">Retailcrm\Retailcrm\Console\Command\CustomersExport</item>
</argument>
</arguments>
</type>
</config>

24
src/i18n/es_ES.csv Normal file
View File

@ -0,0 +1,24 @@
"Settings","La configuración"
"Main settings","La configuración general"
"API key","La llave API"
"You can create an API key in the administration section of retailCRM","Puede crear la llave API en la sección administrativa del retailCRM"
"API version","La versión API"
"Catalogue settings","La configuración del catálogo"
"Attributes for uploading to ICML","Los atributos para importar al ICML"
"Select attributes which will be uploaded to ICML","Seleccione los atributos que se importarán al ICML"
"Delivery types","Los métodos del envío"
"Payment types","Los métodos de pago"
"Order statuses","Los estados de pedidos"
"Uploading orders","La importación de los pedidos"
"Order number","El número del pedido"
"Enter order numbers separated by a comma for uploading","Introduce el número del pedido separado por coma para la importación"
"Setting the store by default","La configuración de la tienda por defecto"
"Setting the stores correspondence","La configuración de la concordancia de tienda"
"Enter API of your URL and API key","Introduce el enlace API y la llave API"
"Incorrect URL of retailCRM","La dirección del retailCRM es incorrecto"
"Make sure that the entered data is correct","Asegúrese de que los datos introducidos son correctos"
"Incorrect API key","La llave API es incorrecta"
"Incorrect URL of retailCRM or API key","La dirección del retailCRM o la llave API son incorrectos"
"The selected API version is unavailable","La versión de la API seleccionada no está disponible"
"Send","Enviar"
"Default site","Tienda por defecto"
1 Settings La configuración
2 Main settings La configuración general
3 API key La llave API
4 You can create an API key in the administration section of retailCRM Puede crear la llave API en la sección administrativa del retailCRM
5 API version La versión API
6 Catalogue settings La configuración del catálogo
7 Attributes for uploading to ICML Los atributos para importar al ICML
8 Select attributes which will be uploaded to ICML Seleccione los atributos que se importarán al ICML
9 Delivery types Los métodos del envío
10 Payment types Los métodos de pago
11 Order statuses Los estados de pedidos
12 Uploading orders La importación de los pedidos
13 Order number El número del pedido
14 Enter order numbers separated by a comma for uploading Introduce el número del pedido separado por coma para la importación
15 Setting the store by default La configuración de la tienda por defecto
16 Setting the stores correspondence La configuración de la concordancia de tienda
17 Enter API of your URL and API key Introduce el enlace API y la llave API
18 Incorrect URL of retailCRM La dirección del retailCRM es incorrecto
19 Make sure that the entered data is correct Asegúrese de que los datos introducidos son correctos
20 Incorrect API key La llave API es incorrecta
21 Incorrect URL of retailCRM or API key La dirección del retailCRM o la llave API son incorrectos
22 The selected API version is unavailable La versión de la API seleccionada no está disponible
23 Send Enviar
24 Default site Tienda por defecto

24
src/i18n/ru_RU.csv Normal file
View File

@ -0,0 +1,24 @@
"Settings","Настройки"
"Main settings","Главные настройки"
"API key","API ключ"
"You can create an API key in the administration section of retailCRM","Вы можете создать API ключ в административном разделе retailCRM"
"API version","Версия API"
"Catalogue settings","Настройки каталога"
"Attributes for uploading to ICML","Атрибуты для выгрузки в ICML"
"Select attributes which will be uploaded to ICML","Выберите атрибуты, которые будут выгружены в ICML"
"Delivery types","Способы доставки"
"Payment types","Способы оплаты"
"Order statuses","Статусы заказа"
"Uploading orders","Выгрузка заказов"
"Order number","Номер заказа"
"Enter order numbers separated by a comma for uploading","Введите номера заказов для выгрузки через запятую"
"Setting the store by default","Настройка магазина по умолчанию"
"Setting the stores correspondence","Настройка соответствия магазинов"
"Enter API of your URL and API key","Введите Ваш API URL и API ключ"
"Incorrect URL of retailCRM","Некорректный адрес retailCRM"
"Make sure that the entered data is correct","Убедитесь, что введенные данные верны"
"Incorrect API key","Некорректный API ключ"
"Incorrect URL of retailCRM or API key","Некорректный адрес retailCRM или API ключ"
"The selected API version is unavailable","Выбранная версия API недоступна"
"Send","Выгрузить"
"Default site","Сайт по умолчанию"
1 Settings Настройки
2 Main settings Главные настройки
3 API key API ключ
4 You can create an API key in the administration section of retailCRM Вы можете создать API ключ в административном разделе retailCRM
5 API version Версия API
6 Catalogue settings Настройки каталога
7 Attributes for uploading to ICML Атрибуты для выгрузки в ICML
8 Select attributes which will be uploaded to ICML Выберите атрибуты, которые будут выгружены в ICML
9 Delivery types Способы доставки
10 Payment types Способы оплаты
11 Order statuses Статусы заказа
12 Uploading orders Выгрузка заказов
13 Order number Номер заказа
14 Enter order numbers separated by a comma for uploading Введите номера заказов для выгрузки через запятую
15 Setting the store by default Настройка магазина по умолчанию
16 Setting the stores correspondence Настройка соответствия магазинов
17 Enter API of your URL and API key Введите Ваш API URL и API ключ
18 Incorrect URL of retailCRM Некорректный адрес retailCRM
19 Make sure that the entered data is correct Убедитесь, что введенные данные верны
20 Incorrect API key Некорректный API ключ
21 Incorrect URL of retailCRM or API key Некорректный адрес retailCRM или API ключ
22 The selected API version is unavailable Выбранная версия API недоступна
23 Send Выгрузить
24 Default site Сайт по умолчанию

View File

@ -1,19 +1,19 @@
<script>
require([
'jquery',
'prototype',
], function(jQuery){
function syncronize() {
params = {
};
var numbers = $('retailcrm_load_number_order').getValue();
new Ajax.Request('<?php echo $block->getAjaxSyncUrl() ?>', {
loaderArea: false,
loaderArea: true,
asynchronous: true,
parameters: params,
parameters: {numbers:numbers},
onSuccess: function(transport) {
var response = JSON.parse(transport.responseText);
if (transport.responseJSON.success === false) {
alert(transport.responseJSON.error);
}
}
});
}