Files
kulakpos_web/public/restaurant/Modules/RestaurantDelivery/app/Console/Commands/ProcessRiderPayouts.php

117 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Modules\RestaurantDelivery\Console\Commands;
use Illuminate\Console\Command;
use Modules\RestaurantDelivery\Jobs\ProcessPayoutJob;
use Modules\RestaurantDelivery\Models\Rider;
class ProcessRiderPayouts extends Command
{
/**
* The name and signature of the console command.
*/
protected $signature = 'delivery:process-payouts
{--rider= : Process payout for specific rider ID}
{--restaurant= : Filter by restaurant ID}
{--payment-method= : Override payment method}
{--dry-run : Show what would be processed without actually processing}';
/**
* The console command description.
*/
protected $description = 'Process pending payouts for riders';
/**
* Execute the console command.
*/
public function handle(): int
{
$riderId = $this->option('rider');
$restaurantId = $this->option('restaurant');
$paymentMethod = $this->option('payment-method');
$dryRun = $this->option('dry-run');
$this->info('Processing rider payouts...');
$query = Rider::query()
->where('status', '!=', 'suspended')
->whereHas('earnings', function ($q) {
$q->where('status', 'pending')
->whereNull('payout_id');
});
if ($riderId) {
$query->where('id', $riderId);
}
if ($restaurantId) {
$query->where('restaurant_id', $restaurantId);
}
$riders = $query->with(['earnings' => function ($q) {
$q->where('status', 'pending')
->whereNull('payout_id');
}])->get();
if ($riders->isEmpty()) {
$this->info('No riders with pending earnings found.');
return self::SUCCESS;
}
$minimumPayout = config('restaurant-delivery.earnings.payout.minimum_amount', 500);
$currency = config('restaurant-delivery.pricing.currency', 'BDT');
$this->info("Found {$riders->count()} riders with pending earnings.");
$this->info("Minimum payout threshold: {$currency} {$minimumPayout}");
$this->newLine();
$processed = 0;
$skipped = 0;
$this->table(
['Rider ID', 'Name', 'Pending Amount', 'Status'],
$riders->map(function ($rider) use ($minimumPayout, $currency, $dryRun, $paymentMethod, &$processed, &$skipped) {
$pendingAmount = $rider->earnings->sum('net_amount');
if ($pendingAmount < $minimumPayout) {
$skipped++;
return [
$rider->id,
$rider->full_name,
"{$currency} ".number_format($pendingAmount, 2),
'Below minimum',
];
}
if (! $dryRun) {
dispatch(new ProcessPayoutJob($rider, $paymentMethod));
}
$processed++;
return [
$rider->id,
$rider->full_name,
"{$currency} ".number_format($pendingAmount, 2),
$dryRun ? 'Would process' : 'Processing',
];
})->toArray()
);
$this->newLine();
if ($dryRun) {
$this->warn("DRY RUN: Would process {$processed} payouts, skip {$skipped} (below minimum).");
} else {
$this->info("Dispatched {$processed} payout jobs, skipped {$skipped} (below minimum).");
}
return self::SUCCESS;
}
}