1
0
mirror of synced 2024-11-21 21:06:09 +03:00

Manual order upload (#137)

This commit is contained in:
Evgeniy-Goroh 2020-09-25 12:31:45 +03:00 committed by GitHub
parent 4125565570
commit 82d6c10c07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 552 additions and 179 deletions

View File

@ -1,3 +1,6 @@
## 2020-09-08 v.5.5.0
* Добавлена возможность ручной выгрузки заказов в CRM
## 2020-09-02 v.5.4.6
* Исправлена ошибка установки модуля при отсутствии заказов в Битрикс

View File

@ -19,6 +19,8 @@
},
"require-dev": {
"phpunit/phpunit": "^7",
"vlucas/phpdotenv": "^3.3"
"vlucas/phpdotenv": "^3.3",
"mockery/mockery" : "^1.0",
"fzaninotto/faker" : "^1.7"
}
}

173
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "9dd92e1798bfa1b664589fa3d38dd4da",
"content-hash": "032aa518034a20c6776e550379084efc",
"packages": [],
"packages-dev": [
{
@ -63,6 +63,168 @@
],
"time": "2019-10-21T16:45:58+00:00"
},
{
"name": "fzaninotto/faker",
"version": "v1.9.1",
"source": {
"type": "git",
"url": "https://github.com/fzaninotto/Faker.git",
"reference": "fc10d778e4b84d5bd315dad194661e091d307c6f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/fc10d778e4b84d5bd315dad194661e091d307c6f",
"reference": "fc10d778e4b84d5bd315dad194661e091d307c6f",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0"
},
"require-dev": {
"ext-intl": "*",
"phpunit/phpunit": "^4.8.35 || ^5.7",
"squizlabs/php_codesniffer": "^2.9.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
}
},
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "François Zaninotto"
}
],
"description": "Faker is a PHP library that generates fake data for you.",
"keywords": [
"data",
"faker",
"fixtures"
],
"time": "2019-12-12T13:22:17+00:00"
},
{
"name": "hamcrest/hamcrest-php",
"version": "v2.0.1",
"source": {
"type": "git",
"url": "https://github.com/hamcrest/hamcrest-php.git",
"reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
"reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
"shasum": ""
},
"require": {
"php": "^5.3|^7.0|^8.0"
},
"replace": {
"cordoval/hamcrest-php": "*",
"davedevelopment/hamcrest-php": "*",
"kodova/hamcrest-php": "*"
},
"require-dev": {
"phpunit/php-file-iterator": "^1.4 || ^2.0",
"phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1-dev"
}
},
"autoload": {
"classmap": [
"hamcrest"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "This is the PHP port of Hamcrest Matchers",
"keywords": [
"test"
],
"time": "2020-07-09T08:09:16+00:00"
},
{
"name": "mockery/mockery",
"version": "1.3.3",
"source": {
"type": "git",
"url": "https://github.com/mockery/mockery.git",
"reference": "60fa2f67f6e4d3634bb4a45ff3171fa52215800d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mockery/mockery/zipball/60fa2f67f6e4d3634bb4a45ff3171fa52215800d",
"reference": "60fa2f67f6e4d3634bb4a45ff3171fa52215800d",
"shasum": ""
},
"require": {
"hamcrest/hamcrest-php": "^2.0.1",
"lib-pcre": ">=7.0",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7.10|^6.5|^7.5|^8.5|^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
}
},
"autoload": {
"psr-0": {
"Mockery": "library/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Pádraic Brady",
"email": "padraic.brady@gmail.com",
"homepage": "http://blog.astrumfutura.com"
},
{
"name": "Dave Marshall",
"email": "dave.marshall@atstsolutions.co.uk",
"homepage": "http://davedevelopment.co.uk"
}
],
"description": "Mockery is a simple yet flexible PHP mock object framework",
"homepage": "https://github.com/mockery/mockery",
"keywords": [
"BDD",
"TDD",
"library",
"mock",
"mock objects",
"mockery",
"stub",
"test",
"test double",
"testing"
],
"time": "2020-08-11T18:10:21+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.9.5",
@ -1541,12 +1703,6 @@
"env",
"environment"
],
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
"type": "tidelift"
}
],
"time": "2020-03-12T13:44:00+00:00"
},
{
@ -1607,6 +1763,5 @@
"ext-json": "*",
"ext-mbstring": "*"
},
"platform-dev": [],
"plugin-api-version": "1.1.0"
"platform-dev": []
}

View File

@ -1 +1 @@
- Исправлена ошибка установки модуля при отсутствии заказов в Битрикс
- Добавлена возможность ручной выгрузки заказов в CRM

View File

@ -1,5 +1,5 @@
<?
$arModuleVersion = array(
"VERSION" => "5.4.6",
"VERSION_DATE" => "2020-09-02 14:40:00"
"VERSION" => "5.5.0",
"VERSION_DATE" => "2020-09-08 12:10:00"
);

View File

@ -68,6 +68,8 @@ $MESS ['MESS_2'] = 'Произошла ошибка сервера, обрати
$MESS ['ORDER_TYPES_LIST_CUSTOM'] = 'Внимание! Используется не стандартное соответвие типов заказов.';
$MESS ['ORDER_UPL_START'] = 'Начать выгрузку';
$MESS ['UPLOAD_ORDERS_OPTIONS'] = 'Ручная выгрузка';
$MESS ['OTHER_OPTIONS'] = 'Прочие настройки';
$MESS ['ORDERS_OPTIONS'] = 'Настройки заказов';
$MESS ['ORDER_NUMBERS'] = 'Транслировать номера заказов созданных в црм в магазин';

View File

@ -733,6 +733,12 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) {
"TAB" => GetMessage('OTHER_OPTIONS'),
"ICON" => '',
"TITLE" => GetMessage('ICRM_OPTIONS_ORDER_DISCHARGE_CAPTION')
),
array(
"DIV" => "edit5",
"TAB" => GetMessage('UPLOAD_ORDERS_OPTIONS'),
"ICON" => '',
"TITLE" => GetMessage('ORDER_UPLOAD'),
)
);
$tabControl = new CAdminTabControl("tabControl", $aTabs);
@ -1488,175 +1494,169 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) {
</td>
</tr>
<?php endif;?>
<?php //manual order upload?>
<?php $tabControl->BeginNextTab(); ?>
<style type="text/css">
.instal-load-label {
color: #000;
margin-bottom: 15px;
}
.instal-progress-bar-outer {
height: 32px;
border:1px solid;
border-color:#9ba6a8 #b1bbbe #bbc5c9 #b1bbbe;
-webkit-box-shadow: 1px 1px 0 #fff, inset 0 2px 2px #c0cbce;
box-shadow: 1px 1px 0 #fff, inset 0 2px 2px #c0cbce;
background-color:#cdd8da;
background-image:-webkit-linear-gradient(top, #cdd8da, #c3ced1);
background-image:-moz-linear-gradient(top, #cdd8da, #c3ced1);
background-image:-ms-linear-gradient(top, #cdd8da, #c3ced1);
background-image:-o-linear-gradient(top, #cdd8da, #c3ced1);
background-image:linear-gradient(top, #ced9db, #c3ced1);
border-radius: 2px;
text-align: center;
color: #6a808e;
text-shadow: 0 1px rgba(255,255,255,0.85);
font-size: 18px;
line-height: 35px;
font-weight: bold;
}
.instal-progress-bar-alignment {
height: 28px;
margin: 0;
position: relative;
}
.instal-progress-bar-inner {
height: 28px;
border-radius: 2px;
border-top: solid 1px #52b9df;
background-color:#2396ce;
background-image:-webkit-linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
background-image:-moz-linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
background-image:-ms-linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
background-image:-o-linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
background-image:linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
position: absolute;
overflow: hidden;
top: 1px;
left:0;
}
.instal-progress-bar-inner-text {
color: #fff;
text-shadow: 0 1px rgba(0,0,0,0.2);
font-size: 18px;
line-height: 32px;
font-weight: bold;
text-align: center;
position: absolute;
left: -2px;
top: -2px;
}
.order-upload-button{
padding: 1px 13px 2px;
height:28px;
}
.order-upload-button div{
float:right;
position:relative;
visible: none;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
$('#percent').width($('.instal-progress-bar-outer').width());
$(window).resize(function(){ // strechin progress bar
$('#percent').width($('.instal-progress-bar-outer').width());
});
// orderUpload function
function orderUpload() {
var handlerUrl = $('#upload-orders').attr('action');
var step = encodeURIComponent($('input[name="step"]').val());
var orders = encodeURIComponent($('input[name="orders"]').val());
var data = 'orders=' + orders + '&step=' + step + '&ajax=2';
// ajax request
$.ajax({
type: 'POST',
url: handlerUrl,
data: data,
dataType: 'json',
success: function(response) {
$('input[name="step"]').val(response.step);
if(response.step == 'end'){
$('input[name="step"]').val(0);
BX.closeWait();
} else {
orderUpload();
}
$('#indicator').css('width', response.percent + '%');
$('#percent').html(response.percent + '%');
$('#percent2').html(response.percent + '%');
},
error: function () {
BX.closeWait();
$('#status').text('<?php echo GetMessage('MESS_4'); ?>');
alert('<?php echo GetMessage('MESS_5'); ?>');
}
});
}
$('input[name="start"]').live('click', function() {
BX.showWait();
$('#indicator').css('width', 0);
$('#percent2').html('0%');
$('#percent').css('width', '100%');
orderUpload();
return false;
});
});
</script>
<form id="upload-orders" action="<?php echo $uri; ?>" method="POST">
<input type="hidden" name="step" value="0">
<div>
<?php echo GetMessage('ORDER_NUMBER'); ?>
<input id="order-nombers" style="width:86%" type="text" value="" name="orders">
</div>
<br>
<div class="instal-load-block" id="result">
<div class="instal-load-label" id="status"><?php echo GetMessage('ORDER_UPLOAD_INFO'); ?></div>
<div class="instal-progress-bar-outer">
<div class="instal-progress-bar-alignment" style="width: 100%;">
<div class="instal-progress-bar-inner" id="indicator" style="width: 0%;">
<div class="instal-progress-bar-inner-text" style="width: 100%;" id="percent">0%</div>
</div>
<span id="percent2">0%</span>
</div>
</div>
</div>
<br />
<div class="order-upload-button">
<div align="left">
<input type="submit" name="start" value="<?php echo GetMessage('ORDER_UPL_START'); ?>" class="adm-btn-save">
</div>
</div>
</form>
<?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 } ?>
<?php //order upload?>
<?php if($_GET['upl'] == 1){?>
<style type="text/css">
.instal-load-label {
color: #000;
margin-bottom: 15px;
}
.instal-progress-bar-outer {
height: 32px;
border:1px solid;
border-color:#9ba6a8 #b1bbbe #bbc5c9 #b1bbbe;
-webkit-box-shadow: 1px 1px 0 #fff, inset 0 2px 2px #c0cbce;
box-shadow: 1px 1px 0 #fff, inset 0 2px 2px #c0cbce;
background-color:#cdd8da;
background-image:-webkit-linear-gradient(top, #cdd8da, #c3ced1);
background-image:-moz-linear-gradient(top, #cdd8da, #c3ced1);
background-image:-ms-linear-gradient(top, #cdd8da, #c3ced1);
background-image:-o-linear-gradient(top, #cdd8da, #c3ced1);
background-image:linear-gradient(top, #ced9db, #c3ced1);
border-radius: 2px;
text-align: center;
color: #6a808e;
text-shadow: 0 1px rgba(255,255,255,0.85);
font-size: 18px;
line-height: 35px;
font-weight: bold;
}
.instal-progress-bar-alignment {
height: 28px;
margin: 0;
position: relative;
}
.instal-progress-bar-inner {
height: 28px;
border-radius: 2px;
border-top: solid 1px #52b9df;
background-color:#2396ce;
background-image:-webkit-linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
background-image:-moz-linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
background-image:-ms-linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
background-image:-o-linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
background-image:linear-gradient(top, #27a8d7, #2396ce, #1c79c0);
position: absolute;
overflow: hidden;
top: 1px;
left:0;
}
.instal-progress-bar-inner-text {
color: #fff;
text-shadow: 0 1px rgba(0,0,0,0.2);
font-size: 18px;
line-height: 32px;
font-weight: bold;
text-align: center;
position: absolute;
left: -2px;
top: -2px;
}
.order-upload-button{
padding: 1px 13px 2px;
height:28px;
}
.order-upload-button div{
float:right;
position:relative;
visible: none;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
$('#percent').width($('.instal-progress-bar-outer').width());
$(window).resize(function(){ // strechin progress bar
$('#percent').width($('.instal-progress-bar-outer').width());
});
// orderUpload function
function orderUpload() {
var handlerUrl = $('#upload-orders').attr('action');
var step = $('input[name="step"]').val();
var orders = $('input[name="orders"]').val();
var data = 'orders=' + orders + '&step=' + step + '&ajax=2';
// ajax request
$.ajax({
type: 'POST',
url: handlerUrl,
data: data,
dataType: 'json',
success: function(response) {
$('input[name="step"]').val(response.step);
if(response.step == 'end'){
$('input[name="step"]').val(0);
BX.closeWait();
}
else{
orderUpload();
}
$('#indicator').css('width', response.percent + '%');
$('#percent').html(response.percent + '%');
$('#percent2').html(response.percent + '%');
},
error: function () {
BX.closeWait();
$('#status').text('<?php echo GetMessage('MESS_4'); ?>');
alert('<?php echo GetMessage('MESS_5'); ?>');
}
});
}
$('input[name="start"]').live('click', function() {
BX.showWait();
$('#indicator').css('width', 0);
$('#percent2').html('0%');
orderUpload();
return false;
});
});
</script>
<br>
<form id="upload-orders" action="<?php echo $uri; ?>" method="POST">
<input type="hidden" name="step" value="0">
<div class="adm-detail-content-item-block">
<table class="adm-detail-content-table edit-table" id="edit1_edit_table">
<tbody>
<tr class="heading">
<td colspan="2"><b><?php echo GetMessage('ORDER_UPLOAD'); ?></b></td>
</tr>
<tr>
<td class="adm-detail-content-cell-r"><?php echo GetMessage('ORDER_NUMBER'); ?> <input id="order-nombers" style="width:86%" type="text" value="" name="orders"></td>
</tr>
</tbody>
</table>
<div class="instal-load-block" id="result">
<div class="instal-load-label" id="status"><?php echo GetMessage('ORDER_UPLOAD_INFO'); ?></div>
<div class="instal-progress-bar-outer">
<div class="instal-progress-bar-alignment" style="width: 100%;">
<div class="instal-progress-bar-inner" id="indicator" style="width: 0%;">
<div class="instal-progress-bar-inner-text" style="width: 100%;" id="percent">0%</div>
</div>
<span id="percent2">0%</span>
</div>
</div>
</div>
<br />
<div class="order-upload-button">
<div align="left">
<input type="submit" name="start" value="<?php echo GetMessage('ORDER_UPL_START'); ?>" class="adm-btn-save">
</div>
</div>
</div>
</form>
<?php }?>

36
tests/BitrixTestCase.php Normal file
View File

@ -0,0 +1,36 @@
<?php
/**
* Class BitrixTestCase
*/
class BitrixTestCase extends \PHPUnit\Framework\TestCase
{
/**
* @var bool
*/
protected $backupGlobals = false;
/**
* @var \Generator
*/
protected $faker;
/**
* этот метод phpUnit вызывает перед запуском текущего теста
* @inheritdoc
*/
public function setUp()
{
// создание экземпляра Faker, который будет создавать рандомные данные
$this->faker = \Faker\Factory::create();
}
/**
* этот метод phpUnit вызывает после исполнения текущего теста
* @inheritdoc
*/
public function tearDown()
{
// без этого вызова Mockery не будет работать
\Mockery::close();
}
}

View File

@ -32,4 +32,7 @@ if (!IsModuleInstalled('intaro.retailcrm')) {
RegisterModule('intaro.retailcrm');
}
COption::SetOptionString('intaro.retailcrm', 'api_version', 'v5');
CModule::IncludeModule('intaro.retailcrm');
require_once 'BitrixTestCase.php';

View File

@ -0,0 +1,172 @@
<?php
/**
* Class RetailCrmOrderTest
*/
use \Bitrix\Main\Loader;
class RetailCrmOrderTest extends BitrixTestCase
{
protected $retailCrmOrder;
protected $test;
/**
* @inheritdoc
*/
public function setUp()
{
parent::setUp();
$this->retailCrmOrder = \Mockery::mock('RetailCrmOrder');
COption::SetOptionString('intaro.retailcrm', 'api_version', 'v5');
CModule::IncludeModule('intaro.retailcrm');
}
public function testModuleInstalled()
{
$this->assertTrue(Loader::includeModule("intaro.retailcrm"));
}
/**
* @param $pSize
* @param $failed
* @param $orderList
*
* @dataProvider getData
*/
public function testUploadOrders($pSize, $failed, $orderList)
{
$this->assertEquals(50, $pSize);
$this->assertFalse($failed);
if ($orderList) {
$this->assertEquals(3, sizeof($orderList));
$this->retailCrmOrder->shouldReceive('uploadOrders')
->andReturn(
array(
array('id' => 001, 'externalId' => 2),
array('id' => 002, 'externalId' => 3),
array('id' => 003, 'externalId' => 4)
)
);
$result = $this->retailCrmOrder->uploadOrders();
foreach ($result as $key => $order) {
$this->assertEquals($order["externalId"], $orderList[$key]);
}
} else {
$this->assertFalse($orderList);
}
}
/**
* @return array
*/
public function getData()
{
return [
[
'pSize' => 50,
'failed' => false,
'orderList' => false
],
[
'pSize' => 50,
'failed' => false,
'orderList' => array(2,3,4)
]
];
}
/**
* @param $pack
* @param $method
* @param $keyResponse
* @param $apiMock
* @param $optionsSitesList
*
* @dataProvider getDataUpload
*/
public function testUploadItems($pack, $method, $keyResponse, $apiMock, $optionsSitesList)
{
$responseBody1 = '';
for ($i = 1; $i < 51; $i++) {
$responseBody1 .= "{\"id\":".$i.",\"externalId\":".$i."},";
}
$responseBody1 = substr($responseBody1,0,-1);
$responseBody1 ='{
"success":true,
"'.$keyResponse.'":['.$responseBody1.']
}';
$responseBody2 ='{
"success":true,
"uploadedCustomers":[
{"id":51,"externalId":"51"}
]
}';
$apiMock->shouldReceive($method)
->andReturn(
new \RetailCrm\Response\ApiResponse(
200,
$responseBody1
),
new \RetailCrm\Response\ApiResponse(
200,
$responseBody2
)
);
$test = new RetailCrmOrder();
$result = $test::uploadItems($pack, $method, $keyResponse, $apiMock, $optionsSitesList);
$this->assertEquals(sizeof($pack['s1']), sizeof($result));
}
/**
* @return mixed
*/
public function getCustomerList()
{
$faker = Faker\Factory::create();
$customerList = [];
for ($i = 1; $i < 52; $i++) {
$customerList['s1'][$i]['externalId'] = $i;
$customerList['s1'][$i]['email'] = $faker->email;
$customerList['s1'][$i]['createdAt'] = $faker->date('Y-m-d H:i:s');
$customerList['s1'][$i]['subscribed'] = '';
$customerList['s1'][$i]['contragent'] = ['contragentType' => 'individual'];
$customerList['s1'][$i]['firstName'] = $faker->firstName;
$customerList['s1'][$i]['lastName'] = $faker->lastName;
}
return $customerList;
}
/**
* @return array
*/
public function getDataUpload()
{
return [
[
'pack' => $this->getCustomerList(),
'customersUpload',
'uploadedCustomers',
'api'=>\Mockery::mock('RetailCrm\ApiClient'),
'optionsSitesList'=>[]
],
[
'pack'=> [],
'ordersUpload',
'uploadedOrders',
'api'=>\Mockery::mock('RetailCrm\ApiClient'),
'optionsSitesList'=>[]
]
];
}
}