|
|
@ -5,12 +5,13 @@ namespace App\Listeners; |
|
|
|
use App\Models\User; |
|
|
|
use App\Models\Business; |
|
|
|
use Illuminate\Support\Arr; |
|
|
|
use App\Channels\FcmChannel; |
|
|
|
use App\Events\BusinessUpdate; |
|
|
|
use App\Events\BusinessUserCreate; |
|
|
|
use App\Notifications\DBNotification; |
|
|
|
use App\Notifications\FcmNotification; |
|
|
|
use App\Notifications\MailNotification; |
|
|
|
use Illuminate\Queue\InteractsWithQueue; |
|
|
|
|
|
|
|
use Illuminate\Contracts\Queue\ShouldQueue; |
|
|
|
use Illuminate\Support\Facades\Notification; |
|
|
|
|
|
|
@ -19,14 +20,68 @@ class BusinessUpdateListener |
|
|
|
public function handle(BusinessUpdate $event) |
|
|
|
{ |
|
|
|
$payload = $event->message; |
|
|
|
$business = Business::findOrFail($payload->business)->load('owners'); |
|
|
|
|
|
|
|
$this->checkWalletIsRunningLow($business); |
|
|
|
$this->checkWalletIsEmptyOrNegative($business); |
|
|
|
$this->accountHasBeenSuspended($business); |
|
|
|
} |
|
|
|
|
|
|
|
public function checkWalletIsRunningLow(Business $business): void |
|
|
|
{ |
|
|
|
$moving_average_days = 7; |
|
|
|
$predict_ahead_hours = 24; |
|
|
|
|
|
|
|
$hours = $moving_average_days * 24; |
|
|
|
$business->load([ |
|
|
|
'cost' => fn ($query) => $query->where('created_at', '>=', now('Asia/Tehran')->subHours($hours)), |
|
|
|
]); |
|
|
|
|
|
|
|
// The wallet is running out
|
|
|
|
// Calculate the average consumption of the N past days
|
|
|
|
$average_cost = $business->cost->sum('cost') / $hours; |
|
|
|
|
|
|
|
// Average hourly consumption multiplied by the next 24 hours
|
|
|
|
// If the account does not charge as much as in the next 24 hours, notified.
|
|
|
|
$message = ['body' => __('notification.business.wallet_almost_empty')]; |
|
|
|
if (($business->wallet / $predict_ahead_hours) < $average_cost) { |
|
|
|
Notification::send($business->owners, new MailNotification($message)); |
|
|
|
Notification::send($business->owners, new DBNotification($message)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public function checkWalletIsEmptyOrNegative(Business $business): void |
|
|
|
{ |
|
|
|
$message = ['body' => __('notification.business.wallet_empty')]; |
|
|
|
if ($business->wallet <= 0) { |
|
|
|
Notification::send($business->owners, new MailNotification($message)); |
|
|
|
Notification::send($business->owners, new DBNotification($message)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public function accountHasBeenSuspended(Business $business): void |
|
|
|
{ |
|
|
|
if ($business->wallet > 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
$recent_payments_number = 10; |
|
|
|
$negativity_threshold = 20; |
|
|
|
$business->load([ |
|
|
|
'transactions' => fn ($query) => $query->where('succeeded', '=', true) |
|
|
|
->orderBy('created_at') |
|
|
|
->take($recent_payments_number), |
|
|
|
]); |
|
|
|
|
|
|
|
$wallet = $payload?->data?->diff?->wallet; |
|
|
|
$owners = Business::findOrFail($payload->business)->owners; |
|
|
|
$message = ['body' => 'Test']; |
|
|
|
// Your account has been blocked.
|
|
|
|
// What is the average of the last 10 payments?
|
|
|
|
$average_payment = $business->transactions->average('amount'); |
|
|
|
|
|
|
|
if ($wallet < 0) { |
|
|
|
Notification::send($owners, new MailNotification($message)); |
|
|
|
Notification::send($owners, new DBNotification($message)); |
|
|
|
$threshold = $average_payment / 100 * $negativity_threshold; |
|
|
|
$message = ['body' => __('notification.business.suspended')]; |
|
|
|
if ($business->wallet < $threshold) { |
|
|
|
Notification::send($business->owners, new MailNotification($message)); |
|
|
|
Notification::send($business->owners, new DBNotification($message)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |