1
0
Fork 0
mirror of synced 2025-04-05 06:03:37 +03:00

Compare commits

...

72 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
Akolzin Dmitry
682fcb8545 Multiversions api (#8) 2018-03-12 16:34:48 +03:00
Alex Lushpai
b5bb377379 Update README.md 2017-06-02 10:32:20 +03:00
Alex Lushpai
f4000c9874 v2.0 2017-05-31 15:24:46 +03:00
Alex Lushpai
f838099bb0 Merge pull request #5 from Rugento/patch-2
Update Order.php
2017-05-18 13:10:47 +03:00
Alex Lushpai
335c192a0e Merge pull request #6 from devzorg/patch-1
Support an purchase price
2017-05-18 13:09:48 +03:00
Oleg
b0402f3558 Support an purchase price
Use Cost attribute in Magento. Don't forget to select this attribute for exchange with RetailCRM for purchase price feature.
2017-05-17 16:33:29 +03:00
Rugento
02bfb8224f Update and rename Order.php to Rugento
Забыли массив
2017-05-14 23:03:15 +03:00
124 changed files with 8571 additions and 5166 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

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 каталог теперь формируется для каждого сайта
* При формировании каталога выгружаются выбранные атрибуты товаров
* Улучшена выгрузка товаров в заказе (теперь учитываются конфигурируемые товары)
* Добавлены переводы на русский и испанский языки
* Из обработки истории удален менеджер объектов

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

View file

@ -1,14 +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 module for interaction with [RetailCRM](http://www.retailcrm.ru) through [REST API](http://retailcrm.ru/docs/Разработчики).
**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 with retailCRM
* Configure relations between dictionaries of RetailCRM and Magento (statuses, payments, delivery types and etc)
* Generate [ICML](http://docs.retailcrm.ru/index.php?n=Разработчики.ФорматICML) (Intaro Markup Language) for catalog loading by 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
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://retailcrm.ru/retailcrm_default.xml
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
```
This module is compatible with Magento up to version 2.2.8

30
README.ru.md Normal file
View file

@ -0,0 +1,30 @@
DEPRECATED Magento module
**Модуль устарел и больше не поддерживается**
Модуль 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
## ICML
По умолчанию ICML-файл генерируется модулем каждые 4 часа. Вы можете найти файл в корневой папке с именем «retailcrm_{{shop_code}}.xml". Например, http://example.ru/retailcrm_default.xml
## Ручная установка
1) Распакуйте архив с модулем в директорию "app/code/Retailcrm/Retailcrm". В файле "app/etc/config.php" в массив `modules` добавьте элемент `'Retailcrm_Retailcrm' => 1`
2) Выполните в папке проекта:
```bash
composer require retailcrm/api-client-php ~5.0
```
В конфигурационный файл `composer.json` вашего проекта будет добавлена библиотека [retailcrm/api-client-php](https://github.com/retailcrm/api-client-php), которая будет установлена в директорию `vendor/`.
Этот модуль совместим с Magento 2 до версии 2.2.8

1
VERSION Normal file
View file

@ -0,0 +1 @@
2.5.2

View file

@ -1,51 +0,0 @@
<?php
class Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Button extends Mage_Adminhtml_Block_System_Config_Form_Field
{
/**
* Set template
*/
protected function _construct()
{
parent::_construct();
$this->setTemplate('retailcrm/system/config/button.phtml');
}
/**
* Return element html
*
* @param Varien_Data_Form_Element_Abstract $element
* @return string
*/
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
{
return $this->_toHtml();
}
/**
* Return ajax url for button
*
* @return string
*/
public function getAjaxCheckUrl()
{
return Mage::helper('adminhtml')->getUrl('adminhtml/adminhtml_Retailcrmbutton/check');
}
/**
* Generate button html
*
* @return string
*/
public function getButtonHtml()
{
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
->setData(
array(
'id' => 'Retailcrmbutton_button',
'label' => $this->helper('adminhtml')->__('Run now'),
'onclick' => 'javascript:check(); return false;'
)
);
return $button->toHtml();
}
}

View file

@ -1,43 +0,0 @@
<?php
class Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Fieldset_Base extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
{
protected $_fieldRenderer;
protected $_values;
protected $_apiKey;
protected $_apiUrl;
protected $_isCredentialCorrect;
public function __construct()
{
parent::__construct();
$this->_apiUrl = Mage::getStoreConfig('retailcrm/general/api_url');
$this->_apiKey = Mage::getStoreConfig('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);
Mage::getModel('core/config')->saveConfig('retailcrm/general/api_url', $this->_apiUrl);
}
$client = new Retailcrm_Retailcrm_Model_ApiClient(
$this->_apiUrl,
$this->_apiKey
);
try {
$response = $client->sitesList();
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
if ($response->isSuccessful()) {
$this->_isCredentialCorrect = true;
if($response['success'] != 1) {
Mage::getModel('core/config')->saveConfig('retailcrm/general/api_url', '');
}
}
}
}
}

View file

@ -1,10 +0,0 @@
<?php
class Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Fieldset_Order extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
{
protected $_numberOrder;
public function __construct()
{
}
}

View file

@ -1,89 +0,0 @@
<?php
class Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Fieldset_Payment extends Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Fieldset_Base
{
public function render(Varien_Data_Form_Element_Abstract $element)
{
$html = $this->_getHeaderHtml($element);
if(!empty($this->_apiUrl) && !empty($this->_apiKey) && $this->_isCredentialCorrect) {
$groups = Mage::getSingleton('payment/config')->getActiveMethods();
foreach ($groups as $group) {
$html .= $this->_getFieldHtml($element, $group);
}
} else {
$html .= '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
}
$html .= $this->_getFooterHtml($element);
return $html;
}
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$this->_fieldRenderer = Mage::getBlockSingleton('adminhtml/system_config_form_field');
}
return $this->_fieldRenderer;
}
/**
* @return array
*/
protected function _getValues()
{
if(!empty($this->_apiUrl) && !empty($this->_apiKey) && $this->_isCredentialCorrect) {
$client = new Retailcrm_Retailcrm_Model_ApiClient(
$this->_apiUrl,
$this->_apiKey
);
try {
$paymentTypes = $client->paymentTypesList();
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
if ($paymentTypes->isSuccessful()) {
if (empty($this->_values)) {
foreach ($paymentTypes['paymentTypes'] as $type) {
$this->_values[] = array('label' => Mage::helper('adminhtml')->__($type['name']), 'value' => $type['code']);
}
}
}
}
return $this->_values;
}
protected function _getFieldHtml($fieldset, $group)
{
$configData = $this->getConfigData();
$path = 'retailcrm/payment/' . $group->getId();
if (isset($configData[$path])) {
$data = $configData[$path];
$inherit = false;
} else {
$data = (int)(string)$this->getForm()->getConfigRoot()->descend($path);
$inherit = true;
}
$field = $fieldset->addField(
'payment_' . $group->getId(), 'select',
array(
'name' => 'groups[payment][fields]['.$group->getId().'][value]',
'label' => Mage::getStoreConfig('payment/'.$group->getId().'/title'),
'value' => $data,
'values' => $this->_getValues(),
'inherit' => $inherit,
'can_use_default_value' => 1,
'can_use_website_value' => 1
)
)->setRenderer($this->_getFieldRenderer());
return $field->toHtml();
}
}

View file

@ -1,89 +0,0 @@
<?php
class Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Fieldset_Shipping extends Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Fieldset_Base
{
public function render(Varien_Data_Form_Element_Abstract $element)
{
$html = $this->_getHeaderHtml($element);
if(!empty($this->_apiUrl) && !empty($this->_apiKey) && $this->_isCredentialCorrect) {
$groups = Mage::getSingleton('shipping/config')->getActiveCarriers();
foreach ($groups as $group) {
$html .= $this->_getFieldHtml($element, $group);
}
} else {
$html .= '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
}
$html .= $this->_getFooterHtml($element);
return $html;
}
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$this->_fieldRenderer = Mage::getBlockSingleton('adminhtml/system_config_form_field');
}
return $this->_fieldRenderer;
}
/**
* @return array
*/
protected function _getValues()
{
if(!empty($this->_apiUrl) && !empty($this->_apiKey) && $this->_isCredentialCorrect) {
$client = new Retailcrm_Retailcrm_Model_ApiClient(
$this->_apiUrl,
$this->_apiKey
);
try {
$deliveryTypes = $client->deliveryTypesList();
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
if ($deliveryTypes->isSuccessful()) {
if (empty($this->_values)) {
foreach ($deliveryTypes['deliveryTypes'] as $type) {
$this->_values[] = array('label'=>Mage::helper('adminhtml')->__($type['name']), 'value'=>$type['code']);
}
}
}
}
return $this->_values;
}
protected function _getFieldHtml($fieldset, $group)
{
$configData = $this->getConfigData();
$path = 'retailcrm/shipping/' . $group->getId();
if (isset($configData[$path])) {
$data = $configData[$path];
$inherit = false;
} else {
$data = (int)(string)$this->getForm()->getConfigRoot()->descend($path);
$inherit = true;
}
$field = $fieldset->addField(
'shipping_' . $group->getId(), 'select',
array(
'name' => 'groups[shipping][fields]['.$group->getId().'][value]',
'label' => Mage::getStoreConfig('carriers/'.$group->getId().'/title'),
'value' => $data,
'values' => $this->_getValues(),
'inherit' => $inherit,
'can_use_default_value' => 1,
'can_use_website_value' => 1
)
)->setRenderer($this->_getFieldRenderer());
return $field->toHtml();
}
}

View file

@ -1,89 +0,0 @@
<?php
class Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Fieldset_Status extends Retailcrm_Retailcrm_Block_Adminhtml_System_Config_Form_Fieldset_Base
{
public function render(Varien_Data_Form_Element_Abstract $element)
{
$html = $this->_getHeaderHtml($element);
if(!empty($this->_apiUrl) && !empty($this->_apiKey) && $this->_isCredentialCorrect) {
$statuses = Mage::getModel('sales/order_status')->getResourceCollection()->getData();
foreach ($statuses as $status) {
$html .= $this->_getFieldHtml($element, $status);
}
} else {
$html .= '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
}
$html .= $this->_getFooterHtml($element);
return $html;
}
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$this->_fieldRenderer = Mage::getBlockSingleton('adminhtml/system_config_form_field');
}
return $this->_fieldRenderer;
}
/**
* @return array
*/
protected function _getValues()
{
if(!empty($this->_apiUrl) && !empty($this->_apiKey) && $this->_isCredentialCorrect) {
$client = new Retailcrm_Retailcrm_Model_ApiClient(
$this->_apiUrl,
$this->_apiKey
);
try {
$statuses = $client->statusesList();
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
if ($statuses->isSuccessful()) {
if (empty($this->_values)) {
foreach ($statuses['statuses'] as $status) {
$this->_values[] = array('label'=>Mage::helper('adminhtml')->__($status['name']), 'value'=>$status['code']);
}
}
}
}
return $this->_values;
}
protected function _getFieldHtml($fieldset, $group)
{
$configData = $this->getConfigData();
$path = 'retailcrm/status/' . $group['status'];
if (isset($configData[$path])) {
$data = $configData[$path];
$inherit = false;
} else {
$data = (int)(string)$this->getForm()->getConfigRoot()->descend($path);
$inherit = true;
}
$field = $fieldset->addField(
'status_' . $group['status'], 'select',
array(
'name' => 'groups[status][fields]['.$group['status'].'][value]',
'label' => $group['label'],
'value' => $data,
'values' => $this->_getValues(),
'inherit' => $inherit,
'can_use_default_value' => 1,
'can_use_website_value' => 1
)
)->setRenderer($this->_getFieldRenderer());
return $field->toHtml();
}
}

View file

@ -1,176 +0,0 @@
<?php
/**
* Default extension helper class
* PHP version 5.3
*
* @category Model
* @package RetailCrm\Model
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license http://opensource.org/licenses/MIT MIT License
* @link http://www.magentocommerce.com/magento-connect/retailcrm-1.html
*/
/**
* Data helper class
*
* @category Model
* @package RetailCrm\Model
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license http://opensource.org/licenses/MIT MIT License
* @link http://www.magentocommerce.com/magento-connect/retailcrm-1.html
*
* @SuppressWarnings(PHPMD.CamelCaseClassName)
*/
class Retailcrm_Retailcrm_Helper_Data extends Mage_Core_Helper_Abstract
{
/**
* Path to store config if front-end output is enabled
*
* @var string
*/
const XML_API_URL = 'retailcrm/general/api_url';
/**
* Path to store config where count of news posts per page is stored
*
* @var string
*/
const XML_API_KEY = 'retailcrm/general/api_key';
/**
* Get api url
*
* @param Mage_Core_Model_Store $store store instance
*
* @SuppressWarnings(PHPMD.StaticAccess)
*
* @return int
*/
public function getApiUrl($store = null)
{
return abs((int)Mage::getStoreConfig(self::XML_API_URL, $store));
}
/**
* Get api key
*
* @param Mage_Core_Model_Store $store store instance
*
* @SuppressWarnings(PHPMD.StaticAccess)
*
* @return int
*/
public function getApiKey($store = null)
{
return abs((int)Mage::getStoreConfig(self::XML_API_KEY, $store));
}
/**
* Get api key
*
* @param string $baseUrl base url
* @param mixed $coreUrl url rewritte
* @param integer $productId product id
* @param integer $storeId product store id
* @param integer $categoryId product category id
*
* @SuppressWarnings(PHPMD.StaticAccess)
*
* @return string
*/
public function rewrittenProductUrl($baseUrl,$coreUrl,$productId,$storeId,$categoryId = null)
{
$idPath = sprintf('product/%d', $productId);
if ($categoryId) {
$idPath = sprintf('%s/%d', $idPath, $categoryId);
}
$coreUrl->setStoreId($storeId);
$coreUrl->loadByIdPath($idPath);
return $baseUrl . $coreUrl->getRequestPath();
}
/**
* Get country code
*
* @param string $string country iso code
*
* @SuppressWarnings(PHPMD.StaticAccess)
*
* @return string
*/
public function getCountryCode($string)
{
$country = empty($string) ? 'RU' : $string;
$xmlObj = new Varien_Simplexml_Config(
sprintf(
"%s%s%s",
Mage::getModuleDir('etc', 'Retailcrm_Retailcrm'),
DS,
'country.xml'
)
);
$xmlData = $xmlObj->getNode();
if ($country != 'RU') {
foreach ($xmlData as $elem) {
if ($elem->name == $country || $elem->english == $country) {
$country = $elem->alpha;
break;
}
}
}
return (string) $country;
}
/**
* Get exchage time
*
* @param string $datetime datetime string
*
* @return \DateTime
*/
public function getExchangeTime($datetime)
{
return $datetime = empty($datetime)
? new DateTime(
date(
'Y-m-d H:i:s',
strtotime('-1 days', strtotime(date('Y-m-d H:i:s')))
)
)
: new DateTime($datetime);
}
/**
* 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;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,43 +0,0 @@
<?php
class Retailcrm_Retailcrm_Model_Attribute
{
/**
* Options getter
*
* @return array
*/
public function toOptionArray()
{
$attributes = Mage::getResourceModel('catalog/product_attribute_collection')
->getItems();
$data = array();
foreach($attributes as $attribute) {
if(empty($attribute->getFrontendLabel())) continue;
$data[] = array(
'label' => $attribute->getFrontendLabel(),
'value' => $attribute->getAttributeCode()
);
}
return $data;
}
/**
* Get options in "key-value" format
*
* @return array
*/
public function toArray()
{
return array();
return array(
0 => Mage::helper('adminhtml')->__('Data1'),
1 => Mage::helper('adminhtml')->__('Data2'),
2 => Mage::helper('adminhtml')->__('Data3'),
);
}
}

View file

@ -1,75 +0,0 @@
<?php
/**
* Customer class
*
* @category Model
* @package RetailCrm\Model
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license http://opensource.org/licenses/MIT MIT License
* @link http://www.magentocommerce.com/magento-connect/retailcrm-1.html
*
* @SuppressWarnings(PHPMD.CamelCaseClassName)
*/
class Retailcrm_Retailcrm_Model_Customer extends Retailcrm_Retailcrm_Model_Exchange
{
/**
* Customer create
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.ElseExpression)
* @param mixed $data
*
* @return bool
*/
public function customerRegister($data)
{
$customer = array(
'externalId' => $data->getId(),
'email' => $data->getEmail(),
'firstName' => $data->getFirstname(),
'patronymic' => $data->getMiddlename(),
'lastName' => $data->getLastname(),
'createdAt' => Mage::getSingleton('core/date')->date()
);
$this->_api->customersEdit($customer);
}
/**
* Customers export
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.ElseExpression)
*
* @return bool
*/
public function customersExport()
{
$customers = array();
$customerCollection = Mage::getModel('customer/customer')
->getCollection()
->addAttributeToSelect('email')
->addAttributeToSelect('firstname')
->addAttributeToSelect('lastname');
foreach ($customerCollection as $customerData) {
$customer = array(
'externalId' => $customerData->getId(),
'email' => $customerData->getData('email'),
'firstName' => $customerData->getData('firstname'),
'lastName' => $customerData->getData('lastname')
);
$customers[] = $customer;
}
unset($customerCollection);
$chunked = array_chunk($customers, 50);
unset($customers);
foreach ($chunked as $chunk) {
$this->_api->customersUpload($chunk);
time_nanosleep(0, 250000000);
}
unset($chunked);
return true;
}
}

View file

@ -1,5 +0,0 @@
<?php
class Retailcrm_Retailcrm_Model_Exception_CurlException extends RuntimeException
{
}

View file

@ -1,5 +0,0 @@
<?php
class Retailcrm_Retailcrm_Model_Exception_InvalidJsonException extends DomainException
{
}

View file

@ -1,981 +0,0 @@
<?php
class Retailcrm_Retailcrm_Model_Exchange
{
protected $_apiKey;
protected $_apiUrl;
protected $_config;
protected $_api;
public function __construct()
{
$this->_apiUrl = Mage::getStoreConfig('retailcrm/general/api_url');
$this->_apiKey = Mage::getStoreConfig('retailcrm/general/api_key');
if(!empty($this->_apiUrl) && !empty($this->_apiKey)) {
$this->_api = new Retailcrm_Retailcrm_Model_ApiClient(
$this->_apiUrl,
$this->_apiKey
);
}
}
/**
* Get orders history & modify orders into shop
*
*/
public function ordersHistory()
{
$runTime = $this->getExchangeTime($this->_config['general']['history']);
$historyFilter = array();
$historiOrder = array();
$historyStart = Mage::getStoreConfig('retailcrm/general/fhistory');
if($historyStart && $historyStart > 0) {
$historyFilter['sinceId'] = $historyStart;
}
while(true) {
try {
$response = $this->_api->ordersHistory($historyFilter);
if ($response->isSuccessful()&&200 === $response->getStatusCode()) {
$nowTime = $response->getGeneratedAt();
} else {
Mage::log(
sprintf("Orders history error: [HTTP status %s] %s", $response->getStatusCode(), $response->getErrorMsg())
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
return false;
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
return false;
}
$orderH = isset($response['history']) ? $response['history'] : array();
if(count($orderH) == 0) {
return true;
}
$historiOrder = array_merge($historiOrder, $orderH);
$end = array_pop($response->history);
$historyFilter['sinceId'] = $end['id'];
if($response['pagination']['totalPageCount'] == 1) {
Mage::getModel('core/config')->saveConfig('retailcrm/general/fhistory', $historyFilter['sinceId']);
$orders = self::assemblyOrder($historiOrder);
$this->processOrders($orders, $nowTime);
return true;
}
}//endwhile
}
/**
* @param array $orders
*/
private function processOrders($orders, $time)
{
if(!empty($orders)) {
Mage::getModel('core/config')->saveConfig(
'retailcrm/general/history', $time
);
foreach ($orders as $order) {
if(!empty($order['externalId'])) {
$this->doUpdate($order);
} else {
$this->doCreate($order);
}
}
die();
}
}
/**
* @param array $order
*/
private function doCreate($order)
{
Mage::log($order, null, 'retailcrmHistoriCreate.log', true);
try {
$response = $this->_api->ordersGet($order['id'], $by = 'id');
if ($response->isSuccessful() && 200 === $response->getStatusCode()) {
$order = $response->order;
} else {
Mage::log(
sprintf(
"Orders get error: [HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
// get references
$this->_config = Mage::getStoreConfig('retailcrm');
$payments = array_flip(array_filter($this->_config['payment']));
$shippings = array_flip(array_filter($this->_config['shipping']));
// get store
$_sendConfirmation = '0';
$storeId = Mage::app()->getStore()->getId();
$siteid = Mage::getModel('core/store')->load($storeId)->getWebsiteId();
// search or create customer
$customer = Mage::getSingleton('customer/customer');
$customer->setWebsiteId($siteid);
$customer->loadByEmail($order['email']);
if (!is_numeric($customer->getId())) {
$customer
->setGropuId(1)
->setWebsiteId($siteid)
->setStore($storeId)
->setEmail($order['email'])
->setFirstname($order['firstName'])
->setLastname($order['lastName'])
->setMiddleName($order['patronymic'])
->setPassword(uniqid());
try {
$customer->save();
$customer->setConfirmation(null);
$customer->save();
} catch (Exception $e) {
Mage::log($e->getMessage());
}
$address = Mage::getModel("customer/address");
$address->setCustomerId($customer->getId())
->setFirstname($customer->getFirstname())
->setMiddleName($customer->getMiddlename())
->setLastname($customer->getLastname())
->setCountryId($this->getCountryCode($order['customer']['address']['country']))
->setPostcode($order['delivery']['address']['index'])
->setCity($order['delivery']['address']['city'])
->setRegion($order['delivery']['address']['region'])
->setTelephone($order['phone'])
->setStreet($order['delivery']['address']['street'])
->setIsDefaultBilling('1')
->setIsDefaultShipping('1')
->setSaveInAddressBook('1');
try{
$address->save();
}
catch (Exception $e) {
Mage::log($e->getMessage());
}
try {
$response = $this->_api->customersFixExternalIds(
array(
'id' => $order['customer']['id'],
'externalId' => $customer->getId()
)
);
if (!$response->isSuccessful() || 200 !== $response->getStatusCode()) {
Mage::log(
sprintf(
"Orders fix error: [HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
}
$products = array();
foreach ($order['items'] as $item) {
$products[$item['offer']['externalId']] = array('qty' => $item['quantity']);
}
$orderData = array(
'session' => array(
'customer_id' => $customer->getId(),
'store_id' => $storeId,
),
'payment' => array(
'method' => $payments[$order['paymentType']],
),
'add_products' => $products,
'order' => array(
'account' => array(
'group_id' => $customer->getGroupId(),
'email' => $order['email']
),
'billing_address' => array(
'firstname' => $order['firstName'],
'middlename' => $order['patronymic'],
'lastname' => $order['lastName'],
'street' => $order['delivery']['address']['street'],
'city' => $order['delivery']['address']['city'],
'country_id' => $this->getCountryCode($order['customer']['address']['country']),
'region' => $order['delivery']['address']['region'],
'postcode' => $order['delivery']['address']['index'],
'telephone' => $order['phone'],
),
'shipping_address' => array(
'firstname' => $order['firstName'],
'middlename' => $order['patronymic'],
'lastname' => $order['lastName'],
'street' => $order['delivery']['address']['street'],
'city' => $order['delivery']['address']['city'],
'country_id' => $this->getCountryCode($order['customer']['address']['country']),
'region' => $order['delivery']['address']['region'],
'postcode' => $order['delivery']['address']['index'],
'telephone' => $order['phone'],
),
'shipping_method' => $shippings[$order['delivery']['code']],
'comment' => array(
'customer_note' => $order['customerComment'],
),
'send_confirmation' => $_sendConfirmation
)
);
Mage::unregister('sales_order_place_after');
Mage::register('sales_order_place_after', 1);
$quote = Mage::getModel('sales/quote')->setStoreId($storeId);
$quote->assignCustomer($customer);
$quote->setSendCconfirmation($_sendConfirmation);
foreach($products as $idx => $val) {
$product = Mage::getModel('catalog/product')->load($idx);
$quote->addProduct($product, new Varien_Object($val));
}
$shipping_method = self::getAllShippingMethodsCode($orderData['order']['shipping_method']);
$billingAddress = $quote->getBillingAddress()->addData($orderData['order']['billing_address']);
$shippingAddress = $quote->getShippingAddress()->addData($orderData['order']['shipping_address']);
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($shipping_method)
->setPaymentMethod($orderData['payment']['method']);
$quote->getPayment()->importData($orderData['payment']);
$quote->collectTotals();
$quote->reserveOrderId();
$quote->save();
$service = Mage::getModel('sales/service_quote', $quote);
try{
$service->submitAll();
}
catch (Exception $e) {
Mage::log($e->getMessage());
}
try {
$response = $this->_api->ordersFixExternalIds(
array(
array(
'id' => $order['id'],
'externalId' =>$service->getOrder()->getRealOrderId()
)
)
);
if (!$response->isSuccessful() || 200 !== $response->getStatusCode()) {
Mage::log(
sprintf(
"Orders fix error: [HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
}
/**
* @param array $order
*/
private function doCreateUp($order)
{
Mage::log($order, null, 'retailcrmHistoriCreateUp.log', true);
try {
$response = $this->_api->ordersGet($order['id'], $by = 'id');
if ($response->isSuccessful() && 200 === $response->getStatusCode()) {
$order = $response->order;
} else {
Mage::log(
sprintf(
"Orders get error: [HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
// get references
$this->_config = Mage::getStoreConfig('retailcrm');
$payments = array_flip(array_filter($this->_config['payment']));
$shippings = array_flip(array_filter($this->_config['shipping']));
// get store
$_sendConfirmation = '0';
$storeId = Mage::app()->getStore()->getId();
$siteid = Mage::getModel('core/store')->load($storeId)->getWebsiteId();
// search or create customer
$customer = Mage::getSingleton('customer/customer');
$customer->setWebsiteId($siteid);
$customer->loadByEmail($order['email']);
if (!is_numeric($customer->getId())) {
$customer
->setGropuId(1)
->setWebsiteId($siteid)
->setStore($storeId)
->setEmail($order['email'])
->setFirstname($order['firstName'])
->setLastname($order['lastName'])
->setMiddleName($order['patronymic'])
->setPassword(uniqid());
try {
$customer->save();
$customer->setConfirmation(null);
$customer->save();
} catch (Exception $e) {
Mage::log($e->getMessage());
}
$address = Mage::getModel("customer/address");
$address->setCustomerId($customer->getId())
->setFirstname($customer->getFirstname())
->setMiddleName($customer->getMiddlename())
->setLastname($customer->getLastname())
->setCountryId($this->getCountryCode($order['customer']['address']['country']))
->setPostcode($order['delivery']['address']['index'])
->setCity($order['delivery']['address']['city'])
->setRegion($order['delivery']['address']['region'])
->setTelephone($order['phone'])
->setStreet($order['delivery']['address']['street'])
->setIsDefaultBilling('1')
->setIsDefaultShipping('1')
->setSaveInAddressBook('1');
try{
$address->save();
}
catch (Exception $e) {
Mage::log($e->getMessage());
}
try {
$response = $this->_api->customersFixExternalIds(
array(
'id' => $order['customer']['id'],
'externalId' => $customer->getId()
)
);
if (!$response->isSuccessful() || 200 !== $response->getStatusCode()) {
Mage::log(
sprintf(
"Orders fix error: [HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
}
$products = array();
foreach ($order['items'] as $item) {
$products[$item['offer']['externalId']] = array('qty' => $item['quantity']);
}
$orderData = array(
'session' => array(
'customer_id' => $customer->getId(),
'store_id' => $storeId,
),
'payment' => array(
'method' => $payments[$order['paymentType']],
),
'add_products' => $products,
'order' => array(
'account' => array(
'group_id' => $customer->getGroupId(),
'email' => $order['email']
),
'billing_address' => array(
'firstname' => $order['firstName'],
'middlename' => $order['patronymic'],
'lastname' => $order['lastName'],
'street' => $order['delivery']['address']['street'],
'city' => $order['delivery']['address']['city'],
'country_id' => $this->getCountryCode($order['customer']['address']['country']),
'region' => $order['delivery']['address']['region'],
'postcode' => $order['delivery']['address']['index'],
'telephone' => $order['phone'],
),
'shipping_address' => array(
'firstname' => $order['firstName'],
'middlename' => $order['patronymic'],
'lastname' => $order['lastName'],
'street' => $order['delivery']['address']['street'],
'city' => $order['delivery']['address']['city'],
'country_id' => $this->getCountryCode($order['customer']['address']['country']),
'region' => $order['delivery']['address']['region'],
'postcode' => $order['delivery']['address']['index'],
'telephone' => $order['phone'],
),
'shipping_method' => $shippings[$order['delivery']['code']],
'comment' => array(
'customer_note' => $order['customerComment'],
),
'send_confirmation' => $_sendConfirmation
)
);
$quote = Mage::getModel('sales/quote')->setStoreId($storeId);
$quote->assignCustomer($customer);
$quote->setSendCconfirmation($_sendConfirmation);
foreach($products as $idx => $val) {
$product = Mage::getModel('catalog/product')->load($idx);
$quote->addProduct($product, new Varien_Object($val));
}
$shipping_method = self::getAllShippingMethodsCode($orderData['order']['shipping_method']);
$billingAddress = $quote->getBillingAddress()->addData($orderData['order']['billing_address']);
$shippingAddress = $quote->getShippingAddress()->addData($orderData['order']['shipping_address']);
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($shipping_method)
->setPaymentMethod($orderData['payment']['method']);
$quote->getPayment()->importData($orderData['payment']);
$quote->collectTotals();
$originalId = $order['externalId'];
$oldOrder = Mage::getModel('sales/order')->loadByIncrementId($originalId);
$oldOrderArr = $oldOrder->getData();
if(!empty($oldOrderArr['original_increment_id'])) {
$originalId = $oldOrderArr['original_increment_id'];
}
$orderDataUp = array(
'original_increment_id' => $originalId,
'relation_parent_id' => $oldOrder->getId(),
'relation_parent_real_id' => $oldOrder->getIncrementId(),
'edit_increment' => $oldOrder->getEditIncrement()+1,
'increment_id' => $originalId.'-'.($oldOrder->getEditIncrement()+1)
);
$quote->setReservedOrderId($orderDataUp['increment_id']);
$quote->save();
$service = Mage::getModel('sales/service_quote', $quote);
$service->setOrderData($orderDataUp);
try{
$service->submitAll();
}
catch (Exception $e) {
Mage::log($e->getMessage());
}
$magentoOrder = Mage::getModel('sales/order')->loadByIncrementId($orderDataUp['relation_parent_real_id']);
$magentoOrder->setState(Mage_Sales_Model_Order::STATE_CANCELED, true)->save();
try {
$response = $this->_api->ordersFixExternalIds(
array(
array(
'id' => $order['id'],
'externalId' =>$service->getOrder()->getRealOrderId()
)
)
);
if (!$response->isSuccessful() || 200 !== $response->getStatusCode()) {
Mage::log(
sprintf(
"Orders fix error: [HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
}
/**
* @param array $order
*/
private function doUpdate($order)
{
$magentoOrder = Mage::getModel('sales/order')->loadByIncrementId($order['externalId']);
$magentoOrderArr = $magentoOrder->getData();
$config = Mage::getStoreConfig('retailcrm');
Mage::log($order, null, 'retailcrmHistoriUpdate.log', true);
if((!empty($order['order_edit']))&&($order['order_edit'] == 1)) {
$this->doCreateUp($order);
}
if (!empty($order['status'])) {
try {
$response = $this->_api->statusesList();
if ($response->isSuccessful() && 200 === $response->getStatusCode()) {
$code = $order['status'];
$group = $response->statuses[$code]['group'];
if ($magentoOrder->hasInvoices()) {
$invIncrementIDs = array();
foreach ($magentoOrder->getInvoiceCollection() as $inv) {
$invIncrementIDs[] = $inv->getIncrementId();
}
}
if (in_array($group, array('approval', 'assembling', 'delivery'))) {
if(empty($invIncrementIDs)) {
$magentoOrder->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true);
$magentoOrder->save();
$invoice = $magentoOrder->prepareInvoice()
->setTransactionId($magentoOrder->getRealOrderId())
->addComment("Add status on CRM")
->register()
->pay();
$transaction_save = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transaction_save->save();
}
}
if (in_array($group, array('complete'))) {
if(empty($invIncrementIDs)){
$invoice = $magentoOrder->prepareInvoice()
->setTransactionId($magentoOrder->getRealOrderId())
->addComment("Add status on CRM")
->register()
->pay();
$transaction_save = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transaction_save->save();
$magentoOrder->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
}
if($magentoOrder->canShip()) {
$itemQty = $magentoOrder->getItemsCollection()->count();
$shipment = Mage::getModel('sales/service_order', $magentoOrder)->prepareShipment($itemQty);
$shipment = new Mage_Sales_Model_Order_Shipment_Api();
$shipmentId = $shipment->create($order['externalId']);
}
}
if($code == $config['status']['canceled']) {
$magentoOrder->setState(Mage_Sales_Model_Order::STATE_CANCELED, true)->save();
}
if($code == $config['status']['holded']) {
if($magentoOrder->canHold()){
$magentoOrder->hold()->save();
}
}
if($code == $config['status']['unhold']) {
if($magentoOrder->canUnhold()) {
$magentoOrder->unhold()->save();
}
}
if($code == $config['status']['closed']) {
if($magentoOrder->canCreditmemo()) {
$orderItem = $magentoOrder->getItemsCollection();
foreach ($orderItem as $item) {
$data['qtys'][$item->getid()] = $item->getQtyOrdered();
}
$service = Mage::getModel('sales/service_order', $magentoOrder);
$creditMemo = $service->prepareCreditmemo($data)->register()->save();
$magentoOrder->addStatusToHistory(Mage_Sales_Model_Order::STATE_CLOSED, 'Add status on CRM', false);
$magentoOrder->save();
}
}
Mage::log("Update: " . $order['externalId'], null, 'history.log');
} else {
Mage::log(
sprintf(
"Statuses list error: [HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
}
if(!empty($order['manager_comment'])) {
$magentoOrder->addStatusHistoryComment($order['manager_comment']);
$magentoOrder->save();
}
}
/**
* @param $customer
* @return mixed
*/
private function setCustomerId($customer)
{
$customerId = $this->searchCustomer($customer);
if (is_array($customerId) && !empty($customerId)) {
if ($customerId['success']) {
return $customerId['result'];
} else {
$this->fixCustomer($customerId['result'], $customer['externalId']);
return $customer['externalId'];
}
} else {
$this->createCustomer(
array(
'externalId' => $customer['externalId'],
'firstName' => $customer['firstName'],
'lastName' => isset($customer['lastName']) ? $customer['lastName'] : '',
'patronymic' => isset($customer['patronymic']) ? $customer['patronymic'] : '',
'phones' => isset($customer['phone']) ? array($customer['phone']) : array(),
)
);
return $customer['externalId'];
}
}
/**
* @param $data
* @return array|bool
*/
private function searchCustomer($data)
{
try {
$customers = $this->_api->customersList(
array(
'name' => isset($data['phone']) ? $data['phone'] : $data['name'],
'email' => $data['email']
),
1,
100
);
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
if ($customers->isSuccessful()) {
return (count($customers['customers']) > 0)
? $this->defineCustomer($customers['customers'])
: false
;
}
}
private function createCustomer($customer)
{
try {
$this->_api->customersCreate($customer);
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log('RestApi::CustomersCreate::Curl: ' . $e->getMessage());
}
}
private function fixCustomer($id, $extId)
{
try {
$this->_api->customersFixExternalIds(
array(
array(
'id' => $id,
'externalId' => $extId
)
)
);
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log('RestApi::CustomersFixExternalIds::Curl: ' . $e->getMessage());
}
}
private function defineCustomer($searchResult)
{
$result = '';
foreach ($searchResult as $customer) {
if (isset($customer['externalId']) && $customer['externalId'] != '') {
$result = $customer['externalId'];
break;
}
}
return ($result != '')
? array('success' => true, 'result' => $result)
: array('success' => false, 'result' => $searchResult[0]['id']);
}
private function getExchangeTime($datetime)
{
if (empty($datetime)) {
$datetime = new DateTime(
date(
'Y-m-d H:i:s',
strtotime('-1 days', strtotime(date('Y-m-d H:i:s')))
)
);
} else {
$datetime = new DateTime($datetime);
}
return $datetime;
}
private function getCountryCode($string)
{
$country = empty($string) ? 'RU' : $string;
$xmlObj = new Varien_Simplexml_Config(Mage::getModuleDir('etc', 'Retailcrm_Retailcrm').DS.'country.xml');
$xmlData = $xmlObj->getNode();
if ($country != 'RU') {
foreach ($xmlData as $elem) {
if ($elem->name == $country || $elem->english == $country) {
$country = $elem->alpha2;
break;
}
}
}
return (string) $country;
}
public static function assemblyOrder($orderHistory)
{
$orders = array();
foreach ($orderHistory as $change) {
$change['order'] = self::removeEmpty($change['order']);
if($change['order']['items']) {
$items = array();
foreach($change['order']['items'] as $item) {
if(isset($change['created'])) {
$item['create'] = 1;
}
$items[$item['id']] = $item;
}
$change['order']['items'] = $items;
}
Mage::log($change, null, 'retailcrmHistoryAssemblyOrder.log', true);
if($change['order']['contragent']['contragentType']) {
$change['order']['contragentType'] = self::newValue($change['order']['contragent']['contragentType']);
unset($change['order']['contragent']);
}
if($orders[$change['order']['id']]) {
$orders[$change['order']['id']] = array_merge($orders[$change['order']['id']], $change['order']);
}
else {
$orders[$change['order']['id']] = $change['order'];
}
if($change['field'] == 'manager_comment'){
$orders[$change['order']['id']][$change['field']] = $change['newValue'];
}
if(($change['field'] != 'status')&&
($change['field'] != 'country')&&
($change['field'] != 'manager_comment')&&
($change['field'] != 'order_product.status')&&
($change['field'] != 'payment_status')&&
($change['field'] != 'prepay_sum')
) {
$orders[$change['order']['id']]['order_edit'] = 1;
}
if($change['item']) {
if($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']] = $change['item'];
}
if(empty($change['oldValue']) && $change['field'] == 'order_product') {
$orders[$change['order']['id']]['items'][$change['item']['id']]['create'] = 1;
$orders[$change['order']['id']]['order_edit'] = 1;
unset($orders[$change['order']['id']]['items'][$change['item']['id']]['delete']);
}
if(empty($change['newValue']) && $change['field'] == 'order_product') {
$orders[$change['order']['id']]['items'][$change['item']['id']]['delete'] = 1;
$orders[$change['order']['id']]['order_edit'] = 1;
}
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($fields['delivery'][$change['field']] == 'service') {
$orders[$change['order']['id']]['delivery']['service']['code'] = self::newValue($change['newValue']);
}
elseif($fields['delivery'][$change['field']]) {
$orders[$change['order']['id']]['delivery'][$fields['delivery'][$change['field']]] = self::newValue($change['newValue']);
}
elseif($fields['orderAddress'][$change['field']]) {
$orders[$change['order']['id']]['delivery']['address'][$fields['orderAddress'][$change['field']]] = $change['newValue'];
}
elseif($fields['integrationDelivery'][$change['field']]) {
$orders[$change['order']['id']]['delivery']['service'][$fields['integrationDelivery'][$change['field']]] = self::newValue($change['newValue']);
}
elseif($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($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;
}
if(isset($change['deleted'])) {
$orders[$change['order']['id']]['deleted'] = 1;
}
}
}
return $orders;
}
public static function removeEmpty($inputArray)
{
$outputArray = array();
if (!empty($inputArray)) {
foreach ($inputArray as $key => $element) {
if(!empty($element) || $element === 0 || $element === '0') {
if (is_array($element)) {
$element = self::removeEmpty($element);
}
$outputArray[$key] = $element;
}
}
}
return $outputArray;
}
public static function newValue($value)
{
if(isset($value['code'])) {
return $value['code'];
} else{
return $value;
}
}
public static function getAllShippingMethodsCode($code)
{
$methods = Mage::getSingleton('shipping/config')->getActiveCarriers();
$options = array();
foreach($methods as $_ccode => $_carrier) {
if($_methods = $_carrier->getAllowedMethods()) {
foreach($_methods as $_mcode => $_method) {
$_code = $_ccode . '_' . $_mcode;
$options[$_ccode] = $_code;
}
}
}
return $options[$code];
}
}

View file

@ -1,107 +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
*/
class Retailcrm_Retailcrm_Model_Http_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 Retailcrm_Retailcrm_Model_Exception_InvalidJsonException(
'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 Retailcrm_Retailcrm_Model_Exception_InvalidJsonException(
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 Retailcrm_Retailcrm_Model_Exception_CurlException($error, $errno);
}
return new Retailcrm_Retailcrm_Model_Response_ApiResponse($statusCode, $responseBody);
}
}

View file

@ -1,359 +0,0 @@
<?php
class Retailcrm_Retailcrm_Model_Icml
{
protected $_dd;
protected $_eCategories;
protected $_eOffers;
protected $_shop;
public function generate($shop)
{
$this->_shop = $shop;
$string = '<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="'.date('Y-m-d H:i:s').'">
<shop>
<name>'.Mage::app()->getStore($shop)->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();
$baseDir = Mage::getBaseDir();
$shopCode = Mage::app()->getStore($shop)->getCode();
$this->_dd->save($baseDir . DS . 'retailcrm_' . $shopCode . '.xml');
}
private function addCategories()
{
$category = Mage::getModel('catalog/category');
$treeModel = $category->getTreeModel();
$treeModel->load();
$ids = $treeModel->getCollection()->getAllIds();
$categories = array();
if (!empty($ids))
{
foreach ($ids as $id)
{
if ($id > 1) {
$category = Mage::getModel('catalog/category');
$category->load($id);
$categoryData = array(
'id' => $category->getId(),
'name'=> $category->getName(),
'parentId' => $category->getParentId()
);
array_push($categories, $categoryData);
}
}
}
foreach($categories as $category) {
$e = $this->_eCategories->appendChild(
$this->_dd->createElement('category')
);
$e->appendChild($this->_dd->createTextNode($category['name']));
$e->setAttribute('id', $category['id']);
if ($category['parentId'] > 1) {
$e->setAttribute('parentId', $category['parentId']);
}
}
}
private function addOffers()
{
$offers = array();
$helper = Mage::helper('retailcrm');
$picUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA);
$baseUrl = Mage::getBaseUrl();
$customAdditionalAttributes = Mage::getStoreConfig('retailcrm/attributes_to_export_into_icml');
$customAdditionalAttributes = explode(',', $customAdditionalAttributes);
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addUrlRewrite();
$collection->addFieldToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
$collection->addFieldToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH);
$collection->addAttributeToFilter('type_id', array('eq' => 'simple'));
foreach ($collection as $product) {
/** @var Mage_Catalog_Model_Product $product */
$offer = array();
$offer['id'] = $product->getTypeId() != 'configurable' ? $product->getId() : null;
$offer['productId'] = $product->getId();
$offer['productActivity'] = $product->isAvailable() ? 'Y' : 'N';
$offer['name'] = $product->getName();
$offer['productName'] = $product->getName();
$offer['initialPrice'] = (float) $product->getPrice();
$offer['url'] = $product->getProductUrl();
$offer['picture'] = $picUrl.'catalog/product'.$product->getImage();
$offer['quantity'] = Mage::getModel('cataloginventory/stock_item')
->loadByProduct($product)->getQty();
foreach ($product->getCategoryIds() as $category_id) {
$offer['categoryId'][] = $category_id;
}
$offer['vendor'] = $product->getAttributeText('manufacturer');
$offer['params'] = array();
$article = $product->getSku();
if(!empty($article)) {
$offer['params'][] = array(
'name' => 'Article',
'code' => 'article',
'value' => $article
);
}
$weight = $product->getWeight();
if(!empty($weight)) {
$offer['params'][] = array(
'name' => 'Weight',
'code' => 'weight',
'value' => $weight
);
}
if(!empty($customAdditionalAttributes)) {
foreach($customAdditionalAttributes as $customAdditionalAttribute) {
$alreadyExists = false;
foreach($offer['params'] as $param) {
if($param['code'] == $customAdditionalAttribute) {
$alreadyExists = true;
break;
}
}
if($alreadyExists) continue;
$attribute = $product->getAttributeText($customAdditionalAttribute);
if(!empty($attribute)) {
$offer['params'][] = array(
'name' => $customAdditionalAttribute,
'code' => $customAdditionalAttribute,
'value' => $attribute
);
}
}
}
$offers[] = $offer;
if($product->getTypeId() == 'configurable') {
/** @var Mage_Catalog_Model_Product_Type_Configurable $product */
$associatedProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null, $product);
$productAttributeOptions = $product->getTypeInstance(true)->getConfigurableAttributesAsArray($product);
foreach($associatedProducts as $associatedProduct) {
$associatedProduct = Mage::getModel('catalog/product')->load($associatedProduct->getId());
$attributes = array();
foreach($productAttributeOptions as $productAttributeOption) {
$attributes[$productAttributeOption['label']] = $associatedProduct->getAttributeText($productAttributeOption['attribute_code']);
}
$attributesString = array();
foreach($attributes AS $attributeName=>$attributeValue) {
$attributesString[] = $attributeName.': '.$attributeValue;
}
$attributesString = ' (' . implode(', ', $attributesString) . ')';
$offer = array();
$offer['id'] = $associatedProduct->getId();
$offer['productId'] = $product->getId();
$offer['productActivity'] = $associatedProduct->isAvailable() ? 'Y' : 'N';
$offer['name'] = $associatedProduct->getName().$attributesString;
$offer['productName'] = $product->getName();
$offer['initialPrice'] = (float) $associatedProduct->getFinalPrice();
$offer['url'] = $associatedProduct->getProductUrl();
$offer['picture'] = $picUrl.'catalog/product'.$associatedProduct->getImage();
$offer['quantity'] = Mage::getModel('cataloginventory/stock_item')
->loadByProduct($associatedProduct)->getQty();
foreach ($associatedProduct->getCategoryIds() as $category_id) {
$offer['categoryId'][] = $category_id;
}
$offer['vendor'] = $associatedProduct->getAttributeText('manufacturer');
$offer['params'] = array();
$article = $associatedProduct->getSku();
if(!empty($article)) {
$offer['params'][] = array(
'name' => 'Article',
'code' => 'article',
'value' => $article
);
}
$weight = $associatedProduct->getWeight();
if(!empty($weight)) {
$offer['params'][] = array(
'name' => 'Weight',
'code' => 'weight',
'value' => $weight
);
}
if(!empty($attributes)) {
foreach($attributes as $attributeName => $attributeValue) {
$offer['params'][] = array(
'name' => $attributeName,
'code' => str_replace(' ', '_', strtolower($attributeName)),
'value' => $attributeValue
);
}
}
if(!empty($customAdditionalAttributes)) {
foreach($customAdditionalAttributes as $customAdditionalAttribute) {
$alreadyExists = false;
foreach($offer['params'] as $param) {
if($param['code'] == $customAdditionalAttribute) {
$alreadyExists = true;
break;
}
}
if($alreadyExists) continue;
$attribute = $associatedProduct->getAttributeText($customAdditionalAttribute);
if(!empty($attribute)) {
$offer['params'][] = array(
'name' => $customAdditionalAttribute,
'code' => $customAdditionalAttribute,
'value' => $attribute
);
}
}
}
$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,72 +0,0 @@
<?php
/**
* Observer
*
* @author RetailDriver LLC
*/
class Retailcrm_Retailcrm_Model_Observer
{
/**
* Event after order created
*
* @param Varien_Event_Observer $observer
* @return bool
*/
public function orderCreate(Varien_Event_Observer $observer)
{
if (Mage::registry('sales_order_place_after') != 1){//do nothing if the event was dispatched
$order = $observer->getEvent()->getOrder();
Mage::getModel('retailcrm/order')->orderCreate($order);
}
return true;
}
public function orderUpdate(Varien_Event_Observer $observer)
{
$order = $observer->getEvent()->getOrder();
Mage::getModel('retailcrm/order')->orderUpdate($order);
return true;
}
public function orderStatusHistoryCheck(Varien_Event_Observer $observer)
{
$order = $observer->getEvent()->getOrder();
Mage::getModel('retailcrm/order')->orderStatusHistoryCheck($order);
return true;
}
/**
* Event after customer created
*
* @param Varien_Event_Observer $observer
*
* @SuppressWarnings(PHPMD.StaticAccess)
*
* @return bool
*/
public function customerRegister(Varien_Event_Observer $observer)
{
if (Mage::registry('customer_save_after') != 1) {
$customer = $observer->getEvent()->getCustomer();
Mage::getModel('retailcrm/customer')->customerRegister($customer);
}
return true;
}
public function exportCatalog()
{
foreach (Mage::app()->getWebsites() as $website) {
foreach ($website->getGroups() as $group) {
Mage::getModel('retailcrm/icml')->generate((int)$group->getId());
}
}
}
public function importHistory()
{
Mage::getModel('retailcrm/exchange')->ordersHistory();
}
}

View file

@ -1,431 +0,0 @@
<?php
/**
* Order class
*
* @category Model
* @package RetailCrm\Model
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license http://opensource.org/licenses/MIT MIT License
* @link http://www.magentocommerce.com/magento-connect/retailcrm-1.html
*
* @SuppressWarnings(PHPMD.CamelCaseClassName)
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
*/
class Retailcrm_Retailcrm_Model_Order extends Retailcrm_Retailcrm_Model_Exchange
{
/**
* Order create
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.ElseExpression)
* @param mixed $order
*
* @return bool
*/
public function orderPay($orderId)
{
$order = Mage::getModel('sales/order')->load($orderId);
if((string)$order->getBaseGrandTotal() == (string)$order->getTotalPaid()){
$preparedOrder = array(
'externalId' => $order->getRealOrderId(),//getId(),
'paymentStatus' => 'paid',
);
$preparedOrder = Mage::helper('retailcrm')->filterRecursive($preparedOrder);
$this->_api->ordersEdit($preparedOrder);
}
}
public function orderStatusHistoryCheck($order)
{
$config = Mage::getModel(
'retailcrm/settings',
array(
'storeId' =>$order->getStoreId()
)
);
$preparedOrder = array(
'externalId' => $order->getRealOrderId(),//getId(),
'status' => $config->getMapping($order->getStatus(), 'status'),
);
$comment = $order->getStatusHistoryCollection()->getData();
if(!empty($comment[0]['comment'])) {
$preparedOrder['managerComment'] = $comment[0]['comment'];
}
$preparedOrder = Mage::helper('retailcrm')->filterRecursive($preparedOrder);
$this->_api->ordersEdit($preparedOrder);
}
public function orderUpdate($order)
{
$config = Mage::getModel(
'retailcrm/settings',
array(
'storeId' =>$order->getStoreId()
)
);
$preparedOrder = array(
'externalId' => $order->getRealOrderId(),//getId(),
'status' => $config->getMapping($order->getStatus(), 'status'),
);
if((float)$order->getBaseGrandTotal() == (float)$order->getTotalPaid()) {
$preparedOrder['paymentStatus'] = 'paid';
$preparedOrder = Mage::helper('retailcrm')->filterRecursive($preparedOrder);
$this->_api->ordersEdit($preparedOrder);
}
}
public function orderCreate($order)
{
$config = Mage::getModel('retailcrm/settings', ['storeId' => $order->getStoreId()]);
$address = $order->getShippingAddress()->getData();
$orderItems = $order->getItemsCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('product_type', array('eq'=>'simple'))
->load();
$items = array();
foreach ($orderItems as $item) {
if ($item->getProductType() == "simple") {
if ($item->getParentItemId()) {
$parent = Mage::getModel('sales/order_item')->load($item->getParentItemId());
}
$product = array(
'productId' => $item->getProductId(),
'productName' => !isset($parent) ? $item->getName() : $parent->getName(),
'quantity' => !isset($parent) ? intval($item->getQtyOrdered()) : intval($parent->getQtyOrdered()),
'initialPrice' => !isset($parent) ? $item->getPrice() : $parent->getPrice(),
'offer'=>array(
'externalId'=>$item->getProductId()
)
);
unset($parent);
$items[] = $product;
} elseif($item->getProductType() == "grouped") {
$product = array(
'productId' => $item->getProductId(),
'productName' => $item->getName(),
'quantity' => $item->getQtyOrdered(),
'initialPrice' => $item->getPrice(),
'offer'=>array(
'externalId'=>$item->getProductId()
)
);
$items[] = $product;
}
}
$shipping = $this->getShippingCode($order->getShippingMethod());
$preparedOrder = array(
'site' => $order->getStore()->getCode(),
'externalId' => $order->getRealOrderId(),
'number' => $order->getRealOrderId(),
'createdAt' => Mage::getModel('core/date')->date(),
'lastName' => $order->getCustomerLastname(),
'firstName' => $order->getCustomerFirstname(),
'patronymic' => $order->getCustomerMiddlename(),
'email' => $order->getCustomerEmail(),
'phone' => $address['telephone'],
'paymentType' => $config->getMapping($order->getPayment()->getMethodInstance()->getCode(), 'payment'),
'status' => $config->getMapping($order->getStatus(), 'status'),
'discount' => abs($order->getDiscountAmount()),
'items' => $items,
'customerComment' => $order->getStatusHistoryCollection()->getFirstItem()->getComment(),
'delivery' => array(
'code' => $config->getMapping($shipping, 'shipping'),
'cost' => $order->getShippingAmount(),
'address' => array(
'index' => $address['postcode'],
'city' => $address['city'],
'country' => $address['country_id'],
'street' => $address['street'],
'region' => $address['region'],
'text' => trim(
',',
implode(
',',
array(
$address['postcode'],
$address['city'],
$address['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 ($order->getCustomerIsGuest() == 0) {
$preparedCustomer = array(
'externalId' => $order->getCustomerId()
);
if ($this->_api->customersCreate($preparedCustomer)) {
$preparedOrder['customer']['externalId'] = $order->getCustomerId();
}
}
$preparedOrder = Mage::helper('retailcrm')->filterRecursive($preparedOrder);
Mage::log($preparedOrder, null, 'retailcrmCreatePreparedOrder.log', true);
try {
$response = $this->_api->ordersCreate($preparedOrder);
if ($response->isSuccessful() && 201 === $response->getStatusCode()) {
Mage::log($response->id);
} else {
Mage::log(
sprintf(
"Order create error: [HTTP status %s] %s",
$response->getStatusCode(),
$response->getErrorMsg()
)
);
if (isset($response['errors'])) {
Mage::log(implode(' :: ', $response['errors']));
}
}
} catch (Retailcrm_Retailcrm_Model_Exception_CurlException $e) {
Mage::log($e->getMessage());
}
}
public function ordersExportNumber()
{
$config = Mage::getStoreConfig('retailcrm');
$ordersId = explode(",", $config['load_order']['numberOrder']);
$orders = array();
$ordersList = Mage::getResourceModel('sales/order_collection')
->addAttributeToSelect('*')
->joinAttribute('billing_firstname', 'order_address/firstname', 'billing_address_id', null, 'left')
->joinAttribute('billing_lastname', 'order_address/lastname', 'billing_address_id', null, 'left')
->joinAttribute('billing_street', 'order_address/street', 'billing_address_id', null, 'left')
->joinAttribute('billing_company', 'order_address/company', 'billing_address_id', null, 'left')
->joinAttribute('billing_city', 'order_address/city', 'billing_address_id', null, 'left')
->joinAttribute('billing_region', 'order_address/region', 'billing_address_id', null, 'left')
->joinAttribute('billing_country', 'order_address/country_id', 'billing_address_id', null, 'left')
->joinAttribute('billing_postcode', 'order_address/postcode', 'billing_address_id', null, 'left')
->joinAttribute('billing_telephone', 'order_address/telephone', 'billing_address_id', null, 'left')
->joinAttribute('billing_fax', 'order_address/fax', 'billing_address_id', null, 'left')
->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_street', 'order_address/street', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_company', 'order_address/company', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_city', 'order_address/city', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_region', 'order_address/region', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_country', 'order_address/country_id', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_postcode', 'order_address/postcode', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_telephone', 'order_address/telephone', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_fax', 'order_address/fax', 'shipping_address_id', null, 'left')
->addAttributeToSort('created_at', 'asc')
->setPageSize(1000)
->setCurPage(1)
->addAttributeToFilter('increment_id', $ordersId)
->load();
foreach ($ordersList as $order) {
$orders[] = $this->prepareOrder($order);
}
$chunked = array_chunk($orders, 50);
unset($orders);
foreach ($chunked as $chunk) {
$this->_api->ordersUpload($chunk);
time_nanosleep(0, 250000000);
}
unset($chunked);
return true;
}
/**
* Orders export
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.ElseExpression)
*
* @return bool
*/
public function ordersExport()
{
$orders = array();
$ordersList = Mage::getResourceModel('sales/order_collection')
->addAttributeToSelect('*')
->joinAttribute('billing_firstname', 'order_address/firstname', 'billing_address_id', null, 'left')
->joinAttribute('billing_lastname', 'order_address/lastname', 'billing_address_id', null, 'left')
->joinAttribute('billing_street', 'order_address/street', 'billing_address_id', null, 'left')
->joinAttribute('billing_company', 'order_address/company', 'billing_address_id', null, 'left')
->joinAttribute('billing_city', 'order_address/city', 'billing_address_id', null, 'left')
->joinAttribute('billing_region', 'order_address/region', 'billing_address_id', null, 'left')
->joinAttribute('billing_country', 'order_address/country_id', 'billing_address_id', null, 'left')
->joinAttribute('billing_postcode', 'order_address/postcode', 'billing_address_id', null, 'left')
->joinAttribute('billing_telephone', 'order_address/telephone', 'billing_address_id', null, 'left')
->joinAttribute('billing_fax', 'order_address/fax', 'billing_address_id', null, 'left')
->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_street', 'order_address/street', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_company', 'order_address/company', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_city', 'order_address/city', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_region', 'order_address/region', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_country', 'order_address/country_id', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_postcode', 'order_address/postcode', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_telephone', 'order_address/telephone', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_fax', 'order_address/fax', 'shipping_address_id', null, 'left')
->addAttributeToSort('created_at', 'asc')
->setPageSize(1000)
->setCurPage(1)
->load();
foreach ($ordersList as $order) {
$orders[] = $this->prepareOrder($order);
}
$chunked = array_chunk($orders, 50);
unset($orders);
foreach ($chunked as $chunk) {
$this->_api->ordersUpload($chunk);
time_nanosleep(0, 250000000);
}
unset($chunked);
return true;
}
protected function prepareOrder($order)
{
$config = Mage::getModel('retailcrm/settings', $order->getStoreId());
$address = $order->getShippingAddress();
$orderItems = $order->getItemsCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('product_type', array('eq'=>'simple'))
->load();
$items = array();
foreach ($orderItems as $item) {
if ($item->getProductType() == "simple") {
if ($item->getParentItemId()) {
$parent = Mage::getModel('sales/order_item')->load($item->getParentItemId());
}
$product = array(
'productId' => $item->getProductId(),
'productName' => !isset($parent) ? $item->getName() : $parent->getName(),
'quantity' => !isset($parent) ? intval($item->getQtyOrdered()) : intval($parent->getQtyOrdered()),
'initialPrice' => !isset($parent) ? $item->getPrice() : $parent->getPrice()
);
unset($parent);
$items[] = $product;
}
}
$shipping = $this->getShippingCode($order->getShippingMethod());
$preparedOrder = array(
'externalId' => $order->getRealOrderId(),
'number' => $order->getRealOrderId(),
'createdAt' => $order->getCreatedAt(),
'lastName' => $order->getCustomerLastname(),
'firstName' => $order->getCustomerFirstname(),
'patronymic' => $order->getCustomerMiddlename(),
'email' => $order->getCustomerEmail(),
'phone' => $address['telephone'],
'paymentType' => $config->getMapping($order->getPayment()->getMethodInstance()->getCode(), 'payment'),
'status' => $config->getMapping($order->getStatus(), 'status'),
'discount' => abs($order->getDiscountAmount()),
'items' => $items,
'customerComment' => $order->getStatusHistoryCollection()->getFirstItem()->getComment(),
'delivery' => array(
'code' => $config->getMapping($shipping, 'shipping'),
'cost' => $order->getShippingAmount(),
'address' => array(
'index' => $address['postcode'],
'city' => $address['city'],
'country' => $address['country_id'],
'street' => $address['street'],
'region' => $address['region'],
'text' => trim(
',',
implode(
',',
array(
$address['postcode'],
$address['city'],
$address['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 ($order->getCustomerIsGuest() != 0) {
$preparedOrder['customer']['externalId'] = $order->getCustomerId();
}
return Mage::helper('retailcrm')->filterRecursive($preparedOrder);
}
protected function getShippingCode($string)
{
$split = array_values(explode('_', $string));
$length = count($split);
$prepare = array_slice($split, 0, $length/2);
return implode('_', $prepare);
}
protected function getLocale($code)
{
$this->_locale = Mage::app()->getLocale()->getLocaleCode();
if (!in_array($this->_locale, array('ru_RU', 'en_US'))) {
$this->_locale = 'en_US';
}
$this->_dict = array(
'ru_RU' => array('sku' => 'Артикул', 'weight' => 'Вес', 'offer' => 'Вариант'),
'en_US' => array('sku' => 'Sku', 'weight' => 'Weight', 'offer' => 'Offer'),
);
return $this->_dict[$this->_locale][$code];
}
}

View file

@ -1,164 +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
*/
class Retailcrm_Retailcrm_Model_Response_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 Retailcrm_Retailcrm_Model_Exception_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,92 +0,0 @@
<?php
/**
* Settings class
*
* @category Model
* @package RetailCrm\Model
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license http://opensource.org/licenses/MIT MIT License
* @link http://www.magentocommerce.com/magento-connect/retailcrm-1.html
*
* @SuppressWarnings(PHPMD.CamelCaseClassName)
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
*/
class Retailcrm_Retailcrm_Model_Settings
{
protected $_config;
protected $_storeDefined;
/**
* Constructor
*
* @param array $params
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.ElseExpression)
*
* @return bool
*/
public function __construct(array $params = array())
{
$this->_config = empty($params)
? $this->setConfigWithoutStoreId()
: $this->setConfigWithStoreId($params['storeId']);
}
/**
* Get mapping values
*
* @param string $code
* @param string $type (default: status, values: status, payment, shipping)
* @param bool $reverse
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*
* @return mixed
*/
public function getMapping($code, $type, $reverse = false)
{
if (!in_array($type, array('status', 'payment', 'shipping'))) {
throw new \InvalidArgumentException(
"Parameter 'type' must be 'status', 'payment' or 'shipping'"
);
}
$array = ($reverse)
? array_flip(array_filter($this->_config[$type]))
: array_filter($this->_config[$type]);
return array_key_exists($code, $array)
? $array[$code]
: false;
}
/**
* Set config with orderStoreId
*
* @param string $storeId
*
* @SuppressWarnings(PHPMD.StaticAccess)
*
* @return mixed
*/
protected function setConfigWithStoreId($storeId)
{
$this->_storeDefined = true;
return Mage::getStoreConfig('retailcrm', $storeId);
}
/**
* Set config without orderStoreId
*
* @SuppressWarnings(PHPMD.StaticAccess)
*
* @return mixed
*/
protected function setConfigWithoutStoreId()
{
$this->_storeDefined = false;
return Mage::getStoreConfig('retailcrm');
}
}

View file

@ -1,24 +0,0 @@
<?php
class Retailcrm_Retailcrm_Adminhtml_RetailcrmbuttonController extends Mage_Adminhtml_Controller_Action
{
/**
* Return some checking result
*
* @return void
*/
public function checkAction()
{
$orders = Mage::getModel('retailcrm/order');
$orders ->ordersExportNumber();
}
/**
* Check is allowed access to action
*
* @return bool
*/
protected function _isAllowed()
{
return Mage::getSingleton('admin/session')->isAllowed('system/config/retailcrm');
}
}

View file

@ -1,139 +0,0 @@
<?xml version="1.0"?>
<!--
The MIT License (MIT)
Copyright (c) 2015 RetailDriver LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<config>
<modules>
<Retailcrm_Retailcrm>
<version>1.0.0</version>
</Retailcrm_Retailcrm>
</modules>
<global>
<helpers>
<retailcrm>
<class>Retailcrm_Retailcrm_Helper</class>
</retailcrm>
</helpers>
<models>
<retailcrm>
<class>Retailcrm_Retailcrm_Model</class>
</retailcrm>
</models>
<blocks>
<retailcrm>
<class>Retailcrm_Retailcrm_Block</class>
</retailcrm>
</blocks>
<events>
<sales_order_place_after>
<observers>
<retailcrm_retailcrm_model_observer>
<type>singleton</type>
<class>Retailcrm_Retailcrm_Model_Observer</class>
<method>orderCreate</method>
</retailcrm_retailcrm_model_observer>
</observers>
</sales_order_place_after>
<sales_order_save_commit_after>
<observers>
<retailcrm_retailcrm_model_observer>
<type>singleton</type>
<class>Retailcrm_Retailcrm_Model_Observer</class>
<method>orderUpdate</method>
</retailcrm_retailcrm_model_observer>
</observers>
</sales_order_save_commit_after>
<sales_order_save_after>
<observers>
<retailcrm_retailcrm_model_observer>
<type>singleton</type>
<class>Retailcrm_Retailcrm_Model_Observer</class>
<method>orderStatusHistoryCheck</method>
</retailcrm_retailcrm_model_observer>
</observers>
</sales_order_save_after>
<customer_save_after>
<observers>
<retailcrm_retailcrm_model_observer>
<type>singleton</type>
<class>Retailcrm_Retailcrm_Model_Observer</class>
<method>customerRegister</method>
</retailcrm_retailcrm_model_observer>
</observers>
</customer_save_after>
</events>
</global>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<Retailcrmbutton after="Mage_Adminhtml">Retailcrm_Retailcrm</Retailcrmbutton>
</modules>
</args>
</adminhtml>
</routers>
</admin>
<crontab>
<jobs>
<icml>
<schedule><cron_expr>* */4 * * *</cron_expr></schedule>
<run><model>retailcrm/observer::exportCatalog</model></run>
</icml>
<history>
<schedule><cron_expr>*/5 * * * *</cron_expr></schedule>
<run><model>retailcrm/observer::importHistory</model></run>
</history>
</jobs>
</crontab>
<adminhtml>
<acl>
<resources>
<admin>
<children>
<system>
<children>
<config>
<children>
<retailcrm>
<title>Store RetailCRM Module Section</title>
</retailcrm>
</children>
</config>
</children>
</system>
</children>
</admin>
</resources>
</acl>
</adminhtml>
</config>

View file

@ -1,160 +0,0 @@
<?xml version="1.0"?>
<!--
The MIT License (MIT)
Copyright (c) 2015 RetailDriver LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<config>
<tabs>
<retailcrm_extension>
<label>RetailCRM</label>
<sort_order>1000</sort_order>
</retailcrm_extension>
</tabs>
<sections>
<retailcrm translate="label" module="retailcrm">
<label>Settings</label>
<class>retailcrm-section</class>
<tab>retailcrm_extension</tab>
<frontend_type>text</frontend_type>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<groups>
<general translate="label comment" module="retailcrm">
<expanded>1</expanded>
<label>General</label>
<frontend_type>text</frontend_type>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
<api_url translate="label comment">
<label>API URL</label>
<frontend_type>text</frontend_type>
<sort_order>1</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<tooltip><![CDATA[https://<i><b>YourCrmName</b></i>.retailcrm.ru]]></tooltip>
</api_url>
<api_key translate="label comment">
<label>API Key</label>
<frontend_type>text</frontend_type>
<sort_order>3</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<tooltip><![CDATA[To generate an API Key, log in to RetailCRM then select Admin > Integration > API Keys]]></tooltip>
</api_key>
</fields>
</general>
<misc>
<expanded>1</expanded>
<label>Misc</label>
<frontend_type>text</frontend_type>
<sort_order>11</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
<attributes_to_export_into_icml translate="label">
<label>Custom attributes to export into ICML</label>
<frontend_type>multiselect</frontend_type>
<config_path>retailcrm/attributes_to_export_into_icml</config_path>
<sort_order>7</sort_order>
<source_model>retailcrm/attribute</source_model>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<can_be_empty>1</can_be_empty>
</attributes_to_export_into_icml>
</fields>
</misc>
<shipping translate="label comment" module="retailcrm">
<expanded>0</expanded>
<label>Shipping</label>
<frontend_type>text</frontend_type>
<sort_order>12</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<frontend_model>retailcrm/adminhtml_system_config_form_fieldset_shipping</frontend_model>
</shipping>
<payment translate="label comment" module="retailcrm">
<expanded>0</expanded>
<label>Payment Method</label>
<frontend_type>text</frontend_type>
<sort_order>13</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<frontend_model>retailcrm/adminhtml_system_config_form_fieldset_payment</frontend_model>
</payment>
<status translate="label comment" module="retailcrm">
<expanded>0</expanded>
<label>Order Statuses</label>
<frontend_type>text</frontend_type>
<sort_order>14</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<frontend_model>retailcrm/adminhtml_system_config_form_fieldset_status</frontend_model>
</status>
<load_order translate="label comment" module="retailcrm">
<expanded>0</expanded>
<label>Order Load</label>
<frontend_type>text</frontend_type>
<sort_order>15</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<frontend_model>retailcrm/adminhtml_system_config_form_fieldset_order</frontend_model>
<fields>
<numberOrder translate="label comment">
<label>Number orders</label>
<frontend_type>text</frontend_type>
<sort_order>1</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<tooltip><![CDATA[Enter your order number, separated by commas]]></tooltip>
</numberOrder>
<button translate="label comment">
<frontend_type>button</frontend_type>
<frontend_model>retailcrm/adminhtml_system_config_form_button</frontend_model>
<sort_order>2</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</button>
</fields>
</load_order>
</groups>
</retailcrm>
</sections>
</config>

View file

@ -1,16 +0,0 @@
<script type="text/javascript">
//<![CDATA[
function check() {
new Ajax.Request('<?php echo $this->getAjaxCheckUrl() ?>', {
method: 'get',
onSuccess: function(transport){
if (transport.responseText){
alert('Completed');
}
}
});
}
//]]>
</script>
<?php echo $this->getButtonHtml() ?>

View file

@ -1,32 +0,0 @@
<?xml version="1.0"?>
<!--
The MIT License (MIT)
Copyright (c) 2015 RetailDriver LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<config>
<modules>
<Retailcrm_Retailcrm>
<active>true</active>
<codePool>community</codePool>
</Retailcrm_Retailcrm>
</modules>
</config>

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

@ -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

@ -0,0 +1,64 @@
<?php
namespace Retailcrm\Retailcrm\Block\Adminhtml\System\Config;
class Button extends \Magento\Config\Block\System\Config\Form\Field
{
/**
* @var string
*/
public $_template = 'Retailcrm_Retailcrm::system/config/button.phtml';
/**
* Remove scope label
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
*/
public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
$element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
return parent::render($element);
}
/**
* Return element html
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
return $this->_toHtml();
}
/**
* Return ajax url for synchronize button
*
* @return string
*/
public function getAjaxSyncUrl()
{
return $this->getUrl('retailcrm_retailcrm/system_config/button');
}
/**
* Generate synchronize button html
*
* @return string
*/
public function getButtonHtml()
{
$button = $this->getLayout()->createBlock(
'Magento\Backend\Block\Widget\Button'
)->setData(
[
'id' => 'order_button',
'label' => __('Send'),
]
);
return $button->toHtml();
}
}

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

@ -0,0 +1,21 @@
<?php
namespace Retailcrm\Retailcrm\Controller\Index;
class Display extends \Magento\Framework\App\Action\Action
{
private $pageFactory;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $pageFactory
) {
$this->pageFactory = $pageFactory;
parent::__construct($context);
}
public function execute()
{
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

@ -0,0 +1,145 @@
<?php
namespace Retailcrm\Retailcrm\Model\Config\Backend;
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\Model\ResourceModel\AbstractResource|null $resource
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
* @param ApiClient $api
* @param array $data
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\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()
{
$this->setParams([
'url' => $this->getValue(),
'apiKey' => $this->getFieldsetDataValue('api_key'),
'version' => $this->getFieldsetDataValue('api_version')
]);
if (!$this->isUrl($this->getValue())) {
throw new \Magento\Framework\Exception\ValidatorException(__('Invalid CRM url'));
}
if (!$this->isHttps($this->getValue())) {
$this->schemeEdit($this->getValue());
}
if ($this->validateApiUrl($this->api)) {
$this->setValue($this->getValue());
}
parent::beforeSave();
}
/**
* Validate selected api url
*
* @param ApiClient $api
* @param string $apiVersion
*
* @throws \Magento\Framework\Exception\ValidatorException
*
* @return boolean
*/
private function validateApiUrl(ApiClient $api)
{
$response = $api->availableVersions();
if ($response === false) {
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(__('Incorrect URL of RetailCRM'));
}
return true;
}
/**
* Check url scheme
*
* @param string $url
*
* @return boolean
*/
private function isHttps($url)
{
$url_array = parse_url($url);
if ($url_array['scheme'] === 'https') {
return true;
} else {
return false;
}
}
/**
* Edit scheme from http to https
*
* @param string $url
*
* @return string
*/
private function schemeEdit(&$url)
{
$url_array = parse_url($url);
$url = 'https://' . $url_array['host'];
}
/**
* 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

@ -0,0 +1,121 @@
<?php
namespace Retailcrm\Retailcrm\Model\Config\Backend;
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\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(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\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()
{
$this->setParams([
'url' => $this->getFieldsetDataValue('api_url'),
'apiKey' => $this->getFieldsetDataValue('api_key'),
'version' => $this->getValue()
]);
$this->validateApiVersion($this->api, $this->getValue());
parent::beforeSave();
}
/**
* Validate selected api version
*
* @param ApiClient $api
* @param string $apiVersion
*
* @throws \Magento\Framework\Exception\ValidatorException
*
* @return void
*/
private function validateApiVersion(ApiClient $api, $apiVersion)
{
$apiVersions = [
'v4' => '4.0',
'v5' => '5.0'
];
$response = $api->availableVersions();
if ($response->isSuccessful()) {
$availableVersions = $response['versions'];
} else {
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(
__('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

@ -0,0 +1,737 @@
<?php
namespace Retailcrm\Retailcrm\Model\History;
class Exchange
{
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(
\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()
{
if (!$this->api->isConfigured()) {
return false;
}
$this->registry->register('RETAILCRM_HISTORY', true);
$historyFilter = [];
$historyOrder = [];
$historyStart = $this->config->getValue('retailcrm/general/filter_history');
if ($historyStart && $historyStart > 0) {
$historyFilter['sinceId'] = $historyStart;
}
while (true) {
$response = $this->api->ordersHistory($historyFilter);
if ($response === false) {
return false;
}
if (!$response->isSuccessful()) {
return true;
}
$orderH = isset($response['history']) ? $response['history'] : [];
if (empty($orderH)) {
return true;
}
$historyOrder = array_merge($historyOrder, $orderH);
$end = array_pop($orderH);
$historyFilter['sinceId'] = $end['id'];
if ($response['pagination']['totalPageCount'] == 1) {
$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->processOrders($orders);
return true;
}
}
$this->registry->register('RETAILCRM_HISTORY', false);
}
/**
* Process orders
*
* @param array $orders
*
* @return void
*/
private function processOrders($orders)
{
$this->logger->writeDump($orders, 'processOrders');
if (!empty($orders)) {
foreach ($orders as $order) {
if (isset($order['externalId']) && !empty($order['externalId'])) {
$this->doUpdate($order);
} else {
$this->doCreate($order);
}
}
}
}
/**
* Create new order from CRM
*
* @param array $order
*
* @return void
*/
private function doCreate($order)
{
$this->logger->writeDump($order, 'doCreate');
$payments = $this->helper->getConfigPayments();
$shippings = $this->helper->getCongigShipping();
$sites = $this->helper->getMappingSites();
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();
}
$region = $this->regionFactory->create();
$customer = $this->customerFactory->create();
$customer->setWebsiteId($websiteId);
if (isset($order['customer']['externalId'])) {
$customer = $this->customerRepository->getById($order['customer']['externalId']);
}
if (!$customer->getId()) {
//If not avilable then create this customer
$customer->setWebsiteId($websiteId)
->setStore($store)
->setFirstname($order['firstName'])
->setLastname($order['lastName'])
->setEmail($order['email'])
->setPassword($order['email']);
try {
$this->customerRepository->save($customer);
} catch (\Exception $exception) {
$this->logger->writeRow($exception->getMessage());
}
$this->api->customersFixExternalIds(
[
[
'id' => $order['customer']['id'],
'externalId' => $customer->getId()
]
]
);
}
//Create object of quote
$quote = $this->quote->create();
//set store for which you create quote
$quote->setStore($store);
// if you have allready buyer id then you can load customer directly
$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 ($ditems as $id =>$item) {
$product = $productRepository->getById($id,false, $store->getId(), false);
$product->setPrice($item['initialPrice']);
$quote->addProduct(
$product,
(int)$item['quantity']
);
}
$products = [];
foreach ($ditems as $id => $item) {
$products[$id] = ['product_id'=>$id,'qty' => $item['quantity']];
}
$orderData = [
'currency_id' => $this->storeManager->getStore()->getCurrentCurrency()->getCode(),
'email' => $order['email'],
'shipping_address' => [
'firstname' => $order['firstName'],
'lastname' => $order['lastName'],
'street' => $order['delivery']['address']['street'],
'city' => $order['delivery']['address']['city'],
'country_id' => $order['countryIso'],
'region' => $order['delivery']['address']['region'],
'postcode' => $order['delivery']['address']['index'],
'telephone' => $order['phone'],
'save_in_address_book' => 1
],
'items'=> $products
];
$region->loadByName($order['delivery']['address']['region'], $order['countryIso']);
if ($region->getId()) {
$orderData['shipping_address']['region_id'] = $region->getId();
}
$shippings = array_flip(array_filter($shippings));
$payments = array_flip(array_filter($payments));
$ShippingMethods = $this->getAllShippingMethodsCode($shippings[$order['delivery']['code']]);
//Set Address to quote
$quote->getBillingAddress()->addData($orderData['shipping_address']);
$quote->getShippingAddress()->addData($orderData['shipping_address']);
$shippingAddress = $quote->getShippingAddress();
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($ShippingMethods);
if ($this->api->getVersion() == 'v4') {
$paymentType = $order['paymentType'];
} elseif ($this->api->getVersion() == 'v5') {
if ($order['payments']) {
$paymentType = $this->getPaymentMethod($order['payments']);
}
}
$quote->setPaymentMethod($payments[$paymentType]);
$quote->setInventoryProcessed(false);
/** @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();
$quoteRepository->save($quote);
// Create Order From Quote
$magentoOrder = $this->quoteManagement->submit($quote);
$increment_id = $magentoOrder->getId();
$this->api->ordersFixExternalIds(
[
[
'id' => $order['id'],
'externalId' => $increment_id
]
]
);
}
/**
* Create old edited order
*
* @param array $order
*
* @return void
*/
private function doCreateUp($order)
{
$manager = \Magento\Framework\App\ObjectManager::getInstance();
$this->logger->writeDump($order, 'doCreateUp');
$response = $this->api->ordersGet($order['id'], $by = 'id');
if (!$response->isSuccessful()) {
return;
}
if (isset($response['order'])) {
$order = $response['order'];
}
$payments = $this->helper->getConfigPayments();
$shippings = $this->helper->getCongigShipping();
$region = $this->regionFactory->create();
$sites = $this->helper->getMappingSites();
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 = $this->customerRepository->getById($order['customer']['externalId']);
}
//Create object of quote
$quote = $this->quote->create();
//set store for which you create quote
$quote->setStore($store);
$quote->setCurrency();
// if you have all ready buyer id then you can load customer directly
if ($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 ($ditems as $id => $item) {
$product = $productRepository->getById($id,false, $store->getId(), false);
$product->setPrice($item['initialPrice']);
$quote->addProduct(
$product,
(int)$item['quantity']
);
}
$products = [];
foreach ($ditems as $id => $item) {
$products[$id] = ['product_id'=>$id,'qty' => $item['quantity']];
}
$orderData = [
'currency_id' => $this->storeManager->getStore()->getCurrentCurrency()->getCode(),
'email' => $order['email'],
'shipping_address' => [
'firstname' => $order['firstName'],
'lastname' => $order['lastName'],
'street' => $order['delivery']['address']['street'],
'city' => $order['delivery']['address']['city'],
'country_id' => $order['countryIso'],//US
'region' => $order['delivery']['address']['region'],
'postcode' => $order['delivery']['address']['index'],
'telephone' => $order['phone'],
'save_in_address_book' => 1
],
'items'=> $products
];
$region->loadByName($order['delivery']['address']['region'], $order['countryIso']);
if ($region->getId()) {
$orderData['shipping_address']['region_id'] = $region->getId();
}
$shippings = array_flip(array_filter($shippings));
$payments = array_flip(array_filter($payments));
$ShippingMethods = $this->getAllShippingMethodsCode($shippings[$order['delivery']['code']]);
//Set Address to quote
$quote->getBillingAddress()->addData($orderData['shipping_address']);
$quote->getShippingAddress()->addData($orderData['shipping_address']);
$shippingAddress = $quote->getShippingAddress();
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($ShippingMethods);
if ($this->api->getVersion() == 'v4') {
$paymentType = $order['paymentType'];
} elseif ($this->api->getVersion() == 'v5') {
$paymentType = $this->getPaymentMethod($order['payments'], false);
}
$quote->setPaymentMethod($payments[$paymentType]);
$quote->setInventoryProcessed(false);
$originalId = $order['externalId'];
$oldOrder = $this->orderInterface->load($originalId);
$orderDataUp = [
'original_increment_id' => $oldOrder->getIncrementId(),
'relation_parent_id' => $oldOrder->getId(),
'relation_parent_real_id' => $oldOrder->getIncrementId(),
'edit_increment' => $oldOrder->getEditIncrement() + 1,
'increment_id' => $oldOrder->getIncrementId() . '-' . ($oldOrder->getEditIncrement() + 1)
];
$quote->setReservedOrderId($orderDataUp['increment_id']);
/** @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();
$quoteRepository->save($quote);
// Create Order From Quote
$magentoOrder = $this->quoteManagement->submit($quote, $orderDataUp);
$oldOrder->setStatus('canceled')->save();
$increment_id = $magentoOrder->getId();
$this->api->ordersFixExternalIds(
[
[
'id' => $order['id'],
'externalId' => $increment_id
]
]
);
}
/**
* Edit order
*
* @param array $order
*
* @return void
*/
private function doUpdate($order)
{
$this->logger->writeDump($order, 'doUpdate');
$Status = $this->helper->getCongigStatus();
$Status = array_flip(array_filter($Status));
$magentoOrder = $this->order->load($order['externalId']);
$magentoOrderArr = $magentoOrder->getData();
$this->logger->writeDump($magentoOrderArr, 'magentoOrderArr');
$this->logger->writeDump($Status, 'status');
if ((!empty($order['order_edit'])) && ($order['order_edit'] == 1)) {
$this->doCreateUp($order);
}
if (!empty($order['status'])) {
$change = $Status[$order['status']];
if ($change == 'canceled') {
$this->orderManagement->cancel($magentoOrderArr['entity_id']);
}
$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)
{
$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;
}
$items[$item['id']] = $item;
}
$change['order']['items'] = $items;
}
if (isset($change['order']['contragent']['contragentType'])) {
$change['order']['contragentType'] = self::newValue($change['order']['contragent']['contragentType']);
unset($change['order']['contragent']);
}
if (isset($orders[$change['order']['id']])) {
$orders[$change['order']['id']] = array_merge($orders[$change['order']['id']], $change['order']);
} else {
$orders[$change['order']['id']] = $change['order'];
}
if ($change['field'] == 'manager_comment') {
$orders[$change['order']['id']][$change['field']] = $change['newValue'];
}
if (($change['field'] != 'status')
&& ($change['field'] != 'country')
&& ($change['field'] != 'manager_comment')
&& ($change['field'] != 'order_product.status')
&& ($change['field'] != 'payment_status')
&& ($change['field'] != 'prepay_sum')
) {
$orders[$change['order']['id']]['order_edit'] = 1;
}
if (isset($change['item'])) {
if (isset($orders[$change['order']['id']]['items'])
&& 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']] = $change['item'];
}
if (empty($change['oldValue']) && $change['field'] == 'order_product') {
$orders[$change['order']['id']]['items'][$change['item']['id']]['create'] = 1;
$orders[$change['order']['id']]['order_edit'] = 1;
unset($orders[$change['order']['id']]['items'][$change['item']['id']]['delete']);
}
if (empty($change['newValue']) && $change['field'] == 'order_product') {
$orders[$change['order']['id']]['items'][$change['item']['id']]['delete'] = 1;
$orders[$change['order']['id']]['order_edit'] = 1;
}
if (!empty($change['newValue']) && $change['field'] == 'order_product.quantity') {
$orders[$change['order']['id']]['order_edit'] = 1;
}
} else {
if (isset($change['created'])) {
$orders[$orderId]['create'] = 1;
}
if (isset($change['deleted'])) {
$orders[$orderId]['deleted'] = 1;
}
}
}
return $orders;
}
/**
* Remove empty elements
*
* @param array $inputArray
*
* @return array $outputArray
*/
public static function removeEmpty($inputArray)
{
$outputArray = [];
if (!empty($inputArray)) {
foreach ($inputArray as $key => $element) {
if (!empty($element) || $element === 0 || $element === '0') {
if (is_array($element)) {
$element = self::removeEmpty($element);
}
$outputArray[$key] = $element;
}
}
}
return $outputArray;
}
/**
* Set new value
*
* @param mixed $value
*
* @return string $value
*/
public static function newValue($value)
{
if (isset($value['code'])) {
return $value['code'];
} else {
return $value;
}
}
/**
* Get shipping methods
*
* @param string $mcode
*
* @return string
*/
public function getAllShippingMethodsCode($mcode)
{
$activeCarriers = $this->shipconfig->getActiveCarriers();
foreach ($activeCarriers as $carrierCode => $carrierModel) {
if ($carrierMethods = $carrierModel->getAllowedMethods()) {
foreach ($carrierMethods as $methodCode => $method) {
$code = $carrierCode . '_'. $methodCode;
if ($mcode == $carrierCode) {
$methods[$mcode] = $code;
}
}
}
}
return $methods[$mcode];
}
/**
* Get payment type for api v5
*
* @param array $payments
* @param boolean $newOrder
*
* @return mixed
*/
private function getPaymentMethod($payments, $newOrder = true)
{
if (count($payments) == 1 || $newOrder) {
$payment = reset($payments);
} elseif (count($payments) > 1 && !$newOrder) {
foreach ($payments as $paymentCrm) {
if (isset($paymentCrm['externalId'])) {
$payment = $paymentCrm;
}
}
}
if (isset($payment)) {
return $payment['type'];
}
return false;
}
}

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

@ -0,0 +1,94 @@
<?php
namespace Retailcrm\Retailcrm\Model\Logger;
class Logger
{
private $logDir;
public function __construct(
\Magento\Framework\Filesystem\DirectoryList $directory
) {
$this->logDir = $directory->getPath('log');
}
/**
* Write data in log file
*
* @param array $data
* @param string $fileName
*
* @return void
*/
public function writeDump($data, $fileName)
{
$filePath = $this->logDir . '/' . $fileName . '.log';
if (!$this->checkSize($filePath)) {
$this->clear($filePath);
}
$logData = [
'date' => date('Y-m-d H:i:s'),
'data' => $data
];
$file = fopen($filePath, "a+");
fwrite($file, print_r($logData, true));
fclose($file);
}
/**
* Write data in log file
*
* @param string $data
* @param string $fileName
*
* @return void
*/
public function writeRow($data, $fileName = 'retailcrm')
{
$filePath = $this->logDir . '/' . $fileName . '.log';
if (!$this->checkSize($filePath)) {
$this->clear($filePath);
}
$nowDate = date('Y-m-d H:i:s');
$logData = "[$nowDate] @ " . $data . "\n";
$file = fopen($filePath, "a+");
fwrite($file, $logData);
fclose($file);
}
/**
* Clear file
*
* @param string $file
*
* @return void
*/
private function clear($file)
{
file_put_contents($file, '');
}
/**
* Check file size
*
* @param string $file
*
* @return boolean
*/
private function checkSize($file)
{
if (!file_exists($file)) {
return true;
} elseif (filesize($file) > 10485760) {
return false;
}
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,14 @@
<?php
namespace Retailcrm\Retailcrm\Model\Setting;
class ApiVersions implements \Magento\Framework\Option\ArrayInterface
{
public function toOptionArray()
{
return [
['value' => 'v4', 'label' => 'v4'],
['value' => 'v5', 'label' => 'v5']
];
}
}

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

@ -0,0 +1,53 @@
<?php
namespace Retailcrm\Retailcrm\Model\Setting;
class Shipping implements \Magento\Framework\Option\ArrayInterface
{
private $entityType;
private $store;
private $config;
private $shippingConfig;
public function __construct(
\Magento\Store\Model\Store $store,
\Magento\Eav\Model\Entity\Type $entityType,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Shipping\Model\Config $shippingConfig
) {
$this->store = $store;
$this->entityType = $entityType;
$this->config = $config;
$this->shippingConfig = $shippingConfig;
}
public function toOptionArray()
{
$activeShipping = $this->shippingConfig->getActiveCarriers();
foreach ($activeShipping as $carrierCode => $carrierModel) {
$options = [];
if ($carrierModel->getAllowedMethods()) {
$carrierMethods = $carrierModel->getAllowedMethods();
foreach ($carrierMethods as $methodCode => $method) {
$code = $carrierCode . '_' . $methodCode;
$options[] = [
'value' => $code,
'label' => $method
];
}
$carrierTitle = $this->config->getValue('carriers/' . $carrierCode . '/title');
}
$methods[] = [
'value' => $options,
'label' => $carrierTitle
];
}
return $methods;
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace Retailcrm\Retailcrm\Model\Setting;
class Status extends \Magento\Config\Model\Config\Backend\Serialized\ArraySerialized
{
public function beforeSave()
{
// For value validations
$exceptions = $this->getValue();
// 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')
];
}
}

View file

@ -0,0 +1,192 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Observer;
use Retailcrm\Retailcrm\Test\TestCase;
class OrderUpdateTest extends TestCase
{
private $unit;
private $objectManager;
private $config;
private $mockApi;
private $mockObserver;
private $mockEvent;
private $mockOrder;
private $mockPayment;
private $registry;
public function setUp()
{
$this->mockApi = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods([
'ordersEdit',
'ordersPaymentsEdit',
'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->objectManager = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class)
->getMockForAbstractClass();
$this->mockOrder = $this->getMockBuilder(\Magento\Sales\Model\Order::class)
->disableOriginalConstructor()
->setMethods([
'getId',
'getPayment',
'getBaseTotalDue',
'getStatus',
'getStore'
])
->getMock();
$this->mockPayment = $this->getMockBuilder(\Magento\Sales\Model\Order\Payment::class)
->setMethods(['getId'])
->disableOriginalConstructor()
->getMock();
$this->config = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
->getMockForAbstractClass();
$this->registry = $this->getMockBuilder(\Magento\Framework\Registry::class)
->disableOriginalConstructor()
->getMock();
$helper = $this->createMock(\Retailcrm\Retailcrm\Helper\Data::class);
$this->unit = new \Retailcrm\Retailcrm\Model\Observer\OrderUpdate(
$this->config,
$this->registry,
$helper,
$this->mockApi
);
}
/**
* @param int $getBaseTotalDue
* @param string $apiVersion
* @param boolean $isConfigured
* @dataProvider dataProviderOrderUpdate
*/
public function testExecute(
$getBaseTotalDue,
$apiVersion,
$isConfigured
) {
$testData = $this->getAfterUpdateOrderTestData();
// mock Payment
$this->mockPayment->expects($this->any())
->method('getId')
->willReturn(1);
// mock Order
$this->mockOrder->expects($this->any())
->method('getId')
->willReturn($testData['order.id']);
$this->mockOrder->expects($this->any())
->method('getStatus')
->willReturn($testData['order.status']);
$this->mockOrder->expects($this->any())
->method('getBaseTotalDue')
->willReturn($getBaseTotalDue);
$this->mockOrder->expects($this->any())
->method('getPayment')
->willReturn($this->mockPayment);
$store = $this->createMock(\Magento\Store\Model\Store::class);
$this->mockOrder->expects($this->any())
->method('getStore')
->willReturn($store);
// mock Api
$this->mockApi->expects($this->any())
->method('getVersion')
->willReturn($apiVersion);
$this->mockApi->expects($this->any())
->method('isConfigured')
->willReturn($isConfigured);
// mock Event
$this->mockEvent->expects($this->any())
->method('getOrder')
->willReturn($this->mockOrder);
// mock Observer
$this->mockObserver->expects($this->any())
->method('getEvent')
->willReturn($this->mockEvent);
$updateOrderObserver = $this->unit->execute($this->mockObserver);
if ($isConfigured) {
$this->assertNotEmpty($this->unit->getOrder());
$this->assertArrayHasKey('externalId', $this->unit->getOrder());
$this->assertArrayHasKey('status', $this->unit->getOrder());
$this->assertInstanceOf(
\Retailcrm\Retailcrm\Model\Observer\OrderUpdate::class,
$updateOrderObserver
);
} else {
$this->assertEmpty($this->unit->getOrder());
}
}
/**
* Get test order data
* @return array $testOrderData
*/
private function getAfterUpdateOrderTestData()
{
$testOrderData = [
'order.id' => 1,
'order.status' => 'processing',
'order.paymentMethod' => 'checkmo'
];
return $testOrderData;
}
public function dataProviderOrderUpdate()
{
return [
[
'get_base_total_due' => 0,
'api_version' => 'v4',
'is_configured' => false
],
[
'get_base_total_due' => 1,
'api_version' => 'v4',
'is_configured' => true
],
[
'get_base_total_due' => 0,
'api_version' => 'v5',
'is_configured' => true
],
[
'get_base_total_due' => 1,
'api_version' => 'v5',
'is_configured' => false
]
];
}
}

View file

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

View file

@ -0,0 +1,147 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Model\Service;
use Retailcrm\Retailcrm\Test\TestCase;
class IntegrationModuleTest extends TestCase
{
private $mockResourceConfig;
private $mockApiClient;
private $mockData;
private $unit;
const ACCOUNT_URL = 'test';
public function setUp()
{
$this->mockData = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->mockResourceConfig = $this->getMockBuilder(\Magento\Config\Model\ResourceModel\Config::class)
->disableOriginalConstructor()
->getMock();
$this->mockApiClient = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods([
'marketplaceSettingsEdit',
'integrationModulesEdit'
])
->getMock();
$this->unit = new \Retailcrm\Retailcrm\Model\Service\IntegrationModule(
$this->mockResourceConfig,
$this->mockData
);
}
/**
* @param $active
* @param $apiVersion
* @param $isSuccessful
*
* @dataProvider dataProvider
*/
public function testSendConfiguration($active, $apiVersion, $isSuccessful)
{
$response = $this->getMockBuilder(\RetailCrm\Response\ApiResponse::class)
->disableOriginalConstructor()
->getMock();
$response->expects($this->any())->method('isSuccessful')->willReturn($isSuccessful);
if ($apiVersion == 'v4') {
$this->mockApiClient->expects($this->any())->method('marketplaceSettingsEdit')
->willReturn($response);
} else {
$this->mockApiClient->expects($this->any())->method('integrationModulesEdit')
->willReturn($response);
}
$this->unit->setAccountUrl(self::ACCOUNT_URL);
$this->unit->setApiVersion($apiVersion);
$this->unit->sendConfiguration($this->mockApiClient, $active);
$configuration = $this->unit->getConfiguration();
$this->assertNotEmpty($configuration);
$this->assertArrayHasKey('name', $configuration);
$this->assertEquals(
\Retailcrm\Retailcrm\Model\Service\IntegrationModule::NAME,
$configuration['name']
);
$this->assertArrayHasKey('logo', $configuration);
$this->assertEquals(
\Retailcrm\Retailcrm\Model\Service\IntegrationModule::LOGO,
$configuration['logo']
);
$this->assertArrayHasKey('code', $configuration);
$this->assertContains(
\Retailcrm\Retailcrm\Model\Service\IntegrationModule::INTEGRATION_CODE,
$configuration['code']
);
$this->assertArrayHasKey('active', $configuration);
$this->assertEquals($active, $configuration['active']);
if ($apiVersion == 'v4') {
$this->assertArrayHasKey('configurationUrl', $configuration);
$this->assertEquals(self::ACCOUNT_URL, $configuration['configurationUrl']);
} else {
$this->assertArrayHasKey('accountUrl', $configuration);
$this->assertEquals(self::ACCOUNT_URL, $configuration['accountUrl']);
$this->assertArrayHasKey('integrationCode', $configuration);
$this->assertContains(
\Retailcrm\Retailcrm\Model\Service\IntegrationModule::INTEGRATION_CODE,
$configuration['integrationCode']
);
$this->assertArrayHasKey('clientId', $configuration);
$this->assertNotEmpty($configuration['clientId']);
}
}
public function dataProvider()
{
return [
[
'active' => true,
'api_version' => 'v4',
'is_successful' => true
],
[
'active' => false,
'api_version' => 'v4',
'is_successful' => true
],
[
'active' => true,
'api_version' => 'v4',
'is_successful' => false
],
[
'active' => false,
'api_version' => 'v4',
'is_successful' => false
],
[
'active' => true,
'api_version' => 'v5',
'is_successful' => true
],
[
'active' => false,
'api_version' => 'v5',
'is_successful' => true
],
[
'active' => true,
'api_version' => 'v5',
'is_successful' => false
],
[
'active' => false,
'api_version' => 'v5',
'is_successful' => false
]
];
}
}

View file

@ -0,0 +1,126 @@
<?php
namespace Retailcrm\Retailcrm\Test\Unit\Model\Service;
use Retailcrm\Retailcrm\Test\TestCase;
class InventoriesUploadTest extends TestCase
{
private $mockApi;
private $mockProductRepository;
private $mockResponse;
private $mockProduct;
public function setUp()
{
$this->mockApi = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
->disableOriginalConstructor()
->setMethods([
'storeInventories',
'isConfigured'
])
->getMock();
$this->mockProductRepository = $this->getMockBuilder(\Magento\Catalog\Api\ProductRepositoryInterface::class)
->disableOriginalConstructor()
->setMethods(['getById'])
->getMockForAbstractClass();
$this->mockResponse = $this->getMockBuilder(\RetailCrm\Response\ApiResponse::class)
->disableOriginalConstructor()
->setMethods(['isSuccessful'])
->getMock();
$this->mockProduct = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
->disableOriginalConstructor()
->setMethods([
'setStockData',
'save'
])
->getMock();
}
/**
* @param $response
*
* @dataProvider dataProviderLoadStocks
*/
public function testInventoriesUpdload($response)
{
if ($response != false) {
$responseInventories = new \RetailCrm\Response\ApiResponse(200, json_encode($response));
$responseInventories->asJsonResponse($response);
$this->mockResponse->expects($this->any())
->method('isSuccessful')
->willReturn(true);
$this->mockApi->expects($this->any())
->method('isConfigured')
->willReturn(true);
$this->mockApi->expects($this->any())
->method('storeInventories')
->willReturn($responseInventories);
$this->mockProductRepository->expects($this->any())
->method('getById')
->willReturn($this->mockProduct);
} else {
$this->mockResponse->expects($this->any())
->method('isSuccessful')
->willReturn($response);
}
$inventoriesUpload = new \Retailcrm\Retailcrm\Model\Service\InventoriesUpload($this->mockProductRepository, $this->mockApi);
$result = $inventoriesUpload->uploadInventory();
if (!$response['success']) {
$this->assertEquals(false, $result);
} else {
$this->assertEquals(true, $result);
}
}
private function getResponseData()
{
return array(
'true' => $this->getApiInventories(),
'false' => false
);
}
public function dataProviderLoadStocks()
{
$response = $this->getResponseData();
return array(
array(
'response' => $response['true']
),
array(
'response' => $response['false']
)
);
}
private function getApiInventories()
{
return array(
'success' => true,
'pagination' => array(
'limit' => 250,
'totalCount' => 1,
'currentPage' => 1,
'totalPageCount' => 1
),
'offers' => array(
array(
'externalId' => 1,
'xmlId' => 'xmlId',
'quantity' => 10
)
)
);
}
}

View file

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

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