|
2 | 2 |
|
3 | 3 | namespace App\Services; |
4 | 4 | use App\Repositories\SettingRepository; |
| 5 | +use App\Repositories\CouponRepository; |
| 6 | +use App\Repositories\WalletRepository; |
| 7 | +use App\Repositories\ReferralRepository; |
| 8 | +use App\Models\Setting; |
| 9 | +use App\Models\User; |
5 | 10 |
|
6 | 11 | class SettingService extends BaseService { |
7 | 12 |
|
8 | 13 | public function __construct( |
9 | | - protected SettingRepository $settingRepository |
| 14 | + protected SettingRepository $settingRepository, |
| 15 | + protected WalletRepository $walletRepository, |
| 16 | + protected CouponRepository $couponRepository, |
| 17 | + protected ReferralRepository $referralRepository |
10 | 18 | ) { parent::__construct($settingRepository); } |
11 | 19 |
|
| 20 | + public function validateCommission ( Setting $commission, User $user, float $amount = null ) { |
| 21 | + |
| 22 | + [$key, $value] = [$commission->key, optional((object) $commission->json_value)]; |
| 23 | + $user = $key === 'referral' ? $this->referralRepository->findReferrer($user) : $user; |
| 24 | + |
| 25 | + if ( |
| 26 | + !$user?->active || |
| 27 | + !$user?->has('allow_commissions') || |
| 28 | + ($value->min_level && $user->level < $value->min_level) || |
| 29 | + ($value->max_level && $user->level > $value->max_level) || |
| 30 | + ($value->min_price && $amount && $amount < $value->min_price) || |
| 31 | + ($value->max_price && $amount && $amount > $value->max_price) || |
| 32 | + ( !is_null($value->max_usages) && $value->max_usages <= 0 ) |
| 33 | + ) return; |
| 34 | + |
| 35 | + return [$key, $value, $user]; |
| 36 | + |
| 37 | + } |
| 38 | + public function contextCommission ( Setting $commission, User $user, float $amount = null ) { |
| 39 | + |
| 40 | + if ( !$context = $this->validateCommission($commission, $user, $amount) ) return; |
| 41 | + [$key, $value, $user] = $context; |
| 42 | + |
| 43 | + $isFixed = $value->amount_type === 'fixed'; |
| 44 | + $perUnit = $value->scope === 'unit'; |
| 45 | + $balance = string($value->balance ?? 'buy'); |
| 46 | + $type = string($value->type); |
| 47 | + $couponId = integer($value->coupon_id); |
| 48 | + |
| 49 | + $ValPoints = positive($value->points); |
| 50 | + $valAmount = positive($value->amount); |
| 51 | + $maxAmount = positive($value->max_amount); |
| 52 | + $maxPoints = positive($value->max_points); |
| 53 | + $mainAmount = positive($amount); |
| 54 | + |
| 55 | + $amount = positive($isFixed ? $valAmount : $mainAmount * $valAmount / 100); |
| 56 | + $amount = positive($perUnit ? $amount * $mainAmount : $amount); |
| 57 | + $points = floor($perUnit ? $ValPoints * $mainAmount : $ValPoints); |
| 58 | + $amount = $maxAmount ? min($maxAmount, $amount) : $amount; |
| 59 | + $points = $maxPoints ? min($maxPoints, $points) : $points; |
| 60 | + |
| 61 | + $wallet = $type !== 'coupon' ? $user->wallet : null; |
| 62 | + $coupon = $type === 'coupon' ? $this->couponRepository->find($couponId) : null; |
| 63 | + |
| 64 | + return [ |
| 65 | + 'user' => $user, |
| 66 | + 'wallet' => $wallet, |
| 67 | + 'coupon' => $coupon, |
| 68 | + 'key' => $key, |
| 69 | + 'type' => $type, |
| 70 | + 'balance' => $balance, |
| 71 | + 'amount' => $amount, |
| 72 | + 'points' => $points, |
| 73 | + ]; |
| 74 | + |
| 75 | + } |
| 76 | + public function applyCommission ( Setting $commission, User $user, float $amount = null ) { |
| 77 | + |
| 78 | + if ( !$context = $this->contextCommission($commission, $user, $amount) ) return; |
| 79 | + |
| 80 | + $key = $context['key']; |
| 81 | + $type = $context['type']; |
| 82 | + $amount = $context['amount']; |
| 83 | + $points = $context['points']; |
| 84 | + $balance = $context['balance']; |
| 85 | + $user = $context['user']; |
| 86 | + $wallet = $context['wallet']; |
| 87 | + $coupon = $context['coupon']; |
| 88 | + |
| 89 | + $result = match ( $type ) { |
| 90 | + 'coupon' => $coupon ? $this->couponRepository->redeem($coupon, $user) : null, |
| 91 | + 'points' => $wallet && $this->walletRepository->addPoints($wallet, $points) ? $points : null, |
| 92 | + 'amount' => $wallet && $this->walletRepository->addCommission($wallet, $amount, $balance, $key) ? $amount : null, |
| 93 | + default => null, |
| 94 | + }; |
| 95 | + |
| 96 | + return $result ? [...$context, 'value' => $result] : null; |
| 97 | + |
| 98 | + } |
| 99 | + public function resolveCommission ( User $user, string $key, float $amount = null ) { |
| 100 | + |
| 101 | + $record = $this->query()->where('group', 'commission')->where('key', $key)->active()->latest()->first(); |
| 102 | + return $record ? $this->applyCommission($record, $user, $amount) : null; |
| 103 | + |
| 104 | + } |
| 105 | + public function handleCommission ( User $user, string $key, float $amount = null, bool $queue = true ) { |
| 106 | + |
| 107 | + if ( !$queue ) return $this->resolveCommission($user, $key, $amount); |
| 108 | + return $this->runJob([static::class, 'resolveCommission'], [$user, $key, $amount]); |
| 109 | + |
| 110 | + } |
| 111 | + public function handleCommissions ( User $user, array $keys, float $amount = null, bool $queue = true ) { |
| 112 | + |
| 113 | + return collect($keys)->filter()->map(fn($key) => $this->handleCommission($user, $key, $amount, $queue))->all(); |
| 114 | + |
| 115 | + } |
| 116 | + |
12 | 117 | } |
0 commit comments