| Server IP : 34.87.99.72 / Your IP : 216.73.217.31 Web Server : Apache/2.4.46 (Unix) OpenSSL/1.1.1n System : Linux zlock-bitnami-lamp-prod-v2-vm 4.19.0-16-cloud-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 User : bitnami ( 1000) PHP Version : 7.4.18 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /opt/bitnami/apache/htdocs/app/app/Http/Services/ |
Upload File : |
<?php
namespace App\Http\Services;
use Carbon\Carbon;
use App\Models\Locker;
use App\Models\LockerBox;
use App\Models\UserBoxDelivery;
use App\Models\UserBoxInventory;
use App\Models\UserBoxBooking;
use App\Http\Services\LockerService;
use App\Http\Services\EmailService;
use App\Http\Services\GooglePubSubService;
use App\Jobs\OpenLockerBoxQueue;
use Pylon\Exceptions\BadRequestException;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Log;
use App\Events\OpenLockerBox;
use App\Events\RestartLocker;
use App\Events\SyncLocker;
class LockerMiddlewareService{
public function __construct(
LockerService $lockerService,
EmailService $emailService,
GooglePubSubService $googlePubSubService
)
{
$this->lockerService = $lockerService;
$this->emailService = $emailService;
$this->googlePubSubService = $googlePubSubService;
}
######################################################################################################
# Passive
######################################################################################################
public function signIn(Array $request)
{
// \Log::debug($request);
$locker = Locker::where('terminal_id', $request['terminalID'])
->withTrashed()
->first();
if($locker){
$locker->is_connect = true;
$locker->last_echo_at = now();
$locker->save();
}else{
$locker = $this->lockerService->lockerCreate($request);
}
$this->googlePubSubService->createTopic($locker->terminal_id);
sleep(1);
$this->googlePubSubService->createSubscription($locker->terminal_id);
return $locker;
}
public function keepAlive(Array $request)
{
$locker = Locker::where('terminal_id', $request['terminalID'])
->withTrashed()
->first();
if(!$locker){
throw ValidationException::withMessages([
'terminalID' => ['Locker does not exist in the database.'],
]);
}
$locker->is_connect = true;
if(isset($request['appVersion']))
$locker->app_version = $request['appVersion'];
else
$locker->app_version = null;
$locker->last_echo_at = now();
$locker->save();
$openStatusArray = str_replace("[","",$request['openStatusArray']);
$openStatusArray = str_replace("]","",$openStatusArray);
$openStatusArray = collect( explode(',', $openStatusArray) );
$locker->load([
"boxes" => fn($q) => $q->withTrashed(),
]);
$lockerBoxes = $locker->boxes;
$openStatusArray->each(function($item,$key) use ($lockerBoxes){
$locker = $lockerBoxes[$key];
$locker->is_open = ($item == 1) ? 0 : 1;
$locker->save();
});
return null;
}
public function disconnect(Array $request)
{
// \Log::notice($request);
$locker = Locker::where('terminal_id',$request['terminalID'])->first();
if($locker){
$locker->is_connect = false;
$locker->save();
$this->emailService->alert_offline_locker($locker);
}
else{
throw ValidationException::withMessages([
'terminalID' => ['Locker does not exist in the database.'],
]);
}
return $locker;
}
######################################################################################################
# Active
######################################################################################################
// public function testLocker($request){
// $locker = Locker::first();
// $lockerBox = LockerBox::where('locker_id',$locker->id)
// // ->where('type_id', 1) // size
// // ->where('')
// ->first();
// $result = $this->openBox('02ef1400a9744e0374240000',$request->box_no);
// if($result){
// $lockerBox->isOpen = 1;
// $lockerBox->save();
// }
// return $result;
// }
public function openBox(Array $request)
{
try {
if(array_key_exists('lockerBoxID', $request))
{
$lockerBox = LockerBox::where('id', $request['lockerBoxID'])
->with(["locker" => function($q) use($request){
$q->where('lockers.terminal_id', '=', $request['terminalID']);
}])
->first();
if($lockerBox->locker)
{
$json = [
"terminal_id" => $request['terminalID'],
"lockerInfo" => $lockerBox->box_no
];
$this->googlePubSubService->publishMessage($request['terminalID'], "OpenLockerBox", $json);
$this->googlePubSubService->publishMessagev2($request['terminalID'], "OpenLockerBox", $json);
Event(new OpenLockerBox($request['terminalID'], $lockerBox->box_no));
$lockerBox->update([
'is_open' => true
]);
}
else{
throw ValidationException::withMessages([
'lockerBoxID' => ['Locker box does not exist in the database.'],
]);
}
}
else
{
// OPEN ALL LOCKER BOX
$locker = Locker::where('terminal_id',$request['terminalID'])->first();
if($locker)
{
$json = [
"terminal_id" => $request['terminalID'],
"lockerInfo" => null
];
$this->googlePubSubService->publishMessage($request['terminalID'], "OpenLockerBox", $json);
$this->googlePubSubService->publishMessagev2($request['terminalID'], "OpenLockerBox", $json);
Event(new OpenLockerBox($request['terminalID'], null));
$locker->boxes()->update([
'is_open' => true,
]);
}
else{
throw ValidationException::withMessages([
'terminalID' => ['Locker does not exist in the database.'],
]);
}
}
} catch (Exception $e) {
$attempt = $attempt - 1;
if($e->getCode() == 404 && $attempt > 0){
$this->openBox($request['terminal_id'], $lockerBox, $attempt);
}else{
throw $e;
}
}
}
public function readQrCode($json)
{
if($json->booking_type == UserBoxBooking::INVENTORY_ORDER)
{
if($json->type == UserBoxBooking::DROP_OFF_ACTION)
{
$boxInventory = UserBoxInventory::where('id',$json->id)
->where('user_id',$json->user_id)
->whereNull('collected_at')
->firstOr( function(){
throw (new BadRequestException("Something went wrong!"))
->withErrorType('ID_INVALID');
});
$boxInventory->load([
'box'
]);
if(isset($json->terminal_id))
$this->checkLockerQr($boxInventory->box->locker->terminal_id, $json->terminal_id);
if($boxInventory->dirty_at != null){
throw (new BadRequestException("Box already opened on ".$boxInventory->dirty_at))
->withErrorType('INVALID_OPEN_PERMISSION');
}
$boxInventory->drop_off_qr_validity = now()->addMinutes(5);
$boxInventory->save();
}
else if($json->type == UserBoxBooking::COLLECT_ACTION)
{
$boxInventory = UserBoxInventory::where('id',$json->id)
->whereNull('collected_at')
->firstOr( function(){
throw (new BadRequestException("Something went wrong!"))
->withErrorType('ID_INVALID');
});
$boxInventory->load([
'box'
]);
if(isset($json->terminal_id))
$this->checkLockerQr($boxInventory->box->locker->terminal_id, $json->terminal_id);
if($boxInventory->dirty_at == null){
throw (new BadRequestException("dropper unlock required"))
->withErrorType('DROPPER_UNLOCK_REQUIRED');
}
$boxInventory->collect_qr_validity = now()->addMinutes(5);
$boxInventory->save();
}
else if($json->type == UserBoxBooking::CANCEL_ORDER_ACTION)
{
$boxInventory = UserBoxInventory::where('id',$json->id)
->where('user_id',$json->user_id)
->whereNull('collected_at')
->firstOr( function(){
throw (new BadRequestException("Item has been collected, failed to cancel order!"))
->withErrorType('ID_INVALID');
});
$boxInventory->load([
'box'
]);
if(isset($json->terminal_id))
$this->checkLockerQr($boxInventory->box->locker->terminal_id, $json->terminal_id);
$boxInventory->cancel_qr_validity = now()->addMinutes(5);
$boxInventory->save();
}
else
throw (new BadRequestException("Unrecognized QR code type"))
->withErrorType('INVALID_QR_CODE');
}
else if($json->booking_type == UserBoxBooking::DELIVERY_ORDER)
{
if($json->type == UserBoxBooking::DROP_OFF_ACTION)
{
$boxDelivery = UserBoxDelivery::where('id',$json->id)
->where('user_id',$json->user_id)
->whereNull('collected_at')
->firstOr( function(){
throw (new BadRequestException("Something went wrong!"))
->withErrorType('ID_INVALID');
});
$boxDelivery->load([
'box',
'locker',
'dropper:id,full_name,mobile_num,unique_id',
'deliveryPartner' => function ($query) {
$query->withTrashed()->with('image');
}
]);
if(isset($json->terminal_id))
$this->checkLockerQr($boxDelivery->box->locker->terminal_id, $json->terminal_id);
if($boxDelivery->dirty_at != null){
throw (new BadRequestException("Box already opened on ".$boxDelivery->dirty_at))
->withErrorType('INVALID_OPEN_PERMISSION');
}
$boxDelivery->drop_off_qr_validity = now()->addMinutes(5);
$boxDelivery->save();
}
else if($json->type == UserBoxBooking::CANCEL_ORDER_ACTION)
{
$boxDelivery = UserBoxDelivery::where('id',$json->id)
->where('user_id',$json->user_id)
->whereNull('collected_at')
->firstOr( function(){
throw (new BadRequestException("Item has been collected, failed to cancel order!"))
->withErrorType('ID_INVALID');
});
$boxDelivery->load([
'box',
'locker',
'dropper:id,full_name,mobile_num,unique_id',
'deliveryPartner' => function ($query) {
$query->withTrashed()->with('image');
}
]);
if(isset($json->terminal_id))
$this->checkLockerQr($boxDelivery->box->locker->terminal_id, $json->terminal_id);
$boxDelivery->cancel_qr_validity = now()->addMinutes(5);
$boxDelivery->save();
}
else
throw (new BadRequestException("Unrecognized QR code type"))
->withErrorType('INVALID_QR_CODE');
}
return [
"message" => "'QR code actiavted, please return to your app and verify yourself by sliding the slider within 5 minutes.'",
"booking_type" => $json->booking_type,
"is_drop_off" => $json->type == UserBoxBooking::DROP_OFF_ACTION ? true : false
];
}
public function checkLockerQr($locker_terminal_id, $qr_terminal_id)
{
if($locker_terminal_id != $qr_terminal_id)
throw (new BadRequestException("Invalid action, this order does not belong to this locker!"))
->withErrorType('LOCKER_ID_MISMATCHED');
}
// public function openAllBox($locker, $attempt = 3)
// {
// try {
// $result = $this->sendOpenBoxRequest($locker->terminal_id, '0');
// $locker->boxes()->update([
// 'is_open' => true,
// ]);
// return $result;
// } catch (Exception $e) {
// $attempt = $attempt - 1;
// if($e->getCode() == 404 && $attempt > 0){
// // try again
// $this->openBox($terminal_id, $attempt);
// }else{
// throw $e;
// }
// }
// }
// protected function sendOpenBoxRequest($terminal_id, $box_no)
// {
// $url = $this->locker_middleware_url."/apis/v1/openbox/";
// $now = Carbon::now('UTC');
// $timestamp = $now->format('Y-m-d H:i:s');
// $data = [
// "gui_no" => $terminal_id,
// "box_no" => $box_no,
// ];
// $headers = [
// "Content-Type: application/json",
// "app_key: ".$this->app_key,
// "timestamp: ".$timestamp,
// "sign: ".$this->encryptSign($terminal_id, $box_no, $timestamp),
// ];
// $curl = curl_init();
// curl_setopt($curl, CURLOPT_URL, $url);
// curl_setopt($curl, CURLOPT_POST, true);
// curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
// curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
// $curl_result = curl_exec($curl);
// curl_close($curl);
// $result = json_decode($curl_result);
// switch ($result->errorCode) {
// case 0:
// return $result->errorDesc;
// break;
// default:
// if($result->errorDesc == "Terminal reponse timeout"){
// throw new BadRequestException($result->errorDesc);
// }
// throw (new BadRequestException($result->errorDesc))->withErrorType($result->errorCode);
// break;
// }
// }
// protected function encryptSign($gui_no, $box_no, $timestamp)
// {
// $signBuffer = $this->computeSignBuffer([
// "app_key" => $this->app_key,
// "box_no" => $box_no,
// "gui_no" => $gui_no,
// "timestamp" => $timestamp,
// "secret" => $this->secret,
// ]);
// return md5($signBuffer, false);
// }
// protected function computeSignBuffer(Array $request)
// {
// $signBuffer = $request['secret']
// ."app_key".$request['app_key']
// ."box_no".$request['box_no']
// ."gui_no".$request['gui_no']
// ."timestamp".$request['timestamp']
// .$request['secret'];
// return $signBuffer;
// }
public function restartLocker(Array $request)
{
$locker = Locker::where('id',$request['id'])
->withTrashed()
->firstOr( function(){
throw ValidationException::withMessages(
[ "id" => "The selected id is invalid." ]
);
});
$json = [
"terminal_id" => $locker->terminal_id
];
$this->googlePubSubService->publishMessage($locker->terminal_id, "RestartLocker", $json);
$this->googlePubSubService->publishMessagev2($locker->terminal_id, "RestartLocker", $json);
Event(new RestartLocker($locker->terminal_id));
return $locker->name . " restarting...";
}
public function syncLocker(Array $request)
{
$locker = Locker::where('id',$request['id'])
->withTrashed()
->firstOr( function(){
throw ValidationException::withMessages(
[ "id" => "The selected id is invalid." ]
);
});
$json = [
"terminal_id" => $locker->terminal_id
];
$this->googlePubSubService->publishMessage($locker->terminal_id, "SyncLocker", $json);
$this->googlePubSubService->publishMessagev2($locker->terminal_id, "SyncLocker", $json);
Event(new SyncLocker($locker->terminal_id));
return $locker->name . " syncing...";
}
}