You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 line
5.5KB

  1. <?php
  2. namespace App\Logics\QRService;
  3. use App\Exceptions\AppCommonException;
  4. use App\Models\ColumnName;
  5. use App\Models\HtpmsCustomer\QRService\AcquisitionAvailableSetting;
  6. use App\Models\HtpmsCustomer\QRService\AcquisitionTicket;
  7. use App\Models\HtpmsCustomer\QRService\AcquisitionTicketToken;
  8. use App\Models\HtpmsCustomer\QRService\ServiceParkingGroupRelation;
  9. use App\Util\DateUtil;
  10. use Illuminate\Support\Carbon;
  11. use Str;
  12. class CreateLogic
  13. {
  14. use DepositCheck;
  15. /**
  16. * サービス券を作成する
  17. */
  18. public static function create(
  19. string $token,
  20. ) {
  21. // トークンから店舗ID検索
  22. $t = AcquisitionTicketToken::whereToken($token)->first();
  23. if ($t instanceof AcquisitionTicketToken === false) {
  24. throw new AppCommonException(sprintf("トークン不正 %s", $token));
  25. }
  26. $shopId = $t->shop_id;
  27. // 割引設定有無の確認
  28. $check = AcquisitionAvailableSetting::whereShopId($shopId)
  29. ->first();
  30. if ($check instanceof AcquisitionAvailableSetting === false) {
  31. throw new AppCommonException("取得できない割引");
  32. }
  33. // デポジットチェック
  34. if (!self::canCreate($shopId)) {
  35. throw new AppCommonException("認証不可 デポジット");
  36. }
  37. [$shop] = self::getData($shopId);
  38. // 設定値の検索
  39. $setting = AcquisitionAvailableSetting::whereShopId($shopId)
  40. ->first();
  41. if ($setting instanceof AcquisitionAvailableSetting === false) {
  42. throw new AppCommonException("QRサービス券取得可能設定 不正");
  43. }
  44. $qr = new AcquisitionTicket();
  45. $qr->qr_service_parking_group_id = $check->qr_service_parking_group_id;
  46. $qr->publishing_no = self::getNextSeqNo($setting->shop_no);
  47. $qr->shop_id = $shopId;
  48. $qr->shop_no = $setting->shop_no;
  49. $qr->discount_ticket_code = $setting->discount_ticket_code;
  50. $qr->qr_service_parking_group_id = $setting->qr_service_parking_group_id;
  51. // 有効期限設定
  52. $qr->expires_at = DateUtil::now()->addMinutes($shop->qr_service_expire_min);
  53. $qr->publishing_date = DateUtil::now();
  54. $qr->save();
  55. return $qr;
  56. }
  57. public static function getUsable(int $shopNo, Carbon $publishingDate, int $seqNo): AcquisitionTicket
  58. {
  59. $qr = AcquisitionTicket::query()
  60. ->whereShopNo($shopNo)
  61. ->wherePublishingDate($publishingDate)
  62. ->wherePublishingNo($seqNo)
  63. ->lockForUpdate()
  64. ->first();
  65. if ($qr instanceof AcquisitionTicket === false) {
  66. throw new AppCommonException("QR 認証なし");
  67. }
  68. if ($qr->iseExpired()) {
  69. throw new AppCommonException("QR 期限切れ");
  70. }
  71. if ($qr->isUsed()) {
  72. throw new AppCommonException("QR 使用済み");
  73. }
  74. return $qr;
  75. }
  76. /**
  77. * サービス券を使用する
  78. *
  79. * @param integer $shopNo
  80. * @param string $parkingManagementCode
  81. * @param Carbon $publishingDate
  82. * @param integer $seqNo
  83. * @param integer $discountTicketCode
  84. * @param Carbon $adjustDatetime
  85. * @param integer $discountAmount
  86. * @return void
  87. */
  88. public static function use(
  89. int $shopNo,
  90. string $parkingManagementCode,
  91. Carbon $publishingDate,
  92. int $seqNo,
  93. int $discountTicketCode,
  94. Carbon $adjustDatetime,
  95. int $discountAmount,
  96. ) {
  97. // QRコード情報の取得
  98. $qr = self::getUsable($shopNo, $publishingDate, $seqNo);
  99. // QRコードサービス券駐車場グループに含まれているかチェック
  100. self::checkQrParkingGroup($qr->qr_service_parking_group_id, $parkingManagementCode);
  101. // デポジット処理
  102. self::useDeposit($qr->shop_id, $discountAmount);
  103. $qr->discount_amount = $discountAmount;
  104. // 利用情報
  105. $qr->used_at = $adjustDatetime;
  106. $qr->discount_ticket_code = $discountTicketCode;
  107. $qr->parking_management_code = $parkingManagementCode;
  108. $qr->save();
  109. }
  110. public static function getToken(string $shopId, bool $refresh = false): AcquisitionTicketToken
  111. {
  112. $token = AcquisitionTicketToken::whereShopId($shopId)
  113. ->first();
  114. if ($refresh) {
  115. if ($token instanceof AcquisitionTicketToken === true) {
  116. $token->delete();
  117. $token = null;
  118. }
  119. }
  120. if ($token instanceof AcquisitionTicketToken) {
  121. return $token;
  122. }
  123. // トークン新規作成
  124. $token = new AcquisitionTicketToken();
  125. $token->token = Str::uuid()->toString();
  126. $token->shop_id = $shopId;
  127. $token->save();
  128. return $token;
  129. }
  130. private static function getNextSeqNo(int $shopNo)
  131. {
  132. $max = AcquisitionTicket::query()
  133. ->whereShopNo($shopNo)
  134. ->wherePublishingDate(DateUtil::now())
  135. ->max(ColumnName::PUBLISHING_NO);
  136. if ($max === null) return 1;
  137. return $max + 1;
  138. }
  139. private static function checkQrParkingGroup(string $groupId, string $parkingManagementCode)
  140. {
  141. $query = ServiceParkingGroupRelation::query()
  142. ->whereQrServiceParkingGroupId($groupId)
  143. ->whereParkingManagementCode($parkingManagementCode);
  144. if (!$query->exists()) {
  145. throw new AppCommonException("利用できない駐車場");
  146. }
  147. }
  148. }