v2board/app/Services/CouponService.php

118 lines
3.3 KiB
PHP
Raw Normal View History

2020-04-09 13:35:27 +08:00
<?php
namespace App\Services;
use App\Models\Coupon;
use App\Models\Order;
use Illuminate\Support\Facades\DB;
class CouponService
{
2021-08-28 15:32:55 +08:00
public $coupon;
public $planId;
public $userId;
2021-12-28 01:59:59 +08:00
public $period;
2020-04-09 13:35:27 +08:00
public function __construct($code)
{
$this->coupon = Coupon::where('code', $code)
->lockForUpdate()
->first();
2020-04-09 13:35:27 +08:00
}
2021-08-29 11:54:15 +08:00
public function use(Order $order):bool
2020-04-09 13:35:27 +08:00
{
2021-08-28 15:32:55 +08:00
$this->setPlanId($order->plan_id);
$this->setUserId($order->user_id);
2021-12-28 01:59:59 +08:00
$this->setPeriod($order->period);
2021-08-28 15:32:55 +08:00
$this->check();
2020-04-09 13:35:27 +08:00
switch ($this->coupon->type) {
case 1:
$order->discount_amount = $this->coupon->value;
break;
case 2:
$order->discount_amount = $order->total_amount * ($this->coupon->value / 100);
break;
}
2021-11-01 02:31:27 +08:00
if ($order->discount_amount > $order->total_amount) {
$order->discount_amount = $order->total_amount;
}
2020-04-09 13:35:27 +08:00
if ($this->coupon->limit_use !== NULL) {
if ($this->coupon->limit_use <= 0) return false;
2022-07-31 19:12:31 +08:00
$this->coupon->limit_use = $this->coupon->limit_use - 1;
2020-04-09 13:35:27 +08:00
if (!$this->coupon->save()) {
return false;
}
}
return true;
}
2020-10-24 23:08:14 +08:00
public function getId()
{
return $this->coupon->id;
}
2021-08-28 15:32:55 +08:00
public function getCoupon()
{
return $this->coupon;
}
public function setPlanId($planId)
{
$this->planId = $planId;
}
public function setUserId($userId)
{
$this->userId = $userId;
}
2021-12-28 01:59:59 +08:00
public function setPeriod($period)
{
$this->period = $period;
}
2021-08-29 11:54:15 +08:00
public function checkLimitUseWithUser():bool
2021-08-28 15:32:55 +08:00
{
$usedCount = Order::where('coupon_id', $this->coupon->id)
->where('user_id', $this->userId)
->whereNotIn('status', [0, 2])
->count();
if ($usedCount >= $this->coupon->limit_use_with_user) return false;
return true;
}
public function check()
{
2022-01-22 02:30:05 +08:00
if (!$this->coupon || !$this->coupon->show) {
2021-08-28 15:32:55 +08:00
abort(500, __('Invalid coupon'));
}
if ($this->coupon->limit_use <= 0 && $this->coupon->limit_use !== NULL) {
abort(500, __('This coupon is no longer available'));
}
if (time() < $this->coupon->started_at) {
abort(500, __('This coupon has not yet started'));
}
if (time() > $this->coupon->ended_at) {
abort(500, __('This coupon has expired'));
}
if ($this->coupon->limit_plan_ids && $this->planId) {
if (!in_array($this->planId, $this->coupon->limit_plan_ids)) {
abort(500, __('The coupon code cannot be used for this subscription'));
}
}
2021-12-28 01:59:59 +08:00
if ($this->coupon->limit_period && $this->period) {
if (!in_array($this->period, $this->coupon->limit_period)) {
abort(500, __('The coupon code cannot be used for this period'));
}
}
2021-08-28 15:32:55 +08:00
if ($this->coupon->limit_use_with_user !== NULL && $this->userId) {
if (!$this->checkLimitUseWithUser()) {
abort(500, __('The coupon can only be used :limit_use_with_user per person', [
'limit_use_with_user' => $this->coupon->limit_use_with_user
]));
}
}
}
2020-04-09 13:35:27 +08:00
}