onQueue(config('restaurant-delivery.queue.queues.earnings', 'restaurant-delivery-earnings')); } /** * Execute the job. */ public function handle(): void { // Get pending earnings $pendingEarnings = $this->rider->earnings() ->where('status', 'pending') ->whereNull('payout_id') ->get(); if ($pendingEarnings->isEmpty()) { Log::info('No pending earnings for rider', [ 'rider_id' => $this->rider->id, ]); return; } // Calculate total $totalAmount = $pendingEarnings->sum('net_amount'); $minimumPayout = config('restaurant-delivery.earnings.payout.minimum_amount', 500); if ($totalAmount < $minimumPayout) { Log::info('Pending amount below minimum payout threshold', [ 'rider_id' => $this->rider->id, 'pending_amount' => $totalAmount, 'minimum' => $minimumPayout, ]); return; } try { DB::transaction(function () use ($pendingEarnings, $totalAmount) { // Create payout record $payout = RiderPayout::create([ 'rider_id' => $this->rider->id, 'restaurant_id' => $this->rider->restaurant_id, 'amount' => $totalAmount, 'currency' => config('restaurant-delivery.pricing.currency', 'BDT'), 'payment_method' => $this->paymentMethod ?? $this->rider->preferred_payment_method, 'payment_details' => $this->getPaymentDetails(), 'status' => 'pending', 'earnings_count' => $pendingEarnings->count(), 'period_start' => $pendingEarnings->min('earned_at'), 'period_end' => $pendingEarnings->max('earned_at'), ]); // Link earnings to payout RiderEarning::whereIn('id', $pendingEarnings->pluck('id')) ->update([ 'payout_id' => $payout->id, 'status' => 'processing', ]); Log::info('Payout created for rider', [ 'payout_id' => $payout->id, 'rider_id' => $this->rider->id, 'amount' => $totalAmount, 'earnings_count' => $pendingEarnings->count(), ]); }); } catch (\Exception $e) { Log::error('Failed to create payout', [ 'rider_id' => $this->rider->id, 'error' => $e->getMessage(), ]); throw $e; } } /** * Get payment details based on payment method. */ protected function getPaymentDetails(): array { $method = $this->paymentMethod ?? $this->rider->preferred_payment_method; return match ($method) { 'bank_transfer' => [ 'bank_name' => $this->rider->bank_name, 'account_number' => $this->rider->bank_account_number, 'branch' => $this->rider->bank_branch, ], 'bkash', 'nagad', 'rocket' => [ 'provider' => $method, 'number' => $this->rider->mobile_banking_number, ], default => [], }; } /** * Handle a job failure. */ public function failed(\Throwable $exception): void { Log::error('Payout processing job failed', [ 'rider_id' => $this->rider->id, 'error' => $exception->getMessage(), ]); } }