From 4383949ff800f31d3260f3ed94b11c0504149e4c Mon Sep 17 00:00:00 2001 From: Aleksey Filippov Date: Thu, 12 Feb 2026 17:10:34 +0300 Subject: [PATCH] =?utf8?q?[ERP-219]=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?utf8?q?=D0=B5=D0=BD=D0=B0=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8?= =?utf8?q?=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=B0=D1=8F=20=D0=BF=D1=80=D0=BE?= =?utf8?q?=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20=D0=BF=D0=BE=20=D0=B8=D1=81?= =?utf8?q?=D1=82=D0=BE=D1=80=D0=B8=D0=B8=20=D0=BA=D0=B0=D1=82=D0=B0=D0=BB?= =?utf8?q?=D0=BE=D0=B3=D0=B0=20,=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?utf8?q?=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=20=D1=81=D0=BE=D1=85=D1=80=D0=B0?= =?utf8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=87=D0=B5=D0=BA=D0=BE=D0=B2?= =?utf8?q?=20=D0=BE=D1=82=20=D0=9C=D0=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- erp24/api2/controllers/DataController.php | 89 +++++++++++++++---- ...120000_add_marketplace_fields_to_sales.php | 80 +++++++++++++++++ ...ter_payments_pay_arr_nullable_in_sales.php | 67 ++++++++++++++ erp24/records/MarketplaceOrders.php | 60 +++++++++++++ erp24/records/Sales.php | 10 ++- erp24/services/MarketplaceService.php | 2 +- erp24/services/UploadService.php | 13 ++- 7 files changed, 302 insertions(+), 19 deletions(-) create mode 100644 erp24/migrations/m260212_120000_add_marketplace_fields_to_sales.php create mode 100644 erp24/migrations/m260212_130000_alter_payments_pay_arr_nullable_in_sales.php diff --git a/erp24/api2/controllers/DataController.php b/erp24/api2/controllers/DataController.php index a21d3069..b3c81425 100644 --- a/erp24/api2/controllers/DataController.php +++ b/erp24/api2/controllers/DataController.php @@ -46,6 +46,7 @@ use yii_app\records\PricesZakup; use yii_app\records\Products1cNomenclature; use yii_app\records\Products1cPropType; use yii_app\records\Products1c; +use yii_app\records\Products1cClassDynamic; use yii_app\records\Products1cAdditionalCharacteristics; use yii_app\records\ReplacementInvoice; use yii_app\records\ReplacementInvoiceProducts; @@ -876,22 +877,22 @@ class DataController extends BaseController foreach ($marketplaceOrders as $marketplaceOrder) { /* @var MarketplaceOrders $marketplaceOrder */ $items = Json::decode(Json::encode($marketplaceOrder->items)); - $itemsToComment = []; $itemsFiltered = []; $summ = 0; - foreach ($items as $item) { - $itemsToComment[] = $item['offer_id'] . ' - ' . $item['offer_name']; - $product1c = Products1c::find()->where(['articule' => $item['offer_id']])->one(); - if (!empty($product1c->id)) { - $itemsFiltered []= [ - 'product_id' => $product1c->id ?? '', - 'color' => '', - 'price' => $item['price'], - 'quantity' => $item['count'], - 'seller_id' => '', - ]; - } - $summ += $item['price'] * $item['count']; + + $productsItemsArticule = $this->getProductsItemsArticule($items); + $itemsToComment = $productsItemsArticule['itemsToComment']; + + foreach ($productsItemsArticule['isProductWithGuid'] as $item) { + $itemsFiltered []= [ + 'product_id' => $item['product_id'] ?? '', + 'color' => '', + 'price' => $item['price'], + 'quantity' => $item['quantity'], + 'seller_id' => '', + ]; + + $summ += $item['price'] * $item['quantity']; } if (!empty($itemsFiltered)) { $eit = ExportImportTable::find()->where(['entity' => 'city_store', 'export_id' => 1, 'entity_id' => $marketplaceOrder->store_id])->one(); @@ -941,7 +942,7 @@ class DataController extends BaseController $itemsWithoutSku = array_map( fn(array $p) => "{$p['product_id']} x{$p['quantity']}", - $marketplaceOrder->getProductsWithoutArticule() + $productsItemsArticule['isProductWithoutGuid'] ); if (!empty($itemsWithoutSku)) { $itemsWithoutSkuString = ', Товары без артикула: ' . implode(', ',$itemsWithoutSku); @@ -1003,6 +1004,64 @@ class DataController extends BaseController return $result; } + /** + * Получение товаров с проверкой наличия артикулов в базе + * @param array $items Массив товаров из заказа маркетплейса + * @return array + */ + private function getProductsItemsArticule($items): array + { + $products = $items; + $isProductWithGuid = []; + $isProductWithoutGuid = []; + $itemsToComment = []; + + foreach ($products as $product) { + $itemsToComment[] = $product['offer_id'] . ' - ' . $product['offer_name']; + + /** @var Products1c $productRow */ + $productRow = Products1c::find() + ->where(['articule' => $product['offer_id']]) + ->one(); + + if (!empty($productRow->id)) { + $isProductWithGuid[$product['offer_id']] = [ + 'product_id' => $productRow->id ?? '', + 'color' => '', + 'price' => $product['price'], + 'quantity' => $product['count'], + 'seller_id' => '', + ]; + } else { + $product1cClassDynamic = Products1cClassDynamic::find() + ->where(['articule' => $product['offer_id']]) + ->andWhere(['active' => Products1cClassDynamic::ACTIVE]) + ->one(); + + if (!empty($product1cClassDynamic->id)) { + $isProductWithGuid[$product['offer_id']] = [ + 'product_id' => $product1cClassDynamic->id ?? '', + 'color' => '', + 'price' => $product['price'], + 'quantity' => $product['count'], + 'seller_id' => '', + ]; + } else { + $isProductWithoutGuid[] = [ + 'product_id' => $product['offer_name'] ?? null, + 'quantity' => $product['count'] ?? null, + ]; + } + } + } + + return [ + 'isProductWithoutGuid' => $isProductWithoutGuid, + 'isProductWithGuid' => $isProductWithGuid, + 'itemsToComment' => $itemsToComment, + ]; + } + private function getCancelledMarketplaceOrders(): array { $canceledStatusId = MarketplaceOrderStatusTypes::find() diff --git a/erp24/migrations/m260212_120000_add_marketplace_fields_to_sales.php b/erp24/migrations/m260212_120000_add_marketplace_fields_to_sales.php new file mode 100644 index 00000000..4727b9a3 --- /dev/null +++ b/erp24/migrations/m260212_120000_add_marketplace_fields_to_sales.php @@ -0,0 +1,80 @@ +db->schema->getTableSchema(self::TABLE_NAME); + if ($table === null) { + return; + } + + // Добавляем поле marketplace_order_id (GUID заказа маркетплейса) + if (!$this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('marketplace_order_id')) { + $this->addColumn( + self::TABLE_NAME, + 'marketplace_order_id', + $this->string(64)->null()->comment('GUID заказа маркетплейса из таблицы marketplace_orders') + ); + } + + // Добавляем поле marketplace_name (название маркетплейса) + if (!$this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('marketplace_name')) { + $this->addColumn( + self::TABLE_NAME, + 'marketplace_name', + $this->string(50)->null()->comment('Название маркетплейса (ФлауВау, ЯндексМаркет)') + ); + } + + // Добавляем индекс для быстрого поиска по marketplace_order_id + $this->createIndex( + 'idx-sales-marketplace_order_id', + self::TABLE_NAME, + 'marketplace_order_id' + ); + + // Добавляем составной индекс для аналитики по маркетплейсам + $this->createIndex( + 'idx-sales-marketplace_name_date', + self::TABLE_NAME, + ['marketplace_name', 'date'] + ); + + echo " > Поля marketplace_order_id и marketplace_name успешно добавлены в таблицу erp24.sales\n"; + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + // Удаляем индексы + $this->dropIndex('idx-sales-marketplace_name_date', self::TABLE_NAME); + $this->dropIndex('idx-sales-marketplace_order_id', self::TABLE_NAME); + + // Удаляем поля + if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('marketplace_name')) { + $this->dropColumn(self::TABLE_NAME, 'marketplace_name'); + } + + if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('marketplace_order_id')) { + $this->dropColumn(self::TABLE_NAME, 'marketplace_order_id'); + } + + echo " > Поля marketplace_order_id и marketplace_name удалены из таблицы erp24.sales\n"; + } +} diff --git a/erp24/migrations/m260212_130000_alter_payments_pay_arr_nullable_in_sales.php b/erp24/migrations/m260212_130000_alter_payments_pay_arr_nullable_in_sales.php new file mode 100644 index 00000000..6cd50328 --- /dev/null +++ b/erp24/migrations/m260212_130000_alter_payments_pay_arr_nullable_in_sales.php @@ -0,0 +1,67 @@ +db->schema->getTableSchema(self::TABLE_NAME); + if ($table === null) { + return; + } + + // Изменяем payments на nullable + $this->alterColumn( + self::TABLE_NAME, + 'payments', + $this->text()->null()->comment('JSON массив с информацией о платежах') + ); + + // Изменяем pay_arr на nullable + $this->alterColumn( + self::TABLE_NAME, + 'pay_arr', + $this->string(15)->null()->comment('ID типов платежей, разделенные запятыми') + ); + + echo " > Поля payments и pay_arr успешно изменены на nullable в таблице erp24.sales\n"; + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + // Перед откатом нужно заполнить NULL значения пустыми строками + $this->update(self::TABLE_NAME, ['payments' => ''], ['payments' => null]); + $this->update(self::TABLE_NAME, ['pay_arr' => ''], ['pay_arr' => null]); + + // Возвращаем NOT NULL ограничения + $this->alterColumn( + self::TABLE_NAME, + 'payments', + $this->text()->notNull()->comment('JSON массив с информацией о платежах') + ); + + $this->alterColumn( + self::TABLE_NAME, + 'pay_arr', + $this->string(15)->notNull()->comment('ID типов платежей, разделенные запятыми') + ); + + echo " > Поля payments и pay_arr возвращены к NOT NULL в таблице erp24.sales\n"; + } +} diff --git a/erp24/records/MarketplaceOrders.php b/erp24/records/MarketplaceOrders.php index a2062bb2..d036315d 100644 --- a/erp24/records/MarketplaceOrders.php +++ b/erp24/records/MarketplaceOrders.php @@ -91,6 +91,14 @@ class MarketplaceOrders extends \yii\db\ActiveRecord return 'marketplace_orders'; } + /** + * {@inheritdoc} + */ + public static function primaryKey() + { + return ['id']; + } + /** * {@inheritdoc} */ @@ -245,6 +253,58 @@ class MarketplaceOrders extends \yii\db\ActiveRecord return $result; } + public function getProductsItemsArticule($items):array + { + $products = $items; + $isProductWithGuid = []; + $isProductWithoutGuid = []; + $itemsToComment = []; + + foreach ($products as $product) { + $itemsToComment[] = $product['offer_id'] . ' - ' . $product['offer_name']; + + /** @var Products1c $productRow */ + $productRow = Products1c::find() + ->where(['articule' => $product['offer_id']]) + ->one(); + if (!empty($productRow->id)) { + $isProductWithGuid[$product['offer_id']] = [ + 'product_id' => $productRow->id ?? '', + 'color' => '', + 'price' => $product['price'], + 'quantity' => $product['count'], + 'seller_id' => '', + ]; + + } else { + $product1cClassDynamic = Products1cClassDynamic::find() + ->where(['articule' => $product['offer_id']]) + ->andWhere(['active' => Products1cClassDynamic::ACTIVE]) + ->one(); + if (!empty($product1cClassDynamic->id)) { + $isProductWithGuid[$product['offer_id']]= [ + 'product_id' => $product1cClassDynamic->id ?? '', + 'color' => '', + 'price' => $product['price'], + 'quantity' => $product['count'], + 'seller_id' => '', + ]; + } else { + $isProductWithoutGuid[] = [ + 'product_id' => $product['offer_name'] ?? null, + 'quantity' => $product['count'] ?? null, + ]; + } + } + } + + return [ + 'isProductWithoutGuid' => $isProductWithoutGuid, + 'isProductWithGuid' => $isProductWithGuid, + 'itemsToComment' => $itemsToComment, + ]; + } + public static function buildStatusesToCode(): array { $statuses = MarketplaceOrder1cStatuses::find() diff --git a/erp24/records/Sales.php b/erp24/records/Sales.php index f5dfeec1..fba684a1 100755 --- a/erp24/records/Sales.php +++ b/erp24/records/Sales.php @@ -35,6 +35,8 @@ use yii\db\Expression; * @property string|null $delivery_date * @property int|null $pickup * @property int $update_source + * @property string|null $marketplace_order_id GUID заказа маркетплейса из таблицы marketplace_orders + * @property string|null $marketplace_name Название маркетплейса (ФлауВау, ЯндексМаркет) */ class Sales extends \yii\db\ActiveRecord { @@ -57,8 +59,8 @@ class Sales extends \yii\db\ActiveRecord public function rules() { return [ - [['id', 'date', 'operation', 'status', 'summ', 'skidka', 'number', 'admin_id', 'seller_id', 'store_id_1c', 'payments', 'pay_arr' /*, 'terminal_id', 'kkm_id', 'held' */], 'required'], - [['date', 'date_up', 'order_id', 'pickup', 'terminal_id'], 'safe'], + [['id', 'date', 'operation', 'status', 'summ', 'skidka', 'number', 'admin_id', 'seller_id', 'store_id_1c' /*, 'terminal_id', 'kkm_id', 'held' */], 'required'], + [['date', 'date_up', 'order_id', 'pickup', 'terminal_id', 'payments', 'marketplace_order_id', 'marketplace_name'], 'safe'], [['summ', 'purchase_sum', 'skidka'], 'number'], [['update_source'], 'integer'], [['admin_id', 'store_id', 'phone', 'status_check', 'held', 'matrix'], 'integer'], @@ -69,6 +71,8 @@ class Sales extends \yii\db\ActiveRecord [['number'], 'string', 'max' => 225], [['pay_arr'], 'string', 'max' => 15], [['terminal'], 'string', 'max' => 255], + [['marketplace_order_id'], 'string', 'max' => 64], + [['marketplace_name'], 'string', 'max' => 50], [['date', 'operation', 'store_id_1c', 'id'], 'unique', 'targetAttribute' => ['date', 'operation', 'store_id_1c', 'id']], [['id'], 'unique'], ]; @@ -103,6 +107,8 @@ class Sales extends \yii\db\ActiveRecord 'held' => 'Held', 'matrix' => 'Matrix', 'date_up' => 'Date Up', + 'marketplace_order_id' => 'Marketplace Order ID', + 'marketplace_name' => 'Marketplace Name', ]; } diff --git a/erp24/services/MarketplaceService.php b/erp24/services/MarketplaceService.php index 8760b59d..2f9bae88 100644 --- a/erp24/services/MarketplaceService.php +++ b/erp24/services/MarketplaceService.php @@ -3236,7 +3236,7 @@ class MarketplaceService } $createChecks->items = Json::encode($items); - $createChecks->payments = ''; + $createChecks->payments = '[]'; $createChecks->held = 1; $createChecks->kkm_id = $kkm_id; $createChecks->comments = ''; diff --git a/erp24/services/UploadService.php b/erp24/services/UploadService.php index b742dae0..fbdf9bd3 100644 --- a/erp24/services/UploadService.php +++ b/erp24/services/UploadService.php @@ -1248,10 +1248,18 @@ class UploadService { $sales2->skidka = $arr["discount"] ?? '0'; $sales2->delivery_date = date('Y-m-d', strtotime($arr['delivery_date'] ?? '')); $sales2->pickup = $arr['pickup'] ?? false; + $sales2->marketplace_order_id = $arr["marketplace_order_id"] ?? null; + $sales2->marketplace_name = $arr["marketplace_name"] ?? null; $sales2->save(); + // ✅ Проверка результата if ($sales2->getErrors()) { - LogService::apiErrorLog(json_encode(["error_id" => 21, "error" => $sales2->getErrors()], JSON_UNESCAPED_UNICODE)); + LogService::apiErrorLog([ + "error_id" => 21, + "error" => $sales2->getErrors(), + "check_id" => $arr["id"] + ]); + continue; // ← ПРОПУСТИТЬ создание товаров! } // Обновляем данные в очереди на создание чеков @@ -2010,6 +2018,9 @@ class UploadService { $pay_arr[] = 2; } } + } else { + //Маркет плейс + $pay_arr[] = 4; } return $pay_arr; -- 2.39.5