From: Aleksey Filippov Date: Fri, 15 Mar 2024 09:17:43 +0000 (+0300) Subject: set actual code from erp X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=3c007141e5d2cc049fa83c6a10db2fe6fb30affb;p=yii-erp24%2F.git set actual code from erp --- diff --git a/erp24/actions/cabinet/IndexClusterAction.php b/erp24/actions/cabinet/IndexClusterAction.php index 39b2375..52c8f99 100755 --- a/erp24/actions/cabinet/IndexClusterAction.php +++ b/erp24/actions/cabinet/IndexClusterAction.php @@ -116,9 +116,9 @@ class IndexClusterAction extends Action ->indexBy('id'); - if (3 == date("n",strtotime($dateFrom)) || 3 == date("n",strtotime($dateTo))) { - $queryClusterAdmin->andWhere(['parent_admin_id' => 182]); // для исключения директора по доставке - } +// if (3 == date("n",strtotime($dateFrom)) || 3 == date("n",strtotime($dateTo))) { +// $queryClusterAdmin->andWhere(['parent_admin_id' => 182]); // для исключения директора по доставке +// } if (date("Y-m-d",strtotime($dateFrom)) < '2023-04-01' && date("Y-m-d",strtotime($dateTo)) < '2023-04-30') { $queryClusterAdmin->andWhere(['parent_admin_id' => 182]); // для исключения директора по доставке @@ -226,6 +226,14 @@ class IndexClusterAction extends Action $param = array_merge($param, $paramAdditionsValue); - return $this->controller->render('/cabinet/cluster', $param); + $cabinetPrefix = ''; + + if ($dateFrom >= '2023-10-01') { + $cabinetPrefix = '202310'; + } + + $view = '/cabinet' . $cabinetPrefix . '/cluster'; + + return $this->controller->render($view, $param); } } diff --git a/erp24/actions/cabinet/PersonClusterAction.php b/erp24/actions/cabinet/PersonClusterAction.php index b70e135..1cbfdab 100755 --- a/erp24/actions/cabinet/PersonClusterAction.php +++ b/erp24/actions/cabinet/PersonClusterAction.php @@ -66,10 +66,10 @@ class PersonClusterAction extends Action ->indexBy('id'); - - if (3 == date("n",strtotime($dateFrom)) || 3 == date("n",strtotime($dateTo))) { - $queryClusterAdmin->andWhere(['parent_admin_id' => 182]); // для исключения директора по доставке - } +// +// if (3 == date("n",strtotime($dateFrom)) || 3 == date("n",strtotime($dateTo))) { +// $queryClusterAdmin->andWhere(['parent_admin_id' => 182]); // для исключения директора по доставке +// } $clusterAdmin = $queryClusterAdmin->asArray()->one(); diff --git a/erp24/actions/dashboard/SalesAction.php b/erp24/actions/dashboard/SalesAction.php index 522db8b..64f6e54 100755 --- a/erp24/actions/dashboard/SalesAction.php +++ b/erp24/actions/dashboard/SalesAction.php @@ -125,11 +125,6 @@ class SalesAction extends Action $date2_smen_time=strtotime($date2)+86400; $date2_smen=date("Y-m-d",$date2_smen_time); - $sales_products = []; - if(!empty($check_id)) { - $sales_products = $salesService->getSalesProducts($check_id); - } - $equal_days = ($date1==$date2); $arr_work = [ @@ -238,8 +233,6 @@ class SalesAction extends Action $saleServices = $salesService->getSalesServices($date1, $date2); $saleServicesIds = ArrayHelper::getColumn($saleServices, 'id'); - $checkSellerDiscount = SalesProductsService::getCheckSellerDiscount($saleServicesIds); - $params = [ 'shift' => $shift, 'date1' => $date1, @@ -252,7 +245,6 @@ class SalesAction extends Action 'number' => $number, 'city_stores' => $city_stores, 'store_traffik' => $store_traffik, - 'sales_products' => $sales_products, 'equal_days' => $equal_days, 'arr_work' => $arr_work, 'date_timetable' => $date_timetable, @@ -272,7 +264,6 @@ class SalesAction extends Action 'productsArrayServices' => $productsArrayServices, 'servises' => $servises, 'saleServices' => $saleServices, - 'checkSellerDiscount' => $checkSellerDiscount, 'daysSearchForm' => $daysSearchForm, ]; diff --git a/erp24/actions/grade/AdminUpdateAction.php b/erp24/actions/grade/AdminUpdateAction.php index b74fab6..6fab236 100644 --- a/erp24/actions/grade/AdminUpdateAction.php +++ b/erp24/actions/grade/AdminUpdateAction.php @@ -24,11 +24,6 @@ class AdminUpdateAction extends Action if (Yii::$app->user->can("updateAdminSettings", ['id' => $model->id])) { if (Yii::$app->request->isPost) { $attributes = Yii::$app->request->post()['Admin']; - $mobile = $attributes['mobile']; - if (mb_strlen($mobile) > 2 && $mobile[0] == 8 && $mobile[1] = 9) { - $mobile[0] = 7; - $attributes['mobile'] = $mobile; - } foreach (['parent_admin_id', 'org_id'] as $fieldName) { if (empty($attributes[$fieldName])) { $attributes[$fieldName] = 0; diff --git a/erp24/actions/infoTable/CabinetAction.php b/erp24/actions/infoTable/CabinetAction.php new file mode 100644 index 0000000..e8a1753 --- /dev/null +++ b/erp24/actions/infoTable/CabinetAction.php @@ -0,0 +1,13 @@ +controller->render('/info_table/cabinet.php', []); + } + +} \ No newline at end of file diff --git a/erp24/actions/payroll/IndexAction.php b/erp24/actions/payroll/IndexAction.php index f2f0bfb..659f878 100755 --- a/erp24/actions/payroll/IndexAction.php +++ b/erp24/actions/payroll/IndexAction.php @@ -125,6 +125,7 @@ class IndexAction extends Action 'allTotalPayroll', // ЗП 'personPrepaidExpense', 'personCounting', + 'partTimeWagesSumAdminAllStore', 'personRetention', 'toPayoff', ]; diff --git a/erp24/actions/payroll/ListAdminsAction.php b/erp24/actions/payroll/ListAdminsAction.php index 556145e..52ddee7 100755 --- a/erp24/actions/payroll/ListAdminsAction.php +++ b/erp24/actions/payroll/ListAdminsAction.php @@ -11,6 +11,7 @@ use yii_app\forms\timetable\TabelSearchForm; use yii_app\helpers\HtmlHelper; use yii_app\records\AdminGroup; use yii_app\records\AdminPayroll; +use yii_app\records\AdminPayrollHistory; use yii_app\records\AdminPayrollValues; use yii_app\records\AdminPayrollValuesDict; use yii_app\records\CityStore; @@ -134,7 +135,7 @@ class ListAdminsAction extends Action $aliasSumFields = [ 'oklad', // Оклад - 'deltaWagesAdmin', +// 'deltaWagesAdmin', 'worksDayByTableFromSelectDay', // Число смен в графике 'adminSumGameCountShiftTotal', // Число смен геймификации 'personVacationDay', @@ -148,9 +149,11 @@ class ListAdminsAction extends Action 'bonusMakeMatrix', 'teamBonusValue', 'userQualityPremium', - 'adminSumGameBonusConversionToMoney', +// 'adminSumGameBonusConversionToMoney', 'personBonuses', // Персональная Премия 'allTotalPayroll', // ЗП + 'adminPayrollCurrentLk', // Значение из личного кабинета + 'adminPayrollDelta', // Дельта значения из личного кабинета и текущего в ведомости 'personPrepaidExpense', 'personCounting', 'personRetention', @@ -165,10 +168,31 @@ class ListAdminsAction extends Action ->asArray() ->all(); + $lastPacketNum = AdminPayrollHistory::find() + ->select(['packet_num']) + ->andWhere(['year' => $yearSelect]) + ->andWhere(['month' => $monthWithZeroSelect]) + ->orderBy(['packet_num' => SORT_DESC]) + ->distinct(true) + ->scalar(); + + $lastPacketDate = date('d.m.Y H:i:s', $lastPacketNum); + + $adminPayrollCurrentLk = AdminPayrollHistory::find() + ->select(['admin_id', 'admin_payroll_history.value_number AS value']) + ->andWhere(['year' => $yearSelect]) + ->andWhere(['group_number' => AdminPayrollHistory::GROUP_VALUE_ALL_TOTAL_PAYROLL]) + ->andWhere(['month' => $monthWithZeroSelect]) + ->andWhere(['packet_num' => $lastPacketNum]) + ->indexBy('admin_id') + ->asArray() + ->all(); + $sumColumnByAlias = []; foreach ($adminPayroll as $key => $rowAdmins) { $payrollIds = $rowAdmins['id']; + $adminIdRow = $rowAdmins['admin_id']; foreach ($aliasSumFields as $keyAlias => $alias) { if (array_key_exists($alias, $adminPayrollValuesDict)) { $keyRow = $alias.'.id'; @@ -184,6 +208,43 @@ class ListAdminsAction extends Action if (!empty($sumRow)) { $sumColumnByAlias[$keyAlias] += $sumRow; } + } else { + if ($dateFrom >= '2023-12-01') { + $sumRow = 0; + if ('adminPayrollCurrentLk' == $alias) { + $payrollStoreColumn[$alias] = 'Значение ЗП в ЛК
( на ' . $lastPacketDate . ')'; + + if (array_key_exists($adminIdRow, $adminPayrollCurrentLk)) { + $keySumRow = $adminIdRow . '.value'; + $sumRow = (float) ArrayHelper::getValue($adminPayrollCurrentLk, $keySumRow); + } + $adminPayroll[$key]['column'][$alias] = $sumRow; + + } + if ('adminPayrollDelta' == $alias) { + $payrollStoreColumn[$alias] = 'Разница ЗП между ведомостью и ЛК'; + + $sumHistoryRow = 0; + if (!empty($adminPayroll[$key]['column']['adminPayrollCurrentLk'])) { + $sumHistoryRow = $adminPayroll[$key]['column']['adminPayrollCurrentLk']; + } + $sumPayrollRow = 0; + $keyAliasNameRow = 'allTotalPayroll.name'; + $aliasNameRow = ArrayHelper::getValue($adminPayrollValuesDict, $keyAliasNameRow); + if (!empty($adminPayroll[$key]['column'][$aliasNameRow])) { + $sumPayrollRow = $adminPayroll[$key]['column'][$aliasNameRow]; + } + $sumRow = $sumPayrollRow - $sumHistoryRow; + $adminPayroll[$key]['column']['adminPayrollDelta'] = $sumRow; + //allTotalPayroll + } + if (!array_key_exists($keyAlias, $sumColumnByAlias)) { + $sumColumnByAlias[$keyAlias] = 0; + } + if (!empty($sumRow)) { + $sumColumnByAlias[$keyAlias] += $sumRow; + } + } } } } @@ -212,6 +273,7 @@ class ListAdminsAction extends Action 'yearMonthSearchForm' => $yearMonthSearchForm, 'sumColumnByAlias' => $sumColumnByAlias, 'monthNameSelect' => $monthNameSelect, + 'lastPacketDate' => $lastPacketDate, ]); } } \ No newline at end of file diff --git a/erp24/actions/payroll/MakeAction.php b/erp24/actions/payroll/MakeAction.php index 7da9d24..a0b494f 100755 --- a/erp24/actions/payroll/MakeAction.php +++ b/erp24/actions/payroll/MakeAction.php @@ -194,6 +194,9 @@ class MakeAction extends Action 'saveValuesOk' => 'saveValuesOk', 'Командный бонус' => 'teamBonusValue', 'Премия за качество' => 'userQualityPremium', + 'Командный бонус детально' => 'teamBonusDetail', + 'Оклады за подработку' => 'partTimeWagesSumAdminAllStore', + 'Число смен подработок' => 'partTimeWagesCountAdminAllStore', ]; $adminPayrollValuesDict = AdminPayrollValuesDict::find() @@ -301,15 +304,7 @@ class MakeAction extends Action ]); } - $groupIds = [ - 30, - 35, - 40, - 45, // подработчики - 50, // Администраторы - 72, // - -1 - ]; + $groupIds = Admin::ADMIN_PAYROLL_MAKE_GROUP_IDS; // пропускать недавно обновлённые, за последние 20 минут $dateCheckReset = date("Y-m-d H:i:s", time() - (60 * 60)); diff --git a/erp24/actions/payroll/StoreAction.php b/erp24/actions/payroll/StoreAction.php index 463e02f..75f0714 100755 --- a/erp24/actions/payroll/StoreAction.php +++ b/erp24/actions/payroll/StoreAction.php @@ -150,6 +150,7 @@ class StoreAction extends Action $aliasSumFields = [ 'oklad', // Оклад 'worksDayByTableFromSelectDay', // Число смен в графике + 'partTimeWagesCountAdminAllStore', 'personVacationDay', 'personVacationPay', 'userSalaryServicesPremium', @@ -165,6 +166,7 @@ class StoreAction extends Action 'allTotalPayroll', // ЗП 'personPrepaidExpense', 'personCounting', + 'partTimeWagesSumAdminAllStore', 'personRetention', 'toPayoff', ]; diff --git a/erp24/actions/timetable/EditPlanAction.php b/erp24/actions/timetable/EditPlanAction.php index ccc4d81..5db84ca 100755 --- a/erp24/actions/timetable/EditPlanAction.php +++ b/erp24/actions/timetable/EditPlanAction.php @@ -3,9 +3,11 @@ declare(strict_types = 1); namespace yii_app\actions\timetable; +use Yii; use yii\base\Action; use yii\web\Response; use yii_app\records\Admin; +use yii_app\records\Timetable; use yii_app\records\TimetableFact; use yii_app\records\TimetablePlan; @@ -36,7 +38,6 @@ class EditPlanAction extends Action 'store_id' => $this->controller->request->get('storeId'), ]; $slot = TimetablePlan::find()->andWhere($row)->one(); - $fact = TimetableFact::find()->andWhere(['plan_id' => $slot->id])->one(); if (!$slot) { $slot = new TimetablePlan($row); /** @var Admin $admin */ @@ -57,6 +58,7 @@ class EditPlanAction extends Action $slot->time_start = $slot->shift ? $slot->shift->start_time : null; $slot->time_end = $slot->shift ? $slot->shift->end_time : null; } + $fact = TimetableFact::find()->andWhere(['plan_id' => $slot->id])->one(); return $this->controller->renderPartial('/timetable/tabel_edit.php', [ 'slot' => $slot, 'fact' => $fact, @@ -110,7 +112,14 @@ class EditPlanAction extends Action $slot->admin_group_id = $slot->validate(['admin_id']) ? $slot->admin->group_id : null; if ($slot->validate(null, false)) { - $slot->save(false); + $session = Yii::$app->session; + $groupId = (int) $session->get('group_id'); + + $numDay = Timetable::getCountDaysAllowEditShift($groupId); + + if (Timetable::getAllowEditShift($slot->date, $numDay)) { + $slot->save(false); + } } return $this->makeResponse($slot); } diff --git a/erp24/api2/controllers/BonusController.php b/erp24/api2/controllers/BonusController.php index b6e3fa1..9e37cbc 100644 --- a/erp24/api2/controllers/BonusController.php +++ b/erp24/api2/controllers/BonusController.php @@ -9,6 +9,7 @@ use yii_app\helpers\ClientHelper; use yii_app\records\Contest001; use yii_app\records\ExportImportTable; use yii_app\records\MessagerUser; +use yii_app\records\NotifiableUser; use yii_app\records\Products1c; use yii_app\records\Sales; use yii_app\records\Timetable; @@ -33,6 +34,8 @@ class BonusController extends BaseController private static $SECOND_SALE_PROCENT = 0.15; private static $MAX_PROCENT = 0.2; private static $CREDIT_PROCENT = 0.1; + private static $CREDIT_HIGH_PROCENT = 0.3; + private static $CREDIT_HIGH_PROCENT_PART20 = 0.2; public function actionGetBonuses() { @@ -96,10 +99,16 @@ class BonusController extends BaseController $percent = ($result['phone'] == "79049031399") ? 0.9 : $max_procent; - $will_be_credited_bonuses = self::$CREDIT_PROCENT * $baza; - if ($result['phone'] == "79049031399") { - $will_be_credited_bonuses = $percent * $check_amount; + $userFound = Users::find()->where(['phone' => $result['phone']])->one(); + /** @var $userFound Users */ + $salesCount = 0; + if ($userFound && $userFound->telegram_created_at) { + $salesCount = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE]) + ->andWhere(['>=', 'date', $userFound->telegram_created_at])->count()); } + $credit_procent = $userFound && $userFound->source > 0 && $salesCount == 0 ? self::$CREDIT_HIGH_PROCENT : self::$CREDIT_PROCENT; + $will_be_credited_bonuses = $credit_procent * $baza; + $will_be_credited_bonuses = round($will_be_credited_bonuses); $mess["will_be_credited_bonuses"] = $will_be_credited_bonuses; @@ -599,7 +608,13 @@ class BonusController extends BaseController // получаем внутренний ID продаца - сотрудника из таблицы admin $store_id = ClientHelper::getExportId($store_id_1c, "city_store", 1); - if ($write_off_bonuses) { + $writeOffAlready = false; + if (!empty($lid_id)) { + $writeOffAlready = UsersBonus::find()->where(['lid_id' => $lid_id, 'phone' => $phone, 'tip_sale' => 'sale', 'tip' => 'minus'])->one() != null; + } + + $user_balans_new = $user_balans; + if ($write_off_bonuses && !$writeOffAlready) { $user_balans_new = $user_balans - $write_off_bonuses; $name_b = "Спиcание бонусов по чеку $check_name"; $usersBonus = new UsersBonus; @@ -642,8 +657,17 @@ class BonusController extends BaseController FILE_APPEND | LOCK_EX); } //начисляем кэшбек клиенту 10% от покупки - с базы за вычитом бонусов которые он списывает - $back = round($baza_back * self::$CREDIT_PROCENT); - $nm = "Возврат с покупки 10% $check_name сумма чека $check_amount"; + $userFound = Users::find()->where(['phone' => $result['phone']])->one(); + /** @var $userFound Users */ + $salesCount = 0; + if ($userFound && $userFound->telegram_created_at) { + $salesCount = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE]) + ->andWhere(['>=', 'date', $userFound->telegram_created_at])->count()); + } + $credit_procent_index = $userFound && $userFound->source > 0 && $salesCount == 0 ? 1 : 0; + + $back1 = $back = round($baza_back * self::$CREDIT_PROCENT); + $nm = "Возврат с покупки " . (100 * self::$CREDIT_PROCENT) . "% $check_name сумма чека $check_amount"; $userBonus2 = UsersBonus::find()->where(['phone' => $phone])->andWhere(['check_id' => $check_id])->andWhere(['site_id' => $site_id]) ->andWhere(['store_id' => $store_id])->andWhere(['tip' => 'plus'])->andWhere(['bonus' => $back])->andWhere(['name' => $nm])->one(); if (!$userBonus2) { @@ -667,10 +691,10 @@ class BonusController extends BaseController $userBonus2->price = $summa_chek; $userBonus2->store_id_1c = $store_id_1c; $userBonus2->seller_id_1c = $seller_id; - $userBonus2->user_id = $user_id; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении - $userBonus2->lid_id = $lid_id; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении - $userBonus2->price_skidka = 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении - $userBonus2->date_dell = $userBonus2->date_end; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении + $userBonus2->user_id = $user_id; + $userBonus2->lid_id = $lid_id; + $userBonus2->price_skidka = 0; + $userBonus2->date_dell = $userBonus2->date_end; $userBonus2->save(); if ($userBonus2->getErrors()) { @@ -681,6 +705,61 @@ class BonusController extends BaseController file_put_contents(self::$USERS_AUTH_CALL_LOG2, "" . date("d.m.Y H:i:s", time()) . " PLUS bonus=" . $back . "\n", FILE_APPEND | LOCK_EX); + if ($credit_procent_index) { + $back = round($baza_back * self::$CREDIT_HIGH_PROCENT_PART20); + $nm = "Возврат с покупки " . (100 * self::$CREDIT_HIGH_PROCENT_PART20) . "% $check_name сумма чека $check_amount"; + + $user_balans_new += $back; + + $userBonus2 = new UsersBonus; + $userBonus2->tip = 'plus'; + $userBonus2->tip_sale = 'sale'; + $userBonus2->date = date('Y-m-d H:i:s'); + $userBonus2->date_start = date('Y-m-d H:i:s', strtotime('+1 day', time())); + $userBonus2->date_end = date('Y-m-d H:i:s', strtotime('+3 month', time())); + $userBonus2->phone = $phone; + $userBonus2->name = $nm; + $userBonus2->check_id = $check_id; + $userBonus2->store_id = $store_id; + $userBonus2->bonus = $back; + $userBonus2->ip = $ip; + $userBonus2->site_id = $site_id; + $userBonus2->referal_id = 0; + $userBonus2->admin_id = $admin_id; + $userBonus2->price = $summa_chek; + $userBonus2->store_id_1c = $store_id_1c; + $userBonus2->seller_id_1c = $seller_id; + $userBonus2->user_id = $user_id; + $userBonus2->lid_id = $lid_id; + $userBonus2->price_skidka = 0; + $userBonus2->date_dell = $userBonus2->date_end; + $userBonus2->save(); + if ($userBonus2->getErrors()) { + + LogService::apiErrorLog(json_encode(["error_id" => 5.2, "error" => $userBonus2->getErrors()], JSON_UNESCAPED_UNICODE)); + + return $this->asJson(["error_id" => 5.2, "error" => $userBonus2->getErrors()]); + } + if ($userFound->telegram_created_at == null) { + $userFound->telegram_created_at = date("Y-m-d H:i:s"); + $userFound->save(); + if ($userFound->getErrors()) { + + LogService::apiErrorLog(json_encode(["error_id" => 5.3, "error" => $userFound->getErrors()], JSON_UNESCAPED_UNICODE)); + + return $this->asJson(["error_id" => 5.3, "error" => $userFound->getErrors()]); + } + } + + $notifiableUser = new NotifiableUser; + $notifiableUser->phone = $phone; + $notifiableUser->type = "first_given_bonus"; + $notifiableUser->data = "" . ($back1 + $back); + $notifiableUser->save(); + if ($notifiableUser->getErrors()) { + return $this->asJson(["error_id" => 5.4, "error" => $notifiableUser->getErrors()]); + } + } } // /////// Добавляем бонусов рефералу @@ -1167,7 +1246,7 @@ class BonusController extends BaseController } // - if (!in_array($result['tip_sale'], ['podarok', 'senat', 'nino802'])) { + if (!in_array($result['tip_sale'], ['podarok', 'senat', 'nino802', 'sale', '14feb', '23feb', '8mar'])) { return $this->asJson(["error_id" => 1.1, "error" => "tip_sale не разрешён (podarok, senat, nino802)"]); } diff --git a/erp24/api3/config/bootstrap.php b/erp24/api3/config/bootstrap.php index 13643ff..238f3a0 100644 --- a/erp24/api3/config/bootstrap.php +++ b/erp24/api3/config/bootstrap.php @@ -3,4 +3,4 @@ $yiiApp = dirname(__DIR__, 3); Yii::setAlias('@yii_app', $yiiApp); -Yii::setAlias('@upload-checkin', dirname(__DIR__, 3) . "/uploads/checkin"); \ No newline at end of file +Yii::setAlias('@upload-checkin', dirname(__DIR__, 3) . "/data/admin"); \ No newline at end of file diff --git a/erp24/api3/core/behaviors/EventBehavior.php b/erp24/api3/core/behaviors/EventBehavior.php index e191a52..c0eb646 100644 --- a/erp24/api3/core/behaviors/EventBehavior.php +++ b/erp24/api3/core/behaviors/EventBehavior.php @@ -59,10 +59,10 @@ class EventBehavior extends Behavior $error['code'] = $response->data['code']; } } elseif($exception instanceof HttpException) { - $error['type'] = $response->data['name'] ? strtolower(str_replace($response->data['name'], " ", "_")) : "invalid_request"; + $error['type'] = $response->data['name'] ? strtolower(str_replace($response->data['name'], " ", "_")) : "invalid_request_type_1"; $error['message'] = $exception->getMessage(); } elseif($exception instanceof InvalidArgumentException) { - $error['type'] = "invalid_request"; + $error['type'] = "invalid_request_type_2"; $error['message'] = $exception->getMessage(); } diff --git a/erp24/api3/core/services/BonusService.php b/erp24/api3/core/services/BonusService.php index 461bea4..e37e5fa 100644 --- a/erp24/api3/core/services/BonusService.php +++ b/erp24/api3/core/services/BonusService.php @@ -672,4 +672,49 @@ class BonusService return true; } + + /** + * @throws \yii\base\Exception + * @throws Exception + */ + public function bonusWriteOff($data) { + $phone = $data->phone; + $price = $data->price; + $bonus = $data->bonus; + $lid_id = $data->lid_id; + + $stop = UsersStopList::find()->select(['phone'])->where(['phone' => $data->phone])->one(); + if ($stop) { + throw new InvalidArgumentException("Номер телефона числится в стоп листе"); + } + + $found = UsersBonus::find()->where(['phone' => $phone])->andWhere(['>=', 'date_start', date('Y-m-d H:i:s', time() - 14 * 86400)]) + ->andWhere(['tip_sale' => 'sale'])->andWhere(['tip' => 'minus'])->andWhere(['lid_id' => $lid_id])->andWhere(['bonus' => $bonus])->one(); + + if ($found) { + throw new InvalidArgumentException("Бонусы уже списаны"); + } + + $userBonus = new UsersBonus; + $userBonus->phone = $phone; + $userBonus->name = "Списание $bonus бонусов с заказа номер $lid_id на общую сумму $price"; + $userBonus->date = date('Y-m-d H:i:s'); + $userBonus->site_id = 1; + $userBonus->setka_id = 1; + $userBonus->tip = 'minus'; + $userBonus->tip_sale = 'sale'; + $userBonus->bonus = $bonus; + $userBonus->price = $price; + $userBonus->lid_id = $lid_id; + $userBonus->date_start = $data->date_start ?? $userBonus->date; + $userBonus->date_end = $data->date_end ?? date("Y-m-d H:i:s", strtotime("+" . self::$YEAR_PERIOD . ' days', strtotime($userBonus->date))); + $userBonus->save(); + + if ($userBonus->getErrors()) { + LogService::apiErrorLog(json_encode(["error_id" => 2, "error" => $userBonus->getErrors()], JSON_UNESCAPED_UNICODE)); + throw new InvalidArgumentException(array_values($userBonus->firstErrors)[0] ?? ""); + } + + return true; + } } \ No newline at end of file diff --git a/erp24/api3/core/services/ClaimService.php b/erp24/api3/core/services/ClaimService.php index 01bcab5..4727721 100644 --- a/erp24/api3/core/services/ClaimService.php +++ b/erp24/api3/core/services/ClaimService.php @@ -20,6 +20,10 @@ class ClaimService extends Model { public function create(Worker $row) { + $found = Admin::find()->where(['mobile' => $row->phone])->one() != null; + if ($found) { + throw new InvalidArgumentException("Пользователь с таким номером телефона уже существует, для создания смены перейдите во вкладку «Календарь смен» —> «Создать смену»"); + } $model = new EmployeeOnShift($row); $model->guid = DataHelper::createGuidMy("06"); $model->created_at = date(DATE_ATOM); @@ -83,7 +87,7 @@ class ClaimService extends Model $exportImportTable->export_val = $model->guid; $exportImportTable->save(); - $timeslot = Timetable::TIMESLOT_FREELANCE; + $timeslot = Timetable::TIMESLOT_WORK; } else { $admin = $oldAdmin; // Чтобы при создании подработчиков в 1с по guid заявки находился admin, @@ -112,6 +116,7 @@ class ClaimService extends Model $timetable->time_end = $model->shift_type == 1 ? '20:00:00' : '08:00:00'; $timetable->work_time = 12; // $timetable->price_hour = $model->price; + $timetable->salary_shift = $model->salary_shift; $timetable->slot_type_id = $timeslot; $timetable->date_add = date('Y-m-d H:i:s'); $timetable->status = Timetable::STATUS_PENDING; diff --git a/erp24/api3/core/services/IncomeService.php b/erp24/api3/core/services/IncomeService.php index 9a87911..ba233f2 100644 --- a/erp24/api3/core/services/IncomeService.php +++ b/erp24/api3/core/services/IncomeService.php @@ -35,10 +35,14 @@ class IncomeService $baseIncome = []; foreach ($plans as $plan) { /* @var $plan Timetable */ + if (!isset($workHoursPerPlanId[$plan->id])) { + continue; + } // получаем отработку со временем для каждой запланированной смены $baseIncome [] = [ 'date' => $plan->date, 'shift_id' => $plan->shift_id, + 'salary_shift' => $plan->salary_shift, 'price' => $plan->shift_id == 1 ? 125 : 145, 'work_hours' => $workHoursPerPlanId[$plan->id] ?? 0, // если план есть, а факта нет, то 0 чаов отработано 'in_shift' => count($plan->checkIns) == 1, diff --git a/erp24/api3/core/services/NotifiableService.php b/erp24/api3/core/services/NotifiableService.php new file mode 100644 index 0000000..b865fdf --- /dev/null +++ b/erp24/api3/core/services/NotifiableService.php @@ -0,0 +1,69 @@ +where(['between', 'date_end', + date("Y-m-d 00:00:00", strtotime($timePeriod, time())), + date("Y-m-d 23:59:59", strtotime($timePeriod, time()))]) + ->andWhere(['tip' => 'plus'])->all(); + foreach ($userBonus as $bonus) { + /** @var $bonus UsersBonus */ + $percent = $bonus->price > $bonus->bonus ? floor($bonus->bonus / $bonus->price * 100) : 0; + $is_cashback = $percent > 19; + $buffer[$bonus->phone] =[ + "date" => date("c", strtotime($bonus->date_end)), + "amount" => $bonus->bonus, + "is_cashback" => $is_cashback + ]; + } + } + + $userBonuses = UsersBonus::find()->select(['phone', 'sum(if(tip=\'plus\', bonus, -bonus)) as sum']) + ->where(['in', 'phone', array_keys($buffer)]) + ->andWhere(['<', 'date_start', new Expression('NOW()')]) + ->andWhere(['>', 'date_end', new Expression('NOW()')]) + ->groupBy(['phone'])->all(); + $buffer2 = ArrayHelper::map($userBonuses, 'phone', 'sum'); + + $phones = []; + foreach ($buffer as $phone => $data) { + $data['amount'] = min($data['amount'], $buffer2[$phone]); + if ($data['amount'] < 1) { + continue; + } + $phones [] = ArrayHelper::merge( + ["phone" => "" . $phone, "balance" => $buffer2[$phone]], + $data + ); + } + + return $phones; + } + + /** + * @throws \yii\base\Exception + * @throws Exception + */ + public function getGetFirstSaleUsers() { + // Приготовиться к копированию + NotifiableUser::updateAll(['status' => 1], ['status' => 0]); + $notifiableUsers = NotifiableUser::find()->where(['status' => 1])->asArray()->all(); + NotifiableUser::deleteAll(['status' => 1]); + return $notifiableUsers; + } +} \ No newline at end of file diff --git a/erp24/api3/core/services/ReportService.php b/erp24/api3/core/services/ReportService.php new file mode 100644 index 0000000..70a6364 --- /dev/null +++ b/erp24/api3/core/services/ReportService.php @@ -0,0 +1,359 @@ +date_start; + $reports = []; + while ($currentDate <= $data->date_end) { + $report = [ + "date" => $currentDate, + "shift_type" => $data->shift_type, + ]; + + $shift_id = $data->shift_type == 0 ? [1, 2, 5, 8] : ($data->shift_type == 1 ? [1, 5, 8] : [2]); + + $timetablesMonth = Timetable::find()->alias('t')->select(['admin_id', 'a.name as adminName', 't.store_id', 't.shift_id']) + ->innerJoin('admin a', 'admin_id = a.id') + ->where(['t.store_id' => $data->stores]) + ->andWhere(['>=', 'date', date("Y-m-01", strtotime($currentDate))]) + ->andWhere(['<=', 'date', $currentDate]) + ->andWhere(['shift_id' => $shift_id, 'tabel' => 0, 'slot_type_id' => Timetable::TIMESLOT_WORK]) + ->asArray()->all(); + + $timetables = Timetable::find()->alias('t')->select(['admin_id', 'a.name as adminName', 't.store_id', 't.shift_id']) + ->innerJoin('admin a', 'admin_id = a.id') + ->where(['t.store_id' => $data->stores]) + ->andWhere(['date' => $currentDate, 'tabel' => 0]) + ->andWhere(['shift_id' => $shift_id, 'slot_type_id' => Timetable::TIMESLOT_WORK]) + ->asArray()->all(); + + $adminIdsMonth = ArrayHelper::getColumn($timetablesMonth, 'admin_id'); + $adminIds = ArrayHelper::getColumn($timetables, 'admin_id'); + + $adminPayrollDaysMonth = AdminPayrollDays::find()->select(["FLOOR(SUM(day_payroll)) as total", "store_id"]) + ->where(['>=', 'date', date("Y-m-01", strtotime($currentDate))]) + ->andWhere(['<=', 'date', $currentDate]) + ->andWhere(['admin_id' => $adminIdsMonth]) + ->groupBy(['store_id']) + ->indexBy('store_id') + ->asArray()->all(); + + $adminPayrollDays = AdminPayrollDays::find()->select(["FLOOR(SUM(day_payroll)) as total", "store_id"]) + ->where(['date' => $currentDate, 'admin_id' => $adminIds]) + ->groupBy(['store_id']) + ->indexBy('store_id') + ->asArray()->all(); + + $date_start = $data->shift_type == 2 ? + date("Y-m-d 20:00:00", strtotime($currentDate)) : + date("Y-m-d 08:00:00", strtotime($currentDate)); + $date_end = $data->shift_type == 1 ? + date("Y-m-d 20:00:00", strtotime($currentDate)) : + date("Y-m-d 08:00:00", strtotime("+1 day", strtotime($currentDate))); + + $storeVisitorsQuery = StoreVisitors::find() + ->select([ + 'counter' => new \yii\db\Expression("SUM(counter)"), + 'store_id', + ]); + + if ($data->shift_type == 1) { + $storeVisitorsQuery->andWhere(['>=', 'date_hour', 8])->andWhere(['<=', 'date_hour', 20]) + ->andWhere(['date' => date("Y-m-d", strtotime($currentDate))]); + } + if ($data->shift_type == 2) { + $storeVisitorsQuery->andWhere([ + 'or', + [ + 'and', + ['>=', 'date_hour', 20], + ['<=', 'date_hour', 23], + ['date' => date("Y-m-d", strtotime($currentDate))] + ], + [ + 'and', + ['>=', 'date_hour', 0], + ['<=', 'date_hour', 7], + ['date' => date("Y-m-d", strtotime("+1 day", strtotime($currentDate)))] + ], + ]); + } + if ($data->shift_type == 0) { + $storeVisitorsQuery->andWhere([ + 'or', + [ + 'and', + ['>=', 'date_hour', 8], + ['<=', 'date_hour', 23], + ['date' => date("Y-m-d", strtotime($currentDate))] + ], + [ + 'and', + ['>=', 'date_hour', 0], + ['<=', 'date_hour', 7], + ['date' => date("Y-m-d", strtotime("+1 day", strtotime($currentDate)))] + ], + ]); + } + + $storeVisitors = $storeVisitorsQuery->groupBy(['store_id'])->asArray()->all(); + $storeVisitorsByStore = ArrayHelper::map($storeVisitors, 'store_id', 'counter'); + + $salesPhones = Sales::find()->alias('s')->select(["DISTINCT(s.phone)"]) + ->where(['between', 's.date', $date_start, $date_end]) + ->andWhere(['IS NOT', 's.phone', new Expression('NULL')]) + ->andWhere(['s.store_id' => $data->stores]) + ->asArray()->all(); + + $sales = Sales::find()->alias('s')->select(["COUNT(*) as cnt", + "sum(IF(operation='Продажа',s.summ,IF(operation='Возврат',-s.summ,0))) as total", + "sum(IF(IfNull(s.phone,-1)=-1,0,1)) as bonusUserCount", + "sum(IF(IfNull(s.phone,-1)!=-1 AND (IfNull(u.sale_cnt, -1) = -1 OR u.sale_cnt < 2), 1, 0)) as newBonusUserCount", + "sum(IF(IfNull(s.phone,-1)!=-1 AND u.sale_cnt > 1, 1, 0)) as repeatBonusUserCount", + "s.store_id", + "s.admin_id"]) + ->leftJoin('users u', 'u.phone = s.phone AND u.phone IN (\'' + . implode('\',\'', ArrayHelper::getColumn($salesPhones, 'phone')) .'\')') + ->where(['between', 's.date', $date_start, $date_end]) + ->andWhere(['s.store_id' => $data->stores]) + ->groupBy(['s.store_id', 's.admin_id'])->asArray()->all(); + + $salesMapArr = []; + foreach ($sales as $sale) { + $salesMapArr[$sale['store_id']][] = $sale; + } + + $writeOffsMonth = WriteOffs::find()->select(['sum(summ) as total', 'store_id']) + ->where(['between', 'date', date("Y-m-01", strtotime($currentDate)), $date_end]) + ->andWhere(['type' => WriteOffsErp::WRITE_OFFS_TYPE_BRAK]) + ->groupBy(['store_id']) + ->indexBy(['store_id']) + ->asArray()->all(); + + $writeOffs = WriteOffs::find()->select(['sum(summ) as total', 'store_id']) + ->where(['between', 'date', $date_start, $date_end]) + ->andWhere(['type' => WriteOffsErp::WRITE_OFFS_TYPE_BRAK]) + ->groupBy(['store_id']) + ->indexBy(['store_id']) + ->asArray()->all(); + + $eitMonth = ExportImportTable::find()->where(['export_val' => array_keys($writeOffsMonth)]) + ->select(['entity_id', 'export_val']) + ->where(['export_id' => 1, 'entity' => 'city_store']) + ->indexBy(['export_val']) + ->asArray()->all(); + + $totalWriteOffsByStoreId = []; + foreach ($writeOffs as $guid => $value) { + $totalWriteOffsByStoreId[$eitMonth[$guid]['entity_id']] = $value['total']; + } + + $totalWriteOffsByStoreIdMonth = []; + foreach ($writeOffsMonth as $guid => $value) { + $totalWriteOffsByStoreIdMonth[$eitMonth[$guid]['entity_id']] = $value['total']; + } + + $specificSales = []; + foreach (['matrix', 'wrap', 'services', 'potted'] as $productTip) { + $productsClass = ProductsClass::find()->select(['category_id', 'tip']) + ->where(['tip' => $productTip]) + ->indexBy('category_id') + ->asArray()->all(); + + $products1c = Products1c::find()->select(['id', 'parent_id', 'name']) + ->where(['parent_id' => array_keys($productsClass), 'tip' => 'products']) + ->indexBy(['id']) + ->asArray()->all(); + + $salesMatrix = Sales::find()->alias('s')->select([ + "sum(IF(operation='Продажа',p.summ,IF(operation='Возврат',-p.summ,0))) as total", + 's.store_id', 's.admin_id']) + ->leftJoin('sales_products p', 'p.check_id = s.id') + ->where(['between', 's.date', $date_start, $date_end]) + ->andWhere(['operation' => Sales::OPERATION_SALE]) + ->andWhere(['p.product_id' => array_keys($products1c)]) + ->groupBy(['s.store_id', 's.admin_id']) + ->asArray()->all(); + + $specificSales[$productTip] = $salesMatrix; + } + + $adminNames = []; + foreach ($timetables as $timetable) { + $adminNames[$timetable['store_id']][] = [ + 'id' => $timetable['admin_id'], + 'name' => $timetable['adminName'], + 'shift_id' => $timetable['shift_id'], + ]; + } + + $storeVisitorsQuantityTotal = 0; + $storeSaleQuantityTotal = 0; + $storeSaleTotalTotal = 0; + $storeSaleBonusCountTotal = 0; + $storeSaleNewBonusCountTotal = 0; + $storeSaleRepeatBonusCountTotal = 0; + $totalWriteOffsPerDateTotal = 0; + $totalWriteOffsPerMonthTotal = 0; + $totalPayrollDaysTotal = 0; + $totalPayrollMonthTotal = 0; + $totalMatrixPerDayTotal = 0; + $totalWrapPerDayTotal = 0; + $totalServicePerDayTotal = 0; + $totalPottedPerDayTotal = 0; + + $stores = CityStore::find()->where(['id' => $data->stores])->all(); + foreach ($stores as $store) { + /** @var CityStore $store */ + $storeSaleArr = $salesMapArr[$store->id] ?? []; + $storeVisitorsQuantity = (int)($storeVisitorsByStore[$store->id] ?? 0); + $storeSaleQuantity = 0; + $storeSaleTotal = 0; + $storeSaleBonusCount = 0; + $storeSaleNewBonusCount = 0; + $storeSaleRepeatBonusCount = 0; + $storeSaleByAdminId = []; + foreach ($storeSaleArr as $storeSale) { + $storeSaleByAdminId[$storeSale['admin_id']] = $storeSale; + $storeSaleQuantity += (int)$storeSale['cnt']; + $storeSaleTotal += (int)$storeSale['total']; + $storeSaleBonusCount += (int)$storeSale['bonusUserCount']; + $storeSaleNewBonusCount += (int)$storeSale['newBonusUserCount']; + $storeSaleRepeatBonusCount += (int)$storeSale['repeatBonusUserCount']; + } + + $storeVisitorsQuantityTotal += $storeVisitorsQuantity; + $storeSaleQuantityTotal += $storeSaleQuantity; + $storeSaleTotalTotal += $storeSaleTotal; + $storeSaleBonusCountTotal += $storeSaleBonusCount; + $storeSaleNewBonusCountTotal += $storeSaleNewBonusCount; + $storeSaleRepeatBonusCountTotal += $storeSaleRepeatBonusCount; + + if (isset($adminNames[$store->id])) { + foreach ($adminNames[$store->id] as &$adminRecord) { + $adminRecord["sale_quantity"] = (int)($storeSaleByAdminId[$adminRecord['id']]['cnt'] ?? 0); + $adminRecord["sale_total"] = (int)($storeSaleByAdminId[$adminRecord['id']]['total'] ?? 0); + $adminRecord["sale_avg"] = $adminRecord["sale_quantity"] > 0 ? floor($adminRecord["sale_total"] / $adminRecord["sale_quantity"]) : 0; + $adminRecord["bonus_user_count"] = (int)($storeSaleByAdminId[$adminRecord['id']]['bonusUserCount'] ?? 0); + $adminRecord["bonus_user_per_sale_percent"] = $adminRecord["sale_quantity"] > 0 ? floor($adminRecord["bonus_user_count"] / $adminRecord["sale_quantity"] * 100) : 0; + $adminRecord["bonus_new_user_count"] = (int)($storeSaleByAdminId[$adminRecord['id']]['newBonusUserCount'] ?? 0); + $adminRecord["bonus_repeat_user_count"] = (int)($storeSaleByAdminId[$adminRecord['id']]['repeatBonusUserCount'] ?? 0); + } + } + + $totalWriteOffsPerDate = (int)($totalWriteOffsByStoreId[$store->id] ?? 0); + $totalWriteOffsPerMonth = (int)($totalWriteOffsByStoreIdMonth[$store->id] ?? 0); + $totalWriteOffsPerDateTotal += $totalWriteOffsPerDate; + $totalWriteOffsPerMonthTotal += $totalWriteOffsPerMonth; + + $totalPayrollDays = (int)($adminPayrollDays[$store->id]['total'] ?? 0); + $totalPayrollMonth = (int)($adminPayrollDaysMonth[$store->id]['total'] ?? 0); + + $totalPayrollDaysTotal += $totalPayrollDays; + $totalPayrollMonthTotal += $totalPayrollMonth; + + $totalSpecificPerDay = []; + foreach (['matrix', 'wrap', 'services', 'potted'] as $spec) { + $totalSpecificPerDay[$spec] = 0; + if (isset($adminNames[$store->id])) { + foreach ($adminNames[$store->id] as &$adminRecord) { + $adminRecord["total_" . $spec . "_per_day"] = 0; + } + } + foreach ($specificSales[$spec] as $specificSale) { + if ($specificSale['store_id'] == $store->id) { + $totalSpecificPerDay[$spec] += $specificSale['total']; + } + if (isset($adminNames[$store->id])) { + foreach ($adminNames[$store->id] as &$adminRecord) { + if ($specificSale['admin_id'] == $adminRecord['id']) { + $adminRecord["total_" . $spec . "_per_day"] = (int)$specificSale['total']; + } + } + } + } + } + $totalMatrixPerDay = $totalSpecificPerDay['matrix']; + $totalWrapPerDay = $totalSpecificPerDay['wrap']; + $totalServicePerDay = $totalSpecificPerDay['services']; + $totalPottedPerDay = $totalSpecificPerDay['potted']; + + $totalMatrixPerDayTotal += $totalMatrixPerDay; + $totalWrapPerDayTotal += $totalWrapPerDay; + $totalServicePerDayTotal += $totalServicePerDay; + $totalPottedPerDayTotal += $totalPottedPerDay; + + + $reportStore = [ + "name" => $store->name, + "id" => $store->id, + "admins" => $adminNames[$store->id] ?? [], + "visitors_quantity" => $storeVisitorsQuantity, + "sale_quantity" => $storeSaleQuantity, + "sale_total" => $storeSaleTotal, + "sale_avg" => $storeSaleQuantity > 0 ? floor($storeSaleTotal / $storeSaleQuantity) : 0, + "bonus_user_count" => $storeSaleBonusCount, + "bonus_user_per_sale_percent" => $storeSaleQuantity > 0 ? floor($storeSaleBonusCount / $storeSaleQuantity * 100) : 0, + "bonus_new_user_count" => $storeSaleNewBonusCount, + "bonus_repeat_user_count" => $storeSaleRepeatBonusCount, + "total_write_offs_per_date_percent" => $storeSaleTotal > 0 ? floor($totalWriteOffsPerDate / $storeSaleTotal * 100) : 0, + "total_write_offs_per_date" => $totalWriteOffsPerDate, + "total_write_offs_per_month" => $totalWriteOffsPerMonth, + "total_payroll_days" => $totalPayrollDays, + "total_payroll_month" => $totalPayrollMonth, + "total_matrix_per_day" => $totalMatrixPerDay, + "total_wrap_per_day" => $totalWrapPerDay, + "total_services_per_day" => $totalServicePerDay, + "total_potted_per_day" => $totalPottedPerDay, + ]; + $report["stores"][] = $reportStore; + } + + $report['total'] = [ + "visitors_quantity" => $storeVisitorsQuantityTotal, + "sale_quantity" => $storeSaleQuantityTotal, + "sale_total" => $storeSaleTotalTotal, + "sale_avg" => $storeSaleQuantityTotal > 0 ? floor($storeSaleTotalTotal / $storeSaleQuantityTotal) : 0, + "bonus_user_count" => $storeSaleBonusCountTotal, + "bonus_user_per_sale_percent" => $storeSaleQuantityTotal > 0 ? floor($storeSaleBonusCountTotal / $storeSaleQuantityTotal * 100) : 0, + "bonus_new_user_count" => $storeSaleNewBonusCountTotal, + "bonus_repeat_user_count" => $storeSaleRepeatBonusCountTotal, + "total_write_offs_per_date_percent" => $storeSaleTotalTotal > 0 ? floor($totalWriteOffsPerDateTotal / $storeSaleTotalTotal * 100) : 0, + "total_write_offs_per_date" => $totalWriteOffsPerDateTotal, + "total_write_offs_per_month" => $totalWriteOffsPerMonthTotal, + "total_payroll_days" => $totalPayrollDaysTotal, + "total_payroll_month" => $totalPayrollMonthTotal, + "total_matrix_per_day" => $totalMatrixPerDayTotal, + "total_wrap_per_day" => $totalWrapPerDayTotal, + "total_services_per_day" => $totalServicePerDayTotal, + "total_potted_per_day" => $totalPottedPerDayTotal, + ]; + + $reports[] = $report; + $currentDate = date("Y-m-d", strtotime("+1 day", strtotime($currentDate))); + } + + return $reports; + } +} \ No newline at end of file diff --git a/erp24/api3/core/services/StoreService.php b/erp24/api3/core/services/StoreService.php index 0560f09..af2bfb5 100644 --- a/erp24/api3/core/services/StoreService.php +++ b/erp24/api3/core/services/StoreService.php @@ -12,6 +12,7 @@ use yii_app\records\Prices; use yii_app\records\Products1c; use yii_app\records\Sales; use yii_app\records\SalesProducts; +use yii_app\records\StoreDynamic; use yii_app\services\LogService; class StoreService @@ -294,4 +295,20 @@ class StoreService return ['response' => true]; } + + public function getClusters() { + $storeDynamic = StoreDynamic::find()->alias('s')->select(['s.store_id as id', 's.value_int as cluster', 'c.name']) + ->innerJoin("city_store c", "c.id = s.store_id") + ->asArray()->all(); + + $storesPerCluster = []; + foreach ($storeDynamic as $data) { + $storesPerCluster[$data['cluster']][] = ['id' => $data['id'], 'name' => $data['name']]; + } + $result = []; + foreach ($storesPerCluster as $key => $data) { + $result[] = ['id' => $key, 'stores' => $data]; + } + return $result; + } } \ No newline at end of file diff --git a/erp24/api3/core/services/TimetableService.php b/erp24/api3/core/services/TimetableService.php index 49340ba..a91eb49 100644 --- a/erp24/api3/core/services/TimetableService.php +++ b/erp24/api3/core/services/TimetableService.php @@ -10,6 +10,7 @@ use yii_app\api3\modules\v1\models\timetable\Timetable; use yii_app\api3\modules\v1\requests\timetable\Fact; use yii_app\records\AdminCheckin; use yii_app\records\AdminDevice; +use yii_app\records\AdminGroup; use yii_app\records\TimetableV3; use yii_app\records\TimetableWorkbot; @@ -66,7 +67,7 @@ class TimetableService $checkIn->lon = $data->lon; $checkIn->photo = $imagePath; $checkIn->device_id = AdminDevice::findOne(['admin_id' => $timetable->admin_id])->id ?? 0; - $checkIn->type_id = AdminCheckin::TYPE_START; + $checkIn->type_id = $checkIn->d_id == AdminGroup::GROUP_ADMINISTRATORS ? AdminCheckin::TYPE_APPEAR : AdminCheckin::TYPE_START; $checkIn->status = 0; $checkIn->save(); if ($checkIn->getErrors()) { @@ -139,7 +140,7 @@ class TimetableService $checkIn->photo = $imagePath; $checkIn->status = 0; $checkIn->device_id = AdminDevice::findOne(['admin_id' => $timetable->admin_id])->id ?? 0; - $checkIn->type_id = AdminCheckin::TYPE_END; + $checkIn->type_id = $checkIn->d_id == AdminGroup::GROUP_ADMINISTRATORS ? AdminCheckin::TYPE_APPEAR : AdminCheckin::TYPE_END; $checkIn->save(); if ($checkIn->getErrors()) { throw new \Exception(Json::encode($checkIn->getErrors())); @@ -148,6 +149,60 @@ class TimetableService return true; } + /** + * @throws \yii\base\Exception + * @throws Exception + */ + public function appear($data) { + /** @var $data Fact */ + $timetable = Timetable::findOne(['id' => $data->plan_id, 'tabel' => 0]); + if(!$timetable) { + throw new NotFoundHttpException("План не найден"); + } + + if ($timetable->date != date("Y-m-d") && + $timetable->date != date("Y-m-d", strtotime("-1 day", time()))) { + throw new InvalidArgumentException("План ссылается на другую дату"); + } + + $currentDate = date('Y-m-d H:i:s'); // вынести в хелпер + $transaction = \Yii::$app->db->beginTransaction(); + try { + + $imagePath = $data->uploadImage($timetable->admin_id); + if (!$imagePath) { + throw new InvalidArgumentException("Не удалось загрузить картинку"); + } + + $checkIn = new AdminCheckin(); + $checkIn->admin_id = $timetable->admin_id; + $checkIn->plan_id = $timetable->id; + $checkIn->store_id = $timetable->store_id; + $checkIn->ball = 5; + $checkIn->comment = ""; + $checkIn->d_id = $timetable->admin->group_id; + $checkIn->date = $timetable->date; + $checkIn->time = $currentDate; + $checkIn->lat = $data->lat; + $checkIn->lon = $data->lon; + $checkIn->photo = $imagePath; + $checkIn->device_id = AdminDevice::findOne(['admin_id' => $timetable->admin_id])->id ?? 0; + $checkIn->type_id = AdminCheckin::TYPE_APPEAR; + $checkIn->status = 0; + $checkIn->save(); + if ($checkIn->getErrors()) { + throw new \Exception(Json::encode($checkIn->getErrors())); + } + + $transaction->commit(); + } catch (Exception $e) { + $transaction->rollBack(); + throw $e; + } + + return $timetable; + } + public function delete($plan_id, $comment, $removed_by) { $timetable = Timetable::find()->where(['id' => $plan_id])->one(); /* @var $timetable Timetable */ diff --git a/erp24/api3/core/traits/ServiceTrait.php b/erp24/api3/core/traits/ServiceTrait.php index 95b8909..2644b14 100644 --- a/erp24/api3/core/traits/ServiceTrait.php +++ b/erp24/api3/core/traits/ServiceTrait.php @@ -9,6 +9,8 @@ use yii_app\api3\core\services\ClientService; use yii_app\api3\core\services\EmployeeService; use yii_app\api3\core\services\IncomeService; use yii_app\api3\core\services\KikService; +use yii_app\api3\core\services\NotifiableService; +use yii_app\api3\core\services\ReportService; use yii_app\api3\core\services\StoreService; use yii_app\api3\core\services\TimetableService; @@ -45,4 +47,12 @@ trait ServiceTrait public function getKikService() { return Service::create(KikService::class); } + + public function getNotifiableService() { + return Service::create(NotifiableService::class); + } + + public function getReportService() { + return Service::create(ReportService::class); + } } \ No newline at end of file diff --git a/erp24/api3/helpers/Util.php b/erp24/api3/helpers/Util.php index 2fcb9a1..17ec946 100644 --- a/erp24/api3/helpers/Util.php +++ b/erp24/api3/helpers/Util.php @@ -8,10 +8,12 @@ class Util { $phone = $phone ?: ""; + $phone = preg_replace("/\D/", '', $phone); + // костыль для русских номеров - if (str_starts_with($phone, "89") && strlen($phone) == 11) + if (str_starts_with($phone, "89")) $phone = "7" . substr($phone, 1); - return preg_replace("/\D/", '', $phone); + return $phone; } } \ No newline at end of file diff --git a/erp24/api3/modules/v1/controllers/AdminController.php b/erp24/api3/modules/v1/controllers/AdminController.php index b586c6b..cbd00a7 100644 --- a/erp24/api3/modules/v1/controllers/AdminController.php +++ b/erp24/api3/modules/v1/controllers/AdminController.php @@ -3,7 +3,9 @@ namespace yii_app\api3\modules\v1\controllers; use yii\db\Query; +use yii\helpers\ArrayHelper; use yii_app\api3\modules\v1\models\Admin; +use yii_app\records\AdminGroup; class AdminController extends \yii_app\api3\controllers\ActiveController { @@ -23,9 +25,26 @@ class AdminController extends \yii_app\api3\controllers\ActiveController 'class' => \yii\data\ActiveDataFilter::class, 'searchModel' => $this->modelClass, ]; + $actions['index']['prepareSearchQuery'] = function ($query, $requestParams) { + return $query->andFilterWhere(['not in', 'group_id', [AdminGroup::GROUP_FIRED]]); + }; unset($actions['create'], $actions['delete'], $actions['update']); return $actions; } + + public function actionEmployees() { + $admins = Admin::find()->select(['id', 'name', 'mobile as phone']) + ->where(['in', 'group_id', AdminGroup::getGroupsForEmployeeOnCashbox()])->asArray()->all(); + $results = []; + foreach ($admins as $admin) { + $results []= [ + 'id' => (int)$admin['id'], + 'name' => $admin['name'], + 'phone' => '+7(***)**' . substr($admin['phone'], -4) + ]; + } + return $results; + } } \ No newline at end of file diff --git a/erp24/api3/modules/v1/controllers/BonusController.php b/erp24/api3/modules/v1/controllers/BonusController.php index e0e2870..4cb3ed6 100644 --- a/erp24/api3/modules/v1/controllers/BonusController.php +++ b/erp24/api3/modules/v1/controllers/BonusController.php @@ -11,6 +11,7 @@ use yii_app\api3\modules\v1\requests\bonus\GetClientInfoInput; use yii_app\api3\modules\v1\requests\bonus\ReturnInput; use yii_app\api3\modules\v1\requests\bonus\SaleInput; use yii_app\api3\modules\v1\requests\bonus\SaveClientInfoInput; +use yii_app\api3\modules\v1\requests\bonus\BonusWriteOffInput; /** * @property BonusService $bonusService @@ -164,4 +165,22 @@ class BonusController extends \yii_app\api3\controllers\NoActiveController return $this->bonusService->bonusAdd($data); } + + public function actionWriteOff() { + // localhost:8888/v1/bonus/write-off + // { + // "phone": "+79200247501", + // "lid_id": "12345", + // "price": 100, + // "bonus": 20, + // "date_start": "2023-06-16", + // "date_end": "2024-01-01 00:00:00" + // } + $params = \Yii::$app->request->post(); + + $model = new BonusWriteOffInput; + $data = $this->validate($model, $params); + + return $this->bonusService->bonusWriteOff($data); + } } \ No newline at end of file diff --git a/erp24/api3/modules/v1/controllers/EmployeeController.php b/erp24/api3/modules/v1/controllers/EmployeeController.php index 07f4373..3a25797 100644 --- a/erp24/api3/modules/v1/controllers/EmployeeController.php +++ b/erp24/api3/modules/v1/controllers/EmployeeController.php @@ -5,6 +5,7 @@ namespace yii_app\api3\modules\v1\controllers; use yii_app\api3\core\services\EmployeeService; use yii_app\api3\core\traits\ServiceTrait; use yii_app\api3\modules\v1\requests\employee\AtStoreInput; +use yii_app\records\Timetable; /** * @property EmployeeService $employeeService @@ -32,4 +33,8 @@ class EmployeeController extends \yii_app\api3\controllers\NoActiveController return $this->employeeService->atStore($data); } + + public function actionSalariesDay() { + return Timetable::getSalariesDay(); + } } \ No newline at end of file diff --git a/erp24/api3/modules/v1/controllers/NotifiableController.php b/erp24/api3/modules/v1/controllers/NotifiableController.php new file mode 100644 index 0000000..5f58041 --- /dev/null +++ b/erp24/api3/modules/v1/controllers/NotifiableController.php @@ -0,0 +1,24 @@ +notifiableService->getExpiredBonuses(); + } + + public function actionGetFirstSaleUsers() { + // localhost:8888/v1/notifiable/get-first-sale-users + return $this->notifiableService->getGetFirstSaleUsers(); + } +} \ No newline at end of file diff --git a/erp24/api3/modules/v1/controllers/ReportController.php b/erp24/api3/modules/v1/controllers/ReportController.php new file mode 100644 index 0000000..ca77e70 --- /dev/null +++ b/erp24/api3/modules/v1/controllers/ReportController.php @@ -0,0 +1,49 @@ +request->post(); + + $model = new ReportInput; + $data = $this->validate($model, $params); + + $result = $this->reportService->show($data); + + $apiLogs = new ApiLogs; + $apiLogs->url = \Yii::$app->request->url; + $apiLogs->request_id = ""; + $apiLogs->date = date('Y-m-d H:i:s'); + $apiLogs->content = Json::encode($data); + $apiLogs->hash_content = ""; + $apiLogs->result = Json::encode($result); + $apiLogs->status = 0; + $apiLogs->store_id = "report_show"; + $apiLogs->seller_id = ""; + $apiLogs->phone = ""; + $apiLogs->ip = "127.0.0.1"; + $apiLogs->save(); + + return $result; + } +} \ No newline at end of file diff --git a/erp24/api3/modules/v1/controllers/StoreController.php b/erp24/api3/modules/v1/controllers/StoreController.php index 9fbe8cc..6edc0aa 100644 --- a/erp24/api3/modules/v1/controllers/StoreController.php +++ b/erp24/api3/modules/v1/controllers/StoreController.php @@ -115,4 +115,8 @@ class StoreController extends \yii_app\api3\controllers\ActiveController return $this->storeService->assemblies($data); } + + public function actionGetClusters() { + return $this->storeService->getClusters(); + } } \ No newline at end of file diff --git a/erp24/api3/modules/v1/controllers/claim/WorkerController.php b/erp24/api3/modules/v1/controllers/claim/WorkerController.php index 3749b74..e0b0a9d 100644 --- a/erp24/api3/modules/v1/controllers/claim/WorkerController.php +++ b/erp24/api3/modules/v1/controllers/claim/WorkerController.php @@ -48,8 +48,6 @@ class WorkerController extends \yii_app\api3\controllers\ActiveController $params = Yii::$app->request->bodyParams; $data = $this->validate(new Worker(), $params); - $data->phone = Util::phoneNormalizer($data->phone); - $this->claimService->create($data); return true; diff --git a/erp24/api3/modules/v1/controllers/timetable/FactController.php b/erp24/api3/modules/v1/controllers/timetable/FactController.php index 66b84fc..6585682 100644 --- a/erp24/api3/modules/v1/controllers/timetable/FactController.php +++ b/erp24/api3/modules/v1/controllers/timetable/FactController.php @@ -63,4 +63,15 @@ class FactController extends ActiveController return $this->timetableService->close($data); } + + public function actionAppear() + { + $params = \Yii::$app->request->post(); + + $model = new Fact(); + $model->image = UploadedFile::getInstanceByName('image'); + $data = $this->validate($model, $params); + + return $this->timetableService->appear($data); + } } \ No newline at end of file diff --git a/erp24/api3/modules/v1/models/Store.php b/erp24/api3/modules/v1/models/Store.php index 42f73b5..c1fc872 100644 --- a/erp24/api3/modules/v1/models/Store.php +++ b/erp24/api3/modules/v1/models/Store.php @@ -21,6 +21,8 @@ class Store extends Products1c return [ 'id', 'name' => fn($m) => mb_substr($m->name, 3), + 'city_store_id' => fn($m) => $m->store ? $m->store->id : null, + 'tg_chat_id' => fn($m) => $m->store ? (!empty($m->store->tg_chat_id) ? $m->store->tg_chat_id : null) : null, // 'parent_id' => fn($m) => intval($m->parent_id), // 'view' ]; @@ -30,6 +32,7 @@ class Store extends Products1c return [ 'view', 'workAdmins' => fn($m) => array_map(fn($x) => [ + 'phone' => $x->mobile, 'name' => $x->name, 'id' => $x->id ], $m->workAdmins) diff --git a/erp24/api3/modules/v1/models/orders/OrdersAmo.php b/erp24/api3/modules/v1/models/orders/OrdersAmo.php index 5a8d92d..481ddf9 100644 --- a/erp24/api3/modules/v1/models/orders/OrdersAmo.php +++ b/erp24/api3/modules/v1/models/orders/OrdersAmo.php @@ -9,7 +9,7 @@ class OrdersAmo extends \yii_app\records\OrdersAmo { public static function getDb() { - return Yii::$app->db2; + return Yii::$app->db; } public function rules(): array diff --git a/erp24/api3/modules/v1/models/timetable/Timetable.php b/erp24/api3/modules/v1/models/timetable/Timetable.php index 9071662..71ba935 100644 --- a/erp24/api3/modules/v1/models/timetable/Timetable.php +++ b/erp24/api3/modules/v1/models/timetable/Timetable.php @@ -21,6 +21,7 @@ class Timetable extends \yii_app\records\TimetableV3 [['tabel'], 'integer', 'skipOnEmpty' => false], [['id', 'shift_id', 'store_id'], 'integer'], [['date'], 'date', 'format' => 'yyyy-M-d'], + [['salary_shift'], 'in', 'range' => \yii_app\records\Timetable::getSalariesDay(), 'skipOnEmpty' => true], [['shift_id'], 'in', 'range' => array_keys(Shift::all()), 'skipOnEmpty' => false], [['store_id'], 'exist', 'targetClass' => CityStore::class, 'targetAttribute' => 'id', 'skipOnEmpty' => false], [['admin_id', 'admin_id_add'], 'exist', 'targetClass' => Admin::class, 'targetAttribute' => 'id', 'skipOnEmpty' => true], @@ -138,6 +139,7 @@ class Timetable extends \yii_app\records\TimetableV3 'admin_id', 'store_id', 'shift_id', + 'salary_shift', // 'price' => fn($x) => $x->shift_id == 2 ? 140 : 125, 'tabel', 'date', diff --git a/erp24/api3/modules/v1/requests/bonus/BonusWriteOffInput.php b/erp24/api3/modules/v1/requests/bonus/BonusWriteOffInput.php new file mode 100644 index 0000000..8018e7b --- /dev/null +++ b/erp24/api3/modules/v1/requests/bonus/BonusWriteOffInput.php @@ -0,0 +1,27 @@ + "yyyy-MM-dd H:m:s"], + ]; + } +} \ No newline at end of file diff --git a/erp24/api3/modules/v1/requests/claim/Worker.php b/erp24/api3/modules/v1/requests/claim/Worker.php index d4c5f8a..18e3509 100644 --- a/erp24/api3/modules/v1/requests/claim/Worker.php +++ b/erp24/api3/modules/v1/requests/claim/Worker.php @@ -3,9 +3,11 @@ namespace yii_app\api3\modules\v1\requests\claim; use yii\base\Model; +use yii_app\api3\core\validators\PhoneValidator; use yii_app\records\Admin; use yii_app\records\EmployeeOnShift; use yii_app\records\Products1c; +use yii_app\records\Timetable; class Worker extends Model { @@ -15,6 +17,7 @@ class Worker extends Model public $datetime_start; public $datetime_end; public $price; + public $salary_shift; public $shift_type; public $first_name; public $last_name; @@ -29,13 +32,16 @@ class Worker extends Model ['shift_date', 'date', 'format' => "yyyy-MM-dd"], ['shift_type', 'in', 'range' => [0, 1, 2]], [['first_name', 'last_name'], 'string', 'min' => 2, 'max' => 40], + [['first_name', 'last_name'], 'filter', 'filter' => 'trim'], ['price', 'number', 'min' => 120, 'max' => 150], + [['salary_shift'], 'in', 'range' => Timetable::getSalariesDay(), 'skipOnEmpty' => false], [['datetime_start', 'datetime_end'], 'datetime', 'format' => "yyyy-MM-dd H:m:s"], // [['guid'], 'unique'], ['created_by', 'exist', 'targetClass' => Admin::class, 'targetAttribute' => 'id', 'filter' => ['group_id' => [1, 7, 8, 10, 30, 35, 40, 50, 51, 71]]], ['store_id', 'exist', 'targetClass' => Products1c::class, 'targetAttribute' => 'id', 'filter' => ['tip' => 'city_store']], ['phone', 'unique', 'targetClass' => EmployeeOnShift::class, 'targetAttribute' => ['phone', 'store_id'], 'filter' => ['status' => EmployeeOnShift::STATUS_INITIAL]], + ['phone', PhoneValidator::class], ['datetime_start', 'checkDateTimeStart'] ]; } diff --git a/erp24/api3/modules/v1/requests/report/ReportInput.php b/erp24/api3/modules/v1/requests/report/ReportInput.php new file mode 100644 index 0000000..0f8465a --- /dev/null +++ b/erp24/api3/modules/v1/requests/report/ReportInput.php @@ -0,0 +1,23 @@ + ['integer']], + [['date_start', 'date_end'], 'datetime', 'format' => 'yyyy-M-d'], + ['shift_type', 'in', 'range' => [0, 1, 2]] + ]; + } +} \ No newline at end of file diff --git a/erp24/api3/modules/v1/requests/timetable/Fact.php b/erp24/api3/modules/v1/requests/timetable/Fact.php index f558fc6..8823e5d 100644 --- a/erp24/api3/modules/v1/requests/timetable/Fact.php +++ b/erp24/api3/modules/v1/requests/timetable/Fact.php @@ -33,19 +33,15 @@ class Fact extends Model { $uploadDir = \Yii::getAlias("@upload-checkin") . "/"; - // можно сделать проверку на mimetype - $extension = mb_strtolower(substr($this->image->name, stripos($this->image->name, ".", -5) + 1)); - - $dir = date("Y") . "/" . date("m") . "/" . substr($adminId, 0, 2) . "/" . $adminId . "/"; - - $filename = date("d-m-H-i-s") . "." . $extension; - - FileHelper::createDirectory($uploadDir . $dir); - - $path = $dir . $filename; + $Y = date("Y"); + $m = date("m"); + if (!is_dir($uploadDir . "$Y/$m")) { + mkdir($uploadDir . "$Y/$m", 0777, true); + } + $fileName = $adminId . '-' . date("YmdHis") . '.jpg'; - if($this->image->saveAs($uploadDir . $path)) { - return $path; + if($this->image->saveAs($uploadDir . "$Y/$m/". $fileName)) { + return "data/admin/$Y/$m/" . $fileName; } else { return false; } diff --git a/erp24/controllers/ChartForManagementController.php b/erp24/controllers/ChartForManagementController.php new file mode 100644 index 0000000..a139ef9 --- /dev/null +++ b/erp24/controllers/ChartForManagementController.php @@ -0,0 +1,622 @@ + Yii::$app->user->id]); + + $access_chart = [ + 'mode_level' => [], + 'mode_shift' => [], + 'visible' => false, + ]; + + $access = [ + 'main' => $access_chart, + 'plan_completed_this_day' => $access_chart, + 'plan_completed_this_month' => $access_chart, + 'sales' => $access_chart, + 'matrix_sales_sum' => $access_chart, + 'avg_sales_value' => $access_chart, + 'fot' => $access_chart, + 'sales_sum_on_admin' => $access_chart, + 'user_bonus' => $access_chart, + 'count_sales_in_hour' => $access_chart, + 'write_offs' => $access_chart, + ]; + + if (in_array($admin->group_id, [1, 81, 71, 51, 10, 9, 74, 14])) { + foreach ($access as $key => &$item) { + if (in_array($key, ['avg_sales_value', 'sales', 'user_bonus', 'matrix_sales_sum', 'count_sales_in_hour'])) { + $item['mode_level'] = [ + //0 => 'Доставка', + 1 => 'Розница', + 2 => 'Куст', + 3 => 'Магазин' + ]; + + $item['mode_shift'] = [ + 3 => 'День+Ночь', + 1 => 'День', + 2 => 'Ночь', + 4 => 'Сутки' + ]; + } else { + $item['mode_level'] = [ + 1 => 'Розница', + 2 => 'Куст', + 3 => 'Магазин' + ]; + + $item['mode_shift'] = [ + 3 => 'День+Ночь', + 1 => 'День', + 2 => 'Ночь', + //4 => 'Сутки' + ]; + } + + $item['visible'] = true; + } + + } else if (in_array($admin->group_id, [Admin::CLUSTER_MANAGER_GROUP_ID])) { + foreach ($access as &$item) { + $item['mode_level'] = [ + 2 => 'Куст', + 3 => 'Магазин', + ]; + + $item['mode_shift'] = [ + 3 => 'День+Ночь', + 1 => 'День', + 2 => 'Ночь', + + ]; + + $item['visible'] = true; + } + + } else if (in_array($admin->group_id, [30, 40])) { + foreach ($access as $key => &$item) { + $item['mode_level'] = [ + 3 => 'Магазин', + ]; + + $item['mode_shift'] = [ + 1 => 'День', + ]; + + if ($key != 'plan_completed_this_day' && $key != 'plan_completed_this_month') { + $item['visible'] = true; + } + + } + + } else if (in_array($admin->group_id, [35, 72])) { + foreach ($access as $key => &$item) { + $item['mode_level'] = [ + 3 => 'Магазин', + ]; + + $item['mode_shift'] = [ + 2 => 'Ночь', + ]; + + if ($key != 'plan_completed_this_day' && $key != 'plan_completed_this_month') { + $item['visible'] = true; + } + + } + + } else if (in_array($admin->group_id, [Admin::ADMINISTRATOR_GROUP_ID])) { + foreach ($access as &$item) { + $item['mode_level'] = [ + 3 => 'Магазин' + ]; + + $item['mode_shift'] = [ + 3 => 'День+Ночь', + 1 => 'День', + 2 => 'Ночь', + + ]; + + $item['visible'] = true; + } + + } else { + throw new Exception('Нет доступа'); + } + + return $this->render('index', [ + 'access' => $access + ]); + } + + public function actionWriteOffPosition() + { + $admin = Admin::findOne(['id' => Yii::$app->user->id]); + + $access = [ + 'mode_level' => [], + 'mode_shift' => [], + 'access_plan' => false, + ]; + + if (in_array($admin->group_id, [1, 81, 71, 51, 10, 9, 74, 14])) { + + $access['mode_level'] = [ + 1 => 'Розница', + 2 => 'Куст', + 3 => 'Магазин' + ]; + + $access['mode_shift'] = [ + 3 => 'День+Ночь', + 1 => 'День', + 2 => 'Ночь', + + ]; + + $access['access_plan'] = true; + + } else if (in_array($admin->group_id, [7])) { + + $access['mode_level'] = [ + 2 => 'Куст', + 3 => 'Магазин', + ]; + + $access['mode_shift'] = [ + 3 => 'День+Ночь', + 1 => 'День', + 2 => 'Ночь', + ]; + + $access['access_plan'] = true; + + } else if (in_array($admin->group_id, [30, 40])) { + + $access['mode_level'] = [ + 3 => 'Магазин', + ]; + + $access['mode_shift'] = [ + 1 => 'День', + ]; + + } else if (in_array($admin->group_id, [35, 72])) { + + $access['mode_level'] = [ + 3 => 'Магазин', + ]; + + $access['mode_shift'] = [ + 2 => 'Ночь', + ]; + + } else if (in_array($admin->group_id, [50])) { + $access['mode_level'] = [ + 3 => 'Магазин' + ]; + + $access['mode_shift'] = [ + 3 => 'День+Ночь', + 1 => 'День', + 2 => 'Ночь', + ]; + + $access['access_plan'] = true; + } else { + throw new Exception('Нет доступа'); + } + + return $this->render('write-offs-position-chart', [ + 'access' => $access + ]); + } + + public function actionGetControlDataAjax() + { + $post_data = Yii::$app->request->post(); + + $date_start = date('Y-m-d H:i:s', strtotime($post_data['date_start'])); + $date_end = date('Y-m-d H:i:s', strtotime($post_data['date_end'])); + + $stores = Admin::find()->where(['admin.id' => Yii::$app->user->id])->leftJoin( + 'store_dynamic', + [ + 'OR', + ['LIKE', 'admin.store_arr', new Expression('CONCAT("%," , store_dynamic.store_id, ",%")')], + ['LIKE', 'admin.store_arr', new Expression('CONCAT("" , store_dynamic.store_id, ",%")')], + ['LIKE', 'admin.store_arr', new Expression('CONCAT("%," , store_dynamic.store_id, "")')], + ['LIKE', 'admin.store_arr', new Expression('CONCAT("" , store_dynamic.store_id, "")')], + ] + + ) + ->innerJoin('city_store', 'store_dynamic.store_id = city_store.id AND store_dynamic.category = 1') + ->select( + [ + 'cluster_name' => 'CONCAT_WS(\' \', \'Куст\', store_dynamic.value_int)', + 'cluster_id' => 'store_dynamic.value_int', + 'store_id' => 'store_dynamic.store_id', + 'store_name' => 'city_store.name', + 'date_from' => 'DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')', + ] + ) + ->andWhere( + [ + 'OR', + [ + 'AND', + ['BETWEEN', 'DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d %H:%i:%s\')', $date_start, $date_end], + ['BETWEEN', 'DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d %H:%i:%s\')', $date_start, $date_end], + ], + [ + 'AND', + ['BETWEEN', 'DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d %H:%i:%s\')', $date_start, $date_end], + ['>=', 'DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d %H:%i:%s\')', $date_end], + ], + [ + 'AND', + ['<=', 'DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d %H:%i:%s\')', $date_start], + ['BETWEEN', 'DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d %H:%i:%s\')', $date_start, $date_end], + ], + [ + 'AND', + ['<=', 'DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d %H:%i:%s\')', $date_start], + ['>=', 'DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d %H:%i:%s\')', $date_start], + ], + ] + ) + ->orderBy(['store_dynamic.value_int' => SORT_ASC, 'city_store.id' => SORT_ASC]) + ->asArray() + ->all(); + + $steps_stores = ArrayHelper::map($stores, 'date_from', 'cluster_name', 'store_name'); + + foreach ($steps_stores as $store_name => $step_store) { + if (count($step_store) === 1) { + unset($steps_stores[$store_name]); + } + } + + $clusters_unic = []; + foreach ($stores as $store) { + if (!in_array(['id' => $store['cluster_id'], 'text' => $store['cluster_name']], $clusters_unic)) { + $clusters_unic[] = ['id' => $store['cluster_id'], 'text' => $store['cluster_name']]; + } + } + + $store_in_cluster = []; + foreach ($stores as $store) { + if (!isset($store_in_cluster[$store['cluster_id']])) { + $store_in_cluster[$store['cluster_id']]['text'] = $store['cluster_name']; + } + $store_in_cluster[$store['cluster_id']]['children'][] = ['id' => $store['store_id'], 'text' => $store['store_name']]; + } + + return Json::encode(['stores_step' => $steps_stores, 'clusters' => $clusters_unic, 'stores_in_cluster' => $store_in_cluster]); + } + + public function actionGetDataAjax() + { + $post_data = Yii::$app->request->post(); + $chart_data_search = new ChartDataSearch(); + + $chart_data_search->mode_level = intval($post_data['mode']); + $chart_data_search->attribute_name = $post_data['attribute']; + $chart_data_search->date_start = $post_data['date_start'] ?? date('Y-m-d', strtotime('-13 day')); + $chart_data_search->date_end = $post_data['date_end'] ?? date('Y-m-d', time()); + $chart_data_search->cluster_id = $post_data['cluster']; + $chart_data_search->store_id = $post_data['store']; + $chart_data_search->mode_shift = $post_data['shift'] ?? 3; + $chart_data_search->select_cluster = true; + + if ($post_data['attribute'] === 'plan_completed_this_day') { + $chart_data_search->date_start = date('Y-m-d', strtotime('first day of this month')); + $chart_data_search->date_end = date('Y-m-d', time()); + + } + + if ($post_data['attribute'] === 'plan_completed_this_month') { + $chart_data_search->date_start = date('Y-m-d', strtotime('first day of this month')); + $chart_data_search->date_end = date('Y-m-d', strtotime('last day of this month')); + + } + + if ($post_data['attribute'] === 'write_offs') { + $chart_data_search->date_start = date('Y-m-d', strtotime('first day of this month', strtotime($chart_data_search->date_start))); + $chart_data_search->mode_shift = 4; + } + + $dates = []; + $chart_opts = null; + $temp_row = ['sales_sum' => 0, 'sum' => 0, 'plan' => 0]; + $interval_days = (strtotime($chart_data_search->date_end) - strtotime($chart_data_search->date_start)) / (60 * 60 * 24); + + $data_answer = $chart_data_search->attributes_config[$post_data['attribute']]; + + if ($post_data['attribute'] === 'write_offs_position') { + $answer_query = $chart_data_search->searchWriteOffsItems(); + } + + if ($post_data['attribute'] === 'write_offs_position') { + if (!isset($answer_query[1])) { + return -1; + } + + $data = $answer_query[1]; + + } else { + $data = $chart_data_search->search(); + + } + + $keys = array_keys($data_answer['attribute']); + $step = 0; + + foreach ($data as $index => $datum) { + if ($post_data['attribute'] === 'plan_completed_this_day') { + $temp_row['sales_sum'] += $datum['value']; + $temp_row['plan'] += $datum['plan']; + + } else if ($post_data['attribute'] === 'plan_completed_this_month') { + $temp_row['sales_sum'] += $datum['value']; + $temp_row['plan'] += $datum['plan']; + + } else if ($post_data['attribute'] === 'sales') { + $data_answer['attribute'][$keys[0]]['data'][] = $datum['value']; + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[1]]['data'][] = $datum['plan']; + + } else if ($post_data['attribute'] === 'count_sales_in_hour') { + $data_answer['attribute'][$keys[0]]['data'][] = $datum['value']; + $data_answer['attribute'][$keys[1]]['data'][] = $datum['value'] / ($interval_days > 0 ? $interval_days : 1); + + } else if ($post_data['attribute'] === 'avg_sales_value') { + if ($step % 2 != 0) { + $step++; + continue; + } + + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[0]]['data'][] = $datum['value'] / ($data[$index + 1]['value'] != 0 ? $data[$index + 1]['value'] : 1); + $data_answer['attribute'][$keys[1]]['data'][] = $datum['plan']; + $step++; + + } else if ($post_data['attribute'] === 'fot') { + if ($step % 2 != 0) { + $step ++; + continue; + + } + + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[0]]['data'][] = $datum['value'] / (($data[$index + 1]['value'] != 0 ? $data[$index + 1]['value'] : 1) / 100); + $data_answer['attribute'][$keys[1]]['data'][] = $datum['plan']; + $step++; + + } else if ($post_data['attribute'] === 'sales_sum_on_admin') { + if ($step % 2 != 0) { + $step ++; + continue; + + } + + $step++; + + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[0]]['data'][] = $datum['value'] / ($data[$index + 1]['value'] != 0 ? $data[$index + 1]['value'] : 1); + + } else if ($post_data['attribute'] === 'write_offs') { + if ($step % 2 != 0) { + $step++; + continue; + + } + + $step++; + + if (date('d', strtotime($datum['date'])) == 1) { + $temp_row['sales_sum'] = 0; + $temp_row['sum'] = 0; + } + $temp_row['sales_sum'] += $datum['value'] ?? 0; + $temp_row['sum'] += $data[$index + 1]['value'] ?? 0; + + if (strtotime($datum['date']) >= (($post_data['date_start']) ? strtotime($post_data['date_start']) : date('Y-m-d', strtotime('-13 day')))) { + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[0]]['data'][] = $data[$index + 1]['value'] ?? 0; + $data_answer['attribute'][$keys[1]]['data'][] = ($data[$index + 1]['value'] ?? 0) / (($datum['value'] != 0 ? $datum['value'] : 1) / 100); + $data_answer['attribute'][$keys[2]]['data'][] = $temp_row['sum'] / ((($temp_row['sales_sum'] != 0) ? $temp_row['sales_sum'] : 1) / 100); + } + } else if ($post_data['attribute'] === 'user_bonus') { + if ($step % 4 == 0) { + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[0]]['data'][] = $data[$index]['value'] ?? 0; + $data_answer['attribute'][$keys[1]]['data'][] = 0; + $data_answer['attribute'][$keys[2]]['data'][] = 0; + $data_answer['attribute'][$keys[3]]['data'][] = 0; + + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[0]]['data'][] = 0; + $data_answer['attribute'][$keys[1]]['data'][] = $data[$index + 1]['value'] ?? 0; + $data_answer['attribute'][$keys[2]]['data'][] = 0; + $data_answer['attribute'][$keys[3]]['data'][] = 0; + + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[0]]['data'][] = 0; + $data_answer['attribute'][$keys[1]]['data'][] = 0; + $data_answer['attribute'][$keys[2]]['data'][] = $data[$index + 2]['value'] ?? 0; + $data_answer['attribute'][$keys[3]]['data'][] = $data[$index + 3]['value'] ?? 0; + + } + + $step++; + + } else if ($post_data['attribute'] === 'matrix_sales_sum') { + if ($step % 3 == 0) { + $dates[] = $datum['date'] . ' ' . $chart_data_search->day_of_week[date('w', strtotime($datum['date']))]; + $data_answer['attribute'][$keys[0]]['data'][] = $data[$index]['value'] ?? 0; + $data_answer['attribute'][$keys[1]]['data'][] = $data[$index + 1]['value'] ?? 0; + $data_answer['attribute'][$keys[2]]['data'][] = $data[$index + 2]['value'] ?? 0; + + } + + $step++; + } + } + + if ($post_data['attribute'] !== 'count_sales_in_hour') { + $chart_opts = [ + 'xaxis' => [ + 'type' => 'text', + 'categories' => $dates, + ] + ]; + } else { + if ($chart_data_search->mode_shift === 3) { + $chart_opts = [ + 'xaxis' => [ + 'type' => 'text', + 'categories' => array_merge(range(8, 23), range(0, 7)) + ] + ]; + } else if ($chart_data_search->mode_shift === 1) { + $chart_opts = [ + 'xaxis' => [ + 'type' => 'text', + 'categories' => range(8, 19) + ] + ]; + } else if ($chart_data_search->mode_shift === 2) { + $chart_opts = [ + 'xaxis' => [ + 'type' => 'text', + 'categories' => array_merge(range(20, 23), range(0, 7)) + ] + ]; + } else if ($chart_data_search->mode_shift === 4) { + $chart_opts = [ + 'xaxis' => [ + 'type' => 'text', + 'categories' => range(0, 23) + ] + ]; + } + + $chart_data_search::sortCountSalesInHour($data_answer, $chart_data_search->mode_shift); + } + + if ($chart_data_search->mode_level === 2) { + $chart_opts['title'] = ['text' => 'Куст ' . $chart_data_search->cluster_id]; + } else if ($chart_data_search->mode_level === 3) { + if ($chart_data_search->attribute_name === 'write_offs_position') { + $chart_opts['title'] = ['text' => 'Магазин: ' . $answer_query[0][0]['store_name']]; + } else { + $chart_opts['title'] = ['text' => 'Магазин: ' . $data[0]['store_name']]; + } + + } else { + $chart_opts['title'] = ['text' => 'Розница']; + } + + if ($post_data['attribute'] === 'plan_completed_this_day') { + $data_answer = []; + $data_answer['attribute']['plan_complete_on_this_day'] = round( + $temp_row['sales_sum'] / + ($temp_row['plan'] !== 0 ? $temp_row['plan'] : 1) * + 100, + 2); + + } + + if ($post_data['attribute'] === 'plan_completed_this_month') { + $data_answer = []; + $data_answer['attribute']['plan_hypothesis_complete_on_this_month'] = round( + $temp_row['sales_sum'] / + date('d', time()) * + date('d', strtotime('last day of this month')) / + ($temp_row['plan'] !== 0 ? $temp_row['plan'] : 1) * + 100, + 2); + + } + + $answer = ['chart_opts' => $chart_opts, 'data_answer' => $data_answer]; + return Json::encode($answer); + } + + public function actionWriteOffsIndex($date, $cluster_id = null, $store_id = null) + { + $query_write_offs = WriteOffs::find() + ->select([ + 'store_name' => 'city_store.name', + 'sum' => 'write_offs.summ', + 'date' => 'write_offs.date', + 'number' => 'write_offs.number', + 'comment' => 'write_offs.comment' + ]) + ->innerJoin('export_import_table', 'export_import_table.export_val = write_offs.store_id') + ->innerJoin('city_store', 'city_store.id = export_import_table.entity_id') + ->innerJoin( + 'store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = city_store.id', + [ + '>=', + new Expression('DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + ], + [ + '<', + new Expression('DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + ] + ] + ) + ->andWhere([ + 'export_import_table.entity' => 'city_store' + ]) + ->andFilterWhere([ + 'store_dynamic.value_int' => $cluster_id, + 'city_store.id' => $store_id + ]) + ->andWhere([ + 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')' => $date + ]) + ->andWhere([ + 'write_offs.type' => 'Брак' + ]) + ->orderBy([ + 'store_dynamic.value_int' => SORT_ASC, + 'city_store.id' => SORT_ASC, + 'write_offs.date' => SORT_ASC, + ]); + + $dataProvider = new ArrayDataProvider([ + 'allModels' => $query_write_offs->asArray()->all() + ]); + + return $this->render('write-offs', [ + 'dataProvider' => $dataProvider, + 'date' => $date + ]); + } +} \ No newline at end of file diff --git a/erp24/controllers/CityStoreController.php b/erp24/controllers/CityStoreController.php index 31b7d1a..a9edbe1 100644 --- a/erp24/controllers/CityStoreController.php +++ b/erp24/controllers/CityStoreController.php @@ -2,6 +2,7 @@ namespace app\controllers; +use Yii; use yii_app\records\CityStore; use yii_app\records\CityStoreSearch; use yii\web\Controller; @@ -40,7 +41,20 @@ class CityStoreController extends Controller { $searchModel = new CityStoreSearch(); $dataProvider = $searchModel->search($this->request->queryParams); - + if (Yii::$app->request->isAjax && Yii::$app->request->post('action') == 'saveTg') { + $storeId = Yii::$app->request->post('storeId'); + $tgInput = Yii::$app->request->post('tgInput'); + if (empty($tgInput)) { + return 'not ok'; + } + $cityStore = CityStore::find()->where(['id' => $storeId])->one(); + if (!$cityStore) { + return 'not ok'; + } + $cityStore->tg_chat_id = $tgInput; + $cityStore->save(false); + return 'ok'; + } return $this->render('/city_store/index', [ 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, diff --git a/erp24/controllers/InfoTableController.php b/erp24/controllers/InfoTableController.php index 32220d2..db3aa8f 100644 --- a/erp24/controllers/InfoTableController.php +++ b/erp24/controllers/InfoTableController.php @@ -24,6 +24,7 @@ class InfoTableController extends \yii\web\Controller 'test' => \yii_app\actions\infoTable\TestAction::class, 'validate' => \yii_app\actions\dashboard\ValidateAction::class, 'charts-fot' => \yii_app\actions\infoTable\ChartsFotAction::class, + 'cabinet' => \yii_app\actions\infoTable\CabinetAction::class, ]; } diff --git a/erp24/controllers/MatrixErpPropertyController.php b/erp24/controllers/MatrixErpPropertyController.php index 500fbb6..7773550 100644 --- a/erp24/controllers/MatrixErpPropertyController.php +++ b/erp24/controllers/MatrixErpPropertyController.php @@ -249,7 +249,7 @@ class MatrixErpPropertyController extends Controller if ($uploadImage) { - if (Images::isImageFile(($uploadImage))) { + if (Images::isImageFile(($uploadImage), ['png', 'jpg'])) { $image = new Images(); $imageId = $image->loadImage(($uploadImage)); diff --git a/erp24/controllers/PagesController.php b/erp24/controllers/PagesController.php index 5570163..1509a2d 100755 --- a/erp24/controllers/PagesController.php +++ b/erp24/controllers/PagesController.php @@ -11,7 +11,6 @@ class PagesController extends \yii\web\Controller { return [ 'index' => \yii_app\actions\pages\IndexAction::class, - 'statistics' => \yii_app\actions\pages\StatisticsAction::class, ]; } } \ No newline at end of file diff --git a/erp24/controllers/ShipmentController.php b/erp24/controllers/ShipmentController.php old mode 100644 new mode 100755 diff --git a/erp24/controllers/SiteController.php b/erp24/controllers/SiteController.php index ad1c3a9..b58b3b2 100644 --- a/erp24/controllers/SiteController.php +++ b/erp24/controllers/SiteController.php @@ -5,127 +5,12 @@ namespace app\controllers; use GuzzleHttp\Client; use Yii; use yii\web\Controller; -use yii\web\Response; -use yii\filters\VerbFilter; -use app\models\LoginForm; -use app\models\ContactForm; -use yii_app\records\CrmMenu; - -class SiteController extends Controller -{ - /** - * {@inheritdoc} - */ - public function behaviors() - { - return [ - 'verbs' => [ - 'class' => VerbFilter::class, - 'actions' => [ - 'logout' => ['get'], - ], - ], - ]; - } - - /** - * {@inheritdoc} - */ - public function actions() - { - return [ - 'error' => [ - 'class' => 'yii\web\ErrorAction', - ], - 'captcha' => [ - 'class' => 'yii\captcha\CaptchaAction', - 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, - ], - ]; - } - - /** - * Displays homepage. - * - * @return string - */ - public function actionIndex() - { - return $this->render('index'); - } - - /** - * Login action. - * - * @return Response|string - */ - public function actionLogin() - { - if (!Yii::$app->user->isGuest) { - return $this->goHome(); - } - - $model = new LoginForm(); - if (Yii::$app->request->isPost) { - if ($model->load(Yii::$app->request->post()) && $model->login()) { - return $this->goBack(); - } else { - return $this->refresh(); - } - } - - $model->password = ''; - return $this->renderPartial('login', [ - 'model' => $model, - ]); - } - - /** - * Logout action. - * - * @return Response - */ - public function actionLogout() - { - if (!Yii::$app->user->isGuest) { - Yii::$app->user->logout(); - } - - return $this->redirect('/site/login'); - } - - /** - * Displays contact page. - * - * @return Response|string - */ - public function actionContact() - { - $model = new ContactForm(); - if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) { - Yii::$app->session->setFlash('contactFormSubmitted'); - - return $this->refresh(); - } - return $this->render('contact', [ - 'model' => $model, - ]); - } - - /** - * Displays about page. - * - * @return string - */ - public function actionAbout() - { - return $this->render('about'); - } +class SiteController extends Controller { public function actionMenuTree() { -// $client = new Client(['base_uri' => Yii::$app->params['API2_URL']]); -// $response = $client->request('GET', '/site/menu-tree?user_id=' . Yii::$app->user->id . '&key=' . Yii::$app->params['API2_TOKEN']); -// return $this->asJson(json_decode($response->getBody(), true)); - return $this->asJson(CrmMenu::getTreeByUserId(Yii::$app->user->id)); + $client = new Client(['base_uri' => Yii::$app->params['API2_URL']]); + $response = $client->request('GET', '/site/menu-tree?user_id=' . Yii::$app->user->id . '&key=' . Yii::$app->params['API2_TOKEN']); +// Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + return $this->asJson(json_decode($response->getBody(), true)); } -} +} \ No newline at end of file diff --git a/erp24/forms/timetable/TabelSearchForm.php b/erp24/forms/timetable/TabelSearchForm.php index cd30346..2fe3461 100755 --- a/erp24/forms/timetable/TabelSearchForm.php +++ b/erp24/forms/timetable/TabelSearchForm.php @@ -88,7 +88,10 @@ class TabelSearchForm extends Model 'group_id' => array_keys(AdminGroup::groupsWithShift()) ]) ->andFilterWhere(['group_id' => $this->adminGroupId]) - ->orderBy(['group_id' => SORT_ASC, 'name' => SORT_ASC]) + ->orderBy(['IF(group_id IN (' + . AdminGroup::GROUP_WORKERS . ', ' + . AdminGroup::GROUP_WORKERS_ARCHIVE . ', ' + . AdminGroup::GROUP_FIRED . '),1,0)' => SORT_ASC, 'group_id' => SORT_ASC, 'name' => SORT_ASC]) ->indexBy('id'); if ($this->storeId) { $adminQuery diff --git a/erp24/helpers/ClientHelper.php b/erp24/helpers/ClientHelper.php index 6064865..c2ecb6e 100644 --- a/erp24/helpers/ClientHelper.php +++ b/erp24/helpers/ClientHelper.php @@ -16,7 +16,7 @@ class ClientHelper { $phone = preg_replace("/[^0-9\,]/i", "", $phone); // $urlstr = preg_replace('/[^A-Za-z0-9_\-]/', '', $urlstr); $phone_str = strlen($phone); - if ($phone_str == 10) { + if ($phone_str == 10 && $phone[0] != '7') { $phone = "7$phone"; } elseif ($phone_str == 11) { $str0 = substr($phone, 0, 1); diff --git a/erp24/helpers/DataHelper.php b/erp24/helpers/DataHelper.php index 3e353e9..29499e6 100644 --- a/erp24/helpers/DataHelper.php +++ b/erp24/helpers/DataHelper.php @@ -80,4 +80,35 @@ class DataHelper { return json_decode($string,true,512,JSON_UNESCAPED_UNICODE); } + + public static function arraysAreEqual($array1, $array2): bool + { + array_multisort($array1); + array_multisort($array2); + + return ( serialize($array1) === serialize($array2) ); + } + + public static function mergeArraysByKey($array1, $array2): array + { + $mergeArray = []; + $array1Keys = array_keys($array1); + $array2Keys = array_keys($array2); + $keys = array_merge($array1Keys,$array2Keys); + + foreach($keys as $key) { + $mergeArray[$key] = array_merge_recursive(isset($array1[$key])?$array1[$key]:[],isset($array2[$key])?$array2[$key]:[]); + } + + return $mergeArray; + + } + + public static function ruPlural($number, $titles = array(/*1*/'комментарий', /*2*/'комментария', /*5*/'комментариев')): string + { + $cases = array (2, 0, 1, 1, 1, 2); + + return $number.' '.$titles[($number % 100 > 4 && $number % 100 < 20) ? 2 : $cases[min($number % 10, 5)]]; + } + } \ No newline at end of file diff --git a/erp24/helpers/File.php b/erp24/helpers/File.php index b357f7f..21252a4 100644 --- a/erp24/helpers/File.php +++ b/erp24/helpers/File.php @@ -125,7 +125,7 @@ class File extends FileHelper } self::createDirectory($resizedPath); - if (!file_exists($resizedFile)) { + if (!file_exists($resizedFile) && !empty($imagePath)) { ImageHelper::resizeImage($imagePath, $resizedFile, $w, $h, $quality); } return $resizedUrl; diff --git a/erp24/helpers/HtmlHelper.php b/erp24/helpers/HtmlHelper.php index 2ecd3a8..8cb0d7b 100755 --- a/erp24/helpers/HtmlHelper.php +++ b/erp24/helpers/HtmlHelper.php @@ -2,6 +2,7 @@ namespace yii_app\helpers; +use DateTime; use yii\helpers\ArrayHelper; use yii_app\records\Admin; @@ -162,4 +163,23 @@ class HtmlHelper } + public static function getAdministratorWorkDays($month, $year): int + { + $adminDayCount = 0; + $dayMonthDateRow = $year . '-' . $month . '-01'; + $dayMonthRow = new DateTime($dayMonthDateRow); + $days = date('j', strtotime($dayMonthRow->format('Y-m-t'))); + foreach (range(1, $days) as $day) { + $dayRow = $year . '-' . $month . '-' . $day; + $time = new DateTime($dayRow); + $dayNumRow = $time->format('w'); + // считаем дни со вторника по субботу + if ($dayNumRow >= 2 && $dayNumRow <= 6) { + $adminDayCount++; + } + } + return $adminDayCount; + } + + } diff --git a/erp24/helpers/SalaryHelper.php b/erp24/helpers/SalaryHelper.php index ac843bd..d717223 100755 --- a/erp24/helpers/SalaryHelper.php +++ b/erp24/helpers/SalaryHelper.php @@ -8,6 +8,8 @@ use yii\db\Exception; use yii\helpers\ArrayHelper; use yii_app\records\Products1c; use yii_app\records\Sales; +use yii_app\records\Timetable; +use yii_app\services\HolidayService; use yii_app\services\SalesService; class SalaryHelper @@ -19,6 +21,8 @@ class SalaryHelper 45=>15, 40=>15, //Помощник день 72=>15, //Помощник ночь + 90=>15, //Помощник ночь + -1=>15, //Помощник ночь ]; public static function getSqlWhereFromArray($array, $pole) @@ -107,16 +111,9 @@ class SalaryHelper } - if (count($adminGuidArr)) { - $i = 0; - $where_p = " AND ("; - foreach ($adminGuidArr as $adminGuid) { - if ($i > 0) - $where_p .= " or "; - $where_p .= " sales.seller_id='$adminGuid'"; - $i++; - } - $where_p .= " )"; + if (is_array($adminGuidArr) && count($adminGuidArr)) { + $adminGuidArrIn = "'" . implode("', '", $adminGuidArr) . "'"; + $where_p = " AND sales.seller_id IN ($adminGuidArrIn) "; } @@ -166,6 +163,8 @@ class SalaryHelper AND sales.id = p.check_id + AND + p.type_id = 1 AND (p.component_parent_id = '' OR p.component_parent_id = 0 OR p.component_parent_id IS NULL) AND @@ -213,9 +212,9 @@ class SalaryHelper $allBonus[$row["seller_id"]]["check"][] = $row; } - foreach ($allBonus as $sallerId => $bonus) { - $allBonus2[$sallerId]["bonus"] = round($bonus["bonus"]); - $allBonus2[$sallerId]["check"] = $bonus["check"]; + foreach ($allBonus as $sellerId => $bonus) { + $allBonus2[$sellerId]["bonus"] = round($bonus["bonus"]); + $allBonus2[$sellerId]["check"] = $bonus["check"]; } @@ -265,17 +264,9 @@ class SalaryHelper $whereProducts = 1; } - - if (count($adminGuidArr)) { - $i = 0; - $where_p = " AND ("; - foreach ($adminGuidArr as $adminGuid) { - if ($i > 0) - $where_p .= " or "; - $where_p .= " sales.seller_id='$adminGuid'"; - $i++; - } - $where_p .= " )"; + if (is_array($adminGuidArr) && count($adminGuidArr)) { + $adminGuidArrIn = "'" . implode("', '", $adminGuidArr) . "'"; + $where_p = " AND sales.seller_id IN ($adminGuidArrIn) "; } @@ -446,17 +437,10 @@ class SalaryHelper ] ); - $action2 = $command->getRawSql(); $data2 = $command->queryAll(); - - } - - - } else { - $command = $connection->createCommand(" SELECT sales.id, @@ -527,7 +511,6 @@ class SalaryHelper } } - return $allBonus2; } @@ -584,4 +567,221 @@ class SalaryHelper return $command->queryColumn(); } + + public static function getSalariesByFocusGroup( + $employeeId, + $adminGuid, + $arrayProducts, + $adminGuidArr, + $dateFrom, + $dateTo, + $exportAdmin, + $isAdministrator, + $employeeSelectStoreId, + $showHolidayVersion = false, + $notHolidayCalculate = true + ): array { + $adminGuidDateArr = []; + $adminGuidArrAll = []; + if ($showHolidayVersion) { + $holidayDatesBetweenPrepared = HolidayService::getHolidayDatesBetween($dateFrom, $dateTo); + if ($notHolidayCalculate) { + $dataKey = 'notHolidayDatesInterval'; + } else { + $dataKey = 'dayHolidayInArray'; + $adminGuidDateArr = self::getAdminGuidByStore($dateFrom, $dateTo, $employeeSelectStoreId); + $isAdministrator = false; + } + $dates = ArrayHelper::getValue($holidayDatesBetweenPrepared, $dataKey); + } else { + $dates = [ + 0 => [ + 'dateFrom' => $dateFrom, + 'dateTo' => $dateTo, + ], + ]; + } + + $arrUsersSalaryServices = []; + $arrUsersSalaryRelated = []; + $arrUsersSalaryPotted = []; + $arrUsersSalaryWrap = []; + $arrUsersSalarySalut = []; + $arrUsersSalaryOtherItems = []; + + $arrUsersSalary = [ + "services" => [], + "related" => [], + "potted" => [], + "wrap" => [], + "salut" => [], + "other_items" => [], + ]; + + $arrUsersSalaryServicesCheck = []; + $arrUsersSalaryRelatedCheck = []; + $arrUsersSalaryPottedCheck = []; + $arrUsersSalaryWrapCheck = []; + $arrUsersSalarySalutCheck = []; + $arrUsersSalaryOtherItemsCheck = []; + + foreach ($dates as $key => $datesRow) { + $dateFromRow = $datesRow['dateFrom']; + $dateToRow = $datesRow['dateTo']; + if ( + false === $notHolidayCalculate + && + $dateFromRow == $dateToRow + && + !empty($adminGuidDateArr) + + ) { + if (array_key_exists($dateFromRow, $adminGuidDateArr)) { + $adminGuidArr = $adminGuidDateArr[$dateFromRow]; + $adminGuidArrAll[$dateFromRow] = $adminGuidArr; + } else { + continue; + } + } + + if (!empty($arrayProducts["services"])) { + $arrUsersSalaryServicesPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["services"], $adminGuidArr, $dateFromRow, $dateToRow, $exportAdmin, $isAdministrator); + $arrUsersSalaryServices[] = array_sum( + ArrayHelper::getColumn($arrUsersSalaryServicesPrepared, 'bonus') + ); + $arrUsersSalaryServicesCheck = DataHelper::mergeArraysByKey( + $arrUsersSalaryServicesCheck, + ArrayHelper::getColumn($arrUsersSalaryServicesPrepared, 'check') + ); + } + + if (!empty($arrayProducts["related"])) { + $arrUsersSalaryRelatedPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["related"], $adminGuidArr, $dateFromRow, $dateToRow, $exportAdmin, $isAdministrator); + $arrUsersSalaryRelated[] = array_sum( + ArrayHelper::getColumn($arrUsersSalaryRelatedPrepared, 'bonus') + ); + + $arrUsersSalaryRelatedCheck = DataHelper::mergeArraysByKey( + $arrUsersSalaryRelatedCheck, + ArrayHelper::getColumn($arrUsersSalaryRelatedPrepared, 'check') + ); + } + + if (!empty($arrayProducts["potted"])) { + $arrUsersSalaryPottedPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["potted"], $adminGuidArr, $dateFromRow, $dateToRow, $exportAdmin, $isAdministrator); + $arrUsersSalaryPotted[] = array_sum( + ArrayHelper::getColumn($arrUsersSalaryPottedPrepared, 'bonus') + ); + $arrUsersSalaryPottedCheck = DataHelper::mergeArraysByKey( + $arrUsersSalaryPottedCheck, + ArrayHelper::getColumn($arrUsersSalaryPottedPrepared, 'check') + ); + } + + if (!empty($arrayProducts["wrap"])) { + $arrUsersSalaryWrapPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["wrap"], $adminGuidArr, $dateFromRow, $dateToRow, $exportAdmin, $isAdministrator); + $arrUsersSalaryWrap[] = array_sum( + ArrayHelper::getColumn($arrUsersSalaryWrapPrepared, 'bonus') + ); + $arrUsersSalaryWrapCheck = DataHelper::mergeArraysByKey( + $arrUsersSalaryWrapCheck, + ArrayHelper::getColumn($arrUsersSalaryWrapPrepared, 'check') + ); + } + + if (!empty($arrayProducts["other_items"])) { + $arrUsersSalaryOtherItemsPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["other_items"], $adminGuidArr, $dateFromRow, $dateToRow, $exportAdmin, $isAdministrator); + $arrUsersSalaryOtherItems[] = array_sum( + ArrayHelper::getColumn($arrUsersSalaryOtherItemsPrepared, 'bonus') + ); + $arrUsersSalaryOtherItemsCheck = DataHelper::mergeArraysByKey( + $arrUsersSalaryOtherItemsCheck, + ArrayHelper::getColumn($arrUsersSalaryOtherItemsPrepared, 'check') + ); + } + + if (!empty($arrayProducts["salut"])) { + $arrUsersSalarySalutPrepared = SalaryHelper::getSalaryBonusSalut($arrayProducts["salut"], $adminGuidArr, $dateFromRow, $dateToRow, $exportAdmin, $isAdministrator, $employeeSelectStoreId); + $arrUsersSalarySalut[] = array_sum( + ArrayHelper::getColumn($arrUsersSalarySalutPrepared, 'bonus') + ); + $arrUsersSalarySalutCheck = DataHelper::mergeArraysByKey( + $arrUsersSalarySalutCheck, + ArrayHelper::getColumn($arrUsersSalarySalutPrepared, 'check') + ); + } + } + + $arrUsersSalaryServicesValue = []; + if (array_sum($arrUsersSalaryServices) > 0) { + $arrUsersSalaryServicesValue = [$adminGuid => array_sum($arrUsersSalaryServices ?? [])]; + } + $arrUsersSalaryRelatedValue = []; + if (array_sum($arrUsersSalaryRelated) > 0) { + $arrUsersSalaryRelatedValue = [$adminGuid => array_sum($arrUsersSalaryRelated ?? [])]; + } + $arrUsersSalaryPottedValue = []; + if (array_sum($arrUsersSalaryPotted) > 0) { + $arrUsersSalaryPottedValue = [$adminGuid => array_sum($arrUsersSalaryPotted ?? [])]; + } + $arrUsersSalaryWrapValue = []; + if (array_sum($arrUsersSalaryWrap) > 0) { + $arrUsersSalaryWrapValue = [$adminGuid => array_sum($arrUsersSalaryWrap ?? [])]; + } + $arrUsersSalarySalutValue = []; + if (array_sum($arrUsersSalarySalut) > 0) { + $arrUsersSalarySalutValue = [$adminGuid => array_sum($arrUsersSalarySalut ?? [])]; + } + $arrUsersSalaryOtherItemsValue = []; + if (array_sum($arrUsersSalaryOtherItems) > 0) { + $arrUsersSalaryOtherItemsValue = [$adminGuid => array_sum($arrUsersSalaryOtherItems ?? [])]; + } + + $arrUsersSalary = [ + "services" => $arrUsersSalaryServicesValue, + "related" => $arrUsersSalaryRelatedValue, + "potted" => $arrUsersSalaryPottedValue, + "wrap" => $arrUsersSalaryWrapValue, + "salut" => $arrUsersSalarySalutValue, + "other_items" => $arrUsersSalaryOtherItemsValue, + ]; + + $arrUsersSalaryCheck = [ + "services" => self::getSubRows($arrUsersSalaryServicesCheck), + "related" => self::getSubRows($arrUsersSalaryRelatedCheck), + "potted" => self::getSubRows($arrUsersSalaryPottedCheck), + "wrap" => self::getSubRows($arrUsersSalaryWrapCheck), + "salut" => self::getSubRows($arrUsersSalarySalutCheck), + "other_items" => self::getSubRows($arrUsersSalaryOtherItemsCheck), + ]; + + return [ + 'arrUsersSalary' => $arrUsersSalary, + 'arrUsersSalaryCheck' => $arrUsersSalaryCheck, + 'adminGuidDateArrByFocusGroup' => $adminGuidArrAll, + ]; + } + + public static function getAdminGuidByStore($dateFrom, $dateTo, $employeeSelectStoreId) + { + $adminsPrepared = Timetable::getAdminsByDates($dateFrom, $dateTo, $employeeSelectStoreId); + + return $adminsPrepared['dateGuids']; + } + + public static function getSubRows(array $arrayRows): array + { + $res = []; + if (!empty($arrayRows)) { + foreach ($arrayRows as $rows) { + if (!empty($rows) && is_array($rows)) { + foreach ($rows as $item) { + $res[] = $item; + } + } + } + } + + return $res; + } } \ No newline at end of file diff --git a/erp24/records/AdminChats.php b/erp24/records/AdminChats.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminCheckin.php b/erp24/records/AdminCheckin.php index 9de516b..85c0c5e 100755 --- a/erp24/records/AdminCheckin.php +++ b/erp24/records/AdminCheckin.php @@ -42,7 +42,7 @@ class AdminCheckin extends ActiveRecord public static function tableName() { - return '{{%admin_checkin}}'; + return 'admin_checkin'; } public function isStart() diff --git a/erp24/records/AdminDesktop.php b/erp24/records/AdminDesktop.php index d333726..3c0a1c0 100755 --- a/erp24/records/AdminDesktop.php +++ b/erp24/records/AdminDesktop.php @@ -32,7 +32,7 @@ class AdminDesktop extends ActiveRecord public static function tableName() { - return '{{%admin_desktop}}'; + return 'admin_desktop'; } /** diff --git a/erp24/records/AdminDevice.php b/erp24/records/AdminDevice.php index 73de07e..7204864 100755 --- a/erp24/records/AdminDevice.php +++ b/erp24/records/AdminDevice.php @@ -27,7 +27,7 @@ class AdminDevice extends ActiveRecord { public static function tableName() { - return '{{%admin_device}}'; + return 'admin_device'; } } \ No newline at end of file diff --git a/erp24/records/AdminDynamic.php b/erp24/records/AdminDynamic.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminDynamicCategoryDict.php b/erp24/records/AdminDynamicCategoryDict.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminGradeHistory.php b/erp24/records/AdminGradeHistory.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminGroup.php b/erp24/records/AdminGroup.php index f8befba..77e37fe 100755 --- a/erp24/records/AdminGroup.php +++ b/erp24/records/AdminGroup.php @@ -16,6 +16,7 @@ use yii\db\ActiveRecord; */ class AdminGroup extends ActiveRecord { + const GROUP_FIRED = -1; const NOT_INITIALIZED_GROUP = 1000; const GROUP_HR = 20; @@ -24,6 +25,7 @@ class AdminGroup extends ActiveRecord const GROUP_FLORIST_NIGHT = 35; const GROUP_FLORIST_SUPPORT_DAY = 40; const GROUP_WORKERS = 45; + const GROUP_WORKERS_ARCHIVE = 90; const GROUP_ADMINISTRATORS = 50; const GROUP_FLORIST_SUPPORT_NIGHT = 72; const GROUP_OPERATIONAL_DIRECTOR = 51; @@ -57,7 +59,7 @@ class AdminGroup extends ActiveRecord public static function tableName() { - return '{{%admin_group}}'; + return 'admin_group'; } public function rules() diff --git a/erp24/records/AdminGroupCompanyFunctionVisibility.php b/erp24/records/AdminGroupCompanyFunctionVisibility.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminGroupRbacConfig.php b/erp24/records/AdminGroupRbacConfig.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminPayrollDays.php b/erp24/records/AdminPayrollDays.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminPayrollDaysSearch.php b/erp24/records/AdminPayrollDaysSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminPayrollHistory.php b/erp24/records/AdminPayrollHistory.php new file mode 100644 index 0000000..88a58b3 --- /dev/null +++ b/erp24/records/AdminPayrollHistory.php @@ -0,0 +1,122 @@ + [ + 'value_type' => AdminPayrollHistory::TYPE_VALUE_NUMBER, + 'group_number' => AdminPayrollHistory::GROUP_VALUE_ALL_TOTAL_PAYROLL, + ], + 'teamBonusValue' => [ + 'value_type' => AdminPayrollHistory::TYPE_VALUE_NUMBER, + 'group_number' => AdminPayrollHistory::GROUP_VALUE_TEAM_BONUS_VALUE, + ], + 'teamBonusDetail' => [ + 'value_type' => AdminPayrollHistory::TYPE_VALUE_STRING, + 'group_number' => AdminPayrollHistory::GROUP_VALUE_TEAM_BONUS_DETAIL, + ], + ]; + + foreach ($arrayList as $key => $row) { + $groupNumber = ArrayHelper::getValue($row, 'group_number'); + $typeValue = ArrayHelper::getValue($row, 'value_type'); + $fieldName = 'value_' . $typeValue; + $adminPayrollHistory = new AdminPayrollHistory(); + $adminPayrollHistory->admin_id = $employeeId; + $adminPayrollHistory->store_id = $storeId; + $adminPayrollHistory->year = $yearSelect; + $adminPayrollHistory->month = $monthSelect; + $adminPayrollHistory->$fieldName = $payrollValues[$key]; + $adminPayrollHistory->group_number = $groupNumber; + $adminPayrollHistory->value_type = $typeValue; + $adminPayrollHistory->created_at = date('Y-m-d H:i:s'); + $adminPayrollHistory->created_date = date('Y-m-d'); + $adminPayrollHistory->packet_num = $packetNum; + if ($adminPayrollHistory->validate()) { + $adminPayrollHistory->save(); + } else { + if (!empty($adminPayrollHistory->getErrors())) { + $errorString = json_encode($adminPayrollHistory->getErrors(), JSON_UNESCAPED_UNICODE); + $error = 'Error: ' . $errorString . ' >>> ' . __FILE__. ' >>> ' . __LINE__; + } + } + } + + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['admin_id', 'store_id', 'year', 'month','packet_num', 'value_type', 'created_at'], 'required'], + [['admin_id', 'store_id', 'year', 'month','packet_num', 'group_number'], 'integer'], + [['created_at', 'created_date'], 'safe'], + [['value_number'], 'number'], + [['value_string'], 'safe'], + [['value_type'], 'safe'], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'admin_id' => 'Admin ID', + 'store_id' => 'Store ID', + 'year' => 'Year', + 'month' => 'Month', + 'group_number' => 'Group Value', + 'value_number' => 'Value Number', + 'value_string' => 'Value String', + 'value_type' => 'Value Type', + 'created_at' => 'Created At', + 'created_date' => 'Created Date', + 'packet_num' => 'packet num', + ]; + } +} diff --git a/erp24/records/AdminPayrollMonthInfo.php b/erp24/records/AdminPayrollMonthInfo.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminPayrollStat.php b/erp24/records/AdminPayrollStat.php old mode 100755 new mode 100644 diff --git a/erp24/records/AdminPersonBonuses.php b/erp24/records/AdminPersonBonuses.php index 477f3d1..1cb821b 100755 --- a/erp24/records/AdminPersonBonuses.php +++ b/erp24/records/AdminPersonBonuses.php @@ -21,6 +21,8 @@ use yii\db\ActiveQueryInterface; * @property int|null $shift_correction * @property int|null $vacation_day * @property string $date_time + * @property int|null $part_time_job_hours + * @property string $retention_comment */ class AdminPersonBonuses extends \yii\db\ActiveRecord { @@ -48,11 +50,12 @@ class AdminPersonBonuses extends \yii\db\ActiveRecord 'prepaid_expense', 'counting', 'shift_correction', - 'vacation_day' + 'vacation_day', + 'part_time_job_hours' ], 'integer' ], - [['date_time'], 'safe'], + [['date_time', 'retention_comment'], 'safe'], [['date'], 'string', 'max' => 100], ]; } @@ -71,7 +74,9 @@ class AdminPersonBonuses extends \yii\db\ActiveRecord 'bonuses' => 'Премия', 'color_ruble_bonuses' => 'Премия в цвето-рублях', 'retention' => 'Вычет', + 'retention_comment' => 'Коментарий к вычету', 'shift_correction' => 'Коррекция смены', + 'part_time_job_hours' => 'Подработка в часах', 'vacation_day' => 'Отпуск, число оплаченных дней', 'prepaid_expense' => 'Аванс', 'counting' => 'Подсчёт', diff --git a/erp24/records/AdminStores.php b/erp24/records/AdminStores.php old mode 100755 new mode 100644 diff --git a/erp24/records/ApiCron.php b/erp24/records/ApiCron.php old mode 100755 new mode 100644 diff --git a/erp24/records/ApiCronTest.php b/erp24/records/ApiCronTest.php old mode 100755 new mode 100644 diff --git a/erp24/records/ApiCronTestSearch.php b/erp24/records/ApiCronTestSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/ApiErrorLog.php b/erp24/records/ApiErrorLog.php old mode 100755 new mode 100644 diff --git a/erp24/records/ApiErrorLogSearch.php b/erp24/records/ApiErrorLogSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/ApiLogs.php b/erp24/records/ApiLogs.php old mode 100755 new mode 100644 diff --git a/erp24/records/ApiLogsSearch.php b/erp24/records/ApiLogsSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/Assemblies.php b/erp24/records/Assemblies.php old mode 100755 new mode 100644 diff --git a/erp24/records/Balances.php b/erp24/records/Balances.php old mode 100755 new mode 100644 diff --git a/erp24/records/BalancesSearch.php b/erp24/records/BalancesSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/CalendarAdminLink.php b/erp24/records/CalendarAdminLink.php old mode 100755 new mode 100644 diff --git a/erp24/records/Cashes.php b/erp24/records/Cashes.php old mode 100755 new mode 100644 diff --git a/erp24/records/ChartDataSearch.php b/erp24/records/ChartDataSearch.php old mode 100755 new mode 100644 index aff0ea0..d633003 --- a/erp24/records/ChartDataSearch.php +++ b/erp24/records/ChartDataSearch.php @@ -487,6 +487,10 @@ class ChartDataSearch $plan_query->andWhere([ 'plan_store.shift_type' => [1, 2] ]); + } else if ($this->mode_shift === 4) { + $rnp_query->andWhere([ + 'rnp_index.shift_type' => 4 + ]); } if ($this->mode_level === 2) { @@ -1073,7 +1077,7 @@ class ChartDataSearch } - static function CalculationCompanyDataForCharts($date_start, $date_end) + static function CalculationCompanyDataForChartsShifts($date_start, $date_end) { $query = StoreDynamic::find(); @@ -1161,7 +1165,40 @@ class ChartDataSearch //region Проверка на возвраты /* Проверка продажи */ - $invalid_sales = Sales::find()->alias('invalid_sales')->andWhere(['invalid_sales.operation' => Sales::OPERATION_RETURN])->select(['check_id' => 'invalid_sales.sales_check']); + $invalid_sales = Sales::find()->alias('invalid_sales'); + + $invalid_sales->innerJoin( + 'city_store', + 'city_store.id = invalid_sales.store_id' + ); + + $invalid_sales->innerJoin( + 'store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = invalid_sales.store_id', + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))') + ], + ] + ); + + $invalid_sales->andWhere(['invalid_sales.operation' => Sales::OPERATION_RETURN]) + ->select([ + 'date' => 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + 'shift_type' => 'if(HOUR(invalid_sales.date) >= 8 && HOUR(invalid_sales.date) < 20, 1, 2)', + 'cluster_id' => 'store_dynamic.value_int', + 'store_dynamic_id' => 'store_dynamic.id', + 'store_id' => 'city_store.id' + ]); + $invalid_sales->andWhere([ '>=', 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', @@ -1169,16 +1206,26 @@ class ChartDataSearch ]); $invalid_sales->andWhere([ - '<=', + '<', 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', - date('Y-m-d', strtotime('+1 week', strtotime($date_start))) + date('Y-m-d', strtotime($date_end)) ]); - $sales_query->andWhere(['sales.operation' => Sales::OPERATION_SALE]); - $sales_query->andWhere(['NOT IN', 'sales.id', $invalid_sales]); + $invalid_sales->groupBy([ + 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + 'if(HOUR(invalid_sales.date) >= 8 && HOUR(invalid_sales.date) < 20, 1, 2)', + 'store_dynamic.value_int', + 'store_dynamic.id', + 'city_store.id' + ]); + + $invalid_sales->andWhere('invalid_sales.order_id = \'\''); + /* Конец проверки продажи */ //endregion + $sales_query->andWhere(['sales.operation' => Sales::OPERATION_SALE]); + //Исключение доставки $sales_query->andWhere('sales.order_id = \'\''); @@ -1190,18 +1237,6 @@ class ChartDataSearch 'city_store.id' ]); /* Конец продажи */ - - /* - SELECT SUM(summ) - FROM `sales` - INNER JOIN city_store ON sales.store_id = city_store.id - WHERE (date BETWEEN "2023-08-01 8:00:00" AND "2023-08-02 7:59:59") AND - (sales.order_id = "") AND - (sales.operation = "Продажа") AND - (sales.id NOT IN ( - SELECT sales.sales_check FROM sales WHERE sales.sales_check != "" - )); - */ //endregion // region ФОТ @@ -1259,58 +1294,6 @@ class ChartDataSearch */ // endregion - //region Списания - $write_offs_query = WriteOffs::find(); - - $write_offs_query->addSelect([ - 'date' => 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', - 'shift_type' => 'if(HOUR(write_offs.date) >= 8 && HOUR(write_offs.date) < 20, 1, 2)', - 'cluster_id' => 'store_dynamic.value_int', - 'store_dynamic_id' => 'store_dynamic.id', - 'store_id' => 'city_store.id' - ]); - - $write_offs_query->innerJoin( - 'export_import_table', - 'write_offs.store_id = export_import_table.export_val' - ); - - $write_offs_query->innerJoin( - 'city_store', - 'export_import_table.entity_id = city_store.id' - ); - - $write_offs_query->innerJoin( - 'store_dynamic', - [ - 'AND', - 'store_dynamic.store_id = export_import_table.entity_id', - [ - '<=', - new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), - new Expression('DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')') - ], - [ - '>', - new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), - new Expression('DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')') - ], - ] - ); - - $write_offs_query->andWhere([ - 'write_offs.type' => 'Брак' - ]); - - $write_offs_query->addGroupBy([ - 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', - 'if(HOUR(write_offs.date) >= 8 && HOUR(write_offs.date) < 20, 1, 2)', - 'store_dynamic.value_int', - 'store_dynamic.id', - 'city_store.id' - ]); - //endregion - //region Ограничения //region Даты @@ -1330,14 +1313,6 @@ class ChartDataSearch date('Y-m-d', strtotime($date_end)) ]); - //Списания - $write_offs_query->andWhere([ - 'BETWEEN', - 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', - date('Y-m-d', strtotime($date_start)), - date('Y-m-d', strtotime($date_end)) - ]); - //Основной запрос $query->andWhere([ 'BETWEEN', @@ -1361,11 +1336,6 @@ class ChartDataSearch 'admin_payroll_days.smena_type' => [1, 2] ]); - //Списания - $write_offs_query->andWhere([ - 'if(HOUR(write_offs.date) >= 8 && HOUR(write_offs.date) < 20, 1, 2)' => [1, 2] - ]); - //Основной запрос $query->andWhere([ 'shift_types.shift_type' => [1, 2] @@ -1415,15 +1385,30 @@ class ChartDataSearch ] ); + $query->leftJoin(['invalid_sub_sales' => $invalid_sales], + [ + 'AND', + 'city_store.id = invalid_sub_sales.store_id', + 'store_dynamic.id = invalid_sub_sales.store_dynamic_id', + 'dates_column.date = invalid_sub_sales.date', + 'shift_types.shift_type = invalid_sub_sales.shift_type' + ] + ); + $sales_query->addSelect([ 'sales_sum' => 'SUM(sales.summ)', 'count' => 'COUNT(sales.id)', ]); + $invalid_sales->addSelect([ + 'invalid_sales' => 'SUM(invalid_sales.summ)', + 'invalid_count' => 'COUNT(invalid_sales.id)', + ]); + $query->addSelect([ - 'sales_sum' => 'SUM(sub_sales.sales_sum)', - 'count_sales' => 'SUM(sub_sales.count)', + 'sales_sum' => 'SUM(sub_sales.sales_sum) - SUM(if (invalid_sub_sales.invalid_sales IS NOT NULL, invalid_sub_sales.invalid_sales, 0))', + 'count_sales' => 'SUM(sub_sales.count) - SUM(if (invalid_sub_sales.invalid_count IS NOT NULL, invalid_sub_sales.invalid_count, 0))', ]); $select_array_sales_query = []; @@ -1464,29 +1449,6 @@ class ChartDataSearch ]); //endregion - //region Списания - $query->leftJoin( - ['sub_write_offs' => $write_offs_query], - [ - 'AND', - 'city_store.id = sub_write_offs.store_id', - 'store_dynamic.id = sub_write_offs.store_dynamic_id', - 'dates_column.date = sub_write_offs.date', - 'shift_types.shift_type = sub_write_offs.shift_type' - ] - ); - - - $write_offs_query->addSelect([ - 'write_offs' => 'SUM(write_offs.summ)', - ]); - - $query->addSelect([ - 'write_offs' => 'SUM(sub_write_offs.write_offs)', - ]); - - - //endregion //endregion $query->orderBy([ @@ -1497,9 +1459,9 @@ class ChartDataSearch ]); //var_dump($plan_store_query->asArray()->all()); exit(); - //var_dump($write_offs_query->asArray()->all()); exit(); //var_dump($sales_query->asArray()->all()); exit(); //var_dump($admin_payroll_days_query->asArray()->all()); exit(); + //var_dump($invalid_sales->asArray()->all()); exit(); //var_dump($query->asArray()->all()); exit(); //var_dump($query->createCommand()->getRawSql()); exit(); @@ -1524,6 +1486,9 @@ class ChartDataSearch $sales_data_batch = $query->asArray()->batch(200); + $rnpDataRows = []; + $rnpIndexId = []; + foreach ($sales_data_batch as $sales_data) { foreach ($sales_data as $datum) { @@ -1547,34 +1512,35 @@ class ChartDataSearch } if ($id != -1) { - $rows = []; foreach ($datum as $key => $item) { if (!in_array($key, ['cluster_id', 'store_id', 'date', 'shift_type'])) { - $rows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpDataRows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpIndexId[] = $id; } } + } + } + } - try { - $transaction = \Yii::$app->db->beginTransaction(); - RnpData::deleteAll(['AND', ['index_id' => $id], ['NOT IN', 'alias_id', [RnpAlias::USERS_COUNT_ID, RnpAlias::FIRST_MINUS_USER_BONUS_ID, RnpAlias::SECOND_MINUS_USER_BONUS_ID]]]); - Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rows)->execute(); - $transaction->commit(); + try { + $transaction = \Yii::$app->db->beginTransaction(); + RnpData::deleteAll(['AND', ['index_id' => $rnpIndexId], ['NOT IN', 'alias_id', [RnpAlias::USERS_COUNT_ID, RnpAlias::FIRST_MINUS_USER_BONUS_ID, RnpAlias::SECOND_MINUS_USER_BONUS_ID]]]); + Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rnpDataRows)->execute(); + $transaction->commit(); + $message .= "COUNT(RnpRows) = " . count($rnpDataRows); - } catch (\Exception $exception) { - $transaction->rollBack(); + } catch (\Exception $exception) { + $transaction->rollBack(); - $message .= "ЗАПИСЬ store_id = " . $datum['store_id'] . " ОТ: " . $datum['date'] . " АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; - $message .= $exception->getMessage() . "\n"; - } - } - } + $message .= "АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= $exception->getMessage() . "\n"; } return $message; } - static function CalculationCompanyDataUsersBonusForCharts($date_start, $date_end) + static function CalculationCompanyDataForChartsDay($date_start, $date_end) { $query = StoreDynamic::find(); @@ -1611,7 +1577,7 @@ class ChartDataSearch //Генерирует столбец типов смен для каждой даты //region Смены - $shift_query = (new Query())->from('(SELECT 1 AS shift_type UNION ALL SELECT 2) shift_types') + $shift_query = (new Query())->from('(SELECT 4 AS shift_type) shift_types') ->select(['shift_type' => 'shift_types.shift_type']); $query->leftJoin( @@ -1630,8 +1596,7 @@ class ChartDataSearch $sales_query = Sales::find(); $sales_query->addSelect([ - 'date' => 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', - 'shift_type' => 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'date' => 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', 'cluster_id' => 'store_dynamic.value_int', 'store_dynamic_id' => 'store_dynamic.id', 'store_id' => 'city_store.id' @@ -1650,42 +1615,82 @@ class ChartDataSearch [ '<=', new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), - new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + new Expression('DATE_FORMAT(sales.date, \'%Y-%m-%d\')') ], [ '>', new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), - new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + new Expression('DATE_FORMAT(sales.date, \'%Y-%m-%d\')') ], ] ); //region Проверка на возвраты /* Проверка продажи */ - $invalid_sales = Sales::find()->alias('invalid_sales')->andWhere(['invalid_sales.operation' => Sales::OPERATION_RETURN])->select(['check_id' => 'invalid_sales.sales_check']); + $invalid_sales = Sales::find()->alias('invalid_sales'); + + $invalid_sales->innerJoin( + 'city_store', + 'city_store.id = invalid_sales.store_id' + ); + + $invalid_sales->innerJoin( + 'store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = invalid_sales.store_id', + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')') + ], + ] + ); + + $invalid_sales->andWhere(['invalid_sales.operation' => Sales::OPERATION_RETURN]) + ->select([ + 'date' => 'DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')', + 'cluster_id' => 'store_dynamic.value_int', + 'store_dynamic_id' => 'store_dynamic.id', + 'store_id' => 'city_store.id' + ]); + $invalid_sales->andWhere([ '>=', - 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + 'DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')', date('Y-m-d', strtotime($date_start)) ]); $invalid_sales->andWhere([ - '<=', - 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', - date('Y-m-d', strtotime('+1 week', strtotime($date_start))) + '<', + 'DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')', + date('Y-m-d', strtotime($date_end)) ]); - $sales_query->andWhere(['sales.operation' => Sales::OPERATION_SALE]); - $sales_query->andWhere(['NOT IN', 'sales.id', $invalid_sales]); + $invalid_sales->groupBy([ + 'DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')', + 'store_dynamic.value_int', + 'store_dynamic.id', + 'city_store.id' + ]); + + $invalid_sales->andWhere('invalid_sales.order_id = \'\''); + /* Конец проверки продажи */ //endregion + $sales_query->andWhere(['sales.operation' => Sales::OPERATION_SALE]); + //Исключение доставки $sales_query->andWhere('sales.order_id = \'\''); $sales_query->addGroupBy([ - 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', - 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', 'store_dynamic.value_int', 'store_dynamic.id', 'city_store.id' @@ -1693,13 +1698,73 @@ class ChartDataSearch /* Конец продажи */ //endregion + + //region Списания + $write_offs_query = WriteOffs::find(); + + $write_offs_query->addSelect([ + 'date' => 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', + 'cluster_id' => 'store_dynamic.value_int', + 'store_dynamic_id' => 'store_dynamic.id', + 'store_id' => 'city_store.id' + ]); + + $write_offs_query->innerJoin( + 'export_import_table', + 'write_offs.store_id = export_import_table.export_val' + ); + + $write_offs_query->innerJoin( + 'city_store', + 'export_import_table.entity_id = city_store.id' + ); + + $write_offs_query->innerJoin( + 'store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = export_import_table.entity_id', + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')') + ], + ] + ); + + $write_offs_query->andWhere([ + 'write_offs.type' => 'Брак' + ]); + + $write_offs_query->addGroupBy([ + 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', + 'store_dynamic.value_int', + 'store_dynamic.id', + 'city_store.id' + ]); + + //endregion + //region Ограничения //region Даты //Продажи $sales_query->andWhere([ 'BETWEEN', - 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + date('Y-m-d', strtotime($date_start)), + date('Y-m-d', strtotime($date_end)) + ]); + + //Списания + $write_offs_query->andWhere([ + 'BETWEEN', + 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', date('Y-m-d', strtotime($date_start)), date('Y-m-d', strtotime($date_end)) ]); @@ -1715,11 +1780,974 @@ class ChartDataSearch $query->addGroupBy(['dates_column.date']); //endregion - //region Тип смены + $query->addSelect([ + 'shift_type' => 'shift_types.shift_type' + ]); - //Продажи - $sales_query->andWhere([ - 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)' => [1, 2] + $query->addGroupBy([ + 'shift_types.shift_type' + ]); + + + //region Уровень данных + + $query->addSelect([ + 'cluster_id' => 'store_dynamic.value_int' + ]); + + $query->addGroupBy([ + 'store_dynamic.value_int' + ]); + + $query->addSelect([ + 'store_id' => 'city_store.id', + ]); + + $query->addGroupBy([ + 'city_store.id', + ]); + + //endregion + //endregion + + //region Атрибут + + //region Продажи + $query->leftJoin( + ['sub_sales' => $sales_query], + [ + 'AND', + 'city_store.id = sub_sales.store_id', + 'store_dynamic.id = sub_sales.store_dynamic_id', + 'dates_column.date = sub_sales.date', + ] + ); + + $query->leftJoin(['invalid_sub_sales' => $invalid_sales], + [ + 'AND', + 'city_store.id = invalid_sub_sales.store_id', + 'store_dynamic.id = invalid_sub_sales.store_dynamic_id', + 'dates_column.date = invalid_sub_sales.date', + ] + ); + + + $sales_query->addSelect([ + 'sales_sum' => 'SUM(sales.summ)', + 'count' => 'COUNT(sales.id)', + ]); + + $invalid_sales->addSelect([ + 'invalid_sales' => 'SUM(invalid_sales.summ)', + 'invalid_count' => 'COUNT(invalid_sales.id)', + ]); + + $query->addSelect([ + 'sales_sum' => 'SUM(sub_sales.sales_sum) - SUM(if (invalid_sub_sales.invalid_sales IS NOT NULL, invalid_sub_sales.invalid_sales, 0))', + 'count_sales' => 'SUM(sub_sales.count) - SUM(if (invalid_sub_sales.invalid_count IS NOT NULL, invalid_sub_sales.invalid_count, 0))', + ]); + + $select_array_sales_query = []; + $select_array_query = []; + $range = array_merge(range(8, 23), range(0, 7)); + + foreach ($range as $item) { + $select_array_sales_query['count_sales_in_' . $item . '_hour'] = 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', ' . $item . ', 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', ' . $item . ', 59, 59), \'%H:%i:%s\'), 1, 0))'; + $select_array_query['count_sales_in_' . $item . '_hour'] = 'SUM(sub_sales.count_sales_in_' . $item . '_hour)'; + } + + $sales_query->addSelect($select_array_sales_query); + $query->addSelect($select_array_query); + + //region Списания + $query->leftJoin( + ['sub_write_offs' => $write_offs_query], + [ + 'AND', + 'city_store.id = sub_write_offs.store_id', + 'store_dynamic.id = sub_write_offs.store_dynamic_id', + 'dates_column.date = sub_write_offs.date', + ] + ); + + + $write_offs_query->addSelect([ + 'write_offs' => 'SUM(write_offs.summ)', + ]); + + $query->addSelect([ + 'write_offs' => 'SUM(sub_write_offs.write_offs)', + ]); + + + //endregion + //endregion + + $query->orderBy([ + 'dates_column.date' => SORT_ASC, + 'store_dynamic.value_int' => SORT_ASC, + 'city_store.id' => SORT_ASC, + 'shift_types.shift_type' => SORT_ASC + ]); + + //var_dump($plan_store_query->asArray()->all()); exit(); + //var_dump($write_offs_query->asArray()->all()); exit(); + //var_dump($sales_query->asArray()->all()); exit(); + //var_dump($admin_payroll_days_query->asArray()->all()); exit(); + //var_dump($invalid_sales->asArray()->all()); exit(); + //var_dump($query->asArray()->all()); exit(); + //var_dump($query->createCommand()->getRawSql()); exit(); + + $message = ""; + + $aliases = RnpAlias::find()->select(['id', 'alias'])->asArray()->all(); + + $aliases = ArrayHelper::map($aliases, 'alias', 'id'); + + $rnp_old_index = RnpIndex::find()->where(['BETWEEN', 'date', $date_start, $date_end])->select([ + 'id', + 'cluster_id', + 'store_id', + 'shift_type', + 'date', + ])->asArray()->all(); + + $ids = []; + foreach ($rnp_old_index as $index) { + $ids[$index['cluster_id'] . $index['store_id'] . $index['shift_type'] . $index['date']] = $index['id']; + } + + $sales_data_batch = $query->asArray()->batch(200); + + $rnpDataRows = []; + $rnpIndexId = []; + + foreach ($sales_data_batch as $sales_data) { + foreach ($sales_data as $datum) { + + $id = -1; + + if (array_key_exists($datum['cluster_id'] . $datum['store_id'] . $datum['shift_type'] . $datum['date'], $ids)) { + $id = $ids[$datum['cluster_id'] . $datum['store_id'] . $datum['shift_type'] . $datum['date']]; + } else { + $rnp_index = new RnpIndex(['cluster_id' => $datum['cluster_id'], 'store_id' => $datum['store_id'], 'shift_type' => $datum['shift_type'], 'date' => $datum['date']]); + + if ($rnp_index->save()) { + $id = $rnp_index->id; + } else { + $message .= "ЗАПИСЬ store_id = " . $datum['store_id'] . " ОТ: " . $datum['date'] . " НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= "Ошибки валидации модели:\n"; + foreach ($rnp_index->getErrors() as $error) { + $message .= $error[0] . "\n"; + } + + } + } + + if ($id != -1) { + + foreach ($datum as $key => $item) { + if (!in_array($key, ['cluster_id', 'store_id', 'date', 'shift_type'])) { + $rnpDataRows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpIndexId[] = $id; + } + } + } + } + } + + try { + $transaction = \Yii::$app->db->beginTransaction(); + RnpData::deleteAll(['AND', ['index_id' => $rnpIndexId], ['NOT IN', 'alias_id', [RnpAlias::USERS_COUNT_ID, RnpAlias::FIRST_MINUS_USER_BONUS_ID, RnpAlias::SECOND_MINUS_USER_BONUS_ID]]]); + Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rnpDataRows)->execute(); + $transaction->commit(); + $message .= "COUNT(RnpRows) = " . count($rnpDataRows); + + } catch (\Exception $exception) { + $transaction->rollBack(); + + $message .= "АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= $exception->getMessage() . "\n"; + } + + return $message; + } + + static function CalculationCompanyDataUsersBonusForChartsShifts($date_start, $date_end) + { + + $query = StoreDynamic::find(); + + $query->innerJoin('city_store', 'store_dynamic.store_id = city_store.id AND store_dynamic.category = 1'); + + // Генерирует столбец дат для каждого магазина в соответствии с кустом + //region Даты + // Нужно для соединения составляющих запроса (left join) + $dates_query = (new Query())->from('( + SELECT :date_end - INTERVAL (units.mul + (10 * tens.mul) + (100 * hundreds.mul) + (1000 * thousands.mul)) DAY AS date + FROM (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS units + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS tens + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS hundreds + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS thousands + ) a' + )->params([':date_end' => date('Y-m-d', strtotime($date_end))]) + ->andWhere([ + 'BETWEEN', 'a.date', date('Y-m-d', strtotime($date_start)), date('Y-m-d', strtotime($date_end)) + ]); + + $dates_query->orderBy(['date' => SORT_ASC]); + + $query->leftJoin( + ['dates_column' => $dates_query], + [ + 'BETWEEN', + 'dates_column.date', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + ] + ); + //endregion + + //Генерирует столбец типов смен для каждой даты + //region Смены + $shift_query = (new Query())->from('(SELECT 1 AS shift_type UNION ALL SELECT 2) shift_types') + ->select(['shift_type' => 'shift_types.shift_type']); + + $query->leftJoin( + ['shift_types' => $shift_query], + [ + '=', + 1, + 1 + ] + ); + //endregion + + //region Продажи + /* Продажи */ + + $sales_query = Sales::find(); + + $sales_query->addSelect([ + 'date' => 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'shift_type' => 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'cluster_id' => 'store_dynamic.value_int', + 'store_dynamic_id' => 'store_dynamic.id', + 'store_id' => 'city_store.id' + ]); + + $sales_query->innerJoin( + 'city_store', + 'city_store.id = sales.store_id' + ); + + $sales_query->innerJoin( + 'store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = sales.store_id', + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + ], + ] + ); + + //region Проверка на возвраты + /* Проверка продажи */ + $invalid_sales = Sales::find()->alias('invalid_sales')->andWhere(['invalid_sales.operation' => Sales::OPERATION_RETURN])->select(['check_id' => 'invalid_sales.sales_check']); + $invalid_sales->andWhere([ + '>=', + 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + date('Y-m-d', strtotime($date_start)) + ]); + + $invalid_sales->andWhere([ + '<=', + 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + date('Y-m-d', strtotime('+1 week', strtotime($date_start))) + ]); + + $sales_query->andWhere(['sales.operation' => Sales::OPERATION_SALE]); + $sales_query->andWhere(['NOT IN', 'sales.id', $invalid_sales]); + /* Конец проверки продажи */ + //endregion + + //Исключение доставки + $sales_query->andWhere('sales.order_id = \'\''); + + $sales_query->addGroupBy([ + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'store_dynamic.value_int', + 'store_dynamic.id', + 'city_store.id' + ]); + /* Конец продажи */ + //endregion + + //region Ограничения + //region Даты + + //Продажи + $sales_query->andWhere([ + 'BETWEEN', + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + date('Y-m-d', strtotime($date_start)), + date('Y-m-d', strtotime($date_end)) + ]); + + //Основной запрос + $query->andWhere([ + 'BETWEEN', + 'dates_column.date', + date('Y-m-d', strtotime($date_start)), + date('Y-m-d', strtotime($date_end)) + ]); + $query->addSelect(['date' => 'dates_column.date']); + $query->addGroupBy(['dates_column.date']); + //endregion + + //region Тип смены + + //Продажи + $sales_query->andWhere([ + 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)' => [1, 2] + ]); + + //Основной запрос + $query->andWhere([ + 'shift_types.shift_type' => [1, 2] + ]); + + $query->addSelect([ + 'shift_type' => 'shift_types.shift_type' + ]); + + $query->addGroupBy([ + 'shift_types.shift_type' + ]); + //endregion + + //region Уровень данных + + $query->addSelect([ + 'cluster_id' => 'store_dynamic.value_int' + ]); + + $query->addGroupBy([ + 'store_dynamic.value_int' + ]); + + $query->addSelect([ + 'store_id' => 'city_store.id', + ]); + + $query->addGroupBy([ + 'city_store.id', + ]); + + //endregion + //endregion + + //region Атрибут + + //region Продажи + $query->leftJoin( + ['sub_sales' => $sales_query], + [ + 'AND', + 'city_store.id = sub_sales.store_id', + 'store_dynamic.id = sub_sales.store_dynamic_id', + 'dates_column.date = sub_sales.date', + 'shift_types.shift_type = sub_sales.shift_type' + ] + ); + + ////region Бонусная + $sales_query->leftJoin('users', 'sales.phone = users.phone') + ->leftJoin('users_bonus', 'users.id = users_bonus.user_id AND sales.id = users_bonus.check_id AND users_bonus.check_id != \'\''); + + ////endregion + + $sales_query->addSelect([ + 'count_users' => 'SUM( IF (sales.phone IS NOT NULL AND sales.phone != \'\', 1, 0))', + 'first_minus_user_bonus' => 'SUM( IF (users.first_minus_balance = users_bonus.date, 1, 0))', + 'second_minus_user_bonus' => 'SUM( IF (users.first_minus_balance < users_bonus.date, 1, 0))' + ]); + + $query->addSelect([ + 'count_users' => 'SUM(sub_sales.count_users)', + 'first_minus_user_bonus' => 'SUM(sub_sales.first_minus_user_bonus)', + 'second_minus_user_bonus' => 'SUM(sub_sales.second_minus_user_bonus)' + ]); + + $query->orderBy([ + 'dates_column.date' => SORT_ASC, + 'store_dynamic.value_int' => SORT_ASC, + 'city_store.id' => SORT_ASC, + 'shift_types.shift_type' => SORT_ASC + ]); + + $message = ""; + + $aliases = RnpAlias::find()->select(['id', 'alias'])->asArray()->all(); + + $aliases = ArrayHelper::map($aliases, 'alias', 'id'); + + $rnp_old_index = RnpIndex::find()->where(['BETWEEN', 'date', $date_start, $date_end])->select([ + 'id', + 'cluster_id', + 'store_id', + 'shift_type', + 'date', + ])->asArray()->all(); + + $ids = []; + foreach ($rnp_old_index as $index) { + $ids[$index['cluster_id'] . $index['store_id'] . $index['shift_type'] . $index['date']] = $index['id']; + } + + //var_dump($date_start); exit(); + $sales_data_batch = $query->asArray()->batch(200); + + $rnpDataRows = []; + $rnpIndexId = []; + + foreach ($sales_data_batch as $sales_data) { + foreach ($sales_data as $datum) { + + $id = -1; + + if (array_key_exists($datum['cluster_id'] . $datum['store_id'] . $datum['shift_type'] . $datum['date'], $ids)) { + $id = $ids[$datum['cluster_id'] . $datum['store_id'] . $datum['shift_type'] . $datum['date']]; + } else { + $rnp_index = new RnpIndex(['cluster_id' => $datum['cluster_id'], 'store_id' => $datum['store_id'], 'shift_type' => $datum['shift_type'], 'date' => $datum['date']]); + + if ($rnp_index->save()) { + $id = $rnp_index->id; + } else { + $message .= "ЗАПИСЬ store_id = " . $datum['store_id'] . " ОТ: " . $datum['date'] . " НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= "Ошибки валидации модели:\n"; + foreach ($rnp_index->getErrors() as $error) { + $message .= $error[0] . "\n"; + } + + } + } + + if ($id != -1) { + + foreach ($datum as $key => $item) { + if (!in_array($key, ['cluster_id', 'store_id', 'date', 'shift_type'])) { + $rnpDataRows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpIndexId[] = $id; + } + } + } + } + } + + try { + $transaction = \Yii::$app->db->beginTransaction(); + RnpData::deleteAll(['AND', ['index_id' => $rnpIndexId], ['alias_id' => [RnpAlias::USERS_COUNT_ID, RnpAlias::FIRST_MINUS_USER_BONUS_ID, RnpAlias::SECOND_MINUS_USER_BONUS_ID]]]); + Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rnpDataRows)->execute(); + $transaction->commit(); + $message .= "COUNT(RnpRows) = " . count($rnpDataRows); + + } catch (\Exception $exception) { + $transaction->rollBack(); + + $message .= "АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= $exception->getMessage() . "\n"; + } + + return $message; + } + + static function CalculationCompanyDataUsersBonusForChartsDay($date_start, $date_end) + { + + $query = StoreDynamic::find(); + + $query->innerJoin('city_store', 'store_dynamic.store_id = city_store.id AND store_dynamic.category = 1'); + + // Генерирует столбец дат для каждого магазина в соответствии с кустом + //region Даты + // Нужно для соединения составляющих запроса (left join) + $dates_query = (new Query())->from('( + SELECT :date_end - INTERVAL (units.mul + (10 * tens.mul) + (100 * hundreds.mul) + (1000 * thousands.mul)) DAY AS date + FROM (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS units + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS tens + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS hundreds + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS thousands + ) a' + )->params([':date_end' => date('Y-m-d', strtotime($date_end))]) + ->andWhere([ + 'BETWEEN', 'a.date', date('Y-m-d', strtotime($date_start)), date('Y-m-d', strtotime($date_end)) + ]); + + $dates_query->orderBy(['date' => SORT_ASC]); + + $query->leftJoin( + ['dates_column' => $dates_query], + [ + 'BETWEEN', + 'dates_column.date', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + ] + ); + //endregion + + //Генерирует столбец типов смен для каждой даты + //region Смены + $shift_query = (new Query())->from('(SELECT 4 AS shift_type) shift_types') + ->select(['shift_type' => 'shift_types.shift_type']); + + $query->leftJoin( + ['shift_types' => $shift_query], + [ + '=', + 1, + 1 + ] + ); + //endregion + + //region Продажи + /* Продажи */ + + $sales_query = Sales::find(); + + $sales_query->addSelect([ + 'date' => 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + 'cluster_id' => 'store_dynamic.value_int', + 'store_dynamic_id' => 'store_dynamic.id', + 'store_id' => 'city_store.id' + ]); + + $sales_query->innerJoin( + 'city_store', + 'city_store.id = sales.store_id' + ); + + $sales_query->innerJoin( + 'store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = sales.store_id', + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(sales.date, \'%Y-%m-%d\')') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(sales.date, \'%Y-%m-%d\')') + ], + ] + ); + + //region Проверка на возвраты + /* Проверка продажи */ + $invalid_sales = Sales::find()->alias('invalid_sales')->andWhere(['invalid_sales.operation' => Sales::OPERATION_RETURN])->select(['check_id' => 'invalid_sales.sales_check']); + $invalid_sales->andWhere([ + '>=', + 'DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')', + date('Y-m-d', strtotime($date_start)) + ]); + + $invalid_sales->andWhere([ + '<=', + 'DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')', + date('Y-m-d', strtotime('+1 week', strtotime($date_start))) + ]); + + $sales_query->andWhere(['sales.operation' => Sales::OPERATION_SALE]); + $sales_query->andWhere(['NOT IN', 'sales.id', $invalid_sales]); + /* Конец проверки продажи */ + //endregion + + //Исключение доставки + $sales_query->andWhere('sales.order_id = \'\''); + + $sales_query->addGroupBy([ + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + 'store_dynamic.value_int', + 'store_dynamic.id', + 'city_store.id' + ]); + /* Конец продажи */ + //endregion + + //region Ограничения + //region Даты + + //Продажи + $sales_query->andWhere([ + 'BETWEEN', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + date('Y-m-d', strtotime($date_start)), + date('Y-m-d', strtotime($date_end)) + ]); + + //Основной запрос + $query->andWhere([ + 'BETWEEN', + 'dates_column.date', + date('Y-m-d', strtotime($date_start)), + date('Y-m-d', strtotime($date_end)) + ]); + $query->addSelect(['date' => 'dates_column.date']); + $query->addGroupBy(['dates_column.date']); + //endregion + + //Основной запрос + $query->addSelect([ + 'shift_type' => 'shift_types.shift_type' + ]); + + $query->addGroupBy([ + 'shift_types.shift_type' + ]); + //endregion + + //region Уровень данных + + $query->addSelect([ + 'cluster_id' => 'store_dynamic.value_int' + ]); + + $query->addGroupBy([ + 'store_dynamic.value_int' + ]); + + $query->addSelect([ + 'store_id' => 'city_store.id', + ]); + + $query->addGroupBy([ + 'city_store.id', + ]); + + //endregion + //endregion + + //region Атрибут + + //region Продажи + $query->leftJoin( + ['sub_sales' => $sales_query], + [ + 'AND', + 'city_store.id = sub_sales.store_id', + 'store_dynamic.id = sub_sales.store_dynamic_id', + 'dates_column.date = sub_sales.date', + ] + ); + + ////region Бонусная + $sales_query->leftJoin('users', 'sales.phone = users.phone') + ->leftJoin('users_bonus', 'users.id = users_bonus.user_id AND sales.id = users_bonus.check_id AND users_bonus.check_id != \'\''); + + ////endregion + + $sales_query->addSelect([ + 'count_users' => 'SUM( IF (sales.phone IS NOT NULL AND sales.phone != \'\', 1, 0))', + 'first_minus_user_bonus' => 'SUM( IF (users.first_minus_balance = users_bonus.date, 1, 0))', + 'second_minus_user_bonus' => 'SUM( IF (users.first_minus_balance < users_bonus.date, 1, 0))' + ]); + + $query->addSelect([ + 'count_users' => 'SUM(sub_sales.count_users)', + 'first_minus_user_bonus' => 'SUM(sub_sales.first_minus_user_bonus)', + 'second_minus_user_bonus' => 'SUM(sub_sales.second_minus_user_bonus)' + ]); + + $query->orderBy([ + 'dates_column.date' => SORT_ASC, + 'store_dynamic.value_int' => SORT_ASC, + 'city_store.id' => SORT_ASC, + 'shift_types.shift_type' => SORT_ASC + ]); + + $message = ""; + + $aliases = RnpAlias::find()->select(['id', 'alias'])->asArray()->all(); + + $aliases = ArrayHelper::map($aliases, 'alias', 'id'); + + $rnp_old_index = RnpIndex::find()->where(['BETWEEN', 'date', $date_start, $date_end])->select([ + 'id', + 'cluster_id', + 'store_id', + 'shift_type', + 'date', + ])->asArray()->all(); + + $ids = []; + foreach ($rnp_old_index as $index) { + $ids[$index['cluster_id'] . $index['store_id'] . $index['shift_type'] . $index['date']] = $index['id']; + } + + $sales_data_batch = $query->asArray()->batch(200); + + $rnpDataRows = []; + $rnpIndexId = []; + + foreach ($sales_data_batch as $sales_data) { + foreach ($sales_data as $datum) { + + $id = -1; + + if (array_key_exists($datum['cluster_id'] . $datum['store_id'] . $datum['shift_type'] . $datum['date'], $ids)) { + $id = $ids[$datum['cluster_id'] . $datum['store_id'] . $datum['shift_type'] . $datum['date']]; + } else { + $rnp_index = new RnpIndex(['cluster_id' => $datum['cluster_id'], 'store_id' => $datum['store_id'], 'shift_type' => $datum['shift_type'], 'date' => $datum['date']]); + + if ($rnp_index->save()) { + $id = $rnp_index->id; + } else { + $message .= "ЗАПИСЬ store_id = " . $datum['store_id'] . " ОТ: " . $datum['date'] . " НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= "Ошибки валидации модели:\n"; + foreach ($rnp_index->getErrors() as $error) { + $message .= $error[0] . "\n"; + } + + } + } + + if ($id != -1) { + + foreach ($datum as $key => $item) { + if (!in_array($key, ['cluster_id', 'store_id', 'date', 'shift_type'])) { + $rnpDataRows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpIndexId[] = $id; + } + } + } + } + } + + try { + $transaction = \Yii::$app->db->beginTransaction(); + RnpData::deleteAll(['AND', ['index_id' => $rnpIndexId], ['alias_id' => [RnpAlias::USERS_COUNT_ID, RnpAlias::FIRST_MINUS_USER_BONUS_ID, RnpAlias::SECOND_MINUS_USER_BONUS_ID]]]); + Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rnpDataRows)->execute(); + $transaction->commit(); + $message .= "COUNT(RnpRows) = " . count($rnpDataRows); + + } catch (\Exception $exception) { + $transaction->rollBack(); + + $message .= "АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= $exception->getMessage() . "\n"; + } + + return $message; + } + + static function CalculationCompanyDataMatrixSalesForChartsShifts($date_start, $date_end) + { + + $query = StoreDynamic::find(); + + $query->innerJoin('city_store', 'store_dynamic.store_id = city_store.id AND store_dynamic.category = 1'); + + // Генерирует столбец дат для каждого магазина в соответствии с кустом + //region Даты + // Нужно для соединения составляющих запроса (left join) + $dates_query = (new Query())->from('( + SELECT :date_end - INTERVAL (units.mul + (10 * tens.mul) + (100 * hundreds.mul) + (1000 * thousands.mul)) DAY AS date + FROM (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS units + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS tens + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS hundreds + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS thousands + ) a' + )->params([':date_end' => date('Y-m-d', strtotime($date_end))]) + ->andWhere([ + 'BETWEEN', 'a.date', date('Y-m-d', strtotime($date_start)), date('Y-m-d', strtotime($date_end)) + ]); + + $dates_query->orderBy(['date' => SORT_ASC]); + + $query->leftJoin( + ['dates_column' => $dates_query], + [ + 'BETWEEN', + 'dates_column.date', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + ] + ); + //endregion + + //Генерирует столбец типов смен для каждой даты + //region Смены + $shift_query = (new Query())->from('(SELECT 1 AS shift_type UNION ALL SELECT 2) shift_types') + ->select(['shift_type' => 'shift_types.shift_type']); + + $query->leftJoin( + ['shift_types' => $shift_query], + [ + '=', + 1, + 1 + ] + ); + //endregion + + //region Матрица + $matrix_query = Sales::find(); + + $matrix_query->addSelect([ + 'date' => 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'shift_type' => 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'cluster_id' => 'store_dynamic.value_int', + 'store_dynamic_id' => 'store_dynamic.id', + 'store_id' => 'city_store.id' + ]); + + $matrix_query->innerJoin( + 'city_store', + 'city_store.id = sales.store_id' + ); + + $matrix_query->innerJoin( + 'store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = sales.store_id', + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + ], + ] + ); + + //region Проверка на возвраты + /* Проверка продажи */ + $invalid_sales = Sales::find()->alias('invalid_sales')->andWhere(['invalid_sales.operation' => Sales::OPERATION_RETURN])->select(['check_id' => 'invalid_sales.sales_check']); + $invalid_sales->andWhere([ + '>=', + 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + date('Y-m-d', strtotime($date_start)) + ]); + + $invalid_sales->andWhere([ + '<=', + 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + date('Y-m-d', strtotime('+1 week', strtotime($date_start))) + ]); + /* Конец проверки продажи */ + //endregion + + //Исключение доставки + $matrix_query->andWhere('sales.order_id = \'\''); + /* Конец продажи */ + + $matrix_query->andWhere(['sales.operation' => Sales::OPERATION_SALE]); + $matrix_query->andWhere(['NOT IN', 'sales.id', $invalid_sales]); + + $matrix_query->addGroupBy([ + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'store_dynamic.value_int', + 'store_dynamic.id', + 'city_store.id' + ]); + + $matrix_query->andWhere([ + 'AND', + [ + '>=', + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + date('Y-m-d', strtotime($date_start)) + ], + [ + '<=', + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + date('Y-m-d', strtotime($date_end)) + ] + ]); + + $matrix_query->innerJoin('sales_products', 'sales.id = sales_products.check_id') + ->innerJoin('products_1c', 'sales_products.product_id = products_1c.id') + ->innerJoin('products_class', 'products_1c.parent_id = products_class.category_id AND products_class.tip = \'matrix\''); + + $matrix_season_guid = Products1c::find()->where(['LIKE', 'name', 'Сезонная матрица'])->select(['id'])->column()[0] ?? ''; + $matrix_base_guid = Products1c::find()->where(['LIKE', 'name', 'Матрица базовая'])->select(['id'])->column()[0] ?? ''; + $matrix_new_guid = Products1c::find()->where(['LIKE', 'name', 'Новая матрица'])->select(['id'])->column()[0] ?? ''; + + $matrix_group = Products1c::find() + ->andWhere( + ['IN', + 'products_1c.parent_id', + [ + $matrix_season_guid, // Сезонная + $matrix_base_guid, // Базовая + $matrix_new_guid, // Новая + ], + ] + ) + ->select([ + 'id' => 'products_1c.id', + 'parent_id' => 'products_1c.parent_id' + ]); + + $matrix_query->leftJoin(['matrix_group' => $matrix_group], '(products_1c.id = matrix_group.id OR products_1c.parent_id = matrix_group.id)') + ->addSelect([ + 'matrix_base_summ' => 'SUM(if (matrix_group.parent_id = \'' . $matrix_base_guid . '\' OR matrix_group.id = \'' . $matrix_base_guid . '\', sales_products.summ, 0))', // Базовая + 'matrix_season_summ' => 'SUM(if (matrix_group.parent_id = \'' . $matrix_season_guid . '\' OR matrix_group.id = \'' . $matrix_season_guid . '\', sales_products.summ, 0))', // Сезонная + 'matrix_new_summ' => 'SUM(if (matrix_group.parent_id = \'' . $matrix_new_guid . '\' OR matrix_group.id = \'' . $matrix_new_guid . '\', sales_products.summ, 0))' // Новая + ]); + + $query->leftJoin( + ['matrix' => $matrix_query], + [ + 'AND', + 'city_store.id = matrix.store_id', + 'store_dynamic.id = matrix.store_dynamic_id', + 'dates_column.date = matrix.date', + 'shift_types.shift_type = matrix.shift_type' + ] + ); + // endregion + + //region Ограничения + //region Даты + + //Основной запрос + $query->andWhere([ + 'BETWEEN', + 'dates_column.date', + date('Y-m-d', strtotime($date_start)), + date('Y-m-d', strtotime($date_end)) + ]); + + $query->addSelect(['date' => 'dates_column.date']); + $query->addGroupBy(['dates_column.date']); + //endregion + + //region Тип смены + + //Продажи + $matrix_query->andWhere([ + 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)' => [1, 2] ]); //Основной запрос @@ -1757,38 +2785,15 @@ class ChartDataSearch //endregion //endregion - //region Атрибут - - //region Продажи - $query->leftJoin( - ['sub_sales' => $sales_query], - [ - 'AND', - 'city_store.id = sub_sales.store_id', - 'store_dynamic.id = sub_sales.store_dynamic_id', - 'dates_column.date = sub_sales.date', - 'shift_types.shift_type = sub_sales.shift_type' - ] - ); - - ////region Бонусная - $sales_query->leftJoin('users', 'sales.phone = users.phone') - ->leftJoin('users_bonus', 'users.id = users_bonus.user_id AND sales.id = users_bonus.check_id AND users_bonus.check_id != \'\''); - - ////endregion - - $sales_query->addSelect([ - 'count_users' => 'SUM( IF (sales.phone IS NOT NULL AND sales.phone != \'\', 1, 0))', - 'first_minus_user_bonus' => 'SUM( IF (users.first_minus_balance = users_bonus.date, 1, 0))', - 'second_minus_user_bonus' => 'SUM( IF (users.first_minus_balance < users_bonus.date, 1, 0))' - ]); - $query->addSelect([ - 'count_users' => 'SUM(sub_sales.count_users)', - 'first_minus_user_bonus' => 'SUM(sub_sales.first_minus_user_bonus)', - 'second_minus_user_bonus' => 'SUM(sub_sales.second_minus_user_bonus)' + 'matrix_base_summ' => 'SUM(matrix.matrix_base_summ)', + 'matrix_season_summ' => 'SUM(matrix.matrix_season_summ)', + 'matrix_new_summ' => 'SUM(matrix.matrix_new_summ)', ]); + + //endregion + $query->orderBy([ 'dates_column.date' => SORT_ASC, 'store_dynamic.value_int' => SORT_ASC, @@ -1817,6 +2822,9 @@ class ChartDataSearch $sales_data_batch = $query->asArray()->batch(200); + $rnpDataRows = []; + $rnpIndexId = []; + foreach ($sales_data_batch as $sales_data) { foreach ($sales_data as $datum) { @@ -1840,34 +2848,35 @@ class ChartDataSearch } if ($id != -1) { - $rows = []; foreach ($datum as $key => $item) { if (!in_array($key, ['cluster_id', 'store_id', 'date', 'shift_type'])) { - $rows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpDataRows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpIndexId[] = $id; } } + } + } + } - try { - $transaction = \Yii::$app->db->beginTransaction(); - RnpData::deleteAll(['AND', ['index_id' => $id], ['alias_id' => [RnpAlias::USERS_COUNT_ID, RnpAlias::FIRST_MINUS_USER_BONUS_ID, RnpAlias::SECOND_MINUS_USER_BONUS_ID]]]); - Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rows)->execute(); - $transaction->commit(); + try { + $transaction = \Yii::$app->db->beginTransaction(); + RnpData::deleteAll(['AND', ['index_id' => $rnpIndexId], ['alias_id' => [RnpAlias::MATRIX_NEW_SUMM_ID, RnpAlias::MATRIX_SEASON_SUMM_ID, RnpAlias::MATRIX_BASE_SUMM_ID]]]); + Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rnpDataRows)->execute(); + $transaction->commit(); + $message .= "COUNT(RnpRows) = " . count($rnpDataRows); - } catch (\Exception $exception) { - $transaction->rollBack(); + } catch (\Exception $exception) { + $transaction->rollBack(); - $message .= "ЗАПИСЬ store_id = " . $datum['store_id'] . " ОТ: " . $datum['date'] . " АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; - $message .= $exception->getMessage() . "\n"; - } - } - } + $message .= "АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= $exception->getMessage() . "\n"; } return $message; } - static function CalculationCompanyDataMatrixSalesForCharts($date_start, $date_end) + static function CalculationCompanyDataMatrixSalesForChartsDay($date_start, $date_end) { $query = StoreDynamic::find(); @@ -1904,7 +2913,7 @@ class ChartDataSearch //Генерирует столбец типов смен для каждой даты //region Смены - $shift_query = (new Query())->from('(SELECT 1 AS shift_type UNION ALL SELECT 2) shift_types') + $shift_query = (new Query())->from('(SELECT 4 AS shift_type) shift_types') ->select(['shift_type' => 'shift_types.shift_type']); $query->leftJoin( @@ -1921,8 +2930,7 @@ class ChartDataSearch $matrix_query = Sales::find(); $matrix_query->addSelect([ - 'date' => 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', - 'shift_type' => 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'date' => 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', 'cluster_id' => 'store_dynamic.value_int', 'store_dynamic_id' => 'store_dynamic.id', 'store_id' => 'city_store.id' @@ -1941,12 +2949,12 @@ class ChartDataSearch [ '<=', new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), - new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + new Expression('DATE_FORMAT(sales.date, \'%Y-%m-%d\')') ], [ '>', new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), - new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + new Expression('DATE_FORMAT(sales.date, \'%Y-%m-%d\')') ], ] ); @@ -1956,13 +2964,13 @@ class ChartDataSearch $invalid_sales = Sales::find()->alias('invalid_sales')->andWhere(['invalid_sales.operation' => Sales::OPERATION_RETURN])->select(['check_id' => 'invalid_sales.sales_check']); $invalid_sales->andWhere([ '>=', - 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + 'DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')', date('Y-m-d', strtotime($date_start)) ]); $invalid_sales->andWhere([ '<=', - 'if (HOUR(invalid_sales.date) < 8, DATE_FORMAT(DATE_SUB(invalid_sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\'))', + 'DATE_FORMAT(invalid_sales.date, \'%Y-%m-%d\')', date('Y-m-d', strtotime('+1 week', strtotime($date_start))) ]); /* Конец проверки продажи */ @@ -1976,8 +2984,7 @@ class ChartDataSearch $matrix_query->andWhere(['NOT IN', 'sales.id', $invalid_sales]); $matrix_query->addGroupBy([ - 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', - 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', 'store_dynamic.value_int', 'store_dynamic.id', 'city_store.id' @@ -1987,12 +2994,12 @@ class ChartDataSearch 'AND', [ '>=', - 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', date('Y-m-d', strtotime($date_start)) ], [ '<=', - 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', date('Y-m-d', strtotime($date_end)) ] ]); @@ -2035,7 +3042,6 @@ class ChartDataSearch 'city_store.id = matrix.store_id', 'store_dynamic.id = matrix.store_dynamic_id', 'dates_column.date = matrix.date', - 'shift_types.shift_type = matrix.shift_type' ] ); // endregion @@ -2057,16 +3063,7 @@ class ChartDataSearch //region Тип смены - //Продажи - $matrix_query->andWhere([ - 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)' => [1, 2] - ]); - //Основной запрос - $query->andWhere([ - 'shift_types.shift_type' => [1, 2] - ]); - $query->addSelect([ 'shift_type' => 'shift_types.shift_type' ]); @@ -2134,6 +3131,9 @@ class ChartDataSearch $sales_data_batch = $query->asArray()->batch(200); + $rnpDataRows = []; + $rnpIndexId = []; + foreach ($sales_data_batch as $sales_data) { foreach ($sales_data as $datum) { @@ -2157,28 +3157,29 @@ class ChartDataSearch } if ($id != -1) { - $rows = []; foreach ($datum as $key => $item) { if (!in_array($key, ['cluster_id', 'store_id', 'date', 'shift_type'])) { - $rows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpDataRows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpIndexId[] = $id; } } + } + } + } - try { - $transaction = \Yii::$app->db->beginTransaction(); - RnpData::deleteAll(['AND', ['index_id' => $id], ['IN', 'alias_id', [RnpAlias::MATRIX_NEW_SUMM_ID, RnpAlias::MATRIX_SEASON_SUMM_ID, RnpAlias::MATRIX_BASE_SUMM_ID]]]); - Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rows)->execute(); - $transaction->commit(); + try { + $transaction = \Yii::$app->db->beginTransaction(); + RnpData::deleteAll(['AND', ['index_id' => $rnpIndexId], ['alias_id' => [RnpAlias::MATRIX_NEW_SUMM_ID, RnpAlias::MATRIX_SEASON_SUMM_ID, RnpAlias::MATRIX_BASE_SUMM_ID]]]); + Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rnpDataRows)->execute(); + $transaction->commit(); + $message .= "COUNT(RnpRows) = " . count($rnpDataRows); - } catch (\Exception $exception) { - $transaction->rollBack(); + } catch (\Exception $exception) { + $transaction->rollBack(); - $message .= "ЗАПИСЬ store_id = " . $datum['store_id'] . " ОТ: " . $datum['date'] . " АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; - $message .= $exception->getMessage() . "\n"; - } - } - } + $message .= "АТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= $exception->getMessage() . "\n"; } return $message; @@ -2195,10 +3196,11 @@ class ChartDataSearch $data['attribute']['count_sales_in_hour']['data'] = array_merge(array_slice($data['attribute']['count_sales_in_hour']['data'], 20, 4), array_slice($data['attribute']['count_sales_in_hour']['data'], 0, 8)); $data['attribute']['avg_count_sales_in_hour']['data'] = array_merge(array_slice($data['attribute']['avg_count_sales_in_hour']['data'], 20, 4), array_slice($data['attribute']['avg_count_sales_in_hour']['data'], 0, 8)); - } else { + } else if ($shift_type === 3) { $data['attribute']['count_sales_in_hour']['data'] = array_merge(array_slice($data['attribute']['count_sales_in_hour']['data'], 8, 12), array_slice($data['attribute']['count_sales_in_hour']['data'], 20, 4), array_slice($data['attribute']['count_sales_in_hour']['data'], 0, 8)); $data['attribute']['avg_count_sales_in_hour']['data'] = array_merge(array_slice($data['attribute']['avg_count_sales_in_hour']['data'], 8, 12), array_slice($data['attribute']['avg_count_sales_in_hour']['data'], 20, 4), array_slice($data['attribute']['avg_count_sales_in_hour']['data'], 0, 8)); } + } } \ No newline at end of file diff --git a/erp24/records/CheckConduct.php b/erp24/records/CheckConduct.php old mode 100755 new mode 100644 diff --git a/erp24/records/CheckConductItem.php b/erp24/records/CheckConductItem.php old mode 100755 new mode 100644 diff --git a/erp24/records/CheckCriteria.php b/erp24/records/CheckCriteria.php old mode 100755 new mode 100644 diff --git a/erp24/records/CheckCriteriaItem.php b/erp24/records/CheckCriteriaItem.php old mode 100755 new mode 100644 diff --git a/erp24/records/CheckGroup.php b/erp24/records/CheckGroup.php old mode 100755 new mode 100644 diff --git a/erp24/records/CheckStatus.php b/erp24/records/CheckStatus.php old mode 100755 new mode 100644 diff --git a/erp24/records/CheckType.php b/erp24/records/CheckType.php old mode 100755 new mode 100644 diff --git a/erp24/records/City.php b/erp24/records/City.php old mode 100755 new mode 100644 diff --git a/erp24/records/CityStoreSearch.php b/erp24/records/CityStoreSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/Cluster.php b/erp24/records/Cluster.php old mode 100755 new mode 100644 diff --git a/erp24/records/ClusterCalendar.php b/erp24/records/ClusterCalendar.php old mode 100755 new mode 100644 diff --git a/erp24/records/ClusterCalendarCategoryDict.php b/erp24/records/ClusterCalendarCategoryDict.php old mode 100755 new mode 100644 diff --git a/erp24/records/ClusterCalendarCategoryDictSearch.php b/erp24/records/ClusterCalendarCategoryDictSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/ClusterSearch.php b/erp24/records/ClusterSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/Comment.php b/erp24/records/Comment.php old mode 100755 new mode 100644 diff --git a/erp24/records/Companies.php b/erp24/records/Companies.php old mode 100755 new mode 100644 diff --git a/erp24/records/Company.php b/erp24/records/Company.php old mode 100755 new mode 100644 diff --git a/erp24/records/CompanyFunctions.php b/erp24/records/CompanyFunctions.php old mode 100755 new mode 100644 diff --git a/erp24/records/CompanySearch.php b/erp24/records/CompanySearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/CompanyStores.php b/erp24/records/CompanyStores.php old mode 100755 new mode 100644 diff --git a/erp24/records/Contest001.php b/erp24/records/Contest001.php old mode 100755 new mode 100644 diff --git a/erp24/records/CreateChecks.php b/erp24/records/CreateChecks.php old mode 100755 new mode 100644 diff --git a/erp24/records/CreateChecks2.php b/erp24/records/CreateChecks2.php old mode 100755 new mode 100644 diff --git a/erp24/records/CreateChecksBags.php b/erp24/records/CreateChecksBags.php old mode 100755 new mode 100644 diff --git a/erp24/records/CrmMenu.php b/erp24/records/CrmMenu.php index f3bd301..68e0392 100755 --- a/erp24/records/CrmMenu.php +++ b/erp24/records/CrmMenu.php @@ -17,7 +17,7 @@ class CrmMenu extends ActiveRecord { public static function tableName() { - return '{{%crm_menu}}'; + return 'crm_menu'; } /** Свёрнуто ли меню для данной страницы */ diff --git a/erp24/records/CrmMenuPermission.php b/erp24/records/CrmMenuPermission.php old mode 100755 new mode 100644 diff --git a/erp24/records/CrmMenuPermissionSearch.php b/erp24/records/CrmMenuPermissionSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/EmployeeOnShift.php b/erp24/records/EmployeeOnShift.php old mode 100755 new mode 100644 index f23878a..11dbe4f --- a/erp24/records/EmployeeOnShift.php +++ b/erp24/records/EmployeeOnShift.php @@ -19,6 +19,7 @@ use Yii; * @property int $created_by Кто создал, ID из Admin * @property string $store_id GUID магазина * @property int $price Ставка в рублях за час + * @property int $salary_shift Ставка в рублях за смену * @property int $status 0 - в ожидании, 1 - подтверждено, 2 - отказано * @property int $status_source -1 - получена ошибка в системе, 0 - не создано, 1 - создано в 1С */ @@ -50,6 +51,7 @@ class EmployeeOnShift extends \yii\db\ActiveRecord [['guid', 'phone', 'created_at', 'shift_date', 'shift_type', 'datetime_start', 'datetime_end', 'created_by', 'store_id', 'price'], 'required'], [['created_at', 'shift_date', 'datetime_start', 'datetime_end'], 'safe'], [['shift_type', 'created_by', 'price', 'status', 'status_source'], 'integer'], + [['salary_shift'], 'in', 'range' => Timetable::getSalariesDay(), 'skipOnEmpty' => false], [['guid', 'store_id'], 'string', 'max' => 36], [['phone'], 'string', 'max' => 16], [['first_name', 'last_name'], 'string', 'max' => 40], @@ -75,6 +77,7 @@ class EmployeeOnShift extends \yii\db\ActiveRecord 'created_by' => 'Created By', 'store_id' => 'Store ID', 'price' => 'Price', + 'salary_shift' => 'Salary Shift', 'status' => 'Status', 'status_source' => 'status_source', ]; diff --git a/erp24/records/ErrorInfoErp.php b/erp24/records/ErrorInfoErp.php old mode 100755 new mode 100644 diff --git a/erp24/records/ErrorInfoErpSearch.php b/erp24/records/ErrorInfoErpSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/ErrorLog.php b/erp24/records/ErrorLog.php index 811dc4b..e6d28b7 100755 --- a/erp24/records/ErrorLog.php +++ b/erp24/records/ErrorLog.php @@ -25,7 +25,7 @@ class ErrorLog extends ActiveRecord public static function tableName() { - return '{{%error_log}}'; + return 'error_log'; } } \ No newline at end of file diff --git a/erp24/records/ExportImport.php b/erp24/records/ExportImport.php old mode 100755 new mode 100644 diff --git a/erp24/records/Firms.php b/erp24/records/Firms.php old mode 100755 new mode 100644 diff --git a/erp24/records/FirmsGroupPrefix.php b/erp24/records/FirmsGroupPrefix.php old mode 100755 new mode 100644 diff --git a/erp24/records/FunctionRegulations.php b/erp24/records/FunctionRegulations.php old mode 100755 new mode 100644 diff --git a/erp24/records/Grade.php b/erp24/records/Grade.php old mode 100755 new mode 100644 diff --git a/erp24/records/GradeGroup.php b/erp24/records/GradeGroup.php old mode 100755 new mode 100644 diff --git a/erp24/records/GradePrice.php b/erp24/records/GradePrice.php old mode 100755 new mode 100644 diff --git a/erp24/records/Holiday.php b/erp24/records/Holiday.php index 3a816b3..e61a3ec 100755 --- a/erp24/records/Holiday.php +++ b/erp24/records/Holiday.php @@ -20,7 +20,7 @@ class Holiday extends ActiveRecord public static function tableName() { - return '{{%holiday}}'; + return 'holiday'; } public function attributeLabels() diff --git a/erp24/records/ImageDocumentLink.php b/erp24/records/ImageDocumentLink.php old mode 100755 new mode 100644 diff --git a/erp24/records/Images.php b/erp24/records/Images.php old mode 100755 new mode 100644 index 52baffa..fe07bb9 --- a/erp24/records/Images.php +++ b/erp24/records/Images.php @@ -112,15 +112,23 @@ class Images extends \yii\db\ActiveRecord return false; } - public static function isImageFile($file) + public static function isImageFile($file, $extension = null) { $result = false; if(!empty($file)) { $ar_file_name = explode('/', $file->type); - $type = ($ar_file_name[array_key_first($ar_file_name)]); + $type = array_shift($ar_file_name); + if ($type === 'image') { - $result = true; + if (!empty($extension) && is_array($extension)) { + $extensionFile = array_shift($ar_file_name); + if (in_array($extensionFile, $extension)) { + $result = true; + } + } else { + $result = true; + } } } diff --git a/erp24/records/Incoming.php b/erp24/records/Incoming.php old mode 100755 new mode 100644 diff --git a/erp24/records/KikFeedbackCategory.php b/erp24/records/KikFeedbackCategory.php old mode 100755 new mode 100644 diff --git a/erp24/records/KikFeedbackRequest.php b/erp24/records/KikFeedbackRequest.php old mode 100755 new mode 100644 diff --git a/erp24/records/KikFeedbackSource.php b/erp24/records/KikFeedbackSource.php old mode 100755 new mode 100644 diff --git a/erp24/records/KikFeedbackSubcategory.php b/erp24/records/KikFeedbackSubcategory.php old mode 100755 new mode 100644 diff --git a/erp24/records/KikFeedbackVerdict.php b/erp24/records/KikFeedbackVerdict.php old mode 100755 new mode 100644 diff --git a/erp24/records/LessonsGroup.php b/erp24/records/LessonsGroup.php old mode 100755 new mode 100644 diff --git a/erp24/records/MatrixErp.php b/erp24/records/MatrixErp.php old mode 100755 new mode 100644 diff --git a/erp24/records/MatrixErpMedia.php b/erp24/records/MatrixErpMedia.php old mode 100755 new mode 100644 diff --git a/erp24/records/MatrixErpProperty.php b/erp24/records/MatrixErpProperty.php old mode 100755 new mode 100644 index 0e844fd..87379f4 --- a/erp24/records/MatrixErpProperty.php +++ b/erp24/records/MatrixErpProperty.php @@ -40,7 +40,12 @@ class MatrixErpProperty extends \yii\db\ActiveRecord [['description'], 'string'], [['id'], 'integer'], [['image_id', 'created_admin_id', 'updated_admin_id'], 'integer'], - [['imageFile'], 'file', 'extensions' => 'png, jpg',], + [ + [ + 'imageFile' + ], + 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg', 'checkExtensionByMimeType' => false + ], [['mediaFile'], 'safe'], [['guid', 'date', 'created_at', 'updated_at'], 'string', 'max' => 100], [['url_link_video'], 'string', 'max' => 255], diff --git a/erp24/records/MatrixErpPropertySearch.php b/erp24/records/MatrixErpPropertySearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/MatrixErpSearch.php b/erp24/records/MatrixErpSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/Meeting.php b/erp24/records/Meeting.php old mode 100755 new mode 100644 diff --git a/erp24/records/MeetingLinkAdmin.php b/erp24/records/MeetingLinkAdmin.php old mode 100755 new mode 100644 diff --git a/erp24/records/MeetingSearch.php b/erp24/records/MeetingSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/MessagerUser.php b/erp24/records/MessagerUser.php old mode 100755 new mode 100644 diff --git a/erp24/records/MultipleModel.php b/erp24/records/MultipleModel.php old mode 100755 new mode 100644 diff --git a/erp24/records/NewsLetterDeliveryStatus.php b/erp24/records/NewsLetterDeliveryStatus.php old mode 100755 new mode 100644 diff --git a/erp24/records/NotifiableUser.php b/erp24/records/NotifiableUser.php new file mode 100644 index 0000000..2ba1dd6 --- /dev/null +++ b/erp24/records/NotifiableUser.php @@ -0,0 +1,53 @@ + 16], + [['type'], 'string', 'max' => 255], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'phone' => 'Phone', + 'type' => 'Type', + 'data' => 'Data', + 'status' => 'Status', + ]; + } +} diff --git a/erp24/records/Notification.php b/erp24/records/Notification.php old mode 100755 new mode 100644 diff --git a/erp24/records/NotificationStatus.php b/erp24/records/NotificationStatus.php old mode 100755 new mode 100644 diff --git a/erp24/records/OrderStoreSort.php b/erp24/records/OrderStoreSort.php old mode 100755 new mode 100644 diff --git a/erp24/records/OrdersAmo.php b/erp24/records/OrdersAmo.php old mode 100755 new mode 100644 index 922f30f..e570d3c --- a/erp24/records/OrdersAmo.php +++ b/erp24/records/OrdersAmo.php @@ -134,12 +134,6 @@ use Yii; * @property int $1c_send Отправлено в 1c * @property string $check_id_arr * @property string $data_md5 - * - * @property Sales $sales - * @property CityStore $storeObj - * @property Admin $courierObj - * @property Admin $floristObj - * @property OrdersStatus $status */ class OrdersAmo extends \yii\db\ActiveRecord { @@ -315,32 +309,4 @@ class OrdersAmo extends \yii\db\ActiveRecord 'data_md5' => 'Data Md5', ]; } - - public function getSales() - { - return $this->hasMany(Sales::class, ['order_id' => 'id']) - ->orderBy([ - 'date' => SORT_ASC - ]); - } - - public function getStoreObj() - { - return $this->hasOne(CityStore::class, ['id' => 'store_id']); - } - - public function getFloristObj() - { - return $this->hasOne(Admin::class, ['id' => 'florist_id']); - } - - public function getCourierObj() - { - return $this->hasOne(Admin::class, ['id' => 'courier_id']); - } - - public function getStatus() - { - return $this->hasOne(OrdersStatus::class, ['status_id' => 'status_id']); - } } diff --git a/erp24/records/OurCities.php b/erp24/records/OurCities.php old mode 100755 new mode 100644 diff --git a/erp24/records/PaymentTypes.php b/erp24/records/PaymentTypes.php old mode 100755 new mode 100644 diff --git a/erp24/records/PhoneChangeHistory.php b/erp24/records/PhoneChangeHistory.php old mode 100755 new mode 100644 diff --git a/erp24/records/PlanStore.php b/erp24/records/PlanStore.php old mode 100755 new mode 100644 diff --git a/erp24/records/PlanStoreGroupSearch.php b/erp24/records/PlanStoreGroupSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/PlanStoreLog.php b/erp24/records/PlanStoreLog.php old mode 100755 new mode 100644 diff --git a/erp24/records/PlanStoreSearch.php b/erp24/records/PlanStoreSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/Prices.php b/erp24/records/Prices.php old mode 100755 new mode 100644 diff --git a/erp24/records/PricesZakup.php b/erp24/records/PricesZakup.php old mode 100755 new mode 100644 diff --git a/erp24/records/Products1c.php b/erp24/records/Products1c.php old mode 100755 new mode 100644 diff --git a/erp24/records/Products1cOptions.php b/erp24/records/Products1cOptions.php old mode 100755 new mode 100644 diff --git a/erp24/records/ProductsVarieties.php b/erp24/records/ProductsVarieties.php old mode 100755 new mode 100644 diff --git a/erp24/records/QualityRating.php b/erp24/records/QualityRating.php old mode 100755 new mode 100644 diff --git a/erp24/records/QualityRatingLog.php b/erp24/records/QualityRatingLog.php old mode 100755 new mode 100644 diff --git a/erp24/records/ReferralStatus.php b/erp24/records/ReferralStatus.php old mode 100755 new mode 100644 diff --git a/erp24/records/Report.php b/erp24/records/Report.php old mode 100755 new mode 100644 diff --git a/erp24/records/Reports.php b/erp24/records/Reports.php old mode 100755 new mode 100644 diff --git a/erp24/records/ReportsFields.php b/erp24/records/ReportsFields.php old mode 100755 new mode 100644 diff --git a/erp24/records/ReportsGroups.php b/erp24/records/ReportsGroups.php old mode 100755 new mode 100644 diff --git a/erp24/records/RnpAlias.php b/erp24/records/RnpAlias.php old mode 100755 new mode 100644 diff --git a/erp24/records/RnpData.php b/erp24/records/RnpData.php old mode 100755 new mode 100644 diff --git a/erp24/records/RnpIndex.php b/erp24/records/RnpIndex.php old mode 100755 new mode 100644 diff --git a/erp24/records/SalesGroupSearch.php b/erp24/records/SalesGroupSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/SalesHistory.php b/erp24/records/SalesHistory.php old mode 100755 new mode 100644 diff --git a/erp24/records/SalesHistorySearch.php b/erp24/records/SalesHistorySearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/SalesItems.php b/erp24/records/SalesItems.php old mode 100755 new mode 100644 diff --git a/erp24/records/SalesProductsHistory.php b/erp24/records/SalesProductsHistory.php old mode 100755 new mode 100644 diff --git a/erp24/records/SalesProductsHistorySearch.php b/erp24/records/SalesProductsHistorySearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/SalesProductsUpdate.php b/erp24/records/SalesProductsUpdate.php old mode 100755 new mode 100644 diff --git a/erp24/records/SalesUpdate.php b/erp24/records/SalesUpdate.php old mode 100755 new mode 100644 diff --git a/erp24/records/SchedulerTaskLogSearch.php b/erp24/records/SchedulerTaskLogSearch.php index e18ab7c..030328e 100755 --- a/erp24/records/SchedulerTaskLogSearch.php +++ b/erp24/records/SchedulerTaskLogSearch.php @@ -11,14 +11,24 @@ use yii_app\records\SchedulerTaskLog; */ class SchedulerTaskLogSearch extends SchedulerTaskLog { + + public $status; + + public $statusArray = [ + -1 => 'Пропущено', + 0 => 'Все', + 1 => 'Выполнено' + ]; + /** * {@inheritdoc} */ public function rules() { return [ - [['id', 'task_num'], 'integer'], + [['id', 'task_num', 'status'], 'integer'], [['date_start', 'date_stop', 'name', 'alias', 'description', 'result', 'error', 'log', 'date'], 'safe'], + ['status', 'default', 'value' => 0] ]; } @@ -72,6 +82,22 @@ class SchedulerTaskLogSearch extends SchedulerTaskLog ->andFilterWhere(['like', 'log', $this->log]) ->andFilterWhere(['like', 'date', $this->date]); + if ($this->status == -1) { + $query->andWhere([ + 'AND', + 'date_start IS NULL', + 'date_stop IS NULL', + ]); + + } else if ($this->status == 1) { + $query->andWhere([ + 'AND', + 'date_start IS NOT NULL', + 'date_stop IS NOT NULL' + ]); + + } + return $dataProvider; } } diff --git a/erp24/records/ScriptLauncherLog.php b/erp24/records/ScriptLauncherLog.php old mode 100755 new mode 100644 diff --git a/erp24/records/Shift.php b/erp24/records/Shift.php index d628d33..e420a04 100755 --- a/erp24/records/Shift.php +++ b/erp24/records/Shift.php @@ -26,7 +26,7 @@ class Shift extends ActiveRecord public static function tableName() { - return '{{%timetable_shift}}'; + return 'timetable_shift'; } public function rules() diff --git a/erp24/records/StoreDynamic.php b/erp24/records/StoreDynamic.php old mode 100755 new mode 100644 diff --git a/erp24/records/StoreOrderStatus.php b/erp24/records/StoreOrderStatus.php old mode 100755 new mode 100644 diff --git a/erp24/records/StoreOrders.php b/erp24/records/StoreOrders.php old mode 100755 new mode 100644 index 746f90d..17c996f --- a/erp24/records/StoreOrders.php +++ b/erp24/records/StoreOrders.php @@ -16,7 +16,7 @@ use Yii; * @property string $division_date дата деления * @property int $division_hours * @property string $delivery_date_fact Дата прихода товара на склад - * @ property int $price_logistic + * @property int $price_logistic * @property string $comments * @property int $admin_id * @property string $date_add @@ -25,12 +25,9 @@ use Yii; * @property string $status_logi * @property string $date_update Дата и врепмя обновления информации в таблице храннеия data * @property string $update_html HTML блок расчета по формулам - * @property int city_id */ class StoreOrders extends \yii\db\ActiveRecord { - public $providers; - /** * {@inheritdoc} */ @@ -45,9 +42,9 @@ class StoreOrders extends \yii\db\ActiveRecord public function rules() { return [ - [['name', 'parent_id', 'date_start', 'date_end', 'delivery_date', 'division_date', 'division_hours', 'delivery_date_fact', /*'price_logistic',*/ 'comments', 'admin_id', 'date_add', 'providers_arr', 'status_logi', 'date_update', 'update_html'], 'required'], - [['parent_id', 'division_hours', /*'price_logistic',*/ 'admin_id', 'status'], 'integer'], - [['date_start', 'date_end', 'delivery_date', 'division_date', 'delivery_date_fact', 'date_add', 'date_update', 'city_id', 'providers'], 'safe'], + [['name', 'parent_id', 'date_start', 'date_end', 'delivery_date', 'division_date', 'division_hours', 'delivery_date_fact', 'price_logistic', 'comments', 'admin_id', 'date_add', 'providers_arr', 'status_logi', 'date_update', 'update_html'], 'required'], + [['parent_id', 'division_hours', 'price_logistic', 'admin_id', 'status'], 'integer'], + [['date_start', 'date_end', 'delivery_date', 'division_date', 'delivery_date_fact', 'date_add', 'date_update'], 'safe'], [['comments', 'status_logi', 'update_html'], 'string'], [['name', 'providers_arr'], 'string', 'max' => 255], ]; @@ -79,16 +76,4 @@ class StoreOrders extends \yii\db\ActiveRecord 'update_html' => 'Update Html', ]; } - - public function getCity() { - return $this->hasOne(CityStore::class, ['id' => 'city_id']); - } - - public function getProviders() { - return explode(',', $this->providers_arr); - } - - public function setProviders() { - $this->providers_arr = implode(',', $this->providers); - } } diff --git a/erp24/records/StoreOrdersFields.php b/erp24/records/StoreOrdersFields.php old mode 100755 new mode 100644 diff --git a/erp24/records/StoreOrdersFieldsData.php b/erp24/records/StoreOrdersFieldsData.php old mode 100755 new mode 100644 diff --git a/erp24/records/StoreOrdersFieldsProperty.php b/erp24/records/StoreOrdersFieldsProperty.php old mode 100755 new mode 100644 diff --git a/erp24/records/StorePlanogram.php b/erp24/records/StorePlanogram.php old mode 100755 new mode 100644 diff --git a/erp24/records/Task.php b/erp24/records/Task.php old mode 100755 new mode 100644 diff --git a/erp24/records/TaskSearch.php b/erp24/records/TaskSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/TaskTemplates.php b/erp24/records/TaskTemplates.php old mode 100755 new mode 100644 diff --git a/erp24/records/TeambonusSettings.php b/erp24/records/TeambonusSettings.php old mode 100755 new mode 100644 diff --git a/erp24/records/TechnicalRequestType.php b/erp24/records/TechnicalRequestType.php old mode 100755 new mode 100644 diff --git a/erp24/records/TechnicalRequestTypeSearch.php b/erp24/records/TechnicalRequestTypeSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/Terminals.php b/erp24/records/Terminals.php old mode 100755 new mode 100644 diff --git a/erp24/records/TimeDiffValue.php b/erp24/records/TimeDiffValue.php old mode 100755 new mode 100644 diff --git a/erp24/records/Timetable.php b/erp24/records/Timetable.php index 2e43d28..7901d5d 100755 --- a/erp24/records/Timetable.php +++ b/erp24/records/Timetable.php @@ -5,6 +5,7 @@ namespace yii_app\records; use yii\db\ActiveQuery; use yii\db\ActiveRecord; +use yii\helpers\ArrayHelper; /** * Табель сотрудников @@ -21,6 +22,7 @@ use yii\db\ActiveRecord; * @property string $time_end * @property float $work_time * @ property float $price_hour + * @property int $salary_shift * @property int $slot_type_id * @property string $comment * @property int $date_add @@ -63,7 +65,64 @@ class Timetable extends ActiveRecord public static function tableName() { - return '{{%timetable}}'; + return 'timetable'; + } + + public static function getSalariesDay() { + return [900, 1200, 1500, 1700, 1800, 2000, 2500, 3500, 5000]; + } + + public function getSalaryShift($timetableId) : array + { + + $salesByAdminPrepared = $this->salesService->getSalesByAdmin($adminGuid, $dateFrom, $dateTo, $isAdministrator); + + $timeTable = []; + if (in_array($adminGuid, $this->adminAdministratorGuids)) { + if (!empty($this->timeTable)) { + $timeTable = $this->timeTable; + } + } + + $result = $this->salesService->getSaleSumByDateArray($salesByAdminPrepared, $timeTable); + + return $result; + + } + + public static function getAllowEditShift($slotDate, $days = 5) : bool + { + return ( + date('Y-m-d',strtotime($slotDate)) >= date('Y-m-d') + || + date('n',strtotime($slotDate)) == date('n') + || + ( + date('n',strtotime($slotDate)) == date('n', strtotime("-1 month")) + && + date('j') <= $days + ) + ); + } + + public static function getCountDaysAllowEditShift($groupId) : int + { + $numDay = 5; + + $accessArray = [ + 1, // Директор + 7, // Кустовые директора + 8, // Руководитель HR + 9, // Главный бухгалтер + 20, // Администратор платформы (HR) + 51, // Операционный директор + ]; + + if (in_array($groupId, $accessArray)) { + $numDay = 13; + } + + return $numDay; } public function getDateTimeStart(): \DateTime @@ -95,6 +154,7 @@ class Timetable extends ActiveRecord 'comment' => 'Комментарий', 'date_add' => 'Дата добавления', 'status' => 'Статус', + 'salary_shift' => 'Оклад в смену', 'datetime_start' => 'Дата и время начала смены', 'datetime_end' => 'Дата и время окончания смены', ]; @@ -184,6 +244,7 @@ class Timetable extends ActiveRecord [['tabel'], 'integer', 'skipOnEmpty' => false], [['id', 'shift_id', 'store_id'], 'integer'], // [['price_hour'], 'number', 'safe'], + [['salary_shift'], 'in', 'range' => self::getSalariesDay(), 'skipOnEmpty' => true], [['date'], 'date', 'format' => 'php:Y-m-d'], [['shift_id'], 'in', 'range' => array_keys(Shift::all()), 'skipOnEmpty' => false], [['store_id'], 'exist', 'targetClass' => CityStore::class, 'targetAttribute' => 'id', 'skipOnEmpty' => false], @@ -344,4 +405,72 @@ class Timetable extends ActiveRecord { return $this->hasOne(Shift::class, ['id' => 'shift_id']); } + + public static function getAdminsByDates($dateFrom, $dateTo, $employeeSelectStoreId) + { + $slotTypeId = [ + Timetable::TIMESLOT_WORK, // "работа" + ]; + + $timeTableDateList = Timetable::find() + ->with('admin') + ->with('shift') + ->andWhere(['>=', 'date', $dateFrom]) + ->andWhere(['<=', 'date', $dateTo]) + ->andWhere(['d_id' => Admin::ADMIN_WORK_GROUP_IDS]) + ->andWhere(['slot_type_id' => $slotTypeId]) + ->andWhere(['store_id' => $employeeSelectStoreId]) + ->andWhere(['tabel' => 0]) + ->asArray() + ->all(); + + + $dateStores = []; + + foreach ($timeTableDateList as $item) { + $dateStores[] = [ + 'date' => $item['date'], + 'store_id' => $item['store_id'], + ]; + } + + foreach ($timeTableDateList as $item) { + $keyRow = $item['date'] . '_' . $item['store_id']; + $timeTableDateAdminList[$keyRow] = Timetable::find() + ->with('admin') + ->with('shift') + ->andWhere(['date' => $item['date']]) + ->andWhere(['store_id' => $item['store_id']]) + ->andWhere(['d_id' => Admin::ADMIN_WORK_GROUP_IDS]) + ->andWhere(['slot_type_id' => $slotTypeId]) + ->andWhere(['tabel' => 0]) + ->asArray() + ->all(); + } + + $adminsPrepared = []; + $adminsByDateGuids = []; + $adminsByDate = []; + if (!empty($timeTableDateAdminList)) { + foreach ($timeTableDateAdminList as $keyRow => $itemRows) { + $dateKeyPreparedRow = explode('_', $keyRow); + $dateKeyRow = ArrayHelper::getValue($dateKeyPreparedRow, array_key_first($dateKeyPreparedRow)); + foreach ($itemRows as $itemRow) { + $arrayRow = [ + 'admin_id' => $itemRow['admin']['id'], + 'admin_guid' => $itemRow['admin']['guid'], + 'admin_name' => $itemRow['admin']['name'], + ]; + $adminsPrepared[$keyRow][] = $arrayRow; + $adminsByDate[$dateKeyRow][] = $arrayRow; + $adminsByDateGuids[$dateKeyRow][] = $itemRow['admin']['guid']; + } + } + } + + return [ + 'dateGuids' => $adminsByDateGuids, + 'dateAdmins' => $adminsByDate, + ]; + } } \ No newline at end of file diff --git a/erp24/records/TimetableShift.php b/erp24/records/TimetableShift.php old mode 100755 new mode 100644 diff --git a/erp24/records/TimetableWorkbot.php b/erp24/records/TimetableWorkbot.php old mode 100755 new mode 100644 diff --git a/erp24/records/UniversalCatalog.php b/erp24/records/UniversalCatalog.php old mode 100755 new mode 100644 diff --git a/erp24/records/UniversalCatalogItem.php b/erp24/records/UniversalCatalogItem.php old mode 100755 new mode 100644 diff --git a/erp24/records/UniversalCatalogItemSearch.php b/erp24/records/UniversalCatalogItemSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/UniversalCatalogSearch.php b/erp24/records/UniversalCatalogSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/UsersAuthCallLog.php b/erp24/records/UsersAuthCallLog.php old mode 100755 new mode 100644 diff --git a/erp24/records/UsersBonus.php b/erp24/records/UsersBonus.php old mode 100755 new mode 100644 diff --git a/erp24/records/UsersEvents.php b/erp24/records/UsersEvents.php old mode 100755 new mode 100644 diff --git a/erp24/records/UsersPhones.php b/erp24/records/UsersPhones.php old mode 100755 new mode 100644 diff --git a/erp24/records/UsersStopList.php b/erp24/records/UsersStopList.php old mode 100755 new mode 100644 diff --git a/erp24/records/UsersStopListSearch.php b/erp24/records/UsersStopListSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/WriteOffsErp.php b/erp24/records/WriteOffsErp.php old mode 100755 new mode 100644 diff --git a/erp24/records/WriteOffsErpCauseDict.php b/erp24/records/WriteOffsErpCauseDict.php old mode 100755 new mode 100644 diff --git a/erp24/records/WriteOffsErpCauseDictSearch.php b/erp24/records/WriteOffsErpCauseDictSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/WriteOffsErpSearch.php b/erp24/records/WriteOffsErpSearch.php old mode 100755 new mode 100644 diff --git a/erp24/records/WriteOffsProductsErp.php b/erp24/records/WriteOffsProductsErp.php old mode 100755 new mode 100644 diff --git a/erp24/records/detection.dat b/erp24/records/detection.dat old mode 100755 new mode 100644 diff --git a/erp24/records/metrics/FotMetrics.php b/erp24/records/metrics/FotMetrics.php new file mode 100644 index 0000000..1aef498 --- /dev/null +++ b/erp24/records/metrics/FotMetrics.php @@ -0,0 +1,78 @@ +select([ + 'date' => 'admin_payroll_days.date', + 'shift_type' => 'admin_payroll_days.smena_type', + 'store_dynamic_id' => 'store_dynamic.id', + 'store_id' => 'city_store.id', + 'day_payroll' => 'SUM(admin_payroll_days.day_payroll)', + 'sales_sum_admin' => 'SUM(admin_payroll_days.sales_sum)', + 'admin_count' => 'COUNT(admin_payroll_days.admin_id)', + ]) + ->innerJoin('city_store', 'admin_payroll_days.store_id = city_store.id') + ->innerJoin('store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = city_store.id', + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(admin_payroll_days.date, \'%Y-%m-%d\')') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(admin_payroll_days.date, \'%Y-%m-%d\')') + ], + ]) + ->andFilterWhere([ + 'store_dynamic.value_int' => $this->cluster, + 'city_store.id' => $this->store, + ]) + ->andWhere([ + 'AND', + ['admin_payroll_days.smena_type' => [1, 2]], + [ + '>=', + 'DATE_FORMAT(admin_payroll_days.date, \'%Y-%m-%d\')', + $this->dateStart + ], + [ + '<=', + 'DATE_FORMAT(admin_payroll_days.date, \'%Y-%m-%d\')', + $this->dateEnd + ], + ]) + ->addGroupBy([ + 'admin_payroll_days.date', + 'admin_payroll_days.smena_type', + 'store_dynamic.id', + 'city_store.id' + ]); + } +} \ No newline at end of file diff --git a/erp24/records/metrics/MatrixMetrics.php b/erp24/records/metrics/MatrixMetrics.php new file mode 100644 index 0000000..bb0be69 --- /dev/null +++ b/erp24/records/metrics/MatrixMetrics.php @@ -0,0 +1,181 @@ + 'SUM(IF (:baseGuids LIKE CONCAT("%", products_1c.id, "%"), sales_products.summ, 0))', // Базовая + 'matrix_season_summ' => 'SUM(IF (:seasonGuids LIKE CONCAT("%", products_1c.id, "%"), sales_products.summ, 0))', // Сезонная + 'matrix_new_summ' => 'SUM(IF (:newGuids LIKE CONCAT("%", products_1c.id, "%"), sales_products.summ, 0))' // Новая + ]; + + protected function loadDefaultValues() + { + $this->getMatrixSearchGroupId(); + $this->guids = $this->getGuidsArray(); + } + + protected function getQueryDataDay(): \yii\db\ActiveQuery + { + return parent::getQueryDataDay() + ->innerJoin('sales_products', 'sales.id = sales_products.check_id') + ->innerJoin('products_1c', 'sales_products.product_id = products_1c.id') + ->params([ + ':baseGuids' => isset($this->guids[$this->matrixGroupSearchGuidDictionary['Сезонная матрица']]) ? implode("/", $this->guids[$this->matrixGroupSearchGuidDictionary['Сезонная матрица']]) : '', + ':seasonGuids' => isset($this->guids[$this->matrixGroupSearchGuidDictionary['Матрица базовая']]) ? implode("/", $this->guids[$this->matrixGroupSearchGuidDictionary['Матрица базовая']]) : '', + ':newGuids' => isset($this->guids[$this->matrixGroupSearchGuidDictionary['Новая матрица']]) ? implode("/", $this->guids[$this->matrixGroupSearchGuidDictionary['Новая матрица']]) : '', + ]); + + } + + protected function getQueryDataShifts(): \yii\db\ActiveQuery + { + return parent::getQueryDataShifts() + ->innerJoin('sales_products', 'sales.id = sales_products.check_id') + ->innerJoin('products_1c', 'sales_products.product_id = products_1c.id') + ->params([ + ':baseGuids' => isset($this->guids[$this->matrixGroupSearchGuidDictionary['Сезонная матрица']]) ? implode("/", $this->guids[$this->matrixGroupSearchGuidDictionary['Сезонная матрица']]) : '', + ':seasonGuids' => isset($this->guids[$this->matrixGroupSearchGuidDictionary['Матрица базовая']]) ? implode("/", $this->guids[$this->matrixGroupSearchGuidDictionary['Матрица базовая']]) : '', + ':newGuids' => isset($this->guids[$this->matrixGroupSearchGuidDictionary['Новая матрица']]) ? implode("/", $this->guids[$this->matrixGroupSearchGuidDictionary['Новая матрица']]) : '', + ]); + } + + private function getArrayIndexParentId($array): array + { + $answer = []; + + foreach ($array as $item) { + $answer[$item['parent_id']][] = $item; + } + + return $answer; + } + + private function getTreeMatrixGroup($array, $parent_id = null, $treeGuid = null): array + { + $tree = []; + + if ($parent_id === null) { + foreach ($array[""] as $item) { + if ($item['name'] === 'МАТРИЦА') { + $tree[$item['id']]['name'] = $item['name']; + $tree[$item['id']]['treeGuid'] = '/' . $item['id'] . '/'; + $tree[$item['id']]['group'] = $this->getTreeMatrixGroup($array, $item['id'], $tree[$item['id']]['treeGuid']); + $tree[$item['id']]['items'] = []; + } + } + } else { + if (isset($array[$parent_id])) { + foreach ($array[$parent_id] as $item) { + if ($item['tip'] === 'products_group') { + $tree[$item['id']]['name'] = $item['name']; + $tree[$item['id']]['id'] = $item['id']; + $tree[$item['id']]['treeGuid'] = $treeGuid . $item['id'] . '/'; + $tree[$item['id']]['group'] = $this->getTreeMatrixGroup($array, $item['id'], $tree[$item['id']]['treeGuid']); + + if (isset($array[$item['id']])) { + foreach ($array[$item['id']] as $product) { + if ($product['tip'] === 'products') { + $tree[$item['id']]['items'][$product['id']]['name'] = $product['name']; + $tree[$item['id']]['items'][$product['id']]['id'] = $product['id']; + $tree[$item['id']]['items'][$product['id']]['treeGuid'] = $treeGuid . $item['id'] . '/' . $product['id'] . '/'; + } + } + + } else { + $tree[$item['id']]['items'] = []; + + } + } + } + } + } + + return $tree; + } + + private function getTreeMatrix(): array + { + $products = Products1c::find() + ->select([ + 'id', + 'parent_id', + 'name', + 'tip' + ]) + ->asArray() + ->all(); + + $productsTree = $this->getArrayIndexParentId($products); + + return $this->getTreeMatrixGroup($productsTree); + } + + + private function getGuidProductsInGroup($tree, &$array, $guids, $guid = null): void + { + foreach ($tree['group'] as $item) { + if (in_array($item['id'], $guids)) { + $this->getGuidProductsInGroup($tree['group'][$item['id']], $array, $guids, $item['id']); + } else if (!in_array($item['id'], $guids) && $guid != null) { + $this->getGuidProductsInGroup($tree['group'][$item['id']], $array, $guids, $guid); + } + } + + if ($guid != null) { + foreach ($tree['items'] as $item) { + $array[$guid][] = $item['id']; + } + } + + + } + + private function getGuidsArray() + { + $tree = $this->getTreeMatrix(); + + $parentId = array_key_first($tree); + $array = []; + + $this->getGuidProductsInGroup($tree[$parentId], $array, $this->matrixGroupSearchGuid); + + return $array; + } + + private function getMatrixSearchGroupId() + { + $matrix_season_guid = Products1c::find()->where(['LIKE', 'name', 'Сезонная матрица'])->select(['id'])->column()[0] ?? ''; + $matrix_base_guid = Products1c::find()->where(['LIKE', 'name', 'Матрица базовая'])->select(['id'])->column()[0] ?? ''; + $matrix_new_guid = Products1c::find()->where(['LIKE', 'name', 'Новая матрица'])->select(['id'])->column()[0] ?? ''; + + $this->matrixGroupSearchGuid = [ + $matrix_season_guid, + $matrix_base_guid, + $matrix_new_guid + ]; + + $this->matrixGroupSearchGuidDictionary = [ + 'Сезонная матрица' => $matrix_season_guid, + 'Матрица базовая' => $matrix_base_guid, + 'Новая матрица' => $matrix_new_guid + ]; + } +} \ No newline at end of file diff --git a/erp24/records/metrics/Metrics.php b/erp24/records/metrics/Metrics.php new file mode 100755 index 0000000..12b3250 --- /dev/null +++ b/erp24/records/metrics/Metrics.php @@ -0,0 +1,366 @@ + 'php:Y-m-d'], + ['dateStart', 'compare', 'compareAttribute' => 'dateEnd', 'operator' => '<='], + ]; + } + + public $dateStart; + + public $dateEnd; + + public $cluster; + + public $store; + + protected array $alias = []; + + protected array $selectQuery = []; + + protected array $listOfExceptionsByShiftType = [ + 1 => [ + + ], + 2 => [ + + ], + 4 => [ + + ], + ]; + + protected bool $calculateShifts = true; + + protected bool $calculateDay = true; + + private bool $calculateIndex = false; + + protected function loadDefaultValues() + { + + } + + protected function loadSelectQuery() + { + $temp = []; + + foreach ($this->alias as $alias) { + if ($this->calculateShifts && $this->calculateDay) { + $temp[$alias] = "IF (shift_types.shift_type != 4, data_shifts.$alias, data_day.$alias)"; + } else if ($this->calculateShifts) { + $temp[$alias] = "data_shifts.$alias"; + } else if ($this->calculateDay) { + $temp[$alias] = "data_day.$alias"; + } + } + + $this->selectQuery = $temp; + } + + protected abstract function getQueryDataDay(); + + protected abstract function getQueryDataShifts(); + + final public function insertData(): string + { + if (!$this->validate()) { + return 'Неккоректные свойства объекта'; + } + + $message = ""; + + $start = microtime(true); + + $query = $this->getQueryDataCollection(); + $dataBatch = $query->asArray()->batch(1000); + + $this->calculateShifts = false; + $this->calculateDay = false; + $this->calculateIndex = true; + + $indexQuery = $this->getQueryDataCollection(); + + $rnpOldIndex = RnpIndex::find() + ->where(['BETWEEN', 'date', $this->dateStart, $this->dateEnd]) + ->select([ + 'index' => 'CONCAT(rnp_index.cluster_id, rnp_index.store_id, rnp_index.date, rnp_index.shift_type)' + ]) + ->indexBy('index') + ->asArray() + ->all(); + + $rnpNewIndex = $indexQuery + ->addSelect([ + 'index' => 'CONCAT(store_dynamic.value_int, city_store.id, dates_column.date, shift_types.shift_type)', + ]) + ->indexBy('index') + ->asArray() + ->all(); + + + $rnpIndexData = array_diff_key($rnpNewIndex, $rnpOldIndex); + + $timeSearch = sprintf('%.6f sec.', microtime(true) - $start); + + $start = microtime(true); + + if (count($rnpIndexData) > 0) { + $rnpIndexRows = []; + foreach ($rnpIndexData as $index) { + $rnpIndexRows[] = [$index['cluster_id'], $index['store_id'], $index['shift_type'], $index['date']]; + } + + try { + $transaction = \Yii::$app->db->beginTransaction(); + Yii::$app->db->createCommand()->batchInsert('rnp_index', ['cluster_id', 'store_id', 'shift_type', 'date'], $rnpIndexRows)->execute(); + $transaction->commit(); + + } catch (\Exception $exception) { + $transaction->rollBack(); + + $message .= "\nИНДЕКСЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= $exception->getMessage() . "\n"; + } + } + + + $timeInsertIndex = sprintf('%.6f sec.', microtime(true) - $start); + + $aliases = RnpAlias::find()->select(['id', 'alias'])->asArray()->all(); + + $aliases = ArrayHelper::map($aliases, 'alias', 'id'); + + $rnp_old_index = RnpIndex::find()->where(['BETWEEN', 'date', $this->dateStart, $this->dateEnd])->select([ + 'id', + 'cluster_id', + 'store_id', + 'shift_type', + 'date', + ])->asArray()->all(); + + $ids = []; + foreach ($rnp_old_index as $index) { + $ids[$index['cluster_id'] . $index['store_id'] . $index['shift_type'] . $index['date']] = $index['id']; + } + + $start = microtime(true); + + $rnpDataRows = []; + $rnpIndexId = []; + foreach ($dataBatch as $data) { + foreach ($data as $datum) { + $id = -1; + + if (array_key_exists($datum['cluster_id'] . $datum['store_id'] . $datum['shift_type'] . $datum['date'], $ids)) { + $id = $ids[$datum['cluster_id'] . $datum['store_id'] . $datum['shift_type'] . $datum['date']]; + } + + if ($id != -1) { + foreach ($datum as $key => $item) { + if (!in_array($key, ['cluster_id', 'store_id', 'date', 'shift_type', 'store_name']) && !in_array($key, $this->listOfExceptionsByShiftType[$datum['shift_type']])) { + $rnpDataRows[] = [$id, $aliases[$key], $item ? round($item, 2) : 0]; + $rnpIndexId[] = $id; + } + } + } + } + } + + try { + $transaction = \Yii::$app->db->beginTransaction(); + RnpData::deleteAll( + [ + 'AND', + ['index_id' => $rnpIndexId], + [ + 'IN', + 'alias_id', + RnpAlias::find() + ->select('id') + ->where(['alias' => $this->alias]) + ] + ] + ); + Yii::$app->db->createCommand()->batchInsert('rnp_data', ['index_id', 'alias_id', 'value'], $rnpDataRows)->execute(); + $transaction->commit(); + + } catch (\Exception $exception) { + $transaction->rollBack(); + + $message .= "\nАТРИБУТЫ НЕ УДАЛОСЬ СОХРАНИТЬ -\n"; + $message .= $exception->getMessage() . "\n"; + } + + $timeInsertData = sprintf('%.6f sec.', microtime(true) - $start); + + $message .= "\n|Время поиска: $timeSearch|Время записи индексов: $timeInsertIndex|Время записи данных: $timeInsertData|\n"; + + return $message; + } + + final public function getQueryDataCollection(): \yii\db\ActiveQuery + { + $this->loadDefaultValues(); + + $this->loadSelectQuery(); + + $datesQuery = (new Query())->from('( + SELECT :date_end - INTERVAL (units.mul + (10 * tens.mul) + (100 * hundreds.mul) + (1000 * thousands.mul)) DAY AS date + FROM (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS units + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS tens + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS hundreds + CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS thousands + ) a' + ) + ->params([':date_end' => $this->dateEnd]) + ->andWhere([ + 'BETWEEN', 'a.date', $this->dateStart, $this->dateEnd + ]) + ->orderBy(['date' => SORT_ASC]); + + $shiftsQuerySelect = ''; + + if ($this->calculateShifts && $this->calculateDay || $this->calculateIndex) { + $shiftsQuerySelect = '( + SELECT 1 AS shift_type UNION ALL SELECT 2 UNION ALL SELECT 4 + ) shift_types'; + + } else if ($this->calculateShifts) { + $shiftsQuerySelect = '( + SELECT 1 AS shift_type UNION ALL SELECT 2 + ) shift_types'; + + } else if ($this->calculateDay) { + $shiftsQuerySelect = '( + SELECT 4 AS shift_type + ) shift_types'; + + } + + $shiftQuery = (new Query())->from( + $shiftsQuerySelect + ) + ->select(['shift_type' => 'shift_types.shift_type']); + + $query = StoreDynamic::find() + ->select(array_merge( + [ + 'date' => 'dates_column.date', + 'shift_type' => 'shift_types.shift_type', + 'cluster_id' => 'store_dynamic.value_int', + 'store_id' => 'city_store.id', + ], + $this->calculateIndex ? [] : $this->selectQuery + )) + ->innerJoin('city_store', 'store_dynamic.store_id = city_store.id AND store_dynamic.category = 1') + ->leftJoin( + ['dates_column' => $datesQuery], + [ + 'BETWEEN', + 'dates_column.date', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + ] + ) + ->leftJoin(['shift_types' => $shiftQuery], '1=1'); + + + if ($this->calculateShifts) { + $query->leftJoin( + ['data_shifts' => $this->getQueryDataShifts()], + [ + 'AND', + 'city_store.id = data_shifts.store_id', + 'store_dynamic.id = data_shifts.store_dynamic_id', + 'dates_column.date = data_shifts.date', + 'shift_types.shift_type = data_shifts.shift_type' + ] + ); + } + + if ($this->calculateDay) { + $query->leftJoin( + ['data_day' => $this->getQueryDataDay()], + [ + 'AND', + 'city_store.id = data_day.store_id', + 'store_dynamic.id = data_day.store_dynamic_id', + 'dates_column.date = data_day.date', + 'shift_types.shift_type = data_day.shift_type' + ] + ); + } + + $query->andWhere([ + 'AND', + ['>=', 'dates_column.date', $this->dateStart], + ['<=', 'dates_column.date', $this->dateEnd] + ]) + ->andFilterWhere([ + 'store_dynamic.value_int' => $this->cluster, + 'city_store.id' => $this->store, + ]); + + return $query; + } + + final protected function getDataArray($clusterId, $storeId, $shift): array + { + return RnpData::find() + ->select([ + 'date' => 'rnp_index.date', + 'shift' => 'rnp_index.shift_type', + 'alias' => 'rnp_alias.alias', + 'value' => 'rnp_data.value' + ]) + ->innerJoin('rnp_alias', 'rnp_data.alias_id = rnp_alias.id') + ->innerJoin('rnp_index', 'rnp_data.index_id = rnp_index.id') + ->andWhere([ + 'AND', + [ + 'rnp_alias.alias' => $this->alias + ], + [ + '>=', + 'rnp_index.date', + $this->dateStart + ], + [ + '<=', + 'rnp_index.date', + $this->dateEnd + ] + ]) + ->andFilterWhere([ + 'rnp_index.cluster_id' => $clusterId, + 'rnp_index.store_id' => $storeId, + 'rnp_index.shift_type' => $shift + ]) + ->orderBy([ + 'rnp_index.date' => SORT_ASC, + 'rnp_index.shift_type' => SORT_ASC, + 'rnp_alias.id' => SORT_ASC + ]) + ->asArray() + ->all(); + } +} \ No newline at end of file diff --git a/erp24/records/metrics/SalesMetrics.php b/erp24/records/metrics/SalesMetrics.php new file mode 100644 index 0000000..34646f3 --- /dev/null +++ b/erp24/records/metrics/SalesMetrics.php @@ -0,0 +1,274 @@ + [ + 'count_sales_in_0_hour', + 'count_sales_in_1_hour', + 'count_sales_in_2_hour', + 'count_sales_in_3_hour', + 'count_sales_in_4_hour', + 'count_sales_in_5_hour', + 'count_sales_in_6_hour', + 'count_sales_in_7_hour', + 'count_sales_in_20_hour', + 'count_sales_in_21_hour', + 'count_sales_in_22_hour', + 'count_sales_in_23_hour', + ], + 2 => [ + 'count_sales_in_8_hour', + 'count_sales_in_9_hour', + 'count_sales_in_10_hour', + 'count_sales_in_11_hour', + 'count_sales_in_12_hour', + 'count_sales_in_13_hour', + 'count_sales_in_14_hour', + 'count_sales_in_15_hour', + 'count_sales_in_16_hour', + 'count_sales_in_17_hour', + 'count_sales_in_18_hour', + 'count_sales_in_19_hour', + ], + 4 => [ + + ], + ]; + + protected array $listSelectedQuery = [ + 'sales_sum' => 'SUM(IF(sales.sales_check = \'\', sales.summ, 0)) - SUM(IF(sales.sales_check != \'\', sales.summ, 0))', + //'sales_sum' => 'SUM(sales.summ)', + 'count_sales' => 'COUNT(sales.id)', + 'count_sales_in_0_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 0, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 0, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_1_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 1, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 1, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_2_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 2, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 2, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_3_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 3, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 3, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_4_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 4, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 4, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_5_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 5, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 5, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_6_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 6, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 6, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_7_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 7, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 7, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_8_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 8, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 8, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_9_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 9, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 9, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_10_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 10, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 10, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_11_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 11, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 11, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_12_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 12, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 12, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_13_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 13, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 13, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_14_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 14, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 14, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_15_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 15, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 15, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_16_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 16, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 16, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_17_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 17, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 17, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_18_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 18, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 18, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_19_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 19, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 19, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_20_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 20, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 20, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_21_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 21, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 21, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_22_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 22, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 22, 59, 59), \'%H:%i:%s\'), 1, 0))', + 'count_sales_in_23_hour' => 'SUM(if (TIME_FORMAT(sales.date, \'%H:%i:%s\') >= TIME_FORMAT(CONCAT_WS(\':\', 23, 0, 0), \'%H:%i:%s\') AND TIME_FORMAT(sales.date, \'%H:%i:%s\') <= TIME_FORMAT(CONCAT_WS(\':\', 23, 59, 59), \'%H:%i:%s\'), 1, 0))', + ]; + + protected function getQueryDataDay(): \yii\db\ActiveQuery + { + return Sales::find() + ->select(array_merge( + [ + 'date' => 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + 'store_id' => 'city_store.id', + 'store_dynamic_id' => 'store_dynamic.id', + 'shift_type' => '(SELECT 4 AS shift_type)', + ], + $this->listSelectedQuery + )) + ->innerJoin('city_store', 'sales.store_id = city_store.id') + ->innerJoin('store_dynamic', + [ + 'AND', + [ + '=', + new Expression('store_dynamic.store_id'), + new Expression('city_store.id') + ], + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(sales.date, \'%Y-%m-%d\')') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(sales.date, \'%Y-%m-%d\')') + ] + ] + ) + ->andFilterWhere([ + 'store_dynamic.value_int' => $this->cluster, + 'city_store.id' => $this->store, + ]) + ->andWhere([ + 'AND', + [ + '>=', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + $this->dateStart + ], + [ + '<=', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + $this->dateEnd + ], + /*[ + 'NOT IN', + 'sales.id', + Sales::find() + ->select([ + 'id' => 'sales.sales_check' + ]) + ->andWhere([ + 'AND', + [ + '>=', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + $this->dateStart + ], + [ + '<', + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + date('Y-m-d', strtotime('+1 week', strtotime($this->dateEnd))) + ], + ]) + ],*/ + ['sales.operation' => 'Продажа'], + ['sales.order_id' => ''] + ]) + ->groupBy([ + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')', + 'city_store.id', + 'store_dynamic.id' + ]) + ->orderBy([ + 'DATE_FORMAT(sales.date, \'%Y-%m-%d\')' => SORT_ASC, + 'city_store.id' => SORT_ASC + ]); + } + + protected function getQueryDataShifts(): \yii\db\ActiveQuery + { + return Sales::find() + ->select(array_merge( + [ + 'date' => 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'store_id' => 'city_store.id', + 'store_dynamic_id' => 'store_dynamic.id', + 'shift_type' => 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + ], + $this->listSelectedQuery + )) + ->innerJoin('city_store', 'sales.store_id = city_store.id') + ->innerJoin('store_dynamic', + [ + 'AND', + [ + '=', + new Expression('store_dynamic.store_id'), + new Expression('city_store.id') + ], + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))') + ] + ] + ) + ->andFilterWhere([ + 'store_dynamic.value_int' => $this->cluster, + 'city_store.id' => $this->store, + ]) + ->andWhere([ + 'AND', + [ + '>=', + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + $this->dateStart + ], + [ + '<=', + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + $this->dateEnd + ], + /*[ + 'NOT IN', + 'sales.id', + Sales::find() + ->select([ + 'id' => 'sales.sales_check' + ]) + ->andWhere([ + 'AND', + [ + '>=', + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + $this->dateStart + ], + [ + '<', + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + date('Y-m-d', strtotime('+1 week', strtotime($this->dateEnd))) + ], + ]) + ],*/ + ['sales.operation' => 'Продажа'], + ['sales.order_id' => ''] + ]) + ->groupBy([ + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))', + 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)', + 'city_store.id', + 'store_dynamic.id' + ]) + ->orderBy([ + 'if (HOUR(sales.date) < 8, DATE_FORMAT(DATE_SUB(sales.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(sales.date, \'%Y-%m-%d\'))' => SORT_ASC, + 'if(HOUR(sales.date) >= 8 && HOUR(sales.date) < 20, 1, 2)' => SORT_ASC, + 'city_store.id' => SORT_ASC + ]); + } +} \ No newline at end of file diff --git a/erp24/records/metrics/UserBonusMetrics.php b/erp24/records/metrics/UserBonusMetrics.php new file mode 100644 index 0000000..9461d04 --- /dev/null +++ b/erp24/records/metrics/UserBonusMetrics.php @@ -0,0 +1,94 @@ + 'SUM( IF (sales.phone IS NOT NULL AND sales.phone != \'\', 1, 0))', + 'first_minus_user_bonus' => 'SUM( IF (users.first_minus_balance = sub_users_bonus.date, 1, 0))', + 'second_minus_user_bonus' => 'SUM( IF (users.first_minus_balance < sub_users_bonus.date, 1, 0))', + ]; + + protected function getQueryDataDay(): \yii\db\ActiveQuery + { + $subUsersBonusQuery = UsersBonus::find() + ->select([ + 'users_bonus.user_id', + 'users_bonus.check_id', + 'users_bonus.date' + ]) + ->andWhere([ + 'AND', + ['>=', 'DATE_FORMAT(users_bonus.date, \'%Y-%m-%d\')', $this->dateStart], + ['<=', 'DATE_FORMAT(users_bonus.date, \'%Y-%m-%d\')', $this->dateStart], + ['!=', 'users_bonus.check_id', ''], + ['users_bonus.tip' => 'minus'], + ]); + + return parent::getQueryDataDay() + ->leftJoin('users', 'sales.phone = users.phone') + ->leftJoin(['sub_users_bonus' => $subUsersBonusQuery], + [ + 'AND', + [ + '=', + new Expression('users.id'), + new Expression('sub_users_bonus.user_id') + ], + [ + '=', + new Expression('sales.id'), + new Expression('sub_users_bonus.check_id') + ], + ] + ); + } + + protected function getQueryDataShifts(): \yii\db\ActiveQuery + { + + $subUsersBonusQuery = UsersBonus::find() + ->select([ + 'users_bonus.user_id', + 'users_bonus.check_id', + 'users_bonus.date' + ]) + ->andWhere([ + 'AND', + ['>=', 'if (HOUR(users_bonus.date) < 8, DATE_FORMAT(DATE_SUB(users_bonus.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(users_bonus.date, \'%Y-%m-%d\'))', $this->dateStart], + ['<=', 'if (HOUR(users_bonus.date) < 8, DATE_FORMAT(DATE_SUB(users_bonus.date, INTERVAL 1 DAY), \'%Y-%m-%d\'), DATE_FORMAT(users_bonus.date, \'%Y-%m-%d\'))', $this->dateStart], + ['!=', 'users_bonus.check_id', ''], + ['users_bonus.tip' => 'minus'], + ]); + + return parent::getQueryDataShifts() + ->leftJoin('users', 'sales.phone = users.phone') + ->leftJoin(['sub_users_bonus' => $subUsersBonusQuery], + [ + 'AND', + [ + '=', + new Expression('users.id'), + new Expression('sub_users_bonus.user_id') + ], + [ + '=', + new Expression('sales.id'), + new Expression('sub_users_bonus.check_id') + ], + ] + ); + } +} \ No newline at end of file diff --git a/erp24/records/metrics/WriteOffsMetrics.php b/erp24/records/metrics/WriteOffsMetrics.php new file mode 100644 index 0000000..b0422e6 --- /dev/null +++ b/erp24/records/metrics/WriteOffsMetrics.php @@ -0,0 +1,67 @@ +select([ + 'date' => 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', + 'shift_type' => '(SELECT 4)', + 'store_dynamic_id' => 'store_dynamic.id', + 'store_id' => 'city_store.id', + 'write_offs' => 'SUM(write_offs.summ)', + ]) + ->innerJoin('export_import_table', 'write_offs.store_id = export_import_table.export_val') + ->innerJoin('city_store', 'export_import_table.entity_id = city_store.id') + ->innerJoin( + 'store_dynamic', + [ + 'AND', + 'store_dynamic.store_id = export_import_table.entity_id', + [ + '<=', + new Expression('DATE_FORMAT(store_dynamic.date_from, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')') + ], + [ + '>', + new Expression('DATE_FORMAT(store_dynamic.date_to, \'%Y-%m-%d\')'), + new Expression('DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')') + ], + ] + ) + ->andFilterWhere([ + 'store_dynamic.value_int' => $this->cluster, + 'city_store.id' => $this->store, + ]) + ->andWhere([ + 'AND', + ['write_offs.type' => 'Брак'], + ['>=', 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', $this->dateStart], + ['<=', 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', $this->dateEnd] + ]) + ->addGroupBy([ + 'DATE_FORMAT(write_offs.date, \'%Y-%m-%d\')', + 'store_dynamic.id', + 'city_store.id' + ]); + } + + protected function getQueryDataShifts(): bool + { + return false; + } +} \ No newline at end of file diff --git a/erp24/scripts/tasks/task_04_dashboard_sales.php b/erp24/scripts/tasks/task_04_dashboard_sales.php index 9aab158..aca200c 100755 --- a/erp24/scripts/tasks/task_04_dashboard_sales.php +++ b/erp24/scripts/tasks/task_04_dashboard_sales.php @@ -83,13 +83,13 @@ try { $paramMinusDays = null; $dayMonthNum = date("j", time()); -// if ('22' . $dateTimeMinuet == $timeGi) { -// $paramDateFrom = date("Y-m-01", time()); -// } + if ('22' . $dateTimeMinuet == $timeGi) { + $paramDateFrom = date("Y-m-01", time()); + } -// if ('07' . $dateTimeMinuet == $timeGi && $dayMonthNum > 7) { -// $paramMinusDays = 7; -// } + if ('07' . $dateTimeMinuet == $timeGi && $dayMonthNum > 7) { + $paramMinusDays = 7; + } if ('09' . $dateTimeMinuet == $timeGi && $dayMonthNum > 3) { $paramMinusDays = 3; diff --git a/erp24/scripts/tasks/task_06_set_payroll_by_day.php b/erp24/scripts/tasks/task_06_set_payroll_by_day.php index 2f6993a..127c99a 100755 --- a/erp24/scripts/tasks/task_06_set_payroll_by_day.php +++ b/erp24/scripts/tasks/task_06_set_payroll_by_day.php @@ -46,7 +46,7 @@ $nmDayStopCalculateLastMonth = 7; $minuetTimeInTask = date('i', $time); $fullTimeInTask = date('Y-m-d H:i:s', $time); -$condition2 = (date('Gi', $time) == '1030' && date("d") < $nmDayStopCalculateLastMonth); +$condition2 = (date('Gi', $time) == '0830' && date("d") < $nmDayStopCalculateLastMonth); @@ -133,6 +133,8 @@ try { $info = ' ================ test Task 0' . $taskNum . ' stop ================'; echo $info; $log .= $info; + $log .= ' ' . $dateFrom; + $log .= ' ' . $dateTo; $dateTaskStop = date('Y-m-d H:i:s'); } else { $info = ' Task 0' . $taskNum . ' skip '; diff --git a/erp24/scripts/tasks/task_09_contest001_update.php b/erp24/scripts/tasks/task_09_contest001_update.php index b0324f8..78dd7ed 100644 --- a/erp24/scripts/tasks/task_09_contest001_update.php +++ b/erp24/scripts/tasks/task_09_contest001_update.php @@ -56,9 +56,9 @@ try { $infoText .= ' test '; ////////////////////////////////////////////// - $sales = Sales::find()->where(['>', 'date', '2023-10-23 00:00:00'])->andWhere(['<=', 'date', '2024-01-07 23:59:59']) + $sales = Sales::find()->where(['>', 'date', '2024-01-15 00:00:00'])->andWhere(['<=', 'date', '2024-03-30 23:59:59']) ->andWhere(['operation' => 'Продажа'])->andWhere(['>=', 'summ', '2500'])->orderBy(['date' => SORT_ASC])->all(); - $returns = Sales::find()->where(['>', 'date', '2023-10-23 00:00:00'])->andWhere(['<=', 'date', '2024-01-07 23:59:59']) + $returns = Sales::find()->where(['>', 'date', '2024-01-15 00:00:00'])->andWhere(['<=', 'date', '2024-03-30 23:59:59']) ->andWhere(['operation' => 'Возврат'])->all(); $returnCheckIds = []; diff --git a/erp24/scripts/tasks/task_17_set_payroll_info_by_month.php b/erp24/scripts/tasks/task_17_set_payroll_info_by_month.php index 151dc4d..4302a4e 100755 --- a/erp24/scripts/tasks/task_17_set_payroll_info_by_month.php +++ b/erp24/scripts/tasks/task_17_set_payroll_info_by_month.php @@ -122,6 +122,8 @@ try { $info = ' ================ test Task ' . $taskNum . ' stop ================'; echo $info; $log .= $info; + $log .= ' ' . $dateFrom; + $log .= ' ' . $dateTo; $dateTaskStop = date('Y-m-d H:i:s'); } else { $info = ' Task ' . $taskNum . ' skip '; diff --git a/erp24/scripts/tasks/task_20_give_500_to_referral_program_participants.php b/erp24/scripts/tasks/task_20_give_500_to_referral_program_participants.php index 53b0299..3172f8b 100644 --- a/erp24/scripts/tasks/task_20_give_500_to_referral_program_participants.php +++ b/erp24/scripts/tasks/task_20_give_500_to_referral_program_participants.php @@ -127,6 +127,8 @@ try { $info = ' ================ test Task ' . $taskNum . ' stop ================'; echo $info; $log .= $info; + $log .= ' ' . $date_start; + $log .= ' ' . $date_end; $dateTaskStop = date('Y-m-d H:i:s'); } else { $info = ' Task ' . $taskNum . ' skip '; diff --git a/erp24/scripts/tasks/task_21_calculation_company_data_sales.php b/erp24/scripts/tasks/task_21_calculation_company_data_sales.php new file mode 100644 index 0000000..2c7e1ee --- /dev/null +++ b/erp24/scripts/tasks/task_21_calculation_company_data_sales.php @@ -0,0 +1,135 @@ +setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ; + $validate = $schedulerTaskLog->validate(); + if ($validate) { + $schedulerTaskLog->save(); + } + + if (date('Y-m-02') == date('Y-m-d', strtotime('today'))) { + $dateStart = date('Y-m-d', strtotime('first day of previous month')); + $dateEnd = date('Y-m-01'); + } else { + $dateStart = date('Y-m-d', strtotime('yesterday -1 day')); + $dateEnd = date('Y-m-d', strtotime('yesterday')); + } + + $salesMetrics = new SalesMetrics(); + $salesMetrics->dateStart = $dateStart; + $salesMetrics->dateEnd = $dateEnd; + + + $startExecution = microtime( true ); + $log .= $salesMetrics->insertData(); + $timeExecution = sprintf( '%.6f sec.', microtime( true ) - $startExecution ); + + $log.= "\nВремя выполнения: $timeExecution\n"; + + $errorsCount = null; + + if (!empty($errorsCount)) { + $infoError .= 'errors count ' . $errorsCount; + $error .= $infoError; +// $valueErrors = json_encode($errors,JSON_UNESCAPED_UNICODE); +// $error .= $valueErrors; + } + + + + + $info = ' ================ test Task ' . $taskNum . ' stop ================'; + echo $info; + $log .= $info; + $log .= ' ' . $dateStart; + $log .= ' ' . $dateEnd; + $dateTaskStop = date('Y-m-d H:i:s'); + } else { + $info = ' Task ' . $taskNum . ' skip '; + echo $info; + $log .= $info; + } +} catch (Exception $e) { + $error = 'Exception: ' . $e->getMessage(); +} + +if (empty($schedulerTaskLog)) { + $schedulerTaskLog = new SchedulerTaskLog(); + $schedulerTaskLog->setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} else { + $schedulerTaskLog->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} +$validate = $schedulerTaskLog->validate(); +if ($validate) { + $schedulerTaskLog->save(); +} \ No newline at end of file diff --git a/erp24/scripts/tasks/task_22_create_employee_for_1c_with_admins_with_empty_guid.php b/erp24/scripts/tasks/task_22_create_employee_for_1c_with_admins_with_empty_guid.php index 701d0f0..1ad061f 100644 --- a/erp24/scripts/tasks/task_22_create_employee_for_1c_with_admins_with_empty_guid.php +++ b/erp24/scripts/tasks/task_22_create_employee_for_1c_with_admins_with_empty_guid.php @@ -4,12 +4,14 @@ * @var $time integer */ +use yii\helpers\ArrayHelper; use yii_app\helpers\DataHelper; use yii_app\records\Admin; use yii_app\records\AdminGroup; use yii_app\records\EmployeeOnShift; use yii_app\records\ExportImportTable; use yii_app\records\SchedulerTaskLog; +use yii_app\services\ExportImportService; ini_set('max_execution_time', (string)(60 * 60 * 1)); // 1 час @@ -66,28 +68,53 @@ try { ////////////////////////////////////////////// + $compareDate = date('Y-m-d H:i:s', strtotime("-1 month", time())); + + $entityCityStore = ExportImportService::getEntityByType(); + $exportCityStore = ArrayHelper::map($entityCityStore, 'entity_id', 'export_val'); + $admins = Admin::find() - ->select(['id', 'guid', 'name', 'mobile as phone']) + ->select(['id', 'guid', 'name', 'store_id', 'mobile as phone']) ->where(['and', ['guid' => ''], ['!=', 'mobile', '']]) ->andWhere(['in', 'group_id', AdminGroup::getGroupsForEmployeeOnCashbox()]) - ->andWhere(['>=', 'date_add', date('Y-m-d H:i:s', strtotime("-2 hour", time()))]) + ->andWhere(['>=', 'date_add', $compareDate]) ->all(); + $adminsIds = implode(',',ArrayHelper::getColumn($admins, 'id')); + + $phones = ArrayHelper::getColumn(EmployeeOnShift::find()->all(), 'phone'); foreach ($admins as $admin) { + /** @var Admin $admin */ + if (in_array($admin->phone, $phones)) { + continue; + } + + $storeGuid = '--'; + + if (!empty($admin->store_id)) { + if (array_key_exists($admin->store_id, $exportCityStore)) { + $storeGuid = $exportCityStore[$admin->store_id]; + } + } + $model = new EmployeeOnShift([ 'first_name' => $admin->name, 'last_name' => '', 'phone' => $admin->phone, 'shift_date' => date('Y-m-d H:i:s'), 'shift_type' => 1, 'datetime_start' => date('Y-m-d H:i:s'), 'datetime_end' => date('Y-m-d H:i:s'), 'created_by' => 1, - 'store_id' => '-', + 'store_id' => $storeGuid, 'price' => 0, + 'salary_shift' => 1500, ]); $model->guid = DataHelper::createGuidMy("06"); $model->created_at = date("Y-m-d H:i:s"); $model->status = EmployeeOnShift::STATUS_ACCEPT; $model->status_source = EmployeeOnShift::STATUS_SOURCE_NOT_CREATED_IN_1C; $model->save(); + if ($model->getErrors()) { + $error .= json_encode($model->getErrors(), JSON_UNESCAPED_UNICODE); + } $admin->guid = $model->guid; $admin->save(false); @@ -105,6 +132,10 @@ try { $info = ' ================ test Task ' . $taskNum . ' stop ================'; echo $info; $log .= $info; + $log .= ' count($admins) = '. count($admins); + $log .= ' $adminsIds = '. $adminsIds; + $log .= ' date_add >='. $compareDate; + $dateTaskStop = date('Y-m-d H:i:s'); } else { $info = ' Task ' . $taskNum . ' skip '; diff --git a/erp24/scripts/tasks/task_23_calculation_company_data_users_bonus.php b/erp24/scripts/tasks/task_23_calculation_company_data_users_bonus.php new file mode 100644 index 0000000..f5b2c2a --- /dev/null +++ b/erp24/scripts/tasks/task_23_calculation_company_data_users_bonus.php @@ -0,0 +1,133 @@ +setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ; + $validate = $schedulerTaskLog->validate(); + if ($validate) { + $schedulerTaskLog->save(); + } + + if (date('Y-m-02') == date('Y-m-d', strtotime('today'))) { + $dateStart = date('Y-m-d', strtotime('first day of previous month')); + $dateEnd = date('Y-m-01'); + } else { + $dateStart = date('Y-m-d', strtotime('yesterday -1 day')); + $dateEnd = date('Y-m-d', strtotime('yesterday')); + } + + $userBonusMetrics = new UserBonusMetrics(); + $userBonusMetrics->dateStart = $dateStart; + $userBonusMetrics->dateEnd = $dateEnd; + + $startExecution = microtime( true ); + $log .= $userBonusMetrics->insertData(); + $timeExecution = sprintf( '%.6f sec.', microtime( true ) - $startExecution ); + + $log.= "\nВремя выполнения: $timeExecution\n"; + + $errorsCount = null; + + if (!empty($errorsCount)) { + $infoError .= 'errors count ' . $errorsCount; + $error .= $infoError; +// $valueErrors = json_encode($errors,JSON_UNESCAPED_UNICODE); +// $error .= $valueErrors; + } + + + + + $info = ' ================ test Task ' . $taskNum . ' stop ================'; + echo $info; + $log .= $info; + $log .= ' ' . $dateStart; + $log .= ' ' . $dateEnd; + $dateTaskStop = date('Y-m-d H:i:s'); + } else { + $info = ' Task ' . $taskNum . ' skip '; + echo $info; + $log .= $info; + } +} catch (Exception $e) { + $error = 'Exception: ' . $e->getMessage(); +} + +if (empty($schedulerTaskLog)) { + $schedulerTaskLog = new SchedulerTaskLog(); + $schedulerTaskLog->setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} else { + $schedulerTaskLog->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} +$validate = $schedulerTaskLog->validate(); +if ($validate) { + $schedulerTaskLog->save(); +} \ No newline at end of file diff --git a/erp24/scripts/tasks/task_24_calculation_company_data_matrix_sales.php b/erp24/scripts/tasks/task_24_calculation_company_data_matrix_sales.php new file mode 100644 index 0000000..312a597 --- /dev/null +++ b/erp24/scripts/tasks/task_24_calculation_company_data_matrix_sales.php @@ -0,0 +1,132 @@ +setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ; + $validate = $schedulerTaskLog->validate(); + if ($validate) { + $schedulerTaskLog->save(); + } + + if (date('Y-m-02') == date('Y-m-d', strtotime('today'))) { + $dateStart = date('Y-m-d', strtotime('first day of previous month')); + $dateEnd = date('Y-m-01'); + } else { + $dateStart = date('Y-m-d', strtotime('yesterday -1 day')); + $dateEnd = date('Y-m-d', strtotime('yesterday')); + } + + $matrixMetrics = new MatrixMetrics(); + $matrixMetrics->dateStart = $dateStart; + $matrixMetrics->dateEnd = $dateEnd; + + $startExecution = microtime( true ); + $log .= $matrixMetrics->insertData(); + $timeExecution = sprintf( '%.6f sec.', microtime( true ) - $startExecution ); + + $log.= "\nВремя выполнения: $timeExecution\n"; + + $errorsCount = null; + + if (!empty($errorsCount)) { + $infoError .= 'errors count ' . $errorsCount; + $error .= $infoError; +// $valueErrors = json_encode($errors,JSON_UNESCAPED_UNICODE); +// $error .= $valueErrors; + } + + + + + $info = ' ================ test Task ' . $taskNum . ' stop ================'; + echo $info; + $log .= $info; + $log .= ' ' . $dateStart; + $log .= ' ' . $dateEnd; + $dateTaskStop = date('Y-m-d H:i:s'); + } else { + $info = ' Task ' . $taskNum . ' skip '; + echo $info; + $log .= $info; + } +} catch (Exception $e) { + $error = 'Exception: ' . $e->getMessage() . ' ' . $e->getFile() . ' >>> ' . $e->getLine(); +} + +if (empty($schedulerTaskLog)) { + $schedulerTaskLog = new SchedulerTaskLog(); + $schedulerTaskLog->setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} else { + $schedulerTaskLog->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} +$validate = $schedulerTaskLog->validate(); +if ($validate) { + $schedulerTaskLog->save(); +} \ No newline at end of file diff --git a/erp24/scripts/tasks/task_25_delivery_bonus_add_after_half_day.php b/erp24/scripts/tasks/task_25_delivery_bonus_add_after_half_day.php index ec15d5f..b27f32d 100644 --- a/erp24/scripts/tasks/task_25_delivery_bonus_add_after_half_day.php +++ b/erp24/scripts/tasks/task_25_delivery_bonus_add_after_half_day.php @@ -6,6 +6,7 @@ use yii\helpers\ArrayHelper; +use yii_app\records\NotifiableUser; use yii_app\records\Users; use yii_app\records\UsersBonus; use yii_app\api3\modules\v1\models\orders\OrdersAmo; @@ -93,15 +94,15 @@ try { $userFound = Users::find()->where(['phone' => $phone])->one(); /** @var $userFound Users */ - $credit_procent = $cnt == 0 - && $userFound && $userFound->source > 0 - && in_array($sale->store_id_1c, [ - '0a575763-8871-11ee-84e2-ac1f6b1b7573', // 31 Энтузиастов 22/18 (Москва) - 'e7fc2ba3-8870-11ee-84e2-ac1f6b1b7573' // 30 Леонова 18 (Москва) - ]) - && date('Y-m-d H:i:s') <= '2023-12-25 23:59:59' ? 0.3 : 0.1; - $back = round($sale->summ * $credit_procent); - $nm = "Возврат с покупки " . (100 * $credit_procent) . "% " . $sale->number . " сумма чека " . $sale->summ; + $salesCount = 0; + if ($userFound && $userFound->telegram_created_at) { + $salesCount = intval(Sales::find()->where(['phone' => $phone, 'operation' => Sales::OPERATION_SALE]) + ->andWhere(['>=', 'date', $userFound->telegram_created_at])->count()); + } + $credit_procent_index = $userFound && $userFound->source > 0 && $salesCount == 0 ? 1 : 0; + + $back1 = $back = round($sale->summ * 0.1); + $nm = "Возврат с покупки " . (100 * 0.1) . "% " . $sale->number . " сумма чека " . $sale->summ; $userBonus = new UsersBonus; $userBonus->tip = 'plus'; @@ -125,6 +126,46 @@ try { if ($userBonus->getErrors()) { $log .= json_encode($userBonus->getErrors(), JSON_UNESCAPED_UNICODE); } + if ($credit_procent_index) { + $back = round($sale->summ * 0.2); + $nm = "Возврат с покупки " . (100 * 0.2) . "% " . $sale->number . " сумма чека " . $sale->summ; + + $userBonus = new UsersBonus; + $userBonus->tip = 'plus'; + $userBonus->tip_sale = 'sale'; + $userBonus->date = $sale->date; + $userBonus->date_start = date('Y-m-d H:i:s', strtotime('+1 day', strtotime($userBonus->date))); + $userBonus->date_end = date('Y-m-d H:i:s', strtotime('+3 month', strtotime($userBonus->date))); + $userBonus->phone = $phone; + $userBonus->name = $nm; + $userBonus->check_id = $sale->id; + $userBonus->store_id = + $userBonus->bonus = $back; + $userBonus->site_id = 0; + $userBonus->referal_id = 0; + $userBonus->admin_id = $sale->admin_id; + $userBonus->price = $sale->summ; + $userBonus->store_id_1c = $sale->store_id_1c; + $userBonus->seller_id_1c = $sale->seller_id; + $userBonus->lid_id = $sale->order_id; + $userBonus->save(); + if ($userBonus->getErrors()) { + $log .= json_encode($userBonus->getErrors(), JSON_UNESCAPED_UNICODE); + } + if ($userFound->telegram_created_at == null) { + $userFound->telegram_created_at = date("Y-m-d H:i:s"); + $userFound->save(); + if ($userFound->getErrors()) { + $log .= json_encode(["error_id" => 5.3, "error" => $userFound->getErrors()]); + } + } + + $notifiableUser = new NotifiableUser; + $notifiableUser->phone = $phone; + $notifiableUser->type = "first_given_bonus"; + $notifiableUser->data = "" . ($back1 + $back); + $notifiableUser->save(); + } } } diff --git a/erp24/scripts/tasks/task_26_delivery_bonus_add_after_weak.php b/erp24/scripts/tasks/task_26_delivery_bonus_add_after_weak.php index 35c34f0..7b91218 100644 --- a/erp24/scripts/tasks/task_26_delivery_bonus_add_after_weak.php +++ b/erp24/scripts/tasks/task_26_delivery_bonus_add_after_weak.php @@ -11,7 +11,7 @@ use yii_app\records\UsersBonus; use yii_app\api3\modules\v1\models\orders\OrdersAmo; use yii_app\records\Sales; use yii_app\records\SchedulerTaskLog; - +use yii_app\records\NotifiableUser; ini_set('max_execution_time', (string)(60 * 60 * 1)); // 1 час ini_set('display_errors', 'on'); @@ -96,15 +96,15 @@ try { $userFound = Users::find()->where(['phone' => $phone])->one(); /** @var $userFound Users */ - $credit_procent = $cnt == 0 - && $userFound && $userFound->source > 0 - && in_array($sale->store_id_1c, [ - '0a575763-8871-11ee-84e2-ac1f6b1b7573', // 31 Энтузиастов 22/18 (Москва) - 'e7fc2ba3-8870-11ee-84e2-ac1f6b1b7573' // 30 Леонова 18 (Москва) - ]) - && date('Y-m-d H:i:s') <= '2023-12-25 23:59:59' ? 0.3 : 0.1; - $back = round($sale->summ * $credit_procent); - $nm = "Возврат с покупки " . (100 * $credit_procent) . "% " . $sale->number . " сумма чека " . $sale->summ; + $salesCount = 0; + if ($userFound && $userFound->telegram_created_at) { + $salesCount = intval(Sales::find()->where(['phone' => $phone, 'operation' => Sales::OPERATION_SALE]) + ->andWhere(['>=', 'date', $userFound->telegram_created_at])->count()); + } + $credit_procent_index = $userFound && $userFound->source > 0 && $salesCount == 0 ? 1 : 0; + + $back1 = $back = round($sale->summ * 0.1); + $nm = "Возврат с покупки " . (100 * 0.1) . "% " . $sale->number . " сумма чека " . $sale->summ; $userBonus = new UsersBonus; $userBonus->tip = 'plus'; @@ -128,12 +128,53 @@ try { if ($userBonus->getErrors()) { $log .= json_encode($userBonus->getErrors(), JSON_UNESCAPED_UNICODE); } + if ($credit_procent_index) { + $back = round($sale->summ * 0.2); + $nm = "Возврат с покупки " . (100 * 0.2) . "% " . $sale->number . " сумма чека " . $sale->summ; + + $userBonus = new UsersBonus; + $userBonus->tip = 'plus'; + $userBonus->tip_sale = 'sale'; + $userBonus->date = $sale->date; + $userBonus->date_start = date('Y-m-d H:i:s', strtotime('+1 day', strtotime($userBonus->date))); + $userBonus->date_end = date('Y-m-d H:i:s', strtotime('+3 month', strtotime($userBonus->date))); + $userBonus->phone = $phone; + $userBonus->name = $nm; + $userBonus->check_id = $sale->id; + $userBonus->store_id = + $userBonus->bonus = $back; + $userBonus->site_id = 0; + $userBonus->referal_id = 0; + $userBonus->admin_id = $sale->admin_id; + $userBonus->price = $sale->summ; + $userBonus->store_id_1c = $sale->store_id_1c; + $userBonus->seller_id_1c = $sale->seller_id; + $userBonus->lid_id = $sale->order_id; + $userBonus->save(); + if ($userBonus->getErrors()) { + $log .= json_encode($userBonus->getErrors(), JSON_UNESCAPED_UNICODE); + } + if ($userFound->telegram_created_at == null) { + $userFound->telegram_created_at = date("Y-m-d H:i:s"); + $userFound->save(); + if ($userFound->getErrors()) { + $log .= json_encode(["error_id" => 5.3, "error" => $userFound->getErrors()]); + } + } + + $notifiableUser = new NotifiableUser; + $notifiableUser->phone = $phone; + $notifiableUser->type = "first_given_bonus"; + $notifiableUser->data = "" . ($back1 + $back); + $notifiableUser->save(); + } } } $info = ' ================ test Task ' . $taskNum . ' stop ================'; echo $info; $log .= $info; + $log .= ' date >= ' . strtotime("-1 week", time()); $dateTaskStop = date('Y-m-d H:i:s'); } else { $info = ' Task ' . $taskNum . ' skip '; diff --git a/erp24/scripts/tasks/task_27_set_payroll_history.php b/erp24/scripts/tasks/task_27_set_payroll_history.php new file mode 100755 index 0000000..086fccb --- /dev/null +++ b/erp24/scripts/tasks/task_27_set_payroll_history.php @@ -0,0 +1,115 @@ +setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ; + $validate = $schedulerTaskLog->validate(); + if ($validate) { + $schedulerTaskLog->save(); + } + + $result = (new AdminPayrollMonthInfoService($dateFrom))->setAdminPayrollHistory(); + + $errorsCount = $result['errorsCount']; + $errors = $result['errors']; + + if (!empty($errorsCount)) { + $infoError .= 'errors count ' . $errorsCount; + $error .= $infoError; + $valueErrors = json_encode($errors,JSON_UNESCAPED_UNICODE); + $error .= $valueErrors; + } + + $infoText .= ' dateFrom = ' . $dateFrom . ' dateTo ' . $dateTo . 'errors count ' . $errorsCount; + + $info = ' ================ test Task ' . $taskNum . ' stop ================'; + echo $info; + $log .= $info; + $dateTaskStop = date('Y-m-d H:i:s'); + } else { + $info = ' Task ' . $taskNum . ' skip ' . $time . ' ' . date('Y-m-d H:i:s', $time). ' ' . date('Gi', $time); + echo $info; + $log .= $info; + } +} catch (Exception $e) { + $error = 'Exception: ' . $e->getMessage() . ' >>> ' . $e->getLine(); +} + + + +if (empty($schedulerTaskLog)) { + $schedulerTaskLog = new SchedulerTaskLog(); + $schedulerTaskLog->setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} else { + $schedulerTaskLog->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} +$validate = $schedulerTaskLog->validate(); +if ($validate) { + $schedulerTaskLog->save(); +} diff --git a/erp24/scripts/tasks/task_28_calculation_company_data_fot.php b/erp24/scripts/tasks/task_28_calculation_company_data_fot.php new file mode 100644 index 0000000..e8b820c --- /dev/null +++ b/erp24/scripts/tasks/task_28_calculation_company_data_fot.php @@ -0,0 +1,134 @@ +setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ; + $validate = $schedulerTaskLog->validate(); + if ($validate) { + $schedulerTaskLog->save(); + } + + if (date('Y-m-02') == date('Y-m-d', strtotime('today'))) { + $dateStart = date('Y-m-d', strtotime('first day of previous month')); + $dateEnd = date('Y-m-01'); + } else { + $dateStart = date('Y-m-d', strtotime('yesterday -1 day')); + $dateEnd = date('Y-m-d', strtotime('yesterday')); + } + + $fotMetrics = new FotMetrics(); + $fotMetrics->dateStart = $dateStart; + $fotMetrics->dateEnd = $dateEnd; + + $startExecution = microtime( true ); + $log .= $fotMetrics->insertData(); + $timeExecution = sprintf( '%.6f sec.', microtime( true ) - $startExecution ); + + $log.= "\nВремя выполнения: $timeExecution\n"; + + $errorsCount = null; + + if (!empty($errorsCount)) { + $infoError .= 'errors count ' . $errorsCount; + $error .= $infoError; +// $valueErrors = json_encode($errors,JSON_UNESCAPED_UNICODE); +// $error .= $valueErrors; + } + + + + + $info = ' ================ test Task ' . $taskNum . ' stop ================'; + echo $info; + $log .= $info; + $log .= ' ' . $dateStart; + $log .= ' ' . $dateEnd; + $dateTaskStop = date('Y-m-d H:i:s'); + } else { + $info = ' Task ' . $taskNum . ' skip '; + echo $info; + $log .= $info; + } +} catch (Exception $e) { + $error = 'Exception: ' . $e->getMessage(); +} + +if (empty($schedulerTaskLog)) { + $schedulerTaskLog = new SchedulerTaskLog(); + $schedulerTaskLog->setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} else { + $schedulerTaskLog->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} +$validate = $schedulerTaskLog->validate(); +if ($validate) { + $schedulerTaskLog->save(); +} \ No newline at end of file diff --git a/erp24/scripts/tasks/task_29_calculation_company_data_write_offs.php b/erp24/scripts/tasks/task_29_calculation_company_data_write_offs.php new file mode 100644 index 0000000..125ace0 --- /dev/null +++ b/erp24/scripts/tasks/task_29_calculation_company_data_write_offs.php @@ -0,0 +1,133 @@ +setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ; + $validate = $schedulerTaskLog->validate(); + if ($validate) { + $schedulerTaskLog->save(); + } + + if (date('Y-m-02') == date('Y-m-d', strtotime('today'))) { + $dateStart = date('Y-m-d', strtotime('first day of previous month')); + $dateEnd = date('Y-m-01'); + } else { + $dateStart = date('Y-m-d', strtotime('yesterday -1 day')); + $dateEnd = date('Y-m-d', strtotime('yesterday')); + } + + $writeOffsMetrics = new WriteOffsMetrics(); + $writeOffsMetrics->dateStart = $dateStart; + $writeOffsMetrics->dateEnd = $dateEnd; + + $startExecution = microtime( true ); + $log .= $writeOffsMetrics->insertData(); + $timeExecution = sprintf( '%.6f sec.', microtime( true ) - $startExecution ); + + $log.= "\nВремя выполнения: $timeExecution\n"; + + $errorsCount = null; + + if (!empty($errorsCount)) { + $infoError .= 'errors count ' . $errorsCount; + $error .= $infoError; +// $valueErrors = json_encode($errors,JSON_UNESCAPED_UNICODE); +// $error .= $valueErrors; + } + + + + + $info = ' ================ test Task ' . $taskNum . ' stop ================'; + echo $info; + $log .= $info; + $log .= ' ' . $dateStart; + $log .= ' ' . $dateEnd; + $dateTaskStop = date('Y-m-d H:i:s'); + } else { + $info = ' Task ' . $taskNum . ' skip '; + echo $info; + $log .= $info; + } +} catch (Exception $e) { + $error = 'Exception: ' . $e->getMessage(); +} + +if (empty($schedulerTaskLog)) { + $schedulerTaskLog = new SchedulerTaskLog(); + $schedulerTaskLog->setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} else { + $schedulerTaskLog->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} +$validate = $schedulerTaskLog->validate(); +if ($validate) { + $schedulerTaskLog->save(); +} \ No newline at end of file diff --git a/erp24/scripts/tasks/task_30_calculation_company_data_matrix_for_chart.php b/erp24/scripts/tasks/task_30_calculation_company_data_matrix_for_chart.php new file mode 100644 index 0000000..bded16e --- /dev/null +++ b/erp24/scripts/tasks/task_30_calculation_company_data_matrix_for_chart.php @@ -0,0 +1,123 @@ +setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ; + $validate = $schedulerTaskLog->validate(); + if ($validate) { + $schedulerTaskLog->save(); + } + + if (date('Y-m-02') == date('Y-m-d', strtotime('today'))) { + $dateStart = date('Y-m-d', strtotime('first day of previous month')); + $dateEnd = date('Y-m-01'); + } else { + $dateStart = date('Y-m-d', strtotime('yesterday -1 day')); + $dateEnd = date('Y-m-d', strtotime('yesterday')); + } + + $log .= ChartDataSearch::CalculationCompanyDataMatrixSalesForChartsDay($dateStart, $dateEnd); + + $errorsCount = null; + + if (!empty($errorsCount)) { + $infoError .= 'errors count ' . $errorsCount; + $error .= $infoError; +// $valueErrors = json_encode($errors,JSON_UNESCAPED_UNICODE); +// $error .= $valueErrors; + } + + + + + $info = ' ================ test Task ' . $taskNum . ' stop ================'; + echo $info; + $log .= $info; + $log .= ' ' . $dateStart; + $log .= ' ' . $dateEnd; + $dateTaskStop = date('Y-m-d H:i:s'); + } else { + $info = ' Task ' . $taskNum . ' skip '; + echo $info; + $log .= $info; + } +} catch (Exception $e) { + $error = 'Exception: ' . $e->getMessage() . ' ' . $e->getFile() . ' >>> ' . $e->getLine(); +} + +if (empty($schedulerTaskLog)) { + $schedulerTaskLog = new SchedulerTaskLog(); + $schedulerTaskLog->setTaskNum($taskNum) + ->setName('Task ' . $taskNum) + ->setDate($dateTask) + ->setDateStart($dateTaskStart) + ->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} else { + $schedulerTaskLog->setDateStop($dateTaskStop) + ->setDescription($description) + ->setError($error) + ->setInfo($infoText) + ->setLog($log) + ; +} +$validate = $schedulerTaskLog->validate(); +if ($validate) { + $schedulerTaskLog->save(); +} \ No newline at end of file diff --git a/erp24/services/AdminPayrollMonthInfoService.php b/erp24/services/AdminPayrollMonthInfoService.php index a7557ea..9cf9f21 100644 --- a/erp24/services/AdminPayrollMonthInfoService.php +++ b/erp24/services/AdminPayrollMonthInfoService.php @@ -3,17 +3,145 @@ namespace yii_app\services; use yii\helpers\ArrayHelper; -use yii_app\helpers\DateHelper; use yii_app\helpers\HtmlHelper; use yii_app\records\Admin; use yii_app\records\AdminGroup; -use yii_app\records\AdminPayrollDays; +use yii_app\records\AdminPayroll; +use yii_app\records\AdminPayrollHistory; use yii_app\records\AdminPayrollMonthInfo; use yii_app\records\CityStore; use yii_app\records\EmployeePosition; class AdminPayrollMonthInfoService { + private $notInStoreIds; + private $yearSelect; + private $monthSelect; + private $monthWithZeroSelect; + private $dateFromBeginMonth; + private $dateToEndMonth; + private $dateTo; + private $dateFrom; + private $groupIds; + private $entityCityStore; + private $exportCityStore; + private $entityAdmin; + private $exportAdmin; + private $employeePosition; + private $employeeAdminGroup; + private $cityStoreNames; + private $monthNameSelect; + private $cabinetService; + + public function __construct($dateFrom) + { + $this->cabinetService = new CabinetService(); + + $this->dateFrom = $dateFrom; + $this->notInStoreIds = Admin::NOT_IN_STORE_IDS; + $this->yearSelect = date("Y", strtotime($this->dateFrom)); + $this->monthSelect = date("n", strtotime($this->dateFrom)); + $this->monthWithZeroSelect = date("m", strtotime($this->dateFrom)); + $this->dateFromBeginMonth = date("Y-m-01", strtotime($this->dateFrom)); + $this->dateToEndMonth = date("Y-m-t", strtotime($this->dateFrom)); + $this->dateTo = $this->dateToEndMonth; + if ($this->monthSelect == date("n")) { + $this->dateTo = date('Y-m-d', strtotime("-1 day")); + } + $this->groupIds = Admin::ADMIN_PAYROLL_MAKE_GROUP_IDS; + $this->employeePosition = EmployeePosition::getAllIdName(); + + + $this->entityCityStore = ExportImportService::getEntityByType('city_store'); + $this->exportCityStore = ArrayHelper::map($this->entityCityStore, 'entity_id', 'export_val'); + $this->entityAdmin = ExportImportService::getEntityByType('admin'); + $this->exportAdmin = ArrayHelper::map($this->entityAdmin, 'entity_id', 'export_val'); + $this->employeePosition = EmployeePosition::getAllIdName(); + $this->employeeAdminGroup = AdminGroup::getNames(); + $this->cityStoreNames = CityStore::getNames(); + $this->monthNameSelect = HtmlHelper::getMonthName($this->monthWithZeroSelect); + } + + public function setAdminPayrollHistory() + { + AdminPayroll::clearPayrollFiredAdmin($this->yearSelect, $this->monthSelect); + AdminPayroll::clearPayrollWithoutShiftAdmin($this->yearSelect, $this->monthSelect); + + $idsTimeTableArray = $this->cabinetService->getTimetableDataList($this->dateFrom, $this->dateTo); + $idsAdminTimeTable = ArrayHelper::getColumn($idsTimeTableArray, 'admin_id'); + + $admins = Admin::getAdmins( + $idsAdminTimeTable, + $this->groupIds, + 'ASC', + null, + null, + $this->notInStoreIds, + true + ); + + $errors = []; + $adminInfo = []; + + if (empty($admins)) { + $errors[] = 'admins is empty'; + } else { + $packetNum = time(); + $winStoreIdDayChallenge = []; + + foreach ($admins as $employeeSelect) { + $employeeId = $employeeSelect['id']; + $controller = null; + $employeeGroupId = $employeeSelect['group_id']; + + $isAdministrator = Admin::isAdministrator($employeeGroupId); + $ratingId = RatingService::getRatingId($employeeGroupId); + + $payrollValues = $this->cabinetService->getDataDynamic202310( + $employeeId, + $employeeSelect, + $employeeGroupId, + $isAdministrator, + $ratingId, + $this->dateFrom, + $this->dateTo, + $controller, + $winStoreIdDayChallenge, + $this->exportCityStore, + $this->exportAdmin, + $this->yearSelect, + $this->monthSelect, + $this->monthWithZeroSelect, + $this->monthNameSelect, + $this->dateFromBeginMonth, + $this->dateToEndMonth, + $this->employeePosition, + $this->employeeAdminGroup, + $this->cityStoreNames + ); + + if (array_key_exists('errorText', $payrollValues)) { + $errors[] = $errorRow = $payrollValues['errorText']; + InfoLogService::setInfoLog(__FILE__, __LINE__, $error ?? [] , 'error payrollHistoryValues'); + } else { + AdminPayrollHistory::setValues($payrollValues, + $employeeId, + $employeeSelect['store_id'], + $this->yearSelect, + $this->monthSelect, + $packetNum + ); + } + + $adminInfo[$employeeId] = $payrollValues; + } + } + return [ + 'errors' => $errors, + 'errorsCount' => count($errors), + 'adminInfo' => $adminInfo, + ]; + } public static function setAdminPayrollMonth($dateFrom, $dateTo) { diff --git a/erp24/services/BonusService.php b/erp24/services/BonusService.php index 0500720..4407523 100755 --- a/erp24/services/BonusService.php +++ b/erp24/services/BonusService.php @@ -4,6 +4,7 @@ namespace yii_app\services; use yii\helpers\ArrayHelper; use yii_app\helpers\DateHelper; +use yii_app\records\Admin; use yii_app\records\AdminBonusConversion; use yii_app\records\AdminPayrollDays; use yii_app\records\CityStore; @@ -871,6 +872,72 @@ class BonusService return $rateId; } + + public function getAdminTeamPayrollTable($teamBonus) : array + { + $adminTeamPayroll = []; + + // $teamBonusAdminPayDayAll + // key 893_2023-12-01 + // value = sum; + $teamBonusAdminPayDayAll = ArrayHelper::getValue($teamBonus, 'adminPayDayAll'); + + // $teamBonusPayrollVariableDaysAll + // key 297_2023-12-07 + // value = sum; + $teamBonusPayrollVariableDaysAll = ArrayHelper::getValue($teamBonus, 'payrollVariableDaysAll'); + + if (!empty($teamBonusAdminPayDayAll) && is_array($teamBonusAdminPayDayAll)) { + $arrayKeysAdminIdDate = array_unique(array_merge(array_keys($teamBonusAdminPayDayAll), array_keys($teamBonusPayrollVariableDaysAll))); + } + $adminIds = []; + $days = []; + if (!empty($arrayKeysAdminIdDate)) { + foreach ($arrayKeysAdminIdDate as $key => $row) { + $arrayRow = explode('_',$row); + $adminIdRow = $arrayRow[0]; + $dateRow = $arrayRow[1]; + $adminIds[] = $adminIdRow; + $days[] = $dateRow; + } + } + + $adminIds = array_unique($adminIds); + + $admins = Admin::getAdmins($adminIds, null, 'ASC'); + + $days = array_unique($days); + + $result = []; + foreach ($admins as $admin) { + $result[$admin['id']]['admin_id'] = $admin['id']; + $result[$admin['id']]['admin_name'] = $admin['name']; + $result[$admin['id']]['group_name'] = $admin['group_name']; + $daysRow = []; + + foreach ($days as $day) { + $keyAdminIdDateRow = $admin['id'] . '_' . $day; + $payConstantRow = 0; + if (array_key_exists($keyAdminIdDateRow, $teamBonusAdminPayDayAll)) { + $payConstantRow = ArrayHelper::getValue($teamBonusAdminPayDayAll, $keyAdminIdDateRow); + } + $payVariableRow = 0; + + if (array_key_exists($keyAdminIdDateRow, $teamBonusPayrollVariableDaysAll)) { + $payVariableRow = ArrayHelper::getValue($teamBonusPayrollVariableDaysAll, $keyAdminIdDateRow); + } + $daysRow[$day] = [ + 'pay_constant' => $payConstantRow, + 'pay_variable' => $payVariableRow, + ]; + } + ksort($daysRow); + + $result[$admin['id']]['days'] = $daysRow; + } + + return $result; + } /** * @param array $normaSmena * @param $summ @@ -878,7 +945,26 @@ class BonusService */ public function getTeamBonus($adminId, $storeId, $storeGuid, $dateFrom, $dateTo): array { - $result = []; + $percentTeamBonusInMonth = self::getPercentTeamBonusInMonth($storeId, $dateFrom); + + $result = [ + 'adminStoreFotStableSum' => 0, + 'adminStoreFotVariableSum' => 0, + 'adminStoreFotSum' => 0, + 'writeOffsSum' => 0, + 'fotStoreAndWriteOff' => 0, + 'salesByStore' => 0, + 'salesByStorePart' => 0, + 'primeFondStore' => 0, + 'shiftCountAll' => 0, + 'primeFondStoreOneShift' => 0, + 'personShiftCount' => 0, + 'personPrimeFondStore' => 0, + 'adminStoreFotSumPercent' => 0, + 'writeOffsSumPercent' => 0, + 'adminStoreFotAndWriteOffsSumPercent' => 0, + 'percentTeamBonusInMonth' => $percentTeamBonusInMonth, + ]; $slotTypeId = [ Timetable::TIMESLOT_WORK, // "работа" @@ -894,10 +980,14 @@ class BonusService ->all(); $adminTimetable = []; + $adminTimetableSalaryShift = []; if (!empty($timeTable)){ foreach ($timeTable as $row) { $adminTimetable[$row['admin_id']][] = $row['date']; + if (!empty($row['salary_shift'])) { + $adminTimetableSalaryShift[$row['admin_id']][$row['date']] = $row['salary_shift']; + } } @@ -929,7 +1019,16 @@ class BonusService $adminTimetableRow = $adminTimetable[$adminId]; foreach ($dates as $date) { if (in_array($date, $adminTimetableRow)) { - $adminPayDayRow = EmployeePayment::getSalary($adminId, $date, $adminPayDayDict); + if ( + array_key_exists($adminId, $adminTimetableSalaryShift) + && + array_key_exists($date, $adminTimetableSalaryShift[$adminId]) + ) { + $adminPayDayRow = $adminTimetableSalaryShift[$adminId][$date]; + } else { + $adminPayDayRow = EmployeePayment::getSalary($adminId, $date, $adminPayDayDict); + } + $keyAdminPayDayDictAllRow = $adminId . '_' . $date; $adminPayDayAll[$keyAdminPayDayDictAllRow] = $adminPayDayRow; $adminPayDay[$adminId][$date] = $adminPayDayRow; @@ -1004,7 +1103,7 @@ class BonusService // echo '
'; $salesByStore = (new CabinetService())->getSalesSaleSum($dateFrom, $dateTo, $storeGuid); - $percentTeamBonusInMonth = self::getPercentTeamBonusInMonth($storeId, $dateFrom); + $percentCoefficient = $percentTeamBonusInMonth / 100; $salesByStorePart = $salesByStore * $percentCoefficient; @@ -1062,6 +1161,9 @@ class BonusService 'writeOffsSumPercent' => $writeOffsSumPercent, 'adminStoreFotAndWriteOffsSumPercent' => $adminStoreFotAndWriteOffsSumPercent, 'percentTeamBonusInMonth' => $percentTeamBonusInMonth, + 'days' => $dates, + 'adminPayDayAll' => $adminPayDayAll, + 'payrollVariableDaysAll' => $payrollVariableDaysAll, ]; } } @@ -1070,19 +1172,20 @@ class BonusService } - public static function getPercentTeamBonusInMonth($storeId, $dateFrom) + public static function getPercentTeamBonusInMonth($storeId, $dateFrom) : int { - $percentDefault = 20; - $year = date("Y" , strtotime($dateFrom)); - $month = date("m" , strtotime($dateFrom)); + $percentDefault = 0; + $year = (int) date("Y" , strtotime($dateFrom)); + $month = (int) date("n" , strtotime($dateFrom)); $percentPrepared = TeambonusSettings::find() ->select(['procent']) ->andWhere(['store_id' => $storeId]) ->andWhere(['year' => $year]) ->andWhere(['month' => $month]) + ->orderBy(['created_at' => SORT_DESC]) ->scalar(); - $percent = (!empty($percentPrepared)) ? $percentPrepared : $percentDefault; + $percent = (isset($percentPrepared)) ? $percentPrepared : $percentDefault; return $percent; } diff --git a/erp24/services/CabinetService.php b/erp24/services/CabinetService.php index c433d29..d386291 100755 --- a/erp24/services/CabinetService.php +++ b/erp24/services/CabinetService.php @@ -155,6 +155,12 @@ class CabinetService 33, // Должанская 33/11 29, // ул. Страж Революции, 1А ], + '2023-11' => [ + 37, // Тимирязева 9к2 + ], + '2023-12' => [ + 37, // Тимирязева 9к2 + ], ]; /** * Расчет демотивации Год к Году заблокирован на указанный месяц @@ -563,7 +569,7 @@ class CabinetService $cityStoreNames, bool $calculatePersonalRating = true ) - { + { //getDataDynamic if (!empty($employeeSelect['store_id'])) { $employeeSelectStoreId = $employeeSelect['store_id']; @@ -2081,7 +2087,7 @@ class CabinetService $cityStoreNames, bool $calculatePersonalRating = true ) - { + { // getDataDynamic202310 if (!empty($employeeSelect['store_id'])) { $employeeSelectStoreId = $employeeSelect['store_id']; @@ -2368,12 +2374,28 @@ class CabinetService $normalCountShiftArray = SalaryHelper::$normalCountShift; if (!empty($employeeSelect["group_id"])) { if (Admin::ADMINISTRATOR_GROUP_ID == $employeeSelect["group_id"]){ - // у Администратора число смен равно количеству рабочих дней в месяце - $normalCountShift = HtmlHelper::getWorkDays($monthSelect, $yearSelect); - + if ($dateFrom >= '2023-12-01') { + $dayMonthDateRow = $yearSelect . '-' . $monthSelect . '-01'; + $timeRow = strtotime($dayMonthDateRow); + $monthSelectRow = date('n', $timeRow); + $yearSelectRow = date('Y', $timeRow); + if ($yearSelectRow == '2024' && $monthSelectRow == 1) { + $normalCountShift = 20; + } else { + // у Администратора число смен равно количеству дней со вторника по субботу в месяце + $normalCountShift = HtmlHelper::getAdministratorWorkDays($monthSelect, $yearSelect); + } + } else { + // у Администратора число смен равно количеству рабочих дней в месяце + $normalCountShift = HtmlHelper::getWorkDays($monthSelect, $yearSelect); + } } else { $employeeSelectGroupId = $this->getGroupId($employeeId, $employeeSelect['group_id'], $dateFrom, $dateTo); - $normalCountShift = $normalCountShiftArray[$employeeSelectGroupId]; + if (array_key_exists($employeeSelectGroupId, $normalCountShiftArray)) { + $normalCountShift = $normalCountShiftArray[$employeeSelectGroupId]; + } else { + $normalCountShift = 15; + } } } @@ -2435,7 +2457,7 @@ class CabinetService $planMonthCalculate = round($salaryAdministratorByDay * $normalCountShiftValue, 1); $planMonthCalculatePercent = round(100 * $planMonthCalculate /$planMonthAdministrator,1); - $administratorOklad = $this->bonusService->getAdministratorOklad($planMonthCalculate); + $administratorOklad = $this->getAdministratorSalaryShift($employeeId, $dateFrom, $planMonthCalculate); } $saleByMonthCalculate = 0; @@ -2462,11 +2484,11 @@ class CabinetService } if ($isAdministrator) { - $administratorOklad = $this->bonusService->getAdministratorOklad($saleByMonthCalculate); + $administratorOklad = $this->getAdministratorSalaryShift($employeeId, $dateFrom, $saleByMonthCalculate); } } elseif ($isAdministrator && !empty($salesByStore)) { - $administratorOklad = $this->bonusService->getAdministratorOklad($salesByStore); + $administratorOklad = $this->getAdministratorSalaryShift($employeeId, $dateFrom, $salesByStore); $showBlockForecast = true; @@ -2476,16 +2498,22 @@ class CabinetService } + $hourPayment = 10; //default value + if (!empty($normalCountShift)) { if ($isAdministrator) { $normalCostShift = round($administratorOklad / $normalCountShift, 1); $dailyPayment = $normalCostShift; + $hourPayment = $dailyPayment / Admin::SHIFT_HOUR_COUNT_ADMINISTRATOR; + } else { $normalCostShift = round($monthlySalary['monthly_salary'] / $normalCountShift, 1); $dailyPayment = $monthlySalary['daily_payment']; + + $hourPayment = $dailyPayment / Admin::SHIFT_HOUR_COUNT_FLORIST; } } @@ -2547,10 +2575,15 @@ class CabinetService $bonusByConvertionPercent = $this->bonusService->getBonusByConvertionPercent($conversionPercent, $employeeSelectStoreId, $dateFrom, $dateTo); $timetableAdmin = []; + $partTimeWagesSumAdminStore = 0; + $partTimeWagesCountAdminStore = 0; if (!empty($timetable)) { if (!empty($storeAdminsGuids)) { - $timetableAdmin = $this->getTimetableDate($timetable, $employeeId, $adminGuid, $storeAdminsGuids, $dateFrom, $dateTo, $normalCostShift, $isAdministrator, $entityCityStoreEmployeeSelect); + $timetableAdminValues = $this->getTimetableDate($timetable, $employeeId, $adminGuid, $storeAdminsGuids, $dateFrom, $dateTo, $normalCostShift, $isAdministrator, $entityCityStoreEmployeeSelect); + $timetableAdmin = ArrayHelper::getValue($timetableAdminValues, 'timetable'); + $partTimeWagesSumAdminStore = ArrayHelper::getValue($timetableAdminValues, 'partTimeWagesSum'); + $partTimeWagesCountAdminStore = ArrayHelper::getValue($timetableAdminValues, 'partTimeWagesCount'); } else { $errorText = 'У сотрудника "' . $employeeSelect['name_full'] . '"
'; $errorText .= 'за выбранный интервал с ' . $dateFrom . ' по ' . $dateTo . '
'; @@ -2569,11 +2602,19 @@ class CabinetService $timetableAdminTypeFirstShift = $timetableAdmin[array_key_first($timetableAdmin)]['typeSmenaInt']; } - if (!empty($timetableAnotherStore)) { - $timetableAdminAnotherStore = $this->getTimetableDate($timetableAnotherStore, $employeeId, $adminGuid, $anotherStoreAdminsGuids, $dateFrom, $dateTo, $normalCostShift, $isAdministrator); + $partTimeWagesSumAdminAnotherStore = 0; + $partTimeWagesCountAdminAnotherStore = 0; + if (!empty($timetableAnotherStore)) { + $timetableAdminAnotherStoreValues = $this->getTimetableDate($timetableAnotherStore, $employeeId, $adminGuid, $anotherStoreAdminsGuids, $dateFrom, $dateTo, $normalCostShift, $isAdministrator); + $timetableAdminAnotherStore = ArrayHelper::getValue($timetableAdminAnotherStoreValues, 'timetable'); + $partTimeWagesSumAdminAnotherStore = ArrayHelper::getValue($timetableAdminAnotherStoreValues, 'partTimeWagesSum'); + $partTimeWagesCountAdminAnotherStore = ArrayHelper::getValue($timetableAdminAnotherStoreValues, 'partTimeWagesCount'); } + $partTimeWagesSumAdminAllStore = $partTimeWagesSumAdminStore + $partTimeWagesSumAdminAnotherStore; + $partTimeWagesCountAdminAllStore = $partTimeWagesCountAdminStore + $partTimeWagesCountAdminAnotherStore; + if ($allowedConversionCalculate) { $conversionDayAdministrator = $this->getSumListConversion($employeeSelectStoreId, $dateFromConversion, $dateTo); $conversionShift = $this->getConversionShift($dateFromConversion, $dateTo, $employeeSelectStoreId); @@ -2684,10 +2725,17 @@ class CabinetService $personBonuses = ArrayHelper::getValue($personBonusesArray, 'bonuses'); // Персональная премия $personColorRubleBonuses = ArrayHelper::getValue($personBonusesArray, 'color_ruble_bonuses'); // Персональная премия $personRetention = ArrayHelper::getValue($personBonusesArray, 'retention'); // Персональный вычет + $personRetentionСomment = 'Персональный вычет'; + $personRetentionСommentText = ArrayHelper::getValue($personBonusesArray, 'retention_comment'); // Комментарий персонального вычета + if (!empty($personRetentionСommentText)) { + $personRetentionСomment = $personRetentionСommentText; + } $personPrepaidExpense = ArrayHelper::getValue($personBonusesArray, 'prepaid_expense'); // Аванс $personCounting = ArrayHelper::getValue($personBonusesArray, 'counting'); // Подсчёт $personVacationDay = ArrayHelper::getValue($personBonusesArray, 'vacation_day'); // Оплаченный отпуск $personVacationPay = $personVacationDay * $normalCostShift;//Стоимость одной смены + $personPartTimeJobHours = ArrayHelper::getValue($personBonusesArray, 'part_time_job_hours'); // Подработки в часах + $personPartTimeJobHoursPay = $personPartTimeJobHours * $hourPayment; // Стоимость подработки по часам в рублях $possibleSumGameBonusValuesFlorist = []; @@ -2717,6 +2765,25 @@ class CabinetService $allSumGameBonusValues = $allPossibleSumGameBonusValuesFlorist + $personSumColorRubleBonusesValues; + // Командный бонус + $teamBonus = $this->bonusService->getTeamBonus( $employeeId, $employeeSelectStoreId, $entityCityStoreEmployeeSelect, $dateFrom, $dateToEndMonth); + $teamBonusDetail = json_encode($teamBonus,JSON_UNESCAPED_UNICODE); + $teamBonusValuePrepared = ArrayHelper::getValue($teamBonus, 'personPrimeFondStore'); + $teamBonusValue = ($teamBonusValuePrepared > 0) ? $teamBonusValuePrepared : 0; + + $adminTeamPayrollTable = []; + if (!empty($teamBonus) && $isAdministrator) { + $adminTeamPayrollTable = $this->bonusService->getAdminTeamPayrollTable($teamBonus); + } + + // Премия за процент качества + $userQualityPercent = 0; // % качества + + $userQualityPercentPrepared = QualityRating::getQualityRating($employeeId, $dateTo); + if (!empty($userQualityPercentPrepared)) { + $userQualityPercent = $userQualityPercentPrepared; + } + $userQualityPremium = $this->bonusService->getBonusForQuality($userQualityPercent); $arrayTypes = ["wrap", "potted", "related","services","salut","other_items"]; @@ -2726,173 +2793,172 @@ class CabinetService $this->arr = [$adminGuid]; $adminGuidArr = $this->arr; - if (!empty($arrayProducts["services"])) { - $arrUsersSalaryServicesPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["services"], $adminGuidArr, $dateFrom, $dateTo, $exportAdmin, $isAdministrator); - $arrUsersSalaryServices = ArrayHelper::getColumn($arrUsersSalaryServicesPrepared, 'bonus'); - $arrUsersSalaryServicesCheck = ArrayHelper::getColumn($arrUsersSalaryServicesPrepared, 'check'); - } - if (!empty($arrayProducts["related"])) { - $arrUsersSalaryRelatedPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["related"], $adminGuidArr, $dateFrom, $dateTo, $exportAdmin, $isAdministrator); - $arrUsersSalaryRelated = ArrayHelper::getColumn($arrUsersSalaryRelatedPrepared, 'bonus'); - $arrUsersSalaryRelatedCheck = ArrayHelper::getColumn($arrUsersSalaryRelatedPrepared, 'check'); - } - if (!empty($arrayProducts["potted"])) { - $arrUsersSalaryPottedPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["potted"], $adminGuidArr, $dateFrom, $dateTo, $exportAdmin, $isAdministrator); - $arrUsersSalaryPotted = ArrayHelper::getColumn($arrUsersSalaryPottedPrepared, 'bonus'); - $arrUsersSalaryPottedCheck = ArrayHelper::getColumn($arrUsersSalaryPottedPrepared, 'check'); - } - if (!empty($arrayProducts["wrap"])) { - $arrUsersSalaryWrapPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["wrap"], $adminGuidArr, $dateFrom, $dateTo, $exportAdmin, $isAdministrator); - $arrUsersSalaryWrap = ArrayHelper::getColumn($arrUsersSalaryWrapPrepared, 'bonus'); - $arrUsersSalaryWrapCheck = ArrayHelper::getColumn($arrUsersSalaryWrapPrepared, 'check'); - } - if (!empty($arrayProducts["other_items"])) { - $arrUsersSalaryOtherItemsPrepared = SalaryHelper::getSalaryBonusMulty($arrayProducts["other_items"], $adminGuidArr, $dateFrom, $dateTo, $exportAdmin, $isAdministrator); - $arrUsersSalaryOtherItems = ArrayHelper::getColumn($arrUsersSalaryOtherItemsPrepared, 'bonus'); - $arrUsersSalaryOtherItemsCheck = ArrayHelper::getColumn($arrUsersSalaryOtherItemsPrepared, 'check'); - } - if (!empty($arrayProducts["salut"])) { -// $dateFromToSalutArray = $this->salesService->getAllowedStart($dateFrom, $dateTo, SalesService::$allowedCalculateBonusForSalut); + /**/ + $showHolidayVersion = HolidayService::getHolidayVersionShow($dateFrom, $dateTo); +// $showHolidayVersion = false; + /**/ - $arrUsersSalarySalutPrepared = SalaryHelper::getSalaryBonusSalut($arrayProducts["salut"], $adminGuidArr, $dateFrom, $dateTo, $exportAdmin, $isAdministrator, $employeeSelectStoreId); - $arrUsersSalarySalut = ArrayHelper::getColumn($arrUsersSalarySalutPrepared, 'bonus'); - $arrUsersSalarySalutCheck = ArrayHelper::getColumn($arrUsersSalarySalutPrepared, 'check'); + $arrResSalariesByFocusGroup = SalaryHelper::getSalariesByFocusGroup( + $employeeId, + $adminGuid, + $arrayProducts, + $adminGuidArr, + $dateFrom, + $dateTo, + $exportAdmin, + $isAdministrator, + $employeeSelectStoreId, + $showHolidayVersion + ); - } + $arrUsersSalary = ArrayHelper::getValue($arrResSalariesByFocusGroup, 'arrUsersSalary'); + $arrUsersSalaryCheck = ArrayHelper::getValue($arrResSalariesByFocusGroup, 'arrUsersSalaryCheck'); - $arrUsersSalary = [ - "services" => $arrUsersSalaryServices ?? [], - "related" => $arrUsersSalaryRelated ?? [], - "potted" => $arrUsersSalaryPotted ?? [], - "wrap" => $arrUsersSalaryWrap ?? [], - "salut" => $arrUsersSalarySalut ?? [], - "other_items" => $arrUsersSalaryOtherItems ?? [], - ]; + $premiumByFocusGroups = $this->getPremiumByFocusGroups($adminGuid, $arrUsersSalary, $dateFrom, $dateTo, $isAdministrator); - $arrUsersSalaryCheck = [ - "services" => $arrUsersSalaryServicesCheck[$adminGuid] ?? [], - "related" => $arrUsersSalaryRelatedCheck[$adminGuid] ?? [], - "potted" => $arrUsersSalaryPottedCheck[$adminGuid] ?? [], - "wrap" => $arrUsersSalaryWrapCheck[$adminGuid] ?? [], - "salut" => $arrUsersSalarySalutCheck[$adminGuid] ?? [], - "other_items" => $arrUsersSalaryOtherItemsCheck[$adminGuid] ?? [], - ]; + $userSalaryServices = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryServices'); + $userSalaryServicesPremium = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryServicesPremium'); - $userSalaryServices = 0; - if (array_key_exists($adminGuid, $arrUsersSalary["services"])) { - $userSalaryServices = ($arrUsersSalary["services"][$adminGuid] > 0) ? $arrUsersSalary["services"][$adminGuid] : 0; - }// услуги + $userSalaryRelated = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryRelated'); + $userSalaryRelatedPremium = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryRelatedPremium'); - $userSalaryRelated = 0; - if (array_key_exists($adminGuid, $arrUsersSalary["related"])) { - $userSalaryRelated = ($arrUsersSalary["related"][$adminGuid] > 0) ? $arrUsersSalary["related"][$adminGuid] : 0; // сопутка - } + $userSalaryPotted = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryPotted'); + $userSalaryPottedPremium = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryPottedPremium'); - $userSalaryPotted = 0; - if (array_key_exists($adminGuid, $arrUsersSalary["potted"])) { - $userSalaryPotted = ($arrUsersSalary["potted"][$adminGuid] > 0) ? $arrUsersSalary["potted"][$adminGuid] : 0; // горшечка - } + $userSalaryWrap = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryWrap'); + $userSalaryWrapPremium = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryWrapPremium'); - $userSalaryWrap = 0; - if (array_key_exists($adminGuid, $arrUsersSalary["wrap"])) { - $userSalaryWrap = ($arrUsersSalary["wrap"][$adminGuid] > 0) ? $arrUsersSalary["wrap"][$adminGuid] : 0; // упаковка - } + $userSalarySalut = ArrayHelper::getValue($premiumByFocusGroups, 'userSalarySalut'); + $userSalarySalutPremium = ArrayHelper::getValue($premiumByFocusGroups, 'userSalarySalutPremium'); - $userSalarySalut = 0; - if (array_key_exists($adminGuid, $arrUsersSalary["salut"])) { - $userSalarySalut = ($arrUsersSalary["salut"][$adminGuid] > 0) ? $arrUsersSalary["salut"][$adminGuid] : 0; // пиротехника - } + $userSalaryOtherItems = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryOtherItems'); + $userSalaryOtherItemsPremium = ArrayHelper::getValue($premiumByFocusGroups, 'userSalaryOtherItemsPremium'); - $userSalaryOtherItems = 0; - if (array_key_exists($adminGuid, $arrUsersSalary["other_items"])) { - $userSalaryOtherItems = ($arrUsersSalary["other_items"][$adminGuid] > 0) ? $arrUsersSalary["other_items"][$adminGuid] : 0; // Другие товары - } + $premiumByMatrix = $this->getPremiumByMatrix( + $employeeSelectStoreId, + $adminGuid, + $dateFrom, + $dateTo, + $isAdministrator, + $showHolidayVersion + ); - $userQualityPercent = 0; // % качества + $salesMatrix = ArrayHelper::getValue($premiumByMatrix, 'salesMatrix'); + $salaryMatrix = ArrayHelper::getValue($premiumByMatrix, 'salaryMatrix'); + $salaryMakeMatrix = ArrayHelper::getValue($premiumByMatrix, 'salaryMakeMatrix'); + $bonusSalaryMatrix = ArrayHelper::getValue($premiumByMatrix, 'bonusSalaryMatrix'); + $makeMatrix = ArrayHelper::getValue($premiumByMatrix, 'makeMatrix'); + $bonusMakeMatrix = ArrayHelper::getValue($premiumByMatrix, 'bonusMakeMatrix'); + $matrixPrime = ArrayHelper::getValue($premiumByMatrix, 'matrixPrime'); - $userQualityPercentPrepared = QualityRating::getQualityRating($employeeId, $dateTo); - if (!empty($userQualityPercentPrepared)) { - $userQualityPercent = $userQualityPercentPrepared; - } - $userQualityPremium = $this->bonusService->getBonusForQuality($userQualityPercent); + $consolidatedPremiumByStore = 0; + $onePartHolidayPremium = 0; + $adminsHolidayShiftCount = 0; + $personPremiumByStore = 0; - $teamBonus = $this->bonusService->getTeamBonus( $employeeId, $employeeSelectStoreId, $entityCityStoreEmployeeSelect, $dateFrom, $dateToEndMonth); - $teamBonusValuePrepared = ArrayHelper::getValue($teamBonus, 'personPrimeFondStore'); - $teamBonusValue = ($teamBonusValuePrepared > 0) ? $teamBonusValuePrepared : 0; + $onePartHolidayPremium = 0; + $personHolidayShiftCount = 0; - $userSalaryServicesPremium = round($userSalaryServices * 0.1); // 10% за продажу услуг - $userSalaryRelatedPremium = round($userSalaryRelated * 0.05); // 5% за личные продажи сопутки - $userSalaryPottedPremium = round($userSalaryPotted * 0.05); - $userSalaryWrapPremium = round($userSalaryWrap * 0.05); // 5% за личные продажи упаковки + if ($showHolidayVersion) { + // Премирование на праздники + $consolidatedArrResSalariesByFocusGroup = SalaryHelper::getSalariesByFocusGroup( + $employeeId, + $adminGuid, + $arrayProducts, + $adminGuidArr, + $dateFrom, + $dateTo, + $exportAdmin, + $isAdministrator, + $employeeSelectStoreId, + $showHolidayVersion, +false + ); - $userSalarySalutPremium = round($userSalarySalut * 0.05); // 5% за личные продажи пиротехники + $consolidatedArrUsersSalary = ArrayHelper::getValue($consolidatedArrResSalariesByFocusGroup, 'arrUsersSalary'); + $consolidatedArrUsersSalaryCheck = ArrayHelper::getValue($consolidatedArrResSalariesByFocusGroup, 'arrUsersSalaryCheck'); + $consolidatedAdminGuidDateArrByFocusGroup = ArrayHelper::getValue($consolidatedArrResSalariesByFocusGroup, 'adminGuidDateArrByFocusGroup'); - $userSalaryOtherItemsPremium = round($userSalaryOtherItems * 0.01); // 1% за личные продажи не фокусной продукции (Другме товары) - //Букеты по матрице + $consolidatedPremiumByFocusGroups = $this->getPremiumByFocusGroups($adminGuid, $consolidatedArrUsersSalary, $dateFrom, $dateTo, $isAdministrator); - $salesMatrix = $this->salesService->getMatrixSalesProducts($adminGuid, $dateFrom, $dateTo, $isAdministrator); + $consolidatedUserSalaryServices = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryServices'); + $consolidatedUserSalaryServicesPremium = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryServicesPremium'); - $salesMatrixProductGuids = ArrayHelper::getColumn($salesMatrix, 'product_guid'); - $salesMatrixProducts = Products1c::getProducts1cByType('products', $salesMatrixProductGuids); - $salesMatrixProductNames = ArrayHelper::map($salesMatrixProducts, 'id','name'); + $consolidatedUserSalaryRelated = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryRelated'); + $consolidatedUserSalaryRelatedPremium = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryRelatedPremium'); - $salaryMatrix = 0; - $bonusSalaryMatrix = 0; - $salesMatrixTemp = $salesMatrix; - foreach ($salesMatrixTemp as $keySalesMatrix => $row) { - $matrixBonusCoefficientRow = $this->bonusService->getMatrixBonusCoefficient($row['date']); - $rowBonus = $row["summ"] * $matrixBonusCoefficientRow; - $salesMatrix[$keySalesMatrix]["bonus"] = $rowBonus; - if($row["operation"] == Sales::OPERATION_SALE) { - $salaryMatrix += $row["summ"]; - $bonusSalaryMatrix += $rowBonus; - } elseif($row["operation"] == Sales::OPERATION_RETURN) { - $salaryMatrix -= $row["summ"]; - $bonusSalaryMatrix -= $rowBonus; - } - $productNameRow = ''; - if (array_key_exists($row["product_guid"], $salesMatrixProductNames)) { - $productNameRow = ArrayHelper::getValue($salesMatrixProductNames, $row["product_guid"]); - } - $salesMatrix[$keySalesMatrix]["product_name"] = $productNameRow; - } + $consolidatedUserSalaryPotted = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryPotted'); + $consolidatedUserSalaryPottedPremium = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryPottedPremium'); - $bonusSalaryMatrix = round($bonusSalaryMatrix); + $consolidatedUserSalaryWrap = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryWrap'); + $consolidatedUserSalaryWrapPremium = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryWrapPremium'); - $makeMatrix = $this->salesService->getMatrixMakeProducts($adminGuid, $dateFrom, $dateTo, $isAdministrator); + $consolidatedUserSalarySalut = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalarySalut'); + $consolidatedUserSalarySalutPremium = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalarySalutPremium'); - $makeMatrixProductGuids = ArrayHelper::getColumn($makeMatrix, 'product_guid'); - $makeMatrixProducts = Products1c::getProducts1cByType('products', $makeMatrixProductGuids); - $makeMatrixProductNames = ArrayHelper::map($makeMatrixProducts, 'id','name'); + $consolidatedUserSalaryOtherItems = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryOtherItems'); + $consolidatedUserSalaryOtherItemsPremium = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryOtherItemsPremium'); - $salaryMakeMatrix = 0; - $bonusMakeMatrix = 0; - $makeMatrixTemp = $makeMatrix; - foreach ($makeMatrixTemp as $kayMakeMatrix => $row) { - $matrixBonusCoefficientRow = $this->bonusService->getMatrixBonusCoefficient($row['date']); - $rowBonus = $row["summ"] * $matrixBonusCoefficientRow; - $makeMatrix[$kayMakeMatrix]["bonus"] = $rowBonus; - if($row["operation"] == Sales::OPERATION_SALE) { - $salaryMakeMatrix += $row["summ"]; - $bonusMakeMatrix += $rowBonus; - } elseif($row["operation"] == Sales::OPERATION_RETURN) { - $salaryMakeMatrix -= $row["summ"]; - $bonusMakeMatrix -= $rowBonus; + $consolidatedUserSalaryPremiumSum = ArrayHelper::getValue($consolidatedPremiumByFocusGroups, 'userSalaryPremiumSum'); + + + + $adminGuidNames = Admin::getAdminGuidNames(); + + $consolidatedArrUsersSalaryCheckTmp = $consolidatedArrUsersSalaryCheck; + foreach ($consolidatedArrUsersSalaryCheckTmp as $key => $rows) { + foreach ($rows as $keyInner => $item) { + $consolidatedArrUsersSalaryCheck[$key][$keyInner]['name'] = $adminGuidNames[$item['seller_id']] ?? $item['seller_id']; + } } - $productNameRow = ''; - if (array_key_exists($row["product_guid"], $makeMatrixProductNames)) { - $productNameRow = ArrayHelper::getValue($makeMatrixProductNames, $row["product_guid"]); + // Премия за матрицу в праздники + + $consolidatedPremiumByMatrix = $this->getPremiumByMatrix( + $employeeSelectStoreId, + $adminGuid, + $dateFrom, + $dateTo, + $isAdministrator, + $showHolidayVersion, + false + ); + + $consolidatedSalesMatrix = ArrayHelper::getValue($consolidatedPremiumByMatrix, 'salesMatrix'); + $consolidatedSalaryMatrix = ArrayHelper::getValue($consolidatedPremiumByMatrix, 'salaryMatrix'); + $consolidatedSalaryMakeMatrix = ArrayHelper::getValue($consolidatedPremiumByMatrix, 'salaryMakeMatrix'); + $consolidatedBonusSalaryMatrix = ArrayHelper::getValue($consolidatedPremiumByMatrix, 'bonusSalaryMatrix'); + $consolidatedMakeMatrix = ArrayHelper::getValue($consolidatedPremiumByMatrix, 'makeMatrix'); + $consolidatedBonusMakeMatrix = ArrayHelper::getValue($consolidatedPremiumByMatrix, 'bonusMakeMatrix'); + $consolidatedMatrixPrime = ArrayHelper::getValue($consolidatedPremiumByMatrix, 'matrixPrime'); + $consolidatedAdminGuidDateArrByMatrix = ArrayHelper::getValue($consolidatedPremiumByMatrix, 'adminGuidDateArrByMatrix'); + + $consolidatedPremiumByStore = $consolidatedMatrixPrime + $consolidatedUserSalaryPremiumSum; + + $shiftCount = []; + $countByUser = []; + + foreach ($consolidatedAdminGuidDateArrByFocusGroup as $subKey => $users) { + $shiftCount[] = count($users); + foreach ($users as $user) { + if (array_key_exists($user, $countByUser)){ + ++$countByUser[$user]; + } else { + $countByUser[$user] = 1; + } + } } - $makeMatrix[$kayMakeMatrix]["product_name"] = $productNameRow; - } - $bonusMakeMatrix = round($bonusMakeMatrix); + $adminsHolidayShiftCount = array_sum($shiftCount) ; + $personHolidayShiftCount = $countByUser[$adminGuid] ?? 0; + if (!empty($adminsHolidayShiftCount)) { + $onePartHolidayPremium = $consolidatedPremiumByStore / $adminsHolidayShiftCount; + } + $personPremiumByStore = $onePartHolidayPremium * $personHolidayShiftCount; - // итого: премия с матрицы - $matrixPrime = $bonusSalaryMatrix + $bonusMakeMatrix; + } $wagesBonusNormaSmenaAnotherStore = []; if (!empty($timetableAdminAnotherStoreById)) { @@ -2955,6 +3021,13 @@ class CabinetService $arrayColumnWages = array_merge($arrayColumnWages, $personBonusesArrayInfo); } + if (!empty($personPartTimeJobHoursPay)) { + $personBonusesArrayInfo = [ + 'Оплата подработок по часам' . ' ('. $personPartTimeJobHours . '*' . $hourPayment . ' руб/час из оклада)' => (int) $personPartTimeJobHoursPay, + ]; + $arrayColumnWages = array_merge($arrayColumnWages, $personBonusesArrayInfo); + } + if (!empty($personVacationPay)) { $personBonusesArrayInfo = [ 'Оплата за отпуск ' . $personVacationDay. ' дня' => $personVacationPay, @@ -3009,6 +3082,14 @@ class CabinetService 'Командный бонус' => $teamBonusValue, ); + if (!empty($personPremiumByStore)) { + $personBonusesArrayInfo = [ + 'Премия за продажу фокусных позиции в праздники' => $personPremiumByStore, + ]; + $variableSumValuesAdministrator = array_merge($personBonusesArrayInfo, $variableSumValuesAdministrator); + } + + $allVariableSumValuesAdministrator = array_sum($variableSumValuesAdministrator); @@ -3057,6 +3138,14 @@ class CabinetService 'Премия за сборку матрицы' => $bonusMakeMatrix, // 'Премия за продажи не фокусной продукции (Другме товары)' => $userSalaryOtherItemsPremium, ]; + + if (!empty($personPremiumByStore)) { + $personBonusesArrayInfo = [ + 'Премия за продажу фокусных позиции в праздники' => $personPremiumByStore, + ]; + $bonusVariable = array_merge($personBonusesArrayInfo, $bonusVariable); + } + $bonusVariableByMonth = [ 'Премия за качество' => $userQualityPremium, ]; @@ -3070,6 +3159,14 @@ class CabinetService $bonusVariableByMonth = array_merge($personBonusesArrayInfo, $bonusVariableByMonth); } + + if (!empty($personPartTimeJobHoursPay)) { + $personBonusesArrayInfo = [ + 'Оплата подработок по часам' . ' ('. $personPartTimeJobHours . '*' . $hourPayment . ' руб/час из оклада)'=> $personPartTimeJobHoursPay, + ]; + $bonusVariableByMonth = array_merge($personBonusesArrayInfo, $bonusVariableByMonth); + } + $bonusConstant = [ ]; @@ -3112,6 +3209,20 @@ class CabinetService $sumValuesFlorist = array_merge($personBonusesArrayInfo, $sumValuesFlorist); } + if (!empty($personPremiumByStore)) { + $personBonusesArrayInfo = [ + 'Премия за продажу фокусных позиции в праздники' => $personPremiumByStore, + ]; + $sumValuesFlorist = array_merge($personBonusesArrayInfo, $sumValuesFlorist); + } + + if (!empty($personPartTimeJobHoursPay)) { + $personBonusesArrayInfo = [ + 'Оплата подработок по часам' . ' ('. $personPartTimeJobHours . '*' . $hourPayment . ' руб/час из оклада)' => (int) $personPartTimeJobHoursPay, + ]; + $arrayColumnWages = array_merge($arrayColumnWages, $personBonusesArrayInfo); + } + if (!empty($personVacationPay)) { $personBonusesArrayInfo = [ 'Оплата за отпуск ' . $personVacationDay. ' дня' => $personVacationPay, @@ -3171,6 +3282,14 @@ class CabinetService 'Премия за продажи не фокусной продукции (Другме товары)' => $userSalaryOtherItemsPremium, ]; + if (!empty($personPremiumByStore)) { + $personBonusesArrayInfo = [ + 'Премия за продажу фокусных позиции в праздники' => $personPremiumByStore, + ]; + $bonusVariable = array_merge($personBonusesArrayInfo, $bonusVariable); + } + + $bonusVariableByMonth = [ 'Премия за качество' => $userQualityPremium, ]; @@ -3183,6 +3302,15 @@ class CabinetService ]; $bonusVariableByMonth = array_merge($personBonusesArrayInfo, $bonusVariableByMonth); } + + + if (!empty($personPartTimeJobHoursPay)) { + $personBonusesArrayInfo = [ + 'Оплата подработок по часам' . ' ('. $personPartTimeJobHours . '*' . $hourPayment . ' руб/час из оклада)' => $personPartTimeJobHoursPay, + ]; + $bonusVariableByMonth = array_merge($personBonusesArrayInfo, $bonusVariableByMonth); + } + if (!empty($sumValuesFloristAnotherStore)) { $bonusConstant = array_merge($bonusConstant, $sumValuesFloristAnotherStore); } @@ -3208,9 +3336,20 @@ class CabinetService $alreadyPay = [ 'Аванс' => $personPrepaidExpense, - 'Подсчет' => $personCounting, ]; + if (!empty($personCounting)) { + $alreadyPay = array_merge($alreadyPay, [ + 'Подсчет' => $personCounting, + ]); + } + + if (!empty($partTimeWagesSumAdminAllStore)) { + $alreadyPay = array_merge($alreadyPay, [ + 'Оплата подработок (количество смен ' . $partTimeWagesCountAdminAllStore . ')' => $partTimeWagesSumAdminAllStore, + ]); + } + $personRetentionValue = 0; if (!empty($personRetention)) { @@ -3218,13 +3357,21 @@ class CabinetService } $personRetentionArray = [ - 'Персональный вычет' => $personRetentionValue, + $personRetentionСomment => $personRetentionValue, ]; + $sumPersonRetention = array_sum($personRetentionArray); + + $alreadyPaySum = array_sum($alreadyPay); + $minusSum = array_merge($alreadyPay, $personRetentionArray); $minusSumValue = array_sum($minusSum); $toPayoff = $allTotalPayroll - $minusSumValue; + + $allowShowPersonRetention = date('Y-m-d',time()) >= date('Y-m-t',strtotime($dateFrom)); + return [ + 'allowShowPersonRetention' => $allowShowPersonRetention, 'dateFrom' => $dateFrom, 'employeeId' => $employeeId, @@ -3294,6 +3441,8 @@ class CabinetService 'userQualityPremium' => $userQualityPremium ?? 0, 'teamBonus' => $teamBonus ?? [], // 'Командный бонус' + 'teamBonusDetail' => $teamBonusDetail ?? '', // 'Командный бонус детально' + 'adminTeamPayrollTable' => $adminTeamPayrollTable ?? [], // 'Командный бонус детально' 'teamBonusValue' => $teamBonusValue ?? 0, // 'Командный бонус' 'userSalaryServicesPremium' => $userSalaryServicesPremium ?? [], @@ -3303,6 +3452,8 @@ class CabinetService 'arrUsersSalaryCheck' => $arrUsersSalaryCheck ?? [], + 'showHolidayVersion' => $showHolidayVersion, + 'daysInSelectMonth' => $daysInSelectMonth, 'daysRemainsInSelectMonth' => $daysRemainsInSelectMonth, @@ -3368,9 +3519,17 @@ class CabinetService 'personBonuses' => $personBonuses, // Персональная премия 'personRetention' => $personRetention, // Персональный вычет + 'personRetentionArray' => $personRetentionArray, // Персональный вычет массив + 'sumPersonRetention' => $sumPersonRetention, // Персональный вычет сумма + 'personPrepaidExpense' => $personPrepaidExpense, // Аванс 'personCounting' => $personCounting, // Подсчёт + 'alreadyPay' => $alreadyPay, // Выплат за выбранный месяц + 'alreadyPaySum' => $alreadyPaySum, // Сумма выплат за выбранный месяц + 'partTimeWagesSumAdminAllStore' => $partTimeWagesSumAdminAllStore, // Оклады за подработку + 'partTimeWagesCountAdminAllStore' => $partTimeWagesCountAdminAllStore, // Число смен подработок + 'toPayoff' => $toPayoff, // К выплате 'oklad' => $oklad, // Оклад штатный @@ -3444,6 +3603,18 @@ class CabinetService 'sumChecksStore' => $sumChecksStore ?? 0, 'sumIncomingTrafficStore' => $sumIncomingTrafficStore ?? 0, 'conversionPercent' => $conversionPercent ?? 0, + + 'consolidatedArrUsersSalaryCheck' => $consolidatedArrUsersSalaryCheck ?? [], + 'consolidatedPremiumByFocusGroups' => $consolidatedPremiumByFocusGroups ?? [], + + 'consolidatedPremiumByMatrix' => $consolidatedPremiumByMatrix ?? [], + 'consolidatedPremiumByStore' => $consolidatedPremiumByStore ?? 0, + + 'onePartHolidayPremium' => $onePartHolidayPremium, + 'adminsHolidayShiftCount' => $adminsHolidayShiftCount, + 'personPremiumByStore' => $personPremiumByStore, + 'personHolidayShiftCount' => $personHolidayShiftCount, + 'saveValuesOk' => 'ok', ]; } @@ -4307,10 +4478,6 @@ Group BY `admin_id` */ public function getTimetableDate($timetable ,$employeeId , $adminGuid, array $storeAdminsGuids, $dateFrom, $dateTo, $normalCostShift, bool $isAdministrator, $entityCityStoreEmployeeSelect = null): array { - - - - $salesForAdmin = $this->getSalurySum($adminGuid, $dateFrom, $dateTo, $isAdministrator); $salesForStore = []; @@ -4375,8 +4542,6 @@ Group BY `admin_id` - - $salesAdmins[$adminId] = [ 'id' => $adminId, 'group_id' => $adminGroupIdRow, @@ -4392,7 +4557,9 @@ Group BY `admin_id` $adminGroupId = AdminGroupDynamic::getGroupByDate($employeeId, $dateFrom, $dateTo); $timetableTemp = $timetable; - + $partTimeWagesSum = 0; + $partTimeWagesCount = 0; + $parTimeWagesAdminIds = []; foreach ($timetableTemp as $keyTimetable => $row) { @@ -4410,6 +4577,8 @@ Group BY `admin_id` $daySale = 0; + $timetable[$keyTimetable]['wagesInfo'] = ''; + $wagesInfo = ''; $timetable[$keyTimetable]['daySale'] = 0; @@ -4430,11 +4599,21 @@ Group BY `admin_id` if ($isAdministrator && $timetable[$keyTimetable]['admin_id'] != $employeeId) { $timetable[$keyTimetable]['wages'] = 0; } else { - $timetable[$keyTimetable]['wages'] = $normalCostShift; + $normalCostShiftRow = $normalCostShift; + if (!empty($row['salary_shift'])) { + $normalCostShiftRow = ($row['salary_shift']); + } + $timetable[$keyTimetable]['wages'] = $normalCostShiftRow; + if ($row['d_id'] == Admin::PART_TIME_WORKER_GROUP_ID) { + $timetable[$keyTimetable]['wagesInfo'] = 'подработка'; + $wagesInfo = ' (подработка)'; + $timetable[$keyTimetable]['partTimeWorkWages'] = $normalCostShiftRow; + $partTimeWagesSum = $partTimeWagesSum + $normalCostShiftRow; + $parTimeWagesAdminIds[] = $row['admin_id']; + ++$partTimeWagesCount; + } } - - $timetableAdminsIds = ArrayHelper::getValue($row, 'timetable_admins_ids'); $rateTimetableAdminsNames = []; @@ -4471,8 +4650,6 @@ Group BY `admin_id` ]; $adminsSales[$timetableAdminsId] = $sumRow; - - } $adminsSalesSum = 0; @@ -4512,19 +4689,21 @@ Group BY `admin_id` } } - - $adminNameColumn = ArrayHelper::getColumn($rateTimetableAdminsNames, 'name'); $adminNameList = implode(',
' , $adminNameColumn); - $timetable[$keyTimetable]['typeSmena'] = $typeSmena; + $timetable[$keyTimetable]['typeSmena'] = $typeSmena . $wagesInfo; $timetable[$keyTimetable]['adminNameList'] = $adminNameList; $timetable[$keyTimetable]['typeSmenaInt'] = $typeSmenaInt; $timetable[$keyTimetable]['adminsSalesSum'] = $adminsSalesSum; } - return $timetable; + return [ + 'timetable' => $timetable, + 'partTimeWagesSum' => $partTimeWagesSum, + 'partTimeWagesCount' => $partTimeWagesCount, + ]; } @@ -6091,7 +6270,7 @@ Group BY `admin_id` $storeIdsString = ArrayHelper::getValue($clusterAdmin, 'store_arr'); $clusterAdminId = ArrayHelper::getValue($clusterAdmin, 'id'); - $storeIds = explode(',', $storeIdsString); + $storeIds = array_unique(explode(',', $storeIdsString)); $groupIds = [ Admin::ADMINISTRATOR_GROUP_ID // Администраторы @@ -7484,4 +7663,241 @@ Group BY `admin_id` return $result; } + /** + * @return int + */ + public function getAdministratorSalaryShift($employeeId, $dateFrom, $salesByStore = null) : int + { + $administratorOklad = 0; + + if ($dateFrom >= '2023-12-01') { + $monthlySalary = EmployeePayment::getMonthlySalary($employeeId, $dateFrom); + $administratorOklad = ArrayHelper::getValue($monthlySalary, 'monthly_salary'); + + } else { + $administratorOklad = $this->bonusService->getAdministratorOklad($salesByStore); + } + + return (int) $administratorOklad; + } + + public function getPremiumByFocusGroups($adminGuid, $arrUsersSalary, $dateFrom, $dateTo, $isAdministrator): array + { + $userSalaryServices = 0; + if (array_key_exists($adminGuid, $arrUsersSalary["services"])) { + $userSalaryServices = ($arrUsersSalary["services"][$adminGuid] > 0) ? $arrUsersSalary["services"][$adminGuid] : 0; + }// услуги + + $userSalaryRelated = 0; + if (array_key_exists($adminGuid, $arrUsersSalary["related"])) { + $userSalaryRelated = ($arrUsersSalary["related"][$adminGuid] > 0) ? $arrUsersSalary["related"][$adminGuid] : 0; // сопутка + } + + $userSalaryPotted = 0; + if (array_key_exists($adminGuid, $arrUsersSalary["potted"])) { + $userSalaryPotted = ($arrUsersSalary["potted"][$adminGuid] > 0) ? $arrUsersSalary["potted"][$adminGuid] : 0; // горшечка + } + + $userSalaryWrap = 0; + if (array_key_exists($adminGuid, $arrUsersSalary["wrap"])) { + $userSalaryWrap = ($arrUsersSalary["wrap"][$adminGuid] > 0) ? $arrUsersSalary["wrap"][$adminGuid] : 0; // упаковка + } + + $userSalarySalut = 0; + if (array_key_exists($adminGuid, $arrUsersSalary["salut"])) { + $userSalarySalut = ($arrUsersSalary["salut"][$adminGuid] > 0) ? $arrUsersSalary["salut"][$adminGuid] : 0; // пиротехника + } + + $userSalaryOtherItems = 0; + if (array_key_exists($adminGuid, $arrUsersSalary["other_items"])) { + $userSalaryOtherItems = ($arrUsersSalary["other_items"][$adminGuid] > 0) ? $arrUsersSalary["other_items"][$adminGuid] : 0; // Другие товары + } + + $userSalaryServicesPremium = round($userSalaryServices * 0.1); // 10% за продажу услуг + $userSalaryRelatedPremium = round($userSalaryRelated * 0.05); // 5% за личные продажи сопутки + $userSalaryPottedPremium = round($userSalaryPotted * 0.05); + $userSalaryWrapPremium = round($userSalaryWrap * 0.05); // 5% за личные продажи упаковки + + $userSalarySalutPremium = round($userSalarySalut * 0.05); // 5% за личные продажи пиротехники + + $userSalaryOtherItemsPremium = round($userSalaryOtherItems * 0.01); // 1% за личные продажи не фокусной продукции (Другме товары) + + $userSalaryPremium = [ + 'userSalaryServicesPremium' => $userSalaryServicesPremium, + 'userSalaryRelatedPremium' => $userSalaryRelatedPremium, + 'userSalaryPottedPremium' => $userSalaryPottedPremium, + 'userSalaryWrapPremium' => $userSalaryWrapPremium, + 'userSalarySalutPremium' => $userSalarySalutPremium, + 'userSalaryOtherItemsPremium' => $userSalaryOtherItemsPremium, + ]; + + $userSalaryPremiumSum = array_sum($userSalaryPremium); + + return [ + 'userSalaryServices' => $userSalaryServices, + 'userSalaryServicesPremium' => $userSalaryServicesPremium, + 'userSalaryRelated' => $userSalaryRelated, + 'userSalaryRelatedPremium' => $userSalaryRelatedPremium, + 'userSalaryPotted' => $userSalaryPotted, + 'userSalaryPottedPremium' => $userSalaryPottedPremium, + 'userSalaryWrap' => $userSalaryWrap, + 'userSalaryWrapPremium' => $userSalaryWrapPremium, + 'userSalarySalut' => $userSalarySalut, + 'userSalarySalutPremium' => $userSalarySalutPremium, + 'userSalaryOtherItems' => $userSalaryOtherItems, + 'userSalaryOtherItemsPremium' => $userSalaryOtherItemsPremium, + 'userSalaryPremiumSum' => $userSalaryPremiumSum, + ]; + } + + public function getPremiumByMatrix( + $employeeSelectStoreId, + $adminGuid, + $dateFrom, + $dateTo, + $isAdministrator, + $showHolidayVersion = false, + $notHolidayCalculate = true + ): array { + $adminGuidDateArr = []; + $adminGuidArrAll = []; + if ($showHolidayVersion) { + $holidayDatesBetweenPrepared = HolidayService::getHolidayDatesBetween($dateFrom, $dateTo); + if ($notHolidayCalculate) { + $dataKey = 'notHolidayDatesInterval'; + } else { + $dataKey = 'dayHolidayInArray'; + $adminGuidDateArr = SalaryHelper::getAdminGuidByStore($dateFrom, $dateTo, $employeeSelectStoreId); + $isAdministrator = false; + } + $dates = ArrayHelper::getValue($holidayDatesBetweenPrepared, $dataKey); + } else { + $dates = [ + 0 => [ + 'dateFrom' => $dateFrom, + 'dateTo' => $dateTo, + ], + ]; + } + + $salesMatrixTemp = []; + $makeMatrixTemp = []; + + foreach ($dates as $key => $datesRow) { + $dateFromRow = $datesRow['dateFrom']; + $dateToRow = $datesRow['dateTo']; + $adminGuids = []; + if ( + true === $showHolidayVersion + && + $dateFromRow == $dateToRow + && + !empty($adminGuidDateArr) + + ) { + if (array_key_exists($dateFromRow, $adminGuidDateArr)) { + $adminGuids = $adminGuidDateArr[$dateFromRow]; + $adminGuidArrAll[] = $adminGuids; + } else { + $testtt = 0; + continue; + } + } + + //Букеты по матрице + + $salesMatrixRow = $this->salesService->getMatrixSalesProducts($adminGuid, $dateFromRow, $dateToRow, $isAdministrator, $adminGuids); + $salesMatrixTemp = array_merge($salesMatrixTemp, $salesMatrixRow); + + + $makeMatrixRow = $this->salesService->getMatrixMakeProducts($adminGuid, $dateFromRow, $dateToRow, $isAdministrator, $adminGuids); + $makeMatrixTemp = array_merge($makeMatrixTemp, $makeMatrixRow); + } + + $productMatrixTemp = array_merge($salesMatrixTemp, $makeMatrixTemp); + + $adminGuidNames = Admin::getAdminGuidNames(); + + $matrixProductGuids = ArrayHelper::getColumn($productMatrixTemp, 'product_guid'); + $matrixProducts = Products1c::getProducts1cByType('products', $matrixProductGuids); + $matrixProductNames = ArrayHelper::map($matrixProducts, 'id', 'name'); + + $salaryMatrix = 0; + $bonusSalaryMatrix = 0; + $salesMatrix = $salesMatrixTemp; + foreach ($salesMatrixTemp as $keySalesMatrix => $row) { + $matrixBonusCoefficientRow = $this->bonusService->getMatrixBonusCoefficient($row['date']); + $rowBonus = $row["summ"] * $matrixBonusCoefficientRow; + $salesMatrix[$keySalesMatrix]["bonus"] = $rowBonus; + if ($row["operation"] == Sales::OPERATION_SALE) { + $salaryMatrix += $row["summ"]; + $bonusSalaryMatrix += $rowBonus; + } elseif ($row["operation"] == Sales::OPERATION_RETURN) { + $salaryMatrix -= $row["summ"]; + $bonusSalaryMatrix -= $rowBonus; + } + $productNameRow = ''; + if (array_key_exists($row["product_guid"], $matrixProductNames)) { + $productNameRow = ArrayHelper::getValue($matrixProductNames, $row["product_guid"]); + } + $salesMatrix[$keySalesMatrix]["product_name"] = $productNameRow; + + if (!$notHolidayCalculate) { + $adminNameRow = ''; + if (array_key_exists($row["seller_id"], $adminGuidNames)) { + $adminNameRow = ArrayHelper::getValue($adminGuidNames, $row["seller_id"]); + } + $salesMatrix[$keySalesMatrix]["admin_name"] = $adminNameRow; + } + } + + $bonusSalaryMatrix = round($bonusSalaryMatrix); + + + $salaryMakeMatrix = 0; + $bonusMakeMatrix = 0; + $makeMatrix = $makeMatrixTemp; + foreach ($makeMatrixTemp as $kayMakeMatrix => $row) { + $matrixBonusCoefficientRow = $this->bonusService->getMatrixBonusCoefficient($row['date']); + $rowBonus = $row["summ"] * $matrixBonusCoefficientRow; + $makeMatrix[$kayMakeMatrix]["bonus"] = $rowBonus; + if ($row["operation"] == Sales::OPERATION_SALE) { + $salaryMakeMatrix += $row["summ"]; + $bonusMakeMatrix += $rowBonus; + } elseif ($row["operation"] == Sales::OPERATION_RETURN) { + $salaryMakeMatrix -= $row["summ"]; + $bonusMakeMatrix -= $rowBonus; + } + + $productNameRow = ''; + if (array_key_exists($row["product_guid"], $matrixProductNames)) { + $productNameRow = ArrayHelper::getValue($matrixProductNames, $row["product_guid"]); + } + $makeMatrix[$kayMakeMatrix]["product_name"] = $productNameRow; + + if (!$notHolidayCalculate) { + $adminNameRow = ''; + if (array_key_exists($row["seller_id"], $adminGuidNames)) { + $adminNameRow = ArrayHelper::getValue($adminGuidNames, $row["seller_id"]); + } + $makeMatrix[$kayMakeMatrix]["admin_name"] = $adminNameRow; + } + } + + $bonusMakeMatrix = round($bonusMakeMatrix); + + // итого: премия с матрицы + $matrixPrime = $bonusSalaryMatrix + $bonusMakeMatrix; + + return [ + 'salesMatrix' => $salesMatrix, + 'bonusSalaryMatrix' => $bonusSalaryMatrix, + 'makeMatrix' => $makeMatrix, + 'salaryMatrix' => $salaryMatrix, + 'salaryMakeMatrix' => $salaryMakeMatrix, + 'bonusMakeMatrix' => $bonusMakeMatrix, + 'matrixPrime' => $matrixPrime, + 'adminGuidDateArrByMatrix' => $adminGuidArrAll, + ]; + } } diff --git a/erp24/services/DashboardService.php b/erp24/services/DashboardService.php index 685d2e3..a64816a 100755 --- a/erp24/services/DashboardService.php +++ b/erp24/services/DashboardService.php @@ -452,6 +452,7 @@ class DashboardService $data = $command->queryAll(); $dataArraySalesAll = []; + $dataSaleCumulative = []; $SalesMStores = []; $SalesM = []; @@ -558,7 +559,17 @@ class DashboardService } else { continue; } - $sale = $dataSaleCumulative[$row["date_p"]][$storeId]; + $sale = 0; + + if ( + array_key_exists($row["date_p"], $dataSaleCumulative) + && + array_key_exists($storeId, $dataSaleCumulative[$row["date_p"]]) + && + !empty($dataSaleCumulative[$row["date_p"]][$storeId]) + ) { + $sale = $dataSaleCumulative[$row["date_p"]][$storeId]; + } if (!array_key_exists($row["date_m"], $write_offs)) { diff --git a/erp24/services/HolidayService.php b/erp24/services/HolidayService.php new file mode 100644 index 0000000..3c60ded --- /dev/null +++ b/erp24/services/HolidayService.php @@ -0,0 +1,85 @@ + $row[array_key_first($row)], + 'dateTo' => $row[array_key_last($row)], + ]; + } + } + $holidaysDatesInterval = []; + + if (!empty($dayHolidayIn)) { + foreach ($dayHolidayIn as $row) { + $holidaysDatesInterval[] = [ + 'dateFrom' => $row, + 'dateTo' => $row, + ]; + } + } + + return [ + 'dayHolidayInArray' => $holidaysDatesInterval, + 'notHolidayDatesInterval' => $notHolidayDatesInterval, + ]; + } +} \ No newline at end of file diff --git a/erp24/services/SalesService.php b/erp24/services/SalesService.php index 40350b1..33c39f1 100755 --- a/erp24/services/SalesService.php +++ b/erp24/services/SalesService.php @@ -1076,7 +1076,6 @@ class SalesService } - /** * "СТАРУЮ МАТРИЦУ" пробитую до 16.11 в зп начисляем как 2,5 %, * с 16.11 по 7.12 за "СТАРУЮ МАТРИЦУ" НАЧИСЛЯЕМ 2%, после 7.12 ее не считаем в ЗП совсем. @@ -1085,18 +1084,24 @@ class SalesService * @param string $adminGuid * @param string $dateFrom * @param string $dateTo + * @param $isAdministrator + * @param null $adminGuids * @return array * @throws \yii\db\Exception */ - public function getMatrixSalesProducts(string $adminGuid, string $dateFrom, string $dateTo, $isAdministrator) : array + public function getMatrixSalesProducts(string $adminGuid, string $dateFrom, string $dateTo, $isAdministrator, $adminGuids = null) : array { $adminsGuids = $this->adminsGuids; $adminId = null; - if (array_key_exists($adminGuid, $adminsGuids)) { + if (array_key_exists($adminGuid, $adminsGuids) && empty($adminGuids)) { $adminId = ArrayHelper::getValue($adminsGuids, $adminGuid); } + if (!empty($adminGuids) && is_array($adminGuids)) { + $adminGuid = implode("','", $adminGuids); + } + $dateTimeStartDay = false; $dateTimeEndDay = false; @@ -1125,7 +1130,7 @@ class SalesService sales_products as p, sales WHERE - sales.seller_id = :admin_guid + sales.seller_id IN ('$adminGuid') AND sales.id = p.check_id AND ( @@ -1155,7 +1160,7 @@ class SalesService sales.date ASC ", - [ ':admin_guid' => $adminGuid, + [ ':date_from' => DateHelper::getDateTimeStartDay($dateFrom, $dateTimeStartDay, $adminId), ':date_to' => DateHelper::getDateTimeEndDay($dateTo, $dateTimeEndDay, $adminId), ] @@ -1244,6 +1249,8 @@ class SalesService ); } + $action = $command->getRawSql(); + return $command->queryAll(); } @@ -1352,18 +1359,24 @@ class SalesService * @param string $adminGuid * @param string $dateFrom * @param string $dateTo + * @param bool $isAdministrator + * @param null|array $adminGuids * @return array * @throws \yii\db\Exception */ - public function getMatrixMakeProducts(string $adminGuid, string $dateFrom, string $dateTo, $isAdministrator) : array + public function getMatrixMakeProducts(string $adminGuid, string $dateFrom, string $dateTo,bool $isAdministrator, $adminGuids = null) : array { $adminsGuids = $this->adminsGuids; $adminId = null; - if (array_key_exists($adminGuid, $adminsGuids)) { + if (array_key_exists($adminGuid, $adminsGuids) && empty($adminGuids)) { $adminId = ArrayHelper::getValue($adminsGuids, $adminGuid); } + if (!empty($adminGuids) && is_array($adminGuids)) { + $adminGuid = implode("','", $adminGuids); + } + $dateTimeStartDay = false; $dateTimeEndDay = false; @@ -1378,7 +1391,7 @@ class SalesService $command = $connection->createCommand(" SELECT DISTINCT (sales.id), - sales.seller_id, + p.seller_id, sales.date, sales.number, (p.summ) AS summ, @@ -1392,7 +1405,7 @@ class SalesService sales_products as p, sales WHERE - p.seller_id = :admin_guid + p.seller_id IN ('$adminGuid') AND sales.id = p.check_id AND ( @@ -1422,7 +1435,7 @@ class SalesService sales.date ASC ", - [':admin_guid' => $adminGuid, + [ ':date_from' => DateHelper::getDateTimeStartDay($dateFrom, $dateTimeStartDay, $adminId), ':date_to' => DateHelper::getDateTimeEndDay($dateTo, $dateTimeEndDay, $adminId), ] @@ -1443,7 +1456,7 @@ class SalesService sales_products as p, sales WHERE - p.seller_id = :admin_guid + p.seller_id IN ('$adminGuid') AND sales.id = p.check_id AND ( @@ -1474,7 +1487,7 @@ class SalesService sales_products as p, sales WHERE - p.seller_id = :admin_guid + p.seller_id IN ('$adminGuid') AND sales.id = p.check_id AND ( @@ -1502,13 +1515,17 @@ class SalesService sales.date <= :date_to ", - [':admin_guid' => $adminGuid, + [ ':date_from' => DateHelper::getDateTimeStartDay($dateFrom, $dateTimeStartDay, $adminId), ':date_to' => DateHelper::getDateTimeEndDay($dateTo, $dateTimeEndDay, $adminId), ] ); } + + $action = $command->getRawSql(); + + return $command->queryAll(); } diff --git a/erp24/tests/_bootstrap.php b/erp24/tests/_bootstrap.php old mode 100644 new mode 100755 diff --git a/erp24/tests/_data/.gitignore b/erp24/tests/_data/.gitignore new file mode 100755 index 0000000..e69de29 diff --git a/erp24/tests/_data/city.php b/erp24/tests/_data/city.php new file mode 100755 index 0000000..966a63d --- /dev/null +++ b/erp24/tests/_data/city.php @@ -0,0 +1,15 @@ + 'Город тест', + 'code' => 'city-test', + 'social' => 'socialsocial', + 'phone' => '+7 (232) 4-335-647', + 'email' => 'nicole.paucek@schultz.info', + 'phone_support' => '8 800 770 70 22', + 'active' => '1', + 'created_at' => '1402312317', + 'updated_at' => '1402312317', + ], +]; diff --git a/erp24/tests/_output/.gitignore b/erp24/tests/_output/.gitignore old mode 100644 new mode 100755 index c96a04f..d6b7ef3 --- a/erp24/tests/_output/.gitignore +++ b/erp24/tests/_output/.gitignore @@ -1,2 +1,2 @@ * -!.gitignore \ No newline at end of file +!.gitignore diff --git a/erp24/tests/_support/.gitignore b/erp24/tests/_support/.gitignore new file mode 100755 index 0000000..36e264c --- /dev/null +++ b/erp24/tests/_support/.gitignore @@ -0,0 +1 @@ +_generated diff --git a/erp24/tests/_support/FunctionalTester.php b/erp24/tests/_support/FunctionalTester.php old mode 100644 new mode 100755 index db2ce28..43327cb --- a/erp24/tests/_support/FunctionalTester.php +++ b/erp24/tests/_support/FunctionalTester.php @@ -1,5 +1,8 @@ [ + 'class' => UserFixture::className(), + 'dataFile' => codecept_data_dir() . 'login_data.php' + ], + 'city' => [ + 'class' => CityFixture::className(), + 'dataFile' => codecept_data_dir() . 'city.php' + ] + + ]; + } + + /** + * @param FunctionalTester $I + * @dataProvider pageProvider + */ + public function testSortLinkClick(FunctionalTester $I, Example $data) + { + $pageH1 = 'Города'; + $I->amLoggedInAs(1); + + $I->amOnPage('/city/'); + $I->see($pageH1, 'h1'); + $I->click(['link' => $data['link']]); + $I->see($pageH1, 'h1'); + $I->seeInTitle($pageH1); + $I->click(['link' => $data['link']]); + $I->see($pageH1, 'h1'); + $I->seeInTitle($pageH1); + + } + + /** + * @return array + */ + protected function pageProvider() + { + return [ + ['link'=>"Название"], + ['link'=>"Символьный код"], + ['link'=>"Телефон"], + ['link'=>"Активность"], + ]; + } + + + + /** + * @param FunctionalTester $I + */ + public function createCity(FunctionalTester $I) + { + + $I->amLoggedInAs(1); + + $I->amOnPage('/city/create/'); + $I->fillField('City[name]', 'Город Город'); + $I->fillField('City[code]', 'codecity'); + $I->fillField('City[phone]', '+7 (132) 4-542-132'); + $I->click('Сохранить'); + + $I->see('Город Город'); + + } + + /** + * @param FunctionalTester $I + */ + public function viewCity(FunctionalTester $I) + { + $I->amLoggedInAs(1); + + $model = City::find()->one(); + + $urlView = '/city/view/'.$model->id.'/'; + $name = $model->name; + $I->amOnPage($urlView); + $I->click(['link' => 'Изменить']); + + $I->see($name); + + } + + /** + * @param FunctionalTester $I + */ + public function updateCity(FunctionalTester $I) + { + $I->amLoggedInAs(1); + + $model = City::find()->one(); + + $urlView = '/city/update/'.$model->id.'/'; + $name = $model->name; + $I->amOnPage($urlView); + $I->click('Сохранить'); + + $I->see($name); + + } +} diff --git a/erp24/tests/functional/_bootstrap.php b/erp24/tests/functional/_bootstrap.php old mode 100644 new mode 100755 index b3d9bbc..30ed54b --- a/erp24/tests/functional/_bootstrap.php +++ b/erp24/tests/functional/_bootstrap.php @@ -1 +1,16 @@ 'davert']); + * ``` + * + * In Cests + * + * ```php + * \Codeception\Util\Fixtures::get('user1'); + * ``` + */ \ No newline at end of file diff --git a/erp24/tests/unit.suite.yml b/erp24/tests/unit.suite.yml old mode 100644 new mode 100755 index c14e49c..78c67c9 --- a/erp24/tests/unit.suite.yml +++ b/erp24/tests/unit.suite.yml @@ -1,11 +1,13 @@ -# Codeception Test Suite Configuration - -# suite for unit (internal) tests. -# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. - +suite_namespace: tests\unit actor: UnitTester +bootstrap: false modules: - enabled: - - Asserts - - Yii2: - part: [orm, email, fixtures] + enabled: + - Yii2: + part: [orm, email, fixtures] + - Asserts +coverage: + enabled: true + whitelist: + include: + - models/* diff --git a/erp24/tests/unit/_bootstrap.php b/erp24/tests/unit/_bootstrap.php old mode 100644 new mode 100755 index 80cc72a..e432ce5 --- a/erp24/tests/unit/_bootstrap.php +++ b/erp24/tests/unit/_bootstrap.php @@ -1,3 +1,16 @@ 'davert']); + * ``` + * + * In Tests + * + * ```php + * \Codeception\Util\Fixtures::get('user1'); + * ``` + */ diff --git a/erp24/tests/unit/models/CityTest.php b/erp24/tests/unit/models/CityTest.php new file mode 100755 index 0000000..788ab43 --- /dev/null +++ b/erp24/tests/unit/models/CityTest.php @@ -0,0 +1,389 @@ +className = City::className(); + + } + + + /** + * @return array + */ + public function _fixtures() + { + return [ + 'city' => [ + 'class' => CityFixture::className(), + 'dataFile' => codecept_data_dir() . 'city.php' + ] + ]; + } + + public function testEmptyValues() + { + $model = new $this->className; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + } + + public function testNameOnly() + { + $model = new $this->className; + + $model->attributes = [ + 'name' => 'Город' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + + } + public function testWrongName() + { + $model = new $this->className; + + $model->attributes = [ + 'name' => 'one title' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key name must have in array errors', $model->errors)->hasKey('name'); + + } + + public function testShortName() + { + $model = new $this->className; + + $model->attributes = [ + 'name' => 'H' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key name must have in array errors', $model->errors)->hasKey('name'); + + } + + public function testFieldActiveNotInteger() + { + $model = new $this->className; + + $model->attributes = [ + 'active' => 'string' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key active must have in array errors', $model->errors)->hasKey('active'); + + } + + public function testLongPhoneSupport() + { + $model = new $this->className; + + $model->attributes = [ + 'phone_support' => '123456789012345678901' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key phone_support must have in array errors', $model->errors)->hasKey('phone_support'); + + } + + /** + * @dataProvider providerIntegerFields + */ + public function testIntegerFieldsWrongSetRussianText($a) + { + $model = new $this->className; + + $model->attributes = [ + $a => 'Название' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key '.$a.' must have in array errors', $model->errors)->hasKey($a); + + } + + /** + * @return array + */ + public function providerIntegerFields() + { + $obj = new City(); + return $obj->getAllFieldsGroupByType()->getFieldsByType('integer'); + } + + + public function testLongPhone() + { + $model = new $this->className; + + $model->attributes = [ + 'phone' => '123456789012345678901' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key phone must have in array errors', $model->errors)->hasKey('phone'); + + } + + public function testLongName() + { + $model = new $this->className; + + $model->attributes = [ + 'name' => 'цщукзшгецзщушкгезщцушкгезщцшугкещзшугкцезщшгцзукешгцушгкеншщцугкенщшгншщгцункещшцгукеншщгцкежрлордорфжваопрфваопрылжвоапрыдлвоапрывалопрылдвоапрылваопрлыдпаловаарыплдоршдкгеншгукрпвшгкеершупоыаршгнкешыгарлыовврппршгыукрлпоыршгыукршшывгралопршыгкршорпчлоавр' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key name must have in array errors', $model->errors)->hasKey('name'); + + } + + public function testLongCode() + { + $model = new $this->className; + + $model->attributes = [ + 'code' => 'qwertwpieurtypiweurtyiweurtyioweurytioweurytioweurtyioaslkjdfhklajfhlkjahfklgjahdkfjghkadjfgkajdfgkajddfhgkajddfhkgkjaddhfkgkjadhfkgkjahdkfjghklazcvbvbzkcvjhblzkcvjhblkzjcvhblkzuvycoiuzyoiuyzouvybozhvblzvzuvbhoizuvcybiozucvhbzjcvhobzciuvhkjewrhtklwjehrtklj' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key code must have in array errors', $model->errors)->hasKey('code'); + + } + +//[['name', 'code', 'phone', 'email'], 'string', 'min' => 2, 'max' => 255], + public function testShortPhoneSupport() + { + $model = new $this->className; + + $model->attributes = [ + 'phone_support' => '1' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key phone_support must have in array errors', $model->errors)->hasKey('phone_support'); + + } + + public function testShortPhone() + { + $model = new $this->className; + + $model->attributes = [ + 'phone' => '1' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key phone must have in array errors', $model->errors)->hasKey('phone'); + + } + + public function testNotUniqueName() + { + $model = new $this->className; + + $nameCityTest = 'Город тест'; + + $model->attributes = [ + 'name' => $nameCityTest, + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect($model->getFirstError('name')); + expect('key name must have in array errors', $model->errors)->hasKey('name'); + + } + + public function testNotUniqueCode() + { + $model = new $this->className; + + $codeTest = 'city-test'; + +// $message = 'Значение «'.$codeTest.'» для «Символьный код» уже занято.'; + + $model->attributes = [ + 'code' => $codeTest, + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); + expect('key code must have in array errors', $model->errors)->hasKey('code'); + } + + public function testWrongCode() + { + $model = new $this->className; + + $codeTest = 'фываы'; + +// $message = 'Значение «'.$codeTest.'» для «Символьный код» уже занято.'; + + $model->attributes = [ + 'code' => $codeTest, + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); +// $test = $model->getFirstError('code'); +// expect($model->getFirstError('code'))->equals($message); + expect('key code must have in array errors', $model->errors)->hasKey('code'); + + } + + public function testCityWrongMail() + { + $model = new $this->className; + $model->attributes = [ + 'email' => 'WrongMail' + ]; + + $validate = $model->validate(); + + expect('Validation should be failed', $validate)->false(); + expect($model->hasErrors())->true(); +// expect($model->getFirstError('email'))->equals('Значение «E-mail» не является правильным email адресом.'); + expect('key email must have in array errors', $model->errors)->hasKey('email'); + } + + public function testTrueCity() + { + $model = new $this->className; + $expectedAttrs = [ + 'name' => 'Город Тест Тест', + 'code' => 'testcode', + 'phone' => '+7 (332) 4-375-847', + 'email' => 'nicuole.pacek@schultz.info', + 'phone_support' => '8 800 770 70 22', + 'active' => '1', + 'created_at' => '1402312317', + 'updated_at' => '1402312317', + ]; + + $model->attributes = $expectedAttrs; + + expect('Validation should be success', $model->validate())->true(); + expect($model->hasErrors())->false(); + + $this->assertTrue($model->save()); + + $expectedAttrs['id'] = $model->id; + + $city = City::find()->where(['id' =>$expectedAttrs['id']])->one(); + $this->assertNotNull($city); + + $this->assertEquals($expectedAttrs['name'], $city->name); + $this->tester->assertEquals($expectedAttrs['name'], $city->name); + + $this->assertEquals($expectedAttrs['email'], $city->email); + $this->assertEquals($expectedAttrs['code'], $city->code); + + } + + public function testDeleteCity() + { + // delete + $record = new $this->className; + $record->name = 'Город Тест Тест Первый Тест'; + $record->code = 'testcode'; + $record->phone = '+7 (332) 4-375-847'; + $record->email = 'nicuole.pacek@schultz.info'; + $record->phone_support = '8 800 770 70 22'; + $record->active = 1; + $record->created_at = 1402312317; + $record->updated_at = 1402312317; + + $record->save(); + + $recordId = $record->id; + + $record = City::findOne($recordId); + $record->delete(); + $record = City::findOne($recordId); + $this->assertNull($record); + + // deleteAll + $record = new $this->className; + $record->name = 'Город Тест Тест Второй Тест'; + $record->code = 'testcode'; + $record->phone = '+7 (332) 4-375-847'; + $record->email = 'nicuole.pacek@schultz.info'; + $record->phone_support = '8 800 770 70 22'; + $record->active = 1; + $record->created_at = 1402312317; + $record->updated_at = 1402312317; + $record->save(); + + $ret = City::deleteAll(['name' => 'Город Тест Тест Второй Тест']); + $this->assertEquals(1, $ret); + $records = City::find()->where(['name' => 'Город Тест Тест Второй Тест'])->all(); + $this->assertEquals(0, count($records)); + } +} diff --git a/erp24/views/admin_person_bonuses/_form.php b/erp24/views/admin_person_bonuses/_form.php index b483be1..96205db 100755 --- a/erp24/views/admin_person_bonuses/_form.php +++ b/erp24/views/admin_person_bonuses/_form.php @@ -52,7 +52,7 @@ use yii_app\records\Admin; ]); ?> field($model, 'year')->dropDownList( - array_combine(range(2022,2026),range(2022,2026)) + array_combine(range(2022,2028),range(2022,2028)) ) ?> field($model, 'month')->dropDownList( @@ -67,6 +67,10 @@ use yii_app\records\Admin; field($model, 'retention')->textInput() ?> + field($model, 'retention_comment')->textarea() ?> + + field($model, 'part_time_job_hours')->textInput() ?> + field($model, 'shift_correction')->textInput() ?> field($model, 'prepaid_expense')->textInput() ?> diff --git a/erp24/views/admin_person_bonuses/_update_form.php b/erp24/views/admin_person_bonuses/_update_form.php index 53b94a2..2ab320d 100755 --- a/erp24/views/admin_person_bonuses/_update_form.php +++ b/erp24/views/admin_person_bonuses/_update_form.php @@ -30,6 +30,8 @@ use yii_app\records\Admin; field($model, 'vacation_day')->textInput() ?> field($model, 'retention')->textInput() ?> + field($model, 'retention_comment')->textarea() ?> + field($model, 'part_time_job_hours')->textInput() ?> field($model, 'shift_correction')->textInput() ?> diff --git a/erp24/views/admin_person_bonuses/create.php b/erp24/views/admin_person_bonuses/create.php index d143700..215d20e 100755 --- a/erp24/views/admin_person_bonuses/create.php +++ b/erp24/views/admin_person_bonuses/create.php @@ -9,7 +9,7 @@ $this->title = 'Создание записи о премии, авансе и $this->params['breadcrumbs'][] = ['label' => 'Персональные премии, авансы и подсчёт ', 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; ?> -
+

title) ?>

diff --git a/erp24/views/admin_person_bonuses/index.php b/erp24/views/admin_person_bonuses/index.php index 940b8ae..20031ac 100755 --- a/erp24/views/admin_person_bonuses/index.php +++ b/erp24/views/admin_person_bonuses/index.php @@ -16,7 +16,7 @@ use yii_app\records\AdminPersonBonuses; $this->title = 'Персональные премии, авансы и подсчёт'; $this->params['breadcrumbs'][] = $this->title; ?> -
+

title) ?>

diff --git a/erp24/views/admin_person_bonuses/update.php b/erp24/views/admin_person_bonuses/update.php index 43e987e..eb22c07 100755 --- a/erp24/views/admin_person_bonuses/update.php +++ b/erp24/views/admin_person_bonuses/update.php @@ -10,7 +10,7 @@ $this->params['breadcrumbs'][] = ['label' => 'Персональные прем $this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]]; $this->params['breadcrumbs'][] = 'Изменмть'; ?> -
+

title) ?>

diff --git a/erp24/views/admin_person_bonuses/view.php b/erp24/views/admin_person_bonuses/view.php index f3c0669..acd456a 100755 --- a/erp24/views/admin_person_bonuses/view.php +++ b/erp24/views/admin_person_bonuses/view.php @@ -11,7 +11,7 @@ $this->params['breadcrumbs'][] = ['label' => 'Персональные прем $this->params['breadcrumbs'][] = $this->title; \yii\web\YiiAsset::register($this); ?> -
+

title) ?>

@@ -33,6 +33,8 @@ $this->params['breadcrumbs'][] = $this->title; 'color_ruble_bonuses', 'vacation_day', 'retention', + 'retention_comment', + 'part_time_job_hours', 'shift_correction', 'prepaid_expense', 'counting', diff --git a/erp24/views/cabinet202310/_admin_salary_by_stores_table.php b/erp24/views/cabinet202310/_admin_salary_by_stores_table.php index f336066..647e056 100755 --- a/erp24/views/cabinet202310/_admin_salary_by_stores_table.php +++ b/erp24/views/cabinet202310/_admin_salary_by_stores_table.php @@ -33,14 +33,11 @@ if (!empty($timetableAdminAnotherStoreById)) { Магазин Число сотрудников в смене Сотрудники смены - Нормы смены магазина Продажи магазина (00:00 - 23:59) - Норма смена сотрудника Сумма продаж сотрудника Число чеков сотрудника Сумма оклада за смену Средний чек магазина - Баллы геймификации - - + - - - - -
-

Сумма баллов геймификации :

+
+ + Таблица выплат за выбранный месяц: + + + + + + $value) { + ?> + + + + + + + + + +
НазваниеСумма, руб
+ + + +
+ К выплате за выбранный месяц руб +
+ diff --git a/erp24/views/cabinet202310/_cluster_personal_values.php b/erp24/views/cabinet202310/_cluster_personal_values.php index 1209e1c..a56321f 100755 --- a/erp24/views/cabinet202310/_cluster_personal_values.php +++ b/erp24/views/cabinet202310/_cluster_personal_values.php @@ -45,88 +45,13 @@ $ratingBy = 'средниму баллу'; $endKey = 1; echo '

Персональные показатели

'; -echo '
Сумма баллов геймификации : ' . $clusterAdminSumGameBonus; echo '
Число магазинов : ' . $administratorCountInRating; -echo '
Среднее значение баллов геймификации : ' . $clusterAdminAvgSumGameBonus; -if (!empty($ratingPerson)) { - echo '
Ваш рейтинг по ' . $ratingBy . ' : ' . $ratingPerson . ' из ' . $countRatingList; -} $tbl = ''; -if (!empty($ratingList)){ - $tbl = ''; - - $arrayReverseKeys = array_reverse(array_keys($ratingList)); - - foreach ($ratingList as $key => $row) { - $firstKeys = range(0,$endKey); - - $cssCurrentUser = ''; - $cssCurrentUserCell = ''; - if ($clusterAdminId == $row['admin_id']) { - $cssCurrentUser = 'table-info'; - $cssCurrentUserCell = 'bg-orange-lighter'; - } - - $sortArray = []; - foreach ( $firstKeys as $item) { - if (array_key_exists($item, $arrayReverseKeys)) { - $sortArray[] = $arrayReverseKeys[$item]; - } - } - - - if ($clusterAdminId == $row['admin_id']) { - $cssCurrentUser .= ' border-info'; - } - - $addText = ''; - $addText = ' (' . $row['value'] . ' балов/' . $row['administrators_count'] . ' администраторов)'; - - $tbl .= " - " . $row['rating'] . " - " . $row[$valueKey] . $addText . " - " . $row['admin']['name_full'] . " - "; - - } - - - $sumRow = ' - - - Сумма баллов ' . $ratingListSum . ' - - - '; - - -echo' -
- показать рейтинг -
- - - - - - - - - ' . $tbl . ' - ' . $sumRow . ' - -
Рейтинг' . $valueName . 'Имя
-
-
- -
'; -} else { - echo '
рейтинга нет'; -} + diff --git a/erp24/views/cabinet202310/_holiday_table_values.php b/erp24/views/cabinet202310/_holiday_table_values.php new file mode 100755 index 0000000..ef5eeff --- /dev/null +++ b/erp24/views/cabinet202310/_holiday_table_values.php @@ -0,0 +1,209 @@ +registerCssFile('/yii_app/css/common/block-info.css'); +$this->registerJsFile('/yii_app/js/common/block-info.js', ['position' => \yii\web\View::POS_END]); + + +echo '

Блок премирования магазина
за продажу фокусных позиций в мартовские праздники

'; + + +if (!empty($consolidatedPremiumByFocusGroups)) { + + $fields = [ + 0 => [ + 'name' => ' услуг ', + 'percentText' => ' 10% ', + 'keySum' => 'userSalaryServices', + 'keyPremium' => 'userSalaryServicesPremium', + 'alias' => 'services', + 'tableName' => 'продажи услуг', + ], + 1 => [ + 'name' => ' сопутки ', + 'percentText' => ' 5% ', + 'keySum' => 'userSalaryRelated', + 'keyPremium' => 'userSalaryRelatedPremium', + 'alias' => 'related', + 'tableName' => 'продажи сопутки', + ], + 2 => [ + 'name' => ' горшечки ', + 'percentText' => ' 5% ', + 'keySum' => 'userSalaryPotted', + 'keyPremium' => 'userSalaryPottedPremium', + 'alias' => 'potted', + 'tableName' => 'продажи горшечки', + ], + 3 => [ + 'name' => ' упаковки ', + 'percentText' => ' 5% ', + 'keySum' => 'userSalaryWrap', + 'keyPremium' => 'userSalaryWrapPremium', + 'alias' => 'wrap', + 'tableName' => 'продажи упаковки', + ], + 4 => [ + 'name' => ' пиротехники ', + 'percentText' => ' 5% ', + 'keySum' => 'userSalarySalut', + 'keyPremium' => 'userSalarySalutPremium', + 'alias' => 'salut', + 'tableName' => 'продажи пиротехники', + ], + 5 => [ + 'name' => ' не фокусных товаров ', + 'percentText' => ' 1% ', + 'keySum' => 'userSalaryOtherItems', + 'keyPremium' => 'userSalaryOtherItemsPremium', + 'alias' => 'other_items', + 'tableName' => 'продажи не фокусных товаров', + ], + ]; + + foreach ($fields as $field) { + if (!empty($consolidatedPremiumByFocusGroups[$field['keySum']])) { + echo '
Факт продаж ' . $field['name'] . ' : ' . HtmlHelper::getNumberFormat($consolidatedPremiumByFocusGroups[$field['keySum']]) . ' руб'; + echo '
Премия за продажу ' . $field['name'] . ' ' . $field['percentText'] . ' : ' . HtmlHelper::getNumberFormat($consolidatedPremiumByFocusGroups[$field['keyPremium']]) . ' руб'; + + echo $this->render('_table_salary_checks', [ + 'arrUsersSalary' => $consolidatedArrUsersSalaryCheck[$field['alias']], + 'tableName' => $field['tableName'], + 'userSalarySum' => $consolidatedPremiumByFocusGroups[$field['keySum']], + 'sellerShow' => true, + ]); + + } else { + echo '
Факта продажи ' . $field['name'] . ' нет
'; + } + } + + if (!empty($consolidatedPremiumByFocusGroups['userSalaryPremiumSum'])) { + echo '
Сумма премии магазина за продажу фокусных позиций ' . HtmlHelper::getNumberFormat($consolidatedPremiumByFocusGroups['userSalaryPremiumSum']) . ' руб
'; + } + +} + +/**/ + +$textInfoMatrix = ' 2% '; + +if (!empty($consolidatedPremiumByMatrix) && !empty($consolidatedPremiumByMatrix['salesMatrix'])) { + + echo"
"; + echo"

Продажи букетов по матрице за праздники по магазину

"; + echo"
Проданные букеты по матрице за праздники
"; + + $tbl = ''; + + foreach ($consolidatedPremiumByMatrix['salesMatrix'] as $row) { + $tbl .= "" . $row["date"] . " " . $row["admin_name"] . " " . $row["operation"] . " " . $row["number"] . " " . $row["product_name"] . " " . HtmlHelper::getNumberFormat($row["summ"]) . " " . HtmlHelper::getNumberFormat($row["bonus"]) . " "; + } + + echo' +
+ показать список +
+ + + + + + + + + + + ' . $tbl . ' +
ДатаСотрудникОперацияНазвание чекаБукетСуммаБонус
+

+ Число чеков ' . count($consolidatedPremiumByMatrix['salesMatrix']) . ' +

+
+
+
+ Сумма продаж матрицы ' . HtmlHelper::getNumberFormat($consolidatedPremiumByMatrix['salaryMatrix']) . ' руб * ' . $textInfoMatrix . ' = ' . HtmlHelper::getNumberFormat($consolidatedPremiumByMatrix['bonusSalaryMatrix']) . ' руб +
+
+ +
'; +} else { + echo '
Продаж по матрице нет'; +} + +echo"
Собранные букеты по матрице за праздники
"; + +if (!empty($consolidatedPremiumByMatrix) && !empty($consolidatedPremiumByMatrix['makeMatrix'])) { + + $tbl2 = ''; + + foreach ($consolidatedPremiumByMatrix['makeMatrix'] as $row) { + $tbl2 .= "" . $row["date"] . " " . $row["admin_name"] . " " . $row["operation"] . " " . $row["number"] . " " . $row["product_name"] . " " . HtmlHelper::getNumberFormat($row["summ"]) . " " . HtmlHelper::getNumberFormat($row["bonus"]) . " "; + } + + echo' +
+ показать список +
+ + + + + + + + + + + ' . $tbl2 . ' +
ДатаСотрудникОперацияНазвание чекаБукетСуммаБонус
+

+ Число чеков ' . count($consolidatedPremiumByMatrix['makeMatrix']) . ' +

+
+
+
+ Сумма продаж собранных букетов матрицы ' . HtmlHelper::getNumberFormat($consolidatedPremiumByMatrix['salaryMakeMatrix']) . ' руб * ' . $textInfoMatrix . ' = ' . HtmlHelper::getNumberFormat($consolidatedPremiumByMatrix['bonusMakeMatrix']) . ' руб +
+
+ +
'; +} else { + echo 'Собранных букутов нет
'; +} + +if (!empty($consolidatedPremiumByMatrix['matrixPrime'])) { + echo '
Сумма премии магазина за матрицу: ' . HtmlHelper::getNumberFormat($consolidatedPremiumByMatrix['matrixPrime']) . ' руб
'; +} + + + +echo '
Сумма премии магазина за продажу фокусных позиций и матрицы
'; +echo '
' + . HtmlHelper::getNumberFormat($consolidatedPremiumByFocusGroups['userSalaryPremiumSum'] ?? 0) . + ' руб + ' + . HtmlHelper::getNumberFormat($consolidatedPremiumByMatrix['matrixPrime'] ?? 0) . + ' руб = ' . HtmlHelper::getNumberFormat($consolidatedPremiumByStore) . ' руб
'; +echo '
Общая сумма премии магазина: ' . HtmlHelper::getNumberFormat($consolidatedPremiumByStore) . ' руб
'; +echo '
Число смен сотрудников, работающих в праздники: ' . DataHelper::ruPlural($adminsHolidayShiftCount, ['смена', 'смены', 'смен']) . '
'; +echo '
Премия за одну смену: ' . HtmlHelper::getNumberFormat($onePartHolidayPremium) . ' руб
'; +echo '
В праздники вы отработали: ' . DataHelper::ruPlural($personHolidayShiftCount, ['смену', 'смены', 'смен']) . '
'; +echo '
Ваша часть премии за продажу фокусных позицый в праздники: ' . HtmlHelper::getNumberFormat($personPremiumByStore) . ' руб
'; +echo '
'; +echo '
'; +echo '
'; + + +/**/ \ No newline at end of file diff --git a/erp24/views/cabinet202310/_personal_info.php b/erp24/views/cabinet202310/_personal_info.php index e2c0707..2d3d474 100755 --- a/erp24/views/cabinet202310/_personal_info.php +++ b/erp24/views/cabinet202310/_personal_info.php @@ -44,8 +44,16 @@ if (!empty($employeeSelect["d_id"]) && array_key_exists($employeeSelect["d_id"], } ?> Оклад : " . HtmlHelper::getNumberFormat($monthlySalary['monthly_salary']) . " руб."; + $monthlySalaryRow = HtmlHelper::getNumberFormat($monthlySalary['monthly_salary']); +} + +if (!empty($monthlySalaryRow)) { + echo "
Оклад : " . $monthlySalaryRow . " руб."; } ?> diff --git a/erp24/views/cabinet202310/_personal_values.php b/erp24/views/cabinet202310/_personal_values.php index 7dbbfd6..9602612 100755 --- a/erp24/views/cabinet202310/_personal_values.php +++ b/erp24/views/cabinet202310/_personal_values.php @@ -68,6 +68,10 @@ $endKey = ($isAdministrator) ? 2 : 4; echo "

Сумма продаж по первому блоку премирования

"; echo '

Первый блок премирования: продажа фокусных позиций

'; +if (!empty($showHolidayVersion)) { + echo '

Премии за продажу фокусных позиций в мартовские праздники (с 05.03.2024 по 08.03.2024 )
в Блоке премирования магазина

'; +} + $tbl = ''; @@ -273,6 +277,14 @@ if (!empty($teamBonus)) { 'teamBonus' => $teamBonus, ]); } +if (!empty($adminTeamPayrollTable)) { + echo '
'; + + echo $this->render('_table_team_payroll', [ + 'teamBonus' => $teamBonus, + 'adminTeamPayrollTable' => $adminTeamPayrollTable, + ]); +} echo '
Командная премия : ' . HtmlHelper::getNumberFormat($teamBonusValue) . ' руб
'; diff --git a/erp24/views/cabinet202310/_table_salary_checks.php b/erp24/views/cabinet202310/_table_salary_checks.php index e6ccf27..fa869bc 100644 --- a/erp24/views/cabinet202310/_table_salary_checks.php +++ b/erp24/views/cabinet202310/_table_salary_checks.php @@ -5,6 +5,7 @@ /* @var $arrUsersSalary array */ /* @var $userSalarySum float */ /* @var $tableName string */ +/* @var $sellerShow bool */ use yii_app\helpers\HtmlHelper; @@ -15,21 +16,37 @@ if (!empty($arrUsersSalary)) { $tbl = ''; foreach ($arrUsersSalary as $row) { - $tbl .= "" . $row["date"] . " " . $row["operation"] . " " . $row["number"] . " " . HtmlHelper::getNumberFormat($row["bonus"]) . " "; + $tbl .= "" . $row["date"] . " "; + if ($sellerShow) { + $tbl .= "" . $row["name"] . " "; + } + $tbl .= "" . $row["operation"] . " " . $row["number"] . " " . HtmlHelper::getNumberFormat($row["bonus"]) . " "; } - $tbl .= "" . HtmlHelper::getNumberFormat($userSalarySum) . " "; + + $tbl .= " + "; + if ($sellerShow) { + $tbl .= ""; + } + $tbl .= "" .HtmlHelper::getNumberFormat($userSalarySum) . " "; + + $tblHeader = " + Дата + "; + if ($sellerShow) { + $tblHeader .= "Продавец"; + } + $tblHeader .= " Операция + Название + Сумма руб. + "; echo'
показать список ' . $tableName . '
- - - - - - + ' . $tblHeader . ' ' . $tbl . '
ДатаОперацияНазваниеСумма руб.
diff --git a/erp24/views/cabinet202310/_table_team_payroll.php b/erp24/views/cabinet202310/_table_team_payroll.php new file mode 100755 index 0000000..2258c11 --- /dev/null +++ b/erp24/views/cabinet202310/_table_team_payroll.php @@ -0,0 +1,119 @@ +registerCssFile('/yii_app/css/common/block-info.css'); +$this->registerJsFile('/yii_app/js/common/block-info.js', ['position' => \yii\web\View::POS_END]); + +if (!empty($adminTeamPayrollTable)) { + + $tbl = ''; +// +// 'adminPayDayAll' +//'payrollVariableDaysAll' + /* + * $result[$admin['id']]['admin_id'] = $admin['id']; + $result[$admin['id']]['admin_name'] = $admin['name']; + $result[$admin['id']]['group_name'] = $admin['group_name']; + $daysRow = []; + + foreach ($days as $day) { + $keyAdminIdDateRow = $admin['id'] . '_' . $day; + $payConstantRow = 0; + if (array_key_exists($keyAdminIdDateRow, $teamBonusAdminPayDayAll)) { + $payConstantRow = ArrayHelper::getValue($teamBonusAdminPayDayAll, $keyAdminIdDateRow); + } + $payVariableRow = 0; + + if (array_key_exists($keyAdminIdDateRow, $teamBonusPayrollVariableDaysAll)) { + $payVariableRow = ArrayHelper::getValue($teamBonusPayrollVariableDaysAll, $keyAdminIdDateRow); + } + $daysRow[$day] = [ + 'pay_constant' => $payConstantRow, + 'pay_variable' => $payVariableRow, + ]; + * */ + + foreach ($adminTeamPayrollTable as $key => $row) { +// $storeIdKey =array_key_first($row); +// $rowValue = $row[array_key_first($row)]; + + + $tbl .= ""; + $tbl .= "" . $row['admin_name'] . " " . $row['group_name'] . " "; + + foreach ($row['days'] as $keyDay => $rowDayValue) { + $rowPayConstant = $rowDayValue['pay_constant'] ?? '-'; + $rowPayVariable = $rowDayValue['pay_variable'] ?? '-'; + $tbl .= "" . $rowPayConstant . " " . $rowPayVariable . " "; + } + + $tbl .= ""; + } + + $days = $teamBonus['days'] ?? []; + $tblHead = ""; + $tblHead .= "Сотрудник"; + $tblRowTwo = "Дата"; + foreach ($adminTeamPayrollTable as $key => $row) { + + $tblHead .= "" . $row['admin_name'] . " (" . $row['group_name'] . ") "; + + $tblRowTwo .= "Оклад"; + $tblRowTwo .= "Премия"; + + } + $tblRowTwo .= ""; + $tblHead .= ""; + + $tblRow = ""; + foreach ($days as $day) { + $tblRow .= ""; + $tblRow .= "" . $day . ""; + foreach ($adminTeamPayrollTable as $key => $row) { + + + if (!empty($row['days'][$day])) { + $rowDayValue = $row['days'][$day]; + $rowPayConstant = $rowDayValue['pay_constant'] ?? '-'; + $rowPayVariable = $rowDayValue['pay_variable'] ?? '-'; + $tblRow .= "" . $rowPayConstant . ""; + $tblRow .= "" . $rowPayVariable . ""; + } + } + + $tblRow .= ""; + + } + + + + echo' +
+ Оклады и премии магазина в командном бонусе +
+
+ + + ' . $tblHead . ' + ' . $tblRowTwo . ' + + + ' . $tblRow . ' + +
+
+
+
+
+ +
'; +} else { + echo '

Нет данных
'; +} \ No newline at end of file diff --git a/erp24/views/cabinet202310/administrator.php b/erp24/views/cabinet202310/administrator.php index 8cb47ba..91e5084 100755 --- a/erp24/views/cabinet202310/administrator.php +++ b/erp24/views/cabinet202310/administrator.php @@ -153,6 +153,30 @@ use yii_app\forms\dashboard\DaysSearchForm; /* @var $sumColumnWages float */ /* @var $teamBonusValue float */ /* @var $teamBonus array */ +/* @var $adminTeamPayrollTable array */ + + +/* @var $personRetention float */ +/* @var $personRetentionArray array */ +/* @var $sumPersonRetention float */ + +/* @var $personPrepaidExpense float */ +/* @var $toPayoff float */ +/* @var $alreadyPay float */ +/* @var $alreadyPaySum float */ + +/* @var $allowShowPersonRetention bool */ + +/* @var $showHolidayVersion bool */ + +/* @var $consolidatedArrUsersSalaryCheck array */ +/* @var $consolidatedPremiumByFocusGroups array */ +/* @var $consolidatedPremiumByMatrix array */ +/* @var $consolidatedPremiumByStore float */ +/* @var $onePartHolidayPremium float */ +/* @var $adminsHolidayShiftCount float */ +/* @var $personPremiumByStore float */ +/* @var $personHolidayShiftCount float */ @@ -198,6 +222,7 @@ $this->params['breadcrumbs'][] = $this->title; 'normalCostShift' => $normalCostShift, 'monthNameSelect' => $monthNameSelect, 'yearSelect' => $yearSelect, + 'administratorOklad' => $administratorOklad, ]); ?> params['breadcrumbs'][] = $this->title; 'userQualityPremium' => $userQualityPremium, 'teamBonus' => $teamBonus, 'teamBonusValue' => $teamBonusValue, + 'adminTeamPayrollTable' => $adminTeamPayrollTable, + 'showHolidayVersion' => $showHolidayVersion ]); ?> + render('_holiday_table_values', [ + 'consolidatedArrUsersSalaryCheck' => $consolidatedArrUsersSalaryCheck, + 'consolidatedPremiumByFocusGroups' => $consolidatedPremiumByFocusGroups, + 'consolidatedPremiumByMatrix' => $consolidatedPremiumByMatrix, + 'consolidatedPremiumByStore' => $consolidatedPremiumByStore, + 'onePartHolidayPremium' => $onePartHolidayPremium, + 'adminsHolidayShiftCount' => $adminsHolidayShiftCount, + 'personPremiumByStore' => $personPremiumByStore, + 'personHolidayShiftCount' => $personHolidayShiftCount, + ]); + } + ?> +

Продажи " . HtmlHelper::getNumberFormat($salaryByAdmin) . " руб

"; @@ -413,4 +455,47 @@ echo "

";

Сумма окладов и премий за выбранный период руб

+ + +
+ + Таблица персональных вычетов за выбранный месяц: + + + + + + $value) { + ?> + + + + + + + + + +
НазваниеСумма, руб
+ + + render('_already_pay_in_month', [ + 'toPayoff' => $toPayoff, + 'alreadyPay' => $alreadyPay, + 'alreadyPaySum' => $alreadyPaySum, + ]); + } + ?> +
+ render('_disclaimer_info'); ?> \ No newline at end of file diff --git a/erp24/views/cabinet202310/cluster.php b/erp24/views/cabinet202310/cluster.php index 937aa76..495b18e 100755 --- a/erp24/views/cabinet202310/cluster.php +++ b/erp24/views/cabinet202310/cluster.php @@ -262,29 +262,6 @@ $this->params['breadcrumbs'][] = $this->title; } ?> - render('_cluster_personal_values', [ -// 'adminSumGameBonus' => $adminSumGameBonus, - 'ratingPerson' => $ratingPerson, - 'ratingList' => $ratingList, - 'ratingListSum' => $ratingListSum, - 'countRatingList' => $countRatingList, -// 'adminSumGameCountShift' => $adminSumGameCountShift, -// 'adminSumGameAvgSum' => $adminSumGameAvgSum, - 'clusterAdminId' => $clusterAdminId, -// 'adminSumGameBonusTotal' => $adminSumGameBonusTotal, -// 'adminSumGameCountShiftTotal' => $adminSumGameCountShiftTotal, -// 'adminSumGameAvgSumTotal' => $adminSumGameAvgSumTotal, - - - 'clusterAdminSumGameBonus' => $clusterAdminSumGameBonus, - 'clusterAdminAvgSumGameBonus' => $clusterAdminAvgSumGameBonus, - 'administratorCountInRating' => $administratorCountInRating, - ]); - ?> - -
- "; ?> diff --git a/erp24/views/cabinet202310/florist.php b/erp24/views/cabinet202310/florist.php index db04b8e..1f3f07c 100755 --- a/erp24/views/cabinet202310/florist.php +++ b/erp24/views/cabinet202310/florist.php @@ -137,6 +137,29 @@ use yii_app\forms\dashboard\DaysSearchForm; /* @var $teamBonusValue float */ /* @var $teamBonus array */ + +/* @var $personRetention float */ +/* @var $personRetentionArray array */ +/* @var $sumPersonRetention float */ + +/* @var $personPrepaidExpense float */ +/* @var $toPayoff float */ + +/* @var $alreadyPay float */ +/* @var $alreadyPaySum float */ + +/* @var $allowShowPersonRetention bool */ +/* @var $showHolidayVersion bool */ + +/* @var $consolidatedArrUsersSalaryCheck array */ +/* @var $consolidatedPremiumByFocusGroups array */ +/* @var $consolidatedPremiumByMatrix array */ +/* @var $consolidatedPremiumByStore float */ +/* @var $onePartHolidayPremium float */ +/* @var $adminsHolidayShiftCount float */ +/* @var $personPremiumByStore float */ +/* @var $personHolidayShiftCount float */ + $cabinetName = 'Кабинет флориста'; if ($person) { @@ -279,8 +302,23 @@ $this->params['breadcrumbs'][] = $this->title; 'userQualityPremium' => $userQualityPremium, 'teamBonus' => $teamBonus, 'teamBonusValue' => $teamBonusValue, + 'showHolidayVersion' => $showHolidayVersion ]); ?> + render('_holiday_table_values', [ + 'consolidatedArrUsersSalaryCheck' => $consolidatedArrUsersSalaryCheck, + 'consolidatedPremiumByFocusGroups' => $consolidatedPremiumByFocusGroups, + 'consolidatedPremiumByMatrix' => $consolidatedPremiumByMatrix, + 'consolidatedPremiumByStore' => $consolidatedPremiumByStore, + 'onePartHolidayPremium' => $onePartHolidayPremium, + 'adminsHolidayShiftCount' => $adminsHolidayShiftCount, + 'personPremiumByStore' => $personPremiumByStore, + 'personHolidayShiftCount' => $personHolidayShiftCount, + ]); + } + ?> +

Сумма окладов и премий за выбранный период руб

+ + +
+ + Таблица персональных вычетов за выбранный месяц: + + + + + + $value) { + ?> + + + + + + + + + +
НазваниеСумма, руб
+ + +render('_already_pay_in_month', [ + 'toPayoff' => $toPayoff, + 'alreadyPay' => $alreadyPay, + 'alreadyPaySum' => $alreadyPaySum, + ]); +} +?> +
render('_disclaimer_info'); ?> diff --git a/erp24/views/city_store/index.php b/erp24/views/city_store/index.php index ecb4da8..2ae85d7 100644 --- a/erp24/views/city_store/index.php +++ b/erp24/views/city_store/index.php @@ -12,6 +12,9 @@ use yii\widgets\Pjax; $this->title = 'Магазины'; $this->params['breadcrumbs'][] = $this->title; + +$this->registerJsFile('/js/city-store/index.js', ['position' => \yii\web\View::POS_END]); + ?>
@@ -54,6 +57,15 @@ $this->params['breadcrumbs'][] = $this->title; // 'content:ntext', // 'email:email', // 'tg_chat_id', + [ + 'label' => 'Телеграм Чат', + 'format' => 'raw', + 'value' => function ($model) { + return !empty($model->tg_chat_id) ? + Html::button($model->tg_chat_id, ['class' => 'btn btn-link btn-sm', 'onclick' => 'setTgDialog("' . $model->id . '", "' . $model->tg_chat_id . '");']) : + Html::button('Настроить', ['class' => 'btn btn-success btn-sm', 'onclick' => 'setTgDialog("' . $model->id . '", "' . $model->tg_chat_id . '");']); + } + ], // 'h1', // 'sprav_id', // 'images:ntext', diff --git a/erp24/views/crud/employee-payment/_search.php b/erp24/views/crud/employee-payment/_search.php index 91774a7..ac3f00c 100755 --- a/erp24/views/crud/employee-payment/_search.php +++ b/erp24/views/crud/employee-payment/_search.php @@ -1,5 +1,6 @@ field($model, 'id') ?>
- field($model, 'admin_id')->dropDownList(\yii_app\records\Admin::find()->select(['name', 'id'])->indexBy('id')->column(), [ - 'prompt' => '---', - ]) ?> + select(['name', 'id'])->indexBy('id')->orderBy('name' , SORT_DESC)->all(); + $admins = []; + foreach ($adminsWithGroup as $key => $item) { + $admins[$key] = $item['name'] . ' (' . $item['id'] . ')'; + + } + + echo $form->field($model, 'admin_id')->widget(Select2::class, [ + 'data' => $admins, + 'language' => 'ru', + 'options' => ['placeholder' => '---'], + 'pluginOptions' => [ + 'allowClear' => true, + ] + ])?>
field($model, 'admin_group_id')->dropDownList(\yii_app\records\AdminGroup::find()->select(['name', 'id'])->indexBy('id')->column(), [ diff --git a/erp24/views/dashboard/sales.php b/erp24/views/dashboard/sales.php index e5b7fae..d369898 100755 --- a/erp24/views/dashboard/sales.php +++ b/erp24/views/dashboard/sales.php @@ -11,7 +11,6 @@ * @var $number * @var $city_stores * @var $store_traffik - * @var $sales_products * @var $equal_days * @var $arr_work * @var $date_timetable @@ -31,7 +30,6 @@ * @var $productsArrayServices * @var $servises * @var $saleServices - * @var $checkSellerDiscount * @var $daysSearchForm * @var \yii\web\View $this */ diff --git a/erp24/views/info_table/cabinet.php b/erp24/views/info_table/cabinet.php new file mode 100644 index 0000000..5aab325 --- /dev/null +++ b/erp24/views/info_table/cabinet.php @@ -0,0 +1,8 @@ +registerCssFile('/yii_app/css/infoTable/cabinet.css'); +$this->registerJsFile('/yii_app/js/infoTable/cabinet.js', ['position' => \yii\web\View::POS_END]); + +?> +

Кабинет

+
f8tg9yhujomip,mkonjihbu
\ No newline at end of file diff --git a/erp24/views/lesson/analytics.php b/erp24/views/lesson/analytics.php index 2f9c62f..749bb73 100644 --- a/erp24/views/lesson/analytics.php +++ b/erp24/views/lesson/analytics.php @@ -60,7 +60,7 @@ use yii_app\helpers\PrintBlockHelper; ] ])->label(false)); ?> -field($filterModel, 'lesson_group_status') ->widget(Select2::class, [ 'data' => $lessonGroupStatuses, diff --git a/erp24/views/matrix_erp_property/_form.php b/erp24/views/matrix_erp_property/_form.php index 07406e7..6f69767 100644 --- a/erp24/views/matrix_erp_property/_form.php +++ b/erp24/views/matrix_erp_property/_form.php @@ -44,6 +44,7 @@ use yii_app\services\FileService; ?>
+ Доступна загрузка изображения только в формате jpg и png ! field($modelMatrixErpProperty, 'imageFile')->fileInput(['accept' => 'image/*', 'extension' => ['png','jpg']])->label(false) ?>
diff --git a/erp24/views/payroll/list-admins.php b/erp24/views/payroll/list-admins.php index f16c1b6..4d595ce 100755 --- a/erp24/views/payroll/list-admins.php +++ b/erp24/views/payroll/list-admins.php @@ -21,6 +21,7 @@ use yii_app\helpers\HtmlHelper; /* @var $yearSelect string */ /* @var $monthSelect string */ /* @var $dateToCabinet string */ +/* @var $lastPacketDate string */ /* @var $allowedPayrollUpdate bool */ /* @var $yearMonthSearchForm yii_app\forms\payroll\YearMonthSearchForm */ diff --git a/erp24/views/scheduler_task_log/index.php b/erp24/views/scheduler_task_log/index.php index a0a9926..8f775c7 100755 --- a/erp24/views/scheduler_task_log/index.php +++ b/erp24/views/scheduler_task_log/index.php @@ -14,7 +14,7 @@ use yii_app\records\SchedulerTaskLog; $this->title = 'Scheduler Task Logs'; $this->params['breadcrumbs'][] = $this->title; ?> -
+

title) ?>

@@ -24,35 +24,58 @@ $this->params['breadcrumbs'][] = $this->title; render('_search', ['model' => $searchModel]); ?> +
+ $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], - $dataProvider, - 'filterModel' => $searchModel, - 'columns' => [ - ['class' => 'yii\grid\SerialColumn'], - - 'id', - 'task_num', - 'date_start', - 'date_stop', - 'name', - 'alias', - 'description:ntext', - 'result:ntext', - 'result_number', - 'error:ntext', - 'info:ntext', - 'log:ntext', - 'date', - [ - 'class' => ActionColumn::className(), - 'urlCreator' => function ($action, SchedulerTaskLog $model, $key, $index, $column) { - return Url::toRoute([$action, 'id' => $model->id]); - } - ], - ], - ]); ?> + 'id', + //'task_num', + 'date_start', + 'date_stop', + [ + 'attribute' => 'status', + 'value' => function (SchedulerTaskLog $model) { + if ($model->date_start != null && $model->date_stop != null) { + return 'Выполнено'; + } + return 'Пропущенно'; + }, + 'filter' => \kartik\select2\Select2::widget([ + 'model' => $searchModel, + 'attribute' => 'status', + 'data' => $searchModel->statusArray + ]) + ], + 'name', + //'alias', + //'description:ntext', + //'result:ntext', + //'result_number', + 'error:ntext', + 'info:ntext', + [ + 'attribute' => 'log', + 'value' => function (SchedulerTaskLog $model) { + return strlen($model->log) > 400 ? mb_substr($model->log, 0, 400) . "..." : $model->log; + }, + 'contentOptions' => [ + 'class' => 'w-25' + ] + ], + 'date', + [ + 'class' => ActionColumn::className(), + 'urlCreator' => function ($action, SchedulerTaskLog $model, $key, $index, $column) { + return Url::toRoute([$action, 'id' => $model->id]); + } + ], + ], + ]); ?> +
diff --git a/erp24/views/shipment/division-print-edit.php b/erp24/views/shipment/division-print-edit.php new file mode 100644 index 0000000..72e0f05 --- /dev/null +++ b/erp24/views/shipment/division-print-edit.php @@ -0,0 +1,491 @@ +registerJsFile('/yii_app/js/shipment/division-print-edit.js', ['position' => \yii\web\View::POS_END]); + +$storeGroupOptions = [-1 => 'Не выбран']; +foreach ($storeGroups as $gIndex) { + $storeGroupOptions[$gIndex] = $gIndex; +} + +$printOrientationOptions = [ + 'portrait' => 'Портретная', + 'landscape' => 'Альбомная', +]; + +?> + +
+
Деление по магазинам Дата деления id=
+ 'filter-form']); ?> +
+
Печатать цвет:
+
field($filterModel, 'printColor')->checkbox(['value' => 1, 'uncheckValue' => 0, + 'onclick' => '$("#filter-form").get(0).submit();'], false)->label(false) ?>
+
Печатать ручных добавок:
+
field($filterModel, 'printHand')->checkbox(['value' => '1', 'uncheckValue' => '0', + 'onclick' => '$("#filter-form").get(0).submit();'], false)->label(false) ?>
+
Показать столбцы итого:
+
field($filterModel, 'printSumm')->checkbox(['value' => '1', 'uncheckValue' => '0', + 'onclick' => '$("#filter-form").get(0).submit();'], false)->label(false) ?>
+
+ field($filterModel, 'groupIndex')->widget(Select2::class, [ + 'data' => $storeGroupOptions, + 'language' => 'ru', + 'options' => ['placeholder' => 'Куст...'], + 'pluginOptions' => [ + 'allowClear' => true, + ], + 'pluginEvents' => [ + 'change' => 'function(e) { + $("#filter-form").get(0).submit(); + }' + ], + ])->label(false)); ?> + field($filterModel, 'printOrientation')->widget(Select2::class, [ + 'data' => $printOrientationOptions, + 'language' => 'ru', + 'options' => ['placeholder' => 'Ориентация...'], + 'pluginOptions' => [ + 'allowClear' => true, + ], + 'pluginEvents' => [ + 'change' => 'function(e) { + $("#filter-form").get(0).submit(); + }' + ], + ])->label(false)); ?> + +
+ +
+
+ + + + + + + groupIndex == -1 || $store->parent_id == $filterModel->groupIndex): ?> + + groupIndex != -1): ?> + + + + + + + + + + + + $productName): ?> + 0): ?> + + + + + + id]["NULL"] ?? 0); + $ostatok[$productId][$store->id] = $value; + $divisionCnt += $value; + if (empty($value)) { + $value = ""; + } + ?> + groupIndex == -1 || $store->parent_id == $filterModel->groupIndex): ?> + + groupIndex != -1): ?> + + + + + + + + + + + printColor == 1): ?> + + + + + + + + + + groupIndex == -1 || $store->parent_id == $filterModel->groupIndex): ?> + id][$colorName] ?? 0); + $ostatok[$productId][$store->id] -= $value; + $colorAllCnt += $value; + ?> + + groupIndex != -1): ?> + + + + + printSumm == 1): ?> + + + + + + + + + + + + + + + groupIndex == -1 || $store->parent_id == $filterModel->groupIndex): ?> + id]; ?> + + groupIndex != -1): ?> + + + + + printSumm == 1): ?> + + + + + + + + 0): ?> + groupIndex == -1): ?> + + + + + + + + + + + + + + +
наименованиемин-ый лот деления шт.name ?>итогокупленоразница
+ + + + + + id]['NULL']) && $filterModel->printHand == 1): ?> + id]["NULL"]) ?> + + >
( шт.) + onclick="ShowInput('division_hand', + 'id ?>', + '', + '', + '', + '', + '')" + id="division_handid ?>" > + + >
остаток >
      
+
+
+ + + + + diff --git a/erp24/views/shipment/fields-data.php b/erp24/views/shipment/fields-data.php new file mode 100644 index 0000000..6a85f32 --- /dev/null +++ b/erp24/views/shipment/fields-data.php @@ -0,0 +1,592 @@ +title = 'Заказ товара'; +$this->params['breadcrumbs'][] = $this->title; +$modul = 'shipment'; + + + +$this->registerCssFile('/yii_app/css/table/table.css', ['position' => \yii\web\View::POS_END]); + +?> + + +
+ +

title) ?>

+ + + + +
+ + +обновить данные в таблице + + +

Заказ товара id= + ваша роль

'; + +загрузить розничные цены $nameProduct) { + echo "
$nameProduct Роз. цена=" . $productsPrices[$productId] . " закуп " . $productsOptions[$productId]["price_zakup"] . " "; + $price = $productsPrices[$productId]; + $data_uper[$productId]["NULL"]["NULL"] = $price; + + $db::sql(" + UPDATE + `store_orders_prices` + SET purchase_price='$price' + WHERE + product_id='$productId' + AND + order_id='$orderId' + AND + provider_id=1 + AND + purchase_price!='0.00'" + ); + + } + +//розничная цена + insert_store_orders_fields($data_uper, "purchase_price"); + + + $data_uper = []; + foreach ($products as $productId => $nameProduct) { + $price = $productsOptions[$productId]["price_zakup"]; + $data_uper[$productId]["NULL"]["NULL"] = $productsOptions[$productId]["price_zakup"]; + $db::sql("UPDATE `store_orders_prices` SET purchase_price_zakup='$price' +WHERE product_id='$productId' AND order_id='$orderId' AND provider_id=1 AND purchase_price_zakup!='0.00'"); + } + insert_store_orders_fields($data_uper, "purchase_price_zakup"); + +//header("Location: /shipment/$urlActionPart/?id=$orderId&group_id=$gid"); + } + + +} + + +//если выбран магазин то +if (!empty($store_id)) echo ''; + +echo ' +
+
+ '; +$html = ' + + '; +$thead = $html; // формируем thead +$head_td = $html; + + + +$rowArraySum = []; +$shipmentService->rowArraySum = []; + + +if (!empty($groupId)) { + foreach ($dataStoreOrdersFields as $row) { + $dostup = $dostup_fields[$row["id"]]; + $bg = $bg_fields[$row["id"]]; + if ($dostup == "edit" or $dostup == "show") { + + + $html = ''; + $thead .= $html; + $head_td .= $html; + } + + } +} + +$thead .= ''; +$head_td .= ''; +echo '' . $thead . ''; + + +//$FiledsData=getDataFiledsData(); + + +// полнограммы по всем магазинам +if (!empty($store_id)) { + $data3 = $db::getRows("SELECT store_id,product_id,quantity FROM store_planogram WHERE color='' +AND store_id!='' AND quantity>0 AND store_id=?", [$store_id]); + foreach ($data3 as $row2) $store_planogramAllStores[$row2["store_id"]][$row2["product_id"]] = $row2["quantity"]; +} + +//$data3 = $db::getRows("SELECT * FROM products_class WHERE tip in ('potted','wrap')"); +//$data3 = ProductsClass::find()->andWhere(['tip' => array('potted','wrap')])->asArray()->all(); + + + + +$trCount = 0; +foreach ($products as $pid => $name) { + if ($trCount == 20) { + $trCount = 0; + echo $head_td; + } + $trCount++; + + echo '= 6) { +// echo ' class="bg-danger"'; +// +// echo ' style="opacity:0.5"'; + } + + + echo '>'; + + +// if (!empty($store_id)) { + foreach ($dataStoreOrdersFields as $row) { + $shipmentService->printFieldTd($row["name_eng"], $pid, null); + } +// } + + echo ''; + + +//begin colors + if (array_key_exists($pid, $productsColorsArray)) { + foreach ($productsColorsArray[$pid] as $color) { + $color = trim($color); + if (!empty($color)) { + echo '"; + } + + } + } +//end colors + + +} + + +echo ''; +foreach ($dataStoreOrdersFields as $row) { + $dostup = $dostup_fields[$row["id"]]; + $bg = $bg_fields[$row["id"]]; + if ($dostup == "edit" or $dostup == "show") { + echo ''; + } +} +echo ' +'; +foreach ($dataStoreOrdersFields as $row) { + $dostup = $dostup_fields[$row["id"]]; + if ($dostup == "edit" or $dostup == "show") { + $s = ""; + if ($fieldsRows[$row["name_eng"]]["row_type_sum"] == "amount") { + $s = $shipmentService->rowArraySum[$row["id"]] ?? 0; + } + if ($fieldsRows[$row["name_eng"]]["row_type_sum"] == "avg") { + if (!empty($shipmentService->rowArraySum["cnt__" . $row["id"]])) { + $s = round($shipmentService->rowArraySum[$row["id"]] ?? 0 / $shipmentService->rowArraySum["cnt__" . $row["id"]]); + } + } + + echo ''; + } +} +echo ''; +echo '
наименование раскрыть цвета + + показать сорта + + +сортировка столбцов + +настройка столбцов + + + + ' . $row["name"] . '
'; +//если статус общий то группируем по магазинам + if (empty($statuses_stores_show[$status_order_id])) { + echo '+'; + } + echo '' . $name . ''; + + +//узнаем категорибю товара + $categoryId = $productsOptions[$pid]["parent_id"]; + $tip = ''; +// по категории узнаем тип товара горшечка или упаковка + if (!empty($products_class[$categoryId])) { + $tip = $products_class[$categoryId]; + } + + + if (array_key_exists($pid, $productsColorsArray)) { + if (count($productsColorsArray[$pid]) > 0) { + echo '+ цвета'; + } + } + echo ''; + echo '
' . $row["name"] . ' (' . $fieldsRows[$row["name_eng"]]["row_type_sum"] . ')
итого -ГО' . $s . '
+ +'; +/* +$db::sql("DELETE FROM store_orders_fields_data WHERE field_name='division_auto_need_all' AND order_id='$orderId'"); + +// суммируем деление и заносим данные в таблицу хранения данных по полям +foreach($products as $productId => $name) { +//echo"
$name "; + $all=0; + $division_auto_need_all=0; + foreach($storesArrayAll as $storeId => $nameStore) { + // echo"
$nameStoredivision_auto_need= ".$FiledsData["division_auto_need"][$productId][$storeId]["NULL"]." "; + // $summ=$FiledsData["division_auto_need"][$productId][$storeId]["NULL"] + $FiledsData["division_hand"][$productId][$storeId]["NULL"]; + $all =$all+$summ; + $division_auto_need_all += $FiledsData["division_auto_need"][$productId][$storeId]["NULL"]; + // if(!empty($summ)) { $data_uper=[];$data_uper[$productId][$storeId]["NULL"]=$summ;insert_store_orders_fields($data_uper,"division_summ");} + + + } + +$field_name="division_auto_need_all"; +//echo" Итого деления потребность + $division_auto_need_all = ".$FiledsData[$field_name][$productId]["NULL"]["NULL"]." division_auto_need_all=$division_auto_need_all "; +if(!empty($division_auto_need_all)) { + $FiledsData["division_auto_need_all"][$productId]["NULL"]["NULL"]=$division_auto_need_all; + $data_uper=[];$data_uper[$productId]["NULL"]["NULL"]=$division_auto_need_all;insert_store_orders_fields($data_uper,"division_auto_need_all");} + + +} + +//пробегаемся по всем продуктам +foreach($products as $productId => $name) { + + +$division_auto_need_all=$FiledsData["division_auto_need_all"][$productId]["NULL"]["NULL"]; +$quantity_warehouseman_fact=$FiledsData["quantity_warehouseman_fact"][$productId]["NULL"]["NULL"]; + + +echo"
$name division_auto_need_all=".$FiledsData["division_auto_need_all"][$productId]["NULL"]["NULL"]." +Сумма потребности =".$division_auto_need_all." +Сумма получаено по факту ".$quantity_warehouseman_fact.""; + +$division_ratio=1; +if($division_auto_need_all > $quantity_warehouseman_fact) { +$division_ratio=round($quantity_warehouseman_fact/$division_auto_need_all,2); + +echo"-меньше!"; + +echo" применяем коэффициент $division_ratio = ".$FiledsData["division_ratio"][$productId]["NULL"]["NULL"]." "; + +} + +$data_uper=[];$data_uper[$productId]["NULL"]["NULL"]=$division_ratio; +insert_store_orders_fields($data_uper,"division_ratio"); + + +} + +*/ + + +echo ""; + +echo ' + '; + + +//include "templates/bottom.php"; + + + + + + + + + + + +/* + +-- + + + +-- + + + */ \ No newline at end of file diff --git a/erp24/views/shipment/index.php b/erp24/views/shipment/index.php old mode 100644 new mode 100755 index e1ea7f1..9c2ece4 --- a/erp24/views/shipment/index.php +++ b/erp24/views/shipment/index.php @@ -1,5 +1,120 @@ title = 'Список закупок'; +$this->params['breadcrumbs'][] = $this->title; +$modul = 'shipments'; + +?> + + +
+ +

title) ?>

+ + +

+ 'btn btn-success']) ?> +

+ + + +
+ +
+ + + + + +
+ + + + + +registerCssFile('/yii_app/css/customSortable.css'); +$this->registerJsFile('/yii_app/js/Sortable.js', ['position' => \yii\web\View::POS_END]); +$this->registerJsFile('/yii_app/js/customSortable.js', ['position' => \yii\web\View::POS_END]); + +?> + +
+ 'filter-form']); ?> + field($filterModel, 'productId')->widget(Select2::class, [ + 'data' => $products, + 'language' => 'ru', + 'options' => ['placeholder' => 'Товар...'], + 'pluginOptions' => [ + 'allowClear' => true, + ], + 'pluginEvents' => [ + 'change' => 'function() { + $("#filter-form").get(0).submit(); + }', + ] + ])->label(false)); ?> + + +
+
+
Магазин
+
Продажи
+
Планограмма минимум
+
Планограмма максимум
+
+
+ +
+
+
+ store_id] ?? '---' ?> +
+
+ store_id] ?? '---' ?> +
+
+ store_id]->quantity ?? '---' ?> +
+
+ store_id]->quantity_max ?? '---' ?> +
+
+ +
+ +
diff --git a/erp24/views/timetable/plan.php b/erp24/views/timetable/plan.php index 65ee50b..1b08908 100755 --- a/erp24/views/timetable/plan.php +++ b/erp24/views/timetable/plan.php @@ -11,6 +11,7 @@ use yii\helpers\ArrayHelper; use yii\helpers\Html; use yii\widgets\ActiveForm; +use yii\widgets\Pjax; use yii_app\forms\timetable\TabelSearchForm; use yii_app\helpers\HtmlHelper; use yii_app\records\AdminGroup; @@ -145,6 +146,9 @@ for ($date = clone $startDatetime; $date <= $endDatetime; $date->modify('+1 day' $dates[] = clone $date; } ?> + + 'some_pjax_id']) ?> +

График сотрудников storeId] ?? '' ?> format('Y') ?> г.

@@ -249,6 +253,9 @@ $rowNumber = 0;
+ + +

short_name; ?> - name; ?> @@ -298,22 +305,32 @@ $rowNumber = 0; }); } - document.querySelectorAll('[data-plan-slot-cell]').forEach(function(element) { - element.addEventListener('click', function (event) { - event.stopPropagation(); - let params = new URLSearchParams({ - adminId: element.dataset.userId, - date: element.dataset.date, - storeId: element.dataset.storeId + function planSlotCellActivate() { + document.querySelectorAll('[data-plan-slot-cell]').forEach(function (element) { + element.addEventListener('click', function (event) { + event.stopPropagation(); + let params = new URLSearchParams({ + adminId: element.dataset.userId, + date: element.dataset.date, + storeId: element.dataset.storeId + }) + fetch('/timetable/edit_plan/?' + params, {method: 'get'}).then(response => response.text()).then(function (text) { + var intervalTime = setInterval(() => { + if ($("#modal-7").css('display') == 'none') { + clearInterval(intervalTime); + setTimeout(() => planSlotCellActivate(), 2000); + $.pjax.reload({container: '#some_pjax_id', async: false}); + } + }, 1000); + return showModal({ + title: 'Добавить сотрудника в смену', + body: text, + }); + }).then(initModal) }) - fetch('/timetable/edit_plan/?' + params, {method: 'get'}).then(response => response.text()).then(function (text) { - return showModal({ - title: 'Добавить сотрудника в смену', - body: text, - }); - }).then(initModal) }) - }) + } + planSlotCellActivate(); })(); (function() { diff --git a/erp24/views/timetable/start_shift_step_three.php b/erp24/views/timetable/start_shift_step_three.php index e5247e0..1d64232 100644 --- a/erp24/views/timetable/start_shift_step_three.php +++ b/erp24/views/timetable/start_shift_step_three.php @@ -43,7 +43,7 @@ if ($userModel->adminGroup->isRoaming()) { if (!empty($lastCheckin)) { if ($lastCheckin->isStart()) { $textButton = 'Закрытие смены'; - $textInfo = 'Смена успешно закрытиа'; + $textInfo = 'Смена успешно закрыта'; $flowersStyleClass = 'closure-flower'; $lastCheckinTimeHours = date("d.m.Y H:i", strtotime($lastCheckin->time)); $dateTimeHoursInfo = $lastCheckinTimeHours . ' - ' . date("H:i d.m.Y", strtotime($currentCheckin->time)); diff --git a/erp24/views/timetable/tabel_edit.php b/erp24/views/timetable/tabel_edit.php index 7c7e3cf..fdc38e2 100755 --- a/erp24/views/timetable/tabel_edit.php +++ b/erp24/views/timetable/tabel_edit.php @@ -7,6 +7,7 @@ use yii\helpers\ArrayHelper; use yii_app\records\AdminGroup; +use yii_app\records\Timetable; ?> @@ -19,7 +20,8 @@ use yii_app\records\AdminGroup;
- field($slot, 'shift_id')->dropDownList(ArrayHelper::map(($slot->admin && $slot->admin->adminGroup) ? $slot->admin->adminGroup->shift: [], 'id', 'name')); ?> + field($slot, 'shift_id')->dropDownList(ArrayHelper::map(($slot->admin && $slot->admin->adminGroup) ? $slot->admin->adminGroup->shift: [], 'id', 'name'), + ['onchange' => '$("#timetableplan-time_start").val(this.value == 1 ? "08:00:00" : "20:00:00"); $("#timetableplan-time_end").val(this.value == 1 ? "20:00:00" : "08:00:00");']); ?>
field($slot, 'store_id')->dropDownList(\yii_app\forms\timetable\TabelSearchForm::stores()); ?> @@ -55,16 +57,44 @@ use yii_app\records\AdminGroup;
-field($slot, 'slot_type_id')->dropDownList($slot::slotTypeName()); ?> +d_id == \yii_app\records\Admin::PART_TIME_WORKER_GROUP_ID) { + ?> +
+
+ field($slot, 'slot_type_id')->dropDownList($slot::slotTypeName()); ?> +
+
+ field($slot, 'salary_shift')->dropDownList($salariesDay); ?> +
+
field($slot, 'slot_type_id')->dropDownList($slot::slotTypeName()); +} +?> + field($slot, 'comment'); ?> field($slot, 'status')->dropDownList($slot::statuses()); ?> - 'btn btn-primary']); ?> -id) { ?> -id], ['data-role'=>'delete', 'class' => 'btn'])); ?> - -
-
+session; +$groupId = (int) $session->get('group_id'); +$numDay = Timetable::getCountDaysAllowEditShift($groupId); +if (Timetable::getAllowEditShift($slot->date, $numDay)) { + ?> + 'btn btn-primary']); ?> + id) { ?> + id], ['data-role'=>'delete', 'class' => 'btn'])); ?> + +
+
Удалить смену и факт
', \yii\helpers\Url::to(['/timetable/edit_plan?delete&force&id=' . $slot->id]), ['data-role'=>'delete', 'data-confirm' => 'Удалить?' , 'style' => "color:#fff!important;"]); ?> + - +