CouponService.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <?php
  2. namespace App\Services;
  3. use App\Models\Coupon;
  4. use App\Models\Order;
  5. use Illuminate\Support\Facades\DB;
  6. class CouponService
  7. {
  8. public $coupon;
  9. public $planId;
  10. public $userId;
  11. public function __construct($code)
  12. {
  13. $this->coupon = Coupon::where('code', $code)->first();
  14. }
  15. public function use(Order $order):bool
  16. {
  17. $this->setPlanId($order->plan_id);
  18. $this->setUserId($order->user_id);
  19. $this->check();
  20. switch ($this->coupon->type) {
  21. case 1:
  22. $order->discount_amount = $this->coupon->value;
  23. break;
  24. case 2:
  25. $order->discount_amount = $order->total_amount * ($this->coupon->value / 100);
  26. break;
  27. }
  28. if ($order->discount_amount > $order->total_amount) {
  29. $order->discount_amount = $order->total_amount;
  30. }
  31. if ($this->coupon->limit_use !== NULL) {
  32. $this->coupon->limit_use = $this->coupon->limit_use - 1;
  33. if (!$this->coupon->save()) {
  34. return false;
  35. }
  36. }
  37. return true;
  38. }
  39. public function getId()
  40. {
  41. return $this->coupon->id;
  42. }
  43. public function getCoupon()
  44. {
  45. return $this->coupon;
  46. }
  47. public function setPlanId($planId)
  48. {
  49. $this->planId = $planId;
  50. }
  51. public function setUserId($userId)
  52. {
  53. $this->userId = $userId;
  54. }
  55. public function checkLimitUseWithUser():bool
  56. {
  57. $usedCount = Order::where('coupon_id', $this->coupon->id)
  58. ->where('user_id', $this->userId)
  59. ->whereNotIn('status', [0, 2])
  60. ->count();
  61. if ($usedCount >= $this->coupon->limit_use_with_user) return false;
  62. return true;
  63. }
  64. public function check()
  65. {
  66. if (!$this->coupon) {
  67. abort(500, __('Invalid coupon'));
  68. }
  69. if ($this->coupon->limit_use <= 0 && $this->coupon->limit_use !== NULL) {
  70. abort(500, __('This coupon is no longer available'));
  71. }
  72. if (time() < $this->coupon->started_at) {
  73. abort(500, __('This coupon has not yet started'));
  74. }
  75. if (time() > $this->coupon->ended_at) {
  76. abort(500, __('This coupon has expired'));
  77. }
  78. if ($this->coupon->limit_plan_ids && $this->planId) {
  79. if (!in_array($this->planId, $this->coupon->limit_plan_ids)) {
  80. abort(500, __('The coupon code cannot be used for this subscription'));
  81. }
  82. }
  83. if ($this->coupon->limit_use_with_user !== NULL && $this->userId) {
  84. if (!$this->checkLimitUseWithUser()) {
  85. abort(500, __('The coupon can only be used :limit_use_with_user per person', [
  86. 'limit_use_with_user' => $this->coupon->limit_use_with_user
  87. ]));
  88. }
  89. }
  90. }
  91. }