AsArrayObject::class]; //------------------------------------------------------------ // -- RELATED TO RELATIONSHIP // HAS ONE public function self(): HasOne { return $this->hasOne(self::class, 'id', 'id'); } /// BELONGS TO public function tv(): BelongsTo { return $this->belongsTo(Tv::class, 'tv_fk', 'id'); } // -- END RELATED TO RELATIONSHIP //------------------------------------------------------------ //------------------------------------------------------------ // -- RELATED TO SCOPE public function scopeAddColumnCanApprove(Builder $query) { $query->withCount(['self as can_approve' => function($q) { $q->whereNull('activated_at'); }]); } public function scopeAddColumnCanReject(Builder $query) { $query->withCount(['self as can_reject' => function($q) { $q->whereNull('activated_at'); }]); } // -- END RELATED TO SCOPE //------------------------------------------------------------ //------------------------------------------------------------ // -- RELATED TO DATA FUNCTION private static function _generateRandomCode(): string { $totalDigit = 6; $randomDigit = ''; while(true) { $randomDigit = strtoupper(Str::random($totalDigit)); $isExist = NewTvRequest::where('code', $randomDigit)->first(); if(!$isExist) break; } return $randomDigit; } // -- END RELATED TO DATA FUNCTION //------------------------------------------------------------ //------------------------------------------------------------ // -- RELATED TO FROM REQUEST FUNCTION private static function _checkOrCreateResponse(NewTvRequest $newTvReq) { if($newTvReq->is_activated) { // make sure waiting tv_device responded before deleted if(empty($newTvReq->responded_at)) { $newTvReq->responded_at = now(); $newTvReq->save(); } return JSONResponse::Success([ 'message' => 'activated', 'is_active' => true, 'new_tv_request' => $newTvReq, 'tv' => $newTvReq->tv ]); } return JSONResponse::Success([ 'message' => 'not activate', 'is_active' => false, 'new_tv_request' => $newTvReq, 'tv' => null ]); } public static function approveFromRequest(Request $request) { $request->validate([ 'id' => 'required|integer|exists:App\Models\NewTvRequest', 'tv' => 'required|array', ]); $tvRequest = new Request($request->tv); if($tvRequest->filled('code')) $tvRequest->code = strtoupper($tvRequest->code); $tvRequest->validate([ 'code' => 'required|string|unique:App\Models\Tv,code', 'col1' => 'nullable|string', 'col2' => 'nullable|string', 'col3' => 'nullable|string', 'col4' => 'nullable|string', 'col5' => 'nullable|string', 'col6' => 'nullable|string', 'col7' => 'nullable|string', 'col8' => 'nullable|string', 'col9' => 'nullable|string', 'col10' => 'nullable|string', 'notes' => 'nullable|string', ]); $newTvReq = NewTvRequest::addColumnCanApprove() ->findOrFail($request->id); if(!$newTvReq->can_approve) throw new \Exception('Cannot approve current request'); try { DB::beginTransaction(); $tv = new Tv(); $tv->code = $tvRequest->code; $tv->col1 = $tvRequest->col1; $tv->col2 = $tvRequest->col2; $tv->col3 = $tvRequest->col3; $tv->col4 = $tvRequest->col4; $tv->col5 = $tvRequest->col5; $tv->col6 = $tvRequest->col6; $tv->col7 = $tvRequest->col7; $tv->col8 = $tvRequest->col8; $tv->col9 = $tvRequest->col9; $tv->col10 = $tvRequest->col10; $tv->notes = $tvRequest->notes; $tv->device_info = $newTvReq->device_info; $tv->save(); $newTvReq->activated_at = now(); $newTvReq->tv_fk = $tv->id; $newTvReq->save(); // try to sys_to_sys with indokargo $jsonResponse = Indokargo::createTVAddress($tvRequest, $tv->id); DB::commit(); return $jsonResponse; } catch(\Throwable $th) { DB::rollback(); throw $th; } } public static function rejectFromRequest(Request $request) { $request->validate([ 'id' => 'required|integer|exists:App\Models\NewTvRequest', ]); $newTvRequest = NewTvRequest::addColumnCanReject() ->findOrFail($request->id); if(!$newTvRequest->can_reject) throw new \Exception('Cannot reject current request'); $newTvRequest->delete(); return JSONResponse::Success(['data' => $newTvRequest ]); } /** * Rule: * 1. if it has not been activated for more than the expiry date, deleted it * 2. if it has been activated & has been responded more than expiry date, delete it * - case: when has been activated, but intenet connection missing, how can device know * that the new request tv has been activated? */ private static function _getMaxExpiredTime() :Carbon { return Carbon::now()->subHour(); } public static function deleteExpiredRequests() { $expiredTime = self::_getMaxExpiredTime()->toString(); NewTvRequest::where(function($q) use ($expiredTime) { $q->whereNull('activated_at')->where('created_at', '<=', $expiredTime); })->orWhere(function($q) use ($expiredTime) { $q->where('responded_at', '<=', $expiredTime ); })->delete(); } // -- END RELATED TO FROM REQUEST FUNCTION //------------------------------------------------------------ }