]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
добавил расчет себестоимости и сохранеинеи в таблицу MotivationValues
authorVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 29 Aug 2024 14:24:25 +0000 (17:24 +0300)
committerVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 29 Aug 2024 14:24:25 +0000 (17:24 +0300)
erp24/actions/motivation/IndexAction.php
erp24/services/MotivationService.php

index 6cd4abb2debb631baf25be4bdada340e0d4c342b..beae4471901ee9d3b41b88b032241b8e7140a810 100644 (file)
@@ -102,6 +102,9 @@ class IndexAction extends Action
         // Подсчёт количества сотрудников
         MotivationService::calculatePersonalCount($model->store_id, $model->year, $model->month);
 
+        // Подсчёт стоимости товара
+        MotivationService::saveCostMotivation($model->store_id, $model->year, $model->month);
+
         $showTable = false;
         $motivationData = [];
         $daysInMonth = null;
index 89be1bffa66952d904b1e5d4f0987072ec570de4..e34eb6bbf98a13bae21c3841c5e5ff19102a4681 100644 (file)
@@ -20,8 +20,7 @@ use yii_app\records\Sales;
 use yii_app\records\SalesProducts;
 use yii_app\records\TimetableFactModel;
 use yii_app\records\Timetable;
-
-
+use yii_app\records\SelfCostProduct;
 
 
 use yii_app\records\EmployeePayment;
@@ -29,34 +28,100 @@ use yii_app\records\EmployeePayment;
 
 class MotivationService
 {
+    const  CODE_OFFLINE_SALES = 1;
+    const CODE_ONLINE_SALES = 2;
+    const CODE_ASSEMBLY_SERVICES = 3;
+    const CODE_DELIVERY_SERVICES = 4;
+    const CODE_DELIVERY_DEFECTS = 6;
+    const CODE_WRITE_OFF_ILLIQUID_GOODS_SPOOLAGE_EXPIRATION_OF_SHELF_LIFE = 7;
+    const CODE_EQUIPMENT_FAILURE_DEFECT = 8;
+    const CODE_REGRADING = 9;
+    const CODE_CONSUMABLES_SALES_SUPPORT = 10;
+    const CODE_RENT = 12;
+    const CODE_PUBLIC_SERVICES = 13;
+    const CODE_SECURITY = 14;
+    const CODE_CLEANING_SERVICES_FOR_PREMISES_AND_TERRITORY = 15;
+    const CODE_DELIVERY_TO_CLIENT_CURRIER = 16;
+    const CODE_DELIVERY_TO_CLIENT_TAXI = 17;
+    const CODE_MARKETPLACE_SERVICES = 18;
+    const CODE_REFRIGERATION_EQUIPMENT_REPAIR_MAINTANANCE = 19;
+    const CODE_COSTS_FOR_MAINTENANCE_AND_REPAIR_OF_OFFICE_EQUIPMENT_INCLUDING_CONSUMABLES = 20;
+    const CODE_EXPENSES_FOR_MAINENANCE_AND_REPAIR_OF_OTHER_FIXED_ASSETS = 21;
+    const CODE_MAINTENANCE_OF_CASH_REGISTERS = 22;
+    const CODE_INTERNET = 23;
+    const CODE_HOUSEHOLD_GOODS = 24;
+    const CODE_STATIONARY = 25;
+    const CODE_ACCOUNTING_SERVICES_SETTING_UP_AND_MAINTAINING_ACCOUNTING_AND_TAX_RECORDS = 27;
+    const CODE_LEGAL_SERVICES = 28;
+    const CODE_PERSONAL_ADMINISTRATION_LABOR_PROTECTION = 29;
+    const CODE_RECRUITMENT_SERVICES = 30;
+    const CODE_ADMINISTRATION_OF_IT_INFRASTRUCTURE_CONNECTIONS_TO_DATABASES_SOFTWARE_MAIL_INTERNET = 31;
+    const CODE_SOFTWARE_LICENSE_ERP_SYSTEM = 32;
+    const CODE_PROMOTION_AND_SALE_OF_GOODS_THROUGH_THE_WEBSITE = 33;
+    const CODE_PERSONAL_ADMINISTRATION_LABOR_PROTECTION_TARIFF = 36;
+    const CODE_BASE_BONUS = 37;
+    const CODE_BONUS_SIZE = 38;
+    const CODE_AGENT_SERVICES_TARIFF = 35;
+    const CODE_NUMBER_OF_EMPLOYEES = 34;
+    const CODE_PAYROLL_FUND = 11;
+    const CODE_THRESHOLD_COEFFICIENT = 39;
+    const CODE_DRINKING_WATER = 26;
+    const CODE_COSTS_OF_GOODS = 5;
+
+    const CODE_REVENUE_FROM_SALES = 1001;
+    const CODE_SALE_OF_GOODS = 1002;
+    const CODE_OTHER_SERVICES = 1003;
+    const CODE_DIRECT_SELLING_COSTS = 1004;
+    const CODE_COST_PRICE_OF_GOODS = 1005;
+    const CODE_AGENT_SERVICES_EXPENSES_FOR_PURCHASING_STORING_DELIVERING_GOODS = 1006;
+    const CODE_DEFECT_RESORTING = 1007;
+    const CODE_MARGINAL_INCOME = 1008;
+    const CODE_OPERATIONAL_EXPANSES_COST = 1009;
+    const CODE_PAYMENT = 1010;
+    const CODE_MAINTENANCE_OF_PRIMISES = 1011;
+    const CODE_DELIVERY_COST = 1012;
+    const CODE_MAINTENANCE_AND_SERVICE_OF_FIXED_ASSETS_AND_INTANGIBLE_ASSETS = 1013;
+    const CODE_COMMUNICATION_SERVICES = 1014;
+    const CODE_OTHER_OPERATING_EXPENSES = 1015;
+    const CODE_GROSS_PROFIT = 1016;
+    const CODE_GENERAL_BUSINESS_EXPENSES = 1017;
+    const CODE_ACCOUNTING_AND_FINANCE = 1018;
+    const CODE_LEGAL_SUPPORT = 1019;
+    const CODE_HR_SERVICES = 1020;
+    const CODE_IT_SERVICES = 1021;
+    const CODE_NET_PROFIT = 1022;
+    const CODE_NET_PROFIT_MARGIN_PERCENT = 1023;
+    const CODE_NET_PROFIT_THRESHOLD_RUB = 1024;
+    const CODE_CALCULATION_OF_PREMIUM = 1025;
 
     // 6. Создание массива дополнительных элементов
     static $additionalItems = [
-            80 => ['name' => 'Выручка от реализации'],
-            90 => ['name' => 'Продажа товара'],
-            115 => ['name' => 'Прочие услуги'],
-            135 => ['name' => 'Прямые расходы на продажу'],
-            143 => ['name' => 'Услуги агентов (Расходы на закупку, хранение, доставку товара)'],
-            146 => ['name' => 'Брак, пересорт'],
-            192 => ['name' => 'Маржинальный доход'],
-            194 => ['name' => 'Операционные расходы (Себестоимость)'],
-            196 => ['name' => 'Оплата труда'],
-            205 => ['name' => 'Содержание помещения'],
-            245 => ['name' => 'Расходы по доставке'],
-            275 => ['name' => 'Содержание и обслуживание ОС и НМА'],
-            315 => ['name' => 'Услуги связи'],
-            325 => ['name' => 'Прочие операционные расходы'],
-            353 => ['name' => 'Валовая прибыль'],
-            355 => ['name' => 'Общехозяйственные расходы'],
-            357 => ['name' => 'Бухгалтерия и финансы'],
-            365 => ['name' => 'Юридическое сопровождение'],
-            375 => ['name' => 'HR- услуги'],
-            395 => ['name' => 'IT услуги'],
-            425 => ['name' => 'Чистая прибыль'],
-            427 => ['name' => 'Рентабельность по чистой прибыли, %'],
-            428 => ['name' => 'Минимальный порог Чистой прибыли, руб.'],
-            435 => ['name' => 'Расчет премии']
-        ];
+        80 => ['name' => 'Выручка от реализации',                 'code' => self::CODE_REVENUE_FROM_SALES],
+        90 => ['name' => 'Продажа товара',                        'code' => self::CODE_SALE_OF_GOODS],
+        115 => ['name' => 'Прочие услуги',                        'code' => self::CODE_OTHER_SERVICES],
+        135 => ['name' => 'Прямые расходы на продажу',            'code' => self::CODE_DIRECT_SELLING_COSTS],
+        139 => ['name' => 'Себестоимость товара',                 'code' => self::CODE_COST_PRICE_OF_GOODS],
+        143 => ['name' => 'Услуги агентов (Расходы на закупку, хранение, доставку товара)', 'code' => self::CODE_AGENT_SERVICES_EXPENSES_FOR_PURCHASING_STORING_DELIVERING_GOODS],
+        146 => ['name' => 'Брак, пересорт',                       'code' => self::CODE_DEFECT_RESORTING],
+        192 => ['name' => 'Маржинальный доход',                   'code' => self::CODE_MARGINAL_INCOME],
+        194 => ['name' => 'Операционные расходы (Себестоимость)', 'code' => self::CODE_OPERATIONAL_EXPANSES_COST],
+        196 => ['name' => 'Оплата труда',                         'code' => self::CODE_PAYMENT],
+        205 => ['name' => 'Содержание помещения',                 'code' => self::CODE_MAINTENANCE_OF_PRIMISES],
+        245 => ['name' => 'Расходы по доставке',                  'code' => self::CODE_DELIVERY_COST],
+        275 => ['name' => 'Содержание и обслуживание ОС и НМА',   'code' => self::CODE_MAINTENANCE_AND_SERVICE_OF_FIXED_ASSETS_AND_INTANGIBLE_ASSETS],
+        315 => ['name' => 'Услуги связи',                         'code' => self::CODE_COMMUNICATION_SERVICES],
+        325 => ['name' => 'Прочие операционные расходы',          'code' => self::CODE_OTHER_OPERATING_EXPENSES],
+        353 => ['name' => 'Валовая прибыль',                      'code' => self::CODE_GROSS_PROFIT],
+        355 => ['name' => 'Общехозяйственные расходы',            'code' => self::CODE_GENERAL_BUSINESS_EXPENSES],
+        357 => ['name' => 'Бухгалтерия и финансы',                'code' => self::CODE_ACCOUNTING_AND_FINANCE],
+        365 => ['name' => 'Юридическое сопровождение',            'code' => self::CODE_LEGAL_SUPPORT],
+        375 => ['name' => 'HR- услуги',                           'code' => self::CODE_HR_SERVICES],
+        395 => ['name' => 'IT услуги',                            'code' => self::CODE_IT_SERVICES],
+        425 => ['name' => 'Чистая прибыль',                       'code' => self::CODE_NET_PROFIT],
+        427 => ['name' => 'Рентабельность по чистой прибыли, %',  'code' => self::CODE_NET_PROFIT_MARGIN_PERCENT],
+        428 => ['name' => 'Минимальный порог Чистой прибыли, руб.', 'code' => self::CODE_NET_PROFIT_THRESHOLD_RUB],
+        435 => ['name' => 'Расчет премии',                        'code' => self::CODE_CALCULATION_OF_PREMIUM]
+    ];
 
 // Код из таблицы MotivationCostsItem строки - Фонд оплаты труда персонала
     const MCI_FOT = 11;
@@ -167,10 +232,10 @@ class MotivationService
             $result[$costsItem->order][$groupAlias] = $actualValue;
         }
 
-        // 5. Сортировка результата по ключу (order)
+        //  Сортировка результата по ключу (order)
         ksort($result);
 
-        // 7. Объединение массивов
+        // TODO Добавление суперфункции для вычисления значений передавая алиас
         foreach (self::$additionalItems as $key => $item) {
             if (!isset($result[$key])) {
                 $result[$key] = array_merge($item, [
@@ -1039,4 +1104,107 @@ class MotivationService
 
         return $weeks;
     }
+
+    /**
+     * Вычисление суммы себестоимости товара по магазину в определенный промежуток дат.
+     *
+     * @param string $startDate Дата начала недели (Y-m-d format).
+     * @param string $endDate Дата конца недели  (Y-m-d format).
+     * @param int $storeId ID магазина.
+     * @return float Суммарная себестоимость товаров по магазину в определенный промежуток дат.
+     */
+    public static function getSelfCostSumByStore($startDate, $endDate, $storeId)
+    {
+
+        $storeId = (int)$storeId;
+        $startDate = date('Y-m-d', strtotime($startDate));
+        $endDate = date('Y-m-d', strtotime($endDate));
+
+
+        $sum = (float)SelfCostProduct::find()
+            ->where(['store_id' => $storeId])
+            ->andWhere(['>=', 'date', $startDate])
+            ->andWhere(['<=', 'date', $endDate])
+            ->sum('price');
+
+        return $sum;
+    }
+
+    /**
+     * Сохраняет мотивацию по себестоимости товара для указанного магазина и месяца.
+     *
+     * @param int $year Год в формате YYYY.
+     * @param int $month Месяц в формате MM.
+     * @param int $storeId ID магазина.
+     * @return bool Возвращает true в случае успешного сохранения данных, иначе false.
+     */
+    public static function saveCostMotivation($storeId, $year, $month )
+    {
+        // Получаем идентификатор мотивации
+        $motivation = Motivation::find()
+            ->where([
+                'store_id' => $storeId,
+                'year' => $year,
+                'month' => $month
+            ])
+            ->one();
+
+        if (!$motivation) {
+            Yii::error("Мотивация не найдена для store_id=$storeId, year=$year, month=$month");
+            return false; // мотивация не найдена, завершаем выполнение
+        }
+
+        $motivationId = $motivation->id;
+
+        // Вычисляем начало и конец месяца
+        $monthStart = date("Y-m-d 00:00:00", strtotime("$year-$month-01"));
+        $monthEnd = date("Y-m-t 23:59:59", strtotime("$year-$month-01"));
+
+        // Переменная для отслеживания успешности сохранений
+        $success = true;
+
+        // Проходим по каждой неделе (максимум 5 недель в месяце)
+        foreach (range(1, 5) as $weekIndex) {
+            // Вычисляем начало и конец недели
+            $weekStart = date("Y-m-d 00:00:00", strtotime("+" . (($weekIndex - 1) * 7) . " days", strtotime($monthStart)));
+            $weekEnd = date("Y-m-d 23:59:59", strtotime("+" . ($weekIndex * 7 - 1) . " days", strtotime($monthStart)));
+
+            // Если конец недели выходит за пределы месяца, ограничиваем его концом месяца
+            if ($weekEnd > $monthEnd) {
+                $weekEnd = $monthEnd;
+            }
+
+            Yii::info("Вычисляем себестоимость для недели $weekIndex: с $weekStart по $weekEnd");
+
+            // Рассчитываем сумму себестоимости за эту неделю
+            $costSum = self::getSelfCostSumByStore($weekStart, $weekEnd, $storeId);
+
+            Yii::info("Сумма себестоимости для недели $weekIndex: $costSum");
+
+            // Определяем alias группы для недели (week1, week2 и т.д.)
+            $groupAlias = 'week' . $weekIndex;
+
+            // Сохраняем или обновляем значение мотивации
+            $saveResult = self::saveOrUpdateMotivationValue(
+                $motivationId,
+                $groupAlias,
+                self::CODE_COSTS_OF_GOODS, // константа для себестоимости
+                'float',
+                $costSum
+            );
+
+            if ($saveResult === false) {
+                Yii::error("Ошибка при сохранении значения для недели $weekIndex: $costSum");
+                $success = false;
+            }
+
+            // Прерываем цикл, если достигнут конец месяца
+            if ($weekEnd == $monthEnd) {
+                break;
+            }
+        }
+
+        return $success;
+    }
+
 }