1
0
Fork 0
mirror of synced 2025-04-04 21:53:34 +03:00

Compare commits

...

51 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
76 changed files with 3891 additions and 824 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

3
.gitignore vendored
View file

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

View file

@ -1,40 +0,0 @@
language: php
sudo: false
env:
global:
- DB_USER=root
- DB_HOST=localhost
- DB_NAME=magento2_test
- ADMIN_FIRSTNAME=admin_firstname
- ADMIN_LASTNAME=admin_lastname
- ADMIN_EMAIL=example@email.com
- ADMIN_USER=admin
- ADMIN_PASS=admin123
matrix:
include:
- php: 7.0
env: BRANCH=2.2-develop
- php: 7.1
env: BRANCH=2.2-develop
- php: 7.1
env: BRANCH=2.3-develop
- php: 7.2
env: BRANCH=2.3-develop
before_script:
- bash bin/install.sh
script:
- bash bin/script.sh
deploy:
skip_cleanup: true
provider: script
script: make
on:
php: 7.2
branch: master
condition: "$DEPLOY = true"

30
CHANGELOG.md Normal file
View file

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

View file

@ -1,14 +1,24 @@
FILE = $(TRAVIS_BUILD_DIR)/VERSION
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
all: build_archive send_to_ftp delete_archive
.PHONY: build_archive delete_archive
build_archive:
cd src; zip -r $(ARCHIVE_NAME) ./*
send_to_ftp:
curl -T $(ARCHIVE_NAME) -u $(FTP_USER):$(FTP_PASSWORD) ftp://$(FTP_HOST)
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,13 +1,21 @@
Magento module
[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)
[![Build Status](https://github.com/retailcrm/magento-module/workflows/magento/badge.svg)](https://github.com/retailcrm/magento-module/actions)
[![Coverage](https://img.shields.io/codecov/c/gh/retailcrm/magento-module/master.svg?logo=github)](https://codecov.io/gh/retailcrm/magento-module)
[![GitHub release](https://img.shields.io/github/release/retailcrm/magento-module.svg?logo=codecov)](https://github.com/retailcrm/magento-module/)
[![PHP version](https://img.shields.io/badge/PHP->=5.6-blue.svg?style=flat-square)](https://php.net/)
DEPRECATED Magento module
==============
Magento 2 module for interaction with [retailCRM](http://www.retailcrm.ru).
**The module is deprecated and no longer supported**
Magento 2 module for interaction with [RetailCRM](http://www.retailcrm.ru) ([Documentation](https://docs.retailcrm.pro/Users/Integration/SiteModules/Magento) page)
Module allows:
* Exchange the orders data with retailCRM
* Exchange the orders data with RetailCRM
* Configure relations between dictionaries of retailCRM and Magento (statuses, payments, delivery types and etc)
* Generate [ICML](http://www.retailcrm.ru/docs/Developers/ICML) (Intaro Markup Language) export file for catalog loading by retailCRM
* Generate [ICML](http://www.retailcrm.ru/docs/Developers/ICML) (Intaro Markup Language) export file for catalog loading by RetailCRM
## ICML
@ -25,8 +33,4 @@ By default ICML file is being generated by module every 4 hours. You can find fi
composer require retailcrm/api-client-php ~5.0
```
2) Unpack the archive with the module into the `app/code/Retailcrm/Retailcrm` directory.
3) Change `app/etc/config.php` file by adding `'Retailcrm_Retailcrm' => 1` line into `modules` array
This module is compatible with Magento up to version 2.2.3
This module is compatible with Magento up to version 2.2.8

View file

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

View file

@ -1 +1 @@
2.2.0
2.5.2

View file

@ -1,13 +1,13 @@
#!/usr/bin/env bash
if [ -z $TRAVIS_BUILD_DIR ]; then
if [ -z $ROOT_DIR ]; then
exit 0;
fi
MAGE_ROOT=$TRAVIS_BUILD_DIR/../magento2
MAGE_ROOT=$ROOT_DIR/../magento2
create_db() {
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"
mysqladmin create "magento2_test" --user="root" --password="root"
}
magento_clone() {
@ -15,22 +15,38 @@ magento_clone() {
git clone https://github.com/magento/magento2
cd magento2
git checkout $BRANCH
composer install
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="$DB_HOST" \
--db-name="$DB_NAME" \
--db-user="$DB_USER" \
--admin-firstname="$ADMIN_FIRSTNAME" \
--admin-lastname="$ADMIN_LASTNAME" \
--admin-email="$ADMIN_EMAIL" \
--admin-user="$ADMIN_USER" \
--admin-password="$ADMIN_PASS" \
--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"
@ -39,7 +55,7 @@ magento_install() {
module_install() {
cd $MAGE_ROOT
mkdir -p app/code/Retailcrm/Retailcrm
cp -R $TRAVIS_BUILD_DIR/src/* 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

View file

@ -1,9 +0,0 @@
#!/usr/bin/env bash
if [ -z $TRAVIS_BUILD_DIR ]; then
exit 0;
fi
MAGE_ROOT=$TRAVIS_BUILD_DIR/../magento2
cd $MAGE_ROOT
php vendor/phpunit/phpunit/phpunit -c dev/tests/unit/phpunit.xml.dist app/code/Retailcrm/Retailcrm/Test/Unit

View file

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

View file

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

View file

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

View file

@ -20,6 +20,7 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
*/
protected $_fieldRenderer;
private $objectFactory;
private $paymentConfig;
private $client;
@ -29,10 +30,12 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
\Magento\Framework\View\Helper\Js $jsHelper,
\Magento\Payment\Model\Config $paymentConfig,
\Retailcrm\Retailcrm\Helper\Proxy $client,
\Magento\Framework\DataObjectFactory $objectFactory,
array $data = []
) {
$this->paymentConfig = $paymentConfig;
$this->client = $client;
$this->objectFactory = $objectFactory;
parent::__construct($context, $authSession, $jsHelper, $data);
}
@ -61,7 +64,7 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = new \Magento\Framework\DataObject(['showInDefault' => 1, 'showInWebsite' => 1]);
$this->_dummyElement = $this->objectFactory->create(['showInDefault' => 1, 'showInWebsite' => 1]);
}
return $this->_dummyElement;
@ -70,12 +73,15 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
public function render(AbstractElement $element)
{
$html = '';
$htmlError = '<div style="margin-left: 15px;"><b><i>Please check your API Url & API Key</i></b></div>';
$htmlError = sprintf(
'<div style="margin-left: 15px;"><b><i>%s</i></b></div>',
__('Enter API of your URL and API key')
);
$html .= $this->_getHeaderHtml($element);
if ($this->client->isConfigured()) {
$paymentMethods = $this->paymentConfig->getActiveMethods();
foreach ($paymentMethods as $code => $payment) {
$html .= $this->_getFieldHtml($element, $payment);
}
@ -110,7 +116,7 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
return $defaultValues;
}
if ($response->isSuccessful()) {
if (isset($response['paymentTypes']) && $response->isSuccessful()) {
$paymentsTypes = $response['paymentTypes'];
} else {
return $defaultValues;
@ -130,7 +136,7 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
* Get field html
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $fieldset
* @param \Magento\Payment\Model\Method\AbstractMethod $payment
* @param \Magento\Payment\Api\Data\PaymentMethodInterface $payment
*
* @return string
*/
@ -138,9 +144,7 @@ class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset
{
$configData = $this->getConfigData();
$path = 'retailcrm/' . $fieldset->getId() . '/' . $payment->getCode();
$data = isset($configData[$path]) ? $configData[$path] : [];
$e = $this->_getDummyElement();
$field = $fieldset->addField(

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

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

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

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

View file

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

View file

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

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);
}
}

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

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

View file

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

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();
}
}
}

View file

@ -2,6 +2,7 @@
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;
@ -14,6 +15,8 @@ class Data extends AbstractHelper
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,
@ -23,6 +26,13 @@ class Data extends AbstractHelper
parent::__construct($context);
}
public function getGeneralSettings($setting = null)
{
return $setting === null
? $this->getConfigValue(self::XML_PATH_RETAILCRM . 'general')
: $this->getConfigValue(self::XML_PATH_RETAILCRM . 'general/' . $setting);
}
public function getConfigValue($field, $storeId = null)
{
return $this->scopeConfig->getValue(
@ -32,17 +42,13 @@ class Data extends AbstractHelper
);
}
public function getGeneralConfig($code, $storeId = null)
{
return $this->getConfigValue(self::XML_PATH_RETAILCRM . $code, $storeId);
}
/**
* Get site code
*
* @param $store
*
* @return mixed|null
* @throws \Exception
*/
public function getSite($store)
{
@ -68,6 +74,9 @@ class Data extends AbstractHelper
return $websitesConfig;
}
/**
* @return array
*/
public function getMappingSites()
{
$sites = [];
@ -88,6 +97,86 @@ class Data extends AbstractHelper
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
*
@ -117,4 +206,63 @@ class Data extends AbstractHelper
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);
}
}
}

View file

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

View file

@ -7,6 +7,8 @@ use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
class ApiVersion extends \Magento\Framework\App\Config\Value
{
private $api;
private $request;
private $integrationModule;
/**
* ApiVersion constructor.
@ -16,6 +18,8 @@ class ApiVersion extends \Magento\Framework\App\Config\Value
* @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
*/
@ -24,12 +28,17 @@ class ApiVersion extends \Magento\Framework\App\Config\Value
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
ApiClient $api,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
\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);
}
@ -73,18 +82,32 @@ class ApiVersion extends \Magento\Framework\App\Config\Value
if ($response->isSuccessful()) {
$availableVersions = $response['versions'];
} else {
throw new \Magento\Framework\Exception\ValidatorException(__('Invalid CRM url or api key'));
throw new \Magento\Framework\Exception\ValidatorException(__('Incorrect URL of RetailCRM or API key'));
}
if (isset($availableVersions)) {
if (in_array($apiVersions[$apiVersion], $availableVersions)) {
$this->setValue($this->getValue());
$this->sendModuleConfiguration($api);
} else {
throw new \Magento\Framework\Exception\ValidatorException(__('Selected api version forbidden'));
throw new \Magento\Framework\Exception\ValidatorException(
__('The selected API version is unavailable')
);
}
}
}
/**
* @param $api
*/
private function sendModuleConfiguration($api)
{
$this->integrationModule->setApiVersion($api->getVersion());
$this->integrationModule->setAccountUrl($this->request->getUriString());
$this->integrationModule->sendConfiguration($api);
}
/**
* @param array $data
*/

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

@ -19,14 +19,11 @@ class Exchange
private $cacheTypeList;
private $order;
private $orderManagement;
private $eventManager;
private $objectManager;
private $orderInterface;
private $storeManager;
private $regionFactory;
public function __construct(
\Magento\Framework\App\ObjectManager $objectManager,
\Retailcrm\Retailcrm\Helper\Data $helper,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Config\Model\ResourceModel\Config $resourceConfig,
@ -40,7 +37,6 @@ class Exchange
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Sales\Api\Data\OrderInterface $orderInterface,
\Magento\Sales\Api\OrderManagementInterface $orderManagement,
\Magento\Framework\Event\Manager $eventManager,
\Retailcrm\Retailcrm\Model\Logger\Logger $logger,
\Magento\Sales\Model\Order $order,
\Magento\Store\Model\StoreManagerInterface $storeManager,
@ -61,8 +57,6 @@ class Exchange
$this->cacheTypeList = $cacheTypeList;
$this->orderInterface = $orderInterface;
$this->orderManagement = $orderManagement;
$this->eventManager = $eventManager;
$this->objectManager = $objectManager;
$this->order = $order;
$this->storeManager = $storeManager;
$this->regionFactory = $regionFactory;
@ -167,11 +161,11 @@ class Exchange
{
$this->logger->writeDump($order, 'doCreate');
$payments = $this->config->getValue('retailcrm/retailcrm_payment');
$shippings = $this->config->getValue('retailcrm/retailcrm_shipping');
$payments = $this->helper->getConfigPayments();
$shippings = $this->helper->getCongigShipping();
$sites = $this->helper->getMappingSites();
if ($sites) {
if ($sites && in_array($order['site'], $sites)) {
$store = $this->storeManager->getStore($sites[$order['site']]);
$websiteId = $store->getWebsiteId();
} else {
@ -184,7 +178,7 @@ class Exchange
$customer->setWebsiteId($websiteId);
if (isset($order['customer']['externalId'])) {
$customer->load($order['customer']['externalId']);
$customer = $this->customerRepository->getById($order['customer']['externalId']);
}
if (!$customer->getId()) {
@ -196,7 +190,7 @@ class Exchange
->setEmail($order['email'])
->setPassword($order['email']);
try {
$customer->save();
$this->customerRepository->save($customer);
} catch (\Exception $exception) {
$this->logger->writeRow($exception->getMessage());
}
@ -222,9 +216,32 @@ class Exchange
$quote->setCurrency();
$quote->assignCustomer($customer); //Assign quote to customer
//add items in quote
$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) {
$product = $this->product->load($item['offer']['externalId']);
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,
@ -234,8 +251,8 @@ class Exchange
$products = [];
foreach ($order['items'] as $item) {
$products[$item['offer']['externalId']] = ['qty' => $item['quantity']];
foreach ($ditems as $id => $item) {
$products[$id] = ['product_id'=>$id,'qty' => $item['quantity']];
}
$orderData = [
@ -286,17 +303,19 @@ class Exchange
$quote->setPaymentMethod($payments[$paymentType]);
$quote->setInventoryProcessed(false);
$quote->save();
/** @var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */
$quoteRepository = $manager->create(\Magento\Quote\Api\CartRepositoryInterface::class);
$quoteRepository->save($quote);
// Set Sales Order Payment
$quote->getPayment()->importData(['method' => $payments[$paymentType]]);
// Collect Totals & Save Quote
$quote->collectTotals()->save();
$quote->collectTotals();
$quoteRepository->save($quote);
// Create Order From Quote
$magentoOrder = $this->quoteManagement->submit($quote);
$increment_id = $magentoOrder->getId();
$this->api->ordersFixExternalIds(
@ -318,8 +337,8 @@ class Exchange
*/
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()) {
@ -330,13 +349,13 @@ class Exchange
$order = $response['order'];
}
$payments = $this->config->getValue('retailcrm/retailcrm_payment');
$shippings = $this->config->getValue('retailcrm/retailcrm_shipping');
$payments = $this->helper->getConfigPayments();
$shippings = $this->helper->getCongigShipping();
$region = $this->regionFactory->create();
$sites = $this->helper->getMappingSites();
if ($sites) {
if ($sites && in_array($order['site'], $sites)) {
$store = $this->storeManager->getStore($sites[$order['site']]);
$websiteId = $store->getWebsiteId();
} else {
@ -348,7 +367,7 @@ class Exchange
$customer->setWebsiteId($websiteId);
if (isset($order['customer']['externalId'])) {
$customer->load($order['customer']['externalId']); // load customer by external id
$customer = $this->customerRepository->getById($order['customer']['externalId']);
}
//Create object of quote
@ -367,9 +386,31 @@ class Exchange
$quote->setCustomerIsGuest(1);
}
//add items in quote
$ditems = [];
foreach ($order['items'] as $item) {
$product = $this->product->load($item['offer']['externalId']);
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,
@ -379,8 +420,8 @@ class Exchange
$products = [];
foreach ($order['items'] as $item) {
$products[$item['offer']['externalId']] = ['qty' => $item['quantity']];
foreach ($ditems as $id => $item) {
$products[$id] = ['product_id'=>$id,'qty' => $item['quantity']];
}
$orderData = [
@ -441,16 +482,20 @@ class Exchange
];
$quote->setReservedOrderId($orderDataUp['increment_id']);
$quote->save();
/** @var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */
$quoteRepository = $manager->create(\Magento\Quote\Api\CartRepositoryInterface::class);
$quoteRepository->save($quote);
// Set Sales Order Payment
$quote->getPayment()->importData(['method' => $payments[$paymentType]]);
// Collect Totals & Save Quote
$quote->collectTotals()->save();
$quote->collectTotals();
$quoteRepository->save($quote);
// Create Order From Quote
$magentoOrder = $this->quoteManagement->submit($quote, $orderDataUp);
$oldOrder->setStatus('canceled')->save();
$increment_id = $magentoOrder->getId();
@ -475,7 +520,7 @@ class Exchange
{
$this->logger->writeDump($order, 'doUpdate');
$Status = $this->config->getValue('retailcrm/retailcrm_status');
$Status = $this->helper->getCongigStatus();
$Status = array_flip(array_filter($Status));
$magentoOrder = $this->order->load($order['externalId']);
@ -514,11 +559,11 @@ class Exchange
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;
@ -557,7 +602,7 @@ class Exchange
if (isset($change['item'])) {
if (isset($orders[$change['order']['id']]['items'])
&& $orders[$change['order']['id']]['items'][$change['item']['id']]
&& isset($orders[$change['order']['id']]['items'][$change['item']['id']])
) {
$orders[$change['order']['id']]['items'][$change['item']['id']] = array_merge(
$orders[$change['order']['id']]['items'][$change['item']['id']],
@ -582,34 +627,6 @@ class Exchange
$orders[$change['order']['id']]['order_edit'] = 1;
}
} else {
if (isset($fields['delivery'][$change['field']])
&& $fields['delivery'][$change['field']] == 'service'
) {
$orders[$orderId]['delivery']['service']['code'] = self::newValue($change['newValue']);
} elseif (isset($fields['delivery'][$change['field']])) {
$field = $fields['delivery'][$change['field']];
$orders[$orderId]['delivery'][$field] = self::newValue($change['newValue']);
unset($field);
} elseif (isset($fields['orderAddress'][$change['field']])) {
$field = $fields['orderAddress'][$change['field']];
$orders[$orderId]['delivery']['address'][$field] = self::newValue($change['newValue']);
unset($field);
} elseif (isset($fields['integrationDelivery'][$change['field']])) {
$field = $fields['integrationDelivery'][$change['field']];
$orders[$orderId]['delivery']['service'][$field] = self::newValue($change['newValue']);
unset($field);
} elseif (isset($fields['customerContragent'][$change['field']])) {
$field = $fields['customerContragent'][$change['field']];
$orders[$orderId][$field] = self::newValue($change['newValue']);
unset($field);
} elseif (strripos($change['field'], 'custom_') !== false) {
$field = str_replace('custom_', '', $change['field']);
$orders[$orderId]['customFields'][$field] = self::newValue($change['newValue']);
unset($field);
} elseif (isset($fields['order'][$change['field']])) {
$orders[$orderId][$fields['order'][$change['field']]] = self::newValue($change['newValue']);
}
if (isset($change['created'])) {
$orders[$orderId]['create'] = 1;
}

View file

@ -10,49 +10,58 @@ class Icml
private $shop;
private $manager;
private $category;
private $product;
private $storeManager;
private $StockState;
private $configurable;
private $config;
private $dirList;
private $ddFactory;
private $resourceModelProduct;
private $searchCriteriaBuilder;
private $productRepository;
private $dimensionFields = ['height', 'length', 'width'];
public function __construct(
\Magento\Store\Model\StoreManagerInterface $manager,
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $product,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\CatalogInventory\Api\StockStateInterface $StockState,
\Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurable,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\DomDocument\DomDocumentFactory $ddFactory,
\Magento\Framework\Filesystem\DirectoryList $dirList
\Magento\Framework\Filesystem\DirectoryList $dirList,
\Magento\Catalog\Model\ResourceModel\Product $resourceModelProduct,
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
\Magento\Catalog\Model\ProductRepository $productRepository
) {
$this->configurable = $configurable;
$this->StockState = $StockState;
$this->storeManager = $storeManager;
$this->product = $product;
$this->category = $categoryCollectionFactory;
$this->manager = $manager;
$this->config = $config;
$this->ddFactory = $ddFactory;
$this->dirList = $dirList;
$this->resourceModelProduct = $resourceModelProduct;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->productRepository = $productRepository;
}
/**
* Generate icml catelog
*
* @param \Magento\Store\Model\Website $website
*
* @return void
*/
public function generate()
public function generate($website)
{
$this->shop = $this->manager->getStore()->getId();
$this->shop = $website;
$string = '<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="'.date('Y-m-d H:i:s').'">
<shop>
<name>'.$this->manager->getStore()->getName().'</name>
<name>' . $website->getName() . '</name>
<categories/>
<offers/>
</shop>
@ -79,8 +88,7 @@ class Icml
$this->addOffers();
$this->dd->saveXML();
$shopCode = $this->manager->getStore()->getCode();
$this->dd->save($this->dirList->getRoot() . '/retailcrm_' . $shopCode . '.xml');
$this->dd->save($this->dirList->getRoot() . '/retailcrm_' . $website->getCode() . '.xml');
}
/**
@ -98,7 +106,13 @@ class Icml
$e = $this->eCategories->appendChild(
$this->dd->createElement('category')
);
$e->appendChild($this->dd->createTextNode($category->getName()));
$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) {
@ -204,6 +218,20 @@ class Icml
);
}
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');
@ -226,22 +254,22 @@ class Icml
{
$offers = [];
$collection = $this->product->create();
$collection->addFieldToFilter('visibility', 4);//catalog, search visible
$collection->addAttributeToSelect('*');
$picUrl = $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$customAdditionalAttributes = $this->config->getValue('retailcrm/Misc/attributes_to_export_into_icml');
$criteria = $this->searchCriteriaBuilder
->addFilter('website_id', $this->shop->getId(), 'eq')
->create();
$collection = $this->productRepository->getList($criteria);
$customAdditionalAttributes = $this->config->getValue('retailcrm/catalog/attributes_to_export_into_icml');
foreach ($collection as $product) {
foreach ($collection->getItems() as $product) {
if ($product->getTypeId() == 'simple') {
$offers[] = $this->buildOffer($product);
$offers[] = $this->buildOffer($product, $customAdditionalAttributes);
}
if ($product->getTypeId() == 'configurable') {
$associated_products = $this->getAssociatedProducts($product);
foreach ($associated_products as $associatedProduct) {
$offers[] = $this->buildOffer($product, $associatedProduct);
$offers[] = $this->buildOffer($product, $customAdditionalAttributes, $associatedProduct);
}
}
}
@ -253,14 +281,17 @@ class Icml
* Build offer array
*
* @param object $product
* @param $customAdditionalAttributes
* @param object $associatedProduct
*
* @return array $offer
*/
private function buildOffer($product, $associatedProduct = null)
private function buildOffer($product, $customAdditionalAttributes, $associatedProduct = null)
{
$offer = [];
$picUrl = $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$store = $this->shop->getDefaultStore() ? $this->shop->getDefaultStore() : $this->storeManager->getStore();
$picUrl = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$offer['id'] = $associatedProduct === null ? $product->getId() : $associatedProduct->getId();
$offer['productId'] = $product->getId();
@ -276,7 +307,7 @@ class Icml
$offer['initialPrice'] = $associatedProduct === null
? $product->getFinalPrice()
: $associatedProduct->getFinalPrice();
$offer['url'] = $product->getProductUrl();
$offer['url'] = $product->getUrlInStore();
if ($associatedProduct === null) {
$offer['picture'] = $picUrl . 'catalog/product' . $product->getImage();
@ -293,8 +324,16 @@ class Icml
$offer['vendor'] = $associatedProduct === null
? $product->getAttributeText('manufacturer')
: $associatedProduct->getAttributeText('manufacturer');
$offer['weight'] = $associatedProduct === null
? $product->getWeight()
: $associatedProduct->getWeight();
$offer['params'] = $this->getOfferParams($product, $associatedProduct);
$params = $this->getOfferParams($product, $customAdditionalAttributes, $associatedProduct);
$offer['params'] = $params['params'];
$offer['dimensions'] = $params['dimensions'];
unset($params);
return $offer;
}
@ -303,62 +342,67 @@ class Icml
* Get parameters offers
*
* @param object $product
* @param $customAdditionalAttributes
* @param object $associatedProduct
*
* @return array $params
*/
private function getOfferParams($product, $associatedProduct = null)
private function getOfferParams($product, $customAdditionalAttributes, $associatedProduct = null)
{
$params = [];
if ($associatedProduct !== null) {
if ($associatedProduct->getResource()->getAttribute('color')) {
$colorAttribute = $associatedProduct->getResource()->getAttribute('color');
$color = $colorAttribute->getSource()->getOptionText($associatedProduct->getColor());
if (!$customAdditionalAttributes) {
return $params;
}
$attributes = explode(',', $customAdditionalAttributes);
$dimensionsAttrs = [];
$dimensions = '';
foreach ($attributes as $attributeCode) {
if ($this->checkDimension($attributeCode) !== false) {
$dimensionsAttrs += $this->checkDimension($attributeCode);
continue;
}
if (isset($color)) {
$attribute = $this->resourceModelProduct->getAttribute($attributeCode);
$attributeValue = $associatedProduct
? $associatedProduct->getData($attributeCode)
: $product->getData($attributeCode);
$attributeText = $attribute->getSource()->getOptionText($attributeValue);
if ($attribute && $attributeValue) {
$params[] = [
'name' => 'Color',
'code' => 'color',
'value' => $color
];
}
if ($associatedProduct->getResource()->getAttribute('size')) {
$sizeAttribute = $associatedProduct->getResource()->getAttribute('size');
$size = $sizeAttribute->getSource()->getOptionText($associatedProduct->getSize());
}
if (isset($size)) {
$params[] = [
'name' => 'Size',
'code' => 'size',
'value' => $size
'name' => $attribute->getDefaultFrontendLabel(),
'code' => $attributeCode,
'value' => $attributeText ? $attributeText : $attributeValue
];
}
}
$article = $associatedProduct === null ? $product->getSku() : $associatedProduct->getSku();
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 (!empty($article)) {
$params[] = [
'name' => 'Article',
'code' => 'article',
'value' => $article
];
if ($length && $width && $height) {
$dimensions = sprintf(
'%s/%s/%s',
$length,
$width,
$height
);
}
}
$weight = $associatedProduct === null ? $product->getWeight() : $associatedProduct->getWeight();
if (!empty($weight)) {
$params[] = [
'name' => 'Weight',
'code' => 'weight',
'value' => $weight
];
}
return $params;
return ['params' => $params, 'dimensions' => $dimensions];
}
/**
@ -391,4 +435,20 @@ class Icml
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

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

View file

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

View file

@ -4,7 +4,7 @@ namespace Retailcrm\Retailcrm\Model\Observer;
use Magento\Framework\Event\Observer;
use Retailcrm\Retailcrm\Helper\Proxy as ApiClient;
use RetailCrm\Retailcrm\Helper\Data as Helper;
use Retailcrm\Retailcrm\Helper\Data as Helper;
class OrderUpdate implements \Magento\Framework\Event\ObserverInterface
{
@ -53,9 +53,11 @@ class OrderUpdate implements \Magento\Framework\Event\ObserverInterface
$order = $observer->getEvent()->getOrder();
if ($order) {
$statusList = $this->helper->getCongigStatus();
$this->order = [
'externalId' => $order->getId(),
'status' => $this->config->getValue('retailcrm/retailcrm_status/' . $order->getStatus())
'status' => $statusList[$order->getStatus()]
];
if ($order->getBaseTotalDue() == 0) {

View file

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

View file

@ -0,0 +1,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

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

View file

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

@ -1 +1 @@
Magento 2 module for interaction with retailCRM
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

@ -2,7 +2,9 @@
namespace Retailcrm\Retailcrm\Test\Helpers;
class FieldsetTest extends \PHPUnit\Framework\TestCase
use Retailcrm\Retailcrm\Test\TestCase;
class FieldsetTest extends TestCase
{
protected $elementMock;
protected $authSessionMock;
@ -17,6 +19,8 @@ class FieldsetTest extends \PHPUnit\Framework\TestCase
protected $form;
protected $testElementId = 'test_element_id';
protected $testFieldSetCss = 'test_fieldset_css';
protected $objectFactory;
protected $secureRenderer;
public function setUp()
{
@ -26,7 +30,7 @@ class FieldsetTest extends \PHPUnit\Framework\TestCase
$escaperMock = $this->createMock(\Magento\Framework\Escaper::class);
$formElementMock = $this->createMock(\Magento\Framework\Data\Form\Element\Select::class);
$factoryMock->expects($this->any())->method('create')->willReturn($formElementMock);
$this->objectFactory = $this->objectManager->getObject(\Magento\Framework\DataObjectFactory::class);
$formElementMock->expects($this->any())->method('setRenderer')->willReturn($formElementMock);
$elementCollection = $this->objectManager->getObject(\Magento\Framework\Data\Form\Element\Collection::class);
@ -85,17 +89,39 @@ class FieldsetTest extends \PHPUnit\Framework\TestCase
$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->groupMock->expects($this->any())->method('getFieldsetCss')
->will($this->returnValue($this->testFieldSetCss));
$this->context = $this->createMock(\Magento\Backend\Block\Context::class);
$this->context->expects($this->any())->method('getRequest')->willReturn($this->requestMock);
$this->context->expects($this->any())->method('getUrlBuilder')->willReturn($this->urlModelMock);
$this->layoutMock->expects($this->any())->method('getBlockSingleton')->willReturn($rendererMock);
$this->helperMock = $this->createMock(\Magento\Framework\View\Helper\Js::class);
$this->form = $this->createPartialMock(\Magento\Config\Block\System\Config\Form::class, ['getElements', 'getRequest']);
$this->form->expects($this->any())->method('getElements')->willReturn($elementCollection);
$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

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

@ -2,7 +2,9 @@
namespace Retailcrm\Retailcrm\Test\Unit\Observer;
class OrderUpdateTest extends \PHPUnit\Framework\TestCase
use Retailcrm\Retailcrm\Test\TestCase;
class OrderUpdateTest extends TestCase
{
private $unit;
private $objectManager;

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];
}
}

View file

@ -1,11 +1,11 @@
{
"name": "retailcrm/retailcrm",
"description": "Retailcrm",
"description": "RetailCRM",
"require": {
"retailcrm/api-client-php": "~5.0"
},
"type": "magento2-module",
"version": "1.0.0",
"version": "2.5.2",
"license": [
"OSL-3.0",
"AFL-3.0"
@ -13,7 +13,7 @@
"authors": [
{
"name": "RetailDriver LLC",
"email": "gorokh@retailcrm.ru",
"email": "integration@retailcrm.ru",
"homepage": "https://www.retailcrm.ru",
"role": "Developer"
}

View file

@ -2,78 +2,97 @@
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="retailcrm" translate="label" sortOrder="10">
<label>Retailcrm</label>
<label>RetailCRM</label>
</tab>
<section id="retailcrm" translate="label" sortOrder="130" showInDefault="1" showInWebsite="1" showInStore="1">
<class>separator-top</class>
<label>Setting</label>
<label>Settings</label>
<tab>retailcrm</tab>
<resource>Retailcrm_Retailcrm::retailcrm_configuration</resource>
<group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General Configuration</label>
<label>Main settings</label>
<field id="api_url" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>API URL</label>
<comment>https://YourCrmName.retailcrm.ru</comment>
<backend_model>Retailcrm\Retailcrm\Model\Config\Backend\ApiUrl</backend_model>
</field>
<field id="api_key" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>API Key</label>
<comment>To generate an API Key, log in to RetailCRM then select Admin > Integration > API Keys</comment>
<label>API key</label>
<comment>You can create an API key in the administration section of RetailCRM</comment>
</field>
<field id="api_version" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>API Version</label>
<label>API version</label>
<source_model>Retailcrm\Retailcrm\Model\Setting\ApiVersions</source_model>
<backend_model>Retailcrm\Retailcrm\Model\Config\Backend\ApiVersion</backend_model>
</field>
</group>
<group id="Misc" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Misc</label>
<group id="catalog" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Catalogue settings</label>
<field id="attributes_to_export_into_icml" translate="label" type="multiselect" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Attributes to export into icml</label>
<comment>Attributes to export into icml</comment>
<label>Attributes for uploading to ICML</label>
<comment>Select attributes which will be uploaded to ICML</comment>
<source_model>Retailcrm\Retailcrm\Model\Setting\Attribute</source_model>
</field>
</group>
<group id="shipping" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Shipping</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Shipping</frontend_model>
<group id="shippingList" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Delivery types</label>
<field id="shippingList" translate="label" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>shipping settings</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\ShippingList</frontend_model>
<backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
</field>
</group>
<group id="payment" translate="label comment" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment method</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Payment</frontend_model>
<group id="paymentList" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment types</label>
<field id="paymentList" translate="label" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>payment settings</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\PaymentList</frontend_model>
<backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
</field>
</group>
<group id="status" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Order Status</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Status</frontend_model>
<group id="statusList" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Status types</label>
<field id="statusList" translate="label" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>status settings</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\StatusList</frontend_model>
<backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
</field>
</group>
<group id="Load" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Order Load</label>
<group id="load" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Uploading orders</label>
<field id="number_order" translate="label" type="text" sortOrder="6" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Order number</label>
<comment>Enter your order number, separated by commas</comment>
<comment>Enter order numbers separated by a comma for uploading</comment>
</field>
<field id="button_order" translate="label comment" type="button" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Button</frontend_model>
</field>
</group>
<group id="site" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Site</label>
<label>Setting the store by default</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Site</frontend_model>
</group>
<group id="sites" translate="label" type="select" sortOrder="70" showInDefault="0" showInWebsite="1" showInStore="0">
<label>Sites</label>
<label>Setting the stores correspondence</label>
<frontend_model>Retailcrm\Retailcrm\Block\Adminhtml\System\Config\Form\Fieldset\Sites</frontend_model>
</group>
<group id="daemon_collector" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Daemon Collector</label>
<field id="active" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Activate</label>
<source_model>Retailcrm\Retailcrm\Model\Setting\Select</source_model>
</field>
<field id="key" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Site key</label>
</field>
</group>
<group id="inventories_upload" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Synchronization of the stock balance</label>
<field id="active" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Activate</label>
<source_model>Retailcrm\Retailcrm\Model\Setting\Select</source_model>
</field>
</group>
</section>
</system>
</config>

View file

@ -4,10 +4,11 @@
<job name="create_icml" instance="Retailcrm\Retailcrm\Cron\Icml" method="execute">
<schedule>* */4 * * *</schedule>
</job>
<job name="order_hystory" instance="Retailcrm\Retailcrm\Cron\OrderHistory" method="execute">
<schedule>*/5 * * * *</schedule>
</job>
<job name="inventories" instance="Retailcrm\Retailcrm\Cron\Inventories" method="execute">
<schedule>*/15 * * * *</schedule>
</job>
</group>
</config>

View file

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

27
src/i18n/es_ES.csv Normal file
View file

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

27
src/i18n/ru_RU.csv Normal file
View file

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

View file

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

View file

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="head.additional">
<block class="Retailcrm\Retailcrm\Block\Frontend\DaemonCollector" name="block_name" template="Retailcrm_Retailcrm::daemon_collector.phtml" />
</referenceBlock>
</body>
</page>

View file

@ -3,4 +3,9 @@
<referenceContainer name="content">
<block class="Retailcrm\Retailcrm\Block\Display" name="retailcrm_display" template="Retailcrm_Retailcrm::sayhello.phtml" />
</referenceContainer>
<body>
<referenceBlock name="head.additional">
<block class="Retailcrm\Retailcrm\Block\Frontend\DaemonCollector" name="block_name" template="Retailcrm_Retailcrm::daemon_collector.phtml" />
</referenceBlock>
</body>
</page>

View file

@ -0,0 +1 @@
<?php echo $block->buildScript()->getJs() ?>