117 lines
3.6 KiB
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;
|
|
}
|
|
}
|