use yii_app\records\AdminStores;
use yii_app\records\CityStore;
use yii_app\records\Companies;
+use yii_app\records\EmployeePosition;
use yii_app\records\ExportImportTable;
use yii_app\services\HistoryService;
Yii::$app->cache->set("dirtyAuthSettings", true);
}
+ // Обновляем group_name на основе выбранной группы
+ if (isset($attributes['group_id'])) {
+ $adminGroup = AdminGroup::findOne($attributes['group_id']);
+ if ($adminGroup) {
+ $attributes['group_name'] = $adminGroup->name;
+ }
+ }
+
$model->setAttributes($attributes, false);
if (Yii::$app->user->can("manageAvatarka", ['id' => $model->id])) {
}
$admins = ArrayHelper::map($adminArr, 'id', 'name', 'groupName');
-
+ $positions = EmployeePosition::find()->orderBy('posit')->all();
$cityStores = ArrayHelper::map(CityStore::find()->select(['id', 'name'])->all(), 'id', 'name');
$adminHistoryCategories = HistoryService::getHistoryAdmin($model->id);
$companies = ArrayHelper::map(Companies::find()->all(), 'id', 'name');
return $this->controller->render('admin-update', compact('model', 'adminGroups', 'admins',
- 'cityStores', 'adminHistoryCategories', 'companies'));
+ 'cityStores', 'adminHistoryCategories', 'companies', 'positions'));
}
}
use yii\db\Expression;
use yii\helpers\ArrayHelper;
use yii_app\api3\modules\v1\models\timetable\Timetable;
+use yii_app\records\Admin;
use yii_app\records\AdminPayrollDays;
use yii_app\records\CityStore;
+use yii_app\records\EmployeePosition;
use yii_app\records\ExportImportTable;
use yii_app\records\Products1c;
use yii_app\records\ProductsClass;
$currentDate = $data->date_start;
$reports = [];
+ $totalEmployeePositionsOnShift = [];
$employees = Sales::find()->select(["COUNT(*) as cnt", "admin_id"])
->where([
->groupBy(['admin_id'])->asArray()->all();
$employeeCount = count($employees);
+ // Получаем все уникальные 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])
+ ->asArray()->all();
+
+ $adminIdsInPeriod = ArrayHelper::getColumn($allAdminsInPeriod, 'admin_id');
+
+ $employeePositions = EmployeePosition::find()->select(['id', 'name'])->indexBy('id')->asArray()->all();
+
+ $adminPositions = Admin::find()->select(['id', 'employee_position_id', 'group_name'])
+ ->where(['id' => $adminIdsInPeriod])
+ ->indexBy('id')
+ ->asArray()->all();
+
+ // Создаем карту должностей для каждого admin_id
+ $positionMap = [];
+ foreach ($adminPositions as $adminId => $admin) {
+ $positionName = '';
+
+ if (!empty($admin['employee_position_id']) && isset($employeePositions[$admin['employee_position_id']])) {
+ $positionName = $employeePositions[$admin['employee_position_id']]['name'];
+ } elseif (!empty($admin['group_name'])) {
+ // Ищем похожее название в employee_positions
+ $groupNameLower = mb_strtolower(trim($admin['group_name']));
+ $found = false;
+ foreach ($employeePositions as $empPos) {
+ if (mb_strpos($groupNameLower, mb_strtolower(trim($empPos['name']))) !== false ||
+ mb_strpos(mb_strtolower(trim($empPos['name'])), $groupNameLower) !== false) {
+ $positionName = $empPos['name'];
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ $positionName = $admin['group_name'];
+ }
+ }
+
+ $positionMap[$adminId] = $positionName;
+ }
+
while ($currentDate <= $data->date_end) {
- $report = [
- "date" => $currentDate,
- "shift_type" => $data->shift_type,
- ];
+ $report = [];
$shift_id = $data->shift_type == 0 ? [1, 2, 5, 8] : ($data->shift_type == 1 ? [1, 5, 8] : [2]);
$adminIdsMonth = ArrayHelper::getColumn($timetablesMonth, 'admin_id');
$adminIds = ArrayHelper::getColumn($timetables, 'admin_id');
+ // Подсчет должностей на смене для этого дня
+ $employeePositionsOnShift = [];
+ foreach ($timetables as $timetable) {
+ $adminId = $timetable['admin_id'];
+ $positionName = $positionMap[$adminId] ?? '';
+
+ if (!empty($positionName)) {
+ if (!isset($employeePositionsOnShift[$positionName])) {
+ $employeePositionsOnShift[$positionName] = 0;
+ }
+ $employeePositionsOnShift[$positionName]++;
+
+ // Суммируем для общего отчета
+ if (!isset($totalEmployeePositionsOnShift[$positionName])) {
+ $totalEmployeePositionsOnShift[$positionName] = 0;
+ }
+ $totalEmployeePositionsOnShift[$positionName]++;
+ }
+ }
+
$adminPayrollDaysMonth = AdminPayrollDays::find()->select(["FLOOR(SUM(day_payroll)) as total", "store_id"])
->where(['>=', 'date', date("Y-m-01", strtotime($currentDate))])
->andWhere(['<=', 'date', $currentDate])
$totalServicePerDayTotal += $totalServicePerDay;
$totalPottedPerDayTotal += $totalPottedPerDay;
+ // Подсчет должностей для этого магазина
+ $storeEmployeePositionsOnShift = [];
+ if (isset($adminNames[$store->id])) {
+ foreach ($adminNames[$store->id] as $adminRecord) {
+ $adminId = $adminRecord['id'];
+ $positionName = $positionMap[$adminId] ?? '';
+
+ if (!empty($positionName)) {
+ if (!isset($storeEmployeePositionsOnShift[$positionName])) {
+ $storeEmployeePositionsOnShift[$positionName] = 0;
+ }
+ $storeEmployeePositionsOnShift[$positionName]++;
+ }
+ }
+ }
$reportStore = [
"name" => $store->name,
"id" => $store->id,
"admins" => $adminNames[$store->id] ?? [],
+ "employee_positions_on_shift" => $storeEmployeePositionsOnShift,
"visitors_quantity" => $storeVisitorsQuantity,
"sale_quantity" => $storeSaleQuantity,
"sale_total" => $storeSaleTotal,
"total_wrap_per_day" => $totalWrapPerDayTotal,
"total_services_per_day" => $totalServicePerDayTotal,
"total_potted_per_day" => $totalPottedPerDayTotal,
+ "employee_positions_on_shift" => $employeePositionsOnShift,
+ ];
+
+ // Создаем итоговый массив для дня с правильным порядком полей
+ $dayReport = [
+ "date" => $currentDate,
+ "shift_type" => $data->shift_type,
+ "stores" => $report["stores"] ?? [],
+ "total" => $report['total'],
];
- $reports[] = $report;
+ $reports[] = $dayReport;
$currentDate = date("Y-m-d", strtotime("+1 day", strtotime($currentDate)));
}
--- /dev/null
+<?php
+
+use yii\db\Migration;
+
+/**
+ * Handles the creation of table `{{%admin_positions}}`.
+ */
+class m251027_071121_create_admin_positions_table extends Migration
+{
+ /**
+ * {@inheritdoc}
+ */
+ const TABLE_NAME = 'erp24.admin_positions';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeUp()
+ {
+ $tableSchema = $this->db->getTableSchema(self::TABLE_NAME);
+
+ if (!isset($tableSchema)) {
+ $this->createTable(self::TABLE_NAME, [
+ 'id' => $this->primaryKey(),
+ 'name' => $this->string()->notNull()->comment('Наименование должности'),
+ 'alias' => $this->string()->notNull()->comment('Алиас должности'),
+ 'salary' => $this->decimal(10, 2)->notNull()->comment('Ставка в рублях'),
+ 'created_at' => $this->dateTime()->notNull()->comment('Дата создания'),
+ 'created_by' => $this->integer()->notNull()->comment('ИД создателя'),
+ 'updated_at' => $this->dateTime()->null()->comment('Дата обновления'),
+ 'updated_by' => $this->integer()->null()->comment('ИД редактировавшего'),
+ ]);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropTable('{{%admin_positions}}');
+ }
+}
--- /dev/null
+<?php
+
+use yii\db\Migration;
+
+class m251027_071237_add_admin_position_id_field_to_admin_table extends Migration
+{
+ /**
+ * {@inheritdoc}
+ */
+ const TABLE_NAME = 'erp24.admin';
+ const COLUMN_NAME = 'employee_position_id';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeUp()
+ {
+ $tableSchema = $this->db->getTableSchema(self::TABLE_NAME);
+
+ if (isset($tableSchema) && !isset($tableSchema->columns[self::COLUMN_NAME])) {
+ $this->addColumn(self::TABLE_NAME, self::COLUMN_NAME, $this->integer()->null()->comment('ID должности администратора'));
+ $this->addForeignKey(
+ 'fk-admin-employee_position_id',
+ self::TABLE_NAME,
+ self::COLUMN_NAME,
+ 'erp24.employee_position',
+ 'id',
+ 'SET NULL',
+ 'CASCADE'
+ );
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $tableSchema = $this->db->getTableSchema(self::TABLE_NAME);
+
+ if (isset($tableSchema) && isset($tableSchema->columns[self::COLUMN_NAME])) {
+ $this->dropForeignKey('fk-admin-employee_position_id', self::TABLE_NAME);
+ $this->dropColumn(self::TABLE_NAME, self::COLUMN_NAME);
+ } else {
+ echo "m251027_071237_add_admin_position_id_field_to_admin_table cannot be reverted.\n";
+ return false;
+ }
+ }
+
+ /*
+ // Use up()/down() to run migration code without a transaction.
+ public function up()
+ {
+
+ }
+
+ public function down()
+ {
+ echo "m251027_071237_add_admin_position_id_field_to_admin_table cannot be reverted.\n";
+
+ return false;
+ }
+ */
+}
--- /dev/null
+<?php
+
+use yii\db\Migration;
+
+class m251028_141001_add_salary_and_group_id_fields_to_employee_position_table extends Migration
+{
+ const TABLE_NAME = 'erp24.employee_position';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeUp()
+ {
+ $tableSchema = $this->db->getTableSchema(self::TABLE_NAME);
+
+ // Добавляем поле salary
+ if (isset($tableSchema) && !isset($tableSchema->columns['salary'])) {
+ $this->addColumn(self::TABLE_NAME, 'salary', $this->integer()->null()->comment('Зарплата'));
+ }
+
+ // Добавляем поле alias
+ if (isset($tableSchema) && !isset($tableSchema->columns['alias'])) {
+ $this->addColumn(self::TABLE_NAME, 'alias', $this->string(255)->null()->comment('Алиас'));
+ }
+
+ // Добавляем поле group_id
+ if (isset($tableSchema) && !isset($tableSchema->columns['group_id'])) {
+ $this->addColumn(self::TABLE_NAME, 'group_id', $this->integer()->null()->comment('Ссылка на группу'));
+ $this->addForeignKey(
+ 'fk-employee_position-group_id',
+ self::TABLE_NAME,
+ 'group_id',
+ 'erp24.admin_group',
+ 'id',
+ 'SET NULL',
+ 'CASCADE'
+ );
+ }
+
+ // Добавляем поле created_by
+ if (isset($tableSchema) && !isset($tableSchema->columns['created_by'])) {
+ $this->addColumn(self::TABLE_NAME, 'created_by', $this->integer()->null()->comment('Кем создано'));
+ }
+
+ // Добавляем поле updated_by
+ if (isset($tableSchema) && !isset($tableSchema->columns['updated_by'])) {
+ $this->addColumn(self::TABLE_NAME, 'updated_by', $this->integer()->null()->comment('Кем изменено'));
+ }
+
+ // Добавляем поле created_at
+ if (isset($tableSchema) && !isset($tableSchema->columns['created_at'])) {
+ $this->addColumn(self::TABLE_NAME, 'created_at', $this->timestamp()->null()->comment('Дата создания'));
+ }
+
+ // Добавляем поле updated_at
+ if (isset($tableSchema) && !isset($tableSchema->columns['updated_at'])) {
+ $this->addColumn(self::TABLE_NAME, 'updated_at', $this->timestamp()->null()->comment('Дата изменения'));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $tableSchema = $this->db->getTableSchema(self::TABLE_NAME);
+
+ // Удаляем поле updated_by
+ if (isset($tableSchema) && isset($tableSchema->columns['updated_by'])) {
+ $this->dropColumn(self::TABLE_NAME, 'updated_by');
+ }
+
+ // Удаляем поле created_by
+ if (isset($tableSchema) && isset($tableSchema->columns['created_by'])) {
+ $this->dropColumn(self::TABLE_NAME, 'created_by');
+ }
+
+ // Удаляем поле group_id
+ if (isset($tableSchema) && isset($tableSchema->columns['group_id'])) {
+ $this->dropForeignKey('fk-employee_position-group_id', self::TABLE_NAME);
+ $this->dropColumn(self::TABLE_NAME, 'group_id');
+ }
+
+ // Удаляем поле alias
+ if (isset($tableSchema) && isset($tableSchema->columns['alias'])) {
+ $this->dropColumn(self::TABLE_NAME, 'alias');
+ }
+
+ // Удаляем поле updated_at
+ if (isset($tableSchema) && isset($tableSchema->columns['updated_at'])) {
+ $this->dropColumn(self::TABLE_NAME, 'updated_at');
+ }
+
+ // Удаляем поле created_at
+ if (isset($tableSchema) && isset($tableSchema->columns['created_at'])) {
+ $this->dropColumn(self::TABLE_NAME, 'created_at');
+ }
+
+ // Удаляем поле salary
+ if (isset($tableSchema) && isset($tableSchema->columns['salary'])) {
+ $this->dropColumn(self::TABLE_NAME, 'salary');
+ }
+ }
+
+ /*
+ // Use up()/down() to run migration code without a transaction.
+ public function up()
+ {
+
+ }
+
+ public function down()
+ {
+ echo "m251028_141001_add_salary_and_group_id_fields_to_employee_position_table cannot be reverted.\n";
+
+ return false;
+ }
+ */
+}
namespace yii_app\records;
use yii\db\ActiveRecord;
+use yii\helpers\ArrayHelper;
/**
* Class AdminGroup
{
return in_array($this->id, [7, Admin::ADMINISTRATOR_GROUP_ID]);
}
+
+ public static function getAllIdName()
+ {
+ $result = [];
+
+ $values = self::find()->all();
+
+ if(!empty($values)){
+ $result = ArrayHelper::map($values, 'id', 'name');
+ }
+
+ return $result;
+ }
}
\ No newline at end of file
use Yii;
use yii\helpers\ArrayHelper;
+use yii\behaviors\TimestampBehavior;
+use yii\behaviors\BlameableBehavior;
/**
* This is the model class for table "employee_position".
* @property string $name
* @property int $next_position_id
* @property int $posit
+ * @property int $salary
+ * @property string $alias
+ * @property int $group_id
+ * @property string $created_at
+ * @property int $created_by
+ * @property string $updated_at
+ * @property int $updated_by
*/
class EmployeePosition extends \yii\db\ActiveRecord
{
return 'employee_position';
}
+ /**
+ * {@inheritdoc}
+ */
+ public function behaviors()
+ {
+ return [
+ [
+ 'class' => TimestampBehavior::class,
+ 'createdAtAttribute' => 'created_at',
+ 'updatedAtAttribute' => 'updated_at',
+ 'value' => function () {
+ return date('Y-m-d H:i:s');
+ },
+ ],
+ [
+ 'class' => BlameableBehavior::class,
+ 'createdByAttribute' => 'created_by',
+ 'updatedByAttribute' => 'updated_by',
+ ],
+ ];
+ }
+
/**
* {@inheritdoc}
*/
{
return [
[['name'], 'required'],
- [['name'], 'string', 'max' => 45],
- [['next_position_id', 'posit'], 'safe'],
+ [['name', 'alias'], 'string', 'max' => 255],
+ [['next_position_id', 'posit', 'salary', 'group_id', 'created_by', 'updated_by'], 'integer'],
+ [['created_at', 'updated_at'], 'safe'],
+ [['salary', 'alias', 'group_id', 'created_at', 'created_by', 'updated_at', 'updated_by'], 'default', 'value' => null],
];
}
{
return [
'id' => 'ID',
- 'name' => 'Name',
- 'next_position_id' => 'Next Position Id',
- 'posit' => 'Posit',
+ 'name' => 'Название',
+ 'next_position_id' => 'Следующая должность',
+ 'posit' => 'Позиция',
+ 'salary' => 'Зарплата',
+ 'alias' => 'Алиас',
+ 'group_id' => 'Группа',
+ 'created_at' => 'Дата создания',
+ 'created_by' => 'Кем создано',
+ 'updated_at' => 'Дата изменения',
+ 'updated_by' => 'Кем изменено',
];
}
public function getSkills() {
return $this->hasMany(EmployeeSkill::class, ['id' => 'skill_id'])->via('positionSkill');
}
+
+ public function getAdminGroup() {
+ return $this->hasOne(\yii_app\records\AdminGroup::class, ['id' => 'group_id']);
+ }
}
/**
* EmployeePositionSearch represents the model behind the search form of `yii_app\records\EmployeePosition`.
*/
-class EmployeePositionSearch extends EmployeePosition
+class EmployeePositionSearch extends Model
{
+ public $id;
+ public $name;
+ public $alias;
+ public $salary;
+ public $group_id;
+
/**
* {@inheritdoc}
*/
public function rules()
{
return [
- [['id'], 'integer'],
- [['name'], 'safe'],
+ [['id', 'salary', 'group_id'], 'integer'],
+ [['name', 'alias'], 'safe'],
];
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
+ 'salary' => $this->salary,
+ 'group_id' => $this->group_id,
]);
- $query->andFilterWhere(['like', 'name', $this->name]);
+ $query->andFilterWhere(['like', 'name', $this->name])
+ ->andFilterWhere(['like', 'alias', $this->alias]);
return $dataProvider;
}
<?php printBlock('Название', $form->field($model, 'name')->textInput(['maxlength' => true])->label(false)) ?>
+ <?php printBlock('Алиас', $form->field($model, 'alias')->textInput(['maxlength' => true])->label(false)) ?>
+
+ <?php printBlock('Зарплата', $form->field($model, 'salary')->textInput(['type' => 'number'])->label(false)) ?>
+
+ <?php printBlock('Группа', $form->field($model, 'group_id')->dropDownList(\yii_app\records\AdminGroup::getAllIdName(), ['prompt' => 'Выберите группу'])->label(false)) ?>
+
<?php printBlock('Позиция', $form->field($model, 'posit')->textInput(['maxlength' => true])->label(false)) ?>
<div class="form-group">
<?= $form->field($model, 'name') ?>
+ <?= $form->field($model, 'alias') ?>
+
+ <?= $form->field($model, 'salary') ?>
+
+ <?= $form->field($model, 'group_id')->dropDownList(\yii_app\records\AdminGroup::getAllIdName(), ['prompt' => 'Все группы']) ?>
+
<div class="form-group">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
<?= Html::resetButton('Reset', ['class' => 'btn btn-outline-secondary']) ?>
$this->params['breadcrumbs'][] = ['label' => 'Employee Positions', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
-<div class="employee-position-create">
+<div class="employee-position-create p-4">
<h1><?= Html::encode($this->title) ?></h1>
$this->title = 'Позиции работников';
$this->params['breadcrumbs'][] = $this->title;
?>
-<div class="employee-position-index">
+<div class="employee-position-index p-4">
<h1><?= Html::encode($this->title) ?></h1>
<?= Html::a('Создать позицию работника', ['create'], ['class' => 'btn btn-success']) ?>
</p>
- <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
+ <?php //echo $this->render('_search', ['model' => $searchModel]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
return Html::a($model->name, ['/crud/employee-position/update', 'id' => $model->id], ['class' => 'btn btn-link']);
}
],
+ 'alias',
+ 'salary',
+ [
+ 'attribute' => 'group_id',
+ 'value' => function ($model) {
+ return $model->adminGroup ? $model->adminGroup->name : null;
+ }
+ ],
[
'class' => ActionColumn::className(),
'urlCreator' => function ($action, EmployeePosition $model, $key, $index, $column) {
$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
$this->params['breadcrumbs'][] = 'Update';
?>
-<div class="employee-position-update">
+<div class="employee-position-update p-4">
<small>Редактирование регламента: </small>
<h3><a href="<?= \yii\helpers\Url::to(['/crud/employee-position']) ?>" class="btn btn-primary m-2">Назад</a>
</div>
</div>
-<div class="employee-position-view">
+<div class="employee-position-view p-4">
<h1><?= Html::encode($this->title) ?></h1>
'attributes' => [
'id',
'name',
+ 'alias',
+ 'salary',
+ [
+ 'attribute' => 'group_id',
+ 'value' => function ($model) {
+ return $model->adminGroup ? $model->adminGroup->name : null;
+ }
+ ],
+ 'created_at',
+ [
+ 'attribute' => 'created_by',
+ 'value' => function ($model) {
+ return $model->created_by ? \yii_app\records\Admin::findOne($model->created_by)->name ?? 'Неизвестен' : null;
+ }
+ ],
+ 'updated_at',
+ [
+ 'attribute' => 'updated_by',
+ 'value' => function ($model) {
+ return $model->updated_by ? \yii_app\records\Admin::findOne($model->updated_by)->name ?? 'Неизвестен' : null;
+ }
+ ],
],
]) ?>
use yii\widgets\ActiveForm;
use yii\helpers\Html;
+use yii\helpers\ArrayHelper;
use yii_app\helpers\PrintBlockHelper;
use yii_app\records\Admin;
use yii_app\records\Products1c;
}
?>
- <?php PrintBlockHelper::printBlock('Должность', $form->field($model, 'group_name')->textInput(['maxlength' => true])->label(false)) ?>
+ <?php PrintBlockHelper::printBlock('Должность', $form->field($model, 'employee_position_id')->dropDownList(
+ ArrayHelper::map($positions, 'id', 'name'), ['prompt' => 'Выберите должность']
+ )->label(false)) ?>
<div id="workRate" style="display: <?= $model->group_id == \yii_app\records\AdminGroup::GROUP_ADMINISTRATORS ? 'block' : 'none'?>">
<?php PrintBlockHelper::printBlock('Рабочий график', $form->field($model, 'work_rate')->dropDownList([1 => '5/2', 2 => '2/2', 3 => '3/3'])->label(false)) ?>