Update: 2026-08-07 06:04:46

This commit is contained in:
Hamza-Ayed
2026-08-07 06:04:46 +03:00
parent 92a6aa5c0f
commit d691e51ba4
3 changed files with 123 additions and 9 deletions
@@ -0,0 +1,12 @@
-- 2026_08_07_verify_food.sql — فحص حالة ترحيلات الطعام
--
-- ‏قراءة خالصة لا تُعدّل شيئاً.
-- sirodb siro_food < backend/food/migrations/2026_08_07_verify_food.sql
SELECT 'TABLE food_courier_settlements' AS item,
COUNT(*) AS ok FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='food_courier_settlements'
UNION ALL SELECT 'food_order_payments.settlement_id', COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='food_order_payments' AND COLUMN_NAME='settlement_id'
UNION ALL SELECT 'food_order_payments.idx_settlement', COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='food_order_payments' AND INDEX_NAME='idx_settlement';
@@ -30,6 +30,8 @@ import '../../../services/ride_live_notification.dart';
import '../../../views/home/map_page_passenger.dart';
import '../../../views/Rate/rate_captain.dart';
import '../../../views/Rate/rating_driver_bottom.dart';
import '../../../views/scheduled/scheduled_rides_page.dart';
import '../../scheduled/scheduled_rides_controller.dart';
import '../../../views/widgets/mydialoug.dart';
import '../../../views/widgets/elevated_btn.dart';
import '../../../views/home/map_widget.dart/car_details_widget_to_go.dart';
@@ -759,6 +761,84 @@ class RideLifecycleController extends GetxController {
bool _isRideBeginLogicExecuted = false;
String driversStatusForSearchWindow = '';
/// ‏يفتح منتقي الموعد ثم يُنشئ حجزاً بدل رحلة فورية.
///
/// ‏المسار موازٍ لـ startSearchingForDriver لا بديل عنه: الحجز لا يفتح
/// ‏نافذة بحث ولا يوصل السوكِت ولا ينتظر سائقاً — يسجّل نيّة سفر فقط،
/// ‏ويتولّى الكرون تحويلها لرحلة قبل الموعد بهامش.
Future<void> scheduleRideForLater() async {
if (mapEngine.polylineCoordinates.isEmpty) {
mySnackbarWarning('حدّد وجهتك أولاً'.tr);
return;
}
final ctrl = Get.put(ScheduledRidesController());
final picked = await _pickScheduleTime(ctrl);
if (picked == null) return;
final startLoc = mapEngine.polylineCoordinates.first;
final endLoc = mapEngine.polylineCoordinates.last;
final ok = await ctrl.create(
startLocation: '${startLoc.latitude},${startLoc.longitude}',
endLocation: '${endLoc.latitude},${endLoc.longitude}',
startName: startNameAddress,
endName: endNameAddress,
carType: box.read(BoxName.carType)?.toString() ?? 'Speed',
distanceKm: double.tryParse(distance.toString()) ?? 0,
// ‏duration بالثواني (سطر 102) — نفس ما يُرسل في postRideDetailsToServer.
durationSeconds: duration.round(),
estimatedPrice: double.tryParse(totalPassenger.toString()) ?? 0,
when: picked,
);
if (ok) {
// ‏نعيد الخريطة لحالتها الخاملة: الحجز ليس رحلة جارية، وإبقاء
// ‏المسار مرسوماً يوهم الراكب أن سائقاً في طريقه إليه الآن.
restCounter();
currentRideState.value = RideState.noRide;
update();
Get.to(() => const ScheduledRidesPage());
}
}
/// ‏منتقي التاريخ ثم الوقت، محصور بحدود الخادم.
///
/// ‏الحصر في المنتقي نفسه لا بعده: عرض مواعيد يرفضها الخادم ثم إظهار
/// ‏خطأ تجربة سيئة، ومنعها من الأساس أوضح.
Future<DateTime?> _pickScheduleTime(ScheduledRidesController ctrl) async {
final now = DateTime.now();
final date = await showDatePicker(
context: Get.context!,
initialDate: ctrl.earliest,
firstDate: now,
lastDate: ctrl.latest,
helpText: 'موعد الرحلة'.tr,
);
if (date == null) return null;
final time = await showTimePicker(
context: Get.context!,
initialTime: TimeOfDay.fromDateTime(ctrl.earliest),
helpText: 'وقت الانطلاق'.tr,
);
if (time == null) return null;
final picked =
DateTime(date.year, date.month, date.day, time.hour, time.minute);
// ‏منتقي التاريخ يحصر اليوم لا الساعة، فقد يختار الراكب يوماً صالحاً
// ‏بساعة ماضية أو قريبة جداً.
if (picked.isBefore(ctrl.earliest)) {
mySnackbarWarning(
'اختر موعداً بعد ${ScheduledRidesController.minLeadMinutes} دقيقة على الأقل'.tr);
return null;
}
return picked;
}
void startSearchingForDriver() async {
if (currentRideState.value == RideState.searching) return;
@@ -120,7 +120,9 @@ class CashConfirmPageShown extends StatelessWidget {
}
// في كل الحالات الأخرى (كاش، أو محفظة برصيد كافٍ)
else {
return MyElevatedButton(
return Column(
children: [
MyElevatedButton(
title: 'Confirm & Find a Ride'.tr,
onPressed: () {
// --- نفس منطقك القديم بالضبط ---
@@ -129,6 +131,26 @@ class CashConfirmPageShown extends StatelessWidget {
controller.startSearchingForDriver();
// controller.update();
},
),
const SizedBox(height: 6),
// ‏مسار موازٍ لا بديل: الحجز لا يفتح نافذة بحث ولا
// ‏ينتظر سائقاً — يسجّل موعداً ويتولّاه الخادم.
// ‏ثانوي بصرياً عمداً: الرحلة الفورية تبقى الافتراض.
TextButton.icon(
onPressed: () {
controller.changeCashConfirmPageShown();
controller.scheduleRideForLater();
},
icon: Icon(Icons.schedule,
size: 18, color: AppColor.primaryColor),
label: Text(
'احجزها لوقت لاحق'.tr,
style: TextStyle(
color: AppColor.primaryColor,
fontWeight: FontWeight.w600),
),
),
],
);
}
}),