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;
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;
$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, [
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;
+ }
+
}