feat: استيراد كود سيرو إلى تريبز (سيرو @ecfe7568) — بلا تعديل
قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ. الخريطة: backend · payment_server · loction_server · ride_server · passenger_server · docker · dashboard · stress_test → الجذر siro_rider → apps/rider siro_driver → apps/driver siro_admin → dashboards/admin siro_service → dashboards/service android_bot → apps/android_bot socialBot → apps/socialBot نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب) لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً: كل ما يلي يصير فرقاً مقروءاً مقابل المصدر. لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز، سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh (ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و dashboards/transit-web). ⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة: 1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر): كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner. 2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist) يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً. 3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع → يجب ضمّ الحزم داخله أسوة بـ apps/rider. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9909d9b4c1
commit
4d8414c96b
Executable
+206
@@ -0,0 +1,206 @@
|
||||
// lib/models/model/order_data.dart
|
||||
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class OrderData {
|
||||
final String customerName;
|
||||
final String customerToken;
|
||||
final double tripDistanceKm; // The total trip distance in kilometers
|
||||
final String price;
|
||||
final String startLocationAddress;
|
||||
final String endLocationAddress;
|
||||
|
||||
final double
|
||||
distanceToPassengerKm; // The distance to the passenger in kilometers
|
||||
final int tripDurationMinutes; // Total trip duration in minutes (rounded up)
|
||||
final int
|
||||
durationToPassengerMinutes; // Duration to reach the passenger in minutes (rounded up)
|
||||
|
||||
final String rideType;
|
||||
final String orderId;
|
||||
final String passengerId;
|
||||
final String passengerRate;
|
||||
|
||||
final String? rawStartCoordinates;
|
||||
final String? rawEndCoordinates;
|
||||
|
||||
// 🆕 "أرباحك أعلى" — الفرق الإيجابي بأجرة السائق مقارنة بالمنافس (إن وُجد)
|
||||
final double? driverEarningsExtra;
|
||||
final String? driverEarningsCurrency;
|
||||
|
||||
OrderData({
|
||||
required this.customerName,
|
||||
required this.customerToken,
|
||||
required this.tripDistanceKm,
|
||||
required this.price,
|
||||
required this.startLocationAddress,
|
||||
required this.endLocationAddress,
|
||||
required this.distanceToPassengerKm,
|
||||
required this.tripDurationMinutes,
|
||||
required this.durationToPassengerMinutes,
|
||||
required this.rideType,
|
||||
required this.orderId,
|
||||
required this.passengerId,
|
||||
required this.passengerRate,
|
||||
this.rawStartCoordinates,
|
||||
this.rawEndCoordinates,
|
||||
this.driverEarningsExtra,
|
||||
this.driverEarningsCurrency,
|
||||
});
|
||||
|
||||
// --- NEW: Factory constructor to create an instance from a Map ---
|
||||
// This is the missing method that was causing the error.
|
||||
factory OrderData.fromMap(Map<String, dynamic> map) {
|
||||
return OrderData(
|
||||
// For strings, provide a default value in case the map key is null
|
||||
customerName: map['customerName']?.toString() ?? 'Unknown Customer',
|
||||
customerToken: map['customerToken']?.toString() ?? 'Unknown token',
|
||||
|
||||
// For numbers, cast from 'num' to handle both int and double, with a default value
|
||||
tripDistanceKm: (map['tripDistanceKm'] as num?)?.toDouble() ?? 0.0,
|
||||
|
||||
price: map['price']?.toString() ?? '0',
|
||||
startLocationAddress:
|
||||
map['startLocationAddress']?.toString() ?? 'Unknown Address',
|
||||
endLocationAddress:
|
||||
map['endLocationAddress']?.toString() ?? 'Unknown Address',
|
||||
|
||||
distanceToPassengerKm:
|
||||
(map['distanceToPassengerKm'] as num?)?.toDouble() ?? 0.0,
|
||||
|
||||
tripDurationMinutes: (map['tripDurationMinutes'] as num?)?.toInt() ?? 0,
|
||||
durationToPassengerMinutes:
|
||||
(map['durationToPassengerMinutes'] as num?)?.toInt() ?? 0,
|
||||
|
||||
rideType: map['rideType']?.toString() ?? 'Unknown',
|
||||
orderId: map['orderId']?.toString() ?? 'N/A',
|
||||
passengerId: map['passengerId']?.toString() ?? 'N/A',
|
||||
passengerRate: map['passengerRate']?.toString() ?? 'N/A',
|
||||
|
||||
// For nullable strings, direct access is fine as it returns null if the key doesn't exist
|
||||
rawStartCoordinates: map['rawStartCoordinates'],
|
||||
rawEndCoordinates: map['rawEndCoordinates'],
|
||||
driverEarningsExtra: (map['driverEarningsExtra'] as num?)?.toDouble(),
|
||||
driverEarningsCurrency: map['driverEarningsCurrency']?.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
// A helper function to convert seconds to rounded-up minutes
|
||||
static int _secondsToRoundedUpMinutes(String secondsString) {
|
||||
final seconds = double.tryParse(secondsString) ?? 0.0;
|
||||
if (seconds <= 0) return 0;
|
||||
return (seconds / 60)
|
||||
.ceil(); // .ceil() rounds up (e.g., 0.1 minutes becomes 1 minute)
|
||||
}
|
||||
|
||||
// Your existing factory for creating an instance from a List
|
||||
factory OrderData.fromList(List<dynamic> list) {
|
||||
double distanceToPassengerMeters =
|
||||
list.length > 12 ? (double.tryParse(list[12].toString()) ?? 0.0) : 0.0;
|
||||
|
||||
return OrderData(
|
||||
customerName: list.length > 8 ? list[8].toString() : 'Unknown Customer',
|
||||
customerToken: list.length > 9 ? list[9].toString() : 'Unknown token',
|
||||
tripDistanceKm:
|
||||
list.length > 5 ? (double.tryParse(list[5].toString()) ?? 0.0) : 0.0,
|
||||
price: list.length > 2 ? list[2].toString().split('.')[0] : '0',
|
||||
startLocationAddress:
|
||||
list.length > 29 ? list[29].toString() : 'Unknown Address',
|
||||
endLocationAddress:
|
||||
list.length > 30 ? list[30].toString() : 'Unknown Address',
|
||||
|
||||
distanceToPassengerKm:
|
||||
distanceToPassengerMeters / 1000.0, // Convert meters to kilometers
|
||||
|
||||
tripDurationMinutes:
|
||||
list.length > 4 ? _secondsToRoundedUpMinutes(list[4].toString()) : 0,
|
||||
durationToPassengerMinutes: list.length > 15
|
||||
? _secondsToRoundedUpMinutes(list[15].toString())
|
||||
: 0,
|
||||
|
||||
rideType:
|
||||
list.length > 31 ? _getRideType(list[31].toString()) : 'Unknown',
|
||||
orderId: list.length > 16 ? list[16].toString() : 'N/A',
|
||||
passengerId: list.length > 7 ? list[7].toString() : 'N/A',
|
||||
passengerRate: list.length > 33 ? list[33].toString() : 'N/A',
|
||||
|
||||
rawStartCoordinates: list.isNotEmpty ? list[0].toString() : null,
|
||||
rawEndCoordinates: list.length > 1 ? list[1].toString() : null,
|
||||
|
||||
// 🆕 Index 35/36: "أرباحك أعلى"
|
||||
driverEarningsExtra: list.length > 35 && list[35].toString().isNotEmpty
|
||||
? double.tryParse(list[35].toString())
|
||||
: null,
|
||||
driverEarningsCurrency:
|
||||
list.length > 36 && list[36].toString().isNotEmpty
|
||||
? list[36].toString()
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
static String _getRideType(String type) {
|
||||
switch (type) {
|
||||
case 'Comfort':
|
||||
return 'Comfort ❄️'.tr;
|
||||
case 'Lady':
|
||||
return 'Lady 👩'.tr;
|
||||
case 'Speed':
|
||||
return 'Speed 🔻'.tr;
|
||||
case 'Mashwari':
|
||||
return 'Mashwari'.tr;
|
||||
case 'Rayeh Gai':
|
||||
return 'Rayeh Gai'.tr;
|
||||
default:
|
||||
return type.tr;
|
||||
}
|
||||
}
|
||||
|
||||
// Getter to parse start coordinates
|
||||
Map<String, double?>? get startCoordinates {
|
||||
if (rawStartCoordinates == null) return null;
|
||||
final parts = rawStartCoordinates!.split(',');
|
||||
if (parts.length == 2) {
|
||||
return {
|
||||
'lat': double.tryParse(parts[0].trim()),
|
||||
'lng': double.tryParse(parts[1].trim())
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Getter to parse end coordinates
|
||||
Map<String, double?>? get endCoordinates {
|
||||
if (rawEndCoordinates == null) return null;
|
||||
final parts = rawEndCoordinates!.split(',');
|
||||
if (parts.length == 2) {
|
||||
return {
|
||||
'lat': double.tryParse(parts[0].trim()),
|
||||
'lng': double.tryParse(parts[1].trim())
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Your existing method to convert the object TO a Map.
|
||||
// This is used to pass the data from the overlay to the main app.
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'customerName': customerName,
|
||||
'tripDistanceKm': tripDistanceKm,
|
||||
'price': price,
|
||||
'startLocationAddress': startLocationAddress,
|
||||
'endLocationAddress': endLocationAddress,
|
||||
'distanceToPassengerKm': distanceToPassengerKm,
|
||||
'tripDurationMinutes': tripDurationMinutes,
|
||||
'durationToPassengerMinutes': durationToPassengerMinutes,
|
||||
'rideType': rideType,
|
||||
'orderId': orderId,
|
||||
'passengerId': passengerId,
|
||||
'passengerRate': passengerRate,
|
||||
'rawStartCoordinates': rawStartCoordinates,
|
||||
'rawEndCoordinates': rawEndCoordinates,
|
||||
'driverEarningsExtra': driverEarningsExtra,
|
||||
'driverEarningsCurrency': driverEarningsCurrency,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user