Compare commits

...

216 commits

Author SHA1 Message Date
ellynoize
b1d013dd30
Added option to round order amount (#269) 2025-01-20 10:26:45 +03:00
ellynoize
c5916fc8f2
Fix constant (#268)
Co-authored-by: ellynoize <a.kolesnikov@retailcrm.ru>
2024-11-14 12:10:15 +03:00
ellynoize
2c6cccc3b1
Добавлена передача дополнительных параметров в GET запросах (#267) 2024-10-14 17:26:34 +03:00
Uryvskiy Dima
c893cf24fb
ref #95381 Support for services in ICML (#265) 2024-05-06 09:07:38 +03:00
Kocmonavtik
d5f29dc5fe
ref #92633 Display module version (#263) 2023-11-23 11:10:52 +03:00
Uryvskiy Dima
3a30986e4b
ref #92124 Added currency validation (#260) 2023-10-06 14:00:10 +03:00
Uryvskiy Dima
571263ca2c
ref #90809 Changed the logic of customer subscriptions to promotional newsletters (#259) 2023-07-24 10:43:13 +03:00
Uryvskiy Dima
a375804086
Added query escaping in method for getting zone 2023-07-10 10:09:36 +03:00
KMityai
a56ce789ed version bump 2023-07-07 16:13:20 +03:00
KMityai
f5f55dd449 added escaping for db query in method for getting zone 2023-07-07 15:58:04 +03:00
KMityai
62605b11ed updated test testGetZoneByName 2023-07-07 15:48:53 +03:00
Uryvskiy Dima
22a9c2d819
ref #73045 Fixed the transfer of the weight of offers 2023-07-04 15:03:31 +03:00
Ivan Chaplygin
a2a4eca8c7 ref #73045 fix code 2023-07-04 14:38:35 +03:00
Ivan Chaplygin
63f625b329 ref #73045 Changing the weight transfer when generating a catalog 2023-07-03 17:15:00 +03:00
Uryvskiy Dima
6a7f395116
ref #90088 Types of deliveries and payments are displayed only active status and available stores 2023-06-07 14:41:33 +03:00
Ivan Chaplygin
792546d007 ref #90088 fix code 2023-06-07 13:39:01 +03:00
Ivan Chaplygin
7d3390bc02 ref #90088 fix style code
edit test
Edit getting site
2023-06-07 13:01:59 +03:00
Ivan Chaplygin
ef6d09c03a ref #90088 fix test
update Dockerfile
2023-06-05 17:18:10 +03:00
Ivan Chaplygin
e4cfdd8c9f ref #90088 create test 2023-06-02 16:27:31 +03:00
Ivan Chaplygin
8b7522ca6c ref #90088 update version 2023-06-02 14:55:21 +03:00
Ivan Chaplygin
b6181ab426 ref #90088 editing handler function 2023-06-02 14:43:54 +03:00
Ivan Chaplygin
3e1c19fd8d ref #90088 Types of deliveries and payments are displayed only active status and available stores 2023-06-02 13:55:00 +03:00
Uryvskiy Dima
090a5783c5
Optimization of the history processing algorithm (#254) 2023-04-28 11:44:38 +03:00
Vlad
feaeca458f
Fix customer create externalId (#251) 2022-09-05 12:58:12 +03:00
Smiley48
b22941cc3e
Update OrderManager.php 2022-05-26 14:27:06 +03:00
Vlad
6790cf7b0e
Minor improvements
* Fix country iso code
* Fix ICML weight generation
* Update phpcs rules to php >= 7.3
2022-04-01 13:14:34 +03:00
463485509e
update CI matrix (#239) 2021-09-02 11:19:20 +03:00
Alex Lushpai
78806e4aef
Update composer.json 2021-08-31 13:58:30 +03:00
RenCurs
4f15310fbb
Create customer if not exist within manual upload 2021-07-19 10:37:41 +03:00
a1f97bc996
Update readme 2021-05-18 12:11:19 +03:00
Day Vladimir
d058173aa4
Changing the connection to bootstrap.php (#229) 2021-05-06 14:42:45 +03:00
Alex Lushpai
4e09c021c8
Bump version to v4.1.6 2021-04-26 12:05:27 +03:00
f4e892d71a Bump version to v4.1.6 2021-04-23 13:18:26 +03:00
Alex Lushpai
92d94c919e
SSL link for product image 2021-04-23 12:20:36 +03:00
Ruslan Efanov
8445980d5a add ssl in link of image for product 2021-04-19 17:35:51 +03:00
Alex Lushpai
072b3a95b0
Merge pull request #225 from DmitreyZl/master
misprint_oc_delivery
2021-04-14 13:54:57 +03:00
DmitreyZl
a0337479ae
misprint_oc_delivery 2021-04-14 12:32:42 +03:00
Alex Lushpai
9e85d3bffb Payment, discount & weight calculation improvements 2021-03-24 15:26:09 +03:00
Yura
60998ad74f
Weight calculation based on product options (#221) 2021-03-24 15:16:13 +03:00
RenCurs
08df9043fa
Optional payment sum exchange (#223)
Closes #219
2021-01-29 14:37:56 +03:00
Yura
7cdab05aa2
Add prefix to externalId payment (#217) 2020-12-28 11:06:01 +03:00
RenCurs
4359f084bd
Add info about discount on order (#211) 2020-12-22 13:06:57 +03:00
Akolzin Dmitry
6391f49d2b
fix upload archive for github release (#215) 2020-12-15 17:48:07 +03:00
Akolzin Dmitry
828cc72930
update release process (#214)
Co-authored-by: Akolzin Dmitry <akolzin@retailcrm.ru>
2020-12-15 16:41:27 +03:00
Akolzin Dmitry
7ed233450c
fetch tags from origin repository (#213) 2020-12-15 14:15:37 +03:00
Akolzin Dmitry
24222d66ca
fix version file path (#212) 2020-12-15 13:50:54 +03:00
Alex Lushpai
ff87f7939e
Product name update within rebranding, minor code cleanup (#210) 2020-12-15 13:17:34 +03:00
Yura
bb23c4cc40
Handle the promotional price 2020-12-04 14:33:29 +03:00
DmitreyZl
cd7f63562d
Fix name option for onlineconsultant (#209) 2020-12-03 16:34:45 +03:00
Akolzin Dmitry
29bdecfc96
Closes #201. Remove payments with empty payment type (#208) 2020-12-03 12:07:20 +03:00
Yura
75fc11c6f9
Closes #200 - Address fix 2020-11-25 10:54:38 +03:00
Yura
fb7290f865
Option identifier for ICML (#203) 2020-11-25 10:52:11 +03:00
Akolzin Dmitry
c2abd5acd8
Move CI to GitHub Actions (#204) 2020-11-24 10:15:27 +03:00
Akolzin Dmitry
579150ea08
cleared api version detecting (#198)
* cleared api version detecting
* phpcs stage
2020-09-25 10:39:00 +03:00
DanielWeiser
769f35f379
fix compatibility with php 5.4 (#197) 2020-09-24 10:52:14 +03:00
vasilevdm
1d9110c364
fix version file path (#194) 2020-09-23 11:57:15 +03:00
Ilyas Salikhov
28391f4134
Merge pull request #196 from DanielWeiser/master
closes #170; Add voucher cost to discount
2020-09-16 15:35:30 +03:00
Daniel Weiser
2dbb56897e Upgrade version 2020-09-16 14:24:31 +03:00
Daniel Weiser
85f47c1984 closes #170; Add voucher cost to discount 2020-09-16 10:22:43 +03:00
2dbccd8a02
Unified address logic (#193) 2020-09-02 12:21:33 +03:00
Alex Lushpai
739c2775b5
version bump (#192) 2020-08-25 17:13:27 +03:00
Yura
6b2d6aeb80
Online Consultant (#183) 2020-08-21 14:15:47 +03:00
Akolzin Dmitry
6a221ab5f8
Fix coupon discount & cli paths 2020-08-18 15:35:27 +03:00
vasilevdm
bc16a2a6f3
fix opencart reward to crm discount convert error (#189) 2020-08-18 14:38:01 +03:00
Akolzin Dmitry
85de4835d5
fixes custom and config path (#188) 2020-08-18 14:37:46 +03:00
Akolzin Dmitry
d73219fcbb
cron fixes, update version 2020-08-07 14:04:05 +03:00
Akolzin Dmitry
2981afb05a
Corporate clients support & ability to change customer 2020-08-07 12:39:59 +03:00
Alex Lushpai
fb5d969ccc
Resend orders with new customer 2020-08-03 15:31:26 +03:00
Daniel Weiser
434ec7b431 refactoring and tests 2020-07-15 23:06:12 +03:00
Daniel Weiser
caf55f67ad refactoring 2020-07-15 12:28:02 +03:00
Daniel Weiser
53767392e9 resend orders with new customer 2020-07-13 14:49:59 +03:00
Alex Lushpai
0d0f0aa1d0
Change logical operator to prevent notices 2020-04-15 14:21:04 +03:00
Akolzin Dmitry
fa3b9e44b3 Fixes #178. Edited logical operator 2020-04-14 09:33:24 +03:00
Alex Lushpai
b57ff08d31
Merge pull request #180 from iyzoer/master
Fix for 3.0 installation, fixes pricing in ICML
2020-04-10 12:42:47 +03:00
Akolzin Dmitry
ce07e06b55 installation fix 2020-04-10 11:51:17 +03:00
Akolzin Dmitry
41da8fe862 Fix for 3.0 installation, fixes pricing in ICML 2020-04-10 11:38:25 +03:00
Dima Uryvskiy
dc2bee57d4
Fix bug with option name (#179)
fixes #178 ICML generation problem
2020-04-02 16:35:35 +03:00
Alex Lushpai
5e695863a3
Merge pull request #176 from iyzoer/master
Fixes tests for OC 3.0
2020-02-20 16:33:35 +03:00
Akolzin Dmitry
14e6584abf update for OC 3 2020-02-20 15:26:18 +03:00
Akolzin Dmitry
b921bc8c37 fix for OC 3 2020-02-20 11:43:04 +03:00
Akolzin Dmitry
e7270aac4b fix for OC 3 2020-02-20 10:26:40 +03:00
Akolzin Dmitry
a48ef3e1ea 'bugfixes' 2020-02-19 21:51:17 +03:00
Alex Lushpai
440e16b50b Update README.md 2020-02-19 21:51:17 +03:00
Akolzin Dmitry
8c8ee17c3d
Update CHANGELOG.md 2020-02-19 21:22:53 +03:00
Akolzin Dmitry
fc7c004988 update matrix, remove deprecated 2020-02-19 18:17:23 +03:00
Alex Lushpai
84ed83f887
Update README.md 2020-02-19 17:43:55 +03:00
Alex Lushpai
24cc5e57a6
Merge pull request #175 from iyzoer/master
Update travis configuration, deployment to Github releases
2020-02-19 17:42:27 +03:00
Akolzin Dmitry
d7221ecd9b update changelog 2020-02-19 17:29:21 +03:00
Akolzin Dmitry
9c8ad156c7 update version 2020-02-19 17:01:35 +03:00
Akolzin Dmitry
5b58d030c9 update fork condition 2020-02-19 16:58:45 +03:00
Akolzin Dmitry
752b11a2b6 test deploy condition 2020-02-19 16:53:05 +03:00
Akolzin Dmitry
1971aa0cb4 fix archive name 2020-02-19 15:47:19 +03:00
Akolzin Dmitry
27af27c1eb test 2020-02-19 15:24:33 +03:00
Akolzin Dmitry
3b6b3d0d9d test 2020-02-19 15:17:18 +03:00
Akolzin Dmitry
4b57be19e1 test 2020-02-19 15:15:21 +03:00
Akolzin Dmitry
137c83aa66 test deployment 2020-02-19 14:05:24 +03:00
Akolzin Dmitry
f0f3b65c02 update phpunit config 2020-02-19 13:01:38 +03:00
Akolzin Dmitry
266e8de11e update setUp 2020-02-19 12:45:02 +03:00
Akolzin Dmitry
5d6fd908f2 update for OC 3.0 2020-02-19 12:37:03 +03:00
Akolzin Dmitry
6bf58537ee update matrix 2020-02-19 12:09:17 +03:00
Akolzin Dmitry
c0f46cb672 test matrix 2020-02-19 11:49:32 +03:00
Akolzin Dmitry
d0467c020e test matrix 2020-02-19 10:50:24 +03:00
Akolzin Dmitry
74a36756f6 fix test script 2020-02-18 21:42:50 +03:00
Akolzin Dmitry
dc9458f434 update phpcov 2020-02-18 21:39:46 +03:00
Akolzin Dmitry
670e7ecfbd merge coverage 2020-02-18 18:22:03 +03:00
Akolzin Dmitry
2551e11e4c merge coverage 2020-02-18 18:17:59 +03:00
Akolzin Dmitry
4a8875dc8d fix for coverage 2020-02-18 18:11:23 +03:00
Akolzin Dmitry
b29b4e1a51 fix for coverage 2020-02-18 18:01:27 +03:00
Akolzin Dmitry
2014deda25 fix for coverage 2020-02-18 17:29:05 +03:00
Akolzin Dmitry
1317770335 codecov 2020-02-18 16:18:15 +03:00
Akolzin Dmitry
f8b651c70f codecov 2020-02-18 16:16:39 +03:00
Akolzin Dmitry
04da58c185 skipping builds on tags 2020-02-18 14:28:55 +03:00
Akolzin Dmitry
bc0d3660ad update travis config 2020-02-18 13:09:49 +03:00
Akolzin Dmitry
5f60b761f0 fix deploy 2020-02-18 13:00:33 +03:00
Akolzin Dmitry
24413ee15b update deploy 2020-02-18 12:53:31 +03:00
Akolzin Dmitry
353557effe test deploy conditions 2020-02-18 12:44:08 +03:00
Akolzin Dmitry
7c0f4d5197 test deploy 2020-02-18 12:33:54 +03:00
Akolzin Dmitry
1cce01d50e skip install script 2020-02-18 11:39:43 +03:00
Akolzin Dmitry
6d1cfa4d0c update travis config 2020-02-18 11:38:11 +03:00
Akolzin Dmitry
979fdf58b6 update travis config 2020-02-18 11:28:07 +03:00
Akolzin Dmitry
c8690e8252 update travis config 2020-02-18 10:50:40 +03:00
Akolzin Dmitry
de3a1ae7e7 test deploy 2020-02-18 10:26:27 +03:00
Akolzin Dmitry
2f099d477c fix 2020-02-18 10:19:05 +03:00
Akolzin Dmitry
9e1edf2fcc test deploy 2020-02-18 10:12:17 +03:00
Akolzin Dmitry
090a4b6cfa update travis config 2020-02-18 09:41:43 +03:00
Akolzin Dmitry
033bac97cf fix stages 2020-02-18 00:29:19 +03:00
Akolzin Dmitry
799c260189 'stages' 2020-02-18 00:11:29 +03:00
Akolzin Dmitry
3516378d7e fix path in restore data 2020-02-17 23:12:51 +03:00
Akolzin Dmitry
484d738e70 fix path 2020-02-17 23:07:01 +03:00
Akolzin Dmitry
2b5faed85b fix vendor dir 2020-02-17 17:56:13 +03:00
Akolzin Dmitry
1caf5860a8 move robofile 2020-02-17 17:46:01 +03:00
Alex Lushpai
9d90c32b17
Merge pull request #174 from Evgeniy-Goroh/price_upload
не выгружать акционные цены равные нулю
2020-01-09 14:46:01 +03:00
Alex Lushpai
3d055a01fe
Merge pull request #173 from Evgeniy-Goroh/task-63938
task 63938 перед отправкой в CRM очищаем пустые поля
2020-01-09 14:45:41 +03:00
Alex Lushpai
81d1d5e94e
Merge pull request #172 from KMityai/master
fixes templates
2020-01-09 14:45:22 +03:00
gorokh
81737b4df3 не выгружать акционные цены равные нулю 2019-12-13 12:43:33 +03:00
Дмитрий
2da9acf18d fixed selecting "special_price" in views 2019-12-11 12:29:08 +03:00
gorokh
1c5053d81f правки теста 2019-12-06 15:48:04 +03:00
gorokh
30e6cb9886 task 63938 перед отправкой в CRM очищаем пустые поля 2019-12-06 11:01:29 +03:00
Дмитрий
268e5b4279 fixed output "status_changes" option 2019-12-06 11:01:26 +03:00
Alex Lushpai
82ff3628cd
Update CHANGELOG.md 2019-07-18 13:11:06 +03:00
Alex Lushpai
60b65cc6d4
Merge pull request #164 from iyzoer/master
Update .travis.yml
2019-07-18 13:10:03 +03:00
Akolzin Dmitry
f4ced73be4 Update .travis.yml 2019-07-18 12:52:24 +03:00
Alex Lushpai
90e7c8913c
Merge pull request #163 from Frosin/master
fixed synchronization when removing or adding products in retailCRM
2019-07-18 11:59:32 +03:00
Frosin
0e90d26dee text correction 2019-07-12 11:43:04 +03:00
Frosin
9e5b1ba2d8 fixed synchronization when removing or adding products in retailCRM 2019-07-11 10:56:24 +03:00
Alex Lushpai
74a5d2c642
Merge pull request #158 from sergeygw1990/master
Closes: #157 Генерация габаритов товара
2019-06-13 15:01:52 +03:00
Sergey
f71002f4d6 Closes: #157 Генерация габаритов товара 2019-06-07 14:43:49 +03:00
Alex Lushpai
93bacf9b7b
Merge pull request #156 from Neur0toxine/master
[fix] Исправление некорректной загрузки акционных цен
2019-05-30 14:41:26 +03:00
bc0469f8cf [fix] Исправление некорректной загрузки акционных цен 2019-05-30 10:33:42 +03:00
Alex Lushpai
a69c4be480
Merge pull request #152 from sergeygw1990/master
Удаление типа цены товара для неустановленных акционных цен
2019-05-24 11:39:45 +03:00
Sergey
eb83212094 Удаление типа цены товара для неустановленных акционных цен 2019-05-17 15:05:37 +03:00
Alex Lushpai
39d596e49d
Merge pull request #151 from sergeygw1990/master
Fixes: #147 Возврат остатка товара при отмене заказа
2019-04-19 10:02:58 +03:00
Sergey
1852d5cb08 Fixes: #147 Возврат остатка товара при отмене заказа 2019-04-18 17:43:54 +03:00
Alex Lushpai
4313505fe5
Merge pull request #149 from Neur0toxine/master
Исправлена ошибка с передачей данных заказа в retailCRM
2019-04-18 16:19:54 +03:00
66d3963dd5 Исправлена ошибка с передачей данных заказа в retailCRM 2019-04-16 15:01:28 +03:00
Alex Lushpai
702c18d757
Merge pull request #146 from sergeygw1990/master
v3.3.0
2019-03-21 16:59:53 +03:00
Sergey
3d9b51704e transfer price type in order 2019-03-21 12:29:10 +03:00
Alex Lushpai
c057540b9d
Merge pull request #145 from iyzoer/master
bug fix
2019-03-21 10:10:32 +03:00
Akolzin Dmitry
adf390c286 bug fix 2019-03-21 10:00:00 +03:00
Alex Lushpai
41ac83aeff
Merge pull request #143 from iyzoer/master
History fix, orders history setting
2019-03-20 09:44:43 +03:00
Akolzin Dmitry
d58b66a01b History fix, orders history setting 2019-03-19 16:43:54 +03:00
Alex Lushpai
08d071edda
Merge pull request #137 from KMityai/master
retailcrm_special customer group fixed
2019-03-05 15:06:45 +03:00
dmitry
068c444c73 retailcrm_special customer group fixed 2019-03-05 14:24:27 +03:00
Alex Lushpai
03679ea62e
Merge pull request #135 from sergeygw1990/master
v3.2.4
2019-03-01 16:25:53 +03:00
Sergey
9fedcb096c fix model prices 2019-03-01 14:27:46 +03:00
Sergey
48ccded014 fix model prices 2019-03-01 11:07:16 +03:00
Sergey
8a823cf3ad v3.2.4 Отправка нулевой цены при отсутсвтующей акционной цене 2019-02-28 16:48:41 +03:00
Sergey
6443e10330 v3.2.4 Добавлена возможность передачи фкционных цен нескольких групп пользователей 2019-02-28 16:48:41 +03:00
Alex Lushpai
24c6de76ec
Merge pull request #132 from sergeygw1990/master
v3.2.2
2019-02-14 13:26:27 +03:00
Sergey
3521bb603e v3.2.2 2019-02-13 17:34:30 +03:00
Alex Lushpai
f79ed21018
Merge pull request #130 from iyzoer/master
Fixes #129 Fix catalog order controller
2019-01-25 15:36:20 +03:00
Akolzin Dmitry
615d9c7c17 Fixes #129 Fix catalog order controller 2019-01-25 09:52:12 +03:00
Alex Lushpai
db80810584
Merge pull request #127 from iyzoer/master
v3.2.1
2019-01-18 10:25:35 +03:00
Akolzin Dmitry
c27383154b
Update .travis.yml 2019-01-18 09:53:27 +03:00
Akolzin Dmitry
ed5de5186e v3.2.1 2019-01-18 09:52:21 +03:00
Alex Lushpai
ee36226b31
Merge pull request #126 from iyzoer/master
v3.2.0
2018-12-25 10:06:03 +03:00
Akolzin Dmitry
dfd6c4a76d Closes #123 v3.2.0 2018-12-25 09:54:03 +03:00
Alex Lushpai
d54e5e8c19
Merge pull request #122 from iyzoer/master
v3.1.6
2018-12-05 17:21:45 +03:00
Akolzin Dmitry
0498e4d761 v3.1.6 2018-12-05 17:11:24 +03:00
Akolzin Dmitry
cfcac1e013 Добавил полчение события из БД для OC 3.0 2018-12-05 17:10:09 +03:00
Alex Lushpai
3e55de0e3a
Merge pull request #120 from iyzoer/master
v3.1.5
2018-11-02 20:18:39 +03:00
Akolzin Dmitry
bceb2069ac Bug fix 2018-11-02 09:29:46 +03:00
Alex Lushpai
5b700332b6
Merge pull request #119 from iyzoer/master
v3.1.4
2018-11-01 15:34:50 +03:00
Akolzin Dmitry
9fb324188b v3.1.4 2018-11-01 15:18:59 +03:00
Alex Lushpai
bca86cc51c
Merge pull request #118 from iyzoer/master
3.1.3
2018-10-25 12:03:30 +03:00
Akolzin Dmitry
0787d4a997
Update VERSION 2018-10-25 11:33:49 +03:00
Akolzin Dmitry
75aed59403
Update CHANGELOG.md 2018-10-25 11:33:35 +03:00
Akolzin Dmitry
273499acdc Update generation clientId 2018-10-25 11:31:19 +03:00
Akolzin Dmitry
0854d36155 Send to crm marketplace activate/deactivate information 2018-10-25 11:31:19 +03:00
Alex Lushpai
30a2600b7b
Merge pull request #112 from sergeygw1990/master
v3.1.2
2018-08-31 17:02:32 +03:00
Sergey
fe5a2abcba v3.1.2 2018-08-31 14:14:01 +03:00
Alex Lushpai
4174195128
Merge pull request #108 from iyzoer/master
v3.1.1
2018-08-03 12:12:59 +03:00
Akolzin Dmitry
57c2ca99c9 v3.1.1 2018-08-03 11:55:21 +03:00
Alex Lushpai
86064c775f
Merge pull request #107 from iyzoer/master
Bug fixes
2018-08-01 09:37:44 +03:00
Akolzin Dmitry
8b8350a290 Bug fixes 2018-08-01 09:31:40 +03:00
Alex Lushpai
761bffef76
Merge pull request #106 from iyzoer/master
v3.1.0
2018-07-31 17:28:01 +03:00
Akolzin Dmitry
6b1cdd5d42 Update test 2018-07-31 17:22:29 +03:00
Akolzin Dmitry
d08519f673 Исправлена ошибка при выгрузке заказа через админку, улучшена передача типа доставки, доработан дизайн страницы настроек, добавлена настройка передачи номера заказа 2018-07-31 17:17:36 +03:00
Alex Lushpai
caa6a03b14
Merge pull request #105 from klaos27/master
Update retailcrm.php
2018-07-30 17:10:43 +03:00
Alex Lushpai
c3120a723d
Merge pull request #102 from klaos27/patch-1
Update retailcrm.tpl
2018-07-30 17:10:28 +03:00
klaos27
7b05d975a4
Update retailcrm.php 2018-07-30 15:03:29 +02:00
klaos27
93641e82ef
Update retailcrm.tpl 2018-07-30 14:43:46 +02:00
klaos27
5cd191b6a4
Update retailcrm.tpl 2018-07-26 15:14:59 +02:00
klaos27
a829cb8f17
Update retailcrm.tpl 2018-07-24 10:30:59 +02:00
Alex Lushpai
9eecfcffb8
Merge pull request #99 from iyzoer/master
Bug fix twig template
2018-07-19 17:07:06 +03:00
Akolzin Dmitry
7151814da8 Update changelog 2018-07-19 17:05:10 +03:00
Akolzin Dmitry
6506dc716f Fix bugs in twig template, fix saving settings with empty history. Fixes #93 2018-07-19 16:56:35 +03:00
Alex Lushpai
4ba6f6ce83
Update README.md 2018-06-18 14:05:15 +03:00
Alex Lushpai
1440c9fdbf
Update README.ru.md 2018-06-14 13:02:34 +03:00
Alex Lushpai
0dcededd62
Merge pull request #92 from iyzoer/master
Travis tests
2018-06-14 12:41:53 +03:00
Akolzin Dmitry
2c4306dad1 Bug fix 2018-06-14 11:26:15 +03:00
Akolzin Dmitry
26a6a0731c Makefile, edit travis.yml 2018-06-13 17:35:29 +03:00
Akolzin Dmitry
a9c8a96101 Edit Robofile 2018-06-13 17:18:06 +03:00
Akolzin Dmitry
f006561d3e Edit travis.yml 2018-06-13 16:26:07 +03:00
Akolzin Dmitry
c49070ea6f Update readme 2018-06-13 16:19:33 +03:00
Akolzin Dmitry
c454db172f Tests 2018-06-13 16:14:44 +03:00
122 changed files with 9756 additions and 6708 deletions

58
.docker/Dockerfile Normal file
View file

@ -0,0 +1,58 @@
FROM php:7.1-apache
RUN apt-get update
RUN apt-get install -y netcat zlib1g-dev libpq-dev git libicu-dev libxml2-dev libpng-dev libjpeg-dev libmcrypt-dev libxslt-dev libfreetype6-dev unzip \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl \
&& docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
&& docker-php-ext-install mysqli pdo pdo_mysql \
&& docker-php-ext-install zip \
&& docker-php-ext-install xml \
&& docker-php-ext-configure gd --with-png-dir=/usr/local/ --with-jpeg-dir=/usr/local/ --with-freetype-dir=/usr/local/ \
&& docker-php-ext-install gd \
&& docker-php-ext-install mcrypt \
&& docker-php-ext-install bcmath \
&& docker-php-ext-install soap \
&& docker-php-ext-install xsl \
&& docker-php-ext-install mbstring
RUN apt-get install -y wget
RUN wget -O /usr/bin/phpunit https://phar.phpunit.de/phpunit-7.phar && chmod +x /usr/bin/phpunit
RUN curl --insecure https://getcomposer.org/download/1.9.3/composer.phar -o /usr/bin/composer && chmod +x /usr/bin/composer
# Set timezone
RUN rm /etc/localtime && \
ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime && \
"date"
ARG TEST_SUITE
ARG OPENCART
ARG SERVER_PORT
ARG OC_DB_HOSTNAME
ARG OC_DB_USERNAME
ARG OC_DB_PASSWORD
ARG OC_DB_DATABASE
ARG OC_USERNAME
ARG OC_PASSWORD
ARG OC_EMAIL
ENV TEST_SUITE=${TEST_SUITE}
ENV OPENCART=${OPENCART}
ENV PORT=${SERVER_PORT}
ENV OC_DB_HOSTNAME=${OC_DB_HOSTNAME}
ENV OC_DB_USERNAME=${OC_DB_USERNAME}
ENV OC_DB_PASSWORD=${OC_DB_PASSWORD}
ENV OC_DB_DATABASE=${OC_DB_DATABASE}
ENV OC_USERNAME=${OC_USERNAME}
ENV OC_PASSWORD=${OC_PASSWORD}
ENV OC_EMAIL=${OC_EMAIL}
ADD .docker/entrypoint.sh /usr/local/bin/docker-php-entrypoint
RUN chmod +x /usr/local/bin/docker-php-entrypoint
RUN sed -i "s/80/$PORT/g" /etc/apache2/sites-enabled/000-default.conf /etc/apache2/ports.conf && \
sed -i 's/var\/www\/html/opencart-module\/www/g' /etc/apache2/sites-enabled/000-default.conf && \
sed -i 's/var\/www/opencart-module/g' /etc/apache2/apache2.conf

28
.docker/entrypoint.sh Normal file
View file

@ -0,0 +1,28 @@
#!/bin/sh
until nc -z -v -w30 mysql 3306
do
echo "Waiting for database connection..."
sleep 5
done
make -C /opencart-module run
mkdir -p /opencart-module/www/system/storage/session
sed -i 's/\?>//g' /opencart-module/www/config.php
sed -i 's/\?>//g' /opencart-module/www/admin/config.php
echo '\nini_set("session.save_path", DIR_SYSTEM . "storage/session");' >> /opencart-module/www/config.php
echo '\nini_set("session.save_path", DIR_SYSTEM . "storage/session");' >> /opencart-module/www/admin/config.php
#chown -R www-data:www-data /opencart-module \
# && find /opencart-module -type d -exec chmod 755 {} \; \
# && find /opencart-module -type f -exec chmod 644 {} \;
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- apache2-foreground "$@"
fi
exec "$@"

18
.env-dist Normal file
View file

@ -0,0 +1,18 @@
# OpenCart Database connection values
OC_DB_HOSTNAME=mysql
OC_DB_USERNAME=opencart
OC_DB_PASSWORD=opencart
OC_DB_DATABASE=opencart
OC_DB_DRIVER=mysqli
# OpenCart Administration user
OC_USERNAME=admin
OC_PASSWORD=admin
OC_EMAIL=you@example.com
# Server Specification
SERVER_PORT=8080
SERVER_URL=http://localhost
TEST_SUITE=3
OPENCART=3.0.2.0

202
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,202 @@
name: ci
on:
push:
branches:
- '**'
tags-ignore:
- '*.*'
pull_request:
env:
OC_DB_HOSTNAME: 127.0.0.1
OC_DB_USERNAME: root
OC_DB_PASSWORD: root
OC_DB_DATABASE: tests_opencart
OC_DB_DRIVER: mysqli
OC_USERNAME: admin
OC_PASSWORD: admin
OC_EMAIL: test@test.com
SERVER_PORT: 80
SERVER_URL: http://localhost
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- php-version: '7.3'
test-suite: '3'
oc: '3.0.1.1'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.1.2'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.2.0'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.0'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.1'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.2'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.3'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.4'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.5'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.6'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.7'
- php-version: '7.3'
test-suite: '3'
oc: '3.0.3.8'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.1.1'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.1.2'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.2.0'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.0'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.1'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.2'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.3'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.4'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.5'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.6'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.7'
- php-version: '7.4'
test-suite: '3'
oc: '3.0.3.8'
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: false
MYSQL_ROOT_PASSWORD: ${{ env.OC_DB_PASSWORD }}
MYSQL_DATABASE: ${{ env.OC_DB_DATABASE }}
ports:
- 3306:3306
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
extensions: gd, mbstring, mysqli, zip, mcrypt, mysql, pdo_mysql, dom
- name: Install Opencart
env:
TEST_SUITE: ${{ matrix.test-suite }}
OPENCART: ${{ matrix.oc }}
run: make before_script
- name: Run tests
env:
TEST_SUITE: ${{ matrix.test-suite }}
OPENCART: ${{ matrix.oc }}
run: composer test
- name: Coverage
env:
COVERAGE: ${{ matrix.coverage }}
if: env.COVERAGE == 1
run: |
make coverage
bash <(curl -s https://codecov.io/bash)
phpcs:
needs: ['test']
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: Install dependencies
run: composer install
- name: Check compatibility
run: make phpcomp
deploy:
needs: ['phpcs']
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.GITHUB_TOKEN }}
with:
tag_name: ${{ env.RELEASE_TAG }}
release_name: ${{ env.RELEASE_TAG }}
body: ${{ env.LAST_COMMIT }}
draft: false
prerelease: false
- name: Upload Release Asset
id: upload-release-asset
if: env.LAST_TAG != env.RELEASE_TAG
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ env.ARCHIVE_PATH }}
asset_name: ${{ env.ARCHIVE_NAME }}
asset_content_type: application/zip
- name: Cleanup
if: env.LAST_TAG != env.RELEASE_TAG
run: make delete_archive

6
.gitignore vendored
View file

@ -3,4 +3,8 @@
*.settings
*.buildpath
*.project
/vendor
/www
/bin
.env
composer.lock

View file

@ -1,32 +1,182 @@
## v4.1.19
* Added option to round order amount
## v4.1.18
* Fixed constant with version of module.
## v4.1.17
* Added additional parameters to GET requests.
## v4.1.16
* Support for services in ICML
## v4.1.15
* Display module version
## v4.1.14
* Added currency validation when configuring the module
## v4.1.13
* Changed the logic of customer subscriptions to promotional newsletters
## v4.1.12
* Added escaping for db query in method for getting zone
## v4.1.11
* Fixed the transfer of the weight offers
## v4.1.10
* Types of deliveries and payments are displayed only active status and available stores
## v4.1.9
* Optimization of the history processing algorithm
## v4.1.8
* Fixed customer externalId when creating a customer and sending it to RetailCRM
## v4.1.7
* Fixed notices in ICML generation and while setting delivery type
* Fixed incorrect data check before setting payment data
* Some other minor improvements
## v4.1.6
* Fix for typo in the history routine
* Fix for incorrect protocol in the ICML product image links
## v4.1.5
* Send discount details into the system
* Prefix for payment external ID (to ensure that it's unique)
* Make payment sum optional
* Weight calculation based on product options
## v.4.1.4
* Create payment only when the payment type is specified
* Checking the availability of promotional price for the product when uploading the order
## v.4.1.3
* Removed the ability to specify the API version
## v.4.1.2
* Added accounting for a gift certificate price when creating an order and sending it to RetailCRM
## v.4.1.1
* Updated the mechanics of processing customer addresses
## v.4.1.0
* Added the ability to connect Online Consultant
## v.4.0.1
* Fixed the transfer of coupon discounts
* Fixed console commands
## v.4.0.0
* Added support for corporate customers
* Added support for changing the customer in the order
## v.3.3.9
* Fixed prices in ICML
## v.3.3.8
* Fixed warnings output when generating ICML
## v.3.3.7
* Changed the configuration of travis-ci for build
## v.3.3.6
* Minor bug fixes
## v.3.3.5
* Added generation of dimensions in the catalog
## v.3.3.4
* Fixed a bug with incorrect uploading of promotional prices for products with characteristics
## v.3.3.3
* Added removal of product's price type for unidentified promotional prices
## v.3.3.2
* Added the return of leftover product stocks when the order is canceled
## v.3.3.1
* Fixed a bug with sending order data to RetailCRM when receiving the history of changes from RetailCRM
## v.3.3.0
* Added setting for recording the history of order changes in Opencart
* Fixed a bug with calling the order editing event when uploading the history of changes from RetailCRM
* Added transfer of the price type when creating or editing an order
## v.3.2.4
* Added the ability to transfer promotional prices for multiple user groups
* Added the ability to transfer zero price for unspecified promotional prices
* Removed the retailcrm base price from the price types conformity settings
## v.3.2.2
* Removed generation of the customer's externalId when order was created without registeration on the website.
## v.3.2.1
* Changed the logic for transferring data for orders and customers. Contact information for delivery is transferred to the order's card, and the payer's contact information is transferred to the customer's card.
## v.3.2.0
* Added uploading images for categories in ICML
* Added setting for selecting the currency in which the price will be uploaded in ICML
## v.3.1.6
* Fixed getting events from the database for OC 3.0
## v.3.1.5
* Bug fixes
## v.3.1.4
* Fixed incorrect combining of delivery types
## v.3.1.3
* Added module activation in the RetailCRM marketplace
## v.3.1.2
* Added Spanish translation
* Reworked English translation
## v.3.1.1
* Added customer creation when manually uploading an order from admin panel
## v.3.1.0
* Redesigned the twig template
* Added a setting for transmitting the order number to RetailCRM
* Improved mechanics of delivery type transfer to RetailCRM
* Fixed an error when uploading a single order in admin panel
## v.3.0.5
* Fixed errors in the twig template
* Added processing of the history of changes when saving settings for setting the current sinceId, if the history in RetailCRM is empty
## v.3.0.4
* Добавлена проверка группы пользователя в заказе при редактировании
* Добавлена передача скидки по бонусным баллам
* Added checking the user group in the order when editing
* Added transfer of discount for bonus points
## v.3.0.3
* Исправлена ошибка с изменением пароля пользователя
* Fixed a bug with changing the user's password
## v.3.0.2
* Улучшена механика выгрузки изменений из RetailCRM на сайт
* Улучшена механика выборки типов доставки на сайте
* Добавлена возможность периодической выгрузки акционных цен для товаров
* Улучшена совместимость с Opencart 3.0
* Improved the mechanics of uploading changes from RetailCRM to the site
* Improved the mechanics of selecting delivery types on the site
* Added the ability to periodically upload promotional prices for products
* Improved compatibility with Opencart 3.0
## v.2.4.3
* Устранены некоторые баги, добавлен вывод ошибок при выгрузке единичных заказов
* Minor bug fixes, added error output when uploading individual orders
## v.2.4.2
* Улучшена синхронизация кастомных полей
* Добавлены настройки дефолтных способов доставки и оплаты
* Улучшена настройка Daemon Collector
* Доработан шаблон twig для совместимости с Opencart 3.0
* Improved synchronization of custom fields
* Added settings for default delivery and payment types
* Improved Daemon Collector configuration
* Improved the twig template for compatibility with Opencart 3.0
## v.2.4.1
* Исправлена работа истории (доработана обработка адресов, добавлена обработка заказов с пустыми полями, доработана история по клиентам)
* История теперь синхронизируется по sinceId
* Проверка доступных версий API через метод /api/versions
* Добавлена возможность сопоставления кастомных полей(для API v5)
* Fixed history of changes (improved address processing, added order processing with empty fields, improved customer history)
* History is now synced by sinceId
* Checking available API versions using the /api/versions method
* Added the ability to map custom fields (for API V5)
## v.2.4.0
* Добавлена возможность работы на 3 версиях API (v3, v4, v5)
* Добавлена совместимость с Opencart 3.0
* Added the ability to work on 3 API versions (v3, v4, v5)
* Added compatibility with Opencart 3.0

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015 RetailDriver LLC
Copyright (c) 2015-2021 RetailDriver LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE

49
Makefile Normal file
View file

@ -0,0 +1,49 @@
ROOT_DIR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
VERSION = `cat $(ROOT_DIR)/VERSION`
ARCHIVE_NAME = '/tmp/retailcrm-'$(VERSION)'.ocmod.zip'
.PHONY: coverage
all: build_archive send_to_ftp delete_archive
build_archive:
zip -r $(ARCHIVE_NAME) ./src/*
send_to_ftp:
curl -T $(ARCHIVE_NAME) -u $(FTP_USER):$(FTP_PASSWORD) ftp://$(FTP_HOST)
delete_archive:
rm -f $(ARCHIVE_NAME)
before_script:
mkdir coverage
composer require --dev beyondit/opencart-test-suite:~$(TEST_SUITE)
composer opencart:install
bin/robo --load-from tests/RoboFile.php project:deploy
(php -S localhost:80 -t www &) 2> /dev/null > /dev/null
sleep 2
coverage:
wget https://phar.phpunit.de/phpcov-2.0.2.phar && php phpcov-2.0.2.phar merge coverage/ --clover coverage.xml
robo_deploy:
bin/robo --load-from tests/RoboFile.php project:deploy
run:
composer require --dev beyondit/opencart-test-suite ~$(TEST_SUITE)
composer opencart:install
bin/robo --load-from tests/RoboFile.php project:deploy
run_test: run
(php -S localhost:$(SERVER_PORT) -t www &) 2> /dev/null > /dev/null
sleep 2
composer test
test: robo_deploy
composer test
phpcs-config:
bin/phpcs --config-set installed_paths vendor/phpcompatibility/php-compatibility
phpcomp: phpcs-config
@bin/phpcs -s -p ./src --standard=PHPCompatibility --runtime-set testVersion 7.3-7.4

View file

@ -1,7 +1,12 @@
[![Build Status](https://github.com/retailcrm/opencart-module/workflows/ci/badge.svg)](https://github.com/retailcrm/opencart-module/actions)
[![Coverage](https://img.shields.io/codecov/c/gh/retailcrm/opencart-module/master.svg?logo=codecov&logoColor=white)](https://codecov.io/gh/retailcrm/opencart-module)
[![GitHub release](https://img.shields.io/github/release/retailcrm/opencart-module.svg?logo=github&logoColor=white)](https://github.com/retailcrm/opencart-module/releases)
[![PHP version](https://img.shields.io/badge/PHP->=5.4-blue.svg?logo=php&logoColor=white)](https://php.net/)
Opencart module
===============
Module allows integrate CMS Opencart >= 2.3 with [retailCRM](http://retailcrm.pro)
This module allows to integrate CMS Opencart >= 2.3 with [RetailCRM](https://retailcrm.pro).
### Previous versions:
@ -11,47 +16,59 @@ Module allows integrate CMS Opencart >= 2.3 with [retailCRM](http://retailcrm.pr
#### Features:
* Export orders to retailCRM & fetch changes back
* Export product catalog into [ICML](http://www.retailcrm.pro/docs/Developers/ICML) format
* Export orders to RetailCRM & receive changes from RetailCRM.
* Export product catalog to the [ICML](https://help.retailcrm.pro/Developers/ICML) format.
#### Install
Copy files to the site root
**Note:** `/path/to/your/site` is just a placeholder. You should replace it with the actual path to your site root in the examples below. The module won't work if you'll use those examples without changing the path placeholder.
Copy module files to the site root (replace `/path/to/your/site` with the actual path to your site):
```
unzip master.zip
cp -r opencart-module/* /path/to/site/root
cp -r opencart-module/src/* /path/to/your/site
```
#### Setup
* Go to Admin -> Extensions -> Modules -> retailCRM
* Fill you api url & api key
* Go to Admin -> Extensions -> Modules -> RetailCRM
* Fill you API URL & API key
* Specify directories matching
#### Migrating to 4.* from early modules versions
It's necessary to remove the `/path/to/your/site/system/library/retailcrm` before copying current module into your site.
#### Getting changes in orders
Add to cron:
Add to cron (replace `/path/to/your/site` with the actual path to your site):
```
*/5 * * * * /usr/bin/php /path/to/opencart/system/cron/history.php >> /path/to/opencart/system/storage/logs/cronjob_history.log 2>&1
*/5 * * * * /usr/bin/php /path/to/your/site/system/library/retailcrm/cron/history.php >> /path/to/your/site/system/storage/logs/cronjob_history.log 2>&1
```
#### Setting product catalog export
Add to cron:
Add to cron (replace `/path/to/your/site` with the actual path to your site):
```
* */4 * * * /usr/bin/php /path/to/opencart/system/cron/icml.php >> /path/to/opencart/system/storage/logs/cronjob_icml.log 2>&1
* */4 * * * /usr/bin/php /path/to/your/site/system/library/retailcrm/cron/icml.php >> /path/to/your/site/system/storage/logs/cronjob_icml.log 2>&1
```
Your export file will be available by following url
Your export file should be available by following url:
```
http://youropencartsite.com/retailcrm.xml
```
Replace `youropencartsite.com` with your site domain and `http` with your site scheme.
#### Export existing orders and customers
You want to run this command onecly:
/usr/bin/php /path/to/opencart/system/cron/export.php
Run this command (replace `/path/to/your/site` with the actual path to your site):
```sh
/usr/bin/php /path/to/your/site/system/library/retailcrm/cron/export.php
```
You should run this command only once.

View file

@ -1,73 +0,0 @@
Opencart module
===============
Модуль интеграции CMS Opencart >= 2.3 c [RetailCRM](https://retailcrm.ru)
Информация о [кастомизации](https://github.com/retailcrm/opencart-module/wiki/%D0%9A%D0%B0%D1%81%D1%82%D0%BE%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD%D0%B0)
### Предыдущие версии:
[v1.x](https://github.com/retailcrm/opencart-module/tree/v1.x)
[v2.x (2.0, 2.1, 2.2)](https://github.com/retailcrm/opencart-module/tree/v2.2)
#### Модуль позволяет:
* Экспортировать в CRM данные о заказах и клиентах и получать обратно изменения по этим данным
* Синхронизировать справочники (способы доставки и оплаты, статусы заказов и т.п.)
* Выгружать каталог товаров в формате [ICML](http://www.retailcrm.ru/docs/Developers/ICML)
#### Установка
Установите модуль скопировав необходимые файлы в корень сайта
```
unzip master.zip
cp -r opencart-module/* /path/to/site/root
```
#### Активируйте модуль
В списке модулей нажмите "Установить"
#### Настройте параметры интеграции
На странице настроек модуля укажите URL Вашей CRM и ключ авторизации, после сохранения этих данных укажите соответствия справочников типов доставок, оплат и статусов заказа.
#### Получение измений из CRM
Для получения изменений и новых данных добавьте в cron следующую запись:
```
*/5 * * * * /usr/bin/php /path/to/opencart/system/cron/history.php >> /path/to/opencart/system/storage/logs/cronjob_history.log 2>&1
```
#### Настройка экспорта каталога
Для периодической выгрузки каталога добавьте в cron следующую запись:
```
* */4 * * * /usr/bin/php /path/to/opencart/system/cron/icml.php >> /path/to/opencart/system/storage/logs/cronjob_icml.log 2>&1
```
В настройках CRM установите путь к файлу выгрузки
```
http://youropencartsite.com/retailcrm.xml
```
#### Настройка выгрузки акционных цен
Для периодической выгрузки акционных цен в CRM в настройках модуля укажите тип цены, в который необходимо выгружать акционные цены, в крон добавьте следующую запись
```
0 0 * * * /usr/bin/php /path/to/opencart/system/cron/prices.php >> /path/to/opencart/system/storage/logs/cronjob_prices.log 2>&1
```
#### Выгрузка существующих заказов и покупателей
Запустите команду единожды:
/usr/bin/php /path/to/opencart/system/cron/export.php
#### Кастомизация моделей
Для создания кастомных классов скопируйте файл модели в директорию custom, в новом файле измените название класса с "ModelExtensionRetailcrmFilename" на "ModelExtensionRetailcrmCustomFilename", где "Filename" - название файла с заглавной буквы. После этого модуль будет использовать методы кастомного класса.

1
VERSION Normal file
View file

@ -0,0 +1 @@
4.1.19

View file

@ -1,80 +0,0 @@
<?php
// Heading Goes here:
$_['heading_title'] = 'RetailCRM';
$_['retailcrm_title'] = 'RetailCRM';
// Text
$_['text_module'] = 'Modules';
$_['text_success'] = 'Setting saved';
$_['text_notice'] = 'Warning! Timezone in CRM & your shop must be equal, you must setup it here:';
$_['retailcrm_base_settings'] = 'Connection settings';
$_['retailcrm_dict_settings'] = 'Dictionary settings';
$_['retailcrm_countries_settings'] = 'Trading zones setting';
$_['retailcrm_upload_order'] = 'Unload single order';
$_['daemon_collector'] = 'Daemon Collector';
$_['general_tab_text'] = 'General';
$_['references_tab_text'] = 'References';
$_['collector_tab_text'] = 'Daemon Collector';
$_['logs_tab_text'] = 'Logs';
$_['collector_custom_text'] = 'Custom form';
$_['custom_fields_tab_text'] = 'Custom fields';
$_['retailcrm_apiversion'] = 'API Version';
$_['retailcrm_url'] = 'RetailCRM URL';
$_['retailcrm_apikey'] = 'RetailCRM API Key';
$_['collector_site_key'] = 'Site key';
$_['special_price_settings'] = 'Settings specials';
$_['special_price'] = 'The type of price at which the share price will be unloaded';
$_['text_success_export'] = 'Orders and customers successfully unloaded';
$_['text_success_export_order'] = 'Order successfully unloaded';
$_['text_button_export'] = 'Unload all orders and customers';
$_['text_button_export_order'] = 'Unload order';
$_['text_button_catalog'] = 'Unload catalog';
$_['text_button_clear'] = 'Clear';
$_['text_success_catalog'] = 'Catalog successfully unloaded';
$_['text_error_order'] = 'Error! Order is not unloaded!';
$_['text_error_order_id'] = 'Error! Enter the correct order number!';
$_['text_collector_activity'] = 'Use Daemon Collector';
$_['text_custom_field_activity'] = 'Send custom fields';
$_['text_collector_form_capture']= 'Show capture form';
$_['text_collector_period'] = 'Form show period (in minutes)';
$_['text_label_promo'] = 'Text form title';
$_['text_label_send'] = 'Text button';
$_['field_name'] = 'Name';
$_['field_email'] = 'Email';
$_['field_phone'] = 'Phone';
$_['text_require'] = 'Require';
$_['text_payment'] = 'Payment';
$_['text_shipping'] = 'Shipping';
$_['text_orders_custom_fields'] = 'Orders custom fields';
$_['text_customers_custom_fields'] = 'Customers custom fields';
$_['text_error_collector_fields']= 'Fill in the field names Daemon Collector';
$_['text_error_api'] = 'The selected version of the API is unavailable';
$_['text_error_custom_field'] = 'Create custom fields for customer in Opencart and RetailCRM, that to configure their transmission';
$_['text_error_cf_opencart'] = 'None custom fields in Opencart';
$_['text_error_cf_retailcrm'] = 'None custom fields in RetailCRM';
$_['text_error_save'] = 'Error saving settings';
$_['text_error_log'] = 'Log size more than 2MB';
$_['text_error_delivery'] = 'Not found delivery methods';
$_['text_confirm_log'] = 'Are you sure you want to clear the log?';
$_['retailcrm_dict_delivery'] = 'Shipment methods';
$_['retailcrm_dict_status'] = 'Order statuses';
$_['retailcrm_dict_payment'] = 'Payment methods';
$_['retailcrm_dict_custom_fields'] = 'Configure custom fields';
$_['retailcrm_dict_default'] = 'Default';
$_['retailcrm_missing_status'] = 'Missing orders status';
$_['column_total'] = 'Total';
$_['product_summ'] = 'Amount';
$_['article'] = 'SKU';
$_['color'] = 'Color';
$_['weight'] = 'Weight';
$_['size'] = 'Size';
$_['text_yes'] = 'Yes';
$_['text_no'] = 'No';
// Errors
$_['error_permission'] = 'Warning! You do not have permission to modify module';

View file

@ -1,112 +0,0 @@
<?php
class ModelExtensionRetailcrmCustomer extends Model {
protected $settings;
protected $moduleTitle;
protected $retailcrmApiClient;
public function __construct($registry)
{
parent::__construct($registry);
$this->load->model('setting/setting');
$this->load->library('retailcrm/retailcrm');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
$this->retailcrmApiClient = $this->retailcrm->getApiClient();
}
/**
* Upload customers
*
* @param array $customers
*
* @return void
*/
public function uploadToCrm($customers)
{
if ($this->retailcrmApiClient === false || empty($customers)) {
return;
}
$customersToCrm = array();
foreach($customers as $customer) {
$customersToCrm[] = $this->process($customer);
}
$chunkedCustomers = array_chunk($customersToCrm, 50);
foreach($chunkedCustomers as $customersPart) {
$this->retailcrmApiClient->customersUpload($customersPart);
}
}
/**
* Edit customer
*
* @param array $customer
*
* @return void
*/
public function changeInCrm($customer)
{
if ($this->retailcrmApiClient === false || empty($customer)) {
return;
}
$customerToCrm = $this->process($customer);
$this->retailcrmApiClient->customersEdit($customerToCrm);
}
/**
* Process customer
*
* @param array $customer
*
* @return array $customerToCrm
*/
private function process($customer)
{
$customerToCrm = array(
'externalId' => $customer['customer_id'],
'firstName' => $customer['firstname'],
'lastName' => $customer['lastname'],
'email' => $customer['email'],
'phones' => array(
array(
'number' => $customer['telephone']
)
),
'createdAt' => $customer['date_added']
);
if (isset($customer['address'])) {
$customerToCrm['address'] = array(
'index' => $customer['address']['postcode'],
'countryIso' => $customer['address']['iso_code_2'],
'region' => $customer['address']['zone'],
'city' => $customer['address']['city'],
'text' => $customer['address']['address_1'] . ' ' . $customer['address']['address_2']
);
}
if (isset($this->settings[$this->moduleTitle . '_custom_field']) && $customer['custom_field']) {
$customFields = json_decode($customer['custom_field']);
foreach ($customFields as $key => $value) {
if (isset($this->settings[$this->moduleTitle . '_custom_field']['c_' . $key])) {
$customFieldsToCrm[$this->settings[$this->moduleTitle . '_custom_field']['c_' . $key]] = $value;
}
}
if (isset($customFieldsToCrm)) {
$customerToCrm['customFields'] = $customFieldsToCrm;
}
}
return $customerToCrm;
}
}

View file

@ -1,122 +0,0 @@
<?php
require_once 'v4_5.php';
class ModelExtensionRetailcrmHistoryV3 extends ModelExtensionRetailcrmHistoryV45
{
protected $createResult;
private $opencartApiClient;
/**
* Getting changes from RetailCRM
*
* @return boolean
*/
public function request()
{
$moduleTitle = $this->retailcrm->getModuleTitle();
$this->load->model('setting/setting');
$this->load->model('setting/store');
$this->load->model('user/api');
$this->load->model('sale/order');
$this->load->model('customer/customer');
$this->load->model('extension/retailcrm/references');
$this->load->model('catalog/product');
$this->load->model('catalog/option');
$this->load->model('localisation/zone');
$this->load->language('extension/module/retailcrm');
$settings = $this->model_setting_setting->getSetting($moduleTitle);
$history = $this->model_setting_setting->getSetting('retailcrm_history');
$settings['domain'] = parse_url(HTTP_SERVER, PHP_URL_HOST);
$url = isset($settings[$moduleTitle . '_url']) ? $settings[$moduleTitle . '_url'] : null;
$key = isset($settings[$moduleTitle . '_apikey']) ? $settings[$moduleTitle . '_apikey'] : null;
if (empty($url) || empty($key)) {
$this->log->addNotice('You need to configure retailcrm module first.');
return false;
}
$crm = new RetailcrmProxy(
$settings[$moduleTitle . '_url'],
$settings[$moduleTitle . '_apikey'],
DIR_SYSTEM . 'storage/logs/retailcrm.log',
$settings[$moduleTitle . '_apiversion']
);
$lastRun = !empty($history['retailcrm_history_datetime'])
? new DateTime($history['retailcrm_history_datetime'])
: new DateTime(date('Y-m-d H:i:s', strtotime('-1 days', strtotime(date('Y-m-d H:i:s')))));
$packsOrders = $crm->ordersHistory($lastRun);
if(!$packsOrders->isSuccessful() && count($packsOrders['orders']) <= 0) {
return false;
}
$generatedAt = $packsOrders['generatedAt'];
$this->totalTitle = $this->totalTitles();
$this->subtotalSettings = $this->model_setting_setting->getSetting($this->totalTitle . 'sub_total');
$this->totalSettings = $this->model_setting_setting->getSetting($this->totalTitle . 'total');
$this->shippingSettings = $this->model_setting_setting->getSetting($this->totalTitle . 'shipping');
$this->delivery = array_flip($settings[$moduleTitle . '_delivery']);
$this->payment = array_flip($settings[$moduleTitle . '_payment']);
$this->status = array_flip($settings[$moduleTitle . '_status']);
$this->payment_default = $settings[$moduleTitle . '_default_payment'];
$this->delivery_default = $settings[$moduleTitle . '_default_shipping'];
$this->ocPayment = $this->model_extension_retailcrm_references
->getOpercartPaymentTypes();
$this->ocDelivery = $this->model_extension_retailcrm_references
->getOpercartDeliveryTypes();
$this->zones = $this->model_localisation_zone->getZones();
$updatedOrders = array();
$newOrders = array();
$orders = $packsOrders['orders'];
foreach ($orders as $order) {
if (isset($order['deleted'])) {
continue;
}
if (isset($order['externalId'])) {
$updatedOrders[] = $order['id'];
} else {
$newOrders[] = $order['id'];
}
}
unset($orders);
if (!empty($newOrders)) {
$orders = $crm->ordersList($filter = array('ids' => $newOrders));
if ($orders) {
$this->createResult = $this->createOrders($orders['orders']);
}
}
if (!empty($updatedOrders)) {
$orders = $crm->ordersList($filter = array('ids' => $updatedOrders));
if ($orders) {
$this->updateOrders($orders['orders']);
}
}
$this->model_setting_setting->editSetting('retailcrm_history', array('retailcrm_history_datetime' => $generatedAt));
if (!empty($this->createResult['customers'])) {
$crm->customersFixExternalIds($this->createResult['customers']);
}
if (!empty($this->createResult['orders'])) {
$crm->ordersFixExternalIds($this->createResult['orders']);
}
}
}

View file

@ -1,830 +0,0 @@
<?php
require_once __DIR__ . '/../history.php';
class ModelExtensionRetailcrmHistoryV45 extends ModelExtensionRetailcrmHistory
{
protected $createResult;
protected $settings;
protected $moduleTitle;
private $opencartApiClient;
private $customFieldSetting;
public function __construct($registry)
{
parent::__construct($registry);
$this->load->library('retailcrm/retailcrm');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->opencartApiClient = $this->retailcrm->getOcApiClient($registry);
}
/**
* Getting changes from RetailCRM
*
* @return boolean
*/
public function request()
{
$this->load->library('retailcrm/retailcrm');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->load->model('setting/setting');
$this->load->model('setting/store');
$this->load->model('user/api');
$this->load->model('sale/order');
$this->load->model('customer/customer');
$this->load->model('extension/retailcrm/references');
$this->load->model('catalog/product');
$this->load->model('catalog/option');
$this->load->model('localisation/zone');
$this->load->language('extension/module/retailcrm');
$settings = $this->model_setting_setting->getSetting($this->moduleTitle);
$history = $this->model_setting_setting->getSetting('retailcrm_history');
$settings['domain'] = parse_url(HTTP_SERVER, PHP_URL_HOST);
$url = isset($settings[$this->moduleTitle . '_url']) ? $settings[$this->moduleTitle . '_url'] : null;
$key = isset($settings[$this->moduleTitle . '_apikey']) ? $settings[$this->moduleTitle . '_apikey'] : null;
if (empty($url) || empty($key)) {
$this->log->addNotice('You need to configure retailcrm module first.');
return false;
}
$this->opencartApiClient = new OpencartApiClient($this->registry);
$crm = new RetailcrmProxy(
$settings[$this->moduleTitle . '_url'],
$settings[$this->moduleTitle . '_apikey'],
DIR_SYSTEM . 'storage/logs/retailcrm.log',
$settings[$this->moduleTitle . '_apiversion']
);
$sinceIdOrders = $history['retailcrm_history_orders'] ? $history['retailcrm_history_orders'] : null;
$sinceIdCustomers = $history['retailcrm_history_customers'] ? $history['retailcrm_history_customers'] : null;
$packsOrders = $crm->ordersHistory(array(
'sinceId' => $sinceIdOrders ? $sinceIdOrders : 0
), 1, 100);
$packsCustomers = $crm->customersHistory(array(
'sinceId' => $sinceIdCustomers ? $sinceIdCustomers : 0
), 1, 100);
if(!$packsOrders->isSuccessful() && count($packsOrders->history) <= 0 && !$packsCustomers->isSuccessful() && count($packsCustomers->history) <= 0) {
return false;
}
$generatedAt = $packsOrders['generatedAt'];
$orders = RetailcrmHistoryHelper::assemblyOrder($packsOrders->history);
$customers = RetailcrmHistoryHelper::assemblyCustomer($packsCustomers->history);
$ordersHistory = $packsOrders->history;
$customersHistory = $packsCustomers->history;
$lastChangeOrders = $ordersHistory ? end($ordersHistory) : null;
$lastChangeCustomers = $customersHistory ? end($customersHistory) : null;
if ($lastChangeOrders !== null) {
$sinceIdOrders = $lastChangeOrders['id'];
}
if ($lastChangeCustomers !== null) {
$sinceIdCustomers = $lastChangeCustomers['id'];
}
$this->settings = $settings;
$this->totalTitle = $this->totalTitles();
$this->subtotalSettings = $this->model_setting_setting->getSetting($this->totalTitle . 'sub_total');
$this->totalSettings = $this->model_setting_setting->getSetting($this->totalTitle . 'total');
$this->shippingSettings = $this->model_setting_setting->getSetting($this->totalTitle . 'shipping');
$this->delivery = array_flip($settings[$this->moduleTitle . '_delivery']);
$this->payment = array_flip($settings[$this->moduleTitle . '_payment']);
$this->status = array_flip($settings[$this->moduleTitle . '_status']);
$this->delivery_default = $settings[$this->moduleTitle . '_default_shipping'];
$this->payment_default = $settings[$this->moduleTitle . '_default_payment'];
$this->ocPayment = $this->model_extension_retailcrm_references
->getOpercartPaymentTypes();
$this->ocDelivery = $this->model_extension_retailcrm_references
->getOpercartDeliveryTypes();
$this->zones = $this->model_localisation_zone->getZones();
if (isset($settings[$this->moduleTitle . '_custom_field'])) {
$this->customFieldSetting = array_flip($settings[$this->moduleTitle . '_custom_field']);
}
$updatedOrders = array();
$newOrders = array();
foreach ($orders as $order) {
if (isset($order['deleted'])) {
continue;
}
if (isset($order['externalId'])) {
$updatedOrders[] = $order['id'];
} else {
$newOrders[] = $order['id'];
}
}
unset($orders);
$updateCustomers = array();
foreach ($customers as $customer) {
if (isset($customer['deleted'])) {
continue;
}
if (isset($customer['externalId'])) {
$updateCustomers[] = $customer['id'];
}
}
unset($customers);
if (!empty($updateCustomers)) {
$customers = $crm->customersList($filter = array('ids' => $updateCustomers));
if ($customers) {
$this->updateCustomers($customers['customers']);
}
}
if (!empty($newOrders)) {
$orders = $crm->ordersList($filter = array('ids' => $newOrders));
if ($orders) {
$this->createResult = $this->createOrders($orders['orders']);
}
}
if (!empty($updatedOrders)) {
$orders = $crm->ordersList($filter = array('ids' => $updatedOrders));
if ($orders) {
$this->updateOrders($orders['orders']);
}
}
$this->model_setting_setting->editSetting(
'retailcrm_history',
array(
'retailcrm_history_orders' => $sinceIdOrders,
'retailcrm_history_customers' => $sinceIdCustomers,
'retailcrm_history_datetime' => $generatedAt
)
);
if (!empty($this->createResult['customers'])) {
$crm->customersFixExternalIds($this->createResult['customers']);
}
if (!empty($this->createResult['orders'])) {
$crm->ordersFixExternalIds($this->createResult['orders']);
}
}
/**
* Update orders from history
*
* @param array $orders
*
* @return void
*/
protected function updateOrders($orders)
{
foreach ($orders as $order) {
$ocOrder = $this->model_sale_order->getOrder($order['externalId']);
if (isset($order['payments']) && $order['payments']) {
foreach ($order['payments'] as $orderPayment) {
if (isset($orderPayment['externalId'])) {
$payment = $orderPayment;
}
}
if (!isset($payment) && count($order['payments']) == 1) {
$payment = end($order['payments']);
}
} elseif (isset($order['paymentType'])) {
$payment['type'] = $order['paymentType'];
}
$data = array();
$mail = isset($order['email']) ? $order['email'] : $order['customer']['email'];
$phone = isset($order['phone']) ? $order['phone'] : '';
if (!$phone) {
$data['telephone'] = $order['customer']['phones'] ? $order['customer']['phones'][0]['number'] : '80000000000';
} else {
$data['telephone'] = $phone;
}
if (isset($order['customer']['externalId']) && $order['customer']['externalId']) {
$customer = $this->model_customer_customer->getCustomer($order['customer']['externalId']);
}
$data['customer'] = $order['firstName'];
$data['customer_id'] = (isset($customer)) ? $customer['customer_id'] : 0;
$data['customer_group_id'] = (isset($customer)) ? $customer['customer_group_id'] : 1;
$data['firstname'] = $order['firstName'];
$data['lastname'] = isset($order['lastName']) ? $order['lastName'] : $order['firstName'];
$data['email'] = $mail ? $mail : uniqid() . '@retailrcm.ru';
$data['comment'] = !empty($order['customerComment']) ? $order['customerComment'] : '';
$data['payment_address'] = '0';
$data['payment_firstname'] = $order['firstName'];
$data['payment_lastname'] = isset($order['lastName']) ? $order['lastName'] : $order['firstName'];
$data['payment_address_1'] = isset($order['customer']['address']) ? $order['customer']['address']['text'] : '';
$data['payment_address_2'] = '';
$data['payment_city'] = !empty($order['customer']['address']['city']) ? $order['customer']['address']['city'] : $order['delivery']['address']['city'];
$data['payment_postcode'] = !empty( $order['customer']['address']['index'] ) ? $order['customer']['address']['index'] : $order['delivery']['address']['index'];
$shippingZone = '';
if (is_int($order['delivery']['address']['region'])) {
$shippingZone = $order['delivery']['address']['region'];
} else {
$shippingZone = $this->getZoneByName($order['delivery']['address']['region']);
if ($shippingZone) {
$shipping_zone_id = $shippingZone['zone_id'];
} else {
$shipping_zone_id = 0;
}
}
if (isset($order['customer']['address']['region'])) {
$paymentZone = $this->getZoneByName($order['customer']['address']['region']);
if ($paymentZone) {
$payment_zone_id = $paymentZone['zone_id'];
} else {
$payment_zone_id = 0;
}
}
if (isset($order['countryIso']) && !empty($order['countryIso'])) {
$shippingCountry = $this->getCountryByIsoCode($order['countryIso']);
}
if (isset($order['customer']['address']['countryIso']) && !empty($order['customer']['address']['countryIso'])) {
$paymentCountry = $this->getCountryByIsoCode($order['customer']['address']['countryIso']);
} else {
$paymentCountry = $this->getCountryByIsoCode($order['countryIso']);
}
$delivery = isset($order['delivery']['code']) ? $order['delivery']['code'] : null;
$data['payment_country_id'] = $paymentCountry ? $paymentCountry['country_id'] : $ocOrder['payment_country_id'];
$data['payment_country'] = isset($paymentCountry) ? $paymentCountry['name'] : $ocOrder['payment_country'];
$data['payment_zone_id'] = $payment_zone_id ? $payment_zone_id : $ocOrder['payment_zone_id'];
$data['payment_zone'] = isset($order['customer']['address']['region']) ? $order['customer']['address']['region'] : $ocOrder['payment_zone'];
$data['shipping_country_id'] = isset($shippingCountry) ? $shippingCountry['country_id'] : $ocOrder['shipping_country_id'];
$data['shipping_country'] = isset($shippingCountry) ? $shippingCountry['name'] : $ocOrder['shipping_country'];
$data['shipping_zone_id'] = $shipping_zone_id ? $shipping_zone_id : $ocOrder['shipping_zone_id'];
$data['shipping_zone'] = $shippingZone ? $shippingZone['name'] : $ocOrder['shipping_zone'];
$data['shipping_address'] = '0';
$data['shipping_firstname'] = $order['firstName'];
$data['shipping_lastname'] = isset($order['lastName']) ? $order['lastName'] : $order['firstName'];
$data['shipping_address_1'] = $order['delivery']['address']['text'];
$data['shipping_address_2'] = '';
$data['shipping_company'] = '';
$data['shipping_company_id'] = '';
$data['shipping_city'] = $order['delivery']['address']['city'];
$data['shipping_postcode'] = $order['delivery']['address']['index'];
if ($delivery !== null) {
if (isset($this->settings[$this->moduleTitle . '_delivery'][$ocOrder['shipping_code']])
&& isset($this->delivery[$delivery])
) {
$data['shipping'] = $this->delivery[$delivery];
$shipping = explode('.', $data['shipping']);
$shippingModule = $shipping[0];
if (isset($this->ocDelivery[$shippingModule][$data['shipping']]['title'])) {
$data['shipping_method'] = $this->ocDelivery[$shippingModule][$data['shipping']]['title'];
} else {
$data['shipping_method'] = $this->ocDelivery[$shippingModule]['title'];
}
$data['shipping_code'] = $data['shipping'];
} elseif (!isset($this->settings[$this->moduleTitle . '_delivery'][$ocOrder['shipping_code']])
) {
$data['shipping_method'] = $ocOrder['shipping_method'];
$data['shipping_code'] = $ocOrder['shipping_code'];
}
} else {
if (!isset($this->settings[$ocOrder['shipping_code']])
|| !isset($this->delivery[$delivery])
) {
$data['shipping_method'] = $ocOrder['shipping_method'];
$data['shipping_code'] = $ocOrder['shipping_code'];
}
}
if (isset($payment)) {
$data['payment'] = $this->payment[$payment['type']];
$data['payment_method'] = isset($this->ocPayment[$data['payment']]) ? $this->ocPayment[$data['payment']] : $ocOrder['payment_method'];
$data['payment_code'] = isset($this->payment[$payment['type']]) ? $this->payment[$payment['type']] : $ocOrder['payment_code'];
} else {
$data['payment_method'] = $ocOrder['payment_method'];
$data['payment_code'] = $ocOrder['payment_code'];
}
// this data will not retrive from crm for now
$data['tax'] = '';
$data['tax_id'] = '';
$data['product'] = '';
$data['product_id'] = '';
$data['reward'] = '';
$data['affiliate'] = '';
$data['affiliate_id'] = '';
$data['payment_tax_id'] = '';
$data['order_product_id'] = '';
$data['payment_company'] = '';
$data['payment_company_id'] = '';
$data['company'] = '';
$data['company_id'] = '';
$data['order_product'] = array();
$discount = false;
foreach ($order['items'] as $item) {
$productId = $item['offer']['externalId'];
$options = array();
if (isset($item['discountTotal']) && $item['discountTotal'] > 0) {
$discount = true;
}
if (mb_strpos($item['offer']['externalId'], '#') > 1) {
$offer = explode('#', $item['offer']['externalId']);
$productId = $offer[0];
$optionsFromCRM = explode('_', $offer[1]);
foreach ($optionsFromCRM as $optionFromCRM) {
$optionData = explode('-', $optionFromCRM);
$productOptionId = $optionData[0];
$optionValueId = $optionData[1];
$productOptions = $this->model_catalog_product->getProductOptions($productId);
foreach($productOptions as $productOption) {
if($productOptionId == $productOption['product_option_id']) {
foreach($productOption['product_option_value'] as $productOptionValue) {
if($productOptionValue['option_value_id'] == $optionValueId) {
$options[] = array(
'product_option_id' => $productOptionId,
'product_option_value_id' => $productOptionValue['product_option_value_id'],
'value' => $this->getOptionValue($productOptionValue['option_value_id'], 'name'),
'type' => $productOption['type'],
'name' => $productOption['name'],
);
}
}
}
}
}
}
$product = $this->model_catalog_product->getProduct($productId);
$data['order_product'][] = array(
'name' => $product['name'],
'model' => $product['model'],
'price' => $item['initialPrice'],
'total' => (float)($item['initialPrice'] * $item['quantity']),
'product_id' => $productId,
'quantity' => $item['quantity'],
'option' => $options
);
}
if (isset($this->customFieldSetting) && $order['customFields']) {
foreach ($order['customFields'] as $code => $value) {
if (array_key_exists($code, $this->customFieldSetting)) {
$fieldCode = str_replace('o_', '', $this->customFieldSetting[$code]);
$customFields[$fieldCode] = $value;
}
}
$data['custom_field'] = isset($customFields) ? $customFields : '';
} else {
$data['custom_field'] = $ocOrder['custom_field'];
}
$deliveryCost = !empty($order['delivery']['cost']) ? $order['delivery']['cost'] : 0;
$data['total'] = $order['totalSumm'];
$data['order_total'] = array(
array(
'order_total_id' => '',
'code' => 'sub_total',
'title' => $this->language->get('product_summ'),
'value' => $order['summ'],
'text' => $order['summ'],
'sort_order' => $this->subtotalSettings['sub_total_sort_order']
),
array(
'order_total_id' => '',
'code' => 'shipping',
'title' => $data['shipping_method'],
'value' => $deliveryCost,
'text' => $deliveryCost,
'sort_order' => $this->shippingSettings[$this->totalTitle . 'shipping_sort_order']
),
array(
'order_total_id' => '',
'code' => 'total',
'title' => $this->language->get('column_total'),
'value' => isset($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost,
'text' => isset($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost,
'sort_order' => $this->totalSettings[$this->totalTitle . 'total_sort_order']
)
);
if ((isset($order['discount'])
&& $order['discount'] > 0)
|| $discount
) {
$orderTotals = $this->model_sale_order->getOrderTotals($order['externalId']);
foreach ($orderTotals as $orderTotal) {
if ($orderTotal['code'] == 'coupon'
|| $orderTotal['code'] == 'reward'
) {
$data['order_total'][] = $orderTotal;
}
}
}
$data['fromApi'] = true;
if (array_key_exists($order['status'], $this->status)) {
$data['order_status_id'] = $this->status[$order['status']];
} else {
$tmpOrder = $this->model_sale_order->getOrder($order['externalId']);
$data['order_status_id'] = $tmpOrder['order_status_id'];
}
$this->editOrder($order['externalId'], $data);
$this->opencartApiClient->addHistory($order['externalId'], $data['order_status_id']);
}
}
/**
* Create orders from history
*
* @param array $orders
*
* @return array
*/
protected function createOrders($orders)
{
$customersIdsFix = array();
$ordersIdsFix = array();
foreach ($orders as $order) {
$store = $this->config->get('config_store_id');
if (isset($order['payments']) && $order['payments']) {
$payment = end($order['payments']);
} elseif (isset($order['paymentType'])) {
$payment['type'] = $order['paymentType'];
}
$customer_id = (!empty($order['customer']['externalId']))
? $order['customer']['externalId']
: 0;
$data = array();
if ($customer_id == 0) {
if (isset($order['customer']['address']['countryIso'])) {
$customerCountry = $this->getCountryByIsoCode($order['customer']['address']['countryIso']);
} else {
$customerCountry = $this->getCountryByIsoCode($order['delivery']['address']['countryIso']);
}
if (isset($order['customer']['address']['region'])) {
$customerZone = $this->getZoneByName($order['customer']['address']['region']);
} else {
$customerZone = $this->getZoneByName($order['delivery']['address']['region']);
}
$cData = array(
'store_id' => 0,
'customer_group_id' => '1',
'firstname' => isset($order['patronymic']) ? $order['firstName'] . ' ' . $order['patronymic'] : $order['firstName'],
'lastname' => (!empty($order['customer']['lastName'])) ? $order['customer']['lastName'] : ' ',
'email' => $order['customer']['email'],
'telephone' => $order['customer']['phones'] ? $order['customer']['phones'][0]['number'] : ' ',
'fax' => '',
'newsletter' => 0,
'password' => 'tmppass',
'status' => 1,
'approved' => 1,
'safe' => 0,
'affiliate' => '',
'address' => array(
array(
'firstname' => isset($order['patronymic']) ? $order['firstName'] . ' ' . $order['patronymic'] : $order['firstName'],
'lastname' => (!empty($order['customer']['lastName'])) ? $order['customer']['lastName'] : ' ',
'address_1' => $order['customer']['address']['text'],
'address_2' => ' ',
'city' => !empty($order['customer']['address']['city']) ? $order['customer']['address']['city'] : $order['delivery']['address']['city'],
'postcode' => isset($order['customer']['address']['index']) ? $order['customer']['address']['index'] : $order['delivery']['address']['index'],
'tax_id' => '1',
'company' => '',
'company_id' => '',
'zone_id' => $customerZone ? $customerZone['zone_id'] : 0,
'country_id' => $customerCountry ? $customerCountry['country_id'] : 0,
'default' => '1'
)
),
);
$customer_id = $this->model_customer_customer->addCustomer($cData);
$customersIdsFix[] = array('id' => $order['customer']['id'], 'externalId' => (int)$customer_id);
}
$mail = isset($order['email']) ? $order['email'] : $order['customer']['email'];
$phone = isset($order['phone']) ? $order['phone'] : '';
if (!$phone) {
$data['telephone'] = $order['customer']['phones'] ? $order['customer']['phones'][0]['number'] : '80000000000';
} else {
$data['telephone'] = $phone;
}
$data['currency_code'] = $this->config->get('config_currency');
$data['currency_value'] = $this->getCurrencyByCode($data['currency_code'], 'value');
$data['currency_id'] = $this->getCurrencyByCode($data['currency_code'], 'currency_id');
$data['language_id'] = $this->getLanguageByCode($this->config->get('config_language'), 'language_id');
$data['store_id'] = $store == null ? 0 : $store;
$data['store_name'] = $this->config->get('config_name');
$data['customer'] = $order['firstName'];
$data['customer_id'] = $customer_id;
$data['customer_group_id'] = 1;
$data['firstname'] = $order['firstName'];
$data['lastname'] = (isset($order['lastName'])) ? $order['lastName'] : $order['firstName'];
$data['email'] = $mail ? $mail : uniqid() . '@retailrcm.ru';
$data['comment'] = !empty($order['customerComment']) ? $order['customerComment'] : '';
$data['fax'] = '';
$data['payment_address'] = '0';
$data['payment_firstname'] = $order['firstName'];
$data['payment_lastname'] = (isset($order['lastName'])) ? $order['lastName'] : $order['firstName'];
$data['payment_address_1'] = $order['customer']['address']['text'];
$data['payment_address_2'] = '';
$data['payment_company'] = '';
$data['payment_company_id'] = '';
$data['payment_city'] = !empty($order['customer']['address']['city']) ? $order['customer']['address']['city'] : $order['delivery']['address']['city'];
$data['payment_postcode'] = !empty($order['customer']['address']['index']) ? $order['customer']['address']['index'] : $order['delivery']['address']['index'];
$shippingZone = '';
if (!empty($order['delivery']['address']['region']) && is_int($order['delivery']['address']['region'])) {
$shippingZone = $order['delivery']['address']['region'];
} else {
$shippingZone = $this->getZoneByName($order['delivery']['address']['region']);
if ($shippingZone) {
$shipping_zone_id = $shippingZone['zone_id'];
} else {
$shipping_zone_id = 0;
}
}
if (isset($order['customer']['address']['region'])) {
$paymentZone = $this->getZoneByName($order['customer']['address']['region']);
if ($paymentZone) {
$payment_zone_id = $paymentZone['zone_id'];
} else {
$payment_zone_id = 0;
}
}
if (isset($order['countryIso'])) {
$shippingCountry = $this->getCountryByIsoCode($order['countryIso']);
}
if (isset($order['customer']['address']['countryIso'])) {
$paymentCountry = $this->getCountryByIsoCode($order['customer']['address']['countryIso']);
}
$delivery = isset($order['delivery']['code']) ? $order['delivery']['code'] : null;
$data['payment_country_id'] = $paymentCountry ? $paymentCountry['country_id'] : 0;
$data['payment_country'] = isset($paymentCountry) ? $paymentCountry['name'] : '';
$data['payment_zone_id'] = $payment_zone_id;
$data['payment_zone'] = isset($order['customer']['address']['region']) ? $order['customer']['address']['region'] : '';
$data['shipping_country_id'] = isset($shippingCountry) ? $shippingCountry['country_id'] : 0;
$data['shipping_country'] = isset($shippingCountry) ? $shippingCountry['name'] : '';
$data['shipping_zone_id'] = $shipping_zone_id;
$data['shipping_zone'] = $shippingZone ? $shippingZone['name'] : $data['payment_zone'];
$data['shipping_address'] = '0';
$data['shipping_firstname'] = $order['firstName'];
$data['shipping_lastname'] = (isset($order['lastName'])) ? $order['lastName'] : $order['firstName'];
$data['shipping_address_1'] = $order['delivery']['address']['text'];
$data['shipping_address_2'] = '';
$data['shipping_company'] = '';
$data['shipping_company_id'] = '';
$data['shipping_city'] = $order['delivery']['address']['city'];
$data['shipping_postcode'] = $order['delivery']['address']['index'];
$data['shipping'] = $delivery != null ? $this->delivery[$delivery] : $this->delivery_default;
$data['shipping_code'] = $delivery != null ? $this->delivery[$delivery] : $this->delivery_default;
$shipping = explode('.', $data['shipping']);
$shippingModule = $shipping[0];
if (isset($this->ocDelivery[$shippingModule][$data['shipping']]['title'])) {
$data['shipping_method'] = $this->ocDelivery[$shippingModule][$data['shipping']]['title'];
} else {
$data['shipping_method'] = $this->ocDelivery[$shippingModule]['title'];
}
if (isset($payment)) {
$data['payment'] = $this->payment[$payment['type']];
$data['payment_method'] = $this->ocPayment[$data['payment']];
$data['payment_code'] = $this->payment[$payment['type']];
} else {
$data['payment'] = $this->payment_default;
$data['payment_method'] = $this->ocPayment[$data['payment']];
$data['payment_code'] = $this->payment_default;
}
// this data will not retrive from crm for now
$data['tax'] = '';
$data['tax_id'] = '';
$data['product'] = '';
$data['product_id'] = '';
$data['reward'] = '';
$data['affiliate'] = '';
$data['affiliate_id'] = 0;
$data['payment_tax_id'] = '';
$data['order_product_id'] = '';
$data['payment_company'] = '';
$data['payment_company_id'] = '';
$data['company'] = '';
$data['company_id'] = '';
$data['order_product'] = array();
foreach ($order['items'] as $item) {
$productId = $item['offer']['externalId'];
$options = array();
if(mb_strpos($item['offer']['externalId'], '#') > 1) {
$offer = explode('#', $item['offer']['externalId']);
$productId = $offer[0];
$optionsFromCRM = explode('_', $offer[1]);
foreach ($optionsFromCRM as $optionFromCRM) {
$optionData = explode('-', $optionFromCRM);
$productOptionId = $optionData[0];
$optionValueId = $optionData[1];
$productOptions = $this->model_catalog_product->getProductOptions($productId);
foreach($productOptions as $productOption) {
if($productOptionId == $productOption['product_option_id']) {
foreach($productOption['product_option_value'] as $productOptionValue) {
if($productOptionValue['option_value_id'] == $optionValueId) {
$options[] = array(
'product_option_id' => $productOptionId,
'product_option_value_id' => $productOptionValue['product_option_value_id'],
'value' => $this->getOptionValue($productOptionValue['option_value_id'], 'name'),
'type' => $productOption['type'],
'name' => $productOption['name'],
);
}
}
}
}
}
}
$product = $this->model_catalog_product->getProduct($productId);
$data['order_product'][] = array(
'name' => $product['name'],
'model' => $product['model'],
'price' => $item['initialPrice'],
'total' => (float)($item['initialPrice'] * $item['quantity']),
'product_id' => $productId,
'quantity' => $item['quantity'],
'option' => $options
);
}
if (isset($this->customFieldSetting) && $order['customFields']) {
foreach ($order['customFields'] as $code => $value) {
if (array_key_exists($code, $this->customFieldSetting)) {
$fieldCode = str_replace('o_', '', $this->customFieldSetting[$code]);
$customFields[$fieldCode] = $value;
}
}
$data['custom_field'] = isset($customFields) ? $customFields : '';
}
$deliveryCost = !empty($order['delivery']['cost']) ? $order['delivery']['cost'] : 0;
$data['total'] = $order['totalSumm'];
$data['order_total'] = array(
array(
'order_total_id' => '',
'code' => 'sub_total',
'title' => $this->language->get('product_summ'),
'value' => $order['summ'],
'text' => $order['summ'],
'sort_order' => $this->subtotalSettings['sub_total_sort_order']
),
array(
'order_total_id' => '',
'code' => 'shipping',
'title' => $data['shipping_method'],
'value' => $deliveryCost,
'text' => $deliveryCost,
'sort_order' => $this->shippingSettings[$this->totalTitle . 'shipping_sort_order']
),
array(
'order_total_id' => '',
'code' => 'total',
'title' => $this->language->get('column_total'),
'value' => !empty($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost,
'text' => isset($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost,
'sort_order' => $this->totalSettings[$this->totalTitle . 'total_sort_order']
)
);
$data['fromApi'] = true;
$data['order_status_id'] = 1;
$order_id = $this->addOrder($data);
$ordersIdsFix[] = array('id' => $order['id'], 'externalId' => (int) $order_id);
}
return array('customers' => $customersIdsFix, 'orders' => $ordersIdsFix);
}
protected function updateCustomers($customers)
{
foreach ($customers as $customer) {
$customer_id = $customer['externalId'];
$customerData = $this->model_customer_customer->getCustomer($customer_id);
$customerData['password'] = false;
$customerData['firstname'] = $customer['firstName'];
$customerData['lastname'] = isset($customer['lastName']) ? $customer['lastName'] : '';
$customerData['email'] = $customer['email'];
$customerData['telephone'] = $customer['phones'] ? $customer['phones'][0]['number'] : '';
$customerAddress = $this->model_customer_customer->getAddress($customerData['address_id']);
if (isset($customer['address']['countryIso'])) {
$customerCountry = $this->getCountryByIsoCode($customer['address']['countryIso']);
}
if (isset($customer['address']['region'])) {
$customerZone = $this->getZoneByName($customer['address']['region']);
}
$customerAddress['firstname'] = isset($customer['patronymic']) ? $customer['firstName'] . ' ' . $customer['patronymic'] : $customer['firstName'];
$customerAddress['lastname'] = isset($customer['lastName']) ? $customer['lastName'] : '';
$customerAddress['address_1'] = $customer['address']['text'];
$customerAddress['city'] = $customer['address']['city'];
$customerAddress['postcode'] = isset($customer['address']['index']) ? $customer['address']['index'] : '';
if (isset($customerCountry)) {
$customerAddress['country_id'] = $customerCountry['country_id'];
}
if (isset($customerZone) && isset($customerZone['zone_id'])) {
$customerAddress['zone_id'] = $customerZone['zone_id'];
}
$customerData['address'] = array($customerAddress);
if (isset($this->customFieldSetting) && $customer['customFields']) {
foreach ($customer['customFields'] as $code => $value) {
if (array_key_exists($code, $this->customFieldSetting)) {
$fieldCode = str_replace('c_', '', $this->customFieldSetting[$code]);
$customFields[$fieldCode] = $value;
}
}
$customerData['custom_field'] = isset($customFields) ? $customFields : '';
}
$this->model_customer_customer->editCustomer($customer_id, $customerData);
}
}
}

View file

@ -1,296 +0,0 @@
<?php
class ModelExtensionRetailcrmOrder extends Model {
protected $settings;
protected $moduleTitle;
protected $retailcrmApiClient;
public function __construct($registry)
{
parent::__construct($registry);
$this->load->model('setting/setting');
$this->load->library('retailcrm/retailcrm');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
$this->retailcrmApiClient = $this->retailcrm->getApiClient();
}
/**
* Upload orders to CRM
*
* @param array $orders
*
* @return void
*/
public function uploadToCrm($orders)
{
if ($this->retailcrmApiClient === false) {
return;
}
$ordersToCrm = array();
foreach($orders as $order) {
$ordersToCrm[] = $this->process($order);
}
$chunkedOrders = array_chunk($ordersToCrm, 50);
foreach($chunkedOrders as $ordersPart) {
$this->retailcrmApiClient->ordersUpload($ordersPart);
}
}
/**
* Send one order by id
*
* @param array $order_data
*
* @return object $result
*/
public function uploadOrder($order_data)
{
if ($this->retailcrmApiClient === false) {
return;
}
if(isset($this->request->post['fromApi'])) {
return;
}
$customers = $this->retailcrmApiClient->customersList(
array(
'name' => $order_data['telephone'],
'email' => $order_data['email']
),
1,
100
);
$order = $this->process($order_data);
if ($customers) {
foreach ($customers['customers'] as $customer) {
$order['customer']['id'] = $customer['id'];
}
}
unset($customers);
$result = $this->retailcrmApiClient->ordersCreate($order);
if ($this->settings[$this->moduleTitle . '_apiversion'] == 'v5' && $result->isSuccessful()) {
$this->createPayment($order_data, $order_data['order_id']);
}
return $result;
}
/**
* Process order
*
* @param array $order_data
*
* @return array $order
*/
private function process($order_data) {
$order = array();
$this->load->model('catalog/product');
$payment_code = $order_data['payment_code'];
if (!empty($order_data['payment_code']) && isset($this->settings[$this->moduleTitle . '_payment'][$order_data['payment_code']])) {
$payment_code = $this->settings[$this->moduleTitle . '_payment'][$order_data['payment_code']];
} else {
$payment_code = '';
}
if (!empty($order_data['shipping_code'])) {
$shippingCode = explode('.', $order_data['shipping_code']);
$shippingModule = $shippingCode[0];
if (isset($this->settings[$this->moduleTitle . '_delivery'][$order_data['shipping_code']])) {
$delivery_code = $this->settings[$this->moduleTitle . '_delivery'][$order_data['shipping_code']];
} elseif (isset($this->settings[$this->moduleTitle . '_delivery'][$shippingModule])) {
$delivery_code = $this->settings[$this->moduleTitle . '_delivery'][$shippingModule];
}
}
$order['number'] = $order_data['order_id'];
$order['externalId'] = $order_data['order_id'];
$order['firstName'] = $order_data['firstname'];
$order['lastName'] = $order_data['lastname'];
$order['phone'] = $order_data['telephone'];
$order['customerComment'] = $order_data['comment'];
if(!empty($order_data['email'])) {
$order['email'] = $order_data['email'];
}
if ($order_data['customer_id']) {
$order['customer']['externalId'] = $order_data['customer_id'];
}
$deliveryCost = 0;
$orderTotals = isset($order_data['totals']) ? $order_data['totals'] : $order_data['order_total'] ;
foreach ($orderTotals as $totals) {
if ($totals['code'] == 'shipping') {
$deliveryCost = $totals['value'];
}
}
$order['createdAt'] = $order_data['date_added'];
if ($this->settings[$this->moduleTitle . '_apiversion'] != 'v5') {
$order['paymentType'] = $payment_code;
}
$country = (isset($order_data['shipping_country'])) ? $order_data['shipping_country'] : '' ;
$order['delivery'] = array(
'code' => $delivery_code,
'cost' => $deliveryCost,
'address' => array(
'index' => $order_data['shipping_postcode'],
'city' => $order_data['shipping_city'],
'country' => $order_data['shipping_country_id'],
'region' => $order_data['shipping_zone_id'],
'text' => implode(', ', array(
$order_data['shipping_postcode'],
$country,
$order_data['shipping_city'],
$order_data['shipping_address_1'],
$order_data['shipping_address_2']
))
)
);
$orderProducts = isset($order_data['products']) ? $order_data['products'] : $order_data['order_product'];
$offerOptions = array('select', 'radio');
foreach ($orderProducts as $product) {
$offerId = '';
if(!empty($product['option'])) {
$options = array();
$productOptions = $this->model_catalog_product->getProductOptions($product['product_id']);
foreach ($product['option'] as $option) {
if ($option['type'] == 'checkbox') {
$properties[] = array(
'code' => $option['product_option_value_id'],
'name' => $option['name'],
'value' => $option['value']
);
}
if(!in_array($option['type'], $offerOptions)) continue;
foreach($productOptions as $productOption) {
if($productOption['product_option_id'] = $option['product_option_id']) {
foreach($productOption['product_option_value'] as $productOptionValue) {
if($productOptionValue['product_option_value_id'] == $option['product_option_value_id']) {
$options[$option['product_option_id']] = $productOptionValue['option_value_id'];
}
}
}
}
}
ksort($options);
$offerId = array();
foreach($options as $optionKey => $optionValue) {
$offerId[] = $optionKey.'-'.$optionValue;
}
$offerId = implode('_', $offerId);
}
if ($this->settings[$this->moduleTitle . '_apiversion'] != 'v3') {
$item = array(
'offer' => array(
'externalId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id']
),
'productName' => $product['name'],
'initialPrice' => $product['price'],
'quantity' => $product['quantity'],
);
} else {
$item = array(
'productName' => $product['name'],
'initialPrice' => $product['price'],
'quantity' => $product['quantity'],
'productId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id']
);
}
if (isset($properties)) $item['properties'] = $properties;
$order['items'][] = $item;
}
if (isset($order_data['order_status_id']) && $order_data['order_status_id'] > 0) {
$order['status'] = $this->settings[$this->moduleTitle . '_status'][$order_data['order_status_id']];
}
if ($this->settings[$this->moduleTitle . '_apiversion'] == 'v5') {
if ($payment_code) {
$payment = array(
'externalId' => $order_data['order_id'],
'type' => $payment_code
);
$order['payments'][] = $payment;
}
}
if (isset($this->settings[$this->moduleTitle . '_custom_field']) && $order_data['custom_field']) {
$customFields = json_decode($order_data['custom_field']);
foreach ($customFields as $key => $value) {
if (isset($this->settings[$moduleTitle . '_custom_field']['o_' . $key])) {
$customFieldsToCrm[$this->settings[$this->moduleTitle . '_custom_field']['o_' . $key]] = $value;
}
}
if (isset($customFieldsToCrm)) {
$order['customFields'] = $customFieldsToCrm;
}
}
return $order;
}
/**
* Create payment
*
* @param array $order
* @param int $order_id
*
* @return void
*/
protected function createPayment($order, $order_id)
{
$payment_code = $order['payment_code'];
foreach ($order['totals'] as $total) {
if ($total['code'] == 'total') {
$amount = $total['value'];
}
}
$payment = array(
'externalId' => $order_id,
'type' => $this->settings[$this->moduleTitle . '_payment'][$payment_code],
'amount' => $amount
);
$payment['order'] = array(
'externalId' => $order_id
);
$this->retailcrmApiClient->ordersPaymentCreate($payment);
}
}

View file

@ -1,201 +0,0 @@
<?php
class ModelExtensionRetailcrmPrices extends Model
{
protected $retailcrmApiClient;
protected $settings;
protected $moduleTitle;
private $options;
private $optionValues;
/**
* Constructor
*
* @param Registry $registry
*/
public function __construct($registry)
{
parent::__construct($registry);
$this->load->library('retailcrm/retailcrm');
$this->load->model('catalog/option');
$this->load->model('setting/setting');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
$this->retailcrmApiClient = $this->retailcrm->getApiClient();
}
/**
* Upload prices to CRM
*
* @param array $products
*
* @return void
*/
public function uploadPrices($products)
{
$prices = $this->getPrices($products);
$pricesUpload = array_chunk($prices, 250);
foreach ($pricesUpload as $priceUpload) {
$this->retailcrmApiClient->storePricesUpload($priceUpload);
}
}
/**
* Get prices
*
* @param array $products
*
* @return array $prices
*/
protected function getPrices($products)
{
$prices = array();
$site = $this->getSite();
if (!isset($this->settings[$this->moduleTitle . '_special'])
|| $this->settings[$this->moduleTitle . '_apiversion'] == 'v3'
) {
return;
}
foreach ($products as $product) {
$specials = $this->model_catalog_product->getProductSpecials($product['product_id']);
if (!$specials) {
continue;
}
if (is_array($specials) && count($specials)) {
$productPrice = $this->getSpecialPrice($specials);
if (!$productPrice) {
continue;
}
}
$offers = $this->retailcrm->getOffers($product);
foreach ($offers as $optionsString => $optionsValues) {
$optionsString = explode('_', $optionsString);
$options = array();
foreach($optionsString as $optionString) {
$option = explode('-', $optionString);
$optionIds = explode(':', $option[0]);
if ($optionString != '0:0-0') {
$optionData = $this->getOptionData($optionIds[1], $option[1]);
$options[$optionIds[0]] = array(
'name' => $optionData['optionName'],
'value' => $optionData['optionValue'],
'value_id' => $option[1]
);
}
}
ksort($options);
$offerId = array();
foreach($options as $optionKey => $optionData) {
$offerId[] = $optionKey.'-'.$optionData['value_id'];
}
$offerId = implode('_', $offerId);
$prices[] = array(
'externalId' => $offerId ? $product['product_id'] . '#' . $offerId : $product['product_id'],
'site' => $site,
'prices' => array(
array(
'code' => $this->settings[$this->moduleTitle . '_special'],
'price' => $productPrice + $optionsValues['price']
)
)
);
}
}
return $prices;
}
/**
* Get actual special
*
* @param array $specials
*
* @return float $productPrice
*/
private function getSpecialPrice($specials)
{
$date = date('Y-m-d');
$always = '0000-00-00';
$productPrice = 0;
foreach ($specials as $special) {
if (($special['date_start'] == $always && $special['date_end'] == $always)
|| ($special['date_start'] <= $date && $special['date_end'] >= $date)
) {
if ((isset($priority) && $priority > $special['priority'])
|| !isset($priority)
) {
$productPrice = $special['price'];
$priority = $special['priority'];
}
}
}
return $productPrice;
}
/**
* Get data option
*
* @param int $optionId
* @param int $optionValueId
*
* @return array
*/
private function getOptionData($optionId, $optionValueId) {
if (!empty($this->options[$optionId])) {
$option = $this->options[$optionId];
} else {
$option = $this->model_catalog_option->getOption($optionId);
$this->options[$optionId] = $option;
}
if (!empty($this->optionValues[$optionValueId])) {
$optionValue = $this->optionValues[$optionValueId];
} else {
$optionValue = $this->model_catalog_option->getOptionValue($optionValueId);
$this->optionValues[$optionValueId] = $optionValue;
}
return array(
'optionName' => $option['name'],
'optionValue' => $optionValue['name']
);
}
/**
* Get site
*
* @return mixed boolean | string
*/
private function getSite()
{
$response = $this->retailcrmApiClient->sitesList();
if ($response && $response->isSuccessful()) {
$sites = $response->sites;
$site = end($sites);
return $site['code'];
}
return false;
}
}

View file

@ -1,460 +0,0 @@
<?php echo $header; ?>
<?php echo $column_left;?>
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<?php if ($export_file) : ?>
<button type="button" id="export" data-toggle="tooltip" title="<?php echo $text_button_export; ?>" class="btn btn-success"><i class="fa fa-download"></i></button>
<?php endif; ?>
<button type="button" id="icml" data-toggle="tooltip" title="<?php echo $text_button_catalog; ?>" class="btn btn-success"><i class="fa fa-file-text-o"></i></button>
<button type="submit" form="form-retailcrm" data-toggle="tooltip" title="<?php echo $button_save; ?>" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="<?php echo $cancel; ?>" data-toggle="tooltip" title="<?php echo $button_cancel; ?>" class="btn btn-default"><i class="fa fa-reply"></i></a></div>
<h1><?php echo $heading_title; ?></h1>
<ul class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a></li>
<?php } ?>
</ul>
</div>
</div>
<div class="container-fluid">
<?php if ($error_warning) : ?>
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?>
</div>
<?php endif; ?>
<?php if (isset($saved_settings['retailcrm_url'])): ?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_notice; ?>
<a href="<?php echo $saved_settings['retailcrm_url']; ?>/admin/settings#t-main"><?php echo $saved_settings['retailcrm_url']; ?>/admin/settings#t-main</a>
</div>
<?php endif; ?>
<div class="panel panel-default">
<div class="panel-body">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-retailcrm">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-general" data-toggle="tab"><?php echo $general_tab_text; ?></a></li>
<?php if (isset($saved_settings['retailcrm_apikey']) && $saved_settings['retailcrm_apikey'] != '' && isset($saved_settings['retailcrm_url']) && $saved_settings['retailcrm_url'] != ''): ?>
<li><a href="#tab-references" data-toggle="tab"><?php echo $references_tab_text; ?></a></li>
<li><a href="#tab-collector" data-toggle="tab"><?php echo $collector_tab_text; ?></a></li>
<?php if ($saved_settings['retailcrm_apiversion'] == 'v5') : ?>
<li><a href="#tab-custom_fields" data-toggle="tab"><?php echo $custom_fields_tab_text; ?></a></li>
<?php endif; ?>
<li><a href="#tab-logs" data-toggle="tab"><?php echo $logs_tab_text; ?></a></li>
<?php endif; ?>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-general">
<input type="hidden" name="retailcrm_status" value="1">
<h3><?php echo $retailcrm_base_settings; ?></h3>
<div class="retailcrm_unit">
<label for="retailcrm_url"><?php echo $retailcrm_apiversion; ?></label><br>
<select name="retailcrm_apiversion">
<?php foreach($api_versions as $version) : ?>
<option value="<?php echo $version; ?>" <?php if (isset($saved_settings['retailcrm_apiversion']) && $saved_settings['retailcrm_apiversion'] == $version) echo "selected='selected'"; elseif (!isset($saved_settings['retailcrm_apiversion']) && $default_apiversion == $version) echo "selected='selected'"; ?>><?php echo $version; ?></option>
<?php endforeach ?>
</select>
</div>
<div class="retailcrm_unit">
<label for="retailcrm_url"><?php echo $retailcrm_url; ?></label><br>
<input id="retailcrm_url" type="text" name="retailcrm_url" value="<?php if (isset($saved_settings['retailcrm_url'])): echo $saved_settings['retailcrm_url']; endif; ?>">
</div>
<div class="retailcrm_unit">
<label for="retailcrm_apikey"><?php echo $retailcrm_apikey; ?></label><br>
<input id="retailcrm_apikey" type="text" name="retailcrm_apikey" value="<?php if (isset($saved_settings['retailcrm_apikey'])): echo $saved_settings['retailcrm_apikey']; endif;?>">
</div>
<h3><?php echo $retailcrm_countries_settings; ?></h3>
<div class="retailcrm_unit">
<div class="well well-sm" style="height: 150px; overflow: auto; width: 30%;">
<?php foreach($countries as $country) : ?>
<div class="checkbox">
<label>
<input type="checkbox" name="<?php echo 'retailcrm_country[]'; ?>" value="<?php echo $country['country_id']; ?>" <?php if(isset($saved_settings['retailcrm_country']) && in_array($country['country_id'], $saved_settings['retailcrm_country'])): echo 'checked'; endif;?>>
<?php echo $country['name']; ?>
</label>
</div>
<?php endforeach; ?>
</div>
</div>
<?php if (isset($saved_settings['retailcrm_apikey']) && $saved_settings['retailcrm_apikey'] != '' && isset($saved_settings['retailcrm_url']) && $saved_settings['retailcrm_url'] != ''): ?>
<?php if (!empty($retailcrm_errors)) : ?>
<?php foreach($retailcrm_errors as $retailcrm_error): ?>
<div class="warning"><?php echo $retailcrm_error ?></div>
<?php endforeach; ?>
<?php else: ?>
<h3><?php echo $retailcrm_upload_order; ?></h3>
<div class="retailcrm_unit">
<label><?php echo $text_button_export_order; ?> № </label><input type="text" name="order_id">
<button type="button" id="export_order" data-toggle="tooltip" title="<?php echo $text_button_export_order; ?>" class="btn btn-success"><i class="fa fa-download"></i></button>
</div>
<?php if (isset($saved_settings['retailcrm_apiversion']) && $saved_settings['retailcrm_apiversion'] != 'v3') : ?>
<h3><?php echo $special_price_settings; ?></h3>
<div class="retailcrm_unit">
<label><?php echo $special_price_settings; ?></label>
<select id="retailcrm_special" name="retailcrm_special">
<?php foreach ($priceTypes as $priceType) :?>
<?php if ($priceType['active'] == true) :?>
<option value="<?php echo $priceType['code']; ?>" <?php if(isset($saved_settings['retailcrm_special']) && $saved_settings['retailcrm_special'] == $priceType['code']):?>selected="selected"<?php endif;?>>
<?php echo $priceType['name']; ?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
</div>
<div class="tab-pane" id="tab-references">
<h3><?php echo $retailcrm_dict_settings; ?></h3>
<h4><?php echo $retailcrm_dict_delivery; ?></h4>
<?php if ($delivery['opencart']) :?>
<?php foreach($delivery['opencart'] as $value): ?>
<div class="pm"><?php echo $value['title'].':'; ?></div>
<?php unset($value['title']); ?>
<?php foreach ($value as $key => $val): ?>
<div class="retailcrm_unit">
<select id="retailcrm_delivery_<?php echo $val['code']; ?>" name="retailcrm_delivery[<?php echo $val['code']; ?>]" >
<?php foreach ($delivery['retailcrm'] as $k => $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_delivery'][$key]) && $v['code'] == $saved_settings['retailcrm_delivery'][$key]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
<label for="retailcrm_pm_<?php echo $val['code']; ?>"><?php echo $val['title']; ?></label>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
<?php else :?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_error_delivery; ?>
</div>
<?php endif; ?>
<h4><?php echo $retailcrm_dict_status; ?></h4>
<?php foreach ($statuses['opencart'] as $status): ?>
<?php $uid = $status['order_status_id']?>
<div class="retailcrm_unit">
<select id="retailcrm_status_<?php echo $uid; ?>" name="retailcrm_status[<?php echo $uid; ?>]" >
<?php foreach ($statuses['retailcrm'] as $k => $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_status'][$uid]) && $v['code'] == $saved_settings['retailcrm_status'][$uid]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
<label for="retailcrm_status_<?php echo $status['order_status_id']; ?>"><?php echo $status['name']; ?></label>
</div>
<?php endforeach; ?>
<h4><?php echo $retailcrm_dict_payment; ?></h4>
<?php foreach ($payments['opencart'] as $key => $value): ?>
<div class="retailcrm_unit">
<select id="retailcrm_payment_<?php echo $key; ?>" name="retailcrm_payment[<?php echo $key; ?>]" >
<?php foreach ($payments['retailcrm'] as $k => $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_payment'][$key]) && $v['code'] == $saved_settings['retailcrm_payment'][$key]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
<label for="retailcrm_payment_<?php echo $key; ?>"><?php echo $value; ?></label>
</div>
<?php endforeach; ?>
<h4><?php echo $retailcrm_dict_default; ?></h4>
<div class="retailcrm_unit">
<select id="retailcrm_default_payment" name="retailcrm_default_payment" >
<?php foreach ($payments['opencart'] as $k => $v): ?>
<option value="<?php echo $k;?>" <?php if(isset($saved_settings['retailcrm_default_payment']) && $k == $saved_settings['retailcrm_default_payment']):?>selected="selected"<?php endif;?>>
<?php echo $v;?>
</option>
<?php endforeach; ?>
</select>
<label for="retailcrm_default_payment"><?php echo $text_payment; ?></label>
</div>
<div class="retailcrm_unit">
<select id="retailcrm_default_shipping" name="retailcrm_default_shipping" >
<?php foreach ($delivery['opencart'] as $key => $value): ?>
<optgroup label="<?php echo $value['title']; ?>">
<?php unset($value['title']); ?>
<?php foreach ($value as $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_default_shipping']) && $v['code'] == $saved_settings['retailcrm_default_shipping']):?>selected="selected"<?php endif;?>>
<?php echo $v['title'];?>
</option>
<?php endforeach; ?>
</optgroup>
<?php endforeach; ?>
</select>
<label for="retailcrm_default_payment"><?php echo $text_shipping; ?></label>
</div>
<h4><?php echo $retailcrm_missing_status; ?></h4>
<div class="retailcrm_unit">
<select id="retailcrm_missing_status" name="retailcrm_missing_status">
<option></option>
<?php foreach ($statuses['retailcrm'] as $k => $v): ?>
<option value="<?php echo $k;?>" <?php if(isset($saved_settings['retailcrm_missing_status']) && $k == $saved_settings['retailcrm_missing_status']):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<div class="tab-pane" id="tab-collector">
<h3><?php echo $daemon_collector; ?></h3>
<div class="retailcrm_unit">
<label for="retailcrm_collector_active" class="col-md-4"><?php echo $text_collector_activity; ?></label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector_active" value="1" <?php if (isset($saved_settings['retailcrm_collector_active']) &&
$saved_settings['retailcrm_collector_active'] == 1) :
echo 'checked'; endif; ?>>
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector_active" value="0" <?php if (!isset($saved_settings['retailcrm_collector_active']) ||
$saved_settings['retailcrm_collector_active'] == 0) :
echo 'checked'; endif; ?>>
<?php echo $text_no; ?>
</label>
</div>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4"><?php echo $collector_site_key; ?></label>
<input id="retailcrm_collector_site_key" type="text" name="retailcrm_collector[site_key]" value="<?php if (isset($saved_settings['retailcrm_collector']['site_key'])): echo $saved_settings['retailcrm_collector']['site_key']; endif; ?>">
</div>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4"><?php echo $text_collector_form_capture; ?></label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector[form_capture]" value="1" <?php if (isset($saved_settings['retailcrm_collector']['form_capture']) &&
$saved_settings['retailcrm_collector']['form_capture'] == 1) :
echo 'checked'; endif; ?>>
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector[form_capture]" value="0" <?php if (!isset($saved_settings['retailcrm_collector']['form_capture']) ||
$saved_settings['retailcrm_collector']['form_capture'] == 0) :
echo 'checked'; endif; ?>>
<?php echo $text_no; ?>
</label>
</div>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4"><?php echo $text_collector_period; ?></label>
<input id="retailcrm_collector_period" type="text" name="retailcrm_collector[period]" value="<?php if (isset($saved_settings['retailcrm_collector']['period'])): echo $saved_settings['retailcrm_collector']['period']; endif; ?>">
</div>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4"><?php echo $text_label_promo; ?></label>
<input id="retailcrm_collector[]" type="text" name="retailcrm_collector[label_promo]" value="<?php if (isset($saved_settings['retailcrm_collector']['label_promo'])): echo $saved_settings['retailcrm_collector']['label_promo']; endif; ?>">
</div>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4"><?php echo $text_label_send; ?></label>
<input id="retailcrm_collector_label_send" type="text" name="retailcrm_collector[label_send]" value="<?php if (isset($saved_settings['retailcrm_collector']['label_send'])): echo $saved_settings['retailcrm_collector']['label_send']; endif; ?>">
</div>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4"><?php echo $collector_custom_text; ?></label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector[custom_form]" value="1" <?php if (isset($saved_settings['retailcrm_collector']['custom_form']) &&
$saved_settings['retailcrm_collector']['custom_form'] == 1) :
echo 'checked'; endif; ?>>
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector[custom_form]" value="0" <?php if (!isset($saved_settings['retailcrm_collector']['custom_form']) ||
$saved_settings['retailcrm_collector']['custom_form'] == 0) :
echo 'checked'; endif; ?>>
<?php echo $text_no; ?>
</label>
</div>
<?php foreach ($collectorFields as $field => $label) : ?>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4"><?php echo $label; ?></label>
<div class="col-md-8">
<input id="retailcrm_collector" type="text" name="retailcrm_collector[custom][<?php echo $field; ?>]" value="<?php if (isset($saved_settings['retailcrm_collector']['custom'][$field])) : echo $saved_settings['retailcrm_collector']['custom'][$field]; endif; ?>">
<input type="checkbox" name="retailcrm_collector[require][<?php echo $field; ?>_require]" value="1" <?php if (isset($saved_settings['retailcrm_collector']['require'][$field.'_require'])) : echo 'checked'; endif;?>>
<label for="retailcrm_collector"><?php echo $text_require; ?></label>
</div>
</div>
<?php endforeach; ?>
</div>
<?php if (isset($saved_settings['retailcrm_apiversion']) && $saved_settings['retailcrm_apiversion'] == 'v5' && isset($customFields)) : ?>
<div class="tab-pane" id="tab-custom_fields">
<h3><?php echo $retailcrm_dict_custom_fields; ?></h3>
<?php if ($customFields['retailcrm'] && $customFields['opencart']) : ?>
<div class="retailcrm_unit">
<label for="retailcrm_custom_field_active"><?php echo $text_custom_field_activity; ?></label>
<label class="radio-inline">
<input type="radio" name="retailcrm_custom_field_active" value="1" <?php if (isset($saved_settings['retailcrm_custom_field_active']) &&
$saved_settings['retailcrm_custom_field_active'] == 1) :
echo 'checked'; endif; ?>>
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_custom_field_active" value="0" <?php if (!isset($saved_settings['retailcrm_custom_field_active']) ||
$saved_settings['retailcrm_custom_field_active'] == 0) :
echo 'checked'; endif; ?>>
<?php echo $text_no; ?>
</label>
</div>
<h4><?php echo $text_customers_custom_fields; ?></h4>
<?php foreach ($customFields['opencart'] as $customField) : ?>
<?php $fid = 'c_' . $customField['custom_field_id'] ?>
<div class="retailcrm_unit">
<select id="retailcrm_custom_field_<?php echo $fid; ?>" name="retailcrm_custom_field[<?php echo $fid; ?>]" >
<?php foreach ($customFields['retailcrm']['customers'] as $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_custom_field'][$fid]) && $v['code'] == $saved_settings['retailcrm_custom_field'][$fid]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
<label for="retailcrm_custom_field_<?php echo $fid; ?>"><?php echo $customField['name']; ?></label>
</div>
<?php endforeach; ?>
<h4><?php echo $text_orders_custom_fields; ?></h4>
<?php foreach ($customFields['opencart'] as $customField) : ?>
<?php $fid = 'o_' . $customField['custom_field_id'] ?>
<div class="retailcrm_unit">
<select id="retailcrm_custom_field_<?php echo $fid; ?>" name="retailcrm_custom_field[<?php echo $fid; ?>]" >
<?php foreach ($customFields['retailcrm']['orders'] as $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_custom_field'][$fid]) && $v['code'] == $saved_settings['retailcrm_custom_field'][$fid]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
<label for="retailcrm_custom_field_<?php echo $fid; ?>"><?php echo $customField['name']; ?></label>
</div>
<?php endforeach; ?>
<?php elseif (!$customFields['retailcrm'] && !$customFields['opencart']) : ?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_error_custom_field; ?>
</div>
<?php elseif (!$customFields['retailcrm']) : ?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_error_cf_retailcrm; ?>
</div>
<?php elseif (!$customFields['opencart']) : ?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_error_cf_opencart; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="tab-pane" id="tab-logs">
<div class="retailcrm_unit">
<span>Retailcrm API error log</span>
<a onclick="confirm('<?php echo $text_confirm_log; ?>') ? location.href='<?php echo $clear_retailcrm; ?>' : false;" data-toggle="tooltip" title="<?php echo $button_clear; ?>" class="btn btn-danger"><i class="fa fa-eraser"></i></a>
</div>
<?php if (isset($logs['retailcrm_log'])) : ?>
<div class="panel-body">
<textarea wrap="off" rows="15" readonly class="form-control"><?php echo $logs['retailcrm_log']; ?></textarea>
</div>
<?php elseif (isset($logs['retailcrm_error'])) : ?>
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> <?php echo $logs['retailcrm_error']; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php endif; ?>
<div class="retailcrm_unit">
<span>Opencart API error log</span>
<a onclick="confirm('<?php echo $text_confirm_log; ?>') ? location.href='<?php echo $clear_opencart; ?>' : false;" data-toggle="tooltip" title="<?php echo $button_clear; ?>" class="btn btn-danger"><i class="fa fa-eraser"></i></a>
</div>
<?php if (isset($logs['oc_api_log'])) : ?>
<div class="panel-body">
<textarea wrap="off" rows="15" readonly class="form-control"><?php echo $logs['oc_api_log']; ?></textarea>
</div>
<?php elseif (isset($logs['oc_error'])) : ?>
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> <?php echo $logs['oc_error']; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php endif; ?>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<?php echo $footer; ?>
<script type="text/javascript">
var token = '<?php echo $token; ?>';
$('#icml').on('click', function() {
$.ajax({
url: '<?php echo $catalog; ?>' + 'admin/index.php?route=extension/module/retailcrm/icml&token=' + token,
beforeSend: function() {
$('#icml').button('loading');
},
complete: function() {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i> <?php echo $text_success_catalog; ?></div>');
$('#icml').button('reset');
},
error: function(){
alert('error');
}
});
});
$('#export').on('click', function() {
$.ajax({
url: '<?php echo $catalog; ?>' + 'admin/index.php?route=extension/module/retailcrm/export&token=' + token,
beforeSend: function() {
$('#export').button('loading');
},
complete: function() {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i> <?php echo $text_success_export; ?></div>');
$('#export').button('reset');
},
error: function(){
alert('error');
}
});
});
$('#export_order').on('click', function() {
var order_id = $('input[name=\'order_id\']').val();
if (order_id && order_id > 0) {
$.ajax({
url: '<?php echo $catalog; ?>' + 'admin/index.php?route=extension/module/retailcrm/exportOrder&token=' + token + '&order_id=' + order_id,
beforeSend: function() {
$('#export_order').button('loading');
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
},
success: function(data, textStatus, jqXHR) {
response = JSON.parse(jqXHR['responseText']);
if (response['status_code'] == '400') {
$('.alert-danger').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i><?php echo $text_error_order; ?>' + response['error_msg'] + '</div>');
$('#export_order').button('reset');
} else {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i><?php echo $text_success_export_order; ?></div>');
$('#export_order').button('reset');
$('input[name=\'order_id\']').val('');
}
}
});
} else {
$('.alert-danger').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> <?php echo $text_error_order_id; ?></div>');
$('#export_order').button('reset');
}
});
</script>

View file

@ -1,456 +0,0 @@
{{ header }} {{ column_left }}
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
{% if export_file %}
<button type="button" id="export" data-toggle="tooltip" title="{{ text_button_export }}" class="btn btn-success"><i class="fa fa-download"></i></button>
{% endif %}
<button type="button" id="icml" data-toggle="tooltip" title="{{ text_button_catalog }}" class="btn btn-success"><i class="fa fa-file-text-o"></i></button>
<button type="submit" form="form-module" data-toggle="tooltip" title="{{ button_save }}" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="{{ cancel }}" data-toggle="tooltip" title="{{ button_cancel }}" class="btn btn-default"><i class="fa fa-reply"></i></a></div>
<h1>{{ heading_title }}</h1>
<ul class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="container-fluid">
{% if error_warning %}
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<i class="fa fa-exclamation-circle"></i> {{ error_warning }}
</div>
{% endif %}
{% if saved_settings.module_retailcrm_url is defined %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_notice }}
<a href="{{ saved_settings.module_retailcrm_url }}/admin/settings#t-main">{{ saved_settings.module_retailcrm_url }}/admin/settings#t-main</a>
</div>
{% endif %}
<div class="panel panel-default">
<div class="panel-body">
<form action="{{ action }}" method="post" enctype="multipart/form-data" id="form-module">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-general" data-toggle="tab">{{ general_tab_text }}</a></li>
{% if saved_settings.module_retailcrm_apikey is defined and saved_settings.module_retailcrm_apikey and saved_settings.module_retailcrm_url is defined and saved_settings.module_retailcrm_url %}
<li><a href="#tab-references" data-toggle="tab">{{ references_tab_text }}</a></li>
<li><a href="#tab-collector" data-toggle="tab">{{ collector_tab_text }}</a></li>
{% if saved_settings.module_retailcrm_apiversion == 'v5' %}
<li><a href="#tab-custom_fields" data-toggle="tab"> {{ custom_fields_tab_text }} </a></li>
{% endif %}
<li><a href="#tab-logs" data-toggle="tab">{{ logs_tab_text }}</a></li>
{% endif %}
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-general">
<input type="hidden" name="module_retailcrm_status" value="1">
<h3>{{ retailcrm_base_settings }}</h3>
<div class="retailcrm_unit">
<label for="retailcrm_url">{{ retailcrm_apiversion }}</label><br>
<select name="module_retailcrm_apiversion">
{% for version in api_versions %}
<option value="{{ version }}" {% if saved_settings.module_retailcrm_apiversion is defined and saved_settings.module_retailcrm_apiversion == version %} selected="selected" {% elseif saved_settings.module_retailcrm_apiversion is not defined and default_apiversion == version %} selected="selected" {% endif %}>{{ version }}</option>
{% endfor %}
</select>
</div>
<div class="retailcrm_unit">
<label for="retailcrm_url">{{ retailcrm_url }}</label><br>
<input id="retailcrm_url" type="text" name="module_retailcrm_url" value="{% if saved_settings.module_retailcrm_url is defined %}{{ saved_settings.module_retailcrm_url }}{% endif %}">
</div>
<div class="retailcrm_unit">
<label for="retailcrm_apikey">{{ retailcrm_apikey }}</label><br>
<input id="retailcrm_apikey" type="text" name="module_retailcrm_apikey" value="{% if saved_settings.module_retailcrm_apikey is defined %}{{ saved_settings.module_retailcrm_apikey }}{% endif %}">
</div>
<h3>{{ retailcrm_countries_settings }}</h3>
<div class="retailcrm_unit">
<div class="well well-sm" style="height: 150px; overflow: auto; width: 30%;">
{% for country in countries %}
<div class="checkbox">
<label>
<input type="checkbox" name="module_retailcrm_country[]" value="{{ country.country_id }}" {% if saved_settings.module_retailcrm_country is defined and country.country_id in saved_settings.module_retailcrm_country %} {{ 'checked' }} {% endif %}">
{{ country.name }}
</label>
</div>
{% endfor %}
</div>
</div>
{% if saved_settings.module_retailcrm_apikey is defined and saved_settings.module_retailcrm_apikey and saved_settings.module_retailcrm_url is defined and saved_settings.module_retailcrm_url %}
{% if retailcrm_errors|length %}
{% for retailcrm_error in retailcrm_errors %}
<div class="warning">{{ retailcrm_error }}</div>
{% endfor %}
{% else %}
<h3>{{ retailcrm_upload_order }}</h3>
<div class="retailcrm_unit">
<label>{{ text_button_export_order }} № </label><input type="text" name="order_id">
<button type="button" id="export_order" data-toggle="tooltip" title="{{ text_button_export_order }}" class="btn btn-success"><i class="fa fa-download"></i></button>
</div>
{% if saved_settings.retailcrm_apiversion is defined and saved_settings.retailcrm_apiversion != 'v3' %}
<h3>{{ special_price_settings }}</h3>
<div class="retailcrm_unit">
<label>{{ special_price_settings }}</label>
<select id="module_retailcrm_special" name="module_retailcrm_special">
{% for priceType in priceTypes %}
{% if priceType.active == true %}
<option value="{{priceType.code }}" {% if saved_settings.retailcrm_special is defined and saved_settings.retailcrm_special == priceType.code %} selected="selected" {% endif %}>
{{ priceType.name }}
</option>
{% endif %}
{% endfor %}
</select>
</div>
{% endif %}
</div>
<div class="tab-pane" id="tab-references">
<h3>{{ retailcrm_dict_settings }}</h3>
<h4>{{ retailcrm_dict_delivery }}</h4>
{% for value in delivery.opencart %}
<div class="pm">{{ value.title ~ ':' }}</div>
{% for key, val in value %}
{% if key != 'title' %}
<div class="retailcrm_unit">
<select id="retailcrm_delivery_{{ val.code }}" name="module_retailcrm_delivery[{{ val.code }}]" >
{% for k, v in delivery.retailcrm %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_delivery[key] is defined and v.code == saved_settings.module_retailcrm_delivery[key] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
<label for="retailcrm_pm_{{ val.code }}">{{ val.title }}</label>
</div>
{% endif %}
{% endfor %}
{% endfor %}
<h4>{{ retailcrm_dict_status }}</h4>
{% for status in statuses.opencart %}
{% set uid = status.order_status_id %}
<div class="retailcrm_unit">
<select id="retailcrm_status_{{ uid }}" name="module_retailcrm_status[{{ status.order_status_id }}]" >
{% for k, v in statuses.retailcrm %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_status[uid] is defined and v.code == saved_settings.module_retailcrm_status[uid] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
<label for="retailcrm_status_{{ status.order_status_id }} ">{{ status.name }}</label>
</div>
{% endfor %}
<h4>{{ retailcrm_dict_payment }}</h4>
{% for key, value in payments.opencart %}
<div class="retailcrm_unit">
<select id="retailcrm_payment_{{ key }}" name="module_retailcrm_payment[{{ key }}]" >
{% for k, v in payments.retailcrm %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_payment[key] is defined and v.code == saved_settings.module_retailcrm_payment[key] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
<label for="retailcrm_payment_{{ key }}">{{ value }}</label>
</div>
{% endfor %}
<h4>{{ retailcrm_dict_default }}</h4>
<div class="retailcrm_unit">
<select id="module_retailcrm_default_payment" name="module_retailcrm_default_payment" >
{% for k, v in payments.opencart %}
<option value="{{ k }}" {% if saved_settings.retailcrm_default_payment is defined and k == saved_settings.retailcrm_default_payment %} selected="selected" {% endif %}>
{{ v }}
</option>
{% endfor %}
</select>
<label for="module_retailcrm_default_payment">{{ text_payment }}</label>
</div>
<div class="retailcrm_unit">
<select id="module_retailcrm_default_shipping" name="module_retailcrm_default_shipping" >
{% for key, value in delivery.opencart %}
<optgroup label="{{ value.title }}">
{% for k, v in value %}
{% if k != 'title' %}
<option value="{{ v.code }}" {% if saved_settings.retailcrm_default_shipping is defined and v.code == saved_settings.retailcrm_default_shipping %} selected="selected" {% endif %}>
{{ v.title }}
</option>
{% endif %}
{% endfor %}
</optgroup>
{% endfor %}
</select>
<label for="module_retailcrm_default_shipping">{{ text_shipping }}</label>
</div>
<h4>{{ retailcrm_missing_status }}</h4>
<div class="retailcrm_unit">
<select id="retailcrm_missing_status" name="retailcrm_missing_status">
<option></option>
{% for k, v in statuses.retailcrm %}
<option value="{{ k }}" {% if saved_settings.retailcrm_missing_status is defined and k == saved_settings.retailcrm_missing_status %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
</div>
{% endif %}
{% endif %}
</div>
<div class="tab-pane" id="tab-collector">
<h3>{{ daemon_collector }}</h3>
<div class="retailcrm_unit">
<label for="retailcrm_collector_active" class="col-md-4">{{ text_collector_activity }}</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_collector_active" value="1" {% if saved_settings.module_retailcrm_collector_active is defined and
saved_settings.module_retailcrm_collector_active == 1 %} {{ 'checked' }}
{% endif %}>
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_collector_active" value="0" {% if not saved_settings.module_retailcrm_collector_active or
saved_settings.module_retailcrm_collector_active == 0 %} {{ 'checked' }}
{% endif %}>
{{ text_no }}
</label>
</div>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4">{{ collector_site_key }}</label>
<input id="retailcrm_collector_site_key" type="text" name="module_retailcrm_collector[site_key]" value="{% if saved_settings.module_retailcrm_collector.site_key is defined %}{{ saved_settings.module_retailcrm_collector.site_key }}{% endif %}">
</div>
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4">{{ text_collector_form_capture }}</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_collector[form_capture]" value="1" {% if saved_settings.module_retailcrm_collector.form_capture is defined and
saved_settings.module_retailcrm_collector.form_capture == 1 %} {{ 'checked' }}
{% endif %}>
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_collector[form_capture]" value="0" {% if saved_settings.module_retailcrm_collector.form_capture is not defined or
saved_settings.module_retailcrm_collector.form_capture == 0 %} {{ 'checked' }}
{% endif %}>
{{ text_no }}
</label>
</div>
<div class="retailcrm_unit">
<label for="module_retailcrm_collector" class="col-md-4">{{ text_collector_period }}</label>
<input id="module_retailcrm_collector_period" type="text" name="module_retailcrm_collector[period]" value="{% if saved_settings.module_retailcrm_collector.period is defined %}{{ saved_settings.module_retailcrm_collector.period }}{% endif %}">
</div>
<div class="retailcrm_unit">
<label for="module_retailcrm_collector" class="col-md-4">{{ text_label_promo }}</label>
<input id="module_retailcrm_collector[]" type="text" name="module_retailcrm_collector[label_promo]" value="{% if saved_settings.module_retailcrm_collector.label_promo is defined %}{{ saved_settings.module_retailcrm_collector.label_promo }}{% endif %}">
</div>
<div class="retailcrm_unit">
<label for="module_retailcrm_collector" class="col-md-4">{{ text_label_send }}</label>
<input id="module_retailcrm_collector_label_send" type="text" name="module_retailcrm_collector[label_send]" value="{% if saved_settings.module_retailcrm_collector.label_send is defined %}{{ saved_settings.module_retailcrm_collector.label_send }}{% endif %}">
</div>
<div class="retailcrm_unit">
<label for="module_retailcrm_collector" class="col-md-4">{{ collector_custom_text }}</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_collector[custom_form]" value="1" {% if saved_settings.module_retailcrm_collector.custom_form is defined and
saved_settings.module_retailcrm_collector.custom_form == 1 %} {{ 'checked' }}
{% endif %}>
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_collector[custom_form]" value="0" {% if saved_settings.module_retailcrm_collector.custom_form is not defined or
saved_settings.module_retailcrm_collector.custom_form == 0 %} {{ 'checked' }}
{% endif %}>
{{ text_no }}
</label>
</div>
{% for field, label in collectorFields %}
<div class="retailcrm_unit">
<label for="retailcrm_collector" class="col-md-4">{{ label }}</label>
<div class="col-md-8">
<input id="module_retailcrm_collector" type="text" name="module_retailcrm_collector[custom][{{ field }}]" value="{% if saved_settings.module_retailcrm_collector.custom[field] is defined %} {{ saved_settings.module_retailcrm_collector.custom[field] }} {% endif %}">
<input type="checkbox" name="module_retailcrm_collector[require][{{ field }}_require]" value="1" {% if saved_settings.module_retailcrm_collector.require[field ~'_require'] %} checked {% endif %}>
<label for="retailcrm_collector">{{ text_require }}</label>
</div>
</div>
{% endfor %}
</div>
{% if saved_settings.module_retailcrm_apiversion is defined and saved_settings.module_retailcrm_apiversion == 'v5' and customFields is defined %}
<div class="tab-pane" id="tab-custom_fields">
<h4>{{ retailcrm_dict_custom_fields }}</h4>
{% if customFields.retailcrm is not empty and customFields.opencart is not empty %}
<div class="retailcrm_unit">
<label for="retailcrm_custom_field_active">{{ text_custom_field_activity }}</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_custom_field_active" value="1" {% if saved_settings.module_retailcrm_custom_field_active is defined and
saved_settings.module_retailcrm_custom_field_active == 1 %}
checked {% endif %} >
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_custom_field_active" value="0" {% if saved_settings.module_retailcrm_custom_field_active is not defined or
saved_settings.module_retailcrm_custom_field_active == 0 %}
checked {% endif %} >
{{ text_no }}
</label>
</div>
<h4>{{ text_customers_custom_fields }}</h4>
{% for customField in customFields.opencart %}
{% set fid = 'c_' ~ customField.custom_field_id %}
<div class="retailcrm_unit">
<select id="module_retailcrm_custom_field_{{ fid }}" name="module_retailcrm_custom_field[{{ fid }}]" >
{% for v in customFields.retailcrm.customers %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_custom_field[fid] is defined and v.code == saved_settings.module_retailcrm_custom_field[fid] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
<label for="module_retailcrm_custom_field_{{ fid }}">{{ customField.name }}</label>
</div>
{% endfor %}
<h4>{{ text_orders_custom_fields }}</h4>
{% for customField in customFields.opencart %}
{% set fid = 'o_' ~ customField.custom_field_id %}
<div class="retailcrm_unit">
<select id="module_retailcrm_custom_field_{{ fid }}" name="module_retailcrm_custom_field[{{ fid }}]" >
{% for v in customFields.retailcrm.orders %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_custom_field[fid] is defined and v.code == saved_settings.module_retailcrm_custom_field[fid] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
<label for="module_retailcrm_custom_field_{{ fid }}">{{ customField.name }}</label>
</div>
{% endfor %}
{% elseif customFields.retailcrm is empty and customFields.opencart is empty %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_error_custom_field }}
</div>
{% elseif customFields.retailcrm is empty %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_error_cf_retailcrm }}
</div>
{% elseif customFields.opencart is empty %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_error_cf_opencart }}
</div>
{% endif %}
</div>
{% endif %}
<div class="tab-pane" id="tab-logs">
<div class="retailcrm_unit">
<span>Retailcrm API error log</span>
<a onclick="confirm('{{ text_confirm_log }}') ? location.href='{{ clear_retailcrm }}' : false;" data-toggle="tooltip" title="{{ button_clear }}" class="btn btn-danger"><i class="fa fa-eraser"></i></a>
</div>
{% if logs.retailcrm_log is defined %}
<div class="panel-body">
<textarea wrap="off" rows="15" readonly class="form-control">{{ logs.retailcrm_log }}</textarea>
</div>
{% elseif logs.retailcrm_error is defined %}
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> {{ logs.retailcrm_error }}
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
{% endif %}
<div class="retailcrm_unit">
<span>Opencart API error log</span>
<a onclick="confirm('{{ text_confirm_log }}') ? location.href='{{ clear_opencart }}' : false;" data-toggle="tooltip" title="{{ button_clear }}" class="btn btn-danger"><i class="fa fa-eraser"></i></a>
</div>
{% if logs.oc_api_log is defined %}
<div class="panel-body">
<textarea wrap="off" rows="15" readonly class="form-control">{{ logs.oc_api_log }}</textarea>
</div>
{% elseif logs.oc_error is defined %}
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> {{ logs.oc_error }}
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
{% endif %}
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{{ footer }}
<script type="text/javascript">
var token = '{{ user_token }}';
$('#icml').on('click', function() {
$.ajax({
url: '{{ catalog }}' + 'admin/index.php?route=extension/module/retailcrm/icml&user_token=' + token,
beforeSend: function() {
$('#icml').button('loading');
},
complete: function() {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i> {{ text_success_catalog }}</div>');
$('#icml').button('reset');
},
error: function(){
alert('error');
}
});
});
$('#export').on('click', function() {
$.ajax({
url: '{{ catalog }}' + 'admin/index.php?route=extension/module/retailcrm/export&user_token=' + token,
beforeSend: function() {
$('#export').button('loading');
},
complete: function() {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i> {{ text_success_export }}</div>');
$('#export').button('reset');
},
error: function(){
alert('error');
}
});
});
$('#export_order').on('click', function() {
var order_id = $('input[name=\'order_id\']').val();
if (order_id && order_id > 0) {
$.ajax({
url: '{{ catalog }}' + 'admin/index.php?route=extension/module/retailcrm/exportOrder&user_token=' + token + '&order_id=' + order_id,
beforeSend: function() {
$('#export_order').button('loading');
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
},
success: function(data, textStatus, jqXHR) {
response = JSON.parse(jqXHR['responseText']);
if (response['status_code'] == '400') {
$('.alert-danger').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i>{{ text_error_order }}' + response['error_msg'] + '</div>');
$('#export_order').button('reset');
} else {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i>{{ text_success_export_order }}</div>');
$('#export_order').button('reset');
$('input[name=\'order_id\']').val('');
}
}
});
} else {
$('.alert-danger').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> {{ text_error_order_id }}</div>');
$('#export_order').button('reset');
}
});
</script>

View file

@ -1,166 +0,0 @@
<?php
/**
* Class ControllerModule
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion3
*/
class ControllerExtensionModuleRetailcrm extends Controller
{
/**
* Create order on event
*
* @param int $order_id order identificator
*
* @return void
*/
public function order_create($parameter1, $parameter2 = null, $parameter3 = null)
{
$this->load->model('checkout/order');
$this->load->model('account/order');
$this->load->library('retailcrm/retailcrm');
$moduleTitle = $this->retailcrm->getModuleTitle();
$order_id = $parameter3;
$data = $this->model_checkout_order->getOrder($order_id);
$data['totals'] = $this->model_account_order->getOrderTotals($order_id);
$data['products'] = $this->model_account_order->getOrderProducts($order_id);
foreach($data['products'] as $key => $product) {
$productOptions = $this->model_account_order->getOrderOptions($order_id, $product['order_product_id']);
if(!empty($productOptions))
$data['products'][$key]['option'] = $productOptions;
}
if (!isset($data['fromApi'])) {
$this->load->model('setting/setting');
$status = $this->model_setting_setting->getSetting($moduleTitle);
if ($data['order_status_id'] > 0) {
$data['order_status'] = $status[$moduleTitle . '_status'][$data['order_status_id']];
}
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/order.php')) {
$this->load->model('extension/retailcrm/custom/order');
$this->model_extension_retailcrm_custom_order->sendToCrm($data, $data['order_id']);
} else {
$this->load->model('extension/retailcrm/order');
$this->model_extension_retailcrm_order->sendToCrm($data, $data['order_id']);
}
}
}
/**
* Update order on event
*
* @param int $order_id order identificator
*
* @return void
*/
public function order_edit($parameter1, $parameter2 = null) {
$order_id = $parameter2[0];
$this->load->model('checkout/order');
$this->load->model('account/order');
$this->load->library('retailcrm/retailcrm');
$moduleTitle = $this->retailcrm->getModuleTitle();
$data = $this->model_checkout_order->getOrder($order_id);
if($data['order_status_id'] == 0) return;
$data['products'] = $this->model_account_order->getOrderProducts($order_id);
$data['totals'] = $this->model_account_order->getOrderTotals($order_id);
foreach($data['products'] as $key => $product) {
$productOptions = $this->model_account_order->getOrderOptions($order_id, $product['order_product_id']);
if(!empty($productOptions))
$data['products'][$key]['option'] = $productOptions;
}
if (!isset($data['fromApi'])) {
$this->load->model('setting/setting');
$status = $this->model_setting_setting->getSetting($moduleTitle);
if ($data['order_status_id'] > 0) {
$data['order_status'] = $status[$moduleTitle . '_status'][$data['order_status_id']];
}
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/order.php')) {
$this->load->model('extension/retailcrm/custom/order');
$this->model_extension_retailcrm_custom_order->changeInCrm($data, $data['order_id']);
} else {
$this->load->model('extension/retailcrm/order');
$this->model_extension_retailcrm_order->changeInCrm($data, $data['order_id']);
}
}
}
/**
* Create customer on event
*
* @param int $customerId customer identificator
*
* @return void
*/
public function customer_create($parameter1, $parameter2 = null, $parameter3 = null) {
$this->load->model('account/customer');
$this->load->model('localisation/country');
$this->load->model('localisation/zone');
$customerId = $parameter3;
$customer = $this->model_account_customer->getCustomer($customerId);
if ($this->request->post) {
$country = $this->model_localisation_country->getCountry($this->request->post['country_id']);
$zone = $this->model_localisation_zone->getZone($this->request->post['zone_id']);
$customer['address'] = array(
'address_1' => $this->request->post['address_1'],
'address_2' => $this->request->post['address_2'],
'city' => $this->request->post['city'],
'postcode' => $this->request->post['postcode'],
'iso_code_2' => $country['iso_code_2'],
'zone' => $zone['name']
);
}
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/customer.php')) {
$this->load->model('extension/retailcrm/custom/customer');
$this->model_extension_retailcrm_custom_customer->sendToCrm($customer);
} else {
$this->load->model('extension/retailcrm/customer');
$this->model_extension_retailcrm_customer->sendToCrm($customer);
}
}
/**
* Update customer on event
*
* @param int $customerId customer identificator
*
* @return void
*/
public function customer_edit($parameter1, $parameter2, $parameter3) {
$customerId = $this->customer->getId();
$this->load->model('account/customer');
$customer = $this->model_account_customer->getCustomer($customerId);
$this->load->model('account/address');
$customer['address'] = $this->model_account_address->getAddress($customer['address_id']);
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/customer.php')) {
$this->load->model('extension/retailcrm/custom/customer');
$this->model_extension_retailcrm_custom_customer->changeInCrm($customer);
} else {
$this->load->model('extension/retailcrm/customer');
$this->model_extension_retailcrm_customer->changeInCrm($customer);
}
}
}

View file

@ -1,102 +0,0 @@
<?php
class ModelExtensionRetailcrmCustomer extends Model {
protected $settings;
protected $moduleTitle;
protected $retailcrmApiClient;
public function __construct($registry)
{
parent::__construct($registry);
$this->load->model('setting/setting');
$this->load->library('retailcrm/retailcrm');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
$this->retailcrmApiClient = $this->retailcrm->getApiClient();
}
/**
* Create customer
*
* @param array $customer
*
* @return void
*/
public function sendToCrm($customer)
{
if(empty($customer) || $this->retailcrmApiClient === false) {
return false;
}
$customerToCrm = $this->process($customer);
$this->retailcrmApiClient->customersCreate($customerToCrm);
}
/**
* Edit customer
*
* @param array $customer
*
* @return void
*/
public function changeInCrm($customer)
{
if(empty($customer) || $this->retailcrmApiClient === false) {
return false;
}
$customerToCrm = $this->process($customer);
$this->retailcrmApiClient->customersEdit($customerToCrm);
}
/**
* Process customer
*
* @param array $customer
*
* @return array $customerToCrm
*/
private function process($customer) {
$customerToCrm = array(
'externalId' => $customer['customer_id'],
'firstName' => $customer['firstname'],
'lastName' => $customer['lastname'],
'email' => $customer['email'],
'phones' => array(
array(
'number' => $customer['telephone']
)
),
'createdAt' => $customer['date_added']
);
if (isset($customer['address'])) {
$customerToCrm['address'] = array(
'index' => $customer['address']['postcode'],
'countryIso' => $customer['address']['iso_code_2'],
'region' => $customer['address']['zone'],
'city' => $customer['address']['city'],
'text' => $customer['address']['address_1'] . ' ' . $customer['address']['address_2']
);
}
if (isset($this->settings[$this->moduleTitle . '_custom_field']) && $customer['custom_field']) {
$customFields = json_decode($customer['custom_field']);
foreach ($customFields as $key => $value) {
if (isset($this->settings[$this->moduleTitle . '_custom_field']['c_' . $key])) {
$customFieldsToCrm[$this->settings[$this->moduleTitle . '_custom_field']['c_' . $key]] = $value;
}
}
if (isset($customFieldsToCrm)) {
$customerToCrm['customFields'] = $customFieldsToCrm;
}
}
return $customerToCrm;
}
}

View file

@ -1,358 +0,0 @@
<?php
class ModelExtensionRetailcrmOrder extends Model {
protected $settings;
protected $moduleTitle;
protected $retailcrmApiClient;
public function __construct($registry)
{
parent::__construct($registry);
$this->load->model('setting/setting');
$this->load->library('retailcrm/retailcrm');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
$this->retailcrmApiClient = $this->retailcrm->getApiClient();
}
/**
* Create order in CRM
*
* @param array $order_data
* @param int $order_id
*
* @return void
*/
public function sendToCrm($order_data, $order_id)
{
if(isset($this->request->post['fromApi']) || $this->retailcrmApiClient === false) {
return;
}
$order = $this->processOrder($order_data, $order_id);
$customers = $this->retailcrmApiClient->customersList(
array(
'name' => $order_data['telephone'],
'email' => $order_data['email']
),
1,
100
);
if($customers) {
foreach ($customers['customers'] as $customer) {
$order['customer']['id'] = $customer['id'];
}
}
unset($customers);
$response = $this->retailcrmApiClient->ordersCreate($order);
if ($this->settings[$this->moduleTitle . '_apiversion'] == 'v5' && $response->isSuccessful()) {
$this->createPayment($order_data, $order_id);
}
}
/**
* Edit order in CRM
*
* @param array $order_data
* @param int $order_id
*
* @return void
*/
public function changeInCrm($order_data, $order_id)
{
if(isset($this->request->post['fromApi']) || $this->retailcrmApiClient === false) {
return;
}
$order = $this->processOrder($order_data, $order_id);
$customers = $this->retailcrmApiClient->customersList(
array(
'name' => $order_data['telephone'],
'email' => $order_data['email']
),
1,
100
);
if($customers) {
foreach ($customers['customers'] as $customer) {
$order['customer']['id'] = $customer['id'];
}
}
unset($customers);
$response = $this->retailcrmApiClient->ordersEdit($order);
if ($this->settings[$this->moduleTitle . '_apiversion'] == 'v5' && $response->isSuccessful()) {
$response_order = $this->retailcrmApiClient->ordersGet($order_id);
if ($response_order->isSuccessful()) {
$order_info = $response_order['order'];
}
foreach ($order_info['payments'] as $payment_data) {
if (isset($payment_data['externalId']) && $payment_data['externalId'] == $order_id) {
$payment = $payment_data;
}
}
if (isset($payment) && $payment['type'] != $this->settings[$this->moduleTitle . '_payment'][$order_data['payment_code']]) {
$response = $this->retailcrmApiClient->ordersPaymentDelete($payment['id']);
if ($response->isSuccessful()) {
$this->createPayment($order_data, $order_id);
}
} elseif (isset($payment) && $payment['type'] == $this->settings[$this->moduleTitle . '_payment'][$order_data['payment_code']]) {
$this->editPayment($order_data, $order_id);
}
}
}
/**
* Process order
*
* @param array $order_data
* @param int $order_id
*
* @return array $order
*/
protected function processOrder($order_data, $order_id)
{
$this->load->model('setting/setting');
$this->load->model('catalog/product');
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
if (!empty($order_data['payment_code']) && isset($this->settings[$this->moduleTitle . '_payment'][$order_data['payment_code']])) {
$payment_code = $this->settings[$this->moduleTitle . '_payment'][$order_data['payment_code']];
} else {
$payment_code = '';
}
if (!empty($order_data['shipping_code'])) {
$shippingCode = explode('.', $order_data['shipping_code']);
$shippingModule = $shippingCode[0];
if (isset($this->settings[$this->moduleTitle . '_delivery'][$order_data['shipping_code']])) {
$delivery_code = $this->settings[$this->moduleTitle . '_delivery'][$order_data['shipping_code']];
} elseif (isset($this->settings[$this->moduleTitle . '_delivery'][$shippingModule])) {
$delivery_code = $this->settings[$this->moduleTitle . '_delivery'][$shippingModule];
}
}
$order['number'] = $order_data['order_id'];
$order['externalId'] = $order_id;
$order['firstName'] = $order_data['firstname'];
$order['lastName'] = $order_data['lastname'];
$order['phone'] = $order_data['telephone'];
$order['customerComment'] = $order_data['comment'];
if(!empty($order_data['email'])) {
$order['email'] = $order_data['email'];
}
$deliveryCost = 0;
$couponTotal = 0;
$orderTotals = isset($order_data['totals']) ? $order_data['totals'] : $order_data['order_total'] ;
foreach ($orderTotals as $totals) {
if ($totals['code'] == 'shipping') {
$deliveryCost = $totals['value'];
}
if ($totals['code'] == 'coupon') {
$couponTotal += abs($totals['value']);
}
if ($totals['code'] == 'reward') {
$couponTotal += abs($totals['value']);
}
}
$order['createdAt'] = $order_data['date_added'];
if ($this->settings[$this->moduleTitle . '_apiversion'] != 'v5') {
$order['paymentType'] = $payment_code;
if ($couponTotal > 0) {
$order['discount'] = $couponTotal;
}
} else {
if ($couponTotal > 0) {
$order['discountManualAmount'] = $couponTotal;
}
}
$country = (isset($order_data['shipping_country'])) ? $order_data['shipping_country'] : '' ;
$order['delivery'] = array(
'code' => $delivery_code,
'address' => array(
'index' => $order_data['shipping_postcode'],
'city' => $order_data['shipping_city'],
'countryIso' => $order_data['shipping_iso_code_2'],
'region' => $order_data['shipping_zone'],
'text' => implode(', ', array(
$order_data['shipping_postcode'],
$country,
$order_data['shipping_city'],
$order_data['shipping_address_1'],
$order_data['shipping_address_2']
))
)
);
if(!empty($deliveryCost)){
$order['delivery']['cost'] = $deliveryCost;
}
$orderProducts = isset($order_data['products']) ? $order_data['products'] : $order_data['order_product'];
$offerOptions = array('select', 'radio');
foreach ($orderProducts as $product) {
$offerId = '';
if (!empty($product['option'])) {
$options = array();
$productOptions = $this->model_catalog_product->getProductOptions($product['product_id']);
foreach($product['option'] as $option) {
if ($option['type'] == 'checkbox') {
$properties[] = array(
'code' => $option['product_option_value_id'],
'name' => $option['name'],
'value' => $option['value']
);
}
if(!in_array($option['type'], $offerOptions)) continue;
foreach($productOptions as $productOption) {
if($productOption['product_option_id'] = $option['product_option_id']) {
foreach($productOption['product_option_value'] as $productOptionValue) {
if($productOptionValue['product_option_value_id'] == $option['product_option_value_id']) {
$options[$option['product_option_id']] = $productOptionValue['option_value_id'];
}
}
}
}
}
ksort($options);
$offerId = array();
foreach($options as $optionKey => $optionValue) {
$offerId[] = $optionKey.'-'.$optionValue;
}
$offerId = implode('_', $offerId);
}
if ($this->settings[$this->moduleTitle . '_apiversion'] != 'v3') {
$item = array(
'offer' => array(
'externalId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id']
),
'productName' => $product['name'],
'initialPrice' => $product['price'],
'quantity' => $product['quantity'],
);
} else {
$item = array(
'productName' => $product['name'],
'initialPrice' => $product['price'],
'quantity' => $product['quantity'],
'productId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id']
);
}
if (isset($properties)) $item['properties'] = $properties;
$order['items'][] = $item;
if (isset($order_data['order_status_id']) && $order_data['order_status_id'] > 0) {
$order['status'] = $this->settings[$this->moduleTitle . '_status'][$order_data['order_status_id']];
} elseif (isset($order_data['order_status_id']) && $order_data['order_status_id'] == 0) {
$order['status'] = $this->settings[$this->moduleTitle . '_missing_status'];
}
if (isset($this->settings[$this->moduleTitle . '_custom_field']) && $order_data['custom_field']) {
$customFields = $order_data['custom_field'];
foreach ($customFields as $key => $value) {
if (isset($this->settings[$this->moduleTitle . '_custom_field']['o_' . $key])) {
$customFieldsToCrm[$this->settings[$this->moduleTitle . '_custom_field']['o_' . $key]] = $value;
}
}
if (isset($customFieldsToCrm)) {
$order['customFields'] = $customFieldsToCrm;
}
}
}
return $order;
}
/**
* Create payment
*
* @param array $order
* @param int $order_id
*
* @return void
*/
protected function createPayment($order, $order_id)
{
$payment_code = $order['payment_code'];
foreach ($order['totals'] as $total) {
if ($total['code'] == 'total') {
$amount = $total['value'];
}
}
$payment = array(
'externalId' => $order_id,
'type' => $this->settings[$this->moduleTitle . '_payment'][$payment_code],
'amount' => $amount
);
$payment['order'] = array(
'externalId' => $order_id
);
$this->retailcrmApiClient->ordersPaymentCreate($payment);
}
/**
* Edit payment
*
* @param array $order
* @param int $order_id
*
* @return void
*/
protected function editPayment($order, $order_id)
{
$payment_code = $order['payment_code'];
foreach ($order['totals'] as $total) {
if ($total['code'] == 'total') {
$amount = $total['value'];
}
}
$payment = array(
'externalId' => $order_id,
'type' => $this->settings[$this->moduleTitle . '_payment'][$payment_code],
'amount' => $amount
);
$this->retailcrmApiClient->ordersPaymentEdit($payment);
}
}

38
composer.json Normal file
View file

@ -0,0 +1,38 @@
{
"name": "retailcrm/opencart-module",
"description": "Integration module for Opencart & RetailCRM",
"license": "GPL-3.0",
"type": "project",
"authors": [
{
"name": "RetailDriverLLC",
"email": "support@retailcrm.pro"
}
],
"config": {
"bin-dir": "bin/",
"preferred-install": "source"
},
"extra": {
"opencart-dir" : "www"
},
"scripts" : {
"test-admin": "bin/phpunit --coverage-php coverage/admin.cov --testsuite admin-tests --colors=always",
"test-catalog": "bin/phpunit --coverage-php coverage/catalog.cov --testsuite catalog-tests --colors=always",
"test-system": "bin/phpunit --coverage-php coverage/system.cov --testsuite system-tests --colors=always",
"test": [
"@test-admin",
"@test-catalog",
"@test-system"
],
"opencart:install" : "bin/robo --load-from tests/RoboFile.php opencart:install"
},
"require": {
"ext-json": "*"
},
"require-dev": {
"consolidation/robo": "~1.0",
"phpcompatibility/php-compatibility": "^9.3",
"beyondit/opencart-test-suite": "~3.0"
}
}

6
doc/Update module.md Normal file
View file

@ -0,0 +1,6 @@
### Обновление версии модуля
Для обновления версии модуля необходимо обновить следующие файлы:
* VERSION
* CHANGELOG.md
* src/upload/admin/controller/extension/module/retailcrm.php

39
docker-compose.yml Normal file
View file

@ -0,0 +1,39 @@
version: '3'
services:
app:
build:
context: .
dockerfile: ./.docker/Dockerfile
args:
- TEST_SUITE=${TEST_SUITE}
- OPENCART=${OPENCART}
- SERVER_PORT=${SERVER_PORT}
- OC_DB_HOSTNAME=${OC_DB_HOSTNAME}
- OC_DB_USERNAME=${OC_DB_USERNAME}
- OC_DB_PASSWORD=${OC_DB_PASSWORD}
- OC_DB_DATABASE=${OC_DB_DATABASE}
- OC_USERNAME=${OC_USERNAME}
- OC_PASSWORD=${OC_PASSWORD}
- OC_EMAIL=${OC_EMAIL}
volumes:
- ./:/opencart-module
links:
- "mysql"
ports:
- "${SERVER_PORT}:${SERVER_PORT}"
depends_on:
- mysql
env_file:
- .env
working_dir: /opencart-module
mysql:
image: mysql:5.7
env_file:
- .env
environment:
- MYSQL_DATABASE=${OC_DB_DATABASE}
- MYSQL_USER=${OC_DB_USERNAME}
- MYSQL_PASSWORD=${OC_DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=root
ports:
- "3306:3306"

41
phpunit.xml.dist Normal file
View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false">
<testsuites>
<testsuite name="catalog-tests">
<directory suffix="CatalogTest.php">./tests/catalog/</directory>
</testsuite>
<testsuite name="admin-tests">
<directory suffix="AdminTest.php">./tests/admin/</directory>
</testsuite>
<testsuite name="system-tests">
<directory suffix="Test.php">./tests/system/</directory>
</testsuite>
</testsuites>
<php>
<env name="OC_ROOT" value="./www/" />
<env name="HTTP_SERVER" value="http://localhost:80/" />
<env name="TEST_CONFIG" value="test-config" />
</php>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix="retailcrm.php">./www/admin/controller</directory>
<directory>./www/admin/model/extension/retailcrm</directory>
<directory suffix="retailcrm.php">./www/catalog/controller</directory>
<directory suffix="daemon_collector.php">./www/catalog/controller</directory>
<directory>./www/catalog/model/extension/retailcrm</directory>
<directory suffix=".php">./www/system/library/retailcrm</directory>
<exclude>
<directory suffix=".php">./www/system/library/retailcrm/lib/api</directory>
</exclude>
</whitelist>
</filter>
</phpunit>

View file

@ -0,0 +1,107 @@
<?php
// Heading Goes here:
$_['heading_title'] = 'RetailCRM';
$_['retailcrm_title'] = 'RetailCRM';
// Text
$_['text_module'] = 'Modules';
$_['text_success'] = 'Settings are saved successfully';
$_['text_notice'] = 'Attention! Time zone in CRM should be the same as the time zone of the store, the time zone is set up at';
$_['retailcrm_base_settings'] = 'Connection settings';
$_['retailcrm_dict_settings'] = 'Configuration of directories correspondence';
$_['retailcrm_countries_settings'] = 'Setting of trade zones';
$_['retailcrm_upload_order'] = 'Uploading one order';
$_['daemon_collector'] = 'Daemon Collector';
$_['consultant_tab_text'] = 'Online Consultant';
$_['general_tab_text'] = 'Main';
$_['references_tab_text'] = 'Directories';
$_['collector_tab_text'] = 'Daemon Collector';
$_['logs_tab_text'] = 'Logs';
$_['collector_custom_text'] = 'Configuration of form fields';
$_['custom_fields_tab_text'] = 'Custom fields';
$_['retailcrm_url'] = 'URL of RetailCRM';
$_['retailcrm_apikey'] = 'API key of RetailCRM';
$_['corporate_enabled_label'] = 'Corporate customers support';
$_['collector_site_key'] = 'Site key';
$_['special_price_settings'] = 'Setting of uploading promotion price';
$_['special_price'] = 'Price type to which the promotion price will be uploaded';
$_['text_success_export'] = 'Orders and customers are uploaded successfully';
$_['text_success_export_order'] = 'Order is uploaded successfully';
$_['text_button_export'] = 'Upload all orders and customers';
$_['text_button_export_order'] = 'Upload the order';
$_['text_button_catalog'] = 'Upload the catalogue';
$_['text_button_clear'] = 'Clear';
$_['text_success_catalog'] = 'Catalogue is uploaded successfully';
$_['text_error_order'] = 'Error! Order is not uploaded!';
$_['text_error_order_id'] = 'Error! Enter the correct order number!';
$_['text_collector_activity'] = 'Use Daemon Collector';
$_['text_custom_field_activity'] = 'Transfer custom fields';
$_['text_collector_form_capture']= 'Show a capture form';
$_['text_collector_period'] = 'Frequency of the form popping up (in minutes)';
$_['text_label_promo'] = 'Form header text';
$_['text_label_send'] = 'Button text';
$_['field_name'] = 'Name';
$_['field_email'] = 'E-mail';
$_['field_phone'] = 'Phone';
$_['text_require'] = 'Required for filling in';
$_['text_payment'] = 'Payment';
$_['text_shipping'] = 'Delivery';
$_['text_orders_custom_fields'] = 'Custom fields of orders';
$_['text_customers_custom_fields'] = 'Custom fields of customers';
$_['text_error_collector_fields'] = 'Fill in the names of fields of Demon Collector form';
$_['text_error_api_empty'] = 'The "RetailCRM URL" and "RetailCRM API key" fields cannot be empty, enter the correct value';
$_['text_error_api_key'] = 'Invalid API key';
$_['text_error_api_key_site'] = 'API key with one-shop access required';
$_['text_error_api_key_currency'] = 'The currency of the site differs from the currency of the store in CRM. For the integration to work correctly, the currencies in CRM and CMS must match';
$_['text_error_custom_field'] = 'Create custom fields on a customer page in Opencart and RetailCRM in order to set up their transfer';
$_['text_error_cf_opencart'] = 'There are no custom fields in Opencart';
$_['text_error_cf_retailcrm'] = 'There are no custom fields in RetailCRM';
$_['text_error_save'] = 'Error when saving settings';
$_['text_error_log'] = 'Log size is more than 2MB';
$_['text_error_delivery'] = 'Delivery types are not found';
$_['text_confirm_log'] = 'Are you sure that you want to clear the log?';
$_['retailcrm_dict_delivery'] = 'Delivery types';
$_['retailcrm_dict_status'] = 'Statuses';
$_['retailcrm_dict_payment'] = 'Payment methods';
$_['retailcrm_dict_custom_fields'] = 'Configuration of custom fields';
$_['retailcrm_dict_default'] = 'By default';
$_['retailcrm_missing_status'] = 'Status of lost orders';
$_['order_number'] = 'Order number';
$_['text_order_number'] = 'Upload the order number to RetailCRM';
$_['summ_around'] = 'Around total summ';
$_['text_summ_around'] = 'Around the order total summ';
$_['icml_settings'] = 'ICML settings';
$_['icml_service_enabled_label'] = 'Upload services in ICML';
$_['icml_service_description'] = 'When the option is enabled, all products for which delivery is disabled will be considered as services and uploaded to CRM as services';
$_['text_currency_label'] = 'Currency of goods';
$_['text_lenght'] = 'Setting of the unit of measurement';
$_['text_lenght_label'] = 'Unit of measurement of goods';
$_['status_changes'] = 'History of changes';
$_['text_status_changes'] = 'Record changes to the order history of Opencart';
$_['column_total'] = 'Total';
$_['product_summ'] = 'Sum';
$_['text_retailcrm_discount'] = 'RetailCRM discount';
$_['text_retailcrm_label_discount'] = 'Label of RetailCRM discount in section total of order';
$_['default_retailcrm_label_discount'] = 'Discount in RetailCRM';
$_['sum_payment'] = 'Sum payment';
$_['text_sum_payment'] = 'Do not upload the sum payment to RetailCRM';
$_['article'] = 'Article';
$_['color'] = 'Color';
$_['weight'] = 'Weight';
$_['size'] = 'Size';
$_['text_yes'] = 'Yes';
$_['text_no'] = 'No';
$_['entry_code'] = 'Online consultant code';
$_['entry_status'] = 'Use code for online consultant';
// Errors
$_['error_permission'] = 'You do not have rights for changing the module settings';

View file

@ -0,0 +1,108 @@
<?php
// Heading Goes here:
$_['heading_title'] = 'RetailCRM';
$_['retailcrm_title'] = 'RetailCRM';
// Text
$_['text_module'] = 'Módulos';
$_['text_success'] = 'Ajustes guardados correctamente';
$_['text_notice'] = '¡Atención! La zona horaria de CRM debe coincidir con la zona horaria de la tienda, la configuración de la zona horaria de CRM se puede establecer en:';
$_['retailcrm_base_settings'] = 'Ajustes de conexión';
$_['retailcrm_dict_settings'] = 'Ajustes de coincidencia de directorios';
$_['retailcrm_countries_settings'] = 'Configurar zonas comerciales';
$_['retailcrm_upload_order'] = 'Exportación de un pedido';
$_['daemon_collector'] = 'Daemon Collector';
$_['consultant_tab_text'] = 'Online Consultant';
$_['general_tab_text'] = 'Inicio';
$_['references_tab_text'] = 'Directorios';
$_['collector_tab_text'] = 'Daemon Collector';
$_['logs_tab_text'] = 'Registro';
$_['collector_custom_text'] = 'Configurar campos de formulario';
$_['custom_fields_tab_text'] = 'Campos personalizados';
$_['retailcrm_url'] = 'Dirección del RetailCRM';
$_['retailcrm_apikey'] = 'Clave de la API del RetailCRM';
$_['corporate_enabled_label'] = 'Corporate customers support';
$_['collector_site_key'] = 'Clave de la página web';
$_['special_price_settings'] = 'Ajuste de la descarga del precio promocional';
$_['special_price'] = 'Tipo de precio en el que se cargará el precio de promoción';
$_['text_success_export'] = 'Los pedidos y los clientes han sido exportados con éxito';
$_['text_success_export_order'] = 'El pedido ha sido exportado con éxito';
$_['text_button_export'] = 'Exportar a todos los pedidos y clientes';
$_['text_button_export_order'] = 'Exportar pedidos';
$_['text_button_catalog'] = 'Exportar catálogo';
$_['text_button_clear'] = 'Limpiar';
$_['text_success_catalog'] = 'El catálogo ha sido exportado con éxito';
$_['text_error_order'] = '¡Error! ¡El pedido no se ha exportado!';
$_['text_error_order_id'] = '¡Error! ¡Introduzca el número del pedido correcto!';
$_['text_collector_activity'] = 'Usar Daemon Collector';
$_['text_custom_field_activity'] = 'Transmitir campos personalizados';
$_['text_collector_form_capture']= 'Mostrar el formulario de captura';
$_['text_collector_period'] = 'Frecuencia de la oleada del formulario (en minutos)';
$_['text_label_promo'] = 'Texto del título del formulario';
$_['text_label_send'] = 'Texto del botón';
$_['field_name'] = 'Nombre';
$_['field_email'] = 'Email';
$_['field_phone'] = 'Teléfono';
$_['text_require'] = 'Necesario para rellenar';
$_['text_payment'] = 'Pago';
$_['text_shipping'] = 'Envío';
$_['text_orders_custom_fields'] = 'Los campos de pedidos personalizados';
$_['text_customers_custom_fields'] = 'Los campos de clientes personalizados';
$_['text_error_collector_fields']= 'Rellene los nombres de los campos del formulario Daemon Collector';
$_['text_error_api_empty'] = 'Los campos "URL de RetailCRM" y "Clave de API de RetailCRM" no pueden estar vacíos, ingrese el valor correcto';
$_['text_error_api_key'] = 'Clave API del CRM no válida';
$_['text_error_api_key_site'] = 'Se requiere clave API con acceso a una tienda';
$_['text_error_api_key_currency'] = 'La moneda del sitio web es distinto a la tienda del CRM. Para el funcionamiento correcto de la integración, las monedas del CMS y CRM deben coincid';
$_['text_error_custom_field'] = 'Cree campos personalizados en la ficha del cliente en Opencart y RetailCRM para configurar sus transmisión.';
$_['text_error_cf_opencart'] = 'Faltan campos personalizados en Opencart';
$_['text_error_cf_retailcrm'] = 'Faltan campos personalizados en RetailCRM';
$_['text_error_save'] = 'Error al guardar la configuración';
$_['text_error_log'] = 'El Tamaño del registro es más de 2MB';
$_['text_error_delivery'] = 'No se encontraron los métodos de envío';
$_['text_confirm_log'] = '¿Estás seguro de que quieres borrar el registro?';
$_['retailcrm_dict_delivery'] = 'Métodos de envío';
$_['retailcrm_dict_status'] = 'Estados';
$_['retailcrm_dict_payment'] = 'Métodos de pago';
$_['retailcrm_dict_custom_fields'] = 'Configurar campos personalizados';
$_['retailcrm_dict_default'] = 'Por defecto';
$_['retailcrm_missing_status'] = 'Estado de pedidos perdidos';
$_['order_number'] = 'Número de pedido';
$_['text_order_number'] = 'Transferir número de pedido a RetailCRM';
$_['summ_around'] = 'Redondeo del costo del pedido';
$_['text_summ_around'] = 'Redondear los costos del pedido a RetailCRM';
$_['icml_settings'] = 'Ajustes de ICML';
$_['icml_service_enabled_label'] = 'Subir servicios de ICML';
$_['icml_service_description'] = 'Si habilita la opción, todos los productos para los que la entrega está desactivada se tratarán como servicios y se cargarán en CRM como servicios';
$_['text_currency_label'] = 'Moneda de bienes';
$_['text_lenght'] = 'Ajustar unidad de medida';
$_['text_lenght_label'] = 'Unidad de medida de bienes';
$_['status_changes'] = 'Historial de cambios';
$_['text_status_changes'] = 'Registrar los cambios en el historial de pedidos de Opencart';
$_['column_total'] = 'Total';
$_['product_summ'] = 'Importe';
$_['text_retailcrm_discount'] = 'RetailCRM descuento';
$_['text_retailcrm_label_discount'] = 'Etiqueta de descuento de RetailCRM en la sección total del pedido';
$_['default_retailcrm_label_discount'] = 'Descuento en RetailCRM';
$_['sum_payment'] = 'Suma de pago';
$_['text_sum_payment'] = 'No transferir suma de pago a RetailCRM';
$_['article'] = 'Artículo';
$_['color'] = 'Color';
$_['weight'] = 'Peso';
$_['size'] = 'Tamaño';
$_['text_yes'] = 'Sí';
$_['text_no'] = 'No';
$_['entry_code'] = 'Código para online consultant';
$_['entry_status'] = 'Usar código para online consultant';
// Errors
$_['error_permission'] = 'No tiene suficientes permisos para cambiar la configuración del módulo';

View file

@ -16,15 +16,16 @@ $_['daemon_collector'] = 'Демон Collector';
$_['general_tab_text'] = 'Главная';
$_['references_tab_text'] = 'Справочники';
$_['collector_tab_text'] = 'Daemon Collector';
$_['consultant_tab_text'] = 'Online Consultant';
$_['logs_tab_text'] = 'Логи';
$_['collector_custom_text'] = 'Настройка полей формы';
$_['custom_fields_tab_text'] = 'Пользовательские поля';
$_['retailcrm_apiversion'] = 'Версия API';
$_['retailcrm_url'] = 'Адрес RetailCRM';
$_['retailcrm_apikey'] = 'Api ключ RetailCRM';
$_['corporate_enabled_label'] = 'Поддержка корпоративных клиентов';
$_['collector_site_key'] = 'Ключ сайта';
$_['special_price_settings'] = 'Настройка выгрузки акционной цены';
$_['special_price'] = 'Тип цены, в который будет выгружаться цена по акции';
$_['special_price'] = 'Тип цены, в который будет выгружаться цена по акции';
$_['text_success_export'] = 'Заказы и клиенты успешно выгружены';
$_['text_success_export_order'] = 'Заказ успешно выгружен';
@ -49,14 +50,17 @@ $_['text_payment'] = 'Оплата';
$_['text_shipping'] = 'Доставка';
$_['text_orders_custom_fields'] = 'Кастомные поля заказов';
$_['text_customers_custom_fields'] = 'Кастомные поля клиентов';
$_['text_error_collector_fields']= 'Заполните названия полей формы Демон Collector';
$_['text_error_api'] = 'Недоступна выбранная версия API.';
$_['text_error_collector_fields'] = 'Заполните названия полей формы Демон Collector';
$_['text_error_api_empty'] = 'Поля "URL RetailCRM" и "Ключ API RetailCRM" не могут быть пустыми, введите корректное значение';
$_['text_error_api_key'] = 'Неверный API ключ';
$_['text_error_api_key_site'] = 'Требуется API ключ с доступом к одному магазину';
$_['text_error_api_key_currency'] = 'Валюта сайта отличается от валюты магазина в CRM. Для корректной работы интеграции, валюты в CRM и CMS должны совпадать';
$_['text_error_custom_field'] = 'Создайте пользовательские поля в карточке клиента в Opencart и RetailCRM, чтобы настроить их передачу';
$_['text_error_cf_opencart'] = 'Отсутствуют пользовательские поля в Opencart';
$_['text_error_cf_retailcrm'] = 'Отсутствуют пользовательские поля в RetailCRM';
$_['text_error_save'] = 'Ошибка сохранения настроек';
$_['text_error_log'] = 'Размер лога более 2MB';
$_['text_error_delivery'] = 'Не найдены типы доставки';
$_['text_error_delivery'] = 'Не найдены типы доставки';
$_['text_confirm_log'] = 'Вы уверены, что хотите очистить лог?';
$_['retailcrm_dict_delivery'] = 'Способы доставки';
@ -66,9 +70,29 @@ $_['retailcrm_dict_custom_fields'] = 'Настройка пользовател
$_['retailcrm_dict_default'] = 'По умолчанию';
$_['retailcrm_missing_status'] = 'Статус пропавших заказов';
$_['order_number'] = 'Номер заказа';
$_['text_order_number'] = 'Передавать номер заказа в RetailCRM';
$_['summ_around'] = 'Округление суммы заказа';
$_['text_summ_around'] = 'Округлять сумму заказа';
$_['icml_settings'] = 'Настройки ICML';
$_['icml_service_enabled_label'] = 'Выгружать услуги в ICML';
$_['icml_service_description'] = 'При включении опции все товары, для которых отключена доставка, будут рассматриваться как услуги и загружаться в CRM как услуги';
$_['text_currency_label'] = 'Валюта товаров';
$_['text_lenght'] = 'Настройка единицы измерения';
$_['text_lenght_label'] = 'Единица измерения товаров';
$_['status_changes'] = 'История изменений';
$_['text_status_changes'] = 'Фиксировать изменения в истории заказа Opencart';
$_['column_total'] = 'Итого';
$_['product_summ'] = 'Сумма';
$_['text_retailcrm_discount'] = 'Скидка RetailCRM';
$_['text_retailcrm_label_discount'] = 'Подпись для скидки, установленной в RetailCRM, в итоговой секции заказа';
$_['default_retailcrm_label_discount'] = 'Скидка в RetailCRM';
$_['sum_payment'] = 'Сумма платежа';
$_['text_sum_payment'] = 'Не передавать сумму платежа в RetailCRM';
$_['article'] = 'Артикул';
$_['color'] = 'Цвет';
$_['weight'] = 'Вес';
@ -78,3 +102,8 @@ $_['text_yes'] = 'Да';
$_['text_no'] = 'Нет';
// Errors
$_['error_permission'] = 'У вас недостаточно прав на изменение настроек модуля';
//online consultant
$_['entry_code'] = 'Код для online consultant';
$_['entry_status'] = 'Использовать код для online consultant';

View file

@ -0,0 +1,29 @@
<?php
class ModelExtensionRetailcrmCustomer extends Model {
/**
* Upload customers
*
* @param array $customers
*
* @return mixed
*/
public function uploadToCrm($customers)
{
$customersToCrm = array();
/** @var CustomerManager $customer_manager */
$customer_manager = $this->retailcrm->getCustomerManager();
foreach($customers as $customer) {
$customersToCrm[] = $customer_manager->prepareCustomer($customer, array());
}
$chunkedCustomers = array_chunk($customersToCrm, 50);
foreach($chunkedCustomers as $customersPart) {
$customer_manager->uploadCustomers($customersPart);
}
return $chunkedCustomers;
}
}

View file

@ -0,0 +1,8 @@
<?php
class ModelExtensionRetailcrmEvent extends Model{
public function getEventByCode($code) {
$query = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "event` WHERE `code` = '" . $this->db->escape($code) . "' LIMIT 1");
return $query->row;
}
}

View file

@ -0,0 +1,341 @@
<?php
class ModelExtensionRetailcrmHistory extends Model {
protected $createResult;
protected $settings;
protected $moduleTitle;
protected $opencartApiClient;
private $orders_history;
private $customers_history;
private $data_repository;
public function __construct($registry) {
parent::__construct($registry);
$this->load->library('retailcrm/retailcrm');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->opencartApiClient = $this->retailcrm->getOcApiClient($registry);
}
/**
* Getting changes from RetailCRM
* @param \RetailcrmProxy $retailcrmApiClient
*
* @return boolean
*/
public function request($retailcrmApiClient) {
$this->load->library('retailcrm/retailcrm');
$this->load->model('setting/setting');
$this->load->model('setting/store');
$this->load->model('user/api');
$this->load->model('sale/order');
$this->load->model('customer/customer');
$this->load->model('extension/retailcrm/references');
$this->load->model('catalog/product');
$this->load->model('catalog/option');
$this->load->model('localisation/zone');
$this->load->language('extension/module/retailcrm');
$this->data_repository = new \retailcrm\repository\DataRepository($this->registry);
$this->orders_history = new retailcrm\history\Order(
$this->data_repository,
new \retailcrm\service\SettingsManager($this->registry),
new \retailcrm\repository\ProductsRepository($this->registry),
new \retailcrm\repository\OrderRepository($this->registry)
);
$this->customers_history = new retailcrm\history\Customer(
$this->data_repository,
new \retailcrm\repository\CustomerRepository($this->registry),
new \retailcrm\service\SettingsManager($this->registry)
);
$this->orders_history->setOcDelivery(
$this->model_extension_retailcrm_references->getOpercartDeliveryTypes()
);
$this->orders_history->setOcPayment(
$this->model_extension_retailcrm_references->getOpercartPaymentTypes()
);
$settings = $this->model_setting_setting->getSetting($this->moduleTitle);
$history = $this->model_setting_setting->getSetting('retailcrm_history');
$settings['domain'] = parse_url(HTTP_SERVER, PHP_URL_HOST);
$url = isset($settings[$this->moduleTitle . '_url']) ? $settings[$this->moduleTitle . '_url'] : null;
$key = isset($settings[$this->moduleTitle . '_apikey']) ? $settings[$this->moduleTitle . '_apikey'] : null;
if (empty($url) || empty($key)) {
$this->log->addNotice('You need to configure retailcrm module first.');
return false;
}
$sinceIdOrders = $history['retailcrm_history_orders'] ?? 0;
$sinceIdCustomers = $history['retailcrm_history_customers'] ?? 0;
$packsOrders = $retailcrmApiClient->ordersHistory(['sinceId' => $sinceIdOrders]);
$packsCustomers = $retailcrmApiClient->customersHistory(['sinceId' => $sinceIdCustomers]);
if (!$packsOrders->isSuccessful() && count($packsOrders->history) <= 0
&& !$packsCustomers->isSuccessful() && count($packsCustomers->history) <= 0
) {
return false;
}
$ordersHistory = $packsOrders->history;
$customersHistory = $packsCustomers->history;
$lastChangeOrders = $ordersHistory ? end($ordersHistory) : null;
$lastChangeCustomers = $customersHistory ? end($customersHistory) : null;
if ($lastChangeOrders !== null && $lastChangeCustomers !== null) {
$this->model_setting_setting->editSetting(
'retailcrm_history',
[
'retailcrm_history_orders' => $lastChangeOrders['id'],
'retailcrm_history_customers' => $lastChangeCustomers['id']
]
);
}
$orders = RetailcrmHistoryHelper::assemblyOrder($ordersHistory);
$customers = RetailcrmHistoryHelper::assemblyCustomer($customersHistory);
$newOrders = [];
$updatedOrders = [];
$this->settings = $settings;
$this->status = array_flip($settings[$this->moduleTitle . '_status']);
foreach ($orders as $order) {
if (isset($order['deleted'])) {
continue;
}
if (isset($order['externalId'])) {
$updatedOrders[] = $order['id'];
} else {
$newOrders[] = $order['id'];
}
}
unset($orders);
$updateCustomers = [];
foreach ($customers as $customer) {
if (isset($customer['deleted'])) {
continue;
}
if (isset($customer['externalId'])) {
$updateCustomers[] = $customer['id'];
}
}
unset($customers);
if (!empty($updateCustomers)) {
$customers = $retailcrmApiClient->customersList(['ids' => $updateCustomers]);
if ($customers) {
$this->updateCustomers($customers['customers']);
}
}
if (!empty($newOrders)) {
$orders = $retailcrmApiClient->ordersList(['ids' => $newOrders]);
if ($orders) {
$this->createResult = $this->createOrders($orders['orders'], $retailcrmApiClient);
}
}
if (!empty($updatedOrders)) {
$orders = $retailcrmApiClient->ordersList(['ids' => $updatedOrders]);
if ($orders) {
$this->updateOrders($orders['orders'], $retailcrmApiClient);
}
}
if (!empty($this->createResult['customers'])) {
$retailcrmApiClient->customersFixExternalIds($this->createResult['customers']);
}
if (!empty($this->createResult['orders'])) {
$retailcrmApiClient->ordersFixExternalIds($this->createResult['orders']);
}
return true;
}
/**
* Create orders from history
*
* @param array $orders
* @param \RetailcrmProxy $retailcrmApiClient
*
* @return array
*/
protected function createOrders($orders, $retailcrmApiClient) {
$customersIdsFix = array();
$ordersIdsFix = array();
foreach ($orders as $order) {
$data = array();
$corporateAddress = array();
if (!empty($order['customer']['type']) && $order['customer']['type'] === 'customer_corporate') {
$customer = $order['contact'];
if (empty($customer['address'])) {
$corporateAddress = $this->getCorporateCustomerAddress($retailcrmApiClient, $order);
if (!empty($corporateAddress)) {
$customer['address'] = $corporateAddress;
}
}
} else {
$customer = $order['customer'];
}
$customer_id = (!empty($customer['externalId']))
? $customer['externalId']
: 0;
if ($customer_id === 0) {
$customer_data = array();
$this->customers_history->handleCustomer($customer_data, $customer);
$address = $this->customers_history->handleAddress($customer, $order);
$this->customers_history->handleCustomFields($customer_data, $customer);
$customer_data['address'] = array($address);
$customer_id = $this->model_customer_customer->addCustomer($customer_data);
$customersIdsFix[] = array('id' => $customer['id'], 'externalId' => (int)$customer_id);
}
$this->orders_history->handleBaseOrderData($data, $order);
$this->orders_history->handleShipping($data, $order);
$this->orders_history->handlePayment($data, $order, $corporateAddress);
$this->orders_history->handleProducts($data, $order);
$this->orders_history->handleTotals($data, $order);
$this->orders_history->handleCustomFields($data, $order);
$data['customer_id'] = $customer_id;
$data['order_status_id'] = 1;
$order_id = $this->data_repository->addOrder($data);
$ordersIdsFix[] = array('id' => $order['id'], 'externalId' => (int) $order_id);
}
return array('customers' => $customersIdsFix, 'orders' => $ordersIdsFix);
}
/**
* Update orders from history
*
* @param array $orders
* @param \RetailcrmProxy $retailcrmApiClient
*
* @return void
*/
protected function updateOrders($orders, $retailcrmApiClient) {
foreach ($orders as $order) {
$corporateAddress = array();
$data = $this->model_sale_order->getOrder($order['externalId']);
if (!empty($order['customer']['type']) && $order['customer']['type'] === 'customer_corporate') {
$customer = $order['contact'];
if (empty($customer['address'])) {
$corporateAddress = $this->getCorporateCustomerAddress($retailcrmApiClient, $order);
if (!empty($corporateAddress)) {
$customer['address'] = $corporateAddress;
}
}
} else {
$customer = $order['customer'];
}
$customer_id = (!empty($customer['externalId']))
? $customer['externalId']
: 0;
if ($customer_id === 0) {
$customer_data = array();
$this->customers_history->handleCustomer($customer_data, $customer);
$address = $this->customers_history->handleAddress($customer, $order);
$this->customers_history->handleCustomFields($customer_data, $customer);
$customer_data['address'] = array($address);
$customer_id = $this->model_customer_customer->addCustomer($customer_data);
$this->createResult['customers'][] = array('id' => $customer['id'], 'externalId' => (int)$customer_id);
}
$this->orders_history->handleBaseOrderData($data, $order);
$this->orders_history->handleShipping($data, $order);
$this->orders_history->handlePayment($data, $order, $corporateAddress);
$this->orders_history->handleProducts($data, $order);
$this->orders_history->handleTotals($data, $order);
$this->orders_history->handleCustomFields($data, $order);
$data['customer_id'] = $customer_id;
if (array_key_exists($order['status'], $this->status)) {
$data['order_status_id'] = $this->status[$order['status']];
}
if (isset($this->settings[$this->moduleTitle . '_status_changes'])
&& $this->settings[$this->moduleTitle . '_status_changes']
) {
$this->opencartApiClient->addHistory($order['externalId'], $data['order_status_id']);
}
$this->data_repository->editOrder($order['externalId'], $data);
}
}
protected function updateCustomers($customers) {
foreach ($customers as $customer) {
$customer_id = $customer['externalId'];
$customer_data = $this->model_customer_customer->getCustomer($customer_id);
$this->customers_history->handleCustomer($customer_data, $customer);
$this->customers_history->handleCustomFields($customer_data, $customer);
if (empty($customer_data['address_id'])) {
$address = $this->customers_history->handleAddress($customer, array());
$addresses = $this->model_customer_customer->getAddresses($customer_id);
$addresses[] = $address;
$customer_data['address'] = $addresses;
} else {
$updateAddress = $this->customers_history->handleAddress($customer, array(), $customer_data['address_id']);
$addresses = $this->model_customer_customer->getAddresses($customer_id);
$addresses[$customer_data['address_id']] = $updateAddress;
$customer_data['address'] = $addresses;
}
$this->model_customer_customer->editCustomer($customer_id, $customer_data);
}
}
/**
* @param \RetailcrmProxy $retailcrmApiClient
* @param array $order
*
* @return array
*/
private function getCorporateCustomerAddress($retailcrmApiClient, $order) {
$addresses = $retailcrmApiClient->customersCorporateAddresses(
$order['customer']['id'],
array('ids' => array($order['customer']['mainAddress'])),
null,
null,
'id'
);
if ($addresses->isSuccessful() && !empty($addresses['addresses'])) {
return $addresses['addresses'][0];
}
return array();
}
}

View file

@ -15,13 +15,14 @@ class ModelExtensionRetailcrmIcml extends Model
/**
* Constructor
*
*
* @param Registry $registry
*/
public function __construct($registry)
{
parent::__construct($registry);
$this->load->library('retailcrm/retailcrm');
$this->load->model('localisation/weight_class');
}
public function generateICML()
@ -31,6 +32,7 @@ class ModelExtensionRetailcrmIcml extends Model
$this->load->model('catalog/product');
$this->load->model('catalog/option');
$this->load->model('catalog/manufacturer');
$this->load->model('localisation/length_class');
$string = '<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="'.date('Y-m-d H:i:s').'">
@ -76,15 +78,20 @@ class ModelExtensionRetailcrmIcml extends Model
*/
private function addCategories()
{
$categories = $this->model_catalog_category->getCategories(array());
foreach($categories as $category) {
$categories = $this->model_catalog_category->getCategories([]);
foreach ($categories as $category) {
$category = $this->model_catalog_category->getCategory($category['category_id']);
$e = $this->eCategories->appendChild(
$this->dd->createElement(
'category', $category['name']
)
);
$c = $this->dd->createElement('category');
if ($category['image']) {
$c->appendChild(
$this->dd->createElement('picture', $this->generateImage($category['image']))
);
}
$c->appendChild($this->dd->createElement('name', $category['name']));
$e = $this->eCategories->appendChild($c);
$e->setAttribute('id', $category['category_id']);
@ -95,27 +102,41 @@ class ModelExtensionRetailcrmIcml extends Model
}
private function addOffers()
{
$offerManufacturers = array();
private function addOffers() {
$offerManufacturers = [];
$servicesForIcml = $this->retailcrm->useServicesForIcml();
$currencyForIcml = $this->retailcrm->getCurrencyForIcml();
$defaultCurrency = $this->getDefaultCurrency();
$settingLenght = $this->retailcrm->getLenghtForIcml();
$leghtsArray = $this->model_localisation_length_class->getLengthClasses();
$weightClassesMas = $this->model_localisation_weight_class->getWeightClasses();
$weightClasses = [];
$manufacturers = $this->model_catalog_manufacturer
->getManufacturers(array());
foreach ($manufacturers as $manufacturer) {
$offerManufacturers[
$manufacturer['manufacturer_id']
] = $manufacturer['name'];
foreach ($weightClassesMas as $weightClass) {
$weightClasses[$weightClass['weight_class_id']]['value'] = $weightClass['value'];
}
$products = $this->model_catalog_product->getProducts(array());
foreach ($leghtsArray as $lenght) {
if ($lenght['value'] == 1) {
$defaultLenght = $lenght;
}
}
$manufacturers = $this->model_catalog_manufacturer
->getManufacturers([]);
foreach ($manufacturers as $manufacturer) {
$offerManufacturers[$manufacturer['manufacturer_id']] = $manufacturer['name'];
}
$products = $this->model_catalog_product->getProducts([]);
foreach ($products as $product) {
$offers = $this->retailcrm->getOffers($product);
foreach ($offers as $optionsString => $optionsValues) {
$optionsString = explode('_', $optionsString);
$options = array();
$options = [];
foreach($optionsString as $optionString) {
$option = explode('-', $optionString);
@ -123,39 +144,50 @@ class ModelExtensionRetailcrmIcml extends Model
if ($optionString != '0:0-0') {
$optionData = $this->getOptionData($optionIds[1], $option[1]);
$options[$optionIds[0]] = array(
'name' => $optionData['optionName'],
'value' => $optionData['optionValue'],
'value_id' => $option[1]
);
if (!empty($optionData)) {
$options[$optionIds[0]] = array(
'name' => $optionData['optionName'],
'value' => $optionData['optionValue'],
'value_id' => $option[1],
'option_id' => $optionIds[1]
);
}
}
}
ksort($options);
$offerId = array();
$offerId = [];
foreach($options as $optionKey => $optionData) {
$offerId[] = $optionKey.'-'.$optionData['value_id'];
}
$offerId = implode('_', $offerId);
$e = $this->eOffers->appendChild($this->dd->createElement('offer'));
$catalog = $this->eOffers->appendChild($this->dd->createElement('offer'));
if (!empty($offerId)) {
$e->setAttribute('id', $product['product_id'] . '#' . $offerId);
$e->setAttribute('productId', $product['product_id']);
$e->setAttribute('quantity', $optionsValues['qty']);
$catalog->setAttribute('id', $product['product_id'] . '#' . $offerId);
$catalog->setAttribute('productId', $product['product_id']);
$catalog->setAttribute('quantity', $optionsValues['qty']);
} else {
$e->setAttribute('id', $product['product_id']);
$e->setAttribute('productId', $product['product_id']);
$e->setAttribute('quantity', $product['quantity']);
$catalog->setAttribute('id', $product['product_id']);
$catalog->setAttribute('productId', $product['product_id']);
$catalog->setAttribute('quantity', $product['quantity']);
}
/**
* Set type for offers
*/
$useServices = $servicesForIcml && isset($product['shipping']) && $product['shipping'] == 0;
$catalog->setAttribute('type', $useServices ? 'service' : 'product');
/**
* Offer activity
*/
$activity = $product['status'] == 1 ? 'Y' : 'N';
$e->appendChild(
$catalog->appendChild(
$this->dd->createElement('productActivity')
)->appendChild(
$this->dd->createTextNode($activity)
@ -167,7 +199,7 @@ class ModelExtensionRetailcrmIcml extends Model
->getProductCategories($product['product_id']);
if (!empty($categories)) {
foreach ($categories as $category) {
$e->appendChild($this->dd->createElement('categoryId'))
$catalog->appendChild($this->dd->createElement('categoryId'))
->appendChild(
$this->dd->createTextNode($category)
);
@ -176,66 +208,113 @@ class ModelExtensionRetailcrmIcml extends Model
/**
* Name & price
*/
$e->appendChild($this->dd->createElement('productName'))
$catalog->appendChild($this->dd->createElement('productName'))
->appendChild($this->dd->createTextNode($product['name']));
if(!empty($options)) {
$optionsString = array();
if (!empty($options)) {
$optionsString = [];
foreach($options as $option) {
$optionsString[] = $option['name'].': '.$option['value'];
}
$optionsString = ' ('.implode(', ', $optionsString).')';
$e->appendChild($this->dd->createElement('name'))
$catalog->appendChild($this->dd->createElement('name'))
->appendChild($this->dd->createTextNode($product['name'].$optionsString));
} else {
$e->appendChild($this->dd->createElement('name'))
$catalog->appendChild($this->dd->createElement('name'))
->appendChild($this->dd->createTextNode($product['name']));
}
$e->appendChild($this->dd->createElement('price'))
->appendChild($this->dd->createTextNode($product['price'] + $optionsValues['price']));
if ($currencyForIcml && $currencyForIcml != $defaultCurrency) {
$price = $this->currency->convert(
$product['price'] + $optionsValues['price'],
$this->getDefaultCurrency(),
$this->retailcrm->getCurrencyForIcml()
);
} else {
$price = $product['price'] + $optionsValues['price'];
}
$catalog->appendChild($this->dd->createElement('price'))
->appendChild($this->dd->createTextNode($price));
/**
* Vendor
*/
if ($product['manufacturer_id'] != 0) {
$e->appendChild($this->dd->createElement('vendor'))
$catalog->appendChild($this->dd->createElement('vendor'))
->appendChild(
$this->dd->createTextNode(
$offerManufacturers[$product['manufacturer_id']]
)
);
}
/**
* Dimensions
*/
if ((!empty($product['length']) && $product['length'] > 0) &&
(!empty($product['width']) && $product['width'] > 0)
&& !empty($product['height']))
{
$lenghtArray = $this->model_localisation_length_class->getLengthClass($product['length_class_id']);
if ($defaultLenght['length_class_id'] != $lenghtArray['length_class_id']) {
$productLength = $product['length'] / $lenghtArray['value'];
$productWidth = $product['width'] / $lenghtArray['value'];
$productHeight = $product['height'] / $lenghtArray['value'];
} else {
$productLength = $product['length'];
$productWidth = $product['width'];
$productHeight = $product['height'];
}
if ($defaultLenght['length_class_id'] != $settingLenght && $settingLenght) {
$unit = $this->model_localisation_length_class->getLengthClass($settingLenght);
$productLength = $productLength * $unit['value'];
$productWidth = $productWidth * $unit['value'];
$productHeight = $productHeight * $unit['value'];
}
$dimensions = sprintf(
'%01.3f/%01.3f/%01.3f',
$productLength,
$productWidth,
$productHeight
);
$catalog->appendChild($this->dd->createElement('dimensions'))
->appendChild($this->dd->createTextNode($dimensions));
}
/**
* Image
*/
if ($product['image']) {
$image = $this->generateImage($product['image']);
$e->appendChild($this->dd->createElement('picture'))
$catalog->appendChild($this->dd->createElement('picture'))
->appendChild($this->dd->createTextNode($image));
}
/**
* Url
*/
$this->url = new Url(
HTTP_CATALOG,
$this->config->get('config_secure')
? HTTP_CATALOG
: HTTPS_CATALOG
);
$e->appendChild($this->dd->createElement('url'))
$this->url = new Url(HTTP_CATALOG, HTTPS_CATALOG);
$catalog->appendChild($this->dd->createElement('url'))
->appendChild(
$this->dd->createTextNode(
$this->url->link(
'product/product&product_id=' . $product['product_id']
'product/product&product_id=' . $product['product_id'],
'',
(bool) $this->config->get('config_secure')
)
)
);
// Options
if(!empty($options)) {
if (!empty($options)) {
foreach($options as $optionKey => $optionData) {
$param = $this->dd->createElement('param');
$param->setAttribute('code', $optionKey);
$param->setAttribute('code', $optionData['option_id']);
$param->setAttribute('name', $optionData['name']);
$param->appendChild($this->dd->createTextNode($optionData['value']));
$e->appendChild($param);
$catalog->appendChild($param);
}
}
if ($product['sku']) {
@ -243,18 +322,24 @@ class ModelExtensionRetailcrmIcml extends Model
$sku->setAttribute('code', 'article');
$sku->setAttribute('name', $this->language->get('article'));
$sku->appendChild($this->dd->createTextNode($product['sku']));
$e->appendChild($sku);
$catalog->appendChild($sku);
}
if ($product['weight'] != '') {
$weight = $this->dd->createElement('param');
$weight->setAttribute('code', 'weight');
$weight->setAttribute('name', $this->language->get('weight'));
$weightValue = (isset($offer['weight_class']))
? round($product['weight'], 3) . ' ' . $product['weight_class']
: round($product['weight'], 3)
$weight = $this->dd->createElement('weight');
$coeffWeight = 1;
if (!empty($weightClasses[$product['weight_class_id']]['value'])) {
$coeffWeight = $weightClasses[$product['weight_class_id']]['value'];
}
$weightValue = !empty($optionsValues['weight'])
? $product['weight'] + $optionsValues['weight']
: $product['weight']
;
$weightValue = round($weightValue / $coeffWeight, 6);
$weight->appendChild($this->dd->createTextNode($weightValue));
$e->appendChild($weight);
$catalog->appendChild($weight);
}
}
}
@ -267,7 +352,7 @@ class ModelExtensionRetailcrmIcml extends Model
private function generateImage($image)
{
$this->load->model('tool/image');
$currentTheme = $this->config->get('config_theme');
$width = $this->config->get($currentTheme . '_image_related_width') ? $this->config->get($currentTheme . '_image_related_width') : 200;
$height = $this->config->get($currentTheme . '_image_related_height') ? $this->config->get($currentTheme . '_image_related_height') : 200;
@ -294,9 +379,23 @@ class ModelExtensionRetailcrmIcml extends Model
$this->optionValues[$optionValueId] = $optionValue;
}
return array(
'optionName' => $option['name'],
'optionValue' => $optionValue['name']
);
if (!empty($option['name']) && !empty($optionValue['name'])) {
return array(
'optionName' => $option['name'],
'optionValue' => $optionValue['name']
);
}
}
private function getDefaultCurrency() {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency");
foreach ($query->rows as $currency) {
if ($currency['value'] == 1) {
return $currency['code'];
}
}
return $query->rows[0]['code'];
}
}

View file

@ -0,0 +1,29 @@
<?php
class ModelExtensionRetailcrmOrder extends Model {
/**
* Upload orders to CRM
*
* @param array $orders
*
* @return mixed
*/
public function uploadToCrm($orders)
{
$ordersToCrm = array();
/** @var OrderManager $order_manager */
$order_manager = $this->retailcrm->getOrderManager();
foreach ($orders as $order) {
$ordersToCrm[] = $order_manager->prepareOrder($order, $order['products'], $order['totals']);
}
$chunkedOrders = array_chunk($ordersToCrm, 50);
foreach($chunkedOrders as $ordersPart) {
$order_manager->uploadOrders($ordersPart);
}
return $chunkedOrders;
}
}

View file

@ -0,0 +1,262 @@
<?php
class ModelExtensionRetailcrmPrices extends Model
{
protected $settings;
protected $moduleTitle;
private $options;
private $optionValues;
/**
* Constructor
*
* @param Registry $registry
*/
public function __construct($registry)
{
parent::__construct($registry);
$this->load->library('retailcrm/retailcrm');
$this->load->model('catalog/option');
$this->load->model('setting/setting');
$this->load->model('customer/customer_group');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
}
/**
* Upload prices to CRM
*
* @param array $products
* @param RetailcrmProxy $retailcrmApiClient
* @return mixed bool | array
*/
public function uploadPrices($products, $retailcrmApiClient)
{
$prices = $this->getPrices($products, $retailcrmApiClient);
if ($retailcrmApiClient === false || !$prices) {
return false;
}
$pricesUpload = array_chunk($prices, 250);
foreach ($pricesUpload as $priceUpload) {
$retailcrmApiClient->storePricesUpload($priceUpload);
}
return $pricesUpload;
}
/**
* Get prices
*
* @param array $products
*
* @return mixed
*/
protected function getPrices($products, $retailcrmApiClient)
{
$prices = array();
$site = $this->getSite($retailcrmApiClient);
foreach ($products as $product) {
$specials = $this->model_catalog_product->getProductSpecials($product['product_id']);
if ($specials) {
$productPrice = array();
if (is_array($specials) && count($specials)) {
$productPrice = $this->getSpecialPrice($specials);
}
$prices = array_merge($this->getPriceRequest($product, $site, $productPrice), $prices);
} else {
$productPrice = $this->getEmptyPrice();
$prices = array_merge($prices, $this->getPriceRequest($product, $site, $productPrice));
continue;
}
}
return $prices;
}
/**
* Get prices for request
*
* @param $product
* @param $site
* @param $productPrice
*
* @return array
*/
private function getPriceRequest($product, $site, $productPrice)
{
$offers = $this->retailcrm->getOffers($product);
$pricesProducts = array();
foreach ($offers as $optionsString => $optionsValues) {
$optionsString = explode('_', $optionsString);
$options = array();
foreach($optionsString as $optionString) {
$option = explode('-', $optionString);
$optionIds = explode(':', $option[0]);
if ($optionString != '0:0-0') {
$optionData = $this->getOptionData($optionIds[1], $option[1]);
$options[$optionIds[0]] = array(
'name' => $optionData['optionName'],
'value' => $optionData['optionValue'],
'value_id' => $option[1]
);
}
}
ksort($options);
$offerId = array();
foreach($options as $optionKey => $optionData) {
$offerId[] = $optionKey.'-'.$optionData['value_id'];
}
$offerId = implode('_', $offerId);
$price = array();
foreach($productPrice as $k => $v) {
if (isset($v['price']) && ($v['price'] + $optionsValues['price'] == 0)) {
continue;
}
if (isset($this->settings[$this->moduleTitle . '_special_' . $k])) {
$price[] = array(
'code' => $this->settings[$this->moduleTitle . '_special_' . $k],
'price' => !$v['remove'] ? $v['price'] + $optionsValues['price'] : 0,
'remove' => $v['remove']
);
}
}
$pricesProducts[] = array(
'externalId' => $offerId ? $product['product_id'] . '#' . $offerId : $product['product_id'],
'site' => $site,
'prices' => $price
);
}
return $pricesProducts;
}
/**
* Get actual special
*
* @param array $specials
*
* @return array $productPrice
*/
private function getSpecialPrice($specials)
{
$date = date('Y-m-d');
$always = '0000-00-00';
$productPrice = array();
foreach ($specials as $special) {
if (($special['date_start'] == $always && $special['date_end'] == $always)
|| ($special['date_start'] <= $date && $special['date_end'] >= $date)
) {
if ((isset($groupId) && $groupId == $special['customer_group_id']) || !isset($groupId)) {
if ((isset($priority) && $priority > $special['priority'])
|| !isset($priority)
) {
$productPrice[$special['customer_group_id']]['price'] = $special['price'];
$productPrice[$special['customer_group_id']]['remove'] = false;
$groupId = $special['customer_group_id'];
$priority = $special['priority'];
}
} else {
$productPrice[$special['customer_group_id']]['price'] = $special['price'];
$productPrice[$special['customer_group_id']]['remove'] = false;
$groupId = $special['customer_group_id'];
}
}
}
$customerGroups = $this->model_customer_customer_group->getCustomerGroups();
foreach ($customerGroups as $customerGroup) {
if (!isset($productPrice[$customerGroup['customer_group_id']])){
$productPrice[$customerGroup['customer_group_id']]['remove'] = true;
}
}
return $productPrice;
}
/**
* Get price for no special
*
* @return array $productPrice
*/
private function getEmptyPrice()
{
$customerGroups = $this->model_customer_customer_group->getCustomerGroups();
$productPrice = array();
foreach ($customerGroups as $customerGroup) {
$productPrice[$customerGroup['customer_group_id']]['remove'] = true;
}
return $productPrice;
}
/**
* Get data option
*
* @param int $optionId
* @param int $optionValueId
*
* @return array
*/
private function getOptionData($optionId, $optionValueId) {
if (!empty($this->options[$optionId])) {
$option = $this->options[$optionId];
} else {
$option = $this->model_catalog_option->getOption($optionId);
$this->options[$optionId] = $option;
}
if (!empty($this->optionValues[$optionValueId])) {
$optionValue = $this->optionValues[$optionValueId];
} else {
$optionValue = $this->model_catalog_option->getOptionValue($optionValueId);
$this->optionValues[$optionValueId] = $optionValue;
}
return array(
'optionName' => $option['name'],
'optionValue' => $optionValue['name']
);
}
/**
* Get site
*
* @param \RetailcrmProxy $retailcrmApiClient
*
* @return mixed boolean | string
*/
private function getSite($retailcrmApiClient)
{
$response = $retailcrmApiClient->sitesList();
if ($response && $response->isSuccessful()) {
$sites = $response->sites;
$site = end($sites);
return $site['code'];
}
return false;
}
}

View file

@ -21,7 +21,7 @@ class ModelExtensionRetailcrmReferences extends Model
/**
* Get opencart delivery methods
*
*
* @return array
*/
public function getOpercartDeliveryTypes()
@ -33,7 +33,7 @@ class ModelExtensionRetailcrmReferences extends Model
/**
* Get all delivery types
*
*
* @return array
*/
public function getDeliveryTypes()
@ -48,7 +48,7 @@ class ModelExtensionRetailcrmReferences extends Model
/**
* Get all statuses
*
*
* @return array
*/
public function getOrderStatuses()
@ -61,7 +61,7 @@ class ModelExtensionRetailcrmReferences extends Model
/**
* Get all payment types
*
*
* @return array
*/
public function getPaymentTypes()
@ -74,7 +74,7 @@ class ModelExtensionRetailcrmReferences extends Model
/**
* Get all custom fields
*
*
* @return array
*/
public function getCustomFields()
@ -87,7 +87,7 @@ class ModelExtensionRetailcrmReferences extends Model
/**
* Get opencart order statuses
*
*
* @return array
*/
public function getOpercartOrderStatuses()
@ -100,7 +100,7 @@ class ModelExtensionRetailcrmReferences extends Model
/**
* Get opencart payment types
*
*
* @return array
*/
public function getOpercartPaymentTypes()
@ -113,7 +113,7 @@ class ModelExtensionRetailcrmReferences extends Model
$extension = basename($file, '.php');
$this->load->language('extension/payment/' . $extension);
if (version_compare(VERSION, '3.0', '<')) {
$configStatus = $extension . '_status';
} else {
@ -133,61 +133,89 @@ class ModelExtensionRetailcrmReferences extends Model
/**
* Get opencart custom fields
*
*
* @return array
*/
public function getOpencartCustomFields()
{
$this->load->model('customer/custom_field');
return $this->model_customer_custom_field->getCustomFields();
}
/**
* Get RetailCRM delivery types
*
*
* @return array
*/
public function getApiDeliveryTypes()
{
$response = $this->retailcrmApiClient->deliveryTypesList();
if (!$response) {
return array();
}
return (!$response->isSuccessful()) ? array() : $response->deliveryTypes;
}
/**
* Get RetailCRM available sites list
*/
public function getApiSite()
{
$response = $this->retailcrmApiClient->sitesList();
if (!$response || !$response->isSuccessful()) {
return [];
}
$sites = $response->sites;
return end($sites);
}
/**
* Get RetailCRM order statuses
*
*
* @return array
*/
public function getApiOrderStatuses()
{
$response = $this->retailcrmApiClient->statusesList();
if (!$response) {
return array();
}
return (!$response->isSuccessful()) ? array() : $response->statuses;
}
/**
* Get RetailCRM payment types
*
*
* @return array
*/
public function getApiPaymentTypes()
{
$response = $this->retailcrmApiClient->paymentTypesList();
if (!$response) {
return array();
}
return (!$response->isSuccessful()) ? array() : $response->paymentTypes;
}
/**
* Get RetailCRM custom fields
*
*
* @return array
*/
public function getApiCustomFields()
{
$customers = $this->retailcrmApiClient->customFieldsList(array('entity' => 'customer'));
$orders = $this->retailcrmApiClient->customFieldsList(array('entity' => 'order'));
if (!$customers || !$orders) {
return array();
}
$customFieldsCustomers = (!$customers->isSuccessful()) ? array() : $customers->customFields;
$customFieldsOrders = (!$orders->isSuccessful()) ? array() : $orders->customFields;
@ -195,18 +223,21 @@ class ModelExtensionRetailcrmReferences extends Model
if (!$customFieldsCustomers && !$customFieldsOrders) {
return array();
}
return array('customers' => $customFieldsCustomers, 'orders' => $customFieldsOrders);
}
/**
* Get RetailCRM price types
*
*
* @return array
*/
public function getPriceTypes()
{
$response = $this->retailcrmApiClient->priceTypesList();
if (!$response) {
return array();
}
return (!$response->isSuccessful()) ? array() : $response->priceTypes;
}

View file

@ -1,5 +1,11 @@
.retailcrm_unit {margin-bottom: 10px;}
.retailcrm_disable_border {border: none !important;}
.retailcrm_unit input {width: 30%;}
.checkbox input{width: auto;}
.retailcrm_unit input[type=checkbox] {width: 13px;}
.retailcrm_unit select {max-width: 500px;}
.retailcrm_unit select {max-width: 500px;}
.question-mark {
cursor: help;
position: relative;
}

View file

@ -0,0 +1,751 @@
<?php echo $header; ?><?php echo $column_left;?>
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<?php if ($export_file) : ?>
<button type="button" id="export" data-toggle="tooltip" title="<?php echo $text_button_export; ?>" class="btn btn-success"><i class="fa fa-download"></i></button>
<?php endif; ?>
<button type="button" id="icml" data-toggle="tooltip" title="<?php echo $text_button_catalog; ?>" class="btn btn-success"><i class="fa fa-file-text-o"></i></button>
<button type="submit" form="form-retailcrm" data-toggle="tooltip" title="<?php echo $button_save; ?>" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="<?php echo $cancel; ?>" data-toggle="tooltip" title="<?php echo $button_cancel; ?>" class="btn btn-default"><i class="fa fa-reply"></i></a>
</div>
<h1><?php echo $heading_title; ?></h1>
<ul class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a></li>
<?php } ?>
</ul>
</div>
</div>
<div class="container-fluid">
<?php if ($error_warning) : ?>
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?>
</div>
<?php endif; ?>
<?php if (isset($saved_settings['retailcrm_url'])): ?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_notice; ?>
<a href="<?php echo $saved_settings['retailcrm_url']; ?>/admin/settings#t-main"><?php echo $saved_settings['retailcrm_url']; ?>/admin/settings#t-main</a>
</div>
<?php endif; ?>
<div class="panel panel-default">
<div class="panel-body">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-retailcrm" class="form-horizontal">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-general" data-toggle="tab"><?php echo $general_tab_text; ?></a></li>
<?php if (isset($saved_settings['retailcrm_apikey']) && $saved_settings['retailcrm_apikey'] != '' && isset($saved_settings['retailcrm_url']) && $saved_settings['retailcrm_url'] != ''): ?>
<li><a href="#tab-references" data-toggle="tab"><?php echo $references_tab_text; ?></a></li>
<li><a href="#tab-collector" data-toggle="tab"><?php echo $collector_tab_text; ?></a></li>
<li><a href="#tab-consultant" data-toggle="tab"><?php echo $consultant_tab_text; ?></a></li>
<li><a href="#tab-custom_fields" data-toggle="tab"><?php echo $custom_fields_tab_text; ?></a></li>
<li><a href="#tab-logs" data-toggle="tab"><?php echo $logs_tab_text; ?></a></li>
<?php endif; ?>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-general">
<input type="hidden" name="retailcrm_status" value="1">
<fieldset>
<legend><?php echo $retailcrm_base_settings; ?></legend>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label" for="retailcrm_url"><?php echo $retailcrm_url; ?></label>
<div class="col-lg-4 col-md-6 col-sm-10">
<input id="retailcrm_url" type="text" name="retailcrm_url" value="<?php if (isset($saved_settings['retailcrm_url'])): echo $saved_settings['retailcrm_url']; endif; ?>" class="form-control" />
</div>
</div>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label" for="retailcrm_apikey"><?php echo $retailcrm_apikey; ?></label>
<div class="col-lg-4 col-md-6 col-sm-10">
<input id="retailcrm_apikey" type="text" name="retailcrm_apikey" value="<?php if (isset($saved_settings['retailcrm_apikey'])): echo $saved_settings['retailcrm_apikey']; endif;?>" class="form-control" />
</div>
</div>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label" for="retailcrm_corporate_enabled"><?php echo $corporate_enabled_label; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_corporate_enabled" value="1"
<?php if(isset($saved_settings['retailcrm_corporate_enabled']) && $saved_settings['retailcrm_corporate_enabled'] == 1): echo 'checked'; endif;?>/>
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_corporate_enabled" value="0"
<?php if(!isset($saved_settings['retailcrm_corporate_enabled']) || $saved_settings['retailcrm_corporate_enabled'] == 0): echo 'checked'; endif;?>/>
<?php echo $text_no; ?>
</label>
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo $retailcrm_countries_settings; ?></legend>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label">Страны</label>
<div class="col-lg-4 col-md-6 col-sm-10">
<div class="well well-sm" style="height: 150px; overflow: auto;">
<?php foreach($countries as $country) : ?>
<div class="checkbox">
<label>
<input type="checkbox" name="<?php echo 'retailcrm_country[]'; ?>" value="<?php echo $country['country_id']; ?>" <?php if(isset($saved_settings['retailcrm_country']) && in_array($country['country_id'], $saved_settings['retailcrm_country'])): echo 'checked'; endif;?>>
<?php echo $country['name']; ?>
</label>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo $icml_settings; ?></legend>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label question-mark" for="retailcrm_icml_service_enabled" title="When the option is enabled, all products for which delivery is disabled will be considered as services and uploaded to CRM as services"><?php echo $icml_service_enabled_label; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_icml_service_enabled value="1"
<?php if(isset($saved_settings['retailcrm_icml_service_enabled']) && $saved_settings['retailcrm_icml_service_enabled'] == 1): echo 'checked'; endif;?>/>
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_icml_service_enabled" value="0"
<?php if(!isset($saved_settings['retailcrm_icml_service_enabled']) || $saved_settings['retailcrm_icml_service_enabled'] == 0): echo 'checked'; endif;?>/>
<?php echo $text_no; ?>
</label>
</div>
</div
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label"><?php echo $text_currency; ?></label>
<div class="col-md-4 col-sm-10">
<select id="retailcrm_currency" name="retailcrm_currency" class="form-control">
<?php foreach ($currencies as $currency) :?>
<?php if ($currency['status']) :?>
<option value="<?php echo $currency['code']; ?>" <?php if(isset($saved_settings['retailcrm_currency']) && $saved_settings['retailcrm_currency'] == $currency['code']):?>selected="selected"<?php endif;?>>
<?php echo $currency['title']; ?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label"><?php echo $text_lenght_label; ?></label>
<div class="col-md-4 col-sm-10">
<select id="retailcrm_lenght" name="retailcrm_lenght" class="form-control">
<?php foreach ($lenghts as $lenght) :?>
<option value="<?php echo $lenght['length_class_id']; ?>" <?php if(isset($saved_settings['retailcrm_lenght']) && $saved_settings['retailcrm_lenght'] == $lenght['length_class_id']):?>selected="selected"<?php endif;?>>
<?php echo $lenght['title']; ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo $status_changes; ?></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_status_changes"><?php echo $text_status_changes; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_status_changes" value="1" <?php if (isset($saved_settings['retailcrm_status_changes']) &&
$saved_settings['retailcrm_status_changes'] == 1) :
echo 'checked'; endif; ?> />
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_status_changes" value="0" <?php if (!isset($saved_settings['retailcrm_status_changes']) ||
$saved_settings['retailcrm_status_changes'] == 0) :
echo 'checked'; endif; ?> />
<?php echo $text_no; ?>
</label>
</div>
</div>
</fieldset>
<?php if (isset($saved_settings['retailcrm_apikey']) && $saved_settings['retailcrm_apikey'] != '' && isset($saved_settings['retailcrm_url']) && $saved_settings['retailcrm_url'] != ''): ?>
<?php if (!empty($retailcrm_errors)) : ?>
<?php foreach($retailcrm_errors as $retailcrm_error): ?>
<div class="warning"><?php echo $retailcrm_error ?></div>
<?php endforeach; ?>
<?php else: ?>
<fieldset>
<legend><?php echo $retailcrm_upload_order; ?></legend>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label"><?php echo $text_button_export_order; ?> №</label>
<div class="col-sm-10">
<div class="row">
<div class="col-lg-3 col-md-6 col-sm-6">
<input type="text" name="order_id" class="form-control" />
</div>
<div class="col-lg-3 col-md-4 col-sm-6">
<button type="button" id="export_order" class="btn btn-success"><i class="fa fa-download"></i> <?php echo $text_button_export_order; ?></button>
</div>
</div>
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo $special_price_settings; ?></legend>
<div class="form-group retailcrm_unit">
<?php foreach ($customerGroups as $customerGroup) :?>
<?php $cid = $customerGroup['customer_group_id']?>
<div class="row retailcrm_unit">
<label class="col-sm-2 control-label" style="text-align:right!important;" for="opencart_customer_group_<?php echo $customerGroup['customer_group_id']; ?>"><?php echo $customerGroup['name']; ?></label>
<div class="col-md-4 col-sm-10">
<select id="retailcrm_special_<?php echo $cid; ?>" name="retailcrm_special_<?php echo $cid; ?>" class="form-control">
<option value="" <?php if (empty($saved_settings['retailcrm_special_' . $cid])) echo 'selected'; ?>>---</option>
<?php foreach ($priceTypes as $k => $priceType): ?>
<?php if ($priceType['active'] == true and $priceType['default'] == false) :?>
<option value="<?php echo $priceType['code'];?>" <?php if(isset($saved_settings['retailcrm_special_' . $cid]) && $priceType['code'] == $saved_settings['retailcrm_special_' . $cid]):?>selected="selected"<?php endif;?>>
<?php echo $priceType['name'];?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</select>
</div>
</div>
<?php endforeach; ?>
</div>
</fieldset>
<fieldset>
<legend><?php echo $order_number; ?></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_order_number"><?php echo $text_order_number; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_order_number" value="1" <?php if (isset($saved_settings['retailcrm_order_number']) &&
$saved_settings['retailcrm_order_number'] == 1) :
echo 'checked'; endif; ?> />
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_order_number" value="0" <?php if (!isset($saved_settings['retailcrm_order_number']) ||
$saved_settings['retailcrm_order_number'] == 0) :
echo 'checked'; endif; ?> />
<?php echo $text_no; ?>
</label>
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo $summ_around; ?></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_summ_around"><?php echo $text_summ_around; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_summ_around" value="1" <?php if (isset($saved_settings['retailcrm_summ_around']) &&
$saved_settings['retailcrm_summ_around'] == 1) :
echo 'checked'; endif; ?> />
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_summ_around" value="0" <?php if (!isset($saved_settings['retailcrm_summ_around']) ||
$saved_settings['retailcrm_summ_around'] == 0) :
echo 'checked'; endif; ?> />
<?php echo $text_no; ?>
</label>
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo $text_retailcrm_discount; ?></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="label_discount"><?php echo $text_retailcrm_label_discount ?></label>
<div class="col-lg-4 col-md-6 col-sm-10">
<input name="retailcrm_label_discount" id="label_discount" class="form-control" value="<?php if (isset($saved_settings['retailcrm_label_discount'])): echo $saved_settings['retailcrm_label_discount']; else: echo $default_retailcrm_label_discount; endif ;?>">
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo $sum_payment; ?></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_sum_payment"><?php echo $text_sum_payment?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_sum_payment" value="1" <?php if (isset($saved_settings['retailcrm_sum_payment']) &&
$saved_settings['retailcrm_sum_payment'] == 1) :
echo 'checked'; endif;?> />
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_sum_payment" value="0" <?php if (!isset($saved_settings['retailcrm_sum_payment']) ||
$saved_settings['retailcrm_sum_payment'] == 0) :
echo 'checked'; endif;?> />
<?php echo $text_no; ?>
</label>
</div>
</div>
</fieldset>
</div>
<div class="tab-pane" id="tab-references">
<fieldset>
<legend><?php echo $retailcrm_dict_settings; ?></legend>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $retailcrm_dict_delivery; ?></label>
<div class="col-sm-10">
<div class="row">
<?php if ($delivery['opencart']) :?>
<?php foreach($delivery['opencart'] as $value): ?>
<div class="col-sm-12" style="margin-bottom:10px;">
<div class="pm" style="margin-bottom:5px;"><?php echo $value['title'].':'; ?></div>
<?php unset($value['title']); ?>
<?php foreach ($value as $key => $val): ?>
<div class="row retailcrm_unit">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_delivery_<?php echo $val['code']; ?>" name="retailcrm_delivery[<?php echo $val['code']; ?>]" class="form-control">
<?php foreach ($delivery['retailcrm'] as $k => $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_delivery'][$key]) && $v['code'] == $saved_settings['retailcrm_delivery'][$key]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="control-label" style="text-align:left!important;" for="retailcrm_pm_<?php echo $val['code']; ?>"><?php echo $val['title']; ?></label>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
<?php else :?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_error_delivery; ?>
</div>
<?php endif; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $retailcrm_dict_status; ?></label>
<div class="col-sm-10">
<?php foreach ($statuses['opencart'] as $status): ?>
<?php $uid = $status['order_status_id']?>
<div class="row retailcrm_unit">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_status_<?php echo $uid; ?>" name="retailcrm_status[<?php echo $uid; ?>]" class="form-control">
<?php foreach ($statuses['retailcrm'] as $k => $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_status'][$uid]) && $v['code'] == $saved_settings['retailcrm_status'][$uid]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="control-label" style="text-align:left!important;" for="retailcrm_status_<?php echo $status['order_status_id']; ?>"><?php echo $status['name']; ?></label>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $retailcrm_dict_payment; ?></label>
<div class="col-sm-10">
<?php foreach ($payments['opencart'] as $key => $value): ?>
<div class="row retailcrm_unit">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_payment_<?php echo $key; ?>" name="retailcrm_payment[<?php echo $key; ?>]" class="form-control">
<?php foreach ($payments['retailcrm'] as $k => $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_payment'][$key]) && $v['code'] == $saved_settings['retailcrm_payment'][$key]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="control-label" for="retailcrm_payment_<?php echo $key; ?>"><?php echo $value; ?></label>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $retailcrm_dict_default; ?></label>
<div class="col-sm-10">
<div class="row">
<div class="retailcrm_unit col-sm-12">
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_default_payment" name="retailcrm_default_payment" class="form-control">
<?php foreach ($payments['opencart'] as $k => $v): ?>
<option value="<?php echo $k;?>" <?php if(isset($saved_settings['retailcrm_default_payment']) && $k == $saved_settings['retailcrm_default_payment']):?>selected="selected"<?php endif;?>>
<?php echo $v;?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="control-label" for="retailcrm_default_payment"><?php echo $text_payment; ?></label>
</div>
</div>
</div>
<div class="retailcrm_unit col-sm-12">
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_default_shipping" name="retailcrm_default_shipping" class="form-control">
<?php foreach ($delivery['opencart'] as $key => $value): ?>
<optgroup label="<?php echo $value['title']; ?>">
<?php unset($value['title']); ?>
<?php foreach ($value as $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_default_shipping']) && $v['code'] == $saved_settings['retailcrm_default_shipping']):?>selected="selected"<?php endif;?>>
<?php echo $v['title'];?>
</option>
<?php endforeach; ?>
</optgroup>
<?php endforeach; ?>
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="control-label" for="retailcrm_default_payment"><?php echo $text_shipping; ?></label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $retailcrm_missing_status; ?></label>
<div class="col-sm-10">
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_missing_status" name="retailcrm_missing_status" class="form-control">
<option>-- Выберите --</option>
<?php foreach ($statuses['retailcrm'] as $k => $v): ?>
<option value="<?php echo $k;?>" <?php if(isset($saved_settings['retailcrm_missing_status']) && $k == $saved_settings['retailcrm_missing_status']):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>
</div>
</fieldset>
<?php endif; ?>
<?php endif; ?>
</div>
<div class="tab-pane" id="tab-collector">
<fieldset>
<legend><?php echo $daemon_collector; ?></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector_active"><?php echo $text_collector_activity; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_collector_active" value="1" <?php if (isset($saved_settings['retailcrm_collector_active']) &&
$saved_settings['retailcrm_collector_active'] == 1) :
echo 'checked'; endif; ?> />
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector_active" value="0" <?php if (!isset($saved_settings['retailcrm_collector_active']) ||
$saved_settings['retailcrm_collector_active'] == 0) :
echo 'checked'; endif; ?> />
<?php echo $text_no; ?>
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector" class="col-md-4"><?php echo $collector_site_key; ?></label>
<div class="col-sm-10">
<input id="retailcrm_collector_site_key" type="text" name="retailcrm_collector[site_key]" value="<?php if (isset($saved_settings['retailcrm_collector']['site_key'])): echo $saved_settings['retailcrm_collector']['site_key']; endif; ?>" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector"><?php echo $text_collector_form_capture; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_collector[form_capture]" value="1" <?php if (isset($saved_settings['retailcrm_collector']['form_capture']) &&
$saved_settings['retailcrm_collector']['form_capture'] == 1) :
echo 'checked'; endif; ?>>
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector[form_capture]" value="0" <?php if (!isset($saved_settings['retailcrm_collector']['form_capture']) ||
$saved_settings['retailcrm_collector']['form_capture'] == 0) :
echo 'checked'; endif; ?>>
<?php echo $text_no; ?>
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector_period" class="col-md-4"><?php echo $text_collector_period; ?></label>
<div class="col-sm-4">
<input id="retailcrm_collector_period" type="text" name="retailcrm_collector[period]" value="<?php if (isset($saved_settings['retailcrm_collector']['period'])): echo $saved_settings['retailcrm_collector']['period']; endif; ?>" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector[]"><?php echo $text_label_promo; ?></label>
<div class="col-sm-10">
<input id="retailcrm_collector[]" type="text" name="retailcrm_collector[label_promo]" value="<?php if (isset($saved_settings['retailcrm_collector']['label_promo'])): echo $saved_settings['retailcrm_collector']['label_promo']; endif; ?>" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector_label_send"><?php echo $text_label_send; ?></label>
<div class="col-sm-10">
<input id="retailcrm_collector_label_send" type="text" name="retailcrm_collector[label_send]" value="<?php if (isset($saved_settings['retailcrm_collector']['label_send'])): echo $saved_settings['retailcrm_collector']['label_send']; endif; ?>" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector"><?php echo $collector_custom_text; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_collector[custom_form]" value="1" <?php if (isset($saved_settings['retailcrm_collector']['custom_form']) &&
$saved_settings['retailcrm_collector']['custom_form'] == 1) :
echo 'checked'; endif; ?>>
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_collector[custom_form]" value="0" <?php if (!isset($saved_settings['retailcrm_collector']['custom_form']) ||
$saved_settings['retailcrm_collector']['custom_form'] == 0) :
echo 'checked'; endif; ?>>
<?php echo $text_no; ?>
</label>
</div>
</div>
<?php foreach ($collectorFields as $field => $label) : ?>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector"><?php echo $label; ?></label>
<div class="col-sm-10">
<div class="row">
<div class="col-md-4 col-sm-6">
<input id="retailcrm_collector" type="text" name="retailcrm_collector[custom][<?php echo $field; ?>]" value="<?php if (isset($saved_settings['retailcrm_collector']['custom'][$field])) : echo $saved_settings['retailcrm_collector']['custom'][$field]; endif; ?>" class="form-control" />
</div>
<div class="col-md-8 col-sm-6" style="margin-top: 8px;">
<input style="margin-top: 0; vertical-align: middle;" type="checkbox" name="retailcrm_collector[require][<?php echo $field; ?>_require]" value="1" <?php if (isset($saved_settings['retailcrm_collector']['require'][$field.'_require'])) : echo 'checked'; endif;?> />
<label style="margin-bottom: 0; vertical-align: middle; margin-left: 5px;" for="retailcrm_collector"><?php echo $text_require; ?></label>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</fieldset>
</div>
<div class="tab-pane" id="tab-consultant">
<fieldset>
<legend><?php echo $consultant_tab_text; ?></legend>
{* onlineConsultant *}
<div class="form-group">
<label class="col-sm-2 control-label" for="input-code"><?php echo $entry_code;?></label>
<div class="col-sm-10">
<textarea name="retailcrm_online_consultant_code" rows="5" placeholder="<?php echo $entry_code;?>" id="retailcrm_entry_code" class="form-control">
<?php if (isset($saved_settings['retailcrm_online_consultant_code'])): echo $saved_settings['retailcrm_online_consultant_code']; endif;?>
</textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_online_consultant_active"><?php echo $entry_status; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_online_consultant_active" value="1" <?php if (isset($saved_settings['retailcrm_online_consultant_active']) &&
$saved_settings['retailcrm_online_consultant_active'] == 1) :
echo 'checked'; endif; ?> />
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_online_consultant_active" value="0" <?php if (!isset($saved_settings['retailcrm_online_consultant_active']) ||
$saved_settings['retailcrm_online_consultant_active'] == 0) :
echo 'checked'; endif; ?> />
<?php echo $text_no; ?>
</label>
</div>
</div>
</fieldset>
</div>
<div class="tab-pane" id="tab-custom_fields">
<fieldset>
<legend><?php echo $retailcrm_dict_custom_fields; ?></legend>
<?php if ($customFields['retailcrm'] && $customFields['opencart']) : ?>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_custom_field_active"><?php echo $text_custom_field_activity; ?></label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="retailcrm_custom_field_active" value="1" <?php if (isset($saved_settings['retailcrm_custom_field_active']) &&
$saved_settings['retailcrm_custom_field_active'] == 1) :
echo 'checked'; endif; ?> />
<?php echo $text_yes; ?>
</label>
<label class="radio-inline">
<input type="radio" name="retailcrm_custom_field_active" value="0" <?php if (!isset($saved_settings['retailcrm_custom_field_active']) ||
$saved_settings['retailcrm_custom_field_active'] == 0) :
echo 'checked'; endif; ?> />
<?php echo $text_no; ?>
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $text_customers_custom_fields; ?></label>
<div class="col-sm-10">
<div class="row">
<?php foreach ($customFields['opencart'] as $customField) : ?>
<div class="col-sm-12" style="margin-bottom:5px;">
<div class="row">
<?php $fid = 'c_' . $customField['custom_field_id'] ?>
<div class="col-sm-4">
<select id="retailcrm_custom_field_<?php echo $fid; ?>" name="retailcrm_custom_field[<?php echo $fid; ?>]" class="form-control">
<?php foreach ($customFields['retailcrm']['customers'] as $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_custom_field'][$fid]) && $v['code'] == $saved_settings['retailcrm_custom_field'][$fid]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
</div>
<label style="padding-top: 9px;" for="retailcrm_custom_field_<?php echo $fid; ?>"><?php echo $customField['name']; ?></label>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $text_orders_custom_fields; ?></label>
<div class="col-sm-10">
<div class="row">
<?php foreach ($customFields['opencart'] as $customField) : ?>
<div class="col-sm-12" style="margin-bottom:5px;">
<div class="row">
<?php $fid = 'o_' . $customField['custom_field_id'] ?>
<div class="col-sm-4">
<select id="retailcrm_custom_field_<?php echo $fid; ?>" name="retailcrm_custom_field[<?php echo $fid; ?>]" class="form-control">
<?php foreach ($customFields['retailcrm']['orders'] as $v): ?>
<option value="<?php echo $v['code'];?>" <?php if(isset($saved_settings['retailcrm_custom_field'][$fid]) && $v['code'] == $saved_settings['retailcrm_custom_field'][$fid]):?>selected="selected"<?php endif;?>>
<?php echo $v['name'];?>
</option>
<?php endforeach; ?>
</select>
</div>
<label style="padding-top: 9px;" for="retailcrm_custom_field_<?php echo $fid; ?>"><?php echo $customField['name']; ?></label>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<?php elseif (!$customFields['retailcrm'] && !$customFields['opencart']) : ?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_error_custom_field; ?>
</div>
<?php elseif (!$customFields['retailcrm']) : ?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_error_cf_retailcrm; ?>
</div>
<?php elseif (!$customFields['opencart']) : ?>
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo $text_error_cf_opencart; ?>
</div>
<?php endif; ?>
</fieldset>
</div>
<div class="tab-pane" id="tab-logs">
<fieldset style="margin-bottom: 30px;">
<legend>RetailCRM API error log</legend>
<div class="retailcrm_unit">
<a onclick="confirm('<?php echo $text_confirm_log; ?>') ? location.href='<?php echo $clear_retailcrm; ?>' : false;" data-toggle="tooltip" title="<?php echo $button_clear; ?>" class="btn btn-danger"><i class="fa fa-eraser"></i> <span class="hidden-xs"><?php echo $button_clear; ?></span></a>
</div>
<?php if (isset($logs['retailcrm_log'])) : ?>
<div class="row">
<div class="col-sm-12">
<textarea wrap="off" rows="15" readonly class="form-control"><?php echo $logs['retailcrm_log']; ?></textarea>
</div>
</div>
<?php elseif (isset($logs['retailcrm_error'])) : ?>
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> <?php echo $logs['retailcrm_error']; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php endif; ?>
</fieldset>
<fieldset>
<legend>Opencart API error log</legend>
<div class="retailcrm_unit">
<a onclick="confirm('<?php echo $text_confirm_log; ?>') ? location.href='<?php echo $clear_opencart; ?>' : false;" data-toggle="tooltip" title="<?php echo $button_clear; ?>" class="btn btn-danger"><i class="fa fa-eraser"></i> <span class="hidden-xs"><?php echo $button_clear; ?></span></a>
</div>
<?php if (isset($logs['oc_api_log'])) : ?>
<div class="row">
<div class="col-sm-12">
<textarea wrap="off" rows="15" readonly class="form-control"><?php echo $logs['oc_api_log']; ?></textarea>
</div>
</div>
<?php elseif (isset($logs['oc_error'])) : ?>
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> <?php echo $logs['oc_error']; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php endif; ?>
</fieldset>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<?php echo $footer; ?>
<script type="text/javascript">
var token = '<?php echo $token; ?>';
$('#icml').on('click', function() {
$.ajax({
url: '<?php echo $catalog; ?>' + 'admin/index.php?route=extension/module/retailcrm/icml&token=' + token,
beforeSend: function() {
$('#icml').button('loading');
},
complete: function() {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i> <?php echo $text_success_catalog; ?></div>');
$('#icml').button('reset');
},
error: function(){
alert('error');
}
});
});
$('#export').on('click', function() {
$.ajax({
url: '<?php echo $catalog; ?>' + 'admin/index.php?route=extension/module/retailcrm/export&token=' + token,
beforeSend: function() {
$('#export').button('loading');
},
complete: function() {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i> <?php echo $text_success_export; ?></div>');
$('#export').button('reset');
},
error: function(){
alert('error');
}
});
});
$('#export_order').on('click', function() {
var order_id = $('input[name=\'order_id\']').val();
if (order_id && order_id > 0) {
$.ajax({
url: '<?php echo $catalog; ?>' + 'admin/index.php?route=extension/module/retailcrm/exportOrder&token=' + token + '&order_id=' + order_id,
beforeSend: function() {
$('#export_order').button('loading');
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
},
success: function(data, textStatus, jqXHR) {
response = JSON.parse(jqXHR['responseText']);
if (response['status_code'] == '400') {
$('.alert-danger').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i><?php echo $text_error_order; ?>' + response['error_msg'] + '</div>');
$('#export_order').button('reset');
} else {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i><?php echo $text_success_export_order; ?></div>');
$('#export_order').button('reset');
$('input[name=\'order_id\']').val('');
}
}
});
} else {
$('.alert-danger').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> <?php echo $text_error_order_id; ?></div>');
$('#export_order').button('reset');
}
});
</script>

View file

@ -0,0 +1,770 @@
{{ header }} {{ column_left }}
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
{% if export_file %}
<button type="button" id="export" data-toggle="tooltip" title="{{ text_button_export }}" class="btn btn-success"><i class="fa fa-download"></i></button>
{% endif %}
<button type="button" id="icml" data-toggle="tooltip" title="{{ text_button_catalog }}" class="btn btn-success"><i class="fa fa-file-text-o"></i></button>
<button type="submit" form="form-module" data-toggle="tooltip" title="{{ button_save }}" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="{{ cancel }}" data-toggle="tooltip" title="{{ button_cancel }}" class="btn btn-default"><i class="fa fa-reply"></i></a></div>
<h1>{{ heading_title }} {{ module_version }}</h1>
<ul class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="container-fluid">
{% if error_warning %}
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<i class="fa fa-exclamation-circle"></i> {{ error_warning }}
</div>
{% endif %}
{% if saved_settings.module_retailcrm_url is defined %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_notice }}
<a href="{{ saved_settings.module_retailcrm_url }}/admin/settings#t-main">{{ saved_settings.module_retailcrm_url }}/admin/settings#t-main</a>
</div>
{% endif %}
<div class="panel panel-default">
<div class="panel-body">
<form action="{{ action }}" method="post" enctype="multipart/form-data" id="form-module" class="form-horizontal">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-general" data-toggle="tab">{{ general_tab_text }}</a></li>
{% if saved_settings.module_retailcrm_apikey is defined and saved_settings.module_retailcrm_apikey and saved_settings.module_retailcrm_url is defined and saved_settings.module_retailcrm_url %}
<li><a href="#tab-references" data-toggle="tab">{{ references_tab_text }}</a></li>
<li><a href="#tab-collector" data-toggle="tab">{{ collector_tab_text }}</a></li>
<li><a href="#tab-consultant" data-toggle="tab">{{ consultant_tab_text }}</a></li>
<li><a href="#tab-custom_fields" data-toggle="tab"> {{ custom_fields_tab_text }} </a></li>
<li><a href="#tab-logs" data-toggle="tab">{{ logs_tab_text }}</a></li>
{% endif %}
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-general">
<input type="hidden" name="module_retailcrm_status" value="1">
<fieldset>
<legend>{{ retailcrm_base_settings }}</legend>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label" for="retailcrm_url">{{ retailcrm_url }}</label>
<div class="col-lg-4 col-md-6 col-sm-10">
<input class="form-control" id="retailcrm_url" type="text" name="module_retailcrm_url" value="{% if saved_settings.module_retailcrm_url is defined %}{{ saved_settings.module_retailcrm_url }}{% endif %}">
</div>
</div>
<div class="form-group retailcrm_unit retailcrm_disable_border">
<label class="col-sm-2 control-label" for="retailcrm_apikey">{{ retailcrm_apikey }}</label>
<div class="col-lg-4 col-md-6 col-sm-10">
<input class="form-control" id="retailcrm_apikey" type="text" name="module_retailcrm_apikey" value="{% if saved_settings.module_retailcrm_apikey is defined %}{{ saved_settings.module_retailcrm_apikey }}{% endif %}">
</div>
</div>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label" for="module_retailcrm_corporate_enabled">{{ corporate_enabled_label }}</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="module_retailcrm_corporate_enabled" value="1"
{% if saved_settings.module_retailcrm_corporate_enabled is defined and saved_settings.module_retailcrm_corporate_enabled == 1 %}
checked
{% endif %} />
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_corporate_enabled" value="0"
{% if saved_settings.module_retailcrm_corporate_enabled is not defined or saved_settings.module_retailcrm_corporate_enabled == 0 %}
checked
{% endif %} />
{{ text_no }}
</label>
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ retailcrm_countries_settings }}</legend>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label"></label>
<div class="col-lg-4 col-md-6 col-sm-10">
<div class="well well-sm" style="height: 150px; overflow: auto;">
{% for country in countries %}
<div class="checkbox">
<label>
<input type="checkbox" name="module_retailcrm_country[]" value="{{ country.country_id }}" {% if saved_settings.module_retailcrm_country is defined and country.country_id in saved_settings.module_retailcrm_country %} {{ 'checked' }} {% endif %}">
{{ country.name }}
</label>
</div>
{% endfor %}
</div>
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ icml_settings }}</legend>
<div class="form-group retailcrm_unit retailcrm_disable_border">
<label class="col-sm-2 control-label question-mark" for="module_retailcrm_icml_service_enabled" title="{{ icml_service_description }}">{{ icml_service_enabled_label }}</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="module_retailcrm_icml_service_enabled" value="1"
{% if saved_settings.module_retailcrm_icml_service_enabled is defined and saved_settings.module_retailcrm_icml_service_enabled == 1 %}
checked
{% endif %} />
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_icml_service_enabled" value="0"
{% if saved_settings.module_retailcrm_icml_service_enabled is not defined or saved_settings.module_retailcrm_icml_service_enabled == 0 %}
checked
{% endif %} />
{{ text_no }}
</label>
</div>
</div>
<div class="form-group retailcrm_unit retailcrm_disable_border">
<label class="col-sm-2 control-label">{{ text_currency_label }}</label>
<div class="col-md-4 col-sm-10">
<select id="module_retailcrm_currency" name="module_retailcrm_currency" class="form-control">
{% for currency in currencies %}
{% if currency.status == 1 %}
<option value="{{ currency.code }}" {% if saved_settings.module_retailcrm_currency is defined and saved_settings.module_retailcrm_currency == currency.code %} selected="selected" {% endif %}>
{{ currency.title }}
</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div class="form-group retailcrm_unit retailcrm_disable_border">
<label class="col-sm-2 control-label">{{ text_lenght_label }}</label>
<div class="col-md-4 col-sm-10">
<select id="module_retailcrm_lenght" name="module_retailcrm_lenght" class="form-control">
{% for lenght in lenghts %}
<option value="{{ lenght.length_class_id }}" {% if saved_settings.module_retailcrm_lenght is defined and saved_settings.module_retailcrm_lenght == lenght.length_class_id %} selected="selected" {% endif %}>
{{ lenght.title }}
</option>
{% endfor %}
</select>
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ status_changes }}</legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="module_retailcrm_status_changes">{{ text_status_changes }}</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="module_retailcrm_status_changes" value="1"
{% if saved_settings.module_retailcrm_status_changes is defined and saved_settings.module_retailcrm_status_changes == 1 %}
checked
{% endif %} />
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_status_changes" value="0"
{% if saved_settings.module_retailcrm_status_changes is not defined or saved_settings.module_retailcrm_status_changes == 0 %}
checked
{% endif %} />
{{ text_no }}
</label>
</div>
</div>
</fieldset>
{% if saved_settings.module_retailcrm_apikey is defined and saved_settings.module_retailcrm_apikey and saved_settings.module_retailcrm_url is defined and saved_settings.module_retailcrm_url %}
{% if retailcrm_errors|length %}
{% for retailcrm_error in retailcrm_errors %}
<div class="warning">{{ retailcrm_error }}</div>
{% endfor %}
{% else %}
<fieldset>
<legend>{{ retailcrm_upload_order }}</legend>
<div class="form-group retailcrm_unit">
<label class="col-sm-2 control-label">{{ text_button_export_order }} № </label>
<div class="col-sm-10">
<div class="row">
<div class="col-lg-3 col-md-6 col-sm-6">
<input type="text" name="order_id" class="form-control">
</div>
<div class="col-lg-3 col-md-4 col-sm-6">
<button type="button" id="export_order" data-toggle="tooltip" title="{{ text_button_export_order }}" class="btn btn-success"><i class="fa fa-download"></i></button>
</div>
</div>
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ special_price_settings }}</legend>
<div class="form-group retailcrm_unit">
{% for customerGroup in customerGroups %}
{% set cud = customerGroup.customer_group_id %}
<div class="row retailcrm_unit">
<label class="col-sm-2 control-label" for="opencart_customer_group_{{ cud }}">{{ customerGroup.name }}</label>
<div class="col-md-4 col-sm-10">
<select id="module_retailcrm_special_{{ cud }}" name="module_retailcrm_special_{{ cud }}" class="form-control">
<option value="" {% if saved_settings['module_retailcrm_special_'~cud] is not defined or saved_settings['module_retailcrm_special_'~cud] is empty %}selected{% endif %}>---</option>
{% for priceType in priceTypes %}
{% if priceType.active == true and priceType.default == false%}
<option value ="{{ priceType.code }}" {% if saved_settings['module_retailcrm_special_'~cud] is defined and priceType.code == saved_settings['module_retailcrm_special_'~cud] %} selected="selected" {% endif %}>
{{ priceType.name }}
</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
{% endfor %}
</div>
</fieldset>
<fieldset>
<legend>{{ order_number }}</legend>
<div class="form-group">
<label class="col-sm-2 control-label" class="col-sm-2 control-label" for="module_retailcrm_order_number">{{ text_order_number }}</label>
<div class="col-sm-10">
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_order_number" value="1"
{% if saved_settings.module_retailcrm_order_number is defined and saved_settings.module_retailcrm_order_number == 1 %}
checked
{% endif %} />
{{ text_yes }}
</label>
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_order_number" value="0"
{% if saved_settings.module_retailcrm_order_number is not defined or saved_settings.module_retailcrm_order_number == 0 %}
checked
{% endif %} />
{{ text_no }}
</label>
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ summ_around }}</legend>
<div class="form-group">
<label class="col-sm-2 control-label" class="col-sm-2 control-label" for="module_retailcrm_summ_around">{{ text_summ_around }}</label>
<div class="col-sm-10">
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_summ_around" value="1"
{% if saved_settings.module_retailcrm_summ_around is defined and saved_settings.module_retailcrm_summ_around == 1 %}
checked
{% endif %} />
{{ text_yes }}
</label>
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_summ_around" value="0"
{% if saved_settings.module_retailcrm_summ_around is not defined or saved_settings.module_retailcrm_summ_around == 0 %}
checked
{% endif %} />
{{ text_no }}
</label>
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ text_retailcrm_discount }}</legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="label_discount">{{ text_retailcrm_label_discount }}</label>
<div class="col-lg-4 col-md-6 col-sm-10">
<input name="module_retailcrm_label_discount" id="label_discount" class="form-control" value="{% if saved_settings.module_retailcrm_label_discount is defined %}{{ saved_settings.module_retailcrm_label_discount }}{% else %}{{ default_retailcrm_label_discount }}{% endif %}">
</div>
</div>
</fieldset>
<fieldset>
<legend>{{ sum_payment }}</legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="module_retailcrm_sum_payment">{{ text_sum_payment }}</label>
<div class="col-sm-10">
<label class="control-label radio-inline">
<input type="radio" name="module_retailcrm_sum_payment" value="1"
{% if saved_settings.module_retailcrm_sum_payment is defined and saved_settings.module_retailcrm_sum_payment == 1 %}
checked
{% endif %} >
{{ text_yes }}
</label>
<label class="control-label radio-inline">
<input type="radio" name="module_retailcrm_sum_payment" value="0"
{% if saved_settings.module_retailcrm_sum_payment is not defined or saved_settings.module_retailcrm_sum_payment == 0 %}
checked
{% endif %} >
{{ text_no }}
</label>
</div>
</div>
</fieldset>
</div>
<div class="tab-pane" id="tab-references">
<fieldset>
<legend>{{ retailcrm_dict_settings }}</legend>
<div class="form-group">
<label class="col-sm-2 control-label"> {{ retailcrm_dict_delivery }}</label>
<div class="col-sm-10">
<div class="row">
{% if delivery.opencart is not empty %}
{% for value in delivery.opencart %}
<div class="col-sm-12" style="margin-bottom:10px;">
<div class="pm">{{ value.title ~ ':' }}</div>
{% for key, val in value %}
{% if key != 'title' %}
<div class="form-group retailcrm_unit">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_delivery_{{ val.code }}" name="module_retailcrm_delivery[{{ val.code }}]" class="form-control">
{% for k, v in delivery.retailcrm %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_delivery[key] is defined and v.code == saved_settings.module_retailcrm_delivery[key] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="control-label" for="retailcrm_pm_{{ val.code }}">{{ val.title }}</label>
</div>
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
{% else %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_error_delivery }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">{{ retailcrm_dict_status }}</label>
<div class="col-sm-10">
{% for status in statuses.opencart %}
{% set uid = status.order_status_id %}
<div class="row retailcrm_unit">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_status_{{ uid }}" name="module_retailcrm_status[{{ status.order_status_id }}]" class="form-control">
{% for k, v in statuses.retailcrm %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_status[uid] is defined and v.code == saved_settings.module_retailcrm_status[uid] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="control-label" for="retailcrm_status_{{ status.order_status_id }} ">{{ status.name }}</label>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">{{ retailcrm_dict_payment }}</label>
<div class="col-sm-10">
{% for key, value in payments.opencart %}
<div class="row retailcrm_unit">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_payment_{{ key }}" name="module_retailcrm_payment[{{ key }}]" class="form-control">
{% for k, v in payments.retailcrm %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_payment[key] is defined and v.code == saved_settings.module_retailcrm_payment[key] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="control-label" for="retailcrm_payment_{{ key }}">{{ value }}</label>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">{{ retailcrm_dict_default }}</label>
<div class="col-sm-10">
<div class="row">
<div class="retailcrm_unit col-sm-12">
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="module_retailcrm_default_payment" name="module_retailcrm_default_payment" class="form-control">
{% for k, v in payments.opencart %}
<option value="{{ k }}" {% if saved_settings.module_retailcrm_default_payment is defined and k == saved_settings.module_retailcrm_default_payment %} selected="selected" {% endif %}>
{{ v }}
</option>
{% endfor %}
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="col-sm-2 control-label" for="module_retailcrm_default_payment">{{ text_payment }}</label>
</div>
</div>
</div>
<div class="retailcrm_unit col-sm-12">
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="module_retailcrm_default_shipping" name="module_retailcrm_default_shipping" class="form-control">
{% for key, value in delivery.opencart %}
<optgroup label="{{ value.title }}">
{% for k, v in value %}
{% if k != 'title' %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_default_shipping is defined and v.code == saved_settings.module_retailcrm_default_shipping %} selected="selected" {% endif %}>
{{ v.title }}
</option>
{% endif %}
{% endfor %}
</optgroup>
{% endfor %}
</select>
</div>
<div class="col-lg-4 col-md-6 col-sm-6">
<label class="col-sm-2 control-label" for="module_retailcrm_default_shipping">{{ text_shipping }}</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">{{ retailcrm_missing_status }}</label>
<div class="col-sm-10">
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-6">
<select id="retailcrm_missing_status" name="module_retailcrm_missing_status" class="form-control">
<option></option>
{% for k, v in statuses.retailcrm %}
<option value="{{ k }}" {% if saved_settings.module_retailcrm_missing_status is defined and k == saved_settings.module_retailcrm_missing_status %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
</fieldset>
{% endif %}
{% endif %}
</div>
<div class="tab-pane" id="tab-collector">
<fieldset>
<legend>{{ daemon_collector }}</legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector_active" class="col-md-4">{{ text_collector_activity }}</label>
<div class="col-sm-10">
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_collector_active" value="1" {% if saved_settings.module_retailcrm_collector_active is defined and
saved_settings.module_retailcrm_collector_active == 1 %} {{ 'checked' }}
{% endif %}>
{{ text_yes }}
</label>
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_collector_active" value="0" {% if not saved_settings.module_retailcrm_collector_active or
saved_settings.module_retailcrm_collector_active == 0 %} {{ 'checked' }}
{% endif %}>
{{ text_no }}
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector" class="col-md-4">{{ collector_site_key }}</label>
<div class="col-sm-4">
<input class="form-control" id="retailcrm_collector_site_key" type="text" name="module_retailcrm_collector[site_key]" value="{% if saved_settings.module_retailcrm_collector.site_key is defined %}{{ saved_settings.module_retailcrm_collector.site_key }}{% endif %}">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector" class="col-md-4">{{ text_collector_form_capture }}</label>
<div class="col-sm-10">
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_collector[form_capture]" value="1" {% if saved_settings.module_retailcrm_collector.form_capture is defined and
saved_settings.module_retailcrm_collector.form_capture == 1 %} {{ 'checked' }}
{% endif %}>
{{ text_yes }}
</label>
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_collector[form_capture]" value="0" {% if saved_settings.module_retailcrm_collector.form_capture is not defined or
saved_settings.module_retailcrm_collector.form_capture == 0 %} {{ 'checked' }}
{% endif %}>
{{ text_no }}
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="module_retailcrm_collector" class="col-md-4">{{ text_collector_period }}</label>
<div class="col-sm-2">
<input class="form-control" id="module_retailcrm_collector_period" type="text" name="module_retailcrm_collector[period]" value="{% if saved_settings.module_retailcrm_collector.period is defined %}{{ saved_settings.module_retailcrm_collector.period }}{% endif %}">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="module_retailcrm_collector" class="col-md-4">{{ text_label_promo }}</label>
<div class="col-sm-4">
<input class="form-control" id="module_retailcrm_collector[]" type="text" name="module_retailcrm_collector[label_promo]" value="{% if saved_settings.module_retailcrm_collector.label_promo is defined %}{{ saved_settings.module_retailcrm_collector.label_promo }}{% endif %}">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="module_retailcrm_collector" class="col-md-4">{{ text_label_send }}</label>
<div class="col-sm-4">
<input class="form-control" id="module_retailcrm_collector_label_send" type="text" name="module_retailcrm_collector[label_send]" value="{% if saved_settings.module_retailcrm_collector.label_send is defined %}{{ saved_settings.module_retailcrm_collector.label_send }}{% endif %}">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="module_retailcrm_collector" class="col-md-4">{{ collector_custom_text }}</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="module_retailcrm_collector[custom_form]" value="1" {% if saved_settings.module_retailcrm_collector.custom_form is defined and
saved_settings.module_retailcrm_collector.custom_form == 1 %} {{ 'checked' }}
{% endif %}>
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_collector[custom_form]" value="0" {% if saved_settings.module_retailcrm_collector.custom_form is not defined or
saved_settings.module_retailcrm_collector.custom_form == 0 %} {{ 'checked' }}
{% endif %}>
{{ text_no }}
</label>
</div>
</div>
{% for field, label in collectorFields %}
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_collector">{{ label }}</label>
<div class="col-sm-10">
<div class="row">
<div class="col-md-4 col-sm-6">
<input class="form-control" id="module_retailcrm_collector" type="text" name="module_retailcrm_collector[custom][{{ field }}]" value="{% if saved_settings.module_retailcrm_collector.custom[field] is defined %} {{ saved_settings.module_retailcrm_collector.custom[field] }} {% endif %}">
</div>
<div class="col-md-8 col-sm-6" style="margin-top: 8px;">
<input input style="margin-top: 0; vertical-align: middle;" type="checkbox" name="module_retailcrm_collector[require][{{ field }}_require]" value="1" {% if saved_settings.module_retailcrm_collector.require[field ~'_require'] %} checked {% endif %}>
<label style="margin-bottom: 0; vertical-align: middle; margin-left: 5px;" for="retailcrm_collector">{{ text_require }}</label>
</div>
</div>
</div>
</div>
{% endfor %}
</fieldset>
</div>
<div class="tab-pane" id="tab-consultant">
<legend>{{ consultant_tab_text }}</legend>
<fieldset>
{# online cosultant #}
<div class="form-group">
<label class="col-sm-2 control-label" for="input-code">{{ entry_code }}</label>
<div class="col-sm-10">
<textarea name="module_retailcrm_online_consultant_code" rows="5" placeholder="{{ entry_code }}" id="retailcrm_entry_code" class="form-control">
{% if saved_settings.module_retailcrm_online_consultant_code is defined %}
{{ saved_settings.module_retailcrm_online_consultant_code }}{% endif %}
</textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_online_consultant_active" class="col-md-4">{{ entry_status }}</label>
<div class="col-sm-10">
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_online_consultant_active" value="1" {% if saved_settings.module_retailcrm_online_consultant_active is defined and
saved_settings.module_retailcrm_online_consultant_active == 1 %} {{ 'checked' }}
{% endif %}>
{{ text_yes }}
</label>
<label class="control-label" class="radio-inline">
<input type="radio" name="module_retailcrm_online_consultant_active" value="0" {% if not saved_settings.module_retailcrm_online_consultant_active or
saved_settings.module_retailcrm_online_consultant_active == 0 %} {{ 'checked' }}
{% endif %}>
{{ text_no }}
</label>
</div>
</div>
</fieldset>
</div>
<div class="tab-pane" id="tab-custom_fields">
<fieldset>
<legend>{{ retailcrm_dict_custom_fields }}</legend>
{% if customFields.retailcrm is not empty and customFields.opencart is not empty %}
<div class="form-group">
<label class="col-sm-2 control-label" for="retailcrm_custom_field_active">{{ text_custom_field_activity }}</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="module_retailcrm_custom_field_active" value="1" {% if saved_settings.module_retailcrm_custom_field_active is defined and
saved_settings.module_retailcrm_custom_field_active == 1 %}
checked {% endif %} >
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="module_retailcrm_custom_field_active" value="0" {% if saved_settings.module_retailcrm_custom_field_active is not defined or
saved_settings.module_retailcrm_custom_field_active == 0 %}
checked {% endif %} >
{{ text_no }}
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">{{ text_customers_custom_fields }}</label>
<div class="col-sm-10">
<div class="row">
{% for customField in customFields.opencart %}
<div class="col-sm-12" style="margin-bottom:5px;">
<div class="row">
{% set fid = 'c_' ~ customField.custom_field_id %}
<div class="col-sm-4">
<select class="form-control" id="module_retailcrm_custom_field_{{ fid }}" name="module_retailcrm_custom_field[{{ fid }}]" >
{% for v in customFields.retailcrm.customers %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_custom_field[fid] is defined and v.code == saved_settings.module_retailcrm_custom_field[fid] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
</div>
<label style="padding-top: 9px;" for="module_retailcrm_custom_field_{{ fid }}">{{ customField.name }}</label>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">{{ text_orders_custom_fields }}</label>
<div class="col-sm-10">
<div class="row">
{% for customField in customFields.opencart %}
<div class="col-sm-12" style="margin-bottom:5px;">
<div class="row">
{% set fid = 'o_' ~ customField.custom_field_id %}
<div class="col-sm-4">
<select class="form-control" id="module_retailcrm_custom_field_{{ fid }}" name="module_retailcrm_custom_field[{{ fid }}]" >
{% for v in customFields.retailcrm.orders %}
<option value="{{ v.code }}" {% if saved_settings.module_retailcrm_custom_field[fid] is defined and v.code == saved_settings.module_retailcrm_custom_field[fid] %} selected="selected" {% endif %}>
{{ v.name }}
</option>
{% endfor %}
</select>
</div>
<label style="padding-top: 9px;" for="module_retailcrm_custom_field_{{ fid }}">{{ customField.name }}</label>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% elseif customFields.retailcrm is empty and customFields.opencart is empty %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_error_custom_field }}
</div>
{% elseif customFields.retailcrm is empty %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_error_cf_retailcrm }}
</div>
{% elseif customFields.opencart is empty %}
<div class="alert alert-info"><i class="fa fa-exclamation-circle"></i>
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ text_error_cf_opencart }}
</div>
{% endif %}
</fieldset>
</div>
<div class="tab-pane" id="tab-logs">
<fieldset style="margin-bottom: 30px;">
<legend>Retailcrm API error log</legend>
<div class="retailcrm_unit">
<a onclick="confirm('{{ text_confirm_log }}') ? location.href='{{ clear_retailcrm }}' : false;" data-toggle="tooltip" title="{{ button_clear }}" class="btn btn-danger"><i class="fa fa-eraser"></i></a>
</div>
{% if logs.retailcrm_log is defined %}
<div class="row">
<div class="col-sm-12">
<textarea wrap="off" rows="15" readonly class="form-control">{{ logs.retailcrm_log }}</textarea>
</div>
</div>
{% elseif logs.retailcrm_error is defined %}
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> {{ logs.retailcrm_error }}
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
{% endif %}
</fieldset>
<fieldset>
<legend>Opencart API error log</legend>
<div class="retailcrm_unit">
<a onclick="confirm('{{ text_confirm_log }}') ? location.href='{{ clear_opencart }}' : false;" data-toggle="tooltip" title="{{ button_clear }}" class="btn btn-danger"><i class="fa fa-eraser"></i></a>
</div>
{% if logs.oc_api_log is defined %}
<div class="row">
<div class="col-sm-12">
<textarea wrap="off" rows="15" readonly class="form-control">{{ logs.oc_api_log }}</textarea>
</div>
</div>
{% elseif logs.oc_error is defined %}
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> {{ logs.oc_error }}
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
{% endif %}
</fieldset>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{{ footer }}
<script type="text/javascript">
var token = '{{ user_token }}';
$('#icml').on('click', function() {
$.ajax({
url: '{{ catalog }}' + 'admin/index.php?route=extension/module/retailcrm/icml&user_token=' + token,
beforeSend: function() {
$('#icml').button('loading');
},
complete: function() {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i> {{ text_success_catalog }}</div>');
$('#icml').button('reset');
},
error: function(){
alert('error');
}
});
});
$('#export').on('click', function() {
$.ajax({
url: '{{ catalog }}' + 'admin/index.php?route=extension/module/retailcrm/export&user_token=' + token,
beforeSend: function() {
$('#export').button('loading');
},
complete: function() {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i> {{ text_success_export }}</div>');
$('#export').button('reset');
},
error: function(){
alert('error');
}
});
});
$('#export_order').on('click', function() {
var order_id = $('input[name=\'order_id\']').val();
if (order_id && order_id > 0) {
$.ajax({
url: '{{ catalog }}' + 'admin/index.php?route=extension/module/retailcrm/exportOrder&user_token=' + token + '&order_id=' + order_id,
beforeSend: function() {
$('#export_order').button('loading');
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
},
success: function(data, textStatus, jqXHR) {
response = JSON.parse(jqXHR['responseText']);
if (response['status_code'] == '400') {
$('.alert-danger').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i>{{ text_error_order }}' + response['error_msg'] + '</div>');
$('#export_order').button('reset');
} else {
$('.alert-success').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-success"><i class="fa fa-exclamation-circle"></i>{{ text_success_export_order }}</div>');
$('#export_order').button('reset');
$('input[name=\'order_id\']').val('');
}
}
});
} else {
$('.alert-danger').remove();
$('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> {{ text_error_order_id }}</div>');
$('#export_order').button('reset');
}
});
</script>

View file

@ -1,6 +1,6 @@
<?php
class ControllerApiRetailcrm extends Controller
class ControllerApiRetailcrm extends Controller
{
public function getDeliveryTypes()
{
@ -13,11 +13,14 @@ class ControllerApiRetailcrm extends Controller
$this->load->model('setting/setting');
$this->load->library('retailcrm/retailcrm');
$moduleTitle = $this->retailcrm->getModuleTitle();
$countries = $this->model_setting_setting->getSetting($moduleTitle)[$moduleTitle . '_country'];
$setting = $this->model_setting_setting->getSetting($moduleTitle);
$response = array();
foreach ($countries as $country) {
$response = array_merge($response, $this->getDeliveryTypesByZones($country));
if (isset($setting[$moduleTitle . '_country']) && $setting[$moduleTitle . '_country']) {
foreach ($setting[$moduleTitle . '_country'] as $country) {
$response = $this->mergeDeliveryTypes($country, $response);
}
}
}
@ -42,7 +45,9 @@ class ControllerApiRetailcrm extends Controller
$response = array('error' => 'Not found data');
} else {
$this->load->model('checkout/order');
\retailcrm\Retailcrm::$history_run = true;
$this->model_checkout_order->addOrderHistory($this->request->post['order_id'], $this->request->post['order_status_id']);
\retailcrm\Retailcrm::$history_run = false;
$response = array('success' => true);
}
@ -58,7 +63,7 @@ class ControllerApiRetailcrm extends Controller
}
protected function getDeliveryTypesByZones($country_id)
{
{
$this->loadModels();
$this->load->model('localisation/zone');
$this->load->model('localisation/country');
@ -72,13 +77,13 @@ class ControllerApiRetailcrm extends Controller
$address = array(
'country_id' => $country_id,
'zone_id' => $zone['zone_id'],
'iso_code_2' => $country['iso_code_2'],
'iso_code_3' => $country['iso_code_3'],
'iso_code_2' => $country['iso_code_2'] ?? '',
'iso_code_3' => $country['iso_code_3'] ?? '',
'zone_code' => $zone['code'],
'postcode' => '',
'city' => ''
);
foreach ($shippingModules as $shippingModule) {
$this->load->model('extension/shipping/' . $shippingModule['code']);
@ -96,7 +101,7 @@ class ControllerApiRetailcrm extends Controller
$this->config->set('free_total', 0);
}
}
if ($this->{'model_extension_shipping_' . $shippingModule['code']}->getQuote($address)) {
$quote_data[] = $this->{'model_extension_shipping_' . $shippingModule['code']}->getQuote($address);
} else {
@ -129,6 +134,20 @@ class ControllerApiRetailcrm extends Controller
return $deliveryTypes;
}
private function mergeDeliveryTypes($country, $result) {
$delivery_types = $this->getDeliveryTypesByZones($country);
foreach ($delivery_types as $shipping_module => $shipping_type) {
if (isset($result[$shipping_module])) {
$result[$shipping_module] = array_merge($result[$shipping_module], $shipping_type);
} else {
$result[$shipping_module] = $shipping_type;
}
}
return $result;
}
private function auth()
{
if (!isset($this->request->get['key'])
@ -145,20 +164,16 @@ class ControllerApiRetailcrm extends Controller
if ( version_compare(VERSION, '3.0', '<')) {
$api = $this->model_account_api->getApiByKey($this->request->get['key']);
} else {
$api = $this->model_account_api->login($this->request->get['username'], $this->request->get['key']);
if (empty($api)) {
$this->load->model('extension/retailcrm/api');
$api = $this->model_extension_retailcrm_api->login($this->request->get['username'], $this->request->get['key']);
}
$this->load->model('extension/retailcrm/api');
$api = $this->model_extension_retailcrm_api->login($this->request->get['username'], $this->request->get['key']);
}
if (!empty($api)) {
return $api;
}
return array('error' => 'Invalid api key');
}
return array('error' => 'Invalid api key');
}
private function loadModels()

View file

@ -1,4 +1,5 @@
<?php
class ControllerExtensionAnalyticsDaemonCollector extends Controller {
public function index() {
$this->load->model('setting/setting');

View file

@ -0,0 +1,17 @@
<?php
class ControllerExtensionAnalyticsOnlineConsultant extends Controller {
/**
* @return string
*/
public function index() {
$this->load->model('setting/setting');
$this->load->library('retailcrm/retailcrm');
$moduleTitle = $this->retailcrm->getModuleTitle();
$settings = $this->model_setting_setting->getSetting($moduleTitle);
$setting = trim($settings['module_retailcrm_online_consultant_code']);
return html_entity_decode($setting, ENT_QUOTES, 'UTF-8');
}
}

View file

@ -0,0 +1,177 @@
<?php
class ControllerExtensionModuleRetailcrm extends Controller {
private $retailcrmApiClient;
public function __construct($registry)
{
parent::__construct($registry);
$this->load->library('retailcrm/retailcrm');
$this->retailcrmApiClient = $this->retailcrm->getApiClient();
}
/**
* Create order on event
*
* @param string $trigger
* @param array $data
* @param int $order_id order identificator
*
* @return void
*/
public function order_create($trigger, $data, $order_id = null) {
if (\retailcrm\Retailcrm::$history_run === true) {
return;
}
$this->load->library('retailcrm/retailcrm');
$order_data = $this->model_checkout_order->getOrder($order_id);
$products = $this->model_account_order->getOrderProducts($order_id);
$totals = $this->model_account_order->getOrderTotals($order_id);
$moduleTitle = $this->retailcrm->getModuleTitle();
foreach ($products as $key => $product) {
$productOptions = $this->model_account_order->getOrderOptions($order_id, $product['order_product_id']);
if (!empty($productOptions)) {
$products[$key]['option'] = $productOptions;
}
}
$this->load->model('setting/setting');
$status = $this->model_setting_setting->getSetting($moduleTitle);
if (isset($order_data['order_status_id']) && $order_data['order_status_id'] > 0) {
$order_data['order_status'] = $status[$moduleTitle . '_status'][$order_data['order_status_id']];
}
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/order.php')) {
$this->load->model('extension/retailcrm/custom/order');
$order_data['products'] = $products;
$order_data['totals'] = $totals;
$order = $this->model_extension_retailcrm_custom_order->processOrder($order_data);
$this->model_extension_retailcrm_custom_order->sendToCrm($order, $this->retailcrmApiClient, $order_data);
} else {
$order_manager = $this->retailcrm->getOrderManager();
$order_manager->createOrder($order_data, $products, $totals);
}
}
/**
* Update order on event
*
* @param string $trigger
* @param array $parameter2
*
* @return void
*/
public function order_edit($trigger, $parameter2 = null) {
if (\retailcrm\Retailcrm::$history_run === true) {
return;
}
$order_id = $parameter2[0];
$this->load->library('retailcrm/retailcrm');
$moduleTitle = $this->retailcrm->getModuleTitle();
$data = $this->model_checkout_order->getOrder($order_id);
if ($data['order_status_id'] == 0) {
return;
}
$products = $this->model_account_order->getOrderProducts($order_id);
$totals = $this->model_account_order->getOrderTotals($order_id);
foreach ($products as $key => $product) {
$productOptions = $this->model_account_order->getOrderOptions($order_id, $product['order_product_id']);
if (!empty($productOptions)) {
$products[$key]['option'] = $productOptions;
}
}
if (!isset($data['fromApi'])) {
$status = $this->model_setting_setting->getSetting($moduleTitle);
if ($data['order_status_id'] > 0) {
$data['order_status'] = $status[$moduleTitle . '_status'][$data['order_status_id']];
}
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/order.php')) {
$this->load->model('extension/retailcrm/custom/order');
$data['products'] = $products;
$data['totals'] = $totals;
$order = $this->model_extension_retailcrm_custom_order->processOrder($data, false);
$this->model_extension_retailcrm_custom_order->sendToCrm($order, $this->retailcrmApiClient, $data, false);
} else {
$order_manager = $this->retailcrm->getOrderManager();
$order_manager->editOrder($data, $products, $totals);
}
}
}
/**
* Create customer on event
*
* @param int $customerId customer identificator
*
* @return void
*/
public function customer_create($parameter1, $parameter2 = null, $parameter3 = null) {
$customerId = $parameter3;
$customer = $this->model_account_customer->getCustomer($customerId);
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/customer.php')) {
$this->load->model('extension/retailcrm/custom/customer');
$this->model_extension_retailcrm_custom_customer->sendToCrm($customer, $this->retailcrmApiClient);
} else {
$address = array();
$customer_manager = $this->retailcrm->getCustomerManager();
$customer_manager->createCustomer($customer, $address);
}
}
public function customer_edit_newsletter($parameter1, $parameter2, $parameter3)
{
$customerId = $this->customer->getId();
$customer = $this->model_account_customer->getCustomer($customerId);
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/customer.php')) {
$this->load->model('extension/retailcrm/custom/customer');
$this->model_extension_retailcrm_custom_customer->changeInCrm($customer, $this->retailcrmApiClient);
} else {
$customer_manager = $this->retailcrm->getCustomerManager();
$customer_manager->editCustomerNewsLetter($customer);
}
}
/**
* Update customer on event
*
* @param int $customerId customer identificator
*
* @return void
*/
public function customer_edit($parameter1, $parameter2, $parameter3) {
$customerId = $this->customer->getId();
$customer = $this->model_account_customer->getCustomer($customerId);
$address = $this->model_account_address->getAddress($customer['address_id']);
if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/customer.php')) {
$this->load->model('extension/retailcrm/custom/customer');
$customer['address'] = $address;
$this->model_extension_retailcrm_custom_customer->changeInCrm($customer, $this->retailcrmApiClient);
} else {
$customer_manager = $this->retailcrm->getCustomerManager();
$customer_manager->editCustomer($customer, $address);
}
}
}

View file

@ -0,0 +1,449 @@
<?php
class ModelExtensionRetailcrmOrder extends Model {
protected $settings;
protected $moduleTitle;
public function __construct($registry) {
parent::__construct($registry);
$this->load->model('setting/setting');
$this->load->library('retailcrm/retailcrm');
$this->moduleTitle = $this->retailcrm->getModuleTitle();
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
}
/**
* Create order in CRM
*
* @param array $order
* @param \RetailcrmProxy $retailcrmApiClient
* @param array $data
* @param bool $create (default = true)
*
* @return mixed
*/
public function sendToCrm($order, $retailcrmApiClient, $data, $create = true) {
if ($retailcrmApiClient === false) {
return false;
}
if (!isset($order['customer']['externalId'])) {
$customer = $this->searchCustomer($order['phone'], $order['email'], $retailcrmApiClient);
if ($customer) {
$order['customer']['id'] = $customer['id'];
}
}
if (!isset($order['customer']['externalId']) && !isset($order['customer']['id'])) {
$res = $this->createCustomer($data, $retailcrmApiClient);
if ($res->isSuccessful() && isset($res['id'])) {
$order['customer']['id'] = $res['id'];
}
}
if ($create) {
$order = self::filterRecursive($order);
$response = $retailcrmApiClient->ordersCreate($order);
if (isset($response['errors']['customer.externalId'])) {
$res = $this->createCustomer($data, $retailcrmApiClient);
if ($res->isSuccessful() && isset($res['id'])) {
$order['customer']['id'] = $res['id'];
}
$retailcrmApiClient->ordersCreate($order);
}
} else {
$order_payment = reset($order['payments']);
unset($order['payments']);
$order = self::filterRecursive($order);
$response = $retailcrmApiClient->ordersEdit($order);
if (isset($response['errors']['customer.externalId'])) {
$res = $this->createCustomer($data, $retailcrmApiClient);
if ($res->isSuccessful() && isset($res['id'])) {
$order['customer']['id'] = $res['id'];
}
$response = $retailcrmApiClient->ordersEdit($order);
}
if ($response->isSuccessful()) {
$this->updatePayment($order_payment, $order['externalId'], $retailcrmApiClient);
}
}
return $order;
}
/**
* Process order
*
* @param array $order_data
* @param bool $create (default = true)
*
* @return array $order
*/
public function processOrder($order_data, $create = true) {
$this->load->model('setting/setting');
$this->load->model('catalog/product');
$this->load->model('account/customer');
$this->load->model('extension/retailcrm/product');
$this->settings = $this->model_setting_setting->getSetting($this->moduleTitle);
$order_id = $order_data['order_id'];
if (!empty($order_data['payment_code']) && isset($this->settings[$this->moduleTitle . '_payment'][$order_data['payment_code']])) {
$payment_code = $this->settings[$this->moduleTitle . '_payment'][$order_data['payment_code']];
} else {
$payment_code = '';
}
if (!empty($order_data['shipping_code'])) {
$shippingCode = explode('.', $order_data['shipping_code']);
$shippingModule = $shippingCode[0];
if (isset($this->settings[$this->moduleTitle . '_delivery'][$order_data['shipping_code']])) {
$delivery_code = $this->settings[$this->moduleTitle . '_delivery'][$order_data['shipping_code']];
} elseif (isset($this->settings[$this->moduleTitle . '_delivery'][$shippingModule])) {
$delivery_code = $this->settings[$this->moduleTitle . '_delivery'][$shippingModule];
}
}
if (!isset($delivery_code) && isset($shippingModule)) {
if (isset($this->settings[$this->moduleTitle . '_delivery'])
&& $this->settings[$this->moduleTitle . '_delivery']
) {
$deliveries = array_keys($this->settings[$this->moduleTitle . '_delivery']);
$shipping_code = '';
array_walk($deliveries, function ($item, $key) use ($shippingModule, &$shipping_code) {
if (strripos($item, $shippingModule) !== false) {
$shipping_code = $item;
}
});
$delivery_code = $this->settings[$this->moduleTitle . '_delivery'][$shipping_code];
}
}
if (!empty($order_data['shipping_iso_code_2'])) {
$order['countryIso'] = $order_data['shipping_iso_code_2'];
}
if (isset($this->settings[$this->moduleTitle . '_order_number'])
&& $this->settings[$this->moduleTitle . '_order_number'] == 1
) {
$order['number'] = $order_data['order_id'];
}
if (isset($this->settings[$this->moduleTitle . '_summ_around'])
&& $this->settings[$this->moduleTitle . '_summ_around'] == 1
) {
$order['applyRound'] = true;
}
$order['externalId'] = $order_id;
$order['firstName'] = $order_data['shipping_firstname'];
$order['lastName'] = $order_data['shipping_lastname'];
$order['phone'] = $order_data['telephone'];
$order['customerComment'] = $order_data['comment'];
if ($order_data['customer_id']) {
$order['customer']['externalId'] = $order_data['customer_id'];
}
if (!empty($order_data['email'])) {
$order['email'] = $order_data['email'];
}
$deliveryCost = 0;
$couponTotal = 0;
$orderTotals = isset($order_data['totals']) ? $order_data['totals'] : $order_data['order_total'] ;
$totals = $this->explodeTotals($orderTotals);
if (isset($totals['shipping'])) {
$deliveryCost = $totals['shipping'];
}
if (isset($totals['coupon'])) {
$couponTotal += abs($totals['coupon']);
}
if (isset($totals['reward'])) {
$couponTotal += abs($totals['reward']);
}
$order['createdAt'] = $order_data['date_added'];
if ($couponTotal > 0) {
$order['discountManualAmount'] = $couponTotal;
}
$country = isset($order_data['shipping_country']) ? $order_data['shipping_country'] : '' ;
$order['delivery'] = array(
'code' => isset($delivery_code) ? $delivery_code : '',
'address' => array(
'index' => $order_data['shipping_postcode'],
'city' => $order_data['shipping_city'],
'countryIso' => $order_data['shipping_iso_code_2'],
'region' => $order_data['shipping_zone'],
'text' => implode(', ', array(
$order_data['shipping_postcode'],
$country,
$order_data['shipping_city'],
$order_data['shipping_address_1'],
$order_data['shipping_address_2']
))
)
);
if (!empty($deliveryCost)){
$order['delivery']['cost'] = $deliveryCost;
}
$orderProducts = isset($order_data['products']) ? $order_data['products'] : $order_data['order_product'];
$offerOptions = array('select', 'radio');
foreach ($orderProducts as $product) {
$offerId = '';
if (!empty($product['option'])) {
$options = array();
$productOptions = $this->model_catalog_product->getProductOptions($product['product_id']);
foreach ($product['option'] as $option) {
if ($option['type'] == 'checkbox') {
$properties[] = array(
'code' => $option['product_option_value_id'],
'name' => $option['name'],
'value' => $option['value']
);
}
if (!in_array($option['type'], $offerOptions)) continue;
foreach($productOptions as $productOption) {
if($productOption['product_option_id'] = $option['product_option_id']) {
foreach($productOption['product_option_value'] as $productOptionValue) {
if($productOptionValue['product_option_value_id'] == $option['product_option_value_id']) {
$options[$option['product_option_id']] = $productOptionValue['option_value_id'];
}
}
}
}
}
ksort($options);
$offerId = array();
foreach ($options as $optionKey => $optionValue) {
$offerId[] = $optionKey.'-'.$optionValue;
}
$offerId = implode('_', $offerId);
}
$item = array(
'offer' => array(
'externalId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id']
),
'productName' => $product['name'],
'initialPrice' => $product['price'],
'quantity' => $product['quantity']
);
$specials = $this->model_extension_retailcrm_product->getProductSpecials($product['product_id']);
if (!empty($specials)) {
$customer = $this->model_account_customer->getCustomer($order_data['customer_id']);
foreach ($specials as $special) {
if (isset($customer['customer_group_id'])) {
if ($special['customer_group_id'] == $customer['customer_group_id']) {
if ($this->settings[$this->moduleTitle . '_special_' . $customer['customer_group_id']]) {
$item['priceType']['code'] = $this->settings[$this->moduleTitle . '_special_' . $customer['customer_group_id']];
}
}
}
}
}
if (isset($properties)) $item['properties'] = $properties;
$order['items'][] = $item;
}
if (isset($order_data['order_status_id']) && $order_data['order_status_id'] > 0) {
$order['status'] = $this->settings[$this->moduleTitle . '_status'][$order_data['order_status_id']];
} elseif (isset($order_data['order_status_id']) && $order_data['order_status_id'] == 0) {
$order['status'] = $this->settings[$this->moduleTitle . '_missing_status'];
}
if (isset($this->settings[$this->moduleTitle . '_custom_field']) && $order_data['custom_field']) {
$customFields = $order_data['custom_field'];
foreach ($customFields as $key => $value) {
if (isset($this->settings[$this->moduleTitle . '_custom_field']['o_' . $key])) {
$customFieldsToCrm[$this->settings[$this->moduleTitle . '_custom_field']['o_' . $key]] = $value;
}
}
if (isset($customFieldsToCrm)) {
$order['customFields'] = $customFieldsToCrm;
}
}
$payment = array(
'externalId' => $order_id,
'type' => $payment_code,
'amount' => $totals['total']
);
if (isset($this->settings[$this->moduleTitle . '_sum_payment']) &&
$this->settings[$this->moduleTitle . '_sum_payment'] == 1
) {
unset($payment['amount']);
}
if (!$create) {
$payment['order'] = array(
'externalId' => $order_id
);
}
$order['payments'][] = $payment;
return $order;
}
/**
* Update payment in CRM
*
* @param array $order_payment
* @param int $orderId
*
* @return void
*/
private function updatePayment($order_payment, $orderId, $retailcrmApiClient) {
$response_order = $retailcrmApiClient->ordersGet($orderId);
if ($response_order->isSuccessful()) {
$order_info = $response_order['order'];
}
foreach ($order_info['payments'] as $payment_data) {
if (isset($payment_data['externalId']) && $payment_data['externalId'] == $orderId) {
$payment = $payment_data;
}
}
if (isset($payment) && $payment['type'] != $order_payment['type']) {
$response = $retailcrmApiClient->ordersPaymentDelete($payment['id']);
if ($response->isSuccessful()) {
$retailcrmApiClient->ordersPaymentCreate($order_payment);
}
} elseif (isset($payment) && $payment['type'] == $order_payment['type']) {
$retailcrmApiClient->ordersPaymentEdit($order_payment);
}
}
private function searchCustomer($phone, $email, $retailcrmApiClient) {
$customer = array();
$response = $retailcrmApiClient->customersList(
array(
'name' => $phone,
'email' => $email
),
1,
100
);
if ($response->isSuccessful() && isset($response['customers'])) {
$customers = $response['customers'];
if ($customers) {
$customer = end($customers);
}
}
return $customer;
}
/**
* @param $totals
*
* @return array
*/
private function explodeTotals($totals)
{
$resultTotals = array();
foreach ($totals as $total) {
$resultTotals[$total['code']] = $total['value'];
}
return $resultTotals;
}
/**
* Recursive array filter
*
* @param array $haystack input array
*
* @return array
*/
public static function filterRecursive($haystack)
{
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = self::filterRecursive($haystack[$key]);
}
if ($haystack[$key] === null
|| $haystack[$key] === ''
|| (is_array($haystack[$key]) && empty($haystack[$key]))
) {
unset($haystack[$key]);
} elseif (!is_array($value)) {
$haystack[$key] = trim($value);
}
}
return $haystack;
}
/**
* @param array $data
* @param \RetailcrmProxy $retailcrmApiClient
*
* @return ApiResponse
*/
private function createCustomer($data, $retailcrmApiClient)
{
$customer = array(
'firstName' => $data['firstname'],
'lastName' => $data['lastname'],
'email' => $data['email'],
'createdAt' => $data['date_added'],
'externalId' => $data['customer_id'],
'address' => array(
'countryIso' => $data['payment_iso_code_2'],
'index' => $data['payment_postcode'],
'city' => $data['payment_city'],
'region' => $data['payment_zone'],
'text' => $data['payment_address_1'] . ' ' . $data['payment_address_2']
)
);
if (!empty($data['telephone'])) {
$customer['phones'] = array(
array(
'number' => $data['telephone']
)
);
}
return $retailcrmApiClient->customersCreate($customer);
}
}

View file

@ -0,0 +1,10 @@
<?php
class ModelExtensionRetailcrmProduct extends Model
{
public function getProductSpecials($product_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "' ORDER BY priority, price");
return $query->rows;
}
}

View file

@ -0,0 +1,11 @@
<?php
/**
* Class ModelExtensionTotalRetailcrmDiscount
*
* This class is unused in this module but used inside opencart as stub in file "catalog/model/checkout/order.php"
* in method addOrderHistory()
*/
class ModelExtensionTotalRetailcrmDiscount extends Model
{
}

View file

@ -0,0 +1,23 @@
<?php
namespace retailcrm;
/**
* Class Base
*
* @property \Loader load
* @property \DB db
* @property \Config config
* @property \Language language
*/
abstract class Base {
protected $registry;
public function __construct(\Registry $registry) {
$this->registry = $registry;
}
public function __get($name) {
return $this->registry->get($name);
}
}

View file

@ -62,13 +62,14 @@ class RetailcrmAutoloader
$directory = new RecursiveDirectoryIterator(self::$pathTop);
$fileIterator = new RecursiveIteratorIterator($directory);
$filename = $className . self::$fileExt;
$chunks = explode("\\", $filename);
$filename = end($chunks);
foreach ($fileIterator as $file) {
if (strtolower($file->getFilename()) === strtolower($filename) && $file->isReadable()) {
include_once $file->getPathname();
}
}
}
/**

View file

@ -1,4 +1,4 @@
<Files *.*>
Allow from all
Satisfy any
</Files>
Satisfy any
</Files>

View file

@ -12,7 +12,7 @@ if (!isset($cli_action)) {
// Version
$version = '2.3.0';
$indexFile = file_get_contents(realpath(dirname(__FILE__)) . '/../../index.php');
$indexFile = file_get_contents(realpath(dirname(__FILE__)) . '/../../../../index.php');
preg_match("/define\([\s]*['\"]VERSION['\"][\s]*,[\s]*['\"](.*)['\"][\s]*\)[\s]*;/mi", $indexFile, $versionMatches);
if (isset($versionMatches[1])) {
@ -22,7 +22,7 @@ if (isset($versionMatches[1])) {
define('VERSION', $version);
// Configuration (note we're using the admin config)
require_once(realpath(dirname(__FILE__)) . '/../../admin/config.php');
require_once(realpath(dirname(__FILE__)) . '/../../../../admin/config.php');
// Configuration check
if (!defined('DIR_APPLICATION')) {

View file

@ -0,0 +1,41 @@
<?php
namespace retailcrm;
class ModelsProvider extends Base {
public function includeDependencies() {
$dependencies = $this->getDependencies();
foreach ($dependencies[$this->getContext()] as $dependency) {
$this->load->model($dependency);
}
}
private function getContext() {
$match = preg_match('/\/catalog\/$/i', DIR_APPLICATION);
return $match === 1 ? 'catalog' : 'admin';
}
private function getDependencies() {
return array(
'catalog' => array(
'setting/setting',
'checkout/order',
'account/order',
'account/customer',
'account/address',
'localisation/country',
'localisation/zone',
'account/address',
'catalog/product',
),
'admin' => array(
'setting/setting',
'sale/order',
'customer/customer',
'catalog/product'
)
);
}
}

View file

@ -0,0 +1,34 @@
<?php
namespace retailcrm;
class Utils {
public static function filterRecursive($haystack) {
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = self::filterRecursive($haystack[$key]);
}
if ($haystack[$key] === null
|| $haystack[$key] === ''
|| (is_array($haystack[$key]) && empty($haystack[$key]))
) {
unset($haystack[$key]);
} elseif (!is_array($value)) {
$haystack[$key] = trim($value);
}
}
return $haystack;
}
public static function addressEquals($address1, $address2) {
foreach ($address1 as $field => $value) {
if (isset($address2[$field]) && $value !== $address2[$field]) {
return false;
}
}
return true;
}
}

View file

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

View file

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

View file

@ -30,8 +30,8 @@ class OpencartApiClient {
$cookieFile = explode("\n", $cookieFile);
$cookies = array();
foreach($cookieFile as $line) {
if(empty($line) OR $line{0} == '#') {
foreach ($cookieFile as $line) {
if (empty($line) OR $line[0] == '#') {
continue;
}

View file

@ -1,18 +1,11 @@
<?php
/**
* PHP version 5.3
*
* API client class
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion5
*/
class RetailcrmApiClient5
{
const VERSION = 'v5';
protected $client;
protected $clientWithoutVersion;
/**
* Site code
@ -22,40 +15,39 @@ class RetailcrmApiClient5
/**
* Client creating
*
* @param string $url api url
* @param string $url api url
* @param string $apiKey api key
* @param string $site site code
* @param string $site site code
*
* @throws \InvalidArgumentException
*
* @return mixed
*/
public function __construct($url, $apiKey, $version = null, $site = null)
public function __construct($url, $apiKey, $site = null)
{
if ('/' !== $url[strlen($url) - 1]) {
$url .= '/';
}
$url = $version == null ? $url . 'api' : $url . 'api/' . $version;
$this->client = new RetailcrmHttpClient($url, array('apiKey' => $apiKey));
$this->client = new RetailcrmHttpClient($url . 'api/' . static::VERSION, array('apiKey' => $apiKey));
$this->clientWithoutVersion = new RetailcrmHttpClient($url . 'api', array('apiKey' => $apiKey));
$this->siteCode = $site;
}
/**
* Returns api versions list
*
*
* @throws \RetailCrm\Exception\InvalidJsonException
* @throws \RetailCrm\Exception\CurlException
* @throws \InvalidArgumentException
*
*
* @return ApiResponse
*/
public function apiVersions()
{
return $this->client->makeRequest('/api-versions', RetailcrmHttpClient::METHOD_GET);
return $this->clientWithoutVersion->makeRequest('/api-versions', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns users list
*
@ -190,7 +182,7 @@ class RetailcrmApiClient5
$parameters
);
}
/**
* Create custom field
*
@ -223,7 +215,7 @@ class RetailcrmApiClient5
array('customField' => json_encode($customField))
);
}
/**
* Edit custom field
*
@ -592,30 +584,18 @@ class RetailcrmApiClient5
/**
* Get orders history
*
* @param array $filter
* @param null $page
* @param null $limit
* @param int|null $limit
*
* @return ApiResponse
*/
public function ordersHistory(array $filter = array(), $page = null, $limit = null)
public function ordersHistory(array $filter = [], ?int $limit = 100)
{
$parameters = array();
if (count($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest(
'/orders/history',
RetailcrmHttpClient::METHOD_GET,
$parameters
['filter' => $filter, 'limit' => $limit]
);
}
@ -730,7 +710,7 @@ class RetailcrmApiClient5
'Parameter `id` must be set'
);
}
return $this->client->makeRequest(
sprintf('/orders/payments/%s/delete', $id),
RetailcrmHttpClient::METHOD_POST
@ -916,30 +896,18 @@ class RetailcrmApiClient5
/**
* Get customers history
*
* @param array $filter
* @param null $page
* @param null $limit
* @param int|null $limit
*
* @return ApiResponse
*/
public function customersHistory(array $filter = array(), $page = null, $limit = null)
public function customersHistory(array $filter = [], ?int $limit = 100)
{
$parameters = array();
if (count($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest(
'/customers/history',
RetailcrmHttpClient::METHOD_GET,
$parameters
['filter' => $filter, 'limit' => $limit]
);
}
@ -1116,34 +1084,17 @@ class RetailcrmApiClient5
/**
* Get orders assembly history
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
*
* @throws \InvalidArgumentException
* @throws \RetailCrm\Exception\CurlException
* @throws \RetailCrm\Exception\InvalidJsonException
* @param array $filter
* @param int|null $limit
*
* @return ApiResponse
*/
public function ordersPacksHistory(array $filter = array(), $page = null, $limit = null)
public function ordersPacksHistory(array $filter = [], ?int $limit = 100)
{
$parameters = array();
if (count($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest(
'/orders/packs/history',
RetailcrmHttpClient::METHOD_GET,
$parameters
['filter' => $filter, 'limit' => $limit]
);
}
@ -2324,6 +2275,34 @@ class RetailcrmApiClient5
);
}
/**
* Edit module configuration
*
* @param array $configuration
*
* @throws \RetailCrm\Exception\InvalidJsonException
* @throws \RetailCrm\Exception\CurlException
* @throws \InvalidArgumentException
*
* @return ApiResponse
*/
public function integrationModulesEdit(array $configuration)
{
if (!count($configuration) || empty($configuration['code'])) {
throw new \InvalidArgumentException(
'Parameter `configuration` must contains a data & configuration `code` must be set'
);
}
$code = $configuration['code'];
return $this->client->makeRequest(
"/integration-modules/$code/edit",
RetailcrmHttpClient::METHOD_POST,
array('integrationModule' => json_encode($configuration))
);
}
/**
* Update CRM basic statistic
*
@ -2341,6 +2320,610 @@ class RetailcrmApiClient5
);
}
/**
* Returns filtered corporate customers list
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateList(array $filter = [], $page = null, $limit = null)
{
$parameters = [];
if (count($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest(
'/customers-corporate',
RetailcrmHttpClient::METHOD_GET,
$parameters
);
}
/**
* Create a corporate customer
*
* @param array $customerCorporate corporate customer data
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateCreate(array $customerCorporate, $site = null)
{
if (! count($customerCorporate)) {
throw new \InvalidArgumentException(
'Parameter `customerCorporate` must contains a data'
);
}
/* @noinspection PhpUndefinedMethodInspection */
return $this->client->makeRequest(
'/customers-corporate/create',
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, ['customerCorporate' => json_encode($customerCorporate)])
);
}
/**
* Save corporate customer IDs' (id and externalId) association in the CRM
*
* @param array $ids ids mapping
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateFixExternalIds(array $ids)
{
if (! count($ids)) {
throw new \InvalidArgumentException(
'Method parameter must contains at least one IDs pair'
);
}
/* @noinspection PhpUndefinedMethodInspection */
return $this->client->makeRequest(
'/customers-corporate/fix-external-ids',
RetailcrmHttpClient::METHOD_POST,
['customersCorporate' => json_encode($ids)]
);
}
/**
* Get corporate customers history
*
* @param array $filter
* @param int|null $limit
*
* @return ApiResponse
*/
public function customersCorporateHistory(array $filter = [], ?int $limit = 100)
{
return $this->client->makeRequest(
'/customers-corporate/history',
RetailcrmHttpClient::METHOD_GET,
['filter' => $filter, 'limit' => $limit]
);
}
/**
* Returns filtered corporate customers notes list
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateNotesList(array $filter = [], $page = null, $limit = null)
{
$parameters = [];
if (count($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest(
'/customers-corporate/notes',
RetailcrmHttpClient::METHOD_GET,
$parameters
);
}
/**
* Create corporate customer note
*
* @param array $note (default: array())
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateNotesCreate($note, $site = null)
{
if (empty($note['customer']['id']) && empty($note['customer']['externalId'])) {
throw new \InvalidArgumentException(
'Customer identifier must be set'
);
}
return $this->client->makeRequest(
'/customers-corporate/notes/create',
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, ['note' => json_encode($note)])
);
}
/**
* Delete corporate customer note
*
* @param integer $id
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateNotesDelete($id)
{
if (empty($id)) {
throw new \InvalidArgumentException(
'Note id must be set'
);
}
return $this->client->makeRequest(
"/customers-corporate/notes/$id/delete",
RetailcrmHttpClient::METHOD_POST
);
}
/**
* Upload array of the corporate customers
*
* @param array $customersCorporate array of corporate customers
* @param string $site (default: null)
*
* @return \ApiResponse
* @throws \CurlException
* @throws \InvalidJsonException
*
* @throws \InvalidArgumentException
*/
public function customersCorporateUpload(array $customersCorporate, $site = null)
{
if (!count($customersCorporate)) {
throw new \InvalidArgumentException(
'Parameter `customersCorporate` must contains array of the corporate customers'
);
}
return $this->client->makeRequest(
'/customers-corporate/upload',
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, ['customersCorporate' => json_encode($customersCorporate)])
);
}
/**
* Get corporate customer by id or externalId
*
* @param string $id corporate customer identifier
* @param string $by (default: 'externalId')
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateGet($id, $by = 'externalId', $site = null)
{
$this->checkIdParameter($by);
return $this->client->makeRequest(
"/customers-corporate/$id",
RetailcrmHttpClient::METHOD_GET,
$this->fillSite($site, ['by' => $by])
);
}
/**
* Get corporate customer addresses by id or externalId
*
* @param string $id corporate customer identifier
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @param string $by (default: 'externalId')
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateAddresses(
$id,
array $filter = [],
$page = null,
$limit = null,
$by = 'externalId',
$site = null
) {
$this->checkIdParameter($by);
$parameters = ['by' => $by];
if (count($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest(
"/customers-corporate/$id/addresses",
RetailcrmHttpClient::METHOD_GET,
$this->fillSite($site, $parameters)
);
}
/**
* Create corporate customer address
*
* @param string $id corporate customer identifier
* @param array $address (default: array())
* @param string $by (default: 'externalId')
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateAddressesCreate($id, array $address = [], $by = 'externalId', $site = null)
{
return $this->client->makeRequest(
"/customers-corporate/$id/addresses/create",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, ['address' => json_encode($address), 'by' => $by])
);
}
/**
* Edit corporate customer address
*
* @param string $customerId corporate customer identifier
* @param string $addressId corporate customer identifier
* @param array $address (default: array())
* @param string $customerBy (default: 'externalId')
* @param string $addressBy (default: 'externalId')
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateAddressesEdit(
$customerId,
$addressId,
array $address = [],
$customerBy = 'externalId',
$addressBy = 'externalId',
$site = null
) {
$addressFiltered = array_filter($address);
if ((count(array_keys($addressFiltered)) <= 1)
&& (!isset($addressFiltered['text'])
|| (isset($addressFiltered['text']) && empty($addressFiltered['text']))
)
) {
throw new \InvalidArgumentException(
'Parameter `address` must contain address text or all other address field'
);
}
return $this->client->makeRequest(
"/customers-corporate/$customerId/addresses/$addressId/edit",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, [
'address' => json_encode($address),
'by' => $customerBy,
'entityBy' => $addressBy
])
);
}
/**
* Get corporate customer companies by id or externalId
*
* @param string $id corporate customer identifier
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @param string $by (default: 'externalId')
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateCompanies(
$id,
array $filter = [],
$page = null,
$limit = null,
$by = 'externalId',
$site = null
) {
$this->checkIdParameter($by);
$parameters = ['by' => $by];
if (count($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest(
"/customers-corporate/$id/companies",
RetailcrmHttpClient::METHOD_GET,
$this->fillSite($site, $parameters)
);
}
/**
* Create corporate customer company
*
* @param string $id corporate customer identifier
* @param array $company (default: array())
* @param string $by (default: 'externalId')
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateCompaniesCreate($id, array $company = [], $by = 'externalId', $site = null)
{
return $this->client->makeRequest(
"/customers-corporate/$id/companies/create",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, ['company' => json_encode($company), 'by' => $by])
);
}
/**
* Edit corporate customer company
*
* @param string $customerId corporate customer identifier
* @param string $companyId corporate customer identifier
* @param array $company (default: array())
* @param string $customerBy (default: 'externalId')
* @param string $companyBy (default: 'externalId')
* @param string $site (default: null)
*
* @return \ApiResponse
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
*/
public function customersCorporateCompaniesEdit(
$customerId,
$companyId,
array $company = [],
$customerBy = 'externalId',
$companyBy = 'externalId',
$site = null
) {
return $this->client->makeRequest(
"/customers-corporate/$customerId/companies/$companyId/edit",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, [
'company' => json_encode($company),
'by' => $customerBy,
'entityBy' => $companyBy
])
);
}
/**
* Get corporate customer contacts by id or externalId
*
* @param string $id corporate customer identifier
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @param string $by (default: 'externalId')
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateContacts(
$id,
array $filter = [],
$page = null,
$limit = null,
$by = 'externalId',
$site = null
) {
$this->checkIdParameter($by);
$parameters = ['by' => $by];
if (count($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest(
"/customers-corporate/$id/contacts",
RetailcrmHttpClient::METHOD_GET,
$this->fillSite($site, $parameters)
);
}
/**
* Create corporate customer contact
*
* @param string $id corporate customer identifier
* @param array $contact (default: array())
* @param string $by (default: 'externalId')
* @param string $site (default: null)
*
* @return \ApiResponse
* @throws \CurlException
* @throws \InvalidJsonException
*
* @throws \InvalidArgumentException
*/
public function customersCorporateContactsCreate($id, array $contact = [], $by = 'externalId', $site = null)
{
return $this->client->makeRequest(
"/customers-corporate/$id/contacts/create",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, ['contact' => json_encode($contact), 'by' => $by])
);
}
/**
* Edit corporate customer contact
*
* @param string $customerId corporate customer identifier
* @param string $contactId corporate customer identifier
* @param array $contact (default: array())
* @param string $customerBy (default: 'externalId')
* @param string $contactBy (default: 'externalId')
* @param string $site (default: null)
*
* @return \ApiResponse
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
*/
public function customersCorporateContactsEdit(
$customerId,
$contactId,
array $contact = [],
$customerBy = 'externalId',
$contactBy = 'externalId',
$site = null
) {
return $this->client->makeRequest(
"/customers-corporate/$customerId/contacts/$contactId/edit",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, [
'contact' => json_encode($contact),
'by' => $customerBy,
'entityBy' => $contactBy
])
);
}
/**
* Edit a corporate customer
*
* @param array $customerCorporate corporate customer data
* @param string $by (default: 'externalId')
* @param string $site (default: null)
*
* @throws \InvalidArgumentException
* @throws \CurlException
* @throws \InvalidJsonException
*
* @return \ApiResponse
*/
public function customersCorporateEdit(array $customerCorporate, $by = 'externalId', $site = null)
{
if (!count($customerCorporate)) {
throw new \InvalidArgumentException(
'Parameter `customerCorporate` must contains a data'
);
}
$this->checkIdParameter($by);
if (!array_key_exists($by, $customerCorporate)) {
throw new \InvalidArgumentException(
sprintf('Corporate customer array must contain the "%s" parameter.', $by)
);
}
return $this->client->makeRequest(
sprintf('/customers-corporate/%s/edit', $customerCorporate[$by]),
RetailcrmHttpClient::METHOD_POST,
$this->fillSite(
$site,
['customerCorporate' => json_encode($customerCorporate), 'by' => $by]
)
);
}
/**
* Return current site
*

View file

@ -1,15 +1,5 @@
<?php
/**
* PHP version 5.3
*
* Response from retailCRM API
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
class RetailcrmApiResponse implements ArrayAccess
{
// HTTP response status code

View file

@ -41,15 +41,13 @@ class RetailcrmHistoryHelper {
$orders[$change['order']['id']]['items'][$change['item']['id']] = $change['item'];
}
if (isset($change['oldValue'])
&& empty($change['oldValue'])
if (empty($change['oldValue'])
&& $change['field'] == 'order_product'
) {
$orders[$change['order']['id']]['items'][$change['item']['id']]['create'] = true;
}
if (isset($change['newValue'])
&& empty($change['newValue'])
if (empty($change['newValue'])
&& $change['field'] == 'order_product'
) {
$orders[$change['order']['id']]['items'][$change['item']['id']]['delete'] = true;
@ -95,7 +93,7 @@ class RetailcrmHistoryHelper {
{
$customers = array();
foreach ($customerHistory as $change) {
$change['order'] = self::removeEmpty($change['customer']);
$change['customer'] = self::removeEmpty($change['customer']);
if(!empty($customers[$change['customer']['id']]) && $customers[$change['customer']['id']]) {
$customers[$change['customer']['id']] = array_merge($customers[$change['customer']['id']], $change['customer']);

View file

@ -1,15 +1,7 @@
<?php
/**
* PHP version 5.3
*
* HTTP client
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
*/
use retailcrm\Retailcrm;
class RetailcrmHttpClient
{
const METHOD_GET = 'GET';
@ -56,9 +48,9 @@ class RetailcrmHttpClient
public function makeRequest(
$path,
$method,
array $parameters = array()
array $parameters = []
) {
$allowedMethods = array(self::METHOD_GET, self::METHOD_POST);
$allowedMethods = [self::METHOD_GET, self::METHOD_POST];
if (!in_array($method, $allowedMethods, false)) {
throw new \InvalidArgumentException(
@ -70,7 +62,16 @@ class RetailcrmHttpClient
);
}
$parameters = array_merge($this->defaultParameters, $parameters);
$parameters = self::METHOD_GET === $method
? array_merge($this->defaultParameters, $parameters, [
'cms_source' => 'OpenCart',
'cms_version' => VERSION,
'php_version' => function_exists('phpversion') ? phpversion() : '',
'module_version' => Retailcrm::VERSION_MODULE,
])
: $parameters = array_merge($this->defaultParameters, $parameters);
$url = $this->url . $path;

View file

@ -0,0 +1,55 @@
<?php
/**
* Class RequestProxy
*
* @method ordersCreate($order, $site = null)
* @method ordersEdit($order, $by = 'externalId', $site = null)
* @method ordersGet($order, $by = 'externalId', $site = null)
* @method ordersList(array $filter = [], $page = null, $limit = null)
* @method customersCreate($customer, $site = null)
* @method customersEdit($customer, $by = 'externalId', $site = null)
* @method customersList(array $filter = [], $page = null, $limit = null)
* @method customersGet($id, $by = 'externalId', $site = null)
* @method customersCorporateList(array $filter = [], $page = null, $limit = null)
* @method customersCorporateCreate(array $customerCorporate, $site = null)
* @method customersCorporateAddresses($id, array $filter = [], $page = null, $limit = null, $by = 'externalId', $site = null)
* @method customersCorporateAddressesCreate($id, array $address = [], $by = 'externalId', $site = null)
* @method customersCorporateAddressesEdit($customerId, $addressId, array $address = [], $customerBy = 'externalId', $addressBy = 'externalId', $site = null)
* @method customersCorporateCompanies($id, array $filter = [], $page = null, $limit = null, $by = 'externalId', $site = null)
* @method customersCorporateCompaniesCreate($id, array $company = [], $by = 'externalId', $site = null)
* @method customersCorporateCompaniesEdit($customerId, $companyId, array $company = [], $customerBy = 'externalId', $companyBy = 'externalId', $site = null)
* @method customersCorporateContacts($id, array $filter = [], $page = null, $limit = null, $by = 'externalId', $site = null)
*/
class RetailcrmProxy {
private $api;
private $log;
public function __construct($url, $key) {
$this->api = new RetailcrmApiClient5($url, $key);
$this->log = new \Log('retailcrm.log');
}
public function __call($method, $arguments) {
try {
$response = call_user_func_array([$this->api, $method], $arguments);
if (!$response->isSuccessful()) {
$this->log->write(sprintf("[%s] %s", $method, $response->getErrorMsg()));
if (isset($response['errors'])) {
$error = implode("\n", $response['errors']);
$this->log->write($error . "\n");
}
}
return $response;
} catch (CurlException $e) {
$this->log->write(sprintf("[%s] %s", $method, $e->getMessage()));
return false;
} catch (InvalidJsonException $e) {
$this->log->write(sprintf("[%s] %s", $method, $e->getMessage()));
return false;
}
}
}

View file

@ -0,0 +1,12 @@
<?php
namespace retailcrm\factory;
use retailcrm\service\RetailcrmCustomerConverter;
use retailcrm\service\SettingsManager;
class CustomerConverterFactory {
public static function create(\Registry $registry) {
return new RetailcrmCustomerConverter(new SettingsManager($registry));
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace retailcrm\factory;
use retailcrm\service\RetailcrmOrderConverter;
use retailcrm\service\SettingsManager;
use retailcrm\repository\CustomerRepository;
use retailcrm\repository\ProductsRepository;
class OrderConverterFactory {
public static function create(\Registry $registry) {
return new RetailcrmOrderConverter(
new SettingsManager($registry),
new CustomerRepository($registry),
new ProductsRepository($registry)
);
}
}

View file

@ -0,0 +1,119 @@
<?php
namespace retailcrm\history;
use retailcrm\repository\CustomerRepository;
use retailcrm\repository\DataRepository;
use retailcrm\service\SettingsManager;
class Customer {
private $data_repository;
private $customer_repository;
private $settings_manager;
public function __construct(
DataRepository $data_repository,
CustomerRepository $customer_repository,
SettingsManager $settings_manager
) {
$this->data_repository = $data_repository;
$this->customer_repository = $customer_repository;
$this->settings_manager = $settings_manager;
}
public function handleCustomer(&$customer_data, $customer) {
// is new customer
if (!$customer_data) {
$customer_data['store_id'] = 0;
$customer_data['customer_group_id'] = '1';
$customer_data['fax'] = '';
$customer_data['newsletter'] = 0;
$customer_data['password'] = 'tmppass';
$customer_data['status'] = 1;
$customer_data['approved'] = 1;
$customer_data['safe'] = 0;
$customer_data['affiliate'] = '';
} else {
$customer_data['password'] = false;
}
$customer_data['firstname'] = $customer['firstName'];
$customer_data['lastname'] = $customer['lastName'] ?? '';
$customer_data['email'] = $customer['email'];
$customer_data['telephone'] = $customer['phones'] ? $customer['phones'][0]['number'] : '';
if (!empty($customer['emailMarketingUnsubscribedAt'])) {
$customer_data['newsletter'] = 0;
}
$customer_data['affiliate'] = false;
}
public function handleAddress($customer, $order, $address_id = 0) {
if (empty($customer['address']) && !empty($order)) {
$customer['address'] = $order['delivery']['address'];
}
if ($address_id) {
$customer_address = $this->customer_repository->getAddress($address_id);
} else {
$customer_address = array(
'address_id' => ''
);
}
if (isset($customer['address']['countryIso'])) {
$customer_country = $this->data_repository->getCountryByIsoCode($customer['address']['countryIso']);
}
if (isset($customer['address']['region'])) {
$customer_zone = $this->data_repository->getZoneByName($customer['address']['region']);
}
$customer_address['firstname'] = isset($customer['patronymic'])
? $customer['firstName'] . ' ' . $customer['patronymic']
: $customer['firstName'];
$customer_address['lastname'] = isset($customer['lastName']) ? $customer['lastName'] : '';
$customer_address['address_2'] = !empty($customer_address['address_2']) ? $customer_address['address_2'] : '';
$customer_address['company'] = !empty($customer_address['company']) ? $customer_address['company'] : '';
if (!empty($customer['address'])) {
$customer_address['address_1'] = !empty($customer['address']['text']) ? $customer['address']['text'] : '';
$customer_address['city'] = !empty($customer['address']['city']) ? $customer['address']['city'] : '';
$customer_address['postcode'] = isset($customer['address']['index']) ? $customer['address']['index'] : '';
}
$customer_address['zone_id'] = 0;
$customer_address['country_id'] = 0;
if (isset($customer_country)) {
$customer_address['country_id'] = $customer_country['country_id'];
}
if (isset($customer_zone) && isset($customer_zone['zone_id'])) {
$customer_address['zone_id'] = $customer_zone['zone_id'];
}
$customer_address['default'] = true;
return $customer_address;
}
public function handleCustomFields(&$customer_data, $customer) {
$settings = $this->settings_manager->getSetting('custom_field');
if (!empty($settings)) {
$custom_field_setting = array_flip($settings);
}
if (isset($custom_field_setting) && $customer['customFields']) {
foreach ($customer['customFields'] as $code => $value) {
if (array_key_exists($code, $custom_field_setting)) {
$field_code = str_replace('c_', '', $custom_field_setting[$code]);
$custom_fields[$field_code] = $value;
}
}
$customer_data['custom_field'] = $custom_fields ?? [];
}
}
}

View file

@ -0,0 +1,386 @@
<?php
namespace retailcrm\history;
use retailcrm\repository\DataRepository;
use retailcrm\repository\OrderRepository;
use retailcrm\repository\ProductsRepository;
use retailcrm\Retailcrm;
use retailcrm\service\SettingsManager;
class Order {
private $data_repository;
private $settings_manager;
private $product_repository;
private $order_repository;
private $payment;
private $delivery;
private $oc_payment;
private $oc_delivery;
public function __construct(
DataRepository $data_repository,
SettingsManager $settings_manager,
ProductsRepository $product_repository,
OrderRepository $order_repository
) {
$this->data_repository = $data_repository;
$this->settings_manager = $settings_manager;
$this->product_repository = $product_repository;
$this->order_repository = $order_repository;
$this->payment = array_flip($settings_manager->getPaymentSettings());
$this->delivery = array_flip($settings_manager->getDeliverySettings());
}
public function setOcPayment($oc_payment) {
$this->oc_payment = $oc_payment;
}
public function setOcDelivery($oc_delivery) {
$this->oc_delivery = $oc_delivery;
}
/**
* @param array $data opencart order
* @param array $order RetailCRM order
*/
public function handleBaseOrderData(&$data, $order) {
$mail = !empty($order['email']) ? $order['email'] : $order['customer']['email'];
$phone = !empty($order['phone']) ? $order['phone'] : '';
if (!$phone) {
$data['telephone'] = $order['customer']['phones'] ? $order['customer']['phones'][0]['number'] : '80000000000';
} else {
$data['telephone'] = $phone;
}
$data['currency_code'] = $this->data_repository->getConfig('config_currency');
$data['currency_value'] = $this->data_repository->getCurrencyByCode($data['currency_code'], 'value');
$data['currency_id'] = $this->data_repository->getCurrencyByCode($data['currency_code'], 'currency_id');
$data['language_id'] = $this->data_repository->getLanguageByCode(
$this->data_repository->getConfig('config_language'),
'language_id'
);
$data['store_id'] = !is_null($this->data_repository->getConfig('config_store_id'))
? $this->data_repository->getConfig('config_store_id') : 0;
$data['store_name'] = $this->data_repository->getConfig('config_name');
// $data['customer_id'] = $customer_id;
$data['customer_group_id'] = 1;
$data['firstname'] = $order['firstName'];
$data['lastname'] = (!empty($order['lastName'])) ? $order['lastName'] : $order['firstName'];
$data['email'] = !empty($mail) ? $mail : uniqid() . '@retailrcm.ru';
$data['comment'] = !empty($order['customerComment']) ? $order['customerComment'] : '';
// this data will not retrive from crm for now
$data['fax'] = '';
$data['tax'] = '';
$data['tax_id'] = '';
$data['product'] = '';
$data['product_id'] = '';
$data['reward'] = '';
$data['affiliate'] = '';
$data['affiliate_id'] = 0;
$data['payment_tax_id'] = '';
$data['order_product_id'] = '';
$data['payment_company'] = '';
}
/**
* @param array $data opencart order
* @param array $order RetailCRM order
* @param array $corporateAddress
*/
public function handlePayment(&$data, $order, $corporateAddress = array()) {
if (!empty($order['customer']['type']) && $order['customer']['type'] === 'customer_corporate') {
$customer = $order['contact'];
if (empty($customer['address'])) {
$customer['address'] = $corporateAddress;
}
if (empty($customer['address'])) {
$customer['address'] = $order['delivery']['address'];
}
} else {
$customer = $order['customer'];
}
$default_payment_country = !empty($data['payment_country']) ? $data['payment_country'] : '';
$default_payment_country_id = !empty($data['payment_country_id']) ? $data['payment_country_id'] : 0;
$default_payment_zone = !empty($data['payment_zone']) ? $data['payment_zone'] : '';
$default_payment_zone_id = !empty($data['payment_zone_id']) ? $data['payment_zone_id'] : 0;
if (isset($customer['address']['countryIso'])) {
$payment_country = $this->data_repository->getCountryByIsoCode($customer['address']['countryIso']);
}
if (isset($customer['address']['region'])) {
$payment_zone = $this->data_repository->getZoneByName($customer['address']['region']);
if ($payment_zone) {
$payment_zone_id = $payment_zone['zone_id'];
}
}
$data['payment_firstname'] = $customer['firstName'];
$data['payment_lastname'] = (isset($customer['lastName'])) ? $customer['lastName'] : $customer['firstName'];
$data['payment_address_2'] = '';
if (!empty($order['company'])) {
$data['payment_company'] = $order['company']['name'];
}
if (!empty($customer['address'])) {
$data['payment_address_1'] = $customer['address']['text'];
$data['payment_city'] = !empty($customer['address']['city'])
? $customer['address']['city']
: $order['delivery']['address']['city'];
$data['payment_postcode'] = !empty($customer['address']['index'])
? $customer['address']['index']
: $order['delivery']['address']['index'];
}
$data['payment_country_id'] = !empty($payment_country['country_id']) ? $payment_country['country_id'] : $default_payment_country_id;
$data['payment_country'] = !empty($payment_country['name']) ? $payment_country['name'] : $default_payment_country;
$data['payment_zone'] = isset($customer['address']['region']) ? $customer['address']['region'] : $default_payment_zone;
$data['payment_zone_id'] = isset($payment_zone_id) ? $payment_zone_id : $default_payment_zone_id;
if (isset($order['payments']) && $order['payments']) {
$payment = end($order['payments']);
$data['payment_method'] = $this->oc_payment[$this->payment[$payment['type']]];
$data['payment_code'] = $this->payment[$payment['type']];
} elseif (empty($data['payment_code']) && empty($data['payment_method'])) {
$data['payment_method'] = $this->oc_payment[$this->settings_manager->getSetting('default_payment')];
$data['payment_code'] = $this->settings_manager->getSetting('default_payment');
}
}
/**
* @param array $data opencart order
* @param array $order RetailCRM order
*/
public function handleShipping(&$data, $order) {
$default_shipping_country = !empty($data['shipping_country']) ? $data['shipping_country'] : '';
$default_shipping_country_id = !empty($data['shipping_country_id']) ? $data['shipping_country_id'] : 0;
$default_shipping_zone = !empty($data['shipping_zone']) ? $data['shipping_zone'] : '';
$default_shipping_zone_id = !empty($data['shipping_zone_id']) ? $data['shipping_zone_id'] : 0;
if (!empty($order['delivery']['address']['region'])) {
$shipping_zone = $this->data_repository->getZoneByName($order['delivery']['address']['region']);
}
if (isset($order['countryIso'])) {
$shipping_country = $this->data_repository->getCountryByIsoCode($order['countryIso']);
}
$delivery = isset($order['delivery']['code']) ? $order['delivery']['code'] : null;
$data['shipping_country_id'] = isset($shipping_country['country_id']) ? $shipping_country['country_id'] : $default_shipping_country_id;
$data['shipping_country'] = isset($shipping_country['name']) ? $shipping_country['name'] : $default_shipping_country;
$data['shipping_zone_id'] = isset($shipping_zone['zone_id']) ? $shipping_zone['zone_id'] : $default_shipping_zone_id;
$data['shipping_zone'] = isset($shipping_zone['name']) ? $shipping_zone['name'] : $default_shipping_zone;
$data['shipping_firstname'] = $order['firstName'];
$data['shipping_lastname'] = (isset($order['lastName'])) ? $order['lastName'] : $order['firstName'];
$data['shipping_address_1'] = $order['delivery']['address']['text'];
$data['shipping_address_2'] = '';
$data['shipping_company'] = '';
$data['shipping_city'] = $order['delivery']['address']['city'];
$data['shipping_postcode'] = $order['delivery']['address']['index'];
if (!isset($data['shipping_code'])) {
$data['shipping_code'] = $delivery != null
? $this->delivery[$delivery]
: $this->settings_manager->getSetting('default_shipping');
$shipping = explode('.', $data['shipping_code']);
$shipping_module = $shipping[0];
if (isset($this->oc_delivery[$shipping_module][$data['shipping_code']]['title'])) {
$data['shipping_method'] = $this->oc_delivery[$shipping_module][$data['shipping_code']]['title'];
} else {
$data['shipping_method'] = $this->oc_delivery[$shipping_module]['title'];
}
} else {
if ($delivery !== null) {
if (isset($this->settings_manager->getDeliverySettings()[$data['shipping_code']])
&& isset($this->delivery[$delivery])
) {
$data['shipping_code'] = $this->delivery[$delivery];
$shipping = explode('.', $data['shipping_code']);
$shippingModule = $shipping[0];
if (isset($this->oc_delivery[$shippingModule][$data['shipping_code']]['title'])) {
$data['shipping_method'] = $this->oc_delivery[$shippingModule][$data['shipping_code']]['title'];
} else {
$data['shipping_method'] = $this->oc_delivery[$shippingModule]['title'];
}
}
}
}
}
/**
* @param array $data opencart order
* @param array $order RetailCRM order
*/
public function handleProducts(&$data, $order) {
$data['order_product'] = array();
foreach ($order['items'] as $item) {
$product_id = $item['offer']['externalId'];
$options = array();
if (mb_strpos($item['offer']['externalId'], '#', 0, mb_internal_encoding()) > 1) {
$offer = explode('#', $item['offer']['externalId']);
$product_id = $offer[0];
$options_from_crm = explode('_', $offer[1]);
foreach ($options_from_crm as $option_from_crm) {
$option_data = explode('-', $option_from_crm);
$product_option_id = $option_data[0];
$option_value_id = $option_data[1];
$product_options = $this->product_repository->getProductOptions($product_id);
foreach ($product_options as $product_option) {
if ($product_option_id == $product_option['product_option_id']) {
foreach ($product_option['product_option_value'] as $product_option_value) {
if ($product_option_value['option_value_id'] == $option_value_id) {
$options[] = array(
'product_option_id' => $product_option_id,
'product_option_value_id' => $product_option_value['product_option_value_id'],
'value' => $this->data_repository->getOptionValue($product_option_value['option_value_id'], 'name'),
'type' => $product_option['type'],
'name' => $product_option['name'],
);
}
}
}
}
}
}
$product = $this->product_repository->getProduct($product_id);
$rewards = $this->product_repository->getProductRewards($product_id);
$data['order_product'][] = array(
'name' => $product['name'],
'model' => $product['model'],
'price' => $item['initialPrice'],
'total' => (float)($item['initialPrice'] * $item['quantity']),
'product_id' => $product_id,
'quantity' => $item['quantity'],
'option' => $options,
'reward' => $rewards[$data['customer_group_id']]['points'] * $item['quantity']
);
}
}
/**
* @param array $data opencart order
* @param array $order RetailCRM order
*/
public function handleTotals(&$data, $order) {
$delivery_cost = !empty($order['delivery']['cost']) ? $order['delivery']['cost'] : 0;
$subtotal_settings = $this->settings_manager->getSettingByKey($this->data_repository->totalTitles() . 'sub_total');
$total_settings = $this->settings_manager->getSettingByKey($this->data_repository->totalTitles() . 'total');
$shipping_settings = $this->settings_manager->getSettingByKey($this->data_repository->totalTitles() . 'shipping');
$retailcrm_label_discount = $this->settings_manager->getSetting('label_discount')
?: $this->data_repository->getLanguage('default_retailcrm_label_discount');
$totalDiscount = 0;
foreach ($order['items'] as $item) {
if ($item['discountTotal'] !== 0) {
$totalDiscount += $item['discountTotal'] * $item['quantity'];
}
}
$data['total'] = $order['totalSumm'];
$data['order_total'] = array(
array(
'order_total_id' => '',
'code' => 'sub_total',
'title' => $this->data_repository->getLanguage('product_summ'),
'value' => $order['summ'],
'text' => $order['summ'],
'sort_order' => $subtotal_settings['sub_total_sort_order']
),
array(
'order_total_id' => '',
'code' => 'shipping',
'title' => $data['shipping_method'],
'value' => $delivery_cost,
'text' => $delivery_cost,
'sort_order' => $shipping_settings[$this->data_repository->totalTitles() . 'shipping_sort_order']
),
array(
'order_total_id' => '',
'code' => 'total',
'title' => $this->data_repository->getLanguage('column_total'),
'value' => !empty($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $delivery_cost,
'text' => isset($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $delivery_cost,
'sort_order' => $total_settings[$this->data_repository->totalTitles() . 'total_sort_order']
)
);
//TODO подкорректировать логику добавления скидки из RetailCRM
//Если заказ создали со скидкой в RetailCRM, то добавить скидку
if (!empty($totalDiscount)) {
$data['order_total'][] = array(
'order_total_id' => '',
'code' => Retailcrm::RETAILCRM_DISCOUNT,
'title' => $retailcrm_label_discount,
'value' => -$totalDiscount,
'sort_order' => Retailcrm::RETAILCRM_DISCOUNT_SORT_ORDER,
);
}
if (!empty($order['externalId'])) {
$orderTotals = $this->order_repository->getOrderTotals($order['externalId']);
foreach ($orderTotals as $orderTotal) {
if ($orderTotal['code'] == 'coupon'
|| $orderTotal['code'] == 'reward'
|| $orderTotal['code'] == 'voucher'
) {
$data['order_total'][] = $orderTotal;
$totalDiscount -= abs($orderTotal['value']);
}
}
//TODO подкорректировать логику добавления скидки из RetailCRM
$keyRetailCrmDiscount = array_search(Retailcrm::RETAILCRM_DISCOUNT, array_map(function ($item) {
return $item['code'];
}, $data['order_total']));
if ($totalDiscount > 0 && false !== $keyRetailCrmDiscount) {
$data['order_total'][$keyRetailCrmDiscount]['value'] = -$totalDiscount;
} elseif ($totalDiscount <= 0 && false !== $keyRetailCrmDiscount) {
unset($data['order_total'][$keyRetailCrmDiscount]);
}
}
}
/**
* @param array $data opencart order
* @param array $order RetailCRM order
*/
public function handleCustomFields(&$data, $order) {
$settings = $this->settings_manager->getSetting('custom_field');
if (!empty($settings)) {
$custom_field_setting = array_flip($settings);
}
if (isset($custom_field_setting) && $order['customFields']) {
foreach ($order['customFields'] as $code => $value) {
if (array_key_exists($code, $custom_field_setting)) {
$field_code = str_replace('o_', '', $custom_field_setting[$code]);
$custom_fields[$field_code] = $value;
}
}
$data['custom_field'] = isset($custom_fields) ? $custom_fields : '';
}
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace retailcrm\repository;
class CustomerRepository extends \retailcrm\Base {
public function getCustomer($customer_id) {
if (null !== $this->model_account_customer) {
return $this->model_account_customer->getCustomer($customer_id);
}
if (null !== $this->model_customer_customer) {
return $this->model_customer_customer->getCustomer($customer_id);
}
return array();
}
public function getAddress($address_id) {
if (null !== $this->model_customer_customer) {
$address_model = $this->model_customer_customer;
} elseif (null !== $this->model_account_address) {
$address_model = $this->model_account_address;
} else {
return array();
}
return $address_model->getAddress($address_id);
}
}

View file

@ -1,17 +1,17 @@
<?php
class ModelExtensionRetailcrmHistory extends Model
{
namespace retailcrm\repository;
class DataRepository extends \retailcrm\Base {
/**
* Create order in OC
*
*
* @param array $order
*
*
* @return int $order_id
*/
public function addOrder($order)
{
$this->db->query("INSERT INTO `" . DB_PREFIX . "order` SET store_id = '" . (int)$order['store_id'] . "', store_name = '" . $order['store_name'] . "', customer_id = '" . (int)$order['customer_id'] . "', customer_group_id = '" . (int)$order['customer_group_id'] . "', firstname = '" . $this->db->escape($order['firstname']) . "', lastname = '" . $this->db->escape($order['lastname']) . "', email = '" . $this->db->escape($order['email']) . "', telephone = '" . $this->db->escape($order['telephone']) . "', custom_field = '" . $this->db->escape(isset($order['custom_field']) ? json_encode($order['custom_field']) : '') . "', payment_firstname = '" . $this->db->escape($order['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($order['payment_lastname']) . "', payment_address_1 = '" . $this->db->escape($order['payment_address_1']) . "', payment_city = '" . $this->db->escape($order['payment_city']) . "', payment_postcode = '" . $this->db->escape($order['payment_postcode']) . "', payment_country = '" . $this->db->escape($order['payment_country']) . "', payment_country_id = '" . (int)$order['payment_country_id'] . "', payment_zone = '" . $this->db->escape($order['payment_zone']) . "', payment_zone_id = '" . (int)$order['payment_zone_id'] . "', payment_method = '" . $this->db->escape($order['payment_method']) . "', payment_code = '" . $this->db->escape($order['payment_code']) . "', shipping_firstname = '" . $this->db->escape($order['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($order['shipping_lastname']) . "', shipping_address_1 = '" . $this->db->escape($order['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($order['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($order['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($order['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($order['shipping_country']) . "', shipping_country_id = '" . (int)$order['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($order['shipping_zone']) . "', shipping_zone_id = '" . (int)$order['shipping_zone_id'] . "', shipping_method = '" . $this->db->escape($order['shipping_method']) . "', shipping_code = '" . $this->db->escape($order['shipping_code']) . "', comment = '" . $this->db->escape($order['comment']) . "', total = '" . (float)$order['total'] . "', affiliate_id = '" . (int)$order['affiliate_id'] . "', language_id = '" . (int)$order['language_id'] . "', currency_id = '" . (int)$order['currency_id'] . "', currency_code = '" . $this->db->escape($order['currency_code']) . "', currency_value = '" . (float)$order['currency_value'] . "', order_status_id = '" . (int)$order['order_status_id'] . "', date_added = NOW(), date_modified = NOW()");
public function addOrder($order) {
$this->db->query("INSERT INTO `" . DB_PREFIX . "order` SET store_id = '" . (int)$order['store_id'] . "', store_name = '" . $order['store_name'] . "', customer_id = '" . (int)$order['customer_id'] . "', customer_group_id = '" . (int)$order['customer_group_id'] . "', firstname = '" . $this->db->escape($order['firstname']) . "', lastname = '" . $this->db->escape($order['lastname']) . "', email = '" . $this->db->escape($order['email']) . "', telephone = '" . $this->db->escape($order['telephone']) . "', custom_field = '" . $this->db->escape(isset($order['custom_field']) ? json_encode($order['custom_field']) : '') . "', payment_firstname = '" . $this->db->escape($order['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($order['payment_lastname']) . "', payment_address_1 = '" . $this->db->escape($order['payment_address_1']) . "', payment_city = '" . $this->db->escape($order['payment_city']) . "', payment_postcode = '" . $this->db->escape($order['payment_postcode']) . "', payment_country = '" . $this->db->escape($order['payment_country']) . "', payment_country_id = '" . (int)$order['payment_country_id'] . "', payment_zone = '" . $this->db->escape($order['payment_zone']) . "', payment_zone_id = '" . (int)$order['payment_zone_id'] . "', payment_method = '" . $this->db->escape($order['payment_method']) . "', payment_code = '" . $this->db->escape($order['payment_code']) . "', payment_company = '" . $this->db->escape($order['payment_company']) . "', shipping_firstname = '" . $this->db->escape($order['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($order['shipping_lastname']) . "', shipping_address_1 = '" . $this->db->escape($order['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($order['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($order['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($order['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($order['shipping_country']) . "', shipping_country_id = '" . (int)$order['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($order['shipping_zone']) . "', shipping_zone_id = '" . (int)$order['shipping_zone_id'] . "', shipping_method = '" . $this->db->escape($order['shipping_method']) . "', shipping_code = '" . $this->db->escape($order['shipping_code']) . "', comment = '" . $this->db->escape($order['comment']) . "', total = '" . (float)$order['total'] . "', affiliate_id = '" . (int)$order['affiliate_id'] . "', language_id = '" . (int)$order['language_id'] . "', currency_id = '" . (int)$order['currency_id'] . "', currency_code = '" . $this->db->escape($order['currency_code']) . "', currency_value = '" . (float)$order['currency_value'] . "', order_status_id = '" . (int)$order['order_status_id'] . "', date_added = NOW(), date_modified = NOW()");
$order_id = $this->db->getLastId();
@ -30,15 +30,14 @@ class ModelExtensionRetailcrmHistory extends Model
/**
* Edit order in OC
*
*
* @param int $order_id
* @param array $order
*
*
* @return void
*/
public function editOrder($order_id, $order)
{
$this->db->query("UPDATE `" . DB_PREFIX . "order` SET customer_id = '" . (int)$order['customer_id'] . "', customer_group_id = '" . (int)$order['customer_group_id'] . "', firstname = '" . $this->db->escape($order['firstname']) . "', lastname = '" . $this->db->escape($order['lastname']) . "', email = '" . $this->db->escape($order['email']) . "', telephone = '" . $this->db->escape($order['telephone']) . "', custom_field = '" . $this->db->escape(json_encode($order['custom_field'])) . "', payment_firstname = '" . $this->db->escape($order['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($order['payment_lastname']) . "', payment_address_1 = '" . $this->db->escape($order['payment_address_1']) . "', payment_address_2 = '" . $this->db->escape($order['payment_address_2']) . "', payment_city = '" . $this->db->escape($order['payment_city']) . "', payment_postcode = '" . $this->db->escape($order['payment_postcode']) . "', payment_country = '" . $this->db->escape($order['payment_country']) . "', payment_country_id = '" . (int)$order['payment_country_id'] . "', payment_zone = '" . $this->db->escape($order['payment_zone']) . "', payment_zone_id = '" . (int)$order['payment_zone_id'] . "', payment_method = '" . $this->db->escape($order['payment_method']) . "', payment_code = '" . $this->db->escape($order['payment_code']) . "', shipping_firstname = '" . $this->db->escape($order['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($order['shipping_lastname']) . "', shipping_address_1 = '" . $this->db->escape($order['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($order['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($order['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($order['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($order['shipping_country']) . "', shipping_country_id = '" . (int)$order['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($order['shipping_zone']) . "', shipping_zone_id = '" . (int)$order['shipping_zone_id'] . "', shipping_method = '" . $this->db->escape($order['shipping_method']) . "', shipping_code = '" . $this->db->escape($order['shipping_code']) . "', comment = '" . $this->db->escape($order['comment']) . "', total = '" . (float)$order['total'] . "', order_status_id = '" . (int)$order['order_status_id'] . "', date_modified = NOW() WHERE order_id = '" . (int)$order_id . "'");
public function editOrder($order_id, $order) {
$this->db->query("UPDATE `" . DB_PREFIX . "order` SET customer_id = '" . (int)$order['customer_id'] . "', customer_group_id = '" . (int)$order['customer_group_id'] . "', firstname = '" . $this->db->escape($order['firstname']) . "', lastname = '" . $this->db->escape($order['lastname']) . "', email = '" . $this->db->escape($order['email']) . "', telephone = '" . $this->db->escape($order['telephone']) . "', custom_field = '" . $this->db->escape(json_encode($order['custom_field'])) . "', payment_firstname = '" . $this->db->escape($order['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($order['payment_lastname']) . "', payment_address_1 = '" . $this->db->escape($order['payment_address_1']) . "', payment_address_2 = '" . $this->db->escape($order['payment_address_2']) . "', payment_city = '" . $this->db->escape($order['payment_city']) . "', payment_postcode = '" . $this->db->escape($order['payment_postcode']) . "', payment_country = '" . $this->db->escape($order['payment_country']) . "', payment_country_id = '" . (int)$order['payment_country_id'] . "', payment_zone = '" . $this->db->escape($order['payment_zone']) . "', payment_zone_id = '" . (int)$order['payment_zone_id'] . "', payment_method = '" . $this->db->escape($order['payment_method']) . "', payment_code = '" . $this->db->escape($order['payment_code']) . "', payment_company = '" . $this->db->escape($order['payment_company']) . "', shipping_firstname = '" . $this->db->escape($order['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($order['shipping_lastname']) . "', shipping_address_1 = '" . $this->db->escape($order['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($order['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($order['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($order['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($order['shipping_country']) . "', shipping_country_id = '" . (int)$order['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($order['shipping_zone']) . "', shipping_zone_id = '" . (int)$order['shipping_zone_id'] . "', shipping_method = '" . $this->db->escape($order['shipping_method']) . "', shipping_code = '" . $this->db->escape($order['shipping_code']) . "', comment = '" . $this->db->escape($order['comment']) . "', total = '" . (float)$order['total'] . "', order_status_id = '" . (int)$order['order_status_id'] . "', date_modified = NOW() WHERE order_id = '" . (int)$order_id . "'");
$this->db->query("DELETE FROM " . DB_PREFIX . "order_product WHERE order_id = '" . (int)$order_id . "'");
@ -57,16 +56,15 @@ class ModelExtensionRetailcrmHistory extends Model
/**
* Add order products
*
*
* @param int $order_id
* @param array $products
*
*
* @return void
*/
public function addOrderProducts($order_id, $products)
{
public function addOrderProducts($order_id, $products) {
foreach ($products as $product) {
$this->db->query("INSERT INTO " . DB_PREFIX . "order_product SET order_id = '" . (int)$order_id . "', product_id = '" . (int)$product['product_id'] . "', name = '" . $this->db->escape($product['name']) . "', model = '" . $this->db->escape($product['model']) . "', quantity = '" . (int)$product['quantity'] . "', price = '" . (float)$product['price'] . "', total = '" . (float)$product['total'] . "'");
$this->db->query("INSERT INTO " . DB_PREFIX . "order_product SET order_id = '" . (int)$order_id . "', product_id = '" . (int)$product['product_id'] . "', name = '" . $this->db->escape($product['name']) . "', model = '" . $this->db->escape($product['model']) . "', quantity = '" . (int)$product['quantity'] . "', price = '" . (float)$product['price'] . "', total = '" . (float)$product['total'] . "', reward = '" . (float)$product['reward'] . "'");
$order_product_id = $this->db->getLastId();
@ -78,14 +76,13 @@ class ModelExtensionRetailcrmHistory extends Model
/**
* Add order totals
*
*
* @param int $order_id
* @param array $totals
*
*
* @return void
*/
public function addOrderTotals($order_id, $totals)
{
public function addOrderTotals($order_id, $totals) {
foreach ($totals as $total) {
$this->db->query("INSERT INTO " . DB_PREFIX . "order_total SET order_id = '" . (int)$order_id . "', code = '" . $this->db->escape($total['code']) . "', title = '" . $this->db->escape($total['title']) . "', `value` = '" . (float)$total['value'] . "', sort_order = '" . (int)$total['sort_order'] . "'");
}
@ -93,11 +90,10 @@ class ModelExtensionRetailcrmHistory extends Model
/**
* Get total titles
*
*
* @return string $title
*/
protected function totalTitles()
{
public function totalTitles() {
if (version_compare(VERSION, '3.0', '<')) {
$title = '';
} else {
@ -109,27 +105,26 @@ class ModelExtensionRetailcrmHistory extends Model
/**
* Get country by iso code 2
*
*
* @param string $isoCode
*
*
* @return array
*/
public function getCountryByIsoCode($isoCode)
{
public function getCountryByIsoCode($isoCode) {
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE iso_code_2 = '" . $isoCode . "'");
return $query->row;
}
/**
* Get zone by name
*
*
* @param string $name
*
*
* @return array
*/
public function getZoneByName($name)
{
public function getZoneByName($name) {
$name = $this->db->escape($name);
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE name = '" . $name . "'");
return $query->row;
@ -137,14 +132,13 @@ class ModelExtensionRetailcrmHistory extends Model
/**
* Get currency
*
*
* @param string $code
* @param string $field (default = '')
*
*
* @return mixed array | string
*/
public function getCurrencyByCode($code, $field = '')
{
public function getCurrencyByCode($code, $field = '') {
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "currency` WHERE code = '" . $code . "'");
if (!$field) {
@ -156,14 +150,13 @@ class ModelExtensionRetailcrmHistory extends Model
/**
* Get language
*
*
* @param string $code
* @param string $field (default = '')
*
*
* @return mixed array | string
*/
public function getLanguageByCode($code, $field = '')
{
public function getLanguageByCode($code, $field = '') {
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "language` WHERE code = '" . $code . "'");
if (!$field) {
@ -175,14 +168,13 @@ class ModelExtensionRetailcrmHistory extends Model
/**
* Get product option value
*
*
* @param int $option_value_id
* @param string $field
*
*
* @return mixed array | string
*/
public function getOptionValue($option_value_id, $field = '')
{
public function getOptionValue($option_value_id, $field = '') {
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "option_value_description` WHERE option_value_id = '" . $option_value_id . "'");
if (!$field) {
@ -191,4 +183,24 @@ class ModelExtensionRetailcrmHistory extends Model
return $query->row[$field];
}
public function getConfig($key) {
return $this->config->get($key);
}
public function getLanguage($key) {
return $this->language->get($key);
}
public function getDeliveryTypes() {
$this->load->model('extension/retailcrm/references');
return $this->model_extension_retailcrm_references->getOpercartDeliveryTypes();
}
public function getPaymentTypes() {
$this->load->model('extension/retailcrm/references');
return $this->model_extension_retailcrm_references->getOpercartPaymentTypes();
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace retailcrm\repository;
class OrderRepository extends \retailcrm\Base {
public function getOrder($order_id) {
if (null !== $this->model_sale_order) {
return $this->model_sale_order->getOrder($order_id);
}
if (null !== $this->model_checkout_order) {
return $this->model_checkout_order->getOrder($order_id);
}
return array();
}
public function getOrderTotals($order_id) {
if (null !== $this->model_sale_order) {
return $this->model_sale_order->getOrderTotals($order_id);
}
if (null !== $this->model_account_order) {
return $this->model_account_order->getOrderTotals($order_id);
}
return array();
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace retailcrm\repository;
class ProductsRepository extends \retailcrm\Base {
public function getProductSpecials($product_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "' ORDER BY priority, price");
return $query->rows;
}
public function getProductOptions($product_id) {
return $this->model_catalog_product->getProductOptions($product_id);
}
public function getProduct($product_id) {
return $this->model_catalog_product->getProduct($product_id);
}
public function getProductRewards($product_id) {
return $this->model_catalog_product->getProductRewards($product_id);
}
}

View file

@ -0,0 +1,227 @@
<?php
namespace retailcrm\service;
use retailcrm\repository\CustomerRepository;
use retailcrm\Utils;
class CorporateCustomer {
private $api;
private $customer_repository;
public function __construct(
\RetailcrmProxy $api,
CustomerRepository $customer_repository
) {
$this->api = $api;
$this->customer_repository = $customer_repository;
}
/**
* @param $order_data
* @param $customer
* @return int|null
*/
public function createCorporateCustomer($order_data, $customer) {
if (!empty($customer['externalId'])) {
return $this->createFromExistingCustomer($order_data, $customer);
}
if (!empty($customer['id'])) {
return $this->createFromNotExistingCustomer($order_data, $customer);
}
return null;
}
public function buildFromExistingCustomer($customer_data, $order_data) {
$builder = CorporateCustomerBuilder::create()
->setCompany($order_data['payment_company'])
->setCustomerExternalId($customer_data['customer_id']);
return $builder->build();
}
public function buildCorporateCustomerFromOrder($order_data, $crm_customer_id) {
$builder = CorporateCustomerBuilder::create()
->setCompany($order_data['payment_company'])
->setCustomerId($crm_customer_id);
return $builder->build();
}
/**
* Search by provided filter, returns first found customer
*
* @param array $filter
* @param bool $returnGroup Return all customers for group filter instead of first
*
* @return bool|array
*/
public function searchCorporateCustomer($filter, $returnGroup = false)
{
$search = $this->api->customersCorporateList($filter);
if ($search && $search->isSuccessful()) {
$customer = false;
if (!empty($search['customersCorporate'])) {
if ($returnGroup) {
return $search['customersCorporate'];
} else {
$dataCorporateCustomers = $search['customersCorporate'];
$customer = reset($dataCorporateCustomers);
}
}
return $customer;
}
return false;
}
/**
* @param $order_data
* @param $customer
* @return int|null
*/
private function createFromExistingCustomer($order_data, $customer) {
$response = $this->api->customersGet($customer['externalId']);
if (!$response || !$response->isSuccessful() || empty($response['customer'])) {
return null;
}
$customer_data = $this->customer_repository->getCustomer($customer['externalId']);
$corp_client = $this->searchCorporateCustomer(array(
'contactIds' => array($response['customer']['id']),
'companyName' => $order_data['payment_company']
));
if (empty($corp_client)) {
$corp_client = $this->searchCorporateCustomer(array(
'companyName' => $order_data['payment_company']
));
}
if ($corp_client) {
$this->updateOrCreateAddress($order_data, $corp_client);
return $corp_client['id'];
}
$response = $this->api->customersCorporateCreate($this->buildFromExistingCustomer($customer_data, $order_data));
if ($response && $response->isSuccessful()) {
$this->createAddressAndCompany($order_data, $response['id']);
return $response['id'];
}
return null;
}
/**
* @param $order_data
* @param $customer
* @return int|null
*/
private function createFromNotExistingCustomer($order_data, $customer) {
$corp_client = $this->searchCorporateCustomer(array(
'contactIds' => array($customer['id']),
'companyName' => $order_data['payment_company']
));
if (empty($corp_client)) {
$corp_client = $this->searchCorporateCustomer(array(
'companyName' => $order_data['payment_company']
));
}
if ($corp_client) {
$this->updateOrCreateAddress($order_data, $corp_client);
return $corp_client['id'];
}
$response = $this->api->customersCorporateCreate(
$this->buildCorporateCustomerFromOrder($order_data, $customer['id'])
);
if ($response && $response->isSuccessful()) {
$this->createAddressAndCompany($order_data, $response['id']);
return $response['id'];
}
return null;
}
private function createAddressAndCompany($order_data, $corp_client_id) {
$corp_address = CorporateCustomerBuilder::create(false)->buildAddress($order_data);
$address_response = $this->api->customersCorporateAddressesCreate($corp_client_id, $corp_address, 'id');
if ($address_response && $address_response->isSuccessful()) {
$company = CorporateCustomerBuilder::create(false)
->setCompany($order_data['payment_company'])
->setCompanyAddressId($address_response['id'])
->buildCompany($order_data);
$this->api->customersCorporateCompaniesCreate($corp_client_id, $company, 'id');
}
}
/**
* @param $order_data
* @param $corp_client
*
* @return void
*/
private function updateOrCreateAddress($order_data, $corp_client) {
$address_id = null;
$addresses_response = $this->api->customersCorporateAddresses($corp_client['id'], array(), null, null, 'id');
$corp_address = CorporateCustomerBuilder::create(false)->buildAddress($order_data);
if ($addresses_response && $addresses_response->isSuccessful() && !empty($addresses_response['addresses'])) {
foreach ($addresses_response['addresses'] as $address) {
if (Utils::addressEquals($corp_address, $address)) {
$address_id = $address['id'];
$exist_address = $address;
break;
}
}
}
if (!isset($exist_address)) {
$response = $this->api->customersCorporateAddressesCreate(
$corp_client['id'],
$corp_address,
'id'
);
if ($response && $response->isSuccessful() && isset($response['id'])) {
$address_id = $response['id'];
}
}
$company = CorporateCustomerBuilder::create(false)
->setCompany($order_data['payment_company'])
->setCompanyAddressId($address_id)
->buildCompany($order_data);
$companies = $this->api->customersCorporateCompanies($corp_client['id'], array(), null, null, 'id');
if ($companies && $companies->isSuccessful() && !empty($companies['companies'])) {
foreach ($companies['companies'] as $crm_company) {
if ($crm_company['name'] === $order_data['payment_company']) {
$this->api->customersCorporateCompaniesEdit(
$corp_client['id'],
$crm_company['id'],
$company,
'id',
'id'
);
}
}
}
}
}

View file

@ -0,0 +1,142 @@
<?php
namespace retailcrm\service;
class CorporateCustomerBuilder {
private $is_main_company = false;
private $company_address_id = null;
private $data = array();
private $company;
public static function create($init = true) {
$self = new self();
if ($init) {
$self->initData();
}
return $self;
}
public function initData() {
$this->data = array(
'customerContacts' => array(
array(
'isMain' => true,
'customer' => array()
)
),
'companies' => array()
);
return $this;
}
public function build() {
$this->data['nickName'] = $this->company;
return $this->data;
}
/**
* @param bool $isMainCompany
*
* @return CorporateCustomerBuilder
*/
public function setIsMainCompany($isMainCompany)
{
$this->is_main_company = $isMainCompany;
return $this;
}
/**
* @param int $companyAddressId
*
* @return CorporateCustomerBuilder
*/
public function setCompanyAddressId($companyAddressId)
{
$this->company_address_id = $companyAddressId;
return $this;
}
public function setCompany($company) {
$this->company = $company;
return $this;
}
public function setCustomerId($customer_id) {
$this->setCustomer($customer_id);
return $this;
}
public function setCustomerExternalId($customer_external_id) {
$this->setCustomer($customer_external_id, 'externalId');
return $this;
}
public function buildAddress($data) {
return array(
'index' => $data['shipping_postcode'],
'countryIso' => $data['shipping_iso_code_2'],
'region' => $data['shipping_zone'],
'city' => $data['shipping_city'],
'name' => $data['payment_company'],
'text' => $data['shipping_address_1'] . ' ' . $data['shipping_address_2']
);
}
public function addAddress($data) {
$this->data['addresses'][] = $this->buildAddress($data);
return $this;
}
public function buildLegalAddress($data) {
return sprintf(
"%s %s %s %s %s",
$data['payment_postcode'],
$data['payment_zone'],
$data['payment_city'],
$data['payment_address_1'],
$data['payment_address_2']
);
}
public function buildCompany($data) {
$company = array(
'name' => $this->company,
'contragent' => array(
'legalAddress' => $this->buildLegalAddress($data),
'contragentType' => 'legal-entity',
)
);
if ($this->is_main_company) {
$company['isMain'] = true;
}
if (null !== $this->company_address_id) {
$company['address'] = array('id' => $this->company_address_id);
}
return $company;
}
public function addCompany($data) {
$this->data['companies'][] = $this->buildCompany($data);
return $this;
}
private function setCustomer($id, $field = 'id') {
foreach ($this->data['customerContacts'] as $key => $customerContact) {
if ($customerContact['isMain']) {
$this->data['customerContacts'][$key]['customer'][$field] = $id;
}
}
}
}

View file

@ -0,0 +1,108 @@
<?php
namespace retailcrm\service;
class CustomerManager {
protected $api;
protected $customer_converter;
public function __construct(\RetailcrmProxy $proxy, RetailcrmCustomerConverter $customer_converter) {
$this->api = $proxy;
$this->customer_converter = $customer_converter;
}
public function createCustomer($customer_data, $address) {
$customer = $this->prepareCustomer($customer_data, $address, !empty($customer_data['newsletter']));
$this->api->customersCreate($customer);
}
public function editCustomer($customer_data, $address) {
$customer = $this->prepareCustomer($customer_data, $address);
$this->api->customersEdit($customer);
}
public function editCustomerNewsLetter($customer_data) {
$this->api->customersEdit(
[
'externalId' => $customer_data['customer_id'],
'subscribed' => !empty($customer_data['newsletter']),
]
);
}
public function uploadCustomers($customers) {
$this->api->customersUpload($customers);
}
public function prepareCustomer($customer_data, $address, $isSubscribed = null) {
return $this->customer_converter
->initCustomerData($customer_data, $address, $isSubscribed)
->setCustomerData()
->setAddress()
->setCustomFields()
->getCustomer();
}
public function getCustomerForOrder($order_data) {
$customer = $this->searchCustomer($order_data['telephone'], $order_data['email']);
if ($customer) {
return $customer;
}
$new_customer = array(
'firstName' => $order_data['firstname'],
'lastName' => $order_data['lastname'],
'email' => $order_data['email'],
'createdAt' => $order_data['date_added'],
'address' => array(
'countryIso' => $order_data['payment_iso_code_2'],
'index' => $order_data['payment_postcode'],
'city' => $order_data['payment_city'],
'region' => $order_data['payment_zone'],
'text' => $order_data['payment_address_1'] . ' ' . $order_data['payment_address_2']
)
);
if (!empty($order_data['telephone'])) {
$new_customer['phones'] = array(
array(
'number' => $order_data['telephone']
)
);
}
$res = $this->api->customersCreate($new_customer);
$customer = array();
if ($res && $res->isSuccessful() && isset($res['id'])) {
$customer['id'] = $res['id'];
}
return $customer;
}
private function searchCustomer($phone, $email) {
$customer = array();
$response = $this->api->customersList(
array(
'name' => $phone,
'email' => $email
),
1,
100
);
if ($response && $response->isSuccessful() && isset($response['customers'])) {
$customers = $response['customers'];
if ($customers) {
$customer = end($customers);
}
}
return $customer;
}
}

View file

@ -0,0 +1,184 @@
<?php
namespace retailcrm\service;
class OrderManager {
protected $api;
protected $customer_manager;
protected $order_converter;
protected $corporate_customer_service;
protected $settings_manager;
/**
* OrderManager constructor.
* @param \RetailcrmProxy $proxy
* @param CustomerManager $customer_manager
* @param RetailcrmOrderConverter $order_converter
* @param CorporateCustomer $corporate_customer_service
* @param SettingsManager $settings_manager
*/
public function __construct(
\RetailcrmProxy $proxy,
CustomerManager $customer_manager,
RetailcrmOrderConverter $order_converter,
CorporateCustomer $corporate_customer_service,
SettingsManager $settings_manager
) {
$this->api = $proxy;
$this->customer_manager = $customer_manager;
$this->order_converter = $order_converter;
$this->corporate_customer_service = $corporate_customer_service;
$this->settings_manager = $settings_manager;
}
/**
* @param array $order_data
* @param array $order_products
* @param array $order_totals
*/
public function createOrder($order_data, $order_products, $order_totals) {
$order = $this->prepareOrder($order_data, $order_products, $order_totals);
if (!isset($order['customer'])
|| (isset($order['customer']['externalId'])
&& !$this->checkExistCustomer($order['customer']['externalId']))
) {
$customer = $this->customer_manager->getCustomerForOrder($order_data);
if (!empty($customer)) {
$order['customer'] = $customer;
}
}
$order['contragent']['contragentType'] = 'individual';
$this->handleCorporate($order, $order_data);
return $this->api->ordersCreate($order);
}
/**
* @param array $order_data
* @param array $order_products
* @param array $order_totals
*/
public function editOrder($order_data, $order_products, $order_totals) {
$order = $this->prepareOrder($order_data, $order_products, $order_totals);
if (!isset($order['customer'])) {
$customer = $this->customer_manager->getCustomerForOrder($order_data);
if (!empty($customer)) {
$order['customer'] = array(
'id' => $customer['id']
);
}
}
$order['contragent']['contragentType'] = 'individual';
$this->handleCorporate($order, $order_data);
$payments = $order['payments'];
unset($order['payments']);
$order_payment = $payments[0];
$order = \retailcrm\Utils::filterRecursive($order);
$response = $this->api->ordersEdit($order);
if ($response && $response->isSuccessful()) {
$this->updatePayment($order_payment, $order['externalId']);
}
}
/**
* @param array $orders
*/
public function uploadOrders($orders) {
$this->api->ordersUpload($orders);
}
/**
* @param array $order_data array of order fields
* @param array $order_products array of order products
* @param array $order_totals array of order totals
* @return array
*/
public function prepareOrder($order_data, $order_products, $order_totals) {
return $this->order_converter->initOrderData($order_data, $order_products, $order_totals)
->setOrderData()
->setDelivery()
->setItems()
->setPayment(false)
->setDiscount()
->setCustomFields()
->getOrder();
}
private function handleCorporate(&$order, $order_data) {
if ($this->isCorporateOrder($order_data)
&& !empty($order['customer'])
&& $this->settings_manager->getSetting('corporate_enabled') == 1
) {
$order_data['payment_company'] = htmlspecialchars_decode($order_data['payment_company']);
$corp_customer_id = $this->corporate_customer_service->createCorporateCustomer($order_data, $order['customer']);
if ($corp_customer_id) {
$order = $this->order_converter->setCorporateCustomer($order, $corp_customer_id);
$companiesResponse = $this->api->customersCorporateCompanies($corp_customer_id, array(), 1, 100, 'id');
if ($companiesResponse && $companiesResponse->isSuccessful() && !empty($companiesResponse['companies'])) {
foreach ($companiesResponse['companies'] as $company) {
if ($company['name'] === $order_data['payment_company']) {
$order['company'] = array(
'id' => $company['id']
);
}
}
}
}
}
}
/**
* @param array $order_data array of order fields
* @return bool
*/
private function isCorporateOrder($order_data) {
return !empty($order_data['payment_company']);
}
/**
* @param array $order_payment
* @param int $orderId
*/
private function updatePayment($order_payment, $orderId) {
$response_order = $this->api->ordersGet($orderId);
if ($response_order && $response_order->isSuccessful()) {
$order_info = $response_order['order'];
}
foreach ($order_info['payments'] as $payment_data) {
if (isset($payment_data['externalId'])) {
$payment = $payment_data;
}
}
if (isset($payment) && $payment['type'] != $order_payment['type']) {
$response = $this->api->ordersPaymentDelete($payment['id']);
if ($response && $response->isSuccessful()) {
$this->api->ordersPaymentCreate($order_payment);
}
} elseif (isset($payment) && $payment['type'] == $order_payment['type']) {
$this->api->ordersPaymentEdit($order_payment);
}
}
/**
* @param string $customerExternalId Customer's external id
*
* @return bool
*/
private function checkExistCustomer($customerExternalId) {
$result = $this->api->customersGet($customerExternalId);
return $result && $result->isSuccessful() && $result->offsetExists('customer');
}
}

View file

@ -0,0 +1,81 @@
<?php
namespace retailcrm\service;
class RetailcrmCustomerConverter {
protected $data;
protected $customer_data = [];
protected $address = [];
protected $isSubscribed;
protected $settingsManager;
public function __construct(
SettingsManager $settingsManager
) {
$this->settingsManager = $settingsManager;
}
public function getCustomer() {
return $this->data;
}
public function initCustomerData($customer_data, $address, $isSubscribed) {
$this->data = [];
$this->customer_data = $customer_data;
$this->address = $address;
$this->isSubscribed = $isSubscribed;
return $this;
}
public function setCustomerData() {
$this->data['externalId'] = $this->customer_data['customer_id'];
$this->data['firstName'] = $this->customer_data['firstname'];
$this->data['lastName'] = $this->customer_data['lastname'];
$this->data['email'] = $this->customer_data['email'];
$this->data['createdAt'] = $this->customer_data['date_added'];
if ($this->isSubscribed !== null) {
$this->data['subscribed'] = $this->isSubscribed;
}
if (!empty($this->customer_data['telephone'])) {
$this->data['phones'] = [['number' => $this->customer_data['telephone']]];
}
return $this;
}
public function setAddress() {
if (!empty($this->address)) {
$this->data['address'] = [
'index' => $this->address['postcode'],
'countryIso' => $this->address['iso_code_2'],
'region' => $this->address['zone'],
'city' => $this->address['city'],
'text' => $this->address['address_1'] . ' ' . $this->address['address_2']
];
}
return $this;
}
public function setCustomFields() {
$settings = $this->settingsManager->getSetting('custom_field');
if (!empty($settings) && $this->customer_data['custom_field']) {
$customFields = json_decode($this->customer_data['custom_field']);
foreach ($customFields as $key => $value) {
if (isset($settings['c_' . $key])) {
$customFieldsToCrm[$settings['c_' . $key]] = $value;
}
}
if (isset($customFieldsToCrm)) {
$this->data['customFields'] = $customFieldsToCrm;
}
}
return $this;
}
}

View file

@ -0,0 +1,331 @@
<?php
namespace retailcrm\service;
use retailcrm\repository\CustomerRepository;
use retailcrm\repository\ProductsRepository;
class RetailcrmOrderConverter {
protected $data;
protected $order_data = array();
protected $order_products = array();
protected $order_totals = array();
protected $settingsManager;
protected $customerRepository;
protected $productsRepository;
public function __construct(
SettingsManager $settingsManager,
CustomerRepository $customerRepository,
ProductsRepository $productsRepository
) {
$this->settingsManager = $settingsManager;
$this->customerRepository = $customerRepository;
$this->productsRepository = $productsRepository;
}
public function initOrderData($order_data, $order_products, $order_totals) {
$this->data = array();
$this->order_data = $order_data;
$this->order_products = $order_products;
$this->order_totals = $order_totals;
return $this;
}
public function getOrder() {
return $this->data;
}
public function setOrderData() {
if (!empty($this->order_data['shipping_iso_code_2'])) {
$this->data['countryIso'] = $this->order_data['shipping_iso_code_2'];
}
if ($this->settingsManager->getSetting('order_number') == 1) {
$this->data['number'] = $this->order_data['order_id'];
}
if ($this->settingsManager->getSetting('summ_around') == 1) {
$this->data['applyRound'] = true;
}
$this->data['externalId'] = $this->order_data['order_id'];
$this->data['firstName'] = $this->order_data['shipping_firstname'];
$this->data['lastName'] = $this->order_data['shipping_lastname'];
$this->data['phone'] = $this->order_data['telephone'];
$this->data['customerComment'] = $this->order_data['comment'];
if (!empty($this->order_data['customer_id'])) {
$this->data['customer']['externalId'] = $this->order_data['customer_id'];
}
if (!empty($this->order_data['email'])) {
$this->data['email'] = $this->order_data['email'];
}
$this->data['createdAt'] = $this->order_data['date_added'];
if (!empty($this->order_data['order_status_id'])) {
$this->data['status'] = $this->settingsManager->getStatusSettings()[$this->order_data['order_status_id']];
} elseif (isset($this->order_data['order_status_id']) && $this->order_data['order_status_id'] == 0) {
$this->data['status'] = $this->settingsManager->getSetting('missing_status');
}
return $this;
}
public function setDiscount() {
$discount = 0;
$totalCoupon = $this->getTotal('coupon');
$totalReward = $this->getTotal('reward');
$totalVoucher = $this->getTotal('voucher');
$retailcrmDiscount = $this->getTotal(\retailcrm\Retailcrm::RETAILCRM_DISCOUNT);
if (!empty($totalCoupon)) {
$discount += abs($totalCoupon);
}
if (!empty($totalReward)) {
$discount += abs($totalReward);
}
if (!empty($totalVoucher)) {
$discount += abs($totalVoucher);
}
if (!empty($retailcrmDiscount)) {
$discount += abs($retailcrmDiscount);
}
$this->data['discountManualAmount'] = $discount;
return $this;
}
public function setPayment($create = true) {
$settings = $this->settingsManager->getPaymentSettings();
if (!empty($this->order_data['payment_code']) && isset($settings[$this->order_data['payment_code']])) {
$payment_type = $settings[$this->order_data['payment_code']];
}
$payment = array(
'externalId' => uniqid($this->order_data['order_id'] . "-"),
'amount' => $this->getTotal('total')
);
if ($this->settingsManager->getSetting('sum_payment') &&
$this->settingsManager->getSetting('sum_payment') == 1) {
unset($payment['amount']);
}
if (!empty($payment_type)) {
$payment['type'] = $payment_type;
}
if (!$create) {
$payment['order'] = array(
'externalId' => $this->order_data['order_id']
);
}
if (!empty($payment['type'])) {
$this->data['payments'][] = $payment;
}
return $this;
}
public function setDelivery() {
$settings = $this->settingsManager->getDeliverySettings();
$this->data['delivery']['address'] = array(
'index' => $this->order_data['shipping_postcode'],
'city' => $this->order_data['shipping_city'],
'countryIso' => $this->order_data['shipping_iso_code_2'],
'region' => $this->order_data['shipping_zone'],
'text' => implode(', ', array(
$this->order_data['shipping_postcode'],
$this->order_data['shipping_country'] ? $this->order_data['shipping_country'] : '',
$this->order_data['shipping_city'],
$this->order_data['shipping_address_1'],
$this->order_data['shipping_address_2']
))
);
if (!empty($this->order_data['shipping_code'])) {
$shippingCode = explode('.', $this->order_data['shipping_code']);
$shippingModule = $shippingCode[0];
if (isset($settings[$this->order_data['shipping_code']])) {
$delivery_code = $settings[$this->order_data['shipping_code']];
} elseif (isset($settings[$shippingModule])) {
$delivery_code = $settings[$shippingModule];
}
}
if (!isset($delivery_code) && isset($shippingModule)) {
if (!empty($settings)) {
$deliveries = array_keys($settings);
$shipping_code = '';
array_walk($deliveries, function ($item, $key) use ($shippingModule, &$shipping_code) {
if (strripos($item, $shippingModule) !== false) {
$shipping_code = $item;
}
});
$delivery_code = $settings[$shipping_code];
}
}
if (!empty($delivery_code)) {
$this->data['delivery']['code'] = $delivery_code;
}
$totalShipping = $this->getTotal('shipping');
if (!empty($totalShipping)) {
$this->data['delivery']['cost'] = $totalShipping;
}
return $this;
}
public function setItems() {
$offerOptions = array('select', 'radio');
foreach ($this->order_products as $product) {
$offerId = '';
if (!empty($product['option'])) {
$options = array();
foreach ($product['option'] as $option) {
if ($option['type'] == 'checkbox') {
$properties[] = array(
'code' => $option['product_option_value_id'],
'name' => $option['name'],
'value' => $option['value']
);
}
if (!in_array($option['type'], $offerOptions)) continue;
$productOptions = $this->productsRepository->getProductOptions($product['product_id']);
foreach ($productOptions as $productOption) {
if ($productOption['product_option_id'] = $option['product_option_id']) {
foreach ($productOption['product_option_value'] as $productOptionValue) {
if ($productOptionValue['product_option_value_id'] == $option['product_option_value_id']) {
$options[$option['product_option_id']] = $productOptionValue['option_value_id'];
}
}
}
}
}
ksort($options);
$offerId = array();
foreach ($options as $optionKey => $optionValue) {
$offerId[] = $optionKey . '-' . $optionValue;
}
$offerId = implode('_', $offerId);
}
$item = array(
'offer' => array(
'externalId' => !empty($offerId) ? $product['product_id'] . '#' . $offerId : $product['product_id']
),
'productName' => $product['name'],
'initialPrice' => $product['price'],
'quantity' => $product['quantity']
);
$date = date('Y-m-d');
$always = '0000-00-00';
$specials = $this->productsRepository->getProductSpecials($product['product_id']);
if (!empty($specials)) {
$customer = $this->customerRepository->getCustomer($this->order_data['customer_id']);
foreach ($specials as $special) {
if (($special['date_start'] == $always && $special['date_end'] == $always)
|| ($special['date_start'] <= $date && $special['date_end'] >= $date)
) {
if ((isset($priority) && $priority > $special['priority'])
|| !isset($priority)) {
if (empty($customer['customer_group_id'])) {
continue;
}
$specialSetting = $this->settingsManager->getSetting('special_' . $customer['customer_group_id']);
if ($special['customer_group_id'] == $customer['customer_group_id'] && !empty($specialSetting)) {
$item['priceType']['code'] = $specialSetting;
$priority = $special['priority'];
}
}
}
}
}
if (isset($properties)) $item['properties'] = $properties;
$this->data['items'][] = $item;
}
return $this;
}
public function setCorporateCustomer($order, $corp_customer_id) {
$order['contragent']['contragentType'] = 'legal-entity';
$order['contact'] = $order['customer'];
unset($order['customer']);
$order['customer'] = array(
'id' => $corp_customer_id
);
return $order;
}
public function setCustomFields() {
$settings = $this->settingsManager->getSetting('custom_field');
if (!empty($settings) && $this->order_data['custom_field']) {
$customFields = $this->order_data['custom_field'];
foreach ($customFields as $key => $value) {
if (isset($settings['o_' . $key])) {
$customFieldsToCrm[$settings['o_' . $key]] = $value;
}
}
if (isset($customFieldsToCrm)) {
$this->data['customFields'] = $customFieldsToCrm;
}
}
return $this;
}
private function getTotal($total) {
$totals = $this->getTotals();
if (!empty($totals[$total])) {
return $totals[$total];
}
return 0;
}
private function getTotals() {
$totals = array();
foreach ($this->order_totals as $total) {
$totals[$total['code']] = $total['value'];
}
return $totals;
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace retailcrm\service;
class SettingsManager extends \retailcrm\Base {
private $settings;
public function getSettings() {
if (!$this->settings) {
$this->settings = $this->model_setting_setting->getSetting($this->retailcrm->getModuleTitle());
}
return $this->settings;
}
public function getSettingByKey($key) {
return $this->model_setting_setting->getSetting($key);
}
public function getSetting($key) {
$settings = $this->getSettings();
if (!empty($settings[$this->retailcrm->getModuleTitle() . '_' . $key])) {
return $settings[$this->retailcrm->getModuleTitle() . '_' . $key];
}
return null;
}
public function getPaymentSettings() {
return $this->getSettings()[$this->retailcrm->getModuleTitle() . '_payment'];
}
public function getDeliverySettings() {
return $this->getSettings()[$this->retailcrm->getModuleTitle() . '_delivery'];
}
public function getStatusSettings() {
return $this->getSettings()[$this->retailcrm->getModuleTitle() . '_status'];
}
}

View file

@ -14,6 +14,7 @@
<field id="cumulative_discount" group="customer">cumulativeDiscount</field>
<field id="personal_discount" group="customer">personalDiscount</field>
<field id="discount_card_number" group="customer">discountCardNumber</field>
<field id="email_marketing_unsubscribed_at" group="customer">emailMarketingUnsubscribedAt</field>
<field id="address.index" group="customerAddress">index</field>
<field id="address.country" group="customerAddress">country</field>

View file

@ -0,0 +1,269 @@
<?php
namespace retailcrm;
use retailcrm\repository\CustomerRepository;
use retailcrm\service\CorporateCustomer;
use retailcrm\service\CustomerManager;
use retailcrm\service\OrderManager;
use retailcrm\factory\OrderConverterFactory;
use retailcrm\factory\CustomerConverterFactory;
use retailcrm\service\SettingsManager;
require_once DIR_SYSTEM . 'library/retailcrm/bootstrap.php';
class Retailcrm {
const RETAILCRM_DISCOUNT = 'retailcrm_discount';
const RETAILCRM_DISCOUNT_SORT_ORDER = 8;
const VERSION_MODULE = '4.1.19';
protected $registry;
/** @var bool */
public static $history_run = false;
public function __construct(\Registry $registry) {
$this->registry = $registry;
$modelsProvider = new ModelsProvider($this->registry);
$modelsProvider->includeDependencies();
}
public function __get($name) {
return $this->registry->get($name);
}
public function getCustomerManager() {
return new CustomerManager($this->getApiClient(), CustomerConverterFactory::create($this->registry));
}
public function getOrderManager() {
return new OrderManager(
$this->getApiClient(),
$this->getCustomerManager(),
OrderConverterFactory::create($this->registry),
$this->getCorporateCustomerService(),
new SettingsManager($this->registry)
);
}
public function getCorporateCustomerService() {
return new CorporateCustomer($this->getApiClient(), new CustomerRepository($this->registry));
}
/**
* Get api client object
*
* @param string $apiUrl (default = null)
* @param string $apiKey (default = null)
*
* @return mixed object | boolean
*/
public function getApiClient($apiUrl = null, $apiKey = null) {
if (!$this->registry->has('RetailcrmProxy')) {
$setting = $this->model_setting_setting->getSetting($this->getModuleTitle());
if ($apiUrl === null && $apiKey === null) {
$apiUrl = isset($setting[$this->getModuleTitle() . '_url'])
? $setting[$this->getModuleTitle() . '_url'] : '';
$apiKey = isset($setting[$this->getModuleTitle() . '_apikey'])
? $setting[$this->getModuleTitle() . '_apikey'] : '';
}
if (!$apiUrl || !$apiKey) {
return false;
}
$this->registry->set(
'RetailcrmProxy',
new \RetailcrmProxy($apiUrl, $apiKey)
);
}
return $this->registry->get('RetailcrmProxy');
}
/**
* Get opencart api client
*
* @param object $registry
*
* @return \OpencartApiClient
*/
public function getOcApiClient($registry) {
return new \OpencartApiClient($registry);
}
/**
* Get module title for this version
*
* @return string $title
*/
public function getModuleTitle() {
if (version_compare(VERSION, '3.0', '<')) {
$title = 'retailcrm';
} else {
$title = 'module_retailcrm';
}
return $title;
}
/**
* Get token param name
*
* @return string $token
*/
public function getTokenTitle() {
if (version_compare(VERSION, '3.0', '<')) {
$token = 'token';
} else {
$token = 'user_token';
}
return $token;
}
public function getOffers($product) {
// Build offers by available options
$options = $this->model_catalog_product->getProductOptions($product['product_id']);
$offerOptions = array('select', 'radio');
$requiredOptions = array();
$notRequiredOptions = array();
// Handle & sort mandatory options
foreach($options as $option) {
if(in_array($option['type'], $offerOptions)) {
if($option['required']) {
$requiredOptions[] = $option;
} else {
$notRequiredOptions[] = $option;
}
}
}
$offers = array();
foreach($requiredOptions as $requiredOption) {
if(empty($offers)) {
foreach($requiredOption['product_option_value'] as $optionValue) {
$offers[$requiredOption['product_option_id'].':'.$requiredOption['option_id'].'-'.$optionValue['option_value_id']] = array(
'price' => (float)$this->getOptionPrice($optionValue),
'qty' => $optionValue['quantity'],
'weight' => round($this->getWeightOption($optionValue), 3)
);
}
} else {
foreach($offers as $optionKey => $optionAttr) {
unset($offers[$optionKey]); // Работая в контексте обязательных опций не забываем удалять прошлые обязательные опции, т.к. они должны быть скомбинированы с другими обязательными опциями
foreach($requiredOption['product_option_value'] as $optionValue) {
$offers[$optionKey.'_'.$requiredOption['product_option_id'].':'.$requiredOption['option_id'].'-'.$optionValue['option_value_id']] = array(
'price' => $optionAttr['price'] + (float)$this->getOptionPrice($optionValue),
'qty' => ($optionAttr['qty'] > $optionValue['quantity']) ?
$optionValue['quantity'] : $optionAttr['qty'],
'weight' => round($optionAttr['weight'] + $this->getWeightOption($optionValue), 3)
);
}
}
}
}
foreach($notRequiredOptions as $notRequiredOption) {
if(empty($offers)) {
$offers['0:0-0'] = 0; // Add empty option for mandatory data
foreach($notRequiredOption['product_option_value'] as $optionValue) {
$offers[$notRequiredOption['product_option_id'].':'.$notRequiredOption['option_id'].'-'.$optionValue['option_value_id']] = array(
'price' => (float)$this->getOptionPrice($optionValue),
'qty' => $optionValue['quantity'],
'weight' => round($this->getWeightOption($optionValue), 3)
);
}
} else {
foreach($offers as $optionKey => $optionAttr) {
foreach($notRequiredOption['product_option_value'] as $optionValue) {
$offers[$optionKey.'_'.$notRequiredOption['product_option_id'].':'.$notRequiredOption['option_id'].'-'.$optionValue['option_value_id']] = array(
'price' => $optionAttr['price'] + (float)$this->getOptionPrice($optionValue),
'qty' => ($optionAttr['qty'] > $optionValue['quantity']) ?
$optionValue['quantity'] : $optionAttr['qty'],
'weight' => round($optionAttr['weight'] + $this->getWeightOption($optionValue), 3)
);
}
}
}
}
if(empty($offers)) {
$offers = array('0:0-0' => array('price' => '0', 'qty' => '0'));
}
return $offers;
}
/**
* @param array $option
*
* @return float
*/
private function getWeightOption($option) {
if ($option['weight_prefix'] === '-') {
return $option['weight'] * -1;
}
return $option['weight'];
}
/**
* @param array $optionValue
* @return float|int|mixed
*/
private function getOptionPrice($optionValue) {
if ($optionValue['price_prefix'] === '-') {
return $optionValue['price'] * -1;
}
return $optionValue['price'];
}
/**
* @return mixed
*/
public function getCurrencyForIcml() {
$this->load->model('setting/setting');
$setting = $this->model_setting_setting->getSetting($this->getModuleTitle());
if (isset($setting[$this->getModuleTitle() . '_currency'])
&& $this->currency->has($setting[$this->getModuleTitle() . '_currency'])
) {
return $setting[$this->getModuleTitle() . '_currency'];
}
return false;
}
public function useServicesForIcml()
{
$this->load->model('setting/setting');
$setting = $this->model_setting_setting->getSetting($this->getModuleTitle());
return $setting['module_retailcrm_icml_service_enabled'] ?? false;
}
/**
* @return mixed
*/
public function getLenghtForIcml() {
$this->load->model('setting/setting');
$setting = $this->model_setting_setting->getSetting($this->getModuleTitle());
if (isset($setting[$this->getModuleTitle() . '_lenght'])) {
return $setting[$this->getModuleTitle() . '_lenght'];
}
return false;
}
}

View file

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

View file

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

View file

@ -1,831 +0,0 @@
<?php
/**
* PHP version 5.3
*
* API client class
*
* @category RetailCrm
* @package RetailCrm
* @author RetailCrm <integration@retailcrm.ru>
* @license https://opensource.org/licenses/MIT MIT License
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion3
*/
class RetailcrmApiClient3
{
protected $client;
/**
* Site code
*/
protected $siteCode;
/**
* Client creating
*
* @param string $url
* @param string $apiKey
* @param string $site
* @return mixed
*/
public function __construct($url, $apiKey, $version = null, $site = null)
{
if ('/' != substr($url, strlen($url) - 1, 1)) {
$url .= '/';
}
$url = $version == null ? $url . 'api' : $url . 'api/' . $version;
$this->client = new RetailcrmHttpClient($url, array('apiKey' => $apiKey));
$this->siteCode = $site;
}
/**
* Returns api versions list
*
* @throws \RetailCrm\Exception\InvalidJsonException
* @throws \RetailCrm\Exception\CurlException
* @throws \InvalidArgumentException
*
* @return ApiResponse
*/
public function apiVersions()
{
return $this->client->makeRequest('/api-versions', RetailcrmHttpClient::METHOD_GET);
}
/**
* Create a order
*
* @param array $order
* @param string $site (default: null)
* @return ApiResponse
*/
public function ordersCreate(array $order, $site = null)
{
if (!sizeof($order)) {
throw new InvalidArgumentException('Parameter `order` must contains a data');
}
return $this->client->makeRequest("/orders/create", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array(
'order' => json_encode($order)
)));
}
/**
* Edit a order
*
* @param array $order
* @param string $by
* @param string $site (default: null)
* @return ApiResponse
*/
public function ordersEdit(array $order, $by = 'externalId', $site = null)
{
if (!sizeof($order)) {
throw new InvalidArgumentException('Parameter `order` must contains a data');
}
$this->checkIdParameter($by);
if (!isset($order[$by])) {
throw new InvalidArgumentException(sprintf('Order array must contain the "%s" parameter.', $by));
}
return $this->client->makeRequest(
"/orders/" . $order[$by] . "/edit",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, array(
'order' => json_encode($order),
'by' => $by,
))
);
}
/**
* Upload array of the orders
*
* @param array $orders
* @param string $site (default: null)
* @return ApiResponse
*/
public function ordersUpload(array $orders, $site = null)
{
if (!sizeof($orders)) {
throw new InvalidArgumentException('Parameter `orders` must contains array of the orders');
}
return $this->client->makeRequest("/orders/upload", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array(
'orders' => json_encode($orders),
)));
}
/**
* Get order by id or externalId
*
* @param string $id
* @param string $by (default: 'externalId')
* @param string $site (default: null)
* @return ApiResponse
*/
public function ordersGet($id, $by = 'externalId', $site = null)
{
$this->checkIdParameter($by);
return $this->client->makeRequest("/orders/$id", RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, array(
'by' => $by
)));
}
/**
* Returns a orders history
*
* @param DateTime $startDate (default: null)
* @param DateTime $endDate (default: null)
* @param int $limit (default: 100)
* @param int $offset (default: 0)
* @param bool $skipMyChanges (default: true)
* @return ApiResponse
*/
public function ordersHistory(
DateTime $startDate = null,
DateTime $endDate = null,
$limit = 100,
$offset = 0,
$skipMyChanges = true
) {
$parameters = array();
if ($startDate) {
$parameters['startDate'] = $startDate->format('Y-m-d H:i:s');
}
if ($endDate) {
$parameters['endDate'] = $endDate->format('Y-m-d H:i:s');
}
if ($limit) {
$parameters['limit'] = (int) $limit;
}
if ($offset) {
$parameters['offset'] = (int) $offset;
}
if ($skipMyChanges) {
$parameters['skipMyChanges'] = (bool) $skipMyChanges;
}
return $this->client->makeRequest('/orders/history', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Returns filtered orders list
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @return ApiResponse
*/
public function ordersList(array $filter = array(), $page = null, $limit = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/orders', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Returns statuses of the orders
*
* @param array $ids (default: array())
* @param array $externalIds (default: array())
* @return ApiResponse
*/
public function ordersStatuses(array $ids = array(), array $externalIds = array())
{
$parameters = array();
if (sizeof($ids)) {
$parameters['ids'] = $ids;
}
if (sizeof($externalIds)) {
$parameters['externalIds'] = $externalIds;
}
return $this->client->makeRequest('/orders/statuses', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Save order IDs' (id and externalId) association in the CRM
*
* @param array $ids
* @return ApiResponse
*/
public function ordersFixExternalIds(array $ids)
{
if (!sizeof($ids)) {
throw new InvalidArgumentException('Method parameter must contains at least one IDs pair');
}
return $this->client->makeRequest("/orders/fix-external-ids", RetailcrmHttpClient::METHOD_POST, array(
'orders' => json_encode($ids),
));
}
/**
* Get orders assembly history
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @return ApiResponse
*/
public function ordersPacksHistory(array $filter = array(), $page = null, $limit = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/orders/packs/history', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Create a customer
*
* @param array $customer
* @param string $site (default: null)
* @return ApiResponse
*/
public function customersCreate(array $customer, $site = null)
{
if (!sizeof($customer)) {
throw new InvalidArgumentException('Parameter `customer` must contains a data');
}
return $this->client->makeRequest("/customers/create", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array(
'customer' => json_encode($customer)
)));
}
/**
* Edit a customer
*
* @param array $customer
* @param string $by (default: 'externalId')
* @param string $site (default: null)
* @return ApiResponse
*/
public function customersEdit(array $customer, $by = 'externalId', $site = null)
{
if (!sizeof($customer)) {
throw new InvalidArgumentException('Parameter `customer` must contains a data');
}
$this->checkIdParameter($by);
if (!isset($customer[$by])) {
throw new InvalidArgumentException(sprintf('Customer array must contain the "%s" parameter.', $by));
}
return $this->client->makeRequest(
"/customers/" . $customer[$by] . "/edit",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite(
$site,
array(
'customer' => json_encode($customer),
'by' => $by
)
)
);
}
/**
* Upload array of the customers
*
* @param array $customers
* @param string $site (default: null)
* @return ApiResponse
*/
public function customersUpload(array $customers, $site = null)
{
if (!sizeof($customers)) {
throw new InvalidArgumentException('Parameter `customers` must contains array of the customers');
}
return $this->client->makeRequest("/customers/upload", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array(
'customers' => json_encode($customers),
)));
}
/**
* Get customer by id or externalId
*
* @param string $id
* @param string $by (default: 'externalId')
* @param string $site (default: null)
* @return ApiResponse
*/
public function customersGet($id, $by = 'externalId', $site = null)
{
$this->checkIdParameter($by);
return $this->client->makeRequest("/customers/$id", RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, array(
'by' => $by
)));
}
/**
* Returns filtered customers list
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @return ApiResponse
*/
public function customersList(array $filter = array(), $page = null, $limit = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/customers', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Save customer IDs' (id and externalId) association in the CRM
*
* @param array $ids
* @return ApiResponse
*/
public function customersFixExternalIds(array $ids)
{
if (!sizeof($ids)) {
throw new InvalidArgumentException('Method parameter must contains at least one IDs pair');
}
return $this->client->makeRequest("/customers/fix-external-ids", RetailcrmHttpClient::METHOD_POST, array(
'customers' => json_encode($ids),
));
}
/**
* Get purchace prices & stock balance
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @param string $site (default: null)
* @return ApiResponse
*/
public function storeInventories(array $filter = array(), $page = null, $limit = null, $site = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/store/inventories', RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, $parameters));
}
/**
* Upload store inventories
*
* @param array $offers
* @param string $site (default: null)
* @return ApiResponse
*/
public function storeInventoriesUpload(array $offers, $site = null)
{
if (!sizeof($offers)) {
throw new InvalidArgumentException('Parameter `offers` must contains array of the customers');
}
return $this->client->makeRequest(
"/store/inventories/upload",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, array('offers' => json_encode($offers)))
);
}
/**
* Returns deliveryServices list
*
* @return ApiResponse
*/
public function deliveryServicesList()
{
return $this->client->makeRequest('/reference/delivery-services', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns deliveryTypes list
*
* @return ApiResponse
*/
public function deliveryTypesList()
{
return $this->client->makeRequest('/reference/delivery-types', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns orderMethods list
*
* @return ApiResponse
*/
public function orderMethodsList()
{
return $this->client->makeRequest('/reference/order-methods', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns orderTypes list
*
* @return ApiResponse
*/
public function orderTypesList()
{
return $this->client->makeRequest('/reference/order-types', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns paymentStatuses list
*
* @return ApiResponse
*/
public function paymentStatusesList()
{
return $this->client->makeRequest('/reference/payment-statuses', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns paymentTypes list
*
* @return ApiResponse
*/
public function paymentTypesList()
{
return $this->client->makeRequest('/reference/payment-types', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns productStatuses list
*
* @return ApiResponse
*/
public function productStatusesList()
{
return $this->client->makeRequest('/reference/product-statuses', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns statusGroups list
*
* @return ApiResponse
*/
public function statusGroupsList()
{
return $this->client->makeRequest('/reference/status-groups', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns statuses list
*
* @return ApiResponse
*/
public function statusesList()
{
return $this->client->makeRequest('/reference/statuses', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns sites list
*
* @return ApiResponse
*/
public function sitesList()
{
return $this->client->makeRequest('/reference/sites', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns stores list
*
* @return ApiResponse
*/
public function storesList()
{
return $this->client->makeRequest('/reference/stores', RetailcrmHttpClient::METHOD_GET);
}
/**
* Edit deliveryService
*
* @param array $data delivery service data
* @return ApiResponse
*/
public function deliveryServicesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/delivery-services/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'deliveryService' => json_encode($data)
)
);
}
/**
* Edit deliveryType
*
* @param array $data delivery type data
* @return ApiResponse
*/
public function deliveryTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/delivery-types/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'deliveryType' => json_encode($data)
)
);
}
/**
* Edit orderMethod
*
* @param array $data order method data
* @return ApiResponse
*/
public function orderMethodsEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/order-methods/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'orderMethod' => json_encode($data)
)
);
}
/**
* Edit orderType
*
* @param array $data order type data
* @return ApiResponse
*/
public function orderTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/order-types/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'orderType' => json_encode($data)
)
);
}
/**
* Edit paymentStatus
*
* @param array $data payment status data
* @return ApiResponse
*/
public function paymentStatusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/payment-statuses/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'paymentStatus' => json_encode($data)
)
);
}
/**
* Edit paymentType
*
* @param array $data payment type data
* @return ApiResponse
*/
public function paymentTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/payment-types/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'paymentType' => json_encode($data)
)
);
}
/**
* Edit productStatus
*
* @param array $data product status data
* @return ApiResponse
*/
public function productStatusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/product-statuses/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'productStatus' => json_encode($data)
)
);
}
/**
* Edit order status
*
* @param array $data status data
* @return ApiResponse
*/
public function statusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/statuses/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'status' => json_encode($data)
)
);
}
/**
* Edit site
*
* @param array $data site data
* @return ApiResponse
*/
public function sitesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/sites/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'site' => json_encode($data)
)
);
}
/**
* Edit store
*
* @param array $data site data
* @return ApiResponse
*/
public function storesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
if (!isset($data['name'])) {
throw new InvalidArgumentException('Data must contain "name" parameter.');
}
return $this->client->makeRequest(
'/reference/stores/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'store' => json_encode($data)
)
);
}
/**
* Update CRM basic statistic
*
* @return ApiResponse
*/
public function statisticUpdate()
{
return $this->client->makeRequest('/statistic/update', RetailcrmHttpClient::METHOD_GET);
}
/**
* Return current site
*
* @return string
*/
public function getSite()
{
return $this->siteCode;
}
/**
* Set site
*
* @param string $site
* @return void
*/
public function setSite($site)
{
$this->siteCode = $site;
}
/**
* Check ID parameter
*
* @param string $by
* @return bool
*/
protected function checkIdParameter($by)
{
$allowedForBy = array('externalId', 'id');
if (!in_array($by, $allowedForBy)) {
throw new InvalidArgumentException(sprintf(
'Value "%s" for parameter "by" is not valid. Allowed values are %s.',
$by,
implode(', ', $allowedForBy)
));
}
return true;
}
/**
* Fill params by site value
*
* @param string $site
* @param array $params
* @return array
*/
protected function fillSite($site, array $params)
{
if ($site) {
$params['site'] = $site;
} elseif ($this->siteCode) {
$params['site'] = $this->siteCode;
}
return $params;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,58 +0,0 @@
<?php
/**
* Class RequestProxy
* @package RetailCrm\Component
*/
class RetailcrmProxy
{
private $api;
private $log;
public function __construct($url, $key, $log, $version = null)
{
switch ($version) {
case 'v5':
$this->api = new RetailcrmApiClient5($url, $key, $version);
break;
case 'v4':
$this->api = new RetailcrmApiClient4($url, $key, $version);
break;
case 'v3':
$this->api = new RetailcrmApiClient3($url, $key, $version);
break;
case null:
$this->api = new RetailcrmApiClient3($url, $key, $version);
break;
}
$this->log = $log;
}
public function __call($method, $arguments)
{
$date = date('[Y-m-d H:i:s]');
try {
$response = call_user_func_array(array($this->api, $method), $arguments);
if (!$response->isSuccessful()) {
error_log($date . " [$method] " . $response->getErrorMsg() . "\n", 3, $this->log);
if (isset($response['errors'])) {
$error = implode("\n", $response['errors']);
error_log($date .' '. $error . "\n", 3, $this->log);
}
}
return $response;
} catch (CurlException $e) {
error_log($date . " [$method] " . $e->getMessage() . "\n", 3, $this->log);
return false;
} catch (InvalidJsonException $e) {
error_log($date . " [$method] " . $e->getMessage() . "\n", 3, $this->log);
return false;
}
}
}

View file

@ -1,166 +0,0 @@
<?php
namespace retailcrm;
require_once 'bootstrap.php';
class Retailcrm {
protected $apiClient;
protected $registry;
public function __construct($registry)
{
$this->registry = $registry;
}
public function __get($name) {
return $this->registry->get($name);
}
/**
* Get api client object
*
* @param string $apiUrl (default = null)
* @param string $apiKey (default = null)
* @param string $apiVersion (default = null)
*
* @return mixed object | boolean
*/
public function getApiClient($apiUrl = null, $apiKey = null, $apiVersion = null)
{
$this->load->model('setting/setting');
$setting = $this->model_setting_setting->getSetting($this->getModuleTitle());
if ($apiUrl === null && $apiKey === null) {
$apiUrl = $setting[$this->getModuleTitle() . '_url'];
$apiKey = $setting[$this->getModuleTitle() . '_apikey'];
$apiVersion = $setting[$this->getModuleTitle() . '_apiversion'];
}
if ($apiUrl && $apiKey) {
$this->apiClient = new \RetailcrmProxy($apiUrl, $apiKey, DIR_LOGS . 'retailcrm.log', $apiVersion);
return $this->apiClient;
}
return false;
}
/**
* Get opencart api client
*
* @param object $registry
*
* @return \OpencartApiClient
*/
public function getOcApiClient($registry)
{
return new \OpencartApiClient($registry);
}
/**
* Get module title for this version
*
* @return string $title
*/
public function getModuleTitle()
{
if (version_compare(VERSION, '3.0', '<')) {
$title = 'retailcrm';
} else {
$title = 'module_retailcrm';
}
return $title;
}
/**
* Get token param name
*
* @return string $token
*/
public function getTokenTitle()
{
if (version_compare(VERSION, '3.0', '<')) {
$token = 'token';
} else {
$token = 'user_token';
}
return $token;
}
public function getOffers($product)
{
// Формируем офферы отнсительно доступных опций
$options = $this->model_catalog_product->getProductOptions($product['product_id']);
$offerOptions = array('select', 'radio');
$requiredOptions = array();
$notRequiredOptions = array();
// Оставляем опции связанные с вариациями товаров, сортируем по параметру обязательный или нет
foreach($options as $option) {
if(in_array($option['type'], $offerOptions)) {
if($option['required']) {
$requiredOptions[] = $option;
} else {
$notRequiredOptions[] = $option;
}
}
}
$offers = array();
// Сначала совмещаем все обязательные опции
foreach($requiredOptions as $requiredOption) {
// Если первая итерация
if(empty($offers)) {
foreach($requiredOption['product_option_value'] as $optionValue) {
$offers[$requiredOption['product_option_id'].':'.$requiredOption['option_id'].'-'.$optionValue['option_value_id']] = array(
'price' => (float)$optionValue['price'],
'qty' => $optionValue['quantity']
);
}
} else {
foreach($offers as $optionKey => $optionAttr) {
unset($offers[$optionKey]); // Работая в контексте обязательных опций не забываем удалять прошлые обязательные опции, т.к. они должны быть скомбинированы с другими обязательными опциями
foreach($requiredOption['product_option_value'] as $optionValue) {
$offers[$optionKey.'_'.$requiredOption['product_option_id'].':'.$requiredOption['option_id'].'-'.$optionValue['option_value_id']] = array(
'price' => $optionAttr['price'] + (float)$optionValue['price'],
'qty' => ($optionAttr['qty'] > $optionValue['quantity']) ?
$optionValue['quantity'] : $optionAttr['qty']
);
}
}
}
}
// Совмещаем или добавляем необязательные опции, учитывая тот факт что обязательных опций может и не быть.
foreach($notRequiredOptions as $notRequiredOption) {
// Если обязательных опцией не оказалось и первая итерация
if(empty($offers)) {
$offers['0:0-0'] = 0; // В случае работы с необязательными опциями мы должны учитывать товарное предложение без опций, поэтому создадим "пустую" опцию
foreach($notRequiredOption['product_option_value'] as $optionValue) {
$offers[$notRequiredOption['product_option_id'].':'.$notRequiredOption['option_id'].'-'.$optionValue['option_value_id']] = array(
'price' => (float)$optionValue['price'],
'qty' => $optionValue['quantity']
);
}
} else {
foreach($offers as $optionKey => $optionAttr) {
foreach($notRequiredOption['product_option_value'] as $optionValue) {
$offers[$optionKey.'_'.$notRequiredOption['product_option_id'].':'.$notRequiredOption['option_id'].'-'.$optionValue['option_value_id']] = array(
'price' => $optionAttr['price'] + (float)$optionValue['price'],
'qty' => ($optionAttr['qty'] > $optionValue['quantity']) ?
$optionValue['quantity'] : $optionAttr['qty']
);
}
}
}
}
if(empty($offers)) {
$offers = array('0:0-0' => array('price' => '0', 'qty' => '0'));
}
return $offers;
}
}

58
tests/3/TestCase.php Normal file
View file

@ -0,0 +1,58 @@
<?php
class TestCase extends \Tests\OpenCartTest {
public function setUp() {
parent::setUp();
$this->load->library('retailcrm/retailcrm');
$this->setSetting(
$this->retailcrm->getModuleTitle(),
array(
$this->retailcrm->getModuleTitle() . '_apiversion' => 'v5',
$this->retailcrm->getModuleTitle() . '_order_number' => 1,
$this->retailcrm->getModuleTitle() . '_status' => array(
1 => 'new'
),
$this->retailcrm->getModuleTitle() . '_delivery' => array(
'flat.flat' => 'flat'
),
$this->retailcrm->getModuleTitle() . '_payment' => array(
'cod' => 'cod'
),
$this->retailcrm->getModuleTitle() . '_special_1' => 'special1',
$this->retailcrm->getModuleTitle() . '_special_2' => 'special2',
$this->retailcrm->getModuleTitle() . '_special_3' => 'special3',
$this->retailcrm->getModuleTitle() . '_collector' => array(
'site_key' => 'RC-XXXXXXXXXX-X',
'custom_form' => 1,
'custom' => array(
'name' => 'Name',
'email' => 'Email',
'phone' => 'Phone',
),
'form_capture' => 1,
'period' => 1
)
)
);
}
protected function setSetting($code, $data, $store_id = 0) {
$this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE store_id = '" . (int)$store_id . "' AND `code` = '" . $this->db->escape($code) . "'");
foreach ($data as $key => $value) {
if (substr($key, 0, strlen($code)) == $code) {
if (!is_array($value)) {
$this->db->query("INSERT INTO " . DB_PREFIX . "setting SET store_id = '" . (int)$store_id . "', `code` = '" . $this->db->escape($code) . "', `key` = '" . $this->db->escape($key) . "', `value` = '" . $this->db->escape($value) . "'");
} else {
$this->db->query("INSERT INTO " . DB_PREFIX . "setting SET store_id = '" . (int)$store_id . "', `code` = '" . $this->db->escape($code) . "', `key` = '" . $this->db->escape($key) . "', `value` = '" . $this->db->escape(json_encode($value, true)) . "', serialized = '1'");
}
}
}
}
public function tearDown()
{
}
}

261
tests/RoboFile.php Normal file
View file

@ -0,0 +1,261 @@
<?php
require_once(__DIR__.'/../vendor/autoload.php');
class RoboFile extends \Robo\Tasks
{
use \Robo\Task\Development\loadTasks;
use \Robo\Common\TaskIO;
const OPENCART_DOWNLOAD_URL = [
'3.0.1.2' => 'https://github.com/opencart/opencart/releases/download/3.0.1.2/3.0.1.2-opencart.zip',
'3.0.2.0' => 'https://github.com/opencart/opencart/releases/download/3.0.2.0/3.0.2.0-OpenCart.zip',
'3.0.3.4' => 'https://github.com/opencart/opencart/releases/download/3.0.3.4/opencart-3.0.3.4-core-pre.zip'
];
const OPENCART_ROOT_DIR = [
'3.0.3.4' => 'opencart-3.0.3.4/upload'
];
/**
* @var array
*/
private $opencart_config;
/**
* @var int
*/
private $server_port = 80;
/**
* @var string
*/
private $server_url = 'http://localhost';
private $root_dir = __DIR__ . '/../';
public function __construct()
{
if ($_ENV) {
foreach ($_ENV as $option => $value) {
if (substr($option, 0, 3) === 'OC_') {
$option = strtolower(substr($option, 3));
$this->opencart_config[$option] = $value;
} elseif ($option === 'SERVER_PORT') {
$this->server_port = (int) $value;
} elseif ($option === 'SERVER_URL') {
$this->server_url = $value;
}
}
} else {
$this->opencart_config = [
'db_hostname' => getenv('OC_DB_HOSTNAME'),
'db_username' => getenv('OC_DB_USERNAME'),
'db_password' => getenv('OC_DB_PASSWORD'),
'db_database' => getenv('OC_DB_DATABASE'),
'db_driver' => getenv('OC_DB_DRIVER'),
'username' => getenv('OC_USERNAME'),
'password' => getenv('OC_PASSWORD'),
'email' => getenv('OC_EMAIL')
];
}
$this->opencart_config['http_server'] = $this->server_url.':'.$this->server_port.'/';
$required = array('db_username', 'password', 'email');
$missing = array();
foreach ($required as $config) {
if (empty($this->opencart_config[$config])) {
$missing[] = 'OC_'.strtoupper($config);
}
}
if (!empty($missing)) {
$this->printTaskError("<error> Missing ".implode(', ', $missing));
$this->printTaskError("<error> See .env.sample ");
die();
}
}
public function opencartInstall()
{
$startUp = 'admin/controller/startup/test_startup.php';
$startUpTo = 'admin/controller/startup/test_startup.php';
$version = getenv('OPENCART');
$ocZip = sprintf('/tmp/opencart-%s.zip', $version);
$this->taskDeleteDir($this->root_dir . 'www')->run();
file_put_contents($ocZip, file_get_contents($this->getOpencartDownloadUrl($version)));
$this->_exec(sprintf('unzip %s -d /tmp/opencart', $ocZip));
$this->taskFileSystemStack()
->mirror(
$this->getOpencartRootDir($version),
$this->root_dir . 'www'
)
->copy(
$this->root_dir . 'vendor/beyondit/opencart-test-suite/src/upload/system/config/test-config.php',
$this->root_dir . 'www/system/config/test-config.php'
)
->copy(
$this->root_dir . 'vendor/beyondit/opencart-test-suite/src/upload/' . $startUp,
$this->root_dir . 'www/' . $startUpTo
)
->chmod($this->root_dir . 'www', 0777, 0000, true)
->run();
if (getenv('TEST_SUITE') === '3') {
$this->taskFileSystemStack()->copy(
$this->root_dir . 'vendor/beyondit/opencart-test-suite/src/upload/system/library/session/test.php',
$this->root_dir . 'www/system/library/session/test.php'
)->run();
}
// Openbay was removed in 3.0.3.6
// Unfortunately, those configs from test suite still require it.
if (
'3.0.3.4' === getenv('OPENCART') ||
version_compare(getenv('OPENCART'), '3.0.3.6', '>=')
) {
$testConfigFile = $this->root_dir . 'www/system/config/test-config.php';
$testStartupFile = $this->root_dir . 'www/' . $startUpTo;
$testConfig = file_get_contents($testConfigFile);
$testStartup = file_get_contents($testStartupFile);
$testConfig = str_ireplace("'openbay'", '', $testConfig);
$testStartup = str_ireplace('$this->registry->set(\'openbay\', new Openbay($this->registry));', '', $testStartup);
file_put_contents($testConfigFile, $testConfig);
file_put_contents($testStartupFile, $testStartup);
}
// Create new database, drop if exists already
try {
$conn = new PDO("mysql:host=".$this->opencart_config['db_hostname'], $this->opencart_config['db_username'], $this->opencart_config['db_password']);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("DROP DATABASE IF EXISTS `" . $this->opencart_config['db_database'] . "`");
$conn->exec("CREATE DATABASE `" . $this->opencart_config['db_database'] . "`");
}
catch(PDOException $e)
{
$this->printTaskError($e->getMessage());
$this->printTaskError("<error> Could not connect to database...");
}
if (version_compare(getenv('OPENCART'), '3.0.2.0', '<=')) {
$install_code = file_get_contents($this->root_dir . 'www/install/cli_install.php');
$storage = <<<EOF
define('DIR_MODIFICATION', DIR_SYSTEM . 'modification/');
define('DIR_STORAGE', DIR_SYSTEM . 'storage/');
EOF;
file_put_contents(
$this->root_dir . 'www/install/cli_install.php',
str_replace("define('DIR_MODIFICATION', DIR_SYSTEM . 'modification/');", $storage, $install_code)
);
}
$install = $this->taskExec('php')->arg($this->root_dir . 'www/install/cli_install.php')->arg('install');
foreach ($this->opencart_config as $option => $value) {
$install->option($option, $value);
}
$install->run();
$this->taskDeleteDir($this->root_dir . 'www/install')->run();
$this->restoreSampleData($conn);
$conn = null;
}
public function opencartRun()
{
$this->taskServer($this->server_port)
->dir($this->root_dir . 'www')
->run();
}
public function projectDeploy()
{
$this->taskFileSystemStack()
->mirror($this->root_dir . 'src/upload', $this->root_dir . 'www')
// ->copy('src/install.xml','www/system/install.ocmod.xml') if exist modification for OCMOD
->run();
}
public function projectWatch()
{
$this->projectDeploy();
$this->taskWatch()
->monitor($this->root_dir . 'composer.json', function () {
$this->taskComposerUpdate()->run();
$this->projectDeploy();
})->monitor($this->root_dir . 'src/', function () {
$this->projectDeploy();
})->run();
}
public function projectPackage()
{
$this->taskDeleteDir('target')->run();
$this->taskFileSystemStack()->mkdir('target')->run();
$zip = new ZipArchive();
$filename = "target/build.ocmod.zip";
if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
$this->printTaskError("<error> Could not create ZipArchive");
exit();
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator("src", \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($iterator as $file) {
if ($file->isFile() && $file->isReadable()) {
$zip->addFile($file->getPathname(),substr($file->getPathname(),4));
}
}
$zip->close();
}
private function getOpencartDownloadUrl(string $version): string
{
if (version_compare($version, '3.0.1.1', '<=')) {
return sprintf('https://github.com/opencart/opencart/releases/download/%s/%s-compiled.zip', $version, $version);
}
if (array_key_exists($version, self::OPENCART_DOWNLOAD_URL)) {
return self::OPENCART_DOWNLOAD_URL[$version];
}
return sprintf('https://github.com/opencart/opencart/releases/download/%s/opencart-%s.zip', $version, $version);
}
private function getOpencartRootDir(string $version): string
{
if (array_key_exists($version, self::OPENCART_ROOT_DIR)) {
return '/tmp/opencart/' . self::OPENCART_ROOT_DIR[$version];
}
return '/tmp/opencart/upload';
}
private function restoreSampleData($conn)
{
$sql = file_get_contents($this->root_dir . 'tests/opencart_sample_data_3.sql');
$conn->exec("USE " . $this->opencart_config['db_database']);
foreach (explode(";\n", $sql) as $sql) {
$sql = trim($sql);
if ($sql) {
$conn->exec($sql);
}
}
}
}

View file

@ -0,0 +1,103 @@
<?php
require_once __DIR__ . '/../' . getenv('TEST_SUITE') . '/TestCase.php';
class ControllerRetailcrmAdminTest extends TestCase
{
const MODULE_TITLE = 'retailcrm';
public function setUp()
{
parent::setUp();
$query = $this->db->query("SELECT permission from ".DB_PREFIX."user_group WHERE name = 'Administrator'");
$permissions = json_decode($query->row['permission'],true);
if (!in_array('extension/module/retailcrm', $permissions['access'])) {
$permissions['access'][] = 'extension/module/retailcrm';
$this->db->query("UPDATE ".DB_PREFIX."user_group SET permission='".$this->db->escape(json_encode($permissions))."' WHERE name = 'Administrator'");
}
$this->retailcrm = $this->getMockBuilder('\retailcrm\Retailcrm')
->disableOriginalConstructor()
->getMock();
}
public function testController()
{
$this->login('admin', 'admin');
$response = $this->dispatchAction('extension/module/retailcrm');
$this->assertRegExp('/Connection settings/', $response->getOutput());
$response = $this->dispatchAction('extension/module/retailcrm/icml');
$this->assertRegExp('/Connection settings/', $response->getOutput());
$this->assertFileExists(DIR_SYSTEM . '../' . 'retailcrm.xml');
$response = $this->dispatchAction('extension/module/retailcrm/install_collector');
$this->assertRegExp('/Connection settings/', $response->getOutput());
$response = $this->dispatchAction('extension/module/retailcrm/uninstall_collector');
$this->assertRegExp('/Connection settings/', $response->getOutput());
}
public function testGetAvailableTypes()
{
$data = $this->getDataForTestAvailableTypes();
$sites = end($data['site']);
$types = $data['types'];
$retailCrm = new ControllerExtensionModuleRetailcrm(self::$registry);
$class = new ReflectionClass($retailCrm);
$method = $class->getMethod('getAvailableTypes');
$method->setAccessible(true);
$result = $method->invokeArgs($retailCrm, [$sites, $types]);
$this->assertNotEmpty($result['opencart']);
$this->assertNotEmpty($result['retailcrm']);
$this->assertCount(2, $result['retailcrm']);
$this->assertNotEmpty($result['retailcrm']['test1']['code']);
$this->assertNotEmpty($result['retailcrm']['test4']['code']);
}
private function getDataForTestAvailableTypes(): array
{
return [
'site' => [
'opencart' => [
'code' => 'opencart',
'name' => 'OpenCart'
]
],
'types' => [
'opencart' => [
'test'
],
'retailcrm' => [
'test1' => [
'active' => true,
'sites' => [],
'code' => 'test1'
],
'test2' => [
'active' => false,
'sites' => [],
'code' => 'test2'
],
'test3' => [
'active' => true,
'sites' => ['otherSite'],
'code' => 'test3'
],
'test4' => [
'active' => true,
'sites' => ['cms1', 'cms2', 'opencart'],
'code' => 'test4'
]
]
]
];
}
}

View file

@ -0,0 +1,44 @@
<?php
require_once __DIR__ . '/../' . getenv('TEST_SUITE') . '/TestCase.php';
class ModelRetailcrmCustomerAdminTest extends TestCase
{
private $customerModel;
private $apiClientMock;
const CUSTOMER_ID = 1;
public function setUp()
{
parent::setUp();
$this->customerModel = $this->loadModel('extension/retailcrm/customer');
$this->apiClientMock = $this->getMockBuilder(\RetailcrmProxy::class)
->disableOriginalConstructor()
->setMethods(array(
'customersUpload',
'customersEdit'
))
->getMock();
self::$registry->set(\RetailcrmProxy::class, $this->apiClientMock);
}
public function testUploadToCrm()
{
$customerModel = $this->loadModel('customer/customer');
$customers = $customerModel->getCustomers();
$customersSend = $this->customerModel->uploadToCrm($customers, $this->apiClientMock);
$customer = $customersSend[0][0];
$this->assertInternalType('array', $customersSend);
$this->assertInternalType('array', $customersSend[0]);
$this->assertArrayHasKey('externalId', $customer);
$this->assertArrayHasKey('firstName', $customer);
$this->assertArrayHasKey('lastName', $customer);
$this->assertArrayHasKey('email', $customer);
}
}

View file

@ -0,0 +1,27 @@
<?php
require_once __DIR__ . '/../' . getenv('TEST_SUITE') . '/TestCase.php';
class ModelRetailcrmEventAdminTest extends TestCase
{
const CODE = 'test';
public function setUp()
{
parent::setUp();
$eventModel = $this->loadModel('setting/event');
$eventModel->addEvent(self::CODE, 'test', 'test');
}
public function testGetEvent()
{
$eventModel = $this->loadModel('extension/retailcrm/event');
$event = $eventModel->getEventByCode(self::CODE);
$this->assertNotEmpty($event);
$this->assertEquals(self::CODE, $event['code']);
$this->assertEquals('test', $event['trigger']);
$this->assertEquals('test', $event['action']);
}
}

View file

@ -0,0 +1,75 @@
<?php
require_once __DIR__ . '/../' . getenv('TEST_SUITE') . '/TestCase.php';
class ModelRetailcrmOrderAdminTest extends TestCase
{
private $orderModel;
private $apiClientMock;
private $settingModel;
const CUSTOMER_ID = 1;
const ORDER_WITH_CUST_ID = 1;
const ORDER_ID = 2;
public function setUp()
{
parent::setUp();
$this->apiClientMock = $this->getMockBuilder(\RetailcrmProxy::class)
->disableOriginalConstructor()
->setMethods(array(
'ordersUpload',
'customersList',
'ordersCreate',
'ordersPaymentCreate',
'customersCreate'
))
->getMock();
self::$registry->set(\RetailcrmProxy::class, $this->apiClientMock);
$this->orderModel = $this->loadModel('extension/retailcrm/order');
$this->settingModel = $this->loadModel('setting/setting');
}
public function testUploadToCrm()
{
$saleOrderModel = $this->loadModel('sale/order');
$orders = $saleOrderModel->getOrders();
$fullOrders = array();
foreach ($orders as $order) {
$fullOrder = $saleOrderModel->getOrder($order['order_id']);
$fullOrder['totals'] = $saleOrderModel->getOrderTotals($order['order_id']);
$fullOrder['products'] = $saleOrderModel->getOrderProducts($order['order_id']);
foreach($fullOrder['products'] as $key => $product) {
$fullOrder['products'][$key]['option'] = $saleOrderModel->getOrderOptions($product['order_id'], $product['order_product_id']);
}
$fullOrders[] = $fullOrder;
}
$chunkedOrders = $this->orderModel->uploadToCrm($fullOrders);
$order = $chunkedOrders[0][0];
$this->assertInternalType('array', $chunkedOrders);
$this->assertInternalType('array', $chunkedOrders[0]);
$this->assertNotEmpty($chunkedOrders[0]);
$this->assertArrayHasKey('externalId', $order);
$this->assertArrayHasKey('number', $order);
$this->assertArrayHasKey('firstName', $order);
$this->assertArrayHasKey('lastName', $order);
$this->assertArrayHasKey('email', $order);
$this->assertArrayHasKey('phone', $order);
$this->assertArrayHasKey('createdAt', $order);
$this->assertArrayHasKey('delivery', $order);
$this->assertArrayHasKey('status', $order);
$this->assertArrayHasKey('items', $order);
$this->assertArrayHasKey('payments', $order);
$this->assertNotEmpty($order['payments']);
}
}

View file

@ -0,0 +1,96 @@
<?php
require_once __DIR__ . '/../' . getenv('TEST_SUITE') . '/TestCase.php';
class ModelRetailcrmPricesAdminTest extends TestCase
{
private $pricesModel;
private $apiClientMock;
private $settingModel;
private $retailcrm;
public function setUp()
{
parent::setUp();
$this->pricesModel = $this->loadModel('extension/retailcrm/prices');
$this->apiClientMock = $this->getMockBuilder(\RetailcrmProxy::class)
->disableOriginalConstructor()
->setMethods(array(
'storePricesUpload',
'sitesList',
'isSuccessful'
))
->getMock();
$this->settingModel = $this->loadModel('setting/setting');
$this->retailcrm = new \retailcrm\Retailcrm(self::$registry);
$this->settingModel->editSetting(
$this->retailcrm->getModuleTitle(),
array(
$this->retailcrm->getModuleTitle() . '_apiversion' => 'v5',
$this->retailcrm->getModuleTitle() . '_special_1' => 'special1',
$this->retailcrm->getModuleTitle() . '_special_2' => 'special2',
$this->retailcrm->getModuleTitle() . '_special_3' => 'special3'
)
);
}
public function testUploadPrices()
{
$response = new \RetailcrmApiResponse(
200,
json_encode(
$this->sites()
)
);
$this->apiClientMock->expects($this->any())->method('sitesList')->willReturn($response);
$productModel = $this->loadModel('catalog/product');
$products = $productModel->getProducts();
$prices = $this->pricesModel->uploadPrices($products, $this->apiClientMock);
$price = $prices[0][0];
$this->assertInternalType('array', $prices);
$this->assertInternalType('array', $prices[0]);
$this->assertInternalType('array', $price);
$this->assertArrayHasKey('externalId', $price);
$this->assertArrayHasKey('site', $price);
$this->assertArrayHasKey('prices', $price);
$this->assertInternalType('array', $price['prices']);
$this->assertEquals('special1', $price['prices'][0]['code']);
$this->assertEquals('special2', $price['prices'][1]['code']);
$this->assertEquals('special3', $price['prices'][2]['code']);
$this->assertFalse($price['prices'][0]['remove']);
$this->assertNotFalse($price['prices'][1]['remove']);
$this->assertNotFalse($price['prices'][2]['remove']);
}
private function sites(){
return array(
"success"=> true,
"sites"=> array(
"opencart"=> array(
"name"=> "site",
"url"=> "http://site.ru",
"code"=> "site",
"defaultForCrm"=> false,
"ymlUrl"=> "http://site.ru/retailcrm.xml",
"loadFromYml"=> false,
"catalogUpdatedAt"=> "2019-02-08 13:30:37",
"catalogLoadingAt"=> "2019-02-11 09:12:18",
"contragent"=> array(
"contragentType"=> "legal-entity",
"legalName"=> "code",
"code"=> "code",
"countryIso"=> "RU",
"vatRate"=> "",
),
"countryIso"=> "",
)
),
);
}
}

View file

@ -0,0 +1,11 @@
<?php
require_once __DIR__ . '/../' . getenv('TEST_SUITE') . '/TestCase.php';
class ControllerDaemonCollectorExtensionAnalyticsCatalogTest extends TestCase {
public function testIndex() {
$data = $this->load->controller('extension/analytics/daemon_collector');
$this->assertContains('RC-XXXXXXXXXX-X', $data);
}
}

View file

@ -0,0 +1,64 @@
<?php
require_once __DIR__ . '/../' . getenv('TEST_SUITE') . '/TestCase.php';
class ControllerRetailcrmApiCatalogTest extends TestCase
{
private $apiKey;
private $retailcrm;
const ORDER_ID = 1;
const USERNAME = 'Default';
public function setUp()
{
parent::setUp();
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "api` WHERE api_id = 1");
$api = $query->row;
$this->apiKey = $api['key'];
$this->retailcrm = new \retailcrm\Retailcrm(self::$registry);
$this->setSetting(
$this->retailcrm->getModuleTitle(),
array(
$this->retailcrm->getModuleTitle() . '_country' => array(1),
)
);
if (isset($this->request->get['key']) && isset($this->request->get['username'])) {
unset($this->request->get['key']);
unset($this->request->get['username']);
}
}
public function testGetDeliveryTypes()
{
$response = $this->dispatchAction('api/retailcrm/getDeliveryTypes');
$data = json_decode($response->getOutput());
$this->assertEquals('Not found api key', $data->error);
$this->request->get['key'] = $this->apiKey;
$this->request->get['username'] = static::USERNAME;
$response = $this->dispatchAction('api/retailcrm/getDeliveryTypes');
$data = json_decode($response->getOutput());
$this->assertNotEmpty($data);
}
public function testAddOrderHistory()
{
$response = $this->dispatchAction('api/retailcrm/addOrderHistory');
$data = json_decode($response->getOutput());
$this->assertEquals('Not found api key', $data->error);
$this->request->get['key'] = $this->apiKey;
$this->request->get['username'] = static::USERNAME;
$response = $this->dispatchAction('api/retailcrm/addOrderHistory');
$data = json_decode($response->getOutput());
$this->assertEquals('Not found data', $data->error);
}
}

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