]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Вывод продаж по МП в отчете /dashboard/sales
authorVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 6 Nov 2025 11:27:15 +0000 (14:27 +0300)
committerVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 6 Nov 2025 11:27:15 +0000 (14:27 +0300)
erp24/actions/dashboard/SalesAction.php
erp24/records/CreateChecks.php
erp24/records/Sales.php
erp24/services/MarketplaceSalesMatchingService.php
erp24/views/dashboard/sales.php

index 670f9f2f0699d31b611590d9a9d831aec783d20d..8f5b5464eabf6dbb44e2a0f234a4d61fa1935b79 100755 (executable)
@@ -207,6 +207,10 @@ class SalesAction extends Action
 
         $sales_delivery = $salesService->salesSumCalculate($salesSumDelivery);
 
+        // Получение продаж МП
+        $marketplaceSalesService = new \yii_app\services\MarketplaceSalesMatchingService();
+        $marketplaceSales = $marketplaceSalesService->getMarketplaceSalesByStore($date1, $date2);
+
         $salesSumWithCity = $dashboardService->getSalesSumWithCityStoreId($sales_summ, $plan, $city_stores);
 
         $sales = ArrayHelper::getValue($salesSumWithCity, 'sales');
@@ -319,7 +323,8 @@ class SalesAction extends Action
             'servises' => $servises,
             'saleServices' => $saleServices,
             'daysSearchForm' => $daysSearchForm,
-            'admins' => $admins
+            'admins' => $admins,
+            'marketplaceSales' => $marketplaceSales,
         ];
 
         return $this->controller->render('/dashboard/sales.php', $params);
index a62ea1eb77d2102db728bac8c409440e5be3bf67..edd3ee29094065d1e82d9f4cfa4d97ddacc24e28 100644 (file)
@@ -90,4 +90,22 @@ class CreateChecks extends \yii\db\ActiveRecord
             'marketplace_name' => 'Marketplace Name',
         ];
     }
+
+    /**
+     * Связь с продажей из 1С
+     * @return \yii\db\ActiveQueryInterface
+     */
+    public function getSale()
+    {
+        return $this->hasOne(Sales::class, ['id' => 'guid']);
+    }
+
+    /**
+     * Связь с заказом МП
+     * @return \yii\db\ActiveQueryInterface
+     */
+    public function getMarketplaceOrder()
+    {
+        return $this->hasOne(MarketplaceOrders::class, ['marketplace_order_id' => 'marketplace_order_id']);
+    }
 }
index 32670e438a486bc1fa62751c9d1b1e77dda6db1d..f5dfeec15ccbf857664918bf5ea0985d63a4931c 100755 (executable)
@@ -144,4 +144,13 @@ class Sales extends \yii\db\ActiveRecord
         return $this->hasOne(self::class, ['id' => 'sales_check'])
             ->from(self::tableName() . ' sc');
     }
+
+    /**
+     * Связь с чеком создания (create_checks)
+     * @return \yii\db\ActiveQueryInterface
+     */
+    public function getCreateCheck()
+    {
+        return $this->hasOne(CreateChecks::class, ['guid' => 'id']);
+    }
 }
\ No newline at end of file
index 3b3ac07f9c107b5f43ea88a6f813becadc240caa..8815353be772dfc2184cfc6b4e5707d57b402fdd 100644 (file)
@@ -467,5 +467,149 @@ class MarketplaceSalesMatchingService
         $productsArr = Products1c::getProductsFromClass(['wrap']);
         return $productsArr['wrap'] ?? [];
     }
+
+    /**
+     * Получить продажи МП из таблицы sales через create_checks
+     * 
+     * @param string $dateFrom
+     * @param string $dateTo
+     * @return array
+     * @throws \Exception
+     */
+    public function getMarketplaceSalesFromChecks(string $dateFrom, string $dateTo): array
+    {
+        $query = Sales::find()
+            ->alias('s')
+            ->select([
+                's.id',
+                's.date',
+                's.summ',
+                's.skidka',
+                's.store_id_1c',
+                's.operation',
+                'cc.marketplace_order_id',
+                'cc.is_marketplace',
+            ])
+            ->innerJoin('create_checks cc', 's.id = cc.guid')
+            ->andWhere(['cc.is_marketplace' => 1])
+            ->andWhere(['>=', 's.date', DateHelper::getDateTimeStartDay($dateFrom, true)])
+            ->andWhere(['<=', 's.date', DateHelper::getDateTimeEndDay($dateTo, true)])
+            ->orderBy(['s.date' => SORT_DESC]);
+
+        return $query->asArray()->all();
+    }
+
+    /**
+     * Получить продажи МП из завершенных заказов (fallback)
+     * 
+     * @param string $dateFrom
+     * @param string $dateTo
+     * @return array
+     * @throws \Exception
+     */
+    public function getMarketplaceSalesFromOrders(string $dateFrom, string $dateTo): array
+    {
+        $orders = $this->getMarketplaceOrdersForPeriod($dateFrom, $dateTo);
+        
+        $result = [];
+        foreach ($orders as $order) {
+            // Получаем store_id_1c через связь
+            $storeId1c = null;
+            if ($order->store && $order->store->storeGuid) {
+                $storeId1c = $order->store->storeGuid->export_val;
+            }
+            
+            if (empty($storeId1c)) {
+                continue;
+            }
+            
+            $result[] = [
+                'id' => $order->id,
+                'date' => $order->updated_at,
+                'summ' => $order->total,
+                'skidka' => 0,
+                'store_id_1c' => $storeId1c,
+                'operation' => Sales::OPERATION_SALE,
+                'marketplace_order_id' => $order->marketplace_order_id,
+                'is_marketplace' => 1,
+            ];
+        }
+        
+        return $result;
+    }
+
+    /**
+     * Получить продажи МП по магазинам с автоматическим выбором источника
+     * 
+     * @param string $dateFrom
+     * @param string $dateTo
+     * @return array
+     * @throws \Exception
+     */
+    public function getMarketplaceSalesByStore(string $dateFrom, string $dateTo): array
+    {
+        // Сначала пытаемся получить из чеков
+        $salesFromChecks = $this->getMarketplaceSalesFromChecks($dateFrom, $dateTo);
+        
+        $sales = [];
+        $source = 'orders'; // По умолчанию fallback
+        
+        if (!empty($salesFromChecks)) {
+            // Если есть чеки МП, используем их
+            $sales = $salesFromChecks;
+            $source = 'checks';
+        } else {
+            // Fallback: используем заказы МП
+            $sales = $this->getMarketplaceSalesFromOrders($dateFrom, $dateTo);
+        }
+        
+        // Группируем по магазинам
+        return $this->groupMarketplaceSalesByStore($sales, $source);
+    }
+
+    /**
+     * Группировка продаж МП по магазинам
+     * 
+     * @param array $sales
+     * @param string $source
+     * @return array
+     */
+    private function groupMarketplaceSalesByStore(array $sales, string $source): array
+    {
+        $grouped = [];
+        
+        foreach ($sales as $sale) {
+            $storeId1c = $sale['store_id_1c'];
+            
+            if (!isset($grouped[$storeId1c])) {
+                $grouped[$storeId1c] = [
+                    'store_id_1c' => $storeId1c,
+                    'total_orders' => 0,
+                    'total_summ' => 0,
+                    'source' => $source,
+                    'sales' => [],
+                ];
+            }
+            
+            $saleAmount = $sale['summ'] - $sale['skidka'];
+            
+            // Применяем операцию (продажа или возврат)
+            if ($sale['operation'] === Sales::OPERATION_SALE) {
+                $grouped[$storeId1c]['total_summ'] += $saleAmount;
+                $grouped[$storeId1c]['total_orders']++;
+            } elseif ($sale['operation'] === Sales::OPERATION_RETURN) {
+                $grouped[$storeId1c]['total_summ'] -= $saleAmount;
+            }
+            
+            $grouped[$storeId1c]['sales'][] = $sale;
+        }
+        
+        // Сортировка по сумме (убывание)
+        uasort($grouped, function ($a, $b) {
+            return $b['total_summ'] <=> $a['total_summ'];
+        });
+        
+        return $grouped;
+    }
 }
 
index 7c992bd339f5dd1461b415f0e781e39edd6cfef3..fd680bfb3122a4e490dd7b587727a4acfdebb82d 100755 (executable)
@@ -316,4 +316,51 @@ foreach($sales_delivery as $storeId => $summ) {
 }
 echo"</tbody></table>
 <b>Итого $itog руб по доставке</b>";
+?>
+
+<?php if (!empty($marketplaceSales)): ?>
+<h5 class="mt-4">Продажи маркетплейсов</h5>
+<div class="table-responsive">
+    <table class="table table-striped">
+        <thead>
+            <tr>
+                <th>Магазин</th>
+                <th>Количество заказов</th>
+                <th>Сумма продаж</th>
+                <th>Источник данных</th>
+            </tr>
+        </thead>
+        <tbody>
+        <?php 
+        $totalMpSumm = 0;
+        $totalMpOrders = 0;
+        foreach ($marketplaceSales as $storeId1c => $data): 
+            $storeName = $city_stores[$storeId1c] ?? 'Неизвестный магазин';
+            $totalMpSumm += $data['total_summ'];
+            $totalMpOrders += $data['total_orders'];
+        ?>
+            <tr>
+                <td><?= $storeName ?></td>
+                <td><?= $data['total_orders'] ?></td>
+                <td><?= number_format($data['total_summ'], 2, '.', ' ') ?> руб</td>
+                <td>
+                    <span class="badge bg-<?= $data['source'] === 'checks' ? 'success' : 'warning' ?>">
+                        <?= $data['source'] === 'checks' ? 'Чеки (1С)' : 'Заказы МП' ?>
+                    </span>
+                </td>
+            </tr>
+        <?php endforeach; ?>
+        </tbody>
+        <tfoot>
+            <tr class="bg-success">
+                <th>Итого</th>
+                <th><?= $totalMpOrders ?></th>
+                <th><?= number_format($totalMpSumm, 2, '.', ' ') ?> руб</th>
+                <th></th>
+            </tr>
+        </tfoot>
+    </table>
+</div>
+<b>Итого <?= number_format($totalMpSumm, 2, '.', ' ') ?> руб по маркетплейсам</b>
+<?php endif; ?>