Compare commits
2 Commits
10f9a2b82f
...
fb281607d1
| Author | SHA1 | Date |
|---|---|---|
|
|
fb281607d1 | 2 years ago |
|
|
546df1abf6 | 2 years ago |
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
namespace App\Helper\STS;
|
||||
|
||||
use App\Helper\JSONResponse;
|
||||
use App\Models\StsLog;
|
||||
use App\Models\Tv;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class Indokargo {
|
||||
const STATUS_SUCCESS = 'Success';
|
||||
const STATUS_FAILURE = 'Failure';
|
||||
// const STATUS_WARNING = 'Warning';
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//-- UTILITIES
|
||||
private static function _checkIkResponse($res) {
|
||||
$status = $res['status'];
|
||||
if($res['status'] == self::STATUS_SUCCESS) return;
|
||||
else if($res['status'] == self::STATUS_FAILURE) {
|
||||
// note: Indokargo error message can be array or string
|
||||
$errorMessage = $res['error']['error_message'];
|
||||
if(is_array($errorMessage)) throw ValidationException::withMessages($errorMessage);
|
||||
else throw new \Exception($errorMessage);
|
||||
}
|
||||
else {
|
||||
throw new \Exception("Indokargo status is not valid (ik status = $status)" );
|
||||
}
|
||||
}
|
||||
//-- END UTILITIES
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
public static function createTVAddress(Request $request, int $tvFk, int $lastSeq = 0) {
|
||||
$seq = $lastSeq + 1;
|
||||
|
||||
/**
|
||||
* local id = TV FK, partnerId = ik_address_id
|
||||
* Why not new tv request id as local_id?
|
||||
* - New Tv request data will be deleted after TV data is inserted into the local DB
|
||||
*/
|
||||
$stsLog = new StsLog();
|
||||
$stsLog->partner = StsLog::PARTNER_INDOKARGO;
|
||||
$stsLog->is_outgoing = false;
|
||||
$stsLog->module = StsLog::MODULE_TV;
|
||||
$stsLog->service_name = StsLog::SERVICE_CREATE_TV_ADDRESS;
|
||||
$stsLog->local_id = $tvFk;
|
||||
$stsLog->partner_id = null;
|
||||
$stsLog->seq = $seq;
|
||||
$stsLog->request_data = $request->all();
|
||||
$stsLog->request_time = Carbon::now();
|
||||
|
||||
try {
|
||||
$request->validate(['code' => 'required|string']);
|
||||
|
||||
$result = Http::indokargo()->post('tv/address/create', $request->all());
|
||||
$res = $result->throw()->json();
|
||||
|
||||
// update stsLog
|
||||
$stsLog->response_data = $res;
|
||||
$stsLog->response_time = Carbon::now();
|
||||
|
||||
self::_checkIkResponse($res);
|
||||
|
||||
$ikAddress = $res['data']['0'];
|
||||
$ikAddressId = $ikAddress['id'];
|
||||
$stsLog->partner_id = $ikAddressId;
|
||||
|
||||
// check ik address id is exist (almost impossible to happen, 0.01%)
|
||||
$isDuplicateIkAddressId = TV::where([
|
||||
['ik_address_id', '=', $ikAddressId],
|
||||
['id', '!=', $tvFk]
|
||||
])->first();
|
||||
if($isDuplicateIkAddressId) throw new \Exception("IK Address ID Already exist in current db ($ikAddressId)");
|
||||
|
||||
DB::beginTransaction();
|
||||
$tv = Tv::findOrFail($tvFk);
|
||||
$tv->ik_address_id = $ikAddressId;
|
||||
$tv->save();
|
||||
|
||||
$stsLog->result = StsLog::STATUS_SUCCESS;
|
||||
$stsLog->save();
|
||||
DB::commit();
|
||||
return JSONResponse::Success(['is_warning' => false, 'message' => 'Success To Save Data']);
|
||||
} catch(ConnectionException $e) {
|
||||
// if error cause by connection error, try again later
|
||||
$stsLog->error_info = [
|
||||
'message' => $e->getMessage(),
|
||||
'errors' => $e->getTrace()
|
||||
];
|
||||
$stsLog->result = StsLog::STATUS_FAILED;
|
||||
$stsLog->is_retry = true;
|
||||
$stsLog->save();
|
||||
return JSONResponse::Success(['is_warning' => true,
|
||||
'message' => "Failed to sync data with indokargo data, don't worry, we will sync data later"]);
|
||||
} catch(\Throwable $th) {
|
||||
DB::rollBack();
|
||||
$stsLog->error_info = [
|
||||
'message' => $th->getMessage(),
|
||||
'errors' => $th->getTrace()
|
||||
];
|
||||
$stsLog->result = StsLog::STATUS_FAILED;
|
||||
$stsLog->save();
|
||||
throw $th;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\api\superadmin\tv;
|
||||
|
||||
use App\Helper\DatabaseHelper;
|
||||
use App\Helper\JSONResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\NewTvRequest;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class NewTvRequestController extends Controller {
|
||||
public function init(Request $request) {
|
||||
NewTvRequest::deleteExpiredRequests();
|
||||
$request->validate([
|
||||
'perPage' => 'nullable|integer|min:1',
|
||||
...DatabaseHelper::getOrderBysValidations(),
|
||||
'search' => DatabaseHelper::getSearchValidation()
|
||||
]);
|
||||
|
||||
$newTvRequests = NewTvRequest::addColumnCanApprove()
|
||||
->addColumnCanReject()
|
||||
->multiSearch($request->search, ['code'])
|
||||
->multiOrderBy($request->orderBys, 'created_at desc')
|
||||
->paginate($request->perPage ?? 10);
|
||||
|
||||
return JSONResponse::Success(['data' => $newTvRequests ]);
|
||||
}
|
||||
|
||||
public function approve(Request $request) { return NewTvRequest::approveFromRequest($request); }
|
||||
public function reject(Request $request) { return NewTvRequest::rejectFromRequest($request); }
|
||||
}
|
||||
@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Helper\JSONResponse;
|
||||
use App\Helper\STS\Indokargo;
|
||||
use App\Helper\Traits\Models\CanMultiOrderBy;
|
||||
use App\Helper\Traits\Models\CanMultiSearch;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class NewTvRequest extends Model {
|
||||
use HasFactory;
|
||||
use CanMultiSearch;
|
||||
use CanMultiOrderBy;
|
||||
|
||||
protected $table = 'new_tv_requests';
|
||||
protected $casts = ['device_info'=>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
|
||||
//------------------------------------------------------------
|
||||
}
|
||||
Loading…
Reference in New Issue