diff --git a/CHACNGELOG.md b/CHACNGELOG.md
index 47f4fa3..2bfc3a3 100644
--- a/CHACNGELOG.md
+++ b/CHACNGELOG.md
@@ -1,3 +1,6 @@
+## 2018-12-25 v.2.4.0
+* Добавлен функционал получения остатков из retailCRM
+
## 2018-12-25 v.2.3.2
* Добавлена выгрузка картинок категорий товаров в ICML
diff --git a/VERSION b/VERSION
index e703481..9183195 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.3.2
\ No newline at end of file
+2.4.0
\ No newline at end of file
diff --git a/src/Cron/Inventories.php b/src/Cron/Inventories.php
new file mode 100644
index 0000000..7433eab
--- /dev/null
+++ b/src/Cron/Inventories.php
@@ -0,0 +1,24 @@
+helper = $helper;
+ $this->inventoriesUpload = $InventoriesUpload;
+ }
+
+ public function execute()
+ {
+ if ($this->helper->getInventoriesUpload() == true) {
+ $this->inventoriesUpload->uploadInventory();
+ }
+ }
+}
diff --git a/src/Helper/Data.php b/src/Helper/Data.php
index 91792c5..dc805fc 100644
--- a/src/Helper/Data.php
+++ b/src/Helper/Data.php
@@ -16,6 +16,7 @@ class Data extends AbstractHelper
const XML_PATH_DEFAULT_SITE = 'retailcrm_site/default';
const XML_PATH_SITES = 'retailcrm_sites/';
const XML_PATH_DAEMON_COLLECTOR = 'daemon_collector/';
+ const XML_PATH_INVENTORIES = 'inventories_upload/';
public function __construct(
Context $context,
@@ -131,6 +132,20 @@ class Data extends AbstractHelper
return false;
}
+ public function getInventoriesUpload()
+ {
+ $inventories = $this->scopeConfig->getValue(
+ self::XML_PATH_RETAILCRM . self::XML_PATH_INVENTORIES . 'active',
+ ScopeConfigInterface::SCOPE_TYPE_DEFAULT
+ );
+
+ if ($inventories) {
+ return true;
+ }
+
+ return false;
+ }
+
/**
* @param $website
*
diff --git a/src/Model/Service/InventoriesUpload.php b/src/Model/Service/InventoriesUpload.php
new file mode 100644
index 0000000..73c7e60
--- /dev/null
+++ b/src/Model/Service/InventoriesUpload.php
@@ -0,0 +1,55 @@
+productRepo = $productRepo;
+ $this->api = $api;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function uploadInventory()
+ {
+ if (!$this->api->isConfigured()) {
+ return false;
+ }
+
+ $page = 1;
+
+ do {
+ $response = $this->api->storeInventories(array(), $page, 250);
+
+ if ($response === false || !$response->isSuccessful()) {
+ return false;
+ }
+
+ foreach ($response['offers'] as $offer) {
+ if (isset($offer['externalId'])) {
+ $product = $this->productRepo->getById($offer['externalId']);
+ $product->setStockData(
+ ['qty' => $offer['quantity'],
+ 'is_in_stock' => $offer['quantity'] > 0]
+ );
+ $product->save();
+ }
+ }
+
+ $totalPageCount = $response['pagination']['totalPageCount'];
+ $page++;
+ } while ($page <= $totalPageCount);
+
+ return true;
+ }
+}
diff --git a/src/Model/Setting/DaemonCollector.php b/src/Model/Setting/Select.php
similarity index 76%
rename from src/Model/Setting/DaemonCollector.php
rename to src/Model/Setting/Select.php
index fc838ca..7fedb6e 100644
--- a/src/Model/Setting/DaemonCollector.php
+++ b/src/Model/Setting/Select.php
@@ -2,7 +2,7 @@
namespace Retailcrm\Retailcrm\Model\Setting;
-class DaemonCollector implements \Magento\Framework\Option\ArrayInterface
+class Select implements \Magento\Framework\Option\ArrayInterface
{
public function toOptionArray()
{
diff --git a/src/Test/Unit/Model/Service/InventoriesUploadTest.php b/src/Test/Unit/Model/Service/InventoriesUploadTest.php
new file mode 100644
index 0000000..edbe880
--- /dev/null
+++ b/src/Test/Unit/Model/Service/InventoriesUploadTest.php
@@ -0,0 +1,123 @@
+mockApi = $this->getMockBuilder(\Retailcrm\Retailcrm\Helper\Proxy::class)
+ ->disableOriginalConstructor()
+ ->setMethods([
+ 'storeInventories',
+ 'isConfigured'
+ ])
+ ->getMock();
+
+ $this->mockProductRepository = $this->getMockBuilder(\Magento\Catalog\Api\ProductRepositoryInterface::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getById'])
+ ->getMockForAbstractClass();
+
+ $this->mockResponse = $this->getMockBuilder(\RetailCrm\Response\ApiResponse::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['isSuccessful'])
+ ->getMock();
+
+ $this->mockProduct = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+ ->disableOriginalConstructor()
+ ->setMethods([
+ 'setStockData',
+ 'save'
+ ])
+ ->getMock();
+ }
+
+ /**
+ * @param $response
+ *
+ * @dataProvider dataProviderLoadStocks
+ */
+ public function testInventoriesUpdload($response)
+ {
+ if ($response != false) {
+ $responseInventories = new \RetailCrm\Response\ApiResponse(200, json_encode($response));
+
+ $this->mockResponse->expects($this->any())
+ ->method('isSuccessful')
+ ->willReturn(true);
+
+ $this->mockApi->expects($this->any())
+ ->method('isConfigured')
+ ->willReturn(true);
+
+ $this->mockApi->expects($this->any())
+ ->method('storeInventories')
+ ->willReturn($responseInventories);
+
+ $this->mockProductRepository->expects($this->any())
+ ->method('getById')
+ ->willReturn($this->mockProduct);
+ } else {
+ $this->mockResponse->expects($this->any())
+ ->method('isSuccessful')
+ ->willReturn($response);
+ }
+
+ $inventoriesUpload = new \Retailcrm\Retailcrm\Model\Service\InventoriesUpload($this->mockProductRepository, $this->mockApi);
+ $result = $inventoriesUpload->uploadInventory();
+
+ if (!$response['success']) {
+ $this->assertEquals(false, $result);
+ } else {
+ $this->assertEquals(true, $result);
+ }
+ }
+
+ private function getResponseData()
+ {
+ return array(
+ 'true' => $this->getApiInventories(),
+ 'false' => false
+ );
+ }
+
+ public function dataProviderLoadStocks()
+ {
+ $response = $this->getResponseData();
+
+ return array(
+ array(
+ 'response' => $response['true']
+ ),
+ array(
+ 'response' => $response['false']
+ )
+ );
+ }
+
+ private function getApiInventories()
+ {
+ return array(
+ 'success' => true,
+ 'pagination' => array(
+ 'limit' => 250,
+ 'totalCount' => 1,
+ 'currentPage' => 1,
+ 'totalPageCount' => 1
+ ),
+ 'offers' => array(
+ array(
+ 'externalId' => 1,
+ 'xmlId' => 'xmlId',
+ 'quantity' => 10
+ )
+ )
+ );
+ }
+}
diff --git a/src/composer.json b/src/composer.json
index 4c327d5..97f5bc7 100644
--- a/src/composer.json
+++ b/src/composer.json
@@ -5,7 +5,7 @@
"retailcrm/api-client-php": "~5.0"
},
"type": "magento2-module",
- "version": "2.3.2",
+ "version": "2.4.0",
"license": [
"OSL-3.0",
"AFL-3.0"
diff --git a/src/etc/adminhtml/system.xml b/src/etc/adminhtml/system.xml
index 8fa6dac..3130bb6 100644
--- a/src/etc/adminhtml/system.xml
+++ b/src/etc/adminhtml/system.xml
@@ -68,12 +68,19 @@
- Retailcrm\Retailcrm\Model\Setting\DaemonCollector
+ Retailcrm\Retailcrm\Model\Setting\Select
+
+
+
+
+ Retailcrm\Retailcrm\Model\Setting\Select
+
+
diff --git a/src/etc/crontab.xml b/src/etc/crontab.xml
index 44e38d3..3ee7f21 100644
--- a/src/etc/crontab.xml
+++ b/src/etc/crontab.xml
@@ -7,5 +7,8 @@
*/5 * * * *
+
+ */15 * * * *
+
\ No newline at end of file
diff --git a/src/i18n/es_ES.csv b/src/i18n/es_ES.csv
index 0dc474f..edd009c 100644
--- a/src/i18n/es_ES.csv
+++ b/src/i18n/es_ES.csv
@@ -23,4 +23,5 @@
"Send","Enviar"
"Default site","Tienda por defecto"
"Activate","Active"
-"Site key","Clave de la página web"
\ No newline at end of file
+"Site key","Clave de la página web"
+"Synchronization of the stock balance","Sincronizar el stock"
\ No newline at end of file
diff --git a/src/i18n/ru_RU.csv b/src/i18n/ru_RU.csv
index 35339e3..43d50aa 100644
--- a/src/i18n/ru_RU.csv
+++ b/src/i18n/ru_RU.csv
@@ -23,4 +23,5 @@
"Send","Выгрузить"
"Default site","Сайт по умолчанию"
"Activate","Активировать"
-"Site key","Ключ сайта"
\ No newline at end of file
+"Site key","Ключ сайта"
+"Synchronization of the stock balance","Синхронизация остатков"
\ No newline at end of file