1
0
Fork 0
mirror of synced 2025-04-19 08:51:00 +00:00

Compare commits

...

65 commits

Author SHA1 Message Date
Eugene Polozov
d7d1cc0d46 The module is marked as deprecated 2021-03-26 15:45:40 +03:00
opheugene
7b21d2c66b
Move to Github Actions 2021-01-30 15:37:57 +03:00
Eugene Polozov
b0d1b7c9fb Change version in magento composer 2020-12-23 15:59:43 +03:00
opheugene
2fb72e4fc0
Rebranding RetailCRM, fix tests 2020-12-23 15:27:23 +03:00
Eugene Polozov
f50a102cc8 Rebranding RetailCRM, fix tests 2020-12-23 10:54:39 +03:00
Akolzin Dmitry
e62591895d
update travis config (#32) 2020-05-18 16:34:25 +03:00
Evgeniy-Goroh
97a9e8b27c
Save config dinamic fields
* save config dinamic fields
* update test
2020-05-18 12:19:01 +03:00
Alex Lushpai
ae03c8c881
Remove unnecessary code
fixes #30
2020-04-16 12:04:10 +03:00
gorokh
966406a609 issues #30 removed unnecessary code 2020-04-07 18:16:09 +03:00
Alex Lushpai
c2c2fa0a95
Merge pull request #28 from Evgeniy-Goroh/master
fix test
2019-10-24 10:49:29 +03:00
gorokh
65e44090de fix test 2019-10-21 14:50:06 +03:00
Alex Lushpai
a314a47d70
Merge pull request #27 from gwinn/master
fix version & travis config
2019-10-17 15:08:23 +03:00
Alex Lushpai
cd1061dfd1 update php version for travis 2019-10-17 14:23:19 +03:00
Alex Lushpai
033817af84 fix version & travis config 2019-10-17 13:40:32 +03:00
Alex Lushpai
4e9c9c087e
Merge pull request #26 from Evgeniy-Goroh/master
Поддержка функции добавления одинакового товара в заказ как разные позиции
2019-10-17 13:36:05 +03:00
Alex Lushpai
43c3e5be80
Merge branch 'master' into master 2019-10-17 13:35:30 +03:00
Alex Lushpai
227b0eb827
Update .travis.yml 2019-10-17 13:15:24 +03:00
Alex Lushpai
56deb86d1c
Update VERSION 2019-10-17 13:11:00 +03:00
Alex Lushpai
2756b8e797
Update CHACNGELOG.md 2019-10-17 13:10:42 +03:00
Alex Lushpai
99ff83c83c
Update .travis.yml 2019-10-17 13:09:47 +03:00
gorokh
fc1e208b08 fix price 2019-10-01 14:40:42 +03:00
gorokh
06ddf9a807 Поддержка функции добавления одинакового товара в заказ как разные товарные позиции из CRM 2019-09-26 16:39:02 +03:00
Alex Lushpai
23602a7b71
Merge pull request #25 from iyzoer/master
Delete duplicate injection
2019-05-07 11:50:59 +03:00
Akolzin Dmitry
7b3b49e563 Fix test 2019-03-21 10:37:20 +03:00
Akolzin Dmitry
2ed36df9f1 Delete duplicate injection 2019-03-21 10:10:55 +03:00
Alex Lushpai
6e9629efef
Merge pull request #22 from sergeygw1990/master
v2.4.1
2019-02-14 13:23:14 +03:00
Sergey
3b97a7f06c v2.4.1 2019-02-12 15:35:53 +03:00
Alex Lushpai
fd2524b207
Merge pull request #21 from iyzoer/master
Fixes for marketplace
2019-01-24 16:11:07 +03:00
Akolzin Dmitry
ccb1a6e77d Fixes for marketplace 2019-01-24 16:01:09 +03:00
Alex Lushpai
86124b1978
Merge pull request #20 from sergeygw1990/master
v2.4.0
2019-01-24 14:33:56 +03:00
Sergey
950f00ac5c fix version change in composer.json 2019-01-24 13:40:33 +03:00
Sergey
6f47b16cbd fix Add constant inventories in src/Helper/Data.php 2019-01-24 12:34:09 +03:00
Sergey
a6d80bf154 v2.4.0 2019-01-24 11:39:40 +03:00
Alex Lushpai
b15f8ec5a8
Merge pull request #19 from iyzoer/master
Изменена логика передачи данных по заказам и клиентам
2019-01-23 13:46:36 +03:00
Akolzin Dmitry
2c8a87c582 Добавлены настройки Daemon Collector 2019-01-22 10:00:52 +03:00
Akolzin Dmitry
f4eca5a7b0 Изменена логика передачи данных по заказам и клиентам 2019-01-18 11:46:10 +03:00
Alex Lushpai
6dd54014ae
Merge pull request #18 from iyzoer/master
Выгрузка габаритов и веса в ICML
2019-01-16 10:36:27 +03:00
Akolzin Dmitry
6e66eb3aea Выгрузка габаритов и веса в ICML 2019-01-15 14:13:20 +03:00
Alex Lushpai
23bfe5c6fb
Merge pull request #17 from iyzoer/master
v2.3.2
2018-12-25 15:34:06 +03:00
Akolzin Dmitry
09090fdd5f v2.3.2 2018-12-25 15:07:54 +03:00
Alex Lushpai
5b6a9762d8
Merge pull request #16 from iyzoer/master
v2.3.1
2018-10-25 13:09:48 +03:00
Akolzin Dmitry
5ecedd12f0 Unit test update 2018-10-25 12:55:32 +03:00
Akolzin Dmitry
ef12474dfc Update changelog 2018-10-25 12:38:17 +03:00
Akolzin Dmitry
15da35916a Добавлена возможность создания нескольких модулей в маркетплейсе 2018-10-25 12:35:40 +03:00
Akolzin Dmitry
f47af54f1a Send to CRM activate/deactivate information in marketplace 2018-10-25 12:35:40 +03:00
Alex Lushpai
520ad44dce
Merge pull request #14 from iyzoer/master
Update version in composer.json
2018-08-31 12:54:14 +03:00
Akolzin Dmitry
c052dc2437 Update version in composer.json 2018-08-31 12:23:47 +03:00
Alex Lushpai
0ed0795be4
Merge pull request #13 from iyzoer/master
v2.3.0
2018-08-21 11:16:07 +03:00
Akolzin Dmitry
e93d2e2018 Update README, update tests 2018-08-21 10:47:31 +03:00
Akolzin Dmitry
cc995b83f5 v2.3.0 2018-08-21 10:19:08 +03:00
Alex Lushpai
9ef3f038c2
Update README.md 2018-06-18 14:02:20 +03:00
Alex Lushpai
2dd34395a3
Update VERSION 2018-06-14 13:19:00 +03:00
Alex Lushpai
9d402797fa
Update README.ru.md 2018-06-14 12:56:00 +03:00
Alex Lushpai
9ef2baf81d
Merge pull request #11 from iyzoer/master
Multisite, tests
2018-06-14 12:42:34 +03:00
Akolzin Dmitry
4cb74ededa
Update Makefile 2018-06-14 12:11:29 +03:00
Akolzin Dmitry
4c23faf1f4 Added script.sh, updated travis config 2018-05-15 16:44:45 +03:00
Akolzin Dmitry
7e7556fef3 Multisite, tests, travis 2018-05-15 15:54:55 +03:00
Akolzin Dmitry
6b83c72f93 Update system.xml 2018-05-11 10:04:51 +03:00
Akolzin Dmitry
364b12e6d4 Update travis.yml 2018-05-04 17:42:17 +03:00
Akolzin Dmitry
2d96fcc531 Update database name in install.sh 2018-05-04 17:14:06 +03:00
Akolzin Dmitry
5c8fa3ee01 Update magento install 2018-05-04 17:07:37 +03:00
Akolzin Dmitry
ad4b469548 Delete pass from install.sh 2018-05-04 17:03:31 +03:00
Akolzin Dmitry
0e40ad1b5f Tests, travis
Src directory
2018-05-04 16:27:45 +03:00
Akolzin Dmitry
3b6430cf7d Refactoring 2018-04-28 11:59:43 +03:00
Akolzin Dmitry
dd515492ab Readme 2018-04-28 11:59:43 +03:00
126 changed files with 7400 additions and 4994 deletions

234
.github/workflows/magento.yml vendored Normal file
View file

@ -0,0 +1,234 @@
# This is a basic workflow to help you get started with Actions
name: magento
on:
push:
branches:
- '**'
tags-ignore:
- '*.*'
pull_request:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- php-version: '7.0'
branch: '2.0.2'
coverage: 1
- php-version: '7.0'
branch: '2.0.4'
- php-version: '7.0'
branch: '2.0.5'
- php-version: '7.0'
branch: '2.0.6'
- php-version: '7.0'
branch: '2.0.7'
- php-version: '7.0'
branch: '2.0.8'
- php-version: '7.0'
branch: '2.0.9'
- php-version: '7.0'
branch: '2.0.10'
- php-version: '7.0'
branch: '2.0.11'
- php-version: '7.0'
branch: '2.0.12'
- php-version: '7.0'
branch: '2.0.13'
- php-version: '7.0'
branch: '2.0.14'
- php-version: '7.0'
branch: '2.0.15'
- php-version: '7.0'
branch: '2.0.16'
- php-version: '7.0'
branch: '2.0.17'
- php-version: '7.0'
branch: '2.0.18'
- php-version: '7.0'
branch: '2.1.0'
- php-version: '7.0'
branch: '2.1.1'
- php-version: '7.0'
branch: '2.1.2'
- php-version: '7.0'
branch: '2.1.3'
- php-version: '7.0'
branch: '2.1.4'
- php-version: '7.0'
branch: '2.1.5'
- php-version: '7.0'
branch: '2.1.6'
- php-version: '7.0'
branch: '2.1.7'
- php-version: '7.0'
branch: '2.1.8'
- php-version: '7.0'
branch: '2.1.9'
- php-version: '7.0'
branch: '2.1.10'
- php-version: '7.0'
branch: '2.1.11'
- php-version: '7.0'
branch: '2.1.12'
- php-version: '7.0'
branch: '2.1.13'
- php-version: '7.0'
branch: '2.1.14'
- php-version: '7.0'
branch: '2.1.15'
- php-version: '7.0'
branch: '2.1.16'
- php-version: '7.1'
branch: '2.1.16'
- php-version: '7.0'
branch: '2.1.17'
- php-version: '7.1'
branch: '2.1.17'
- php-version: '7.0'
branch: '2.1.18'
- php-version: '7.1'
branch: '2.1.18'
- php-version: '7.0'
branch: '2.2.0'
- php-version: '7.1'
branch: '2.2.0'
- php-version: '7.0'
branch: '2.2.1'
- php-version: '7.1'
branch: '2.2.1'
- php-version: '7.0'
branch: '2.2.2'
- php-version: '7.1'
branch: '2.2.2'
- php-version: '7.0'
branch: '2.2.3'
- php-version: '7.1'
branch: '2.2.3'
- php-version: '7.0'
branch: '2.2.4'
- php-version: '7.1'
branch: '2.2.4'
- php-version: '7.0'
branch: '2.2.5'
- php-version: '7.1'
branch: '2.2.5'
- php-version: '7.0'
branch: '2.2.6'
- php-version: '7.1'
branch: '2.2.6'
- php-version: '7.0'
branch: '2.2.7'
- php-version: '7.1'
branch: '2.2.7'
- php-version: '7.0'
branch: '2.2.8'
- php-version: '7.1'
branch: '2.2.8'
- php-version: '7.0'
branch: '2.2.9'
- php-version: '7.1'
branch: '2.2.9'
- php-version: '7.0'
branch: '2.2.10'
- php-version: '7.1'
branch: '2.2.10'
services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: root
ports:
- 3306/tcp
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5
steps:
- uses: actions/checkout@v2
- name: Setup PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: xdebug
tools: composer:v1, phpunit:6.4.3
extensions: gd, mbstring, zip, mcrypt, pdo_mysql, dom, soap, bcmath
- name: Start mysql service
run: sudo /etc/init.d/mysql start
- name: Status mysql service
run: sudo systemctl status mysql
- name: Install Magento
env:
BRANCH: ${{ matrix.branch }}
PUBLIC_KEY: ${{ secrets.PUBLIC_KEY}}
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY}}
run: make before_script
- name: Run tests
run: make test
- name: Coverage
env:
COVERAGE: ${{ matrix.coverage }}
if: env.COVERAGE == 1
run: |
make coverage
bash <(curl -s https://codecov.io/bash)
deploy:
needs: ['test']
if: success() && github.event_name == 'push' && github.repository_owner == 'retailcrm' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup PHP 7.2
uses: shivammathur/setup-php@v2
with:
php-version: '7.2'
tools: composer:v1
- name: Build release
run: |
git fetch origin --unshallow --tags
export LAST_TAG=`git describe --abbrev=0 --tags`
export VERSION=`cat VERSION`
export ARCHIVE_NAME=retailcrm-$VERSION.ocmod.zip
export ARCHIVE_PATH="/tmp/$ARCHIVE_NAME"
export RELEASE_TAG=v$VERSION
export LAST_COMMIT=`git log --oneline --format=%B -n 1 HEAD | head -n 1`
echo RELEASE_TAG=$RELEASE_TAG >> $GITHUB_ENV
echo LAST_TAG=$LAST_TAG >> $GITHUB_ENV
echo LAST_COMMIT=$LAST_COMMIT >> $GITHUB_ENV
echo ARCHIVE_PATH=$ARCHIVE_PATH >> $GITHUB_ENV
echo ARCHIVE_NAME=$ARCHIVE_NAME >> $GITHUB_ENV
make build_archive
- name: Create Release
id: create_release
uses: actions/create-release@v1
if: env.LAST_TAG != env.RELEASE_TAG
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
with:
tag_name: ${{ env.RELEASE_TAG }}
release_name: ${{ env.RELEASE_TAG }}
body: ${{ env.LAST_COMMIT }}
draft: false
prerelease: false
- name: Cleanup
if: env.LAST_TAG != env.RELEASE_TAG
run: make delete_archive

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/nbproject/private/
.idea

View file

@ -1,63 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Attributes extends \Magento\Config\Block\System\Config\Form\Field
{
protected function _getElementHtml(AbstractElement $element)
{
$values = $element->getValues();
$html = '<table id="' . $element->getId() . '_table" class="ui_select_table" cellspacing="0">';
$html .= '<tbody><tr>';
$html .= '<td><ul id="' . $element->getId() . '_selected" class="ui_select selected sortable">';
$selected = explode(',', $element->getValue());
foreach ($selected as $value) {
if ($key = array_search($value, array_column($values, 'value'))) {
$html .= '<li value="' . $value . '" title="' . $values[$key]['title'] . '">';
$html .= isset($values[$key]['label'])?$values[$key]['label']:'n/a';
$html .= '</li>';
$values[$key]['selected'] = TRUE;
}
}
$html .= '</ul></td><td>';
$html .= '<ul id="' . $element->getId() . '_source" class="ui_select source sortable">';
if ($values) {
foreach ($values as $option) {
if (!isset($option['selected'])) {
$html .= '<li value="' . $option['value'] . '" title="' . $option['title'] . '">';
$html .= isset($option['label'])?$option['label']:'n/a';
$html .= '</li>';
}
}
}
$html .= '</ul></td></tr></tbody></table>';
$html .= '<div style="display:none;">' . $element->getElementHtml() . '</div>';
$html .= '<script type="text/javascript">
require(["jquery"], function(jQuery){
require(["BelVG_Pricelist/js/verpage", "ui/1.11.4"], function(){
jQuery(document).ready( function() {
jQuery("#' . $element->getId() . '_selected, #' . $element->getId() . '_source").sortable({
connectWith: ".sortable",
stop: function(event, ui) {
var vals = [];
jQuery("#' . $element->getId() . '_selected").find("li").each(function(index, element){
vals.push(jQuery(element).val());
});
jQuery("#' . $element->getId() . '").val(vals);
}
}).disableSelection();
});
})
})
</script>';
return $html;
}
}

View file

@ -1,72 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field;
class Base extends \Magento\Framework\Model\AbstractModel
{
public $_apiKey;
public $_apiUrl;
public $_isCredentialCorrect;
protected $logger;
protected $_cacheTypeList;
protected $_resourceConfig;
public function __construct()
{
$om = \Magento\Framework\App\ObjectManager::getInstance();
$config = $om->get('\Magento\Framework\App\Config\ScopeConfigInterface');
$logger = $om->get('\Psr\Log\LoggerInterface');
$cacheTypeList = $om->get('\Magento\Framework\App\Cache\TypeListInterface');
$resourceConfig = $om->get('Magento\Config\Model\ResourceModel\Config');
$this->_resourceConfig = $resourceConfig;
$this->_cacheTypeList = $cacheTypeList;
$this->logger = $logger;
$this->_apiUrl = $config->getValue('retailcrm/general/api_url');
$this->_apiKey = $config->getValue('retailcrm/general/api_key');
$this->_isCredentialCorrect = false;
if (!empty($this->_apiUrl) && !empty($this->_apiKey)) {
if (false === stripos($this->_apiUrl, 'https://')) {
$this->_apiUrl = str_replace("http://", "https://", $this->_apiUrl);
$this->_resourceConfig->saveConfig('retailcrm/general/api_url', $this->_apiUrl, 'default', 0);
$this->_cacheTypeList->cleanType('config');
}
if (!$this->is_url($this->_apiUrl)){
echo 'URL not valid<br>';
echo 'Please check your Url and Reload page<br>';
$this->_resourceConfig->saveConfig('retailcrm/general/api_url', '', 'default', 0);
$this->_cacheTypeList->cleanType('config');
}
$client = new \Retailcrm\Retailcrm\Model\ApiClient\ApiClient(
$this->_apiUrl,
$this->_apiKey
);
try {
$response = $client->sitesList();
} catch (\Retailcrm\Retailcrm\Model\ApiClient\Exception\CurlException $e) {
$this->_logger->addDebug($e->getMessage());
}
if ($response->isSuccessful()) {
$this->_isCredentialCorrect = true;
if($response['success'] != 1) {
$this->_resourceConfig->saveConfig('retailcrm/general/api_url', '', 'default', 0);
$this->_cacheTypeList->cleanType('config');
}
}
}
}
public function is_url($url) {
return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
}
}

View file

@ -1,16 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\ListMode;
class ListMode implements \Magento\Framework\Option\ArrayInterface
{
public function toOptionArray()
{
return [
['value' => 'grid', 'label' => __('Grid Only')],
['value' => 'list', 'label' => __('List Only')],
['value' => 'grid-list', 'label' => __('Grid (default) / List')],
['value' => 'list-grid', 'label' => __('List (default) / Grid')]
];
}
}

View file

@ -1,87 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class Payment extends \Magento\Config\Block\System\Config\Form\Field
{
protected $_apiUrl;
protected $_apiKey;
protected $_systemStore;
protected $_formFactory;
protected $_logger;
public function __construct(
\Magento\Framework\Data\FormFactory $formFactory,
\Magento\Store\Model\System\Store $systemStore
) {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$config = $objectManager->get('\Magento\Framework\App\Config\ScopeConfigInterface');
$this->_apiUrl = $config->getValue('retailcrm/general/api_url');
$this->_apiKey = $config->getValue('retailcrm/general/api_key');
$this->_apiVersion = $config->getValue('retailcrm/general/api_version');
$this->_systemStore = $systemStore;
$this->_formFactory = $formFactory;
}
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
if ((!empty($this->_apiUrl)) && (!empty($this->_apiKey))) {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$paymentConfig = $objectManager->get('Magento\Payment\Model\Config');
$activePaymentMethods = $paymentConfig->getActiveMethods();
$client = new ApiClient($this->_apiUrl, $this->_apiKey, $this->_apiVersion);
$response = $client->paymentTypesList();
if ($response === false) {
return $htmlError;
}
if ($response->isSuccessful()) {
$paymentTypes = $response['paymentTypes'];
} else {
return $htmlError;
}
$config = \Magento\Framework\App\ObjectManager::getInstance()->get(
'Magento\Framework\App\Config\ScopeConfigInterface'
);
foreach (array_keys($activePaymentMethods) as $k=>$payment){
$html .='<table id="' . $element->getId() . '_table">';
$html .='<tr id="row_retailcrm_payment_'.$payment.'">';
$html .='<td class="label">'.$payment.'</td>';
$html .='<td>';
$html .='<select id="1" name="groups[Payment][fields]['.$payment.'][value]">';
$selected = $config->getValue('retailcrm/Payment/' . $payment);
foreach ($paymentTypes as $k => $value){
if ((!empty($selected)) && (($selected == $value['code']))) {
$select = 'selected="selected"';
}else{
$select = '';
}
$html .= '<option '.$select.' value="'.$value['code'].'"> '.$value['name'].'</option>';
}
$html .= '</select>';
$html .= '</td>';
$html .= '</tr>';
$html .= '</table>';
}
return $html;
} else {
return $htmlError;
}
}
}

View file

@ -1,88 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class Shipping extends \Magento\Config\Block\System\Config\Form\Field
{
protected $_apiUrl;
protected $_apiKey;
protected $_systemStore;
protected $_formFactory;
protected $_logger;
protected $_objectManager;
public function __construct(
\Magento\Framework\Data\FormFactory $formFactory,
\Magento\Store\Model\System\Store $systemStore
) {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$config = $objectManager->get('\Magento\Framework\App\Config\ScopeConfigInterface');
$this->_apiUrl = $config->getValue('retailcrm/general/api_url');
$this->_apiKey = $config->getValue('retailcrm/general/api_key');
$this->_apiVersion = $config->getValue('retailcrm/general/api_version');
$this->_systemStore = $systemStore;
$this->_formFactory = $formFactory;
$this->_objectManager = $objectManager;
}
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
if (!empty($this->_apiUrl) && !empty($this->_apiKey)) {
$shipConfig = $this->_objectManager->get('Magento\Shipping\Model\Config');
$deliveryMethods = $shipConfig->getActiveCarriers();
$client = new ApiClient($this->_apiUrl, $this->_apiKey, $this->_apiVersion);
$response = $client->deliveryTypesList();
if ($response === false) {
return $htmlError;
}
if ($response->isSuccessful()) {
$deliveryTypes = $response['deliveryTypes'];
} else {
return $htmlError;
}
$config = \Magento\Framework\App\ObjectManager::getInstance()->get(
'Magento\Framework\App\Config\ScopeConfigInterface'
);
foreach (array_keys($deliveryMethods) as $k => $delivery) {
$html .='<table id="' . $element->getId() . '_table">';
$html .='<tr id="row_retailcrm_shipping_'.$delivery.'">';
$html .='<td class="label">'.$delivery.'</td>';
$html .='<td>';
$html .='<select id="1" name="groups[Shipping][fields]['.$delivery.'][value]">';
$selected = $config->getValue('retailcrm/Shipping/'.$delivery);
foreach ($deliveryTypes as $k => $value) {
if ((!empty($selected)) && (($selected == $value['code']))) {
$select ='selected="selected"';
}else{
$select ='';
}
$html .='<option '.$select.' value="'.$value['code'].'"> '.$value['name'].'</option>';
}
$html .='</select>';
$html .='</td>';
$html .='</tr>';
$html .='</table>';
}
return $html;
} else {
return $htmlError;
}
}
}

View file

@ -1,91 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class Status extends \Magento\Config\Block\System\Config\Form\Field
{
protected $_apiUrl;
protected $_apiKey;
protected $_systemStore;
protected $_formFactory;
protected $_logger;
protected $_objectManager;
public function __construct(
\Magento\Framework\Data\FormFactory $formFactory,
\Magento\Store\Model\System\Store $systemStore
) {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$config = $objectManager->get('\Magento\Framework\App\Config\ScopeConfigInterface');
$this->_apiUrl = $config->getValue('retailcrm/general/api_url');
$this->_apiKey = $config->getValue('retailcrm/general/api_key');
$this->_apiVersion = $config->getValue('retailcrm/general/api_version');
$this->_systemStore = $systemStore;
$this->_formFactory = $formFactory;
$this->_objectManager = $objectManager;
}
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
if ((!empty($this->_apiUrl)) && (!empty($this->_apiKey))) {
$statusCollection = $this->_objectManager->create('Magento\Sales\Model\ResourceModel\Order\Status\Collection');
$statuses = $statusCollection->toOptionArray();
$client = new ApiClient($this->_apiUrl, $this->_apiKey, $this->_apiVersion);
$response = $client->statusesList();
if ($response === false) {
return $htmlError;
}
if ($response->isSuccessful()) {
$statusTypes = $response['statuses'];
} else {
return $htmlError;
}
$config = $this->_objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface');
foreach ($statuses as $k => $status){
$html .= '<table id="' . $element->getId() . '_table">';
$html .= '<tr id="row_retailcrm_status_' . $status['label'] . '">';
$html .= '<td class="label">' . $status['label'] . '</td>';
$html .= '<td>';
$html .= '<select name="groups[Status][fields][' . $status['value'] . '][value]">';
$selected = $config->getValue('retailcrm/Status/' . $status['value']);
$html .= '<option value=""> Select status </option>';
foreach ($statusTypes as $k => $value){
if (
(!empty($selected))
&& (($selected == $value['name']))
|| (($selected == $value['code']))
) {
$select = 'selected="selected"';
} else {
$select = '';
}
$html .= '<option ' . $select . 'value="' . $value['code'] . '"> ' . $value['name'] . '</option>';
}
$html .= '</select>';
$html .= '</td>';
$html .= '</tr>';
$html .= '</table>';
}
return $html;
} else {
return $htmlError;
}
}
}

View file

@ -1,16 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Block;
class Display extends \Magento\Framework\View\Element\Template
{
public function __construct(\Magento\Framework\View\Element\Template\Context $context)
{
parent::__construct($context);
}
public function sayHello()
{
return __('Hello World');
}
}

30
CHANGELOG.md Normal file
View file

@ -0,0 +1,30 @@
## 2021-01-30 v.2.5.2
* Переход на GitHub Actions
## 2020-12-17 v.2.5.1
* Ребрендинг RetailCRM
## 2018-12-25 v.2.5.0
* Поддержка передачи в заказе нескольких позиций одного товара
## 2018-12-25 v.2.4.1
* Удалена генерация externalId покупателя при заказе от незарегестрированного пользователя
## 2018-12-25 v.2.4.0
* Добавлен функционал получения остатков из RetailCRM
## 2018-12-25 v.2.3.2
* Добавлена выгрузка картинок категорий товаров в ICML
## 2018-10-25 v.2.3.1
* Добавлена активация модуля в маркетплейсе RetailCRM
## 2018-08-21 v.2.3.0
* Добавлены консольные команды для выгрузки архива клиентов и заказов
* Обработка данных для формирования структуры перед отправкой вынесена в сервисы
* Теперь при ручной выгрузке заказов из админки не нужно сохранять номера заказов
* ICML каталог теперь формируется для каждого сайта
* При формировании каталога выгружаются выбранные атрибуты товаров
* Улучшена выгрузка товаров в заказе (теперь учитываются конфигурируемые товары)
* Добавлены переводы на русский и испанский языки
* Из обработки истории удален менеджер объектов

View file

@ -1,30 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Controller\Adminhtml\System\Config;
class Button extends \Magento\Backend\App\Action
{
/**
* @var \Psr\Log\LoggerInterface
*/
protected $_logger;
/**
* @param \Magento\Backend\App\Action\Context $context
* @param \Psr\Log\LoggerInterface $logger
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Psr\Log\LoggerInterface $logger
) {
$this->_logger = $logger;
parent::__construct($context);
}
public function execute()
{
$order = new \Retailcrm\Retailcrm\Model\Order\OrderNumber();
$order->ExportOrderNumber();
}
}

View file

@ -1,36 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Controller\Index;
use Magento\Framework\App\Helper\Context;
use Psr\Log\LoggerInterface;
class Test extends \Magento\Framework\App\Action\Action
{
protected $logger;
public function __construct(
LoggerInterface $logger,
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Page\Config $pageConfig,
\Magento\Framework\App\Config\ScopeConfigInterface $config
) {
$this->logger = $logger;
$api_url = $config->getValue('retailcrm/general/api_url');
$api_key = $config->getValue('retailcrm/general/api_key');
var_dump($api_key);
var_dump($api_url);
//$this->logger->debug($api_url);
parent::__construct($context);
}
public function execute()
{
//
exit;
}
}

View file

@ -1,19 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Cron;
class Icml {
protected $_logger;
public function __construct() {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$logger = new \Retailcrm\Retailcrm\Model\Logger\Logger($objectManager);
$this->_logger = $logger;
}
public function execute()
{
$Icml = new \Retailcrm\Retailcrm\Model\Icml\Icml();
$Icml->generate();
}
}

View file

@ -1,23 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Cron;
class OrderHistory
{
protected $_logger;
public function __construct()
{
$om = \Magento\Framework\App\ObjectManager::getInstance();
$logger = new \Retailcrm\Retailcrm\Model\Logger\Logger($om);
$this->_logger = $logger;
}
public function execute()
{
$history = new \Retailcrm\Retailcrm\Model\History\Exchange();
$history->ordersHistory();
$this->_logger->writeRow('Cron Works: OrderHistory');
}
}

View file

@ -1,68 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\ScopeInterface;
class Data extends AbstractHelper
{
protected $storeManager;
protected $objectManager;
const XML_PATH_RETAILCRM = 'retailcrm/';
public function __construct(Context $context,
ObjectManagerInterface $objectManager,
StoreManagerInterface $storeManager
) {
$this->objectManager = $objectManager;
$this->storeManager = $storeManager;
parent::__construct($context);
}
public function getConfigValue($field, $storeId = null)
{
return $this->scopeConfig->getValue(
$field, ScopeInterface::SCOPE_STORE, $storeId
);
}
public function getGeneralConfig($code, $storeId = null)
{
return $this->getConfigValue(self::XML_PATH_RETAILCRM . $code, $storeId);
}
/**
* Recursive array filter
*
* @param array $haystack input array
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.ElseExpression)
*
* @return array
*/
public function filterRecursive($haystack)
{
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = self::filterRecursive($haystack[$key]);
}
if (is_null($haystack[$key])
|| $haystack[$key] === ''
|| count($haystack[$key]) == 0
) {
unset($haystack[$key]);
} elseif (!is_array($value)) {
$haystack[$key] = trim($value);
}
}
return $haystack;
}
}

View file

@ -1,81 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Helper;
use RetailCrm\ApiClient;
use Magento\Framework\App\ObjectManager;
use Retailcrm\Retailcrm\Model\Logger\Logger;
class Proxy
{
protected $logger;
protected $apiClient;
private $errorAccount = 'Account does not exist.';
private $errorNotFound = 'Not found';
private $errorApiKey = 'Wrong "apiKey" value.';
public function __construct ($url, $key, $apiVersion)
{
$objectManager = ObjectManager::getInstance();
$this->logger = new Logger($objectManager);
$this->apiClient = new ApiClient($url, $key, $apiVersion);
}
public function __call($method, $arguments)
{
try {
$response = call_user_func_array([$this->apiClient->request, $method], $arguments);
if (!$response->isSuccessful()) {
$this->logger->writeRow(
sprintf(
"[HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
$this->logger->writeRow(implode(' :: ', $response['errors']));
}
}
} catch (\RetailCrm\Exception\CurlException $exception) {
$this->logger->writeRow($exception->getMessage());
return false;
} catch (\RetailCrm\Exception\InvalidJsonException $exception) {
$this->logger->writeRow($exception->getMessage());
return false;
} catch (\InvalidArgumentException $exception) {
$this->logger->writeRow($exception->getMessage());
}
return $response;
}
/**
* Get API version
*
* @return string
*/
public function getVersion()
{
if (!is_object($this->apiClient)) {
return false;
}
return $this->apiClient->getVersion();
}
/**
* Get error text message
*
* @param string $property
*
* @return string
*/
public function getErrorText($property)
{
return $this->{$property};
}
}

24
Makefile Normal file
View file

@ -0,0 +1,24 @@
export ROOT_DIR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
VERSION = `cat $(FILE)`
ARCHIVE_NAME = '/tmp/retailcrm-retailcrm-'$(VERSION)'.zip'
MAGE_ROOT=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/../magento2
.PHONY: build_archive delete_archive
build_archive:
cd src; zip -r $(ARCHIVE_NAME) ./*
delete_archive:
rm -f $(ARCHIVE_NAME)
test:
mkdir coverage
php $(MAGE_ROOT)/vendor/phpunit/phpunit/phpunit -c $(MAGE_ROOT)/dev/tests/unit/phpunit.xml.dist $(MAGE_ROOT)/app/code/Retailcrm/Retailcrm/Test/Unit
before_script:
bash bin/install.sh
coverage:
wget https://phar.phpunit.de/phpcov-2.0.2.phar && php phpcov-2.0.2.phar merge coverage/ --clover coverage.xml

File diff suppressed because it is too large Load diff

View file

@ -1,30 +0,0 @@
<?php
/**
* PHP version 5.3
*
* Class CurlException
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
namespace Retailcrm\Retailcrm\Model\ApiClient\Exception;
/**
* PHP version 5.3
*
* Class CurlException
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
class CurlException extends \RuntimeException
{
}

View file

@ -1,30 +0,0 @@
<?php
/**
* PHP version 5.3
*
* Class InvalidJsonException
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
namespace Retailcrm\Retailcrm\Model\ApiClient\Exception;
/**
* PHP version 5.3
*
* Class InvalidJsonException
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
class InvalidJsonException extends \DomainException
{
}

View file

@ -1,128 +0,0 @@
<?php
/**
* PHP version 5.3
*
* HTTP client
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
namespace Retailcrm\Retailcrm\Model\ApiClient\Http;
use Retailcrm\Retailcrm\Model\ApiClient\Exception\CurlException;
use Retailcrm\Retailcrm\Model\ApiClient\Exception\InvalidJsonException;
use Retailcrm\Retailcrm\Model\ApiClient\Response\ApiResponse;
/**
* PHP version 5.3
*
* HTTP client
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
class Client
{
const METHOD_GET = 'GET';
const METHOD_POST = 'POST';
protected $url;
protected $defaultParameters;
/**
* Client constructor.
*
* @param string $url api url
* @param array $defaultParameters array of parameters
*
* @throws \InvalidArgumentException
*/
public function __construct($url, array $defaultParameters = array())
{
if (false === stripos($url, 'https://')) {
throw new \InvalidArgumentException(
'API schema requires HTTPS protocol'
);
}
$this->url = $url;
$this->defaultParameters = $defaultParameters;
}
/**
* Make HTTP request
*
* @param string $path request url
* @param string $method (default: 'GET')
* @param array $parameters (default: array())
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*
* @throws \InvalidArgumentException
* @throws CurlException
* @throws InvalidJsonException
*
* @return ApiResponse
*/
public function makeRequest(
$path,
$method,
array $parameters = array()
) {
$allowedMethods = array(self::METHOD_GET, self::METHOD_POST);
if (!in_array($method, $allowedMethods, false)) {
throw new \InvalidArgumentException(
sprintf(
'Method "%s" is not valid. Allowed methods are %s',
$method,
implode(', ', $allowedMethods)
)
);
}
$parameters = array_merge($this->defaultParameters, $parameters);
$url = $this->url . $path;
if (self::METHOD_GET === $method && count($parameters)) {
$url .= '?' . http_build_query($parameters, '', '&');
}
$curlHandler = curl_init();
curl_setopt($curlHandler, CURLOPT_URL, $url);
curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlHandler, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curlHandler, CURLOPT_FAILONERROR, false);
curl_setopt($curlHandler, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curlHandler, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curlHandler, CURLOPT_TIMEOUT, 30);
curl_setopt($curlHandler, CURLOPT_CONNECTTIMEOUT, 30);
if (self::METHOD_POST === $method) {
curl_setopt($curlHandler, CURLOPT_POST, true);
curl_setopt($curlHandler, CURLOPT_POSTFIELDS, $parameters);
}
$responseBody = curl_exec($curlHandler);
$statusCode = curl_getinfo($curlHandler, CURLINFO_HTTP_CODE);
$errno = curl_errno($curlHandler);
$error = curl_error($curlHandler);
curl_close($curlHandler);
if ($errno) {
throw new CurlException($error, $errno);
}
return new ApiResponse($statusCode, $responseBody);
}
}

View file

@ -1,180 +0,0 @@
<?php
/**
* PHP version 5.3
*
* Response from retailCRM API
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
namespace Retailcrm\Retailcrm\Model\ApiClient\Response;
use Retailcrm\Retailcrm\Model\ApiClient\Exception\InvalidJsonException;
/**
* PHP version 5.3
*
* Response from retailCRM API
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
class ApiResponse implements \ArrayAccess
{
// HTTP response status code
protected $statusCode;
// response assoc array
protected $response;
/**
* ApiResponse constructor.
*
* @param int $statusCode HTTP status code
* @param mixed $responseBody HTTP body
*
* @throws InvalidJsonException
*/
public function __construct($statusCode, $responseBody = null)
{
$this->statusCode = (int) $statusCode;
if (!empty($responseBody)) {
$response = json_decode($responseBody, true);
if (!$response && JSON_ERROR_NONE !== ($error = json_last_error())) {
throw new InvalidJsonException(
"Invalid JSON in the API response body. Error code #$error",
$error
);
}
$this->response = $response;
}
}
/**
* Return HTTP response status code
*
* @return int
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* HTTP request was successful
*
* @return bool
*/
public function isSuccessful()
{
return $this->statusCode < 400;
}
/**
* Allow to access for the property throw class method
*
* @param string $name method name
* @param mixed $arguments method parameters
*
* @throws \InvalidArgumentException
*
* @return mixed
*/
public function __call($name, $arguments)
{
// convert getSomeProperty to someProperty
$propertyName = strtolower(substr($name, 3, 1)) . substr($name, 4);
if (!isset($this->response[$propertyName])) {
throw new \InvalidArgumentException("Method \"$name\" not found");
}
return $this->response[$propertyName];
}
/**
* Allow to access for the property throw object property
*
* @param string $name property name
*
* @throws \InvalidArgumentException
*
* @return mixed
*/
public function __get($name)
{
if (!isset($this->response[$name])) {
throw new \InvalidArgumentException("Property \"$name\" not found");
}
return $this->response[$name];
}
/**
* Offset set
*
* @param mixed $offset offset
* @param mixed $value value
*
* @throws \BadMethodCallException
* @return void
*/
public function offsetSet($offset, $value)
{
throw new \BadMethodCallException('This activity not allowed');
}
/**
* Offset unset
*
* @param mixed $offset offset
*
* @throws \BadMethodCallException
* @return void
*/
public function offsetUnset($offset)
{
throw new \BadMethodCallException('This call not allowed');
}
/**
* Check offset
*
* @param mixed $offset offset
*
* @return bool
*/
public function offsetExists($offset)
{
return isset($this->response[$offset]);
}
/**
* Get offset
*
* @param mixed $offset offset
*
* @throws \InvalidArgumentException
*
* @return mixed
*/
public function offsetGet($offset)
{
if (!isset($this->response[$offset])) {
throw new \InvalidArgumentException("Property \"$offset\" not found");
}
return $this->response[$offset];
}
}

View file

@ -1,312 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Model\Icml;
class Icml
{
protected $_dd;
protected $_eCategories;
protected $_eOffers;
protected $_shop;
protected $_manager;
protected $_category;
protected $_product;
protected $_storeManager;
protected $_StockState;
protected $_configurable;
protected $_config;
public function __construct()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$manager = $objectManager->get('Magento\Store\Model\StoreManagerInterface');
$categoryCollectionFactory = $objectManager->get('\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory');
$product = $objectManager->get('\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$StockState = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
$configurable = $objectManager->get('Magento\ConfigurableProduct\Model\Product\Type\Configurable');
$config = $objectManager->get('\Magento\Framework\App\Config\ScopeConfigInterface');
$this->_configurable = $configurable;
$this->_StockState = $StockState;
$this->_storeManager = $storeManager;
$this->_product = $product;
$this->_category = $categoryCollectionFactory;
$this->_manager = $manager;
$this->_config = $config;
}
public function generate()
{
$this->_shop = $this->_manager->getStore()->getId();
$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>
<categories/>
<offers/>
</shop>
</yml_catalog>
';
$xml = new \SimpleXMLElement(
$string,
LIBXML_NOENT | LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE
);
$this->_dd = new \DOMDocument();
$this->_dd->preserveWhiteSpace = false;
$this->_dd->formatOutput = true;
$this->_dd->loadXML($xml->asXML());
$this->_eCategories = $this->_dd->
getElementsByTagName('categories')->item(0);
$this->_eOffers = $this->_dd
->getElementsByTagName('offers')->item(0);
$this->addCategories();
$this->addOffers();
$this->_dd->saveXML();
$dirlist = new \Magento\Framework\Filesystem\DirectoryList('');
$baseDir = $dirlist->getRoot();
$shopCode = $this->_manager->getStore()->getCode();
$this->_dd->save($baseDir . 'retailcrm_' . $shopCode . '.xml');
}
private function addCategories()
{
$collection = $this->_category->create();
$collection->addAttributeToSelect('*');
foreach ($collection as $category) {
if ($category->getId() > 1){
$e = $this->_eCategories->appendChild(
$this->_dd->createElement('category')
);
$e->appendChild($this->_dd->createTextNode($category->getName()));
$e->setAttribute('id', $category->getId());
if ($category->getParentId() > 1) {
$e->setAttribute('parentId', $category->getParentId());
}
}
}
}
private function addOffers()
{
$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);
$baseUrl = $this->_storeManager->getStore()->getBaseUrl();
$customAdditionalAttributes = [];
$customAdditionalAttributes = $this->_config->getValue('retailcrm/Misc/attributes_to_export_into_icml');
foreach ($collection as $product) {
if ($product->getTypeId() == 'simple') {
$offer['id'] = $product->getId();
$offer['productId'] = $product->getId();
$offer['productActivity'] = $product->isAvailable() ? 'Y' : 'N';
$offer['name'] = $product->getName();
$offer['productName'] = $product->getName();
$offer['initialPrice'] = $product->getFinalPrice();
$offer['url'] = $product->getProductUrl();
$offer['picture'] = $picUrl.'catalog/product'.$product->getImage();
$offer['quantity'] = $this->_StockState->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
$offer['categoryId'] = $product->getCategoryIds();
$offer['vendor'] = $product->getAttributeText('manufacturer');
$offer['params'] = [];
$article = $product->getSku();
if(!empty($article)) {
$offer['params'][] = [
'name' => 'Article',
'code' => 'article',
'value' => $article
];
}
$weight = $product->getWeight();
if(!empty($weight)) {
$offer['params'][] = [
'name' => 'Weight',
'code' => 'weight',
'value' => $weight
];
}
if(!empty($customAdditionalAttributes)) {
//var_dump($customAdditionalAttributes);
}
$offers[] = $offer;
}
if ($product->getTypeId() == 'configurable') {
$associated_products = $this->_configurable
->getUsedProductCollection($product)
->addAttributeToSelect('*')
->addFilterByRequiredOptions();
foreach ($associated_products as $associatedProduct) {
$offer['id'] = $associatedProduct->getId();
$offer['productId'] = $product->getId();
$offer['productActivity'] = $associatedProduct->isAvailable() ? 'Y' : 'N';
$offer['name'] = $associatedProduct->getName();
$offer['productName'] = $product->getName();
$offer['initialPrice'] = $associatedProduct->getFinalPrice();
$offer['url'] = $product->getProductUrl();
$offer['picture'] = $picUrl.'catalog/product'.$associatedProduct->getImage();
$offer['quantity'] = $this->_StockState->getStockQty($associatedProduct->getId(), $associatedProduct->getStore()->getWebsiteId());
$offer['categoryId'] = $associatedProduct->getCategoryIds();
$offer['vendor'] = $associatedProduct->getAttributeText('manufacturer');
$offer['params'] = [];
$article = $associatedProduct->getSku();
if ($associatedProduct->getResource()->getAttribute('color')) {
$colorAttribute = $associatedProduct->getResource()->getAttribute('color');
$color = $colorAttribute->getSource()->getOptionText($associatedProduct->getColor());
}
if (isset($color)) {
$offer['params'][] = [
'name' => 'Color',
'code' => 'color',
'value' => $color
];
}
if ($associatedProduct->getResource()->getAttribute('size')) {
$sizeAttribute = $associatedProduct->getResource()->getAttribute('size');
$size = $sizeAttribute->getSource()->getOptionText($associatedProduct->getSize());
}
if (isset($size)) {
$offer['params'][] = [
'name' => 'Size',
'code' => 'size',
'value' => $size
];
}
if (!empty($article)) {
$offer['params'][] = [
'name' => 'Article',
'code' => 'article',
'value' => $article
];
}
$weight = $associatedProduct->getWeight();
if(!empty($weight)) {
$offer['params'][] = [
'name' => 'Weight',
'code' => 'weight',
'value' => $weight
];
}
$offers[] = $offer;
}
}
}
foreach ($offers as $offer) {
$e = $this->_eOffers->appendChild(
$this->_dd->createElement('offer')
);
$e->setAttribute('id', $offer['id']);
$e->setAttribute('productId', $offer['productId']);
if (!empty($offer['quantity'])) {
$e->setAttribute('quantity', (int) $offer['quantity']);
} else {
$e->setAttribute('quantity', 0);
}
if (!empty($offer['categoryId'])) {
foreach ($offer['categoryId'] as $categoryId) {
$e->appendChild(
$this->_dd->createElement('categoryId')
)->appendChild(
$this->_dd->createTextNode($categoryId)
);
}
} else {
$e->appendChild($this->_dd->createElement('categoryId', 1));
}
$e->appendChild($this->_dd->createElement('productActivity'))
->appendChild(
$this->_dd->createTextNode($offer['productActivity'])
);
$e->appendChild($this->_dd->createElement('name'))
->appendChild(
$this->_dd->createTextNode($offer['name'])
);
$e->appendChild($this->_dd->createElement('productName'))
->appendChild(
$this->_dd->createTextNode($offer['productName'])
);
$e->appendChild($this->_dd->createElement('price'))
->appendChild(
$this->_dd->createTextNode($offer['initialPrice'])
);
if (!empty($offer['purchasePrice'])) {
$e->appendChild($this->_dd->createElement('purchasePrice'))
->appendChild(
$this->_dd->createTextNode($offer['purchasePrice'])
);
}
if (!empty($offer['picture'])) {
$e->appendChild($this->_dd->createElement('picture'))
->appendChild(
$this->_dd->createTextNode($offer['picture'])
);
}
if (!empty($offer['url'])) {
$e->appendChild($this->_dd->createElement('url'))
->appendChild(
$this->_dd->createTextNode($offer['url'])
);
}
if (!empty($offer['vendor'])) {
$e->appendChild($this->_dd->createElement('vendor'))
->appendChild(
$this->_dd->createTextNode($offer['vendor'])
);
}
if(!empty($offer['params'])) {
foreach($offer['params'] as $param) {
$paramNode = $this->_dd->createElement('param');
$paramNode->setAttribute('name', $param['name']);
$paramNode->setAttribute('code', $param['code']);
$paramNode->appendChild(
$this->_dd->createTextNode($param['value'])
);
$e->appendChild($paramNode);
}
}
}
}
}

View file

@ -1,66 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Model\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class Customer implements \Magento\Framework\Event\ObserverInterface
{
protected $_api;
protected $_config;
protected $_helper;
protected $_logger;
protected $_objectManager;
protected $registry;
public function __construct(
\Magento\Framework\ObjectManagerInterface $objectManager,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\Registry $registry
) {
$helper = $objectManager->get('\Retailcrm\Retailcrm\Helper\Data');
$logger = $objectManager->get('\Retailcrm\Retailcrm\Model\Logger\Logger');
$this->_logger = $logger;
$this->_helper = $helper;
$this->_config = $config;
$this->_objectManager = $objectManager;
$this->registry = $registry;
$url = $config->getValue('retailcrm/general/api_url');
$key = $config->getValue('retailcrm/general/api_key');
$version = $config->getValue('retailcrm/general/api_version');
if (!empty($url) && !empty($key)) {
$this->_api = new ApiClient($url, $key, $version);
}
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
if ($this->registry->registry('RETAILCRM_HISTORY') === true) {
return;
}
$data = $observer->getEvent()->getCustomer();
$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()))
];
$response = $this->_api->customersEdit($customer);
if ($response === false) {
return;
}
if (!$response->isSuccessful() && $response->errorMsg == $this->_api->getErrorText('errorNotFound')) {
$this->_api->customersCreate($customer);
}
}
}

View file

@ -1,268 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Model\Observer;
use Magento\Framework\Event\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class OrderCreate implements \Magento\Framework\Event\ObserverInterface
{
protected $_api;
protected $_objectManager;
protected $_config;
protected $_helper;
protected $_logger;
protected $_registry;
/**
* Constructor
*
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Retailcrm\Retailcrm\Model\Logger\Logger $logger
* @param \Magento\Framework\Registry $registry
*/
public function __construct(
\Magento\Framework\ObjectManagerInterface $objectManager,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\Registry $registry
) {
$helper = $objectManager->get('\Retailcrm\Retailcrm\Helper\Data');
$this->_logger = $objectManager->get('\Retailcrm\Retailcrm\Model\Logger\Logger');
$this->_helper = $helper;
$this->_objectManager = $objectManager;
$this->_config = $config;
$this->_registry = $registry;
$url = $config->getValue('retailcrm/general/api_url');
$key = $config->getValue('retailcrm/general/api_key');
$apiVersion = $config->getValue('retailcrm/general/api_version');
if (!empty($url) && !empty($key)) {
$this->_api = new ApiClient($url, $key, $apiVersion);
}
}
/**
* Execute send order in CRM
*
* @param Observer $observer
*
* @return $this
*/
public function execute(Observer $observer)
{
if ($this->_registry->registry('RETAILCRM_HISTORY') === true) {
return;
}
$order = $observer->getEvent()->getOrder();
if ($this->existsInCrm($order->getId()) === true) {
return;
}
$items = [];
$addressObj = $order->getBillingAddress();
foreach ($order->getAllItems() as $item) {
if ($item->getProductType() == "simple") {
$price = $item->getPrice();
if ($price == 0) {
$omproduct = $this->_objectManager->get('Magento\Catalog\Model\ProductRepository')
->getById($item->getProductId());
$price = $omproduct->getPrice();
}
$product = [
'productId' => $item->getProductId(),
'productName' => $item->getName(),
'quantity' => $item->getQtyOrdered(),
'initialPrice' => $price,
'offer' => [
'externalId' => $item->getProductId()
]
];
unset($omproduct);
unset($price);
$items[] = $product;
}
}
$shippingCode = $this->getShippingCode($order->getShippingMethod());
$preparedOrder = [
'site' => $order->getStore()->getCode(),
'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/Status/' . $order->getStatus()),
'items' => $items,
'delivery' => [
'code' => $this->_config->getValue('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')) {
$preparedOrder['countryIso'] = $addressObj->getData('country_id');
}
if ($this->_api->getVersion() == 'v4') {
$preparedOrder['paymentType'] = $this->_config->getValue('retailcrm/Payment/'.$order->getPayment()->getMethodInstance()->getCode());
$preparedOrder['discount'] = abs($order->getDiscountAmount());
} elseif ($this->_api->getVersion() == 'v5') {
$preparedOrder['discountManualAmount'] = abs($order->getDiscountAmount());
$payment = [
'type' => $this->_config->getValue('retailcrm/Payment/' . $order->getPayment()->getMethodInstance()->getCode()),
'externalId' => $order->getId(),
'order' => [
'externalId' => $order->getId(),
]
];
if ($order->getBaseTotalDue() == 0) {
$payment['status'] = 'paid';
}
$preparedOrder['payments'][] = $payment;
}
if (trim($preparedOrder['delivery']['code']) == '') {
unset($preparedOrder['delivery']['code']);
}
if (isset($preparedOrder['paymentType']) && trim($preparedOrder['paymentType']) == '') {
unset($preparedOrder['paymentType']);
}
if (trim($preparedOrder['status']) == '') {
unset($preparedOrder['status']);
}
if ($order->getCustomerIsGuest() == 1) {
$customer = $this->getCustomerByEmail($order->getCustomerEmail());
if ($customer !== false) {
$preparedOrder['customer']['id'] = $customer['id'];
}
} elseif ($order->getCustomerIsGuest() == 0) {
if ($this->existsInCrm($order->getCustomerId(), 'customersGet')) {
$preparedOrder['customer']['externalId'] = $order->getCustomerId();
} else {
$preparedCustomer = [
'externalId' => $order->getCustomerId(),
'firstName' => $order->getCustomerFirstname(),
'lastName' => $order->getCustomerLastname(),
'email' => $order->getCustomerEmail()
];
if ($addressObj->getTelephone()) {
$preparedCustomer['phones'][] = [
'number' => $addressObj->getTelephone()
];
}
if ($this->_api->customersCreate($preparedCustomer)) {
$preparedOrder['customer']['externalId'] = $order->getCustomerId();
}
}
}
$this->_helper->filterRecursive($preparedOrder);
$this->_logger->writeDump($preparedOrder,'CreateOrder');
$this->_api->ordersCreate($preparedOrder);
return $this;
}
/**
* Get shipping code
*
* @param string $string
*
* @return string
*/
protected 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
*
* @param int $id
*
* @return boolean
*/
protected function existsInCrm($id, $method = 'ordersGet', $by = 'externalId')
{
$response = $this->_api->{$method}($id, $by);
if ($response === false) {
return;
}
if (!$response->isSuccessful() && $response->errorMsg == $this->_api->getErrorText('errorNotFound')) {
return false;
}
return true;
}
/**
* Get customer by email from CRM
*
* @param string $email
*
* @return mixed
*/
protected function getCustomerByEmail($email)
{
$response = $this->_api->customersList(['email' => $email]);
if ($response === false) {
return false;
}
if ($response->isSuccessful() && isset($response['customers'])) {
if (!empty($response['customers'])) {
return reset($response['customers']);
}
}
return false;
}
}

View file

@ -1,79 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Model\Observer;
use Magento\Framework\Event\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class OrderUpdate implements \Magento\Framework\Event\ObserverInterface
{
protected $_api;
protected $_config;
protected $_helper;
protected $_objectManager;
protected $registry;
/**
* Constructor
*
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
*/
public function __construct(
\Magento\Framework\ObjectManagerInterface $objectManager,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\Registry $registry
) {
$this->_helper = $objectManager->get('\Retailcrm\Retailcrm\Helper\Data');
$this->_objectManager = $objectManager;
$this->_config = $config;
$this->registry = $registry;
$url = $config->getValue('retailcrm/general/api_url');
$key = $config->getValue('retailcrm/general/api_key');
$apiVersion = $config->getValue('retailcrm/general/api_version');
if (!empty($url) && !empty($key)) {
$this->_api = new ApiClient($url, $key, $apiVersion);
}
}
/**
* Execute update order in CRM
*
* @param Observer $observer
*
* @return void
*/
public function execute(Observer $observer)
{
if ($this->registry->registry('RETAILCRM_HISTORY') === true) {
return;
}
$order = $observer->getEvent()->getOrder();
if ($order) {
$preparedOrder = [
'externalId' => $order->getId(),
'status' => $this->_config->getValue('retailcrm/Status/' . $order->getStatus())
];
if ($order->getBaseTotalDue() == 0) {
if ($this->_api->getVersion() == 'v4') {
$preparedOrder['paymentStatus'] = 'paid';
} elseif ($this->_api->getVersion() == 'v5') {
$payment = [
'externalId' => $order->getPayment()->getId(),
'status' => 'paid'
];
$this->_api->ordersPaymentsEdit($payment);
}
}
$this->_helper->filterRecursive($preparedOrder);
$this->_api->ordersEdit($preparedOrder);
}
}
}

View file

@ -1,165 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Model\Order;
use Retailcrm\Retailcrm\Model\Observer\OrderCreate;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class OrderNumber extends OrderCreate
{
protected $_orderRepository;
protected $_searchCriteriaBuilder;
protected $_config;
protected $_filterBuilder;
protected $_order;
protected $_helper;
protected $_api;
protected $_logger;
public function __construct()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$orderRepository = $objectManager->get('Magento\Sales\Model\OrderRepository');
$searchCriteriaBuilder = $objectManager->get('Magento\Framework\Api\SearchCriteriaBuilder');
$config = $objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface');
$filterBuilder = $objectManager->get('Magento\Framework\Api\FilterBuilder');
$order = $objectManager->get('\Magento\Sales\Api\Data\OrderInterface');
$helper = $objectManager->get('\Retailcrm\Retailcrm\Helper\Data');
$this->_orderRepository = $orderRepository;
$this->_searchCriteriaBuilder = $searchCriteriaBuilder;
$this->_config = $config;
$this->_filterBuilder = $filterBuilder;
$this->_order = $order;
$this->_helper = $helper;
$this->_logger = $objectManager->get('\Retailcrm\Retailcrm\Model\Logger\Logger');
$url = $config->getValue('retailcrm/general/api_url');
$key = $config->getValue('retailcrm/general/api_key');
$version = $config->getValue('retailcrm/general/api_version');
if (!empty($url) && !empty($key)) {
$this->_api = new ApiClient($url, $key, $version);
}
}
public function ExportOrderNumber()
{
$ordernumber = $this->_config->getValue('retailcrm/Load/number_order');
$ordersId = explode(",", $ordernumber);
$orders = [];
foreach ($ordersId as $id) {
$orders[] = $this->prepareOrder($id);
}
$chunked = array_chunk($orders, 50);
unset($orders);
foreach ($chunked as $chunk) {
$this->_api->ordersUpload($chunk);
time_nanosleep(0, 250000000);
}
unset($chunked);
return true;
}
public function prepareOrder($id)
{
$magentoOrder = $this->_order->load($id);
$items = [];
$addressObj = $magentoOrder->getBillingAddress();
foreach ($magentoOrder->getAllItems() as $item) {
if ($item->getProductType() == "simple") {
$price = $item->getPrice();
if ($price == 0){
$om = \Magento\Framework\App\ObjectManager::getInstance();
$omproduct = $om->get('Magento\Catalog\Model\ProductRepository')
->getById($item->getProductId());
$price = $omproduct->getPrice();
}
$product = [
'productId' => $item->getProductId(),
'productName' => $item->getName(),
'quantity' => $item->getQtyOrdered(),
'initialPrice' => $price,
'offer' => [
'externalId'=>$item->getProductId()
]
];
unset($om);
unset($omproduct);
unset($price);
$items[] = $product;
}
}
$ship = $this->getShippingCode($magentoOrder->getShippingMethod());
$preparedOrder = [
'site' => $magentoOrder->getStore()->getCode(),
'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 $this->_helper->filterRecursive($preparedOrder);
}
}

View file

@ -1,34 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Model\Setting;
class Attribute implements \Magento\Framework\Option\ArrayInterface
{
protected $_entityType;
protected $_store;
public function __construct(
\Magento\Store\Model\Store $store,
\Magento\Eav\Model\Entity\Type $entityType
) {
$this->_store = $store;
$this->_entityType = $entityType;
}
public function toOptionArray()
{
$types = ['text', 'multiselect', 'decimal'];
$attributes = $this->_entityType->loadByCode('catalog_product')->getAttributeCollection();
$attributes->addFieldToFilter('frontend_input', $types);
$result = [];
foreach ($attributes as $attr) {
if ($attr->getFrontendLabel()) {
$result[] = array('value' => $attr->getAttributeId(), 'label' => $attr->getFrontendLabel(), 'title' => $attr->getAttributeCode());
}
}
return $result;
}
}

View file

@ -1,29 +1,36 @@
Magento module
[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)
[![Build Status](https://github.com/retailcrm/magento-module/workflows/magento/badge.svg)](https://github.com/retailcrm/magento-module/actions)
[![Coverage](https://img.shields.io/codecov/c/gh/retailcrm/magento-module/master.svg?logo=github)](https://codecov.io/gh/retailcrm/magento-module)
[![GitHub release](https://img.shields.io/github/release/retailcrm/magento-module.svg?logo=codecov)](https://github.com/retailcrm/magento-module/)
[![PHP version](https://img.shields.io/badge/PHP->=5.6-blue.svg?style=flat-square)](https://php.net/)
DEPRECATED Magento module
==============
Magento 2 module for interaction with [retailCRM](http://www.retailcrm.ru).
**The module is deprecated and no longer supported**
Magento 2 module for interaction with [RetailCRM](http://www.retailcrm.ru) ([Documentation](https://docs.retailcrm.pro/Users/Integration/SiteModules/Magento) page)
Module allows:
* Exchange the orders data with retailCRM
* Exchange the orders data with RetailCRM
* Configure relations between dictionaries of retailCRM and Magento (statuses, payments, delivery types and etc)
* Generate [ICML](http://www.retailcrm.ru/docs/Developers/ICML) (Intaro Markup Language) export file for catalog loading by retailCRM
* Generate [ICML](http://www.retailcrm.ru/docs/Developers/ICML) (Intaro Markup Language) export file for catalog loading by RetailCRM
### ICML
## ICML
By default ICML file is being generated by module every 4 hours. You can find file in the web root folder with name "retailcrm_{{shop_code}}.xml". For example, http://example.org/retailcrm_default.xml
### Manual install
1) Run into your project root directory:
1) Unpack the archive with the module in the directory "app/code/Retailcrm/Retailcrm". In the file "app/etc/config.php" in array `modules` add an element `'Retailcrm_Retailcrm' => 1`
2) Run into your project directory:
```bash
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
This module is compatible with Magento up to version 2.2.8

View file

@ -1,31 +1,30 @@
Magento module
==============
DEPRECATED Magento module
Модуль Magento 2 для интеграции с [retailCRM](http://www.retailcrm.ru).
**Модуль устарел и больше не поддерживается**
Модуль Magento 2 для интеграции с [RetailCRM](http://www.retailcrm.ru) ([Документация](https://docs.retailcrm.ru/Users/Integration/SiteModules/Magento))
Модуль позволяет:
* Производить обмен заказами с retailCRM
* Настроить соответствие справочников retailCRM и Magento (статусы, оплаты, типы доставки и т.д.)
* Создать [ICML](http://www.retailcrm.ru/docs/Developers/ICML) (Intaro Markup Language) для загрузки каталога товаров в retailCRM
* Производить обмен заказами с RetailCRM
* Настроить соответствие справочников RetailCRM и Magento (статусы, оплаты, типы доставки и т.д.)
* Создать [ICML](http://www.retailcrm.ru/docs/Developers/ICML) (Intaro Markup Language) для загрузки каталога товаров в RetailCRM
### ICML
## ICML
По умолчанию ICML-файл генерируется модулем каждые 4 часа. Вы можете найти файл в корневой директории с именем «retailcrm_{{shop_code}}.xml". Например, http://example.org/retailcrm_default.xml
По умолчанию ICML-файл генерируется модулем каждые 4 часа. Вы можете найти файл в корневой папке с именем «retailcrm_{{shop_code}}.xml". Например, http://example.ru/retailcrm_default.xml
### Ручная установка
## Ручная установка
1) Находясь в корневой директории проекта выполните команду:
1) Распакуйте архив с модулем в директорию "app/code/Retailcrm/Retailcrm". В файле "app/etc/config.php" в массив `modules` добавьте элемент `'Retailcrm_Retailcrm' => 1`
2) Выполните в папке проекта:
```bash
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/`.
Этот модуль совместим с Magento 2 до версии 2.2.3
Этот модуль совместим с Magento 2 до версии 2.2.8

View file

@ -1,159 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Observer;
class CustomerTest extends \PHPUnit\Framework\TestCase
{
protected $mockApi;
protected $mockResponse;
protected $config;
protected $registry;
protected $mockObserver;
protected $mockEvent;
protected $objectManager;
protected $mockCustomer;
public function setUp()
{
$this->mockApi = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods([
'customersEdit',
'customersCreate'
])
->getMock();
$this->mockResponse = $this->getMockBuilder(\RetailCrm\Response\ApiResponse::class)
->disableOriginalConstructor()
->setMethods(['isSuccessful'])
->getMock();
$this->config = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
->getMockForAbstractClass();
$this->registry = $this->getMockBuilder(\Magento\Framework\Registry::class)
->disableOriginalConstructor()
->getMock();
$this->mockObserver = $this->getMockBuilder(\Magento\Framework\Event\Observer::class)
->disableOriginalConstructor()
->getMock();
$this->mockEvent = $this->getMockBuilder(\Magento\Framework\Event::class)
->disableOriginalConstructor()
->setMethods(['getCustomer'])
->getMock();
$this->objectManager = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class)
->getMockForAbstractClass();
$this->mockCustomer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class)
->disableOriginalConstructor()
->setMethods([
'getId',
'getEmail',
'getFirstname',
'getMiddlename',
'getLastname'
])
->getMock();
$this->unit = new \Retailcrm\Retailcrm\Model\Observer\Customer(
$this->objectManager,
$this->config,
$this->registry
);
$reflection = new \ReflectionClass($this->unit);
$reflection_property = $reflection->getProperty('_api');
$reflection_property->setAccessible(true);
$reflection_property->setValue($this->unit, $this->mockApi);
}
/**
* @param boolean $isSuccessful
* @dataProvider dataProviderCustomer
*/
public function testExecute(
$isSuccessful
) {
$testData = $this->getAfterSaveCustomerTestData();
// mock Response
$this->mockResponse->expects($this->any())
->method('isSuccessful')
->willReturn($isSuccessful);
$this->mockResponse->errorMsg = 'Not found';
// mock API
$this->mockApi->expects($this->any())
->method('customersEdit')
->willReturn($this->mockResponse);
$this->mockApi->expects($this->any())
->method('customersCreate')
->willReturn($this->mockResponse);
// mock Customer
$this->mockCustomer->expects($this->once())
->method('getId')
->willReturn($testData['id']);
$this->mockCustomer->expects($this->once())
->method('getEmail')
->willReturn($testData['email']);
$this->mockCustomer->expects($this->once())
->method('getFirstname')
->willReturn($testData['firstname']);
$this->mockCustomer->expects($this->once())
->method('getMiddlename')
->willReturn($testData['middlename']);
$this->mockCustomer->expects($this->once())
->method('getLastname')
->willReturn($testData['lastname']);
// mock Event
$this->mockEvent->expects($this->once())
->method('getCustomer')
->willReturn($this->mockCustomer);
// mock Observer
$this->mockObserver->expects($this->once())
->method('getEvent')
->willReturn($this->mockEvent);
$this->unit->execute($this->mockObserver);
}
/**
* Get test customer data
*
* @return array
*/
protected function getAfterSaveCustomerTestData()
{
return [
'id' => 1,
'email' => 'test@mail.com',
'firstname' => 'TestFirstname',
'lastname' => 'Testlastname',
'middlename' => 'Testmiddlename'
];
}
public function dataProviderCustomer()
{
return [
[
'is_successful' => true
],
[
'is_successful' => false
]
];
}
}

View file

@ -1,426 +0,0 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Observer;
/**
* Order create observer test class
*/
class OrderCreateTest extends \PHPUnit\Framework\TestCase
{
protected $objectManager;
protected $_config;
protected $_unit;
protected $_mockEvent;
protected $_mockObserver;
protected $_registry;
protected $_mockApi;
protected $_mockOrder;
protected $_mockItem;
protected $_mockStore;
protected $_mockBillingAddress;
protected $_mockResponse;
protected $_mockPayment;
protected $_mockPaymentMethod;
protected function setUp()
{
$this->_mockApi = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods([
'ordersGet',
'ordersCreate',
'customersGet',
'customersCreate',
'customersList',
'getVersion'
])
->getMock();
$this->_mockObserver = $this->getMockBuilder(\Magento\Framework\Event\Observer::class)
->disableOriginalConstructor()
->getMock();
$this->_mockEvent = $this->getMockBuilder(\Magento\Framework\Event::class)
->disableOriginalConstructor()
->setMethods(['getOrder'])
->getMock();
$this->objectManager = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class)
->getMockForAbstractClass();
// mock Object Manager
$this->objectManager->expects($this->any())
->method('get')
->with($this->logicalOr(
$this->equalTo('\Retailcrm\Retailcrm\Helper\Data'),
$this->equalTo('\Retailcrm\Retailcrm\Model\Logger\Logger')
))
->will($this->returnCallback([$this, 'getCallbackDataClasses']));
$this->_config = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
->getMockForAbstractClass();
$this->_logger = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Logger\Logger::class)
->disableOriginalConstructor()
->getMock();
$this->_registry = $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'])
->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'])
->getMock();
$this->_mockBillingAddress = $this->getMockBuilder(\Magento\Customer\Model\Address\AddressModelInterface::class)
->disableOriginalConstructor()
->setMethods(['getTelephone', 'getData'])
->getMockForAbstractClass();
$this->_mockResponse = $this->getMockBuilder(\RetailCrm\Response\ApiResponse::class)
->disableOriginalConstructor()
->setMethods(['isSuccessful'])
->getMock();
$this->_unit = new \Retailcrm\Retailcrm\Model\Observer\OrderCreate(
$this->objectManager,
$this->_config,
$this->_registry
);
$reflection = new \ReflectionClass($this->_unit);
$reflection_property = $reflection->getProperty('_api');
$reflection_property->setAccessible(true);
$reflection_property->setValue($this->_unit, $this->_mockApi);
}
/**
* @param boolean $isSuccessful
* @param string $errorMsg
* @param int $customerIsGuest
* @param string $apiVersion
* @dataProvider dataProviderOrderCreate
*/
public function testExecute(
$isSuccessful,
$errorMsg,
$customerIsGuest,
$apiVersion
) {
$testData = $this->getAfterSaveOrderTestData();
// mock Response
$this->_mockResponse->expects($this->any())
->method('isSuccessful')
->willReturn($isSuccessful);
$this->_mockResponse->errorMsg = $errorMsg;
// mock API
$this->_mockApi->expects($this->any())
->method('ordersGet')
->willReturn($this->_mockResponse);
$this->_mockApi->expects($this->any())
->method('ordersCreate')
->willReturn($this->_mockResponse);
$this->_mockApi->expects($this->any())
->method('customersGet')
->willReturn($this->_mockResponse);
$this->_mockApi->expects($this->any())
->method('customersCreate')
->willReturn($this->_mockResponse);
$this->_mockApi->expects($this->any())
->method('customersList')
->willReturn($this->_mockResponse);
$this->_mockApi->expects($this->any())
->method('getVersion')
->willReturn($apiVersion);
// billing address mock set data
$this->_mockBillingAddress->expects($this->any())
->method('getTelephone')
->willReturn($testData['order.billingAddress']['telephone']);
$this->_mockBillingAddress->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']));
// store mock set data
$this->_mockStore->expects($this->any())
->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')
->willReturn($testData['order.id']);
$this->_mockOrder->expects($this->any())
->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->once())
->method('getOrder')
->willReturn($this->_mockOrder);
// mock Observer
$this->_mockObserver->expects($this->once())
->method('getEvent')
->willReturn($this->_mockEvent);
$this->_unit->execute($this->_mockObserver);
}
/**
* Get test order data
*
* @return array $testOrderData
*/
protected function getAfterSaveOrderTestData()
{
$testOrderData = [
'order.id' => 1,
'order.status' => 'processing',
'order.realOrderId' => '000000001',
'order.billingAddress' => [
'telephone' => '890000000000',
'data' => [
'city' => 'Moscow',
'region' => 'Moscow',
'street' => 'TestStreet',
'postcode' => '111111',
'country_id' => 'RU'
]
],
'order.allItems' => [$this->_mockItem],
'order.shippingMethod' => 'flatrate_flatrate',
'order.paymentMethod' => 'checkmo',
'order.customerLastname' => 'Test',
'order.customerFirstname' => 'Test',
'order.customerMiddlename' => 'Test',
'order.customerEmail' => 'test@gmail.com'
];
return $testOrderData;
}
public function getCallbackDataAddress($dataKey)
{
$testData = $this->getAfterSaveOrderTestData();
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 [
[
'is_successful' => true,
'error_msg' => 'Not found',
'customer_is_guest' => 1,
'api_version' => 'v4'
],
[
'is_successful' => true,
'error_msg' => 'Not found',
'customer_is_guest' => 0,
'api_version' => 'v4'
],
[
'is_successful' => false,
'error_msg' => 'Not found',
'customer_is_guest' => 1,
'api_version' => 'v4'
],
[
'is_successful' => false,
'error_msg' => 'Not found',
'customer_is_guest' => 0,
'api_version' => 'v4'
],
[
'is_successful' => true,
'error_msg' => 'Not found',
'customer_is_guest' => 1,
'api_version' => 'v5'
],
[
'is_successful' => true,
'error_msg' => 'Not found',
'customer_is_guest' => 0,
'api_version' => 'v5'
],
[
'is_successful' => false,
'error_msg' => 'Not found',
'customer_is_guest' => 1,
'api_version' => 'v5'
],
[
'is_successful' => false,
'error_msg' => 'Not found',
'customer_is_guest' => 0,
'api_version' => 'v5'
]
];
}
}

1
VERSION Normal file
View file

@ -0,0 +1 @@
2.5.2

68
bin/install.sh Normal file
View file

@ -0,0 +1,68 @@
#!/usr/bin/env bash
if [ -z $ROOT_DIR ]; then
exit 0;
fi
MAGE_ROOT=$ROOT_DIR/../magento2
create_db() {
mysqladmin create "magento2_test" --user="root" --password="root"
}
magento_clone() {
cd ..
git clone https://github.com/magento/magento2
cd magento2
git checkout $BRANCH
touch auth.json
echo '
{
"http-basic": {
"repo.magento.com": {
"username": "<public-key>",
"password": "<private-key>"
}
}
}
' > auth.json
sudo sed -e "s?<public-key>?$PUBLIC_KEY?g" --in-place auth.json
sudo sed -e "s?<private-key>?$PRIVATE_KEY?g" --in-place auth.json
composer install --no-interaction --prefer-dist
composer require retailcrm/api-client-php
}
magento_install() {
cd $MAGE_ROOT
php bin/magento setup:install \
--db-host="localhost" \
--db-name="magento2_test" \
--db-user="root" \
--db-password="root" \
--admin-firstname="admin_firstname" \
--admin-lastname="admin_lastname" \
--admin-email="example@email.com" \
--admin-user="admin" \
--admin-password="admin123" \
--language="en_US" \
--currency="USD" \
--timezone="Europe/Moscow"
}
module_install() {
cd $MAGE_ROOT
mkdir -p app/code/Retailcrm/Retailcrm
cp -R $ROOT_DIR/src/* app/code/Retailcrm/Retailcrm
php bin/magento module:enable Retailcrm_Retailcrm
php bin/magento setup:upgrade
php bin/magento setup:di:compile
}
create_db
magento_clone
magento_install
module_install

View file

@ -1,97 +0,0 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="retailcrm" translate="label" sortOrder="10">
<label>Retailcrm</label>
</tab>
<section id="retailcrm" translate="label" sortOrder="130" showInDefault="1" showInWebsite="1" showInStore="1">
<class>separator-top</class>
<label>Setting</label>
<tab>retailcrm</tab>
<resource>Retailcrm_Retailcrm::retailcrm_configuration</resource>
<group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<label>General Configuration</label>
<field id="api_url" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<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="0" showInStore="0">
<label>API Key</label>
<comment>To generate an API Key, log in to RetailCRM then select Admin > Integration > API Keys</comment>
</field>
<field id="api_version" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0">
<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="2" showInWebsite="0" showInStore="0">
<label>Misc</label>
<field id="attributes_to_export_into_icml" translate="label" type="multiselect" sortOrder="2" showInDefault="1" showInWebsite="0" showInStore="0">
<label>attributes to export into icml</label>
<comment>attributes to export into icml</comment>
<source_model>Retailcrm\Retailcrm\Model\Setting\Attribute</source_model>
<!--
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field\Attributes</frontend_model>
-->
</field>
</group>
<group id="Shipping" translate="label" type="text" sortOrder="30" showInDefault="3" showInWebsite="0" showInStore="0">
<label>Shipping</label>
<field id="Shipping" translate="label" type="select" sortOrder="3" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Shipping</label>
<!-- <source_model>Retailcrm\Retailcrm\Model\Setting\Shipping</source_model>
-->
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field\Shipping</frontend_model>
</field>
</group>
<group id="Payment" translate="label comment" type="text" sortOrder="40" showInDefault="4" showInWebsite="0" showInStore="0">
<label>Payment method</label>
<field id="display_text" translate="label" type="text" sortOrder="5" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Payment</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field\Payment</frontend_model>
<comment>This text will display on the frontend.</comment>
</field>
</group>
<group id="Status" translate="label" type="text" sortOrder="50" showInDefault="5" showInWebsite="0" showInStore="0">
<label>Order Status</label>
<field id="status_text" translate="label" type="text" sortOrder="5" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Status</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Field\Status</frontend_model>
<comment>This text will display on the frontend.</comment>
</field>
</group>
<group id="Load" translate="label" type="text" sortOrder="60" showInDefault="6" showInWebsite="0" showInStore="0">
<label>Order Load</label>
<field id="number_order" translate="label" type="text" sortOrder="6" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Order number</label>
<comment>Enter your order number, separated by commas</comment>
</field>
<field id="button_order" translate="label comment" type="button" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Button</frontend_model>
</field>
</group>
</section>
</system>
</config>

View file

@ -1,11 +0,0 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\Console\CommandList">
<arguments>
<argument name="commands" xsi:type="array">
<item name="retailcrm_command" xsi:type="object">Retailcrm\Retailcrm\Console\Command\Command</item>
</argument>
</arguments>
</type>
</config>

View file

@ -1,6 +0,0 @@
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Retailcrm_Retailcrm',
__DIR__
);

View file

@ -0,0 +1,12 @@
<?php
namespace Retailcrm\Retailcrm\Api;
interface ConfigManagerInterface
{
const URL_PATH = 'retailcrm/general/api_url';
const KEY_PATH = 'retailcrm/general/api_key';
const API_VERSION_PATH = 'retailcrm/general/api_version';
public function getConfigValue($path);
}

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

@ -0,0 +1,18 @@
<?php
namespace Retailcrm\Retailcrm\ApiClient;
class ApiClientFactory
{
/**
* @param $url
* @param $api_key
* @param null $version
*
* @return \RetailCrm\ApiClient
*/
public function create($url, $api_key, $version = null)
{
return new \RetailCrm\ApiClient($url, $api_key, $version);
}
}

View file

@ -6,18 +6,7 @@ class Button extends \Magento\Config\Block\System\Config\Form\Field
/**
* @var string
*/
protected $_template = 'Retailcrm_Retailcrm::system/config/button.phtml';
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
array $data = []
) {
parent::__construct($context, $data);
}
public $_template = 'Retailcrm_Retailcrm::system/config/button.phtml';
/**
* Remove scope label
@ -39,7 +28,7 @@ class Button extends \Magento\Config\Block\System\Config\Form\Field
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
public function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
return $this->_toHtml();
}
@ -66,7 +55,7 @@ class Button extends \Magento\Config\Block\System\Config\Form\Field
)->setData(
[
'id' => 'order_button',
'label' => __('Run'),
'label' => __('Send'),
]
);

View file

@ -0,0 +1,168 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
{
/**
* Dummy element
*
* @var \Magento\Framework\DataObject
*/
protected $_dummyElement;
/**
* Field renderer
*
* @var \Magento\Config\Block\System\Config\Form\Field
*/
protected $_fieldRenderer;
private $objectFactory;
private $paymentConfig;
private $client;
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Backend\Model\Auth\Session $authSession,
\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);
}
/**
* Get field renderer
*
* @return \Magento\Config\Block\System\Config\Form\Field
*/
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$this->_fieldRenderer = $this->getLayout()->getBlockSingleton(
\Magento\Config\Block\System\Config\Form\Field::class
);
}
return $this->_fieldRenderer;
}
/**
* Get dummy element
*
* @return \Magento\Framework\DataObject
*/
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 1]);
}
return $this->_dummyElement;
}
public function render(AbstractElement $element)
{
$html = '';
$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()) {
$paymentMethods = $this->paymentConfig->getActiveMethods();
foreach ($paymentMethods as $code => $payment) {
$html .= $this->_getFieldHtml($element, $payment);
}
} else {
$html .= $htmlError;
}
$html .= $this->_getFooterHtml($element);
return $html;
}
/**
* Get options values
*
* @return array
*/
private function getValues()
{
$defaultValues = [
[
'value' => '',
'label' => ''
]
];
$values = [];
$response = $this->client->paymentTypesList();
if ($response === false) {
return $defaultValues;
}
if (isset($response['paymentTypes']) && $response->isSuccessful()) {
$paymentsTypes = $response['paymentTypes'];
} else {
return $defaultValues;
}
foreach ($paymentsTypes as $paymentType) {
$values[] = [
'label' => $paymentType['name'],
'value' => $paymentType['code']
];
}
return $values;
}
/**
* Get field html
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $fieldset
* @param \Magento\Payment\Api\Data\PaymentMethodInterface $payment
*
* @return string
*/
protected function _getFieldHtml($fieldset, $payment)
{
$configData = $this->getConfigData();
$path = 'retailcrm/' . $fieldset->getId() . '/' . $payment->getCode();
$data = isset($configData[$path]) ? $configData[$path] : [];
$e = $this->_getDummyElement();
$field = $fieldset->addField(
$payment->getCode(),
'select',
[
'name' => 'groups[' . $fieldset->getId() . '][fields][' . $payment->getCode() . '][value]',
'label' => $payment->getTitle(),
'value' => isset($data) ? $data : '',
'values' => $this->getValues(),
'inherit' => true,
'can_use_default_value' => $this->getForm()->canUseDefaultValue($e),
'can_use_website_value' => $this->getForm()->canUseWebsiteValue($e)
]
)->setRenderer(
$this->_getFieldRenderer()
);
return $field->toHtml();
}
}

View file

@ -0,0 +1,95 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset;
class PaymentList extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray
{
/**
* @var $_paymentCms \Retailcrm\Retailcrm\Model\Config\Backend\PaymentCms
*/
protected $_paymentCms;
/**
* @var $_paymentCrm \Retailcrm\Retailcrm\Model\Config\Backend\PaymentCrm
*/
protected $_paymentCrm;
/**
* @return \Magento\Framework\View\Element\BlockInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getPaymentCmsRenderer()
{
if (!$this->_paymentCms) {
$this->_paymentCms = $this->getLayout()->createBlock(
'\Retailcrm\Retailcrm\Model\Config\Backend\PaymentCms',
'',
['data' => ['is_render_to_js_template' => true]]
);
}
return $this->_paymentCms;
}
/**
* @return \Magento\Framework\View\Element\BlockInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getPaymentCrmRenderer()
{
if (!$this->_paymentCrm) {
$this->_paymentCrm = $this->getLayout()->createBlock(
'\Retailcrm\Retailcrm\Model\Config\Backend\PaymentCrm',
'',
['data' => ['is_render_to_js_template' => true]]
);
}
return $this->_paymentCrm;
}
/**
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _prepareToRender()
{
$this->addColumn(
'payment_cms',
[
'label' => __('CMS'),
'renderer' => $this->_getPaymentCmsRenderer()
]
);
$this->addColumn(
'payment_crm',
[
'label' => __('CRM'),
'renderer' => $this->_getPaymentCrmRenderer()
]
);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add');
}
/**
*
* @param \Magento\Framework\DataObject $row
* @throws \Magento\Framework\Exception\LocalizedException
* @return void
*/
protected function _prepareArrayRow(\Magento\Framework\DataObject $row)
{
$options = [];
$customAttribute = $row->getData('payment_cms');
$key = 'option_' . $this->_getPaymentCmsRenderer()->calcOptionHash($customAttribute);
$options[$key] = 'selected="selected"';
$customAttribute = $row->getData('payment_crm');
$key = 'option_' . $this->_getPaymentCrmRenderer()->calcOptionHash($customAttribute);
$options[$key] = 'selected="selected"';
$row->setData('option_extra_attrs', $options);
}
}

View file

@ -0,0 +1,181 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Shipping extends \Magento\Config\Block\System\Config\Form\Fieldset
{
/**
* Dummy element
*
* @var \Magento\Framework\DataObject
*/
protected $_dummyElement;
/**
* Field renderer
*
* @var \Magento\Config\Block\System\Config\Form\Field
*/
protected $_fieldRenderer;
private $objectFactory;
private $shippingConfig;
private $client;
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Backend\Model\Auth\Session $authSession,
\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);
}
/**
* Get field renderer
*
* @return \Magento\Config\Block\System\Config\Form\Field
*/
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$this->_fieldRenderer = $this->getLayout()->getBlockSingleton(
\Magento\Config\Block\System\Config\Form\Field::class
);
}
return $this->_fieldRenderer;
}
/**
* Get dummy element
*
* @return \Magento\Framework\DataObject
*/
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 1]);
}
return $this->_dummyElement;
}
/**
* Render element
*
* @param AbstractElement $element
* @return string
*/
public function render(AbstractElement $element)
{
$html = '';
$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()) {
$deliveryMethods = $this->shippingConfig->getActiveCarriers();
foreach ($deliveryMethods as $code => $delivery) {
$html .= $this->_getFieldHtml($element, $delivery);
}
} else {
$html .= $htmlError;
}
$html .= $this->_getFooterHtml($element);
return $html;
}
/**
* Get options values
*
* @return array
*/
private function getValues()
{
$defaultValues = [
[
'value' => '',
'label' => ''
]
];
$values = [];
try {
$response = $this->client->deliveryTypesList();
} catch (\Exception $exception) {
return $defaultValues;
}
if ($response === false) {
return $defaultValues;
}
if (isset($response['deliveryTypes']) && $response->isSuccessful()) {
$deliveryTypes = $response['deliveryTypes'];
} else {
return $defaultValues;
}
foreach ($deliveryTypes as $deliveryType) {
$values[] = [
'label' => $deliveryType['name'],
'value' => $deliveryType['code']
];
}
return $values;
}
/**
* Get field html
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $fieldset
* @param \Magento\Shipping\Model\Carrier\AbstractCarrier $shipping
*
* @return string
*/
protected function _getFieldHtml($fieldset, $shipping)
{
$configData = $this->getConfigData();
$path = 'retailcrm/' . $fieldset->getId() . '/' . $shipping->getCarrierCode();
$data = isset($configData[$path]) ? $configData[$path] : [];
$e = $this->_getDummyElement();
$field = $fieldset->addField(
$shipping->getCarrierCode(),
'select',
[
'name' => 'groups[' . $fieldset->getId() . '][fields][' . $shipping->getCarrierCode() . '][value]',
'label' => $shipping->getConfigData('title'),
'value' => isset($data) ? $data : '',
'values' => $this->getValues(),
'inherit' => true,
'can_use_default_value' => $this->getForm()->canUseDefaultValue($e),
'can_use_website_value' => $this->getForm()->canUseWebsiteValue($e)
]
)->setRenderer(
$this->_getFieldRenderer()
);
return $field->toHtml();
}
}

View file

@ -0,0 +1,95 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset;
class ShippingList extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray
{
/**
* @var $_shippingCms \Retailcrm\Retailcrm\Model\Config\Backend\ShippingCms
*/
protected $_shippingCms;
/**
* @var $_shippingCrm \Retailcrm\Retailcrm\Model\Config\Backend\ShippingCrm
*/
protected $_shippingCrm;
/**
* @return \Magento\Framework\View\Element\BlockInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getShippingCmsRenderer()
{
if (!$this->_shippingCms) {
$this->_shippingCms = $this->getLayout()->createBlock(
'\Retailcrm\Retailcrm\Model\Config\Backend\ShippingCms',
'',
['data' => ['is_render_to_js_template' => true]]
);
}
return $this->_shippingCms;
}
/**
* @return \Magento\Framework\View\Element\BlockInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getShippingCrmRenderer()
{
if (!$this->_shippingCrm) {
$this->_shippingCrm = $this->getLayout()->createBlock(
'\Retailcrm\Retailcrm\Model\Config\Backend\ShippingCrm',
'',
['data' => ['is_render_to_js_template' => true]]
);
}
return $this->_shippingCrm;
}
/**
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _prepareToRender()
{
$this->addColumn(
'shipping_cms',
[
'label' => __('CMS'),
'renderer' => $this->_getShippingCmsRenderer()
]
);
$this->addColumn(
'shipping_crm',
[
'label' => __('CRM'),
'renderer' => $this->_getShippingCrmRenderer()
]
);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add');
}
/**
*
* @param \Magento\Framework\DataObject $row
* @throws \Magento\Framework\Exception\LocalizedException
* @return void
*/
protected function _prepareArrayRow(\Magento\Framework\DataObject $row)
{
$options = [];
$customAttribute = $row->getData('shipping_cms');
$key = 'option_' . $this->_getShippingCmsRenderer()->calcOptionHash($customAttribute);
$options[$key] = 'selected="selected"';
$customAttribute = $row->getData('shipping_crm');
$key = 'option_' . $this->_getShippingCrmRenderer()->calcOptionHash($customAttribute);
$options[$key] = 'selected="selected"';
$row->setData('option_extra_attrs', $options);
}
}

View file

@ -0,0 +1,171 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Site extends \Magento\Config\Block\System\Config\Form\Fieldset
{
/**
* Dummy element
*
* @var \Magento\Framework\DataObject
*/
protected $_dummyElement;
/**
* Field renderer
*
* @var \Magento\Config\Block\System\Config\Form\Field
*/
protected $_fieldRenderer;
private $objectFactory;
private $client;
public function __construct(
\Magento\Backend\Block\Context $context,
\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);
}
/**
* Get field renderer
*
* @return \Magento\Config\Block\System\Config\Form\Field
*/
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$this->_fieldRenderer = $this->getLayout()->getBlockSingleton(
\Magento\Config\Block\System\Config\Form\Field::class
);
}
return $this->_fieldRenderer;
}
/**
* Get dummy element
*
* @return \Magento\Framework\DataObject
*/
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 0]);
}
return $this->_dummyElement;
}
/**
* Render element
*
* @param AbstractElement $element
* @return string
*/
public function render(AbstractElement $element)
{
$html = '';
$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()) {
$html .= $this->_getFieldHtml($element);
} else {
$html .= $htmlError;
}
$html .= $this->_getFooterHtml($element);
return $html;
}
/**
* Get options values
*
* @return array
*/
private function getValues()
{
$defaultValues = [
[
'value' => '',
'label' => ''
]
];
$values = [];
try {
$response = $this->client->sitesList();
} catch (\Exception $exception) {
return $defaultValues;
}
if ($response === false) {
return $defaultValues;
}
if (isset($response['sites']) && $response->isSuccessful()) {
$sites = $response['sites'];
} else {
return $defaultValues;
}
foreach ($sites as $site) {
$values[] = [
'label' => $site['name'],
'value' => $site['code']
];
}
return $values;
}
/**
* Get field html
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $fieldset
* @param \Magento\Shipping\Model\Carrier\AbstractCarrier $shipping
*
* @return string
*/
protected function _getFieldHtml($fieldset)
{
$configData = $this->getConfigData();
$path = 'retailcrm/' . $fieldset->getId() . '/default';
$data = isset($configData[$path]) ? $configData[$path] : [];
$e = $this->_getDummyElement();
$field = $fieldset->addField(
'default',
'select',
[
'name' => 'groups[' . $fieldset->getId() . '][fields][default][value]',
'label' => __('Default site'),
'value' => isset($data) ? $data : '',
'values' => $this->getValues(),
'inherit' => isset($data['inherit']) ? $data['inherit'] : '',
'can_use_default_value' => $this->getForm()->canUseDefaultValue($e),
'can_use_website_value' => $this->getForm()->canUseWebsiteValue($e)
]
)->setRenderer(
$this->_getFieldRenderer()
);
return $field->toHtml();
}
}

View file

@ -0,0 +1,177 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Sites extends \Magento\Config\Block\System\Config\Form\Fieldset
{
/**
* Dummy element
*
* @var \Magento\Framework\DataObject
*/
protected $_dummyElement;
/**
* Field renderer
*
* @var \Magento\Config\Block\System\Config\Form\Field
*/
protected $_fieldRenderer;
private $objectFactory;
private $storeManager;
private $client;
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Backend\Model\Auth\Session $authSession,
\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);
}
/**
* Get field renderer
*
* @return \Magento\Config\Block\System\Config\Form\Field
*/
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$this->_fieldRenderer = $this->getLayout()->getBlockSingleton(
\Magento\Config\Block\System\Config\Form\Field::class
);
}
return $this->_fieldRenderer;
}
/**
* Get dummy element
*
* @return \Magento\Framework\DataObject
*/
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 0]);
}
return $this->_dummyElement;
}
/**
* Render element
*
* @param AbstractElement $element
* @return string
*/
public function render(AbstractElement $element)
{
$html = '';
$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()) {
$website = $this->storeManager->getWebsite($this->getRequest()->getParam('website', 0));
foreach ($website->getStores() as $store) {
$html .= $this->_getFieldHtml($element, $store);
}
} else {
$html .= $htmlError;
}
$html .= $this->_getFooterHtml($element);
return $html;
}
/**
* Get options values
*
* @return array
*/
private function getValues()
{
$defaultValues = [
[
'value' => '',
'label' => ''
]
];
$values = [];
try {
$response = $this->client->sitesList();
} catch (\Exception $exception) {
return $defaultValues;
}
if ($response === false) {
return $defaultValues;
}
if (isset($response['sites']) && $response->isSuccessful()) {
$sites = $response['sites'];
} else {
return $defaultValues;
}
foreach ($sites as $site) {
$values[] = [
'label' => $site['name'],
'value' => $site['code']
];
}
return $values;
}
/**
* Get field html
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $fieldset
* @param \Magento\Shipping\Model\Carrier\AbstractCarrier $shipping
*
* @return string
*/
protected function _getFieldHtml($fieldset, $store)
{
$configData = $this->getConfigData();
$path = 'retailcrm/' . $fieldset->getId() . '/' . $store->getCode();
$data = isset($configData[$path]) ? $configData[$path] : [];
$e = $this->_getDummyElement();
$field = $fieldset->addField(
$store->getCode(),
'select',
[
'name' => 'groups[' . $fieldset->getId() . '][fields][' . $store->getCode() . '][value]',
'label' => $store->getName(),
'value' => isset($data) ? $data : '',
'values' => $this->getValues(),
'inherit' => isset($data['inherit']) ? $data['inherit'] : '',
'can_use_default_value' => $this->getForm()->canUseDefaultValue($e),
'can_use_website_value' => $this->getForm()->canUseWebsiteValue($e)
]
)->setRenderer(
$this->_getFieldRenderer()
);
return $field->toHtml();
}
}

View file

@ -0,0 +1,175 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Status extends \Magento\Config\Block\System\Config\Form\Fieldset
{
/**
* Dummy element
*
* @var \Magento\Framework\DataObject
*/
protected $_dummyElement;
/**
* Field renderer
*
* @var \Magento\Config\Block\System\Config\Form\Field
*/
protected $_fieldRenderer;
private $objectFactory;
private $statusCollection;
private $client;
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Backend\Model\Auth\Session $authSession,
\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);
}
/**
* Get field renderer
*
* @return \Magento\Config\Block\System\Config\Form\Field
*/
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$this->_fieldRenderer = $this->getLayout()->getBlockSingleton(
\Magento\Config\Block\System\Config\Form\Field::class
);
}
return $this->_fieldRenderer;
}
/**
* Get dummy element
*
* @return \Magento\Framework\DataObject
*/
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 1]);
}
return $this->_dummyElement;
}
public function render(AbstractElement $element)
{
$html = '';
$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();
foreach ($statuses as $code => $status) {
$html .= $this->_getFieldHtml($element, $status);
}
} else {
$html .= $htmlError;
}
$html .= $this->_getFooterHtml($element);
return $html;
}
/**
* Get options values
*
* @return array
*/
private function getValues()
{
$defaultValues = [
[
'value' => '',
'label' => ''
]
];
$values = [];
try {
$response = $this->client->statusesList();
} catch (\Exception $exception) {
return $defaultValues;
}
if ($response === false) {
return $defaultValues;
}
if (isset($response['statuses']) && $response->isSuccessful()) {
$statuses = $response['statuses'];
} else {
return $defaultValues;
}
foreach ($statuses as $status) {
$values[] = [
'label' => $status['name'],
'value' => $status['code']
];
}
return $values;
}
/**
* Get field html
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $fieldset
* @param array $status
*
* @return string
*/
protected function _getFieldHtml($fieldset, $status)
{
$configData = $this->getConfigData();
$path = 'retailcrm/' . $fieldset->getId() . '/' . $status['value'];
$data = isset($configData[$path]) ? $configData[$path] : [];
$e = $this->_getDummyElement();
$field = $fieldset->addField(
$status['value'],
'select',
[
'name' => 'groups[' . $fieldset->getId() . '][fields][' . $status['value'] . '][value]',
'label' => $status['label'],
'value' => isset($data) ? $data : '',
'values' => $this->getValues(),
'inherit' => true,
'can_use_default_value' => $this->getForm()->canUseDefaultValue($e),
'can_use_website_value' => $this->getForm()->canUseWebsiteValue($e)
]
)->setRenderer(
$this->_getFieldRenderer()
);
return $field->toHtml();
}
}

View file

@ -0,0 +1,95 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset;
class StatusList extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray
{
/**
* @var $_statusCms \Retailcrm\Retailcrm\Model\Config\Backend\StatusCms
*/
protected $_statusCms;
/**
* @var $_statusCrm \Retailcrm\Retailcrm\Model\Config\Backend\StatusCrm
*/
protected $_statusCrm;
/**
* @return \Magento\Framework\View\Element\BlockInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getStatusCmsRenderer()
{
if (!$this->_statusCms) {
$this->_statusCms = $this->getLayout()->createBlock(
'\Retailcrm\Retailcrm\Model\Config\Backend\StatusCms',
'',
['data' => ['is_render_to_js_template' => true]]
);
}
return $this->_statusCms;
}
/**
* @return \Magento\Framework\View\Element\BlockInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getStatusCrmRenderer()
{
if (!$this->_statusCrm) {
$this->_statusCrm = $this->getLayout()->createBlock(
'\Retailcrm\Retailcrm\Model\Config\Backend\StatusCrm',
'',
['data' => ['is_render_to_js_template' => true]]
);
}
return $this->_statusCrm;
}
/**
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _prepareToRender()
{
$this->addColumn(
'status_cms',
[
'label' => __('CMS'),
'renderer' => $this->_getStatusCmsRenderer()
]
);
$this->addColumn(
'status_crm',
[
'label' => __('CRM'),
'renderer' => $this->_getStatusCrmRenderer()
]
);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add');
}
/**
*
* @param \Magento\Framework\DataObject $row
* @throws \Magento\Framework\Exception\LocalizedException
* @return void
*/
protected function _prepareArrayRow(\Magento\Framework\DataObject $row)
{
$options = [];
$customAttribute = $row->getData('status_cms');
$key = 'option_' . $this->_getStatusCmsRenderer()->calcOptionHash($customAttribute);
$options[$key] = 'selected="selected"';
$customAttribute = $row->getData('status_crm');
$key = 'option_' . $this->_getStatusCrmRenderer()->calcOptionHash($customAttribute);
$options[$key] = 'selected="selected"';
$row->setData('option_extra_attrs', $options);
}
}

11
src/Block/Display.php Normal file
View file

@ -0,0 +1,11 @@
<?php
namespace Retailcrm\Retailcrm\Block;
class Display extends \Magento\Framework\View\Element\Template
{
public function sayHello()
{
return __('Hello World');
}
}

View file

@ -0,0 +1,85 @@
<?php
namespace Retailcrm\Retailcrm\Block\Frontend;
class DaemonCollector extends \Magento\Framework\View\Element\Template
{
private $customer;
private $helper;
private $storeResolver;
private $js = '';
private $template = <<<EOT
<script type="text/javascript">
(function(_,r,e,t,a,i,l){_['retailCRMObject']=a;_[a]=_[a]||function(){(_[a].q=_[a].q||[]).push(arguments)};_[a].l=1*new Date();l=r.getElementsByTagName(e)[0];i=r.createElement(e);i.async=!0;i.src=t;l.parentNode.insertBefore(i,l)})(window,document,'script','https://collector.retailcrm.pro/w.js','_rc');
{{ code }}
_rc('send', 'pageView');
</script>
EOT;
/**
* DaemonCollector constructor.
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Store\Api\StoreResolverInterface $storeResolver
* @param \Retailcrm\Retailcrm\Helper\Data $helper
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Customer\Model\Session $customerSession,
\Magento\Store\Api\StoreResolverInterface $storeResolver,
\Retailcrm\Retailcrm\Helper\Data $helper,
array $data = []
) {
parent::__construct($context, $data);
$this->customer = $customerSession->getCustomer();
$this->storeResolver = $storeResolver;
$this->helper = $helper;
}
/**
* @return string
*/
public function getJs()
{
return $this->js;
}
/**
* @return $this
*/
public function buildScript()
{
$params = array();
if ($this->customer->getId()) {
$params['customerId'] = $this->customer->getId();
}
try {
$siteKey = $this->helper->getSiteKey(
$this->_storeManager->getStore(
$this->storeResolver->getCurrentStoreId()
)->getWebsiteId()
);
} catch (\Magento\Framework\Exception\NoSuchEntityException $entityException) {
return $this;
}
if ($siteKey) {
$this->js = preg_replace(
'/{{ code }}/',
sprintf(
"\t_rc('create', '%s', %s);\n",
$siteKey,
json_encode((object) $params)
),
$this->template
);
}
return $this;
}
}

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 int
*/
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 0;
}
/** @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 0;
}
}

View file

@ -0,0 +1,79 @@
<?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 IcmlGenerate extends Command
{
private $icml;
private $storeManager;
private $appState;
public function __construct(
\Retailcrm\Retailcrm\Model\Icml\Icml $icml,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\App\State $appState
) {
$this->icml = $icml;
$this->storeManager = $storeManager;
$this->appState = $appState;
parent::__construct();
}
protected function configure()
{
$this->setName('retailcrm:icml:generate')
->setDescription('Generating ICML catalog in root directory')
->addArgument('website', InputArgument::OPTIONAL, 'Website id');
parent::configure();
}
/**
* Generate ICML catalog
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @throws \Exception
*
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);
$arguments = $input->getArguments();
$websites = [];
if (isset($arguments['website'])) {
$websites[] = $this->storeManager->getWebsite($arguments['website']);
} else {
$websites = $this->storeManager->getWebsites();
}
if (!$websites) {
$output->writeln('<comment>Websites not found</comment>');
return 0;
}
foreach ($websites as $website) {
try {
$this->icml->generate($website);
} catch (\Exception $exception) {
$output->writeln('<comment>' . $exception->getMessage() . '</comment>');
return 1;
}
}
return 0;
}
}

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

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

View file

@ -4,18 +4,18 @@ namespace Retailcrm\Retailcrm\Controller\Index;
class Display extends \Magento\Framework\App\Action\Action
{
protected $_pageFactory;
private $pageFactory;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $pageFactory
) {
$this->_pageFactory = $pageFactory;
return parent::__construct($context);
$this->pageFactory = $pageFactory;
parent::__construct($context);
}
public function execute()
{
return $this->_pageFactory->create();
return $this->pageFactory->create();
}
}
}

29
src/Cron/Icml.php Normal file
View file

@ -0,0 +1,29 @@
<?php
namespace Retailcrm\Retailcrm\Cron;
class Icml
{
private $logger;
private $icml;
private $storeManager;
public function __construct(
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Retailcrm\Retailcrm\Model\Icml\Icml $icml,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->logger = $logger;
$this->icml = $icml;
$this->storeManager = $storeManager;
}
public function execute()
{
$websites = $this->storeManager->getWebsites();
foreach ($websites as $website) {
$this->icml->generate($website);
}
}
}

24
src/Cron/Inventories.php Normal file
View file

@ -0,0 +1,24 @@
<?php
namespace Retailcrm\Retailcrm\Cron;
class Inventories
{
private $inventoriesUpload;
private $helper;
public function __construct(
\Retailcrm\Retailcrm\Helper\Data $helper,
\Retailcrm\Retailcrm\Model\Service\InventoriesUpload $InventoriesUpload
) {
$this->helper = $helper;
$this->inventoriesUpload = $InventoriesUpload;
}
public function execute()
{
if ($this->helper->getInventoriesUpload() == true) {
$this->inventoriesUpload->uploadInventory();
}
}
}

23
src/Cron/OrderHistory.php Normal file
View file

@ -0,0 +1,23 @@
<?php
namespace Retailcrm\Retailcrm\Cron;
class OrderHistory
{
private $logger;
private $history;
public function __construct(
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Retailcrm\Retailcrm\Model\History\Exchange $history
) {
$this->logger = $logger;
$this->history = $history;
}
public function execute()
{
$this->history->ordersHistory();
$this->logger->writeRow('Cron Works: OrderHistory');
}
}

268
src/Helper/Data.php Normal file
View file

@ -0,0 +1,268 @@
<?php
namespace Retailcrm\Retailcrm\Helper;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\ScopeInterface;
class Data extends AbstractHelper
{
private $storeManager;
const XML_PATH_RETAILCRM = 'retailcrm/';
const XML_PATH_DEFAULT_SITE = 'retailcrm_site/default';
const XML_PATH_SITES = 'retailcrm_sites/';
const XML_PATH_DAEMON_COLLECTOR = 'daemon_collector/';
const XML_PATH_INVENTORIES = 'inventories_upload/';
public function __construct(
Context $context,
StoreManagerInterface $storeManager
) {
$this->storeManager = $storeManager;
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(
$field,
ScopeInterface::SCOPE_STORE,
$storeId
);
}
/**
* Get site code
*
* @param $store
*
* @return mixed|null
* @throws \Exception
*/
public function getSite($store)
{
if (is_int($store)) {
$store = $this->storeManager->getStore($store);
}
$websitesConfig = $this->scopeConfig->getValue(
self::XML_PATH_RETAILCRM . self::XML_PATH_SITES . $store->getCode(),
ScopeInterface::SCOPE_WEBSITES
);
if (!$websitesConfig) {
$defaultSite = $this->scopeConfig->getValue(self::XML_PATH_RETAILCRM . self::XML_PATH_DEFAULT_SITE);
if (!$defaultSite) {
return null;
}
return $defaultSite;
}
return $websitesConfig;
}
/**
* @return array
*/
public function getMappingSites()
{
$sites = [];
$websites = $this->storeManager->getWebsites();
foreach ($websites as $website) {
foreach ($website->getStores() as $store) {
$site = $this->scopeConfig->getValue(
self::XML_PATH_RETAILCRM . self::XML_PATH_SITES . $store->getCode(),
ScopeInterface::SCOPE_WEBSITES,
$website->getId()
);
$sites[$site] = $store->getId();
}
}
return $sites;
}
/**
* @param $website
*
* @return array|bool
*/
public function getDaemonCollector($website)
{
$forWebsite = $this->scopeConfig->getValue(
self::XML_PATH_RETAILCRM . self::XML_PATH_DAEMON_COLLECTOR . 'active',
ScopeInterface::SCOPE_WEBSITES,
$website
);
if ($forWebsite) {
return [
'website' => $website,
'active' => $forWebsite
];
}
$forDefault = $this->scopeConfig->getValue(
self::XML_PATH_RETAILCRM . self::XML_PATH_DAEMON_COLLECTOR . 'active',
ScopeConfigInterface::SCOPE_TYPE_DEFAULT
);
if ($forDefault) {
return [
'website' => 0,
'active' => $forDefault
];
}
return false;
}
public function getInventoriesUpload()
{
$inventories = $this->scopeConfig->getValue(
self::XML_PATH_RETAILCRM . self::XML_PATH_INVENTORIES . 'active',
ScopeConfigInterface::SCOPE_TYPE_DEFAULT
);
if ($inventories) {
return true;
}
return false;
}
/**
* @param $website
*
* @return bool|mixed
*/
public function getSiteKey($website)
{
$daemonCollector = $this->getDaemonCollector($website);
if ($daemonCollector === false) {
return false;
}
if ($daemonCollector['active']) {
if ($daemonCollector['website'] > 0) {
return $this->scopeConfig->getValue(
self::XML_PATH_RETAILCRM . self::XML_PATH_DAEMON_COLLECTOR . 'key',
ScopeInterface::SCOPE_WEBSITES,
$website
);
} else {
return $this->scopeConfig->getValue(
self::XML_PATH_RETAILCRM . self::XML_PATH_DAEMON_COLLECTOR . 'key',
ScopeConfigInterface::SCOPE_TYPE_DEFAULT
);
}
}
return false;
}
/**
* Recursive array filter
*
* @param array $haystack input array
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.ElseExpression)
*
* @return array
*/
public static function filterRecursive($haystack)
{
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = self::filterRecursive($haystack[$key]);
}
if ($haystack[$key] === null
|| $haystack[$key] === ''
|| (is_array($haystack[$key]) && empty($haystack[$key]))
) {
unset($haystack[$key]);
} elseif (!is_array($value)) {
$haystack[$key] = trim($value);
}
}
return $haystack;
}
/**
* @return mixed
*/
public function getConfigPayments()
{
$json = $this->scopeConfig->getValue('retailcrm/paymentList/paymentList');
$List = $this->getConfigJsonUnserialize($json);
foreach ($List as $code => $el) {
$payments[$el['payment_cms']] = $el['payment_crm'];
}
return $payments;
}
/**
* @return mixed
*/
public function getCongigShipping()
{
$json = $this->scopeConfig->getValue('retailcrm/shippingList/shippingList');
$shippingList = $this->getConfigJsonUnserialize($json);
foreach ($shippingList as $code => $el) {
$shippings[$el['shipping_cms']] = $el['shipping_crm'];
}
return $shippings;
}
/**
* @return mixed
*/
public function getCongigStatus()
{
$json = $this->scopeConfig->getValue('retailcrm/statusList/statusList');
$List = $this->getConfigJsonUnserialize($json);
foreach ($List as $code => $el) {
$statusList[$el['status_cms']] = $el['status_crm'];
}
return $statusList;
}
/**
* @param $json
*
* @return mixed
*/
public function getConfigJsonUnserialize($json)
{
if (class_exists(\Magento\Framework\Serialize\Serializer\Json::class)) {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$serializer = $objectManager->create(\Magento\Framework\Serialize\Serializer\Json::class);
return $serializer->unserialize($json);
} else {
return json_decode($json);
}
}
}

176
src/Helper/Proxy.php Normal file
View file

@ -0,0 +1,176 @@
<?php
namespace Retailcrm\Retailcrm\Helper;
use Retailcrm\Retailcrm\Model\Logger\Logger;
use Retailcrm\Retailcrm\Model\Service\ConfigManager;
use Retailcrm\Retailcrm\ApiClient\ApiClientFactory;
class Proxy
{
private $logger;
private $apiClient;
private $url;
private $apiKey;
private $version;
private $apiClientFactory;
private $errorAccount = 'Account does not exist.';
private $errorNotFound = 'Not found';
private $errorApiKey = 'Wrong "apiKey" value.';
/**
* Proxy constructor.
* @param string $pathUrl
* @param string $pathKey
* @param string $pathVersion
* @param ConfigManager $config
* @param Logger $logger
* @param ApiClientFactory $apiClientFactory
*/
public function __construct(
$pathUrl,
$pathKey,
$pathVersion,
ConfigManager $config,
Logger $logger,
ApiClientFactory $apiClientFactory
) {
$this->logger = $logger;
$this->url = $config->getConfigValue($pathUrl);
$this->apiKey = $config->getConfigValue($pathKey);
$this->version = $config->getConfigValue($pathVersion);
$this->apiClientFactory = $apiClientFactory;
if ($this->isConfigured()) {
$this->init();
}
}
public function __call($method, $arguments)
{
try {
$response = call_user_func_array([$this->apiClient->request, $method], $arguments);
if (!$response->isSuccessful()) {
$this->logger->writeRow(
sprintf(
"[HTTP status %s] %s - %s",
$response->getStatusCode(),
$method,
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
$this->logger->writeRow(implode(' :: ', $response['errors']));
}
}
} catch (\RetailCrm\Exception\CurlException $exception) {
$this->logger->writeRow($exception->getMessage());
return false;
} catch (\RetailCrm\Exception\InvalidJsonException $exception) {
$this->logger->writeRow($exception->getMessage());
return false;
} catch (\InvalidArgumentException $exception) {
$this->logger->writeRow($exception->getMessage());
}
return $response;
}
/**
* Init retailcrm api client
*/
public function init()
{
$this->apiClient = $this->apiClientFactory->create(
$this->url,
$this->apiKey,
$this->version
);
}
/**
* @param $url
*/
public function setUrl($url)
{
$this->url = $url;
}
/**
* @param $apiKey
*/
public function setApiKey($apiKey)
{
$this->apiKey = $apiKey;
}
/**
* @param $version
*/
public function setVersion($version)
{
$this->version = $version;
}
/**
* @return bool
*/
public function isConfigured()
{
return $this->url && $this->apiKey;
}
/**
* Get API version
*
* @return string
*/
public function getVersion()
{
if (!is_object($this->apiClient)) {
return false;
}
return $this->apiClient->getVersion();
}
/**
* Set site code
*
* @param $site
*/
public function setSite($site)
{
if ($this->isConfigured()) {
$this->apiClient->request->setSite($site);
}
}
/**
* Get site code
*
* @return null | mixed
*/
public function getSite()
{
if ($this->isConfigured()) {
return $this->apiClient->request->getSite();
}
return null;
}
/**
* Get error text message
*
* @param string $property
*
* @return string
*/
public function getErrorText($property)
{
return $this->{$property};
}
}

View file

@ -6,15 +6,17 @@ use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class ApiUrl extends \Magento\Framework\App\Config\Value
{
private $api;
/**
* ApiUrl constructor.
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
* @param \Magento\Framework\App\Config\ValueFactory $configValueFactory
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param string $runModelPath
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
* @param ApiClient $api
* @param array $data
*/
public function __construct(
@ -22,71 +24,65 @@ class ApiUrl extends \Magento\Framework\App\Config\Value
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
ApiClient $api,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
) {
$this->api = $api;
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
}
/**
* Call before save api url
*
*
* @throws \Magento\Framework\Exception\ValidatorException
*
* @return void
*/
public function beforeSave()
{
$apiUrl = $this->getValue();
$apiKey = $this->getFieldsetDataValue('api_key');
$apiVersion = $this->getFieldsetDataValue('api_version');
$this->setParams([
'url' => $this->getValue(),
'apiKey' => $this->getFieldsetDataValue('api_key'),
'version' => $this->getFieldsetDataValue('api_version')
]);
if (!$this->isUrl($apiUrl)) {
if (!$this->isUrl($this->getValue())) {
throw new \Magento\Framework\Exception\ValidatorException(__('Invalid CRM url'));
}
if (!$this->isHttps($apiUrl)) {
$this->schemeEdit($apiUrl);
if (!$this->isHttps($this->getValue())) {
$this->schemeEdit($this->getValue());
}
$api = new ApiClient($apiUrl, $apiKey, $apiVersion);
if ($this->validateApiUrl($api)) {
$this->setValue($apiUrl);
if ($this->validateApiUrl($this->api)) {
$this->setValue($this->getValue());
}
parent::beforeSave();
}
/**
* Call after save api url
*
* @return void
*/
public function afterSave()
{
return parent::afterSave();
}
/**
* Validate selected api url
*
*
* @param ApiClient $api
* @param string $apiVersion
*
*
* @throws \Magento\Framework\Exception\ValidatorException
*
*
* @return boolean
*/
protected function validateApiUrl(ApiClient $api)
private function validateApiUrl(ApiClient $api)
{
$response = $api->availableVersions();
if ($response === false) {
throw new \Magento\Framework\Exception\ValidatorException(__('Verify that the data entered 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(__('Make sure that the entered data is correct'));
} elseif (!$response->isSuccessful() && $response['errorMsg'] == $api->getErrorText('errorApiKey')) {
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;
@ -94,12 +90,12 @@ class ApiUrl extends \Magento\Framework\App\Config\Value
/**
* Check url scheme
*
*
* @param string $url
*
*
* @return boolean
*/
protected function isHttps($url)
private function isHttps($url)
{
$url_array = parse_url($url);
@ -112,12 +108,12 @@ class ApiUrl extends \Magento\Framework\App\Config\Value
/**
* Edit scheme from http to https
*
*
* @param string $url
*
*
* @return string
*/
protected function schemeEdit(&$url)
private function schemeEdit(&$url)
{
$url_array = parse_url($url);
@ -126,13 +122,24 @@ class ApiUrl extends \Magento\Framework\App\Config\Value
/**
* Check url
*
*
* @param string $url
*
*
* @return type
*/
public function isUrl($url)
{
return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
}
/**
* @param array $data
*/
private function setParams(array $data)
{
$this->api->setUrl($data['url']);
$this->api->setApiKey($data['apiKey']);
$this->api->setVersion($data['version']);
$this->api->init();
}
}

View file

@ -6,15 +6,21 @@ use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class ApiVersion extends \Magento\Framework\App\Config\Value
{
private $api;
private $request;
private $integrationModule;
/**
* ApiVersion constructor.
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
* @param \Magento\Framework\App\Config\ValueFactory $configValueFactory
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param string $runModelPath
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
* @param \Magento\Framework\App\Request\Http $request
* @param \Retailcrm\Retailcrm\Model\Service\IntegrationModule $integrationModule
* @param ApiClient $api
* @param array $data
*/
public function __construct(
@ -24,50 +30,47 @@ class ApiVersion extends \Magento\Framework\App\Config\Value
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
\Magento\Framework\App\Request\Http $request,
\Retailcrm\Retailcrm\Model\Service\IntegrationModule $integrationModule,
ApiClient $api,
array $data = []
) {
$this->api = $api;
$this->request = $request;
$this->integrationModule = $integrationModule;
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
}
/**
* Call before save api version
*
*
* @return void
*/
public function beforeSave()
{
$apiUrl = $this->getFieldsetDataValue('api_url');
$apiKey = $this->getFieldsetDataValue('api_key');
$apiVersion = $this->getValue();
$this->setParams([
'url' => $this->getFieldsetDataValue('api_url'),
'apiKey' => $this->getFieldsetDataValue('api_key'),
'version' => $this->getValue()
]);
$api = new ApiClient($apiUrl, $apiKey, $apiVersion);
$this->validateApiVersion($api, $apiVersion);
$this->validateApiVersion($this->api, $this->getValue());
parent::beforeSave();
}
/**
* Call after save api version
*
* @return void
*/
public function afterSave()
{
return parent::afterSave();
}
/**
* Validate selected api version
*
*
* @param ApiClient $api
* @param string $apiVersion
*
*
* @throws \Magento\Framework\Exception\ValidatorException
*
*
* @return void
*/
protected function validateApiVersion(ApiClient $api, $apiVersion)
private function validateApiVersion(ApiClient $api, $apiVersion)
{
$apiVersions = [
'v4' => '4.0',
@ -79,15 +82,40 @@ 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());
$this->sendModuleConfiguration($api);
} else {
throw new \Magento\Framework\Exception\ValidatorException(__('Selected api version forbidden'));
throw new \Magento\Framework\Exception\ValidatorException(
__('The selected API version is unavailable')
);
}
}
}
/**
* @param $api
*/
private function sendModuleConfiguration($api)
{
$this->integrationModule->setApiVersion($api->getVersion());
$this->integrationModule->setAccountUrl($this->request->getUriString());
$this->integrationModule->sendConfiguration($api);
}
/**
* @param array $data
*/
private function setParams(array $data)
{
$this->api->setUrl($data['url']);
$this->api->setApiKey($data['apiKey']);
$this->api->setVersion($data['version']);
$this->api->init();
}
}

View file

@ -0,0 +1,71 @@
<?php
namespace Retailcrm\Retailcrm\Model\Config\Backend;
class PaymentCms extends \Magento\Framework\View\Element\Html\Select
{
/**
* @var \Magento\Payment\Model\Config
*/
private $paymentConfig;
/**
* @var \Retailcrm\Retailcrm\Model\Logger\Logger
*/
private $logger;
/**
* PaymentCms constructor.
*
* @param \Magento\Framework\View\Element\Context $context
* @param \Magento\Payment\Model\Config $paymentConfig
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Context $context,
\Magento\Payment\Model\Config $paymentConfig,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
array $data = []
) {
parent::__construct($context, $data);
$this->paymentConfig = $paymentConfig;
$this->logger = $logger;
}
/**
* @param string $value
* @return Magently\Tutorial\Block\Adminhtml\Form\Field\Activation
*/
public function setInputName($value)
{
return $this->setName($value);
}
/**
* Parse to html.
*
* @return mixed
*/
public function _toHtml()
{
if (!$this->getOptions()) {
$paymentMethods = array();
try {
$paymentMethods = $this->paymentConfig->getActiveMethods();
} catch (\Exception $exception) {
$this->logger->writeRow($exception->getMessage());
}
$this->addOption( 'null', "not selected");
if ($paymentMethods) {
foreach ($paymentMethods as $code => $payment) {
$this->addOption($payment->getCode(), $payment->getTitle());
}
}
}
return parent::_toHtml();
}
}

View file

@ -0,0 +1,75 @@
<?php
namespace Retailcrm\Retailcrm\Model\Config\Backend;
class PaymentCrm extends \Magento\Framework\View\Element\Html\Select
{
/**
* @var \Retailcrm\Retailcrm\Helper\Proxy
*/
private $client;
/**
* @var \Retailcrm\Retailcrm\Model\Logger\Logger
*/
private $logger;
/**
* Activation constructor.
*
* @param \Magento\Framework\View\Element\Context $context
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Context $context,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
array $data = []
) {
parent::__construct($context, $data);
$this->client = $client;
$this->logger = $logger;
}
/**
* @param string $value
* @return Magently\Tutorial\Block\Adminhtml\Form\Field\Activation
*/
public function setInputName($value)
{
return $this->setName($value);
}
/**
* Parse to html.
*
* @return mixed
*/
public function _toHtml()
{
if (!$this->getOptions()) {
$paymentsTypes = array();
try {
$response = $this->client->paymentTypesList();
} catch (\Exception $exception) {
$this->logger->writeRow($exception->getMessage());
}
if (isset($response) && $response->isSuccessful()) {
$paymentsTypes = $response['paymentTypes'];
}
$this->addOption( 'null', "not selected");
if ($paymentsTypes) {
foreach ($paymentsTypes as $paymentsType) {
$this->addOption($paymentsType['code'], $paymentsType['name']);
}
}
}
return parent::_toHtml();
}
}

View file

@ -0,0 +1,72 @@
<?php
namespace Retailcrm\Retailcrm\Model\Config\Backend;
class ShippingCms extends \Magento\Framework\View\Element\Html\Select
{
/**
* @var \Magento\Shipping\Model\Config
*/
private $shippingConfig;
/**
* @var \Retailcrm\Retailcrm\Model\Logger\Logger
*/
private $logger;
/**
* ShippingColumn constructor.
*
* @param \Magento\Framework\View\Element\Context $context
* @param \Magento\Shipping\Model\Config $shippingConfig
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Context $context,
\Magento\Shipping\Model\Config $shippingConfig,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
array $data = []
) {
parent::__construct($context, $data);
$this->shippingConfig = $shippingConfig;
$this->logger = $logger;
}
/**
* @param string $value
* @return Magently\Tutorial\Block\Adminhtml\Form\Field\Activation
*/
public function setInputName($value)
{
return $this->setName($value);
}
/**
* Parse to html.
*
* @return mixed
*/
public function _toHtml()
{
if (!$this->getOptions()) {
$deliveryMethods = array();
try {
$deliveryMethods = $this->shippingConfig->getActiveCarriers();
} catch (\Exception $exception) {
$this->logger->writeRow($exception->getMessage());
}
$this->addOption( 'null', "not selected");
if ($deliveryMethods) {
foreach ($deliveryMethods as $code => $delivery) {
$this->addOption($delivery->getCarrierCode(), $delivery->getConfigData('title'));
}
}
}
return parent::_toHtml();
}
}

View file

@ -0,0 +1,74 @@
<?php
namespace Retailcrm\Retailcrm\Model\Config\Backend;
class ShippingCrm extends \Magento\Framework\View\Element\Html\Select
{
/**
* @var \Retailcrm\Retailcrm\Helper\Proxy
*/
private $client;
/**
* @var \Retailcrm\Retailcrm\Model\Logger\Logger
*/
private $logger;
/**
* Activation constructor.
*
* @param \Magento\Framework\View\Element\Context $context
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Context $context,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
array $data = []
) {
parent::__construct($context, $data);
$this->client = $client;
$this->logger = $logger;
}
/**
* @param string $value
* @return Magently\Tutorial\Block\Adminhtml\Form\Field\Activation
*/
public function setInputName($value)
{
return $this->setName($value);
}
/**
* Parse to html.
*
* @return mixed
*/
public function _toHtml()
{
if (!$this->getOptions()) {
$deliveryTypes = array();
try {
$response = $this->client->deliveryTypesList();
} catch (\Exception $exception) {
$this->logger->writeRow($exception->getMessage());
}
if (isset($response) && $response->isSuccessful()) {
$deliveryTypes = $response['deliveryTypes'];
}
$this->addOption( 'null', "not selected");
if ($deliveryTypes) {
foreach ($deliveryTypes as $deliveryType) {
$this->addOption($deliveryType['code'], $deliveryType['name']);
}
}
}
return parent::_toHtml();
}
}

View file

@ -0,0 +1,71 @@
<?php
namespace Retailcrm\Retailcrm\Model\Config\Backend;
class StatusCms extends \Magento\Framework\View\Element\Html\Select
{
/**
* @var \Magento\Sales\Model\ResourceModel\Order\Status\Collection
*/
private $statusCollection;
/**
* @var \Retailcrm\Retailcrm\Model\Logger\Logger
*/
private $logger;
/**
* StatusCms constructor.
*
* @param \Magento\Framework\View\Element\Context $context
* @param \Magento\Sales\Model\ResourceModel\Order\Status\Collection $statusCollection
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Context $context,
\Magento\Sales\Model\ResourceModel\Order\Status\Collection $statusCollection,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
array $data = []
) {
parent::__construct($context, $data);
$this->statusCollection = $statusCollection;
$this->logger = $logger;
}
/**
* @param string $value
* @return Magently\Tutorial\Block\Adminhtml\Form\Field\Activation
*/
public function setInputName($value)
{
return $this->setName($value);
}
/**
* Parse to html.
*
* @return mixed
*/
public function _toHtml()
{
if (!$this->getOptions()) {
$statuses = array();
try {
$statuses = $this->statusCollection->toOptionArray();
} catch (\Exception $exception) {
$this->logger->writeRow($exception->getMessage());
}
$this->addOption( 'null', "not selected");
if ($statuses) {
foreach ($statuses as $code => $status) {
$this->addOption( $status['value'], $status['label']);
}
}
}
return parent::_toHtml();
}
}

View file

@ -0,0 +1,75 @@
<?php
namespace Retailcrm\Retailcrm\Model\Config\Backend;
class StatusCrm extends \Magento\Framework\View\Element\Html\Select
{
/**
* @var \Retailcrm\Retailcrm\Helper\Proxy
*/
private $client;
/**
* @var \Retailcrm\Retailcrm\Model\Logger\Logger
*/
private $logger;
/**
* Activation constructor.
*
* @param \Magento\Framework\View\Element\Context $context
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Context $context,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
array $data = []
) {
parent::__construct($context, $data);
$this->client = $client;
$this->logger = $logger;
}
/**
* @param string $value
* @return Magently\Tutorial\Block\Adminhtml\Form\Field\Activation
*/
public function setInputName($value)
{
return $this->setName($value);
}
/**
* Parse to html.
*
* @return mixed
*/
public function _toHtml()
{
if (!$this->getOptions()) {
$statuses = array();
try {
$response = $this->client->statusesList();
} catch (\Exception $exception) {
$this->logger->writeRow($exception->getMessage());
}
if (isset($response) && $response->isSuccessful()) {
$statuses = $response['statuses'];
}
$this->addOption( 'null', "not selected");
if ($statuses) {
foreach ($statuses as $status) {
$this->addOption($status['code'], $status['name']);
}
}
}
return parent::_toHtml();
}
}

View file

@ -2,102 +2,94 @@
namespace Retailcrm\Retailcrm\Model\History;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class Exchange
{
protected $_api;
protected $_config;
protected $_helper;
protected $_logger;
protected $_resourceConfig;
protected $_customerFactory;
protected $_quote;
protected $_customerRepository;
protected $_product;
protected $_shipconfig;
protected $_quoteManagement;
protected $_registry;
protected $_cacheTypeList;
protected $_order;
protected $_orderManagement;
//protected $_transaction;
//protected $_invoiceService;
protected $_eventManager;
protected $_objectManager;
private $api;
private $config;
private $helper;
private $logger;
private $resourceConfig;
private $customerFactory;
private $quote;
private $customerRepository;
private $product;
private $shipconfig;
private $quoteManagement;
private $registry;
private $cacheTypeList;
private $order;
private $orderManagement;
private $orderInterface;
private $storeManager;
private $regionFactory;
public function __construct()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$helper = $objectManager->get('\Retailcrm\Retailcrm\Helper\Data');
$config = $objectManager->get('\Magento\Framework\App\Config\ScopeConfigInterface');
$resourceConfig = $objectManager->get('Magento\Config\Model\ResourceModel\Config');
$customerFactory = $objectManager->get('\Magento\Customer\Model\CustomerFactory');
$quote = $objectManager->get('\Magento\Quote\Model\QuoteFactory');
$customerRepository = $objectManager->get('\Magento\Customer\Api\CustomerRepositoryInterface');
$product = $objectManager->get('\Magento\Catalog\Model\Product');
$shipconfig = $objectManager->get('\Magento\Shipping\Model\Config');
$quoteManagement = $objectManager->get('\Magento\Quote\Model\QuoteManagement');
$registry = $objectManager->get('\Magento\Framework\Registry');
$cacheTypeList = $objectManager->get('\Magento\Framework\App\Cache\TypeListInterface');
$order = $objectManager->get('\Magento\Sales\Api\Data\OrderInterface');
$orderManagement = $objectManager->get('\Magento\Sales\Api\OrderManagementInterface');
//$invoiceService = $objectManager->get('\Magento\Sales\Model\Service\InvoiceService');
//$transaction = $objectManager->get('\Magento\Framework\DB\Transaction');
$eventManager = $objectManager->get('\Magento\Framework\Event\Manager');
$logger = new \Retailcrm\Retailcrm\Model\Logger\Logger($objectManager);
$this->_shipconfig = $shipconfig;
$this->_logger = $logger;
$this->_helper = $helper;
$this->_config = $config;
$this->_resourceConfig = $resourceConfig;
$this->_customerFactory = $customerFactory;
$this->_quote = $quote;
$this->_customerRepository = $customerRepository;
$this->_product = $product;
$this->_quoteManagement = $quoteManagement;
$this->_registry = $registry;
$this->_cacheTypeList = $cacheTypeList;
$this->_order = $order;
$this->_orderManagement = $orderManagement;
//$this->_transaction = $transaction;
//$this->_invoiceService = $invoiceService;
$this->_eventManager = $eventManager;
$this->_objectManager = $objectManager;
$url = $config->getValue('retailcrm/general/api_url');
$key = $config->getValue('retailcrm/general/api_key');
$version = $config->getValue('retailcrm/general/api_version');
if (!empty($url) && !empty($key)) {
$this->_api = new ApiClient($url, $key, $version);
}
public function __construct(
\Retailcrm\Retailcrm\Helper\Data $helper,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Config\Model\ResourceModel\Config $resourceConfig,
\Magento\Customer\Model\CustomerFactory $customerFactory,
\Magento\Quote\Model\QuoteFactory $quote,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
\Magento\Catalog\Model\Product $product,
\Magento\Shipping\Model\Config $shipconfig,
\Magento\Quote\Model\QuoteManagement $quoteManagement,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Sales\Api\Data\OrderInterface $orderInterface,
\Magento\Sales\Api\OrderManagementInterface $orderManagement,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Magento\Sales\Model\Order $order,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Directory\Model\RegionFactory $regionFactory,
\Retailcrm\Retailcrm\Helper\Proxy $api
) {
$this->shipconfig = $shipconfig;
$this->logger = $logger;
$this->helper = $helper;
$this->config = $config;
$this->resourceConfig = $resourceConfig;
$this->customerFactory = $customerFactory;
$this->quote = $quote;
$this->customerRepository = $customerRepository;
$this->product = $product;
$this->quoteManagement = $quoteManagement;
$this->registry = $registry;
$this->cacheTypeList = $cacheTypeList;
$this->orderInterface = $orderInterface;
$this->orderManagement = $orderManagement;
$this->order = $order;
$this->storeManager = $storeManager;
$this->regionFactory = $regionFactory;
$this->api = $api;
}
/**
* Get orders history from CRM
*
*
* @return boolean
*/
public function ordersHistory()
{
$this->_registry->register('RETAILCRM_HISTORY', true);
if (!$this->api->isConfigured()) {
return false;
}
$this->registry->register('RETAILCRM_HISTORY', true);
$historyFilter = [];
$historyOrder = [];
$historyStart = $this->_config->getValue('retailcrm/general/filter_history');
$historyStart = $this->config->getValue('retailcrm/general/filter_history');
if ($historyStart && $historyStart > 0) {
$historyFilter['sinceId'] = $historyStart;
}
while (true) {
$response = $this->_api->ordersHistory($historyFilter);
$response = $this->api->ordersHistory($historyFilter);
if ($response === false) {
return;
return false;
}
if (!$response->isSuccessful()) {
@ -106,7 +98,7 @@ class Exchange
$orderH = isset($response['history']) ? $response['history'] : [];
if (count($orderH) == 0) {
if (empty($orderH)) {
return true;
}
@ -115,32 +107,37 @@ class Exchange
$historyFilter['sinceId'] = $end['id'];
if ($response['pagination']['totalPageCount'] == 1) {
$this->_resourceConfig->saveConfig('retailcrm/general/filter_history', $historyFilter['sinceId'], 'default', 0);
$this->_cacheTypeList->cleanType('config');
$this->resourceConfig->saveConfig(
'retailcrm/general/filter_history',
$historyFilter['sinceId'],
'default',
0
);
$this->cacheTypeList->cleanType('config');
$orders = self::assemblyOrder($historyOrder);
$this->_logger->writeDump($orders,'OrderHistory');
$this->logger->writeDump($orders, 'OrderHistory');
$this->processOrders($orders);
return true;
}
}//endwhile
}
$this->_registry->register('RETAILCRM_HISTORY', false);
$this->registry->register('RETAILCRM_HISTORY', false);
}
/**
* Process orders
*
*
* @param array $orders
*
*
* @return void
*/
private function processOrders($orders)
{
$this->_logger->writeDump($orders,'processOrders');
$this->logger->writeDump($orders, 'processOrders');
if (!empty($orders)) {
foreach ($orders as $order) {
@ -155,28 +152,33 @@ class Exchange
/**
* Create new order from CRM
*
*
* @param array $order
*
*
* @return void
*/
private function doCreate($order)
{
$this->_logger->writeDump($order,'doCreate');
$this->logger->writeDump($order, 'doCreate');
$payments = $this->_config->getValue('retailcrm/Payment');
$shippings = $this->_config->getValue('retailcrm/Shipping');
$payments = $this->helper->getConfigPayments();
$shippings = $this->helper->getCongigShipping();
$sites = $this->helper->getMappingSites();
$manager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
$region = $this->_objectManager->get('Magento\Directory\Model\RegionFactory')->create();
$store = $manager->getStore();
$websiteId = $manager->getStore()->getWebsiteId();
if ($sites && in_array($order['site'], $sites)) {
$store = $this->storeManager->getStore($sites[$order['site']]);
$websiteId = $store->getWebsiteId();
} else {
$store = $this->storeManager->getStore();
$websiteId = $this->storeManager->getStore()->getWebsiteId();
}
$customer = $this->_customerFactory->create();
$region = $this->regionFactory->create();
$customer = $this->customerFactory->create();
$customer->setWebsiteId($websiteId);
if (isset($order['customer']['externalId'])) {
$customer->load($order['customer']['externalId']);
$customer = $this->customerRepository->getById($order['customer']['externalId']);
}
if (!$customer->getId()) {
@ -188,12 +190,12 @@ class Exchange
->setEmail($order['email'])
->setPassword($order['email']);
try {
$customer->save();
$this->customerRepository->save($customer);
} catch (\Exception $exception) {
$this->_logger->writeRow($exception->getMessage());
$this->logger->writeRow($exception->getMessage());
}
$this->_api->customersFixExternalIds(
$this->api->customersFixExternalIds(
[
[
'id' => $order['customer']['id'],
@ -204,34 +206,57 @@ class Exchange
}
//Create object of quote
$quote = $this->_quote->create();
$quote = $this->quote->create();
//set store for which you create quote
$quote->setStore($store);
$quote->setStore($store);
// if you have allready buyer id then you can load customer directly
$customer = $this->_customerRepository->getById($customer->getId());
$customer = $this->customerRepository->getById($customer->getId());
$quote->setCurrency();
$quote->assignCustomer($customer); //Assign quote to customer
$manager = \Magento\Framework\App\ObjectManager::getInstance();
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
$productRepository = $manager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
$ditems = [];
foreach ($order['items'] as $item) {
if (!isset($ditems[$item['offer']['externalId']]['quantity'])) {
$ditems[$item['offer']['externalId']] = [
'quantity' => null,
'discountTotal' => null,
'initialPrice' => null,
'price_sum' => null,
'price_item' => null
];
}
$ditems[$item['offer']['externalId']]['quantity'] += $item['quantity'];
$ditems[$item['offer']['externalId']]['discountTotal'] += $item['quantity'] * $item['discountTotal'];
$ditems[$item['offer']['externalId']]['initialPrice'] = (float)$item['initialPrice'];
$ditems[$item['offer']['externalId']]['price_sum'] = $ditems[$item['offer']['externalId']]['initialPrice'] * $ditems[$item['offer']['externalId']]['quantity'] - $ditems[$item['offer']['externalId']]['discountTotal'];
$ditems[$item['offer']['externalId']]['price_item'] = $ditems[$item['offer']['externalId']]['price_sum'] / $ditems[$item['offer']['externalId']]['quantity'];
}
//add items in quote
foreach($order['items'] as $item){
$product = $this->_product->load($item['offer']['externalId']);
foreach ($ditems as $id =>$item) {
$product = $productRepository->getById($id,false, $store->getId(), false);
$product->setPrice($item['initialPrice']);
$quote->addProduct(
$product,
intval($item['quantity'])
(int)$item['quantity']
);
}
$products = [];
foreach ($order['items'] as $item) {
$products[$item['offer']['externalId']] = ['qty' => $item['quantity']];
foreach ($ditems as $id => $item) {
$products[$id] = ['product_id'=>$id,'qty' => $item['quantity']];
}
$orderData = [
'currency_id' => $manager->getStore()->getCurrentCurrency()->getCode(),
'currency_id' => $this->storeManager->getStore()->getCurrentCurrency()->getCode(),
'email' => $order['email'],
'shipping_address' => [
'firstname' => $order['firstName'],
@ -267,9 +292,9 @@ class Exchange
->collectShippingRates()
->setShippingMethod($ShippingMethods);
if ($this->_api->getVersion() == 'v4') {
if ($this->api->getVersion() == 'v4') {
$paymentType = $order['paymentType'];
} elseif ($this->_api->getVersion() == 'v5') {
} elseif ($this->api->getVersion() == 'v5') {
if ($order['payments']) {
$paymentType = $this->getPaymentMethod($order['payments']);
}
@ -278,20 +303,22 @@ class Exchange
$quote->setPaymentMethod($payments[$paymentType]);
$quote->setInventoryProcessed(false);
$quote->save();
/** @var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */
$quoteRepository = $manager->create(\Magento\Quote\Api\CartRepositoryInterface::class);
$quoteRepository->save($quote);
// Set Sales Order Payment
$quote->getPayment()->importData(['method' => $payments[$paymentType]]);
// Collect Totals & Save Quote
$quote->collectTotals()->save();
$quote->collectTotals();
$quoteRepository->save($quote);
// Create Order From Quote
$magentoOrder = $this->_quoteManagement->submit($quote);
$magentoOrder = $this->quoteManagement->submit($quote);
$increment_id = $magentoOrder->getId();
$this->_api->ordersFixExternalIds(
$this->api->ordersFixExternalIds(
[
[
'id' => $order['id'],
@ -303,16 +330,16 @@ class Exchange
/**
* Create old edited order
*
*
* @param array $order
*
*
* @return void
*/
private function doCreateUp($order)
{
$this->_logger->writeDump($order,'doCreateUp');
$response = $this->_api->ordersGet($order['id'], $by = 'id');
$manager = \Magento\Framework\App\ObjectManager::getInstance();
$this->logger->writeDump($order, 'doCreateUp');
$response = $this->api->ordersGet($order['id'], $by = 'id');
if (!$response->isSuccessful()) {
return;
@ -322,57 +349,85 @@ class Exchange
$order = $response['order'];
}
$payments = $this->_config->getValue('retailcrm/Payment');
$shippings = $this->_config->getValue('retailcrm/Shipping');
$payments = $this->helper->getConfigPayments();
$shippings = $this->helper->getCongigShipping();
$manager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
$region = $this->_objectManager->get('Magento\Directory\Model\RegionFactory')->create();
$store = $manager->getStore();
$websiteId = $manager->getStore()->getWebsiteId();
$region = $this->regionFactory->create();
$sites = $this->helper->getMappingSites();
$customer = $this->_customerFactory->create();
if ($sites && in_array($order['site'], $sites)) {
$store = $this->storeManager->getStore($sites[$order['site']]);
$websiteId = $store->getWebsiteId();
} else {
$store = $this->storeManager->getStore();
$websiteId = $this->storeManager->getStore()->getWebsiteId();
}
$customer = $this->customerFactory->create();
$customer->setWebsiteId($websiteId);
if (isset($order['customer']['externalId'])) {
$customer->load($order['customer']['externalId']); // load customet by external id
$customer = $this->customerRepository->getById($order['customer']['externalId']);
}
//Create object of quote
$quote = $this->_quote->create();
$quote = $this->quote->create();
//set store for which you create quote
$quote->setStore($store);
$quote->setCurrency();
// if you have allready buyer id then you can load customer directly
// if you have all ready buyer id then you can load customer directly
if ($customer->getId()) {
$customer = $this->_customerRepository->getById($customer->getId());
$customer = $this->customerRepository->getById($customer->getId());
$quote->assignCustomer($customer); //Assign quote to customer
} else {
$quote->setCustomerEmail($order['email']);
$quote->setCustomerIsGuest(1);
}
$ditems = [];
foreach ($order['items'] as $item) {
if (!isset($ditems[$item['offer']['externalId']]['quantity'])) {
$ditems[$item['offer']['externalId']] = [
'quantity' => null,
'discountTotal' => null,
'initialPrice' => null,
'price_sum' => null,
'price_item' => null
];
}
$ditems[$item['offer']['externalId']]['quantity'] += $item['quantity'];
$ditems[$item['offer']['externalId']]['discountTotal'] += $item['quantity'] * $item['discountTotal'];
$ditems[$item['offer']['externalId']]['initialPrice'] = (float)$item['initialPrice'];
$ditems[$item['offer']['externalId']]['price_sum'] = $ditems[$item['offer']['externalId']]['initialPrice'] * $ditems[$item['offer']['externalId']]['quantity'] - $ditems[$item['offer']['externalId']]['discountTotal'];
$ditems[$item['offer']['externalId']]['price_item'] = $ditems[$item['offer']['externalId']]['price_sum'] / $ditems[$item['offer']['externalId']]['quantity'];
}
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
$productRepository = $manager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
//add items in quote
foreach($order['items'] as $item){
$product = $this->_product->load($item['offer']['externalId']);
foreach ($ditems as $id => $item) {
$product = $productRepository->getById($id,false, $store->getId(), false);
$product->setPrice($item['initialPrice']);
$quote->addProduct(
$product,
intval($item['quantity'])
(int)$item['quantity']
);
}
$products = [];
foreach ($order['items'] as $item) {
$products[$item['offer']['externalId']] = ['qty' => $item['quantity']];
foreach ($ditems as $id => $item) {
$products[$id] = ['product_id'=>$id,'qty' => $item['quantity']];
}
$orderData = [
'currency_id' => $manager->getStore()->getCurrentCurrency()->getCode(),
'currency_id' => $this->storeManager->getStore()->getCurrentCurrency()->getCode(),
'email' => $order['email'],
'shipping_address' =>array(
'shipping_address' => [
'firstname' => $order['firstName'],
'lastname' => $order['lastName'],
'street' => $order['delivery']['address']['street'],
@ -382,7 +437,7 @@ class Exchange
'postcode' => $order['delivery']['address']['index'],
'telephone' => $order['phone'],
'save_in_address_book' => 1
),
],
'items'=> $products
];
@ -406,18 +461,17 @@ class Exchange
->collectShippingRates()
->setShippingMethod($ShippingMethods);
if ($this->_api->getVersion() == 'v4') {
if ($this->api->getVersion() == 'v4') {
$paymentType = $order['paymentType'];
} elseif ($this->_api->getVersion() == 'v5') {
} elseif ($this->api->getVersion() == 'v5') {
$paymentType = $this->getPaymentMethod($order['payments'], false);
}
$quote->setPaymentMethod($payments[$paymentType]);
$quote->setInventoryProcessed(false);
$originalId = $order['externalId'];
$oldOrder = $this->_order->load($originalId);
$oldOrder = $this->orderInterface->load($originalId);
$orderDataUp = [
'original_increment_id' => $oldOrder->getIncrementId(),
@ -428,20 +482,24 @@ class Exchange
];
$quote->setReservedOrderId($orderDataUp['increment_id']);
$quote->save();
/** @var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */
$quoteRepository = $manager->create(\Magento\Quote\Api\CartRepositoryInterface::class);
$quoteRepository->save($quote);
// Set Sales Order Payment
$quote->getPayment()->importData(['method' => $payments[$paymentType]]);
// Collect Totals & Save Quote
$quote->collectTotals()->save();
$quote->collectTotals();
$quoteRepository->save($quote);
// Create Order From Quote
$magentoOrder = $this->_quoteManagement->submit($quote,$orderDataUp);
$magentoOrder = $this->quoteManagement->submit($quote, $orderDataUp);
$oldOrder->setStatus('canceled')->save();
$increment_id = $magentoOrder->getId();
$this->_api->ordersFixExternalIds(
$this->api->ordersFixExternalIds(
[
[
'id' => $order['id'],
@ -453,23 +511,23 @@ class Exchange
/**
* Edit order
*
*
* @param array $order
*
*
* @return void
*/
private function doUpdate($order)
{
$this->_logger->writeDump($order,'doUpdate');
$this->logger->writeDump($order, 'doUpdate');
$Status = $this->_config->getValue('retailcrm/Status');
$Status = $this->helper->getCongigStatus();
$Status = array_flip(array_filter($Status));
$magentoOrder = $this->_order->load($order['externalId']);
$magentoOrder = $this->order->load($order['externalId']);
$magentoOrderArr = $magentoOrder->getData();
$this->_logger->writeDump($magentoOrderArr, 'magentoOrderArr');
$this->_logger->writeDump($Status, 'status');
$this->logger->writeDump($magentoOrderArr, 'magentoOrderArr');
$this->logger->writeDump($Status, 'status');
if ((!empty($order['order_edit'])) && ($order['order_edit'] == 1)) {
$this->doCreateUp($order);
@ -478,88 +536,21 @@ class Exchange
if (!empty($order['status'])) {
$change = $Status[$order['status']];
if($change == 'canceled'){
$this->_orderManagement->cancel($magentoOrderArr['entity_id']);
if ($change == 'canceled') {
$this->orderManagement->cancel($magentoOrderArr['entity_id']);
}
if($change == 'holded'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('holded');
$order_status->save();
}
if(($change == 'complete')||($order['status']== 'complete')){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('complete');
$order_status->save();
}
if($change == 'closed'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('closed');
$order_status->save();
}
if($change == 'processing'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('processing');
$order_status->save();
}
if($change == 'fraud'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('fraud');
$order_status->save();
}
if($change == 'payment_review'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('payment_review');
$order_status->save();
}
if($change == 'paypal_canceled_reversal'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('paypal_canceled_reversal');
$order_status->save();
}
if($change == 'paypal_reversed'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('paypal_reversed');
$order_status->save();
}
if($change == 'pending_payment'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('pending_payment');
$order_status->save();
}
if($change == 'pending_paypal'){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order_status = $objectManager->get('Magento\Sales\Model\Order')->load($magentoOrder->getId());
$order_status->setStatus('pending_paypal');
$order_status->save();
}
$order_status = $this->order->load($magentoOrder->getId());
$order_status->setStatus($change);
$order_status->save();
}
}
/**
* Assembly orders from history
*
*
* @param array $orderHistory
*
*
* @return array $orders
*/
public static function assemblyOrder($orderHistory)
@ -567,11 +558,12 @@ class Exchange
$orders = [];
foreach ($orderHistory as $change) {
$orderId = $change['order']['id'];
$change['order'] = self::removeEmpty($change['order']);
if (isset($change['order']['items'])) {
$items = [];
foreach ($change['order']['items'] as $item) {
if (isset($change['created'])) {
$item['create'] = 1;
@ -610,10 +602,13 @@ class Exchange
if (isset($change['item'])) {
if (isset($orders[$change['order']['id']]['items'])
&& $orders[$change['order']['id']]['items'][$change['item']['id']]
&& isset($orders[$change['order']['id']]['items'][$change['item']['id']])
) {
$orders[$change['order']['id']]['items'][$change['item']['id']] = array_merge($orders[$change['order']['id']]['items'][$change['item']['id']], $change['item']);
} else{
$orders[$change['order']['id']]['items'][$change['item']['id']] = array_merge(
$orders[$change['order']['id']]['items'][$change['item']['id']],
$change['item']
);
} else {
$orders[$change['order']['id']]['items'][$change['item']['id']] = $change['item'];
}
@ -631,33 +626,13 @@ class Exchange
if (!empty($change['newValue']) && $change['field'] == 'order_product.quantity') {
$orders[$change['order']['id']]['order_edit'] = 1;
}
if (!$orders[$change['order']['id']]['items'][$change['item']['id']]['create'] && $fields['item'][$change['field']]) {
$orders[$change['order']['id']]['items'][$change['item']['id']][$fields['item'][$change['field']]] = $change['newValue'];
}
} else {
if ((isset($fields['delivery'][$change['field']]))&&($fields['delivery'][$change['field']] == 'service')) {
$orders[$change['order']['id']]['delivery']['service']['code'] = self::newValue($change['newValue']);
} elseif (isset($fields['delivery'][$change['field']])) {
$orders[$change['order']['id']]['delivery'][$fields['delivery'][$change['field']]] = self::newValue($change['newValue']);
} elseif (isset($fields['orderAddress'][$change['field']])) {
$orders[$change['order']['id']]['delivery']['address'][$fields['orderAddress'][$change['field']]] = $change['newValue'];
} elseif (isset($fields['integrationDelivery'][$change['field']])) {
$orders[$change['order']['id']]['delivery']['service'][$fields['integrationDelivery'][$change['field']]] = self::newValue($change['newValue']);
} elseif (isset($fields['customerContragent'][$change['field']])) {
$orders[$change['order']['id']][$fields['customerContragent'][$change['field']]] = self::newValue($change['newValue']);
} elseif (strripos($change['field'], 'custom_') !== false) {
$orders[$change['order']['id']]['customFields'][str_replace('custom_', '', $change['field'])] = self::newValue($change['newValue']);
} elseif (isset($fields['order'][$change['field']])) {
$orders[$change['order']['id']][$fields['order'][$change['field']]] = self::newValue($change['newValue']);
}
if (isset($change['created'])) {
$orders[$change['order']['id']]['create'] = 1;
$orders[$orderId]['create'] = 1;
}
if (isset($change['deleted'])) {
$orders[$change['order']['id']]['deleted'] = 1;
$orders[$orderId]['deleted'] = 1;
}
}
}
@ -667,9 +642,9 @@ class Exchange
/**
* Remove empty elements
*
*
* @param array $inputArray
*
*
* @return array $outputArray
*/
public static function removeEmpty($inputArray)
@ -678,7 +653,7 @@ class Exchange
if (!empty($inputArray)) {
foreach ($inputArray as $key => $element) {
if(!empty($element) || $element === 0 || $element === '0') {
if (!empty($element) || $element === 0 || $element === '0') {
if (is_array($element)) {
$element = self::removeEmpty($element);
}
@ -700,28 +675,25 @@ class Exchange
*/
public static function newValue($value)
{
if(isset($value['code'])) {
if (isset($value['code'])) {
return $value['code'];
} else{
} else {
return $value;
}
}
/**
* Get shipping methods
*
*
* @param string $mcode
*
*
* @return string
*/
public function getAllShippingMethodsCode($mcode)
{
$activeCarriers = $this->_shipconfig->getActiveCarriers();
$storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
foreach($activeCarriers as $carrierCode => $carrierModel) {
$options = [];
$activeCarriers = $this->shipconfig->getActiveCarriers();
foreach ($activeCarriers as $carrierCode => $carrierModel) {
if ($carrierMethods = $carrierModel->getAllowedMethods()) {
foreach ($carrierMethods as $methodCode => $method) {
$code = $carrierCode . '_'. $methodCode;
@ -738,13 +710,13 @@ class Exchange
/**
* Get payment type for api v5
*
*
* @param array $payments
* @param boolean $newOrder
*
*
* @return mixed
*/
protected function getPaymentMethod($payments, $newOrder = true)
private function getPaymentMethod($payments, $newOrder = true)
{
if (count($payments) == 1 || $newOrder) {
$payment = reset($payments);

454
src/Model/Icml/Icml.php Normal file
View file

@ -0,0 +1,454 @@
<?php
namespace Retailcrm\Retailcrm\Model\Icml;
class Icml
{
private $dd;
private $eCategories;
private $eOffers;
private $shop;
private $manager;
private $category;
private $storeManager;
private $StockState;
private $configurable;
private $config;
private $dirList;
private $ddFactory;
private $resourceModelProduct;
private $searchCriteriaBuilder;
private $productRepository;
private $dimensionFields = ['height', 'length', 'width'];
public function __construct(
\Magento\Store\Model\StoreManagerInterface $manager,
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
\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\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->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($website)
{
$this->shop = $website;
$string = '<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="'.date('Y-m-d H:i:s').'">
<shop>
<name>' . $website->getName() . '</name>
<categories/>
<offers/>
</shop>
</yml_catalog>
';
$xml = simplexml_load_string(
$string,
'\Magento\Framework\Simplexml\Element',
LIBXML_NOENT | LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE
);
$this->dd = $this->ddFactory->create();
$this->dd->preserveWhiteSpace = false;
$this->dd->formatOutput = true;
$this->dd->loadXML($xml->asXML());
$this->eCategories = $this->dd
->getElementsByTagName('categories')->item(0);
$this->eOffers = $this->dd
->getElementsByTagName('offers')->item(0);
$this->addCategories();
$this->addOffers();
$this->dd->saveXML();
$this->dd->save($this->dirList->getRoot() . '/retailcrm_' . $website->getCode() . '.xml');
}
/**
* Add product categories in icml catalog
*
* @return void
*/
private function addCategories()
{
$collection = $this->category->create();
$collection->addAttributeToSelect('*');
foreach ($collection as $category) {
if ($category->getId() > 1) {
$e = $this->eCategories->appendChild(
$this->dd->createElement('category')
);
$e->appendChild($this->dd->createElement('name', \htmlspecialchars($category->getName())));
if ($category->getImageUrl()) {
$e->appendChild($this->dd->createElement('picture', \htmlspecialchars($category->getImageUrl())));
}
$e->setAttribute('id', $category->getId());
if ($category->getParentId() > 1) {
$e->setAttribute('parentId', $category->getParentId());
}
}
}
}
/**
* Write products in icml catalog
*
* @return void
*/
private function addOffers()
{
$offers = $this->buildOffers();
foreach ($offers as $offer) {
$this->addOffer($offer);
}
}
/**
* Write product in icml catalog
*
* @param array $offer
*
* @return void
*/
private function addOffer($offer)
{
$e = $this->eOffers->appendChild(
$this->dd->createElement('offer')
);
$e->setAttribute('id', $offer['id']);
$e->setAttribute('productId', $offer['productId']);
if (!empty($offer['quantity'])) {
$e->setAttribute('quantity', (int) $offer['quantity']);
} else {
$e->setAttribute('quantity', 0);
}
if (!empty($offer['categoryId'])) {
foreach ($offer['categoryId'] as $categoryId) {
$e->appendChild(
$this->dd->createElement('categoryId')
)->appendChild(
$this->dd->createTextNode($categoryId)
);
}
} else {
$e->appendChild($this->dd->createElement('categoryId', 1));
}
$e->appendChild($this->dd->createElement('productActivity'))
->appendChild(
$this->dd->createTextNode($offer['productActivity'])
);
$e->appendChild($this->dd->createElement('name'))
->appendChild(
$this->dd->createTextNode($offer['name'])
);
$e->appendChild($this->dd->createElement('productName'))
->appendChild(
$this->dd->createTextNode($offer['productName'])
);
$e->appendChild($this->dd->createElement('price'))
->appendChild(
$this->dd->createTextNode($offer['initialPrice'])
);
if (!empty($offer['purchasePrice'])) {
$e->appendChild($this->dd->createElement('purchasePrice'))
->appendChild(
$this->dd->createTextNode($offer['purchasePrice'])
);
}
if (!empty($offer['picture'])) {
$e->appendChild($this->dd->createElement('picture'))
->appendChild(
$this->dd->createTextNode($offer['picture'])
);
}
if (!empty($offer['url'])) {
$e->appendChild($this->dd->createElement('url'))
->appendChild(
$this->dd->createTextNode($offer['url'])
);
}
if (!empty($offer['vendor'])) {
$e->appendChild($this->dd->createElement('vendor'))
->appendChild(
$this->dd->createTextNode($offer['vendor'])
);
}
if (!empty($offer['dimensions'])) {
$e->appendChild($this->dd->createElement('dimensions'))
->appendChild(
$this->dd->createTextNode($offer['dimensions'])
);
}
if (!empty($offer['weight'])) {
$e->appendChild($this->dd->createElement('weight'))
->appendChild(
$this->dd->createTextNode($offer['weight'])
);
}
if (!empty($offer['params'])) {
foreach ($offer['params'] as $param) {
$paramNode = $this->dd->createElement('param');
$paramNode->setAttribute('name', $param['name']);
$paramNode->setAttribute('code', $param['code']);
$paramNode->appendChild(
$this->dd->createTextNode($param['value'])
);
$e->appendChild($paramNode);
}
}
}
/**
* Build offers array
*
* @return array $offers
*/
private function buildOffers()
{
$offers = [];
$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->getItems() as $product) {
if ($product->getTypeId() == 'simple') {
$offers[] = $this->buildOffer($product, $customAdditionalAttributes);
}
if ($product->getTypeId() == 'configurable') {
$associated_products = $this->getAssociatedProducts($product);
foreach ($associated_products as $associatedProduct) {
$offers[] = $this->buildOffer($product, $customAdditionalAttributes, $associatedProduct);
}
}
}
return $offers;
}
/**
* Build offer array
*
* @param object $product
* @param $customAdditionalAttributes
* @param object $associatedProduct
*
* @return array $offer
*/
private function buildOffer($product, $customAdditionalAttributes, $associatedProduct = null)
{
$offer = [];
$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();
if ($associatedProduct === null) {
$offer['productActivity'] = $product->isAvailable() ? 'Y' : 'N';
} else {
$offer['productActivity'] = $associatedProduct->isAvailable() ? 'Y' : 'N';
}
$offer['name'] = $associatedProduct === null ? $product->getName() : $associatedProduct->getName();
$offer['productName'] = $product->getName();
$offer['initialPrice'] = $associatedProduct === null
? $product->getFinalPrice()
: $associatedProduct->getFinalPrice();
$offer['url'] = $product->getUrlInStore();
if ($associatedProduct === null) {
$offer['picture'] = $picUrl . 'catalog/product' . $product->getImage();
} else {
$offer['picture'] = $picUrl . 'catalog/product' . $associatedProduct->getImage();
}
$offer['quantity'] = $associatedProduct === null
? $this->getStockQuantity($product)
: $this->getStockQuantity($associatedProduct);
$offer['categoryId'] = $associatedProduct === null
? $product->getCategoryIds()
: $associatedProduct->getCategoryIds();
$offer['vendor'] = $associatedProduct === null
? $product->getAttributeText('manufacturer')
: $associatedProduct->getAttributeText('manufacturer');
$offer['weight'] = $associatedProduct === null
? $product->getWeight()
: $associatedProduct->getWeight();
$params = $this->getOfferParams($product, $customAdditionalAttributes, $associatedProduct);
$offer['params'] = $params['params'];
$offer['dimensions'] = $params['dimensions'];
unset($params);
return $offer;
}
/**
* Get parameters offers
*
* @param object $product
* @param $customAdditionalAttributes
* @param object $associatedProduct
*
* @return array $params
*/
private function getOfferParams($product, $customAdditionalAttributes, $associatedProduct = null)
{
$params = [];
if (!$customAdditionalAttributes) {
return $params;
}
$attributes = explode(',', $customAdditionalAttributes);
$dimensionsAttrs = [];
$dimensions = '';
foreach ($attributes as $attributeCode) {
if ($this->checkDimension($attributeCode) !== false) {
$dimensionsAttrs += $this->checkDimension($attributeCode);
continue;
}
$attribute = $this->resourceModelProduct->getAttribute($attributeCode);
$attributeValue = $associatedProduct
? $associatedProduct->getData($attributeCode)
: $product->getData($attributeCode);
$attributeText = $attribute->getSource()->getOptionText($attributeValue);
if ($attribute && $attributeValue) {
$params[] = [
'name' => $attribute->getDefaultFrontendLabel(),
'code' => $attributeCode,
'value' => $attributeText ? $attributeText : $attributeValue
];
}
}
if ($dimensionsAttrs && count($dimensionsAttrs) == 3) {
$length = $associatedProduct
? $associatedProduct->getData($dimensionsAttrs['length'])
: $product->getData($dimensionsAttrs['length']);
$width = $associatedProduct
? $associatedProduct->getData($dimensionsAttrs['width'])
: $product->getData($dimensionsAttrs['width']);
$height = $associatedProduct
? $associatedProduct->getData($dimensionsAttrs['height'])
: $product->getData($dimensionsAttrs['height']);
if ($length && $width && $height) {
$dimensions = sprintf(
'%s/%s/%s',
$length,
$width,
$height
);
}
}
return ['params' => $params, 'dimensions' => $dimensions];
}
/**
* Get associated products
*
* @param object $product
*
* @return object
*/
private function getAssociatedProducts($product)
{
return $this->configurable
->getUsedProductCollection($product)
->addAttributeToSelect('*')
->addFilterByRequiredOptions();
}
/**
* Get product stock quantity
*
* @param object $offer
* @return int $quantity
*/
private function getStockQuantity($offer)
{
$quantity = $this->StockState->getStockQty(
$offer->getId(),
$offer->getStore()->getWebsiteId()
);
return $quantity;
}
/**
* @param string $attrCode
*
* @return mixed
*/
private function checkDimension($attrCode)
{
foreach ($this->dimensionFields as $dimensionField) {
if (mb_strpos($attrCode, $dimensionField) !== false) {
return [$dimensionField => $attrCode];
}
}
return false;
}
}

View file

@ -6,18 +6,18 @@ class Logger
{
private $logDir;
public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager)
{
$directory = $objectManager->get('\Magento\Framework\Filesystem\DirectoryList');
public function __construct(
\Magento\Framework\Filesystem\DirectoryList $directory
) {
$this->logDir = $directory->getPath('log');
}
/**
* Write data in log file
*
*
* @param array $data
* @param str $fileName
*
* @param string $fileName
*
* @return void
*/
public function writeDump($data, $fileName)
@ -40,10 +40,10 @@ class Logger
/**
* Write data in log file
*
* @param str $data
* @param str $fileName
*
*
* @param string $data
* @param string $fileName
*
* @return void
*/
public function writeRow($data, $fileName = 'retailcrm')
@ -64,24 +64,24 @@ class Logger
/**
* Clear file
*
* @param str $file
*
*
* @param string $file
*
* @return void
*/
protected function clear($file)
private function clear($file)
{
file_put_contents($file, '');
}
/**
* Check file size
*
* @param str $file
*
*
* @param string $file
*
* @return boolean
*/
protected function checkSize($file)
private function checkSize($file)
{
if (!file_exists($file)) {
return true;

View file

@ -0,0 +1,60 @@
<?php
namespace Retailcrm\Retailcrm\Model\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
use Retailcrm\Retailcrm\Helper\Data as Helper;
class Customer implements \Magento\Framework\Event\ObserverInterface
{
private $api;
private $registry;
private $customer;
private $helper;
private $serviceCustomer;
public function __construct(
\Magento\Framework\Registry $registry,
Helper $helper,
ApiClient $api,
\Retailcrm\Retailcrm\Model\Service\Customer $serviceCustomer
) {
$this->api = $api;
$this->helper = $helper;
$this->registry = $registry;
$this->serviceCustomer = $serviceCustomer;
$this->customer = [];
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
if ($this->registry->registry('RETAILCRM_HISTORY') === true
|| !$this->api->isConfigured()
) {
return false;
}
$customer = $observer->getEvent()->getCustomer();
$this->customer = $this->serviceCustomer->process($customer);
$this->api->setSite($this->helper->getSite($customer->getStore()));
$response = $this->api->customersEdit($this->customer);
if ($response === false) {
return false;
}
if (!$response->isSuccessful() && $response->errorMsg == $this->api->getErrorText('errorNotFound')) {
$this->api->customersCreate($this->customer);
}
return $this;
}
/**
* @return array
*/
public function getCustomer()
{
return $this->customer;
}
}

View file

@ -0,0 +1,171 @@
<?php
namespace Retailcrm\Retailcrm\Model\Observer;
use Magento\Framework\Event\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
use Retailcrm\Retailcrm\Helper\Data as Helper;
class OrderCreate implements \Magento\Framework\Event\ObserverInterface
{
protected $api;
protected $logger;
protected $helper;
private $registry;
private $order;
private $serviceOrder;
private $serviceCustomer;
/**
* Constructor
*
* @param \Magento\Framework\Registry $registry
* @param \Retailcrm\Retailcrm\Model\Logger\Logger $logger
* @param \Retailcrm\Retailcrm\Model\Service\Order $serviceOrder
* @param \Retailcrm\Retailcrm\Model\Service\Customer $serviceCustomer
* @param Helper $helper
* @param ApiClient $api
*/
public function __construct(
\Magento\Framework\Registry $registry,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Retailcrm\Retailcrm\Model\Service\Order $serviceOrder,
\Retailcrm\Retailcrm\Model\Service\Customer $serviceCustomer,
Helper $helper,
ApiClient $api
) {
$this->logger = $logger;
$this->registry = $registry;
$this->serviceOrder = $serviceOrder;
$this->serviceCustomer = $serviceCustomer;
$this->helper = $helper;
$this->api = $api;
$this->order = [];
}
/**
* Execute send order in CRM
*
* @param Observer $observer
*
* @return mixed
*/
public function execute(Observer $observer)
{
if ($this->registry->registry('RETAILCRM_HISTORY') === true
|| !$this->api->isConfigured()
) {
return false;
}
/** @var \Magento\Sales\Model\Order $order */
$order = $observer->getEvent()->getOrder();
$this->api->setSite($this->helper->getSite($order->getStore()));
if ($this->existsInCrm($order->getId()) === true) {
return false;
}
$this->order = $this->serviceOrder->process($order);
$this->setCustomer($order);
Helper::filterRecursive($this->order);
$this->logger->writeDump($this->order, 'CreateOrder');
$this->api->ordersCreate($this->order);
return $this;
}
/**
* @param \Magento\Sales\Model\Order $order
* @param \Magento\Sales\Model\Order\Address $billingAddress
*/
private function setCustomer($order)
{
if ($order->getCustomerIsGuest() == 1) {
$customer = $this->getCustomerByEmail($order->getCustomerEmail());
if ($customer !== false) {
$this->order['customer']['id'] = $customer['id'];
} else {
$newCustomer = $this->serviceCustomer->prepareCustomerFromOrder($order);
$response = $this->api->customersCreate($newCustomer);
if ($response && isset($response['id'])) {
$this->order['customer']['id'] = $response['id'];
}
}
}
if ($order->getCustomerIsGuest() == 0) {
if ($this->existsInCrm($order->getCustomerId(), 'customersGet')) {
$this->order['customer']['externalId'] = $order->getCustomerId();
} else {
$preparedCustomer = $this->serviceCustomer->process($order->getCustomer());
if ($this->api->customersCreate($preparedCustomer)) {
$this->order['customer']['externalId'] = $order->getCustomerId();
}
}
}
}
/**
* Check exists order or customer in CRM
*
* @param int $id
* @param string $method
* @param string $by
* @param string $site
*
* @return boolean
*/
private function existsInCrm($id, $method = 'ordersGet', $by = 'externalId', $site = null)
{
$response = $this->api->{$method}($id, $by, $site);
if ($response === false) {
return false;
}
if (!$response->isSuccessful() && $response->errorMsg == $this->api->getErrorText('errorNotFound')) {
return false;
}
return true;
}
/**
* Get customer by email from CRM
*
* @param string $email
*
* @return mixed
*/
private function getCustomerByEmail($email)
{
$response = $this->api->customersList(['email' => $email]);
if ($response === false) {
return false;
}
if ($response->isSuccessful() && isset($response['customers'])) {
if (!empty($response['customers'])) {
return reset($response['customers']);
}
}
return false;
}
/**
* @return array
*/
public function getOrder()
{
return $this->order;
}
}

View file

@ -0,0 +1,91 @@
<?php
namespace Retailcrm\Retailcrm\Model\Observer;
use Magento\Framework\Event\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
use Retailcrm\Retailcrm\Helper\Data as Helper;
class OrderUpdate implements \Magento\Framework\Event\ObserverInterface
{
private $api;
private $config;
private $registry;
private $order;
private $helper;
/**
* Constructor
*
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\Registry $registry
* @param Helper $helper
* @param ApiClient $api
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\Registry $registry,
Helper $helper,
ApiClient $api
) {
$this->config = $config;
$this->registry = $registry;
$this->helper = $helper;
$this->api = $api;
$this->order = [];
}
/**
* Execute update order in CRM
*
* @param Observer $observer
*
* @return mixed
*/
public function execute(Observer $observer)
{
if ($this->registry->registry('RETAILCRM_HISTORY') === true
|| !$this->api->isConfigured()
) {
return false;
}
$order = $observer->getEvent()->getOrder();
if ($order) {
$statusList = $this->helper->getCongigStatus();
$this->order = [
'externalId' => $order->getId(),
'status' => $statusList[$order->getStatus()]
];
if ($order->getBaseTotalDue() == 0) {
if ($this->api->getVersion() == 'v4') {
$this->order['paymentStatus'] = 'paid';
} elseif ($this->api->getVersion() == 'v5') {
$payment = [
'externalId' => $order->getPayment()->getId(),
'status' => 'paid'
];
$this->api->ordersPaymentsEdit($payment);
}
}
Helper::filterRecursive($this->order);
$this->api->setSite($this->helper->getSite($order->getStore()));
$this->api->ordersEdit($this->order);
}
return $this;
}
/**
* @return mixed
*/
public function getOrder()
{
return $this->order;
}
}

View file

@ -0,0 +1,66 @@
<?php
namespace Retailcrm\Retailcrm\Model\Order;
use Retailcrm\Retailcrm\Helper\Data as Helper;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class OrderNumber
{
private $salesOrder;
private $orderService;
private $helper;
private $api;
public function __construct(
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;
$this->orderService = $orderService;
}
/**
* @param string $orderNumbers
*
* @return array
*/
public function exportOrderNumber($orderNumbers)
{
$ordersId = explode(",", $orderNumbers);
$orders = [];
foreach ($ordersId as $id) {
$magentoOrder = $this->salesOrder->load($id);
$orders[$magentoOrder->getStore()->getId()][] = $this->orderService->process($magentoOrder);
}
foreach ($orders as $storeId => $ordersStore) {
$chunked = array_chunk($ordersStore, 50);
unset($ordersStore);
foreach ($chunked as $chunk) {
$this->api->setSite($this->helper->getSite($storeId));
$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 ['success' => true];
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Retailcrm\Retailcrm\Model\Service;
class ConfigManager implements \Retailcrm\Retailcrm\Api\ConfigManagerInterface
{
private $config;
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $config
) {
$this->config = $config;
}
public function getConfigValue($path)
{
return $this->config->getValue($path);
}
}

View file

@ -0,0 +1,156 @@
<?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
*/
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;
}
/**
* @param \Magento\Sales\Model\Order $order
*
* @return array
*/
public function prepareCustomerFromOrder(\Magento\Sales\Model\Order $order)
{
$billing = $order->getBillingAddress();
$preparedCustomer = [
'email' => $billing->getEmail(),
'firstName' => $billing->getFirstname(),
'patronymic' => $billing->getMiddlename(),
'lastName' => $billing->getLastname(),
'createdAt' => $order->getCreatedAt(),
'address' => [
'countryIso' => $billing->getCountryId(),
'index' => $billing->getPostcode(),
'region' => $billing->getRegion(),
'city' => $billing->getCity(),
'street' => is_array($billing->getStreet())
? implode(', ', $billing->getStreet())
: $billing->getStreet(),
'text' => sprintf(
'%s %s %s %s',
$billing->getPostcode(),
$billing->getRegion(),
$billing->getCity(),
is_array($billing->getStreet())
? implode(', ', $billing->getStreet())
: $billing->getStreet()
)
]
];
if ($billing->getTelephone()) {
$preparedCustomer['phones'] = [
[
'number' => $billing->getTelephone()
]
];
}
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;
}
}

View file

@ -0,0 +1,130 @@
<?php
namespace Retailcrm\Retailcrm\Model\Service;
use Retailcrm\Retailcrm\Helper\Data as Helper;
use Magento\Framework\App\Config\ScopeConfigInterface;
class IntegrationModule
{
const LOGO = 'https://s3.eu-central-1.amazonaws.com/retailcrm-billing/images/5b846b1fef57e-magento.svg';
const INTEGRATION_CODE = 'magento';
const NAME = 'Magento 2';
private $accountUrl = null;
private $apiVersion = 'v5';
private $configuration = [];
private $resourceConfig;
private $clientId;
private $helper;
/**
* IntegrationModule constructor.
*
* @param \Magento\Config\Model\ResourceModel\Config $resourceConfig
* @param \Retailcrm\Retailcrm\Helper\Data $helper
*/
public function __construct(
\Magento\Config\Model\ResourceModel\Config $resourceConfig,
Helper $helper
) {
$this->resourceConfig = $resourceConfig;
$this->helper = $helper;
}
/**
* @param $accountUrl
*/
public function setAccountUrl($accountUrl)
{
$this->accountUrl = $accountUrl;
}
/**
* @param $apiVersion
*/
public function setApiVersion($apiVersion)
{
$this->apiVersion = $apiVersion;
}
/**
* @return array
*/
public function getConfiguration()
{
return $this->configuration;
}
/**
* @param $active
*
* @return void
*/
private function setConfiguration($active)
{
$this->clientId = $this->helper->getGeneralSettings('client_id_in_crm');
if (!$this->clientId) {
$this->clientId = uniqid();
}
if ($this->apiVersion == 'v4') {
$this->configuration = [
'name' => self::NAME,
'code' => self::INTEGRATION_CODE . '-' . $this->clientId,
'logo' => self::LOGO,
'configurationUrl' => $this->accountUrl,
'active' => $active
];
} else {
$this->configuration = [
'clientId' => $this->clientId,
'code' => self::INTEGRATION_CODE . '-' . $this->clientId,
'integrationCode' => self::INTEGRATION_CODE,
'active' => $active,
'name' => self::NAME,
'logo' => self::LOGO,
'accountUrl' => $this->accountUrl
];
}
}
/**
* @param \Retailcrm\Retailcrm\Helper\Proxy $apiClient
* @param boolean $active
*
* @return boolean
*/
public function sendConfiguration($apiClient, $active = true)
{
$this->setConfiguration($active);
if ($this->apiVersion == 'v4') {
$response = $apiClient->marketplaceSettingsEdit(Helper::filterRecursive($this->configuration));
} else {
$response = $apiClient->integrationModulesEdit(Helper::filterRecursive($this->configuration));
}
if (!$response) {
return false;
}
if ($response->isSuccessful() && $active == true) {
$scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT;
$scopeId = 0;
$this->resourceConfig->saveConfig(
Helper::XML_PATH_RETAILCRM . 'general/client_id_in_crm',
$this->clientId,
$scope,
$scopeId
);
return true;
}
return false;
}
}

View file

@ -0,0 +1,55 @@
<?php
namespace Retailcrm\Retailcrm\Model\Service;
use Magento\Catalog\Api\ProductRepositoryInterface;
class InventoriesUpload
{
private $productRepo;
private $api;
public function __construct(
ProductRepositoryInterface $productRepo,
\Retailcrm\Retailcrm\Helper\Proxy $api
) {
$this->productRepo = $productRepo;
$this->api = $api;
}
/**
* {@inheritdoc}
*/
public function uploadInventory()
{
if (!$this->api->isConfigured()) {
return false;
}
$page = 1;
do {
$response = $this->api->storeInventories(array(), $page, 250);
if ($response === false || !$response->isSuccessful()) {
return false;
}
foreach ($response['offers'] as $offer) {
if (isset($offer['externalId'])) {
$product = $this->productRepo->getById($offer['externalId']);
$product->setStockData(
['qty' => $offer['quantity'],
'is_in_stock' => $offer['quantity'] > 0]
);
$product->save();
}
}
$totalPageCount = $response['pagination']['totalPageCount'];
$page++;
} while ($page <= $totalPageCount);
return true;
}
}

177
src/Model/Service/Order.php Normal file
View file

@ -0,0 +1,177 @@
<?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);
$shippingAddress = $order->getShippingAddress();
$shipping = $this->getShippingCode($order->getShippingMethod());
$shipList = $this->helper->getCongigShipping();
$statusList = $this->helper->getCongigStatus();
$paymentList = $this->helper->getConfigPayments();
$preparedOrder = [
'externalId' => $order->getId(),
'number' => $order->getRealOrderId(),
'createdAt' => $order->getCreatedAt(),
'lastName' => $shippingAddress->getLastname(),
'firstName' => $shippingAddress->getFirstname(),
'patronymic' => $shippingAddress->getMiddlename(),
'email' => $shippingAddress->getEmail(),
'phone' => $shippingAddress->getTelephone(),
'status' => $statusList[$order->getStatus()],
'items' => $products,
'delivery' => [
'code' => $shipList[$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'),
]
)
)
]
]
];
$codeShop = $this->config->getValue('retailcrm/retailcrm_site/default');
if ($shippingAddress->getData('country_id')) {
$preparedOrder['countryIso'] = $shippingAddress->getData('country_id');
}
if ($this->helper->getGeneralSettings('api_version') == 'v4') {
$preparedOrder['discount'] = abs($order->getDiscountAmount());
$preparedOrder['paymentType'] = $paymentList[$order->getPayment()->getMethodInstance()->getCode()];
} elseif ($this->helper->getGeneralSettings('api_version') == 'v5') {
$preparedOrder['discountManualAmount'] = abs($order->getDiscountAmount());
$payment = [
'type'=> $paymentList[$order->getPayment()->getMethodInstance()->getCode()],
'externalId' => $codeShop.$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

@ -0,0 +1,45 @@
<?php
namespace Retailcrm\Retailcrm\Model\Setting;
class Attribute implements \Magento\Framework\Option\ArrayInterface
{
private $entityType;
private $store;
public function __construct(
\Magento\Store\Model\Store $store,
\Magento\Eav\Model\Entity\Type $entityType
) {
$this->store = $store;
$this->entityType = $entityType;
}
public function toOptionArray()
{
$types = [
'text',
'decimal',
'boolean',
'select',
'price'
];
$attributes = $this->entityType->loadByCode('catalog_product')->getAttributeCollection();
$attributes->addFieldToFilter('frontend_input', $types);
$result = [];
foreach ($attributes as $attr) {
if ($attr->getFrontendLabel()) {
$result[] = [
'value' => $attr->getAttributeCode(),
'label' => $attr->getFrontendLabel(),
'title' => $attr->getAttributeCode()
];
}
}
return $result;
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace Retailcrm\Retailcrm\Model\Setting;
class Select implements \Magento\Framework\Option\ArrayInterface
{
public function toOptionArray()
{
return [
['value' => true, 'label' => __('Yes')],
['value' => false, 'label' => __('No')]
];
}
}

View file

@ -4,23 +4,26 @@ namespace Retailcrm\Retailcrm\Model\Setting;
class Shipping implements \Magento\Framework\Option\ArrayInterface
{
protected $_entityType;
protected $_store;
private $entityType;
private $store;
private $config;
private $shippingConfig;
public function __construct(
\Magento\Store\Model\Store $store,
\Magento\Eav\Model\Entity\Type $entityType
\Magento\Eav\Model\Entity\Type $entityType,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Shipping\Model\Config $shippingConfig
) {
$this->_store = $store;
$this->_entityType = $entityType;
$this->store = $store;
$this->entityType = $entityType;
$this->config = $config;
$this->shippingConfig = $shippingConfig;
}
public function toOptionArray()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$activeShipping = $objectManager->create('Magento\Shipping\Model\Config')->getActiveCarriers();
$config = $objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface');
$activeShipping = $this->shippingConfig->getActiveCarriers();
foreach ($activeShipping as $carrierCode => $carrierModel) {
$options = [];
@ -36,7 +39,7 @@ class Shipping implements \Magento\Framework\Option\ArrayInterface
];
}
$carrierTitle = $config->getValue('carriers/' . $carrierCode . '/title');
$carrierTitle = $this->config->getValue('carriers/' . $carrierCode . '/title');
}
$methods[] = [

View file

@ -9,7 +9,7 @@ class Status extends \Magento\Config\Model\Config\Backend\Serialized\ArraySerial
// For value validations
$exceptions = $this->getValue();
// Validations
// Validations
$this->setValue($exceptions);
return parent::beforeSave();

1
src/README.md Normal file
View file

@ -0,0 +1 @@
Magento 2 module for interaction with RetailCRM

26
src/Setup/Uninstall.php Normal file
View file

@ -0,0 +1,26 @@
<?php
namespace Retailcrm\Retailcrm\Setup;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
class Uninstall implements \Magento\Framework\Setup\UninstallInterface
{
private $apiClient;
private $integrationModule;
public function __construct(
\Retailcrm\Retailcrm\Helper\Proxy $apiClient,
\Retailcrm\Retailcrm\Model\Service\IntegrationModule $integrationModule
) {
$this->apiClient = $apiClient;
$this->integrationModule = $integrationModule;
}
public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$this->integrationModule->setApiVersion($this->apiClient->getVersion());
$this->integrationModule->sendConfiguration($this->apiClient, false);
}
}

View file

@ -0,0 +1,127 @@
<?php
namespace Retailcrm\Retailcrm\Test\Helpers;
use Retailcrm\Retailcrm\Test\TestCase;
class FieldsetTest extends TestCase
{
protected $elementMock;
protected $authSessionMock;
protected $userMock;
protected $requestMock;
protected $urlModelMock;
protected $layoutMock;
protected $helperMock;
protected $groupMock;
protected $objectManager;
protected $context;
protected $form;
protected $testElementId = 'test_element_id';
protected $testFieldSetCss = 'test_fieldset_css';
protected $objectFactory;
protected $secureRenderer;
public function setUp()
{
$this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$factoryMock = $this->createMock(\Magento\Framework\Data\Form\Element\Factory::class);
$collectionFactoryMock = $this->createMock(\Magento\Framework\Data\Form\Element\CollectionFactory::class);
$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);
// element mock
$this->elementMock = $this->getMockBuilder(\Magento\Framework\Data\Form\Element\AbstractElement::class)
->setMethods([
'getId',
'getHtmlId',
'getName',
'getElements',
'getLegend',
'getComment',
'getIsNested',
'getExpanded',
'getForm',
'addField'
])
->setConstructorArgs([$factoryMock, $collectionFactoryMock, $escaperMock])
->getMockForAbstractClass();
$this->elementMock->expects($this->any())
->method('getId')
->willReturn($this->testElementId);
$this->elementMock->expects($this->any())
->method('getHtmlId')
->willReturn($this->testElementId);
$this->elementMock->expects($this->any())
->method('addField')
->willReturn($formElementMock);
$this->elementMock->expects($this->any())
->method('getElements')
->willReturn($elementCollection);
$this->authSessionMock = $this->getMockBuilder(\Magento\Backend\Model\Auth\Session::class)
->setMethods(['getUser'])
->disableOriginalConstructor()
->getMock();
$this->userMock = $this->getMockBuilder(\Magento\User\Model\User::class)
->setMethods(['getExtra'])
->disableOriginalConstructor()
->getMock();
$this->authSessionMock->expects($this->any())
->method('getUser')
->willReturn($this->userMock);
$this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)
->disableOriginalConstructor()
->getMock();
$this->requestMock->expects($this->any())
->method('getParam')
->willReturn('Test Param');
$factoryCollection = $this->createMock(\Magento\Framework\Data\Form\Element\CollectionFactory::class);
$elementCollection = $this->createMock(\Magento\Framework\Data\Form\Element\Collection::class);
$factoryCollection->expects($this->any())->method('create')->willReturn($elementCollection);
$rendererMock = $this->createMock(\Magento\Framework\Data\Form\Element\Renderer\RendererInterface::class);
if (class_exists(\Magento\Framework\View\Helper\SecureHtmlRenderer::class)) {
$this->secureRenderer = $this->createMock(\Magento\Framework\View\Helper\SecureHtmlRenderer::class);
$this->secureRenderer->method('renderEventListenerAsTag')
->willReturnCallback(
function (string $event, string $js, string $selector): string {
return "<script>document.querySelector('$selector').$event = function () { $js };</script>";
}
);
$this->secureRenderer->method('renderStyleAsTag')
->willReturnCallback(
function (string $style, string $selector): string {
return "<style>$selector { $style }</style>";
}
);
}
$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->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']
['getRequest']
);
//$this->form->expects($this->any())->method('getElements')->willReturn($elementCollection);
$this->form->expects($this->any())->method('getRequest')->willReturn($this->requestMock);
}
}

58
src/Test/TestCase.php Normal file
View file

@ -0,0 +1,58 @@
<?php
namespace Retailcrm\Retailcrm\Test;
// backward compatibility with phpunit < v.6
if (!class_exists('\PHPUnit\Framework\TestCase')) {
class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
abstract class TestCase extends \PHPUnit\Framework\TestCase
{
public function createMock($originalClassName)
{
if (method_exists(\PHPUnit\Framework\TestCase::class, 'createMock')) {
return parent::createMock($originalClassName);
} else {
return $this->getMockBuilder($originalClassName)
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
->getMock();
}
}
protected function createPartialMock($originalClassName, $methods)
{
if (method_exists(\PHPUnit\Framework\TestCase::class, 'createPartialMock')) {
return parent::createMock($originalClassName);
} else {
return $this->getMockBuilder($originalClassName)
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
// ->disallowMockingUnknownTypes()
->setMethods(empty($methods) ? null : $methods)
->getMock();
}
}
}
} else {
abstract class TestCase extends \PHPUnit\Framework\TestCase
{
public function createMock($originalClassName)
{
if (method_exists(\PHPUnit\Framework\TestCase::class, 'createMock')) {
return parent::createMock($originalClassName);
} else {
return $this->getMockBuilder($originalClassName)
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
->getMock();
}
}
}
}

View file

@ -0,0 +1,130 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Block\Adminhtml\System\Config\Form\Fieldset;
class PaymentTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
{
/**
* @param boolean $isSuccessful
* @param boolean $isConfigured
* @dataProvider dataProvider
*/
public function testRender($isSuccessful, $isConfigured)
{
// response
$response = $this->objectManager->getObject(
\RetailCrm\Response\ApiResponse::class,
[
'statusCode' => $isSuccessful ? 200 : 404,
'responseBody' => json_encode($this->getTestResponse())
]
);
// api client mock
$client = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods(
[
'isConfigured',
'paymentTypesList'
]
)
->getMock();
$client->expects($this->any())
->method('isConfigured')
->willReturn($isConfigured);
$client->expects($this->any())
->method('paymentTypesList')
->willReturn($response);
// payment config mock
$paymentConfig = $this->getMockBuilder(\Magento\Payment\Model\Config::class)
->disableOriginalConstructor()
->getMock();
$paymentConfig->expects($this->any())
->method('getActiveMethods')
->willReturn($this->getTestActiveMethods());
$data = [
'authSession' => $this->authSessionMock,
'jsHelper' => $this->helperMock,
'data' => ['group' => $this->groupMock],
'client' => $client,
'paymentConfig' => $paymentConfig,
'context' => $this->context,
'objectFactory' => $this->objectFactory,
'secureRenderer' => $this->secureRenderer
];
$payment = $this->objectManager->getObject(
\Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Payment::class,
$data
);
$payment->setForm($this->form);
$payment->setLayout($this->layoutMock);
$html = $payment->render($this->elementMock);
$this->assertContains($this->testElementId, $html);
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$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 getTestActiveMethods()
{
$payment = $this->getMockBuilder(\Magento\Payment\Model\MethodInterface::class)
->setMethods(['getData'])
->disableOriginalConstructor()
->getMockForAbstractClass();
$payment->expects($this->any())
->method('getData')
->with('title')
->willReturn('Test Payment');
return ['test_payment' => $payment];
}
private function getTestResponse()
{
return [
'success' => true,
'paymentTypes' => [
[
'code' => 'payment',
'name' => 'Test payment type'
]
]
];
}
public function dataProvider()
{
return [
[
'is_successful' => true,
'is_configured' => true
],
[
'is_successful' => false,
'is_configured' => false
],
[
'is_successful' => true,
'is_configured' => false
],
[
'is_successful' => false,
'is_configured' => true
]
];
}
}

View file

@ -0,0 +1,129 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Block\Adminhtml\System\Config\Form\Fieldset;
class ShippingTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
{
/**
* @param $isSuccessful
* @param $isConfigured
* @dataProvider dataProvider
*/
public function testRender($isSuccessful, $isConfigured)
{
// response
$response = $this->objectManager->getObject(
\RetailCrm\Response\ApiResponse::class,
[
'statusCode' => $isSuccessful ? 200 : 404,
'responseBody' => json_encode($this->getTestResponse())
]
);
// api client mock
$client = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods(
[
'isConfigured',
'deliveryTypesList'
]
)
->getMock();
$client->expects($this->any())
->method('isConfigured')
->willReturn($isConfigured);
$client->expects($this->any())
->method('deliveryTypesList')
->willReturn($response);
// shipping config mock
$shippingConfig = $this->getMockBuilder(\Magento\Shipping\Model\Config::class)
->disableOriginalConstructor()
->getMock();
$shippingConfig->expects($this->any())
->method('getActiveCarriers')
->willReturn($this->getTestActiveCarriers());
$data = [
'authSession' => $this->authSessionMock,
'jsHelper' => $this->helperMock,
'data' => ['group' => $this->groupMock],
'client' => $client,
'shippingConfig' => $shippingConfig,
'context' => $this->context,
'objectFactory' => $this->objectFactory,
'secureRenderer' => $this->secureRenderer
];
$shipping = $this->objectManager->getObject(
\Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Shipping::class,
$data
);
$shipping->setForm($this->form);
$shipping->setLayout($this->layoutMock);
$html = $shipping->render($this->elementMock);
$this->assertContains($this->testElementId, $html);
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$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);
}
}
private function getTestActiveCarriers()
{
$shipping = $this->getMockBuilder(\Magento\Shipping\Model\Carrier\AbstractCarrierInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$shipping->expects($this->any())
->method('getConfigData')
->with('title')
->willReturn('Test Shipping');
return ['test_shipping' => $shipping];
}
private function getTestResponse()
{
return [
'success' => true,
'deliveryTypes' => [
[
'code' => 'delivery',
'name' => 'Test delivery type'
]
]
];
}
public function dataProvider()
{
return [
[
'is_successful' => true,
'is_configured' => true
],
[
'is_successful' => false,
'is_configured' => false
],
[
'is_successful' => true,
'is_configured' => false
],
[
'is_successful' => false,
'is_configured' => true
]
];
}
}

View file

@ -0,0 +1,106 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Block\Adminhtml\System\Config\Form\Fieldset;
class SiteTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
{
/**
* @param boolean $isSuccessful
* @param boolean $isConfigured
* @dataProvider dataProvider
*/
public function testRender($isSuccessful, $isConfigured)
{
// response
$response = $this->objectManager->getObject(
\RetailCrm\Response\ApiResponse::class,
[
'statusCode' => $isSuccessful ? 200 : 404,
'responseBody' => json_encode($this->getTestResponse())
]
);
// api client mock
$client = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods(
[
'isConfigured',
'sitesList'
]
)
->getMock();
$client->expects($this->any())
->method('isConfigured')
->willReturn($isConfigured);
$client->expects($this->any())
->method('sitesList')
->willReturn($response);
$data = [
'authSession' => $this->authSessionMock,
'jsHelper' => $this->helperMock,
'data' => ['group' => $this->groupMock],
'client' => $client,
'context' => $this->context,
'objectFactory' => $this->objectFactory,
'secureRenderer' => $this->secureRenderer
];
$site = $this->objectManager->getObject(
\Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Site::class,
$data
);
$site->setForm($this->form);
$site->setLayout($this->layoutMock);
$html = $site->render($this->elementMock);
$this->assertContains($this->testElementId, $html);
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$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);
}
}
private function getTestResponse()
{
return [
'success' => true,
'sites' => [
[
'code' => 'payment',
'name' => 'Test site'
]
]
];
}
public function dataProvider()
{
return [
[
'is_successful' => true,
'is_configured' => true
],
[
'is_successful' => false,
'is_configured' => false
],
[
'is_successful' => true,
'is_configured' => false
],
[
'is_successful' => false,
'is_configured' => true
]
];
}
}

View file

@ -0,0 +1,135 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Block\Adminhtml\System\Config\Form\Fieldset;
class SitesTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
{
/**
* @param boolean $isSuccessful
* @param boolean $isConfigured
* @dataProvider dataProvider
*/
public function testRender($isSuccessful, $isConfigured)
{
// response
$response = $this->objectManager->getObject(
\RetailCrm\Response\ApiResponse::class,
[
'statusCode' => $isSuccessful ? 200 : 404,
'responseBody' => json_encode($this->getTestResponse())
]
);
// api client mock
$client = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods(
[
'isConfigured',
'sitesList'
]
)
->getMock();
$client->expects($this->any())
->method('isConfigured')
->willReturn($isConfigured);
$client->expects($this->any())
->method('sitesList')
->willReturn($response);
$websiteMock = $this->createMock(\Magento\Store\Model\Website::class);
$websiteMock->expects($this->any())->method('getStores')->willReturn($this->getTestStores());
// payment config mock
$storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$storeManager->expects($this->any())
->method('getWebsite')
->willReturn($websiteMock);
$data = [
'authSession' => $this->authSessionMock,
'jsHelper' => $this->helperMock,
'data' => ['group' => $this->groupMock],
'client' => $client,
'storeManager' => $storeManager,
'context' => $this->context,
'objectFactory' => $this->objectFactory,
'secureRenderer' => $this->secureRenderer
];
$sites = $this->objectManager->getObject(
\Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Sites::class,
$data
);
$sites->setForm($this->form);
$sites->setLayout($this->layoutMock);
$html = $sites->render($this->elementMock);
$this->assertContains($this->testElementId, $html);
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$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);
}
}
private function getTestStores()
{
$store = $this->getMockBuilder(\Magento\Store\Model\Store::class)
->disableOriginalConstructor()
->getMock();
$store->expects($this->any())
->method('getName')
->willReturn('Test Store');
$store->expects($this->any())
->method('getCode')
->willReturn('test_store_code');
return ['test_site' => $store];
}
private function getTestResponse()
{
return [
'success' => true,
'sites' => [
[
'code' => 'payment',
'name' => 'Test site'
]
]
];
}
public function dataProvider()
{
return [
[
'is_successful' => true,
'is_configured' => true
],
[
'is_successful' => false,
'is_configured' => false
],
[
'is_successful' => true,
'is_configured' => false
],
[
'is_successful' => false,
'is_configured' => true
]
];
}
}

View file

@ -0,0 +1,125 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Block\Adminhtml\System\Config\Form\Fieldset;
class StatusTest extends \Retailcrm\Retailcrm\Test\Helpers\FieldsetTest
{
/**
* @param boolean $isSuccessful
* @param boolean $isConfigured
* @dataProvider dataProvider
*/
public function testRender($isSuccessful, $isConfigured)
{
// response
$response = $this->objectManager->getObject(
\RetailCrm\Response\ApiResponse::class,
[
'statusCode' => $isSuccessful ? 200 : 404,
'responseBody' => json_encode($this->getTestResponse())
]
);
// api client mock
$client = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods(
[
'isConfigured',
'statusesList'
]
)
->getMock();
$client->expects($this->any())
->method('isConfigured')
->willReturn($isConfigured);
$client->expects($this->any())
->method('statusesList')
->willReturn($response);
// status collection mock
$statusCollection = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Status\Collection::class)
->disableOriginalConstructor()
->getMock();
$statusCollection->expects($this->any())
->method('toOptionArray')
->willReturn($this->getTestStatuses());
$data = [
'authSession' => $this->authSessionMock,
'jsHelper' => $this->helperMock,
'data' => ['group' => $this->groupMock],
'client' => $client,
'statusCollection' => $statusCollection,
'context' => $this->context,
'objectFactory' => $this->objectFactory,
'secureRenderer' => $this->secureRenderer
];
$status = $this->objectManager->getObject(
\Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Status::class,
$data
);
$status->setForm($this->form);
$status->setLayout($this->layoutMock);
$html = $status->render($this->elementMock);
$this->assertContains($this->testElementId, $html);
$this->assertContains($this->testFieldSetCss, $html);
if (!$isConfigured) {
$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);
}
}
private function getTestStatuses()
{
$status = [
'label' => 'Test Status',
'value' => 'Test status'
];
return ['test_status' => $status];
}
private function getTestResponse()
{
return [
'success' => true,
'statuses' => [
[
'code' => 'status',
'name' => 'Test status'
]
]
];
}
public function dataProvider()
{
return [
[
'is_successful' => true,
'is_configured' => true
],
[
'is_successful' => false,
'is_configured' => false
],
[
'is_successful' => true,
'is_configured' => false
],
[
'is_successful' => false,
'is_configured' => true
]
];
}
}

View file

@ -0,0 +1,81 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Block\Frontend;
use Retailcrm\Retailcrm\Test\TestCase;
class DaemonCollectorTest extends TestCase
{
private $unit;
private $customer;
const SITE_KEY = 'RC-XXXXXXX-X';
public function setUp()
{
$context = $this->createMock(\Magento\Framework\View\Element\Template\Context::class);
$customerSession = $this->createMock(\Magento\Customer\Model\Session::class);
$storeManager = $this->createMock(\Magento\Store\Model\StoreManager::class);
$storeResolver = $this->createMock(\Magento\Store\Model\StoreResolver::class);
$helper = $this->createMock(\Retailcrm\Retailcrm\Helper\Data::class);
$this->customer = $this->createMock(\Magento\Customer\Model\Customer::class);
$store = $this->createMock(\Magento\Store\Model\Store::class);
$customerSession->expects($this->any())
->method('getCustomer')
->willReturn($this->customer);
$storeResolver->expects($this->any())
->method('getCurrentStoreId')
->willReturn(1);
$store->expects($this->any())
->method('getWebsiteId')
->willReturn(1);
$storeManager->expects($this->any())
->method('getStore')
->willReturn($store);
$helper->expects($this->any())
->method('getSiteKey')
->willReturn(self::SITE_KEY);
$context->expects($this->any())
->method('getStoreManager')
->willReturn($storeManager);
$this->unit = new \Retailcrm\Retailcrm\Block\Frontend\DaemonCollector(
$context,
$customerSession,
$storeResolver,
$helper
);
}
public function testGetJSWithCustomer()
{
$this->customer->expects($this->any())
->method('getId')
->willReturn(1);
$js = $this->unit->buildScript()->getJs();
$this->assertContains('<script type="text/javascript">', $js);
$this->assertContains('</script>', $js);
$this->assertContains('_rc(\'send\', \'pageView\');', $js);
$this->assertContains(self::SITE_KEY, $js);
$this->assertContains('customerId', $js);
}
public function testGetJSWithoutCustomer()
{
$this->customer->expects($this->any())
->method('getId')
->willReturn(null);
$js = $this->unit->buildScript()->getJs();
$this->assertContains('<script type="text/javascript">', $js);
$this->assertContains('</script>', $js);
$this->assertContains('_rc(\'send\', \'pageView\');', $js);
$this->assertContains(self::SITE_KEY, $js);
$this->assertNotContains('customerId', $js);
}
}

View file

@ -0,0 +1,168 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Model\Observer;
use Retailcrm\Retailcrm\Test\TestCase;
class CustomerTest extends TestCase
{
private $mockApi;
private $mockResponse;
private $registry;
private $mockObserver;
private $mockEvent;
private $mockCustomer;
private $unit;
private $helper;
private $mockServiceCustomer;
public function setUp()
{
$this->mockApi = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods([
'customersEdit',
'customersCreate',
'isConfigured',
'setSite'
])
->getMock();
$this->mockResponse = $this->getMockBuilder(\RetailCrm\Response\ApiResponse::class)
->disableOriginalConstructor()
->setMethods(['isSuccessful'])
->getMock();
$this->registry = $this->getMockBuilder(\Magento\Framework\Registry::class)
->disableOriginalConstructor()
->getMock();
$this->mockObserver = $this->getMockBuilder(\Magento\Framework\Event\Observer::class)
->disableOriginalConstructor()
->getMock();
$this->mockEvent = $this->getMockBuilder(\Magento\Framework\Event::class)
->disableOriginalConstructor()
->setMethods(['getCustomer'])
->getMock();
$this->mockCustomer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class)
->disableOriginalConstructor()
->setMethods([
'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->mockServiceCustomer
);
}
/**
* @param boolean $isSuccessful
* @param boolean $isConfigured
* @dataProvider dataProviderCustomer
*/
public function testExecute(
$isSuccessful,
$isConfigured
) {
// mock Response
$this->mockResponse->expects($this->any())
->method('isSuccessful')
->willReturn($isSuccessful);
$this->mockResponse->errorMsg = 'Not found';
// mock API
$this->mockApi->expects($this->any())
->method('customersEdit')
->willReturn($this->mockResponse);
$this->mockApi->expects($this->any())
->method('customersCreate')
->willReturn($this->mockResponse);
$this->mockApi->expects($this->any())
->method('isConfigured')
->willReturn($isConfigured);
$store = $this->createMock(\Magento\Store\Model\Store::class);
$this->mockCustomer->expects($this->any())
->method('getStore')
->willReturn($store);
// mock Event
$this->mockEvent->expects($this->any())
->method('getCustomer')
->willReturn($this->mockCustomer);
// mock Observer
$this->mockObserver->expects($this->any())
->method('getEvent')
->willReturn($this->mockEvent);
$customerObserver = $this->unit->execute($this->mockObserver);
if ($isConfigured) {
$this->assertNotEmpty($this->unit->getCustomer());
$this->assertArrayHasKey('externalId', $this->unit->getCustomer());
$this->assertArrayHasKey('email', $this->unit->getCustomer());
$this->assertArrayHasKey('firstName', $this->unit->getCustomer());
$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);
} else {
$this->assertEmpty($this->unit->getCustomer());
}
}
/**
* @return array
*/
private function getCustomerTestData()
{
return [
'externalId' => 1,
'email' => 'test@mail.com',
'firstName' => 'TestFirstname',
'lastName' => 'Testlastname',
'patronymic' => 'Testmiddlename',
'createdAt' => \date('Y-m-d H:i:s')
];
}
public function dataProviderCustomer()
{
return [
[
'is_successful' => true,
'is_configured' => true
],
[
'is_successful' => false,
'is_configured' => false
],
[
'is_successful' => false,
'is_configured' => true
],
[
'is_successful' => true,
'is_configured' => false
]
];
}
}

View file

@ -0,0 +1,481 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Observer;
use Retailcrm\Retailcrm\Test\TestCase;
/**
* Order create observer test class
*/
class OrderCreateTest extends TestCase
{
private $unit;
private $mockEvent;
private $mockObserver;
private $mockRegistry;
private $mockApi;
private $mockOrder;
private $mockItem;
private $mockStore;
private $mockBillingAddress;
private $mockResponse;
private $mockLogger;
private $mockServiceOrder;
private $mockHelper;
private $mockServiceCustomer;
private $mockCustomer;
public function setUp()
{
$this->mockApi = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods([
'ordersGet',
'ordersCreate',
'customersGet',
'customersCreate',
'customersList',
'getVersion',
'isConfigured',
'setSite'
])
->getMock();
$this->mockObserver = $this->getMockBuilder(\Magento\Framework\Event\Observer::class)
->disableOriginalConstructor()
->getMock();
$this->mockEvent = $this->getMockBuilder(\Magento\Framework\Event::class)
->disableOriginalConstructor()
->setMethods(['getOrder'])
->getMock();
$this->mockLogger = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Logger\Logger::class)
->disableOriginalConstructor()
->getMock();
$this->mockRegistry = $this->getMockBuilder(\Magento\Framework\Registry::class)
->disableOriginalConstructor()
->getMock();
$this->mockOrder = $this->getMockBuilder(\Magento\Sales\Model\Order::class)
->disableOriginalConstructor()
->setMethods([
'getCustomer',
'getId',
'getBillingAddress',
'getStore'
])
->getMock();
$this->mockStore = $this->getMockBuilder(\Magento\Store\Model\Store::class)
->disableOriginalConstructor()
->setMethods(['getCode'])
->getMock();
$this->mockBillingAddress = $this->getMockBuilder(\Magento\Customer\Model\Address\AddressModelInterface::class)
->disableOriginalConstructor()
->setMethods(['getTelephone', 'getData'])
->getMockForAbstractClass();
$this->mockResponse = $this->getMockBuilder(\RetailCrm\Response\ApiResponse::class)
->disableOriginalConstructor()
->setMethods(['isSuccessful'])
->getMock();
$this->mockServiceOrder = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Service\Order::class)
->disableOriginalConstructor()
->getMock();
$this->mockHelper = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->mockServiceCustomer = $this->getMockBuilder(\Retailcrm\Retailcrm\Model\Service\Customer::class)
->disableOriginalConstructor()
->getMock();
$this->mockServiceCustomer->expects($this->any())->method('process')->willReturn($this->getCustomerTestData());
$this->mockServiceCustomer
->expects($this->any())
->method('prepareCustomerFromOrder')
->willReturn(
$this->getCustomerTestData()
);
$this->mockCustomer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class)
->disableOriginalConstructor()
->setMethods([
'getId',
'getEmail',
'getFirstname',
'getMiddlename',
'getLastname',
'getStore',
'getGender',
'getDob',
'getDefaultBillingAddress',
'getAddressesCollection'
])
->getMock();
$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->unit = new \Retailcrm\Retailcrm\Model\Observer\OrderCreate(
$this->mockRegistry,
$this->mockLogger,
$this->mockServiceOrder,
$this->mockServiceCustomer,
$this->mockHelper,
$this->mockApi
);
}
/**
* @param boolean $isSuccessful
* @param string $errorMsg
* @param int $customerIsGuest
* @param string $apiVersion
* @param boolean $isConfigured
* @dataProvider dataProviderOrderCreate
*/
public function testExecute(
$isSuccessful,
$errorMsg,
$customerIsGuest,
$apiVersion,
$isConfigured
) {
$testData = $this->getAfterSaveOrderTestData();
// mock Response
$this->mockResponse->expects($this->any())
->method('isSuccessful')
->willReturn($isSuccessful);
$this->mockResponse->errorMsg = $errorMsg;
// mock API
$this->mockApi->expects($this->any())
->method('ordersGet')
->willReturn($this->mockResponse);
$this->mockApi->expects($this->any())
->method('ordersCreate')
->willReturn($this->mockResponse);
$this->mockApi->expects($this->any())
->method('customersGet')
->willReturn($this->mockResponse);
$this->mockApi->expects($this->any())
->method('customersCreate')
->willReturn($this->mockResponse);
$this->mockApi->expects($this->any())
->method('customersList')
->willReturn($this->mockResponse);
$this->mockApi->expects($this->any())
->method('getVersion')
->willReturn($apiVersion);
$this->mockApi->expects($this->any())
->method('isConfigured')
->willReturn($isConfigured);
// billing address mock set data
$this->mockBillingAddress->expects($this->any())
->method('getTelephone')
->willReturn($testData['order.billingAddress']['telephone']);
$this->mockBillingAddress->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']));
// store mock set data
$this->mockStore->expects($this->any())
->method('getCode')
->willReturn(1);
// order mock set data
$this->mockOrder->expects($this->any())
->method('getId')
->willReturn($testData['order.id']);
$this->mockOrder->expects($this->any())
->method('getBillingAddress')
->willReturn($this->mockBillingAddress);
$this->mockOrder->expects($this->any())
->method('getStore')
->willReturn($this->mockStore);
$this->mockOrder->expects($this->any())
->method('getCustomer')
->willReturn($this->mockCustomer);
// mock Event
$this->mockEvent->expects($this->any())
->method('getOrder')
->willReturn($this->mockOrder);
// mock Observer
$this->mockObserver->expects($this->any())
->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) {
$this->assertNotEmpty($this->unit->getOrder());
$this->assertArrayHasKey('externalId', $this->unit->getOrder());
$this->assertArrayHasKey('number', $this->unit->getOrder());
$this->assertArrayHasKey('createdAt', $this->unit->getOrder());
$this->assertArrayHasKey('lastName', $this->unit->getOrder());
$this->assertArrayHasKey('firstName', $this->unit->getOrder());
$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('items', $this->unit->getOrder());
$this->assertArrayHasKey('delivery', $this->unit->getOrder());
if ($apiVersion == 'v5') {
$this->assertArrayHasKey('payments', $this->unit->getOrder());
} else {
$this->assertArrayHasKey('paymentType', $this->unit->getOrder());
}
$this->assertInstanceOf(\Retailcrm\Retailcrm\Model\Observer\OrderCreate::class, $orderCreateObserver);
} elseif (!$isConfigured || $isSuccessful) {
$this->assertEmpty($this->unit->getOrder());
}
}
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
*
* @return array $testOrderData
*/
private function getAfterSaveOrderTestData()
{
$testOrderData = [
'order.id' => 1,
'order.status' => 'processing',
'order.realOrderId' => '000000001',
'order.billingAddress' => [
'telephone' => '890000000000',
'data' => [
'city' => 'Moscow',
'region' => 'Moscow',
'street' => 'TestStreet',
'postcode' => '111111',
'country_id' => 'RU'
]
],
'order.allItems' => [$this->mockItem],
'order.shippingMethod' => 'flatrate_flatrate',
'order.paymentMethod' => 'checkmo',
'order.customerLastname' => 'Test',
'order.customerFirstname' => 'Test',
'order.customerMiddlename' => 'Test',
'order.customerEmail' => 'test@gmail.com'
];
return $testOrderData;
}
public function getCallbackDataAddress($dataKey)
{
$testData = $this->getAfterSaveOrderTestData();
return $testData['order.billingAddress']['data'][$dataKey];
}
public function dataProviderOrderCreate()
{
return [
[
'is_successful' => true,
'error_msg' => 'Not found',
'customer_is_guest' => 1,
'api_version' => 'v4',
'is_configured' => true
],
[
'is_successful' => true,
'error_msg' => 'Not found',
'customer_is_guest' => 0,
'api_version' => 'v4',
'is_configured' => false
],
[
'is_successful' => false,
'error_msg' => 'Not found',
'customer_is_guest' => 1,
'api_version' => 'v4',
'is_configured' => true
],
[
'is_successful' => false,
'error_msg' => 'Not found',
'customer_is_guest' => 0,
'api_version' => 'v4',
'is_configured' => false
],
[
'is_successful' => true,
'error_msg' => 'Not found',
'customer_is_guest' => 1,
'api_version' => 'v5',
'is_configured' => true
],
[
'is_successful' => true,
'error_msg' => 'Not found',
'customer_is_guest' => 0,
'api_version' => 'v5',
'is_configured' => false
],
[
'is_successful' => false,
'error_msg' => 'Not found',
'customer_is_guest' => 1,
'api_version' => 'v5',
'is_configured' => true
],
[
'is_successful' => false,
'error_msg' => 'Not found',
'customer_is_guest' => 0,
'api_version' => 'v5',
'is_configured' => false
]
];
}
/**
* 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
];
}
/**
* @return array
*/
private function getCustomerTestData()
{
return [
'externalId' => 1,
'email' => 'test@mail.com',
'firstName' => 'TestFirstname',
'lastName' => 'Testlastname',
'patronymic' => 'Testmiddlename',
'createdAt' => \date('Y-m-d H:i:s')
];
}
}

Some files were not shown because too many files have changed in this diff Show more