From: Vladimir Fomichev Date: Wed, 17 Dec 2025 08:52:59 +0000 (+0300) Subject: Удаляем синхронизацию зарплат X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=d9b5405a8cacf5df64b1cf4003d94d78b3991862;p=erp24_rep%2Fyii-erp24%2F.git Удаляем синхронизацию зарплат --- diff --git a/erp24/controllers/crud/EmployeePaymentController.php b/erp24/controllers/crud/EmployeePaymentController.php index dfa58d4c..615f55f8 100755 --- a/erp24/controllers/crud/EmployeePaymentController.php +++ b/erp24/controllers/crud/EmployeePaymentController.php @@ -9,7 +9,6 @@ use yii\helpers\ArrayHelper; use yii_app\records\Admin; use yii_app\records\EmployeePayment; use yii_app\forms\EmployeePaymentSearch; -use yii_app\services\SalarySyncService; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -213,24 +212,6 @@ class EmployeePaymentController extends Controller return $this->redirect(['view', 'id' => $adminId]); } - /** - * Синхронизирует оклады для всех сотрудников с заполненным employee_position_id - * @return \yii\web\Response - */ - public function actionSyncSalaries() - { - $syncService = new SalarySyncService(); - $result = $syncService->syncAllEmployeesFromPositions(); - - if ($result['success']) { - Yii::$app->session->setFlash('success', $result['message']); - } else { - Yii::$app->session->setFlash('error', $result['message']); - } - - return $this->redirect(['index']); - } - /** * Finds the EmployeePayment model based on its primary key value. diff --git a/erp24/controllers/crud/EmployeePositionController.php b/erp24/controllers/crud/EmployeePositionController.php index fd77e822..6b7099ee 100755 --- a/erp24/controllers/crud/EmployeePositionController.php +++ b/erp24/controllers/crud/EmployeePositionController.php @@ -4,7 +4,6 @@ namespace yii_app\controllers\crud; use yii_app\records\EmployeePosition; use yii_app\records\EmployeePositionSearch; -use yii_app\services\SalarySyncService; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -118,24 +117,6 @@ class EmployeePositionController extends Controller return $this->redirect(['index']); } - /** - * Синхронизирует оклады для всех сотрудников с заполненным employee_position_id - * @return \yii\web\Response - */ - public function actionSyncSalaries() - { - $syncService = new SalarySyncService(); - $result = $syncService->syncAllEmployeesFromPositions(); - - if ($result['success']) { - Yii::$app->session->setFlash('success', $result['message']); - } else { - Yii::$app->session->setFlash('error', $result['message']); - } - - return $this->redirect(['index']); - } - /** * Finds the EmployeePosition model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. diff --git a/erp24/records/Admin.php b/erp24/records/Admin.php index 856eca3b..c0e39f83 100755 --- a/erp24/records/Admin.php +++ b/erp24/records/Admin.php @@ -12,7 +12,6 @@ use yii\db\Expression; use yii\helpers\ArrayHelper; use yii\web\IdentityInterface; use yii_app\api3\core\validators\PhoneValidator; -use yii_app\services\SalarySyncService; /** * Class Admin @@ -778,16 +777,8 @@ class Admin extends ActiveRecord implements IdentityInterface * a) Закрывает все активные записи истории (closed_at = NOW) * b) Создаёт новую запись с текущей должностью (closed_at = NULL) * - Важно: история НЕ создаётся при первом сохранении нового сотрудника, - * так как нет предыдущей позиции для закрытия - * - * 2. **СИНХРОНИЗАЦИЯ ЗАРПЛАТЫ (EmployeePayment)** - * - Автоматически создаёт запись о зарплате через SalarySyncService - * - Срабатывает когда: - * a) Установлена должность (employee_position_id не NULL) - * b) Должность изменилась ИЛИ создаётся новая запись ($insert) - * c) Сотрудник не уволен (group_id != AdminGroup::GROUP_FIRED) - * - В отличие от истории грейдов, работает и для новых записей - * + * так как нет предыдущей позиции для закрытия * + * * **Обработка ошибок:** * - Все операции обёрнуты в try-catch * - Ошибки логируются, но НЕ прерывают сохранение Admin @@ -802,7 +793,6 @@ class Admin extends ActiveRecord implements IdentityInterface * @return void * * @see EmployeePositionStatus Модель для истории должностей - * @see SalarySyncService Сервис синхронизации зарплаты * @see EmployeePayment Модель зарплатных данных */ public function afterSave($insert, $changedAttributes) @@ -842,19 +832,5 @@ class Admin extends ActiveRecord implements IdentityInterface // Не бросаем исключение, чтобы не прервать сохранение Admin } } - //TODO: разобраться с синхронизацией окладов по должностям - if ($newPositionId && ($oldPositionId != $newPositionId || $insert) && $this->group_id != AdminGroup::GROUP_FIRED) { - try { - $syncService = new SalarySyncService(); - $result = $syncService->createPaymentFromPosition($this->id); - - if ($result) { - Yii::info("Автоматически создана запись EmployeePayment для admin_id={$this->id}, position_id={$newPositionId}", 'salary-sync'); - } - } catch (\Exception $e) { - Yii::error("Ошибка автоматической синхронизации оклада для admin_id={$this->id}: " . $e->getMessage(), 'salary-sync'); - // Не бросаем исключение, чтобы не прервать сохранение Admin - } - } } } diff --git a/erp24/records/EmployeePosition.php b/erp24/records/EmployeePosition.php index dc29f537..5b876c38 100755 --- a/erp24/records/EmployeePosition.php +++ b/erp24/records/EmployeePosition.php @@ -6,8 +6,6 @@ use Yii; use yii\helpers\ArrayHelper; use yii\behaviors\TimestampBehavior; use yii\behaviors\BlameableBehavior; -use yii_app\records\EmployeePayment; -use yii_app\services\SalarySyncService; /** * This is the model class for table "employee_position". @@ -142,31 +140,4 @@ class EmployeePosition extends \yii\db\ActiveRecord return $this->hasMany(EmployeePayment::class, ['employee_position_id' => 'id']); } - /** - * После сохранения проверяем, изменился ли оклад, и синхронизируем для всех сотрудников с этой должностью - */ - public function afterSave($insert, $changedAttributes) - { - parent::afterSave($insert, $changedAttributes); - - // Проверяем, изменились ли оклады (monthly_salary или daily_payment) - $salaryChanged = array_key_exists('monthly_salary', $changedAttributes) || - array_key_exists('daily_payment', $changedAttributes); - - // Если оклады изменились и они заполнены, синхронизируем для всех сотрудников - if ($salaryChanged && $this->monthly_salary !== null && $this->daily_payment !== null) { - try { - $syncService = new SalarySyncService(); - $creatorId = $this->updated_by ?? Yii::$app->user->id ?? null; - $result = $syncService->syncEmployeesByPosition($this->id, $creatorId); - - if ($result['success']) { - Yii::info("Автоматическая синхронизация окладов для должности ID={$this->id}: {$result['message']}", 'salary-sync'); - } - } catch (\Exception $e) { - Yii::error("Ошибка автоматической синхронизации окладов для должности ID={$this->id}: " . $e->getMessage(), 'salary-sync'); - // Не бросаем исключение, чтобы не прервать сохранение EmployeePosition - } - } - } } diff --git a/erp24/services/SalarySyncService.php b/erp24/services/SalarySyncService.php deleted file mode 100644 index 280b1c82..00000000 --- a/erp24/services/SalarySyncService.php +++ /dev/null @@ -1,280 +0,0 @@ - bool, 'message' => string, 'created' => int, 'skipped' => int] - */ - public function syncAllEmployeesFromPositions($creatorId = null): array - { - if ($creatorId === null) { - $creatorId = Yii::$app->user->id ?? null; - } - - if (!$creatorId) { - return [ - 'success' => false, - 'message' => 'Не указан ID пользователя для создания записей', - 'created' => 0, - 'skipped' => 0 - ]; - } - - $created = 0; - $skipped = 0; - $errors = []; - - // Получаем всех сотрудников с заполненным employee_position_id, не уволенных - $admins = Admin::find() - ->where(['IS NOT', 'employee_position_id', null]) - ->andWhere(['!=', 'group_id', AdminGroup::GROUP_FIRED]) - ->all(); - - foreach ($admins as $admin) { - $position = EmployeePosition::findOne($admin->employee_position_id); - - if (!$position) { - $skipped++; - continue; - } - - // Проверяем, заполнены ли оклады для должности - if ($position->monthly_salary === null || $position->daily_payment === null) { - $skipped++; - continue; - } - - // Проверяем, есть ли уже запись EmployeePayment для этого сотрудника - $existingPayment = EmployeePayment::find() - ->where(['admin_id' => $admin->id]) - ->orderBy(['date' => SORT_DESC]) - ->one(); - - // Если запись уже есть, создаем новую с датой следующего месяца - $date = date('Y-m-01', strtotime('+1 month')); - - // Проверяем, нет ли уже записи на эту дату - $paymentOnDate = EmployeePayment::find() - ->where(['admin_id' => $admin->id, 'date' => $date]) - ->one(); - - if ($paymentOnDate) { - $skipped++; - continue; - } - - // Создаем новую запись - $payment = new EmployeePayment(); - $payment->admin_id = $admin->id; - $payment->admin_group_id = $admin->group_id; - $payment->employee_position_id = $position->id; - $payment->monthly_salary = $position->monthly_salary; - $payment->daily_payment = $position->daily_payment; - $payment->date = $date; - $payment->creator_id = $creatorId; - - if ($payment->save()) { - $created++; - } else { - $skipped++; - $errors[] = "Ошибка для сотрудника {$admin->name} (ID: {$admin->id}): " . implode(', ', $payment->getFirstErrors()); - } - } - - $message = "Синхронизация завершена. Создано записей: {$created}, пропущено: {$skipped}"; - if (!empty($errors)) { - $message .= ". Ошибки: " . implode('; ', array_slice($errors, 0, 5)); - } - - return [ - 'success' => true, - 'message' => $message, - 'created' => $created, - 'skipped' => $skipped, - 'errors' => $errors - ]; - } - - /** - * Создает или обновляет запись EmployeePayment для сотрудника на основе его должности - * Дата устанавливается первым числом текущего месяца - * Если запись за этот месяц уже существует, она обновляется - * - * @param int $adminId ID сотрудника - * @param int|null $creatorId ID пользователя, создающего запись - * @param string|null $date Дата записи (по умолчанию первое число текущего месяца) - * @return EmployeePayment|null Созданная или обновленная запись или null в случае ошибки - */ - public function createPaymentFromPosition($adminId, $creatorId = null, $date = null): ?EmployeePayment - { - if ($creatorId === null) { - $creatorId = Yii::$app->user->id ?? null; - } - - if (!$creatorId) { - return null; - } - // Первое число следующего месяца - $date = date('Y-m-01', strtotime('+1 month')); - - $admin = Admin::findOne($adminId); - if (!$admin || !$admin->employee_position_id) { - return null; - } - - $position = EmployeePosition::findOne($admin->employee_position_id); - if (!$position || $position->monthly_salary === null || $position->daily_payment === null) { - return null; - } - - // Проверяем, есть ли уже запись за этот месяц и год - $year = date('Y', strtotime($date)); - $month = date('m', strtotime($date)); - - $existingPayment = EmployeePayment::find() - ->where(['admin_id' => $adminId]) - ->andWhere(['EXTRACT(YEAR FROM date)' => $year]) - ->andWhere(['EXTRACT(MONTH FROM date)' => $month]) - ->one(); - - if ($existingPayment) { - // Обновляем существующую запись - $existingPayment->admin_group_id = $admin->group_id; - $existingPayment->employee_position_id = $position->id; - $existingPayment->monthly_salary = $position->monthly_salary; - $existingPayment->daily_payment = $position->daily_payment; - $existingPayment->date = $date; - $existingPayment->creator_id = $creatorId; - - if ($existingPayment->save()) { - return $existingPayment; - } - return null; - } - - // Создаем новую запись - $payment = new EmployeePayment(); - $payment->admin_id = $adminId; - $payment->admin_group_id = $admin->group_id; - $payment->employee_position_id = $position->id; - $payment->monthly_salary = $position->monthly_salary; - $payment->daily_payment = $position->daily_payment; - $payment->date = $date; - $payment->creator_id = $creatorId; - - if ($payment->save()) { - return $payment; - } - - return null; - } - - /** - * Синхронизирует оклады для всех сотрудников с указанной должностью - * Используется при изменении оклада должности - * Дата устанавливается первым числом текущего месяца - * Если запись за этот месяц уже существует, она обновляется - * - * @param int $positionId ID должности - * @param int|null $creatorId ID пользователя, изменившего оклад - * @return array ['success' => bool, 'message' => string, 'created' => int, 'updated' => int] - */ - public function syncEmployeesByPosition($positionId, $creatorId = null): array - { - if ($creatorId === null) { - $creatorId = Yii::$app->user->id ?? null; - } - - if (!$creatorId) { - return [ - 'success' => false, - 'message' => 'Не указан ID пользователя для создания записей', - 'created' => 0, - 'updated' => 0 - ]; - } - - $position = EmployeePosition::findOne($positionId); - if (!$position || $position->monthly_salary === null || $position->daily_payment === null) { - return [ - 'success' => false, - 'message' => 'Должность не найдена или оклады не заполнены', - 'created' => 0, - 'updated' => 0 - ]; - } - - $created = 0; - $updated = 0; - $date = date('Y-m-01', strtotime('+1 month')); // Первое число следующего месяца - $year = date('Y'); - $month = date('m'); - - // Получаем всех сотрудников с этой должностью, не уволенных - $admins = Admin::find() - ->where(['employee_position_id' => $positionId]) - ->andWhere(['!=', 'group_id', AdminGroup::GROUP_FIRED]) - ->all(); - - foreach ($admins as $admin) { - // Проверяем, есть ли уже запись за этот месяц и год - $existingPayment = EmployeePayment::find() - ->where(['admin_id' => $admin->id]) - ->andWhere(['EXTRACT(YEAR FROM date)' => $year]) - ->andWhere(['EXTRACT(MONTH FROM date)' => $month]) - ->one(); - - if ($existingPayment) { - // Обновляем существующую запись - $existingPayment->admin_group_id = $admin->group_id; - $existingPayment->employee_position_id = $position->id; - $existingPayment->monthly_salary = $position->monthly_salary; - $existingPayment->daily_payment = $position->daily_payment; - $existingPayment->date = $date; - $existingPayment->creator_id = $creatorId; - - if ($existingPayment->save()) { - $updated++; - } - } else { - // Создаем новую запись - $payment = new EmployeePayment(); - $payment->admin_id = $admin->id; - $payment->admin_group_id = $admin->group_id; - $payment->employee_position_id = $position->id; - $payment->monthly_salary = $position->monthly_salary; - $payment->daily_payment = $position->daily_payment; - $payment->date = $date; - $payment->creator_id = $creatorId; - - if ($payment->save()) { - $created++; - } - } - } - - $message = "Синхронизация завершена. Создано записей: {$created}, обновлено: {$updated}"; - return [ - 'success' => true, - 'message' => $message, - 'created' => $created, - 'updated' => $updated - ]; - } -} - diff --git a/erp24/views/crud/employee-payment/index.php b/erp24/views/crud/employee-payment/index.php index 9e0e3420..8bab1f79 100755 --- a/erp24/views/crud/employee-payment/index.php +++ b/erp24/views/crud/employee-payment/index.php @@ -21,13 +21,6 @@ $this->params['breadcrumbs'][] = $this->title; user->identity && Yii::$app->user->identity->hasPermission('employee-paymentEdit')): ?> 'btn btn-success mb-4']) ?> - 'btn btn-primary mb-4', - 'data' => [ - 'confirm' => 'Вы уверены, что хотите синхронизировать оклады для всех сотрудников с заполненной должностью?', - 'method' => 'post', - ], - ]) ?> diff --git a/erp24/views/crud/employee-position/index.php b/erp24/views/crud/employee-position/index.php index b3323592..3f3b11ae 100755 --- a/erp24/views/crud/employee-position/index.php +++ b/erp24/views/crud/employee-position/index.php @@ -19,13 +19,6 @@ $this->params['breadcrumbs'][] = $this->title;

'btn btn-success']) ?> - 'btn btn-primary', - 'data' => [ - 'confirm' => 'Вы уверены, что хотите синхронизировать оклады для всех сотрудников с заполненной должностью?', - 'method' => 'post', - ], - ]) ?>

render('_search', ['model' => $searchModel]); ?>