$monthSubcategoryWriteOffsShare = $service->getMonthSubcategoryShareOrWriteOff($filters['plan_date'], $filters, $filters['type']);
$monthSubcategoryWriteOffsGoals = $service->getMonthSubcategoryGoal($monthSubcategoryWriteOffsShare, $monthCategoryWriteOffsGoal, $filters['type']);
$monthSpeciesWriteOffShare = $service->getMonthSpeciesShareOrWriteOff($filters['plan_date'], $filters, $filters['type']);
- $goals = $service->getMonthSpeciesGoalDirty($monthSpeciesWriteOffShare, $monthSubcategoryWriteOffsGoals, $filters['type'], $data);
+ $goals = $service->getMonthSpeciesGoalDirty($monthSpeciesWriteOffShare, $monthSubcategoryWriteOffsGoals, $filters['type'], $goals);
}
$filters['species']
);*/
- $matrixForecast = MatrixBouquetForecast::find()
- ->where(['year' => $filters['year'], 'month' => $filters['month']])
- ->asArray()
- ->all();
- $matrixGroups = array_unique(ArrayHelper::getColumn($matrixForecast, 'group'));
- $bouquetForecast = StorePlanService::getBouquetSpiecesMonthGoalFromForecast($filters['month'], $filters['year'], $filters['store_id'], $matrixGroups);
- $speciesData = $bouquetForecast['final'];
- foreach ($speciesData as $store_id => $categoryData) {
- foreach ($categoryData as $category => $subcategoryData) {
- foreach ($subcategoryData as $subcategory => $species) {
- foreach ($species as $speciesInd => $row) {
- $bouquetSpeciesForecast[] = [
- 'category' => $category,
- 'subcategory' => $subcategory,
- 'store_id' => $store_id,
- 'species' => $speciesInd,
- 'goal' => $row
- ];
- }
- }
- }
-
- }
- $cleanedSpeciesGoals = $service->subtractSpeciesGoals($goals, $bouquetSpeciesForecast, $noHistoryProductData);
-
+// $matrixForecast = MatrixBouquetForecast::find()
+// ->where(['year' => $filters['year'], 'month' => $filters['month']])
+// ->asArray()
+// ->all();
+// $matrixGroups = array_unique(ArrayHelper::getColumn($matrixForecast, 'group'));
+// $bouquetForecast = StorePlanService::getBouquetSpiecesMonthGoalFromForecast($filters['month'], $filters['year'], $filters['store_id'], $matrixGroups);
+// $speciesData = $bouquetForecast['final'];
+// foreach ($speciesData as $store_id => $categoryData) {
+// foreach ($categoryData as $category => $subcategoryData) {
+// foreach ($subcategoryData as $subcategory => $species) {
+// foreach ($species as $speciesInd => $row) {
+// $bouquetSpeciesForecast[] = [
+// 'category' => $category,
+// 'subcategory' => $subcategory,
+// 'store_id' => $store_id,
+// 'species' => $speciesInd,
+// 'goal' => $row
+// ];
+// }
+// }
+// }
+//
+// }
+
+ $cleanedSpeciesGoals = $service->subtractSpeciesGoals($goals, [], []);
$salesProductForecastShare = $service->calculateProductForecastShare($noHistoryProductData, $historyProductData);
->asArray()
->all();
- $rawGoals = [];
+ $rawGoalsSales = [];
+ $rawGoalsWriteOffs = [];
foreach ($categoryPlan as $categoryName => $category) {
- if ($filters['type'] == AutoPlannogrammaService::TYPE_SALES) {
- $rawGoals[$categoryName] = (float)$category['offline'] + (float)$category['internet_shop'] + (float)$category['marketplace'];
- } else {
- $rawGoals[$categoryName] = (float)$category['write_offs'];
- }
+ $rawGoalsSales[$categoryName] = (float)$category['offline'] + (float)$category['internet_shop'] + (float)$category['marketplace'];
+ $rawGoalsWriteOffs[$categoryName] = (float)$category['write_offs'];
}
- $matrixGoal = $rawGoals['Матрица'] ?? 0.0;
- $nonMatrixGoals = array_filter(
- $rawGoals,
- fn($v, $k) => $k !== 'Матрица',
- ARRAY_FILTER_USE_BOTH
- );
- $sumWithoutMatrix = array_sum($nonMatrixGoals);
-
- if ($sumWithoutMatrix <= 0) {
- foreach ($nonMatrixGoals as $categoryName => $_) {
- $monthCategoryGoal[] = [
- 'category' => $categoryName,
- 'store_id' => $filters['store_id'],
- 'share' => 0.0,
- 'goal' => 0.0,
- ];
- }
- } else {
- foreach ($nonMatrixGoals as $categoryName => $value) {
- $share = $value / $sumWithoutMatrix;
-
- if ($filters['type'] == AutoPlannogrammaService::TYPE_SALES) {
- $distributable = max(0.0, $sumWithoutMatrix - $matrixGoal);
- } else {
- $distributable = $sumWithoutMatrix;
- }
-
- $newGoal = $share * $distributable;
-
- $monthCategoryGoal[] = [
- 'category' => $categoryName,
- 'store_id' => $filters['store_id'],
- 'share' => $share,
- 'goal' => $newGoal,
- ];
- }
- }
+ $monthCategoryGoalSales = $this->buildCategoryGoals($rawGoalsSales, true, $filters['store_id']); // для продаж: вычитаем матрицу
+ $monthCategoryGoalWriteOffs = $this->buildCategoryGoals($rawGoalsWriteOffs, false, $filters['store_id']); // для списаний: без вычитания
$monthSubcategoryShare = $this->getMonthSubcategoryShareOrWriteOff($datePlan, $filters);
- $monthSubcategoryGoal = $this->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoal);
-
+ $monthSubcategoryGoal = $this->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoalSales);
$monthSpeciesShare = $this->getMonthSpeciesShareOrWriteOff($datePlan, $filters);
$monthSpeciesGoal = $this->getMonthSpeciesGoalDirty($monthSpeciesShare, $monthSubcategoryGoal);
+ if ($filters['type'] == AutoPlannogrammaService::TYPE_WRITE_OFFS) {
+ $monthSubcategoryWriteOffsShare = $this->getMonthSubcategoryShareOrWriteOff($datePlan, $filters, $filters['type']);
+ $monthSubcategoryWriteOffsGoals = $this->getMonthSubcategoryGoal($monthSubcategoryWriteOffsShare, $monthCategoryGoalWriteOffs, $filters['type'], $monthSubcategoryGoal);
+ $monthSpeciesWriteOffShare = $this->getMonthSpeciesShareOrWriteOff($datePlan, $filters, $filters['type']);
+ $monthSpeciesGoal = $this->getMonthSpeciesGoalDirty($monthSpeciesWriteOffShare, $monthSubcategoryWriteOffsGoals, $filters['type'], $monthSpeciesGoal);
+ }
+
$filtered = array_filter($monthSpeciesGoal, function ($row) use ($filters) {
foreach ($filters as $key => $value) {
if ($value === null || $value === '') {
return array_values($filtered);
}
+ /**
+ * @param array $rawGoals
+ * @param bool $subtractMatrix если true — для распределения вычитается "Матрица"
+ * @param int $storeId
+ * @return array
+ */
+private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $storeId): array {
+ $result = [];
+
+ $matrixGoal = $rawGoals['Матрица'] ?? 0.0;
+
+ $nonMatrixGoals = array_filter(
+ $rawGoals,
+ fn($v, $k) => $k !== 'Матрица',
+ ARRAY_FILTER_USE_BOTH
+ );
+ $sumWithoutMatrix = array_sum($nonMatrixGoals);
+
+ if ($sumWithoutMatrix <= 0) {
+ foreach ($nonMatrixGoals as $categoryName => $_) {
+ $result[] = [
+ 'category' => $categoryName,
+ 'store_id' => $storeId,
+ 'share' => 0.0,
+ 'goal' => 0.0,
+ ];
+ }
+ return $result;
+ }
+
+ $distributableBase = $subtractMatrix
+ ? max(0.0, $sumWithoutMatrix - $matrixGoal)
+ : $sumWithoutMatrix;
+
+ foreach ($nonMatrixGoals as $categoryName => $value) {
+ $share = $value / $sumWithoutMatrix;
+ $newGoal = $share * $distributableBase;
+
+ $result[] = [
+ 'category' => $categoryName,
+ 'store_id' => $storeId,
+ 'share' => $share,
+ 'goal' => $newGoal,
+ ];
+ }
+
+ return $result;
+}
// Недельные расчеты
$goals = $this->calculateFullGoalChain($filters);
$noHistoryProductData = $this->calculateSpeciesForecastForProductsWithoutHistory($filters['plan_date'], $filters);
$historyProductData = $this->calculateSpeciesForecastForProductsWithHistory($filters['plan_date'], $filters, $goals);
- $matrixForecast = MatrixBouquetForecast::find()
- ->where(['year' => $filters['year'], 'month' => $filters['month']])
- ->asArray()
- ->all();
- $matrixGroups = array_unique(ArrayHelper::getColumn($matrixForecast, 'group'));
- $bouquetForecast = StorePlanService::getBouquetSpiecesMonthGoalFromForecast($filters['month'], $filters['year'], $filters['store_id'], $matrixGroups);
- $speciesData = $bouquetForecast['final'];
- foreach ($speciesData as $store_id => $categoryData) {
- foreach ($categoryData as $category => $subcategoryData) {
- foreach ($subcategoryData as $subcategory => $species) {
- foreach ($species as $speciesInd => $row) {
- $bouquetSpeciesForecast[] = [
- 'category' => $category,
- 'subcategory' => $subcategory,
- 'store_id' => $store_id,
- 'species' => $speciesInd,
- 'goal' => $row
- ];
- }
- }
- }
- }
- $cleanedSpeciesGoals = $this->subtractSpeciesGoals($goals, $bouquetSpeciesForecast, $noHistoryProductData);
+// $matrixForecast = MatrixBouquetForecast::find()
+// ->where(['year' => $filters['year'], 'month' => $filters['month']])
+// ->asArray()
+// ->all();
+// $matrixGroups = array_unique(ArrayHelper::getColumn($matrixForecast, 'group'));
+// $bouquetForecast = StorePlanService::getBouquetSpiecesMonthGoalFromForecast($filters['month'], $filters['year'], $filters['store_id'], $matrixGroups);
+// $speciesData = $bouquetForecast['final'];
+// foreach ($speciesData as $store_id => $categoryData) {
+// foreach ($categoryData as $category => $subcategoryData) {
+// foreach ($subcategoryData as $subcategory => $species) {
+// foreach ($species as $speciesInd => $row) {
+// $bouquetSpeciesForecast[] = [
+// 'category' => $category,
+// 'subcategory' => $subcategory,
+// 'store_id' => $store_id,
+// 'species' => $speciesInd,
+// 'goal' => $row
+// ];
+// }
+// }
+// }
+//
+// }
+ $cleanedSpeciesGoals = $this->subtractSpeciesGoals($goals, [], []);
$salesProductForecastShare = $this->calculateProductForecastShare($noHistoryProductData, $historyProductData);