mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2024-11-06 02:56:32 +01:00
134 lines
3.7 KiB
C#
134 lines
3.7 KiB
C#
|
using System;
|
||
|
using System.Threading.Tasks;
|
||
|
using Serilog;
|
||
|
using ShareeBike.Repository.Exception;
|
||
|
using ShareeBike.Services.CopriApi.Exception;
|
||
|
using ShareeBike.Model.Connector;
|
||
|
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||
|
|
||
|
namespace ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Provides functionality to get the locked bike location.
|
||
|
/// </summary>
|
||
|
public static class StartReservationCommand
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Possible steps of requesting a bike.
|
||
|
/// </summary>
|
||
|
public enum Step
|
||
|
{
|
||
|
ReserveBike,
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Possible steps of requesting a bike.
|
||
|
/// </summary>
|
||
|
public enum State
|
||
|
{
|
||
|
TooManyBikesError,
|
||
|
WebConnectFailed,
|
||
|
GeneralStartReservationError,
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Interface to notify view model about steps/ state changes of closing process.
|
||
|
/// </summary>
|
||
|
public interface IStartReservationCommandListener
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Reports current step.
|
||
|
/// </summary>
|
||
|
/// <param name="currentStep">Current step to report.</param>
|
||
|
void ReportStep(Step currentStep);
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reports current state.
|
||
|
/// </summary>
|
||
|
/// <param name="currentState">Current state to report.</param>
|
||
|
/// <param name="message">Message describing the current state.</param>
|
||
|
/// <returns></returns>
|
||
|
Task ReportStateAsync(State currentState, string message);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Get current location.
|
||
|
/// </summary>
|
||
|
/// <param name="listener"></param>
|
||
|
/// <returns></returns>
|
||
|
/// <exception cref="Exception"></exception>
|
||
|
public static async Task InvokeAsync<T>(
|
||
|
IBikeInfoMutable bike,
|
||
|
Func<bool> isConnectedDelegate,
|
||
|
Func<bool, IConnector> connectorFactory,
|
||
|
IStartReservationCommandListener listener)
|
||
|
{
|
||
|
// Invokes member to notify about step being started.
|
||
|
void InvokeCurrentStep(Step step)
|
||
|
{
|
||
|
if (listener == null)
|
||
|
return;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
listener.ReportStep(step);
|
||
|
}
|
||
|
catch (Exception exception)
|
||
|
{
|
||
|
Log.ForContext<T>().Error("An exception {@exception} was thrown invoking step-action for step {step} ", exception, step);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Invokes member to notify about state change.
|
||
|
async Task InvokeCurrentStateAsync(State state, string message)
|
||
|
{
|
||
|
if (listener == null)
|
||
|
return;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
await listener.ReportStateAsync(state, message);
|
||
|
}
|
||
|
catch (Exception exception)
|
||
|
{
|
||
|
Log.ForContext<T>().Error("An exception {@exception} was thrown invoking state-action for state {state} ", exception, state);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//// Start Action
|
||
|
//// Step: Reserve Bike
|
||
|
InvokeCurrentStep(Step.ReserveBike);
|
||
|
|
||
|
try
|
||
|
{
|
||
|
await connectorFactory(true).Command.DoReserve(bike);
|
||
|
Log.ForContext<T>().Information("User reserved bike {bikeId} successfully.", bike.Id);
|
||
|
}
|
||
|
catch (Exception exception)
|
||
|
{
|
||
|
Log.ForContext<T>().Information("Request to reserve bike {bikeId} declined.", bike.Id);
|
||
|
if (exception is BookingDeclinedException)
|
||
|
{
|
||
|
// Too many bikes booked.
|
||
|
Log.ForContext<T>().Error("Maximum count of bikes {exception.MaxBikesCount} already requested/ booked.", (exception as BookingDeclinedException).MaxBikesCount);
|
||
|
await InvokeCurrentStateAsync(State.TooManyBikesError, (exception as BookingDeclinedException).MaxBikesCount.ToString());
|
||
|
}
|
||
|
else if (exception is WebConnectFailureException
|
||
|
|| exception is RequestNotCachableException)
|
||
|
{
|
||
|
// Copri server is not reachable.
|
||
|
Log.ForContext<T>().Error("Copri server not reachable.");
|
||
|
await InvokeCurrentStateAsync(State.WebConnectFailed, exception.Message);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Log.ForContext<T>().Error("{@exception}", exception);
|
||
|
await InvokeCurrentStateAsync(State.GeneralStartReservationError, exception.Message);
|
||
|
}
|
||
|
|
||
|
throw;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|