update: add coupon per user limit

This commit is contained in:
tokumeikoi 2021-08-28 16:32:55 +09:00
parent 2d5fb03937
commit 5a3b897c57
8 changed files with 76 additions and 41 deletions

View File

@ -3,6 +3,7 @@
namespace App\Http\Controllers\User; namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Services\CouponService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\Coupon; use App\Models\Coupon;
@ -13,26 +14,12 @@ class CouponController extends Controller
if (empty($request->input('code'))) { if (empty($request->input('code'))) {
abort(500, __('Coupon cannot be empty')); abort(500, __('Coupon cannot be empty'));
} }
$coupon = Coupon::where('code', $request->input('code'))->first(); $couponService = new CouponService($request->input('code'));
if (!$coupon) { $couponService->setPlanId($request->input('plan_id'));
abort(500, __('Invalid coupon')); $couponService->setUserId($request->session()->get('id'));
} $couponService->check();
if ($coupon->limit_use <= 0 && $coupon->limit_use !== NULL) {
abort(500, __('This coupon is no longer available'));
}
if (time() < $coupon->started_at) {
abort(500, __('This coupon has not yet started'));
}
if (time() > $coupon->ended_at) {
abort(500, __('This coupon has expired'));
}
if ($coupon->limit_plan_ids) {
if (!in_array($request->input('plan_id'), $coupon->limit_plan_ids)) {
abort(500, __('The coupon code cannot be used for this subscription'));
}
}
return response([ return response([
'data' => $coupon 'data' => $couponService->getCoupon()
]); ]);
} }
} }

View File

@ -20,6 +20,7 @@ class CouponSave extends FormRequest
'started_at' => 'required|integer', 'started_at' => 'required|integer',
'ended_at' => 'required|integer', 'ended_at' => 'required|integer',
'limit_use' => 'nullable|integer', 'limit_use' => 'nullable|integer',
'limit_use_with_user' => 'nullable|integer',
'limit_plan_ids' => 'nullable|array', 'limit_plan_ids' => 'nullable|array',
'code' => '' 'code' => ''
]; ];

View File

@ -8,27 +8,20 @@ use Illuminate\Support\Facades\DB;
class CouponService class CouponService
{ {
public $order; public $coupon;
public $planId;
public $userId;
public function __construct($code) public function __construct($code)
{ {
$this->coupon = Coupon::where('code', $code)->first(); $this->coupon = Coupon::where('code', $code)->first();
if (!$this->coupon) {
abort(500, '优惠券无效');
}
if ($this->coupon->limit_use <= 0 && $this->coupon->limit_use !== NULL) {
abort(500, '优惠券已无可用次数');
}
if (time() < $this->coupon->started_at) {
abort(500, '优惠券还未到可用时间');
}
if (time() > $this->coupon->ended_at) {
abort(500, '优惠券已过期');
}
} }
public function use(Order $order) public function use(Order $order)
{ {
$this->setPlanId($order->plan_id);
$this->setUserId($order->user_id);
$this->check();
switch ($this->coupon->type) { switch ($this->coupon->type) {
case 1: case 1:
$order->discount_amount = $this->coupon->value; $order->discount_amount = $this->coupon->value;
@ -43,11 +36,6 @@ class CouponService
return false; return false;
} }
} }
if ($this->coupon->limit_plan_ids) {
if (!in_array($order->plan_id, $this->coupon->limit_plan_ids)) {
return false;
}
}
return true; return true;
} }
@ -55,4 +43,57 @@ class CouponService
{ {
return $this->coupon->id; return $this->coupon->id;
} }
public function getCoupon()
{
return $this->coupon;
}
public function setPlanId($planId)
{
$this->planId = $planId;
}
public function setUserId($userId)
{
$this->userId = $userId;
}
public function checkLimitUseWithUser()
{
$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()
{
if (!$this->coupon) {
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'));
}
}
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
]));
}
}
}
} }

View File

@ -27,6 +27,7 @@ CREATE TABLE `v2_coupon` (
`type` tinyint(1) NOT NULL, `type` tinyint(1) NOT NULL,
`value` int(11) NOT NULL, `value` int(11) NOT NULL,
`limit_use` int(11) DEFAULT NULL, `limit_use` int(11) DEFAULT NULL,
`limit_use_with_user` int(11) DEFAULT NULL,
`limit_plan_ids` varchar(255) DEFAULT NULL, `limit_plan_ids` varchar(255) DEFAULT NULL,
`started_at` int(11) NOT NULL, `started_at` int(11) NOT NULL,
`ended_at` int(11) NOT NULL, `ended_at` int(11) NOT NULL,
@ -351,4 +352,4 @@ CREATE TABLE `v2_user` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 2021-08-18 12:22:48 -- 2021-08-28 06:53:57

View File

@ -435,3 +435,6 @@ ADD INDEX `server_id` (`server_id`);
ALTER TABLE `v2_ticket_message` ALTER TABLE `v2_ticket_message`
CHANGE `message` `message` text COLLATE 'utf8mb4_general_ci' NOT NULL AFTER `ticket_id`; CHANGE `message` `message` text COLLATE 'utf8mb4_general_ci' NOT NULL AFTER `ticket_id`;
ALTER TABLE `v2_coupon`
ADD `limit_use_with_user` int(11) NULL AFTER `limit_use`;

File diff suppressed because one or more lines are too long

View File

@ -84,5 +84,6 @@
"Email format is incorrect": "Email format is incorrect", "Email format is incorrect": "Email format is incorrect",
"Password can not be empty": "Password can not be empty", "Password can not be empty": "Password can not be empty",
"The traffic usage in :app_name has reached 80%": "The traffic usage in :app_name has reached 80%", "The traffic usage in :app_name has reached 80%": "The traffic usage in :app_name has reached 80%",
"The service in :app_name is about to expire": "The service in :app_name is about to expire" "The service in :app_name is about to expire": "The service in :app_name is about to expire",
"The coupon can only be used :limit_use_with_user per person": "The coupon can only be used :limit_use_with_user per person"
} }

View File

@ -84,5 +84,6 @@
"Email format is incorrect": "邮箱格式不正确", "Email format is incorrect": "邮箱格式不正确",
"Password can not be empty": "密码不能为空", "Password can not be empty": "密码不能为空",
"The traffic usage in :app_name has reached 80%": "在:app_name的流量使用已达到80%", "The traffic usage in :app_name has reached 80%": "在:app_name的流量使用已达到80%",
"The service in :app_name is about to expire": "在:app_name的服务即将到期" "The service in :app_name is about to expire": "在:app_name的服务即将到期",
"The coupon can only be used :limit_use_with_user per person": "该优惠券每人只能用:limit_use_with_user次"
} }