%PDF- %PDF-
Direktori : /var/www/html/hr/api/app/Models/ |
Current File : /var/www/html/hr/api/app/Models/Timecard.php |
<?php namespace App\Models; use App\Exceptions\AppException; use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\DB; use Throwable; /** * @property integer id * @property mixed date * @property mixed start_time * @property mixed end_time * @property string notes * @property string status * @property float hours * @property float approved_hours * @property integer user_id * @property integer approved_by * @property integer project_id * @property User user * @property User approvedBy * @property Project project */ class Timecard extends BaseModel { const TO_APPROVE = 'TO_APPROVE'; const APPROVED = 'APPROVED'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'date', 'start_time', 'end_time', 'notes', 'status', 'hours', 'approved_hours', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'id' => 'integer', 'date' => 'date', 'start_time' => 'time', 'end_time' => 'time', 'notes' => 'string', 'status' => 'string', 'hours' => 'float', 'approved_hours' => 'float', 'user_id' => 'integer', 'project_id' => 'integer', ]; /** * @param $data * @return self * @throws Throwable */ public static function createItem($data) { try { $user = self::getLoggedInUser(); $timecardsOnDate = self::query() ->where('user_id', $user->id) ->where('date', Carbon::parse($data['date'])) ->where('start_time', '<', Carbon::parse($data['end_time'])) ->where('end_time', '>', Carbon::parse($data['start_time'])) ->exists(); if ($timecardsOnDate) { throw new AppException('This timecard entry overlaps with other timecards on the same date, please check start and end time.'); } /** @var Project $project */ $project = Project::query() ->find($data['project_id']); if (!$project->canLogTimecard($user->id)) { throw new AppException('You are not allowed to log hours into this project'); } DB::beginTransaction(); /** @var self $item */ $item = self::query() ->make([ 'date' => $data['date'], 'start_time' => $data['start_time'], 'end_time' => $data['end_time'], 'notes' => $data['notes'], 'hours' => self::diffInHours($data['end_time'], $data['start_time']), ]); $item->user() ->associate($user); $item->project() ->associate($data['project_id']); $item->save(); DB::commit(); return $item; } catch (Throwable $e) { DB::rollBack(); throw $e; } } public function user() { return $this->belongsTo(User::class); } public function project() { return $this->belongsTo(Project::class); } public static function bulkApprove($timecards) { forEach ($timecards as $t) { /** @var Timecard $timecard */ $timecard = Timecard::query() ->find($t['id']); $timecard->approve($t['approved_hours']); } } public function approve($approved_hours) { $this->status = self::APPROVED; $this->approved_hours = $approved_hours; $this->approvedBy() ->associate(self::getLoggedInUser()); $this->save(); $this->save(); } public function approvedBy() { return $this->belongsTo(User::class, 'approved_by'); } public static function bulkUnApprove($timecards) { self::query() ->whereIn('id', $timecards) ->update([ 'status' => self::TO_APPROVE, 'approved_hours' => null, ]); } public static function approveAll() { $user = BaseModel::getLoggedInUser(); $timecards = Timecard::query() ->where('status', self::TO_APPROVE) ->private($user); if ($user->isManager()) { $timecards = $timecards->whereHas('project', function (Builder $p) use ($user) { $p->where('manager_id', $user->id); }); } $timecards->update([ 'status' => self::APPROVED, 'approved_hours' => DB::raw("`hours`"), 'approved_by' => $user->id, ]); } /** * @param $data * @return self * @throws Throwable */ public function updateItem($data) { try { if (!$this->isEditable()) { throw new AppException(trans('timecards.cant_edit_due_approval')); } $timecardsOnDate = self::query() ->where('id', '!=', $this->id) ->where('date', Carbon::parse($data['date'])) ->where('start_time', '<', Carbon::parse($data['end_time'])) ->where('end_time', '>', Carbon::parse($data['start_time'])) ->exists(); if ($timecardsOnDate) { throw new AppException(trans('timecards.overlapping')); } DB::beginTransaction(); $this->date = $data['date']; $this->start_time = $data['start_time']; $this->end_time = $data['end_time']; $this->notes = $data['notes']; $this->hours = self::diffInHours($data['end_time'], $data['start_time']); $this->project() ->associate($data['project_id']); $this->save(); DB::commit(); return $this; } catch (Throwable $e) { DB::rollBack(); throw $e; } } public function isEditable() { return $this->status !== self::APPROVED; } /** * @throws Throwable */ public function deleteItem() { try { if (!$this->isDeletable()) { throw new AppException(trans('timecards.cant_delete_due_approval')); } $this->delete(); } catch (Throwable $e) { throw $e; } } public function isDeletable() { return $this->status !== self::APPROVED; } public function scopePrivate(Builder $query, $user) { return $query->whereHas('project', function (Builder $q) use ($user) { $q->where('is_private', false); $q->orWhere(function (Builder $u) use ($user) { $u->where('is_private', true); $u->where('manager_id', $user->id); }); }); } }