Update: 2026-05-07 03:23:32

This commit is contained in:
Hamza-Ayed
2026-05-07 03:23:32 +03:00
parent a7915bab46
commit 440c8c1633
4 changed files with 35 additions and 11 deletions

View File

@@ -16,8 +16,8 @@ $db = Database::getInstance();
try {
$stmt = $db->prepare("
SELECT pr.id, pr.plan_id, pr.amount_jod, pr.reference_number, pr.cliq_alias,
pr.status, pr.ai_match_score, pr.created_at, pr.verified_at,
SELECT pr.id, pr.plan_id, pr.amount_jod, pr.internal_reference, pr.cliq_alias,
pr.bank_reference, pr.status, pr.created_at, pr.verified_at,
sp.name_ar AS plan_name
FROM payment_requests pr
LEFT JOIN subscription_plans sp ON pr.plan_id = sp.id
@@ -27,9 +27,14 @@ try {
$stmt->execute([$tenantId]);
$requests = $stmt->fetchAll();
// Map internal_reference to reference_number for Flutter compatibility
foreach ($requests as &$req) {
$req['reference_number'] = $req['internal_reference'];
}
json_success($requests, 'طلبات الدفع الخاصة بك');
} catch (\Exception $e) {
} catch (\Throwable $e) {
error_log("My Payment Requests Error: " . $e->getMessage());
json_error('حدث خطأ أثناء جلب طلبات الدفع.', 500);
}

View File

@@ -54,7 +54,7 @@ try {
// Recent payments (last 10)
$stmt = $db->query("
SELECT pr.id, pr.amount_jod, pr.status, pr.reference_number, pr.ai_match_score, pr.created_at, pr.verified_at,
SELECT pr.id, pr.amount_jod, pr.status, pr.internal_reference, pr.bank_reference, pr.created_at, pr.verified_at,
u.name AS payer_name, sp.name_ar AS plan_name
FROM payment_requests pr
LEFT JOIN users u ON pr.user_id = u.id

View File

@@ -1,5 +1,7 @@
import 'package:get/get.dart';
import 'package:dio/dio.dart';
import '../../../core/network/dio_client.dart';
import '../../../core/utils/app_snackbar.dart';
import '../../../core/utils/logger.dart';
class SubscriptionController extends GetxController {
@@ -54,7 +56,9 @@ class SubscriptionController extends GetxController {
if (res.data['success'] == true && res.data['data'] != null) {
myPayments.value = List<Map<String, dynamic>>.from(res.data['data']);
// Check for active pending payment
final pending = myPayments.firstWhereOrNull((p) => p['status'] == 'pending');
final pending = myPayments.firstWhereOrNull(
(p) => p['status'] == 'pending' || p['status'] == 'uploaded',
);
activePaymentRequest.value = pending;
}
} catch (e) {
@@ -72,6 +76,21 @@ class SubscriptionController extends GetxController {
await loadMyPayments();
return result;
}
} on DioException catch (e) {
if (e.response?.statusCode == 409) {
// Already has a pending payment — show existing one
AppSnackbar.showWarning(
'طلب قائم',
'لديك طلب دفع قائم بالفعل. قم بإتمامه أو انتظر المراجعة.',
);
// Navigate to the existing pending payment
if (activePaymentRequest.value != null) {
Get.toNamed('/payment-receipt', arguments: activePaymentRequest.value);
}
} else {
AppLogger.error('Failed to create payment', e);
AppSnackbar.showError('خطأ', e.response?.data?['message'] ?? 'فشل إنشاء طلب الدفع');
}
} catch (e) {
AppLogger.error('Failed to create payment', e);
} finally {

View File

@@ -86,10 +86,11 @@ class SubscriptionView extends StatelessWidget {
}
Widget _buildCurrentPlan(Map<String, dynamic> sub, bool isDark) {
final planName = sub['plan_name'] ?? sub['plan_id'] ?? 'مجانية';
final planName = sub['plan_name'] ?? sub['plan_name_en'] ?? sub['plan_id'] ?? 'مجانية';
final daysLeft = sub['days_remaining'] ?? 0;
final used = sub['invoices_used'] ?? 0;
final limit = sub['invoices_limit'] ?? 0;
final invoices = sub['invoices'] as Map<String, dynamic>?;
final used = invoices?['used'] ?? 0;
final limit = invoices?['limit'] ?? 0;
return Container(
padding: const EdgeInsets.all(20),
@@ -280,9 +281,8 @@ class SubscriptionView extends StatelessWidget {
onPressed: ctrl.isCreatingPayment.value ? null : () async {
final result = await ctrl.createPaymentRequest(plan['id'].toString());
if (result != null) {
AppSnackbar.showSuccess('تم إنشاء طلب الدفع', 'قم بالتحويل عبر CliQ ثم ارفع وصل الدفع');
} else {
AppSnackbar.showError('خطأ', 'فشل إنشاء طلب الدفع');
AppSnackbar.showSuccess('تم إنشاء طلب الدفع', 'قم بالتحويل عبر CliQ ثم أدخل رقم المرجع');
Get.toNamed('/payment-receipt', arguments: result);
}
},
style: ElevatedButton.styleFrom(