first(); if ($t instanceof AcquisitionTicketToken === false) { throw new AppCommonException(sprintf("トークン不正 %s", $token)); } $shopId = $t->shop_id; // 割引設定有無の確認 $check = AcquisitionAvailableSetting::whereShopId($shopId) ->first(); if ($check instanceof AcquisitionAvailableSetting === false) { throw new AppCommonException("取得できない割引"); } // デポジットチェック if (!self::canCreate($shopId)) { throw new AppCommonException("認証不可 デポジット"); } [$shop] = self::getData($shopId); // 設定値の検索 $setting = AcquisitionAvailableSetting::whereShopId($shopId) ->first(); if ($setting instanceof AcquisitionAvailableSetting === false) { throw new AppCommonException("QRサービス券取得可能設定 不正"); } $qr = new AcquisitionTicket(); $qr->qr_service_parking_group_id = $check->qr_service_parking_group_id; $qr->publishing_no = self::getNextSeqNo($setting->shop_no); $qr->shop_id = $shopId; $qr->shop_no = $setting->shop_no; $qr->discount_ticket_code = $setting->discount_ticket_code; $qr->qr_service_parking_group_id = $setting->qr_service_parking_group_id; // 有効期限設定 $qr->expires_at = DateUtil::now()->addMinutes($shop->qr_service_expire_min); $qr->publishing_date = DateUtil::now(); $qr->save(); return $qr; } public static function getUsable(int $shopNo, Carbon $publishingDate, int $seqNo): AcquisitionTicket { $qr = AcquisitionTicket::query() ->whereShopNo($shopNo) ->wherePublishingDate($publishingDate) ->wherePublishingNo($seqNo) ->lockForUpdate() ->first(); if ($qr instanceof AcquisitionTicket === false) { throw new AppCommonException("QR 認証なし"); } if ($qr->iseExpired()) { throw new AppCommonException("QR 期限切れ"); } if ($qr->isUsed()) { throw new AppCommonException("QR 使用済み"); } return $qr; } /** * サービス券を使用する * * @param integer $shopNo * @param string $parkingManagementCode * @param Carbon $publishingDate * @param integer $seqNo * @param integer $discountTicketCode * @param Carbon $adjustDatetime * @param integer $discountAmount * @return void */ public static function use( int $shopNo, string $parkingManagementCode, Carbon $publishingDate, int $seqNo, int $discountTicketCode, Carbon $adjustDatetime, int $discountAmount, ) { // QRコード情報の取得 $qr = self::getUsable($shopNo, $publishingDate, $seqNo); // QRコードサービス券駐車場グループに含まれているかチェック self::checkQrParkingGroup($qr->qr_service_parking_group_id, $parkingManagementCode); // デポジット処理 self::useDeposit($qr->shop_id, $discountAmount); $qr->discount_amount = $discountAmount; // 利用情報 $qr->used_at = $adjustDatetime; $qr->discount_ticket_code = $discountTicketCode; $qr->parking_management_code = $parkingManagementCode; $qr->save(); } public static function getToken(string $shopId, bool $refresh = false): AcquisitionTicketToken { $token = AcquisitionTicketToken::whereShopId($shopId) ->first(); if ($refresh) { if ($token instanceof AcquisitionTicketToken === true) { $token->delete(); $token = null; } } if ($token instanceof AcquisitionTicketToken) { return $token; } // トークン新規作成 $token = new AcquisitionTicketToken(); $token->token = Str::uuid()->toString(); $token->shop_id = $shopId; $token->save(); return $token; } private static function getNextSeqNo(int $shopNo) { $max = AcquisitionTicket::query() ->whereShopNo($shopNo) ->wherePublishingDate(DateUtil::now()) ->max(ColumnName::PUBLISHING_NO); if ($max === null) return 1; return $max + 1; } private static function checkQrParkingGroup(string $groupId, string $parkingManagementCode) { $query = ServiceParkingGroupRelation::query() ->whereQrServiceParkingGroupId($groupId) ->whereParkingManagementCode($parkingManagementCode); if (!$query->exists()) { throw new AppCommonException("利用できない駐車場"); } } }