public Test_TripLifeCycle_Base( string filename, Gateway tripthru, TimeSpan? maxLateness = null, PartnerTrip.Origination? origination = null, PartnerTrip.Origination? service = null, double? locationVerificationTolerance = null) { this.filename = filename; this.tripthru = tripthru; if (maxLateness != null) this.maxLateness = (TimeSpan)maxLateness; if (origination != null) this.origination = origination; if (service != null) this.service = service; if (locationVerificationTolerance != null) this.locationVerificationTolerance = (double)locationVerificationTolerance; PartnerConfiguration configuration = Partner.LoadPartnerConfigurationFromJsonFile(filename); partner = new Partner(configuration.Partner.ClientId, configuration.Partner.Name, new GatewayClientMock(tripthru), configuration.partnerFleets); partner.tripthru.RegisterPartner(partner); }
// TODO: make these more real public double GetPrice(PartnerTrip trip) { return baseCost + (GetDistance(trip) * costPerMile); // once we have the distance it won't be too hard to come up with some prices. }
private void ProcessStatusEnroute(PartnerTrip t) { if (TripServicedByForeignProvider(t)) return; // partner.GetTripStatusFromForeignServiceProvider(t, true); else { UpdateTripDriverLocation(t); if (DriverHasReachedThePickupLocation(t)) MakeTripPickedUp(t); else if (TripStatusUpdateIntervalReached(t)) LogTheNewDriverLocation(t); } }
private bool MissedPeriodReached(PartnerTrip t) { return DateTime.UtcNow > t.pickupTime + missedPeriod; }
private void MakeTripEnroute(PartnerTrip trip) { Logger.Log("Driver is now enroute: " + trip); Logger.Tab(); DateTime eta = UpdateDriverRouteAndGetETA(trip.driver, trip.pickupLocation); trip.UpdateTripStatus(notifyPartner: true, status: Status.Enroute, driverLocation: trip.driver.location, eta: eta); Logger.Untab(); }
void DispatchTrip(PartnerTrip t) { if (TripOriginatedLocally(t)) { if (MissedPeriodReached(t)) { CancelTrip(t); return; } if (TripServicedByForeignProvider(t)) // means serviced through partner return; } // If origination is foreign, then it means we're servicing the trip so we have to process it. if (CriticalPeriodNotYetReached(t)) return; Logger.Log("Ready for dispatch: " + t); Logger.Tab(); if (!TryDispatchTripLocally(t) && TripOriginatedLocally(t)) TryToDispatchToForeignProvider(t); Logger.Untab(); }
private bool DispatchRetryIntervalReached(PartnerTrip t) { return DateTime.UtcNow > t.lastDispatchAttempt + retryInterval; }
private static void UpdateTripDriverLocation(PartnerTrip t) { t.driver.location = t.driver.route.GetCurrentWaypoint(t.driver.routeStartTime, DateTime.UtcNow); }
private static void CancelTrip(PartnerTrip t) { Logger.Log("Missed period reached: -- so cancel " + t); Logger.Tab(); t.UpdateTripStatus(notifyPartner: true, status: Status.Cancelled); Logger.Untab(); }
private static bool AgeSinceCompletedClock_HasNotBeenSet(PartnerTrip t) { return t.dropoffTime == null; }
public bool TryDispatchTripLocally(PartnerTrip t) { Logger.Log("DispatchTripLocally"); if (!FleetServesLocation(t.pickupLocation)) { Logger.Log("Pickup location " + t.pickupLocation + " is outside of coverage area"); return false; } if (t.status != Status.Queued) throw new Exception("Invalid 'Dispatch' status"); if (ThereAreAvailableDrivers()) { DispatchToFirstAvailableDriver(t); t.UpdateTripStatus(notifyPartner: true, status: Status.Dispatched, driverLocation: t.driver.location, eta: t.pickupTime); return true; } Logger.Log("No drivers are currently available"); return false; }
public bool TripStatusUpdateIntervalReached(PartnerTrip t) { return DateTime.UtcNow > t.lastUpdate + updateInterval; }
public void RemoveTrip(PartnerTrip t) { queue.Remove(queue.Find(t)); }
public bool QueueTrip(PartnerTrip t) { lock (locker) { if (availableDrivers.Count == 0 && t.origination == PartnerTrip.Origination.Foreign) return false; // don't except from parters if no available drivers Logger.Log("Queueing " + t); queue.AddLast(t); partner.tripsByID.Add(t.ID, t); partner.activeTrips.Add(t.ID, new Trip { FleetId = t.PartnerFleet != null ? t.PartnerFleet.ID : null, FleetName = t.PartnerFleet != null ? t.PartnerFleet.name : null, DriverId = t.driver != null ? t.driver.ID : null, DriverLocation = t.driver != null ? t.driver.location : null, DriverName = t.driver != null ? t.driver.name : null, DropoffLocation = t.dropoffLocation, DriverInitiaLocation = null, DropoffTime = t.dropoffTime, Id = t.ID, OriginatingPartnerId = this.ID, OriginatingPartnerName = this.name, PassengerName = t.passengerName, PickupLocation = t.pickupLocation, PickupTime = t.pickupTime, Price = t.price, Status = t.status, VehicleType = t.vehicleType, }); t.UpdateTripStatus(notifyPartner: false, status: Status.Queued); return true; } }
public void ProcessTrip(PartnerTrip t) { //Logger.LogDebug("Processing " + t); lock (locker) { switch (t.status) { case Status.New: { Logger.Log("Unexpected status (New): Something wrong with " + t); break; } case Status.Queued: { ProcessStatusQueued(t); break; } case Status.Dispatched: { ProcessStatusDispatched(t); break; } case Status.Enroute: { ProcessStatusEnroute(t); break; } case Status.PickedUp: { ProcessStatusPickedUp(t); break; } } } }
private static bool TripOriginatedLocally(PartnerTrip t) { return t.origination == PartnerTrip.Origination.Local; }
private static bool TripServicedByForeignProvider(PartnerTrip t) { return t.service == PartnerTrip.Origination.Foreign; }
private static bool DestinationReached(PartnerTrip t) { return t.driver.location.Equals(t.driver.route.end); }
private bool CriticalPeriodNotYetReached(PartnerTrip t) { return DateTime.UtcNow < t.pickupTime - criticalPeriod; }
private static bool DriverHasReachedThePickupLocation(PartnerTrip t) { return t.driver.location.Equals(t.pickupLocation); }
private void DispatchToFirstAvailableDriver(PartnerTrip t) { if (availableDrivers.Count == 0) throw new Exception("Invalid condition: no available drivers"); t.driver = availableDrivers.First(); t.PartnerFleet = this; availableDrivers.RemoveFirst(); //throw new Exception("driver = " + t.driver + ", name = " + t.driver.name); if (t.driver == null) throw new Exception("Invalid condition: driver object null"); Logger.Log("Dispatched to " + t.driver.name); }
private static bool DriverWillBeLateIfHeDoesntLeaveNow(PartnerTrip t) { return DateTime.UtcNow >= t.pickupTime - MapTools.GetRoute(t.driver.location, t.pickupLocation).duration; }
private void MakeTripComplete(PartnerTrip t) { Logger.Log("The destination has been reached for: " + t); Logger.Tab(); t.dropoffTime = DateTime.UtcNow; CompleteTrip(t); t.UpdateTripStatus(notifyPartner: true, status: Status.Complete); Logger.Untab(); }
private static TimeSpan GetAgeSinceCancelledOrRejected(PartnerTrip t) { return DateTime.UtcNow - (DateTime)t.pickupTime; }
private void MakeTripPickedUp(PartnerTrip trip) { Logger.Log("Picking up: " + trip); Logger.Tab(); DateTime eta = UpdateDriverRouteAndGetETA(trip.driver, trip.dropoffLocation); trip.UpdateTripStatus(notifyPartner: true, status: Status.PickedUp, driverLocation: trip.driver.location, eta: eta); Logger.Untab(); }
private static TimeSpan GetAgeSinceCompleted(PartnerTrip t) { return DateTime.UtcNow - (DateTime)t.dropoffTime; }
private void ProcessStatusDispatched(PartnerTrip t) { if (TripServicedByForeignProvider(t)) return; // partner.GetTripStatusFromForeignServiceProvider(t, true); else if (DriverWillBeLateIfHeDoesntLeaveNow(t)) MakeTripEnroute(t); else if (TripStatusUpdateIntervalReached(t)) LogTheNewDriverLocation(t); }
private static void LogTheNewDriverLocation(PartnerTrip t) { Logger.Log("Getting status of: " + t); t.lastUpdate = DateTime.UtcNow; }
private void ProcessStatusPickedUp(PartnerTrip t) { if (TripServicedByForeignProvider(t)) return; // partner.GetTripStatusFromForeignServiceProvider(t, true); else { UpdateTripDriverLocation(t); if (DestinationReached(t)) MakeTripComplete(t); else if (TripStatusUpdateIntervalReached(t)) LogTheNewDriverLocation(t); } }
private static void StartTheAgeSinceCompletedClock_FromNow(PartnerTrip t) { t.dropoffTime = DateTime.UtcNow; }