You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
5.3 KiB
194 lines
5.3 KiB
<?php |
|
|
|
namespace App\Models; |
|
|
|
// use Illuminate\Contracts\Auth\MustVerifyEmail; |
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
|
use Illuminate\Foundation\Auth\User as Authenticatable; |
|
use Illuminate\Notifications\Notifiable; |
|
use Laravel\Sanctum\HasApiTokens; |
|
use Tymon\JWTAuth\Contracts\JWTSubject; |
|
use Carbon\Carbon; |
|
|
|
class User extends Authenticatable implements JWTSubject |
|
{ |
|
use HasApiTokens, HasFactory, Notifiable; |
|
|
|
/** |
|
* The attributes that are mass assignable. |
|
* |
|
* @var array<int, string> |
|
*/ |
|
protected $table = 'm_users', $guarded = ['id']; |
|
|
|
const CREATED_AT = 'created_at'; |
|
const UPDATED_AT = 'updated_at'; |
|
|
|
const DEFAULT_TZ = 'Asia/Jakarta'; |
|
const INSIDE = "INSIDE"; |
|
const OUTSIDE = "OUTSIDE"; |
|
const HOLIDAY = "HOLIDAY"; |
|
/** |
|
* The attributes that should be hidden for serialization. |
|
* |
|
* @var array<int, string> |
|
*/ |
|
protected $hidden = [ |
|
'password', |
|
'remember_token', |
|
]; |
|
|
|
/** |
|
* The attributes that should be cast. |
|
* |
|
* @var array<string, string> |
|
*/ |
|
protected $casts = [ |
|
'email_verified_at' => 'datetime', |
|
]; |
|
|
|
/** |
|
* Get the identifier that will be stored in the subject claim of the JWT. |
|
* |
|
* @return mixed |
|
*/ |
|
public function getJWTIdentifier() |
|
{ |
|
return $this->getKey(); |
|
} |
|
|
|
/** |
|
* Return a key value array, containing any custom claims to be added to the JWT. |
|
* |
|
* @return array |
|
*/ |
|
public function getJWTCustomClaims() |
|
{ |
|
return []; |
|
} |
|
|
|
/** |
|
* Get working hours for given timestamp |
|
* |
|
* @return array of carbon or NULL in case HOLIDAY |
|
*/ |
|
|
|
public function getWorkingTime(Carbon $ts, $f = "08:00", $t = "17:00", $tz = self::DEFAULT_TZ) |
|
{ |
|
$workingTime = array( |
|
"from" => Carbon::createFromTimeString($f, $tz), |
|
"to" => Carbon::createFromTimeString($t, $tz) |
|
); |
|
|
|
$userShift = UserShift::query()->where('user_id', '=', $this->id) |
|
->orderByDesc('from_date') |
|
->first(); |
|
|
|
$shift = null; |
|
if ($userShift->exists()) { |
|
$shiftId = null; |
|
switch ($ts->shortEnglishDayOfWeek) { |
|
case "Mon": |
|
$shiftId = $userShift['mon_shift_id']; |
|
break; |
|
case "Tue": |
|
$shiftId = $userShift['tue_shift_id']; |
|
break; |
|
case "Wed": |
|
$shiftId = $userShift['wed_shift_id']; |
|
break; |
|
case "Thu": |
|
$shiftId = $userShift['thu_shift_id']; |
|
break; |
|
case "Fri": |
|
$shiftId = $userShift['fri_shift_id']; |
|
break; |
|
case "Sat": |
|
$shiftId = $userShift['sat_shift_id']; |
|
break; |
|
case "Sun": |
|
$shiftId = $userShift['sun_shift_id']; |
|
break; |
|
} |
|
|
|
if ($shiftId === null) { |
|
return null; |
|
} |
|
|
|
$shift = Shift::query()->find($shiftId); |
|
} else { |
|
$shift = Shift::query()->where('is_non_shift', '=', true) |
|
->orderByDesc('created_at') |
|
->first(); |
|
} |
|
|
|
|
|
if ($shift->exists()) { |
|
$from = Carbon::createFromTimeString($shift->start_time, $tz) |
|
->subMinutes($shift->flex_time_minute); |
|
$to = Carbon::createFromTimeString($shift->end_time, $tz) |
|
->addMinutes($shift->flex_time_minute); |
|
|
|
$workingTime['from'] = $from; |
|
$workingTime['to'] = $to; |
|
} |
|
|
|
return $workingTime; |
|
} |
|
|
|
/** |
|
* Get presence status |
|
*/ |
|
public function presenceStatus(Carbon $at = null, $tz = self::DEFAULT_TZ) |
|
{ |
|
|
|
$ts = $at; |
|
if ($at !== null) { |
|
$ts = Carbon::now($tz); |
|
} |
|
$tsSec = $ts->secondsSinceMidnight(); |
|
|
|
$status = ""; |
|
$wt = $this->getWorkingTime($ts, $tz); |
|
if ($wt === null) { |
|
$status = self::HOLIDAY; |
|
} else { |
|
$from = $wt->from; |
|
$to = $wt->to; |
|
$tsFrom = $from->secondsSinceMidnight(); |
|
$tsTo = $to->secondsSinceMidnight(); |
|
|
|
if ($from->greaterThan($to)) { |
|
24 * 60 * 60 - $tsFrom; |
|
if ($tsSec >= $tsFrom || $tsSec < $tsTo) { |
|
$status = self::INSIDE; |
|
} else { |
|
$status = self::OUTSIDE; |
|
} |
|
} else { |
|
if ($tsSec < $tsFrom || $tsSec > $tsTo) { |
|
$status = self::OUTSIDE; |
|
} else { |
|
$status = self::INSIDE; |
|
} |
|
} |
|
} |
|
|
|
$clockIn = null; |
|
$clockOut = null; |
|
$inout = Presence::query()->where('user_id', '=', $this->id) |
|
->orderByDesc('clock_in') |
|
->first(); |
|
if ($inout->exists()) { |
|
$clockIn = Carbon::parse($inout->clock_in, $tz); |
|
$clockOut = Carbon::parse($inout->clock_out, $tz); |
|
} |
|
|
|
return [ |
|
"status" => $status, |
|
"ts" => $ts, |
|
"clock_in" => $clockIn, |
|
"clock_out" => $clockOut |
|
]; |
|
} |
|
}
|
|
|