Implement a comprehensive notification system using Kavenegar SMS
gateway and enhance system traceability through audit logging and
detailed shipment status history.
- SMS Integration:
- Add Kavenegar SMS service with configurable API keys and sender
numbers via system settings.
- Implement automated SMS notifications for shipment approval,
rejection, successful payments, and tracking updates.
- Add administrative UI in Filament to manage SMS gateway settings
and toggle specific notification types.
- Audit & Tracking:
- Apply `Auditable` trait to core models (User, Shipment, Wallet,
etc.) to track changes.
- Refactor `ShipmentStatusHistory` to include status transitions
(`from_status` to `to_status`) and specific reasons for changes.
- Implement `ShipmentObserver` to automate notification triggers
on status changes.
- Database & Config:
- Add migrations for enhanced shipment status history tracking.
- Update `.env.example` and `config/ifnex.php` with Kavenegar
configuration parameters.
138 lines
4.8 KiB
PHP
138 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\User;
|
|
use App\Models\Shipment;
|
|
use App\Models\WalletTransaction;
|
|
use App\Enums\ShipmentStatus;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class CustomerFinancialController extends Controller
|
|
{
|
|
/**
|
|
* جستجوی مشتری بر اساس نام یا ایمیل
|
|
* GET /api/v1/staff/customers/search?q=search_term
|
|
*/
|
|
public function search(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'q' => ['required', 'string', 'min:2'],
|
|
]);
|
|
|
|
$query = User::query()
|
|
->where(function ($q) use ($validated) {
|
|
$q->where('name', 'LIKE', "%{$validated['q']}%")
|
|
->orWhere('email', 'LIKE', "%{$validated['q']}%")
|
|
->orWhere('phone', 'LIKE', "%{$validated['q']}%");
|
|
})
|
|
->with('wallet');
|
|
|
|
$customers = $query->take(20)->get()->map(function ($customer) {
|
|
return [
|
|
'id' => $customer->id,
|
|
'name' => $customer->name,
|
|
'email' => $customer->email,
|
|
'phone' => $customer->phone,
|
|
'wallet_balance' => $customer->wallet ? $customer->wallet->balance : 0,
|
|
];
|
|
});
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $customers,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* دریافت وضعیت مالی کامل مشتری
|
|
* GET /api/v1/staff/customers/{customer}/financial-status
|
|
*/
|
|
public function financialStatus(User $customer): JsonResponse
|
|
{
|
|
// دریافت سفارشات در انتظار پرداخت (تأیید شده)
|
|
$pending_orders = Shipment::where('user_id', $customer->id)
|
|
->where('status', ShipmentStatus::Approved)
|
|
->with(['fromCountry', 'toCountry'])
|
|
->orderBy('created_at', 'desc')
|
|
->get();
|
|
|
|
// محاسبه بدهی به هر ارز
|
|
$debts_by_currency = $pending_orders->groupBy(function ($order) {
|
|
return $order->fromCountry?->iso_code ?? 'unknown';
|
|
})->map(function ($orders, $currency) {
|
|
return [
|
|
'currency' => $currency,
|
|
'total' => $orders->sum('total_fee'),
|
|
'count' => $orders->count(),
|
|
];
|
|
});
|
|
|
|
// دریافت تراکنشهای اخیر
|
|
$recent_transactions = WalletTransaction::whereHas('wallet', function ($q) use ($customer) {
|
|
$q->where('user_id', $customer->id);
|
|
})
|
|
->orderBy('created_at', 'desc')
|
|
->take(10)
|
|
->get()
|
|
->map(fn ($tx) => [
|
|
'id' => $tx->id,
|
|
'type' => $tx->type,
|
|
'amount' => $tx->amount,
|
|
'description' => $tx->description,
|
|
'created_at' => $tx->created_at->format('Y-m-d H:i'),
|
|
]);
|
|
|
|
// دریافت سفارشات اخیر
|
|
$recent_orders = Shipment::where('user_id', $customer->id)
|
|
->with(['fromCountry', 'toCountry'])
|
|
->orderBy('created_at', 'desc')
|
|
->take(10)
|
|
->get()
|
|
->map(fn ($order) => [
|
|
'id' => $order->id,
|
|
'awb_no' => $order->awb_no,
|
|
'status' => [
|
|
'value' => $order->status?->value,
|
|
'label' => $order->status?->label(),
|
|
],
|
|
'direction' => $order->direction?->value,
|
|
'total_fee' => $order->total_fee,
|
|
'from_country' => $order->fromCountry?->name,
|
|
'to_country' => $order->toCountry?->name,
|
|
'created_at' => $order->created_at->format('Y-m-d H:i'),
|
|
]);
|
|
|
|
// محاسبه کل بدهی
|
|
$total_debt = $pending_orders->sum('total_fee');
|
|
|
|
// موجودی کیف پول
|
|
$wallet_balance = $customer->wallet ? $customer->wallet->balance : 0;
|
|
|
|
// مانده حساب
|
|
$account_balance = $wallet_balance - $total_debt;
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'customer' => [
|
|
'id' => $customer->id,
|
|
'name' => $customer->name,
|
|
'email' => $customer->email,
|
|
'phone' => $customer->phone,
|
|
],
|
|
'financial' => [
|
|
'wallet_balance' => $wallet_balance,
|
|
'total_debt' => $total_debt,
|
|
'account_balance' => $account_balance,
|
|
'debts_by_currency' => array_values($debts_by_currency->toArray()),
|
|
'pending_orders_count' => $pending_orders->count(),
|
|
],
|
|
'recent_transactions' => $recent_transactions,
|
|
'recent_orders' => $recent_orders,
|
|
]);
|
|
}
|
|
}
|