Update: 2026-08-07 06:04:46
This commit is contained in:
@@ -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),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user