204 lines
5.6 KiB
Dart
204 lines
5.6 KiB
Dart
class BusStopModel {
|
|
final String id;
|
|
final String name;
|
|
final double lat;
|
|
final double lng;
|
|
final String? city;
|
|
final String? address;
|
|
final String? parentId;
|
|
final String? side;
|
|
final String stopType;
|
|
final bool hasShelter;
|
|
final bool hasSeating;
|
|
final bool isAccessible;
|
|
final DateTime? createdAt;
|
|
final DateTime? updatedAt;
|
|
|
|
// Route-specific fields (from route_stops junction table)
|
|
final int? stopOrder;
|
|
final int? travelTimeMinutes;
|
|
final bool? isPickupPoint;
|
|
final bool? isDropoffPoint;
|
|
|
|
BusStopModel({
|
|
required this.id,
|
|
required this.name,
|
|
required this.lat,
|
|
required this.lng,
|
|
this.city,
|
|
this.address,
|
|
this.parentId,
|
|
this.side,
|
|
this.stopType = 'regular',
|
|
this.hasShelter = false,
|
|
this.hasSeating = false,
|
|
this.isAccessible = false,
|
|
this.createdAt,
|
|
this.updatedAt,
|
|
this.stopOrder,
|
|
this.travelTimeMinutes,
|
|
this.isPickupPoint,
|
|
this.isDropoffPoint,
|
|
});
|
|
|
|
factory BusStopModel.fromJson(Map<String, dynamic> json) {
|
|
return BusStopModel(
|
|
id: json['id']?.toString() ?? '',
|
|
name: json['name']?.toString() ?? '',
|
|
lat: double.tryParse(json['lat']?.toString() ?? '0') ?? 0.0,
|
|
lng: double.tryParse(json['lng']?.toString() ?? '0') ?? 0.0,
|
|
city: json['city']?.toString(),
|
|
address: json['address']?.toString(),
|
|
parentId: json['parent_id']?.toString(),
|
|
side: json['side']?.toString(),
|
|
stopType: json['stop_type']?.toString() ?? 'regular',
|
|
hasShelter: json['has_shelter'] == true,
|
|
hasSeating: json['has_seating'] == true,
|
|
isAccessible: json['is_accessible'] == true,
|
|
createdAt:
|
|
json['created_at'] != null
|
|
? DateTime.tryParse(json['created_at'].toString())
|
|
: null,
|
|
updatedAt:
|
|
json['updated_at'] != null
|
|
? DateTime.tryParse(json['updated_at'].toString())
|
|
: null,
|
|
stopOrder:
|
|
json['stop_order'] != null
|
|
? int.tryParse(json['stop_order'].toString())
|
|
: null,
|
|
travelTimeMinutes:
|
|
json['travel_time_minutes'] != null
|
|
? int.tryParse(json['travel_time_minutes'].toString())
|
|
: null,
|
|
isPickupPoint: json['is_pickup_point'] == true,
|
|
isDropoffPoint: json['is_dropoff_point'] == true,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'name': name,
|
|
'lat': lat,
|
|
'lng': lng,
|
|
'city': city,
|
|
'address': address,
|
|
'parent_id': parentId,
|
|
'side': side,
|
|
'stop_type': stopType,
|
|
'has_shelter': hasShelter,
|
|
'has_seating': hasSeating,
|
|
'is_accessible': isAccessible,
|
|
'created_at': createdAt?.toIso8601String(),
|
|
'updated_at': updatedAt?.toIso8601String(),
|
|
'stop_order': stopOrder,
|
|
'travel_time_minutes': travelTimeMinutes,
|
|
'is_pickup_point': isPickupPoint,
|
|
'is_dropoff_point': isDropoffPoint,
|
|
};
|
|
}
|
|
|
|
// Helper getters
|
|
String get displayName => name;
|
|
|
|
String get fullAddress {
|
|
if (address != null && address!.isNotEmpty) {
|
|
return city != null ? '$address, $city' : address!;
|
|
}
|
|
return city ?? 'Ubicación desconocida';
|
|
}
|
|
|
|
String get stopTypeDisplay {
|
|
switch (stopType) {
|
|
case 'terminal':
|
|
return 'Terminal';
|
|
case 'express_only':
|
|
return 'Solo Express';
|
|
case 'regular':
|
|
default:
|
|
return 'Parada Regular';
|
|
}
|
|
}
|
|
|
|
List<String> get amenities {
|
|
List<String> amenityList = [];
|
|
if (hasShelter) amenityList.add('Refugio');
|
|
if (hasSeating) amenityList.add('Asientos');
|
|
if (isAccessible) amenityList.add('Accesible');
|
|
return amenityList;
|
|
}
|
|
|
|
String get amenitiesText {
|
|
final amenityList = amenities;
|
|
if (amenityList.isEmpty) return 'Sin servicios especiales';
|
|
return amenityList.join(', ');
|
|
}
|
|
|
|
bool get isTerminal => stopType == 'terminal';
|
|
bool get isExpressOnly => stopType == 'express_only';
|
|
|
|
String get travelTimeText {
|
|
if (travelTimeMinutes != null && travelTimeMinutes! > 0) {
|
|
return '${travelTimeMinutes} min';
|
|
}
|
|
return 'N/A';
|
|
}
|
|
|
|
BusStopModel copyWith({
|
|
String? id,
|
|
String? name,
|
|
double? lat,
|
|
double? lng,
|
|
String? city,
|
|
String? address,
|
|
String? parentId,
|
|
String? side,
|
|
String? stopType,
|
|
bool? hasShelter,
|
|
bool? hasSeating,
|
|
bool? isAccessible,
|
|
DateTime? createdAt,
|
|
DateTime? updatedAt,
|
|
int? stopOrder,
|
|
int? travelTimeMinutes,
|
|
bool? isPickupPoint,
|
|
bool? isDropoffPoint,
|
|
}) {
|
|
return BusStopModel(
|
|
id: id ?? this.id,
|
|
name: name ?? this.name,
|
|
lat: lat ?? this.lat,
|
|
lng: lng ?? this.lng,
|
|
city: city ?? this.city,
|
|
address: address ?? this.address,
|
|
parentId: parentId ?? this.parentId,
|
|
side: side ?? this.side,
|
|
stopType: stopType ?? this.stopType,
|
|
hasShelter: hasShelter ?? this.hasShelter,
|
|
hasSeating: hasSeating ?? this.hasSeating,
|
|
isAccessible: isAccessible ?? this.isAccessible,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
updatedAt: updatedAt ?? this.updatedAt,
|
|
stopOrder: stopOrder ?? this.stopOrder,
|
|
travelTimeMinutes: travelTimeMinutes ?? this.travelTimeMinutes,
|
|
isPickupPoint: isPickupPoint ?? this.isPickupPoint,
|
|
isDropoffPoint: isDropoffPoint ?? this.isDropoffPoint,
|
|
);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BusStopModel(id: $id, name: $name, city: $city, stopType: $stopType)';
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
return other is BusStopModel && other.id == id;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => id.hashCode;
|
|
}
|