Compare commits
789 commits
Author | SHA1 | Date | |
---|---|---|---|
|
e61259ded9 | ||
|
0359315c79 | ||
|
08ff21ce04 | ||
|
de7ecd4100 | ||
|
54692c50d4 | ||
|
61044988d5 | ||
|
7a36fa5de7 | ||
|
8cf4420592 | ||
|
84c7d10146 | ||
|
8c38d21477 | ||
|
115cf33423 | ||
|
3162031b65 | ||
|
1ec3bccd0c | ||
|
41257b9d7c | ||
|
b68779a054 | ||
|
d25c7fc484 | ||
|
317a30b682 | ||
|
534757e6c6 | ||
|
7e260a2d22 | ||
|
6fb061e6cc | ||
|
a77b29cd49 | ||
|
c1deb9e91e | ||
|
1d2a87f277 | ||
|
74833ed2db | ||
|
8eab4864c5 | ||
|
169509c263 | ||
|
1b64044013 | ||
|
a83ff3cc6b | ||
|
6a6a4545b8 | ||
|
10745c4c8d | ||
|
ebb32869aa | ||
|
3e3e37b297 | ||
|
1ab3dacaf7 | ||
|
0550d8ffba | ||
|
51f8c98010 | ||
|
ee6d654d8c | ||
|
453bc495c0 | ||
|
1eabbe323b | ||
|
c1f59ead7f | ||
|
cbddd69001 | ||
|
7f69ebfa1f | ||
|
830fe34e3e | ||
|
85749c8602 | ||
|
d298cffb22 | ||
|
50997b729f | ||
|
4f07b9a16b | ||
|
ad04daa904 | ||
|
b8ac495a37 | ||
|
d9cdfced49 | ||
|
a66ec1d663 | ||
|
46570494a3 | ||
|
62b165f5de | ||
|
3d3326018a | ||
|
6d479ae441 | ||
|
e918317f6a | ||
|
992162c01e | ||
|
d47852dc31 | ||
|
18a10bf916 | ||
|
748ebdf4a3 | ||
|
693031012d | ||
|
a0005e1ff8 | ||
|
7b7371e37f | ||
|
7404105dec | ||
|
8db6531fc8 | ||
|
b9030b94ac | ||
|
0a6c409e11 | ||
|
4f438b6f0f | ||
|
8ce4f5d6c6 | ||
|
e003b63f2f | ||
|
25b4a17e40 | ||
|
9b3bfaf3ff | ||
|
7008ac92f0 | ||
|
8832287cdd | ||
|
56ab4b43de | ||
|
7c667112d5 | ||
|
c7cec20c02 | ||
|
17e3b00dd7 | ||
|
7a2ab16cf3 | ||
|
ce5ea1f1a5 | ||
|
f44cf792b2 | ||
|
57419cadc6 | ||
|
555d7e2513 | ||
|
de7a2bc1de | ||
|
595d713931 | ||
|
bc31ffa50c | ||
|
83c7a3305b | ||
|
cbf8c9ac17 | ||
|
c67eb37124 | ||
|
198d8b2e9e | ||
|
0ca2527c5f | ||
|
be1447c6ec | ||
|
cf6729cbdc | ||
|
9c5ce1e53b | ||
|
b8aab91880 | ||
|
b4f4aaa023 | ||
|
c7aad78e5f | ||
|
2e6b105d8d | ||
|
6cd01dd572 | ||
|
4c61df9701 | ||
|
6a07f5220b | ||
|
656c076195 | ||
|
3267e72b7c | ||
|
be5d7ba33e | ||
|
e046a1d6f1 | ||
|
ccdc6f489e | ||
|
6f5cd18a07 | ||
|
6322f25c36 | ||
|
f7a5a39e1b | ||
|
26639fd5d6 | ||
|
37b94086fe | ||
|
d4204b71d6 | ||
|
526f55bd3b | ||
|
61177b712d | ||
|
f14a087b16 | ||
|
a012f48a20 | ||
|
f87c07e2e1 | ||
|
19fbf04f60 | ||
|
d52974c7d1 | ||
|
5c6ac38b12 | ||
|
9b8f5282b7 | ||
|
96e5bce336 | ||
|
9b1e641b16 | ||
|
af7982f790 | ||
|
9cf274ec66 | ||
|
60e818e793 | ||
|
134c92199a | ||
|
6e792412de | ||
|
a8d99c2a08 | ||
|
dfad5edffb | ||
|
243ec1ee99 | ||
|
38e6ce092a | ||
|
56f6e54dcc | ||
|
bec3ede2f5 | ||
|
bbdf690bb3 | ||
|
976d5511fc | ||
|
e8aedb39be | ||
|
559bf79f7b | ||
|
34e8105583 | ||
|
e3e0d41ff5 | ||
|
a1d6e00d18 | ||
c391379515 | |||
|
1d814d69bc | ||
64ac89d1d3 | |||
|
2b20702e58 | ||
|
3e5a04af62 | ||
|
380e1f0081 | ||
|
c3216f72d3 | ||
|
d06cb3c6e6 | ||
|
9354bca0b3 | ||
|
30ef0ebf8a | ||
|
a3c5cc9632 | ||
e519a933f0 | |||
|
8458360a30 | ||
|
c731fae369 | ||
|
876e255be8 | ||
|
3676808046 | ||
|
3967130660 | ||
|
a4c06ed8ee | ||
|
c37b05c6d2 | ||
|
4f2bc1a1b1 | ||
|
e422557514 | ||
|
c40e049485 | ||
|
176278ece4 | ||
|
de2b68c349 | ||
|
554a182d66 | ||
|
8e444e0880 | ||
|
6fd52027df | ||
|
06ccfd9add | ||
|
f842142791 | ||
|
b2b637f016 | ||
|
422c0fa787 | ||
|
2689836c65 | ||
|
cec1dafd36 | ||
|
1d2a9dca82 | ||
|
26bc64f5e1 | ||
|
72c53b8bd4 | ||
|
2c161d3d26 | ||
|
185434f531 | ||
|
12ae53cfea | ||
|
797a4d41de | ||
|
4a5c5d6fd2 | ||
|
ae16e5b0f0 | ||
9822ba1c23 | |||
|
559ff1d8f7 | ||
|
b34da9a756 | ||
0fa7c8d819 | |||
|
83534eaf0f | ||
e705ba456a | |||
|
460b254a13 | ||
|
4f5ae21915 | ||
|
f0a7350ae5 | ||
|
c1cef99627 | ||
|
4c2c80e324 | ||
|
7d806a5fea | ||
|
4ba328ac7b | ||
f123652591 | |||
|
a0897cdefb | ||
42f05ea7d8 | |||
|
da6074da36 | ||
|
80066dc6d7 | ||
|
365720fc0f | ||
|
2355f3dd6a | ||
|
ec8f5ac661 | ||
|
82d6c10c07 | ||
4125565570 | |||
|
cf8a8eb0ab | ||
|
c39f0eb888 | ||
d64dd971d3 | |||
|
b19c857cc3 | ||
5d49d16955 | |||
|
235ebd051f | ||
ecb845546d | |||
346a0ea5fe | |||
|
eff355041f | ||
|
458febab46 | ||
|
745d1afd5a | ||
|
17df3a2b22 | ||
1451d0c230 | |||
|
2bc97c84ff | ||
|
ad73c0c1dc | ||
|
a43881166b | ||
09f82bcfdf | |||
|
d0252f4ef2 | ||
|
50caf0240f | ||
|
5521b7fd82 | ||
|
5f7f234dd9 | ||
|
1cee1ff6af | ||
|
672598a228 | ||
|
d89461b366 | ||
aee9926dfb | |||
acaaf98c56 | |||
|
bbfb2f600a | ||
|
9a3ce0fc29 | ||
|
0fec821438 | ||
|
735b0f977d | ||
|
30555f8146 | ||
|
fa207afd15 | ||
|
d14a078804 | ||
|
6713bc9245 | ||
|
86a51c8401 | ||
|
bc64f8e1bd | ||
|
7630dedc84 | ||
0e67c1d93d | |||
d47709ba87 | |||
|
594feae948 | ||
|
686548ab63 | ||
|
0c3fd7e491 | ||
|
331e76e28a | ||
|
ae0ebc55b4 | ||
|
0085f1af2c | ||
|
d183a3350f | ||
|
1a8340e0e4 | ||
|
d475c95a01 | ||
|
a1bce2bda0 | ||
|
0956021d8c | ||
|
af3720f80d | ||
|
37c347276c | ||
|
c4109cf1c6 | ||
|
0ca164a825 | ||
|
00e6f1716e | ||
|
202e0ffd17 | ||
|
b6828440f7 | ||
|
027e3571a5 | ||
|
17c853144c | ||
|
b81cd1ccc4 | ||
|
f0aeabe505 | ||
|
bdc764e492 | ||
|
46c50034f3 | ||
|
a0db53017c | ||
|
27a4e558fb | ||
|
b98c6ba9ea | ||
|
defebe6439 | ||
|
80e9a279f1 | ||
|
58b2348ce3 | ||
|
da0f976f1f | ||
|
3ea5e69e81 | ||
|
6fb591c39b | ||
|
36bed88ef3 | ||
|
d06567ce7f | ||
|
7fe717b76a | ||
|
88ad72354e | ||
|
f26e36052f | ||
|
a56965dcba | ||
|
e706ae7d25 | ||
|
93315c7a5b | ||
|
83121c4518 | ||
|
f8d7c03ac1 | ||
|
d5d38b2e46 | ||
|
3e8b496e95 | ||
|
3bf7da198d | ||
|
6d379c52f5 | ||
c9cf33cfbb | |||
24f862d93f | |||
d65e248ba8 | |||
376024e2bd | |||
5eb64d9c84 | |||
366e3e2b1d | |||
057a529170 | |||
|
65e5085275 | ||
|
58f4ed739d | ||
|
fa706de2e1 | ||
|
1c5a15d30b | ||
|
fb9be7859e | ||
|
b4bc21815b | ||
|
0d9458ad2d | ||
|
04c1cc4c98 | ||
|
581b7de410 | ||
|
5c94edd285 | ||
|
b4cadedadd | ||
|
8b1c130ba6 | ||
|
f41d04fb0e | ||
|
e28ce27b89 | ||
|
dbccb53eb4 | ||
|
ba74cc6847 | ||
|
6665799bfc | ||
|
c62fe78703 | ||
|
e1c2dcd09d | ||
|
8c360e512a | ||
|
462acb2218 | ||
|
4c9654eac9 | ||
|
d98992abe9 | ||
|
27f4d6e6e9 | ||
|
1a84e87e82 | ||
|
92ce32d8a0 | ||
|
6c7e717a07 | ||
|
e61d68a4db | ||
|
b223a0ae5b | ||
|
aac8e50559 | ||
|
6bb711bc52 | ||
|
54bfa6ceeb | ||
|
7a429e0129 | ||
|
2f5ec11017 | ||
|
524b815a47 | ||
|
6f6fb032e7 | ||
|
eba735b740 | ||
|
1ad5ecf6a2 | ||
|
91349647ed | ||
|
16c4020982 | ||
|
e4ba1db330 | ||
|
562d16a597 | ||
|
f80fed989a | ||
|
a91c8b4952 | ||
|
5187ec6e1f | ||
|
27ff20e9b1 | ||
|
ee067af354 | ||
|
e0903610b5 | ||
|
93db4eb3c7 | ||
|
3efbd85c16 | ||
|
35ea2532f2 | ||
|
4e244d9791 | ||
|
5f80630806 | ||
|
e1f429449f | ||
|
24ee93d335 | ||
|
69f9cd2219 | ||
|
730791b834 | ||
|
0c423865e4 | ||
|
7fd94ccd6e | ||
|
038739d45f | ||
|
b22d464b56 | ||
|
71a057387d | ||
|
cccc4072c7 | ||
|
c81b2e0038 | ||
|
74aea02a61 | ||
|
4320aec880 | ||
|
457cce647b | ||
|
7e3ea3fa87 | ||
|
6412e6bf7f | ||
|
e52cdd6859 | ||
|
0ebb1be7d1 | ||
|
83d3ec1dc1 | ||
|
ab51935b92 | ||
|
6b98bf0ee2 | ||
|
7ae099236c | ||
|
1e1426f6d3 | ||
|
a27d2f361e | ||
|
cf41e3dc20 | ||
|
02e6beb385 | ||
|
6d398f7160 | ||
|
c357c45072 | ||
|
1e12e4d418 | ||
|
0e1ec2b03c | ||
|
09fdf232b7 | ||
|
a6486001f2 | ||
|
f495f98468 | ||
|
99bf28c786 | ||
|
3c27283ba4 | ||
|
d73b150c80 | ||
|
e405c683ed | ||
|
0557b573a3 | ||
|
ef4c4a7d33 | ||
|
8d646a735c | ||
|
f77294b6d2 | ||
|
fea35d72ae | ||
|
02dc926ea3 | ||
|
ab2f363db0 | ||
|
c330a7fbd2 | ||
|
6504288ab4 | ||
|
8ee4e81104 | ||
|
02b4e5cf08 | ||
|
7856d7942b | ||
|
8768ab86a0 | ||
|
aaad8c1670 | ||
|
8e8415f6ea | ||
|
f7393dd251 | ||
|
eaa54795c5 | ||
|
1482c93cdc | ||
|
0b4c15d819 | ||
|
99e634d8ce | ||
|
3f858702c4 | ||
|
526c74631b | ||
|
02828f45e6 | ||
|
8507c71c27 | ||
|
53c1117621 | ||
|
9353834226 | ||
|
26788ef82f | ||
|
256f87ae9a | ||
|
3dc3799408 | ||
|
6de40139e1 | ||
|
84bccdac53 | ||
|
18dc543494 | ||
|
f8e378a7a7 | ||
|
b6fee101cc | ||
|
61574183e8 | ||
|
ff9970b2be | ||
|
6fec60fdd2 | ||
|
2380ce6108 | ||
|
d032ce81a2 | ||
|
8481fed0a9 | ||
|
7da2d5cdf0 | ||
|
3d85b30c42 | ||
|
ae4f284107 | ||
|
85c8837079 | ||
|
a5095603e9 | ||
|
5bd37b65a2 | ||
|
1cc9533a25 | ||
|
7fb059d21d | ||
|
1589ec0395 | ||
|
8ff572ec56 | ||
|
50196887e4 | ||
|
2613b2a2d7 | ||
|
325ddbb697 | ||
|
8c90db7d2c | ||
|
f93924eed4 | ||
|
b8299b7718 | ||
|
88ca56156e | ||
|
54e953eec4 | ||
|
3a90a7c28e | ||
|
a570eede61 | ||
|
2f7235654b | ||
|
aa506c5c6b | ||
|
b140140a9b | ||
|
7bdf5ebea6 | ||
|
80ab0cb4c6 | ||
|
56b70beb36 | ||
|
fa612ab5a4 | ||
|
37634e19a4 | ||
|
983f653d86 | ||
|
f6ce86310d | ||
|
3f3d2e4ef3 | ||
|
b2a82791df | ||
|
567ebf1c22 | ||
|
467e5f19f7 | ||
|
dc54ac50e2 | ||
|
546a89429f | ||
|
07d4eb31c7 | ||
|
1b5e41cd10 | ||
|
9846d3612e | ||
|
464e568156 | ||
|
5085dfbd66 | ||
|
bbaec03723 | ||
|
c03d1e4b65 | ||
|
e45cde522a | ||
|
42995cef29 | ||
|
ef1327f153 | ||
|
a16a08aa5d | ||
|
7627f5cfa2 | ||
|
949f5ce35d | ||
|
fde49c3c9c | ||
|
2964ea86d8 | ||
|
b536c07e78 | ||
|
570a01ea77 | ||
|
cd5f791b6d | ||
|
adb09334a8 | ||
|
09fa897f07 | ||
|
4aaaaf0f57 | ||
|
10962c7fe6 | ||
|
eb69ba73ec | ||
|
1a4eb93684 | ||
|
e68139ab54 | ||
|
a67fbd3a2f | ||
|
6624be556e | ||
|
c28ad23f56 | ||
|
0c534c11a7 | ||
|
74eb5f1d39 | ||
|
9218018b7c | ||
|
31e1941f0b | ||
|
928d7f59ac | ||
|
3502aa4433 | ||
|
ea2ea70c05 | ||
|
743b29c484 | ||
|
120aa7c713 | ||
|
e5f7b0e1d6 | ||
|
5c492b6e9c | ||
|
ea4348a856 | ||
|
ab8fcffa66 | ||
|
4d42861b07 | ||
|
400e8c4958 | ||
|
c4ce5da2fe | ||
|
f02c9c7b57 | ||
|
0d1edca441 | ||
|
480b4345ce | ||
|
6c7ab6c47b | ||
|
ca8c7a2719 | ||
|
d051204e4b | ||
|
fc4447d925 | ||
|
76e0db8202 | ||
|
3a738a5d00 | ||
|
7f952813be | ||
|
562d60bd5a | ||
|
e04486e6db | ||
|
acae7ab0bb | ||
|
6225fbc041 | ||
|
1378c1d531 | ||
|
77bb3160c1 | ||
|
62ad023f03 | ||
|
4b5dea4263 | ||
|
c5c0804ee7 | ||
|
9e4b72c3ae | ||
|
f73a4feeb9 | ||
|
9f0a2a1b1d | ||
|
2406c71652 | ||
|
695f26cc67 | ||
|
7dcc438fe8 | ||
|
7657ae434a | ||
|
38e7157d18 | ||
|
92d559d822 | ||
|
413bab2be6 | ||
|
4fadc1d43c | ||
|
abb4bae99a | ||
|
6f70fcaac7 | ||
|
274fd7a9a4 | ||
|
2f309dee4a | ||
|
b16af9db1f | ||
|
0f885e2e54 | ||
|
45662c78ed | ||
|
a1cf53dedf | ||
|
8dbcb9e55d | ||
|
e53d63116d | ||
|
5cbab8609f | ||
|
3590e998f5 | ||
|
14d7d2d201 | ||
|
663431dc19 | ||
|
1df0d65827 | ||
|
9fa0d8e1b8 | ||
|
5d0f4e745a | ||
|
74fb142f05 | ||
|
98a6012fe5 | ||
|
d2d814f731 | ||
|
512cac0b27 | ||
|
8718f7f637 | ||
|
513f852b60 | ||
|
1fdd539252 | ||
|
8910c7ef37 | ||
|
68aefcf6c5 | ||
|
ffc5c8c3b4 | ||
|
db0f8e4bd7 | ||
|
5c1917a8e8 | ||
|
88af200829 | ||
|
296c7a82c1 | ||
|
75d44cd73e | ||
|
98ad65413c | ||
|
4469c44861 | ||
|
2de2077055 | ||
|
091d13b163 | ||
|
a8f746d1bd | ||
|
08c5169417 | ||
|
af06a1decd | ||
|
83f84ebb7f | ||
|
f08b54033e | ||
|
fb148315d7 | ||
|
13a91ebf6a | ||
|
48a19f8ce5 | ||
|
7fd2c09059 | ||
|
3f7cc6b963 | ||
|
ccf74770a9 | ||
|
34f83d5dcc | ||
|
c024e9609c | ||
|
3b41004926 | ||
|
4eaaec53b7 | ||
|
36a5c31bae | ||
|
098d966039 | ||
|
4bc57cc63a | ||
|
deac6e4cb4 | ||
|
be1041a38f | ||
|
d4abc60e2f | ||
|
5ce54327c2 | ||
|
5df36eaa5d | ||
|
18906ce9ce | ||
|
531799b16a | ||
|
870c1f4a11 | ||
|
fae73904d2 | ||
|
344a952f99 | ||
|
63d03327f3 | ||
|
8f2d6befbc | ||
|
c67359ce94 | ||
|
e8ffdbc62c | ||
|
6f2d8b2a7b | ||
|
c8e6ec6e59 | ||
|
b9e681a683 | ||
|
5e33d50f98 | ||
|
60c3af7f97 | ||
|
317b580d8a | ||
|
f22f5d310c | ||
|
c6b9fe67c5 | ||
|
3ee055c215 | ||
|
2de51507a7 | ||
|
3d2ac096d2 | ||
|
2f83fed243 | ||
|
cbff7073bf | ||
|
270bb72c9d | ||
|
7cdda7aa11 | ||
|
45c180c40e | ||
|
43cb653ee2 | ||
|
fb16243351 | ||
|
6603923d53 | ||
|
24ff76ee0d | ||
|
3e45e317bd | ||
|
16a94ebac4 | ||
|
b79577105a | ||
|
52e6e1d933 | ||
|
d4c6d405dd | ||
|
3623a8e134 | ||
|
59ed1b87cc | ||
|
eddf81659d | ||
|
78c5ff8252 | ||
|
494b5a2701 | ||
|
c070e5bec5 | ||
|
a616532ae9 | ||
|
0a84b8f2ba | ||
|
323b67d400 | ||
|
3644c385b3 | ||
|
8508c6bebb | ||
|
0d8d174980 | ||
|
b2ae04bebb | ||
|
2b0b5c0049 | ||
|
a6f94494c7 | ||
|
5265c5d5c8 | ||
|
d058783a60 | ||
|
62bbcc0f48 | ||
|
f63a3271a6 | ||
|
78087575a8 | ||
|
66c0d8998b | ||
|
6c2552881b | ||
|
0e5c9b5b6c | ||
|
7af1925bb2 | ||
|
e210a7a26f | ||
|
e13fddda75 | ||
|
622dd0e56c | ||
|
e3ceadfe67 | ||
|
77abe318ac | ||
|
13f72cc89f | ||
|
d59d100afc | ||
|
596709946c | ||
|
e8f55aa087 | ||
|
084147eb2b | ||
|
90ea4b3eab | ||
|
ebbc5d2763 | ||
|
4a9375d906 | ||
|
903774d57d | ||
|
cbff873be0 | ||
|
597696b692 | ||
|
e6731c7a65 | ||
|
3f1840b323 | ||
|
3e9f019f7e | ||
|
c6e2a8c1b7 | ||
|
6db7bc93e1 | ||
|
5ef7ec6538 | ||
|
0397aad602 | ||
|
22b82eff3f | ||
|
3e8013c29a | ||
|
fc469781b2 | ||
|
f09cec3e5d | ||
|
8271e5ab45 | ||
|
98aa0afcbb | ||
|
84a512eefa | ||
|
b3f1800754 | ||
|
f29c0f62a4 | ||
|
3fa296423b | ||
|
1524a94db0 | ||
|
2ccc2999e6 | ||
|
0812440edc | ||
|
5dd88b798d | ||
|
f4e33b5af5 | ||
|
ba82f22b64 | ||
|
6f97c22b54 | ||
|
8d7ee7b132 | ||
|
be7d3d76cd | ||
|
0ce0403311 | ||
|
1d611ef2f7 | ||
|
bb94fba4c3 | ||
|
a3a72718f8 | ||
|
edcadcd052 | ||
|
c2729dcb93 | ||
|
c1c298b4eb | ||
|
84d9727fa4 | ||
|
76ff775810 | ||
|
28ccea77e7 | ||
|
3ebf5a1d31 | ||
|
fbddb65f37 | ||
|
4306e37e5d | ||
|
cb94c210c0 | ||
|
f684763ea9 | ||
|
d02d4a9f1a | ||
|
6d77b107cf | ||
|
3b8ea43d80 | ||
|
6c340f17b2 | ||
|
24088aa568 | ||
|
8d883e407d | ||
|
bb22ddb413 | ||
|
db6f1d7013 | ||
|
2bb2331047 | ||
|
fbd56c2512 | ||
|
eda0e3b68b | ||
|
f0b87087e7 | ||
|
0e4988e415 | ||
|
a592053447 | ||
|
535e665fc7 | ||
|
42d54b1982 | ||
|
63b10e658f | ||
|
82fce596dc | ||
|
b1a71726fc | ||
|
57335ffb54 | ||
|
04ea0ea00e | ||
|
a1258b9af2 | ||
|
2a66f0a67b | ||
|
6bb71edd15 | ||
|
3926b01901 | ||
|
07e42e793c | ||
|
9ce341cf43 | ||
|
cf6a9ab203 | ||
|
9a3ec002d6 | ||
|
67781a6f00 | ||
|
e68db44642 | ||
|
ca6e71d55f | ||
|
f2097f72f0 | ||
|
4c12e36c67 | ||
|
c947c7109f | ||
|
a7d5828caa | ||
|
b1b2d685db | ||
|
d0a5ad4cf0 | ||
|
bba1df38dc | ||
|
f564c6c8e0 | ||
|
8d5918cfc3 | ||
|
5e99c0c71d | ||
|
33f279f90c | ||
|
dec7cd50ea | ||
|
1a7cd55b46 | ||
|
6d7829b03c | ||
|
29bf585826 | ||
|
f92a62f70e | ||
|
e6c8e49fc1 | ||
|
14dce123c4 | ||
|
0fc3b0d3df | ||
|
05bd2807fd | ||
|
d2949b1a80 | ||
|
f101809165 | ||
|
2e4d520f65 | ||
|
114b2f1aae | ||
|
6db7f6e656 | ||
|
fbcc052513 | ||
|
7fdddd5edf | ||
|
07805eb6c4 | ||
|
878a958ee3 | ||
|
fb582a1752 | ||
|
d2aa99fdad | ||
|
47452c4f25 | ||
|
1a674a91be | ||
|
03a72e37a3 | ||
|
b52e3062ca | ||
|
8935639265 | ||
|
cdef1b84c5 | ||
|
f33f4c304f | ||
|
db12c374d3 | ||
|
eb9b3c46ed | ||
|
2da03f3025 | ||
|
72bf320605 | ||
|
befb6f59d4 | ||
|
4f934aed10 | ||
|
e1776dfb46 |
704 changed files with 121066 additions and 4202 deletions
12
.docker/Dockerfile
Executable file
12
.docker/Dockerfile
Executable file
|
@ -0,0 +1,12 @@
|
|||
FROM php:8.0-apache
|
||||
|
||||
RUN a2enmod rewrite
|
||||
|
||||
RUN set -xe \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y unzip libpng-dev libzip-dev libonig-dev libjpeg-dev libmcrypt-dev wget \
|
||||
&& docker-php-ext-install mysqli zip
|
||||
|
||||
RUN curl --insecure https://getcomposer.org/composer.phar -o /usr/bin/composer && chmod +x /usr/bin/composer
|
||||
|
||||
WORKDIR /bitrix-module
|
25
.docker/php.ini
Executable file
25
.docker/php.ini
Executable file
|
@ -0,0 +1,25 @@
|
|||
[php]
|
||||
short_open_tag = On
|
||||
display_errors = On
|
||||
error_log = "/var/log/php/error.log"
|
||||
error_reporting = E_ALL
|
||||
log_errors = On
|
||||
display_startup_errors = On
|
||||
cgi.fix_pathinfo = 0
|
||||
date.timezone = "Europe/Moscow"
|
||||
default_charset = utf-8
|
||||
max_input_vars = 10000
|
||||
post_max_size = 1024M
|
||||
memory_limit = 256M
|
||||
upload_max_filesize = 1024M
|
||||
pcre.jit = 0
|
||||
pcre.recursion_limit = 10485760
|
||||
|
||||
[opcache]
|
||||
opcache.revalidate_freq = 0
|
||||
opcache.validate_timestamps = 1
|
||||
opcache.max_accelerated_files = 100000
|
||||
opcache.memory_consumption = 512
|
||||
opcache.interned_strings_buffer = 64
|
||||
opcache.fast_shutdown = 1
|
||||
opcache.error_log = "/var/log/php/opcache.log"
|
6
.env.dist
Executable file
6
.env.dist
Executable file
|
@ -0,0 +1,6 @@
|
|||
DB_BITRIX_HOST=""
|
||||
DB_BITRIX_LOGIN=""
|
||||
DB_BITRIX_PASS=""
|
||||
DB_BITRIX_NAME=""
|
||||
BITRIX_PATH=/var/www/html
|
||||
BITRIX_EDITION=small_business_encode
|
116
.github/workflows/ci.yml
vendored
Normal file
116
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
tags-ignore:
|
||||
- '*.*'
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
DB_BITRIX_HOST: 0.0.0.0
|
||||
DB_BITRIX_LOGIN: root
|
||||
DB_BITRIX_PASS: root
|
||||
DB_BITRIX_NAME: bitrix
|
||||
BITRIX_PATH: ${{ github.workspace }}/bitrix
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['8.1']
|
||||
bitrix-edition: ['small_business_encode', 'business_encode']
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: ${{ env.DB_BITRIX_PASS }}
|
||||
MYSQL_DATABASE: bitrix
|
||||
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 }}
|
||||
ini-values: short_open_tag=On, mbstring.func_overload=2, mbstring.internal_encoding="UTF-8"
|
||||
coverage: xdebug
|
||||
- name: Install Bitrix
|
||||
env:
|
||||
BITRIX_EDITION: ${{ matrix.bitrix-edition }}
|
||||
run: make install_bitrix
|
||||
- name: Enable debug mode for tests
|
||||
run: php bin/enable_debugging "${{ env.BITRIX_PATH }}"
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-
|
||||
- name: Install dependencies
|
||||
if: steps.composer-cache.outputs.cache-hit != 'true'
|
||||
run: make deps
|
||||
- name: Run tests
|
||||
run: make test
|
||||
- name: Coverage
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
||||
deploy:
|
||||
needs: ['test']
|
||||
if: success() && github.event_name == 'push' && github.repository_owner == 'retailcrm' && github.ref == 'refs/heads/master'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup PHP 8.1
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
ini-values: short_open_tag=On, mbstring.func_overload=2, mbstring.internal_encoding="UTF-8"
|
||||
- name: Build release
|
||||
run: |
|
||||
git fetch origin --unshallow --tags
|
||||
export CURRENT_VERSION=`php bin/bitrix-version`
|
||||
export ARCHIVE_PATH="${{ github.workspace }}/release/$CURRENT_VERSION.tar.gz"
|
||||
export LAST_TAG=`git describe --tags $(git rev-list --tags --max-count=1) || true`
|
||||
export RELEASE_TAG=v$CURRENT_VERSION
|
||||
echo CURRENT_VERSION=$CURRENT_VERSION >> $GITHUB_ENV
|
||||
echo LAST_TAG=$LAST_TAG >> $GITHUB_ENV
|
||||
echo ARCHIVE_NAME="$CURRENT_VERSION.tar.gz" >> $GITHUB_ENV
|
||||
echo ARCHIVE_PATH=$ARCHIVE_PATH >> $GITHUB_ENV
|
||||
echo RELEASE_TAG=$RELEASE_TAG >> $GITHUB_ENV
|
||||
echo Current version is $CURRENT_VERSION, release tag will be v$CURRENT_VERSION
|
||||
echo Last tag is $LAST_TAG, archive will be saved to $ARCHIVE_PATH
|
||||
make build_release
|
||||
- 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_path: ${{ github.workspace }}/intaro.retailcrm/description.ru
|
||||
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/gzip
|
||||
- name: Cleanup
|
||||
if: env.LAST_TAG != env.RELEASE_TAG
|
||||
run: make cleanup
|
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
.DS_Store
|
||||
*~
|
||||
/nbproject/*
|
||||
/.idea/*
|
||||
/*tags*
|
||||
.idea
|
||||
.idea/*
|
||||
/.idea
|
||||
/.idea/*
|
||||
|
||||
/intaro.retailcrm/log/*
|
||||
/tmp/
|
||||
/vendor/
|
||||
.env
|
||||
.phpunit.result.cache
|
||||
/release/
|
||||
coverage.xml
|
749
CHANGELOG.md
Normal file
749
CHANGELOG.md
Normal file
|
@ -0,0 +1,749 @@
|
|||
|
||||
## 2025-03-26 v6.6.11
|
||||
- Исправлена передача габаритов при выгрузке заказов по агенту
|
||||
|
||||
## 2025-03-25 v6.6.10
|
||||
- Исправлено некорректное изменение статуса оплаты отмененных заказов
|
||||
|
||||
## 2025-03-04 v6.6.9
|
||||
- Исправлено обновление модуля
|
||||
|
||||
## 2025-03-03 v6.6.8
|
||||
- Исправлена ошибка экспорта дополнительных свойств товаров
|
||||
|
||||
## 2025-02-04 v6.6.7
|
||||
- Исправлена ошибка установки модуля на PHP 8.0
|
||||
|
||||
## 2025-01-29 v6.6.6
|
||||
- Поддержка нулевой закупочной стоимости при генерации каталога
|
||||
|
||||
## 2025-01-28 v6.6.5
|
||||
- Исправлена ошибка редактирования интеграционных доставок при активации опции передачи статусов интеграционных оплат
|
||||
|
||||
## 2025-01-27 v6.6.4
|
||||
- Исправлено некорректное удаление признака применения промокода при изменении состава заказа в CRM
|
||||
|
||||
## 2025-01-14 v6.6.3
|
||||
- Исправлены ошибки при обновлении модуля
|
||||
|
||||
## 2025-01-14 v6.6.2
|
||||
- Исправлена выгрузка архива заказов при установке модуля
|
||||
|
||||
## 2024-12-17 v6.6.1
|
||||
- Исправлены API методы по взаимодействию с пользовательскими полями и справочниками
|
||||
|
||||
## 2024-12-09 v6.6.0
|
||||
- Добавлено динамическое изменение свойств товаров при настройке экспорта
|
||||
|
||||
## 2024-12-08 v6.5.39
|
||||
- Исправлена поломка заказов с промокодом Maxma при включенной передаче корзины в CRM
|
||||
|
||||
## 2024-10-31 v6.5.38
|
||||
- Исправлена выгрузка заказов через агент
|
||||
|
||||
## 2024-10-30 v6.5.37
|
||||
- Исправлена подписка модуля на событие сохранения заказа
|
||||
|
||||
## 2024-10-24 v6.5.36
|
||||
- Добавлена передача профилей доставки Официального модуля Почты России
|
||||
|
||||
## 2024-10-22 v6.5.35
|
||||
- Исправлена подписка модуля на событие сохранения заказа
|
||||
|
||||
## 2024-10-21 v6.5.34
|
||||
- Исправлена ошибка агента выгрузки изменений при наличии у заказа клиента без магазина
|
||||
|
||||
## 2024-10-14 v6.5.33
|
||||
- Добавлена передача дополнительных параметров в GET запросах
|
||||
|
||||
## 2024-10-03 v6.5.32
|
||||
- Исправлена подписка на событие создания заказа при обновлении
|
||||
|
||||
## 2024-09-23 v6.5.31
|
||||
- Добавлено логирование ответа от API при неудачном создании заказа
|
||||
|
||||
## 2024-09-23 v6.5.30
|
||||
- Добавлена передача контрагентов с типом ИП
|
||||
|
||||
## 2024-09-19 v6.5.29
|
||||
- Исправлена подписка модуля на событие сохранения заказа
|
||||
|
||||
## 2024-09-11 v6.5.28
|
||||
- Исправлен возврат на предыдущий статус в заказе Bitrix
|
||||
|
||||
## 2024-09-02 v.6.5.27
|
||||
- Исправлена передача изменений по клиентам, отсутствующим в Bitrix
|
||||
|
||||
## 2024-08-26 v.6.5.26
|
||||
- Исправлено удаление модуля
|
||||
|
||||
## 2024-08-12 v.6.5.25
|
||||
- Улучшена генерация каталога с маркированными товарами
|
||||
|
||||
## 2024-08-06 v.6.5.24
|
||||
- Добавлены переводы текста в программе лояльности
|
||||
- Установка функционала программы лоялности перенесена в настройки модуля
|
||||
|
||||
## 2024-08-06 v.6.5.23
|
||||
- Исправлена ошибка с присвоением externalId при добавлении товара в заказ как разные товарные позиции из CRM
|
||||
|
||||
## 2024-07-18 v.6.5.22
|
||||
- Добавлена передача скидок на торговые позиции в брошенных корзинах
|
||||
|
||||
## 2024-07-15 v.6.5.21
|
||||
- Добавлена передача поля link при выгрузке брошенных корзин
|
||||
|
||||
## 2024-06-20 v.6.5.20
|
||||
- Рефакторинг настроек модуля
|
||||
|
||||
## 2024-06-14 v.6.5.19
|
||||
- Исправление работы программы лояльности при использовании подтверждения списание бонусов по SMS
|
||||
|
||||
## 2024-06-05 v.6.5.18
|
||||
- Добавлена возможность исправления даты регистрации клиентов в CRM
|
||||
|
||||
## 2024-06-04 v.6.5.17
|
||||
- Добавлена передача признака маркировки товара в ICML каталоге
|
||||
|
||||
## 2024-04-27 v.6.5.16
|
||||
- Обновлены аннотации в коде модуля
|
||||
|
||||
## 2024-04-23 v.6.5.15
|
||||
- Добавлена передача услуг через ICML каталог
|
||||
|
||||
## 2024-04-18 v.6.5.14
|
||||
- Исправление работы кнопки "Выгрузка служб доставок"
|
||||
|
||||
## 2024-04-03 v.6.5.13
|
||||
- Исправление присваивания номера заказа к платежу при синхронизации с CRM
|
||||
|
||||
## 2024-03-28 v.6.5.12
|
||||
- Исправлена подстановка домена при генерации каталога
|
||||
|
||||
## 2024-03-28 v.6.5.11
|
||||
- Исправлена ошибка дублирования скидок
|
||||
|
||||
## 2024-03-18 v.6.5.10
|
||||
- Добавлена валидация прав API ключа
|
||||
|
||||
## 2024-03-01 v.6.5.9
|
||||
- Исправлена проверка ФИО при отправке заказа в систему
|
||||
|
||||
## 2024-02-05 v.6.5.8
|
||||
- Удалена возможность выбора свойств с множественным выбором в настройках экспорта каталога
|
||||
|
||||
## 2024-01-22 v.6.5.7
|
||||
- Доработана передача данных интеграционных оплат в систему
|
||||
|
||||
## 2024-01-12 v.6.5.6
|
||||
- Добавлена передача дополнительных свойств товаров через конфигурируемый файл
|
||||
|
||||
## 2024-01-09 v.6.5.5
|
||||
- Исправлен вывод справочников при установке модуля
|
||||
|
||||
## 2023-12-29 v.6.5.4
|
||||
- Исправлена передача адреса доставки
|
||||
|
||||
## 2023-12-27 v.6.5.3
|
||||
- Исправлена ошибка с двойной сериализацией при получении списка пользователей
|
||||
|
||||
## 2023-12-21 v.6.5.2
|
||||
- Добавлена функциональность, позволяющая выгружать из CRM в Bitrix заказы с определенным способом оформления
|
||||
|
||||
## 2023-12-19 v.6.5.1
|
||||
- Исправлено отображение настройки пользовательских полей
|
||||
|
||||
## 2023-12-18 v.6.5.0
|
||||
- Добавлена поддержка функционала пользовательских полей
|
||||
|
||||
## 2023-12-13 v.6.4.13
|
||||
- Исправлена ошибка с получением данных программы лояльности администратора при изменении заказа в админке
|
||||
|
||||
## 2023-12-12 v.6.4.12
|
||||
- Исправлена критическая ошибка при переходе в настройки модуля
|
||||
|
||||
## 2023-12-08 v.6.4.11
|
||||
- Исправлена ошибка при передаче подписки на рекламно-информационные рассылки
|
||||
|
||||
## 2023-10-25 v.6.4.10
|
||||
- Добавлена передача трек-номера в заказе из CRM в Bitrix
|
||||
|
||||
## 2023-10-24 v.6.4.9
|
||||
- Исправлена ошибка при деактивации модуля
|
||||
|
||||
## 2023-10-17 v.6.4.8
|
||||
- Добавлена передача адреса пункта самовывоза в заказе из Bitrix в CRM
|
||||
|
||||
## 2023-10-10 v.6.4.7
|
||||
- Изменена логика передачи адреса доставки в заказе из Bitrix в CRM
|
||||
|
||||
## 2023-09-07 v.6.4.6
|
||||
- Исправлена передача ФИО покупателя в заказе
|
||||
|
||||
## 2023-09-01 v.6.4.5
|
||||
- Удалена поддержка API V4
|
||||
|
||||
## 2023-09-01 v.6.4.4
|
||||
- Исправлены ошибки при работе с программой лояльности
|
||||
|
||||
## 2023-08-29 v.6.4.3
|
||||
- Добавлена валидация валют при настройке модуля
|
||||
|
||||
## 2023-08-23 v.6.4.2
|
||||
- Исправлена ошибка создания заказов для корпоративных клиентов при использовании функционала брошенных корзин
|
||||
|
||||
## 2023-08-22 v.6.4.1
|
||||
- Исправлена передача даты регистрации клиента
|
||||
|
||||
## 2023-08-22 v.6.4.0
|
||||
- Добавлена функция подписки на рекламно-информационные рассылки
|
||||
|
||||
## 2023-07-25 v.6.3.20
|
||||
- Исправлена ошибка некорректного вывода информации о программе лояльности в личном кабинете клиента
|
||||
|
||||
## 2023-07-21 v.6.3.19
|
||||
- Добавлена возможность кастомизации генерации каталога
|
||||
|
||||
## 2023-07-20 v.6.3.18
|
||||
- Исправлена передача брошенных корзин
|
||||
|
||||
## 2023-07-04 v.6.3.17
|
||||
- Добавлен функционал передачи примененного купона в заказе Bitrix в пользовательское поле заказа CRM
|
||||
|
||||
## 2023-06-30 v.6.3.16
|
||||
- Добавлена передача НДС товаров
|
||||
|
||||
## 2023-06-22 v.6.3.15
|
||||
- Исправлено зависание агента выгрузки заказов
|
||||
|
||||
## 2023-06-12 v.6.3.14
|
||||
- Исправлена ошибка при изменении торгового предложения в товаре
|
||||
|
||||
## 2023-06-09 v.6.3.13
|
||||
- Правка генерации при работе со значением Без НДС
|
||||
|
||||
## 2023-06-08 v.6.3.12
|
||||
- Исправление критических ошибок при обновлении модуля и php
|
||||
|
||||
## 2023-06-07 v.6.3.11
|
||||
- Исправление критической ошибки при изменении настроек модуля
|
||||
|
||||
## 2023-06-02 v.6.3.10
|
||||
- Добавлено ограничение по магазинам для типов доставок и оплат
|
||||
|
||||
## 2023-06-01 v.6.3.9
|
||||
- Исправление ошибок генерации ICML каталога при установке модуля
|
||||
|
||||
## 2023-06-01 v.6.3.8
|
||||
- Исправлена ошибка с получением настроек при генерации файла каталога
|
||||
|
||||
## 2023-06-01 v.6.3.7
|
||||
- Исправлено получение основного сайта для записи логов модуля
|
||||
|
||||
## 2023-05-19 v.6.3.6
|
||||
- В настройки добавлена опция деактивации модуля
|
||||
|
||||
## 2023-05-18 v.6.3.5
|
||||
- Добавлен функционал обновления номера телефона, адреса и других полей заказа, связанных с курьерской доставкой
|
||||
|
||||
## 2023-04-26 v.6.3.4
|
||||
- Оптимизирован алгоритм получения истории заказов и клиентов
|
||||
|
||||
## 2023-04-10 v.6.3.3
|
||||
- Исправлено некорректное отображение настроек модуля
|
||||
- Добавлена поддержка PHP 8.1-8.2
|
||||
|
||||
## 2023-04-10 v.6.3.2
|
||||
- Добавлена возможность экспорта неактивных товаров и торговых предложений
|
||||
|
||||
## 2023-04-10 v.6.3.1
|
||||
- Добавлена валидация свойств товаров и торговых предложений в настройках экспорта
|
||||
|
||||
## 2023-04-06 v.6.3.0
|
||||
- Добавлен функционал передачи данных о содержимом корзины в систему
|
||||
|
||||
## 2023-03-30 v.6.2.4
|
||||
- Добавлен функционал слияния дублей пользователей по истории
|
||||
|
||||
## 2023-03-29 v.6.2.3
|
||||
- Исправление ошибок при установке модуля и выгрузке истории заказов для работы с несколькими сайтами
|
||||
|
||||
## 2023-03-27 v.6.2.2
|
||||
- Добавление значения по умолчанию у элемента выбора контрагента
|
||||
- Добавлена фильтрация полей по активности
|
||||
|
||||
## 2023-03-17 v.6.2.1
|
||||
- Добавлена передача менеджера при изменении заказа по истории
|
||||
|
||||
## 2023-03-10 v.6.2.0
|
||||
- Добавлена поддержка PHP 8.0
|
||||
|
||||
## 2023-02-16 v.6.1.16
|
||||
- Добавление передачи магазина для корпоративных клиентов
|
||||
|
||||
## 2023-01-10 v.6.1.15
|
||||
- Добавлен фильтр активности менеджеров
|
||||
|
||||
## 2023-01-24 v.6.1.14
|
||||
- Исправление обновления и отправки заказа в црм систему
|
||||
|
||||
## 2023-01-10 v.6.1.13
|
||||
- Изменение метода обновления полей программы лояльности в административной панели
|
||||
|
||||
## 2022-12-28 v.6.1.12
|
||||
- Исправление генерации пароля у корпоративного клиента
|
||||
- Добавлена проверка на существование пользователя в заказе
|
||||
|
||||
## 2022-12-13 v.6.1.11
|
||||
- Добавление фильтрации не активных справочников и статусов
|
||||
|
||||
## 2022-12-02 v.6.1.10
|
||||
- Удаление управления конфигурацией cron
|
||||
|
||||
## 2022-12-01 v.6.1.9
|
||||
- Исправление ошибки создания клиента без email по истории
|
||||
- Добавление передачи комментария к статусу заказа в CRM
|
||||
|
||||
## 2022-09-30 v.6.1.8
|
||||
- Исправление ошибки в работе модуля при отмене заказа в Bitrix
|
||||
|
||||
## 2022-09-09 v.6.1.7
|
||||
- Корректировка получения истории удалённых товаров
|
||||
|
||||
## 2022-09-07 v.6.1.6
|
||||
- Корректировка редактирования данных пользователя Bitrix при выгрузке истории изменений
|
||||
|
||||
## 2022-08-22 v.6.1.5
|
||||
- Корректировка получения НДС товаров в каталоге
|
||||
|
||||
## 2022-07-21 v.6.1.4
|
||||
- Исправление ошибки при записи товаров в HL блок лояльности
|
||||
|
||||
## 2022-07-18 v.6.1.3
|
||||
- Исправление работы модуля при попытке регистрации в программе лояльности уже существующего в ней клиента
|
||||
- Исправление тестов
|
||||
|
||||
## 2022-07-01 v.6.1.2
|
||||
- Исправление передачи корпоративных клиентов
|
||||
|
||||
## 2022-06-28 v.6.1.1
|
||||
- Исправлена ошибка при удалении модуля
|
||||
|
||||
## 2022-06-28 v.6.1.0
|
||||
- Исправлены ошибки дублирования скидок при обмене данными
|
||||
- Скорректирована работа с общей скидкой по заказу, она более не переносится в скидку по товару в CRM
|
||||
- Скорректирована передача бонусов и персональных скидок
|
||||
- Исправлены типы полей скидок в HL-блоке программы лояльности
|
||||
|
||||
## 2022-06-17 v.6.0.6
|
||||
- Замена устаревшего jQuery метода
|
||||
|
||||
## 2022-06-14 v.6.0.5
|
||||
- Исправление автозагрузки классов для мультисайта
|
||||
- Исправление страницы экспорта каталога
|
||||
|
||||
## 2022-05-18 v.6.0.4
|
||||
* Исправление передачи местоположения в адресе доставки по истории
|
||||
|
||||
## 2022-05-13 v.6.0.3
|
||||
* Исправление автозагрузки классов
|
||||
|
||||
## 2022-04-18 v.6.0.2
|
||||
* Исправление конвертирования строк из utf-8
|
||||
* Исправление редактирования свойств заказа в 1С Битрикс
|
||||
* Добавлена передача параметра site для метода работы с корпоративными клиентами
|
||||
* Добавлена передача параметра site для метода получения списка заказов
|
||||
## 2022-04-08 v.6.0.1
|
||||
* Исправлены ошибки подключения кастомных классов
|
||||
|
||||
## 2021-11-12 v.6.0.0
|
||||
* Добавлена поддержка программы лояльности
|
||||
|
||||
## 2022-02-03 v.5.8.5
|
||||
* Исправление ошибка восстановления отсутствующей отгрузки во время выгрузки истории из системы
|
||||
* Исправлена ошибка обработки магазинов с кодами, содержащими ".", в настройках модуля
|
||||
* Исправлен баг выгрузки заказов, связанный с неверным указанием namespace для LocationTable
|
||||
* При обмене данными итоговая стоимость доставки теперь указывается принудительно
|
||||
* Исправлена ошибка генерации icml для проиндексированных каталогов с простыми товарами
|
||||
* Исправлена ошибка выгрузки клиентов, при которой одни и те же клиенты могли попасть в лист выгрузки повторно
|
||||
* Исправления в документации
|
||||
|
||||
## 2021-10-15 v.5.8.4
|
||||
* Исправление некорректной генерации каталога при повторных запусках генерации
|
||||
|
||||
## 2021-10-09 v.5.8.3
|
||||
* Исправлено определение пути к файлу ICML-каталога
|
||||
|
||||
## 2021-09-08 v.5.8.2
|
||||
* Оптимизирована работа с памятью в генераторе каталога
|
||||
* Исправлены ошибки в генераторе каталога
|
||||
|
||||
## 2021-09-08 v.5.8.1
|
||||
* Оптимизирована работа генератора icml каталога
|
||||
* В генератор каталога добавлена возможность указывать свойства выгрузки одновременно для простых товаров и товаров с торговыми предложениями
|
||||
* Исправлена ошибка выгрузки заказов из неподключенного к CRM магазина при использовании нескольких сайтов на одной лицензии
|
||||
* Изменена логика обмена оплатами: для интеграционных оплат дата оплаты больше не передается из Битрикса
|
||||
|
||||
## 2021-08-19 v.5.8.0
|
||||
* Добавлена синхронизация ответственного менеджера в заказе
|
||||
* Исправлена ошибка выгрузки заказов с корпоративными клиентами, уже присутствующими в системе
|
||||
* Исправлена ошибка выгрузки остатков при наличии более 100 складов в Битрикс
|
||||
|
||||
## 2021-06-28 v.5.7.1
|
||||
* Исправлена ошибка в методе получения типов интеграционных оплат RetailcrmConfigProvider::getIntegrationPaymentTypes().
|
||||
|
||||
## 2021-05-31 v.5.7.0
|
||||
* Переработан генератор ICML каталога:
|
||||
- генератор использует потоковую запись в файл через `XMLWriter`;
|
||||
- по умолчанию опция выгрузки каталога в момент установки модуля отключена;
|
||||
- код генератора каталога теперь использует автолоадер Битрикса.
|
||||
* Скидка на позицию больше не учитывается в заказе при установке произвольной цены для позиции.
|
||||
|
||||
## 2021-01-14 v.5.6.2
|
||||
* Исправлено формирование картинок в ICML при включеном CDN
|
||||
* Убрана некорректная запись внешнего идентификатора платежа для новых платежей по истории
|
||||
* Добавлена проверка на длину email при отправке в систему
|
||||
|
||||
## 2020-12-15 v.5.6.1
|
||||
* Обновлено наименование бренда
|
||||
|
||||
## 2020-11-24 v.5.6.0
|
||||
* Добавлена возможность активации онлайн-консультанта
|
||||
* Обновлен список стран
|
||||
* Улучшена синхронизация ФИО в истории
|
||||
* Добавлен перевод на английский язык
|
||||
* Заменены некорректные символы в списке стран
|
||||
|
||||
## 2020-10-14 v.5.5.3
|
||||
* Исправлено затирание полей при создании заказа по агенту
|
||||
|
||||
## 2020-10-01 v.5.5.2
|
||||
* Исправлена ошибка, препятствовавшая обновлению модуля
|
||||
* Исправлена неверная кодировка в настройках модуля
|
||||
|
||||
## 2020-09-28 v.5.5.1
|
||||
* Исправлена ошибка переноса полей в RetailCRM для заказов с интеграционными доставками
|
||||
|
||||
## 2020-09-08 v.5.5.0
|
||||
* Добавлена возможность ручной выгрузки заказов в CRM
|
||||
|
||||
## 2020-09-02 v.5.4.6
|
||||
* Исправлена ошибка установки модуля при отсутствии заказов в Битрикс
|
||||
|
||||
## 2020-09-02 v.5.4.5
|
||||
* Исправлена ошибка установки статуса оплаты в заказе
|
||||
|
||||
## 2020-08-26 v.5.4.4
|
||||
* Исправлена ошибка при установке модуля
|
||||
|
||||
## 2020-08-25 v.5.4.3
|
||||
* Исправлена ошибка с некорректным ID товара при редактировании заказа
|
||||
* Исправлены опечатки в API-клиенте RetailCRM
|
||||
* Добавлена фильтрация изменений истории по текущему API-ключу
|
||||
|
||||
## 2020-07-24 v.5.4.2
|
||||
* Исправлена кодировка
|
||||
|
||||
## 2020-07-24 v.5.4.1
|
||||
* Оптимизирован генератор каталога
|
||||
* Передача статуса оплаты и статуса отгрузки заказа в Битрикс
|
||||
* Предупреждение в случае обнаружения несовместимых настроек
|
||||
* Запрещенные для редактирования поля в заказах с интеграционной доставкой более не передаются при редактировании заказа из Битрикс
|
||||
|
||||
## 2020-07-14 v.5.4.0
|
||||
* Добавлена поддержка функционала смены клиента
|
||||
|
||||
## 2020-05-04 v.5.3.2
|
||||
* Исправлена кодировка в настройках модуля
|
||||
|
||||
## 2020-04-27 v.5.3.1
|
||||
* Добавлена локализация свойств при генерации каталога
|
||||
|
||||
## 2020-04-23 v.5.3.0
|
||||
* Добавлена поддержка корпоративных клиентов
|
||||
|
||||
## 2020-01-09 v.5.2.5
|
||||
* Добавлена передача "externalIds" у позиций товаров в заказе
|
||||
* Добавлено разделение поля строение/корпус на два отдельных
|
||||
|
||||
## 2019-12-20 v.5.2.4
|
||||
* Добавлена обработка изменения номера заказа по истории
|
||||
|
||||
## 2019-11-1 v.2.5.3
|
||||
* Исправление при обработке полученных изменений о контрагенте
|
||||
* При обработки истории по клиентам добавлены кастомные поля
|
||||
* Исправлены мелкие ошибки и недочеты
|
||||
|
||||
## 2019-09-17 v.2.5.2
|
||||
* Поддержка функции добавления одинакового товара в заказ как разные товарные позиции из CRM
|
||||
|
||||
## 2019-08-28 v.2.5.1
|
||||
* Исправление генерации единиц измерения
|
||||
|
||||
## 2019-07-26 v.2.5.0
|
||||
* Исправление создание дублей заказов
|
||||
|
||||
## 2019-07-18 v.2.4.9
|
||||
* Добавлен поиск города по почтовому индексу при выгрузке истории изменений
|
||||
|
||||
## 2019-07-01 v.2.4.8
|
||||
* Исправлена отправка пустого заказа при удалении заказа из СMS
|
||||
* Изменена логика генерации внешнего идентификатора оплат для сохранения его уникальности в пределах системы
|
||||
|
||||
## 2019-03-28 v.2.4.7
|
||||
* Добавлено удаление в системе типа цены у товара для неактивного типа цены на сайте
|
||||
|
||||
## 2019-03-28 v.2.4.6
|
||||
* Исправление проверки информации о контрагенте при обработке полученных изменений
|
||||
|
||||
## 2019-03-28 v.2.4.5
|
||||
* Обновлен конфигурационный файл для валидатора
|
||||
|
||||
## 2019-01-22 v.2.4.4
|
||||
* Добавлена обработка клиентов с внешним кодом в виде хэша при выгрузке истории изменений
|
||||
|
||||
## 2019-01-15 v.2.4.3
|
||||
* Добавлена выгрузка НДС в ICML каталоге
|
||||
* Улучшена выгрузка истории изменений заказа
|
||||
* Улучшена настройка выгрузки типов цен
|
||||
|
||||
## 2018-12-26 v.2.4.2
|
||||
* Добавлена конвертация закупочной цены при выгрузке заказа
|
||||
* Исправлен файл переводов для выгрузки каталога
|
||||
* В настройку экспорта каталога добавлена настройка максимального количества торговых предложений у товара
|
||||
* Исправлен вызов обработчика сохранения оплаты при создании заказа
|
||||
|
||||
## 2018-11-02 v.2.4.1
|
||||
* Исправлены ошибки в файле options.php
|
||||
|
||||
## 2018-11-02 v.2.4.0
|
||||
* Изменена привязка на событие сохранения заказа. Используется привязка к событию "OnSaleOrderSaved"
|
||||
* Исправлено удаление событий модуля при удалении модуля интеграции из CMS
|
||||
* Добавлено подключение файла Logger.php при удалении модуля
|
||||
* Изменен механизм определения протокола, с которым работает сайт. Используется метод isHttps() 1С-Bitrix
|
||||
* Исправлена передача веса товара при отправке габбаритов заказа
|
||||
|
||||
## 2018-10-29 v.2.3.14
|
||||
* Добавлено подключение файла RCrmActions.php при удалении модуля
|
||||
|
||||
## 2018-10-25 v.2.3.13
|
||||
* Добавлен функционал для активации модуля в маркетплейсе RetailCRM
|
||||
* Исправлен баг при генерации каталога с подстановкой схемы
|
||||
|
||||
## 2018-10-17 v.2.3.12
|
||||
* Исрпавлена некорректная выгрузка остатков по складам
|
||||
* Исправлена отправка габаритов товаров в заказах
|
||||
|
||||
## 2018-10-04 v.2.3.11
|
||||
* Добавлен учет настроек часового пояса при создании заказа
|
||||
* Устранено удаление событий изменения оплат при переводе выгрузки на агент
|
||||
* Добавлена возможность указать свойство в настройках экспорта, из которого будет подставляться картинка, если отсутствует в "Подробно" и "Анонс"
|
||||
* Добавлена подстановка домена в ссылках каталога в зависимости от пренадлежности инфоблока к сайту
|
||||
|
||||
## 2018-09-26 v.2.3.10
|
||||
* Исправлена некорректная генерация скрипта UA
|
||||
* Исправлена выгрузка остатков, если для товара указано более 50 складов
|
||||
* Добавлен перехват исключений при сохранении заказа в Битрикс
|
||||
|
||||
## 2018-08-08 v.2.3.9
|
||||
* Устранено резервирование товара в отмененном заказе
|
||||
* Исправлен некорректный расчет скидки на товар
|
||||
|
||||
## 2018-07-16 v.2.3.8
|
||||
* Добавлен рассчет стоимости товара с учетом наценки
|
||||
* Добавлена выгрузка картинок товара, если отсутствует картинка торгового предложения
|
||||
* Заменены устаревшие методы в API клиенте
|
||||
|
||||
## 2018-06-13 v.2.3.7
|
||||
* Добавлена выгрузка штрихкодов в ICML
|
||||
* Добавлена выгрузка картинок торговых предложений в ICML
|
||||
* Улучшена передача типа доставки в заказе
|
||||
* Добавлена проверка некоторых настроек при передаче заказа
|
||||
|
||||
## 2018-05-23 v.2.3.6
|
||||
* Улучшена выгрузка свойств товаров типа "справочник"
|
||||
* Добавлена настройка выгрузки габаритов и веса в заказе
|
||||
* Добавлена совместимость натройки экспорта для Google Chrome
|
||||
* Исправлена ошибка при выгрузке истории с пустым городом
|
||||
* Добавлены проверки на существование модуля Highloadblock
|
||||
* Исправлен баг с отправкой пустого заказа при удалении в 1С-Битрикс
|
||||
|
||||
## 2018-03-22 v.2.3.5
|
||||
* В настройку экспорта добавлена настройка свойств типа "справочник"(highloadblock)
|
||||
* Добавлена проверка необходимости резервации товаров при выгрузке заказов из RetailCRM
|
||||
* Исправлен вызов рекурсивного метода в RCrmActions
|
||||
* Добавлены недостающие поля retailcrm.json
|
||||
|
||||
## 2018-02-27 v.2.3.4
|
||||
* Добавлена передача веса и габаритов в заказе
|
||||
* Добавлена проверка существования fuser у корзины товаров перед сохранением
|
||||
* Добавлено снятие резерва с товаров при отмене заказа в CRM
|
||||
* Исправлена выборка данных для UA, когда id заказа не совпадает с номером
|
||||
* Исправлены мелкие баги
|
||||
|
||||
## 2018-01-23 v.2.3.3
|
||||
* Исправлен баг с передачей номера заказа
|
||||
* Исправлены мелкие ошибки и недочеты
|
||||
|
||||
## 2017-12-27 v.2.3.2
|
||||
* Исправлен баг с рассчетом суммы заказа
|
||||
* Добавлен перехват исключения при редактировании отгруженной доставки
|
||||
|
||||
## 2017-12-27 v.2.3.1
|
||||
* Исправлены мелкие баги и недочеты
|
||||
|
||||
## 2017-12-04 v.2.3.0
|
||||
* Добавлен выбор валюты в настройках, для выгрузки заказов из CRM
|
||||
* Исправлена выборка свойств заказа
|
||||
* Устранен баг в настройках соответствия полей свойств заказа
|
||||
* Улучшена механика выгрузки заказов из CRM
|
||||
|
||||
## 2017-11-20 v.2.2.10
|
||||
* Устранен баг с созданием чеков
|
||||
* Улучшен механизм работы с оплатами
|
||||
|
||||
## 2017-11-13 v.2.2.9
|
||||
* Исправлены ошибки подключения кастомных классов
|
||||
* Улучшена обработка истории
|
||||
|
||||
## 2017-11-01 v.2.2.8
|
||||
* Исправлены баги пакетной выгрузки
|
||||
* Исправлена ошибка при работе на php7.1
|
||||
|
||||
## 2017-10-26 v.2.2.7
|
||||
* Исправлен баг при работе с одним сайтом
|
||||
|
||||
## 2017-10-25 v.2.2.6
|
||||
* Доработана система синхронизации оплат
|
||||
* Исправлены ошибки в истории заказов
|
||||
|
||||
## 2017-09-22 v.2.2.5
|
||||
* Теперь учитываются группы доставки
|
||||
* Изменен алгоритм передачи оплат
|
||||
* Исправлено задваивание количества товаров в отгрузке
|
||||
* Небольшие исправления
|
||||
|
||||
## 2017-09-07 v.2.2.4
|
||||
* Исправлена работа истории пользователей
|
||||
* Убраны события для старого API
|
||||
|
||||
## 2017-09-04 v.2.2.3
|
||||
* Исправлена работа истории
|
||||
|
||||
## 2017-09-04 v.2.2.2
|
||||
* Исправлен инсталлятор
|
||||
* Изменена передача данных по пользователю
|
||||
|
||||
## 2017-09-01 v.2.2.1
|
||||
* Добавлена встроенная функция retailCrmApiResult
|
||||
* Добавлен триггерный вариант истории изменений
|
||||
* Исправлены ошибки
|
||||
|
||||
## 2017-08-21 v.2.2.0
|
||||
* API V5
|
||||
* Возможность выбора версии API
|
||||
* Добавлена возможность выгрузки остатков в разрезе складов
|
||||
* Добавлена возможность выгрузки типов цен
|
||||
* Добавлена базовая интеграция Daemon Collector
|
||||
* Добавлена интеграция с Universal Analytics
|
||||
* Доработана логика работы встроенных функций для модификации данных
|
||||
* Исправлены ошибки
|
||||
|
||||
## 2016-12-09 v.2.1.2
|
||||
* Добавлены единицы измерения в экспорте каталога
|
||||
* Исправлены пути в include
|
||||
* Добавлено время нового формата в валидатор
|
||||
* Исправлено неверное изменение типа заказа по истории
|
||||
* Исправлена ошибка с некорректным разбиением ФИО
|
||||
* Небольшие исправления по коду
|
||||
## 2016-11-15 v.2.1.1
|
||||
* Исправлена проблема с отсутствием в настройках доставок
|
||||
* Небольшие исправления
|
||||
|
||||
## 2016-10-31 v.2.1.0
|
||||
* Добавлена передача адреса из карточки клиента в RetailCRM
|
||||
* Добавлено больше информации в журнале битрикса и дополнительное логирование
|
||||
* Небольшие исправления
|
||||
|
||||
## 2016-10-25 v.2.0.9
|
||||
* Исправлена ошибка с неверной кодировкой ФИО
|
||||
* Исправлена ошибка с отсутствием местоположения
|
||||
|
||||
## 2016-10-20 v.2.0.8
|
||||
* Исправлена ошибка с отсутствием LID
|
||||
* Изменены методы для совместимости с ранними версиями sale 16 версии
|
||||
|
||||
## 2016-10-20 v.2.0.7
|
||||
* Исправлена ошибка с недобавлением товара в заказ по истории
|
||||
* Исправлена ошибка с недобавлением сервиса доставки в црм
|
||||
|
||||
## 2016-10-14 v.2.0.6
|
||||
* Оптимизация History
|
||||
* Исправлены ошибки
|
||||
|
||||
## 2016-10-11 v.2.0.5
|
||||
* Исправлена ошибка при обработке Ф.И.О.
|
||||
* Исправлена ошибка с неверной кодировкой свойств
|
||||
* Исправлена ошибка формирования списка статусов
|
||||
|
||||
## 2016-10-06 v.2.0.4
|
||||
* Оптимизация History
|
||||
* Исправлена ошибка выгрузки доставок при установке
|
||||
|
||||
## 2016-10-04 v.2.0.3
|
||||
* fix состава отгрузки
|
||||
|
||||
## 2016-10-04 v.2.0.2
|
||||
* Исправлены ошибки
|
||||
|
||||
## 2016-10-03 v.2.0.1
|
||||
* Исправлены ошибки
|
||||
|
||||
## 2016-09-12 v.2.0.0
|
||||
* API V4
|
||||
* Переход на ядро d7
|
||||
* История изменений по клиентам
|
||||
* Множественный флаг отмены заказа
|
||||
|
||||
## 2015-11-09 v.1.1.3
|
||||
* Добавлено логгирование в файл для приходящей из црм и уходящей в црм информации
|
||||
* Изменен механизм добавления товара в заказ
|
||||
* Возможность добавить товар в заказ, который есть в црм, но нет на сайте
|
||||
* Изменил логику выбора товаров для выгрузки в xml
|
||||
* Появилась возможность перевести History на триггер
|
||||
* Исправлены ошибки
|
||||
|
||||
## 2015-05-18 v.1.1.2
|
||||
* Добавлена возможность изменять файлы основных классов(ICMLLoader и ICrmOrderActions) и экспорт каталога без потери обновлений
|
||||
* Исправлены мелкие ошибки
|
||||
|
||||
## 2015-03-19 v.1.1.1
|
||||
* Исправлена ошибка, связанная с версионностью PHP в History.
|
||||
* Добавлена выгрузка закупочной цены вместе с заказом
|
||||
* Добавлены индивидуальные настройки для профилей выгрузки
|
||||
* Исправлены мелкие ошибки
|
||||
|
||||
## 2015-02-20 v.1.1.0
|
||||
* Модуль переведен на новую версию API
|
||||
* Добавлена поддержка реквизитов юр. лиц
|
||||
* Добавлена многосайтовость
|
||||
* Добавлена выборочная загрузка заказов из настроек модуля
|
||||
* Оптимизирована загрузка старых заказов
|
||||
* Исправлена ошибка с удалением id товара в заказе
|
||||
* Исправлена ошибка пустого $_SERVER['SERVER_NAME'] при экспорте каталога
|
||||
* Исправлена ошибка с неправильной скидкой у товара при наличии копеек
|
||||
* Исправлена ошибка с пропаданием автоматических служб доставок из настроек модуля
|
||||
* Исправлена неправильная выгрузка сервисов для служб доставок
|
||||
* Исправлено не правильное определение местоположения
|
||||
* Рефакторинг модуля
|
||||
|
||||
## 2015-02-13 v.1.0.16
|
||||
* Все действия агента происходят от имени retailcrm
|
||||
|
||||
## 2015-02-12 v.1.0.16
|
||||
* Исправлен агент
|
||||
* Исправлены ошибки с запоминанием пользователя
|
||||
* Исправлена ошибка с выходом пользователя из системы
|
||||
* Исправлена ошибка хождения пользователя под другим логином
|
||||
* Исправлены проблема с fix-external-ids
|
||||
* Добавлена возможность получения скидки из CRM в Битрикс
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 RetailDriver LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
51
Makefile
Executable file
51
Makefile
Executable file
|
@ -0,0 +1,51 @@
|
|||
ROOT_DIR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
test: prepare_module
|
||||
composer tests
|
||||
|
||||
prepare_module:
|
||||
composer pre-module-install
|
||||
|
||||
deps:
|
||||
ifneq ($(NOT_USE_VENDOR),1)
|
||||
composer install
|
||||
endif
|
||||
|
||||
install_bitrix: download_bitrix
|
||||
@echo "===== Installing Bitrix..."
|
||||
@php bin/bitrix-install db_type
|
||||
@php bin/bitrix-install requirement
|
||||
@php bin/bitrix-install db_create
|
||||
@php bin/bitrix-install main_module
|
||||
@php bin/bitrix-install module
|
||||
@php bin/bitrix-install admin
|
||||
@php bin/bitrix-install load_module
|
||||
@php bin/bitrix-install load_module_action
|
||||
@php bin/bitrix-install finish
|
||||
|
||||
download_bitrix:
|
||||
ifeq ("$(wildcard $(BITRIX_PATH)/bitrix/php_interface/dbconn.php)","")
|
||||
wget --progress=dot -e dotbytes=10M -O /tmp/$(BITRIX_EDITION).tar.gz https://www.1c-bitrix.ru/download/$(BITRIX_EDITION).tar.gz
|
||||
mkdir -p $(BITRIX_PATH)
|
||||
chmod -R 777 $(BITRIX_PATH)
|
||||
tar -xf /tmp/$(BITRIX_EDITION).tar.gz -C $(BITRIX_PATH)
|
||||
rm /tmp/$(BITRIX_EDITION).tar.gz
|
||||
endif
|
||||
|
||||
build_release:
|
||||
ifneq ($(LAST_TAG),$(RELEASE_TAG))
|
||||
git diff --name-status $(LAST_TAG) HEAD > $(ROOT_DIR)/release/diff
|
||||
php bin/build-release
|
||||
bash bin/build $(CURRENT_VERSION) $(ROOT_DIR)/release/
|
||||
else
|
||||
@exit 0
|
||||
endif
|
||||
|
||||
cleanup:
|
||||
@rm -rf $(ROOT_DIR)/release/$(CURRENT_VERSION)
|
||||
@rm $(ROOT_DIR)/release/$(CURRENT_VERSION).tar.gz
|
||||
|
||||
run_local_tests:
|
||||
docker-compose up -d --build
|
||||
docker exec app_test make install_bitrix deps test
|
||||
docker-compose down
|
17
README.md
17
README.md
|
@ -1,15 +1,22 @@
|
|||
[](https://github.com/retailcrm/bitrix-module/actions)
|
||||
[](https://github.com/retailcrm/bitrix-module/releases)
|
||||
[](https://codecov.io/gh/retailcrm/bitrix-module)
|
||||
[](https://php.net/)
|
||||
|
||||
Bitrix module
|
||||
=============
|
||||
|
||||
Bitrix module for interaction with [IntaroCRM](http://www.intarocrm.com) through [REST API](http://docs.intarocrm.ru/rest-api/).
|
||||
Bitrix module for interaction with [RetailCRM](https://www.retailcrm.ru)
|
||||
|
||||
Module allows:
|
||||
|
||||
* Send to IntaroCRM new orders
|
||||
* Configure relations between dictionaries of IntaroCRM and Bitrix (statuses, payments, delivery types and etc)
|
||||
* Generate [ICML](http://docs.intarocrm.ru/index.php?n=Пользователи.ФорматICML) (IntaroCRM Markup Language) for catalog loading by IntaroCRM
|
||||
* Exchange the orders with RetailCRM
|
||||
* Configure relations between dictionaries of RetailCRM and Bitrix (statuses, payments, delivery types and etc)
|
||||
* Generate [ICML](https://docs.retailcrm.ru/ru/Developers/modules/ICML) (Intaro Markup Language) for catalog loading by RetailCRM
|
||||
|
||||
Installation
|
||||
-------------
|
||||
|
||||
You should install module through [Bitrix.Marketplace](http://marketplace.1c-bitrix.ru).
|
||||
You should install module through [Bitrix.Marketplace](http://marketplace.1c-bitrix.ru/solutions/intaro.retailcrm/).
|
||||
|
||||
[Setup guide](https://docs.retailcrm.ru/Users/Integration/SiteModules/1CBitrix)
|
||||
|
|
58
bin/bitrix-install
Executable file
58
bin/bitrix-install
Executable file
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
if (ini_get('memory_limit') > 0 && (int)ini_get('memory_limit') < 784) {
|
||||
ini_set('memory_limit', '784M');
|
||||
}
|
||||
|
||||
$_SERVER['DOCUMENT_ROOT'] = getenv('BITRIX_PATH') ? getenv('BITRIX_PATH') : '/var/www/html';
|
||||
|
||||
define("B_PROLOG_INCLUDED", true);
|
||||
define("DEBUG_MODE", true);
|
||||
|
||||
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/install/wizard/wizard.php')) {
|
||||
throw new \RuntimeException('Bitrix`s install files is not exists');
|
||||
}
|
||||
|
||||
ob_start();
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/install/wizard/wizard.php';
|
||||
ob_clean();
|
||||
|
||||
require_once __DIR__ . '/../helpers/installation/ExtendedCreateModulesStep.php';
|
||||
require_once __DIR__ . '/../helpers/installation/Installer.php';
|
||||
|
||||
$installer = new Installer();
|
||||
|
||||
$step = $argv[1];
|
||||
|
||||
switch ($step) {
|
||||
case 'db_type':
|
||||
$installer->dbTypeStep();
|
||||
exit(0);
|
||||
case 'requirement':
|
||||
$installer->requirementStep();
|
||||
exit(0);
|
||||
case 'db_create':
|
||||
$installer->createDBStep();
|
||||
exit(0);
|
||||
case 'main_module':
|
||||
$installer->createModulesStep(true);
|
||||
exit(0);
|
||||
case 'module':
|
||||
$installer->createModulesStep();
|
||||
exit(0);
|
||||
case 'admin':
|
||||
$installer->createAdminStep();
|
||||
exit(0);
|
||||
case 'load_module':
|
||||
$installer->createLoadModuleStep();
|
||||
exit(0);
|
||||
case 'load_module_action':
|
||||
$installer->createLoadModuleActionStep();
|
||||
exit(0);
|
||||
case 'finish':
|
||||
$installer->createFinishStep();
|
||||
exit(0);
|
||||
}
|
13
bin/bitrix-version
Normal file
13
bin/bitrix-version
Normal file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
if (ini_get('memory_limit') > 0 && (int) ini_get('memory_limit') < 784) {
|
||||
ini_set('memory_limit', '784M');
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../intaro.retailcrm/install/version.php';
|
||||
|
||||
echo $arModuleVersion['VERSION'];
|
||||
exit(0);
|
46
bin/build
Normal file
46
bin/build
Normal file
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
# $1 -- folder name to pack;
|
||||
|
||||
version=$1
|
||||
dir=${2-$PWD}
|
||||
|
||||
cd $dir
|
||||
|
||||
date=`date +"%Y-%m-%d %H:%M:%S"`
|
||||
|
||||
if [ ! -d "$version/install" ]; then
|
||||
mkdir -p "./$version/install"
|
||||
echo "Created a folder \"install\""
|
||||
fi
|
||||
|
||||
if [ ! -f "$version/install/version.php" ]; then
|
||||
touch "./$version/install/version.php"
|
||||
echo "Created a file \"version.php\""
|
||||
fi
|
||||
|
||||
echo "
|
||||
<?
|
||||
\$arModuleVersion = array(
|
||||
\"VERSION\" => \"$version\",
|
||||
\"VERSION_DATE\" => \"$date\"
|
||||
);
|
||||
" > "./$version/install/version.php"
|
||||
echo "Update version and date in the file \"version.php\""
|
||||
|
||||
for i in `find ./"$version" -type f -name '*.*'`; do
|
||||
encoding=`file -b --mime-encoding "$i"`
|
||||
if [ "$encoding" != "iso-8859-1" ] && [ "$encoding" != "us-ascii" ] && [ "$encoding" != "binary" ]; then
|
||||
echo "$i: converting from $encoding to cp1251"
|
||||
result=$(iconv -f $encoding -t "cp1251" $i -o $i.cp1251 2>&1 > /dev/null)
|
||||
if [ ! -z "$result" ]; then
|
||||
echo "Errors in file $i"
|
||||
echo $result
|
||||
exit 255
|
||||
fi
|
||||
mv $i.cp1251 $i
|
||||
fi
|
||||
done
|
||||
echo "Encoding the file has changed"
|
||||
|
||||
tar -czf $version.tar.gz $version
|
||||
echo "Update has been successfully packaged"
|
38
bin/build-release
Normal file
38
bin/build-release
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
error_reporting(E_ALL ^ E_DEPRECATED);
|
||||
|
||||
require_once __DIR__ . '/../helpers/release/ReleaseBuilder.php';
|
||||
require_once __DIR__ . '/../helpers/release/ModifiedFile.php';
|
||||
require_once __DIR__ . '/../intaro.retailcrm/install/version.php';
|
||||
|
||||
define('RELEASE_DIR', __DIR__ . '/../release/');
|
||||
define('ORIGINAL', __DIR__ . '/../intaro.retailcrm/');
|
||||
|
||||
if (!file_exists(RELEASE_DIR . 'diff')) {
|
||||
print('Diff file does not exists');
|
||||
exit(255);
|
||||
}
|
||||
|
||||
$handle = fopen(RELEASE_DIR . 'diff', 'r');
|
||||
|
||||
if (!$handle) {
|
||||
exit(255);
|
||||
}
|
||||
|
||||
$modifiedFiles = [];
|
||||
|
||||
while (($buffer = fgets($handle)) !== false) {
|
||||
$modifiedFiles[] = new ModifiedFile($buffer);
|
||||
}
|
||||
|
||||
try {
|
||||
$builder = new ReleaseBuilder($modifiedFiles, $arModuleVersion['VERSION']);
|
||||
$builder->build();
|
||||
} catch(\Exception $exception) {
|
||||
print($exception->getMessage());
|
||||
exit(255);
|
||||
}
|
||||
|
||||
exit(0);
|
6
bin/enable_debugging
Normal file
6
bin/enable_debugging
Normal file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
$file = $argv[1] . '/bitrix/.settings.php';
|
||||
$params = include $file;
|
||||
$params['exception_handling']['value']['debug'] = true;
|
||||
file_put_contents($file, "<?php\nreturn " . var_export($params, true) . ';', LOCK_EX);
|
28
composer.json
Executable file
28
composer.json
Executable file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "retailcrm/bitrix-module",
|
||||
"scripts": {
|
||||
"pre-module-install": "cp -R intaro.retailcrm $BITRIX_PATH/bitrix/modules",
|
||||
"tests": "vendor/bin/phpunit -c phpunit.xml.dist --whitelist=$BITRIX_PATH/bitrix/modules/intaro.retailcrm"
|
||||
},
|
||||
"description": "Integration module for Bitrix & RetailCRM",
|
||||
"license": "MIT",
|
||||
"type": "bitrix-module",
|
||||
"authors": [
|
||||
{
|
||||
"name": "RetailDriver LLC",
|
||||
"email": "integration@retailcrm.ru"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"ext-xmlwriter": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"vlucas/phpdotenv": "^3.3",
|
||||
"mockery/mockery" : "^1.0",
|
||||
"fakerphp/faker": "^1.21"
|
||||
}
|
||||
}
|
1982
composer.lock
generated
Normal file
1982
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
41
doc/Module settings/Customization.md
Normal file
41
doc/Module settings/Customization.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
### Кастомизация модуля
|
||||
|
||||
В модуле доступна кастомизация классов, без потери модифицированного кода при обновлении.
|
||||
|
||||
Для этого требуется создать копию необходимого для кастомизации файла и расположить его директории
|
||||
`bitrix/php_inteface/retailcrm`
|
||||
|
||||
Имеется возможность кастомизации следующих файлов:
|
||||
* RestNormalizer.php
|
||||
* Logger.php
|
||||
* Client.php
|
||||
* RCrmActions.php
|
||||
* RetailCrmUser.php
|
||||
* RetailCrmICML.php
|
||||
* RetailCrmInventories.php
|
||||
* RetailCrmPrices.php
|
||||
* RetailCrmCollector.php
|
||||
* RetailCrmUa.php
|
||||
* RetailCrmEvent.php
|
||||
* RetailCrmHistory_v5.php
|
||||
* RetailCrmOrder_v5.php
|
||||
* ApiClient_v5.php
|
||||
|
||||
С версии 6.3.19 доступна кастомизация ICML, файлы которого расположены в модуле по пути `lib/icml`:
|
||||
* xmlofferbuilder.php
|
||||
* xmlofferdirector.php
|
||||
* icmlwriter.php
|
||||
* queryparamsmolder.php
|
||||
* settingsservice.php
|
||||
* xmlcategorydirector.php
|
||||
* xmlcategoryfactory.php
|
||||
* icmldirector.php
|
||||
|
||||
Кастомизированные файлы каталога также должны быть расположены в директории `bitrix/php_inteface/retailcrm`
|
||||
Например, кастом оригинального файла `lib/icml/xmlofferbuilder.php` будет иметь путь `bitrix/php_interface/retailcrm/xmlofferbuilder.php`
|
||||
|
||||
Для кастомизации файлов, в названии которых есть используемая версия API,
|
||||
создаются файлы с названием без указания версии, например - `RetailCrmHistory.php`.
|
||||
|
||||
После создания копии файла с классом в директории `bitrix/php_interface/retailcrm`
|
||||
модуль будет использовать кастомизированный класс, в котором можно вносить изменения в его методы.
|
11
doc/Module settings/Deactivate module.md
Normal file
11
doc/Module settings/Deactivate module.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
### Настройки активности модуля
|
||||
|
||||
В версии 6.3.6 в настройки модуля добавлена опция деактивации модуля.
|
||||
|
||||
Для деактивации модуля в настройках необходимо выбрать опцию ***Деактивировать модуль***
|
||||
|
||||
Данная опция необходима для кейсов:
|
||||
* проверка работоспособности Bitrix в целом, с исключением внешних факторов;
|
||||
* при некорректной передачи данных из CMS в CRM и обратно.
|
||||
|
||||
При деактивации модуля, данные передаваться не будут, но все пользовательские настройки будут сохранены.
|
1
doc/README.md
Normal file
1
doc/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Developers documentation
|
34
docker-compose.yml
Executable file
34
docker-compose.yml
Executable file
|
@ -0,0 +1,34 @@
|
|||
version: '3'
|
||||
services:
|
||||
bitrix:
|
||||
container_name: app_test
|
||||
build: ./.docker
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- MYSQL_SERVER=${DB_BITRIX_HOST}
|
||||
- MYSQL_DATABASE=${DB_BITRIX_NAME}
|
||||
- MYSQL_USER=${DB_BITRIX_LOGIN}
|
||||
- MYSQL_PASSWORD=${DB_BITRIX_PASS}
|
||||
- BITRIX_PATH=${BITRIX_PATH}
|
||||
depends_on:
|
||||
- mysql
|
||||
ports:
|
||||
- '8080:80'
|
||||
links:
|
||||
- mysql
|
||||
volumes:
|
||||
- ./:/bitrix-module
|
||||
- ./.docker/php.ini:/usr/local/etc/php/conf.d/z-bitrix.ini
|
||||
- ./tmp:/tmp
|
||||
mysql:
|
||||
env_file:
|
||||
- .env
|
||||
image: mysql:5.6
|
||||
ports:
|
||||
- '3306:3306'
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=root
|
||||
- MYSQL_DATABASE=${DB_BITRIX_NAME}
|
||||
- MYSQL_USER=${DB_BITRIX_LOGIN}
|
||||
- MYSQL_PASSWORD=${DB_BITRIX_PASS}
|
15
helpers/installation/ExtendedCreateModulesStep.php
Normal file
15
helpers/installation/ExtendedCreateModulesStep.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class ExtendedCreateModulesStep
|
||||
*/
|
||||
class ExtendedCreateModulesStep extends CreateModulesStep
|
||||
{
|
||||
/**
|
||||
* @param string $str
|
||||
*/
|
||||
public function SendResponse($str)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
345
helpers/installation/Installer.php
Normal file
345
helpers/installation/Installer.php
Normal file
|
@ -0,0 +1,345 @@
|
|||
<?php
|
||||
|
||||
ob_start();
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/install/wizard/wizard.php';
|
||||
ob_clean();
|
||||
|
||||
/**
|
||||
* Class Installer
|
||||
*/
|
||||
class Installer
|
||||
{
|
||||
private $dbName;
|
||||
private $dbHost;
|
||||
private $dbUser;
|
||||
private $dbPass;
|
||||
|
||||
/**
|
||||
* Installer constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->deleteDefaultInstallation();
|
||||
|
||||
$this->dbHost = getenv('DB_BITRIX_HOST') ? getenv('DB_BITRIX_HOST') : 'localhost';
|
||||
$this->dbName = getenv('DB_BITRIX_NAME') ? getenv('DB_BITRIX_NAME') : 'bitrix';
|
||||
$this->dbUser = getenv('DB_BITRIX_LOGIN') ? getenv('DB_BITRIX_LOGIN') : 'bitrix';
|
||||
$this->dbPass = getenv('DB_BITRIX_PASS') ? getenv('DB_BITRIX_PASS') : 'bitrix';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
private function setCurrentStepID($value)
|
||||
{
|
||||
$this->setRequestParam('CurrentStepID', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
private function setNextStepID($value)
|
||||
{
|
||||
$this->setRequestParam('NextStepID', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
private function setPreviousStepID($value)
|
||||
{
|
||||
$this->setRequestParam('PreviousStepID', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return self
|
||||
*/
|
||||
private function setRequestParam($key, $value)
|
||||
{
|
||||
$_REQUEST[$key] = $value;
|
||||
$_POST[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute installation step
|
||||
* @return void
|
||||
*/
|
||||
protected function request()
|
||||
{
|
||||
$this->setParams();
|
||||
|
||||
$steps = array(
|
||||
CheckLicenseKey::class,
|
||||
DBTypeStep::class,
|
||||
RequirementStep::class,
|
||||
CreateDBStep::class,
|
||||
ExtendedCreateModulesStep::class,
|
||||
CreateAdminStep::class,
|
||||
SelectWizardStep::class,
|
||||
LoadModuleStep::class,
|
||||
LoadModuleActionStep::class,
|
||||
SelectWizard1Step::class
|
||||
);
|
||||
|
||||
$wizard = new CWizardBase(
|
||||
str_replace("#VERS#", SM_VERSION, InstallGetMessage("INS_TITLE")),
|
||||
$package = null
|
||||
);
|
||||
|
||||
$wizard->AddSteps($steps);
|
||||
$wizard->SetReturnOutput(true);
|
||||
$wizard->Display();
|
||||
|
||||
foreach ($wizard->GetWizardSteps() as $step) {
|
||||
if ($step->GetErrors()) {
|
||||
foreach ($step->GetErrors() as $error) {
|
||||
$this->println(sprintf('error: %s', mb_convert_encoding($error[0], 'UTF-8', 'windows-1251')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set request params for installation steps
|
||||
* @return void
|
||||
*/
|
||||
private function setParams()
|
||||
{
|
||||
$params = array(
|
||||
'__wiz_agree_license' => 'Y',
|
||||
'__wiz_dbType' => 'mysql',
|
||||
'__wiz_lic_key_variant' => '',
|
||||
'__wiz_utf8' => 'Y',
|
||||
'__wiz_create_user' => 'N',
|
||||
'__wiz_host' => $this->dbHost,
|
||||
'__wiz_user' => $this->dbUser,
|
||||
'__wiz_password' => $this->dbPass,
|
||||
'__wiz_database' => $this->dbName,
|
||||
'__wiz_create_database' => 'N',
|
||||
'__wiz_create_database_type' => 'innodb',
|
||||
'__wiz_root_user' => '',
|
||||
'__wiz_root_password' => '',
|
||||
'__wiz_file_access_perms' => '0644',
|
||||
'__wiz_folder_access_perms' => '0755',
|
||||
'__wiz_login' => 'admin',
|
||||
'__wiz_admin_password' => 'admin123',
|
||||
'__wiz_admin_password_confirm' => 'admin123',
|
||||
'__wiz_email' => 'admin@mail.com',
|
||||
'__wiz_user_name' => 'FirstName',
|
||||
'__wiz_user_surname' => 'LastName',
|
||||
'__wiz_selected_wizard' => 'bitrix.eshop:bitrix:eshop',
|
||||
);
|
||||
|
||||
foreach ($params as $code => $param) {
|
||||
$this->setRequestParam($code, $param);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Step of select database type
|
||||
* @return self
|
||||
*/
|
||||
public function dbTypeStep()
|
||||
{
|
||||
$this->setCurrentStepID('select_database');
|
||||
$this->setNextStepID('requirements');
|
||||
|
||||
ob_start();
|
||||
$this->request();
|
||||
ob_clean();
|
||||
|
||||
$this->println('Selected database type');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requirements step
|
||||
* @return self
|
||||
*/
|
||||
public function requirementStep()
|
||||
{
|
||||
$this->setCurrentStepID('requirements');
|
||||
$this->setNextStepID('create_database');
|
||||
|
||||
$this->request();
|
||||
|
||||
$this->println('Requirements step');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create database step
|
||||
* @return self
|
||||
*/
|
||||
public function createDBStep()
|
||||
{
|
||||
$this->setCurrentStepID('create_database');
|
||||
$this->setNextStepID('create_modules');
|
||||
|
||||
$this->request();
|
||||
|
||||
$this->println('Database setup');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation modules step
|
||||
* @param bool $isMain
|
||||
* @return self
|
||||
*/
|
||||
public function createModulesStep($isMain = false)
|
||||
{
|
||||
$threeSteps = array(
|
||||
'utf8',
|
||||
'database',
|
||||
'files'
|
||||
);
|
||||
|
||||
if ($isMain) {
|
||||
$modules = array(
|
||||
'main' => $threeSteps
|
||||
);
|
||||
} else {
|
||||
$modules = array(
|
||||
'abtest' => $threeSteps,
|
||||
'bitrix.eshop' => $threeSteps,
|
||||
'catalog' => $threeSteps,
|
||||
'compression' => $threeSteps,
|
||||
'conversion' => $threeSteps,
|
||||
'currency' => $threeSteps,
|
||||
'fileman' => $threeSteps,
|
||||
'form' => $threeSteps,
|
||||
'highloadblock' => $threeSteps,
|
||||
'iblock' => $threeSteps,
|
||||
'pull' => $threeSteps,
|
||||
'rest' => $threeSteps,
|
||||
'sale' => $threeSteps,
|
||||
'scale' => $threeSteps,
|
||||
'search' => $threeSteps,
|
||||
'security' => $threeSteps,
|
||||
'sender' => $threeSteps,
|
||||
'storeassist' => $threeSteps,
|
||||
'translate' => $threeSteps,
|
||||
'ui' => $threeSteps,
|
||||
'remove_mysql' => array(
|
||||
array('single')
|
||||
),
|
||||
'remove_mssql' => array(
|
||||
array('single')
|
||||
),
|
||||
'remove_oracle' => array(
|
||||
array('single')
|
||||
),
|
||||
'remove_misc' => array(
|
||||
array('single')
|
||||
),
|
||||
'__finish' => array(
|
||||
array('single')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->setCurrentStepID('create_modules');
|
||||
|
||||
foreach ($modules as $module => $steps) {
|
||||
foreach ($steps as $step) {
|
||||
$this->setRequestParam('__wiz_nextStep', $module);
|
||||
$this->setRequestParam('__wiz_nextStepStage', $step);
|
||||
|
||||
$this->request();
|
||||
|
||||
$this->println(sprintf('%s module install, step %s', $module, $step));
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create admin interface step
|
||||
* @return self
|
||||
*/
|
||||
public function createAdminStep()
|
||||
{
|
||||
$this->setCurrentStepID('create_admin');
|
||||
|
||||
$this->request();
|
||||
|
||||
$this->println('Setup admin');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load modules step
|
||||
* @return self
|
||||
*/
|
||||
public function createLoadModuleStep()
|
||||
{
|
||||
$this->setCurrentStepID('load_module');
|
||||
|
||||
$this->request();
|
||||
|
||||
$this->println('Load modules');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load modules action step
|
||||
* @return self
|
||||
*/
|
||||
public function createLoadModuleActionStep()
|
||||
{
|
||||
$this->setCurrentStepID('load_module_action');
|
||||
|
||||
$this->request();
|
||||
|
||||
$this->println('Load modules action');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish install step
|
||||
* @return self
|
||||
*/
|
||||
public function createFinishStep()
|
||||
{
|
||||
$this->setCurrentStepID('finish');
|
||||
|
||||
$this->request();
|
||||
|
||||
$this->println('Installation finish');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove code for web install
|
||||
* @return void
|
||||
*/
|
||||
private function deleteDefaultInstallation()
|
||||
{
|
||||
$data = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/install/wizard/wizard.php');
|
||||
$newData = preg_replace('/\$wizard= new CWizardBase.+$/', '', $data);
|
||||
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/install/wizard/wizard.php', $newData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return void
|
||||
*/
|
||||
private function println($string)
|
||||
{
|
||||
print($string);
|
||||
print(PHP_EOL);
|
||||
}
|
||||
}
|
125
helpers/release/ModifiedFile.php
Normal file
125
helpers/release/ModifiedFile.php
Normal file
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class ModifiedFile
|
||||
*/
|
||||
class ModifiedFile
|
||||
{
|
||||
/** @var string */
|
||||
const ADDED = 'A';
|
||||
|
||||
/** @var string */
|
||||
const DELETED = 'D';
|
||||
|
||||
/** @var string */
|
||||
const MODIFIED = 'M';
|
||||
|
||||
/** @var string */
|
||||
const RENAMED = 'R';
|
||||
|
||||
/** @var string */
|
||||
const MODULE_ID = 'intaro.retailcrm';
|
||||
|
||||
/** @var string */
|
||||
const DESCRIPTION = 'description.ru';
|
||||
|
||||
/** @var string */
|
||||
const VERSION = 'install/version.php';
|
||||
|
||||
/** @var string */
|
||||
protected $filename;
|
||||
|
||||
/** @var string */
|
||||
protected $oldFilename;
|
||||
|
||||
/** @var string */
|
||||
protected $modificator;
|
||||
|
||||
/** @var int */
|
||||
protected $percent;
|
||||
|
||||
/**
|
||||
* ModifiedFile constructor.
|
||||
* @param string $source
|
||||
*/
|
||||
public function __construct($source)
|
||||
{
|
||||
$params = explode("\t", trim($source));
|
||||
|
||||
$this->filename = $params[1];
|
||||
$this->modificator = $params[0][0];
|
||||
|
||||
if (strlen($params[0]) > 1) {
|
||||
$this->percent = (int) substr($params[0], 1);
|
||||
}
|
||||
|
||||
if (count($params) >= 3) {
|
||||
$this->filename = $params[2];
|
||||
$this->oldFilename = $params[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAdded()
|
||||
{
|
||||
return $this->modificator === static::ADDED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDeleted()
|
||||
{
|
||||
return $this->modificator === static::DELETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isModified()
|
||||
{
|
||||
return $this->modificator === static::MODIFIED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isRenamed()
|
||||
{
|
||||
return $this->modificator === static::RENAMED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isModuleFile()
|
||||
{
|
||||
return strpos($this->filename, static::MODULE_ID) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOldFilename()
|
||||
{
|
||||
return $this->oldFilename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPercent()
|
||||
{
|
||||
return $this->percent;
|
||||
}
|
||||
}
|
113
helpers/release/ReleaseBuilder.php
Normal file
113
helpers/release/ReleaseBuilder.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
require_once 'ModifiedFile.php';
|
||||
|
||||
/**
|
||||
* Class ReleaseBuilder
|
||||
*/
|
||||
class ReleaseBuilder
|
||||
{
|
||||
/** @var ModifiedFile[] */
|
||||
protected $files;
|
||||
|
||||
/** @var string */
|
||||
protected $releaseDir;
|
||||
|
||||
/**
|
||||
* ReleaseBuilder constructor.
|
||||
* @param ModifiedFile[] $files
|
||||
* @param string $releaseVersion
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($files, $releaseVersion)
|
||||
{
|
||||
$this->files = $files;
|
||||
|
||||
if (!defined('RELEASE_DIR') || !defined('ORIGINAL')) {
|
||||
throw new \RuntimeException('`RELEASE_DIR` or `ORIGINAL` not defined');
|
||||
}
|
||||
|
||||
$this->releaseDir = RELEASE_DIR . $releaseVersion . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$this->createReleaseDir();
|
||||
$modifiedFiles = [];
|
||||
|
||||
foreach ($this->files as $file) {
|
||||
if (!$file->isModuleFile() || $file->isDeleted()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$modifiedFiles[] = $this->getRealFilename($file->getFilename());
|
||||
}
|
||||
|
||||
if (!in_array(ModifiedFile::DESCRIPTION, $modifiedFiles) || !in_array(ModifiedFile::VERSION, $modifiedFiles)) {
|
||||
throw new \UnexpectedValueException('Version or description file does not exists');
|
||||
}
|
||||
|
||||
if (empty($modifiedFiles)) {
|
||||
throw new \LogicException('Not found modified files for release');
|
||||
}
|
||||
|
||||
$this->createDirNodes($modifiedFiles);
|
||||
$this->copyFiles($modifiedFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $files
|
||||
*/
|
||||
private function copyFiles($files)
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
copy(ORIGINAL . $file, $this->releaseDir . $file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $files
|
||||
*/
|
||||
private function createDirNodes($files)
|
||||
{
|
||||
$paths = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$dirs = explode('/', $file, -1);
|
||||
$path = $this->releaseDir;
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
$path .= $dir . '/';
|
||||
$paths[] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (!file_exists($path)) {
|
||||
mkdir($path, 0755);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function createReleaseDir()
|
||||
{
|
||||
if (!file_exists($this->releaseDir)) {
|
||||
mkdir($this->releaseDir, 0755);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
private function getRealFilename($filename)
|
||||
{
|
||||
return str_replace(ModifiedFile::MODULE_ID . '/', '', $filename);
|
||||
}
|
||||
}
|
|
@ -1,378 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ICrmOrderActions
|
||||
{
|
||||
protected static $MODULE_ID = 'intaro.intarocrm';
|
||||
protected static $CRM_API_HOST_OPTION = 'api_host';
|
||||
protected static $CRM_API_KEY_OPTION = 'api_key';
|
||||
protected static $CRM_ORDER_TYPES_ARR = 'order_types_arr';
|
||||
protected static $CRM_DELIVERY_TYPES_ARR = 'deliv_types_arr';
|
||||
protected static $CRM_PAYMENT_TYPES = 'pay_types_arr';
|
||||
protected static $CRM_PAYMENT_STATUSES = 'pay_statuses_arr';
|
||||
protected static $CRM_PAYMENT = 'payment_arr'; //order payment Y/N
|
||||
protected static $CRM_ORDER_LAST_ID = 'order_last_id';
|
||||
|
||||
/**
|
||||
* Mass order uploading, without repeating; always returns true, but writes error log
|
||||
* @return boolean
|
||||
*/
|
||||
public static function uploadOrders($steps = false, $pSize = 50) {
|
||||
|
||||
//COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, 0); // -- for test
|
||||
|
||||
if (!CModule::IncludeModule("iblock")) {
|
||||
//handle err
|
||||
self::eventLog('ICrmOrderActions::uploadOrders', 'iblock', 'module not found');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CModule::IncludeModule("sale")) {
|
||||
//handle err
|
||||
self::eventLog('ICrmOrderActions::uploadOrders', 'sale', 'module not found');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CModule::IncludeModule("catalog")) {
|
||||
//handle err
|
||||
self::eventLog('ICrmOrderActions::uploadOrders', 'catalog', 'module not found');
|
||||
return true;
|
||||
}
|
||||
|
||||
$resOrders = array();
|
||||
|
||||
$lastUpOrderId = COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, 0);
|
||||
$lastOrderId = 0;
|
||||
|
||||
$dbOrder = CSaleOrder::GetList(array("ID" => "ASC"), array('>ID' => $lastUpOrderId));
|
||||
|
||||
$api_host = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_HOST_OPTION, 0);
|
||||
$api_key = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_KEY_OPTION, 0);
|
||||
|
||||
//saved cat params
|
||||
$optionsOrderTypes = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_TYPES_ARR, 0));
|
||||
$optionsDelivTypes = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_DELIVERY_TYPES_ARR, 0));
|
||||
$optionsPayTypes = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_TYPES, 0));
|
||||
$optionsPayStatuses = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_STATUSES, 0)); // --statuses
|
||||
$optionsPayment = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT, 0));
|
||||
|
||||
$api = new IntaroCrm\RestApi($api_host, $api_key);
|
||||
|
||||
$arParams = array(
|
||||
'optionsOrderTypes' => $optionsOrderTypes,
|
||||
'optionsDelivTypes' => $optionsDelivTypes,
|
||||
'optionsPayTypes' => $optionsPayTypes,
|
||||
'optionsPayStatuses' => $optionsPayStatuses,
|
||||
'optionsPayment' => $optionsPayment
|
||||
);
|
||||
|
||||
// pack mode enable / disable
|
||||
// can send data evry 500 rows
|
||||
if (!$steps) {
|
||||
|
||||
while ($arOrder = $dbOrder->GetNext()) { //here orders by id asc; with offset
|
||||
|
||||
$order = self::orderCreate($arOrder['ID'], $api, $arParams);
|
||||
|
||||
if (!$order)
|
||||
continue;
|
||||
|
||||
$resOrders[] = $order;
|
||||
|
||||
$lastOrderId = $arOrder['ID'];
|
||||
}
|
||||
|
||||
if (!empty($resOrders)) {
|
||||
$orders = $api->orderUpload($resOrders);
|
||||
|
||||
// error pushing orders
|
||||
if ($api->getStatusCode() != 201) {
|
||||
//handle err
|
||||
self::eventLog('ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload', $api->getLastError());
|
||||
|
||||
if ($api->getStatusCode() != 460) // some orders were sent
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} else { // package mode (by default runs after install)
|
||||
$orderCount = 0;
|
||||
|
||||
while ($arOrder = $dbOrder->GetNext()) { // here orders by id asc
|
||||
|
||||
$order = self::orderCreate($arOrder['ID'], $api, $arParams);
|
||||
|
||||
if (!$order)
|
||||
continue;
|
||||
|
||||
$orderCount++;
|
||||
|
||||
$resOrders[] = $order;
|
||||
|
||||
$lastOrderId = $arOrder['ID'];
|
||||
|
||||
if($orderCount >= $pSize) {
|
||||
$orders = $api->orderUpload($resOrders);
|
||||
|
||||
// error pushing orders
|
||||
if ($api->getStatusCode() != 201) {
|
||||
//handle err
|
||||
self::eventLog('ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload', $api->getLastError());
|
||||
|
||||
if($api->getStatusCode() != 460) // some orders were sent
|
||||
return false; // in pack mode return errors
|
||||
|
||||
}
|
||||
|
||||
if($lastOrderId)
|
||||
COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, $lastOrderId);
|
||||
|
||||
return true; // end of pack
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($resOrders)) {
|
||||
$orders = $api->orderUpload($resOrders);
|
||||
|
||||
// error pushing orders
|
||||
if ($api->getStatusCode() != 201) {
|
||||
//handle err
|
||||
self::eventLog('ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload', $api->getLastError());
|
||||
|
||||
if ($api->getStatusCode() != 460) // some orders were sent
|
||||
return false; // in pack mode return errors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($lastOrderId)
|
||||
COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, $lastOrderId);
|
||||
|
||||
return true; //all ok!
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* w+ event in bitrix log
|
||||
*/
|
||||
private static function eventLog($auditType, $itemId, $description) {
|
||||
CEventLog::Add(array(
|
||||
"SEVERITY" => "SECURITY",
|
||||
"AUDIT_TYPE_ID" => $auditType,
|
||||
"MODULE_ID" => self::$MODULE_ID,
|
||||
"ITEM_ID" => $itemId,
|
||||
"DESCRIPTION" => $description,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Agent function
|
||||
*
|
||||
* @return self name
|
||||
*/
|
||||
|
||||
public static function uploadOrdersAgent() {
|
||||
|
||||
if(self::uploadOrders())
|
||||
return 'ICrmOrderActions::uploadOrdersAgent();';
|
||||
|
||||
else return;
|
||||
}
|
||||
|
||||
public static function orderCreate($orderId, $api, $arParams, $send = false) {
|
||||
if(!$api || empty($arParams) || !$orderId) { // add cond to check $arParams
|
||||
return false;
|
||||
}
|
||||
|
||||
$arFields = CSaleOrder::GetById($orderId);
|
||||
|
||||
if (empty($arFields)) {
|
||||
//handle err
|
||||
self::eventLog('ICrmOrderActions::orderCreate', 'empty($arFields)', 'incorrect order');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$rsUser = CUser::GetByID($arFields['USER_ID']);
|
||||
$arUser = $rsUser->Fetch();
|
||||
|
||||
$createdAt = new \DateTime($arUser['DATE_REGISTER']);
|
||||
$createdAt = $createdAt->format('Y-m-d H:i:s');
|
||||
|
||||
// push customer (for crm)
|
||||
$firstName = self::toJSON($arUser['NAME']);
|
||||
$lastName = self::toJSON($arUser['LAST_NAME']);
|
||||
$patronymic = self::toJSON($arUser['SECOND_NAME']);
|
||||
|
||||
$phonePersonal = array(
|
||||
'number' => self::toJSON($arUser['PERSONAL_PHONE']),
|
||||
'type' => 'mobile'
|
||||
);
|
||||
$phones[] = $phonePersonal;
|
||||
|
||||
$phoneWork = array(
|
||||
'number' => self::toJSON($arUser['WORK_PHONE']),
|
||||
'type' => 'work'
|
||||
);
|
||||
$phones[] = $phoneWork;
|
||||
|
||||
$result = self::clearArr(array(
|
||||
'externalId' => $arFields['USER_ID'],
|
||||
'lastName' => $lastName,
|
||||
'firstName' => $firstName,
|
||||
'patronymic' => $patronymic,
|
||||
'phones' => $phones,
|
||||
'createdAt' => $createdAt
|
||||
));
|
||||
|
||||
$customer = $api->customerEdit($result);
|
||||
|
||||
// error pushing customer
|
||||
if (!$customer) {
|
||||
//handle err
|
||||
self::eventLog('ICrmOrderActions::orderCreate', 'IntaroCrm\RestApi::customerEdit', $api->getLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// delivery types
|
||||
$arId = array();
|
||||
if (strpos($arFields['DELIVERY_ID'], ":") !== false)
|
||||
$arId = explode(":", $arFields["DELIVERY_ID"]);
|
||||
|
||||
if ($arId)
|
||||
$resultDeliveryTypeId = $arId[0];
|
||||
else
|
||||
$resultDeliveryTypeId = $arFields['DELIVERY_ID'];
|
||||
|
||||
|
||||
$resOrder = array();
|
||||
$resOrderDeliveryAddress = array();
|
||||
|
||||
$rsOrderProps = CSaleOrderPropsValue::GetList(array(), array('ORDER_ID' => $arFields['ID']));
|
||||
while ($ar = $rsOrderProps->Fetch()) {
|
||||
switch ($ar['CODE']) {
|
||||
case 'ZIP': $resOrderDeliveryAddress['index'] = self::toJSON($ar['VALUE']);
|
||||
break;
|
||||
case 'CITY': $resOrderDeliveryAddress['city'] = self::toJSON($ar['VALUE']);
|
||||
break;
|
||||
case 'ADDRESS': $resOrderDeliveryAddress['text'] = self::toJSON($ar['VALUE']);
|
||||
break;
|
||||
case 'LOCATION': if(!isset($resOrderDeliveryAddress['city']) && !$resOrderDeliveryAddress['city']) {
|
||||
$resOrderDeliveryAddress['city'] = CSaleLocation::GetByID($ar['VALUE']);
|
||||
$resOrderDeliveryAddress['city'] = self::toJSON($resOrderDeliveryAddress['city']['CITY_NAME_LANG']);
|
||||
}
|
||||
break;
|
||||
case 'FIO': $resOrder['contactName'] = explode(" ", self::toJSON($ar['VALUE']));
|
||||
break;
|
||||
case 'PHONE': $resOrder['phone'] = $ar['VALUE'];
|
||||
break;
|
||||
case 'EMAIL': $resOrder['email'] = $ar['VALUE'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$items = array();
|
||||
|
||||
$rsOrderBasket = CSaleBasket::GetList(array('PRODUCT_ID' => 'ASC'), array('ORDER_ID' => $arFields['ID']));
|
||||
while ($p = $rsOrderBasket->Fetch()) {
|
||||
$pr = CCatalogProduct::GetList(array('ID' => $p['PRODUCT_ID']))->Fetch();
|
||||
if ($pr)
|
||||
$pr = $pr['PURCHASING_PRICE'];
|
||||
else
|
||||
$pr = '';
|
||||
|
||||
if($p['DISCOUNT_VALUE'])
|
||||
$p['DISCOUNT_PRICE'] = null;
|
||||
|
||||
$items[] = array(
|
||||
'initialPrice' => (double) $p['PRICE'] + (double) $p['DISCOUNT_PRICE'],
|
||||
'purchasePrice' => $pr,
|
||||
'discount' => $p['DISCOUNT_PRICE'],
|
||||
'discountPercent' => $p['DISCOUNT_VALUE'],
|
||||
'quantity' => $p['QUANTITY'],
|
||||
'productId' => $p['PRODUCT_ID'],
|
||||
'productName' => self::toJSON($p['NAME'])
|
||||
);
|
||||
}
|
||||
|
||||
if($arFields['CANCELED'] == 'Y')
|
||||
$arFields['STATUS_ID'] = $arFields['CANCELED'];
|
||||
|
||||
$createdAt = new \DateTime($arFields['DATE_INSERT']);
|
||||
$createdAt = $createdAt->format('Y-m-d H:i:s');
|
||||
|
||||
$resOrder = self::clearArr(array(
|
||||
'lastName' => $resOrder['contactName'][0],
|
||||
'firstName' => $resOrder['contactName'][1],
|
||||
'patronymic' => $resOrder['contactName'][2],
|
||||
'phone' => $resOrder['phone'],
|
||||
'email' => $resOrder['email'],
|
||||
'deliveryCost' => $arFields['PRICE_DELIVERY'],
|
||||
'summ' => $arFields['PRICE'],
|
||||
'markDateTime' => $arFields['DATE_MARKED'],
|
||||
'externalId' => $arFields['ID'],
|
||||
'customerId' => $arFields['USER_ID'],
|
||||
'paymentType' => $arParams['optionsPayTypes'][$arFields['PAY_SYSTEM_ID']],
|
||||
'paymentStatus' => $arParams['optionsPayment'][$arFields['PAYED']],
|
||||
'orderType' => $arParams['optionsOrderTypes'][$arFields['PERSON_TYPE_ID']],
|
||||
'deliveryType' => $arParams['optionsDelivTypes'][$resultDeliveryTypeId],
|
||||
'status' => $arParams['optionsPayStatuses'][$arFields['STATUS_ID']],
|
||||
'statusComment' => $arFields['REASON_CANCELED'],
|
||||
'createdAt' => $createdAt,
|
||||
'deliveryAddress' => $resOrderDeliveryAddress,
|
||||
'items' => $items
|
||||
));
|
||||
|
||||
if($send)
|
||||
return $api->createOrder($resOrder);
|
||||
|
||||
return $resOrder;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* removes all empty fields from arrays
|
||||
* working with nested arrs
|
||||
*
|
||||
* @param type $arr
|
||||
* @return boolean
|
||||
*/
|
||||
public static function clearArr($arr) {
|
||||
if(!$arr || !is_array($arr))
|
||||
return false;
|
||||
|
||||
foreach($arr as $key => $value) {
|
||||
if(!$value || (is_array($value) && empty($value)))
|
||||
unset($arr[$key]);
|
||||
|
||||
if(is_array($value) && !empty($value))
|
||||
$arr[$key] = self::clearArr($value);
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @global type $APPLICATION
|
||||
* @param type $str in SITE_CHARSET
|
||||
* @return type $str in utf-8
|
||||
*/
|
||||
protected static function toJSON($str) {
|
||||
global $APPLICATION;
|
||||
|
||||
return $APPLICATION->ConvertCharset($str, SITE_CHARSET, 'utf-8');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @global type $APPLICATION
|
||||
* @param type $str in utf-8
|
||||
* @return type $str in SITE_CHARSET
|
||||
*/
|
||||
public static function fromJSON($str) {
|
||||
global $APPLICATION;
|
||||
|
||||
return $APPLICATION->ConvertCharset($str, 'utf-8', SITE_CHARSET);
|
||||
}
|
||||
}
|
|
@ -1,501 +0,0 @@
|
|||
<?php
|
||||
namespace IntaroCrm;
|
||||
|
||||
class RestApi
|
||||
{
|
||||
protected $apiUrl;
|
||||
protected $apiKey;
|
||||
protected $apiVersion = '1';
|
||||
|
||||
protected $response;
|
||||
protected $statusCode;
|
||||
protected $parameters;
|
||||
|
||||
/**
|
||||
* @param string $crmUrl - адрес CRM
|
||||
* @param string $apiKey - ключ для работы с api
|
||||
*/
|
||||
public function __construct($crmUrl, $apiKey)
|
||||
{
|
||||
$this->apiUrl = $crmUrl.'/api/v'.$this->apiVersion.'/';
|
||||
$this->apiKey = $apiKey;
|
||||
$this->parameters = array('apiKey' => $this->apiKey);
|
||||
}
|
||||
|
||||
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/* Получение кода статуса и сообщения об ошибке */
|
||||
public function getLastError()
|
||||
{
|
||||
if (isset($this->response['errorMsg']) && isset($this->response['errors']))
|
||||
{
|
||||
$result = $this->statusCode . ' ' . $this->response['errorMsg'];
|
||||
foreach ($this->response['errors'] as $error)
|
||||
$result .= ' ' . $error;
|
||||
}
|
||||
elseif (isset($this->response['errorMsg']))
|
||||
$result = $this->statusCode . ' ' . $this->response['errorMsg'];
|
||||
else
|
||||
$result = null;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* Псообщения об ошибке */
|
||||
public function getLastErrorMessage()
|
||||
{
|
||||
return $this->response['errorMsg'];
|
||||
}
|
||||
|
||||
|
||||
/* Методы для работы с заказами */
|
||||
/**
|
||||
* Получение заказа по id
|
||||
*
|
||||
* @param string $id - идентификатор заказа
|
||||
* @param string $by - поиск заказа по id или externalId
|
||||
* @return array - информация о заказе
|
||||
*/
|
||||
public function orderGet($id, $by = 'externalId')
|
||||
{
|
||||
$url = $this->apiUrl.'orders/'.$id;
|
||||
|
||||
if ($by != 'externalId')
|
||||
$this->parameters['by'] = $by;
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание заказа
|
||||
*
|
||||
* @param array $order- информация о заказе
|
||||
* @return array
|
||||
*/
|
||||
public function orderCreate($order)
|
||||
{
|
||||
$dataJson = json_encode($order);
|
||||
$this->parameters['order'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'orders/create';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Изменение заказа
|
||||
*
|
||||
* @param array $order- информация о заказе
|
||||
* @return array
|
||||
*/
|
||||
public function orderEdit($order)
|
||||
{
|
||||
$dataJson = json_encode($order);
|
||||
$this->parameters['order'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'orders/'.$order['externalId'].'/edit';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Пакетная загрузка заказов
|
||||
*
|
||||
* @param array $orders - массив заказов
|
||||
* @return array
|
||||
*/
|
||||
public function orderUpload($orders)
|
||||
{
|
||||
$dataJson = json_encode($orders);
|
||||
$this->parameters['orders'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'orders/upload';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
if (is_null($result) && isset($result['uploadedOrders']))
|
||||
return $result['uploadedOrders'];
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление externalId у заказов с переданными id
|
||||
*
|
||||
* @param array $orders- массив, содержащий id и externalId заказа
|
||||
* @return array
|
||||
*/
|
||||
public function orderFixExternalIds($order)
|
||||
{
|
||||
$dataJson = json_encode($order);
|
||||
$this->parameters['orders'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'orders/fix-external-ids';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление заказа
|
||||
*
|
||||
* @param string $id - идентификатор заказа
|
||||
* @param string $by - поиск заказа по id или externalId
|
||||
* @return array
|
||||
*/
|
||||
/*
|
||||
public function orderDelete($id, $by = 'externalId')
|
||||
{
|
||||
$url = $this->apiUrl.'orders/'.$id.'/delete';
|
||||
if ($by != 'externalId')
|
||||
$this->parameters['by'] = $by;
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Получение последних измененных заказов
|
||||
*
|
||||
* @param DateTime $startDate - начальная дата выборки
|
||||
* @param DateTime $endDate - конечная дата
|
||||
* @param int $limit - ограничение на размер выборки
|
||||
* @param int $offset - сдвиг
|
||||
* @return array - массив заказов
|
||||
*/
|
||||
public function orderHistory($startDate = null, $endDate = null, $limit = 100, $offset = 0)
|
||||
{
|
||||
$url = $this->apiUrl.'orders/history';
|
||||
$this->parameters['startDate'] = $startDate;
|
||||
$this->parameters['endDate'] = $endDate;
|
||||
$this->parameters['limit'] = $limit;
|
||||
$this->parameters['offset'] = $offset;
|
||||
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/* Методы для работы с клиентами */
|
||||
/**
|
||||
* Получение клиента по id
|
||||
*
|
||||
* @param string $id - идентификатор
|
||||
* @param string $by - поиск заказа по id или externalId
|
||||
* @return array - информация о клиенте
|
||||
*/
|
||||
public function customerGet($id, $by = 'externalId')
|
||||
{
|
||||
$url = $this->apiUrl.'customers/'.$id;
|
||||
if ($by != 'externalId')
|
||||
$this->parameters['by'] = $by;
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание клиента
|
||||
*
|
||||
* @param array $customer - информация о клиенте
|
||||
* @return array
|
||||
*/
|
||||
public function customerCreate($customer)
|
||||
{
|
||||
$dataJson = json_encode($customer);
|
||||
$this->parameters['customer'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'customers/create';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Редактирование клиента
|
||||
*
|
||||
* @param array $customer - информация о клиенте
|
||||
* @return array
|
||||
*/
|
||||
public function customerEdit($customer)
|
||||
{
|
||||
$dataJson = json_encode($customer);
|
||||
$this->parameters['customer'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'customers/'.$customer['externalId'].'/edit';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Пакетная загрузка клиентов
|
||||
*
|
||||
* @param array $customers - массив клиентов
|
||||
* @return array
|
||||
*/
|
||||
public function customerUpload($customers)
|
||||
{
|
||||
$dataJson = json_encode($customers);
|
||||
$dataJson = str_replace(self::$jsonReplaceSource, self::$jsonReplaceTarget,
|
||||
$dataJson);
|
||||
$this->parameters['customers'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'customers/upload';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
if (is_null($result) && isset($result['uploaded']))
|
||||
return $result['uploaded'];
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление клиента
|
||||
*
|
||||
* @param string $id - идентификатор
|
||||
* @param string $by - поиск заказа по id или externalId
|
||||
* @return array
|
||||
*/
|
||||
/*
|
||||
public function customerDelete($id, $by = 'externalId')
|
||||
{
|
||||
$url = $this->apiUrl.'customers/'.$id.'/delete';
|
||||
if ($by != 'externalId')
|
||||
$this->parameters['by'] = $by;
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Получение списка заказов клиента
|
||||
*
|
||||
* @param string $id - идентификатор клиента
|
||||
* @param string $by - поиск заказа по id или externalId
|
||||
* @param DateTime $startDate - начальная дата выборки
|
||||
* @param DateTime $endDate - конечная дата
|
||||
* @param int $limit - ограничение на размер выборки
|
||||
* @param int $offset - сдвиг
|
||||
* @return array - массив заказов
|
||||
*/
|
||||
public function customerOrdersList($id, $startDate = null, $endDate = null,
|
||||
$limit = 100, $offset = 0, $by = 'externalId')
|
||||
{
|
||||
$url = $this->apiUrl.'customers/'.$id.'/orders';
|
||||
if ($by != 'externalId')
|
||||
$this->parameters['by'] = $by;
|
||||
$this->parameters['startDate'] = $startDate;
|
||||
$this->parameters['endDate'] = $endDate;
|
||||
$this->parameters['limit'] = $limit;
|
||||
$this->parameters['offset'] = $offset;
|
||||
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* Методы для работы со справочниками */
|
||||
/**
|
||||
* Получение списка типов доставки
|
||||
*
|
||||
* @return array - массив типов доставки
|
||||
*/
|
||||
public function deliveryTypesList()
|
||||
{
|
||||
$url = $this->apiUrl.'reference/delivery-types';
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Редактирование типа доставки
|
||||
*
|
||||
* @param array $deliveryType - информация о типе доставки
|
||||
* @return array
|
||||
*/
|
||||
public function deliveryTypeEdit($deliveryType)
|
||||
{
|
||||
$dataJson = json_encode($deliveryType);
|
||||
$this->parameters['deliveryType'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'delivery-types/'.$deliveryType['code'].'/edit';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Получение списка типов оплаты
|
||||
*
|
||||
* @return array - массив типов оплаты
|
||||
*/
|
||||
public function paymentTypesList()
|
||||
{
|
||||
$url = $this->apiUrl.'reference/payment-types';
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Редактирование типа оплаты
|
||||
*
|
||||
* @param array $paymentType - информация о типе оплаты
|
||||
* @return array
|
||||
*/
|
||||
public function paymentTypesEdit($paymentType)
|
||||
{
|
||||
$dataJson = json_encode($paymentType);
|
||||
$this->parameters['paymentType'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'payment-types/'.$paymentType['code'].'/edit';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Получение списка статусов оплаты
|
||||
*
|
||||
* @return array - массив статусов оплаты
|
||||
*/
|
||||
public function paymentStatusesList()
|
||||
{
|
||||
$url = $this->apiUrl.'reference/payment-statuses';
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Редактирование статуса оплаты
|
||||
*
|
||||
* @param array $paymentStatus - информация о статусе оплаты
|
||||
* @return array
|
||||
*/
|
||||
public function paymentStatusesEdit($paymentStatus)
|
||||
{
|
||||
$dataJson = json_encode($paymentStatus);
|
||||
$this->parameters['paymentStatus'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'payment-statuses/'.$paymentStatus['code'].'/edit';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Получение списка типов заказа
|
||||
*
|
||||
* @return array - массив типов заказа
|
||||
*/
|
||||
public function orderTypesList()
|
||||
{
|
||||
$url = $this->apiUrl.'reference/order-types';
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Редактирование типа заказа
|
||||
*
|
||||
* @param array $orderType - информация о типе заказа
|
||||
* @return array
|
||||
*/
|
||||
public function orderTypesEdit($orderType)
|
||||
{
|
||||
$dataJson = json_encode($orderType);
|
||||
$this->parameters['orderType'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'order-types/'.$orderType['code'].'/edit';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение списка статусов заказа
|
||||
*
|
||||
* @return array - массив статусов заказа
|
||||
*/
|
||||
public function orderStatusesList()
|
||||
{
|
||||
$url = $this->apiUrl.'reference/statuses';
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Редактирование статуса заказа
|
||||
*
|
||||
* @param array $status - информация о статусе заказа
|
||||
* @return array
|
||||
*/
|
||||
public function orderStatusEdit($status)
|
||||
{
|
||||
$dataJson = json_encode($status);
|
||||
$this->parameters['status'] = $dataJson;
|
||||
|
||||
$url = $this->apiUrl.'statuses/'.$status['code'].'/edit';
|
||||
$result = $this->curlRequest($url, 'POST');
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Получение списка групп статусов заказа
|
||||
*
|
||||
* @return array - массив групп статусов заказа
|
||||
*/
|
||||
public function orderStatusGroupsList()
|
||||
{
|
||||
$url = $this->apiUrl.'reference/status-groups';
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление статистики
|
||||
*
|
||||
* @return array - статус вып обновления
|
||||
*/
|
||||
public function statisticUpdate()
|
||||
{
|
||||
$url = $this->apiUrl.'statistic/update';
|
||||
$result = $this->curlRequest($url);
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function curlRequest($url, $method = 'GET', $format = 'json')
|
||||
{
|
||||
if ($method == 'GET' && !is_null($this->parameters))
|
||||
$url .= '?'.http_build_query($this->parameters);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, FALSE);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// allow redirects
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return into a variable
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // times out after 30s
|
||||
|
||||
if ($method == 'POST')
|
||||
{
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->parameters);
|
||||
}
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$this->statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
unset($this->parameters);
|
||||
/* Сброс массива с параметрами */
|
||||
$this->parameters = array('apiKey' => $this->apiKey);
|
||||
|
||||
if (curl_errno($ch))
|
||||
{
|
||||
$this->response = array('errorMsg' => 'Curl error: ' . curl_error($ch));
|
||||
return null;
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$result = (array)json_decode($response, true);
|
||||
$this->response = $result;
|
||||
if ($result['success'] == false)
|
||||
return null;
|
||||
|
||||
unset($result['success']);
|
||||
if (count($result) == 0)
|
||||
return true;
|
||||
return reset($result);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
CModule::AddAutoloadClasses(
|
||||
'intaro.intarocrm', // module name
|
||||
array (
|
||||
'IntaroCrm\RestApi' => 'classes/general/RestApi.php',
|
||||
'ICrmOrderActions' => 'classes/general/ICrmOrderActions.php',
|
||||
'ICrmOrderEvent' => 'classes/general/events/ICrmOrderEvent.php'
|
||||
)
|
||||
);
|
File diff suppressed because it is too large
Load diff
|
@ -1,173 +0,0 @@
|
|||
<?
|
||||
//<title>IntaroCRM</title>
|
||||
__IncludeLang(GetLangFileName($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/intaro.intarocrm/lang/", "/export_setup_templ.php"));
|
||||
|
||||
global $APPLICATION;
|
||||
|
||||
$arSetupErrors = array();
|
||||
if (($ACTION == 'EXPORT_EDIT' || $ACTION == 'EXPORT_COPY') && $STEP == 1)
|
||||
{
|
||||
if (isset($arOldSetupVars['YANDEX_EXPORT']))
|
||||
$YANDEX_EXPORT = $arOldSetupVars['YANDEX_EXPORT'];
|
||||
if (isset($arOldSetupVars['SETUP_FILE_NAME']))
|
||||
$SETUP_FILE_NAME = $arOldSetupVars['SETUP_FILE_NAME'];
|
||||
if (isset($arOldSetupVars['SETUP_PROFILE_NAME']))
|
||||
$SETUP_PROFILE_NAME = $arOldSetupVars['SETUP_PROFILE_NAME'];
|
||||
if (isset($arOldSetupVars['SETUP_SERVER_NAME']))
|
||||
$SETUP_SERVER_NAME = $arOldSetupVars['SETUP_SERVER_NAME'];
|
||||
}
|
||||
|
||||
if ($STEP>1)
|
||||
{
|
||||
if (!is_array($YANDEX_EXPORT) || count($YANDEX_EXPORT)<=0)
|
||||
{
|
||||
$arSetupErrors[] = GetMessage("CET_ERROR_NO_IBLOCKS");
|
||||
}
|
||||
|
||||
if (strlen($SETUP_FILE_NAME)<=0)
|
||||
{
|
||||
$arSetupErrors[] = GetMessage("CET_ERROR_NO_FILENAME");
|
||||
}
|
||||
elseif (preg_match(BX_CATALOG_FILENAME_REG,$SETUP_FILE_NAME))
|
||||
{
|
||||
$arSetupErrors[] = GetMessage("CES_ERROR_BAD_EXPORT_FILENAME");
|
||||
}
|
||||
elseif ($APPLICATION->GetFileAccessPermission($SETUP_FILE_NAME) < "W")
|
||||
{
|
||||
$arSetupErrors[] = str_replace("#FILE#", $SETUP_FILE_NAME, GetMessage('CET_YAND_RUN_ERR_SETUP_FILE_ACCESS_DENIED'));
|
||||
}
|
||||
|
||||
if (($ACTION=="EXPORT_SETUP" || $ACTION == 'EXPORT_EDIT' || $ACTION == 'EXPORT_COPY') && strlen($SETUP_PROFILE_NAME)<=0)
|
||||
{
|
||||
$arSetupErrors[] = GetMessage("CET_ERROR_NO_PROFILE_NAME");
|
||||
}
|
||||
|
||||
if (!empty($arSetupErrors))
|
||||
{
|
||||
$STEP = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($arSetupErrors))
|
||||
echo ShowError(implode('<br />', $arSetupErrors));
|
||||
|
||||
if ($STEP==1)
|
||||
{
|
||||
if (CModule::IncludeModule("iblock"))
|
||||
{
|
||||
// Get IBlock list
|
||||
?>
|
||||
<form method="POST" action="<? echo $APPLICATION->GetCurPage(); ?>" enctype="multipart/form-data" name="dataload">
|
||||
<? echo bitrix_sessid_post(); ?>
|
||||
<?if ($ACTION == 'EXPORT_EDIT' || $ACTION == 'EXPORT_COPY')
|
||||
{
|
||||
?><input type="hidden" name="PROFILE_ID" value="<? echo intval($PROFILE_ID); ?>"><?
|
||||
}
|
||||
?>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td valign="top">
|
||||
<?
|
||||
if (!isset($YANDEX_EXPORT) || !is_array($YANDEX_EXPORT))
|
||||
{
|
||||
$YANDEX_EXPORT = array();
|
||||
}
|
||||
$boolAll = false;
|
||||
$intCountChecked = 0;
|
||||
$intCountAvailIBlock = 0;
|
||||
$arIBlockList = array();
|
||||
$db_res = CIBlock::GetList(Array("IBLOCK_TYPE"=>"ASC", "NAME"=>"ASC"),array('CHECK_PERMISSIONS' => 'Y','MIN_PERMISSION' => 'W'));
|
||||
while ($res = $db_res->Fetch())
|
||||
{
|
||||
if ($ar_res1 = CCatalog::GetByID($res["ID"]))
|
||||
{
|
||||
$arSiteList = array();
|
||||
$rsSites = CIBlock::GetSite($res["ID"]);
|
||||
while ($arSite = $rsSites->Fetch())
|
||||
{
|
||||
$arSiteList[] = $arSite["SITE_ID"];
|
||||
}
|
||||
|
||||
$boolYandex = (in_array($res['ID'],$YANDEX_EXPORT));
|
||||
$arIBlockList[] = array(
|
||||
'ID' => $res['ID'],
|
||||
'NAME' => $res['NAME'],
|
||||
'IBLOCK_TYPE_ID' => $res['IBLOCK_TYPE_ID'],
|
||||
'YANDEX_EXPORT' => $boolYandex,
|
||||
'SITE_LIST' => '('.implode(' ',$arSiteList).')',
|
||||
);
|
||||
if ($boolYandex)
|
||||
$intCountChecked++;
|
||||
$intCountAvailIBlock++;
|
||||
}
|
||||
}
|
||||
if ($intCountChecked == $intCountAvailIBlock)
|
||||
$boolAll = true;
|
||||
?>
|
||||
|
||||
<?
|
||||
foreach ($arIBlockList as $key => $arIBlock)
|
||||
{
|
||||
?>
|
||||
<input type="hidden" name="YANDEX_EXPORT[<? echo $key; ?>]" id="YANDEX_EXPORT_<? echo $key; ?>" value="<? echo $arIBlock["ID"]; ?>" checked>
|
||||
<?
|
||||
}
|
||||
?>
|
||||
<input type="hidden" name="count_checked" id="count_checked" value="<? echo $intCountChecked; ?>">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
<td width="0%" valign="top"></td>
|
||||
<td width="100%" valign="top">
|
||||
<font class="text">
|
||||
<?echo GetMessage("CET_SAVE_FILENAME");?> <input type="text" name="SETUP_FILE_NAME" value="<?echo htmlspecialcharsbx(strlen($SETUP_FILE_NAME)>0 ? $SETUP_FILE_NAME : (COption::GetOptionString("catalog", "export_default_path", "/bitrix/catalog_export/"))."intarocrm"/* .mt_rand(0, 999999) */.".php"); ?>" size="50">
|
||||
</font>
|
||||
<br><br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?if ($ACTION=="EXPORT_SETUP" || $ACTION == 'EXPORT_EDIT' || $ACTION == 'EXPORT_COPY'):?>
|
||||
<tr>
|
||||
<td width="0%" valign="top">
|
||||
<font class="text" style="font-size: 20px;">4. </font>
|
||||
</td>
|
||||
<td width="100%" valign="top">
|
||||
<font class="text">
|
||||
<?echo GetMessage("CET_PROFILE_NAME");?> <input type="text" name="SETUP_PROFILE_NAME" value="<?echo htmlspecialcharsbx($SETUP_PROFILE_NAME)?>" size="30">
|
||||
</font>
|
||||
<br><br>
|
||||
</td>
|
||||
</tr>
|
||||
<?endif;?>
|
||||
|
||||
<tr>
|
||||
<td width="0%" valign="top">
|
||||
|
||||
</td>
|
||||
<td width="100%" valign="top">
|
||||
<input type="hidden" name="lang" value="<?echo LANGUAGE_ID ?>">
|
||||
<input type="hidden" name="ACT_FILE" value="<?echo htmlspecialchars($_REQUEST["ACT_FILE"]) ?>">
|
||||
<input type="hidden" name="ACTION" value="<?echo htmlspecialchars($ACTION) ?>">
|
||||
<input type="hidden" name="STEP" value="<?echo intval($STEP) + 1 ?>">
|
||||
<input type="hidden" name="SETUP_FIELDS_LIST" value="YANDEX_EXPORT,SETUP_SERVER_NAME,SETUP_FILE_NAME">
|
||||
<input type="submit" value="<?echo ($ACTION=="EXPORT")?GetMessage("CET_EXPORT"):GetMessage("CET_SAVE")?>">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<?
|
||||
}
|
||||
}
|
||||
elseif ($STEP==2)
|
||||
{
|
||||
$SETUP_SERVER_NAME = htmlspecialcharsbx($SETUP_SERVER_NAME);
|
||||
$_POST['SETUP_SERVER_NAME'] = htmlspecialcharsbx($_POST['SETUP_SERVER_NAME']);
|
||||
$_REQUEST['SETUP_SERVER_NAME'] = htmlspecialcharsbx($_REQUEST['SETUP_SERVER_NAME']);
|
||||
|
||||
$FINITE = true;
|
||||
}
|
||||
?>
|
|
@ -1,443 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Module Install/Uninstall script
|
||||
* Module name: intaro.intarocrm
|
||||
* Class name: intaro_intarocrm
|
||||
*/
|
||||
|
||||
global $MESS;
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
if (class_exists('intaro_intarocrm'))
|
||||
return;
|
||||
|
||||
class intaro_intarocrm extends CModule
|
||||
{
|
||||
var $MODULE_ID = 'intaro.intarocrm';
|
||||
var $MODULE_VERSION;
|
||||
var $MODULE_VERSION_DATE;
|
||||
var $MODULE_NAME;
|
||||
var $MODULE_DESCRIPTION;
|
||||
var $MODULE_GROUP_RIGHTS = 'N';
|
||||
var $PARTNER_NAME;
|
||||
var $PARTNER_URI;
|
||||
var $INTARO_CRM_API;
|
||||
|
||||
var $CRM_API_HOST_OPTION = 'api_host';
|
||||
var $CRM_API_KEY_OPTION = 'api_key';
|
||||
var $CRM_ORDER_TYPES_ARR = 'order_types_arr';
|
||||
var $CRM_DELIVERY_TYPES_ARR = 'deliv_types_arr';
|
||||
var $CRM_PAYMENT_TYPES = 'pay_types_arr';
|
||||
var $CRM_PAYMENT_STATUSES = 'pay_statuses_arr';
|
||||
var $CRM_PAYMENT = 'payment_arr'; //order payment Y/N
|
||||
var $CRM_ORDER_LAST_ID = 'order_last_id';
|
||||
|
||||
|
||||
var $INSTALL_PATH;
|
||||
|
||||
function intaro_intarocrm()
|
||||
{
|
||||
$arModuleVersion = array();
|
||||
$path = str_replace("\\", "/", __FILE__);
|
||||
$path = substr($path, 0, strlen($path) - strlen("/index.php"));
|
||||
$this->INSTALL_PATH = $path;
|
||||
include($path."/version.php");
|
||||
$this->MODULE_VERSION = $arModuleVersion["VERSION"];
|
||||
$this->MODULE_VERSION_DATE = $arModuleVersion["VERSION_DATE"];
|
||||
$this->MODULE_NAME = GetMessage('MODULE_NAME');
|
||||
$this->MODULE_DESCRIPTION = GetMessage('MODULE_DESCRIPTION');
|
||||
$this->PARTNER_NAME = GetMessage('MODULE_PARTNER_NAME');
|
||||
$this->PARTNER_URI = GetMessage('MODULE_PARTNER_URI');
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions DoInstall and DoUninstall are
|
||||
* All other functions are optional
|
||||
*/
|
||||
|
||||
function DoInstall()
|
||||
{
|
||||
global $APPLICATION, $step, $arResult;
|
||||
|
||||
if (!in_array('curl', get_loaded_extensions())) {
|
||||
$APPLICATION->ThrowException( GetMessage("INTAROCRM_CURL_ERR") );
|
||||
return false;
|
||||
}
|
||||
|
||||
include($this->INSTALL_PATH . '/../classes/general/RestApi.php');
|
||||
include($this->INSTALL_PATH . '/../classes/general/ICrmOrderActions.php');
|
||||
|
||||
$step = intval($_REQUEST['step']);
|
||||
|
||||
if ($step <= 1) {
|
||||
if(!CModule::IncludeModule("sale")) {
|
||||
$arResult['errCode'] = 'ERR_SALE';
|
||||
}
|
||||
|
||||
if(!CModule::IncludeModule("iblock")) {
|
||||
$arResult['errCode'] = 'ERR_IBLOCK';
|
||||
}
|
||||
|
||||
if(!CModule::IncludeModule("catalog")) {
|
||||
$arResult['errCode'] = 'ERR_CATALOG';
|
||||
}
|
||||
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_INSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php'
|
||||
);
|
||||
} else if ($step == 2) {
|
||||
if(!CModule::IncludeModule("sale")) {
|
||||
$arResult['errCode'] = 'ERR_SALE';
|
||||
}
|
||||
|
||||
if(!CModule::IncludeModule("iblock")) {
|
||||
$arResult['errCode'] = 'ERR_IBLOCK';
|
||||
}
|
||||
|
||||
if(!CModule::IncludeModule("catalog")) {
|
||||
$arResult['errCode'] = 'ERR_CATALOG';
|
||||
}
|
||||
|
||||
if(isset($arResult['errCode']) && $arResult['errCode']) {
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_INSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$api_host = htmlspecialchars(trim($_POST[$this->CRM_API_HOST_OPTION]));
|
||||
$api_key = htmlspecialchars(trim($_POST[$this->CRM_API_KEY_OPTION]));
|
||||
|
||||
// form correct url
|
||||
$api_host = parse_url($api_host);
|
||||
$api_host = $api_host['scheme'] . '://' . $api_host['host'];
|
||||
|
||||
if(!$api_host || !$api_key) {
|
||||
$arResult['errCode'] = 'ERR_FIELDS_API_HOST';
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_INSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->INTARO_CRM_API = new \IntaroCrm\RestApi($api_host, $api_key);
|
||||
|
||||
$this->INTARO_CRM_API->paymentStatusesList();
|
||||
|
||||
//check connection & apiKey valid
|
||||
if((int) $this->INTARO_CRM_API->getStatusCode() != 200) {
|
||||
$arResult['errCode'] = 'ERR_' . $this->INTARO_CRM_API->getStatusCode();
|
||||
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_INSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
COption::SetOptionString($this->MODULE_ID, $this->CRM_API_HOST_OPTION, $api_host);
|
||||
COption::SetOptionString($this->MODULE_ID, $this->CRM_API_KEY_OPTION, $api_key);
|
||||
|
||||
//prepare crm lists
|
||||
$arResult['orderTypesList'] = $this->INTARO_CRM_API->orderTypesList();
|
||||
$arResult['deliveryTypesList'] = $this->INTARO_CRM_API->deliveryTypesList();
|
||||
$arResult['paymentTypesList'] = $this->INTARO_CRM_API->paymentTypesList();
|
||||
$arResult['paymentStatusesList'] = $this->INTARO_CRM_API->paymentStatusesList(); // --statuses
|
||||
$arResult['paymentList'] = $this->INTARO_CRM_API->orderStatusesList();
|
||||
$arResult['paymentGroupList'] = $this->INTARO_CRM_API->orderStatusGroupsList(); // -- statuses groups
|
||||
|
||||
//bitrix orderTypesList -- personTypes
|
||||
$dbOrderTypesList = CSalePersonType::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y",
|
||||
),
|
||||
false,
|
||||
false,
|
||||
array()
|
||||
);
|
||||
|
||||
if ($arOrderTypesList = $dbOrderTypesList->Fetch()) {
|
||||
do {
|
||||
$arResult['bitrixOrderTypesList'][] = $arOrderTypesList;
|
||||
} while ($arOrderTypesList = $dbOrderTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix deliveryTypesList
|
||||
$dbDeliveryTypesList = CSaleDelivery::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y",
|
||||
),
|
||||
false,
|
||||
false,
|
||||
array()
|
||||
);
|
||||
|
||||
if ($arDeliveryTypesList = $dbDeliveryTypesList->Fetch()) {
|
||||
do {
|
||||
$arResult['bitrixDeliveryTypesList'][] = $arDeliveryTypesList;
|
||||
} while ($arDeliveryTypesList = $dbDeliveryTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix paymentTypesList
|
||||
$dbPaymentTypesList = CSalePaySystem::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y"
|
||||
)
|
||||
);
|
||||
|
||||
if ($arPaymentTypesList = $dbPaymentTypesList->Fetch()) {
|
||||
do {
|
||||
$arResult['bitrixPaymentTypesList'][] = $arPaymentTypesList;
|
||||
} while ($arPaymentTypesList = $dbPaymentTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix paymentStatusesList --statuses
|
||||
$dbPaymentStatusesList = CSaleStatus::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"LID" => "ru", //ru
|
||||
"ACTIVE" => "Y"
|
||||
)
|
||||
);
|
||||
|
||||
if ($arPaymentStatusesList = $dbPaymentStatusesList->Fetch()) {
|
||||
do {
|
||||
$arResult['bitrixPaymentStatusesList'][] = $arPaymentStatusesList;
|
||||
} while ($arPaymentStatusesList = $dbPaymentStatusesList->Fetch());
|
||||
}
|
||||
|
||||
$arResult['bitrixPaymentStatusesList'][] = array(
|
||||
'ID' => 'Y',
|
||||
'NAME' => GetMessage('CANCELED')
|
||||
);
|
||||
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_INSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step2.php'
|
||||
);
|
||||
|
||||
} else if ($step == 3) {
|
||||
if(!CModule::IncludeModule("sale")) {
|
||||
//handler
|
||||
}
|
||||
|
||||
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
|
||||
&& isset($_POST['ajax']) && ($_POST['ajax'] == 1)) {
|
||||
ICrmOrderActions::uploadOrders(true); // each 50
|
||||
|
||||
$lastUpOrderId = COption::GetOptionString($this->MODULE_ID, $this->CRM_ORDER_LAST_ID, 0);
|
||||
$countLeft = (int) CSaleOrder::GetList(array("ID" => "ASC"), array('>ID' => $lastUpOrderId), array());
|
||||
$countAll = (int) CSaleOrder::GetList(array("ID" => "ASC"), array(), array());
|
||||
|
||||
if(!isset($_POST['finish']))
|
||||
$finish = 0;
|
||||
else
|
||||
$finish = (int) $_POST['finish'];
|
||||
|
||||
$percent = 100 - round(($countLeft * 100 / $countAll), 1);
|
||||
|
||||
if(!$countLeft) {
|
||||
$api_host = COption::GetOptionString($mid, $this->CRM_API_HOST_OPTION, 0);
|
||||
$api_key = COption::GetOptionString($mid, $this->CRM_API_KEY_OPTION, 0);
|
||||
$this->INTARO_CRM_API = new \IntaroCrm\RestApi($api_host, $api_key);
|
||||
$this->INTARO_CRM_API->statisticUpdate();
|
||||
$finish = 1;
|
||||
}
|
||||
|
||||
|
||||
$APPLICATION->RestartBuffer();
|
||||
header('Content-Type: application/x-javascript; charset='.LANG_CHARSET);
|
||||
die(json_encode(array("finish" => $finish, "percent" => $percent)));
|
||||
}
|
||||
|
||||
if (isset($_POST['back']) && $_POST['back']) {
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_INSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php'
|
||||
);
|
||||
}
|
||||
|
||||
//bitrix orderTypesList -- personTypes
|
||||
$dbOrderTypesList = CSalePersonType::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y",
|
||||
),
|
||||
false,
|
||||
false,
|
||||
array()
|
||||
);
|
||||
|
||||
//form order types ids arr
|
||||
$orderTypesArr = array();
|
||||
if ($arOrderTypesList = $dbOrderTypesList->Fetch()) {
|
||||
do {
|
||||
$orderTypesArr[$arOrderTypesList['ID']] = htmlspecialchars(trim($_POST['order-type-' . $arOrderTypesList['ID']]));
|
||||
} while ($arOrderTypesList = $dbOrderTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix deliveryTypesList
|
||||
$dbDeliveryTypesList = CSaleDelivery::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y",
|
||||
),
|
||||
false,
|
||||
false,
|
||||
array()
|
||||
);
|
||||
|
||||
//form delivery types ids arr
|
||||
$deliveryTypesArr = array();
|
||||
if ($arDeliveryTypesList = $dbDeliveryTypesList->Fetch()) {
|
||||
do {
|
||||
$deliveryTypesArr[$arDeliveryTypesList['ID']] = htmlspecialchars(trim($_POST['delivery-type-' . $arDeliveryTypesList['ID']]));
|
||||
} while ($arDeliveryTypesList = $dbDeliveryTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix paymentTypesList
|
||||
$dbPaymentTypesList = CSalePaySystem::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y"
|
||||
)
|
||||
);
|
||||
|
||||
//form payment types ids arr
|
||||
$paymentTypesArr = array();
|
||||
if ($arPaymentTypesList = $dbPaymentTypesList->Fetch()) {
|
||||
do {
|
||||
$paymentTypesArr[$arPaymentTypesList['ID']] = htmlspecialchars(trim($_POST['payment-type-' . $arPaymentTypesList['ID']]));
|
||||
} while ($arPaymentTypesList = $dbPaymentTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix paymentStatusesList
|
||||
$dbPaymentStatusesList = CSaleStatus::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"LID" => "ru", //ru
|
||||
"ACTIVE" => "Y"
|
||||
)
|
||||
);
|
||||
|
||||
//form payment statuses ids arr
|
||||
$paymentStatusesArr['Y'] = htmlspecialchars(trim($_POST['payment-status-Y']));
|
||||
|
||||
if ($arPaymentStatusesList = $dbPaymentStatusesList->Fetch()) {
|
||||
do {
|
||||
$paymentStatusesArr[$arPaymentStatusesList['ID']] = htmlspecialchars(trim($_POST['payment-status-' . $arPaymentStatusesList['ID']]));
|
||||
} while ($arPaymentStatusesList = $dbPaymentStatusesList->Fetch());
|
||||
}
|
||||
|
||||
//form payment ids arr
|
||||
$paymentArr = array();
|
||||
$paymentArr['Y'] = htmlspecialchars(trim($_POST['payment-Y']));
|
||||
$paymentArr['N'] = htmlspecialchars(trim($_POST['payment-N']));
|
||||
|
||||
COption::SetOptionString($this->MODULE_ID, $this->CRM_ORDER_TYPES_ARR, serialize($orderTypesArr));
|
||||
COption::SetOptionString($this->MODULE_ID, $this->CRM_DELIVERY_TYPES_ARR, serialize($deliveryTypesArr));
|
||||
COption::SetOptionString($this->MODULE_ID, $this->CRM_PAYMENT_TYPES, serialize($paymentTypesArr));
|
||||
COption::SetOptionString($this->MODULE_ID, $this->CRM_PAYMENT_STATUSES, serialize($paymentStatusesArr));
|
||||
COption::SetOptionString($this->MODULE_ID, $this->CRM_PAYMENT, serialize($paymentArr));
|
||||
COption::SetOptionString($this->MODULE_ID, $this->CRM_ORDER_LAST_ID, 0);
|
||||
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_INSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step3.php'
|
||||
);
|
||||
} else if ($step == 4) {
|
||||
|
||||
RegisterModule($this->MODULE_ID);
|
||||
|
||||
//agent
|
||||
$dateAgent = new DateTime();
|
||||
$intAgent = new DateInterval('PT60S'); // PT60S - 60 sec;
|
||||
$dateAgent->add($intAgent);
|
||||
|
||||
CAgent::AddAgent(
|
||||
"ICrmOrderActions::uploadOrdersAgent();",
|
||||
$this->MODULE_ID,
|
||||
"N",
|
||||
600, // interval - 10 mins
|
||||
$dateAgent->format('d.m.Y H:i:s'), // date of first check
|
||||
"Y", // агент активен
|
||||
$dateAgent->format('d.m.Y H:i:s'), // date of first start
|
||||
30
|
||||
);
|
||||
|
||||
$this->CopyFiles();
|
||||
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_INSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step4.php'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function DoUninstall() {
|
||||
global $APPLICATION;
|
||||
|
||||
CAgent::RemoveAgent("ICrmOrderActions::uploadOrdersAgent();", $this->MODULE_ID);
|
||||
|
||||
COption::RemoveOption($this->MODULE_ID, $this->CRM_API_HOST_OPTION);
|
||||
COption::RemoveOption($this->MODULE_ID, $this->CRM_API_KEY_OPTION);
|
||||
COption::RemoveOption($this->MODULE_ID, $this->CRM_DELIVERY_TYPES_ARR);
|
||||
COption::RemoveOption($this->MODULE_ID, $this->CRM_PAYMENT_TYPES);
|
||||
COption::RemoveOption($this->MODULE_ID, $this->CRM_PAYMENT_STATUSES);
|
||||
COption::RemoveOption($this->MODULE_ID, $this->CRM_PAYMENT);
|
||||
COption::RemoveOption($this->MODULE_ID, $this->CRM_ORDER_LAST_ID);
|
||||
|
||||
$this->DeleteFiles();
|
||||
|
||||
UnRegisterModule($this->MODULE_ID);
|
||||
|
||||
$APPLICATION->IncludeAdminFile(
|
||||
GetMessage('MODULE_UNINSTALL_TITLE'),
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/unstep1.php'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function CopyFiles() {
|
||||
CopyDirFiles(
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/export/',
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/include/catalog_export/',
|
||||
true, true
|
||||
);
|
||||
}
|
||||
|
||||
function DeleteFiles() {
|
||||
unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/include/catalog_export/intarocrm_run.php');
|
||||
unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/include/catalog_export/intarocrm_setup.php');
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
<?php
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
//bitrix pyament Y/N
|
||||
$arResult['bitrixPaymentList'][0]['NAME'] = GetMessage('PAYMENT_Y');
|
||||
$arResult['bitrixPaymentList'][0]['ID'] = 'Y';
|
||||
$arResult['bitrixPaymentList'][1]['NAME'] = GetMessage('PAYMENT_N');
|
||||
$arResult['bitrixPaymentList'][1]['ID'] = 'N';
|
||||
|
||||
$defaultOrderTypes = array (
|
||||
1 => 'eshop-individual',
|
||||
2 => 'eshop-legal'
|
||||
);
|
||||
|
||||
$defaultDelivTypes = array (
|
||||
1 => 'courier',
|
||||
2 => 'self-delivery'
|
||||
);
|
||||
|
||||
$defaultPayTypes = array (
|
||||
1 => 'cash',
|
||||
5 => 'bank-card',
|
||||
6 => 'bank-transfer'
|
||||
);
|
||||
|
||||
$defaultPayStatuses = array (
|
||||
'N' => 'new',
|
||||
'P' => 'approval',
|
||||
'F' => 'complete',
|
||||
'Y' => 'cancel-other'
|
||||
);
|
||||
|
||||
$defaultPayment = array(
|
||||
'Y' => 'paid',
|
||||
'N' => 'not-paid'
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
<div class="adm-detail-content-item-block">
|
||||
<form action="<?php echo $APPLICATION->GetCurPage() ?>" method="POST">
|
||||
<?php echo bitrix_sessid_post(); ?>
|
||||
<input type="hidden" name="lang" value="<?php echo LANGUAGE_ID ?>">
|
||||
<input type="hidden" name="id" value="intaro.intarocrm">
|
||||
<input type="hidden" name="install" value="Y">
|
||||
<input type="hidden" name="step" value="3">
|
||||
|
||||
<table class="adm-detail-content-table edit-table" id="edit1_edit_table">
|
||||
<tbody>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('STEP_NAME'); ?></b></td>
|
||||
</tr>
|
||||
<tr align="center">
|
||||
<td colspan="2"><b><?php echo GetMessage('INFO_1'); ?></b></td>
|
||||
</tr>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('DELIVERY_TYPES_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixDeliveryTypesList'] as $bitrixDeliveryType): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixDeliveryType['ID']; ?>">
|
||||
<?php echo $bitrixDeliveryType['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="delivery-type-<?php echo $bitrixDeliveryType['ID']; ?>" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php foreach($arResult['deliveryTypesList'] as $deliveryType): ?>
|
||||
<option value="<?php echo $deliveryType['code']; ?>"
|
||||
<?php if($defaultDelivTypes[$bitrixDeliveryType['ID']] == $deliveryType['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($deliveryType['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('PAYMENT_TYPES_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixPaymentTypesList'] as $bitrixPaymentType): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixPaymentType['ID']; ?>">
|
||||
<?php echo $bitrixPaymentType['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="payment-type-<?php echo $bitrixPaymentType['ID']; ?>" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php foreach($arResult['paymentTypesList'] as $paymentType): ?>
|
||||
<option value="<?php echo $paymentType['code']; ?>"
|
||||
<?php if($defaultPayTypes[$bitrixPaymentType['ID']] == $paymentType['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($paymentType['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('PAYMENT_STATUS_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixPaymentStatusesList'] as $bitrixPaymentStatus): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixPaymentStatus['ID']; ?>">
|
||||
<?php echo $bitrixPaymentStatus['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="payment-status-<?php echo $bitrixPaymentStatus['ID']; ?>" class="typeselect">
|
||||
<option value="" selected=""></option>
|
||||
<?php foreach($arResult['paymentGroupList'] as $orderStatusGroup): if(!empty($orderStatusGroup['statuses'])) : ?>
|
||||
<optgroup label="<?php echo $orderStatusGroup['name']; ?>">
|
||||
<?php foreach($orderStatusGroup['statuses'] as $payment): ?>
|
||||
<option value="<?php echo $arResult['paymentList'][$payment]['code']; ?>"
|
||||
<?php if ($defaultPayStatuses[$bitrixPaymentStatus['ID']] == $arResult['paymentList'][$payment]['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($arResult['paymentList'][$payment]['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<?php endif; endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('PAYMENT_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixPaymentList'] as $bitrixPayment): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixPayment['ID']; ?>">
|
||||
<?php echo $bitrixPayment['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="payment-<?php echo $bitrixPayment['ID']; ?>" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php foreach($arResult['paymentStatusesList'] as $paymentStatus): ?>
|
||||
<option value="<?php echo $paymentStatus['code']; ?>"
|
||||
<?php if($defaultPayment[$bitrixPayment['ID']] == $paymentStatus['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($paymentStatus['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('ORDER_TYPES_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixOrderTypesList'] as $bitrixOrderType): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixOrderType['ID']; ?>">
|
||||
<?php echo $bitrixOrderType['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="order-type-<?php echo $bitrixOrderType['ID']; ?>" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php foreach($arResult['orderTypesList'] as $orderType): ?>
|
||||
<option value="<?php echo $orderType['code']; ?>"
|
||||
<?php if($defaultOrderTypes[$bitrixOrderType['ID']] == $orderType['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($orderType['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<div style="padding: 1px 13px 2px; height:28px;">
|
||||
<div align="right" style="float:right; width:50%; position:relative;">
|
||||
<input type="submit" name="inst" value="<?php echo GetMessage("MOD_NEXT_STEP"); ?>" class="adm-btn-save">
|
||||
</div>
|
||||
<div align="left" style="float:right; width:50%; position:relative;">
|
||||
<input type="submit" name="back" value="<?php echo GetMessage("MOD_PREV_STEP"); ?>" class="adm-btn-save">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -1,5 +0,0 @@
|
|||
<?
|
||||
$arModuleVersion = array(
|
||||
'VERSION' => '0.3.6',
|
||||
'VERSION_DATE' => '2013-07-29 12:29:00',
|
||||
);
|
|
@ -1,124 +0,0 @@
|
|||
<?php
|
||||
$MESS["CET_ERROR_NO_NAME"] = "Введите название профиля выгрузки.";
|
||||
$MESS["CET_STEP1"] = "Шаг";
|
||||
$MESS["CET_STEP2"] = "из";
|
||||
$MESS["CET_SAVE"] = "Сохранить";
|
||||
$MESS["CET_ERROR_NO_IBLOCK1"] = "Информационный блок";
|
||||
$MESS["CET_ERROR_NO_IBLOCK2"] = "не найден.";
|
||||
$MESS["CET_ERROR_NO_FILENAME"] = "Не указано имя файла для экспорта.";
|
||||
$MESS["CET_ERROR_NO_GROUPS"] = "Не указаны выгружаемые группы.";
|
||||
$MESS["CET_ERROR_NO_PROFILE_NAME"] = "Введите название профиля выгрузки.";
|
||||
$MESS["CET_SELECT_IBLOCK"] = "Выберите инфоблок";
|
||||
$MESS["CET_SELECT_IBLOCK_EXT"] = "Выберите инфоблок для экспорта:";
|
||||
$MESS["CET_SELECT_GROUP"] = "Выберите группы:";
|
||||
$MESS["CET_FIRST_SELECT_IBLOCK"] = "Сначала выберите информационный блок";
|
||||
$MESS["CET_ALL_GROUPS"] = "Все группы";
|
||||
$MESS["CET_SERVER_NAME"] = "Доменное имя:";
|
||||
$MESS["CET_SERVER_NAME_SET_CURRENT"] = "текущее";
|
||||
$MESS["CET_SAVE_FILENAME"] = "Сохранить в файл:";
|
||||
$MESS["CET_PROFILE_NAME"] = "Имя профиля:";
|
||||
$MESS["CET_EXPORT"] = "Экспортировать";
|
||||
$MESS["CET_ERROR_NO_IBLOCKS"] = "Не указаны выгружаемые информационные блоки.";
|
||||
$MESS["CET_EXPORT_CATALOGS"] = "Каталоги для экспорта:";
|
||||
$MESS["CET_CATALOG"] = "Каталог";
|
||||
$MESS["CET_EXPORT2YANDEX"] = "Экспортировать в Яндекс.Товары";
|
||||
$MESS["CATI_DATA_EXPORT"] = "Экспорт данных";
|
||||
$MESS["CATI_NO_IBLOCK"] = "Информационный блок не выбран. Выгрузка невозможна.";
|
||||
$MESS["CATI_NO_FORMAT"] = "Укажите формат файла данных и его свойства.";
|
||||
$MESS["CATI_NO_DELIMITER"] = "Укажите символ-разделитель полей.";
|
||||
$MESS["CATI_NO_SAVE_FILE"] = "Укажите файл для сохранения результата.";
|
||||
$MESS["CATI_CANNOT_CREATE_FILE"] = "Ошибка создания файла данных.";
|
||||
$MESS["CATI_NO_FIELDS"] = "Не заданы поля для экспорта.";
|
||||
$MESS["CATI_SCHEME_EXISTS"] = "Схема с таким именем уже существует.";
|
||||
$MESS["CATI_PAGE_TITLE"] = "Выгрузка каталога: шаг";
|
||||
$MESS["CATI_NEXT_STEP"] = "Далее";
|
||||
$MESS["CATI_INFOBLOCK"] = "Информационный блок для экспорта:";
|
||||
$MESS["CATI_SCHEME_NAME"] = "Схема выгрузки:";
|
||||
$MESS["CATI_NOT"] = "Нет";
|
||||
$MESS["CATI_DELETE"] = "удалить";
|
||||
$MESS["CATI_FIELDS"] = "Задайте соответствие полей в файле полям в базе";
|
||||
$MESS["CATI_FI_ID"] = "Идентификатор";
|
||||
$MESS["CATI_FI_NAME"] = "Название";
|
||||
$MESS["CATI_FI_ACTIV"] = "Активность";
|
||||
$MESS["CATI_FI_ACTIVFROM"] = "Активность с";
|
||||
$MESS["CATI_FI_ACTIVTO"] = "Активность до";
|
||||
$MESS["CATI_FI_CATIMG"] = "Картинка для списка";
|
||||
$MESS["CATI_FI_CATDESCR"] = "Описание для списка";
|
||||
$MESS["CATI_FI_DETIMG"] = "Картинка";
|
||||
$MESS["CATI_FI_DETDESCR"] = "Описание";
|
||||
$MESS["CATI_FI_UNIXML"] = "Уникальный идентификатор";
|
||||
$MESS["CATI_FI_QUANT"] = "Количество";
|
||||
$MESS["CATI_FI_WEIGHT"] = "Вес";
|
||||
$MESS["CATI_FI_PROPS"] = "Свойство";
|
||||
$MESS["CATI_FI_GROUP_LEV"] = "Группа уровня";
|
||||
$MESS["CATI_FI_PRICE_TYPE"] = "Цена типа";
|
||||
$MESS["CATI_FIELD"] = "поле";
|
||||
$MESS["CATI_FORMAT_PROPS"] = "Задайте свойства формата файла";
|
||||
$MESS["CATI_DELIMITERS"] = "С разделителями";
|
||||
$MESS["CATI_DELIMITER_TYPE"] = "Разделитель полей";
|
||||
$MESS["CATI_TAB"] = "табуляция";
|
||||
$MESS["CATI_TZP"] = "точка с запятой";
|
||||
$MESS["CATI_ZPT"] = "запятая";
|
||||
$MESS["CATI_SPS"] = "пробел";
|
||||
$MESS["CATI_OTR"] = "другой";
|
||||
$MESS["CATI_SAVE_SCHEME"] = "Сохранить настройки как схему";
|
||||
$MESS["CATI_SSCHEME_NAME"] = "Имя схемы";
|
||||
$MESS["CATI_DATA_FILE_NAME"] = "Сохранить файл данных как...";
|
||||
$MESS["CATI_DATA_FILE_NAME1"] = "Имя файла данных";
|
||||
$MESS["CATI_SUCCESS"] = "Выгрузка завершена";
|
||||
$MESS["CATI_SU_ALL"] = "Всего выгружено строк:";
|
||||
$MESS["CATI_BACK"] = "Назад";
|
||||
$MESS["CATI_FIRST_LINE_NAMES"] = "Первая строка содержит имена полей";
|
||||
$MESS["CATI_SU_ALL1"] = "Скачать файл %DATA_URL% на свой компьютер";
|
||||
$MESS["CATI_FIELDS_NEEDED"] = "Выгружать";
|
||||
$MESS["CATI_FIELDS_NAMES"] = "Название поля";
|
||||
$MESS["CATI_FIELDS_SORTING"] = "Порядок";
|
||||
$MESS["CATI_NEXT_STEP_F"] = "Начать выгрузку";
|
||||
$MESS["CATI_DATA_FILE_NAME1_DESC"] = "Если такой файл существует, то он будет перезаписан";
|
||||
$MESS["CATI_TOO_MANY_TABLES"] = "Слишком большое объединение таблиц. Уменьшите количество экспортируемых свойств или типов цен.";
|
||||
$MESS["EST_QUANTITY_FROM"] = "Покупаемое количество от";
|
||||
$MESS["EST_QUANTITY_TO"] = "Покупаемое количество до";
|
||||
$MESS["EST_PRICE_TYPE"] = "Тип цен \"#TYPE#\"";
|
||||
$MESS["EST_PRICE_TYPE2"] = "Тип цен \"#NAME#\" (#TYPE#)";
|
||||
$MESS["CAT_DETAIL_PROPS"] = "Детальные настройки";
|
||||
$MESS["CAT_DETAIL_PROPS_RUN"] = "настроить";
|
||||
$MESS["CET_IS_SKU"] = "Выбран инфоблок торговых предложений.";
|
||||
$MESS["CET_USE_PARENT_SECT"] = "Использовать группы инфоблока товаров";
|
||||
$MESS["CET_YAND_RUN_ERR_IBLOCK_ABSENT"] = "Инфоблок ##IBLOCK_ID# не существует";
|
||||
$MESS["CET_YAND_RUN_ERR_PRODUCT_IBLOCK_ABSENT"] = "Инфоблок товаров ##IBLOCK_ID# не существует";
|
||||
$MESS["CET_YAND_RUN_ERR_SECTION_SET_EMPTY"] = "Список групп не задан";
|
||||
$MESS["CET_YAND_RUN_ERR_SETUP_FILE_ACCESS_DENIED"] = "Недостаточно прав для перезаписи файла #FILE#";
|
||||
$MESS["CET_YAND_RUN_ERR_SETUP_FILE_OPEN_WRITING"] = "Невозможно открыть файл #FILE# для записи";
|
||||
$MESS["CET_YAND_RUN_ERR_SETUP_FILE_WRITE"] = "Запись в файл #FILE# невозможна";
|
||||
$MESS["CET_YAND_SELECT_IBLOCK"] = "Инфоблок для экспорта";
|
||||
$MESS["CET_SELECT_IBLOCK_TYPE"] = "Выберите тип инфоблока";
|
||||
$MESS["CET_YAND_GROUP_AND_OFFERS"] = "Группы и товары для импорта";
|
||||
$MESS["CET_YAND_USE_IBLOCK_SITE"] = "Брать доменное имя из инфоблока";
|
||||
$MESS["CET_ERROR_IBLOCK_PERM"] = "Недостаточно прав для работы с инфоблоком ##IBLOCK_ID#";
|
||||
$MESS["YANDEX_ERR_SKU_SETTINGS_ABSENT"] = "Отсутствуют настройки экспорта торговых предложений";
|
||||
$MESS["CES_ERROR_BAD_EXPORT_FILENAME"] = "Имя файла экспорта содержит запрещенные символы";
|
||||
$MESS["CES_ERROR_BAD_EXPORT_FILENAME_EXTENTIONS"] = "Имя файла экспорта содержит запрещенное расширение";
|
||||
$MESS["CES_ERROR_FORBIDDEN_EXPORT_FILENAME"] = "Запрещенное имя файла экспорта";
|
||||
$MESS["CES_ERROR_PATH_WITHOUT_DEFAUT"] = "Экспорт может быть осуществлён только в папку, указанную в поле <b>Путь по умолчанию для экспортируемых файлов</b> настроек модуля.";
|
||||
$MESS["CAT_ADM_CSV_EXP_TAB1"] = "Инфоблок";
|
||||
$MESS["CAT_ADM_CSV_EXP_TAB1_TITLE"] = "Выбор информационного блока для экспорта";
|
||||
$MESS["CAT_ADM_CSV_EXP_TAB2"] = "Параметры экспорта";
|
||||
$MESS["CAT_ADM_CSV_EXP_TAB2_TITLE"] = "Настройка параметров экспорта";
|
||||
$MESS["CAT_ADM_CSV_EXP_TAB3"] = "Результат";
|
||||
$MESS["CAT_ADM_CSV_EXP_TAB3_TITLE"] = "Результат экспорта";
|
||||
$MESS["CAT_ADM_CSV_EXP_IBLOCK_ID"] = "Инфоблок";
|
||||
$MESS["CAT_ADM_CSV_EXP_ADD_SETTINGS"] = "Дополнительные настройки";
|
||||
$MESS["CAT_ADM_CSV_EXP_EXPORT_FILES"] = "Выгружать файлы";
|
||||
$MESS["CAT_ADM_CSV_EXP_TIME_STEP"] = "Время выполнения шага";
|
||||
$MESS["CAT_ADM_CSV_EXP_TIME_STEP_COMMENT"] = "0 - загрузить все сразу<br>положительное значение - число секунд на выполнение одного шага";
|
||||
$MESS["CAT_ADM_CSV_EXP_SEP_ELEMENTS"] = "Поля и свойства элементов";
|
||||
$MESS["CAT_ADM_CSV_EXP_SEP_SECTIONS"] = "Поля разделов";
|
||||
$MESS["CAT_ADM_CSV_EXP_SEP_SECTIONS_EXT"] = "Поля и пользовательские свойства разделов";
|
||||
$MESS["CAT_ADM_CSV_EXP_SEP_PRODUCT"] = "Свойства товара";
|
||||
$MESS["CAT_ADM_CSV_EXP_SEP_PRICES"] = "Цены";
|
||||
$MESS["CAT_ADM_CSV_EXP_SEP_SKU"] = "Поля и свойства торговых предложений";
|
||||
$MESS["CAT_ADM_CSV_EXP_DESCR_SECT_PROP"] = "Пользовательское свойство";
|
||||
$MESS["CAT_ADM_CSV_EXP_SECTION_LEVEL"] = "Раздел уровня #LEVEL#";
|
||||
$MESS["CATI_FI_PRICE_TYPE2"] = "Цена типа \"#TYPE#\"";
|
||||
$MESS["CATI_FI_PRICE_TYPE3"] = "Цена типа \"#NAME#\" (#TYPE#)";
|
||||
$MESS["CATI_FI_PRICE_CURRENCY"] = "в валюте #CURRENCY#";
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
$MESS ['MODULE_NAME'] = 'IntaroCRM';
|
||||
$MESS ['MODULE_DESCRIPTION'] = 'Модуль интеграции с IntaroCRM — аналитической CRM для электронной коммерции';
|
||||
$MESS ['MODULE_PARTNER_NAME'] = 'Интаро Софт';
|
||||
$MESS ['MODULE_PARTNER_URI'] = 'http://intaro.ru';
|
||||
$MESS ['MODULE_INSTALL_TITLE'] = 'Установка модуля';
|
||||
$MESS ['MODULE_UNINSTALL_TITLE'] = 'Удаление модуля';
|
||||
$MESS ['CANCELED'] = 'Флаг «Отменен»';
|
||||
$MESS ['ERR_SALE'] = 'Отсутствует модуль sale! Дальнейшая установка невозможна.';
|
||||
$MESS ['ERR_IBLOCK'] = 'Отсутствует модуль iblock! Дальнейшая установка невозможна.';
|
||||
$MESS ['ERR_CATALOG'] = 'Отсутствует модуль catalog! Дальнейшая установка невозможна.';
|
||||
$MESS ['ERR_CATALOG'] = 'Отсутствует модуль catalog! Дальнейшая установка невозможна.';
|
||||
$MESS ['INTAROCRM_CURL_ERR'] = 'Для работы модуля интеграции с IntaroCRM требуется PHP-расширение CURL.';
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
$MESS ['STEP_NAME'] = 'Шаг 1';
|
||||
$MESS ['MOD_NEXT_STEP'] = 'Следующий шаг';
|
||||
$MESS ['ICRM_API_HOST'] = 'Адрес IntaroCRM:';
|
||||
$MESS ['ICRM_API_KEY'] = 'Ключ авторизации:';
|
||||
$MESS ['ERR_404'] = 'Возможно неверно введен адрес IntaroCRM.';
|
||||
$MESS ['ERR_403'] = 'Неверный apiKey.';
|
||||
$MESS ['ERR_0'] = 'Превышено время ожидания ответа от сервера.';
|
||||
$MESS ['ERR_FIELDS_API_HOST'] = 'Неверно заполнены поля.';
|
||||
$MESS ['INFO_1'] = 'Введите адрес экземпляра IntaroCRM (например, http://demo.intarocrm.ru) и API-ключ.';
|
||||
$MESS ['INFO_2'] = 'API-ключ можно сгенерировать при регистрации магазина в IntaroCRM (Администрирование > Магазины).';
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
$MESS ['STEP_NAME'] = 'Шаг 2';
|
||||
$MESS ['MOD_NEXT_STEP'] = 'Следующий шаг';
|
||||
$MESS ['MOD_PREV_STEP'] = 'Предыдущий шаг';
|
||||
$MESS ['DELIVERY_TYPES_LIST'] = 'Способы доставки';
|
||||
$MESS ['PAYMENT_TYPES_LIST'] = 'Способы оплаты';
|
||||
$MESS ['PAYMENT_STATUS_LIST'] = 'Статусы';
|
||||
$MESS ['ORDER_TYPES_LIST'] = 'Типы заказа';
|
||||
$MESS ['PAYMENT_LIST'] = 'Оплата';
|
||||
$MESS ['PAYMENT_Y'] = 'Оплачен';
|
||||
$MESS ['PAYMENT_N'] = 'Не оплачен';
|
||||
$MESS ['CANCELED'] = 'Флаг «Отменен»';
|
||||
$MESS ['INFO_1'] = ' Задайте соответствие между справочниками 1C-Битрикс и справочниками IntaroCRM.';
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
$MESS ['ICRM_OPTIONS_GENERAL_TAB'] = 'Общие настройки';
|
||||
$MESS ['ICRM_OPTIONS_IMPORT_TAB'] = 'Настройки импората';
|
||||
$MESS ['ICRM_CONN_SETTINGS'] = 'Настройка соединения';
|
||||
$MESS ['ICRM_API_HOST'] = 'Адрес Intaro CRM:';
|
||||
$MESS ['ICRM_API_KEY'] = 'Ключ авторизации:';
|
||||
|
||||
$MESS ['ICRM_OPTIONS_CATALOG_TAB'] = 'Настройка справочников';
|
||||
$MESS ['DELIVERY_TYPES_LIST'] = 'Способы доставки';
|
||||
$MESS ['PAYMENT_TYPES_LIST'] = 'Способы оплаты';
|
||||
$MESS ['PAYMENT_STATUS_LIST'] = 'Статусы';
|
||||
$MESS ['ORDER_TYPES_LIST'] = 'Типы заказа';
|
||||
$MESS ['PAYMENT_LIST'] = 'Оплата';
|
||||
$MESS ['PAYMENT_Y'] = 'Оплачен';
|
||||
$MESS ['PAYMENT_N'] = 'Не оплачен';
|
||||
|
||||
$MESS ['ICRM_OPTIONS_SUBMIT_TITLE'] = 'Сохранить настройки';
|
||||
$MESS ['ICRM_OPTIONS_SUBMIT_VALUE'] = 'Сохранить';
|
||||
|
||||
$MESS ['ERR_404'] = 'Возможно не верно введен адрес CRM.';
|
||||
$MESS ['ERR_403'] = 'Неверный apiKey.';
|
||||
$MESS ['ERR_0'] = 'Превышено время ожидания ответа от сервера.';
|
||||
$MESS ['ICRM_OPTIONS_OK'] = 'Изменения успешно сохранены.';
|
||||
$MESS ['CANCELED'] = 'Флаг «Отменен»';
|
|
@ -1,400 +0,0 @@
|
|||
<?php
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
$mid = 'intaro.intarocrm';
|
||||
$uri = $APPLICATION->GetCurPage() . '?mid=' . htmlspecialchars($mid) . '&lang=' . LANGUAGE_ID;
|
||||
|
||||
$CRM_API_HOST_OPTION = 'api_host';
|
||||
$CRM_API_KEY_OPTION = 'api_key';
|
||||
$CRM_ORDER_TYPES_ARR = 'order_types_arr';
|
||||
$CRM_DELIVERY_TYPES_ARR = 'deliv_types_arr';
|
||||
$CRM_PAYMENT_TYPES = 'pay_types_arr';
|
||||
$CRM_PAYMENT_STATUSES = 'pay_statuses_arr';
|
||||
$CRM_PAYMENT = 'payment_arr'; //order payment Y/N
|
||||
$CRM_ORDER_LAST_ID = 'order_last_id';
|
||||
|
||||
if(!CModule::IncludeModule('intaro.intarocrm')
|
||||
|| !CModule::IncludeModule('sale'))
|
||||
return;
|
||||
|
||||
$_GET['errc'] = htmlspecialchars(trim($_GET['errc']));
|
||||
$_GET['ok'] = htmlspecialchars(trim($_GET['ok']));
|
||||
|
||||
if($_GET['errc']) echo CAdminMessage::ShowMessage(GetMessage($_GET['errc']));
|
||||
if($_GET['ok'] && $_GET['ok'] == 'Y') echo CAdminMessage::ShowNote(GetMessage('ICRM_OPTIONS_OK'));
|
||||
|
||||
$arResult = array();
|
||||
|
||||
//update connection settings
|
||||
if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) {
|
||||
$api_host = htmlspecialchars(trim($_POST['api_host']));
|
||||
$api_key = htmlspecialchars(trim($_POST['api_key']));
|
||||
|
||||
if($api_host && $api_key) {
|
||||
$api = new IntaroCrm\RestApi($api_host, $api_key);
|
||||
|
||||
$api->paymentStatusesList();
|
||||
|
||||
//check connection & apiKey valid
|
||||
if((int) $api->getStatusCode() != 200) {
|
||||
$uri .= '&errc=ERR_' . $api->getStatusCode();
|
||||
LocalRedirect($uri);
|
||||
} else {
|
||||
COption::SetOptionString($mid, 'api_host', $api_host);
|
||||
COption::SetOptionString($mid, 'api_key', $api_key);
|
||||
}
|
||||
}
|
||||
|
||||
//bitrix orderTypesList -- personTypes
|
||||
$dbOrderTypesList = CSalePersonType::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y",
|
||||
),
|
||||
false,
|
||||
false,
|
||||
array()
|
||||
);
|
||||
|
||||
//form order types ids arr
|
||||
$orderTypesArr = array();
|
||||
if ($arOrderTypesList = $dbOrderTypesList->Fetch()) {
|
||||
do {
|
||||
$orderTypesArr[$arOrderTypesList['ID']] = $_POST['order-type-' . $arOrderTypesList['ID']];
|
||||
} while ($arOrderTypesList = $dbOrderTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix deliveryTypesList
|
||||
$dbDeliveryTypesList = CSaleDelivery::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y",
|
||||
),
|
||||
false,
|
||||
false,
|
||||
array()
|
||||
);
|
||||
|
||||
//form delivery types ids arr
|
||||
$deliveryTypesArr = array();
|
||||
if ($arDeliveryTypesList = $dbDeliveryTypesList->Fetch()) {
|
||||
do {
|
||||
$deliveryTypesArr[$arDeliveryTypesList['ID']] = htmlspecialchars(trim($_POST['delivery-type-' . $arDeliveryTypesList['ID']]));
|
||||
} while ($arDeliveryTypesList = $dbDeliveryTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix paymentTypesList
|
||||
$dbPaymentTypesList = CSalePaySystem::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y"
|
||||
)
|
||||
);
|
||||
|
||||
//form payment types ids arr
|
||||
$paymentTypesArr = array();
|
||||
if ($arPaymentTypesList = $dbPaymentTypesList->Fetch()) {
|
||||
do {
|
||||
$paymentTypesArr[$arPaymentTypesList['ID']] = htmlspecialchars(trim($_POST['payment-type-' . $arPaymentTypesList['ID']]));
|
||||
} while ($arPaymentTypesList = $dbPaymentTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix paymentStatusesList
|
||||
$dbPaymentStatusesList = CSaleStatus::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"LID" => "ru", //ru
|
||||
"ACTIVE" => "Y"
|
||||
)
|
||||
);
|
||||
|
||||
//form payment statuses ids arr
|
||||
$paymentStatusesArr['Y'] = htmlspecialchars(trim($_POST['payment-status-Y']));
|
||||
if ($arPaymentStatusesList = $dbPaymentStatusesList->Fetch()) {
|
||||
do {
|
||||
$paymentStatusesArr[$arPaymentStatusesList['ID']] = htmlspecialchars(trim($_POST['payment-status-' . $arPaymentStatusesList['ID']]));
|
||||
} while ($arPaymentStatusesList = $dbPaymentStatusesList->Fetch());
|
||||
}
|
||||
|
||||
//form payment ids arr
|
||||
$paymentArr = array();
|
||||
$paymentArr['Y'] = htmlspecialchars(trim($_POST['payment-Y']));
|
||||
$paymentArr['N'] = htmlspecialchars(trim($_POST['payment-N']));
|
||||
|
||||
COption::SetOptionString($mid, $CRM_ORDER_TYPES_ARR, serialize($orderTypesArr));
|
||||
COption::SetOptionString($mid, $CRM_DELIVERY_TYPES_ARR, serialize($deliveryTypesArr));
|
||||
COption::SetOptionString($mid, $CRM_PAYMENT_TYPES, serialize($paymentTypesArr));
|
||||
COption::SetOptionString($mid, $CRM_PAYMENT_STATUSES, serialize($paymentStatusesArr));
|
||||
COption::SetOptionString($mid, $CRM_PAYMENT, serialize($paymentArr));
|
||||
|
||||
$uri .= '&ok=Y';
|
||||
LocalRedirect($uri);
|
||||
} else {
|
||||
$api_host = COption::GetOptionString($mid, $CRM_API_HOST_OPTION, 0);
|
||||
$api_key = COption::GetOptionString($mid, $CRM_API_KEY_OPTION, 0);
|
||||
|
||||
$api = new IntaroCrm\RestApi($api_host, $api_key);
|
||||
|
||||
//prepare crm lists
|
||||
$arResult['orderTypesList'] = $api->orderTypesList();
|
||||
$arResult['deliveryTypesList'] = $api->deliveryTypesList();
|
||||
$arResult['paymentTypesList'] = $api->paymentTypesList();
|
||||
$arResult['paymentStatusesList'] = $api->paymentStatusesList(); // --statuses
|
||||
$arResult['paymentList'] = $api->orderStatusesList();
|
||||
$arResult['paymentGroupList'] = $api->orderStatusGroupsList(); // -- statuses groups
|
||||
|
||||
//check connection & apiKey valid
|
||||
if ((int) $api->getStatusCode() != 200)
|
||||
echo CAdminMessage::ShowMessage(GetMessage('ERR_' . $api->getStatusCode()));
|
||||
|
||||
//bitrix orderTypesList -- personTypes
|
||||
$dbOrderTypesList = CSalePersonType::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y",
|
||||
),
|
||||
false,
|
||||
false,
|
||||
array()
|
||||
);
|
||||
|
||||
if ($arOrderTypesList = $dbOrderTypesList->Fetch()) {
|
||||
do {
|
||||
$arResult['bitrixOrderTypesList'][] = $arOrderTypesList;
|
||||
} while ($arOrderTypesList = $dbOrderTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix deliveryTypesList
|
||||
$dbDeliveryTypesList = CSaleDelivery::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y",
|
||||
),
|
||||
false,
|
||||
false,
|
||||
array()
|
||||
);
|
||||
|
||||
if ($arDeliveryTypesList = $dbDeliveryTypesList->Fetch()) {
|
||||
do {
|
||||
$arResult['bitrixDeliveryTypesList'][] = $arDeliveryTypesList;
|
||||
} while ($arDeliveryTypesList = $dbDeliveryTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix paymentTypesList
|
||||
$dbPaymentTypesList = CSalePaySystem::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"ACTIVE" => "Y"
|
||||
)
|
||||
);
|
||||
|
||||
if ($arPaymentTypesList = $dbPaymentTypesList->Fetch()) {
|
||||
do {
|
||||
$arResult['bitrixPaymentTypesList'][] = $arPaymentTypesList;
|
||||
} while ($arPaymentTypesList = $dbPaymentTypesList->Fetch());
|
||||
}
|
||||
|
||||
//bitrix paymentStatusesList
|
||||
$dbPaymentStatusesList = CSaleStatus::GetList(
|
||||
array(
|
||||
"SORT" => "ASC",
|
||||
"NAME" => "ASC"
|
||||
),
|
||||
array(
|
||||
"LID" => "ru", //ru
|
||||
"ACTIVE" => "Y"
|
||||
)
|
||||
);
|
||||
|
||||
if ($arPaymentStatusesList = $dbPaymentStatusesList->Fetch()) {
|
||||
do {
|
||||
$arResult['bitrixPaymentStatusesList'][] = $arPaymentStatusesList;
|
||||
} while ($arPaymentStatusesList = $dbPaymentStatusesList->Fetch());
|
||||
}
|
||||
$arResult['bitrixPaymentStatusesList'][] = array(
|
||||
'ID' => 'Y',
|
||||
'NAME' => GetMessage('CANCELED')
|
||||
);
|
||||
|
||||
//bitrix pyament Y/N
|
||||
$arResult['bitrixPaymentList'][0]['NAME'] = GetMessage('PAYMENT_Y');
|
||||
$arResult['bitrixPaymentList'][0]['ID'] = 'Y';
|
||||
$arResult['bitrixPaymentList'][1]['NAME'] = GetMessage('PAYMENT_N');
|
||||
$arResult['bitrixPaymentList'][1]['ID'] = 'N';
|
||||
|
||||
//saved cat params
|
||||
$optionsOrderTypes = unserialize(COption::GetOptionString($mid, $CRM_ORDER_TYPES_ARR, 0));
|
||||
$optionsDelivTypes = unserialize(COption::GetOptionString($mid, $CRM_DELIVERY_TYPES_ARR, 0));
|
||||
$optionsPayTypes = unserialize(COption::GetOptionString($mid, $CRM_PAYMENT_TYPES, 0));
|
||||
$optionsPayStatuses = unserialize(COption::GetOptionString($mid, $CRM_PAYMENT_STATUSES, 0)); // --statuses
|
||||
$optionsPayment = unserialize(COption::GetOptionString($mid, $CRM_PAYMENT, 0));
|
||||
|
||||
$aTabs = array(
|
||||
array(
|
||||
"DIV" => "edit1",
|
||||
"TAB" => GetMessage('ICRM_OPTIONS_GENERAL_TAB'),
|
||||
"ICON" => "",
|
||||
"TITLE" => GetMessage('ICRM_OPTIONS_GENERAL_CAPTION')
|
||||
),
|
||||
array(
|
||||
"DIV" => "edit2",
|
||||
"TAB" => GetMessage('ICRM_OPTIONS_CATALOG_TAB'),
|
||||
"ICON" => '',
|
||||
"TITLE" => GetMessage('ICRM_OPTIONS_CATALOG_CAPTION')
|
||||
),
|
||||
);
|
||||
$tabControl = new CAdminTabControl("tabControl", $aTabs);
|
||||
$tabControl->Begin();
|
||||
?>
|
||||
<form method="POST" action="<?php echo $uri; ?>" id="FORMACTION">
|
||||
<?php
|
||||
echo bitrix_sessid_post();
|
||||
$tabControl->BeginNextTab();
|
||||
?>
|
||||
<input type="hidden" name="tab" value="catalog">
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('ICRM_CONN_SETTINGS'); ?></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l"><?php echo GetMessage('ICRM_API_HOST'); ?></td>
|
||||
<td width="50%" class="adm-detail-content-cell-r"><input type="text" id="api_host" name="api_host" value="<?php echo $api_host; ?>"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l"><?php echo GetMessage('ICRM_API_KEY'); ?></td>
|
||||
<td width="50%" class="adm-detail-content-cell-r"><input type="text" id="api_key" name="api_key" value="<?php echo $api_key; ?>"></td>
|
||||
</tr>
|
||||
<?php $tabControl->BeginNextTab(); ?>
|
||||
<input type="hidden" name="tab" value="catalog">
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('DELIVERY_TYPES_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixDeliveryTypesList'] as $bitrixDeliveryType): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixDeliveryType['ID']; ?>">
|
||||
<?php echo $bitrixDeliveryType['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="delivery-type-<?php echo $bitrixDeliveryType['ID']; ?>" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php foreach($arResult['deliveryTypesList'] as $deliveryType): ?>
|
||||
<option value="<?php echo $deliveryType['code']; ?>" <?php if ($optionsDelivTypes[$bitrixDeliveryType['ID']] == $deliveryType['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($deliveryType['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('PAYMENT_TYPES_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixPaymentTypesList'] as $bitrixPaymentType): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixPaymentType['ID']; ?>">
|
||||
<?php echo $bitrixPaymentType['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="payment-type-<?php echo $bitrixPaymentType['ID']; ?>" class="typeselect">
|
||||
<option value="" selected=""></option>
|
||||
<?php foreach($arResult['paymentTypesList'] as $paymentType): ?>
|
||||
<option value="<?php echo $paymentType['code']; ?>" <?php if ($optionsPayTypes[$bitrixPaymentType['ID']] == $paymentType['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($paymentType['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('PAYMENT_STATUS_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixPaymentStatusesList'] as $bitrixPaymentStatus): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixPaymentStatus['ID']; ?>">
|
||||
<?php echo $bitrixPaymentStatus['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="payment-status-<?php echo $bitrixPaymentStatus['ID']; ?>" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php foreach($arResult['paymentGroupList'] as $orderStatusGroup): if(!empty($orderStatusGroup['statuses'])) : ?>
|
||||
<optgroup label="<?php echo $orderStatusGroup['name']; ?>">
|
||||
<?php foreach($orderStatusGroup['statuses'] as $payment): ?>
|
||||
<option value="<?php echo $arResult['paymentList'][$payment]['code']; ?>" <?php if ($optionsPayStatuses[$bitrixPaymentStatus['ID']] == $arResult['paymentList'][$payment]['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($arResult['paymentList'][$payment]['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<?php endif; endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('PAYMENT_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixPaymentList'] as $bitrixPayment): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixPayment['ID']; ?>">
|
||||
<?php echo $bitrixPayment['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="payment-<?php echo $bitrixPayment['ID']; ?>" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php foreach($arResult['paymentStatusesList'] as $paymentStatus): ?>
|
||||
<option value="<?php echo $paymentStatus['code']; ?>" <?php if ($optionsPayment[$bitrixPayment['ID']] == $paymentStatus['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($paymentStatus['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="heading">
|
||||
<td colspan="2"><b><?php echo GetMessage('ORDER_TYPES_LIST'); ?></b></td>
|
||||
</tr>
|
||||
<?php foreach($arResult['bitrixOrderTypesList'] as $bitrixOrderType): ?>
|
||||
<tr>
|
||||
<td width="50%" class="adm-detail-content-cell-l" name="<?php echo $bitrixOrderType['ID']; ?>">
|
||||
<?php echo $bitrixOrderType['NAME']; ?>
|
||||
</td>
|
||||
<td width="50%" class="adm-detail-content-cell-r">
|
||||
<select name="order-type-<?php echo $bitrixOrderType['ID']; ?>" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php foreach($arResult['orderTypesList'] as $orderType): ?>
|
||||
<option value="<?php echo $orderType['code']; ?>" <?php if ($optionsOrderTypes[$bitrixOrderType['ID']] == $orderType['code']) echo 'selected'; ?>>
|
||||
<?php echo $APPLICATION->ConvertCharset($orderType['name'], 'utf-8', SITE_CHARSET); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php $tabControl->BeginNextTab(); ?>
|
||||
<?php $tabControl->Buttons(); ?>
|
||||
<input type="hidden" name="Update" value="Y" />
|
||||
<input type="submit" title="<?php echo GetMessage('ICRM_OPTIONS_SUBMIT_TITLE'); ?>" value="<?php echo GetMessage('ICRM_OPTIONS_SUBMIT_VALUE'); ?>" name="btn-update" class="adm-btn-save" />
|
||||
<?php $tabControl->End(); ?>
|
||||
</form>
|
||||
|
||||
<?php } ?>
|
12
intaro.retailcrm/.settings.php
Normal file
12
intaro.retailcrm/.settings.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'controllers' => [
|
||||
'value' => [
|
||||
'namespaces' => [
|
||||
'\\Intaro\\RetailCrm\\Controller' => 'api'
|
||||
],
|
||||
],
|
||||
'readonly' => true,
|
||||
]
|
||||
];
|
357
intaro.retailcrm/RetailcrmClasspathBuilder.php
Normal file
357
intaro.retailcrm/RetailcrmClasspathBuilder.php
Normal file
|
@ -0,0 +1,357 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class RetailcrmClasspathBuilder.
|
||||
* Builds classpath for Bitrix autoloader. Contains some hardcoded things, which will go away when everything refactored.
|
||||
*/
|
||||
class RetailcrmClasspathBuilder
|
||||
{
|
||||
/**
|
||||
* File extension as a string. Defaults to ".php".
|
||||
* @var string
|
||||
*/
|
||||
protected $fileExt = 'php';
|
||||
|
||||
/**
|
||||
* @var string $moduleId
|
||||
*/
|
||||
protected $moduleId = 'intaro.retailcrm';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $customizedFilesPath = '/bitrix/php_interface/retailcrm/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $customizedClassesPath = '../../php_interface/retailcrm/';
|
||||
|
||||
/**
|
||||
* The topmost directory where recursion should begin. Default: `classes/general`. Relative to the __DIR__.
|
||||
* @var string
|
||||
*/
|
||||
protected $path = 'classes/general';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bitrixModulesPath = 'bitrix/modules';
|
||||
|
||||
/**
|
||||
* Do not include directory paths as namespaces.
|
||||
* @var bool
|
||||
*/
|
||||
protected $disableNamespaces;
|
||||
|
||||
/**
|
||||
* Bitrix document root
|
||||
* @var string
|
||||
*/
|
||||
protected $documentRoot;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* @var array $result
|
||||
*/
|
||||
protected $result = [];
|
||||
|
||||
/**
|
||||
* @var array $notIncluded
|
||||
*/
|
||||
protected $notIncluded = [];
|
||||
|
||||
protected $directories = [];
|
||||
|
||||
/**
|
||||
* These classes can be customized, in which case they would be replaced with files from
|
||||
* directory <root>/bitrix/php_interface/retailcrm
|
||||
*
|
||||
* Array format:
|
||||
* [
|
||||
* 'class path with namespace' => 'file name'
|
||||
* ]
|
||||
*/
|
||||
protected static $customizableClasses = [
|
||||
'classes' => [
|
||||
'RestNormalizer' => 'RestNormalizer.php',
|
||||
'Logger' => 'Logger.php',
|
||||
'RetailCrm\ApiClient' => 'ApiClient_v5.php',
|
||||
'RetailCrm\Http\Client' => 'Client.php',
|
||||
'RCrmActions' => 'RCrmActions.php',
|
||||
'RetailCrmUser' => 'RetailCrmUser.php',
|
||||
'RetailCrmICML' => 'RetailCrmICML.php',
|
||||
'RetailCrmInventories' => 'RetailCrmInventories.php',
|
||||
'RetailCrmPrices' => 'RetailCrmPrices.php',
|
||||
'RetailCrmCollector' => 'RetailCrmCollector.php',
|
||||
'RetailCrmUa' => 'RetailCrmUa.php',
|
||||
'RetailCrmEvent' => 'RetailCrmEvent.php',
|
||||
'RetailCrmCorporateClient' => 'RetailCrmCorporateClient.php'
|
||||
],
|
||||
'lib/icml' => [
|
||||
'Intaro\RetailCrm\Icml\XmlOfferBuilder' => 'xmlofferbuilder.php',
|
||||
'Intaro\RetailCrm\Icml\XmlOfferDirector' => 'xmlofferdirector.php',
|
||||
'Intaro\RetailCrm\Icml\IcmlWriter' => 'icmlwriter.php',
|
||||
'Intaro\RetailCrm\Icml\QueryParamsMolder' => 'queryparamsmolder.php',
|
||||
'Intaro\RetailCrm\Icml\SettingsService' => 'settingsservice.php',
|
||||
'Intaro\RetailCrm\Icml\XmlCategoryDirector' => 'xmlcategorydirector.php',
|
||||
'Intaro\RetailCrm\Icml\XmlCategoryFactory' => 'xmlcategoryfactory.php',
|
||||
'Intaro\RetailCrm\Icml\IcmlDirector' => 'icmldirector.php'
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* These classes can be customized, in which case they would be replaced with files from
|
||||
* directory <root>/bitrix/php_interface/retailcrm
|
||||
* Customized versions have fixed name, and original versions name depends on API version
|
||||
*
|
||||
* Array format:
|
||||
* [
|
||||
* 'class path with namespace' => ['customized file name', 'original file name with %s for API version']
|
||||
* ]
|
||||
*/
|
||||
protected static $versionedClasses = [
|
||||
'classes' => [
|
||||
'RetailCrm\ApiClient' => ['ApiClient.php', 'ApiClient_%s.php'],
|
||||
'RetailCrmOrder' => ['RetailCrmOrder.php', 'RetailCrmOrder_%s.php'],
|
||||
'RetailCrmHistory' => ['RetailCrmHistory.php', 'RetailCrmHistory_%s.php'],
|
||||
'RetailCrmCart' => ['RetailCrmCart.php', 'RetailCrmCart_%s.php']
|
||||
],
|
||||
'lib/icml' => []
|
||||
];
|
||||
|
||||
/**
|
||||
* These classes will be ignored while loading from original files
|
||||
*/
|
||||
protected static $ignoredClasses = [
|
||||
'classes' => [
|
||||
'ApiClient_v5.php',
|
||||
'RetailCrmOrder_v5.php',
|
||||
'RetailCrmHistory_v5.php',
|
||||
'RetailCrmCart_v5.php',
|
||||
],
|
||||
'lib/icml' => []
|
||||
];
|
||||
|
||||
/**
|
||||
* These namespaces are hardcoded.
|
||||
*/
|
||||
protected static $hardcodedNamespaces = [
|
||||
'classes' => [
|
||||
'RetailCrm\Response\ApiResponse' => 'ApiResponse.php',
|
||||
'RetailCrm\Exception\InvalidJsonException' => 'InvalidJsonException.php',
|
||||
'RetailCrm\Exception\CurlException' => 'CurlException.php'
|
||||
],
|
||||
'lib/icml' => []
|
||||
];
|
||||
|
||||
protected function buildCustomizableClasspath()
|
||||
{
|
||||
foreach (static::$customizableClasses[$this->path] as $className => $fileName) {
|
||||
if (file_exists($this->documentRoot . $this->customizedFilesPath . $fileName)) {
|
||||
$this->result[$className] = $this->customizedClassesPath . $fileName;
|
||||
} else {
|
||||
$this->notIncluded[$className] = $fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function buildVersionedClasspath()
|
||||
{
|
||||
foreach (static::$versionedClasses[$this->path] as $className => $fileNames) {
|
||||
if (file_exists($this->documentRoot . $this->customizedFilesPath . $fileNames[0])) {
|
||||
$this->result[$className] = $this->customizedClassesPath . $fileNames[0];
|
||||
} else {
|
||||
$this->notIncluded[$className] = sprintf($fileNames[1], $this->version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse through directories, build include paths
|
||||
* @return $this
|
||||
*/
|
||||
public function build(): self
|
||||
{
|
||||
foreach ($this->directories as $path) {
|
||||
$this->path = $path;
|
||||
|
||||
$directory = new RecursiveDirectoryIterator(
|
||||
$this->getSearchPath(),
|
||||
RecursiveDirectoryIterator::SKIP_DOTS
|
||||
);
|
||||
|
||||
$fileIterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::LEAVES_ONLY);
|
||||
|
||||
$this->buildCustomizableClasspath();
|
||||
$this->buildVersionedClasspath();
|
||||
|
||||
$notIncludedClasses = array_flip($this->notIncluded);
|
||||
$hardcodedNamespaces = array_flip(static::$hardcodedNamespaces[$path]);
|
||||
|
||||
/** @var \SplFileObject $file */
|
||||
foreach ($fileIterator as $file) {
|
||||
$fileNameWithoutExt = str_ireplace('.' . $this->fileExt, '', $file->getFilename());
|
||||
|
||||
if ($file->getExtension() !== $this->fileExt) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($file->getFilename(), static::$customizableClasses[$path])
|
||||
|| in_array($file->getFilename(), static::$ignoredClasses[$path])
|
||||
) {
|
||||
if (in_array($file->getFilename(), $this->notIncluded)) {
|
||||
$this->result[$notIncludedClasses[$file->getFilename()]] = $this->getImportPath($file->getPathname());
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($file->getFilename(), static::$hardcodedNamespaces[$path])) {
|
||||
$this->result[$hardcodedNamespaces[$file->getFilename()]] = $this->getImportPath($file->getPathname());
|
||||
} else {
|
||||
$this->result[$this->getImportClass($fileNameWithoutExt, $file->getPath())] = $this->getImportPath($file->getPathname());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the $fileExt property
|
||||
*
|
||||
* @param string $fileExt The file extension used for class files. Default is "php".
|
||||
*
|
||||
* @return \RetailcrmClasspathBuilder
|
||||
*/
|
||||
public function setFileExt($fileExt)
|
||||
{
|
||||
$this->fileExt = $fileExt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $documentRoot
|
||||
*
|
||||
* @return RetailcrmClasspathBuilder
|
||||
*/
|
||||
public function setDocumentRoot(string $documentRoot): RetailcrmClasspathBuilder
|
||||
{
|
||||
$this->documentRoot = $documentRoot;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the $path property
|
||||
*
|
||||
* @param array $path Top path to load files
|
||||
*
|
||||
* @return \RetailcrmClasspathBuilder
|
||||
*/
|
||||
public function setPath(array $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $directories
|
||||
* @return \RetailcrmClasspathBuilder
|
||||
*/
|
||||
public function setDirectories(array $directories)
|
||||
{
|
||||
$this->directories = $directories;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $disableNamespaces
|
||||
*
|
||||
* @return RetailcrmClasspathBuilder
|
||||
*/
|
||||
public function setDisableNamespaces($disableNamespaces)
|
||||
{
|
||||
$this->disableNamespaces = $disableNamespaces;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $moduleId
|
||||
*
|
||||
* @return RetailcrmClasspathBuilder
|
||||
*/
|
||||
public function setModuleId(string $moduleId): RetailcrmClasspathBuilder
|
||||
{
|
||||
$this->moduleId = $moduleId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*
|
||||
* @return RetailcrmClasspathBuilder
|
||||
*/
|
||||
public function setVersion(string $version): RetailcrmClasspathBuilder
|
||||
{
|
||||
$this->version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getResult(): array
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getSearchPath(): string
|
||||
{
|
||||
return $this->documentRoot . DIRECTORY_SEPARATOR . $this->bitrixModulesPath . DIRECTORY_SEPARATOR
|
||||
. $this->moduleId. DIRECTORY_SEPARATOR . $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filePath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getImportPath(string $filePath): string
|
||||
{
|
||||
return (string) str_ireplace(implode(DIRECTORY_SEPARATOR, [
|
||||
$this->documentRoot,
|
||||
$this->bitrixModulesPath,
|
||||
$this->moduleId
|
||||
]) . DIRECTORY_SEPARATOR, '', $filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileNameWithoutExt
|
||||
* @param string $filePath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getImportClass(string $fileNameWithoutExt, string $filePath): string
|
||||
{
|
||||
if ($this->disableNamespaces) {
|
||||
return $fileNameWithoutExt;
|
||||
}
|
||||
|
||||
$importClass = str_ireplace($this->getSearchPath(), '', $filePath). '\\' . $fileNameWithoutExt;
|
||||
|
||||
if (strlen($importClass) > 0 && $importClass[0] === '/') {
|
||||
$importClass = '\\' . substr($importClass, 1);
|
||||
}
|
||||
|
||||
return (string) str_replace(DIRECTORY_SEPARATOR, '\\', $importClass);
|
||||
}
|
||||
}
|
73
intaro.retailcrm/classes/general/AbstractBuilder.php
Normal file
73
intaro.retailcrm/classes/general/AbstractBuilder.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class AbstractBuilder
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
abstract class AbstractBuilder
|
||||
{
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getValue($key, $default = NULL)
|
||||
{
|
||||
return isset($this->dataCrm[$key]) && !empty($this->dataCrm[$key]) ? $this->dataCrm[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getValueArray($array, $key, $default = NULL)
|
||||
{
|
||||
return isset($this->dataCrm[$array][$key]) && !empty($this->dataCrm[$array][$key]) ? $this->dataCrm[$array][$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @param array $symbols
|
||||
* @return array
|
||||
*/
|
||||
public function arrayClear(array $array, array $symbols = array('', 0, null))
|
||||
{
|
||||
return array_diff($array, $symbols);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function objectToArray($data)
|
||||
{
|
||||
return $this->arrayClear(json_decode(json_encode($data), true));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string|array|\SplFixedArray $str in utf-8
|
||||
*
|
||||
* @return array|bool|\SplFixedArray|string $str in SITE_CHARSET
|
||||
* @global $APPLICATION
|
||||
*/
|
||||
public function fromJSON($str)
|
||||
{
|
||||
global $APPLICATION;
|
||||
|
||||
return $APPLICATION->ConvertCharset($str, 'utf-8', SITE_CHARSET);
|
||||
}
|
||||
}
|
88
intaro.retailcrm/classes/general/AddressBuilder.php
Normal file
88
intaro.retailcrm/classes/general/AddressBuilder.php
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class AddressBuilder
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class AddressBuilder extends AbstractBuilder implements RetailcrmBuilderInterface
|
||||
{
|
||||
/**
|
||||
* @var CustomerAddress
|
||||
*/
|
||||
private $customerAddress;
|
||||
|
||||
/** @var array $dataCrm customerHistory */
|
||||
protected $dataCrm;
|
||||
|
||||
/**
|
||||
* CustomerBuilder constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->customerAddress = new CustomerAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dataCrm
|
||||
* @return $this|RetailcrmBuilderInterface
|
||||
*/
|
||||
public function setDataCrm($dataCrm)
|
||||
{
|
||||
$this->dataCrm = $dataCrm;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomerAddress($data)
|
||||
{
|
||||
$this->customerAddress = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CustomerAddress
|
||||
*/
|
||||
public function getCustomerAddress()
|
||||
{
|
||||
return $this->customerAddress;
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
$this->customerAddress->setText($this->getValue('text'))
|
||||
->setNotes($this->getValue('notes'))
|
||||
->setBuilding($this->getValue('building'))
|
||||
->setBlock($this->getValue('block'))
|
||||
->setCity($this->getValue('city'))
|
||||
->setFlat($this->getValue('flat'))
|
||||
->setHouse($this->getValue('house'))
|
||||
->setFloor($this->getValue('floor'))
|
||||
->setCountry($this->getValue('countryIso'))
|
||||
->setIndex($this->getValue('index'))
|
||||
->setIntercomCode($this->getValue('intercomCode'))
|
||||
->setMetro($this->getValue('metro'))
|
||||
->setRegion($this->getValue('region'))
|
||||
->setStreet($this->getValue('street'));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->customerAddress = new CustomerAddress();
|
||||
}
|
||||
}
|
3143
intaro.retailcrm/classes/general/ApiClient_v5.php
Normal file
3143
intaro.retailcrm/classes/general/ApiClient_v5.php
Normal file
File diff suppressed because it is too large
Load diff
276
intaro.retailcrm/classes/general/CorporateCustomerBuilder.php
Normal file
276
intaro.retailcrm/classes/general/CorporateCustomerBuilder.php
Normal file
|
@ -0,0 +1,276 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class CorporateCustomerBuilder
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class CorporateCustomerBuilder extends AbstractBuilder implements RetailcrmBuilderInterface
|
||||
{
|
||||
/** @var Customer */
|
||||
protected $customer;
|
||||
|
||||
/**@var CustomerBuilder */
|
||||
protected $customerBuilder;
|
||||
|
||||
/** @var CustomerAddress */
|
||||
protected $customerAddress;
|
||||
|
||||
/** @var array $dataCrm customerHistory */
|
||||
protected $dataCrm;
|
||||
|
||||
/** @var array $corporateContact */
|
||||
protected $corporateContact;
|
||||
|
||||
/** @var int $orderCustomerExtId */
|
||||
protected $orderCustomerExtId;
|
||||
|
||||
/** @var BuyerProfile */
|
||||
public $buyerProfile;
|
||||
|
||||
/** @var bool $registerNewUser */
|
||||
protected $registerNewUser;
|
||||
|
||||
/** @var int $registeredUserID */
|
||||
protected $registeredUserID;
|
||||
|
||||
/**@var AddressBuilder */
|
||||
protected $addressBuilder;
|
||||
|
||||
/**@var array $contragentTypes */
|
||||
protected $contragentTypes;
|
||||
|
||||
/**
|
||||
* CorporateCustomerBuilder constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->customer = new Customer();
|
||||
$this->customerBuilder = new CustomerBuilder();
|
||||
$this->customerAddress = new CustomerAddress();
|
||||
$this->buyerProfile = new BuyerProfile();
|
||||
$this->addressBuilder = new AddressBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer $customer
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomer($customer)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Customer
|
||||
*/
|
||||
public function getCustomer()
|
||||
{
|
||||
return $this->customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CustomerBuilder $customerBuilder
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomerBuilder($customerBuilder)
|
||||
{
|
||||
$this->$customerBuilder = $customerBuilder;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CustomerBuilder
|
||||
*/
|
||||
public function getCustomerBuilder()
|
||||
{
|
||||
return $this->customerBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CustomerAddress $customerAddress
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomerAddress($customerAddress)
|
||||
{
|
||||
$this->customerAddress = $customerAddress;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CustomerAddress
|
||||
*/
|
||||
public function getCustomerAddress()
|
||||
{
|
||||
return $this->customerAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dataCrm
|
||||
* @return $this
|
||||
*/
|
||||
public function setDataCrm($dataCrm)
|
||||
{
|
||||
$this->dataCrm = $dataCrm;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $registeredUserID
|
||||
* @return $this
|
||||
*/
|
||||
public function setRegisteredUserID($registeredUserID)
|
||||
{
|
||||
$this->registeredUserID = $registeredUserID;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getRegisterNewUser()
|
||||
{
|
||||
return $this->registerNewUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRegisteredUserID()
|
||||
{
|
||||
return $this->registeredUserID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setOrderCustomerExtId($data)
|
||||
{
|
||||
$this->orderCustomerExtId = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getOrderCustomerExtId()
|
||||
{
|
||||
return $this->orderCustomerExtId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setCorporateContact($data)
|
||||
{
|
||||
$this->corporateContact = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCorporateContact()
|
||||
{
|
||||
return $this->corporateContact;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BuyerProfile
|
||||
*/
|
||||
public function getBuyerProfile()
|
||||
{
|
||||
return $this->buyerProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $contragentTypes
|
||||
* @return $this
|
||||
*/
|
||||
public function setContragentTypes($contragentTypes)
|
||||
{
|
||||
$this->contragentTypes = $contragentTypes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
if (isset($this->dataCrm['contact'])) {
|
||||
$this->customerBuilder->setDataCrm($this->dataCrm['contact'])->build();
|
||||
$this->corporateContact = $this->customerBuilder->getCustomer();
|
||||
$this->customer = $this->customerBuilder->getCustomer();
|
||||
} elseif (isset($this->dataCrm['customer'])) {
|
||||
$this->customerBuilder->setDataCrm($this->dataCrm['customer'])->build();
|
||||
$this->corporateContact = $this->customerBuilder->getCustomer();
|
||||
$this->customer = $this->customerBuilder->getCustomer();
|
||||
} else {
|
||||
$this->corporateContact = null;
|
||||
$this->customer = null;
|
||||
}
|
||||
|
||||
if (isset($this->dataCrm['company']['address'])) {
|
||||
$this->buildAddress();
|
||||
}
|
||||
|
||||
if (isset($this->dataCrm['company'])) {
|
||||
$this->buildBuyerProfile();
|
||||
}
|
||||
}
|
||||
|
||||
public function buildBuyerProfile()
|
||||
{
|
||||
if (RetailCrmOrder::isOrderCorporate($this->dataCrm) && !empty($this->dataCrm['company'])) {
|
||||
$this->buyerProfile->setName($this->dataCrm['company']['name'])
|
||||
->setUserId($this->dataCrm['contact']['externalId'])
|
||||
->setPersonTypeId($this->contragentTypes['legal-entity']);
|
||||
}
|
||||
}
|
||||
|
||||
public function buildAddress()
|
||||
{
|
||||
if (isset($this->dataCrm['company']['address'])) {
|
||||
$this->addressBuilder->setDataCrm($this->dataCrm['company']['address'])->build();
|
||||
$this->customerAddress = $this->addressBuilder->getCustomerAddress();
|
||||
} else {
|
||||
$this->customerAddress = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $login
|
||||
* @return $this
|
||||
*/
|
||||
public function setLogin($login)
|
||||
{
|
||||
$this->customerBuilder->setLogin($login);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $email
|
||||
* @return $this
|
||||
*/
|
||||
public function setEmail($email)
|
||||
{
|
||||
$this->customerBuilder->setEmail($email);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
303
intaro.retailcrm/classes/general/CustomerBuilder.php
Normal file
303
intaro.retailcrm/classes/general/CustomerBuilder.php
Normal file
|
@ -0,0 +1,303 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class CustomerBuilder
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class CustomerBuilder extends AbstractBuilder implements RetailcrmBuilderInterface
|
||||
{
|
||||
/** @var Customer */
|
||||
protected $customer;
|
||||
|
||||
/** @var CustomerAddress */
|
||||
protected $customerAddress;
|
||||
|
||||
/** @var array $dataCrm customerHistory */
|
||||
protected $dataCrm;
|
||||
|
||||
/** @var AddressBuilder */
|
||||
protected $addressBuilder;
|
||||
|
||||
/** @var CUser */
|
||||
protected $user;
|
||||
|
||||
/** @var bool $registerNewUser */
|
||||
protected $registerNewUser;
|
||||
|
||||
/** @var int $registeredUserID */
|
||||
protected $registeredUserID;
|
||||
|
||||
/**
|
||||
* CustomerBuilder constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->customer = new Customer();
|
||||
$this->customerAddress = new CustomerAddress();
|
||||
$this->addressBuilder = new AddressBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer $customer
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomer(Customer $customer)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Customer
|
||||
*/
|
||||
public function getCustomer()
|
||||
{
|
||||
return $this->customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CustomerAddress $customerAddress
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomerAddress($customerAddress): CustomerBuilder
|
||||
{
|
||||
$this->customerAddress = $customerAddress;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CustomerAddress
|
||||
*/
|
||||
public function getCustomerAddress()
|
||||
{
|
||||
return $this->customerAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dataCrm
|
||||
* @return $this
|
||||
*/
|
||||
public function setDataCrm($dataCrm)
|
||||
{
|
||||
$this->dataCrm = $dataCrm;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $user
|
||||
* @return $this
|
||||
*/
|
||||
public function setUser($user)
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $registeredUserID
|
||||
* @return $this
|
||||
*/
|
||||
public function setRegisteredUserID(int $registeredUserID)
|
||||
{
|
||||
$this->registeredUserID = $registeredUserID;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRegisteredUserID()
|
||||
{
|
||||
return $this->registeredUserID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getRegisterNewUser()
|
||||
{
|
||||
return $this->registerNewUser;
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
if (!empty($this->dataCrm['firstName'])) {
|
||||
$this->customer->setName($this->fromJSON($this->dataCrm['firstName']));
|
||||
}
|
||||
|
||||
if (!empty($this->dataCrm['lastName'])) {
|
||||
$this->customer->setLastName($this->fromJSON($this->dataCrm['lastName']));
|
||||
}
|
||||
|
||||
if (!empty($this->dataCrm['patronymic'])) {
|
||||
$this->customer->setSecondName($this->fromJSON($this->dataCrm['patronymic']));
|
||||
}
|
||||
|
||||
if (isset($this->dataCrm['phones'])) {
|
||||
foreach ($this->dataCrm['phones'] as $phone) {
|
||||
if (is_array($this->user) && isset($phone['old_number']) && in_array($phone['old_number'], $this->user)) {
|
||||
$key = array_search($phone['old_number'], $this->user);
|
||||
|
||||
if (isset($phone['number'])) {
|
||||
$this->user[$key] = $phone['number'];
|
||||
} else {
|
||||
$this->user[$key] = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($phone['number'])) {
|
||||
if ((!isset($this->user['PERSONAL_PHONE']) || '' == $this->user['PERSONAL_PHONE'])
|
||||
&& $this->user['PERSONAL_MOBILE'] != $phone['number']
|
||||
) {
|
||||
$this->customer->setPersonalPhone($phone['number']);
|
||||
$this->user['PERSONAL_PHONE'] = $phone['number'];
|
||||
continue;
|
||||
}
|
||||
if ((!isset($this->user['PERSONAL_MOBILE']) || '' == $this->user['PERSONAL_MOBILE'])
|
||||
&& $this->user['PERSONAL_PHONE'] != $phone['number']
|
||||
) {
|
||||
$this->customer->setPersonalMobile($phone['number']);
|
||||
$this->user['PERSONAL_MOBILE'] = $phone['number'];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->dataCrm['address']['index'])) {
|
||||
$this->customer->setPersonalZip($this->fromJSON($this->dataCrm['address']['index']));
|
||||
}
|
||||
|
||||
if (!empty($this->dataCrm['address']['city'])) {
|
||||
$this->customer->setPersonalCity($this->fromJSON($this->dataCrm['address']['city']));
|
||||
}
|
||||
|
||||
if (!empty($this->dataCrm['birthday'])) {
|
||||
$this->customer->setPersonalBirthday($this->fromJSON(
|
||||
date("d.m.Y", strtotime($this->dataCrm['birthday']))
|
||||
));
|
||||
}
|
||||
|
||||
if (!empty($this->dataCrm['email'])) {
|
||||
$this->customer->setEmail($this->fromJSON($this->dataCrm['email']));
|
||||
}
|
||||
|
||||
if (!empty($this->dataCrm['sex'])) {
|
||||
$this->customer->setPersonalGender($this->fromJSON($this->dataCrm['sex']));
|
||||
}
|
||||
|
||||
if ((!isset($this->dataCrm['email']) || $this->dataCrm['email'] == '')
|
||||
&& (!isset($this->dataCrm['externalId']))
|
||||
) {
|
||||
$login = uniqid('user_' . time()) . '@example.com';
|
||||
$this->customer->setLogin($login)
|
||||
->setEmail($login);
|
||||
}
|
||||
|
||||
if (isset($this->dataCrm['address'])) {
|
||||
$this->buildAddress();
|
||||
}
|
||||
|
||||
// клиент считается подписанным при значении равном null
|
||||
if (array_key_exists('emailMarketingUnsubscribedAt', $this->dataCrm)) {
|
||||
if (empty($this->dataCrm['emailMarketingUnsubscribedAt'])) {
|
||||
$this->customer->setSubscribe('Y');
|
||||
} else {
|
||||
$this->customer->setSubscribe('N');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->dataCrm['externalId'])
|
||||
&& (empty($this->dataCrm['firstName'])
|
||||
|| empty($this->dataCrm['email']))
|
||||
) {
|
||||
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
||||
$customerResponse = RCrmActions::apiMethod($api, 'customersGetById', __METHOD__, $this->dataCrm['id']);
|
||||
|
||||
if ($customerResponse instanceof RetailCrm\Response\ApiResponse
|
||||
&& $customerResponse->isSuccessful()
|
||||
&& !empty($customerResponse['customer'])
|
||||
) {
|
||||
$crmCustomer = $customerResponse['customer'];
|
||||
|
||||
if (empty($this->dataCrm['email'])
|
||||
&& !empty($crmCustomer['email'])
|
||||
) {
|
||||
$email = $crmCustomer['email'];
|
||||
|
||||
$this->customer->setEmail($this->fromJSON($email));
|
||||
$this->customer->setLogin($email);
|
||||
}
|
||||
|
||||
if (empty($this->dataCrm['firstName'])
|
||||
&& !empty($crmCustomer['firstName'])
|
||||
) {
|
||||
$this->customer->setName($this->fromJSON($crmCustomer['firstName']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function buildPassword()
|
||||
{
|
||||
$userPassword = uniqid("R");
|
||||
$this->customer->setPassword($userPassword)
|
||||
->setConfirmPassword($userPassword);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildAddress()
|
||||
{
|
||||
if (isset($this->dataCrm['address'])) {
|
||||
$this->addressBuilder->setDataCrm($this->dataCrm['address'])->build();
|
||||
$this->customerAddress = $this->addressBuilder->getCustomerAddress();
|
||||
} else {
|
||||
$this->customerAddress = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $login
|
||||
* @return $this
|
||||
*/
|
||||
public function setLogin(string $login)
|
||||
{
|
||||
$this->customer->setLogin($login);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $email
|
||||
* @return $this
|
||||
*/
|
||||
public function setEmail(string $email)
|
||||
{
|
||||
$this->customer->setEmail($email);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->customer = new Customer();
|
||||
$this->customerAddress = new CustomerAddress();
|
||||
$this->addressBuilder->reset();
|
||||
}
|
||||
}
|
22
intaro.retailcrm/classes/general/Exception/CurlException.php
Normal file
22
intaro.retailcrm/classes/general/Exception/CurlException.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Exception
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Exception;
|
||||
|
||||
/**
|
||||
* Class CurlException
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Exception
|
||||
*/
|
||||
class CurlException extends \RuntimeException
|
||||
{
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Exception
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidJsonException
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Exception
|
||||
*/
|
||||
class InvalidJsonException extends \DomainException
|
||||
{
|
||||
}
|
160
intaro.retailcrm/classes/general/Http/Client.php
Normal file
160
intaro.retailcrm/classes/general/Http/Client.php
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Http
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Http;
|
||||
|
||||
use Intaro\RetailCrm\Component\Constants;
|
||||
use RetailCrm\Exception\CurlException;
|
||||
use RetailCrm\Exception\InvalidJsonException;
|
||||
use RetailCrm\Response\ApiResponse;
|
||||
|
||||
/**
|
||||
* Class Client
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Http
|
||||
*/
|
||||
class Client
|
||||
{
|
||||
const METHOD_GET = 'GET';
|
||||
const METHOD_POST = 'POST';
|
||||
|
||||
protected $url;
|
||||
protected $defaultParameters;
|
||||
protected $retry;
|
||||
|
||||
/**
|
||||
* Client constructor.
|
||||
*
|
||||
* @param string $url api url
|
||||
* @param array $defaultParameters array of parameters
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($url, array $defaultParameters = [])
|
||||
{
|
||||
if (false === stripos($url, 'https://')) {
|
||||
throw new \InvalidArgumentException(
|
||||
'API schema requires HTTPS protocol'
|
||||
);
|
||||
}
|
||||
|
||||
$this->url = $url;
|
||||
$this->defaultParameters = $defaultParameters;
|
||||
$this->retry = 0;
|
||||
$this->curlErrors = [
|
||||
CURLE_COULDNT_RESOLVE_PROXY,
|
||||
CURLE_COULDNT_RESOLVE_HOST,
|
||||
CURLE_COULDNT_CONNECT,
|
||||
CURLE_OPERATION_TIMEOUTED,
|
||||
CURLE_HTTP_POST_ERROR,
|
||||
CURLE_SSL_CONNECT_ERROR,
|
||||
CURLE_SEND_ERROR,
|
||||
CURLE_RECV_ERROR,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Make HTTP request
|
||||
*
|
||||
* @param string $path request url
|
||||
* @param string $method (default: 'GET')
|
||||
* @param array $parameters (default: array())
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws CurlException
|
||||
* @throws InvalidJsonException
|
||||
*
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function makeRequest(
|
||||
$path,
|
||||
$method,
|
||||
array $parameters = []
|
||||
) {
|
||||
$allowedMethods = [self::METHOD_GET, self::METHOD_POST];
|
||||
|
||||
if (!in_array($method, $allowedMethods, false)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf(
|
||||
'Method "%s" is not valid. Allowed methods are %s',
|
||||
$method,
|
||||
implode(', ', $allowedMethods)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$parameters = self::METHOD_GET === $method
|
||||
? array_merge($this->defaultParameters, $parameters, [
|
||||
'cms_source' => 'Bitrix',
|
||||
'cms_version' => SM_VERSION,
|
||||
'php_version' => function_exists('phpversion') ? phpversion() : '',
|
||||
'module_version' => Constants::MODULE_VERSION,
|
||||
])
|
||||
: $parameters = array_merge($this->defaultParameters, $parameters);
|
||||
|
||||
$url = $this->url . $path;
|
||||
|
||||
if (self::METHOD_GET === $method && count($parameters)) {
|
||||
$url .= '?' . http_build_query($parameters, '', '&');
|
||||
}
|
||||
|
||||
$curlHandler = curl_init();
|
||||
curl_setopt($curlHandler, CURLOPT_URL, $url);
|
||||
curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curlHandler, CURLOPT_FAILONERROR, false);
|
||||
curl_setopt($curlHandler, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curlHandler, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($curlHandler, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($curlHandler, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
|
||||
if (self::METHOD_POST === $method) {
|
||||
curl_setopt($curlHandler, CURLOPT_POST, true);
|
||||
curl_setopt($curlHandler, CURLOPT_POSTFIELDS, $parameters);
|
||||
}
|
||||
|
||||
$responseBody = curl_exec($curlHandler);
|
||||
$statusCode = curl_getinfo($curlHandler, CURLINFO_HTTP_CODE);
|
||||
$errno = curl_errno($curlHandler);
|
||||
$error = curl_error($curlHandler);
|
||||
|
||||
curl_close($curlHandler);
|
||||
|
||||
if (
|
||||
$errno
|
||||
&& in_array($errno, $this->curlErrors, false)
|
||||
&& $this->retry < 3
|
||||
) {
|
||||
$errno = null;
|
||||
$error = null;
|
||||
++$this->retry;
|
||||
$this->makeRequest($path, $method, $parameters);
|
||||
}
|
||||
|
||||
if ($errno) {
|
||||
throw new CurlException($error, $errno);
|
||||
}
|
||||
|
||||
return new ApiResponse($statusCode, $responseBody);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry connect
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRetry()
|
||||
{
|
||||
return $this->retry;
|
||||
}
|
||||
}
|
122
intaro.retailcrm/classes/general/Logger.php
Normal file
122
intaro.retailcrm/classes/general/Logger.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Logger
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class Logger
|
||||
{
|
||||
/** @var self $instance */
|
||||
private static $instance;
|
||||
|
||||
/** @var string $logPath */
|
||||
private $logPath;
|
||||
|
||||
/** @var int $files */
|
||||
private $files;
|
||||
|
||||
/**
|
||||
* Get logger instance or re-initialize it with new parameters
|
||||
*
|
||||
* @param string $logPath
|
||||
* @param int $files
|
||||
*
|
||||
* @return \Logger
|
||||
*/
|
||||
public static function getInstance($logPath = '/bitrix/modules/intaro.retailcrm/log', $files = 3)
|
||||
{
|
||||
if (empty(self::$instance)
|
||||
|| (self::$instance instanceof self
|
||||
&& (self::$instance->logPath !== $logPath || self::$instance->files !== $files))
|
||||
) {
|
||||
self::$instance = new Logger($logPath, $files);
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logger constructor.
|
||||
*
|
||||
* @param string $logPath
|
||||
* @param int $files
|
||||
*/
|
||||
public function __construct($logPath = '/bitrix/modules/intaro.retailcrm/log', $files = 3)
|
||||
{
|
||||
$this->logPath = $logPath;
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
public function write($dump, $file = 'info')
|
||||
{
|
||||
$rsSites = CSite::GetList($by, $sort, array('DEFAULT' => 'Y'));
|
||||
$ar = $rsSites->Fetch();
|
||||
|
||||
if (!is_dir($ar['ABS_DOC_ROOT'] . $this->logPath . '/')) {
|
||||
mkdir($ar['ABS_DOC_ROOT'] . $this->logPath . '/');
|
||||
}
|
||||
|
||||
$file = $ar['ABS_DOC_ROOT'] . $this->logPath . '/' . $file . '.log';
|
||||
|
||||
$data['TIME'] = date('Y-m-d H:i:s');
|
||||
$data['DATA'] = $dump;
|
||||
|
||||
$f = fopen($file, "a+");
|
||||
fwrite($f, print_r($data, true));
|
||||
fclose($f);
|
||||
|
||||
// if filesize more than 5 Mb rotate it
|
||||
if (filesize($file) > 5242880) {
|
||||
$this->rotate($file);
|
||||
}
|
||||
}
|
||||
|
||||
private function rotate($file)
|
||||
{
|
||||
$path = pathinfo($file);
|
||||
$rotate = implode('', array(
|
||||
$path['dirname'],
|
||||
'/',
|
||||
$path['filename'],
|
||||
'_',
|
||||
date('Y-m-d_H:i:s'),
|
||||
'.',
|
||||
$path['extension']
|
||||
));
|
||||
|
||||
copy($file, $rotate);
|
||||
$this->clean($file);
|
||||
|
||||
$files = glob($path['dirname'] . '/' . $path['filename'] . "*" . ".log");
|
||||
|
||||
if (0 === $this->files) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count($files) > $this->files) {
|
||||
natsort($files);
|
||||
$files = array_reverse($files);
|
||||
foreach (array_slice($files, $this->files) as $log) {
|
||||
if (is_writable($log)) {
|
||||
unlink($log);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function clean($file)
|
||||
{
|
||||
file_put_contents($file, '');
|
||||
}
|
||||
}
|
50
intaro.retailcrm/classes/general/Model/BaseModel.php
Normal file
50
intaro.retailcrm/classes/general/Model/BaseModel.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class BaseModel
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
*/
|
||||
abstract class BaseModel
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getObjectToArray()
|
||||
{
|
||||
return $this->arrayClear(call_user_func('get_object_vars', $this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @param array $symbols
|
||||
* @return array
|
||||
*/
|
||||
public function arrayClear(array $array, array $symbols = array('', 0, null))
|
||||
{
|
||||
return array_diff($array, $symbols);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $array
|
||||
* @return $this
|
||||
*/
|
||||
public function getArrayToObject($array)
|
||||
{
|
||||
foreach ($array as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
61
intaro.retailcrm/classes/general/Model/BuyerProfile.php
Normal file
61
intaro.retailcrm/classes/general/Model/BuyerProfile.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class BuyerProfile
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
*/
|
||||
class BuyerProfile extends BaseModel
|
||||
{
|
||||
/**@var string $NAME */
|
||||
protected $NAME;
|
||||
|
||||
/**@var string $USER_ID */
|
||||
protected $USER_ID;
|
||||
|
||||
/**@var string $PERSON_TYPE_ID */
|
||||
protected $PERSON_TYPE_ID;
|
||||
|
||||
/**
|
||||
* @param string $NAME
|
||||
* @return $this
|
||||
*/
|
||||
public function setName($NAME)
|
||||
{
|
||||
$this->NAME = $NAME;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $USER_ID
|
||||
* @return $this
|
||||
*/
|
||||
public function setUserId($USER_ID)
|
||||
{
|
||||
$this->USER_ID = $USER_ID;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $PERSON_TYPE_ID
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersonTypeId($PERSON_TYPE_ID)
|
||||
{
|
||||
$this->PERSON_TYPE_ID = $PERSON_TYPE_ID;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
229
intaro.retailcrm/classes/general/Model/Customer.php
Normal file
229
intaro.retailcrm/classes/general/Model/Customer.php
Normal file
|
@ -0,0 +1,229 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Customer
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
*/
|
||||
class Customer extends BaseModel
|
||||
{
|
||||
/**@var string $EMAIL */
|
||||
protected $EMAIL;
|
||||
|
||||
/**@var string $LOGIN */
|
||||
protected $LOGIN;
|
||||
|
||||
/**@var string $ACTIVE */
|
||||
protected $ACTIVE;
|
||||
|
||||
/**@var string $PASSWORD */
|
||||
protected $PASSWORD;
|
||||
|
||||
/**@var string $CONFIRM_PASSWORD */
|
||||
protected $CONFIRM_PASSWORD;
|
||||
|
||||
/**@var string $NAME */
|
||||
protected $NAME;
|
||||
|
||||
/**@var string $LAST_NAME */
|
||||
protected $LAST_NAME;
|
||||
|
||||
/**@var string $SECOND_NAME */
|
||||
protected $SECOND_NAME;
|
||||
|
||||
/**@var string $PERSONAL_MOBILE */
|
||||
protected $PERSONAL_MOBILE;
|
||||
|
||||
/**@var string $PERSONAL_PHONE */
|
||||
protected $PERSONAL_PHONE;
|
||||
|
||||
/**@var string $PERSONAL_ZIP */
|
||||
protected $PERSONAL_ZIP;
|
||||
|
||||
/**@var string $PERSONAL_CITY */
|
||||
protected $PERSONAL_CITY;
|
||||
|
||||
/**@var string $PERSONAL_BIRTHDAY */
|
||||
protected $PERSONAL_BIRTHDAY;
|
||||
|
||||
/**@var string $PERSONAL_GENDER */
|
||||
protected $PERSONAL_GENDER;
|
||||
|
||||
/**@var string $UF_SUBSCRIBE_USER_EMAIL */
|
||||
protected $UF_SUBSCRIBE_USER_EMAIL;
|
||||
|
||||
/**
|
||||
* @param string $EMAIL
|
||||
* @return $this
|
||||
*/
|
||||
public function setEmail($EMAIL)
|
||||
{
|
||||
$this->EMAIL = $EMAIL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $LOGIN
|
||||
* @return $this
|
||||
*/
|
||||
public function setLogin($LOGIN)
|
||||
{
|
||||
$this->LOGIN = $LOGIN;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ACTIVE
|
||||
* @return $this
|
||||
*/
|
||||
public function setActive($ACTIVE)
|
||||
{
|
||||
$this->ACTIVE = $ACTIVE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $PASSWORD
|
||||
* @return $this
|
||||
*/
|
||||
public function setPassword($PASSWORD)
|
||||
{
|
||||
$this->PASSWORD = $PASSWORD;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $CONFIRM_PASSWORD
|
||||
* @return $this
|
||||
*/
|
||||
public function setConfirmPassword($CONFIRM_PASSWORD)
|
||||
{
|
||||
$this->CONFIRM_PASSWORD = $CONFIRM_PASSWORD;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $NAME
|
||||
* @return $this
|
||||
*/
|
||||
public function setName($NAME)
|
||||
{
|
||||
$this->NAME = $NAME;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $LAST_NAME
|
||||
* @return $this
|
||||
*/
|
||||
public function setLastName($LAST_NAME)
|
||||
{
|
||||
$this->LAST_NAME = $LAST_NAME;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $SECOND_NAME
|
||||
* @return $this
|
||||
*/
|
||||
public function setSecondName($SECOND_NAME)
|
||||
{
|
||||
$this->SECOND_NAME = $SECOND_NAME;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $PERSONAL_MOBILE
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersonalMobile($PERSONAL_MOBILE)
|
||||
{
|
||||
$this->PERSONAL_MOBILE = $PERSONAL_MOBILE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $PERSONAL_PHONE
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersonalPhone($PERSONAL_PHONE)
|
||||
{
|
||||
$this->PERSONAL_PHONE = $PERSONAL_PHONE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $PERSONAL_ZIP
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersonalZip($PERSONAL_ZIP)
|
||||
{
|
||||
$this->PERSONAL_ZIP = $PERSONAL_ZIP;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $PERSONAL_CITY
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersonalCity($PERSONAL_CITY)
|
||||
{
|
||||
$this->PERSONAL_CITY = $PERSONAL_CITY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $PERSONAL_BIRTHDAY
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersonalBirthday($PERSONAL_BIRTHDAY)
|
||||
{
|
||||
$this->PERSONAL_BIRTHDAY = $PERSONAL_BIRTHDAY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $PERSONAL_GENDER
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersonalGender($PERSONAL_GENDER)
|
||||
{
|
||||
$this->PERSONAL_GENDER = $PERSONAL_GENDER;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $UF_SUBSCRIBE_USER_EMAIL
|
||||
* @return $this
|
||||
*/
|
||||
public function setSubscribe($UF_SUBSCRIBE_USER_EMAIL)
|
||||
{
|
||||
$this->UF_SUBSCRIBE_USER_EMAIL = $UF_SUBSCRIBE_USER_EMAIL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
216
intaro.retailcrm/classes/general/Model/CustomerAddress.php
Normal file
216
intaro.retailcrm/classes/general/Model/CustomerAddress.php
Normal file
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class CustomerAddress
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
*/
|
||||
class CustomerAddress extends BaseModel
|
||||
{
|
||||
/**@var string $index */
|
||||
protected $index;
|
||||
|
||||
/**@var string $country */
|
||||
protected $country;
|
||||
|
||||
/**@var string $region */
|
||||
protected $region;
|
||||
|
||||
/**@var string $city */
|
||||
protected $city;
|
||||
|
||||
/**@var string $street */
|
||||
protected $street;
|
||||
|
||||
/**@var string $building */
|
||||
protected $building;
|
||||
|
||||
/**@var string $house */
|
||||
protected $house;
|
||||
|
||||
/**@var string $block */
|
||||
protected $block;
|
||||
|
||||
/**@var string $flat */
|
||||
protected $flat;
|
||||
|
||||
/**@var string $floor */
|
||||
protected $floor;
|
||||
|
||||
/**@var string $intercomCode */
|
||||
protected $intercomCode;
|
||||
|
||||
/**@var string $metro */
|
||||
protected $metro;
|
||||
|
||||
/**@var string $notes */
|
||||
protected $notes;
|
||||
|
||||
/**@var string $text */
|
||||
protected $text;
|
||||
|
||||
/**
|
||||
* @param string $index
|
||||
* @return $this
|
||||
*/
|
||||
public function setIndex($index)
|
||||
{
|
||||
$this->index = $index;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $country
|
||||
* @return $this
|
||||
*/
|
||||
public function setCountry($country)
|
||||
{
|
||||
$this->country = $country;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $region
|
||||
* @return $this
|
||||
*/
|
||||
public function setRegion($region)
|
||||
{
|
||||
$this->region = $region;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $city
|
||||
* @return $this
|
||||
*/
|
||||
public function setCity($city)
|
||||
{
|
||||
$this->city = $city;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $street
|
||||
* @return $this
|
||||
*/
|
||||
public function setStreet($street)
|
||||
{
|
||||
$this->street = $street;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $building
|
||||
* @return $this
|
||||
*/
|
||||
public function setBuilding($building)
|
||||
{
|
||||
$this->building = $building;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $house
|
||||
* @return $this
|
||||
*/
|
||||
public function setHouse($house)
|
||||
{
|
||||
$this->house = $house;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $block
|
||||
* @return $this
|
||||
*/
|
||||
public function setBlock($block)
|
||||
{
|
||||
$this->block = $block;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $flat
|
||||
* @return $this
|
||||
*/
|
||||
public function setFlat($flat)
|
||||
{
|
||||
$this->flat = $flat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $floor
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFloor(?string $floor): CustomerAddress
|
||||
{
|
||||
$this->floor = $floor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $intercomCode
|
||||
* @return $this
|
||||
*/
|
||||
public function setIntercomCode($intercomCode)
|
||||
{
|
||||
$this->intercomCode = $intercomCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $metro
|
||||
* @return $this
|
||||
*/
|
||||
public function setMetro($metro)
|
||||
{
|
||||
$this->metro = $metro;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $notes
|
||||
* @return $this
|
||||
*/
|
||||
public function setNotes($notes)
|
||||
{
|
||||
$this->notes = $notes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @return $this
|
||||
*/
|
||||
public function setText($text)
|
||||
{
|
||||
$this->text = $text;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
145
intaro.retailcrm/classes/general/Model/CustomerContragent.php
Normal file
145
intaro.retailcrm/classes/general/Model/CustomerContragent.php
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class CustomerContragent
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Model
|
||||
*/
|
||||
class CustomerContragent extends BaseModel
|
||||
{
|
||||
/**@var string $contragentType */
|
||||
protected $contragentType;
|
||||
|
||||
/**@var string $legalName */
|
||||
protected $legalName;
|
||||
|
||||
/**@var string $legalAddress */
|
||||
protected $legalAddress;
|
||||
|
||||
/**@var string $certificateNumber */
|
||||
protected $certificateNumber;
|
||||
|
||||
/**@var string $certificateDate */
|
||||
protected $certificateDate;
|
||||
|
||||
/**@var string $bank */
|
||||
protected $bank;
|
||||
|
||||
/**@var string $bankAddress */
|
||||
protected $bankAddress;
|
||||
|
||||
/**@var string $corrAccount */
|
||||
protected $corrAccount;
|
||||
|
||||
/**@var string $bankAccount */
|
||||
protected $bankAccount;
|
||||
|
||||
/**
|
||||
* @param string $contragentType
|
||||
* @return $this
|
||||
*/
|
||||
public function setContragentType($contragentType)
|
||||
{
|
||||
$this->contragentType = $contragentType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $legalName
|
||||
* @return $this
|
||||
*/
|
||||
public function setLegalName($legalName)
|
||||
{
|
||||
$this->legalName = $legalName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $legalAddress
|
||||
* @return $this
|
||||
*/
|
||||
public function setLegalAddress($legalAddress)
|
||||
{
|
||||
$this->legalAddress = $legalAddress;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $certificateNumber
|
||||
* @return $this
|
||||
*/
|
||||
public function setCertificateNumber($certificateNumber)
|
||||
{
|
||||
$this->certificateNumber = $certificateNumber;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $certificateDate
|
||||
* @return $this
|
||||
*/
|
||||
public function setCertificateDate($certificateDate)
|
||||
{
|
||||
$this->certificateDate = $certificateDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bank
|
||||
* @return $this
|
||||
*/
|
||||
public function setBank($bank)
|
||||
{
|
||||
$this->bank = $bank;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bankAddress
|
||||
* @return $this
|
||||
*/
|
||||
public function setBankAddress($bankAddress)
|
||||
{
|
||||
$this->bankAddress = $bankAddress;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $corrAccount
|
||||
* @return $this
|
||||
*/
|
||||
public function setCorrAccount($corrAccount)
|
||||
{
|
||||
$this->corrAccount = $corrAccount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bankAccount
|
||||
* @return $this
|
||||
*/
|
||||
public function setBankAccount($bankAccount)
|
||||
{
|
||||
$this->bankAccount = $bankAccount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
894
intaro.retailcrm/classes/general/RCrmActions.php
Normal file
894
intaro.retailcrm/classes/general/RCrmActions.php
Normal file
|
@ -0,0 +1,894 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
use Bitrix\Sale\PersonType;
|
||||
use Intaro\RetailCrm\Component\ServiceLocator;
|
||||
use Bitrix\Sale\Delivery\Services\EmptyDeliveryService;
|
||||
use Bitrix\Sale\Internals\OrderPropsTable;
|
||||
use Bitrix\Sale\Internals\StatusTable;
|
||||
use Bitrix\Sale\PaySystem\Manager;
|
||||
use Intaro\RetailCrm\Service\Utils;
|
||||
use RetailCrm\Exception\CurlException;
|
||||
use RetailCrm\Exception\InvalidJsonException;
|
||||
use Intaro\RetailCrm\Service\ManagerService;
|
||||
use Bitrix\Main\UserFieldTable;
|
||||
use Bitrix\Main\UserFieldLangTable;
|
||||
use Bitrix\Sale\Internals\SiteCurrencyTable;
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
require_once __DIR__ . '/../../lib/component/servicelocator.php';
|
||||
require_once __DIR__ . '/../../lib/service/utils.php';
|
||||
|
||||
/**
|
||||
* class RCrmActions
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class RCrmActions
|
||||
{
|
||||
public static $MODULE_ID = 'intaro.retailcrm';
|
||||
public static $CRM_ORDER_FAILED_IDS = 'order_failed_ids';
|
||||
public static $CRM_API_VERSION = 'api_version';
|
||||
|
||||
public static function getCurrencySites(): array
|
||||
{
|
||||
$sites = self::getSitesList();
|
||||
$baseCurrency = CCurrency::GetBaseCurrency();
|
||||
$sitesCurrency = [];
|
||||
|
||||
foreach ($sites as $site) {
|
||||
$siteCurrency = SiteCurrencyTable::getCurrency($site['LID']);
|
||||
|
||||
$sitesCurrency[$site['LID']] = !empty($siteCurrency['CURRENCY'])
|
||||
? $siteCurrency['CURRENCY']
|
||||
: $baseCurrency;
|
||||
}
|
||||
|
||||
return $sitesCurrency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getSitesList(): array
|
||||
{
|
||||
$arSites = [];
|
||||
$rsSites = CSite::GetList($by, $sort, ['ACTIVE' => 'Y']);
|
||||
|
||||
while ($ar = $rsSites->Fetch()) {
|
||||
$arSites[] = $ar;
|
||||
}
|
||||
|
||||
return $arSites;
|
||||
}
|
||||
|
||||
public static function OrderTypesList($arSites)
|
||||
{
|
||||
$orderTypesList = [];
|
||||
|
||||
foreach ($arSites as $site) {
|
||||
$personTypes = PersonType::load($site['LID']);
|
||||
$bitrixOrderTypesList = [];
|
||||
|
||||
foreach ($personTypes as $personType) {
|
||||
if (!array_key_exists($personType['ID'], $orderTypesList)) {
|
||||
$bitrixOrderTypesList[$personType['ID']] = $personType;
|
||||
}
|
||||
|
||||
asort($bitrixOrderTypesList);
|
||||
}
|
||||
|
||||
$orderTypesList += $bitrixOrderTypesList;
|
||||
}
|
||||
|
||||
return $orderTypesList;
|
||||
}
|
||||
|
||||
public static function DeliveryList()
|
||||
{
|
||||
$bitrixDeliveryTypesList = [];
|
||||
$arDeliveryServiceAll = \Bitrix\Sale\Delivery\Services\Manager::getActiveList();
|
||||
$noOrderId = EmptyDeliveryService::getEmptyDeliveryServiceId();
|
||||
$groups = [];
|
||||
|
||||
foreach ($arDeliveryServiceAll as $arDeliveryService) {
|
||||
if ($arDeliveryService['CLASS_NAME'] == '\Bitrix\Sale\Delivery\Services\Group') {
|
||||
$groups[] = $arDeliveryService['ID'];
|
||||
}
|
||||
}
|
||||
foreach ($arDeliveryServiceAll as $arDeliveryService) {
|
||||
if ((($arDeliveryService['PARENT_ID'] == '0' || $arDeliveryService['PARENT_ID'] == null) ||
|
||||
in_array($arDeliveryService['PARENT_ID'], $groups)) &&
|
||||
$arDeliveryService['ID'] != $noOrderId &&
|
||||
$arDeliveryService['CLASS_NAME'] != '\Bitrix\Sale\Delivery\Services\Group') {
|
||||
if (in_array($arDeliveryService['PARENT_ID'], $groups)) {
|
||||
$arDeliveryService['PARENT_ID'] = 0;
|
||||
}
|
||||
$bitrixDeliveryTypesList[] = $arDeliveryService;
|
||||
}
|
||||
}
|
||||
|
||||
return $bitrixDeliveryTypesList;
|
||||
}
|
||||
|
||||
public static function PaymentList()
|
||||
{
|
||||
$bitrixPaymentTypesList = [];
|
||||
$dbPaymentAll = Manager::getList(['select' => ['ID', 'NAME'], 'filter' => ['ACTIVE' => 'Y']]);
|
||||
|
||||
while ($payment = $dbPaymentAll->fetch()) {
|
||||
$bitrixPaymentTypesList[] = $payment;
|
||||
}
|
||||
|
||||
return $bitrixPaymentTypesList;
|
||||
}
|
||||
|
||||
public static function StatusesList()
|
||||
{
|
||||
$bitrixPaymentStatusesList = [];
|
||||
$obStatuses = StatusTable::getList([
|
||||
'filter' => ['TYPE' => 'O', '=Bitrix\Sale\Internals\StatusLangTable:STATUS.LID' => LANGUAGE_ID],
|
||||
'select' => ['ID', 'NAME' => 'Bitrix\Sale\Internals\StatusLangTable:STATUS.NAME'],
|
||||
]);
|
||||
|
||||
while ($arStatus = $obStatuses->fetch()) {
|
||||
$bitrixPaymentStatusesList[$arStatus['ID']] = ['ID' => $arStatus['ID'], 'NAME' => $arStatus['NAME']];
|
||||
}
|
||||
|
||||
return $bitrixPaymentStatusesList;
|
||||
}
|
||||
|
||||
public static function OrderPropsList()
|
||||
{
|
||||
$bitrixPropsList = [];
|
||||
$arPropsAll = OrderPropsTable::getList([
|
||||
'select' => ['*'],
|
||||
'filter' => [
|
||||
['CODE' => '_%'],
|
||||
['!=TYPE' => 'LOCATION']
|
||||
]
|
||||
]);
|
||||
|
||||
while ($prop = $arPropsAll->Fetch()) {
|
||||
$bitrixPropsList[$prop['PERSON_TYPE_ID']][] = $prop;
|
||||
}
|
||||
|
||||
return $bitrixPropsList;
|
||||
}
|
||||
|
||||
public static function getLocationProps()
|
||||
{
|
||||
$bitrixPropsList = [];
|
||||
$arPropsAll = OrderPropsTable::getList([
|
||||
'select' => ['*'],
|
||||
'filter' => [
|
||||
['CODE' => '_%'],
|
||||
['TYPE' => 'LOCATION']
|
||||
]
|
||||
]);
|
||||
|
||||
while ($prop = $arPropsAll->Fetch()) {
|
||||
$bitrixPropsList[$prop['PERSON_TYPE_ID']][] = $prop;
|
||||
}
|
||||
|
||||
return $bitrixPropsList;
|
||||
}
|
||||
|
||||
public static function PricesExportList()
|
||||
{
|
||||
$catalogExportPrices = [];
|
||||
$dbPriceType = CCatalogGroup::GetList([], [], false, false, ['ID', 'NAME', 'NAME_LANG']);
|
||||
|
||||
while ($arPriceType = $dbPriceType->Fetch())
|
||||
{
|
||||
$catalogExportPrices[$arPriceType['ID']] = $arPriceType;
|
||||
}
|
||||
|
||||
return $catalogExportPrices;
|
||||
}
|
||||
|
||||
public static function StoresExportList()
|
||||
{
|
||||
$catalogExportStores = [];
|
||||
$dbStores = CCatalogStore::GetList([], ['ACTIVE' => 'Y'], false, false, ['ID', 'TITLE']);
|
||||
|
||||
while ($stores = $dbStores->Fetch()) {
|
||||
$catalogExportStores[] = $stores;
|
||||
}
|
||||
|
||||
return $catalogExportStores;
|
||||
}
|
||||
|
||||
public static function IblocksExportList()
|
||||
{
|
||||
$catalogExportIblocks = [];
|
||||
$dbIblocks = CIBlock::GetList(['IBLOCK_TYPE' => 'ASC', 'NAME' => 'ASC'], ['CHECK_PERMISSIONS' => 'Y', 'MIN_PERMISSION' => 'W']);
|
||||
|
||||
while ($iblock = $dbIblocks->Fetch()) {
|
||||
if ($arCatalog = CCatalog::GetByIDExt($iblock['ID'])) {
|
||||
if($arCatalog['CATALOG_TYPE'] == 'D' || $arCatalog['CATALOG_TYPE'] == 'X' || $arCatalog['CATALOG_TYPE'] == 'P') {
|
||||
$catalogExportIblocks[$iblock['ID']] = [
|
||||
'ID' => $iblock['ID'],
|
||||
'IBLOCK_TYPE_ID' => $iblock['IBLOCK_TYPE_ID'],
|
||||
'LID' => $iblock['LID'],
|
||||
'CODE' => $iblock['CODE'],
|
||||
'NAME' => $iblock['NAME'],
|
||||
];
|
||||
|
||||
if ($arCatalog['CATALOG_TYPE'] == 'X' || $arCatalog['CATALOG_TYPE'] == 'P') {
|
||||
$iblockOffer = CCatalogSKU::GetInfoByProductIBlock($iblock['ID']);
|
||||
$catalogExportIblocks[$iblock['ID']]['SKU'] = $iblockOffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $catalogExportIblocks;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* w+ event in bitrix log
|
||||
*/
|
||||
|
||||
public static function eventLog($auditType, $itemId, $description)
|
||||
{
|
||||
CEventLog::Add([
|
||||
'SEVERITY' => 'SECURITY',
|
||||
'AUDIT_TYPE_ID' => $auditType,
|
||||
'MODULE_ID' => self::$MODULE_ID,
|
||||
'ITEM_ID' => $itemId,
|
||||
'DESCRIPTION' => $description,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Agent function
|
||||
*
|
||||
* @return self name
|
||||
*/
|
||||
public static function uploadOrdersAgent()
|
||||
{
|
||||
RetailCrmOrder::uploadOrders();
|
||||
$failedIds = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_FAILED_IDS, 0));
|
||||
|
||||
if (is_array($failedIds) && !empty($failedIds)) {
|
||||
RetailCrmOrder::uploadOrders(50, true);
|
||||
}
|
||||
|
||||
return 'RCrmActions::uploadOrdersAgent();';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Agent function
|
||||
*
|
||||
* @return self name
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public static function orderAgent()
|
||||
{
|
||||
if (COption::GetOptionString('main', 'agents_use_crontab', 'N') !== 'N') {
|
||||
define('NO_AGENT_CHECK', true);
|
||||
}
|
||||
|
||||
try {
|
||||
$service = ManagerService::getInstance();
|
||||
$service->synchronizeManagers();
|
||||
|
||||
RetailCrmHistory::customerHistory();
|
||||
RetailCrmHistory::orderHistory();
|
||||
} catch (\Throwable $exception) {
|
||||
Logger::getInstance()->write(
|
||||
'Fail orderAgent:' . PHP_EOL .
|
||||
$exception->getMessage() . PHP_EOL .
|
||||
'File: ' . $exception->getFile() . PHP_EOL .
|
||||
'Line: ' . $exception->getLine() . PHP_EOL,
|
||||
'orderAgent'
|
||||
);
|
||||
}
|
||||
|
||||
return 'RCrmActions::orderAgent();';
|
||||
}
|
||||
|
||||
/**
|
||||
* removes all empty fields from arrays
|
||||
* working with nested arrs
|
||||
*
|
||||
* @param array $arr
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function clearArr(array $arr): array
|
||||
{
|
||||
/** @var Utils $utils */
|
||||
$utils = ServiceLocator::getOrCreate(Utils::class);
|
||||
|
||||
return $utils->clearArray($arr);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array|bool|\SplFixedArray|string $str in SITE_CHARSET
|
||||
*
|
||||
* @return array|bool|\SplFixedArray|string $str in utf-8
|
||||
*/
|
||||
public static function toJSON($str)
|
||||
{
|
||||
/** @var Utils $utils */
|
||||
$utils = ServiceLocator::getOrCreate(Utils::class);
|
||||
|
||||
return $utils->toUTF8($str);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string|array|\SplFixedArray $str in utf-8
|
||||
*
|
||||
* @return array|bool|\SplFixedArray|string $str in SITE_CHARSET
|
||||
*/
|
||||
public static function fromJSON($str)
|
||||
{
|
||||
if ($str === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/** @var Utils $utils */
|
||||
$utils = ServiceLocator::getOrCreate(Utils::class);
|
||||
|
||||
return $utils->fromUTF8($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts payment ID or client ID from payment externalId
|
||||
* Payment ID - pass nothing or 'id' as second argument
|
||||
* Client ID - pass 'client_id' as second argument
|
||||
*
|
||||
* @param $externalId
|
||||
* @param string $data
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function getFromPaymentExternalId($externalId, $data = 'id')
|
||||
{
|
||||
switch ($data) {
|
||||
case 'id':
|
||||
if (false === strpos($externalId, '_')) {
|
||||
return $externalId;
|
||||
} else {
|
||||
return substr($externalId, 0, strpos($externalId, '_'));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'client_id':
|
||||
if (false === strpos($externalId, '_')) {
|
||||
return '';
|
||||
} else {
|
||||
return substr($externalId, strpos($externalId, '_'), count($externalId));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if provided externalId in new format (id_clientId)
|
||||
*
|
||||
* @param $externalId
|
||||
* @return bool
|
||||
*/
|
||||
public static function isNewExternalId($externalId)
|
||||
{
|
||||
return !(false === strpos($externalId, '_'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates payment external ID
|
||||
*
|
||||
* @param $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generatePaymentExternalId($id)
|
||||
{
|
||||
return sprintf(
|
||||
'%s_%s',
|
||||
$id,
|
||||
COption::GetOptionString(self::$MODULE_ID, 'client_id', 0)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialize array
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function unserializeArrayRecursive($string)
|
||||
{
|
||||
if ($string === false || empty($string)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_string($string)) {
|
||||
$string = unserialize($string);
|
||||
}
|
||||
|
||||
if (!is_array($string)) {
|
||||
$string = self::unserializeArrayRecursive($string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $fio
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function explodeFio(?string $fio): array
|
||||
{
|
||||
$result = [];
|
||||
$fio = preg_replace('|[\s]+|s', ' ', trim($fio));
|
||||
|
||||
if (empty($fio)) {
|
||||
return $result;
|
||||
} else {
|
||||
$newFio = explode(' ', $fio, 3);
|
||||
}
|
||||
|
||||
switch (count($newFio)) {
|
||||
default:
|
||||
case 0:
|
||||
$result['firstName'] = $fio;
|
||||
break;
|
||||
case 1:
|
||||
$result['firstName'] = $newFio[0];
|
||||
break;
|
||||
case 2:
|
||||
$result = [
|
||||
'lastName' => $newFio[0],
|
||||
'firstName' => $newFio[1],
|
||||
];
|
||||
break;
|
||||
case 3:
|
||||
$result = [
|
||||
'lastName' => $newFio[0],
|
||||
'firstName' => $newFio[1],
|
||||
'patronymic' => $newFio[2],
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function customOrderPropList()
|
||||
{
|
||||
$typeMatched = [
|
||||
'STRING' => 'STRING',
|
||||
'NUMBER' => 'NUMERIC',
|
||||
'Y/N' => 'BOOLEAN',
|
||||
'DATE' => 'DATE'
|
||||
];
|
||||
|
||||
//Базовые свойства заказа и используемые свойства в функционале модуля
|
||||
$bannedCodeList = [
|
||||
'FIO',
|
||||
'EMAIL',
|
||||
'PHONE',
|
||||
'ZIP',
|
||||
'CITY',
|
||||
'LOCATION',
|
||||
'ADDRESS',
|
||||
'COMPANY',
|
||||
'COMPANY_ADR',
|
||||
'INN',
|
||||
'KPP',
|
||||
'CONTACT_PERSON',
|
||||
'FAX',
|
||||
'LP_BONUS_INFO',
|
||||
'LP_DISCOUNT_INFO',
|
||||
''
|
||||
];
|
||||
|
||||
$listPersons = PersonType::getList([
|
||||
'select' => ['ID', 'NAME'],
|
||||
'filter' => ['ENTITY_REGISTRY_TYPE' => 'ORDER']
|
||||
])->fetchAll();
|
||||
|
||||
$persons = [];
|
||||
|
||||
foreach ($listPersons as $person) {
|
||||
$persons[$person['ID']] = $person['NAME'];
|
||||
}
|
||||
|
||||
$propsList = OrderPropsTable::getList([
|
||||
'select' => ['ID', 'CODE', 'NAME', 'PERSON_TYPE_ID', 'TYPE'],
|
||||
'filter' => [
|
||||
['!=CODE' => $bannedCodeList],
|
||||
['?TYPE' => 'STRING | NUMBER | Y/N | DATE'],
|
||||
['MULTIPLE' => 'N'],
|
||||
['ACTIVE' => 'Y']
|
||||
]
|
||||
])->fetchAll();
|
||||
|
||||
$resultList = [];
|
||||
|
||||
foreach ($propsList as $prop) {
|
||||
$type = $typeMatched[$prop['TYPE']] ?? $prop['TYPE'];
|
||||
$key = $prop['ID'] . '#' . $prop['CODE'];
|
||||
$resultList[$type . '_TYPE'][$key] = $prop['NAME'] . ' (' . $persons[$prop['PERSON_TYPE_ID']] . ')';
|
||||
}
|
||||
|
||||
ksort($resultList);
|
||||
|
||||
return $resultList;
|
||||
}
|
||||
|
||||
public static function customUserFieldList()
|
||||
{
|
||||
$typeMatched = [
|
||||
'string' => 'STRING',
|
||||
'double' => 'NUMERIC',
|
||||
'boolean' => 'BOOLEAN',
|
||||
'date' => 'DATE',
|
||||
'integer' => 'INTEGER'
|
||||
];
|
||||
|
||||
$userFields = UserFieldTable::getList([
|
||||
'select' => ['ID', 'FIELD_NAME', 'USER_TYPE_ID'],
|
||||
'filter' => [
|
||||
['ENTITY_ID' => 'USER'],
|
||||
['?FIELD_NAME' => '~%INTARO%'],
|
||||
['!=FIELD_NAME' => 'UF_SUBSCRIBE_USER_EMAIL'],
|
||||
['!=USER_TYPE_ID' => 'datetime'],
|
||||
['?USER_TYPE_ID' => 'string | date | integer | double | boolean'],
|
||||
['MULTIPLE' => 'N'],
|
||||
]
|
||||
])->fetchAll();
|
||||
|
||||
$resultList = [];
|
||||
|
||||
foreach ($userFields as $userField) {
|
||||
$label = UserFieldLangTable::getList([
|
||||
'select' => ['EDIT_FORM_LABEL'],
|
||||
'filter' => [
|
||||
["USER_FIELD_ID" => $userField['ID']],
|
||||
['LANGUAGE_ID' => LANGUAGE_ID]
|
||||
]
|
||||
])->fetch();
|
||||
|
||||
$type = $typeMatched[$userField['USER_TYPE_ID']] ?? $userField['USER_TYPE_ID'];
|
||||
$resultList[$type . '_TYPE'][$userField['FIELD_NAME']] = $label['EDIT_FORM_LABEL'];
|
||||
}
|
||||
|
||||
ksort($resultList);
|
||||
|
||||
return $resultList;
|
||||
}
|
||||
|
||||
public static function getTypeUserField()
|
||||
{
|
||||
$userFields = UserFieldTable::getList([
|
||||
'select' => ['FIELD_NAME', 'USER_TYPE_ID'],
|
||||
'filter' => [
|
||||
['ENTITY_ID' => 'USER'],
|
||||
['?FIELD_NAME' => '~%INTARO%'],
|
||||
['!=FIELD_NAME' => 'UF_SUBSCRIBE_USER_EMAIL'],
|
||||
['?USER_TYPE_ID' => 'string | date | datetime | integer | double | boolean'],
|
||||
['MULTIPLE' => 'N'],
|
||||
]
|
||||
])->fetchAll();
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($userFields as $userField) {
|
||||
$result[$userField['FIELD_NAME']] = $userField['USER_TYPE_ID'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function convertCmsFieldToCrmValue($value, $type)
|
||||
{
|
||||
$result = $value;
|
||||
|
||||
switch ($type) {
|
||||
case 'boolean':
|
||||
$result = $value === '1' ? 1 : 0;
|
||||
break;
|
||||
case 'Y/N':
|
||||
$result = $result === 'Y' ? 1 : 0;
|
||||
break;
|
||||
case 'STRING':
|
||||
case 'string':
|
||||
$result = strlen($value) <= 500 ? $value : '';
|
||||
break;
|
||||
case 'datetime':
|
||||
$result = date('Y-m-d', strtotime($value));
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function convertCrmValueToCmsField($crmValue, $type)
|
||||
{
|
||||
$result = $crmValue;
|
||||
|
||||
switch ($type) {
|
||||
case 'Y/N':
|
||||
case 'boolean':
|
||||
$result = $crmValue == 1 ? 'Y' : 'N';
|
||||
break;
|
||||
case 'DATE':
|
||||
case 'date':
|
||||
if (empty($crmValue)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
$result = date('d.m.Y', strtotime($crmValue));
|
||||
} catch (\Exception $exception) {
|
||||
$result = '';
|
||||
}
|
||||
|
||||
break;
|
||||
case 'STRING':
|
||||
case 'string':
|
||||
case 'text':
|
||||
$result = strlen($crmValue) <= 500 ? $crmValue : '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function sendConfiguration($api, $active = true)
|
||||
{
|
||||
$scheme = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
|
||||
$baseUrl = $scheme . $_SERVER['HTTP_HOST'];
|
||||
$integrationCode = 'bitrix';
|
||||
$logo = 'https://s3.eu-central-1.amazonaws.com/retailcrm-billing/images/5af47fe682bf2-1c-bitrix-logo.svg';
|
||||
$accountUrl = $baseUrl . '/bitrix/admin';
|
||||
|
||||
$clientId = COption::GetOptionString(self::$MODULE_ID, 'client_id', 0);
|
||||
|
||||
if (!$clientId) {
|
||||
$clientId = uniqid();
|
||||
|
||||
COption::SetOptionString(self::$MODULE_ID, 'client_id', $clientId);
|
||||
}
|
||||
|
||||
$code = $integrationCode . '-' . $clientId;
|
||||
|
||||
$configuration = [
|
||||
'clientId' => $clientId,
|
||||
'code' => $code,
|
||||
'integrationCode' => $integrationCode,
|
||||
'active' => $active,
|
||||
'name' => GetMessage('API_MODULE_NAME'),
|
||||
'logo' => $logo,
|
||||
'baseUrl' => $baseUrl,
|
||||
'accountUrl' => $accountUrl
|
||||
];
|
||||
|
||||
self::apiMethod($api, 'integrationModulesEdit', __METHOD__, $configuration);
|
||||
}
|
||||
|
||||
public static function apiMethod($api, $methodApi, $method, $params, $site = null)
|
||||
{
|
||||
switch ($methodApi) {
|
||||
case 'ordersPaymentDelete':
|
||||
case 'ordersHistory':
|
||||
case 'customerHistory':
|
||||
case 'ordersFixExternalIds':
|
||||
case 'customersFixExternalIds':
|
||||
case 'customersCorporateContacts':
|
||||
case 'customersList':
|
||||
case 'customersCorporateList':
|
||||
return self::proxy($api, $methodApi, $method, [$params]);
|
||||
case 'orderGet':
|
||||
return self::proxy($api, 'ordersGet', $method, [$params, 'id', $site]);
|
||||
|
||||
case 'ordersGet':
|
||||
case 'ordersEdit':
|
||||
case 'customersGet':
|
||||
case 'customersEdit':
|
||||
case 'customersCorporateGet':
|
||||
return self::proxy($api, $methodApi, $method, [$params, 'externalId', $site]);
|
||||
case 'customersCorporateGetById':
|
||||
return self::proxy($api, 'customersCorporateGet', $method, [$params, 'id', $site]);
|
||||
case 'customersGetById':
|
||||
return self::proxy($api, 'customersGet', $method, [$params, 'id', $site]);
|
||||
|
||||
case 'paymentEditById':
|
||||
return self::proxy($api, 'ordersPaymentEdit', $method, [$params, 'id', $site]);
|
||||
|
||||
case 'paymentEditByExternalId':
|
||||
return self::proxy($api, 'ordersPaymentEdit', $method, [$params, 'externalId', $site]);
|
||||
case 'customersCorporateEdit':
|
||||
return self::proxy($api, 'customersCorporateEdit', $method, [$params, 'externalId', $site]);
|
||||
case 'cartGet':
|
||||
return self::proxy($api, $methodApi, $method, [$params, $site, 'externalId']);
|
||||
case 'cartSet':
|
||||
case 'cartClear':
|
||||
return self::proxy($api, $methodApi, $method, [$params, $site]);
|
||||
default:
|
||||
return self::proxy($api, $methodApi, $method, [$params, $site]);
|
||||
}
|
||||
}
|
||||
|
||||
private static function proxy($api, $methodApi, $method, $params) {
|
||||
$version = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_VERSION, 0);
|
||||
try {
|
||||
$result = call_user_func_array([$api, $methodApi], $params);
|
||||
|
||||
if (!$result) {
|
||||
$err = new RuntimeException(
|
||||
$methodApi . ': Got null instead of valid result!'
|
||||
);
|
||||
Logger::getInstance()->write(sprintf(
|
||||
'%s%s%s',
|
||||
$err->getMessage(),
|
||||
PHP_EOL,
|
||||
$err->getTraceAsString()
|
||||
), 'apiErrors');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($result->getStatusCode() !== 200 && $result->getStatusCode() !== 201) {
|
||||
if ($methodApi == 'ordersGet'
|
||||
|| $methodApi == 'customersGet'
|
||||
|| $methodApi == 'customersCorporateGet'
|
||||
) {
|
||||
Logger::getInstance()->write([
|
||||
'api' => $version,
|
||||
'methodApi' => $methodApi,
|
||||
'errorMsg' => !empty($result['errorMsg']) ? $result['errorMsg'] : '',
|
||||
'errors' => !empty($result['errors']) ? $result['errors'] : '',
|
||||
'params' => $params
|
||||
], 'apiErrors');
|
||||
} elseif ($methodApi == 'customersUpload' || $methodApi == 'ordersUpload') {
|
||||
Logger::getInstance()->write([
|
||||
'api' => $version,
|
||||
'methodApi' => $methodApi,
|
||||
'errorMsg' => !empty($result['errorMsg']) ? $result['errorMsg'] : '',
|
||||
'errors' => !empty($result['errors']) ? $result['errors'] : '',
|
||||
'params' => $params
|
||||
], 'uploadApiErrors');
|
||||
} elseif ($methodApi == 'cartGet') {
|
||||
Logger::getInstance()->write(
|
||||
[
|
||||
'api' => $version,
|
||||
'methodApi' => $methodApi,
|
||||
'errorMsg' => !empty($result['errorMsg']) ? $result['errorMsg'] : '',
|
||||
'errors' => !empty($result['errors']) ? $result['errors'] : '',
|
||||
'params' => $params,
|
||||
],
|
||||
'apiErrors'
|
||||
);
|
||||
} else {
|
||||
self::eventLog(
|
||||
__CLASS__ . '::' . $method,
|
||||
'RetailCrm\ApiClient::' . $methodApi,
|
||||
!empty($result['errorMsg']) ? $result['errorMsg'] : ''
|
||||
);
|
||||
|
||||
Logger::getInstance()->write([
|
||||
'api' => $version,
|
||||
'methodApi' => $methodApi,
|
||||
'errorMsg' => !empty($result['errorMsg']) ? $result['errorMsg'] : '',
|
||||
'errors' => !empty($result['errors']) ? $result['errors'] : '',
|
||||
'params' => $params,
|
||||
], 'apiErrors');
|
||||
}
|
||||
|
||||
if (function_exists('retailCrmApiResult')) {
|
||||
retailCrmApiResult($methodApi, false, $result->getStatusCode());
|
||||
}
|
||||
|
||||
if ($result->getStatusCode() == 460) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} catch (CurlException $e) {
|
||||
static::logException(
|
||||
$method,
|
||||
$methodApi,
|
||||
'CurlException',
|
||||
'CurlException',
|
||||
$e,
|
||||
$version,
|
||||
$params
|
||||
);
|
||||
|
||||
return false;
|
||||
} catch (InvalidArgumentException $e) {
|
||||
static::logException(
|
||||
$method,
|
||||
$methodApi,
|
||||
'InvalidArgumentException',
|
||||
'ArgumentException',
|
||||
$e,
|
||||
$version,
|
||||
$params
|
||||
);
|
||||
|
||||
return false;
|
||||
} catch (InvalidJsonException $e) {
|
||||
static::logException(
|
||||
$method,
|
||||
$methodApi,
|
||||
'InvalidJsonException',
|
||||
'ArgumentException',
|
||||
$e,
|
||||
$version,
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
if (function_exists('retailCrmApiResult')) {
|
||||
retailCrmApiResult($methodApi, true, isset($result) ? $result->getStatusCode() : 0);
|
||||
}
|
||||
|
||||
return isset($result) ? $result : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log exception into log file and event log
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $methodApi
|
||||
* @param string $exceptionName
|
||||
* @param string $apiResultExceptionName
|
||||
* @param \Exception|\Error|\Throwable $exception
|
||||
* @param string $version
|
||||
* @param array $params
|
||||
*/
|
||||
protected static function logException(
|
||||
$method,
|
||||
$methodApi,
|
||||
$exceptionName,
|
||||
$apiResultExceptionName,
|
||||
$exception,
|
||||
$version,
|
||||
$params
|
||||
) {
|
||||
self::eventLog(
|
||||
__CLASS__ . '::' . $method, 'RetailCrm\ApiClient::' . $methodApi . '::' . $exceptionName,
|
||||
$exception->getCode() . ': ' . $exception->getMessage()
|
||||
);
|
||||
|
||||
Logger::getInstance()->write([
|
||||
'api' => $version,
|
||||
'methodApi' => $methodApi,
|
||||
'errorMsg' => $exception->getMessage(),
|
||||
'errors' => $exception->getCode(),
|
||||
'params' => $params
|
||||
], 'apiErrors');
|
||||
|
||||
if (function_exists('retailCrmApiResult')) {
|
||||
retailCrmApiResult($methodApi, false, $apiResultExceptionName);
|
||||
}
|
||||
}
|
||||
}
|
181
intaro.retailcrm/classes/general/Response/ApiResponse.php
Normal file
181
intaro.retailcrm/classes/general/Response/ApiResponse.php
Normal file
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Response
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
namespace RetailCrm\Response;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RetailCrm\Exception\InvalidJsonException;
|
||||
|
||||
/**
|
||||
* Class ApiResponse
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Response
|
||||
*/
|
||||
class ApiResponse implements \ArrayAccess
|
||||
{
|
||||
// HTTP response status code
|
||||
protected $statusCode;
|
||||
|
||||
// response assoc array
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* ApiResponse constructor.
|
||||
*
|
||||
* @param int $statusCode HTTP status code
|
||||
* @param mixed $responseBody HTTP body
|
||||
*
|
||||
* @throws InvalidJsonException
|
||||
*/
|
||||
public function __construct($statusCode, $responseBody = null)
|
||||
{
|
||||
$this->statusCode = (int) $statusCode;
|
||||
|
||||
if (!empty($responseBody)) {
|
||||
$response = json_decode($responseBody, true);
|
||||
|
||||
if (!$response && JSON_ERROR_NONE !== ($error = json_last_error())) {
|
||||
throw new InvalidJsonException(
|
||||
"Invalid JSON in the API response body. Error code #$error",
|
||||
$error
|
||||
);
|
||||
}
|
||||
|
||||
$this->response = $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTTP response status code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request was successful
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccessful()
|
||||
{
|
||||
return $this->statusCode < 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to access for the property throw class method
|
||||
*
|
||||
* @param string $name method name
|
||||
* @param mixed $arguments method parameters
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
// convert getSomeProperty to someProperty
|
||||
$propertyName = strtolower(substr($name, 3, 1)) . substr($name, 4);
|
||||
|
||||
if (!isset($this->response[$propertyName])) {
|
||||
throw new \InvalidArgumentException("Method \"$name\" not found");
|
||||
}
|
||||
|
||||
return $this->response[$propertyName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to access for the property throw object property
|
||||
*
|
||||
* @param string $name property name
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (!isset($this->response[$name])) {
|
||||
throw new \InvalidArgumentException("Property \"$name\" not found");
|
||||
}
|
||||
|
||||
return $this->response[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset set
|
||||
*
|
||||
* @param mixed $offset offset
|
||||
* @param mixed $value value
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
throw new \BadMethodCallException('This activity not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset unset
|
||||
*
|
||||
* @param mixed $offset offset
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
throw new \BadMethodCallException('This call not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check offset
|
||||
*
|
||||
* @param mixed $offset offset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->response[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offset
|
||||
*
|
||||
* @param mixed $offset offset
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (!isset($this->response[$offset])) {
|
||||
throw new InvalidArgumentException("Property \"$offset\" not found");
|
||||
}
|
||||
|
||||
return $this->response[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getResponseBody()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
}
|
364
intaro.retailcrm/classes/general/RestNormalizer.php
Normal file
364
intaro.retailcrm/classes/general/RestNormalizer.php
Normal file
|
@ -0,0 +1,364 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* RestNormalizer - The main class
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class RestNormalizer
|
||||
{
|
||||
public $clear = true;
|
||||
private $validation = [];
|
||||
private $originalValidation = [];
|
||||
private $server;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
* @return void
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function __construct()
|
||||
{
|
||||
if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) {
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
}
|
||||
$this->server = \Bitrix\Main\Context::getCurrent()->getServer()->getDocumentRoot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsing the file validation
|
||||
* @param string $file The path to the file validation
|
||||
* @return boolean
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function parseConfig($file)
|
||||
{
|
||||
if (json_decode(file_get_contents($file)) !== null) {
|
||||
$this->originalValidation = json_decode(file_get_contents($file), true);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starting the process of normalization of the data
|
||||
* @param array $data The key is to sort the data validation
|
||||
* @param string $key Data normalization
|
||||
* @return array
|
||||
* @access public
|
||||
* @final
|
||||
*/
|
||||
final public function normalize($data, $key = false, $file = '/bitrix/modules/intaro.retailcrm/classes/general/config/retailcrm.json')
|
||||
{
|
||||
$server = \Bitrix\Main\Context::getCurrent()->getServer()->getDocumentRoot();
|
||||
$file = $server . $file;
|
||||
if (is_null($file) || is_file($file) === false
|
||||
|| json_decode(file_get_contents($file)) === null
|
||||
|| $this->parseConfig($file) === false
|
||||
) {
|
||||
RCrmActions::eventLog('RestNormalizer', 'intaro.retailcrm', 'Incorrect file normalize.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_string($data)) {
|
||||
$data = json_decode($data, true);
|
||||
}
|
||||
|
||||
if (is_string($key) && isset($this->originalValidation[ $key ])) {
|
||||
$this->validation = $this->originalValidation[ $key ];
|
||||
} else {
|
||||
$this->validation = $this->originalValidation;
|
||||
}
|
||||
|
||||
if (!is_array($data) || count($data) < 1) {
|
||||
RCrmActions::eventLog('RestNormalizer', 'intaro.retailcrm', 'Incorrect data array.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->formatting($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data formatting
|
||||
* @param array $data The key is to sort the data validation
|
||||
* @param boolean $skip Skip perform methods intended for the first run
|
||||
* @return array
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function formatting($data, $skip = false)
|
||||
{
|
||||
$formatted = [];
|
||||
|
||||
foreach ($data as $code => $value) {
|
||||
if (isset($this->validation[ $code ]) && $this->validation[ $code ]['type'] == 'skip') {
|
||||
$formatted[ $code ] = $value;
|
||||
} elseif (isset($this->validation[ $code ]) && is_array($value) === false) {
|
||||
$formatted[ $code ] = $this->setFormat($value, $this->validation[ $code ]);
|
||||
} elseif (is_array($value)) {
|
||||
$formatted[ $code ] = $this->formatting($value, true);
|
||||
}
|
||||
|
||||
//Удаление пустых переменных, кроме значений равных 0
|
||||
if (empty($formatted[$code]) && $formatted[$code] !== 0 && $formatted[$code] !== 0.0) {
|
||||
if ($this->clear === true) {
|
||||
unset($formatted[ $code ]);
|
||||
}
|
||||
|
||||
if (isset($this->validation[ $code ]['required']) && $this->validation[ $code ]['required'] === true) {
|
||||
$formatted = [];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($skip === false) {
|
||||
foreach ($this->validation as $code => $valid) {
|
||||
if (isset($valid['required']) && $valid['required'] === true && isset($formatted[ $code ]) === false) {
|
||||
RCrmActions::eventLog('RestNormalizer', 'intaro.retailcrm', "NOT VALID: $code");
|
||||
}
|
||||
}
|
||||
|
||||
$formatted = $this->multiConvert($formatted);
|
||||
}
|
||||
|
||||
return count($formatted) < 1 ? false : $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting data depending on the type
|
||||
* @param mixed $data The value to be formatted
|
||||
* @param array $validation The data for the current data type validation
|
||||
* @return mixed
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function setFormat($data, $validation)
|
||||
{
|
||||
$format = null;
|
||||
|
||||
switch ($validation['type']) {
|
||||
case 'string':
|
||||
$format = $this->setString($data, $validation);
|
||||
break;
|
||||
case 'int':
|
||||
$format = $this->setInt($data, $validation);
|
||||
break;
|
||||
case 'double':
|
||||
$format = $this->setDouble($data, $validation);
|
||||
break;
|
||||
case 'bool':
|
||||
$format = $this->setBool($data, $validation);
|
||||
break;
|
||||
case 'datetime':
|
||||
$format = $this->setDateTime($data, $validation);
|
||||
break;
|
||||
case 'enum':
|
||||
$format = $this->setEnum($data, $validation);
|
||||
break;
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting data for strings
|
||||
* @param string $data String to formatting
|
||||
* @param array $validation The data for the current data type validation
|
||||
* @return string
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function setString($data, $validation)
|
||||
{
|
||||
$data = trim((string) $data);
|
||||
|
||||
if (isset($validation['default']) && is_string($validation['default']) && trim($validation['default']) != ''
|
||||
&& ($data == '' || is_string($data) === false)
|
||||
) {
|
||||
$data = trim($validation['default']);
|
||||
} elseif ($data == '' || is_string($data) === false) {
|
||||
return null;
|
||||
} elseif (isset($validation['min']) && mb_strlen($data) < $validation['min']) {
|
||||
$pad = isset($validation['pad']) && mb_strlen($validation['pad']) == 1 ? $validation['pad'] : ' ';
|
||||
$data .= str_repeat($pad, $validation['min'] - mb_strlen($data));
|
||||
} elseif (isset($validation['max']) && mb_strlen($data) > $validation['max']) {
|
||||
$data = mb_substr($data, 0, $validation['max']);
|
||||
}
|
||||
|
||||
return (string) $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting data for integers
|
||||
* @param integer $data Integer to formatting
|
||||
* @param array $validation The data for the current data type validation
|
||||
* @return integer
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function setInt($data, $validation)
|
||||
{
|
||||
if (isset($validation['default']) && is_numeric($validation['default']) && is_numeric($data) === false) {
|
||||
$data = $validation['default'];
|
||||
} elseif (is_numeric($data) === false) {
|
||||
return null;
|
||||
} elseif (isset($validation['min']) && $data < $validation['min']) {
|
||||
$data += $validation['min'] - $data;
|
||||
} elseif (isset($validation['max']) && $data > $validation['max']) {
|
||||
$data -= $data - $validation['max'];
|
||||
}
|
||||
|
||||
return (int) $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting data for floating-point numbers
|
||||
* @param float $data Floating-point number to formatting
|
||||
* @param array $validation The data for the current data type validation
|
||||
* @return float
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function setDouble($data, $validation)
|
||||
{
|
||||
if (isset($validation['default']) && is_numeric($validation['default']) && is_numeric($data) === false) {
|
||||
$data = $validation['default'];
|
||||
} elseif (is_numeric($data) === false) {
|
||||
return null;
|
||||
} elseif (isset($validation['min']) && $data < $validation['min']) {
|
||||
$data += $validation['min'] - $data;
|
||||
} elseif (isset($validation['max']) && $data > $validation['max']) {
|
||||
$data -= $data - $validation['max'];
|
||||
}
|
||||
|
||||
if (isset($validation['decimals'])) {
|
||||
$data = number_format($data, $validation['decimals'], '.', '');
|
||||
}
|
||||
|
||||
return (double) $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting data for logical values
|
||||
* @param boolean $data Boolean value to formatting
|
||||
* @param array $validation The data for the current data type validation
|
||||
* @return boolean
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function setBool($data, $validation)
|
||||
{
|
||||
if (isset($validation['default']) && is_bool($validation['default']) && is_bool($data) === false) {
|
||||
$data = $validation['default'];
|
||||
} elseif (is_bool($data) === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (bool) $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting data for date and time
|
||||
* @param mixed $data Date and time of to formatting
|
||||
* @param array $validation The data for the current data type validation
|
||||
* @param boolean $skip Skip perform methods intended for the first run
|
||||
* @return mixed
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function setDateTime($data, $validation, $skip = false)
|
||||
{
|
||||
if (is_a($data, 'DateTime') && isset($validation['format'])) {
|
||||
$data = (string) $data->format($validation['format']);
|
||||
} elseif (is_string($data) && isset($validation['format']) && strtotime($data) !== false) {
|
||||
$data = (string) date($validation['format'], strtotime($data));
|
||||
} elseif (is_numeric($data) && isset($validation['format'])) {
|
||||
$data = (string) date($validation['format'], (int) $data);
|
||||
} elseif (is_numeric($data)) {
|
||||
$data = (int) $data;
|
||||
} elseif (isset($validation['format'])) {
|
||||
$data = (string) date($validation['format']);
|
||||
} elseif (isset($validation['default']) && $skip === false) {
|
||||
$data = $this->setDateTime(time(), $validation, true);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting data for enum
|
||||
* @param string $data Enum to formatting
|
||||
* @param array $validation The data for the current data type validation
|
||||
* @return string
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function setEnum($data, $validation)
|
||||
{
|
||||
if (isset($validation['values']) === false || count($validation['values']) < 1) {
|
||||
return null;
|
||||
} elseif (isset($validation['default']) && in_array($validation['default'], $validation['values']) === false) {
|
||||
return null;
|
||||
} elseif (in_array($data, $validation['values']) === false
|
||||
&& isset($validation['default']) && in_array($validation['default'], $validation['values'])
|
||||
) {
|
||||
$data = $validation['default'];
|
||||
} elseif (in_array($data, $validation['values']) === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installing the specified encoding
|
||||
* @param array $data The original dataset
|
||||
* @return array
|
||||
* @access private
|
||||
* @final
|
||||
*/
|
||||
final private function multiConvert($data)
|
||||
{
|
||||
global $APPLICATION;
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $code => $value) {
|
||||
if (is_array($value)) {
|
||||
$value = array_diff($value, array('', NULL));
|
||||
}
|
||||
|
||||
$data[$APPLICATION->ConvertCharset($code, SITE_CHARSET, 'utf-8')] = is_array($value)
|
||||
? $this->multiConvert($value)
|
||||
: $APPLICATION->ConvertCharset($value, SITE_CHARSET, 'utf-8')
|
||||
;
|
||||
}
|
||||
|
||||
return $data;
|
||||
} else {
|
||||
return $APPLICATION->ConvertCharset($data, SITE_CHARSET, 'utf-8');
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
/**
|
||||
* Interface RetailcrmBuilderInterface
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
interface RetailcrmBuilderInterface
|
||||
{
|
||||
/**
|
||||
* Set data array customerHistory
|
||||
*
|
||||
* @param array $dataCrm
|
||||
*
|
||||
* @return RetailcrmBuilderInterface
|
||||
*/
|
||||
public function setDataCrm($dataCrm);
|
||||
|
||||
/**
|
||||
* Build result
|
||||
*/
|
||||
public function build();
|
||||
}
|
35
intaro.retailcrm/classes/general/RetailcrmConfigProvider.php
Normal file
35
intaro.retailcrm/classes/general/RetailcrmConfigProvider.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* RetailcrmConfigProvider class
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
|
||||
use Intaro\RetailCrm\Component\ConfigProvider;
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
require_once __DIR__ . '/../../lib/component/configprovider.php';
|
||||
|
||||
/**
|
||||
* PHP version 5.3
|
||||
*
|
||||
* RetailcrmConfigProvider class
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class RetailcrmConfigProvider extends ConfigProvider
|
||||
{
|
||||
}
|
35
intaro.retailcrm/classes/general/RetailcrmConstants.php
Normal file
35
intaro.retailcrm/classes/general/RetailcrmConstants.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* RetailcrmConstants
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
|
||||
use Intaro\RetailCrm\Component\Constants;
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
require_once __DIR__ . '/../../lib/component/constants.php';
|
||||
|
||||
/**
|
||||
* PHP version 5.3
|
||||
*
|
||||
* RetailcrmConstants
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class RetailcrmConstants extends Constants
|
||||
{
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* RetailcrmDependencyLoader class
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
require_once __DIR__ . '/../../lib/component/dependencyloader.php';
|
||||
|
||||
/**
|
||||
* PHP version 5.3
|
||||
*
|
||||
* RetailcrmDependencyLoader class
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM
|
||||
*/
|
||||
class RetailcrmDependencyLoader extends \Intaro\RetailCrm\Component\DependencyLoader
|
||||
{
|
||||
}
|
168
intaro.retailcrm/classes/general/cart/RetailCrmCart_v5.php
Normal file
168
intaro.retailcrm/classes/general/cart/RetailCrmCart_v5.php
Normal file
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Cart
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
use Bitrix\Main\Context\Culture;
|
||||
use Bitrix\Sale\Basket;
|
||||
use Bitrix\Sale\Discount\Context\Fuser;
|
||||
use Bitrix\Sale\Discount;
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
|
||||
/**
|
||||
* Class RetailCrmCart
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Cart
|
||||
*/
|
||||
class RetailCrmCart
|
||||
{
|
||||
private static string $dateFormat = "Y-m-d H:i:sP";
|
||||
|
||||
/**
|
||||
* @param array $arBasket
|
||||
* @throws \Bitrix\Main\ArgumentException
|
||||
* @throws \Bitrix\Main\ObjectPropertyException
|
||||
* @throws \Bitrix\Main\SystemException
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public static function handlerCart(array $arBasket)
|
||||
{
|
||||
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
||||
$optionsSitesList = RetailcrmConfigProvider::getSitesList();
|
||||
|
||||
if ($optionsSitesList) {
|
||||
if (array_key_exists($arBasket['LID'], $optionsSitesList) && $optionsSitesList[$arBasket['LID']] !== null) {
|
||||
$site = $optionsSitesList[$arBasket['LID']];
|
||||
|
||||
$api->setSite($site);
|
||||
} else {
|
||||
RCrmActions::eventLog(
|
||||
'RetailCrmCart::handlerCart',
|
||||
'RetailcrmConfigProvider::getSitesList',
|
||||
'Error set site'
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
$site = RetailcrmConfigProvider::getSitesAvailable();
|
||||
}
|
||||
|
||||
$crmBasket = RCrmActions::apiMethod($api, 'cartGet', __METHOD__, $arBasket['USER_ID'], $site);
|
||||
|
||||
if (empty($arBasket['BASKET'])) {
|
||||
if (!empty($crmBasket['cart']['items'])) {
|
||||
return RCrmActions::apiMethod(
|
||||
$api,
|
||||
'cartClear',
|
||||
__METHOD__,
|
||||
[
|
||||
'clearedAt' => date(self::$dateFormat),
|
||||
'customer' => [
|
||||
'externalId' => $arBasket['USER_ID']
|
||||
]
|
||||
],
|
||||
$site
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$date = 'createdAt';
|
||||
$items = [];
|
||||
|
||||
foreach ($arBasket['BASKET'] as $itemBitrix) {
|
||||
$item['quantity'] = $itemBitrix['QUANTITY'];
|
||||
$item['price'] = $itemBitrix['PRICE'];
|
||||
$item['createdAt'] = $itemBitrix['DATE_INSERT']->format(self::$dateFormat);
|
||||
$item['updateAt'] = $itemBitrix['DATE_UPDATE']->format(self::$dateFormat);
|
||||
$item['offer']['externalId'] = $itemBitrix['PRODUCT_ID'];
|
||||
$items[] = $item;
|
||||
}
|
||||
|
||||
if (!empty($crmBasket['cart']['items'])) {
|
||||
$date = 'updatedAt';
|
||||
}
|
||||
|
||||
return RCrmActions::apiMethod(
|
||||
$api,
|
||||
'cartSet',
|
||||
__METHOD__,
|
||||
[
|
||||
'customer' => [
|
||||
'externalId' => $arBasket['USER_ID'],
|
||||
'site' => $site,
|
||||
],
|
||||
$date => date(self::$dateFormat),
|
||||
'droppedAt' => date(self::$dateFormat),
|
||||
'items' => $items,
|
||||
'link' => static::generateCartLink(),
|
||||
],
|
||||
$site
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Bitrix\Main\SystemException
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public static function getBasketArray($event): ?array
|
||||
{
|
||||
if ($event instanceof Basket) {
|
||||
$obBasket = $event;
|
||||
} elseif ($event instanceof Event) {
|
||||
$obBasket = $event->getParameter('ENTITY');
|
||||
} else {
|
||||
RCrmActions::eventLog('RetailCrmEvent::onChangeBasket', 'getBasketArray', 'event error');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$items = $obBasket->getBasket();
|
||||
$arBasket = ['LID' => $obBasket->getSiteId()];
|
||||
|
||||
if (count($items) !== 0) {
|
||||
$fUser = new Fuser($obBasket->getFUserId());
|
||||
$discounts = Discount::buildFromBasket($obBasket, $fUser);
|
||||
|
||||
$discounts->calculate();
|
||||
|
||||
$resultBasket = $discounts->getApplyResult(true);
|
||||
$basketItems = $resultBasket['PRICES']['BASKET'] ?? [];
|
||||
|
||||
|
||||
foreach ($items as $item) {
|
||||
$itemFields = $item->getFields()->getValues();
|
||||
|
||||
if (isset($basketItems[(int) $itemFields['ID']])) {
|
||||
$itemFields['PRICE'] = $basketItems[(int) $itemFields['ID']]['PRICE'];
|
||||
}
|
||||
|
||||
$arBasket['BASKET'][] = $itemFields;
|
||||
}
|
||||
}
|
||||
|
||||
return $arBasket;
|
||||
}
|
||||
|
||||
public static function generateCartLink()
|
||||
{
|
||||
return sprintf(
|
||||
'%s://%s/personal/cart',
|
||||
!empty($_SERVER['HTTPS']) ? 'https' : 'http',
|
||||
$_SERVER['HTTP_HOST']
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Collector
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class RetailCrmCollector
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Collector
|
||||
*/
|
||||
class RetailCrmCollector
|
||||
{
|
||||
public static $MODULE_ID = 'intaro.retailcrm';
|
||||
public static $CRM_COLL_KEY = 'coll_key';
|
||||
public static $CRM_COLL = 'collector';
|
||||
|
||||
/**
|
||||
* Add Daemon Collector script
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function add()
|
||||
{
|
||||
$keys = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_COLL_KEY, 0));
|
||||
$collector = COption::GetOptionString(self::$MODULE_ID, self::$CRM_COLL, 0);
|
||||
$request = \Bitrix\Main\Context::getCurrent()->getRequest();
|
||||
|
||||
if ($collector === 'Y' && !empty($keys[SITE_ID]) && $request->isAdminSection() !== true) {
|
||||
global $USER;
|
||||
|
||||
$params = array();
|
||||
if ($USER->IsAuthorized()) {
|
||||
$params['customerId'] = $USER->GetID();
|
||||
}
|
||||
|
||||
$str = "<script type=\"text/javascript\">
|
||||
(function(_,r,e,t,a,i,l){_['retailCRMObject']=a;_[a]=_[a]||function(){(_[a].q=_[a].q||[]).push(arguments)};_[a].l=1*new Date();l=r.getElementsByTagName(e)[0];i=r.createElement(e);i.async=!0;i.src=t;l.parentNode.insertBefore(i,l)})(window,document,'script','https://collector.retailcrm.pro/w.js','_rc');
|
||||
_rc('create', '" . $keys[SITE_ID] . "', " . json_encode((object) $params) . ");
|
||||
_rc('send', 'pageView');
|
||||
</script>";
|
||||
\Bitrix\Main\Page\Asset::getInstance()->addString($str, true);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
2785
intaro.retailcrm/classes/general/config/country.xml
Normal file
2785
intaro.retailcrm/classes/general/config/country.xml
Normal file
File diff suppressed because it is too large
Load diff
120
intaro.retailcrm/classes/general/config/objects.xml
Normal file
120
intaro.retailcrm/classes/general/config/objects.xml
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<options>
|
||||
<fields>
|
||||
<field id="id" group="customer">id</field>
|
||||
<field id="first_name" group="customer">firstName</field>
|
||||
<field id="last_name" group="customer">lastName</field>
|
||||
<field id="patronymic" group="customer">patronymic</field>
|
||||
<field id="email" group="customer">email</field>
|
||||
<field id="birthday" group="customer">birthday</field>
|
||||
<field id="sex" group="customer">sex</field>
|
||||
<field id="phones" group="customer">phones</field>
|
||||
<field id="manager" group="customer">manager</field>
|
||||
<field id="commentary" group="customer">commentary</field>
|
||||
<field id="external_id" group="customer">externalId</field>
|
||||
<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">countryIso</field>
|
||||
<field id="address.region" group="customerAddress">region</field>
|
||||
<field id="address.city" group="customerAddress">city</field>
|
||||
<field id="address.street" group="customerAddress">street</field>
|
||||
<field id="address.building" group="customerAddress">building</field>
|
||||
<field id="address.house" group="customerAddress">house</field>
|
||||
<field id="address.block" group="customerAddress">block</field>
|
||||
<field id="address.flat" group="customerAddress">flat</field>
|
||||
<field id="address.floor" group="customerAddress">floor</field>
|
||||
<field id="address.intercom_code" group="customerAddress">intercomCode</field>
|
||||
<field id="address.metro" group="customerAddress">metro</field>
|
||||
<field id="address.notes" group="customerAddress">notes</field>
|
||||
|
||||
<field id="contragent.contragent_type" group="customerContragent">contragentType</field>
|
||||
<field id="contragent.legal_name" group="customerContragent">legalName</field>
|
||||
<field id="contragent.legal_address" group="customerContragent">legalAddress</field>
|
||||
<field id="contragent.certificate_number" group="customerContragent">certificateNumber</field>
|
||||
<field id="contragent.certificate_date" group="customerContragent">certificateDate</field>
|
||||
<field id="contragent.bank" group="customerContragent">bank</field>
|
||||
<field id="contragent.bank_address" group="customerContragent">bankAddress</field>
|
||||
<field id="contragent.i_n_n" group="customerContragent">INN</field>
|
||||
<field id="contragent.o_k_p_o" group="customerContragent">OKPO</field>
|
||||
<field id="contragent.k_p_p" group="customerContragent">KPP</field>
|
||||
<field id="contragent.o_g_r_n" group="customerContragent">OGRN</field>
|
||||
<field id="contragent.o_g_r_n_i_p" group="customerContragent">OGRNIP</field>
|
||||
<field id="contragent.certificate_number" group="customerContragent">certificateNumber</field>
|
||||
<field id="contragent.certificate_date" group="customerContragent">certificateDate</field>
|
||||
<field id="contragent.b_i_k" group="customerContragent">BIK</field>
|
||||
<field id="contragent.corr_account" group="customerContragent">corrAccount</field>
|
||||
<field id="contragent.bank_account" group="customerContragent">bankAccount</field>
|
||||
|
||||
<field id="id" group="order">id</field>
|
||||
<field id="created_at" group="order">createdAt</field>
|
||||
<field id="order_type" group="order">orderType</field>
|
||||
<field id="order_method" group="order">orderMethod</field>
|
||||
<field id="site" group="order">site</field>
|
||||
<field id="status" group="order">status</field>
|
||||
<field id="status_comment" group="order">statusComment</field>
|
||||
<field id="manager" group="order">manager</field>
|
||||
<field id="first_name" group="order">firstName</field>
|
||||
<field id="last_name" group="order">lastName</field>
|
||||
<field id="patronymic" group="order">patronymic</field>
|
||||
<field id="phone" group="order">phone</field>
|
||||
<field id="additional_phone" group="order">additionalPhone</field>
|
||||
<field id="email" group="order">email</field>
|
||||
<field id="payment_type" group="order">paymentType</field>
|
||||
<field id="payment_status" group="order">paymentStatus</field>
|
||||
<field id="discount" group="order">discount</field>
|
||||
<field id="discount_percent" group="order">discountPercent</field>
|
||||
<field id="prepay_sum" group="order">prepaySum</field>
|
||||
<field id="customer_comment" group="order">customerComment</field>
|
||||
<field id="manager_comment" group="order">managerComment</field>
|
||||
<field id="shipment_store" group="order">shipmentStore</field>
|
||||
<field id="shipment_date" group="order">shipmentDate</field>
|
||||
<field id="shipped" group="order">shipped</field>
|
||||
<!--<field id="order_product" group="order">item</field>-->
|
||||
|
||||
<field id="order_product.id" group="item">id</field>
|
||||
<field id="order_product.initial_price" group="item">initialPrice</field>
|
||||
<field id="order_product.discount" group="item">discount</field>
|
||||
<field id="order_product.discount_percent" group="item">discountPercent</field>
|
||||
<field id="order_product.quantity" group="item">quantity</field>
|
||||
<field id="order_product.status" group="item">status</field>
|
||||
<field id="order_product.discount_total" group="item">discountTotal</field>
|
||||
<field id="order_product.bonuses_charge" group="item">bonusesCharge</field>
|
||||
<field id="order_product.bonuses_credit" group="item">bonusesCredit</field>
|
||||
|
||||
<field id="payments.status" group="payment">status</field>
|
||||
<field id="payments.type" group="payment">type</field>
|
||||
<field id="payments.external_id" group="payment">externalId</field>
|
||||
<field id="payments.amount" group="payment">amount</field>
|
||||
<field id="payments.comment" group="payment">comment</field>
|
||||
|
||||
<field id="delivery_type" group="delivery">code</field>
|
||||
<field id="delivery_service" group="delivery">service</field>
|
||||
<field id="delivery_date" group="delivery">date</field>
|
||||
<field id="delivery_time" group="delivery">time</field>
|
||||
<field id="delivery_cost" group="delivery">cost</field>
|
||||
<field id="delivery_net_cost" group="delivery">netCost</field>
|
||||
|
||||
<field id="delivery_address.country" group="orderAddress">country</field>
|
||||
<field id="delivery_address.index" group="orderAddress">index</field>
|
||||
<field id="delivery_address.region" group="orderAddress">region</field>
|
||||
<field id="delivery_address.city" group="orderAddress">city</field>
|
||||
<field id="delivery_address.street" group="orderAddress">street</field>
|
||||
<field id="delivery_address.building" group="orderAddress">building</field>
|
||||
<field id="delivery_address.house" group="orderAddress">house</field>
|
||||
<field id="delivery_address.housing" group="orderAddress">housing</field>
|
||||
<field id="delivery_address.block" group="orderAddress">block</field>
|
||||
<field id="delivery_address.flat" group="orderAddress">flat</field>
|
||||
<field id="delivery_address.floor" group="orderAddress">floor</field>
|
||||
<field id="delivery_address.intercom_code" group="orderAddress">intercomCode</field>
|
||||
<field id="delivery_address.metro" group="orderAddress">metro</field>
|
||||
<field id="delivery_address.notes" group="orderAddress">notes</field>
|
||||
|
||||
<field id="integration_delivery_data.status" group="integrationDelivery">status</field>
|
||||
<field id="integration_delivery_data.track_number" group="integrationDelivery">trackNumber</field>
|
||||
<field id="integration_delivery_data.courier" group="integrationDelivery">courier</field>
|
||||
</fields>
|
||||
</options>
|
42
intaro.retailcrm/classes/general/config/options.xml
Normal file
42
intaro.retailcrm/classes/general/config/options.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<options>
|
||||
<contragents>
|
||||
<contragent id="individual">Физ. лицо</contragent>
|
||||
<contragent id="legal-entity">Юр. лицо</contragent>
|
||||
<contragent id="enterpreneur">ИП</contragent>
|
||||
</contragents>
|
||||
<fields>
|
||||
<field id="fio">Ф.И.О.</field>
|
||||
<field id="phone">Телефон</field>
|
||||
<field id="email">E-mail</field>
|
||||
<field id="text">Адрес (строкой)</field>
|
||||
<field id="city">Город</field>
|
||||
<field id="index">Индекс</field>
|
||||
<field id="street">Улица</field>
|
||||
<field id="building">Номер дома</field>
|
||||
<field id="flat">Квартира</field>
|
||||
<field id="intercomcode">Домофон</field>
|
||||
<field id="floor">Этаж</field>
|
||||
<field id="block">Подъезд</field>
|
||||
<field id="house">Строение</field>
|
||||
<field id="housing">Корпус</field>
|
||||
|
||||
<field id="legalName" group="legal-entity, enterpreneur">Полное наименование</field>
|
||||
<field id="legalAddress" group="legal-entity, enterpreneur">Адрес регистрации (Юридический адрес)</field>
|
||||
<field id="INN" group="legal-entity, enterpreneur">ИНН</field>
|
||||
<field id="OKPO" group="legal-entity, enterpreneur">ОКПО</field>
|
||||
<field id="BIK" group="legal-entity, enterpreneur">БИК</field>
|
||||
<field id="bank" group="legal-entity, enterpreneur">Банк</field>
|
||||
<field id="bankAddress" group="legal-entity, enterpreneur">Адрес банка</field>
|
||||
<field id="corrAccount" group="legal-entity, enterpreneur">Корреспондентский счет</field>
|
||||
<field id="bankAccount" group="legal-entity, enterpreneur">Расчетный счет</field>
|
||||
|
||||
<field id="KPP" group="legal-entity">КПП</field>
|
||||
<field id="OGRN" group="legal-entity">ОГРН</field>
|
||||
|
||||
<field id="OGRNIP" group="enterpreneur">ОГРНИП</field>
|
||||
<field id="certificateNumber" group="enterpreneur">Номер свидетельства</field>
|
||||
<field id="certificateDate" group="enterpreneur">Дата свидетельства</field>
|
||||
|
||||
</fields>
|
||||
</options>
|
567
intaro.retailcrm/classes/general/config/retailcrm.json
Normal file
567
intaro.retailcrm/classes/general/config/retailcrm.json
Normal file
|
@ -0,0 +1,567 @@
|
|||
{
|
||||
"customers": {
|
||||
"externalId": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastName": {
|
||||
"type": "string"
|
||||
},
|
||||
"patronymic": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"number": {
|
||||
"type": "string"
|
||||
},
|
||||
"birthday": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d"
|
||||
},
|
||||
"site": {
|
||||
"type": "string"
|
||||
},
|
||||
"index": {
|
||||
"type": "string"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"street": {
|
||||
"type": "string"
|
||||
},
|
||||
"building": {
|
||||
"type": "string"
|
||||
},
|
||||
"flat": {
|
||||
"type": "string"
|
||||
},
|
||||
"intercomCode": {
|
||||
"type": "string"
|
||||
},
|
||||
"floor": {
|
||||
"type": "int"
|
||||
},
|
||||
"block": {
|
||||
"type": "int"
|
||||
},
|
||||
"house": {
|
||||
"type": "string"
|
||||
},
|
||||
"metro": {
|
||||
"type": "string"
|
||||
},
|
||||
"notes": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d H:i:s"
|
||||
},
|
||||
"vip": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"bad": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"subscribed": {
|
||||
"type": "string"
|
||||
},
|
||||
"commentary": {
|
||||
"type": "string"
|
||||
},
|
||||
"customFields": {
|
||||
"type": "skip"
|
||||
},
|
||||
"contragentType": {
|
||||
"type": "enum",
|
||||
"default": "individual",
|
||||
"values": ["individual", "legal-entity", "enterpreneur"]
|
||||
},
|
||||
"legalName": {
|
||||
"type": "string"
|
||||
},
|
||||
"legalAddress": {
|
||||
"type": "string"
|
||||
},
|
||||
"INN": {
|
||||
"type": "string"
|
||||
},
|
||||
"OKPO": {
|
||||
"type": "string"
|
||||
},
|
||||
"KPP": {
|
||||
"type": "string"
|
||||
},
|
||||
"OGRN": {
|
||||
"type": "string"
|
||||
},
|
||||
"OGRNIP": {
|
||||
"type": "string"
|
||||
},
|
||||
"certificateNumber": {
|
||||
"type": "string"
|
||||
},
|
||||
"certificateDate": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d"
|
||||
},
|
||||
"BIK": {
|
||||
"type": "string"
|
||||
},
|
||||
"bank": {
|
||||
"type": "string"
|
||||
},
|
||||
"bankAddress": {
|
||||
"type": "string"
|
||||
},
|
||||
"corrAccount": {
|
||||
"type": "string"
|
||||
},
|
||||
"bankAccount": {
|
||||
"type": "string"
|
||||
},
|
||||
"managerId": {
|
||||
"type": "int"
|
||||
},
|
||||
"browserId": {
|
||||
"type": "string"
|
||||
},
|
||||
"discountCardNumber": {
|
||||
"type": "string"
|
||||
},
|
||||
"personalDiscount": {
|
||||
"type": "string"
|
||||
},
|
||||
"sex": {
|
||||
"type": "string"
|
||||
},
|
||||
"emailMarketingUnsubscribedAt" : {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d H:i:s"
|
||||
},
|
||||
"source": {
|
||||
"type": "string"
|
||||
},
|
||||
"medium": {
|
||||
"type": "string"
|
||||
},
|
||||
"campaign": {
|
||||
"type": "string"
|
||||
},
|
||||
"keyword": {
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"customerCorporate": {
|
||||
"externalId": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d H:i:s"
|
||||
},
|
||||
"contragentType": {
|
||||
"type": "enum",
|
||||
"default": "legal-entity",
|
||||
"values": ["individual", "legal-entity", "enterpreneur"]
|
||||
},
|
||||
"isMain": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"site": {
|
||||
"type": "string"
|
||||
},
|
||||
"nickName": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"legalName": {
|
||||
"type": "string"
|
||||
},
|
||||
"legalAddress": {
|
||||
"type": "string"
|
||||
},
|
||||
"INN": {
|
||||
"type": "string"
|
||||
},
|
||||
"KPP": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"orders": {
|
||||
"number": {
|
||||
"type": "string"
|
||||
},
|
||||
"externalId": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"required": false
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d H:i:s"
|
||||
},
|
||||
"discountManualAmount": {
|
||||
"type": "double",
|
||||
"default": 0,
|
||||
"min": 0,
|
||||
"decimals": 2
|
||||
},
|
||||
"discountManualPercent": {
|
||||
"type": "double",
|
||||
"default": 0,
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"decimals": 2
|
||||
},
|
||||
"discount": {
|
||||
"type": "double",
|
||||
"default": 0,
|
||||
"min": 0,
|
||||
"decimals": 2
|
||||
},
|
||||
"discountPercent": {
|
||||
"type": "double",
|
||||
"default": 0,
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"decimals": 2
|
||||
},
|
||||
"mark": {
|
||||
"type": "int",
|
||||
"max": 10,
|
||||
"min": 0
|
||||
},
|
||||
"markDatetime": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d H:i:s"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastName": {
|
||||
"type": "string"
|
||||
},
|
||||
"patronymic": {
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string"
|
||||
},
|
||||
"additionalPhone": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"site": {
|
||||
"type": "string"
|
||||
},
|
||||
"countryIso": {
|
||||
"type": "string"
|
||||
},
|
||||
"call": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"expired": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"customerComment": {
|
||||
"type": "string"
|
||||
},
|
||||
"managerComment": {
|
||||
"type": "string"
|
||||
},
|
||||
"weight": {
|
||||
"type": "double"
|
||||
},
|
||||
"length": {
|
||||
"type": "int"
|
||||
},
|
||||
"width": {
|
||||
"type": "int"
|
||||
},
|
||||
"height": {
|
||||
"type": "int"
|
||||
},
|
||||
"paymentDetail": {
|
||||
"type": "string"
|
||||
},
|
||||
"statusComment": {
|
||||
"type": "string"
|
||||
},
|
||||
"customFields": {
|
||||
"type": "skip"
|
||||
},
|
||||
"contragentType": {
|
||||
"type": "enum",
|
||||
"default": "individual",
|
||||
"values": ["individual", "legal-entity", "enterpreneur"]
|
||||
},
|
||||
"legalName": {
|
||||
"type": "string"
|
||||
},
|
||||
"legalAddress": {
|
||||
"type": "string"
|
||||
},
|
||||
"INN": {
|
||||
"type": "string"
|
||||
},
|
||||
"OKPO": {
|
||||
"type": "string"
|
||||
},
|
||||
"KPP": {
|
||||
"type": "string"
|
||||
},
|
||||
"OGRN": {
|
||||
"type": "string"
|
||||
},
|
||||
"OGRNIP": {
|
||||
"type": "string"
|
||||
},
|
||||
"certificateNumber": {
|
||||
"type": "string"
|
||||
},
|
||||
"certificateDate": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d"
|
||||
},
|
||||
"BIK": {
|
||||
"type": "string"
|
||||
},
|
||||
"bank": {
|
||||
"type": "string"
|
||||
},
|
||||
"bankAddress": {
|
||||
"type": "string"
|
||||
},
|
||||
"corrAccount": {
|
||||
"type": "string"
|
||||
},
|
||||
"bankAccount": {
|
||||
"type": "string"
|
||||
},
|
||||
"shipmentDate": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d"
|
||||
},
|
||||
"shipped": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"orderType": {
|
||||
"type": "string"
|
||||
},
|
||||
"orderMethod": {
|
||||
"type": "string"
|
||||
},
|
||||
"customerId": {
|
||||
"type": "string"
|
||||
},
|
||||
"managerId": {
|
||||
"type": "int"
|
||||
},
|
||||
"deliveryTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"paymentType": {
|
||||
"type": "string"
|
||||
},
|
||||
"paymentStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"amount": {
|
||||
"type": "double",
|
||||
"default": 0,
|
||||
"min": 0,
|
||||
"decimals": 2
|
||||
},
|
||||
"paidAt": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d H:i:s"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"sourceId": {
|
||||
"type": "string"
|
||||
},
|
||||
"initialPrice": {
|
||||
"type": "double",
|
||||
"default": 0,
|
||||
"min": 0,
|
||||
"decimals": 2
|
||||
},
|
||||
"quantity": {
|
||||
"type": "double",
|
||||
"default": 1,
|
||||
"min": 0,
|
||||
"decimals": 3
|
||||
},
|
||||
"properties": {
|
||||
"type": "skip"
|
||||
},
|
||||
"productId": {
|
||||
"type": "string"
|
||||
},
|
||||
"productName": {
|
||||
"type": "string"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "double",
|
||||
"default": 0,
|
||||
"min": 0,
|
||||
"decimals": 2
|
||||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"integrationCode": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "skip"
|
||||
},
|
||||
"service": {
|
||||
"type": "skip"
|
||||
},
|
||||
"cost": {
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"type": "datetime",
|
||||
"format": "Y-m-d"
|
||||
},
|
||||
"index": {
|
||||
"type": "string"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"street": {
|
||||
"type": "string"
|
||||
},
|
||||
"building": {
|
||||
"type": "string"
|
||||
},
|
||||
"flat": {
|
||||
"type": "string"
|
||||
},
|
||||
"intercomCode": {
|
||||
"type": "string"
|
||||
},
|
||||
"floor": {
|
||||
"type": "int"
|
||||
},
|
||||
"block": {
|
||||
"type": "int"
|
||||
},
|
||||
"house": {
|
||||
"type": "string"
|
||||
},
|
||||
"housing": {
|
||||
"type": "string"
|
||||
},
|
||||
"metro": {
|
||||
"type": "string"
|
||||
},
|
||||
"notes": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"shipmentStore": {
|
||||
"type": "string"
|
||||
},
|
||||
"from": {
|
||||
"type": "skip"
|
||||
},
|
||||
"to": {
|
||||
"type": "skip"
|
||||
},
|
||||
"custom": {
|
||||
"type": "string"
|
||||
},
|
||||
"vatRate": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"xmlId": {
|
||||
"type": "string"
|
||||
},
|
||||
"netCost": {
|
||||
"type": "double"
|
||||
},
|
||||
"source": {
|
||||
"type": "string"
|
||||
},
|
||||
"medium": {
|
||||
"type": "string"
|
||||
},
|
||||
"campaign": {
|
||||
"type": "string"
|
||||
},
|
||||
"keyword": {
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"type": "string"
|
||||
},
|
||||
"privilegeType": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Consultant
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class RetailCrmOnlineConsultant
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Consultant
|
||||
*/
|
||||
class RetailCrmOnlineConsultant
|
||||
{
|
||||
/**
|
||||
* Add a script of online consultant
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function add()
|
||||
{
|
||||
$request = \Bitrix\Main\Context::getCurrent()->getRequest();
|
||||
|
||||
if (RetailcrmConfigProvider::isOnlineConsultantEnabled() && $request->isAdminSection() !== true) {
|
||||
\Bitrix\Main\Page\Asset::getInstance()->addString(
|
||||
RetailcrmConfigProvider::getOnlineConsultantScript(),
|
||||
true
|
||||
);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
763
intaro.retailcrm/classes/general/events/RetailCrmEvent.php
Normal file
763
intaro.retailcrm/classes/general/events/RetailCrmEvent.php
Normal file
|
@ -0,0 +1,763 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Events
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
use Bitrix\Main\Context\Culture;
|
||||
use Bitrix\Main\Engine\CurrentUser;
|
||||
use Intaro\RetailCrm\Component\Constants;
|
||||
use Intaro\RetailCrm\Component\ServiceLocator;
|
||||
use Intaro\RetailCrm\Repository\UserRepository;
|
||||
use Intaro\RetailCrm\Service\CustomerService;
|
||||
use Intaro\RetailCrm\Service\LoyaltyAccountService;
|
||||
use Intaro\RetailCrm\Service\ManagerService;
|
||||
use Bitrix\Sale\Payment;
|
||||
use Bitrix\Catalog\Model\Event;
|
||||
use Bitrix\Main\UserTable;
|
||||
use Bitrix\Sale\Order;
|
||||
use Intaro\RetailCrm\Component\ConfigProvider;
|
||||
use Intaro\RetailCrm\Model\Api\Response\OrdersCreateResponse;
|
||||
use Intaro\RetailCrm\Model\Api\Response\OrdersEditResponse;
|
||||
|
||||
/**
|
||||
* Class RetailCrmEvent
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Events
|
||||
*/
|
||||
class RetailCrmEvent
|
||||
{
|
||||
protected static $MODULE_ID = 'intaro.retailcrm';
|
||||
protected static $CRM_API_HOST_OPTION = 'api_host';
|
||||
protected static $CRM_API_KEY_OPTION = 'api_key';
|
||||
protected static $CRM_ORDER_TYPES_ARR = 'order_types_arr';
|
||||
protected static $CRM_DELIVERY_TYPES_ARR = 'deliv_types_arr';
|
||||
protected static $CRM_PAYMENT_TYPES = 'pay_types_arr';
|
||||
protected static $CRM_PAYMENT_STATUSES = 'pay_statuses_arr';
|
||||
protected static $CRM_PAYMENT = 'payment_arr';
|
||||
protected static $CRM_ORDER_LAST_ID = 'order_last_id';
|
||||
protected static $CRM_ORDER_PROPS = 'order_props';
|
||||
protected static $CRM_LEGAL_DETAILS = 'legal_details';
|
||||
protected static $CRM_CUSTOM_FIELDS = 'custom_fields';
|
||||
protected static $CRM_CONTRAGENT_TYPE = 'contragent_type';
|
||||
protected static $CRM_ORDER_FAILED_IDS = 'order_failed_ids';
|
||||
protected static $CRM_SITES_LIST = 'sites_list';
|
||||
protected static $CRM_CC = 'cc';
|
||||
protected static $CRM_CORP_NAME = 'nickName-corporate';
|
||||
protected static $CRM_CORP_ADRES = 'adres-corporate';
|
||||
|
||||
/**
|
||||
* @param $arFields
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function OnAfterUserUpdate($arFields)
|
||||
{
|
||||
RetailCrmService::writeLogsSubscribe($arFields);
|
||||
|
||||
if (isset($GLOBALS['RETAIL_CRM_HISTORY']) && $GLOBALS['RETAIL_CRM_HISTORY']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$arFields['RESULT']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$optionsSitesList = RetailcrmConfigProvider::getSitesList();
|
||||
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
||||
$resultOrder = RetailCrmUser::customerEdit($arFields, $api, $optionsSitesList);
|
||||
|
||||
if (!$resultOrder) {
|
||||
RCrmActions::eventLog('RetailCrmEvent::OnAfterUserUpdate', 'RetailCrmUser::customerEdit', 'error update customer');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* onUpdateOrder
|
||||
*
|
||||
* @param mixed $ID - Order id
|
||||
* @param mixed $arFields - Order arFields
|
||||
*/
|
||||
public static function onUpdateOrder($ID, $arFields)
|
||||
{
|
||||
if (isset($GLOBALS['RETAIL_CRM_HISTORY']) && $GLOBALS['RETAIL_CRM_HISTORY']) {
|
||||
$GLOBALS['RETAILCRM_ORDER_OLD_EVENT'] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS['RETAILCRM_ORDER_OLD_EVENT'] = true;
|
||||
|
||||
if (($arFields['CANCELED'] === 'Y')
|
||||
&& (sizeof($arFields['BASKET_ITEMS']) == 0)
|
||||
&& (sizeof($arFields['ORDER_PROP']) == 0)
|
||||
) {
|
||||
$GLOBALS['ORDER_DELETE_USER_ADMIN'] = true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* orderDelete
|
||||
*
|
||||
* @param object $event - Order object
|
||||
*/
|
||||
public static function orderDelete($event)
|
||||
{
|
||||
$GLOBALS['RETAILCRM_ORDER_DELETE'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* событие изменения корзины
|
||||
*
|
||||
* @param object $event
|
||||
*/
|
||||
public static function onChangeBasket($event)
|
||||
{
|
||||
$apiVersion = COption::GetOptionString(self::$MODULE_ID, 'api_version', 0);
|
||||
|
||||
if ($apiVersion !== 'v5') {
|
||||
return;
|
||||
}
|
||||
|
||||
$id = CurrentUser::get()->getId();
|
||||
|
||||
if ($id) {
|
||||
$arBasket = RetailCrmCart::getBasketArray($event);
|
||||
|
||||
if ($arBasket === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$arBasket['USER_ID'] = $id;
|
||||
|
||||
RetailCrmCart::handlerCart($arBasket);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $event
|
||||
*
|
||||
* @return array|bool|OrdersCreateResponse|OrdersEditResponse|null
|
||||
* @throws \Bitrix\Main\ArgumentException
|
||||
* @throws \Bitrix\Main\ObjectPropertyException
|
||||
* @throws \Bitrix\Main\SystemException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function orderSave($event)
|
||||
{
|
||||
if (!static::checkConfig()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$arOrder = static::getOrderArray($event);
|
||||
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
||||
|
||||
//params
|
||||
$optionsOrderTypes = RetailcrmConfigProvider::getOrderTypes();
|
||||
$optionsDelivTypes = RetailcrmConfigProvider::getDeliveryTypes();
|
||||
$optionsPayTypes = RetailcrmConfigProvider::getPaymentTypes();
|
||||
$optionsPayStatuses = RetailcrmConfigProvider::getPaymentStatuses(); // --statuses
|
||||
$optionsPayment = RetailcrmConfigProvider::getPayment();
|
||||
$optionsSitesList = RetailcrmConfigProvider::getSitesList();
|
||||
$optionsOrderProps = RetailcrmConfigProvider::getOrderProps();
|
||||
$optionsLegalDetails = RetailcrmConfigProvider::getLegalDetails();
|
||||
$optionsContragentType = RetailcrmConfigProvider::getContragentTypes();
|
||||
$optionsCustomFields = RetailcrmConfigProvider::getCustomFields();
|
||||
|
||||
//corp cliente swich
|
||||
$optionCorpClient = RetailcrmConfigProvider::getCorporateClientStatus();
|
||||
$arParams = RCrmActions::clearArr([
|
||||
'optionsOrderTypes' => $optionsOrderTypes,
|
||||
'optionsDelivTypes' => $optionsDelivTypes,
|
||||
'optionsPayTypes' => $optionsPayTypes,
|
||||
'optionsPayStatuses' => $optionsPayStatuses,
|
||||
'optionsPayment' => $optionsPayment,
|
||||
'optionsOrderProps' => $optionsOrderProps,
|
||||
'optionsLegalDetails' => $optionsLegalDetails,
|
||||
'optionsContragentType' => $optionsContragentType,
|
||||
'optionsSitesList' => $optionsSitesList,
|
||||
'optionsCustomFields' => $optionsCustomFields,
|
||||
'customOrderProps' => RetailcrmConfigProvider::getMatchedOrderProps(),
|
||||
]);
|
||||
|
||||
//many sites?
|
||||
if ($optionsSitesList) {
|
||||
if (array_key_exists($arOrder['LID'], $optionsSitesList) && $optionsSitesList[$arOrder['LID']] !== null) {
|
||||
$site = $optionsSitesList[$arOrder['LID']];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} elseif (!$optionsSitesList) {
|
||||
$site = null;
|
||||
}
|
||||
|
||||
$api->setSite($site);
|
||||
|
||||
//new order?
|
||||
$orderCrm = RCrmActions::apiMethod($api, 'ordersGet', __METHOD__, $arOrder['ID'], $site);
|
||||
|
||||
if (isset($orderCrm['order'])) {
|
||||
$methodApi = 'ordersEdit';
|
||||
$arParams['crmOrder'] = $orderCrm['order'];
|
||||
} else {
|
||||
$methodApi = 'ordersCreate';
|
||||
}
|
||||
|
||||
$orderCompany = null;
|
||||
|
||||
if (
|
||||
('Y' === $optionCorpClient)
|
||||
&& true === RetailCrmCorporateClient::isCorpTookExternalId((string)$arOrder['USER_ID'], $api, $site)
|
||||
) {
|
||||
RetailCrmCorporateClient::setPrefixForExternalId((string) $arOrder['USER_ID'], $api, $site);
|
||||
}
|
||||
|
||||
//TODO эта управляющая конструкция по функционалу дублирует RetailCrmOrder::createCustomerForOrder.
|
||||
// Необходимо устранить дублирование, вынеся логику в обособленный класс-сервис
|
||||
if ('Y' === $optionCorpClient && in_array($optionsContragentType[$arOrder['PERSON_TYPE_ID']], ['legal-entity', 'enterpreneur'])) {
|
||||
//corparate cliente
|
||||
$nickName = '';
|
||||
$address = '';
|
||||
$corpAddress = '';
|
||||
$contragent = [];
|
||||
$userCorp = [];
|
||||
$corpName = RetailcrmConfigProvider::getCorporateClientName();
|
||||
$corpAddress = RetailcrmConfigProvider::getCorporateClientAddress();
|
||||
|
||||
foreach ($arOrder['PROPS']['properties'] as $prop) {
|
||||
if ($prop['CODE'] === $corpName) {
|
||||
$nickName = $prop['VALUE'][0];
|
||||
}
|
||||
|
||||
if ($prop['CODE'] === $corpAddress) {
|
||||
$address = $prop['VALUE'][0];
|
||||
}
|
||||
|
||||
if (!empty($optionsLegalDetails)
|
||||
&& $search = array_search($prop['CODE'], $optionsLegalDetails[$arOrder['PERSON_TYPE_ID']])
|
||||
) {
|
||||
$contragent[$search] = $prop['VALUE'][0];//legal order data
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contragentType)) {
|
||||
$contragent['contragentType'] = $contragentType;
|
||||
}
|
||||
|
||||
$customersCorporate = false;
|
||||
$response = $api->customersCorporateList(['companyName' => $nickName]);
|
||||
|
||||
if ($response && $response->getStatusCode() == 200) {
|
||||
$customersCorporate = $response['customersCorporate'];
|
||||
$singleCorp = reset($customersCorporate);
|
||||
|
||||
if (!empty($singleCorp)) {
|
||||
$userCorp['customerCorporate'] = $singleCorp;
|
||||
$companiesResponse = $api->customersCorporateCompanies(
|
||||
$singleCorp['id'],
|
||||
[],
|
||||
null,
|
||||
null,
|
||||
'id',
|
||||
$site
|
||||
);
|
||||
|
||||
if ($companiesResponse && $companiesResponse->isSuccessful()) {
|
||||
$orderCompany = array_reduce(
|
||||
$companiesResponse['companies'],
|
||||
function ($carry, $item) use ($nickName) {
|
||||
if (is_array($item) && $item['name'] === $nickName) {
|
||||
$carry = $item;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
},
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RCrmActions::eventLog(
|
||||
'RetailCrmEvent::orderSave',
|
||||
'ApiClient::customersCorporateList',
|
||||
'error during fetching corporate customers'
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//user
|
||||
$userCrm = RCrmActions::apiMethod($api, 'customersGet', __METHOD__, $arOrder['USER_ID'], $site);
|
||||
|
||||
if (!isset($userCrm['customer'])) {
|
||||
$arUser = CUser::GetByID($arOrder['USER_ID'])->Fetch();
|
||||
|
||||
if (!empty($address)) {
|
||||
$arUser['PERSONAL_STREET'] = $address;
|
||||
}
|
||||
|
||||
$resultUser = RetailCrmUser::customerSend($arUser, $api, 'individual', true, $site);
|
||||
|
||||
if (!$resultUser) {
|
||||
RCrmActions::eventLog(
|
||||
__CLASS__ . '::' . __METHOD__,
|
||||
'RetailCrmUser::customerSend',
|
||||
'error during creating customer'
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$userCrm = ['customer' => ['externalId' => $arOrder['USER_ID']]];
|
||||
}
|
||||
|
||||
if (!isset($userCorp['customerCorporate'])) {
|
||||
$resultUserCorp = RetailCrmCorporateClient::clientSend(
|
||||
$arOrder,
|
||||
$api,
|
||||
$optionsContragentType[$arOrder['PERSON_TYPE_ID']],
|
||||
true,
|
||||
false,
|
||||
$site
|
||||
);
|
||||
|
||||
Logger::getInstance()->write($resultUserCorp, 'resultUserCorp');
|
||||
|
||||
if (!$resultUserCorp) {
|
||||
RCrmActions::eventLog('RetailCrmEvent::orderSave', 'RetailCrmCorporateClient::clientSend', 'error during creating client');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$arParams['customerCorporate'] = $resultUserCorp;
|
||||
$arParams['orderCompany'] = $resultUserCorp['mainCompany'] ?? null;
|
||||
|
||||
$customerCorporateAddress = [];
|
||||
$customerCorporateCompany = [];
|
||||
$addressResult = null;
|
||||
$companyResult = null;
|
||||
|
||||
if (!empty($address)) {
|
||||
//TODO address builder add
|
||||
$customerCorporateAddress = [
|
||||
'name' => $nickName,
|
||||
'isMain' => true,
|
||||
'text' => $address,
|
||||
];
|
||||
|
||||
$addressResult = $api->customersCorporateAddressesCreate($resultUserCorp['id'], $customerCorporateAddress, 'id', $site);
|
||||
}
|
||||
|
||||
$customerCorporateCompany = [
|
||||
'name' => $nickName,
|
||||
'isMain' => true,
|
||||
'contragent' => $contragent,
|
||||
];
|
||||
|
||||
if (!empty($addressResult)) {
|
||||
$customerCorporateCompany['address'] = [
|
||||
'id' => $addressResult['id'],
|
||||
];
|
||||
}
|
||||
|
||||
$companyResult = $api->customersCorporateCompaniesCreate($resultUserCorp['id'], $customerCorporateCompany, 'id', $site);
|
||||
|
||||
$customerCorporateContact = [
|
||||
'isMain' => true,
|
||||
'customer' => [
|
||||
'externalId' => $arOrder['USER_ID'],
|
||||
'site' => $site,
|
||||
],
|
||||
];
|
||||
|
||||
if (!empty($companyResult)) {
|
||||
$orderCompany = [
|
||||
'id' => $companyResult['id'],
|
||||
];
|
||||
|
||||
$customerCorporateContact['companies'] = [
|
||||
[
|
||||
'company' => $orderCompany,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$api->customersCorporateContactsCreate(
|
||||
$resultUserCorp['id'],
|
||||
$customerCorporateContact,
|
||||
'id',
|
||||
$site
|
||||
);
|
||||
|
||||
$arParams['orderCompany'] = array_merge(
|
||||
$customerCorporateCompany,
|
||||
['id' => $companyResult['id']]
|
||||
);
|
||||
} else {
|
||||
RetailCrmCorporateClient::addCustomersCorporateAddresses(
|
||||
$userCorp['customerCorporate']['id'],
|
||||
$nickName,
|
||||
$address,
|
||||
$api,
|
||||
$site
|
||||
);
|
||||
|
||||
$arParams['customerCorporate'] = $userCorp['customerCorporate'];
|
||||
|
||||
if (!empty($orderCompany)) {
|
||||
$arParams['orderCompany'] = $orderCompany;
|
||||
}
|
||||
}
|
||||
|
||||
$arParams['contactExId'] = $userCrm['customer']['externalId'];
|
||||
} else {
|
||||
//user
|
||||
$userCrm = RCrmActions::apiMethod($api, 'customersGet', __METHOD__, $arOrder['USER_ID'], $site);
|
||||
|
||||
if (!isset($userCrm['customer'])) {
|
||||
$arUser = CUser::GetByID($arOrder['USER_ID'])->Fetch();
|
||||
|
||||
$resultUser = RetailCrmUser::customerSend(
|
||||
$arUser,
|
||||
$api,
|
||||
$optionsContragentType[$arOrder['PERSON_TYPE_ID']],
|
||||
true,
|
||||
$site
|
||||
);
|
||||
|
||||
if (!$resultUser) {
|
||||
RCrmActions::eventLog(
|
||||
'RetailCrmEvent::orderSave',
|
||||
'RetailCrmUser::customerSend',
|
||||
'error during creating customer'
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($arOrder['RESPONSIBLE_ID']) && !empty($arOrder['RESPONSIBLE_ID'])) {
|
||||
$managerService = ManagerService::getInstance();
|
||||
$arParams['managerId'] = $managerService->getManagerCrmId($arOrder['RESPONSIBLE_ID']);
|
||||
}
|
||||
//order
|
||||
$resultOrder = RetailCrmOrder::orderSend($arOrder, $api, $arParams, true, $site, $methodApi);
|
||||
|
||||
if (!$resultOrder) {
|
||||
RCrmActions::eventLog(
|
||||
'RetailCrmEvent::orderSave',
|
||||
'RetailCrmOrder::orderSend',
|
||||
'error during creating order'
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $resultOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Bitrix\Sale\Payment $event
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
*/
|
||||
public static function paymentSave(Payment $event)
|
||||
{
|
||||
$apiVersion = COption::GetOptionString(self::$MODULE_ID, 'api_version', 0);
|
||||
|
||||
/** @var \Bitrix\Sale\Order $order */
|
||||
$order = $event->getCollection()->getOrder();
|
||||
|
||||
if ((isset($GLOBALS['RETAIL_CRM_HISTORY']) && $GLOBALS['RETAIL_CRM_HISTORY'])
|
||||
|| $apiVersion !== 'v5'
|
||||
|| $order->isNew()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$optionsSitesList = RetailcrmConfigProvider::getSitesList();
|
||||
$optionsPaymentTypes = RetailcrmConfigProvider::getPaymentTypes();
|
||||
$optionsPayStatuses = RetailcrmConfigProvider::getPayment();
|
||||
$integrationPaymentTypes = RetailcrmConfigProvider::getIntegrationPaymentTypes();
|
||||
|
||||
$arPayment = [
|
||||
'ID' => $event->getId(),
|
||||
'ORDER_ID' => $event->getField('ORDER_ID'),
|
||||
'PAID' => $event->getField('PAID'),
|
||||
'PAY_SYSTEM_ID' => $event->getField('PAY_SYSTEM_ID'),
|
||||
'SUM' => $event->getField('SUM'),
|
||||
'LID' => $order->getSiteId(),
|
||||
'DATE_PAID' => $event->getField('DATE_PAID'),
|
||||
];
|
||||
|
||||
if ($optionsSitesList) {
|
||||
if (array_key_exists($arPayment['LID'], $optionsSitesList) && $optionsSitesList[$arPayment['LID']] !== null) {
|
||||
$site = $optionsSitesList[$arPayment['LID']];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} elseif (!$optionsSitesList) {
|
||||
$site = null;
|
||||
}
|
||||
|
||||
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
||||
$orderCrm = RCrmActions::apiMethod($api, 'ordersGet', __METHOD__, $arPayment['ORDER_ID'], $site);
|
||||
|
||||
if (isset($orderCrm['order'])) {
|
||||
$payments = $orderCrm['order']['payments'];
|
||||
}
|
||||
|
||||
$paymentsExternalIds = [];
|
||||
|
||||
if (!empty($payments)) {
|
||||
foreach ($payments as $payment) {
|
||||
if (isset($payment['externalId'])) {
|
||||
if (RCrmActions::isNewExternalId($payment['externalId'])) {
|
||||
$paymentsExternalIds[RCrmActions::getFromPaymentExternalId($payment['externalId'])] =
|
||||
$payment;
|
||||
} else {
|
||||
$paymentsExternalIds[$payment['externalId']] = $payment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($arPayment['PAY_SYSTEM_ID']) && isset($optionsPaymentTypes[$arPayment['PAY_SYSTEM_ID']])) {
|
||||
$paymentToCrm = [];
|
||||
|
||||
if (!empty($arPayment['ID'])) {
|
||||
$paymentToCrm['externalId'] = RCrmActions::generatePaymentExternalId($arPayment['ID']);
|
||||
}
|
||||
|
||||
if (!empty($arPayment['DATE_PAID'])) {
|
||||
if (is_object($arPayment['DATE_PAID'])) {
|
||||
$culture = new Culture(['FORMAT_DATETIME' => 'YYYY-MM-DD HH:MI:SS']);
|
||||
$paymentToCrm['paidAt'] = $arPayment['DATE_PAID']->toString($culture);
|
||||
} elseif (is_string($arPayment['DATE_PAID'])) {
|
||||
$paymentToCrm['paidAt'] = $arPayment['DATE_PAID'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($optionsPayStatuses[$arPayment['PAID']])) {
|
||||
$paymentToCrm['status'] = $optionsPayStatuses[$arPayment['PAID']];
|
||||
}
|
||||
|
||||
if (!empty($arPayment['ORDER_ID'])) {
|
||||
$paymentToCrm['order']['externalId'] = $arPayment['ORDER_ID'];
|
||||
}
|
||||
|
||||
if (RetailcrmConfigProvider::shouldSendPaymentAmount()) {
|
||||
$paymentToCrm['amount'] = $arPayment['SUM'];
|
||||
}
|
||||
|
||||
$paymentToCrm = RetailCrmService::preparePayment($paymentToCrm, $arPayment, $optionsPaymentTypes);
|
||||
} else {
|
||||
RCrmActions::eventLog('RetailCrmEvent::paymentSave', 'payments', 'OrderID = ' . $arPayment['ID'] . '. Payment not found.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$arPaymentExtId = RCrmActions::generatePaymentExternalId($arPayment['ID']);
|
||||
|
||||
if (!empty($paymentsExternalIds) && array_key_exists($arPaymentExtId, $paymentsExternalIds)) {
|
||||
$paymentData = $paymentsExternalIds[$arPaymentExtId];
|
||||
} elseif (!empty($paymentsExternalIds) && array_key_exists($arPayment['ID'], $paymentsExternalIds)) {
|
||||
$paymentData = $paymentsExternalIds[$arPayment['ID']];
|
||||
} else {
|
||||
$paymentData = [];
|
||||
}
|
||||
|
||||
if (empty($paymentData)) {
|
||||
RCrmActions::apiMethod($api, 'ordersPaymentCreate', __METHOD__, $paymentToCrm, $site);
|
||||
} elseif ($paymentData['type'] == $optionsPaymentTypes[$arPayment['PAY_SYSTEM_ID']]) {
|
||||
if (in_array($paymentData['type'], $integrationPaymentTypes)) {
|
||||
RCrmActions::eventLog(
|
||||
'RetailCrmEvent::paymentSave',
|
||||
'payments',
|
||||
'OrderID = ' . $arPayment['ID'] . '. Integration payment detected, which is not editable.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$paymentToCrm['externalId'] = $paymentData['externalId'];
|
||||
RCrmActions::apiMethod($api, 'paymentEditByExternalId', __METHOD__, $paymentToCrm, $site);
|
||||
} elseif ($paymentData['type'] != $optionsPaymentTypes[$arPayment['PAY_SYSTEM_ID']]) {
|
||||
RCrmActions::apiMethod(
|
||||
$api,
|
||||
'ordersPaymentDelete',
|
||||
__METHOD__,
|
||||
$paymentData['id']
|
||||
);
|
||||
RCrmActions::apiMethod($api, 'ordersPaymentCreate', __METHOD__, $paymentToCrm, $site);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Bitrix\Sale\Payment $event
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function paymentDelete(Payment $event): void
|
||||
{
|
||||
$apiVersion = COption::GetOptionString(self::$MODULE_ID, 'api_version', 0);
|
||||
|
||||
if ((isset($GLOBALS['RETAIL_CRM_HISTORY']) && $GLOBALS['RETAIL_CRM_HISTORY'])
|
||||
|| $apiVersion !== 'v5'
|
||||
|| !$event->getId()
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$optionsSitesList = RetailcrmConfigProvider::getSitesList();
|
||||
|
||||
$arPayment = [
|
||||
'ID' => $event->getId(),
|
||||
'ORDER_ID' => $event->getField('ORDER_ID'),
|
||||
'LID' => $event->getCollection()->getOrder()->getSiteId(),
|
||||
];
|
||||
|
||||
if ($optionsSitesList) {
|
||||
if (array_key_exists($arPayment['LID'], $optionsSitesList) && $optionsSitesList[$arPayment['LID']] !== null) {
|
||||
$site = $optionsSitesList[$arPayment['LID']];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} elseif (!$optionsSitesList) {
|
||||
$site = null;
|
||||
}
|
||||
|
||||
$api = new RetailCrm\ApiClient(ConfigProvider::getApiUrl(), ConfigProvider::getApiKey());
|
||||
$orderCrm = RCrmActions::apiMethod($api, 'ordersGet', __METHOD__, $arPayment['ORDER_ID'], $site);
|
||||
|
||||
if (isset($orderCrm['order']['payments']) && $orderCrm['order']['payments']) {
|
||||
foreach ($orderCrm['order']['payments'] as $payment) {
|
||||
if (isset($payment['externalId'])
|
||||
&& ($payment['externalId'] == $event->getId()
|
||||
|| RCrmActions::getFromPaymentExternalId($payment['externalId']) == $event->getId())
|
||||
) {
|
||||
RCrmActions::apiMethod($api, 'ordersPaymentDelete', __METHOD__, $payment['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Регистрирует пользователя в CRM системе после регистрации на сайте
|
||||
*
|
||||
* @param array $arFields
|
||||
* @return mixed
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function OnAfterUserRegister(array $arFields): void
|
||||
{
|
||||
if (isset($arFields['USER_ID']) && $arFields['USER_ID'] > 0) {
|
||||
$user = UserRepository::getById($arFields['USER_ID']);
|
||||
|
||||
if (isset($_POST['REGISTER']['PERSONAL_PHONE'])) {
|
||||
$phone = htmlspecialchars($_POST['REGISTER']['PERSONAL_PHONE']);
|
||||
|
||||
if ($user !== null) {
|
||||
$user->setPersonalPhone($phone);
|
||||
$user->save();
|
||||
}
|
||||
|
||||
$arFields['PERSONAL_PHONE'] = $phone;
|
||||
}
|
||||
|
||||
/* @var CustomerService $customerService */
|
||||
$customerService = ServiceLocator::get(CustomerService::class);
|
||||
$customer = $customerService->createModel($arFields['USER_ID']);
|
||||
|
||||
$customerService->createOrUpdateCustomer($customer);
|
||||
|
||||
RetailCrmService::writeLogsSubscribe($arFields);
|
||||
|
||||
//Если пользователь выразил желание зарегистрироваться в ПЛ и согласился со всеми правилами
|
||||
if ((int) $arFields['UF_REG_IN_PL_INTARO'] === 1
|
||||
&& (int) $arFields['UF_AGREE_PL_INTARO'] === 1
|
||||
&& (int) $arFields['UF_PD_PROC_PL_INTARO'] === 1
|
||||
) {
|
||||
$phone = $arFields['PERSONAL_PHONE'] ?? '';
|
||||
$card = $arFields['UF_CARD_NUM_INTARO'] ?? '';
|
||||
$customerId = (string) $arFields['USER_ID'];
|
||||
|
||||
/** @var LoyaltyAccountService $service */
|
||||
$service = ServiceLocator::get(LoyaltyAccountService::class);
|
||||
$createResponse = $service->createLoyaltyAccount($phone, $card, $customerId);
|
||||
|
||||
$service->activateLpUserInBitrix($createResponse, $arFields['USER_ID']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $arFields
|
||||
*
|
||||
* @return void
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function OnAfterUserAdd($arFields)
|
||||
{
|
||||
RetailCrmService::writeLogsSubscribe($arFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private static function checkConfig(): bool
|
||||
{
|
||||
if (true == $GLOBALS['ORDER_DELETE_USER_ADMIN']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($GLOBALS['RETAILCRM_ORDER_OLD_EVENT'] === false
|
||||
&& $GLOBALS['RETAILCRM_ORDER_DELETE'] === true
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($GLOBALS['RETAIL_CRM_HISTORY'] === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!RetailcrmDependencyLoader::loadDependencies()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Bitrix\Sale\Order|\Bitrix\Main\Event $event
|
||||
*
|
||||
* @throws \Bitrix\Main\SystemException
|
||||
*/
|
||||
private static function getOrderArray($event): ?array
|
||||
{
|
||||
if ($event instanceof Order) {
|
||||
$obOrder = $event;
|
||||
} elseif ($event instanceof Event) {
|
||||
$obOrder = $event->getParameter('ENTITY');
|
||||
} else {
|
||||
RCrmActions::eventLog('RetailCrmEvent::orderSave', 'events', 'event error');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return RetailCrmOrder::orderObjToArr($obOrder);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\History
|
||||
*/
|
||||
|
||||
define("NO_KEEP_STATISTIC", true);
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
|
||||
$GLOBALS['APPLICATION']->RestartBuffer();
|
||||
$moduleId = 'intaro.retailcrm';
|
||||
$historyTime = 'history_time';
|
||||
$idOrderCRM = (int) $_REQUEST['idOrderCRM'];
|
||||
|
||||
if (CModule::IncludeModule($moduleId) && $idOrderCRM && $idOrderCRM > 0) {
|
||||
$timeBd = COption::GetOptionString($moduleId, $historyTime, 0);
|
||||
$nowDate = date('Y-m-d H:i:s');
|
||||
if (!empty($timeBd)) {
|
||||
$timeBdObj = new \DateTime($timeBd);
|
||||
$newTimeBdObj = $timeBdObj->modify('+5 min');
|
||||
$nowDateObj = new \DateTime($nowDate);
|
||||
//If there is a record, but it is older than 5 minutes, overwrite
|
||||
if ($newTimeBdObj < $nowDateObj) {
|
||||
COption::SetOptionString($moduleId, $historyTime, $nowDate);
|
||||
//call history
|
||||
RCrmActions::orderAgent();
|
||||
|
||||
COption::RemoveOption($moduleId, $historyTime);
|
||||
}
|
||||
} else {
|
||||
COption::SetOptionString($moduleId, $historyTime, $nowDate);
|
||||
//call history
|
||||
RCrmActions::orderAgent();
|
||||
|
||||
COption::RemoveOption($moduleId, $historyTime);
|
||||
}
|
||||
}
|
2313
intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
Normal file
2313
intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
Normal file
File diff suppressed because it is too large
Load diff
54
intaro.retailcrm/classes/general/history/RetailUser.php
Normal file
54
intaro.retailcrm/classes/general/history/RetailUser.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\History
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class RetailUser
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\History
|
||||
*/
|
||||
class RetailUser extends CUser
|
||||
{
|
||||
/**
|
||||
* @return int|mixed|string|null
|
||||
*/
|
||||
public function GetID()
|
||||
{
|
||||
$rsUser = CUser::GetList(($by = 'ID'), ($order = 'DESC'), ['LOGIN' => 'retailcrm']);
|
||||
|
||||
if ($arUser = $rsUser->Fetch()) {
|
||||
return $arUser['ID'];
|
||||
}
|
||||
|
||||
$retailUser = new CUser;
|
||||
$userPassword = uniqid();
|
||||
|
||||
$arFields = [
|
||||
'NAME' => 'retailcrm',
|
||||
'LAST_NAME' => 'retailcrm',
|
||||
'EMAIL' => 'retailcrm@retailcrm.com',
|
||||
'LOGIN' => 'retailcrm',
|
||||
'LID' => 'ru',
|
||||
'ACTIVE' => 'Y',
|
||||
'GROUP_ID' => [2],
|
||||
'PASSWORD' => $userPassword,
|
||||
'CONFIRM_PASSWORD' => $userPassword,
|
||||
];
|
||||
|
||||
$id = $retailUser->Add($arFields);
|
||||
|
||||
if (!$id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Inventories
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class RetailCrmInventories
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Inventories
|
||||
*/
|
||||
class RetailCrmInventories
|
||||
{
|
||||
public static $pageSize = 500;
|
||||
|
||||
public static function inventoriesUpload()
|
||||
{
|
||||
if (!CModule::IncludeModule('iblock')) {
|
||||
RCrmActions::eventLog('RetailCrmHistory::orderHistory', 'iblock', 'module not found');
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!CModule::IncludeModule('sale')) {
|
||||
RCrmActions::eventLog('RetailCrmHistory::orderHistory', 'sale', 'module not found');
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!CModule::IncludeModule('catalog')) {
|
||||
RCrmActions::eventLog('RetailCrmHistory::orderHistory', 'catalog', 'module not found');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
||||
$infoBlocks = RetailcrmConfigProvider::getInfoblocksInventories();
|
||||
$stores = RetailcrmConfigProvider::getStores();
|
||||
$shops = RetailcrmConfigProvider::getShops();
|
||||
|
||||
try {
|
||||
$inventoriesList = $api->storesList()->stores;
|
||||
} catch (\RetailCrm\Exception\CurlException $e) {
|
||||
RCrmActions::eventLog(
|
||||
'RetailCrmInventories::inventoriesUpload()', 'RetailCrm\ApiClient::storesList::CurlException',
|
||||
$e->getCode() . ': ' . $e->getMessage()
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$inventoriesType = array();
|
||||
if (count($inventoriesList) > 0) {
|
||||
foreach ($inventoriesList as $inventory) {
|
||||
$inventoriesType[$inventory['code']] = $inventory['inventoryType'];
|
||||
}
|
||||
} else {
|
||||
RCrmActions::eventLog('RetailCrmInventories::inventoriesUpload()', '$inventoriesList', 'Stores in crm not found');
|
||||
|
||||
return false;
|
||||
}
|
||||
if (count($shops) == 0) {
|
||||
RCrmActions::eventLog('RetailCrmInventories::inventoriesUpload()', '$shops', 'No stores selected for download');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($infoBlocks) > 0) {
|
||||
foreach ($infoBlocks as $id) {
|
||||
$iblockOffer = CCatalogSKU::GetInfoByProductIBlock($id);
|
||||
|
||||
$arNavStatParams = array(
|
||||
'iNumPage' => 1,
|
||||
'nPageSize' => self::$pageSize,
|
||||
);
|
||||
|
||||
do {
|
||||
$dbResProductsIds = CIBlockElement::GetList(array('ID'), array('IBLOCK_ID' => $id), false, $arNavStatParams, array('ID'));
|
||||
$products = array();
|
||||
while ($product = $dbResProductsIds->fetch()) {
|
||||
$products[$product['ID']] = $product;
|
||||
$products[$product['ID']]['offers'] = array();
|
||||
}
|
||||
|
||||
if (!empty($iblockOffer['IBLOCK_ID'])) {
|
||||
$arFilterOffer = array(
|
||||
'IBLOCK_ID' => $iblockOffer['IBLOCK_ID'],
|
||||
'PROPERTY_' . $iblockOffer['SKU_PROPERTY_ID'] => array_keys($products),
|
||||
);
|
||||
|
||||
$dbResOffers = CIBlockElement::GetList(array('ID'), $arFilterOffer, false, false, array('ID', 'PROPERTY_' . $iblockOffer['SKU_PROPERTY_ID']));
|
||||
while ($offer = $dbResOffers->fetch()) {
|
||||
$products[$offer['PROPERTY_' . $iblockOffer['SKU_PROPERTY_ID'] . '_VALUE']]['offers'][] = $offer['ID'];
|
||||
}
|
||||
}
|
||||
|
||||
$elems = array();
|
||||
$storesChunks = array_chunk($stores, 50, true);
|
||||
foreach ($storesChunks as $storesChunk) {
|
||||
foreach ($products as $product) {
|
||||
if (count($product['offers']) > 0) {
|
||||
$elems = array_merge($elems, $product['offers']);
|
||||
} else {
|
||||
$elems[] = $product['ID'];
|
||||
}
|
||||
}
|
||||
|
||||
$invUpload = array();
|
||||
$dbStoreProduct = CCatalogStoreProduct::GetList(
|
||||
array(),
|
||||
array('PRODUCT_ID' => $elems, 'STORE_ID' => array_keys($storesChunk)),
|
||||
false,
|
||||
false,
|
||||
array('PRODUCT_ID', 'STORE_ID', 'AMOUNT')
|
||||
);
|
||||
while ($arStoreProduct = $dbStoreProduct->Fetch()) {
|
||||
if (!isset($invUpload[$arStoreProduct['PRODUCT_ID']])) {
|
||||
$invUpload[$arStoreProduct['PRODUCT_ID']] = array(
|
||||
'externalId' => $arStoreProduct['PRODUCT_ID']
|
||||
);
|
||||
}
|
||||
$invUpload[$arStoreProduct['PRODUCT_ID']]['stores'][] = array(
|
||||
'code' => $storesChunk[$arStoreProduct['STORE_ID']],
|
||||
'available' => self::switchCount($arStoreProduct['AMOUNT'], $inventoriesType[$storesChunk[$arStoreProduct['STORE_ID']]]),
|
||||
);
|
||||
}
|
||||
//for log
|
||||
$splitedItems = array_chunk($invUpload, 200);
|
||||
foreach ($splitedItems as $chunk) {
|
||||
Logger::getInstance()->write($chunk, 'inventoriesUpload');
|
||||
|
||||
foreach ($shops as $shop) {
|
||||
RCrmActions::apiMethod($api, 'storeInventoriesUpload', __METHOD__, $chunk, $shop);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
}
|
||||
|
||||
$arNavStatParams['iNumPage'] = $dbResProductsIds->NavPageNomer + 1;
|
||||
}
|
||||
} while($dbResProductsIds->NavPageNomer < $dbResProductsIds->NavPageCount);
|
||||
}
|
||||
} else {
|
||||
RCrmActions::eventLog('RetailCrmInventories::inventoriesUpload()', '$infoBlocks', 'No iblocks selected');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return 'RetailCrmInventories::inventoriesUpload();';
|
||||
}
|
||||
|
||||
public static function switchCount($val, $type)
|
||||
{
|
||||
if ($val < 0) {
|
||||
$val = 0;
|
||||
} elseif ($val > 999999) {
|
||||
$val = 999999;
|
||||
}
|
||||
|
||||
if ($type == 'available' && $val > 0) {
|
||||
$val = 1;
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
}
|
1084
intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php
Normal file
1084
intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php
Normal file
File diff suppressed because it is too large
Load diff
170
intaro.retailcrm/classes/general/prices/RetailCrmPrices.php
Normal file
170
intaro.retailcrm/classes/general/prices/RetailCrmPrices.php
Normal file
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Prices
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
/**
|
||||
* Class RetailCrmPrices
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Prices
|
||||
*/
|
||||
class RetailCrmPrices
|
||||
{
|
||||
public static $MODULE_ID = 'intaro.retailcrm';
|
||||
public static $CRM_API_HOST_OPTION = 'api_host';
|
||||
public static $CRM_API_KEY_OPTION = 'api_key';
|
||||
public static $CRM_PRICES_UPLOAD = 'prices_upload';
|
||||
public static $CRM_PRICES = 'prices';
|
||||
public static $CRM_PRICE_SHOPS = 'price_shops';
|
||||
public static $CRM_IBLOCKS_PRICES = 'iblock_prices';
|
||||
public static $pageSize = 500;
|
||||
|
||||
public static function pricesUpload()
|
||||
{
|
||||
if (!CModule::IncludeModule('iblock')) {
|
||||
RCrmActions::eventLog('RetailCrmHistory::orderHistory', 'iblock', 'module not found');
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!CModule::IncludeModule('sale')) {
|
||||
RCrmActions::eventLog('RetailCrmHistory::orderHistory', 'sale', 'module not found');
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!CModule::IncludeModule('catalog')) {
|
||||
RCrmActions::eventLog('RetailCrmHistory::orderHistory', 'catalog', 'module not found');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$api_host = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_HOST_OPTION, 0);
|
||||
$api_key = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_KEY_OPTION, 0);
|
||||
$api = new RetailCrm\ApiClient($api_host, $api_key);
|
||||
|
||||
$infoBlocks = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_IBLOCKS_PRICES, 0));
|
||||
$prices = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PRICES, 0));
|
||||
$shops = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PRICE_SHOPS, 0));
|
||||
|
||||
if (count($shops) == 0) {
|
||||
RCrmActions::eventLog('RetailCrmPrices::pricesUpload()', '$shops', 'No stores selected for download');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($prices) == 0) {
|
||||
RCrmActions::eventLog('RetailCrmPrices::pricesUpload()', '$prices', 'No prices selected for download');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($infoBlocks) > 0) {
|
||||
foreach ($infoBlocks as $id) {
|
||||
$iblockOffer = CCatalogSKU::GetInfoByProductIBlock($id);
|
||||
|
||||
$arNavStatParams = array(
|
||||
'iNumPage' => 1,
|
||||
'nPageSize' => self::$pageSize,
|
||||
);
|
||||
|
||||
do {
|
||||
$dbResProductsIds = CIBlockElement::GetList(array('ID'), array('IBLOCK_ID' => $id), false, $arNavStatParams, array('ID'));
|
||||
$products = array();
|
||||
while ($product = $dbResProductsIds->fetch()) {
|
||||
$products[$product['ID']] = $product;
|
||||
$products[$product['ID']]['offers'] = array();
|
||||
}
|
||||
|
||||
if (!empty($iblockOffer['IBLOCK_ID'])) {
|
||||
$arFilterOffer = array(
|
||||
'IBLOCK_ID' => $iblockOffer['IBLOCK_ID'],
|
||||
'PROPERTY_' . $iblockOffer['SKU_PROPERTY_ID'] => array_keys($products),
|
||||
);
|
||||
|
||||
$dbResOffers = CIBlockElement::GetList(array('ID'), $arFilterOffer, false, false, array('ID', 'PROPERTY_' . $iblockOffer['SKU_PROPERTY_ID']));
|
||||
while ($offer = $dbResOffers->fetch()) {
|
||||
$products[$offer['PROPERTY_' . $iblockOffer['SKU_PROPERTY_ID'] . '_VALUE']]['offers'][] = $offer['ID'];
|
||||
}
|
||||
}
|
||||
|
||||
$elems = array();
|
||||
foreach ($products as $product) {
|
||||
if (count($product['offers']) > 0) {
|
||||
$elems = array_merge($elems, $product['offers']);
|
||||
} else {
|
||||
$elems[] = $product['ID'];
|
||||
}
|
||||
}
|
||||
|
||||
$pricesUpload = array();
|
||||
$dbPricesProduct = CPrice::GetList(
|
||||
array(),
|
||||
array('PRODUCT_ID' => $elems, 'CATALOG_GROUP_ID' => array_keys($prices)),
|
||||
false,
|
||||
false,
|
||||
array('PRODUCT_ID', 'CATALOG_GROUP_ID', 'PRICE')
|
||||
);
|
||||
while ($arPricesProduct = $dbPricesProduct->Fetch()) {
|
||||
foreach ($shops as $shop) {
|
||||
if (!isset($pricesUpload[$arPricesProduct['PRODUCT_ID'] . '-' . $shop])) {
|
||||
$pricesUpload[$arPricesProduct['PRODUCT_ID'] . '-' . $shop] = array(
|
||||
'externalId' => $arPricesProduct['PRODUCT_ID'],
|
||||
'site' => $shop
|
||||
);
|
||||
}
|
||||
$pricesUpload[$arPricesProduct['PRODUCT_ID'] . '-' . $shop]['prices'][] = array(
|
||||
'code' => $prices[$arPricesProduct['CATALOG_GROUP_ID']],
|
||||
'price' => $arPricesProduct['PRICE'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($shops as $shop) {
|
||||
foreach ($elems as $value) {
|
||||
if (!array_key_exists($value . '-' . $shop, $pricesUpload)) {
|
||||
foreach ($prices as $key => $price) {
|
||||
$pricesUpload[$value . '-' . $shop] = array(
|
||||
'externalId' => $value,
|
||||
'site' => $shop
|
||||
);
|
||||
|
||||
$pricesUpload[$value . '-'. $shop]['prices'][] = array(
|
||||
'code' => $prices[$key],
|
||||
'remove' => true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//for log
|
||||
$splitedItems = array_chunk($pricesUpload, 200);
|
||||
foreach ($splitedItems as $chunk) {
|
||||
Logger::getInstance()->write($chunk, 'storePricesUpload');
|
||||
|
||||
foreach ($shops as $shop) {
|
||||
RCrmActions::apiMethod($api, 'storePricesUpload', __METHOD__, $chunk, $shop);
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
}
|
||||
|
||||
$arNavStatParams['iNumPage'] = $dbResProductsIds->NavPageNomer + 1;
|
||||
} while($dbResProductsIds->NavPageNomer < $dbResProductsIds->NavPageCount);
|
||||
}
|
||||
} else {
|
||||
RCrmActions::eventLog('RetailCrmPrices::pricesUpload()', '$infoBlocks', 'No iblocks selected');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return 'RetailCrmPrices::pricesUpload();';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Service
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
use Bitrix\Sale\Order;
|
||||
use Bitrix\Main\Context;
|
||||
use Bitrix\Catalog\StoreTable;
|
||||
|
||||
/**
|
||||
* Class BitrixOrderService
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Service
|
||||
*/
|
||||
class BitrixOrderService
|
||||
{
|
||||
public static function getCountryList()
|
||||
{
|
||||
$server = Context::getCurrent()->getServer()->getDocumentRoot();
|
||||
$countryList = [];
|
||||
|
||||
if (file_exists($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/country.xml')) {
|
||||
$countryFile = simplexml_load_file($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/country.xml');
|
||||
|
||||
foreach ($countryFile->country as $country) {
|
||||
$countryList[RCrmActions::fromJSON((string) $country->name)] = (string) $country->alpha;
|
||||
}
|
||||
}
|
||||
|
||||
return $countryList;
|
||||
}
|
||||
|
||||
public static function getPickupPointAddress($arOrder)
|
||||
{
|
||||
$address = '';
|
||||
$orderInfo = Order::load($arOrder['ID']);
|
||||
|
||||
foreach ($orderInfo->getShipmentCollection() as $store) {
|
||||
$storeId = $store->getStoreId();
|
||||
|
||||
if ($storeId) {
|
||||
$arStore = StoreTable::getRow([
|
||||
'filter' => [
|
||||
'ID' => $storeId,
|
||||
]
|
||||
]);
|
||||
|
||||
if (!empty($arStore['ADDRESS'])) {
|
||||
$address = GetMessage('PICKUP_POINT') . $arStore['ADDRESS'];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $address;
|
||||
}
|
||||
}
|
220
intaro.retailcrm/classes/general/services/RetailCrmService.php
Normal file
220
intaro.retailcrm/classes/general/services/RetailCrmService.php
Normal file
|
@ -0,0 +1,220 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Service
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
use Intaro\RetailCrm\Component\Constants;
|
||||
|
||||
/**
|
||||
* Class RetailCrmService
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Service
|
||||
*/
|
||||
class RetailCrmService
|
||||
{
|
||||
/**
|
||||
* @param $order
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function unsetIntegrationDeliveryFields(array $order): array
|
||||
{
|
||||
$integrationDelivery = RetailcrmConfigProvider::getCrmIntegrationDelivery();
|
||||
|
||||
if (isset($order['delivery']['code'])) {
|
||||
$deliveryCode = $order['delivery']['code'];
|
||||
|
||||
if (!empty($integrationDelivery[$deliveryCode])
|
||||
&& $integrationDelivery[$deliveryCode] !== 'sdek'
|
||||
&& $integrationDelivery[$deliveryCode] !== 'dpd'
|
||||
&& $integrationDelivery[$deliveryCode] !== 'newpost'
|
||||
&& $integrationDelivery[$deliveryCode] !== 'courier'
|
||||
) {
|
||||
unset($order['weight']);
|
||||
unset($order['firstName']);
|
||||
unset($order['lastName']);
|
||||
unset($order['phone']);
|
||||
unset($order['delivery']['cost']);
|
||||
unset($order['paymentType']);
|
||||
unset($order['shipmentStore']);
|
||||
unset($order['delivery']['address']);
|
||||
unset($order['delivery']['data']);
|
||||
}
|
||||
|
||||
switch ($integrationDelivery[$deliveryCode]) {
|
||||
case "sdek":
|
||||
unset($order['weight']);
|
||||
unset($order['length']);
|
||||
unset($order['width']);
|
||||
unset($order['height']);
|
||||
unset($order['phone']);
|
||||
unset($order['delivery']['cost']);
|
||||
unset($order['paymentType']);
|
||||
unset($order['shipmentStore']);
|
||||
unset($order['number']);
|
||||
unset($order['delivery']['address']);
|
||||
unset($order['delivery']['data']);
|
||||
break;
|
||||
case "dpd":
|
||||
unset($order['weight']);
|
||||
unset($order['manager']);
|
||||
unset($order['phone']);
|
||||
unset($order['firstName']);
|
||||
unset($order['lastName']);
|
||||
unset($order['delivery']['cost']);
|
||||
unset($order['paymentType']);
|
||||
unset($order['shipmentStore']);
|
||||
unset($order['delivery']['address']);
|
||||
unset($order['delivery']['data']);
|
||||
break;
|
||||
case "newpost":
|
||||
unset($order['weight']);
|
||||
unset($order['customer']);
|
||||
unset($order['phone']);
|
||||
unset($order['shipmentStore']);
|
||||
unset($order['paymentType']);
|
||||
unset($order['delivery']['cost']);
|
||||
unset($order['delivery']['address']);
|
||||
unset($order['delivery']['data']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function selectIntegrationDeliveries(array $data): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($data as $elem) {
|
||||
if (!empty($elem['integrationCode'])) {
|
||||
$result[$elem['code']] = $elem['integrationCode'];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function selectIntegrationPayments(array $data): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($data as $elem) {
|
||||
if (!empty($elem['integrationModule'])) {
|
||||
$result[] = $elem['code'];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $paySystemId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isIntegrationPayment(?int $paySystemId): bool {
|
||||
return in_array(
|
||||
RetailcrmConfigProvider::getPaymentTypes()[$paySystemId] ?? null,
|
||||
RetailcrmConfigProvider::getIntegrationPaymentTypes(),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $availableSites
|
||||
* @param array|null $types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getAvailableTypes(?array $availableSites, ?array $types)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($types as $type) {
|
||||
if ($type['active'] !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($type['sites'])) {
|
||||
$result[$type['code']] = $type;
|
||||
} else {
|
||||
foreach ($type['sites'] as $site) {
|
||||
if (!empty($availableSites[$site])) {
|
||||
$result[$type['code']] = $type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arFields
|
||||
* @return void
|
||||
*/
|
||||
public static function writeLogsSubscribe(array $arFields): void
|
||||
{
|
||||
if (array_key_exists('UF_SUBSCRIBE_USER_EMAIL', $arFields)) {
|
||||
$actionSub = GetMessage('SUBSCRIBED_USER');
|
||||
$fileSub = 'subscribe';
|
||||
|
||||
if (empty($arFields['UF_SUBSCRIBE_USER_EMAIL'])) {
|
||||
$actionSub = GetMessage('UNSUBSCRIBED_USER');
|
||||
$fileSub = 'unSubscribe';
|
||||
}
|
||||
|
||||
$id = $arFields['ID'] ?? $arFields['USER_ID'];
|
||||
|
||||
Logger::getInstance()->write(
|
||||
$actionSub . ' (' . $id . ')',
|
||||
$fileSub
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmPayment
|
||||
* @param array $bitrixPayment
|
||||
* @param array $optionsPaymentTypes
|
||||
* @return array mixed
|
||||
*/
|
||||
public static function preparePayment($crmPayment, $bitrixPayment, $optionsPaymentTypes)
|
||||
{
|
||||
$isIntegrationPayment = self::isIntegrationPayment($bitrixPayment['PAY_SYSTEM_ID'] ?? null);
|
||||
|
||||
if ($isIntegrationPayment && RetailcrmConfigProvider::getSyncIntegrationPayment() === 'Y') {
|
||||
$crmPayment['type'] = $optionsPaymentTypes[$bitrixPayment['PAY_SYSTEM_ID']] .
|
||||
Constants::CRM_PART_SUBSTITUTED_PAYMENT_CODE;
|
||||
} else {
|
||||
$crmPayment['type'] = $optionsPaymentTypes[$bitrixPayment['PAY_SYSTEM_ID']];
|
||||
|
||||
if ($isIntegrationPayment) {
|
||||
unset($crmPayment['paidAt'], $crmPayment['status']);
|
||||
}
|
||||
}
|
||||
|
||||
return $crmPayment;
|
||||
}
|
||||
|
||||
}
|
101
intaro.retailcrm/classes/general/ua/RetailCrmUa.php
Normal file
101
intaro.retailcrm/classes/general/ua/RetailCrmUa.php
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Ua
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class RetailCrmUa
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\Ua
|
||||
*/
|
||||
class RetailCrmUa
|
||||
{
|
||||
public static $MODULE_ID = 'intaro.retailcrm';
|
||||
public static $CRM_UA = 'ua';
|
||||
public static $CRM_UA_KEYS = 'ua_keys';
|
||||
|
||||
public static function add()
|
||||
{
|
||||
$ua = COption::GetOptionString(self::$MODULE_ID, self::$CRM_UA, 0);
|
||||
$uaKeys = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_UA_KEYS, 0));
|
||||
$request = \Bitrix\Main\Context::getCurrent()->getRequest();
|
||||
|
||||
if ($ua === 'Y' && !empty($uaKeys[SITE_ID]['ID']) && !empty($uaKeys[SITE_ID]['INDEX']) && $request->isAdminSection() !== true) {
|
||||
global $APPLICATION;
|
||||
|
||||
$ua = "
|
||||
<script type=\"text/javascript\">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', '" . $uaKeys[SITE_ID]['ID'] . "', 'auto');
|
||||
function getRetailCRMCookie(name) {
|
||||
var matches = document.cookie.match(new RegExp(
|
||||
'(?:^|; )' + name + '=([^;]*)'
|
||||
));
|
||||
return matches ? decodeURIComponent(matches[1]) : '';
|
||||
}
|
||||
ga('set', 'dimension" . $uaKeys[SITE_ID]['INDEX'] . "', getRetailCRMCookie('_ga'));
|
||||
ga('send', 'pageview');
|
||||
</script>";
|
||||
|
||||
/**
|
||||
* В $_GET['ORDER_ID'] содержится номер заказа, а не его ID.
|
||||
* Номер может совпадать с ID заказа, но это необязательное условие,
|
||||
* то есть они могут отличаться.
|
||||
*/
|
||||
if (isset($_GET['ORDER_ID'])) {
|
||||
CModule::IncludeModule("sale");
|
||||
$order = \Bitrix\Sale\Order::loadByAccountNumber($_GET['ORDER_ID']);
|
||||
|
||||
if ($order instanceof \Bitrix\Sale\Order) {
|
||||
$arOrder = array(
|
||||
'ID' => $order->getId(),
|
||||
'PRICE' => $order->getPrice(),
|
||||
'DISCOUNT_VALUE' => $order->getField('DISCOUNT_VALUE')
|
||||
);
|
||||
|
||||
$ua .= "<script type=\"text/javascript\">
|
||||
ga('require', 'ecommerce', 'ecommerce.js');
|
||||
ga('ecommerce:addTransaction', {
|
||||
'id': $arOrder[ID],
|
||||
'affiliation': '$_SERVER[SERVER_NAME]',
|
||||
'revenue': $arOrder[PRICE],
|
||||
'tax': $arOrder[DISCOUNT_VALUE]
|
||||
});
|
||||
";
|
||||
$arBasketItems = CsaleBasket::GetList(
|
||||
array('id' => 'asc'),
|
||||
array('ORDER_ID' => $_GET['ORDER_ID']),
|
||||
false,
|
||||
false,
|
||||
array('PRODUCT_ID', 'NAME', 'PRICE', 'QUANTITY', 'ORDER_ID', 'ID')
|
||||
);
|
||||
while ($arItem = $arBasketItems->fetch()) {
|
||||
$ua .= "
|
||||
ga('ecommerce:addItem', {
|
||||
'id': $arOrder[ID],
|
||||
'sku': '$arItem[PRODUCT_ID]',
|
||||
'name': '$arItem[NAME]',
|
||||
'price': $arItem[PRICE],
|
||||
'quantity': $arItem[QUANTITY]
|
||||
});
|
||||
";
|
||||
}
|
||||
$ua .= "ga('ecommerce:send');";
|
||||
$ua .= "</script>";
|
||||
}
|
||||
}
|
||||
|
||||
$APPLICATION->AddHeadString($ua);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\User
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
use Bitrix\Main\UserTable;
|
||||
use RetailCrm\ApiClient;
|
||||
use RetailCrm\Response\ApiResponse;
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
/**
|
||||
* Class RetailCrmCorporateClient
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\User
|
||||
*/
|
||||
class RetailCrmCorporateClient
|
||||
{
|
||||
const CORP_PREFIX = 'corp';
|
||||
|
||||
public static function clientSend($arOrder, $api, $contragentType, $send = false, $fillCorp = false, $site = null)
|
||||
{
|
||||
if (!$api || empty($contragentType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$address = array();
|
||||
$contragent = array();
|
||||
$shops = RetailcrmConfigProvider::getSitesListCorporate();
|
||||
$optionsLegalDetails = RetailcrmConfigProvider::getLegalDetails();
|
||||
$arUser = UserTable::getById($arOrder['USER_ID'])->fetch();
|
||||
|
||||
if (count($shops) == 0) {
|
||||
RCrmActions::eventLog('RetailCrmCorporateClient::clientSend()', '$shops', 'No stores selected for download');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($arOrder['PROPS']['properties'] as $prop) {
|
||||
if ($prop['CODE'] == RetailcrmConfigProvider::getCorporateClientName()) {
|
||||
$nickName = $prop['VALUE'][0];
|
||||
}
|
||||
|
||||
if ($prop['CODE'] == RetailcrmConfigProvider::getCorporateClientAddress()) {
|
||||
$address = $prop['VALUE'][0];
|
||||
}
|
||||
|
||||
if (!empty($optionsLegalDetails)
|
||||
&& $search = array_search($prop['CODE'], $optionsLegalDetails[$arOrder['PERSON_TYPE_ID']])
|
||||
) {
|
||||
$contragent[$search] = $prop['VALUE'][0];//legal order data
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($nickName)) {
|
||||
$nickName = $arUser['WORK_COMPANY'];
|
||||
}
|
||||
|
||||
if (!empty($contragentType)) {
|
||||
$contragent['contragentType'] = $contragentType;
|
||||
}
|
||||
|
||||
foreach ($shops as $shop) {
|
||||
$customerCorporate = [
|
||||
'createdAt' => $arOrder['DATE_INSERT'],
|
||||
"nickName" => $nickName,
|
||||
];
|
||||
|
||||
if ($fillCorp) {
|
||||
$customerCorporate = array_merge(
|
||||
$customerCorporate,
|
||||
[
|
||||
'customerContacts' => [
|
||||
[
|
||||
'isMain' => true,
|
||||
'customer' => [
|
||||
'externalId' => $arUser['ID'],
|
||||
'site' => $shop,
|
||||
],
|
||||
],
|
||||
],
|
||||
'companies' => [
|
||||
[
|
||||
'name' => $nickName,
|
||||
'isMain' => true,
|
||||
],
|
||||
],
|
||||
'addresses' => [
|
||||
[
|
||||
'name' => $nickName,
|
||||
'isMain' => true,
|
||||
'text' => $address,
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($customerCorporate)) {
|
||||
if ($send && isset($_COOKIE['_rc']) && $_COOKIE['_rc'] != '') {
|
||||
$customerCorporate['browserId'] = $_COOKIE['_rc'];
|
||||
}
|
||||
|
||||
$normalizer = new RestNormalizer();
|
||||
$customerCorporate = $normalizer->normalize($customerCorporate, 'customerCorporate');
|
||||
|
||||
Logger::getInstance()->write($customerCorporate, 'clientCorporate');
|
||||
|
||||
if ($send) {
|
||||
$result = RCrmActions::apiMethod($api, 'customersCorporateCreate', __METHOD__, $customerCorporate, $site);
|
||||
|
||||
if (!$result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$customerCorporate['id'] = $result['id'];
|
||||
}
|
||||
|
||||
return $customerCorporate;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public static function addCustomersCorporateAddresses($customeId, $legalName, $adress, $api, $site)
|
||||
{
|
||||
$found = false;
|
||||
$addresses = $api->customersCorporateAddresses(
|
||||
$customeId,
|
||||
array(),
|
||||
null,
|
||||
100,
|
||||
'id',
|
||||
$site
|
||||
);
|
||||
|
||||
if ($addresses && $addresses->isSuccessful() && $addresses->offsetExists('addresses')) {
|
||||
foreach ($addresses['addresses'] as $corpAddress) {
|
||||
if (isset($corpAddress['text']) && $corpAddress['text'] == $adress) {
|
||||
$found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$customerCorporateAddress = array(
|
||||
'name' => $legalName,
|
||||
'text' => $adress
|
||||
);
|
||||
|
||||
$addressResult = $api->customersCorporateAddressesCreate(
|
||||
$customeId,
|
||||
$customerCorporateAddress,
|
||||
'id',
|
||||
$site
|
||||
);
|
||||
|
||||
if (!$addressResult || ($addressResult && !$addressResult->isSuccessful())) {
|
||||
Logger::getInstance()->write(sprintf(
|
||||
'error while trying to append address to corporate customer%s%s',
|
||||
PHP_EOL,
|
||||
print_r(array(
|
||||
'address' => $customerCorporateAddress,
|
||||
'customer' => $customeId
|
||||
), true)
|
||||
), 'apiErrors');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет, существует ли корпоративный клиент с указанным externalId
|
||||
*
|
||||
* @param string $bitrixUserId
|
||||
* @param \RetailCrm\ApiClient $api
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isCorpTookExternalId(string $bitrixUserId, ApiClient $api, $site = null): bool
|
||||
{
|
||||
$response = RCrmActions::apiMethod(
|
||||
$api,
|
||||
'customersCorporateGet',
|
||||
__METHOD__,
|
||||
$bitrixUserId,
|
||||
$site
|
||||
);
|
||||
|
||||
if (false === $response) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($response instanceof ApiResponse && $response->offsetGet('customerCorporate')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @param \RetailCrm\ApiClient $api
|
||||
*/
|
||||
public static function setPrefixForExternalId(string $externalId, ApiClient $api, $site = null)
|
||||
{
|
||||
$response = RCrmActions::apiMethod(
|
||||
$api,
|
||||
'customersCorporateEdit',
|
||||
__METHOD__,
|
||||
[
|
||||
'urlId' => $externalId,
|
||||
'externalId' => self::CORP_PREFIX . $externalId
|
||||
],
|
||||
$site
|
||||
);
|
||||
|
||||
if (false === $response) {
|
||||
Logger::getInstance()->write(
|
||||
sprintf('Не удалось добавить префикс для корпоративного клиента %s', $externalId),
|
||||
'clientCorporate'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
267
intaro.retailcrm/classes/general/user/RetailCrmUser.php
Normal file
267
intaro.retailcrm/classes/general/user/RetailCrmUser.php
Normal file
|
@ -0,0 +1,267 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\User
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license MIT
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://retailcrm.ru/docs
|
||||
*/
|
||||
|
||||
IncludeModuleLangFile(__FILE__);
|
||||
|
||||
use Bitrix\Main\UserTable;
|
||||
|
||||
/**
|
||||
* Class RetailCrmUser
|
||||
*
|
||||
* @category RetailCRM
|
||||
* @package RetailCRM\User
|
||||
*/
|
||||
class RetailCrmUser
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $arFields
|
||||
* @param $api
|
||||
* @param $contragentType
|
||||
* @param false $send
|
||||
* @param null $site
|
||||
*
|
||||
* @return array|false
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function customerSend(array $arFields, $api, $contragentType, bool $send = false, $site = null)
|
||||
{
|
||||
if (!$api || empty($contragentType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($arFields)) {
|
||||
RCrmActions::eventLog('RetailCrmUser::customerSend', 'empty($arFields)', 'incorrect customer');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$customer = self::getSimpleCustomer($arFields);
|
||||
$customer['createdAt'] = new \DateTime($arFields['DATE_REGISTER']);
|
||||
$customer['contragent'] = ['contragentType' => $contragentType];
|
||||
|
||||
if (RetailcrmConfigProvider::getCustomFieldsStatus() === 'Y') {
|
||||
$customer['customFields'] = self::getCustomFields($arFields);
|
||||
}
|
||||
|
||||
if ($send && isset($_COOKIE['_rc']) && $_COOKIE['_rc'] != '') {
|
||||
$customer['browserId'] = $_COOKIE['_rc'];
|
||||
}
|
||||
|
||||
if (function_exists('retailCrmBeforeCustomerSend')) {
|
||||
$newResCustomer = retailCrmBeforeCustomerSend($customer);
|
||||
|
||||
if (is_array($newResCustomer) && !empty($newResCustomer)) {
|
||||
$customer = $newResCustomer;
|
||||
} elseif ($newResCustomer === false) {
|
||||
RCrmActions::eventLog('RetailCrmUser::customerSend', 'retailCrmBeforeCustomerSend()', 'UserID = ' . $arFields['ID'] . '. Sending canceled after retailCrmBeforeCustomerSend');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$normalizer = new RestNormalizer();
|
||||
$customer = $normalizer->normalize($customer, 'customers');
|
||||
|
||||
if (array_key_exists('UF_SUBSCRIBE_USER_EMAIL', $arFields)) {
|
||||
// UF_SUBSCRIBE_USER_EMAIL = '1' or '0'
|
||||
$customer['subscribed'] = (bool) $arFields['UF_SUBSCRIBE_USER_EMAIL'];
|
||||
}
|
||||
|
||||
Logger::getInstance()->write($customer, 'customerSend');
|
||||
|
||||
if (
|
||||
$send
|
||||
&& !RCrmActions::apiMethod($api, 'customersCreate', __METHOD__, $customer, $site)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $customer;
|
||||
}
|
||||
|
||||
public static function customerEdit($arFields, $api, $optionsSitesList = array()) : bool
|
||||
{
|
||||
if (empty($arFields)) {
|
||||
RCrmActions::eventLog('RetailCrmUser::customerEdit', 'empty($arFields)', 'incorrect customer');
|
||||
return false;
|
||||
}
|
||||
|
||||
$customer = self::getSimpleCustomer($arFields);
|
||||
$found = false;
|
||||
|
||||
if (RetailcrmConfigProvider::getCustomFieldsStatus() === 'Y') {
|
||||
$customer['customFields'] = self::getCustomFields($arFields);
|
||||
}
|
||||
|
||||
if (count($optionsSitesList) > 0) {
|
||||
foreach ($optionsSitesList as $site) {
|
||||
$userCrm = RCrmActions::apiMethod($api, 'customersGet', __METHOD__, $arFields['ID'], $site);
|
||||
if (isset($userCrm['customer'])) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$site = null;
|
||||
$userCrm = RCrmActions::apiMethod($api, 'customersGet', __METHOD__, $arFields['ID'], $site);
|
||||
if (isset($userCrm['customer'])) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
$normalizer = new RestNormalizer();
|
||||
$customer = $normalizer->normalize($customer, 'customers');
|
||||
$customer = self::getBooleanFields($customer, $arFields);
|
||||
|
||||
if (function_exists('retailCrmBeforeCustomerSend')) {
|
||||
$newResCustomer = retailCrmBeforeCustomerSend($customer);
|
||||
if (is_array($newResCustomer) && !empty($newResCustomer)) {
|
||||
$customer = $newResCustomer;
|
||||
} elseif ($newResCustomer === false) {
|
||||
RCrmActions::eventLog('RetailCrmUser::customerEdit', 'retailCrmBeforeCustomerSend()', 'UserID = ' . $arFields['ID'] . '. Sending canceled after retailCrmBeforeCustomerSend');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::getInstance()->write($customer, 'customerSend');
|
||||
|
||||
RCrmActions::apiMethod($api, 'customersEdit', __METHOD__, $customer, $site);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arFields
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getSimpleCustomer(array $arFields): array
|
||||
{
|
||||
$customer['externalId'] = $arFields['ID'];
|
||||
$customer['firstName'] = $arFields['NAME'] ?? null;
|
||||
$customer['lastName'] = $arFields['LAST_NAME'] ?? null;
|
||||
$customer['patronymic'] = $arFields['SECOND_NAME'] ?? null;
|
||||
$customer['phones'][]['number'] = $arFields['PERSONAL_PHONE'] ?? null;
|
||||
$customer['phones'][]['number'] = $arFields['WORK_PHONE'] ?? null;
|
||||
$customer['address']['city'] = $arFields['PERSONAL_CITY'] ?? null;
|
||||
$customer['address']['text'] = $arFields['PERSONAL_STREET'] ?? null;
|
||||
$customer['address']['index'] = $arFields['PERSONAL_ZIP'] ?? null;
|
||||
|
||||
if (mb_strlen($arFields['EMAIL']) < 100) {
|
||||
$customer['email'] = $arFields['EMAIL'];
|
||||
}
|
||||
|
||||
return $customer;
|
||||
}
|
||||
|
||||
private static function getBooleanFields($customer, $arFields)
|
||||
{
|
||||
if (isset($arFields['UF_SUBSCRIBE_USER_EMAIL'])) {
|
||||
if ($arFields['UF_SUBSCRIBE_USER_EMAIL'] === "1") {
|
||||
$customer['subscribed'] = true;
|
||||
} else {
|
||||
$customer['subscribed'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $customer;
|
||||
}
|
||||
|
||||
private static function getCustomFields(array $arFields)
|
||||
{
|
||||
if (!method_exists(RCrmActions::class, 'getTypeUserField')
|
||||
|| !method_exists(RCrmActions::class, 'convertCmsFieldToCrmValue')
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$customUserFields = RetailcrmConfigProvider::getMatchedUserFields();
|
||||
$typeList = RCrmActions::getTypeUserField();
|
||||
$result = [];
|
||||
|
||||
foreach ($customUserFields as $code => $codeCrm) {
|
||||
if (isset($arFields[$code])) {
|
||||
$type = $typeList[$code] ?? '';
|
||||
$result[$codeCrm] = RCrmActions::convertCmsFieldToCrmValue($arFields[$code], $type);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function fixDateCustomer(): void
|
||||
{
|
||||
CAgent::RemoveAgent("RetailCrmUser::fixDateCustomer();", RetailcrmConstants::MODULE_ID);
|
||||
COption::SetOptionString(RetailcrmConstants::MODULE_ID, RetailcrmConstants::OPTION_FIX_DATE_CUSTOMER, 'Y');
|
||||
|
||||
$startId = COption::GetOptionInt(RetailcrmConstants::MODULE_ID, RetailcrmConstants::OPTION_FIX_DATE_CUSTOMER_LAST_ID, 0);
|
||||
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
||||
$optionsSitesList = RetailcrmConfigProvider::getSitesList();
|
||||
$limit = 50;
|
||||
$offset = 0;
|
||||
|
||||
while(true) {
|
||||
try {
|
||||
$usersResult = UserTable::getList([
|
||||
'select' => ['ID', 'DATE_REGISTER', 'LID'],
|
||||
'filter' => ['>ID' => $startId],
|
||||
'order' => ['ID'],
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
]);
|
||||
} catch (\Throwable $exception) {
|
||||
Logger::getInstance()->write($exception->getMessage(), 'fixDateCustomers');
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$users = $usersResult->fetchAll();
|
||||
|
||||
if ($users === []) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$site = null;
|
||||
|
||||
if ($optionsSitesList) {
|
||||
if (isset($user['LID']) && array_key_exists($user['LID'], $optionsSitesList) && $optionsSitesList[$user['LID']] !== null) {
|
||||
$site = $optionsSitesList[$user['LID']];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$customer['externalId'] = $user['ID'];
|
||||
|
||||
try {
|
||||
$date = new \DateTime($user['DATE_REGISTER']);
|
||||
$customer['createdAt'] = $date->format('Y-m-d H:i:s');
|
||||
|
||||
RCrmActions::apiMethod($api, 'customersEdit', __METHOD__, $customer, $site);
|
||||
} catch (\Throwable $exception) {
|
||||
Logger::getInstance()->write($exception->getMessage(), 'fixDateCustomers');
|
||||
continue;
|
||||
}
|
||||
|
||||
time_nanosleep(0, 250000000);
|
||||
}
|
||||
|
||||
COption::SetOptionInt(RetailcrmConstants::MODULE_ID, RetailcrmConstants::OPTION_FIX_DATE_CUSTOMER_LAST_ID, end($users)['ID']);
|
||||
|
||||
$offset += $limit;
|
||||
}
|
||||
}
|
||||
}
|
1
intaro.retailcrm/description.ru
Normal file
1
intaro.retailcrm/description.ru
Normal file
|
@ -0,0 +1 @@
|
|||
- Исправлена передача габаритов при выгрузке заказов по агенту
|
163
intaro.retailcrm/export/export_run.php
Normal file
163
intaro.retailcrm/export/export_run.php
Normal file
|
@ -0,0 +1,163 @@
|
|||
<?php
|
||||
|
||||
use Bitrix\Highloadblock\HighloadBlockTable;
|
||||
use Intaro\RetailCrm\Icml\IcmlDirector;
|
||||
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetup;
|
||||
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetupProps;
|
||||
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetupPropsCategories;
|
||||
use Intaro\RetailCrm\Repository\CatalogRepository;
|
||||
use Intaro\RetailCrm\Icml\SettingsService;
|
||||
|
||||
/** @var $SETUP_FILE_NAME */
|
||||
|
||||
if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/retailcrm/export_run.php')) {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/retailcrm/export_run.php');
|
||||
} else {
|
||||
ignore_user_abort(true);
|
||||
set_time_limit(0);
|
||||
|
||||
global $APPLICATION;
|
||||
|
||||
if (
|
||||
!CModule::IncludeModule('iblock')
|
||||
|| !CModule::IncludeModule('catalog')
|
||||
|| !CModule::IncludeModule('intaro.retailcrm')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hlblockModule = false;
|
||||
|
||||
if (CModule::IncludeModule('highloadblock')) {
|
||||
$hlblockModule = true;
|
||||
$hlblockList = [];
|
||||
$hlblockListDb = HighloadBlockTable::getList();
|
||||
|
||||
while ($hlblockArr = $hlblockListDb->Fetch()) {
|
||||
$hlblockList[$hlblockArr["TABLE_NAME"]] = $hlblockArr;
|
||||
}
|
||||
}
|
||||
|
||||
global $PROFILE_ID;
|
||||
$settingService = SettingsService::getInstance([], '', $PROFILE_ID ?? $profile_id);
|
||||
$iblockPropertySku = [];
|
||||
$iblockPropertySkuHl = [];
|
||||
$iblockPropertyUnitSku = [];
|
||||
$iblockPropertyProduct = [];
|
||||
$iblockPropertyProductHl = [];
|
||||
$iblockPropertyUnitProduct = [];
|
||||
|
||||
foreach (array_keys($settingService->actualPropList) as $prop) {
|
||||
$skuUnitProps = ('iblockPropertyUnitSku_' . $prop);
|
||||
$skuUnitProps = $$skuUnitProps;
|
||||
|
||||
if (is_array($skuUnitProps)) {
|
||||
foreach ($skuUnitProps as $iblock => $val) {
|
||||
$iblockPropertyUnitSku[$iblock][$prop] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
$skuProps = ('iblockPropertySku_' . $prop);
|
||||
$skuProps = $$skuProps;
|
||||
if (is_array($skuProps)) {
|
||||
foreach ($skuProps as $iblock => $val) {
|
||||
$iblockPropertySku[$iblock][$prop] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hlblockModule === true) {
|
||||
foreach ($hlblockList as $hlblockTable => $hlblock) {
|
||||
$hbProps = ('highloadblock' . $hlblockTable . '_' . $prop);
|
||||
$hbProps = $$hbProps;
|
||||
|
||||
if (is_array($hbProps)) {
|
||||
foreach ($hbProps as $iblock => $val) {
|
||||
$iblockPropertySkuHl[$hlblockTable][$iblock][$prop] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$productUnitProps = 'iblockPropertyUnitProduct_' . $prop;
|
||||
$productUnitProps = $$productUnitProps;
|
||||
if (is_array($productUnitProps)) {
|
||||
foreach ($productUnitProps as $iblock => $val) {
|
||||
$iblockPropertyUnitProduct[$iblock][$prop] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
$productProps = "iblockPropertyProduct_" . $prop;
|
||||
$productProps = $$productProps;
|
||||
if (is_array($productProps)) {
|
||||
foreach ($productProps as $iblock => $val) {
|
||||
$iblockPropertyProduct[$iblock][$prop] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hlblockModule === true) {
|
||||
foreach ($hlblockList as $hlblockTable => $hlblock) {
|
||||
$hbProps = ('highloadblock_product' . $hlblockTable . '_' . $prop);
|
||||
$hbProps = $$hbProps;
|
||||
|
||||
if (is_array($hbProps)) {
|
||||
foreach ($hbProps as $iblock => $val) {
|
||||
$iblockPropertyProductHl[$hlblockTable][$iblock][$prop] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$productPictures = [];
|
||||
|
||||
if (is_array($iblockPropertyProduct_picture)) {
|
||||
foreach ($iblockPropertyProduct_picture as $key => $value) {
|
||||
$productPictures[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$skuPictures = [];
|
||||
|
||||
if (is_array($iblockPropertySku_picture)) {
|
||||
foreach ($iblockPropertySku_picture as $key => $value) {
|
||||
$skuPictures[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$xmlProps = new XmlSetupPropsCategories(
|
||||
new XmlSetupProps($iblockPropertyProduct, $iblockPropertyUnitProduct, $productPictures),
|
||||
new XmlSetupProps($iblockPropertySku, $iblockPropertyUnitSku, $skuPictures)
|
||||
);
|
||||
|
||||
if ($hlblockModule === true) {
|
||||
$xmlProps->highloadblockSku = $iblockPropertySkuHl;
|
||||
$xmlProps->highloadblockProduct = $iblockPropertyProductHl;
|
||||
}
|
||||
|
||||
$logger = Logger::getInstance('/bitrix/catalog_export/');
|
||||
|
||||
if (!file_exists(dirname($SETUP_FILE_NAME))) {
|
||||
$SETUP_FILE_NAME = $_SERVER['DOCUMENT_ROOT'] . $SETUP_FILE_NAME;
|
||||
|
||||
if (!file_exists(dirname($SETUP_FILE_NAME))) {
|
||||
$logger->write(GetMessage('TARGET_DIR_DOESNT_EXIST'), 'i_crm_load_log');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$fileSetup = new XmlSetup($xmlProps);
|
||||
$fileSetup->profileId = $profile_id;
|
||||
$fileSetup->iblocksForExport = $iblockExport;
|
||||
$fileSetup->maxOffersValue = $maxOffersValue ?? null;
|
||||
$fileSetup->filePath = $SETUP_FILE_NAME;
|
||||
$fileSetup->loadPurchasePrice = $loadPurchasePrice === 'Y';
|
||||
$fileSetup->loadNonActivity = $loadNonActivity === 'Y';
|
||||
$fileSetup->basePriceId = CatalogRepository::getBasePriceId($fileSetup->profileId);
|
||||
|
||||
if (!is_array($fileSetup->iblocksForExport) || count($fileSetup->iblocksForExport) === 0) {
|
||||
$logger->write(GetMessage("IBLOCK_NOT_SELECTED"), 'i_crm_load_log');
|
||||
} else {
|
||||
$loader = new IcmlDirector($fileSetup, $logger);
|
||||
$loader->generateXml();
|
||||
}
|
||||
}
|
984
intaro.retailcrm/export/export_setup.php
Normal file
984
intaro.retailcrm/export/export_setup.php
Normal file
|
@ -0,0 +1,984 @@
|
|||
<?php
|
||||
|
||||
use Intaro\RetailCrm\Icml\SettingsService;
|
||||
|
||||
CModule::IncludeModule('intaro.retailcrm');
|
||||
|
||||
/**
|
||||
* Документация по шаблонам экспорта:
|
||||
* @link https://dev.1c-bitrix.ru/api_help/catalog/templates.php
|
||||
*
|
||||
* Предопределенные переменные:
|
||||
*
|
||||
* Ранее сохраненные настройки экспорта из SETUP_VARS b_catalog_export
|
||||
* @var $arOldSetupVars
|
||||
*
|
||||
* @var $APPLICATION
|
||||
* @var $ACTION
|
||||
*
|
||||
* 1 - вывод настроек, 2 - сохранение формы с настройками
|
||||
* @var $STEP
|
||||
* @var $PROFILE_ID
|
||||
* @var $SETUP_FILE_NAME
|
||||
* @var $SETUP_PROFILE_NAME
|
||||
*/
|
||||
|
||||
//TODO заменить вызов на сервис-локатор, когда он приедет
|
||||
$settingsService = SettingsService::getInstance(
|
||||
$arOldSetupVars ?? [],
|
||||
$ACTION,
|
||||
$PROFILE_ID
|
||||
);
|
||||
|
||||
$isSetupModulePage = $settingsService->isSetupModulePage();
|
||||
|
||||
if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/retailcrm/export_setup.php')) {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/retailcrm/export_setup.php');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!check_bitrix_sessid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
__IncludeLang(GetLangFileName(
|
||||
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/intaro.retailcrm/lang/',
|
||||
'/icml_export_setup.php')
|
||||
);
|
||||
|
||||
$basePriceId = RetailcrmConfigProvider::getCrmBasePrice($_REQUEST['PROFILE_ID']);
|
||||
$priceTypes = $settingsService->priceTypes;
|
||||
$iblockFieldsName = $settingsService->getIblockFieldsNames();
|
||||
$units = $settingsService->getUnitsNames();
|
||||
$hintUnit = $settingsService->getHintUnit();
|
||||
|
||||
//highloadblock
|
||||
if (CModule::IncludeModule('highloadblock')) {
|
||||
$hlblockModule = true;
|
||||
$hlBlockList = $settingsService->getHlBlockList();
|
||||
}
|
||||
|
||||
if (($ACTION === 'EXPORT' || $ACTION === 'EXPORT_EDIT' || $ACTION === 'EXPORT_COPY') && $STEP === 1) {
|
||||
$SETUP_FILE_NAME = $settingsService->setupFileName;
|
||||
$SETUP_PROFILE_NAME = $settingsService->setupProfileName;
|
||||
|
||||
$loadPurchasePrice = $settingsService->loadPurchasePrice;
|
||||
$iblockExport = $settingsService->iblockExport;
|
||||
$loadNonActivity = $settingsService->loadNonActivity;
|
||||
|
||||
if ($iblockExport) {
|
||||
$maxOffersValue = $settingsService->getSingleSetting('maxOffersValue');
|
||||
}
|
||||
|
||||
$settingsService->setProps();
|
||||
|
||||
$iblockPropertySku = $settingsService->iblockPropertySku;
|
||||
$iblockPropertyUnitSku = $settingsService->iblockPropertyUnitSku;
|
||||
$iblockPropertyProduct = $settingsService->iblockPropertyProduct;
|
||||
$iblockPropertyUnitProduct = $settingsService->iblockPropertyUnitProduct;
|
||||
|
||||
$boolAll = false;
|
||||
$intCountChecked = 0;
|
||||
$intCountAvailIBlock = 0;
|
||||
}
|
||||
|
||||
if (!isset($iblockExport) || !is_array($iblockExport)) {
|
||||
$iblockExport = [];
|
||||
}
|
||||
|
||||
[$arIBlockList, $intCountChecked, $intCountAvailIBlock, $isExportIblock]
|
||||
= $settingsService->getSettingsForIblocks();
|
||||
|
||||
if (count($iblockExport) !== 0) {
|
||||
if ($intCountChecked === $intCountAvailIBlock) {
|
||||
$boolAll = true;
|
||||
}
|
||||
} else {
|
||||
$intCountChecked = $intCountAvailIBlock;
|
||||
$boolAll = true;
|
||||
}
|
||||
|
||||
//Проверка на ошибки
|
||||
$STEP = $settingsService->returnIfErrors($STEP, $SETUP_FILE_NAME, $SETUP_PROFILE_NAME);
|
||||
|
||||
//Отображение формы
|
||||
if ($STEP === 1) {
|
||||
?>
|
||||
<style>
|
||||
.iblock-export-table-display-none {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<form method="post" id="submit-form" action="<?=$APPLICATION->GetCurPage()?>">
|
||||
<?php
|
||||
if ($ACTION === 'EXPORT_EDIT' || $ACTION === 'EXPORT_COPY') {
|
||||
?>
|
||||
<input type="hidden" name="PROFILE_ID" value="<?=(int)$PROFILE_ID?>">
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<h3><?=GetMessage('SETTINGS_INFOBLOCK')?></h3>
|
||||
<span class="text"><?=GetMessage('EXPORT_CATALOGS');?><br><br></span>
|
||||
<span class="text" style="font-weight: bold;"><?=GetMessage('CHECK_ALL_INFOBLOCKS')?></span>
|
||||
<input
|
||||
style="vertical-align: middle;"
|
||||
type="checkbox"
|
||||
name="icml_export_all"
|
||||
id="icml_export_all"
|
||||
value="Y"
|
||||
onclick="checkAll(this,<?=$intCountAvailIBlock?>);"
|
||||
<?=($boolAll ? ' checked' : '')?>>
|
||||
</br>
|
||||
</br>
|
||||
<div>
|
||||
<?php
|
||||
$checkBoxCounter = 0;
|
||||
|
||||
//Перебираем все торговые каталоги, формируя для каждого таблицу настроек
|
||||
foreach ($arIBlockList as $arIBlock) {
|
||||
?>
|
||||
<div>
|
||||
<div>
|
||||
<span class="text" style="font-weight: bold;">
|
||||
<?= htmlspecialcharsex('['
|
||||
. $arIBlock['IBLOCK_TYPE_ID']
|
||||
. '] '
|
||||
. $arIBlock['NAME']
|
||||
. ' '
|
||||
. $arIBlock['SITE_LIST']) ?>
|
||||
</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="iblockExport[<?=$arIBlock['ID']?>]"
|
||||
id="iblockExport<?=++$checkBoxCounter?>"
|
||||
value="<?=$arIBlock['ID']?>"
|
||||
<?php
|
||||
if ($arIBlock['iblockExport']) {
|
||||
echo ' checked';
|
||||
} ?>
|
||||
onclick="checkOne(this,<?=$intCountAvailIBlock?>);"
|
||||
>
|
||||
</div>
|
||||
<br>
|
||||
<div id="iblockExportTable<?=$checkBoxCounter?>" class="iblockExportTable"
|
||||
data-type="<?=$arIBlock['ID']?>">
|
||||
<table class="adm-list-table" id="export_setup"
|
||||
<?=($arIBlock['PROPERTIES_SKU'] === null ? 'style="width: 66%;"' : '')?>
|
||||
>
|
||||
<thead>
|
||||
<tr class="adm-list-table-header">
|
||||
<td class="adm-list-table-cell">
|
||||
<div class="adm-list-table-cell-inner"><?=GetMessage('LOADED_PROPERTY');?></div>
|
||||
</td>
|
||||
<td class="adm-list-table-cell">
|
||||
<div class="adm-list-table-cell-inner">
|
||||
<?=GetMessage('PROPERTY_PRODUCT_HEADER_NAME')?>
|
||||
</div>
|
||||
</td>
|
||||
<?php
|
||||
if ($arIBlock['PROPERTIES_SKU'] !== null) {?>
|
||||
<td class="adm-list-table-cell">
|
||||
<div class="adm-list-table-cell-inner">
|
||||
<?=GetMessage('PROPERTY_OFFER_HEADER_NAME');?>
|
||||
</div>
|
||||
</td>
|
||||
<?php
|
||||
} ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
foreach ($settingsService->defaultPropList as $propertyKey => $property) { ?>
|
||||
|
||||
<tr class="adm-list-table-row">
|
||||
<td class="adm-list-table-cell">
|
||||
<?=htmlspecialcharsex($property)?>
|
||||
</td>
|
||||
<td class="adm-list-table-cell">
|
||||
<select
|
||||
style="width: 200px;"
|
||||
id="iblockPropertyProduct_<?=$propertyKey . $arIBlock['ID']?>"
|
||||
name="iblockPropertyProduct_<?=$propertyKey?>[<?=$arIBlock['ID']?>]"
|
||||
class="property-export"
|
||||
data-type="<?=$propertyKey?>"
|
||||
onchange="propertyChange(this);">
|
||||
<option value=""></option>
|
||||
<?php
|
||||
if ($settingsService->isOptionHasPreset($propertyKey)) {
|
||||
?>
|
||||
<optgroup label="<?=GetMessage('SELECT_FIELD_NAME')?>">
|
||||
<?php
|
||||
foreach ($iblockFieldsName as $keyField => $field) {
|
||||
if ($keyField === $propertyKey) { ?>
|
||||
<option value="<?=$field['CODE']?>"
|
||||
<?php
|
||||
$isSelected = $settingsService->isOptionSelected(
|
||||
$field,
|
||||
$arIBlock['OLD_PROPERTY_PRODUCT_SELECT'],
|
||||
$propertyKey
|
||||
);
|
||||
?>
|
||||
|
||||
<?= $isSelected ? ' selected' : ''?>
|
||||
>
|
||||
<?=$field['name']?>
|
||||
</option>
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?=GetMessage('SELECT_PROPERTY_NAME')?>">
|
||||
<?php
|
||||
}
|
||||
|
||||
$productHlTableName = '';
|
||||
|
||||
foreach ($arIBlock['PROPERTIES_PRODUCT'] as $prop) { ?>
|
||||
<option value="<?=$prop['CODE']?>"
|
||||
<?php
|
||||
echo $settingsService->getOptionClass($prop, true);
|
||||
|
||||
$isSelected = $settingsService->isOptionSelected(
|
||||
$prop,
|
||||
$arIBlock['OLD_PROPERTY_PRODUCT_SELECT'],
|
||||
$propertyKey
|
||||
);
|
||||
|
||||
$productHlTableName
|
||||
= $settingsService->getHlTableName($prop)
|
||||
?? $productHlTableName;
|
||||
|
||||
echo $isSelected ? ' selected' : '';
|
||||
?>
|
||||
>
|
||||
<?=$prop['NAME']?>
|
||||
</option>
|
||||
<?php
|
||||
}
|
||||
|
||||
if ($settingsService->isOptionHasPreset($propertyKey)) {
|
||||
?>
|
||||
</optgroup>
|
||||
<?php
|
||||
} ?>
|
||||
</select>
|
||||
<?php
|
||||
if ($settingsService->isHlSelected(
|
||||
$propertyKey,
|
||||
$arIBlock['ID'],
|
||||
$productHlTableName,
|
||||
'_product'
|
||||
)
|
||||
) {?>
|
||||
<select name="highloadblock_product<?=$productHlTableName . '_' .
|
||||
$propertyKey . '[' . $arIBlock['ID'] . ']' ?>" id="highloadblock"
|
||||
style="width: 100px; margin-left: 50px;">
|
||||
<?php
|
||||
foreach ($hlBlockList[$productHlTableName]['FIELDS'] as $field) {
|
||||
?>
|
||||
<option value="<?=$field?>"
|
||||
<?= $settingsService->getHlOptionStatus(
|
||||
$productHlTableName,
|
||||
$propertyKey,
|
||||
$arIBlock['ID'],
|
||||
(string) $field,
|
||||
'highloadblock_product'
|
||||
) ?>
|
||||
>
|
||||
<?=$field?>
|
||||
</option>
|
||||
<?php
|
||||
} ?>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
//Единицы измерения для товаров
|
||||
if (array_key_exists($propertyKey, $iblockFieldsName)) :?>
|
||||
<select
|
||||
style="width: 100px; margin-left: 50px;"
|
||||
id="iblockPropertyUnitProduct_<?=$propertyKey . $arIBlock['ID']?>"
|
||||
name="iblockPropertyUnitProduct_<?=$propertyKey?>[<?=$arIBlock['ID']?>]"
|
||||
>
|
||||
<?php
|
||||
foreach ($units as $unitTypeName => $unitType) { ?>
|
||||
<?php
|
||||
if ($unitTypeName == $iblockFieldsName[$propertyKey]['unit']): ?>
|
||||
<?php
|
||||
foreach ($unitType as $keyUnit => $unit): ?>
|
||||
<option value="<?=$keyUnit?>"
|
||||
<?=$settingsService->getUnitOptionStatus(
|
||||
$arIBlock['OLD_PROPERTY_UNIT_PRODUCT_SELECT'],
|
||||
$keyUnit,
|
||||
$propertyKey,
|
||||
(string) $unitTypeName
|
||||
)
|
||||
?>
|
||||
>
|
||||
<?=$unit?>
|
||||
</option>
|
||||
<?php
|
||||
endforeach; ?>
|
||||
<?php
|
||||
endif; ?>
|
||||
<?php
|
||||
} ?>
|
||||
</select>
|
||||
<?php
|
||||
endif; ?>
|
||||
</td>
|
||||
<?php
|
||||
//Столбец со свойствами тороговых предложений
|
||||
if ($arIBlock['PROPERTIES_SKU'] !== null) {?>
|
||||
<td class="adm-list-table-cell">
|
||||
<select
|
||||
style="width: 200px;"
|
||||
id="iblockPropertySku_<?=$propertyKey?><?=$arIBlock['ID']?>"
|
||||
name="iblockPropertySku_<?=$propertyKey?>[<?=$arIBlock['ID']?>]"
|
||||
class="property-export"
|
||||
data-type="<?=$propertyKey?>"
|
||||
onchange="propertyChange(this);">
|
||||
|
||||
<option value=""></option>
|
||||
<?php
|
||||
if ($settingsService->isOptionHasPreset($propertyKey)) {
|
||||
?>
|
||||
<optgroup label="<?=GetMessage('SELECT_FIELD_NAME');?>">
|
||||
<?php
|
||||
foreach ($iblockFieldsName as $keyField => $field) {
|
||||
if ($keyField === $propertyKey) :?>
|
||||
<option value="<?=$field['CODE']?>"
|
||||
<?php
|
||||
$isSelected = $settingsService->isOptionSelected(
|
||||
$field,
|
||||
$arIBlock['OLD_PROPERTY_SKU_SELECT'],
|
||||
$propertyKey
|
||||
);
|
||||
echo $isSelected ? ' selected' : '';
|
||||
?>
|
||||
>
|
||||
<?=$field['name']?>
|
||||
</option>
|
||||
<?php
|
||||
endif;
|
||||
} ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?=GetMessage('SELECT_PROPERTY_NAME');?>">
|
||||
<?php
|
||||
}
|
||||
|
||||
$skuHlTableName = '';
|
||||
|
||||
foreach ($arIBlock['PROPERTIES_SKU'] as $prop) { ?>
|
||||
<option value="<?=$prop['CODE']?>"
|
||||
<?php
|
||||
echo $settingsService->getOptionClass($prop, false);
|
||||
|
||||
$isSelected = $settingsService->isOptionSelected(
|
||||
$prop,
|
||||
$arIBlock['OLD_PROPERTY_SKU_SELECT'],
|
||||
$propertyKey
|
||||
);
|
||||
|
||||
$skuHlTableName
|
||||
= $settingsService->getHlTableName($prop)
|
||||
?? $skuHlTableName;
|
||||
|
||||
echo $isSelected ? ' selected' : '';
|
||||
?>
|
||||
>
|
||||
<?=$prop['NAME']?>
|
||||
</option>
|
||||
<?php
|
||||
}
|
||||
|
||||
if ($settingsService->isOptionHasPreset($propertyKey)) {
|
||||
?>
|
||||
</optgroup>
|
||||
<?php
|
||||
} ?>
|
||||
</select>
|
||||
<?php
|
||||
if (
|
||||
$settingsService->isHlSelected(
|
||||
$propertyKey,
|
||||
$arIBlock['ID'],
|
||||
$skuHlTableName
|
||||
)
|
||||
) { ?>
|
||||
<select
|
||||
name="highloadblock<?=$skuHlTableName . '_' . $propertyKey . '['
|
||||
. $arIBlock['ID'] . ']'?>"
|
||||
id="highloadblock"
|
||||
style="width: 100px;
|
||||
margin-left: 50px;"
|
||||
>
|
||||
<?php
|
||||
foreach ($hlBlockList[$skuHlTableName]['FIELDS'] as $field)
|
||||
: ?>
|
||||
<option value="<?=$field?>"
|
||||
<?=
|
||||
$settingsService->getHlOptionStatus(
|
||||
$skuHlTableName,
|
||||
$propertyKey,
|
||||
$arIBlock['ID'],
|
||||
(string) $field,
|
||||
'highloadblock'
|
||||
)?>
|
||||
>
|
||||
<?=$field?>
|
||||
</option>
|
||||
<?php
|
||||
endforeach; ?>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
if (array_key_exists($propertyKey, $iblockFieldsName)) {?>
|
||||
<select
|
||||
style="width: 100px; margin-left: 50px;"
|
||||
id="iblockPropertyUnitSku_<?=$propertyKey?><?=$arIBlock['ID']?>"
|
||||
name="iblockPropertyUnitSku_<?=$propertyKey?>[<?=$arIBlock['ID']?>]"
|
||||
>
|
||||
<?php
|
||||
foreach ($units as $unitTypeName => $unitType) {
|
||||
if ($unitTypeName == $iblockFieldsName[$propertyKey]['unit']) {
|
||||
foreach ($unitType as $keyUnit => $unit) { ?>
|
||||
<option value="<?=$keyUnit?>"
|
||||
<?php
|
||||
echo $settingsService->getUnitOptionStatus(
|
||||
$arIBlock['OLD_PROPERTY_UNIT_SKU_SELECT'],
|
||||
$keyUnit,
|
||||
$propertyKey,
|
||||
$unitTypeName
|
||||
);
|
||||
?>
|
||||
>
|
||||
<?=$unit?>
|
||||
</option>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
} ?>
|
||||
</select>
|
||||
<?php
|
||||
} ?>
|
||||
</td>
|
||||
<?php
|
||||
} ?>
|
||||
</tr>
|
||||
<?php
|
||||
} ?>
|
||||
|
||||
<?php
|
||||
$catalogId = $arIBlock['ID'];
|
||||
$catalogCustomProps = $settingsService->customPropList[$catalogId];
|
||||
|
||||
if (!empty($catalogCustomProps)) {
|
||||
foreach ($catalogCustomProps as $catalogCustomPropCode => $catalogCustomPropValue) { ?>
|
||||
<tr class="adm-list-table-row custom-property-row">
|
||||
<td class="adm-list-table-cell custom-property-title">
|
||||
<?=htmlspecialcharsex($catalogCustomPropValue)?>
|
||||
</td>
|
||||
<td class="adm-list-table-cell">
|
||||
<select
|
||||
name="iblockPropertyProduct_<?=$catalogCustomPropCode?>[<?= $catalogId ?>]"
|
||||
id="iblockPropertyProduct_<?=$catalogCustomPropCode . $catalogId ?>"
|
||||
class="property-export"
|
||||
data-type="<?= $catalogCustomPropCode ?>"
|
||||
onchange="propertyChange(this)"
|
||||
style="width: 200px">
|
||||
|
||||
<option value=""></option>
|
||||
<?php foreach ($arIBlock['PROPERTIES_PRODUCT'] as $prop) {
|
||||
$productHlTableName = ''; ?>
|
||||
<option value="<?=$prop['CODE']?>"
|
||||
<?php
|
||||
echo $settingsService->getOptionClass($prop, true);
|
||||
|
||||
$isSelected = $settingsService->isOptionSelected(
|
||||
$prop,
|
||||
$arIBlock['OLD_PROPERTY_PRODUCT_SELECT'],
|
||||
$catalogCustomPropCode
|
||||
);
|
||||
|
||||
$productHlTableName
|
||||
= $settingsService->getHlTableName($prop)
|
||||
?? $productHlTableName;
|
||||
|
||||
echo $isSelected ? ' selected' : '';
|
||||
?>
|
||||
>
|
||||
<?=$prop['NAME']?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</td>
|
||||
|
||||
<?php if ($arIBlock['PROPERTIES_SKU'] !== null) { ?>
|
||||
<td class="adm-list-table-cell">
|
||||
<select
|
||||
name="iblockPropertySku_<?=$catalogCustomPropCode?>[<?= $catalogId ?>]"
|
||||
id="iblockPropertySku_<?=$catalogCustomPropCode . $catalogId ?>"
|
||||
class="property-export"
|
||||
data-type="<?= $catalogCustomPropCode ?>"
|
||||
onchange="propertyChange(this)"
|
||||
style="width: 200px">
|
||||
|
||||
<option value=""></option>
|
||||
<?php foreach ($arIBlock['PROPERTIES_SKU'] as $prop) {
|
||||
$skuHlTableName = ''; ?>
|
||||
<option value="<?=$prop['CODE']?>"
|
||||
<?php
|
||||
echo $settingsService->getOptionClass($prop, false);
|
||||
|
||||
$isSelected = $settingsService->isOptionSelected(
|
||||
$prop,
|
||||
$arIBlock['OLD_PROPERTY_SKU_SELECT'],
|
||||
$catalogCustomPropCode
|
||||
);
|
||||
|
||||
$skuHlTableName
|
||||
= $settingsService->getHlTableName($prop)
|
||||
?? $skuHlTableName;
|
||||
|
||||
echo $isSelected ? ' selected' : '';
|
||||
?>
|
||||
>
|
||||
<?=$prop['NAME']?>
|
||||
</option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
<button id="delete-custom-row" class="adm-btn-save" type="button" style="margin-left: 10px"><?= GetMessage('DELETE_PROPERTY');?></button>
|
||||
</td>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
<?php }
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<button class="adm-btn-save add-custom-row" type="button" style="margin-top: 20px;"><?= GetMessage('ADD_PROPERTY');?></button>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
} ?>
|
||||
</div>
|
||||
<input type="hidden" name="count_checked" id="count_checked" value="<?=$intCountChecked?>">
|
||||
<br>
|
||||
<template id="custom-property-template-row">
|
||||
<tr class="adm-list-table-row custom-property-row">
|
||||
<td class="adm-list-table-cell">
|
||||
<input type="text" title="Название нового свойства" name="custom-property-title" style="width: 200px">
|
||||
</td>
|
||||
<td class="adm-list-table-cell">
|
||||
<select name="iblockPropertyProduct_" id="iblockPropertyProduct_" class="property-export" onchange="propertyChange(this)" style="width: 200px"></select>
|
||||
</td>
|
||||
<td class="adm-list-table-cell">
|
||||
<select name="iblockPropertySku_" id="iiblockPropertySku_" class="property-export" onchange="propertyChange(this)" style="width: 200px"></select>
|
||||
<button id="delete-new-custom-row" class="adm-btn-save" type="button" style="margin-left: 10px"><?= GetMessage('DELETE_PROPERTY');?></button>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
<h3><?=GetMessage('SETTINGS_EXPORT')?></h3>
|
||||
<span class="text"><?=GetMessage('FILENAME')?><br><br></span>
|
||||
<input type="text" name="SETUP_FILE_NAME" value="<?=htmlspecialcharsbx(strlen($SETUP_FILE_NAME) > 0 ?
|
||||
$SETUP_FILE_NAME : $settingsService->setupFileName); ?>" size="50"><br><br>
|
||||
<span class="text"><?=GetMessage('LOAD_PURCHASE_PRICE')?> </span>
|
||||
<input type="checkbox" name="loadPurchasePrice" value="Y" <?=$loadPurchasePrice === 'Y' ? 'checked' : ''?>>
|
||||
<br><br>
|
||||
<span class="text"><?=GetMessage('LOAD_NON_ACTIVITY')?> </span>
|
||||
<input type="checkbox" name="loadNonActivity" value="Y" <?=$loadNonActivity === 'Y' ? 'checked' : ''?>>
|
||||
<br><br>
|
||||
<?php
|
||||
if ($isSetupModulePage) { ?>
|
||||
<span class="text"><?=GetMessage('AGENT_LOADING')?> </span>
|
||||
<input id="add-agent" type="checkbox" name="NEED_CATALOG_AGENT" value="agent"><br><br>
|
||||
<span class="text" style="font-weight: bold; font-size: 14px"><?=GetMessage('LOAD_NOW')?> </span>
|
||||
<input id="load-now" type="checkbox" onchange="checkLoadStatus(this)" name="LOAD_NOW" value="now"><br>
|
||||
<br>
|
||||
<div id="loadMessageNow" hidden><?=GetMessage('LOAD_NOW_MSG')?></div>
|
||||
<br>
|
||||
<?php
|
||||
}?>
|
||||
|
||||
<span class="text"><?=GetMessage('BASE_PRICE')?> </span>
|
||||
<select name="price-types" class="typeselect">
|
||||
<option value=""></option>
|
||||
<?php
|
||||
foreach ($priceTypes as $priceType) { ?>
|
||||
<option value="<?=$priceType['ID']?>" <?= $priceType['ID'] == $basePriceId ? ' selected' : ''?>>
|
||||
<?=$priceType['NAME']?>
|
||||
</option>
|
||||
<?php
|
||||
} ?>
|
||||
</select><br><br><br>
|
||||
<?php
|
||||
if ($ACTION === 'EXPORT_SETUP' || $ACTION === 'EXPORT_EDIT' || $ACTION === 'EXPORT_COPY') { ?>
|
||||
<span class="text"><?=GetMessage('OFFERS_VALUE')?><br><br></span>
|
||||
<label>
|
||||
<input
|
||||
type="text"
|
||||
name="maxOffersValue"
|
||||
value="<?=htmlspecialchars($maxOffersValue)?>"
|
||||
size="15">
|
||||
</label><br><br><br>
|
||||
|
||||
<span class="text"><?=GetMessage('PROFILE_NAME')?><br><br></span>
|
||||
<label>
|
||||
<input
|
||||
type="text"
|
||||
name="SETUP_PROFILE_NAME"
|
||||
value="<?=htmlspecialchars(strlen($SETUP_PROFILE_NAME) > 0 ?
|
||||
$SETUP_PROFILE_NAME : $settingsService->setupProfileName)?>"
|
||||
size="50">
|
||||
</label><br><br><br>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<?=bitrix_sessid_post()?>
|
||||
<?php
|
||||
if ($isSetupModulePage) { ?>
|
||||
<input type="hidden" name="lang" value="<?= LANG; ?>">
|
||||
<input type="hidden" name="id" value="intaro.retailcrm">
|
||||
<input type="hidden" name="install" value="Y">
|
||||
<input type="hidden" name="step" value="6">
|
||||
<input type="hidden" name="continue" value="5">
|
||||
<div style="padding: 1px 13px 2px; height:28px;">
|
||||
<div align="right" style="float:right; width:50%; position:relative;">
|
||||
<input type="submit" name="inst" onclick="BX.showWait()" value="<?= GetMessage('MOD_NEXT_STEP'); ?>"
|
||||
class="adm-btn-save">
|
||||
</div>
|
||||
<div align="left" style="float:right; width:50%; position:relative;">
|
||||
<input type="submit" name="back" value="<?= GetMessage('MOD_PREV_STEP'); ?>" class="adm-btn-save">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
} else {?>
|
||||
<input type="hidden" name="lang" value="<?=LANGUAGE_ID?>">
|
||||
<input type="hidden" name="ACT_FILE" value="<?=htmlspecialcharsbx($_REQUEST['ACT_FILE'])?>">
|
||||
<input type="hidden" name="ACTION" value="<?=htmlspecialcharsbx($ACTION)?>">
|
||||
<input type="hidden" name="STEP" value="<?=$STEP + 1?>">
|
||||
<input type="hidden" name="SETUP_FIELDS_LIST" value="<?=
|
||||
$settingsService->getSetupFieldsString(
|
||||
array_keys($settingsService->actualPropList) ?? [],
|
||||
$hlblockModule === true,
|
||||
$hlBlockList ?? []
|
||||
)
|
||||
?>">
|
||||
<input type="submit" value="<?=($ACTION === 'EXPORT') ? GetMessage('EXPORT') : GetMessage('SAVE')?>">
|
||||
<?php
|
||||
} ?>
|
||||
</form>
|
||||
|
||||
<?php CJSCore::Init(['jquery']);?>
|
||||
<?php CUtil::InitJSCore(['intaro_custom_props']); ?>
|
||||
<script type="text/javascript">
|
||||
BX.ready(function() {
|
||||
if (typeof createCustomPropsRaw !== 'function') {
|
||||
$('.add-custom-row').hide();
|
||||
}
|
||||
});
|
||||
|
||||
$('.add-custom-row').click(function () {
|
||||
if (typeof createCustomPropsRaw === 'function') {
|
||||
createCustomPropsRaw($(this));
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', '#delete-new-custom-row', function () {
|
||||
if (typeof deleteCustomPropRow === 'function') {
|
||||
deleteCustomPropRow($(this));
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', '#delete-custom-row', function () {
|
||||
let buttonElem = $(this);
|
||||
|
||||
if (typeof addCustomPropToDelete === 'function' && typeof deleteCustomPropRow === 'function') {
|
||||
addCustomPropToDelete(buttonElem);
|
||||
deleteCustomPropRow(buttonElem);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('blur', 'input[name="custom-property-title"]', function () {
|
||||
|
||||
if (typeof getUniquePropertyCode === 'function' && typeof addCustomPropCodeToSelectAttributes === 'function') {
|
||||
let inputElem = $(this);
|
||||
let newPropertyTitle = inputElem.val();
|
||||
|
||||
if (!newPropertyTitle) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newPropertyCode = getUniquePropertyCode(newPropertyTitle);
|
||||
addCustomPropCodeToSelectAttributes(newPropertyCode, inputElem);
|
||||
}
|
||||
});
|
||||
|
||||
$('#submit-form').submit(function (formEvent) {
|
||||
if (typeof setCustomProperties !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
formEvent.preventDefault();
|
||||
let savePromise = null;
|
||||
let deletePromise = null;
|
||||
let formElem = formEvent.currentTarget;
|
||||
let profileId = $($('input[name="PROFILE_ID"]')).val();
|
||||
|
||||
setCustomProperties();
|
||||
|
||||
if (Object.keys(customProps).length > 0) {
|
||||
savePromise = BX.ajax.runAction('intaro:retailcrm.api.customexportprops.save', {
|
||||
json: {
|
||||
properties: customProps,
|
||||
profileId: profileId
|
||||
},
|
||||
}).then(addParamsToSetupFieldsList());
|
||||
}
|
||||
|
||||
if (Object.keys(customPropsToDelete).length > 0) {
|
||||
deletePromise = BX.ajax.runAction('intaro:retailcrm.api.customexportprops.delete', {
|
||||
json: {
|
||||
properties: customPropsToDelete,
|
||||
profileId: profileId
|
||||
},
|
||||
}).then(deleteParamsFromSetupFieldsList());
|
||||
}
|
||||
|
||||
const promises = [savePromise, deletePromise].filter(Boolean);
|
||||
|
||||
if (promises.length > 0) {
|
||||
Promise.all(promises)
|
||||
.finally(() => {
|
||||
formElem.submit();
|
||||
});
|
||||
} else {
|
||||
formElem.submit();
|
||||
}
|
||||
});
|
||||
|
||||
const setupFieldsListElement = $('input[name="SETUP_FIELDS_LIST"]');
|
||||
let customProps = {};
|
||||
let customPropsToDelete = {};
|
||||
const setupFieldsParamsToFill = [
|
||||
'iblockPropertySku_',
|
||||
'iblockPropertyUnitSku_',
|
||||
'iblockPropertyProduct_',
|
||||
'iblockPropertyUnitProduct_',
|
||||
'highloadblockb_hlsys_marking_code_group_',
|
||||
'highloadblock_productb_hlsys_marking_code_group_',
|
||||
'highloadblockeshop_color_reference_',
|
||||
'highloadblock_producteshop_color_reference_',
|
||||
'highloadblockeshop_brand_reference_',
|
||||
'highloadblock_producteshop_brand_reference_'
|
||||
];
|
||||
|
||||
function checkLoadStatus(object)
|
||||
{
|
||||
if (object.checked) {
|
||||
$('#loadMessageNow').show();
|
||||
} else {
|
||||
$('#loadMessageNow').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function checkAll(obj, cnt) {
|
||||
for (let i = 0; i < cnt; i++) {
|
||||
if (obj.checked) {
|
||||
BX.removeClass('iblockExportTable' + (i + 1), "iblock-export-table-display-none");
|
||||
}
|
||||
}
|
||||
|
||||
const table = BX(obj.id.replace('iblockExport', 'iblockExportTable'));
|
||||
|
||||
if (obj.checked) {
|
||||
BX.removeClass(table, "iblock-export-table-display-none");
|
||||
}
|
||||
|
||||
const easing = new BX.easing({
|
||||
duration: 150,
|
||||
start: {opacity: obj.checked ? 0 : 100},
|
||||
finish: {opacity: obj.checked ? 100 : 0},
|
||||
transition: BX.easing.transitions.linear,
|
||||
step: function(state) {
|
||||
for (let i = 0; i < cnt; i++) {
|
||||
BX('iblockExportTable' + (i + 1)).style.opacity = state.opacity / 100;
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
for (let i = 0; i < cnt; i++) {
|
||||
if (!obj.checked) {
|
||||
BX.addClass('iblockExportTable' + (i + 1), "iblock-export-table-display-none");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
easing.animate();
|
||||
const boolCheck = obj.checked;
|
||||
|
||||
for (let i = 0; i < cnt; i++) {
|
||||
BX('iblockExport' + (i + 1)).checked = boolCheck;
|
||||
}
|
||||
|
||||
BX('count_checked').value = (boolCheck ? cnt : 0);
|
||||
}
|
||||
|
||||
function checkOne(obj, cnt) {
|
||||
const table = BX(obj.id.replace('iblockExport', 'iblockExportTable'));
|
||||
|
||||
if (obj.checked) {
|
||||
BX.removeClass(table, "iblock-export-table-display-none");
|
||||
}
|
||||
|
||||
const easing = new BX.easing({
|
||||
duration: 150,
|
||||
start: {opacity: obj.checked ? 0 : 100},
|
||||
finish: {opacity: obj.checked ? 100 : 0},
|
||||
transition: BX.easing.transitions.linear,
|
||||
step: function(state) {
|
||||
table.style.opacity = state.opacity / 100;
|
||||
},
|
||||
complete: function() {
|
||||
if (!obj.checked) {
|
||||
BX.addClass(table, "iblock-export-table-display-none");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
easing.animate();
|
||||
const boolCheck = obj.checked;
|
||||
let intCurrent = parseInt(BX('count_checked').value);
|
||||
intCurrent += (boolCheck ? 1 : -1);
|
||||
BX('icml_export_all').checked = (intCurrent >= cnt);
|
||||
BX('count_checked').value = intCurrent;
|
||||
}
|
||||
|
||||
function propertyChange(obj) {
|
||||
let selectedOption = $(obj).find('option')[obj.selectedIndex];
|
||||
|
||||
if (selectedOption.className === 'not-highloadblock') {
|
||||
let objId = '#' + obj.id;
|
||||
|
||||
$(objId).parent().children('#highloadblock').remove();
|
||||
}
|
||||
|
||||
if (selectedOption.className === 'highloadblock') {
|
||||
getHlTablesFromController(selectedOption, 'sku', obj.getAttribute('data-type'));
|
||||
}
|
||||
|
||||
if (selectedOption.className === 'highloadblock-product') {
|
||||
getHlTablesFromController(selectedOption, 'product', obj.getAttribute('data-type'));
|
||||
}
|
||||
}
|
||||
|
||||
function setHlFieldsInInstallPage(that, type, key){
|
||||
const td = $(that).parents('td .adm-list-table-cell');
|
||||
const select = $(that).parent('select').siblings('#highloadblock');
|
||||
const iblock = $(that).parents('.iblockExportTable').attr('data-type');
|
||||
const sessid = BX.bitrix_sessid();
|
||||
const table_name = $(that).attr('id');
|
||||
const step = $('input[name="continue"]').val();
|
||||
const id = $('input[name="id"]').val();
|
||||
const install = $('input[name="install"]').val();
|
||||
const data = 'install=' + install + '&step=' + step + '&sessid=' + sessid +
|
||||
'&id=' + id + '&ajax=1&table=' + table_name;
|
||||
|
||||
$.ajax({
|
||||
url: '/bitrix/admin/partner_modules.php',
|
||||
type: 'POST',
|
||||
data: data,
|
||||
dataType: "json",
|
||||
success: function(res) {
|
||||
$(select).remove();
|
||||
$('#waiting').remove();
|
||||
let new_options = '';
|
||||
$.each(res.fields, function(key, value) {
|
||||
new_options += '<option value="' + value + '">' + value + '</option>';
|
||||
});
|
||||
|
||||
if (type === 'sku') {
|
||||
$(td).append(getSelect(res, key, iblock, new_options, 'highloadblock'));
|
||||
}
|
||||
|
||||
if (type === 'product') {
|
||||
$(td).append(getSelect(res, key, iblock, new_options, 'highloadblock_product'));
|
||||
}
|
||||
},
|
||||
beforeSend: function() {
|
||||
$(td).append('<span style="margin-left:50px;" id="waiting"><?=GetMessage('WAIT')?></span>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setHlFieldsInSettingsPage(that, type, key){
|
||||
const td = $(that).parents('td .adm-list-table-cell');
|
||||
const select = $(that).parent('select').siblings('#highloadblock');
|
||||
const table_name = $(that).attr('id');
|
||||
const iblock = $(that).parents('.iblockExportTable').attr('data-type');
|
||||
|
||||
BX.ajax.runAction('intaro:retailcrm.api.icml.getHlTable',
|
||||
{
|
||||
method: 'POST',
|
||||
data: {
|
||||
sessid: BX.bitrix_sessid(),
|
||||
tableName: table_name
|
||||
}
|
||||
}
|
||||
).then((response) => {
|
||||
$(select).remove();
|
||||
$('#waiting').remove();
|
||||
let new_options = '';
|
||||
$.each(response.data.fields, function(key, value) {
|
||||
new_options += '<option value="' + value + '">' + value + '</option>';
|
||||
});
|
||||
|
||||
let typeValue = 'highloadblock';
|
||||
|
||||
if (type === 'product') {
|
||||
typeValue += '_product'
|
||||
}
|
||||
|
||||
$(td).append(getSelect (response.data, key, iblock, new_options, typeValue));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getHlTablesFromController(that, type, key) {
|
||||
const url = $('td .adm-list-table-cell').parents('form').attr('action');
|
||||
|
||||
if (url === '/bitrix/admin/partner_modules.php') {
|
||||
setHlFieldsInInstallPage(that, type, key);
|
||||
} else {
|
||||
setHlFieldsInSettingsPage(that, type, key)
|
||||
}
|
||||
}
|
||||
|
||||
function getSelect (res, key, iblock, new_options, type){
|
||||
let select = document.createElement('select');
|
||||
let atrName = type + res.table + '_' + key + '[' + iblock + ']';
|
||||
select.setAttribute('name', atrName);
|
||||
select.setAttribute('id', 'highloadblock');
|
||||
select.setAttribute('style','width: 100px; margin-left: 50px;');
|
||||
select.innerHTML = new_options;
|
||||
|
||||
return select;
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
//Сохранение и выход
|
||||
if ($STEP === 2) {
|
||||
RetailcrmConfigProvider::setProfileBasePrice($_REQUEST['PROFILE_ID'], $_POST['price-types']);
|
||||
$FINITE = true;
|
||||
}
|
||||
?>
|
72
intaro.retailcrm/include.php
Normal file
72
intaro.retailcrm/include.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
use Bitrix\Main\ArgumentOutOfRangeException;
|
||||
use Bitrix\Main\Context;
|
||||
use Bitrix\Main\Loader;
|
||||
use Intaro\RetailCrm\Component\ConfigProvider;
|
||||
use Intaro\RetailCrm\Component\Factory\ClientFactory;
|
||||
use Intaro\RetailCrm\Component\ServiceLocator;
|
||||
use Intaro\RetailCrm\Service\CookieService;
|
||||
use Intaro\RetailCrm\Service\OrderLoyaltyDataService;
|
||||
use Intaro\RetailCrm\Service\LoyaltyService;
|
||||
use Intaro\RetailCrm\Service\LoyaltyAccountService;
|
||||
use Intaro\RetailCrm\Service\CustomerService;
|
||||
use Intaro\RetailCrm\Vendor\Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Intaro\RetailCrm\Vendor\Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use \Intaro\RetailCrm\Component\Builder\Api\CustomerBuilder;
|
||||
use RetailCrm\Exception\CurlException;
|
||||
|
||||
require_once __DIR__ . '/RetailcrmClasspathBuilder.php';
|
||||
|
||||
$retailcrmModuleId = 'intaro.retailcrm';
|
||||
$server = Context::getCurrent()->getServer()->getDocumentRoot();
|
||||
$version = COption::GetOptionString('intaro.retailcrm', 'api_version');
|
||||
|
||||
$builder = new RetailcrmClasspathBuilder();
|
||||
$builder->setDisableNamespaces(true)
|
||||
->setDocumentRoot($server)
|
||||
->setModuleId($retailcrmModuleId)
|
||||
->setDirectories(['classes', 'lib/icml'])
|
||||
->setVersion($version)
|
||||
->build();
|
||||
|
||||
Loader::registerAutoLoadClasses('intaro.retailcrm', $builder->getResult());
|
||||
AnnotationRegistry::registerLoader('class_exists');
|
||||
|
||||
ServiceLocator::registerServices([
|
||||
\Intaro\RetailCrm\Service\Utils::class,
|
||||
Logger::class,
|
||||
AnnotationReader::class,
|
||||
CookieService::class,
|
||||
LoyaltyAccountService::class,
|
||||
LoyaltyService::class,
|
||||
CustomerService::class,
|
||||
OrderLoyaltyDataService::class,
|
||||
CustomerBuilder::class
|
||||
]);
|
||||
|
||||
$arJsConfig = [
|
||||
'intaro_countdown' => [
|
||||
'js' => '/bitrix/js/intaro/sms.js',
|
||||
'rel' => [],
|
||||
],
|
||||
'intaro_custom_props' => [
|
||||
'js' => '/bitrix/js/intaro/export/custom-props-export.js',
|
||||
'rel' => [],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($arJsConfig as $ext => $arExt) {
|
||||
CJSCore::RegisterExt($ext, $arExt);
|
||||
}
|
||||
|
||||
if (empty(ConfigProvider::getSitesAvailable())) {
|
||||
$client = ClientFactory::createClientAdapter();
|
||||
try {
|
||||
$credentials = $client->getCredentials();
|
||||
|
||||
ConfigProvider::setSitesAvailable($credentials->sitesAvailable[0] ?? '');
|
||||
} catch (ArgumentOutOfRangeException | CurlException $exception) {
|
||||
Logger::getInstance()->write($exception->getMessage());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
|
||||
function deleteCustomPropRow(deleteButton)
|
||||
{
|
||||
deleteButton.closest('tr').remove();
|
||||
}
|
||||
|
||||
function addCustomPropToDelete(deleteButton)
|
||||
{
|
||||
let deletedPropTitle = deleteButton.closest('td').siblings().filter('.custom-property-title').text().trim();
|
||||
let deletedPropCode = deleteButton.siblings().filter('select').first().data('type');
|
||||
let customPropCatalogId = deleteButton.closest('.iblockExportTable').data('type');
|
||||
|
||||
let values = {
|
||||
'code': deletedPropCode,
|
||||
'title': deletedPropTitle,
|
||||
};
|
||||
|
||||
if (customPropsToDelete.hasOwnProperty(customPropCatalogId)) {
|
||||
customPropsToDelete[customPropCatalogId].push(values);
|
||||
} else {
|
||||
customPropsToDelete[customPropCatalogId] = [values];
|
||||
}
|
||||
}
|
||||
|
||||
function addCustomPropCodeToSelectAttributes(customPropCode, customPropTitleElem)
|
||||
{
|
||||
let selectElements = customPropTitleElem.closest('.custom-property-row').find('td select');
|
||||
let catalogId = customPropTitleElem.closest('.iblockExportTable').data('type');
|
||||
|
||||
selectElements.each(function (index, element) {
|
||||
let selectElem = $(element);
|
||||
let newSelectIdValue = selectElem.attr('id').match(/^[^_]*_/)[0] + customPropCode + catalogId;
|
||||
let newSelectNameValue = selectElem.attr('name').match(/^[^_]*_/)[0] + customPropCode + `[${catalogId}]`;
|
||||
|
||||
selectElem.attr('id', newSelectIdValue);
|
||||
selectElem.attr('name', newSelectNameValue);
|
||||
selectElem.data('type', customPropCode);
|
||||
triggerSelectChange(selectElem);
|
||||
});
|
||||
}
|
||||
|
||||
function triggerSelectChange(selectElem)
|
||||
{
|
||||
if (selectElem.val().length > 0) {
|
||||
selectElem.trigger('change', [self]);
|
||||
}
|
||||
}
|
||||
|
||||
function setCustomProperties()
|
||||
{
|
||||
let customPropertiesRows = $('.custom-property-row');
|
||||
|
||||
if (customPropertiesRows.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let customPropertyCatalogId;
|
||||
let customPropertyTitle = '';
|
||||
let customPropertyCode = '';
|
||||
let productPropertyMatch = '';
|
||||
let offerPropertyMatch = '';
|
||||
|
||||
let catalogIds = [];
|
||||
customPropertiesRows.each(function (index, propertyRow) {
|
||||
let propertyRowObj = $(propertyRow);
|
||||
customPropertyCatalogId = propertyRowObj.closest('.iblockExportTable').data('type');
|
||||
customPropertyTitle = propertyRowObj.find('input[name="custom-property-title"]').val();
|
||||
|
||||
if (!customPropertyTitle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
customPropertyCode = getUniquePropertyCode(customPropertyTitle);
|
||||
productPropertyMatch = propertyRowObj.find('select[name=custom-product-property-select]').val();
|
||||
offerPropertyMatch = propertyRowObj.find('select[name=custom-offer-property-select]').val();
|
||||
|
||||
let values = {
|
||||
'title': customPropertyTitle,
|
||||
'code': customPropertyCode,
|
||||
'productProperty': productPropertyMatch,
|
||||
'offerProperty': offerPropertyMatch
|
||||
};
|
||||
|
||||
if (catalogIds.indexOf(customPropertyCatalogId) === -1) {
|
||||
customProps[customPropertyCatalogId] = [values];
|
||||
} else {
|
||||
customProps[customPropertyCatalogId].push(values);
|
||||
}
|
||||
|
||||
catalogIds.push(customPropertyCatalogId);
|
||||
});
|
||||
}
|
||||
|
||||
function getUniquePropertyCode(customPropertyTitle)
|
||||
{
|
||||
let uniqueValue = transliterate(customPropertyTitle).replace(/ /g, '_');
|
||||
let counter = 0;
|
||||
const setupFieldsListValues = setupFieldsListElement.val().split(',');
|
||||
|
||||
while (setupFieldsListValues.includes(uniqueValue)) {
|
||||
uniqueValue = `${customPropertyTitle}${++counter}`;
|
||||
}
|
||||
|
||||
return uniqueValue;
|
||||
}
|
||||
|
||||
function addParamsToSetupFieldsList()
|
||||
{
|
||||
let newParams = '';
|
||||
|
||||
if (Object.keys(customProps).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let propertiesByCatalogId of Object.values(customProps)) {
|
||||
propertiesByCatalogId.forEach(function (values) {
|
||||
setupFieldsParamsToFill.forEach(function (param) {
|
||||
newParams += ',' + param + values.code;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let newValue = setupFieldsListElement.val() + newParams;
|
||||
setupFieldsListElement.val(newValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function deleteParamsFromSetupFieldsList()
|
||||
{
|
||||
let setupFields = setupFieldsListElement.val();
|
||||
|
||||
if (Object.keys(customPropsToDelete).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let propsByCatalogId of Object.values(customPropsToDelete)) {
|
||||
propsByCatalogId.forEach(function (propValues) {
|
||||
setupFieldsParamsToFill.forEach(function (param) {
|
||||
let paramToDelete = ',' + param + propValues.code;
|
||||
setupFields = setupFields.replace(paramToDelete, '');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setupFieldsListElement.val(setupFields);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function createCustomPropsRaw(addRowButton)
|
||||
{
|
||||
let templateRow = $($('#custom-property-template-row').html());
|
||||
let templateSelectElements = templateRow.find('select');
|
||||
|
||||
let prevTableRow = $(addRowButton).prev('table').find('tbody tr:last-child');
|
||||
let lastRawSelectElements = prevTableRow.find('td select');
|
||||
|
||||
lastRawSelectElements.each(function (index, element) {
|
||||
let selectElement = $(element);
|
||||
let templateSelectElement = templateSelectElements[index];
|
||||
fillTemplateSelect(selectElement, templateSelectElement);
|
||||
prevTableRow.after(templateRow);
|
||||
});
|
||||
}
|
||||
|
||||
function fillTemplateSelect(sourceSelectElement, templateSelectElement)
|
||||
{
|
||||
let selectOptions = sourceSelectElement.find('option');
|
||||
|
||||
selectOptions.each(function (index, element) {
|
||||
let optionElem = $(element);
|
||||
let value = $(optionElem).val();
|
||||
let text = $(optionElem).text();
|
||||
|
||||
$('<option>', { value: value, text: text }).appendTo(templateSelectElement);
|
||||
});
|
||||
}
|
||||
|
||||
function transliterate(titleToTransliterate)
|
||||
{
|
||||
const hasCyrillicChars = /[\u0400-\u04FF]/.test(titleToTransliterate);
|
||||
|
||||
if (!hasCyrillicChars) {
|
||||
return titleToTransliterate;
|
||||
}
|
||||
|
||||
translitedText = '';
|
||||
for (var i = 0; i < titleToTransliterate.length; i++) {
|
||||
switch (titleToTransliterate[i]) {
|
||||
case 'а': case 'А': translitedText += 'a'; break;
|
||||
case 'б': case 'Б': translitedText += 'b'; break;
|
||||
case 'в': case 'В': translitedText += 'v'; break;
|
||||
case 'г': case 'Г': translitedText += 'g'; break;
|
||||
case 'д': case 'Д': translitedText += 'd'; break;
|
||||
case 'е': case 'Е': translitedText += 'e'; break;
|
||||
case 'ё': case 'Ё': translitedText += 'yo'; break;
|
||||
case 'ж': case 'Ж': translitedText += 'zh'; break;
|
||||
case 'з': case 'З': translitedText += 'z'; break;
|
||||
case 'и': case 'И': translitedText += 'i'; break;
|
||||
case 'й': case 'Й': translitedText += 'y'; break;
|
||||
case 'к': case 'К': translitedText += 'k'; break;
|
||||
case 'л': case 'Л': translitedText += 'l'; break;
|
||||
case 'м': case 'М': translitedText += 'm'; break;
|
||||
case 'н': case 'Н': translitedText += 'n'; break;
|
||||
case 'о': case 'О': translitedText += 'o'; break;
|
||||
case 'п': case 'П': translitedText += 'p'; break;
|
||||
case 'р': case 'Р': translitedText += 'r'; break;
|
||||
case 'с': case 'С': translitedText += 's'; break;
|
||||
case 'т': case 'Т': translitedText += 't'; break;
|
||||
case 'у': case 'У': translitedText += 'u'; break;
|
||||
case 'ф': case 'Ф': translitedText += 'f'; break;
|
||||
case 'х': case 'Х': translitedText += 'h'; break;
|
||||
case 'ц': case 'Ц': translitedText += 'c'; break;
|
||||
case 'ч': case 'Ч': translitedText += 'ch'; break;
|
||||
case 'ш': case 'Ш': translitedText += 'sh'; break;
|
||||
case 'щ': case 'Щ': translitedText += 'sch'; break;
|
||||
case 'ъ': case 'Ъ': translitedText += ''; break;
|
||||
case 'ы': case 'Ы': translitedText += 'y'; break;
|
||||
case 'ь': case 'Ь': translitedText += ''; break;
|
||||
case 'э': case 'Э': translitedText += 'e'; break;
|
||||
case 'ю': case 'Ю': translitedText += 'yu'; break;
|
||||
case 'я': case 'Я': translitedText += 'ya'; break;
|
||||
default: translitedText += titleToTransliterate[i]; break;
|
||||
}
|
||||
}
|
||||
return translitedText;
|
||||
}
|
59
intaro.retailcrm/install/export/bitrix/js/intaro/sms.js
Normal file
59
intaro.retailcrm/install/export/bitrix/js/intaro/sms.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
function getTimeRemaining(endtime) {
|
||||
return Date.parse(endtime) - Date.parse(new Date());
|
||||
}
|
||||
|
||||
function initializeClock(id, endtime) {
|
||||
$('#countdownDiv').show();
|
||||
$('#deadlineMessage').hide();
|
||||
|
||||
const timeInterval = setInterval(updateClock, 1000);
|
||||
const clock = document.getElementById(id);
|
||||
|
||||
function updateClock() {
|
||||
const time = getTimeRemaining(endtime);
|
||||
|
||||
if (time <= 0) {
|
||||
$('#countdownDiv').hide();
|
||||
$('#deadlineMessage').show();
|
||||
clearInterval(timeInterval);
|
||||
return true;
|
||||
}
|
||||
|
||||
clock.innerText = String(time).slice(0, -3);
|
||||
}
|
||||
|
||||
updateClock();
|
||||
}
|
||||
|
||||
function resendRegisterSms(idInLoyalty) {
|
||||
BX.ajax.runAction('intaro:retailcrm.api.loyalty.register.resendRegisterSms',
|
||||
{
|
||||
data: {
|
||||
sessid: BX.bitrix_sessid(),
|
||||
idInLoyalty: idInLoyalty
|
||||
}
|
||||
}
|
||||
).then(function(response) {
|
||||
$('#lpRegMsg').text(response.data.msg);
|
||||
$('#checkIdField').val(response.data.form.fields.checkId.value);
|
||||
initializeClock("countdown", response.data.resendAvailable);
|
||||
});
|
||||
}
|
||||
|
||||
function resendOrderSms(orderId) {
|
||||
BX.ajax.runAction('intaro:retailcrm.api.loyalty.order.resendOrderSms',
|
||||
{
|
||||
data: {
|
||||
sessid: BX.bitrix_sessid(),
|
||||
orderId: orderId
|
||||
}
|
||||
}
|
||||
).then(function(response) {
|
||||
if (response.data.msg !== undefined) {
|
||||
$('#msg').text(response.data.msg);
|
||||
} else if (response.data.resendAvailable !== undefined) {
|
||||
$('#checkIdVerify').val(response.data.checkId);
|
||||
initializeClock("countdown", new Date(response.data.resendAvailable.date));
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<?
|
||||
//<title>RetailCRM</title>
|
||||
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/intaro.retailcrm/export/export_run.php");
|
|
@ -0,0 +1,3 @@
|
|||
<?
|
||||
//<title>RetailCRM</title>
|
||||
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/intaro.retailcrm/export/export_setup.php");
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
|
||||
die();
|
||||
}
|
||||
|
||||
$arComponentDescription = [
|
||||
"NAME" => GetMessage("COMP_MAIN_USER_REGISTER_TITLE"),
|
||||
"DESCRIPTION" => GetMessage("COMP_MAIN_USER_REGISTER_DESCR"),
|
||||
"PATH" => [
|
||||
"ID" => "utility",
|
||||
"CHILD" => [
|
||||
"ID" => "user",
|
||||
"NAME" => GetMessage("MAIN_USER_GROUP_NAME"),
|
||||
],
|
||||
],
|
||||
];
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
|
||||
die();
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
if(!defined("B_PROLOG_INCLUDED")||B_PROLOG_INCLUDED!==true) {
|
||||
die();
|
||||
}
|
||||
|
||||
$this->IncludeComponentTemplate();
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
$MESS ['COMP_MAIN_USER_REGISTER_TITLE'] = "Регистрация в программе лояльности";
|
||||
$MESS ['COMP_MAIN_USER_REGISTER_DESCR'] = "Управляемая регистрация в программе лояльности";
|
||||
$MESS ['MAIN_USER_GROUP_NAME'] = "Пользователь";
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
$MESS ['INTARO_NOT_INSTALLED'] = "Модуль интеграции с RetailCRM не установлен";
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
|
||||
die();
|
||||
}
|
||||
|
||||
$arTemplateParameters = [];
|
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
$MESS ['USER_PROPERTY_NAME'] = "Name of the custom property block";
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
$MESS["main_register_sms"] = "Confirmation code from SMS:";
|
||||
$MESS["PERSONAL_PHONE"] = "Phone";
|
||||
$MESS["main_register_sms_send"] = "Send";
|
||||
$MESS["UF_REG_IN_PL_INTARO"] = "Register in loyalty program";
|
||||
$MESS["UF_AGREE_PL_INTARO"] = "loyalty programs:";
|
||||
$MESS["I_AM_AGREE"] = "I agree to the terms and conditions";
|
||||
$MESS["UF_PD_PROC_PL_INTARO"] = "personal data processing:";
|
||||
$MESS["LP_CARD_NUMBER"] = "Loyalty program card number";
|
||||
$MESS["SEND"] = "Send";
|
||||
$MESS["TRY_AGAIN"] = "Try Again";
|
||||
$MESS["VERIFICATION_CODE"] = "Confirmation Code";
|
||||
$MESS["SEND_VERIFICATION_CODE"] = "Send confirmation code";
|
||||
$MESS["REG_LP_MESSAGE"] = "Enter your phone number and loyalty program card number to complete your loyalty program registration.";
|
||||
$MESS["YES"] = "Yes";
|
||||
$MESS["BONUS_CARD_NUMBER"] = "Loyalty card number (if any):";
|
||||
$MESS["SUCCESS_PL_REG"] = "You have successfully registered in the loyalty program.";
|
||||
$MESS["LP_FIELDS_NOT_EXIST"] = "PL module installation error. UF fields for USER are missing.";
|
||||
$MESS["REG_LP_ERROR"] = "Error of registration in the Loyalty Program";
|
||||
$MESS["REGISTER_CONTINUE"] = "Fill out the form to complete your registration in the loyalty program.";
|
||||
$MESS["UF_CARD_NUM_INTARO"] = "Loyalty card number (if any)";
|
||||
$MESS["REGISTER_LP_TITLE"] = "Registration in the loyalty program";
|
||||
$MESS["NOT_AUTHORIZED"] = "You are not logged in. To register, please follow the <a href=\"./lp-register\">link</a>";
|
||||
$MESS["LP_NOT_ACTIVE"] = "Loyalty program is not active at the moment";
|
||||
$MESS["SEC"] = "seconds";
|
||||
$MESS["RESEND_SMS"] = "Send sms again";
|
||||
$MESS["RESEND_POSSIBLE"] = "It is possible to resend sms via";
|
||||
$MESS["LOYALTY_CONNECTION_ERROR"] = "There are problems connecting to the remote server. Try reloading the page.";
|
||||
$MESS ["NO_VALID_EMAIL"] = "Check that your email is filled in correctly";
|
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
$MESS ['USER_PROPERTY_NAME'] = "Название блока пользовательских свойств";
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
$MESS["main_register_sms"] = "Код подтверждения из СМС:";
|
||||
$MESS["PERSONAL_PHONE"] = "Телефон";
|
||||
$MESS["main_register_sms_send"] = "Отправить";
|
||||
$MESS["UF_REG_IN_PL_INTARO"] = "Зарегистрироваться в программе лояльности";
|
||||
$MESS["UF_AGREE_PL_INTARO"] = "программы лояльности:";
|
||||
$MESS["I_AM_AGREE"] = "Я согласен с условиями";
|
||||
$MESS["UF_PD_PROC_PL_INTARO"] = "обработки персональных данных:";
|
||||
$MESS["LP_CARD_NUMBER"] = "Номер карты программы лояльности";
|
||||
$MESS["SEND"] = "Отправить";
|
||||
$MESS["TRY_AGAIN"] = "Попробовать снова";
|
||||
$MESS["VERIFICATION_CODE"] = "Код подтверждения";
|
||||
$MESS["SEND_VERIFICATION_CODE"] = "Отправьте код подтверждения";
|
||||
$MESS["REG_LP_MESSAGE"] = "Для завершения регистрации в программе лояльности введите номер телефона и номер карты программы лояльности";
|
||||
$MESS["YES"] = "Да";
|
||||
$MESS["BONUS_CARD_NUMBER"] = "Номер карты лояльности (если есть):";
|
||||
$MESS["SUCCESS_PL_REG"] = "Вы успешно зарегистрировались в программе лояльности.";
|
||||
$MESS["LP_FIELDS_NOT_EXIST"] = "Ошибка установки модуля ПЛ. Отсутствуют UF поля для USER";
|
||||
$MESS["REG_LP_ERROR"] = "Ошибка регистрации в Программе лояльности";
|
||||
$MESS["REGISTER_CONTINUE"] = "Для завершения регистрации в программе лояльности заполните форму.";
|
||||
$MESS["UF_CARD_NUM_INTARO"] = "Номер карты лояльности (если есть)";
|
||||
$MESS["REGISTER_LP_TITLE"] = "Регистрация в программе лояльности";
|
||||
$MESS["NOT_AUTHORIZED"] = "Вы не авторизованы на сайте. Для регистрации пройдите по <a href=\"./lp-register\">ссылке</a>";
|
||||
$MESS["LP_NOT_ACTIVE"] = "Программа лояльности в данный момент не активна";
|
||||
$MESS["SEC"] = "сек.";
|
||||
$MESS["RESEND_SMS"] = "Отправить смс повторно";
|
||||
$MESS["RESEND_POSSIBLE"] = "Повторная отправка смс возможна через";
|
||||
$MESS["LOYALTY_CONNECTION_ERROR"] = "Возникли проблемы с подключением к удаленному серверу. Попробуйте перезагрузить страницу.";
|
||||
$MESS ["NO_VALID_EMAIL"] = "Проверьте правильность заполнения email";
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
use Bitrix\Main\ArgumentException;
|
||||
use Bitrix\Main\Loader;
|
||||
use Bitrix\Main\LoaderException;
|
||||
use Bitrix\Main\ObjectPropertyException;
|
||||
use Bitrix\Main\SystemException;
|
||||
use Intaro\RetailCrm\Component\ConfigProvider;
|
||||
use Intaro\RetailCrm\Component\Constants;
|
||||
use Intaro\RetailCrm\Component\ServiceLocator;
|
||||
use Intaro\RetailCrm\Repository\AgreementRepository;
|
||||
use Intaro\RetailCrm\Service\CustomerService;
|
||||
use Intaro\RetailCrm\Service\LoyaltyAccountService;
|
||||
use RetailCrm\Exception\CurlException;
|
||||
|
||||
/** RetailCRM loyalty program start */
|
||||
function checkLoadIntaro(): bool
|
||||
{
|
||||
try {
|
||||
return Loader::includeModule('intaro.retailcrm');
|
||||
} catch (LoaderException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkLoadIntaro()) {
|
||||
$arResult['LOYALTY_STATUS'] = ConfigProvider::getLoyaltyProgramStatus();
|
||||
|
||||
global $USER;
|
||||
|
||||
if ('Y' === $arResult['LOYALTY_STATUS'] && $USER->IsAuthorized()) {
|
||||
try {
|
||||
/** @var CustomerService $customerService */
|
||||
$customerService = ServiceLocator::get(CustomerService::class);
|
||||
$customer = $customerService->createModel($USER->GetID());
|
||||
|
||||
$customerService->createCustomer($customer);
|
||||
|
||||
/* @var LoyaltyAccountService $service */
|
||||
$service = ServiceLocator::get(LoyaltyAccountService::class);
|
||||
$arResult['LP_REGISTER'] = $service->checkRegInLp();
|
||||
} catch (CurlException $exception){
|
||||
Logger::getInstance()->write($exception->getMessage(), Constants::TEMPLATES_ERROR);
|
||||
|
||||
$arResult['LOYALTY_CONNECTION_ERROR'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$arResult['ACTIVATE'] = isset($_GET['activate'])
|
||||
&& $_GET['activate'] === 'Y'
|
||||
&& $arResult['LP_REGISTER']['form']['button']['action'] === 'activateAccount';
|
||||
|
||||
try {
|
||||
$agreementPersonalData = AgreementRepository::getFirstByWhere(
|
||||
['AGREEMENT_TEXT'],
|
||||
[
|
||||
['CODE', '=', 'AGREEMENT_PERSONAL_DATA_CODE'],
|
||||
]
|
||||
);
|
||||
|
||||
$agreementLoyaltyProgram = AgreementRepository::getFirstByWhere(
|
||||
['AGREEMENT_TEXT'],
|
||||
[
|
||||
['CODE', '=', 'AGREEMENT_LOYALTY_PROGRAM_CODE'],
|
||||
]
|
||||
);
|
||||
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
|
||||
Logger::getInstance()->write($exception->getMessage(), Constants::TEMPLATES_ERROR);
|
||||
}
|
||||
|
||||
$arResult['AGREEMENT_PERSONAL_DATA'] = $agreementPersonalData['AGREEMENT_TEXT'];
|
||||
$arResult['AGREEMENT_LOYALTY_PROGRAM'] = $agreementLoyaltyProgram['AGREEMENT_TEXT'];
|
||||
} else {
|
||||
AddMessage2Log(GetMessage('INTARO_NOT_INSTALLED'));
|
||||
}
|
||||
/** RetailCRM loyalty program end */
|
|
@ -0,0 +1,229 @@
|
|||
function serializeObject(array) {
|
||||
const object = {};
|
||||
$.each(array, function() {
|
||||
if (object[this.name] !== undefined) {
|
||||
if (!object[this.name].push) {
|
||||
object[this.name] = [object[this.name]];
|
||||
}
|
||||
object[this.name].push(this.value || '');
|
||||
} else {
|
||||
object[this.name] = this.value || '';
|
||||
}
|
||||
});
|
||||
return object;
|
||||
}
|
||||
|
||||
function saveUserLpFields() {
|
||||
const formArray = $('#lpRegFormInputs').serializeArray();
|
||||
const formObject = serializeObject(formArray);
|
||||
|
||||
BX.ajax.runAction('intaro:retailcrm.api.loyalty.register.saveUserLpFields',
|
||||
{
|
||||
data: {
|
||||
sessid: BX.bitrix_sessid(),
|
||||
request: formObject
|
||||
}
|
||||
}
|
||||
).then(
|
||||
function(response) {
|
||||
if (response.data.result === true) {
|
||||
location.reload();
|
||||
} else {
|
||||
$('#errMsg').text(response.data.msg)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function resetUserLpFields() {
|
||||
BX.ajax.runAction('intaro:retailcrm.api.loyalty.register.resetUserLpFields').then(
|
||||
function(response) {
|
||||
if (response.data.result === true) {
|
||||
location.reload();
|
||||
} else {
|
||||
$('#errMsg').text(response.data.msg)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function activateAccount() {
|
||||
let checkboxes = [];
|
||||
let numbers = [];
|
||||
let strings = [];
|
||||
let dates = [];
|
||||
let options = [];
|
||||
let form = $('#lpRegFormInputs');
|
||||
|
||||
let emailViolation = false;
|
||||
|
||||
form.find(':input[type="email"]')
|
||||
.each(
|
||||
(index, value) => {
|
||||
if (/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(value.value) !== true) {
|
||||
emailViolation = true;
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (emailViolation) {
|
||||
$('#errMsg').text(BX.message("NO_VALID_EMAIL"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
form.find(':checkbox')
|
||||
.each(
|
||||
(index, value) => {
|
||||
checkboxes[index] = {
|
||||
'code': value.name,
|
||||
'value': value.checked,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
form.find(':input[type="number"]')
|
||||
.each(
|
||||
(index, value) => {
|
||||
numbers[index] = {
|
||||
'code': value.name,
|
||||
'value': value.value,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
form.find(':input[type="string"], :input[type="text"], :input[type="email"], textarea')
|
||||
.each(
|
||||
(index, value) => {
|
||||
strings[index] = {
|
||||
'code': value.name,
|
||||
'value': value.value,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
form.find(':input[type="date"]')
|
||||
.each(
|
||||
(index, value) => {
|
||||
dates[index] = {
|
||||
'code': value.name,
|
||||
'value': value.value,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
form.find('select')
|
||||
.each(
|
||||
(index, value) => {
|
||||
options[index] = {
|
||||
'code': value.name,
|
||||
'value': value.value,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
let formObject = {
|
||||
checkboxes: checkboxes,
|
||||
numbers: numbers,
|
||||
strings: strings,
|
||||
dates: dates,
|
||||
options: options
|
||||
}
|
||||
|
||||
BX.ajax.runAction('intaro:retailcrm.api.loyalty.register.activateAccount',
|
||||
{
|
||||
data: {
|
||||
sessid: BX.bitrix_sessid(),
|
||||
allFields: formObject
|
||||
}
|
||||
}
|
||||
).then(
|
||||
function(response) {
|
||||
if (response.data.status === 'activate') {
|
||||
location.reload();
|
||||
} else {
|
||||
$('#errMsg').text(response.data.msg)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//TODO проверить - возможно, это мертвый метод
|
||||
function addTelNumber(customerId) {
|
||||
const phone = $('#loyaltyRegPhone').val();
|
||||
const card = $('#loyaltyRegCard').val();
|
||||
|
||||
BX.ajax.runAction('intaro:retailcrm.api.loyalty.register.accountCreate',
|
||||
{
|
||||
data: {
|
||||
sessid: BX.bitrix_sessid(),
|
||||
request: {
|
||||
phone: phone,
|
||||
card: card,
|
||||
customerId: customerId
|
||||
}
|
||||
}
|
||||
}
|
||||
).then(
|
||||
function(response) {
|
||||
if (response.data.status === 'error' && response.data.msg !== undefined) {
|
||||
const msgBlock = $('#msg');
|
||||
msgBlock.text(response.data.msg);
|
||||
msgBlock.css('color', response.data.msgColor);
|
||||
}
|
||||
|
||||
if (response.data.status === 'activate') {
|
||||
const msgBlock = $('#regbody');
|
||||
msgBlock.text(response.data.msg);
|
||||
msgBlock.css('color', response.data.msgColor);
|
||||
}
|
||||
|
||||
if (response.data.status === 'smsVerification') {
|
||||
$('#verificationCodeBlock').show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sendVerificationCode() {
|
||||
const verificationCode = $('#smsVerificationCodeField').val();
|
||||
const checkId = $('#checkIdField').val();
|
||||
|
||||
BX.ajax.runAction('intaro:retailcrm.api.loyalty.register.activateLpBySms',
|
||||
{
|
||||
data: {
|
||||
sessid: BX.bitrix_sessid(),
|
||||
verificationCode: verificationCode,
|
||||
checkId: checkId
|
||||
}
|
||||
}
|
||||
).then(
|
||||
function(response) {
|
||||
if (response.data.status === 'error' && response.data.msg !== undefined) {
|
||||
const msg = response.data.msg;
|
||||
$('#errMsg').text(msg);
|
||||
}
|
||||
|
||||
if (response.data.status === 'activate') {
|
||||
const msgBlock = $('#regBody');
|
||||
msgBlock.text(response.data.msg);
|
||||
msgBlock.css('color', response.data.msgColor);
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/** Управляет отображением блока с полями программы лояльности на странице регистрации. */
|
||||
function lpFieldToggle() {
|
||||
let phone = $('#personalPhone');
|
||||
if ($('#checkbox_UF_REG_IN_PL_INTARO').is(':checked')) {
|
||||
$('.lp_toggled_block').css('display', 'table-row');
|
||||
$('.lp_agree_checkbox').prop('checked', true);
|
||||
phone.prop('type', 'tel');
|
||||
phone.attr('name', 'REGISTER[PERSONAL_PHONE]');
|
||||
} else {
|
||||
phone.removeAttr('name');
|
||||
phone.prop('type', 'hidden');
|
||||
$('.lp_agree_checkbox').prop('checked', false);
|
||||
$('.lp_toggled_block').css('display', 'none');
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue