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), ]); // Your account has been blocked. // What is the average of the last 10 payments? $average_payment = $business->transactions->average('amount'); $threshold = $average_payment / 100 * $negativity_threshold; $message = ['body' => __('notification.business.suspended')]; if ($business->wallet < $threshold) { $business->update(['suspended_at' => now(),]); Notification::send($business->owners, new MailNotification($message)); Notification::send($business->owners, new DBNotification($message)); } } }