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.

118 lines
3.7KB

  1. <?php
  2. namespace App\Logics\QRService;
  3. use App\Codes\DepositTransferReason;
  4. use App\Contexts\Model\Deposit as ContextDeposit;
  5. use App\Contexts\Model\Shop as ContextShop;
  6. use App\Exceptions\AppCommonException;
  7. use App\Models\HtpmsCustomer\Deposit\Deposit;
  8. use App\Models\HtpmsCustomer\Deposit\DepositTransfer;
  9. use App\Models\HtpmsCustomer\Mst\Shop;
  10. use App\Util\DateUtil;
  11. use LogicException;
  12. trait DepositCheck
  13. {
  14. protected static function canCreate(string $shopId): bool
  15. {
  16. [$shop, $deposit] = self::getData($shopId);
  17. return self::checkDepositWhenCertificate($shop, $deposit);
  18. }
  19. protected static function canCertificate(string $shopId): bool
  20. {
  21. [$shop, $deposit] = self::getData($shopId);
  22. return self::checkDepositWhenCertificate($shop, $deposit);
  23. }
  24. protected static function canUseDeposit(string $shopId, $amount): bool
  25. {
  26. [$shop, $deposit] = self::getData($shopId);
  27. return self::checkDepositWhenUse($shop, $deposit, $amount);
  28. }
  29. protected static function useDeposit(
  30. string $shopId,
  31. int $amount,
  32. DepositTransferReason $reason,
  33. ) {
  34. // データ取得
  35. [$shop, $deposit] = self::getData($shopId);
  36. if (!self::checkDepositWhenUse($shop, $deposit, $amount)) {
  37. throw new AppCommonException("利用時残高不足");
  38. }
  39. // 異動履歴作成
  40. $history = self::makeTransferHistory($shopId, -1 * $amount);
  41. $history->transfer_reason = $reason;
  42. // デポジット減算
  43. $deposit->deposit -= $amount;
  44. // 保存
  45. $deposit->save();
  46. $history->save();
  47. }
  48. /**
  49. * デポジット異動履歴の作成 amountはdepositを使う場合は負の整数、チャージする場合は正の整数
  50. */
  51. protected static function makeTransferHistory(string $shopId, int $amount): DepositTransfer
  52. {
  53. [$shop, $deposit] = self::getData($shopId);
  54. $transfer = new DepositTransfer();
  55. $transfer->shop_id = $shopId;
  56. $transfer->transfer_datetime = DateUtil::now();
  57. $transfer->transfer_amount = $amount;
  58. $transfer->before_amount = $deposit->deposit;
  59. $transfer->after_amount = $deposit->deposit + $amount;
  60. return $transfer;
  61. }
  62. /**
  63. * @param string $shopId
  64. * @return array{Shop, Deposit}
  65. */
  66. protected static function getData(string $shopId)
  67. {
  68. // データ取得 コンテキストから取得する
  69. $shop = ContextShop::instance()->get();
  70. $deposit = ContextDeposit::instance()->get();
  71. if ($shop === null) {
  72. $shop = Shop::whereId($shopId)->firstOrFail();
  73. ContextShop::instance()->set($shop);
  74. } else {
  75. // 確認
  76. if ($shopId !== $shop->id) {
  77. throw new LogicException("コンテキスト不正");
  78. }
  79. }
  80. if ($deposit === null) {
  81. $deposit = Deposit::whereShopId($shopId)->firstOrFail();
  82. ContextDeposit::instance()->set($deposit);
  83. } else {
  84. // 確認
  85. if ($shopId !== $deposit->shop_id) {
  86. throw new LogicException("コンテキスト不正");
  87. }
  88. }
  89. return [$shop, $deposit];
  90. }
  91. private static function checkDepositWhenUse(Shop $shop, Deposit $deposit, int $amount)
  92. {
  93. return $shop->under_amount_when_use < $deposit->deposit - $amount;
  94. }
  95. private static function checkDepositWhenCertificate(Shop $shop, Deposit $deposit)
  96. {
  97. return $shop->under_amount_when_auth < $deposit->deposit;
  98. }
  99. private static function checkDepositWhenCreate(Shop $shop, Deposit $deposit)
  100. {
  101. return $shop->under_amount_when_create < $deposit->deposit;
  102. }
  103. }