From: fomichev Date: Tue, 15 Apr 2025 15:03:16 +0000 (+0300) Subject: Вывод расчетов X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=1b46f83a9a745aa2983ecc0c03ae35829cecb571;p=erp24_rep%2Fyii-erp24%2F.git Вывод расчетов --- diff --git a/erp24/controllers/BouquetController.php b/erp24/controllers/BouquetController.php index 2d23296c..e3e0f85a 100644 --- a/erp24/controllers/BouquetController.php +++ b/erp24/controllers/BouquetController.php @@ -13,12 +13,16 @@ use yii\web\NotFoundHttpException; use yii\web\Response; use yii_app\helpers\DataHelper; use yii_app\records\{BouquetComposition, + BouquetCompositionPrice, BouquetCompositionProducts, BouquetForecast, CityStore, + CityStoreParams, Files, MatrixType, + PricesDynamic, Products1cNomenclature, + SelfCostProduct, StoreType, WriteOffsErp}; use yii_app\services\StorePlanService; @@ -249,19 +253,27 @@ class BouquetController extends Controller return $data; } - public function actionMonthGoal() + public function actionMonthGoal($month, $year) { - $matrixTypesIds = StorePlanService::getActiveMatrixTypes(); - // var_dump($matrixTypesIds);die(); - $bouquets = []; - if ($matrixTypesIds) { - foreach ($matrixTypesIds as $matrixTypeId) { - $bouquets[$matrixTypeId] = StorePlanService::getBouqetsByDate(5, 2025, $matrixTypeId); - } - } + $result = StorePlanService::getBouquetSpiecesMonthGoal($month, $year); + + $month = $month ?? 5; + $year = $year ?? 2025; + $stores = CityStore::find() + ->select(['id', 'name']) + ->where(['visible' => CityStore::IS_VISIBLE]) + ->asArray() + ->all(); - var_dump($bouquets);die(); + $storesMap = ArrayHelper::map($stores, 'id', 'name'); + + return $this->render('month-goal', [ + 'result' => $result, + 'storesMap' => $storesMap, + 'month' => $month, + 'year' => $year, + ]); } } diff --git a/erp24/records/BouquetComposition.php b/erp24/records/BouquetComposition.php index 9a70d754..873f9781 100644 --- a/erp24/records/BouquetComposition.php +++ b/erp24/records/BouquetComposition.php @@ -457,6 +457,7 @@ class BouquetComposition extends ActiveRecord $costModel->bouquet_id = $this->id; $costModel->region_id = $region_id; } + // TODO не понятно как задается региональность цены - точнее как она от региона зависит $costModel->selfcost = $this->getSelfCost($data); $costModel->selfcost_markup = 30; $costModel->selfcost_markup_price = 0.3 * $costModel->selfcost; diff --git a/erp24/services/StorePlanService.php b/erp24/services/StorePlanService.php index 6fcd365b..98bab0ec 100755 --- a/erp24/services/StorePlanService.php +++ b/erp24/services/StorePlanService.php @@ -7,13 +7,19 @@ use yii\db\Expression; use yii\helpers\ArrayHelper; use yii_app\records\BouquetComposition; use yii_app\records\BouquetCompositionMatrixTypeHistory; +use yii_app\records\BouquetCompositionPrice; +use yii_app\records\BouquetCompositionProducts; +use yii_app\records\BouquetForecast; use yii_app\records\CityStore; +use yii_app\records\CityStoreParams; use yii_app\records\Motivation; use yii_app\records\PricesDynamic; use yii_app\records\Products1cAdditionalCharacteristics; +use yii_app\records\Products1cNomenclature; use yii_app\records\Sales; use yii_app\records\SalesProducts; use yii_app\records\StorePlan; +use yii_app\records\StoreType; use yii_app\records\WriteOffsErp; class StorePlanService @@ -763,15 +769,25 @@ class StorePlanService public static function getBouqetsByDate($month, $year, $matrix_type = null) { $query = BouquetComposition::find() + ->select([ + 'bouquet_composition.*', + 'bf.year AS forecast_year', + 'bf.month AS forecast_month', + + + ]) ->orderBy(['id' => SORT_DESC]) - ->groupBy('bouquet_composition.id') + ->groupBy(['bouquet_composition.id', 'bf.year', + 'bf.month']) ->andWhere(['status' => [ WriteOffsErp::STATUS_CREATED_1С, ]]) - ->joinWith('bouquetForecast as bf') - ->andWhere(['bf.year' => $year]) - ->andWhere(['bf.month' => $month]); + ->innerJoinWith(['bouquetForecast bf' => function($query) use ($year, $month) { + $query->andWhere(['bf.year' => $year]) + ->andWhere(['bf.month' => $month]) + ->andWhere(['not', ['bf.type_sales_value' => null]]); + }]); if ($matrix_type) { $query->leftJoin( @@ -782,9 +798,116 @@ class StorePlanService 'mth.is_active' => true ]); } + return $query->asArray()->all(); + } + public static function getBouquetSpiecesMonthGoal($month, $year) { + $stores = ArrayHelper::map(CityStore::find()->select(['id'])->where(['visible' => CityStore::IS_VISIBLE])->asArray()->all(), 'id', 'id'); + $storesParams = ArrayHelper::map(CityStoreParams::find() + ->select(['store_id', 'address_region']) + ->where(['store_id' => array_keys($stores)]) + ->andWhere(['not', ['address_region' => '']]) + ->asArray() + ->indexBy('store_id') + ->all(), 'store_id', 'address_region'); + + $matrixTypesIds = StorePlanService::getActiveMatrixTypes(); + + $storesForecasts = []; + // получаем букеты из матрицы + if ($matrixTypesIds) { + foreach ($matrixTypesIds as $matrixTypeId) { + $bouquetsArray = StorePlanService::getBouqetsByDate($month, $year, $matrixTypeId); + $forecasts = ArrayHelper::getColumn($bouquetsArray , 'bouquetForecast'); + + foreach ($forecasts as $forecastArray) { + if (is_array($forecastArray)) { + foreach ($forecastArray as $fc) { + $bouquetPrice = 0; + if(isset($storesParams[$fc["type_sales_id"]])){ + $bouquetPrice = BouquetCompositionPrice::find() + ->where(['bouquet_id' => $fc['bouquet_id']]) + ->andWhere(['region_id' => $storesParams[$fc["type_sales_id"]]])->one()->price; + } + + $storesForecasts[] = array_merge($fc, ['matrixTypeId' => $matrixTypeId], ['price' => $bouquetPrice] ); + + } + } + } + } + } + $resultArr = []; + foreach ($storesForecasts as $storeForecast) { + $products = ArrayHelper::toArray(BouquetCompositionProducts::getCompositionProducts($storeForecast['bouquet_id'])); + $productGuids = array_filter(array_column($products, 'product_guid')); + $pricesData = ArrayHelper::map(PricesDynamic::find() + ->where(['product_id' => $productGuids]) + ->andWhere(['active' => 1]) + ->andWhere(['region_id' => $storesParams[$fc["type_sales_id"]]]) + ->select(['price', 'product_id'])->asArray()->all(), 'product_id', 'price') ; + // var_dump($products); die(); + foreach ($products as $product) { + $species = Products1cNomenclature::find()->where(['id' => $product['product_guid']])->one()->species; + $productCost = round($pricesData[$product['product_guid']] * $product['count'] * 1.15, 2); + if (!isset($resultArr[$storeForecast["type_sales_id"]][$species][$storeForecast["type_sales"]])) { + $resultArr[$storeForecast["type_sales_id"]][$species][$storeForecast["type_sales"]] = 0; + } + $resultArr[$storeForecast["type_sales_id"]][$species][$storeForecast["type_sales"]] += $productCost; + + } + + } + $finalResult = []; + foreach ($resultArr as $typeSalesId => $speciesData) { + foreach ($speciesData as $species => $salesDetails) { + // Здесь $salesDetails — это массив вида [storeSalesType1 => cost1, storeSalesType2 => cost2, …] + $finalResult[$typeSalesId][$species] = round(array_sum($salesDetails), 2); + } + } + + return ['detail' => $resultArr, 'final' => $finalResult]; + + + + } + + + public static function getBouquetGoal($bouquet) { + $onlineStores = BouquetForecast::getStoresList( + $bouquet['id'], + BouquetForecast::ONLINE_STORES, + CityStore::class, + ['visible' => CityStore::IS_VISIBLE], + $bouquet['forecast_month'], + $bouquet['forecast_year'] + ); + $marketplaceStores = BouquetForecast::getStoresList( + $bouquet['id'], + BouquetForecast::MARKETPLACE, + CityStore::class, + ['visible' => CityStore::IS_VISIBLE], + $bouquet['forecast_month'], + $bouquet['forecast_year'] + ); + $offlineStores = BouquetForecast::getStoresList( + $bouquet['id'], + BouquetForecast::OFFLINE_STORES, + StoreType::class, + [], + $bouquet['forecast_month'], + $bouquet['forecast_year'] + ); + return [ + 'onlineStores' => $onlineStores, + 'marketplaceStores' => $marketplaceStores, + 'offlineStores' => $offlineStores, + + ]; +} + } diff --git a/erp24/views/bouquet/month-goal.php b/erp24/views/bouquet/month-goal.php new file mode 100644 index 00000000..a6ff09ca --- /dev/null +++ b/erp24/views/bouquet/month-goal.php @@ -0,0 +1,40 @@ + store_name] +@var $month integer +@var $year integer + */ +?> +

Цели на месяц: /

+ +

Итоговые суммы по магазинам и видам продукции

+ + + + + + + + + + + $speciesData): ?> + + $sum): ?> + + + + + + + + + + + + + +
МагазинВид продукцииСумма
Нет данных для отображения.
\ No newline at end of file