]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Обработка создания заказа
authorfomichev <vladimir.fomichev@erp-flowers.ru>
Mon, 24 Feb 2025 12:44:35 +0000 (15:44 +0300)
committerfomichev <vladimir.fomichev@erp-flowers.ru>
Mon, 24 Feb 2025 12:44:35 +0000 (15:44 +0300)
erp24/media/controllers/NotificationController.php
erp24/services/MarketplaceService.php

index 7c3212f896695ddc67e979b7992d3a8c17f41fab..600df9484db657dd5ae19e1bc71d978147b93d23 100644 (file)
@@ -16,10 +16,12 @@ use yii_app\records\Images;
 use yii_app\records\MatrixErp;
 use yii_app\records\MatrixErpProperty;
 use yii_app\services\FileService;
+use yii_app\services\MarketplaceService;
 
 class NotificationController extends Controller
 {
-    public function actionTest() {
+    public function actionTest()
+    {
         Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
         return ['ok'];
     }
@@ -27,14 +29,31 @@ class NotificationController extends Controller
     public function actionNotification()
     {
         if (!Yii::$app->request->isPost) {
-            throw new BadRequestHttpException('Только Post');
+            throw new BadRequestHttpException('Только POST запросы разрешены');
         }
 
         $rawBody = Yii::$app->request->getRawBody();
-        $data = Json::decode($rawBody);
+        try {
+            $data = Json::decode($rawBody);
+        } catch (\Exception $e) {
+            Yii::error("Ошибка декодирования JSON: " . $e->getMessage());
+            Yii::$app->response->statusCode = 400;
+            return $this->asJson([
+                'error' => [
+                    'type' => 'WRONG_EVENT_FORMAT',
+                    'message' => 'Некорректный формат JSON'
+                ]
+            ]);
+        }
 
         if (!isset($data['notificationType'])) {
-            throw new BadRequestHttpException('Неверное событие');
+            Yii::$app->response->statusCode = 400;
+            return $this->asJson([
+                'error' => [
+                    'type' => 'WRONG_EVENT_FORMAT',
+                    'message' => 'Неверное событие: notificationType не указан'
+                ]
+            ]);
         }
 
         $eventType = $data['notificationType'];
@@ -42,20 +61,63 @@ class NotificationController extends Controller
         try {
             switch ($eventType) {
                 case 'PING':
-                    return $this->asJson(['version' => '1', 'name' => 'БазаЦветов24', 'timestamp' => date('Y-m-d H:i:s')]);
+                    return $this->asJson([
+                        'version' => '1',
+                        'name' => 'БазаЦветов24',
+                        'timestamp' => date('Y-m-d H:i:s')
+                    ]);
 
                 case 'ORDER_CREATED':
-                    break;
+                    $requiredFields = ['campaignId', 'orderId', 'createdAt', 'items'];
+                    foreach ($requiredFields as $field) {
+                        if (!isset($data[$field])) {
+                            Yii::$app->response->statusCode = 400;
+                            return $this->asJson([
+                                'error' => [
+                                    'type' => 'WRONG_EVENT_FORMAT',
+                                    'message' => "Отсутствует обязательное поле: {$field}"
+                                ]
+                            ]);
+                        }
+                    }
+
+                    $campaignId = $data['campaignId'];
+                    $orderId = $data['orderId'];
+
+                    $orderData = MarketplaceService::fetchOrder($campaignId, $orderId);
+                    if (empty($orderData)) {
+                        Yii::$app->response->statusCode = 400;
+                        return $this->asJson([
+                            'error' => [
+                                'type' => 'WRONG_EVENT_FORMAT',
+                                'message' => "Не удалось получить заказ с orderId: {$orderId} для кампании: {$campaignId}"
+                            ]
+                        ]);
+                    }
+
+                    $result = MarketplaceService::processOrders($orderData);
+                    return $this->asJson([
+                        'success' => true,
+                        'message' => "ORDER_CREATED событие обработано успешно",
+                        'result' => $result
+                    ]);
 
                 default:
                     Yii::info("Неизвестный тип события: {$eventType}");
-                    return $this->asJson(['success' => true, 'message' => 'Unknown event ignored']);
+                    return $this->asJson([
+                        'success' => true,
+                        'message' => 'Unknown event ignored'
+                    ]);
             }
-
-            return $this->asJson(['success' => true, 'message' => "Event {$eventType} processed successfully"]);
         } catch (\Exception $e) {
             Yii::error("Error processing event {$eventType}: " . $e->getMessage());
-            return $this->asJson(['success' => false, 'message' => 'Failed to process event']);
+            Yii::$app->response->statusCode = 500;
+            return $this->asJson([
+                'error' => [
+                    'type' => 'UNKNOWN',
+                    'message' => 'Failed to process event'
+                ]
+            ]);
         }
     }
-}
+}
\ No newline at end of file
index 74c50c232f784d35d55cd3558a842a050871643c..a9b3db833c49ca8cbaf5654db1adb51415199974 100644 (file)
@@ -4,6 +4,7 @@ namespace yii_app\services;
 
 use GuzzleHttp\Client;
 use OpenAPI\Client\Api\OrdersApi;
+use OpenAPI\Client\ApiException;
 use OpenAPI\Client\Configuration;
 use Yii;
 use yii\helpers\ArrayHelper;
@@ -865,6 +866,42 @@ class MarketplaceService
         return $allOrders;
     }
 
+    /**
+     * Получает данные об одном заказе из API Яндекс.Маркета.
+     *
+     * Метод вызывает API-метод getOrder и десериализует ответ,
+     * возвращая данные в виде массива, где ключ – идентификатор кампании (магазина),
+     * а значение – массив заказов (в данном случае с одним заказом).
+     *
+     * @param int         $campaignId  Идентификатор кампании (магазина) в API.
+     * @param int         $orderId     Идентификатор заказа.
+     * @param string|null $contentType Заголовок Content-Type. Если не передан, используется значение по умолчанию.
+     *
+     * @return array Массив заказов в виде: [ $campaignId => [ $order ] ]
+     *
+     * @throws ApiException При ошибке вызова API.
+     */
+    public static function fetchOrder($campaignId, $orderId, string $contentType = null)
+    {
+        $config = Configuration::getDefaultConfiguration()
+            ->setApiKey('Api-Key', Yii::$app->params['YANDEX_MARKET_API_KEY']);
+        $apiInstance = new OrdersApi(new Client(), $config);
+
+        if ($contentType === null) {
+            $contentType = OrdersApi::contentTypes['getOrder'][0];
+        }
+
+        try {
+            $response = $apiInstance->getOrder($campaignId, $orderId, $contentType);
+            $order = $response->getOrder();
+
+            return [$campaignId => [$order]];
+        } catch (ApiException $e) {
+            Yii::error('Ошибка при получении заказа: ' . $e->getMessage());
+            return [];
+        }
+    }
+
     public static function processOrders(array $allOrders)
     {
         $statuses = MarketplaceOrderStatusTypes::find()