]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Документация
authorVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Fri, 14 Nov 2025 15:08:39 +0000 (18:08 +0300)
committerVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Fri, 14 Nov 2025 15:08:39 +0000 (18:08 +0300)
erp24/actions/grade/AdminUpdateAction.php
erp24/actions/grade/UpdateAction.php
erp24/api3/core/services/ReportService.php
erp24/views/grade/admin-update.php
erp24/views/grade/update.php
erp24/views/store-staffing/index.php

index 968766fa6600cfc8ef4de22a3075eb752556767d..4aca3a8d5af8d100dbcd745ebcfd9691c7cef9a3 100644 (file)
@@ -212,7 +212,25 @@ class AdminUpdateAction extends Action
 
         $companies = ArrayHelper::map(Companies::find()->all(), 'id', 'name');
 
+        // Извлекаем смену из group_name, если она там есть
+        $shift = '';
+        if ($model->employee_position_id && !empty($model->group_name)) {
+            $position = EmployeePosition::findOne($model->employee_position_id);
+            if ($position) {
+                $positionName = $position->name;
+                // Проверяем, что group_name начинается с названия должности и заканчивается на " день" или " ночь"
+                if (mb_strpos($model->group_name, $positionName) === 0) {
+                    $remaining = mb_substr($model->group_name, mb_strlen($positionName));
+                    if ($remaining === ' день') {
+                        $shift = 'день';
+                    } elseif ($remaining === ' ночь') {
+                        $shift = 'ночь';
+                    }
+                }
+            }
+        }
+
         return $this->controller->render('admin-update', compact('model', 'adminGroups', 'admins',
-            'cityStores', 'adminHistoryCategories', 'companies', 'positions'));
+            'cityStores', 'adminHistoryCategories', 'companies', 'positions', 'shift'));
     }
 }
index 0b4ff8bc6504c8b189067ece509e49befbb965ad..2b35edef4bd8236e49b37b1bb9360750418b49bb 100755 (executable)
@@ -21,17 +21,23 @@ class UpdateAction extends Action
 
         $positions = EmployeePosition::find()->orderBy('posit')->all();
 
-        $modelPosition = DynamicModel::validateData(['position_id' => null, 'action' => 'updatePosition'], [['position_id', 'integer'], ['action', 'string']]);
+        $modelPosition = DynamicModel::validateData(['position_id' => null, 'shift' => '', 'action' => 'updatePosition'], 
+            [['position_id', 'integer'], ['shift', 'string'], ['action', 'string']]);
 
         if ($modelPosition->load(Yii::$app->request->post()) && $modelPosition->action == 'updatePosition') {
             // Гибридный подход: обновляем основное поле (источник истины)
             $admin->employee_position_id = $modelPosition->position_id;
             
-            // Синхронизируем group_name с выбранной должностью (как в AdminUpdateAction)
+            // Синхронизируем group_name с выбранной должностью и сменой (как в AdminUpdateAction)
             if ($modelPosition->position_id) {
                 $position = EmployeePosition::findOne($modelPosition->position_id);
                 if ($position) {
-                    $admin->group_name = $position->name;
+                    $groupName = $position->name;
+                    // Если выбрана смена, добавляем её к названию
+                    if (!empty($modelPosition->shift)) {
+                        $groupName .= ' ' . $modelPosition->shift;
+                    }
+                    $admin->group_name = $groupName;
                 }
             }
             
@@ -47,6 +53,25 @@ class UpdateAction extends Action
             // Показываем текущий грейд из основного поля (источник истины)
             $modelPosition->position_id = $admin->employee_position_id;
             $modelPosition->action = 'updatePosition';
+            
+            // Извлекаем смену из group_name, если она там есть
+            $shift = '';
+            if ($admin->employee_position_id && !empty($admin->group_name)) {
+                $position = EmployeePosition::findOne($admin->employee_position_id);
+                if ($position) {
+                    $positionName = $position->name;
+                    // Проверяем, что group_name начинается с названия должности и заканчивается на " день" или " ночь"
+                    if (mb_strpos($admin->group_name, $positionName) === 0) {
+                        $remaining = mb_substr($admin->group_name, mb_strlen($positionName));
+                        if ($remaining === ' день') {
+                            $shift = 'день';
+                        } elseif ($remaining === ' ночь') {
+                            $shift = 'ночь';
+                        }
+                    }
+                }
+            }
+            $modelPosition->shift = $shift;
             $modelPosition->validate();
         }
 
index fbf95dfa454b3a890d0dcb7daf0883f37abeccdd..a0d3664833e580d3c9809d8d54abf49431966b4c 100644 (file)
@@ -334,11 +334,12 @@ class ReportService
         // Получаем все уникальные admin_id сотрудников за период
         $allAdminsInPeriod = Timetable::find()->alias('t')
             ->select(['admin_id'])
-            ->distinct()
             ->where(['t.store_id' => $data->stores])
             ->andWhere(['>=', 'date', date("Y-m-01", strtotime($data->date_start))])
             ->andWhere(['<=', 'date', $data->date_end])
             ->andWhere(['tabel' => 0, 'slot_type_id' => Timetable::TIMESLOT_WORK])
+            ->andWhere(['IS', 't.deleted_at', null])
+            ->groupBy(['admin_id'])
             ->asArray()->all();
 
         $adminIdsInPeriod = ArrayHelper::getColumn($allAdminsInPeriod, 'admin_id');
@@ -358,6 +359,7 @@ class ReportService
                 ->andWhere(['>=', 'date', date("Y-m-01", strtotime($currentDate))])
                 ->andWhere(['<=', 'date', $currentDate])
                 ->andWhere(['shift_id' => $shift_id, 'tabel' => 0, 'slot_type_id' => Timetable::TIMESLOT_WORK])
+                ->andWhere(['IS', 't.deleted_at', null])
                 ->asArray()->all();
 
             $timetables = Timetable::find()->alias('t')->select(['admin_id', 'a.name as adminName', 't.store_id', 't.shift_id'])
@@ -365,6 +367,7 @@ class ReportService
                 ->where(['t.store_id' => $data->stores])
                 ->andWhere(['date' => $currentDate, 'tabel' => 0])
                 ->andWhere(['shift_id' => $shift_id, 'slot_type_id' => Timetable::TIMESLOT_WORK])
+                ->andWhere(['IS', 't.deleted_at', null])
                 ->asArray()->all();
 
             $adminIdsMonth = ArrayHelper::getColumn($timetablesMonth, 'admin_id');
@@ -552,17 +555,20 @@ class ReportService
 
             $adminNames = [];
             foreach ($timetables as $timetable) {
-                $adminNames[$timetable['store_id']][] = [
+                $storeId = $timetable['store_id'];
+                
+                if (!isset($adminNames[$storeId])) {
+                    $adminNames[$storeId] = [];
+                }
+                
+                // Добавляем все записи из timetable (фильтрация по deleted_at уже применена в запросе)
+                // Один администратор может работать в несколько смен в один день
+                $adminNames[$storeId][] = [
                     'id' => $timetable['admin_id'],
                     'name' => $timetable['adminName'],
                     'shift_id' => $timetable['shift_id'],
                 ];
             }
-            
-            // Преобразуем индексированный массив обратно в обычный для совместимости с остальным кодом
-            foreach ($adminNames as $storeId => $admins) {
-                $adminNames[$storeId] = array_values($admins);
-            }
 
             $storeVisitorsQuantityTotal = 0;
             $storeSaleQuantityTotal = 0;
index 9161c6fdc7d3cf5f7b0f519cdb2201ccad3840b7..f974f6bc68c50d3dcaab4fd950287826e2572e42 100644 (file)
@@ -77,7 +77,7 @@ use yii_app\services\FileService;
             ArrayHelper::map($positions, 'id', 'name'), ['prompt' => 'Выберите должность']
         )->label(false)) ?>
 
-        <?php PrintBlockHelper::printBlock('Смена', Html::dropDownList('Admin[shift]', '', [
+        <?php PrintBlockHelper::printBlock('Смена', Html::dropDownList('Admin[shift]', $shift ?? '', [
             '' => 'Не выбрана',
             'день' => 'День',
             'ночь' => 'Ночь'
index 3f1b020bd18a674cf078609be451372011b8234e..3db9687272eb787d0521287c24cce12abe819078 100755 (executable)
@@ -74,7 +74,13 @@ use dosamigos\datetimepicker\DateTimePicker;
                 ['' => '-- Выберите грейд --'] + ArrayHelper::map($positions, 'id', 'name'),
                 ['class' => 'form-control']
             )->label(false); ?>
+             <?= $gradeForm->field($modelPosition, 'shift')->dropDownList([
+                '' => 'Не выбрана',
+                'день' => 'День',
+                'ночь' => 'Ночь'
+            ], ['class' => 'form-control'])->label('Смена') ?>
         </div>
+
         <div class="col-2">
             <?= Html::submitButton('💾 Сохранить грейд', ['class' => 'btn btn-primary'])?>
         </div>
index 0d1388c32b4164060fba58b18da32c8e328c9714..baed117b897f35506fbf8fc21594aaa8814bcadc 100644 (file)
@@ -111,10 +111,11 @@ $this->params['breadcrumbs'][] = $this->title;
             }
 
             foreach ($storeSkills as $storeId => $data) {
-                $avgScore = $data['totalCount'] > 0 ? round($data['totalWeighted'] / $data['totalCount'], 1) : 0;
+                $avgScore = $data['totalCount'] > 0 ? round($data['totalWeighted'] / $data['totalCount'], 2) : 0;
+                $avgScoreFormatted = number_format($avgScore, 2, ',', ' ');
                 echo '<tr>';
                 echo '<td>' . Html::a($data['storeName'], ['logs', 'store_id' => $storeId]) . '</td>';
-                echo '<td><strong>' . $avgScore . '</strong></td>';
+                echo '<td><strong>' . $avgScoreFormatted . '</strong></td>';
                 echo '</tr>';
             }
             ?>