$model->admin_id = $userModel->id;
$model->d_id = $userModel->group_id;
$model->ball = 5;
+ $model->shift_id = $request->getBodyParam('shift_id');
if (empty($model->store_id)) {
$model->store_id = (!empty($adminStoreId)) ? $adminStoreId : $device->store_id;
}
$validate = $model->validate();
if ($validate) {
$model->save();
- TimetableFactModel::setValues($model, $request->getBodyParam('shift_id'));
$model->checkin_id = $model->checkinModel->id;
$model->id = $model->checkinModel->id;
+ TimetableFactModel::setValues($model);
if ($this->controller->request->getHeaders()->get('Accept') == 'application/json') {
$this->controller->response->format = Response::FORMAT_JSON;
--- /dev/null
+<?php
+
+namespace app\controllers;
+
+use app\records\TimetableFactModel;
+use yii\data\ActiveDataProvider;
+use yii\web\Controller;
+use yii\web\NotFoundHttpException;
+use yii\filters\VerbFilter;
+
+/**
+ * TimetableFactController implements the CRUD actions for TimetableFactModel model.
+ */
+class TimetableFactController extends Controller
+{
+ /**
+ * @inheritDoc
+ */
+ public function behaviors()
+ {
+ return array_merge(
+ parent::behaviors(),
+ [
+ 'verbs' => [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Lists all TimetableFactModel models.
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ $dataProvider = new ActiveDataProvider([
+ 'query' => TimetableFactModel::find(),
+ /*
+ 'pagination' => [
+ 'pageSize' => 50
+ ],
+ 'sort' => [
+ 'defaultOrder' => [
+ 'id' => SORT_DESC,
+ ]
+ ],
+ */
+ ]);
+
+ return $this->render('index', [
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single TimetableFactModel model.
+ * @param int $id
+ * @return string
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new TimetableFactModel model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return string|\yii\web\Response
+ */
+ public function actionCreate()
+ {
+ $model = new TimetableFactModel();
+
+ if ($this->request->isPost) {
+ if ($model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+ } else {
+ $model->loadDefaultValues();
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Updates an existing TimetableFactModel model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id
+ * @return string|\yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Deletes an existing TimetableFactModel model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id
+ * @return \yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the TimetableFactModel model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param int $id
+ * @return TimetableFactModel the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = TimetableFactModel::findOne(['id' => $id])) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
+ }
+}
$this->addError('date', 'Дата не совпадает с планом');
}
}],
- [['shift_id'], 'safe'],
+ [['shift_id'], 'required'],
];
}
--- /dev/null
+<?php
+
+use yii\db\Migration;
+
+/**
+ * Class m240611_095133_change_timetable_fact_table
+ */
+class m240611_095133_change_timetable_fact_table extends Migration
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function safeUp()
+ {
+ $this->dropForeignKey('fk_timetable_fact_to_store', 'timetable_fact');
+
+ $this->alterColumn('timetable_fact', 'work_time', $this->integer()->comment('рабочее время'));
+
+ $this->addColumn('timetable_fact', 'checkin_start_id', $this->integer()->comment('ID Отметка о начале работы'));
+ $this->addColumn('timetable_fact', 'checkin_end_id', $this->integer()->comment('ID Отметки об окончании работы'));
+
+ $this->addForeignKey('fk_timetable_fact_to_admin_checkin_start', 'timetable_fact', 'checkin_start_id', 'admin_checkin', 'id');
+ $this->addForeignKey('fk_timetable_fact_to_admin_checkin_end', 'timetable_fact', 'checkin_end_id', 'admin_checkin', 'id');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->addForeignKey('fk_timetable_fact_to_store', 'timetable_fact', 'store_id', 'city_store', 'id');
+
+ $this->alterColumn('timetable_fact', 'work_time', $this->float()->comment('рабочее время'));
+
+ $this->dropColumn('timetable_fact', 'checkin_start_id');
+ $this->dropColumn('timetable_fact', 'checkin_end_id');
+
+ $this->dropForeignKey('fk_timetable_fact_to_admin_checkin_start', 'timetable_fact');
+ $this->dropForeignKey('fk_timetable_fact_to_admin_checkin_end', 'timetable_fact');
+ }
+}
namespace app\records;
+use Throwable;
use yii\db\ActiveRecord;
+use yii_app\records\AdminCheckin;
use yii_app\records\TimetablePlan;
use yii_app\records\Timetable;
use yii_app\records\Admin;
* @property int $admin_id_add ID поставившего смену
* @property $time_start время начала работы по графику
* @property $time_end время окончания работы по графику
- * @property float $work_time время окончания работы по графику
+ * @property int $work_time время окончания работы по графику
* @property float $price_hour часовая ставка
* @property float $salary_shift оплата за смену
* @property float $slot_type_id тип занятности
* @property string $comment комментарий
* @property $date_add дата постановки смены
* @property int $status статус смены
+ * @property int $checkin_start_id ID Отметка о начале работы
+ * @property int $checkin_end_id ID Отметки об окончании работы
*/
class TimetableFactModel extends ActiveRecord
{
public function rules()
{
return [
-// [['is_opening, is_close'], 'boolean'],
-// [['is_opening, is_close'], 'default', 'value' => null],
[['d_id', 'admin_group_id'], 'exist', 'targetClass' => AdminGroup::class, 'targetAttribute' => 'id', 'skipOnEmpty' => true],
+ [['checkin_start_id', 'checkin_end_id'], 'exist', 'targetClass' => AdminCheckin::class, 'targetAttribute' => 'id', 'skipOnEmpty' => true],
[['admin_id', 'admin_id_add'], 'exist', 'targetClass' => Admin::class, 'targetAttribute' => 'id', 'skipOnEmpty' => true],
[['store_id'], 'exist', 'targetClass' => CityStore::class, 'targetAttribute' => 'id', 'skipOnEmpty' => true],
[['time_start', 'time_end'], 'date', 'format' => 'HH:mm:ss'],
[['work_time'], 'number', 'min' => 0, 'max' => 24],
[['comment'], 'string'],
[['comment'], 'default', 'value' => null],
- [['slot_type_id', 'shift_id', 'date_add', 'time_end', 'salary_shift', 'price_hour'], 'safe'],
+ [['slot_type_id', 'date_add', 'date_end', 'time_end', 'salary_shift', 'price_hour'], 'safe'],
[['date_shift'], 'date', 'format' => 'yyyy-M-d'],
-// [['salary_shift'], 'in', 'range' => \yii_app\records\Timetable::getSalariesDay(), 'skipOnEmpty' => true],
- [['time_start'], 'required'],
-// [['price_hour'], 'number', 'numberPattern' => '/^\d+(\.\d{1,2})?$/'],
-// [['date_add'], 'datetime', 'format' => "yyyy-MM-dd H:m:s"],
+ [['time_start', 'shift_id'], 'required'],
];
}
- public static function setValues($adminCheckin, $shift_id)
+ public static function setValues($adminCheckin)
{
- if ($model = self::findOne(['admin_id' => $adminCheckin->admin_id, 'date_shift' => date('Y-m-d', strtotime($adminCheckin->date)), 'is_opening' => true]) ??
- self::findOne(['admin_id' => $adminCheckin->admin_id, 'date_shift' => date('Y-m-d', strtotime($adminCheckin->date . ' -1 day')), 'is_opening' => true])) {
-
- $model->date_start = date("Y-m-d", strtotime($adminCheckin->time));
- $model->time_end = date("H:i:s", strtotime($adminCheckin->time));
- $model->is_close = true;
- $model->work_time = min((strtotime($model->time_end) - strtotime($model->time_start)) / 3600, self::WORK_HOURS_TIME);
- $model->status = $adminCheckin->type_id;
+ if ($model = self::find()
+ ->where(['admin_id' => $adminCheckin->admin_id, 'is_opening' => true])
+ ->andWhere(['between', 'date_shift', date('Y-m-d', strtotime($adminCheckin->date . ' -1 day')), date('Y-m-d', strtotime($adminCheckin->date))])
+ ->andWhere(['status' => AdminCheckin::TYPE_START])
+ ->one()) {
+
+ $model->date_end = date("Y-m-d", strtotime($adminCheckin->time));
+ $model->time_end = date("H:i:s", strtotime($adminCheckin->time));
+ $model->is_close = true;
+ $model->is_opening = false;
+ $model->work_time = min((strtotime($model->time_end) - strtotime($model->time_start)) / 3600, self::WORK_HOURS_TIME);
+ $model->status = AdminCheckin::TYPE_END;
+ $model->checkin_end_id = $adminCheckin->id;
+
+ } else {
+ $model = new TimetableFactModel();
+ $model->date_end = null;
+ $model->date_start = date("Y-m-d", strtotime($adminCheckin->time));
+ $model->time_start = date("H:i:s", strtotime($adminCheckin->time));
+ $model->is_opening = true;
+ $model->status = AdminCheckin::TYPE_START;
+ $model->checkin_start_id = $adminCheckin->id;
+
+ $timetable = Timetable::findOne(['date' => $adminCheckin->date]);
+
+ if (!empty($timetable)) {
+ $model->tabel = $timetable->id;
+ $model->plan_id = $timetable->plan_id;
+ $model->admin_id_add = $timetable->admin_id_add;
+ $model->comment = $timetable->comment;
+ $model->date_add = $timetable->date_add;
} else {
- $model = new TimetableFactModel();
- $model->date_end = null;
- $model->date_start = date("Y-m-d", strtotime($adminCheckin->time));
- $model->time_start = date("H:i:s", strtotime($adminCheckin->time));
- $model->is_opening = true;
- $model->status = $adminCheckin->type_id;
-
- $timetable = Timetable::findOne(['date' => $adminCheckin->date]);
-
- if (!empty($timetable)) {
- $model->tabel = $timetable->id;
- $model->plan_id = $timetable->plan_id;
- $model->admin_id_add = $timetable->admin_id_add;
- $model->comment = $timetable->comment;
- $model->date_add = $timetable->date_add;
-
- } else {
- $model->tabel = 1;
- $model->plan_id = null;
- $model->admin_id_add = null;
- $model->comment = null;
- $model->date_add = null;
- }
-
- $model->admin_id = $adminCheckin->admin_id;
- $model->admin_group_id = Admin::findOne(['id' => $adminCheckin->admin_id])->group_id;
- $model->d_id = $adminCheckin->d_id;
- $model->store_id = $adminCheckin->store_id;
- $model->date_shift = $adminCheckin->date;
- $model->shift_id = $shift_id;
- $model->salary_shift = !empty($salary = EmployeePayment::findOne(['admin_id' => $adminCheckin->admin_id])) ? $salary->daily_payment : null;
- $model->price_hour = $model->salary_shift / ($model->d_id == AdminGroup::GROUP_ADMINISTRATORS ? 8 : 12);
+ $model->tabel = 1;
+ $model->plan_id = null;
+ $model->admin_id_add = null;
+ $model->comment = null;
+ $model->date_add = null;
}
- if ($model->validate()) {
- $model->save();
- } else {
- var_dump($model->getErrors());
- die();
- }
+ $model->admin_id = $adminCheckin->admin_id;
+ $model->admin_group_id = Admin::findOne(['id' => $adminCheckin->admin_id])->group_id;
+ $model->d_id = $adminCheckin->d_id;
+ $model->store_id = $adminCheckin->store_id;
+ $model->date_shift = $adminCheckin->date;
+ $model->shift_id = $adminCheckin->shift_id;
+ $model->salary_shift = !empty($salary = EmployeePayment::findOne(['admin_id' => $adminCheckin->admin_id])) ? $salary->daily_payment : null;
+ $model->price_hour = $model->salary_shift / ($model->d_id == AdminGroup::GROUP_ADMINISTRATORS ? 8 : 12);
}
-// }
+
+ if($model->validate()) {
+ $model->save();
+ } else {
+ var_dump($model->getErrors());die();
+ }
+ }
+
public function getAdmin()
{
return $this->hasOne(Admin::class, ['id' => 'admin_id']);
}
+ public function getCheckinStart()
+{
+ return $this->hasOne(AdminCheckin::class, ['id' => 'checkin_start_id']);
+}
+
+ public function getCheckinEnd()
+ {
+ return $this->hasOne(AdminCheckin::class, ['id' => 'checkin_end_id']);
+ }
+ public function getShift()
+ {
+ return $this->hasOne(Shift::class, ['id' => 'shift_id']);
+ }
+
public function getAdminAdd()
{
return $this->hasOne(Admin::class, ['id' => 'admin_id_add']);
--- /dev/null
+<?php
+
+use app\records\TimetableFactModel;
+use yii\helpers\Html;
+use yii\helpers\Url;
+use yii\grid\ActionColumn;
+use yii\grid\GridView;
+use yii_app\services\FileService;
+
+/** @var yii\web\View $this */
+/** @var yii\data\ActiveDataProvider $dataProvider */
+
+$this->title = Yii::t('app', 'Фактический табель сотрудников (Новый!)');
+$this->params['breadcrumbs'][] = $this->title;
+?>
+<div class="timetable-fact-model-index">
+
+ <h1><?= Html::encode($this->title) ?></h1>
+
+
+ <?= GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+ [
+ 'attribute' => 'admin_id',
+ 'label' => 'Пользователь',
+ 'value' => function ($data) {
+ return $data->admin->name;
+ }
+ ],
+ [
+ 'attribute' => 'store_id',
+ 'label' => 'Магазин, Должность',
+ 'format' => 'raw',
+ 'value' => function ($data) {
+ return $data->store->name . "<br>" . $data->adminGroup->name;
+ }
+ ],
+ [
+ 'label' => 'Тип смены',
+ 'attribute' => 'shift_id',
+ 'format' => 'raw',
+ 'value' => function ($model) {
+ return $model->shift->name;
+ },
+ ],
+ [
+ 'label' => 'Отработанное время',
+ 'attribute' => 'work_time',
+ ],
+ [
+ 'label' => 'Дата смены',
+ 'attribute' => 'date_shift',
+ 'format' => ['date', 'php:d.m.Y'],
+ ],
+ [
+ 'label' => 'Начало',
+ 'attribute' => 'date_start',
+ 'format' => 'raw',
+ 'value' => function ($model) {
+ return Yii::$app->formatter->asDatetime($model->date_start, 'php:d.m.Y') . "<br>" .
+ Yii::$app->formatter->asDatetime($model->time_start, 'php:H:i:s');
+ },
+ ],
+ [
+ 'label' => 'Конец',
+ 'attribute' => 'date_end',
+ 'format' => 'raw',
+ 'value' => function ($model) {
+ return !empty($model->date_end) ? Yii::$app->formatter->asDatetime($model->date_end, 'php:d.m.Y') . "<br>" .
+ Yii::$app->formatter->asDatetime($model->time_end, 'php:H:i:s') : 'Работает';
+ },
+ ],
+ [
+ 'label' => 'Отметка о начале',
+ 'format' => 'raw',
+ 'value' => function ($model) {
+ return !empty($model->checkinStart->photo) ? Html::img($model->checkinStart->photo, ['alt="selfie" height="100px"']) : '';
+ },
+ ],
+ [
+ 'label' => 'Отметка о конце',
+ 'format' => 'raw',
+ 'value' => function ($model) {
+ return !empty($model->checkinEnd->photo) ? Html::img($model->checkinEnd->photo, ['alt="selfie" height="100px"']) : '';
+ },
+ ],
+ ],
+ ]); ?>
+
+
+</div>
use yii\helpers\Html;\r
use yii_app\forms\timetable\StartForm;\r
use yii_app\records\AdminCheckin;\r
+use yii_app\records\Shift;\r
use yii_app\records\TimetablePlan;\r
\r
\yii_app\assets\timetable\StartAsset::register($this);\r
<?= Html::activeHiddenInput($model, 'admin_id'); ?>\r
<?= Html::activeHiddenInput($model, 'checkin_id'); ?>\r
<?= Html::activeHiddenInput($model, 'ball'); ?>\r
+ <?= Html::activeHiddenInput($model, 'shift_id'); ?>\r
<?php if ($model->isStart()) { ?>\r
<?= Html::activeHiddenInput($model, 'd_id'); ?>\r
<?php } ?>\r
<div class="text-secondary"><?= $userModel->adminGroup->name?></div>\r
</div>\r
<div\r
- class="d-flex gap-3 justify-content-left justify-content-lg-start align-items-lg-end"\r
+ class="d-flex gap-3 justify-content-left justify-content-lg-start align-items-lg-end my-5"\r
>\r
<div class="text-secondary">Магазин</div>\r
</div>\r
+ <div\r
+ class="row d-flex gap-3 justify-content-left justify-content-lg-start align-items-lg-end my-3"\r
+ >\r
+ <div class="text-secondary">Тип смены</div>\r
+\r
+ </div>\r
+\r
</div>\r
<div class="col-lg-6">\r
<div>\r
>\r
<div class="fs-5"><?= $adminStoreName?></div>\r
</div>\r
+ <div\r
+ class="d-flex gap-3 justify-content-left justify-content-lg-start align-items-lg-end my-3"\r
+ >\r
+ <div class="fs-5"><?= Shift::findOne($model->shift_id)->name ?></div>\r
+ </div>\r
</div>\r
</div>\r
</div>\r