Compare commits
28 Commits
aee6d9440c
...
cfea605fc1
| Author | SHA1 | Date |
|---|---|---|
|
|
cfea605fc1 | 1 year ago |
|
|
e2ab453d66 | 1 year ago |
|
|
2ed57016bc | 1 year ago |
|
|
3ff470bc55 | 1 year ago |
|
|
3322055ac5 | 1 year ago |
|
|
163d5a0486 | 1 year ago |
|
|
56384c1fa9 | 1 year ago |
|
|
b82fb64dd3 | 1 year ago |
|
|
22f99b29fa | 1 year ago |
|
|
52b7e91405 | 1 year ago |
|
|
eee7c263ab | 1 year ago |
|
|
d50cde1189 | 1 year ago |
|
|
9ae7e9f7b3 | 1 year ago |
|
|
363f11136e | 1 year ago |
|
|
b6e3edecde | 2 years ago |
|
|
2c1a415979 | 2 years ago |
|
|
158106c758 | 2 years ago |
|
|
d947df81d3 | 2 years ago |
|
|
7118fea237 | 2 years ago |
|
|
d1c4f39591 | 2 years ago |
|
|
e2e6c2b6f8 | 2 years ago |
|
|
cbbe612658 | 2 years ago |
|
|
5e46b20720 | 2 years ago |
|
|
4b56d762f6 | 2 years ago |
|
|
fb281607d1 | 2 years ago |
|
|
546df1abf6 | 2 years ago |
|
|
2a7a0b32f3 | 2 years ago |
|
|
4bde317a23 | 2 years ago |
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Helper\Sts\Indokargo;
|
||||||
|
use App\Models\StsLog;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class StsReschedule extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'sts:reschedule';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Resschedule failed sts to sts data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle(): void {
|
||||||
|
$sleep = 30; // 30 second
|
||||||
|
while(true) {
|
||||||
|
$this->info('---------------------------');
|
||||||
|
$this->info('reschedule sts:' . Carbon::now()->toDateTimeString());
|
||||||
|
$this->info('---------------------------');
|
||||||
|
|
||||||
|
// get reschedu;e sts logs
|
||||||
|
$success = 0;
|
||||||
|
$failed = 0;
|
||||||
|
$rescheduleStsLogs = StsLog::where(['is_retry' => true])->get();
|
||||||
|
foreach($rescheduleStsLogs as $rescheduleStsLog) {
|
||||||
|
try {
|
||||||
|
$partner = $rescheduleStsLog->partner;
|
||||||
|
$module = $rescheduleStsLog->module;
|
||||||
|
$serviceName = $rescheduleStsLog->service_name;
|
||||||
|
$request = new Request((array) $rescheduleStsLog->request_data ?? []);
|
||||||
|
$localId = $rescheduleStsLog->local_id;
|
||||||
|
$partnerId = $rescheduleStsLog->partner_id;
|
||||||
|
$lastSeq = $rescheduleStsLog->seq;
|
||||||
|
|
||||||
|
if($partner == StsLog::PARTNER_INDOKARGO) {
|
||||||
|
if($module == StsLog::MODULE_TV) {
|
||||||
|
if($serviceName == StsLog::SERVICE_CREATE_TV_ADDRESS) {
|
||||||
|
Indokargo::createTVAddress($request, $localId, $lastSeq);
|
||||||
|
} else if($serviceName == StsLog::SERVICE_UPDATE_TV_ADDRESS) {
|
||||||
|
Indokargo::updateTVAddress($request, $localId, $partnerId, $lastSeq);
|
||||||
|
} else if($serviceName == StsLog::SERVICE_CHANGE_STATUS_TV_ADDRESS) {
|
||||||
|
Indokargo::changeStatusAddress($request, $localId, $partnerId, $lastSeq);
|
||||||
|
} else {
|
||||||
|
throw new \Exception("Service name '$partner' > '$module' > '$serviceName' not found service");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new \Exception("Module name '$partner' > '$module' not found service");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new \Exception("Partner name '$partner' not found service");
|
||||||
|
}
|
||||||
|
$success++;
|
||||||
|
} catch(\Throwable $th) {
|
||||||
|
$failed++;
|
||||||
|
$this->info("stsLog id: ". $rescheduleStsLog->id . " => " . $th->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save all retry request is retry false
|
||||||
|
$rescheduleStsLogIds = $rescheduleStsLogs->pluck('id')->toArray();
|
||||||
|
StsLog::whereIn('id', $rescheduleStsLogIds)->update(['is_retry' => false]);
|
||||||
|
|
||||||
|
$this->info('---------------------------');
|
||||||
|
$this->info("result: $success success, $failed failed" );
|
||||||
|
$this->info("Sleep in $sleep seconds" );
|
||||||
|
$this->info('---------------------------');
|
||||||
|
sleep($sleep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Helper\Frontend;
|
||||||
|
|
||||||
|
use App\Helper\JSONResponse;
|
||||||
|
use App\Models\Tv;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note:
|
||||||
|
* if any of frontend component need specific api query / data specific.
|
||||||
|
* Please add function to get data here.
|
||||||
|
*
|
||||||
|
* But, if the parent component still needs to pass the url to the
|
||||||
|
* child component, the url api can be placed in the app/Http/Controllers/api/superadmin/GeneralController
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ApiUtilities {
|
||||||
|
|
||||||
|
// for components/app/tv/button/excel.vue
|
||||||
|
public static function tvExcel(Request $request) {
|
||||||
|
$request->validate(['a' => 'nullable|string']);
|
||||||
|
|
||||||
|
switch($request->a) {
|
||||||
|
case 'excelTemplate':
|
||||||
|
return Tv::getExcelTemplate();
|
||||||
|
break;
|
||||||
|
case 'validateData':
|
||||||
|
$tvCodes = $request->tvCodes ?? [];
|
||||||
|
$tvs = $request->tvs ?? [];
|
||||||
|
$oValidation = TV::validateExcel($tvs, $tvCodes);
|
||||||
|
return JSONResponse::Success(['oValidation' => $oValidation]);
|
||||||
|
break;
|
||||||
|
case 'uploadExcel':
|
||||||
|
$tvCodes = $request->tvCodes ?? [];
|
||||||
|
$tvs = $request->tvs ?? [];
|
||||||
|
$oValidation = TV::validateExcel($tvs, $tvCodes);
|
||||||
|
$result = TV::uploadExcel($tvs, $oValidation, $request->user());
|
||||||
|
return JSONResponse::Success($result);
|
||||||
|
break;
|
||||||
|
case 'exportData':
|
||||||
|
return Tv::getExportData($request);
|
||||||
|
break;
|
||||||
|
case 'excelDetail':
|
||||||
|
return Tv::getExcelDetail($request);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
throw new \Exception('Invalid Request Command');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@ -0,0 +1,180 @@
|
|||||||
|
<?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)" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static function _HttpTransaction(StsLog $stsLog, $callback) {
|
||||||
|
try {
|
||||||
|
return $callback();
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-- 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 = true;
|
||||||
|
$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();
|
||||||
|
|
||||||
|
return self::_HttpTransaction($stsLog, function() use($tvFk, $request, $stsLog) {
|
||||||
|
$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']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateTVAddress(Request $request, int $tvFk, String $ikAddressId, int $lastSeq = 0) {
|
||||||
|
$seq = $lastSeq + 1;
|
||||||
|
|
||||||
|
$request->merge(['ik_address_id' => $ikAddressId]);
|
||||||
|
$stsLog = new StsLog();
|
||||||
|
$stsLog->partner = StsLog::PARTNER_INDOKARGO;
|
||||||
|
$stsLog->is_outgoing = true;
|
||||||
|
$stsLog->module = StsLog::MODULE_TV;
|
||||||
|
$stsLog->service_name = StsLog::SERVICE_UPDATE_TV_ADDRESS;
|
||||||
|
$stsLog->local_id = $tvFk;
|
||||||
|
$stsLog->partner_id = $ikAddressId;
|
||||||
|
$stsLog->seq = $seq;
|
||||||
|
$stsLog->request_data = $request->all();
|
||||||
|
$stsLog->request_time = Carbon::now();
|
||||||
|
|
||||||
|
return self::_HttpTransaction($stsLog, function() use($stsLog, $request) {
|
||||||
|
$request->validate(['code' => 'required|string', 'ik_address_id' => 'required|string']);
|
||||||
|
$result = Http::indokargo()->post('tv/address/update-tv', $request->all());
|
||||||
|
$res = $result->throw()->json();
|
||||||
|
|
||||||
|
// update stsLog
|
||||||
|
$stsLog->response_data = $res;
|
||||||
|
$stsLog->response_time = Carbon::now();
|
||||||
|
self::_checkIkResponse($res);
|
||||||
|
$stsLog->result = StsLog::STATUS_SUCCESS;
|
||||||
|
$stsLog->save();
|
||||||
|
DB::commit();
|
||||||
|
return JSONResponse::Success(['message' => "Success to save data"]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function changeStatusAddress(Request $request, int $tvFk, String $ikAddressId, int $lastSeq = 0) {
|
||||||
|
$seq = $lastSeq + 1;
|
||||||
|
|
||||||
|
$request->merge(['ik_address_id' => $ikAddressId]);
|
||||||
|
$stsLog = new StsLog();
|
||||||
|
$stsLog->partner = StsLog::PARTNER_INDOKARGO;
|
||||||
|
$stsLog->is_outgoing = true;
|
||||||
|
$stsLog->module = StsLog::MODULE_TV;
|
||||||
|
$stsLog->service_name = StsLog::SERVICE_CHANGE_STATUS_TV_ADDRESS;
|
||||||
|
$stsLog->local_id = $tvFk;
|
||||||
|
$stsLog->partner_id = $request->ik_address_id;
|
||||||
|
$stsLog->seq = $seq;
|
||||||
|
$stsLog->request_data = $request->all();
|
||||||
|
$stsLog->request_time = Carbon::now();
|
||||||
|
|
||||||
|
return self::_HttpTransaction($stsLog, function() use($stsLog, $request) {
|
||||||
|
$request->validate(['ik_address_id' => 'required|string', 'is_active'=> 'required|boolean']);
|
||||||
|
$result = Http::indokargo()->post('tv/address/change-status', $request->all());
|
||||||
|
$res = $result->throw()->json();
|
||||||
|
|
||||||
|
// update stsLog
|
||||||
|
$stsLog->response_data = $res;
|
||||||
|
$stsLog->response_time = Carbon::now();
|
||||||
|
self::_checkIkResponse($res);
|
||||||
|
$stsLog->result = StsLog::STATUS_SUCCESS;
|
||||||
|
$stsLog->save();
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
return JSONResponse::Success(['is_warning' => false, 'message' => 'Success To Change Status']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\api\mobile;
|
||||||
|
|
||||||
|
use App\Helper\JSONResponse;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\ApkUpdate;
|
||||||
|
use App\Models\NewTvRequest;
|
||||||
|
use App\Models\Tv;
|
||||||
|
use App\Models\VideoUpdate;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class TvController extends Controller {
|
||||||
|
public function newRequest(Request $request) {
|
||||||
|
return NewTvRequest::checkOrCreateFromRequest($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkUpdate(Request $request) {
|
||||||
|
$request->validate(['id' => 'nullable|integer',
|
||||||
|
'apk_version_code' => 'required|integer',
|
||||||
|
'apk_version_name' => 'required|string']);
|
||||||
|
|
||||||
|
$tv = null;
|
||||||
|
$latestApkUpdate = null;
|
||||||
|
$latestVideoUpdate = null;
|
||||||
|
if($request->id) {
|
||||||
|
$tv = Tv::find($request->id);
|
||||||
|
$tv->last_connected_at = now();
|
||||||
|
$tv->apk_version_code = $request->apk_version_code;
|
||||||
|
$tv->apk_version_name = $request->apk_version_name;
|
||||||
|
$tv->save();
|
||||||
|
$latestApkUpdate = ApkUpdate::getLatest();
|
||||||
|
$latestVideoUpdate = VideoUpdate::getLatestSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSONResponse::Success(['tv' => $tv, 'latestApkUpdate' => $latestApkUpdate, 'latestVideoUpdate' => $latestVideoUpdate]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\api\superadmin;
|
||||||
|
|
||||||
|
use App\Helper\JSONResponse;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Tv;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class GeneralController extends Controller {
|
||||||
|
public function tvSearch(Request $request) {
|
||||||
|
$request->validate(['search' => 'nullable|string']);
|
||||||
|
$tvs = Tv::multiSearch($request->search, ['code'])->orderBy('code', 'asc')->limit(10)->get();
|
||||||
|
return JSONResponse::Success(['tvs' => $tvs ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?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::with('tv')
|
||||||
|
->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,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\api\superadmin\tv;
|
||||||
|
|
||||||
|
use App\Helper\DatabaseHelper;
|
||||||
|
use App\Helper\Frontend\ApiUtilities;
|
||||||
|
use App\Helper\JSONResponse;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\ApkUpdate;
|
||||||
|
use App\Models\Tv;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class TvController extends Controller {
|
||||||
|
public function init(Request $request) {
|
||||||
|
$request->validate([
|
||||||
|
'perPage' => 'nullable|integer|min:1',
|
||||||
|
'isFirstTime' => 'nullable|boolean',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$additionalData = [];
|
||||||
|
if($request->isFirstTime) {
|
||||||
|
$additionalData['apkUpdates'] = ApkUpdate::select('version_code', 'version_name')
|
||||||
|
->orderBy('version_code', 'desc')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
$newTvRequests = TV::validateAndGetEloquentFromRequest($request)->paginate($request->perPage ?? 10);
|
||||||
|
return JSONResponse::Success(['data' => $newTvRequests, ...$additionalData ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function excel(Request $request) { return ApiUtilities::tvExcel($request); }
|
||||||
|
public function update(Request $request) { return Tv::updateFromRequest($request); }
|
||||||
|
public function changeStatus(Request $request) { return Tv::changeStatusFromRequest($request); }
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class TvAppInfo extends Model {
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'tv_app_infos';
|
||||||
|
protected $primaryKey = 'tv_fk';
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO RELATIONSHIP
|
||||||
|
/// BELONGS TO
|
||||||
|
public function tv(): BelongsTo { return $this->belongsTo(Tv::class, 'tv_fk', 'id'); }
|
||||||
|
// -- END RELATED TO RELATIONSHIP
|
||||||
|
//------------------------------------------------------------
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class TvConnectLog extends Model {
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO RELATIONSHIP
|
||||||
|
/// BELONGS TO
|
||||||
|
public function tv(): BelongsTo { return $this->belongsTo(Tv::class, 'tv_fk', 'id'); }
|
||||||
|
// -- END RELATED TO RELATIONSHIP
|
||||||
|
//------------------------------------------------------------
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class TvSession extends Model {
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO RELATIONSHIP
|
||||||
|
/// BELONGS TO
|
||||||
|
public function tv(): BelongsTo { return $this->belongsTo(Tv::class, 'tv_fk', 'id'); }
|
||||||
|
// -- END RELATED TO RELATIONSHIP
|
||||||
|
//------------------------------------------------------------
|
||||||
|
}
|
||||||
@ -0,0 +1,225 @@
|
|||||||
|
<?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('approved_at');
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
public function scopeAddColumnCanReject(Builder $query) {
|
||||||
|
$query->withCount(['self as can_reject' => function($q) {
|
||||||
|
$q->whereNull('approved_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rule:
|
||||||
|
* 1. if it has not been approved for more than the expiry date, deleted it
|
||||||
|
* 2. if it has been approved & has been responded more than expiry date, delete it
|
||||||
|
* - case: when has been approved, but intenet connection missing, how can device know
|
||||||
|
* that the new request tv has been approved?
|
||||||
|
*/
|
||||||
|
private static function _getMaxExpiredTime() :Carbon { return Carbon::now()->subHour(); }
|
||||||
|
public static function deleteExpiredRequests() {
|
||||||
|
$expiredTime = self::_getMaxExpiredTime()->toDateTimeString();
|
||||||
|
NewTvRequest::where(function($q) use ($expiredTime) {
|
||||||
|
$q->whereNull('approved_at')->where('created_at', '<=', $expiredTime);
|
||||||
|
})->orWhere(function($q) use ($expiredTime) {
|
||||||
|
$q->where('responded_at', '<=', $expiredTime );
|
||||||
|
})->delete();
|
||||||
|
}
|
||||||
|
// -- END RELATED TO DATA FUNCTION
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO FROM REQUEST FUNCTION
|
||||||
|
private static function _checkOrCreateResponse(NewTvRequest $newTvReq) {
|
||||||
|
if($newTvReq->approved_at) {
|
||||||
|
// make sure waiting tv_device responded before deleted
|
||||||
|
if(empty($newTvReq->responded_at)) {
|
||||||
|
$newTvReq->responded_at = now();
|
||||||
|
$newTvReq->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSONResponse::Success([
|
||||||
|
'message' => 'approved',
|
||||||
|
'new_tv_request' => $newTvReq,
|
||||||
|
'tv' => $newTvReq->tv
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSONResponse::Success([
|
||||||
|
'message' => 'not activate',
|
||||||
|
'new_tv_request' => $newTvReq,
|
||||||
|
'tv' => null
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
public static function checkOrCreateFromRequest(Request $request) {
|
||||||
|
$request->validate([
|
||||||
|
'id' => 'nullable|string|required_with:code|integer',
|
||||||
|
'code' => 'nullable|string|required_with:id',
|
||||||
|
'device_info' => 'required|array'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if(!empty($request->id)) {
|
||||||
|
$checkTvReq = NewTvRequest::where('code', $request->code)->find($request->id);
|
||||||
|
if($checkTvReq) return self::_checkOrCreateResponse($checkTvReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
$newTvReq = new self;
|
||||||
|
$newTvReq->code = self::_generateRandomCode();
|
||||||
|
$newTvReq->device_info = $request->device_info;
|
||||||
|
$newTvReq->save();
|
||||||
|
return self::_checkOrCreateResponse($newTvReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function approveFromRequest(Request $request) {
|
||||||
|
$request->validate([
|
||||||
|
'id' => 'required|integer|exists:App\Models\NewTvRequest',
|
||||||
|
'tv' => 'nullable|array',
|
||||||
|
'existingTv' => 'nullable|array',
|
||||||
|
'action' => 'required|string',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$newTvReq = NewTvRequest::addColumnCanApprove()
|
||||||
|
->findOrFail($request->id);
|
||||||
|
if(!$newTvReq->can_approve) throw new \Exception('Cannot approve current request');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$tv = null;
|
||||||
|
if($request->action == 'existing') {
|
||||||
|
$existingTvRequest = new Request($request->existingTv);
|
||||||
|
$existingTvRequest->validate([
|
||||||
|
'id' => 'required|integer|exists:App\Models\Tv',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tv = TV::findOrFail($existingTvRequest->id);
|
||||||
|
} else if ($request->action == 'new') {
|
||||||
|
$tvRequest = new Request($request->tv);
|
||||||
|
if($tvRequest->code) $tvRequest->merge(['code' => strtoupper($tvRequest->code)]);
|
||||||
|
|
||||||
|
$tvRequest->validate([
|
||||||
|
'company_name' => 'nullable|string',
|
||||||
|
'address' => 'nullable|string',
|
||||||
|
'street_address' => 'nullable|string',
|
||||||
|
'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',
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
$tv = new Tv();
|
||||||
|
$tv->code = TV::generateUniqueCode();
|
||||||
|
$tv->company_name = $tvRequest->company_name;
|
||||||
|
$tv->address = $tvRequest->address;
|
||||||
|
$tv->street_address = $tvRequest->street_address;
|
||||||
|
$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->installed_at = now();
|
||||||
|
$tv->save();
|
||||||
|
TVLog::historyCreate($request->user(), $tv->id, $tv);
|
||||||
|
|
||||||
|
// TODO: waiting execution until update from ops
|
||||||
|
// NEED TO REFACTOR (cause by add existing tv code)
|
||||||
|
// // try to sys_to_sys with indokargo
|
||||||
|
// DB::commit();
|
||||||
|
// $jsonResponse = Indokargo::createTVAddress($tvRequest, $tv->id);
|
||||||
|
// return $jsonResponse;
|
||||||
|
} else {
|
||||||
|
throw new \Exception('INVALID FORM ACTION');
|
||||||
|
}
|
||||||
|
|
||||||
|
$newTvReq->approved_at = now();
|
||||||
|
$newTvReq->tv_fk = $tv->id;
|
||||||
|
$newTvReq->save();
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
return JSONResponse::Success(['message'=>'Success to approve new tv request']);
|
||||||
|
} 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 ]);
|
||||||
|
}
|
||||||
|
// -- END RELATED TO FROM REQUEST FUNCTION
|
||||||
|
//------------------------------------------------------------
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||||
|
|
||||||
|
class Outlet extends Model {
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'outlets';
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO MIGRATION
|
||||||
|
/// HAS ONE
|
||||||
|
public function tv_app_info(): HasOne { return $this->hasOne(Tv::class, 'outlet_fk', 'id'); }
|
||||||
|
// -- END RELATED TO MIGRATION2
|
||||||
|
//------------------------------------------------------------
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class StsLog extends Model {
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'sts_logs';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'partner',
|
||||||
|
'is_outgoing',
|
||||||
|
'module',
|
||||||
|
'service_name',
|
||||||
|
'local_id',
|
||||||
|
'partner_id',
|
||||||
|
'seq',
|
||||||
|
'result',
|
||||||
|
'error_info',
|
||||||
|
'request_data',
|
||||||
|
'request_time',
|
||||||
|
'response_data',
|
||||||
|
'response_time',
|
||||||
|
'is_retry',
|
||||||
|
'created_at',
|
||||||
|
'updated_at'
|
||||||
|
];
|
||||||
|
protected $casts = [
|
||||||
|
'error_info' => AsArrayObject::class,
|
||||||
|
'request_data' => AsArrayObject::class,
|
||||||
|
'response_data' => AsArrayObject::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
const STATUS_SUCCESS = 'success';
|
||||||
|
const STATUS_FAILED = 'failed';
|
||||||
|
const STATUS_WARNING = 'warning';
|
||||||
|
|
||||||
|
const PARTNER_INDOKARGO = 'indokargo';
|
||||||
|
|
||||||
|
// related to indokargo
|
||||||
|
const MODULE_TV = 'tv';
|
||||||
|
const SERVICE_CREATE_TV_ADDRESS = 'create-tv-address';
|
||||||
|
const SERVICE_UPDATE_TV_ADDRESS = 'update-tv-address';
|
||||||
|
const SERVICE_CHANGE_STATUS_TV_ADDRESS = 'change-statustv-address';
|
||||||
|
}
|
||||||
@ -0,0 +1,372 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Helper\Common;
|
||||||
|
use App\Helper\DatabaseHelper;
|
||||||
|
use App\Helper\JSONResponse;
|
||||||
|
use App\Helper\STS\Indokargo;
|
||||||
|
use App\Helper\Traits\Models\CanMultiOrderBy;
|
||||||
|
use App\Helper\Traits\Models\CanMultiSearch;
|
||||||
|
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\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
|
class Tv extends Model {
|
||||||
|
use HasFactory;
|
||||||
|
use CanMultiSearch;
|
||||||
|
use CanMultiOrderBy;
|
||||||
|
|
||||||
|
protected $table = 'tvs';
|
||||||
|
protected $hidden = ['ik_cust_id', 'ik_address_id'];
|
||||||
|
protected $casts = ['device_info'=>AsArrayObject::class];
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO RELATIONSHIP
|
||||||
|
/// HAS ONE
|
||||||
|
public function new_tv_request(): HasOne { return $this->hasOne(NewTvRequest::class, 'tv_fk', 'id'); }
|
||||||
|
public function tv_app_info(): HasOne { return $this->hasOne(TvAppInfo::class, 'tv_fk', 'id'); }
|
||||||
|
/// HAS MANY
|
||||||
|
public function tv_connect_logs(): HasMany { return $this->hasMany(TvConnectLog::class, 'tv_fk', 'id'); }
|
||||||
|
public function tv_sessions(): HasMany { return $this->hasMany(TvSession::class, 'tv_fk', 'id'); }
|
||||||
|
/// BELONGS TO
|
||||||
|
public function outlet(): BelongsTo { return $this->belongsTo(Outlet::class, 'outlet_fk', 'id'); }
|
||||||
|
// -- END RELATED TO RELATIONSHIP
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO DATA FUNCTION
|
||||||
|
public static function generateUniqueCode() {
|
||||||
|
// init
|
||||||
|
$countSuffixDigit = 5;
|
||||||
|
date_default_timezone_set('Asia/Jakarta');
|
||||||
|
$prefixCode = 'TV' . date('Ym');
|
||||||
|
|
||||||
|
// try to get unique suffix
|
||||||
|
$uniqueCode = '';
|
||||||
|
while(true) {
|
||||||
|
$suffixCode = strtoupper(Str::random($countSuffixDigit));
|
||||||
|
$uniqueCode = $prefixCode . $suffixCode;
|
||||||
|
$isUnique = TV::where('code', $uniqueCode)->first();
|
||||||
|
if(!$isUnique) break;
|
||||||
|
}
|
||||||
|
return $uniqueCode;
|
||||||
|
}
|
||||||
|
// -- END RELATED TO DATA FUNCTION
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO REQUEST
|
||||||
|
public static function validateAndGetEloquentFromRequest(Request $request) {
|
||||||
|
$request->validate([
|
||||||
|
...DatabaseHelper::getOrderBysValidations(),
|
||||||
|
'search' => DatabaseHelper::getSearchValidation(),
|
||||||
|
'apkVersionCode' => 'nullable|integer',
|
||||||
|
'tz' => 'required|timezone',
|
||||||
|
'isActive' => 'nullable|boolean',
|
||||||
|
'installedAt' => 'nullable|array',
|
||||||
|
'installedAt.from' => 'nullable|date',
|
||||||
|
'installedAt.to' => 'nullable|date',
|
||||||
|
'lastConnectedAt' => 'nullable|array',
|
||||||
|
'lastConnectedAt.from' => 'nullable|date',
|
||||||
|
'lastConnectedAt.to' => 'nullable|date',
|
||||||
|
'lastConnectedDay' => 'nullable|int'
|
||||||
|
]);
|
||||||
|
Common::setTimezone($request->tz);
|
||||||
|
|
||||||
|
return Tv::when($request->isActive != null, function($q) use($request) {
|
||||||
|
$q->where('is_active', $request->isActive);
|
||||||
|
})
|
||||||
|
->when($request->apkVersionCode, function($q, $apkVersionCode) {
|
||||||
|
$q->where('apk_version_code', $apkVersionCode);
|
||||||
|
})
|
||||||
|
->when($request->installedAt['from'] ?? '', function($q, $from) {
|
||||||
|
$q->where(DB::raw('DATE(installed_at)'), '>=', $from);
|
||||||
|
})
|
||||||
|
->when($request->installedAt['to'] ?? '', function($q, $to) {
|
||||||
|
$q->where(DB::raw('DATE(installed_at)'), '<=', $to);
|
||||||
|
})
|
||||||
|
->when($request->lastConnectedAt['from'] ?? '', function($q, $from) {
|
||||||
|
$q->where(DB::raw('DATE(last_connected_at)'), '>=', $from);
|
||||||
|
})
|
||||||
|
->when($request->lastConnectedAt['to'] ?? '', function($q, $to) {
|
||||||
|
$q->where(DB::raw('DATE(last_connected_at)'), '<=', $to);
|
||||||
|
})
|
||||||
|
->multiSearch($request->search, ['code', 'company_name'])
|
||||||
|
->multiOrderBy($request->orderBys, 'created_at desc');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateFromRequest(Request $request) {
|
||||||
|
if($request->code) $request->merge(['code' => strtoupper($request->code)]);
|
||||||
|
$request->validate([
|
||||||
|
'id' => 'required|integer|exists:App\Models\Tv',
|
||||||
|
'code' => ['required','string',Rule::unique('tvs', 'code')
|
||||||
|
->when($request->id, function($q, $id) { $q->whereNot('id', $id);})],
|
||||||
|
'company_name' => 'nullable|string',
|
||||||
|
'address' => 'nullable|string',
|
||||||
|
'street_address' => 'nullable|string',
|
||||||
|
'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',
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
$tv = TV::findOrFail($request->id);
|
||||||
|
$oldTv = $tv->replicate();
|
||||||
|
$tv->company_name = $request->company_name;
|
||||||
|
$tv->address = $request->address;
|
||||||
|
$tv->street_address = $request->street_address;
|
||||||
|
$tv->code = $request->code;
|
||||||
|
$tv->col1 = $request->col1;
|
||||||
|
$tv->col2 = $request->col2;
|
||||||
|
$tv->col3 = $request->col3;
|
||||||
|
$tv->col4 = $request->col4;
|
||||||
|
$tv->col5 = $request->col5;
|
||||||
|
$tv->col6 = $request->col6;
|
||||||
|
$tv->col7 = $request->col7;
|
||||||
|
$tv->col8 = $request->col8;
|
||||||
|
$tv->col9 = $request->col9;
|
||||||
|
$tv->col10 = $request->col10;
|
||||||
|
$tv->notes = $request->notes;
|
||||||
|
$tv->update();
|
||||||
|
|
||||||
|
TvLog::historyUpdate($request->user(), $tv->id, $oldTv, $tv);
|
||||||
|
DB::commit();
|
||||||
|
return JSONResponse::Success(['message'=>'Success to update tv data']);
|
||||||
|
|
||||||
|
// TODO: waiting from ops workflow (Dont forget to resync co_name, address, street address in ik)
|
||||||
|
// // try to sys_to_sys with indokargo
|
||||||
|
// $jsonResponse = Indokargo::updateTVAddress($request, $tv->id, $tv->ik_address_id);
|
||||||
|
// DB::commit();
|
||||||
|
// return $jsonResponse;
|
||||||
|
} catch(\Throwable $th) {
|
||||||
|
DB::rollback();
|
||||||
|
throw $th;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public static function changeStatusFromRequest(Request $request) {
|
||||||
|
$request->validate(['id' => 'required|integer|exists:App\Models\TV,id']);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
$tv = Tv::findOrFail($request->id);
|
||||||
|
$tv->is_active = !$tv->is_active;
|
||||||
|
$tv->save();
|
||||||
|
DB::commit();
|
||||||
|
return JSONResponse::Success(['message'=>'Success to change tv status']);
|
||||||
|
|
||||||
|
// TODO: waiting from ops workflow (Dont forget to resync co_name, address, street address in ik)
|
||||||
|
// // try to sys_to_sys with indokargo
|
||||||
|
// $jsonResponse = Indokargo::changeStatusAddress(new Request(['is_active' => $tv->is_active]),
|
||||||
|
// $tv->id, $tv->ik_address_id);
|
||||||
|
// DB::commit();
|
||||||
|
// return $jsonResponse;
|
||||||
|
} catch(\Throwable $th) {
|
||||||
|
DB::rollback();
|
||||||
|
throw $th;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// -- END RELATED TO REQUEST
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// -- RELATED TO EXCEL
|
||||||
|
public static function getExcelDetail(Request $request) {
|
||||||
|
return JSONResponse::Success(['rows' => TV::validateAndGetEloquentFromRequest($request)->get()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- RELATED TO EXPORT IMPORT
|
||||||
|
const EXCEL_SUCCESS = 'success';
|
||||||
|
const EXCEL_FAILED = 'failed';
|
||||||
|
const EXCEL_NO_CHANGE = 'no_change';
|
||||||
|
const EXCEL_UPDATE = 'update';
|
||||||
|
const EXCEL_TEMPLATE_COLS = ['code', 'company_name', 'address', 'street_address', 'notes',
|
||||||
|
'col1', 'col2', 'col3', 'col4', 'col5',
|
||||||
|
'col6', 'col7', 'col8', 'col9', 'col10',
|
||||||
|
'is_active'];
|
||||||
|
public static function getExcelTemplate() {
|
||||||
|
$row = [];
|
||||||
|
foreach(self::EXCEL_TEMPLATE_COLS as $col) { $row[$col] = ''; }
|
||||||
|
$rows = [$row];
|
||||||
|
return JSONResponse::Success(['rows' => $rows]);
|
||||||
|
}
|
||||||
|
public static function getExportData(Request $request) {
|
||||||
|
$rows = TV::validateAndGetEloquentFromRequest($request)->get();
|
||||||
|
return JSONResponse::Success(['rows' => $rows, 'cols' => self::EXCEL_TEMPLATE_COLS]);
|
||||||
|
}
|
||||||
|
// ------ RELATED TO IMPORT
|
||||||
|
private static function _checkExcelFormat($tvRows) {
|
||||||
|
if(!$tvRows) throw new \Exception("No Data");
|
||||||
|
|
||||||
|
$firstTvRow = $tvRows[0];
|
||||||
|
if(!$firstTvRow) throw new \Exception('Column not found');
|
||||||
|
|
||||||
|
// check if excel is empty or not
|
||||||
|
$firstTvRow['row'] = null;
|
||||||
|
if(!array_filter($firstTvRow)) throw new \Exception("Excel is empty");
|
||||||
|
|
||||||
|
// check is header col is exists
|
||||||
|
$errors = [];
|
||||||
|
foreach(self::EXCEL_TEMPLATE_COLS as $col) {
|
||||||
|
if(!array_key_exists($col, $firstTvRow)) $errors[$col] = "Column $col is Required";
|
||||||
|
}
|
||||||
|
if($errors) throw ValidationException::withMessages($errors);
|
||||||
|
}
|
||||||
|
private static function _getCountTvCodes($tvRows, $tvCodes) {
|
||||||
|
if(!$tvCodes) $tvCodes = array_column($tvRows, 'code');
|
||||||
|
$tvCodes = array_map(function($code) { return DatabaseHelper::trimUpperNull($code) ?? ''; }, $tvCodes);
|
||||||
|
return array_count_values($tvCodes);
|
||||||
|
}
|
||||||
|
private static function _changeModelFromTvRow(Tv $tv, $tvRow) {
|
||||||
|
$tv->company_name = $tvRow['company_name'];
|
||||||
|
$tv->address = $tvRow['address'];
|
||||||
|
$tv->street_address = $tvRow['street_address'];
|
||||||
|
$tv->code = $tvRow['code'];
|
||||||
|
$tv->col1 = $tvRow['col1'];
|
||||||
|
$tv->col2 = $tvRow['col2'];
|
||||||
|
$tv->col3 = $tvRow['col3'];
|
||||||
|
$tv->col4 = $tvRow['col4'];
|
||||||
|
$tv->col5 = $tvRow['col5'];
|
||||||
|
$tv->col6 = $tvRow['col6'];
|
||||||
|
$tv->col7 = $tvRow['col7'];
|
||||||
|
$tv->col8 = $tvRow['col8'];
|
||||||
|
$tv->col9 = $tvRow['col9'];
|
||||||
|
$tv->col10 = $tvRow['col10'];
|
||||||
|
$tv->notes = $tvRow['notes'];
|
||||||
|
return $tv;
|
||||||
|
}
|
||||||
|
public static function validateExcel($tvRows, $tvCodes = []) {
|
||||||
|
self::_checkExcelFormat($tvRows);
|
||||||
|
$countTvCodes = self::_getCountTvCodes($tvRows, $tvCodes);
|
||||||
|
|
||||||
|
$endStatus = self::EXCEL_SUCCESS;
|
||||||
|
$results = [];
|
||||||
|
foreach($tvRows as $tvRow) {
|
||||||
|
$status = self::EXCEL_NO_CHANGE;
|
||||||
|
$message = '';
|
||||||
|
$tvRow['code'] = strtoupper($tvRow['code'] ?? '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// STEP 1: check validation
|
||||||
|
$validator = Validator::make($tvRow, [
|
||||||
|
'row' => 'required|integer',
|
||||||
|
'code' => 'required|string',
|
||||||
|
'company_name' => 'nullable|string',
|
||||||
|
'address' => 'nullable|string',
|
||||||
|
'street_address' => 'nullable|string',
|
||||||
|
'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',
|
||||||
|
]);
|
||||||
|
if($validator->fails()) {
|
||||||
|
$errors = $validator->errors()->toArray();
|
||||||
|
$messages = [];
|
||||||
|
foreach($errors as $eMessages) { $messages = array_merge($messages, $eMessages); }
|
||||||
|
throw new \Exception(implode(', ', $messages));
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP 2: check code is duplicate or not or not
|
||||||
|
$code = $tvRow['code'];
|
||||||
|
if(($countTvCodes[$code] ?? 0) > 1) throw new \Exception('Code is Duplicate in Excel');
|
||||||
|
|
||||||
|
// STEP 3: check code existing in database or not
|
||||||
|
$tvCheck = Tv::where('code', 'ilike', $code)->first();
|
||||||
|
if(!$tvCheck) throw new \Exception("TV Code '$code' not found in database");
|
||||||
|
|
||||||
|
// STEP 4: check has update data or not
|
||||||
|
$tvCheck = self::_changeModelFromTvRow($tvCheck, $tvRow);
|
||||||
|
if($tvCheck->isDirty()) {
|
||||||
|
$status = self::EXCEL_UPDATE;
|
||||||
|
$message = DatabaseHelper::compileDirtyEloquentToArrMessage($tvCheck);
|
||||||
|
}
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
$endStatus = self::EXCEL_FAILED;
|
||||||
|
$status = self::EXCEL_FAILED;
|
||||||
|
$message = $th->getMessage();
|
||||||
|
}
|
||||||
|
$results[] = ['row' => $tvRow['row'], 'status' => $status, 'message' => $message];
|
||||||
|
}
|
||||||
|
return ['status' => $endStatus, 'results' => $results];
|
||||||
|
}
|
||||||
|
public static function uploadExcel($tvRows, $oValidation, User $user) {
|
||||||
|
$validationResults = $oValidation['results'];
|
||||||
|
$countUploads = [
|
||||||
|
self::EXCEL_UPDATE => 0, self::EXCEL_NO_CHANGE => 0, self::EXCEL_FAILED => 0
|
||||||
|
];
|
||||||
|
$additionalErrors = [];
|
||||||
|
|
||||||
|
foreach($validationResults as $result) {
|
||||||
|
$validateStatus = $result['status'];
|
||||||
|
try {
|
||||||
|
switch($validateStatus) {
|
||||||
|
case self::EXCEL_FAILED:
|
||||||
|
throw new \Exception($result['message']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case self::EXCEL_UPDATE:
|
||||||
|
// get sparepart data
|
||||||
|
$idxTvRow = array_search($result['row'], array_column($tvRows, 'row'));
|
||||||
|
if($idxTvRow === false) throw new \Exception('Row Not Found');
|
||||||
|
$tvRow = $tvRows[$idxTvRow];
|
||||||
|
$tvRow['code'] = strtoupper($tvRow['code'] ?? '');
|
||||||
|
|
||||||
|
// try to upsert
|
||||||
|
DB::beginTransaction();
|
||||||
|
$tv = TV::where('code', 'ilike', $tvRow['code'])->firstOrFail();
|
||||||
|
$oldTV = $tv->replicate();
|
||||||
|
$newTv = self::_changeModelFromTvRow($tv, $tvRow);
|
||||||
|
if(!$newTv->isDirty()) throw new \Exception('No Change');
|
||||||
|
$newTv->save();
|
||||||
|
|
||||||
|
// save data log
|
||||||
|
TvLog::historyUpdateExcel($user, $newTv->id, $oldTV, $newTv);
|
||||||
|
DB::commit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case self::EXCEL_NO_CHANGE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
DB::rollBack();
|
||||||
|
$validateStatus = self::EXCEL_FAILED;
|
||||||
|
$additionalErrors[] = 'row ' . ($result['row'] ?? '-') . ' => ' . $th->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$countUploads[$validateStatus]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['countUploads' => $countUploads, 'additionalErrors' => $additionalErrors];
|
||||||
|
}
|
||||||
|
// ------ END RELATED TO IMPORT
|
||||||
|
// ---- END RELATED TO EXPORT IMPORT
|
||||||
|
// -- END RELATED TO EXCEL
|
||||||
|
//------------------------------------------------------------
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class TvLog extends Model {
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'tv_logs';
|
||||||
|
protected $hidden = ['ik_cust_id', 'ik_address_id'];
|
||||||
|
protected $casts = ['from'=>'object', 'to'=>'object'];
|
||||||
|
|
||||||
|
const TYPES = ['create', 'update', 'update-excel'];
|
||||||
|
|
||||||
|
public static function historyCreate(User $user, int $tvFk, Tv $newTv) { self::saveHistory('create', $user, $tvFk, null, $newTv); }
|
||||||
|
public static function historyUpdate(User $user, int $tvFk, Tv $oldTv, Tv $newTv) { self::saveHistory('update', $user, $tvFk, $oldTv, $newTv); }
|
||||||
|
public static function historyUpdateExcel(User $user, int $tvFk, Tv $oldTv, Tv $newTv) { self::saveHistory('update-excel', $user, $tvFk, $oldTv, $newTv); }
|
||||||
|
|
||||||
|
private static function saveHistory(String $type, ?User $user, int $tvFk, ?Tv $oldTv, ?Tv $newTv) {
|
||||||
|
if(!in_array($type, self::TYPES)) throw new \Exception("Type '$type' No Valid");
|
||||||
|
$tvLog = new TvLog();
|
||||||
|
$tvLog->tv_fk = $tvFk;
|
||||||
|
$tvLog->type = $type;
|
||||||
|
if($oldTv) {
|
||||||
|
$oldTv = $oldTv->toArray();
|
||||||
|
unset($oldTv['id']);
|
||||||
|
$tvLog->from =$oldTv;
|
||||||
|
}
|
||||||
|
if($newTv) {
|
||||||
|
$newTv = $newTv->toArray();
|
||||||
|
unset($newTv['id']);
|
||||||
|
$tvLog->to = $newTv;
|
||||||
|
}
|
||||||
|
if($user) { $tvLog->user_fk = $user->id; }
|
||||||
|
$tvLog->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
Notes:
|
||||||
|
- Auto Update app
|
||||||
|
- Auto Update video
|
||||||
|
- Laravel Sanctum
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
Notes:
|
||||||
|
- TV information & Logs
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void {
|
||||||
|
Schema::create('outlets', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('code', 50)->index();
|
||||||
|
$table->string('name', 255)->nullable()->index();
|
||||||
|
$table->string('address', 255)->nullable();
|
||||||
|
$table->string('street_address', 255)->nullable();
|
||||||
|
$table->string('phone', 50)->nullable()->index();
|
||||||
|
$table->double('lat')->default(0);
|
||||||
|
$table->double('long')->default(0);
|
||||||
|
$table->string('notes', 255)->nullable();
|
||||||
|
$table->string('country', 255);
|
||||||
|
$table->string('ik_country_id', 255);
|
||||||
|
$table->string('state', 255);
|
||||||
|
$table->string('ik_state_id', 255);
|
||||||
|
$table->string('region', 255);
|
||||||
|
$table->string('ik_region_id', 255);
|
||||||
|
$table->string('city', 255);
|
||||||
|
$table->string('ik_city_id', 255);
|
||||||
|
$table->string('zipcode', 255)->nullable();
|
||||||
|
$table->timestampTz('last_visited_at')->nullable();
|
||||||
|
$table->timestampsTz();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void {
|
||||||
|
Schema::drop('outlets');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void {
|
||||||
|
Schema::create('tvs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('code', 50)->unique();
|
||||||
|
$table->string('ik_address_id', 255)->nullable();
|
||||||
|
$table->integer('apk_version_code')->nullable();
|
||||||
|
$table->string('apk_version_name')->nullable();
|
||||||
|
$table->string('company_name')->nullable();
|
||||||
|
$table->string('address')->nullable();
|
||||||
|
$table->string('street_address')->nullable();
|
||||||
|
$table->string('col1', 255)->nullable();
|
||||||
|
$table->string('col2', 255)->nullable();
|
||||||
|
$table->string('col3', 255)->nullable();
|
||||||
|
$table->string('col4', 255)->nullable();
|
||||||
|
$table->string('col5', 255)->nullable();
|
||||||
|
$table->string('col6', 255)->nullable();
|
||||||
|
$table->string('col7', 255)->nullable();
|
||||||
|
$table->string('col8', 255)->nullable();
|
||||||
|
$table->string('col9', 255)->nullable();
|
||||||
|
$table->string('col10', 255)->nullable();
|
||||||
|
$table->string('notes', 255)->nullable();
|
||||||
|
$table->boolean('is_active')->default(true);
|
||||||
|
$table->jsonb('device_info')->nullable();
|
||||||
|
$table->timestampTz('installed_at');
|
||||||
|
$table->timestampTz('last_connected_at')->nullable();
|
||||||
|
$table->timestampsTz();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('new_tv_requests', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('code', 50);
|
||||||
|
$table->jsonb('device_info')->nullable();
|
||||||
|
$table->foreignId('tv_fk')->nullable();
|
||||||
|
$table->timestampTz('approved_at')->nullable();
|
||||||
|
$table->timestampTz('responded_at')->nullable();
|
||||||
|
$table->timestampsTz();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('tv_logs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('tv_fk');
|
||||||
|
$table->string('type');
|
||||||
|
$table->json('from')->nullable();
|
||||||
|
$table->json('to')->nullable();
|
||||||
|
$table->foreignId('user_fk')->nullable();
|
||||||
|
$table->timestampsTz();
|
||||||
|
|
||||||
|
$table->foreign('tv_fk')->references('id')->on('tvs')->cascadeOnDelete();
|
||||||
|
$table->foreign('user_fk')->references('id')->on('users');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Schema::create('tv_sessions', function (Blueprint $table) {
|
||||||
|
// $table->id();
|
||||||
|
// $table->foreignId('tv_fk')->index();
|
||||||
|
// $table->timestampTz('started_at')->index();
|
||||||
|
// $table->timestampTz('finished_at')->nullable()->index();
|
||||||
|
// $table->boolean('is_playing_video');
|
||||||
|
// $table->jsonb('current_videos')->nullable();
|
||||||
|
// $table->timestampsTz();
|
||||||
|
|
||||||
|
// $table->foreign('tv_fk')->references('id')->on('tvs');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Schema::create('tv_app_infos', function (Blueprint $table) {
|
||||||
|
// $table->foreignId('tv_fk')->unique()->index();
|
||||||
|
// $table->timestampTz('installed_at')->nullable()->index();
|
||||||
|
// $table->jsonb('current_videos')->nullable();
|
||||||
|
// $table->timestampTz('last_updated_video')->nullable()->index();
|
||||||
|
// $table->timestampsTz();
|
||||||
|
|
||||||
|
// $table->foreign('tv_fk')->references('id')->on('tvs');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Schema::create('tv_app_logs', function (Blueprint $table) {
|
||||||
|
// $table->id();
|
||||||
|
// $table->foreignId('tv_fk')->index();
|
||||||
|
// $table->string('requested_to');
|
||||||
|
// $table->string('ip', 50);
|
||||||
|
// $table->jsonb('request_data')->nullable();
|
||||||
|
// $table->enum('result', ['success', 'failed']);
|
||||||
|
// $table->jsonb('response_data')->nullable();
|
||||||
|
// $table->timestampsTz();
|
||||||
|
|
||||||
|
// $table->foreign('tv_fk')->references('id')->on('tvs');
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void {
|
||||||
|
// Schema::drop('tv_app_logs');
|
||||||
|
// Schema::drop('tv_app_infos');
|
||||||
|
// Schema::drop('tv_sessions');
|
||||||
|
Schema::drop('tv_logs');
|
||||||
|
Schema::drop('new_tv_requests');
|
||||||
|
Schema::drop('tvs');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void {
|
||||||
|
Schema::create('sts_logs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('partner', 255)->nullable();
|
||||||
|
$table->boolean('is_outgoing');
|
||||||
|
$table->string('module', 255)->nullable();
|
||||||
|
$table->string('service_name', 255)->nullable();
|
||||||
|
$table->string('local_id', 255)->nullable();
|
||||||
|
$table->string('partner_id', 255)->nullable();
|
||||||
|
$table->enum('result', ['success', 'failed', 'warning']);
|
||||||
|
$table->jsonb('error_info')->nullable();
|
||||||
|
$table->tinyInteger('seq');
|
||||||
|
$table->jsonb('request_data')->nullable();
|
||||||
|
$table->timestampTz('request_time')->nullable();
|
||||||
|
$table->jsonb('response_data')->nullable();
|
||||||
|
$table->timestampTz('response_time')->nullable();
|
||||||
|
$table->boolean('is_retry')->default('false');
|
||||||
|
$table->timestampsTz();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void {
|
||||||
|
Schema::drop('sts_logs');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void {
|
||||||
|
Schema::table('video_updates', function(Blueprint $table) {
|
||||||
|
$table->double('file_size_kb')->default(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void {
|
||||||
|
Schema::table('video_updates', function(Blueprint $table) {
|
||||||
|
$table->dropColumn('file_size_kb');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('apk_updates', function (Blueprint $table) {
|
||||||
|
$table->string('version_name', 50)->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('apk_updates', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('version_name');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,10 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\api\mobile\CheckUpdateController;
|
use App\Http\Controllers\api\mobile\CheckUpdateController;
|
||||||
|
use App\Http\Controllers\api\mobile\TvController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::controller(CheckUpdateController::class)->group(function() {
|
Route::controller(CheckUpdateController::class)->group(function() {
|
||||||
Route::post('/check-update/video-update/latest', 'videoUpdateLatest');
|
Route::post('/check-update/video-update/latest', 'videoUpdateLatest');
|
||||||
Route::post('/check-update/apk-update/latest', 'apkUpdateLatest');
|
Route::post('/check-update/apk-update/latest', 'apkUpdateLatest');
|
||||||
})
|
});
|
||||||
|
|
||||||
|
Route::controller(TvController::class)->group(function() {
|
||||||
|
Route::post('/tv/new-request', 'newRequest');
|
||||||
|
Route::post('/tv/check-update', 'checkUpdate');
|
||||||
|
});
|
||||||
?>
|
?>
|
||||||
Loading…
Reference in New Issue