feat: improve planning engine travel handling, itinerary reordering, and scenario planners
Add TravelInfo initializers and city normalization helpers to fix repeat city-pair disambiguation. Improve drag-and-drop reordering with segment index tracking and source-row-aware zone calculation. Enhance all five scenario planners with better next-day departure handling and travel segment placement. Add comprehensive tests across all planners. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -831,21 +831,23 @@ enum ItineraryReorderingLogic {
|
||||
in travelValidRanges: [String: ClosedRange<Int>],
|
||||
model: ItineraryItem? = nil
|
||||
) -> String {
|
||||
let suffix = "\(segment.fromLocation.name.lowercased())->\(segment.toLocation.name.lowercased())"
|
||||
let from = TravelInfo.normalizeCityName(segment.fromLocation.name)
|
||||
let to = TravelInfo.normalizeCityName(segment.toLocation.name)
|
||||
let suffix = "\(from)->\(to)"
|
||||
let matchingKeys = travelValidRanges.keys.filter { $0.hasSuffix(suffix) }
|
||||
|
||||
if let segIdx = model?.travelInfo?.segmentIndex {
|
||||
let indexedKey = "travel:\(segIdx):\(suffix)"
|
||||
if matchingKeys.contains(indexedKey) {
|
||||
return indexedKey
|
||||
}
|
||||
return indexedKey
|
||||
}
|
||||
|
||||
if matchingKeys.count == 1, let key = matchingKeys.first {
|
||||
return key
|
||||
}
|
||||
|
||||
// Multiple matches (repeat city pair) — use segmentIndex from model to disambiguate
|
||||
if let segIdx = model?.travelInfo?.segmentIndex {
|
||||
let expected = "travel:\(segIdx):\(suffix)"
|
||||
if matchingKeys.contains(expected) {
|
||||
return expected
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: return first match or construct without index
|
||||
return matchingKeys.first ?? "travel:\(suffix)"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user