sharee.bike-App/TINKLib/Model/Connector/Updater/BikeInfoFactory.cs

328 lines
12 KiB
C#
Raw Normal View History

2023-01-18 14:22:51 +01:00
using System;
2022-08-30 15:42:25 +02:00
using System.Collections.Generic;
using Serilog;
2023-01-18 14:22:51 +01:00
using TINK.Model.Bikes.BikeInfoNS.BC;
2022-08-30 15:42:25 +02:00
using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.MiniSurvey;
using TINK.Model.State;
using TINK.Repository.Response;
using BikeExtension = TINK.Model.Bikes.BikeInfoNS.BikeNS.BikeExtension;
namespace TINK.Model.Connector.Updater
{
2022-09-06 16:08:19 +02:00
/// <summary>
/// Constructs bike info instances/ bike info derived instances.
/// </summary>
public static class BikeInfoFactory
{
/// <summary> Set default lock type to . </summary>
public static LockModel DEFAULTLOCKMODEL = LockModel.Sigo;
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
/// <summary> Creates a bike info object from copri response. </summary>
/// <param name="bikeInfo">Copri response for a disposable bike. </param>
2023-01-18 14:22:51 +01:00
/// <param name="dataSource">Specifies the data source.</param>
public static BikeInfo Create(
BikeInfoAvailable bikeInfo,
DataSource dataSource)
2022-09-06 16:08:19 +02:00
{
if (bikeInfo == null) throw new ArgumentNullException(nameof(bikeInfo));
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
var lockModel = bikeInfo.GetLockModel();
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
if (lockModel.HasValue
&& lockModel.Value == LockModel.BordComputer)
{
// Manual lock bikes are no more supported.
Log.Error(
$"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoAvailable)} argument. " +
"Manual lock bikes are no more supported." +
$"Bike number: {bikeInfo.bike}{(bikeInfo.station != null ? $"station number {bikeInfo.station}" : string.Empty)}."
);
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
return null;
}
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
switch (bikeInfo.GetState())
{
case InUseStateEnum.Disposable:
case InUseStateEnum.FeedbackPending:
break;
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
default:
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoAvailable)} argument. Unexpected state {bikeInfo.GetState()} detected.");
return null;
}
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
if (string.IsNullOrEmpty(bikeInfo.station))
{
// Bike available must always have a station id because bikes can only be returned at a station.
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoAvailable)} argument. No station info set.");
return null;
}
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
var lockType = lockModel.HasValue
? BikeExtension.GetLockType(lockModel.Value)
2023-04-19 12:14:14 +02:00
: BikeExtension.GetLockType(DEFAULTLOCKMODEL); // Map bikes without "system"- entry in response to back end- locks.
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
try
{
switch (lockType)
{
case LockType.Backend:
return new Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike(
bikeInfo.bike,
LockModel.Sigo,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
2023-04-19 12:14:14 +02:00
bikeInfo.GetAaRideType(),
2022-09-06 16:08:19 +02:00
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
2023-01-18 14:22:51 +01:00
dataSource,
2022-09-06 16:08:19 +02:00
bikeInfo.station,
new Bikes.BikeInfoNS.CopriLock.LockInfo.Builder { State = bikeInfo.GetCopriLockingState() }.Build(),
bikeInfo.GetState() == InUseStateEnum.FeedbackPending,
bikeInfo.GetOperatorUri(),
2022-08-30 15:42:25 +02:00
#if !NOTARIFFDESCRIPTION
2022-09-06 16:08:19 +02:00
bikeInfo.rental_description != null
? RentalDescriptionFactory.Create(bikeInfo.rental_description)
: TariffDescriptionFactory.Create(bikeInfo.tariff_description),
2022-08-30 15:42:25 +02:00
#else
Create((TINK.Repository.Response.TariffDescription) null),
#endif
2022-09-06 16:08:19 +02:00
bikeInfo.GetIsDemo(),
bikeInfo.GetGroup(),
miniSurvey: bikeInfo.user_miniquery != null
? new MiniSurveyModel(new Dictionary<string, IQuestionModel> {
2023-04-19 12:14:14 +02:00
{ "q1", new QuestionModel()} // Add a dummy query. Queries are not yet read from COPRI but compiled into the app.
2022-08-30 15:42:25 +02:00
})
2022-09-06 16:08:19 +02:00
: new MiniSurveyModel(),
co2Saving: bikeInfo.co2saving);
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
case LockType.Bluethooth:
return new Bikes.BikeInfoNS.BluetoothLock.BikeInfo(
new Bike(
bikeInfo.bike,
LockModel.ILockIt,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
2023-04-19 12:14:14 +02:00
bikeInfo.GetAaRideType(),
2022-09-06 16:08:19 +02:00
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
2023-01-18 14:22:51 +01:00
dataSource,
2022-09-06 16:08:19 +02:00
bikeInfo.GetBluetoothLockId(),
bikeInfo.GetBluetoothLockGuid(),
bikeInfo.station,
bikeInfo.GetOperatorUri(),
2022-08-30 15:42:25 +02:00
#if !NOTARIFFDESCRIPTION
2022-09-06 16:08:19 +02:00
bikeInfo.rental_description != null
? RentalDescriptionFactory.Create(bikeInfo.rental_description)
: TariffDescriptionFactory.Create(bikeInfo.tariff_description),
2022-08-30 15:42:25 +02:00
#else
Create((TINK.Repository.Response.TariffDescription)null),
#endif
2022-09-06 16:08:19 +02:00
bikeInfo.GetIsDemo(),
bikeInfo.GetGroup());
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
default:
throw new ArgumentException($"Unsupported lock type {lockType} detected.");
}
}
catch (ArgumentException ex)
{
2023-04-19 12:14:14 +02:00
// Constructor reported invalid arguments (missing lock id, ....).
2022-09-06 16:08:19 +02:00
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoAvailable)} argument. Invalid response detected. Available bike with id {bikeInfo.bike} skipped. {ex.Message}");
return null;
}
}
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
/// <summary> Creates a bike info object from copri response. </summary>
/// <param name="bikeInfo">Copri response. </param>
/// <param name="mailAddress">Mail address of user.</param>
/// <param name="dateTimeProvider">Date and time provider function.</param>
2023-01-18 14:22:51 +01:00
/// <param name="dataSource">Specified the source of the data.</param>
2022-09-06 16:08:19 +02:00
public static BikeInfo Create(
BikeInfoReservedOrBooked bikeInfo,
string mailAddress,
2023-01-18 14:22:51 +01:00
Func<DateTime> dateTimeProvider,
DataSource dataSource)
2022-09-06 16:08:19 +02:00
{
if (bikeInfo == null) throw new ArgumentNullException(nameof(bikeInfo));
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
var lockModel = bikeInfo.GetLockModel();
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
if (lockModel.HasValue
&& lockModel.Value == LockModel.BordComputer)
{
// Manual lock bikes are no more supported.
Log.Error(
$"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoAvailable)} argument. " +
"Manual lock bikes are no more supported." +
$"Bike number: {bikeInfo.bike}{(bikeInfo.station != null ? $", station number {bikeInfo.station}" : string.Empty)}."
);
return null;
}
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
var lockType = lockModel.HasValue
? BikeExtension.GetLockType(lockModel.Value)
: BikeExtension.GetLockType(DEFAULTLOCKMODEL); // Map bikes without "system"- entry in response to backend- locks.
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
// Check if bike is a bluetooth lock bike.
int lockSerial = bikeInfo.GetBluetoothLockId();
Guid lockGuid = bikeInfo.GetBluetoothLockGuid();
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
switch (bikeInfo.GetState())
{
case InUseStateEnum.Reserved:
try
{
switch (lockType)
{
case LockType.Bluethooth:
return new Bikes.BikeInfoNS.BluetoothLock.BikeInfo(
new Bike(
bikeInfo.bike,
LockModel.ILockIt,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
2023-04-19 12:14:14 +02:00
bikeInfo.GetAaRideType(),
2022-09-06 16:08:19 +02:00
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
2023-01-18 14:22:51 +01:00
dataSource,
2022-09-06 16:08:19 +02:00
lockSerial,
lockGuid,
bikeInfo.GetUserKey(),
bikeInfo.GetAdminKey(),
bikeInfo.GetSeed(),
bikeInfo.GetFrom(),
mailAddress,
bikeInfo.station,
bikeInfo.GetOperatorUri(),
2022-08-30 15:42:25 +02:00
#if !NOTARIFFDESCRIPTION
2022-09-06 16:08:19 +02:00
bikeInfo.rental_description != null
? RentalDescriptionFactory.Create(bikeInfo.rental_description)
: TariffDescriptionFactory.Create(bikeInfo.tariff_description),
2022-08-30 15:42:25 +02:00
#else
Create((TINK.Repository.Response.TariffDescription)null),
#endif
2022-09-06 16:08:19 +02:00
dateTimeProvider,
bikeInfo.GetIsDemo(),
bikeInfo.GetGroup());
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
case LockType.Backend:
return new Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike(
bikeInfo.bike,
LockModel.Sigo,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
2023-04-19 12:14:14 +02:00
bikeInfo.GetAaRideType(),
2022-09-06 16:08:19 +02:00
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
2023-01-18 14:22:51 +01:00
dataSource,
2022-09-06 16:08:19 +02:00
bikeInfo.GetFrom(),
mailAddress,
bikeInfo.station,
new Bikes.BikeInfoNS.CopriLock.LockInfo.Builder { State = bikeInfo.GetCopriLockingState() }.Build(),
bikeInfo.GetOperatorUri(),
2022-08-30 15:42:25 +02:00
#if !NOTARIFFDESCRIPTION
2022-09-06 16:08:19 +02:00
bikeInfo.rental_description != null
? RentalDescriptionFactory.Create(bikeInfo.rental_description)
: TariffDescriptionFactory.Create(bikeInfo.tariff_description),
2022-08-30 15:42:25 +02:00
#else
Create((TINK.Repository.Response.TariffDescription)null),
#endif
2022-09-06 16:08:19 +02:00
dateTimeProvider,
bikeInfo.GetIsDemo(),
bikeInfo.GetGroup());
default:
throw new ArgumentException($"Unsupported lock type {lockType} detected.");
}
}
catch (ArgumentException ex)
{
2023-04-19 12:14:14 +02:00
// Constructor reported invalid arguments (missing lock id, ....).
2022-09-06 16:08:19 +02:00
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoReservedOrBooked)} argument. Invalid response detected. Reserved bike with id {bikeInfo.bike} skipped. {ex.Message}");
return null;
}
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
case InUseStateEnum.Booked:
try
{
switch (lockModel)
{
case LockModel.ILockIt:
return new Bikes.BikeInfoNS.BluetoothLock.BikeInfo(
new Bike(
bikeInfo.bike,
LockModel.ILockIt,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
2023-04-19 12:14:14 +02:00
bikeInfo.GetAaRideType(),
2022-09-06 16:08:19 +02:00
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
2023-01-18 14:22:51 +01:00
dataSource,
2022-09-06 16:08:19 +02:00
lockSerial,
bikeInfo.GetBluetoothLockGuid(),
bikeInfo.GetUserKey(),
bikeInfo.GetAdminKey(),
bikeInfo.GetSeed(),
bikeInfo.GetFrom(),
mailAddress,
bikeInfo.station,
bikeInfo.GetOperatorUri(),
2022-08-30 15:42:25 +02:00
#if !NOTARIFFDESCRIPTION
2022-09-06 16:08:19 +02:00
bikeInfo.rental_description != null
? RentalDescriptionFactory.Create(bikeInfo.rental_description)
: TariffDescriptionFactory.Create(bikeInfo.tariff_description),
2022-08-30 15:42:25 +02:00
#else
Create((TINK.Repository.Response.TariffDescription)null),
#endif
2022-09-06 16:08:19 +02:00
bikeInfo.GetIsDemo(),
bikeInfo.GetGroup());
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
case LockModel.BordComputer:
2023-04-19 12:14:14 +02:00
throw new NotSupportedException($"Bikes with lock model of type {lockModel} are no more supported.");
2022-09-06 16:08:19 +02:00
default:
return new Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike(
bikeInfo.bike,
LockModel.Sigo,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
2023-04-19 12:14:14 +02:00
bikeInfo.GetAaRideType(),
2022-09-06 16:08:19 +02:00
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
2023-01-18 14:22:51 +01:00
DataSource.Copri,
2022-09-06 16:08:19 +02:00
bikeInfo.GetFrom(),
mailAddress,
bikeInfo.station,
new Bikes.BikeInfoNS.CopriLock.LockInfo.Builder { State = bikeInfo.GetCopriLockingState() }.Build(),
bikeInfo.GetOperatorUri(),
2022-08-30 15:42:25 +02:00
#if !NOTARIFFDESCRIPTION
2022-09-06 16:08:19 +02:00
bikeInfo.rental_description != null
? RentalDescriptionFactory.Create(bikeInfo.rental_description)
: TariffDescriptionFactory.Create(bikeInfo.tariff_description),
2022-08-30 15:42:25 +02:00
#else
Create((TINK.Repository.Response.TariffDescription)null),
#endif
2022-09-06 16:08:19 +02:00
bikeInfo.GetIsDemo(),
bikeInfo.GetGroup());
}
}
catch (ArgumentException ex)
{
2023-06-06 12:00:24 +02:00
// Constructor reported invalid arguments (missing lock id, ....).
2022-09-06 16:08:19 +02:00
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoReservedOrBooked)} argument. Invalid response detected. Booked bike with id {bikeInfo.bike} skipped. {ex.Message}");
return null;
}
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
default:
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoAvailable)} argument. Unexpected state {bikeInfo.GetState()} detected.");
return null;
}
}
}
2022-08-30 15:42:25 +02:00
}