diff --git a/app/Http/Controllers/Web/QRService/Acquisition/GetAcquisitionTokenController.php b/app/Http/Controllers/Web/QRService/Acquisition/GetAcquisitionTokenController.php index 10dc006..67219e9 100644 --- a/app/Http/Controllers/Web/QRService/Acquisition/GetAcquisitionTokenController.php +++ b/app/Http/Controllers/Web/QRService/Acquisition/GetAcquisitionTokenController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Web\QRService\Acquisition; use App\Http\Controllers\Web\WebController; +use App\Logics\QRService\QRCryptoLogic; use App\Models\HtpmsCustomer\QRService\AcquisitionTicketToken; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -43,6 +44,7 @@ class GetAcquisitionTokenController extends WebController $res = [ "token" => $token->token, ]; + return $this->successResponse($res); } } diff --git a/app/Http/Controllers/Web/QRService/Certification/CertificationController.php b/app/Http/Controllers/Web/QRService/Certification/CertificationController.php new file mode 100644 index 0000000..be7e2c0 --- /dev/null +++ b/app/Http/Controllers/Web/QRService/Certification/CertificationController.php @@ -0,0 +1,48 @@ +param; + + $cartification = CertificateLogic::certificate( + $param->parkingManagementCode, + $param->publishingTerminalCode, + $param->publishingDate, + $param->publishingNo, + $this->sessionUser->shopId(), + $param->discountTicketCode, + ); + + $res = [ + "expires_at" => $cartification->expires_at, + ]; + + return $this->successResponse($res); + } +} diff --git a/app/Http/Controllers/Web/QRService/Certification/CertificationParam.php b/app/Http/Controllers/Web/QRService/Certification/CertificationParam.php new file mode 100644 index 0000000..d97e796 --- /dev/null +++ b/app/Http/Controllers/Web/QRService/Certification/CertificationParam.php @@ -0,0 +1,29 @@ + $this->str([...Rule::parkingManagementCode()]), + CertificationTicket::COL_NAME_PUBLISHING_TERMINAL_CODE => $this->str("reg_ex:/^[0-9]{2}$/"), + CertificationTicket::COL_NAME_PUBLISHING_DATE => $this->date(), + CertificationTicket::COL_NAME_PUBLISHING_NO => $this->numeric("between:0,999999"), + CertificationTicket::COL_NAME_DISCOUNT_TICKET_CODE => $this->numeric("between:0,99"), + ]; + } +} diff --git a/app/Http/Controllers/Web/QRService/Certification/CheckDataFormatController.php b/app/Http/Controllers/Web/QRService/Certification/CheckDataFormatController.php new file mode 100644 index 0000000..f5b4a13 --- /dev/null +++ b/app/Http/Controllers/Web/QRService/Certification/CheckDataFormatController.php @@ -0,0 +1,138 @@ +param; + + // 暗号化文字列の解読 + $data = DataConverter::read($param->data); + + // 対象の駐車場か判定 + $relation = ShopNoRelation::whereShopId($this->sessionUser->shopId()) + ->whereParkingManagementCode($data->駐車場管理コード) + ->first(); + + if ($relation === null) { + throw new GeneralErrorMessageException("認証できない駐車場"); + } + + + // 認証可能なサービス券一覧取得 + $setting = CertificationAvailableSetting::whereShopId($this->sessionUser->shopId()) + ->whereParkingManagementCode($data->駐車場管理コード) + ->get(); + + + if ($setting->isEmpty()) { + throw new GeneralErrorMessageException("認証できるサービス券なし"); + } + + // 駐車場情報の取得 + $parking = Parking::whereParkCode($data->駐車場管理コード) + ->first(); + + if ($parking instanceof Parking === false) { + throw new GeneralErrorMessageException("存在しない駐車場"); + } + + // 認証済みチェック + if (CertificationTicket::whereParkingManagementCode($data->駐車場管理コード) + ->wherePublishingTerminalCode($data->発行端末) + ->wherePublishingDate($data->発行日) + ->wherePublishingNo($data->発行連番) + ->exists() + ) { + throw new GeneralErrorMessageException("認証ずみのサービス券"); + } + + + // サービス券一覧の取得 + $discountTicketCodes = $setting->pluck(CertificationAvailableSetting::COL_NAME_DISCOUNT_TICKET_CODE)->toArray(); + $discountTickets = DiscountTicket::whereParkId($parking->id) + ->whereIn(DiscountTicket::COL_NAME_DISCOUNT_TICKET_CODE, $discountTicketCodes) + ->select([ + sprintf("%s as %s", DiscountTicket::COL_NAME_DISCOUNT_TICKET_CODE, ColumnName::DISCOUNT_TICKET_CODE), + sprintf("%s as %s", DiscountTicket::COL_NAME_TICKET_NAME, "ticket_name"), + ])->get(); + + + $res = [ + "parking" => [ + "parking_name" => $parking->park_name, + "parking_management_code" => $parking->park_code, + "publishing_terminal_code" => $data->発行端末, + "publishing_date" => $data->発行日, + "publishing_no" => $data->発行連番, + ], + "discount_tickets" => $discountTickets, + ]; + + return $this->successResponse($res); + } +} + +/** + * 精算機で暗号化された文字列をパースする + */ +class DataConverter +{ + public string $発行端末; + public Carbon $発行日; + public int $発行連番; + public string $顧客コード; + public string $駐車場管理コード; + + public static function read(string $data): static + { + $ret = new static(); + + $dec = QRCryptoLogic::decrypt($data); + if (strlen($dec) !== 30) { + throw new GeneralErrorMessageException("文字数不正"); + } + $data = substr($dec, 5); + + $ret->発行端末 = substr($data, 0, 2); + $ret->発行日 = Carbon::createFromFormat("Ymd", substr($data, 2, 8)); + $ret->発行連番 = intval(substr($data, 10, 6)); + $ret->顧客コード = substr($data, 16, 4); + $ret->駐車場管理コード = substr($data, 20, 5); + + + return $ret; + } +} diff --git a/app/Http/Controllers/Web/QRService/Certification/CheckDataFormatParam.php b/app/Http/Controllers/Web/QRService/Certification/CheckDataFormatParam.php new file mode 100644 index 0000000..d8ee718 --- /dev/null +++ b/app/Http/Controllers/Web/QRService/Certification/CheckDataFormatParam.php @@ -0,0 +1,18 @@ + $this->str(), + ]; + } +} diff --git a/app/Models/HtpmsCustomer/Existing/DiscountTicket.php b/app/Models/HtpmsCustomer/Existing/DiscountTicket.php index 6f74df1..95bf99e 100644 --- a/app/Models/HtpmsCustomer/Existing/DiscountTicket.php +++ b/app/Models/HtpmsCustomer/Existing/DiscountTicket.php @@ -2,6 +2,7 @@ namespace App\Models\HtpmsCustomer\Existing; +use App\Models\ColumnName; use App\Util\DateUtil; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Query\Builder; @@ -20,6 +21,8 @@ class DiscountTicket extends Model protected $visible = [ self::COL_NAME_TICKET_NAME, self::COL_NAME_DISCOUNT_TICKET_CODE, + "ticket_name", + ColumnName::DISCOUNT_TICKET_CODE, ]; diff --git a/routes/api.php b/routes/api.php index cab44fa..4bd37ff 100644 --- a/routes/api.php +++ b/routes/api.php @@ -65,6 +65,8 @@ Route::middleware('auth:sanctum')->group(function () { RouteHelper::get('/shop/deposit', App\Http\Controllers\Web\Shop\MyDepositController::class); RouteHelper::get('/qr-service/acquisition/token', App\Http\Controllers\Web\QRService\Acquisition\GetAcquisitionTokenController::class); RouteHelper::post('/qr-service/acquisition/token/refresh', App\Http\Controllers\Web\QRService\Acquisition\RefreshAcquisitionTokenController::class); + RouteHelper::post('/qr-service/certification/check-data-format', App\Http\Controllers\Web\QRService\Certification\CheckDataFormatController::class); + RouteHelper::post('/qr-service/certification', App\Http\Controllers\Web\QRService\Certification\CertificationController::class); }); // 管理者運営会社ルート diff --git a/tests/Feature/Http/Customer/CustomerListTest.php b/tests/Feature/Http/Customer/CustomerListTest.php new file mode 100644 index 0000000..5f8504f --- /dev/null +++ b/tests/Feature/Http/Customer/CustomerListTest.php @@ -0,0 +1,31 @@ +firstOrFail(); + $res = $this->actingAs($user) + ->get('/api/customer/list'); + + print_r($res->json()); + + $this->assertEquals("0", $res->json('result')); + } +} diff --git a/tests/Unit/Repositories/LoginUserRepositoryTest.php b/tests/Unit/Repositories/LoginUserRepositoryTest.php new file mode 100644 index 0000000..c545a51 --- /dev/null +++ b/tests/Unit/Repositories/LoginUserRepositoryTest.php @@ -0,0 +1,45 @@ +get([]); + $this->assertTrue(true); + } + public function test_email_condition(): void + { + $repository = new LoginUserRepository(); + $data = $repository->get([ + LoginUserRepository::CONDITION_EMAIL => "aa.com" + ]); + $this->assertCount(1, $data); + $data = $repository->get([ + LoginUserRepository::CONDITION_EMAIL => "satellite" + ]); + $this->assertCount(0, $data); + } + public function test_role_condition(): void + { + $repository = new LoginUserRepository(); + $data = $repository->get([ + LoginUserRepository::CONDITION_ROLE => UserRole::ADMIN + ]); + $this->assertCount(1, $data); + $data = $repository->get([ + LoginUserRepository::CONDITION_ROLE => UserRole::SHOP + ]); + $this->assertCount(0, $data); + } +} diff --git a/tests/Unit/Repositories/QRServiceParkingGroupRepositoryTest.php b/tests/Unit/Repositories/QRServiceParkingGroupRepositoryTest.php new file mode 100644 index 0000000..4099a27 --- /dev/null +++ b/tests/Unit/Repositories/QRServiceParkingGroupRepositoryTest.php @@ -0,0 +1,22 @@ +get([]); + $this->assertTrue(true); + } +}