mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-05-02 17:06:30 +02:00
Version 3.0.381
This commit is contained in:
parent
f963c0a219
commit
3a363acf3a
1525 changed files with 60589 additions and 125098 deletions
24
SharedBusinessLogic/Model/State/BaseState.cs
Normal file
24
SharedBusinessLogic/Model/State/BaseState.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System.Runtime.Serialization;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// Base type for serialization purposes.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[KnownType(typeof(StateFeedbackPendingInfo))]
|
||||
[KnownType(typeof(StateAvailableInfo))]
|
||||
[KnownType(typeof(StateRequestedInfo))]
|
||||
[KnownType(typeof(StateOccupiedInfo))]
|
||||
public abstract class BaseState
|
||||
{
|
||||
/// <summary> Constructor for JSON serialization. </summary>
|
||||
/// <param name="value">State value.</param>
|
||||
protected BaseState(InUseStateEnum value) { }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the state value.
|
||||
/// </summary>
|
||||
public abstract InUseStateEnum Value { get; }
|
||||
}
|
||||
}
|
11
SharedBusinessLogic/Model/State/IBaseState.cs
Normal file
11
SharedBusinessLogic/Model/State/IBaseState.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// Base state information.
|
||||
/// </summary>
|
||||
public interface IBaseState
|
||||
{
|
||||
InUseStateEnum Value { get; }
|
||||
}
|
||||
}
|
14
SharedBusinessLogic/Model/State/INotAvailableState.cs
Normal file
14
SharedBusinessLogic/Model/State/INotAvailableState.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// State of bikes which are either reserved or booked.
|
||||
/// </summary>
|
||||
public interface INotAvailableState : IBaseState
|
||||
{
|
||||
DateTime From { get; }
|
||||
string MailAddress { get; }
|
||||
string Code { get; }
|
||||
}
|
||||
}
|
24
SharedBusinessLogic/Model/State/IStateInfo.cs
Normal file
24
SharedBusinessLogic/Model/State/IStateInfo.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to access informations about bike information.
|
||||
/// </summary>
|
||||
public interface IStateInfo : IBaseState
|
||||
{
|
||||
string MailAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Date of request/ booking action.
|
||||
/// </summary>
|
||||
DateTime? From { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Time span for which a bike can be reserved.
|
||||
/// </summary>
|
||||
TimeSpan? MaxReservationTimeSpan { get; }
|
||||
|
||||
string Code { get; }
|
||||
}
|
||||
}
|
24
SharedBusinessLogic/Model/State/IStateInfoMutable.cs
Normal file
24
SharedBusinessLogic/Model/State/IStateInfoMutable.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
public interface IStateInfoMutable
|
||||
{
|
||||
InUseStateEnum Value { get; }
|
||||
|
||||
/// <summary> Updates state from web server. </summary>
|
||||
/// <param name="state">State of the bike.</param>
|
||||
/// <param name="from">Date time when bike was reserved/ booked.</param>
|
||||
/// <param name="reservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
/// <param name="mailAddress">Mail address of the one which reserved/ booked.</param>
|
||||
/// <param name="code">Booking code if bike is booked or reserved.</param>
|
||||
/// <param name="notifyLevel">Controls whether notify property changed events are fired or not.</param>
|
||||
void Load(
|
||||
InUseStateEnum state,
|
||||
DateTime? from = null,
|
||||
TimeSpan? reservationTimeSpan = null,
|
||||
string mailAddress = null,
|
||||
string code = null,
|
||||
Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel notifyLevel = Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.All);
|
||||
}
|
||||
}
|
28
SharedBusinessLogic/Model/State/StateAvailableInfo.cs
Normal file
28
SharedBusinessLogic/Model/State/StateAvailableInfo.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the state available.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public sealed class StateAvailableInfo : BaseState, IBaseState
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs state info object representing state available.
|
||||
/// </summary>
|
||||
public StateAvailableInfo() : base(InUseStateEnum.Disposable) { }
|
||||
|
||||
/// <summary> Constructor for Json serialization. </summary>
|
||||
/// <param name="value">Unused value.</param>
|
||||
[JsonConstructor]
|
||||
private StateAvailableInfo(InUseStateEnum value) : base(InUseStateEnum.Disposable) { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the info that state is disposable.
|
||||
/// Setter exists only for serialization purposes.
|
||||
/// </summary>
|
||||
public override InUseStateEnum Value => InUseStateEnum.Disposable;
|
||||
}
|
||||
}
|
28
SharedBusinessLogic/Model/State/StateFeedbackPendingInfo.cs
Normal file
28
SharedBusinessLogic/Model/State/StateFeedbackPendingInfo.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the state feedback pending.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public sealed class StateFeedbackPendingInfo : BaseState, IBaseState
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs state info object representing feedback pending.
|
||||
/// </summary>
|
||||
public StateFeedbackPendingInfo() : base(InUseStateEnum.FeedbackPending) { }
|
||||
|
||||
/// <summary> Constructor for Json serialization. </summary>
|
||||
/// <param name="value">Unused value.</param>
|
||||
[JsonConstructor]
|
||||
private StateFeedbackPendingInfo(InUseStateEnum value) : base(InUseStateEnum.FeedbackPending) { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the info that state is disposable.
|
||||
/// Setter exists only for serialization purposes.
|
||||
/// </summary>
|
||||
public override InUseStateEnum Value => InUseStateEnum.FeedbackPending;
|
||||
}
|
||||
}
|
175
SharedBusinessLogic/Model/State/StateInfo.cs
Normal file
175
SharedBusinessLogic/Model/State/StateInfo.cs
Normal file
|
@ -0,0 +1,175 @@
|
|||
using System;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// Types of rent states
|
||||
/// </summary>
|
||||
public enum InUseStateEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// Bike was returned but no feedback given.
|
||||
/// This applies to COPRI locks only because returning of bike is not done using app (Status: Supported locks are ILockIt and COPRI).
|
||||
/// </summary>
|
||||
FeedbackPending,
|
||||
|
||||
/// <summary>
|
||||
/// Bike is not in use. Corresponding COPRI state is "available".
|
||||
/// </summary>
|
||||
Disposable,
|
||||
|
||||
/// <summary>
|
||||
/// Bike is reserved. Corresponding COPRI state is "requested".
|
||||
/// </summary>
|
||||
Reserved,
|
||||
|
||||
/// <summary>
|
||||
/// Bike is booked. Corresponding COPRI state is "occupied".
|
||||
/// </summary>
|
||||
Booked
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manages the state of a bike.
|
||||
/// </summary>
|
||||
public class StateInfo : IStateInfo
|
||||
{
|
||||
// Holds the current disposable state value.
|
||||
private readonly BaseState _InUseState;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a state info object when state is available.
|
||||
/// </summary>
|
||||
/// <param name="isFeedbackPending">Specifies whether feedback is pending or not.</param>
|
||||
public StateInfo(bool isFeedbackPending = false)
|
||||
{
|
||||
_InUseState = isFeedbackPending
|
||||
? (BaseState)new StateFeedbackPendingInfo()
|
||||
: new StateAvailableInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a state info object when state is requested.
|
||||
/// </summary>
|
||||
/// <param name="requestedAt">Date time when bike was requested</param>
|
||||
/// <param name="maxReservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
/// <param name="mailAddress">Mail address of user which requested bike.</param>
|
||||
/// <param name="code">Booking code.</param>
|
||||
/// <param name="dateTimeNowProvider">Date time provider to calculate remaining time.</param>
|
||||
public StateInfo(
|
||||
Func<DateTime> dateTimeNowProvider,
|
||||
DateTime requestedAt,
|
||||
TimeSpan maxReservationTimeSpan,
|
||||
string mailAddress,
|
||||
string code)
|
||||
{
|
||||
_InUseState = new StateRequestedInfo(
|
||||
dateTimeNowProvider ?? (() => DateTime.Now),
|
||||
requestedAt,
|
||||
maxReservationTimeSpan,
|
||||
mailAddress,
|
||||
code);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a state info object when state is booked.
|
||||
/// </summary>
|
||||
/// <param name="p_oBookedAt">Date time when bike was booked</param>
|
||||
/// <param name="p_strMailAddress">Mail address of user which booked bike.</param>
|
||||
/// <param name="p_strCode">Booking code.</param>
|
||||
public StateInfo(
|
||||
DateTime p_oBookedAt,
|
||||
string p_strMailAddress,
|
||||
string p_strCode)
|
||||
{
|
||||
_InUseState = new StateOccupiedInfo(
|
||||
p_oBookedAt,
|
||||
p_strMailAddress,
|
||||
p_strCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state value of object.
|
||||
/// </summary>
|
||||
public InUseStateEnum Value
|
||||
{
|
||||
get { return _InUseState.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Member for serialization purposes.
|
||||
/// </summary>
|
||||
internal BaseState StateInfoObject
|
||||
{
|
||||
get { return _InUseState; }
|
||||
}
|
||||
/// Transforms object to string.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return _InUseState.Value.ToString("g");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Date of request/ booking action.
|
||||
/// </summary>
|
||||
public DateTime? From
|
||||
{
|
||||
get
|
||||
{
|
||||
var l_oNotDisposableInfo = _InUseState as INotAvailableState;
|
||||
return l_oNotDisposableInfo != null ? l_oNotDisposableInfo.From : (DateTime?)null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Time span for which a bike can be reserved.
|
||||
/// </summary>
|
||||
public TimeSpan? MaxReservationTimeSpan =>
|
||||
_InUseState is StateRequestedInfo reserved
|
||||
? reserved.MaxReservationTimeSpan
|
||||
: (TimeSpan?)null;
|
||||
|
||||
/// <summary>
|
||||
/// Mail address.
|
||||
/// </summary>
|
||||
public string MailAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
var l_oNotDisposableInfo = _InUseState as INotAvailableState;
|
||||
return l_oNotDisposableInfo?.MailAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reservation code.
|
||||
/// </summary>
|
||||
public string Code
|
||||
{
|
||||
get
|
||||
{
|
||||
var l_oNotDisposableInfo = _InUseState as INotAvailableState;
|
||||
return l_oNotDisposableInfo?.Code;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries update
|
||||
/// </summary>
|
||||
/// <returns>True if reservation span has not exceeded and state remains reserved, false otherwise.</returns>
|
||||
/// <todo>Implement logging of time stamps.</todo>
|
||||
public bool GetIsStillReserved(out TimeSpan? p_oRemainingTime)
|
||||
{
|
||||
var l_oReservedInfo = _InUseState as StateRequestedInfo;
|
||||
if (l_oReservedInfo == null)
|
||||
{
|
||||
p_oRemainingTime = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return l_oReservedInfo.GetIsStillReserved(out p_oRemainingTime);
|
||||
}
|
||||
}
|
||||
}
|
13
SharedBusinessLogic/Model/State/StateInfoHelper.cs
Normal file
13
SharedBusinessLogic/Model/State/StateInfoHelper.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ShareeBike.Model.State
|
||||
{
|
||||
public static class StateInfoHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets whether bike is available or occupied, i.e. reserved or booked.
|
||||
/// </summary>
|
||||
/// <param name="state">State to be info from.</param>
|
||||
/// <returns>True if bike is reserved to booked.</returns>
|
||||
public static bool IsOccupied(this InUseStateEnum state)
|
||||
=> state != InUseStateEnum.Disposable && state != InUseStateEnum.FeedbackPending;
|
||||
}
|
||||
}
|
297
SharedBusinessLogic/Model/State/StateInfoMutable.cs
Normal file
297
SharedBusinessLogic/Model/State/StateInfoMutable.cs
Normal file
|
@ -0,0 +1,297 @@
|
|||
using System;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// Manges the state of a bike.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class StateInfoMutable : INotifyPropertyChanged, IStateInfoMutable
|
||||
{
|
||||
/// <summary>
|
||||
/// Provider for current date time to calculate remaining time on demand for state of type reserved.
|
||||
/// </summary>
|
||||
private readonly Func<DateTime> _DateTimeNowProvider;
|
||||
|
||||
// Holds the current disposable state value
|
||||
private StateInfo _StateInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Backs up remaining time of child object.
|
||||
/// </summary>
|
||||
private TimeSpan? _RemainingTime = null;
|
||||
|
||||
/// <summary> Notifies clients about state changes. </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a state object from source.
|
||||
/// </summary>
|
||||
/// <param name="state">State info to load from.</param>
|
||||
public StateInfoMutable(
|
||||
Func<DateTime> dateTimeNowProvider = null,
|
||||
IStateInfo state = null)
|
||||
{
|
||||
// Back up date time provider to be able to pass this to requested- object if state changes to requested.
|
||||
_DateTimeNowProvider = dateTimeNowProvider != null
|
||||
? dateTimeNowProvider
|
||||
: () => DateTime.Now;
|
||||
|
||||
_StateInfo = Create(state, dateTimeNowProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads state from immutable source.
|
||||
/// </summary>
|
||||
/// <param name="state">State to load from.</param>
|
||||
public void Load(IStateInfo state)
|
||||
{
|
||||
if (state == null)
|
||||
{
|
||||
throw new ArgumentException("Can not load state info, object must not be null.");
|
||||
}
|
||||
|
||||
// Back up last state value and remaining time value
|
||||
// to be able to check whether an event has to be fired or not.
|
||||
var l_oLastState = Value;
|
||||
var l_oLastRemainingTime = _RemainingTime;
|
||||
|
||||
// Create new state info object from source.
|
||||
_StateInfo = Create(state, _DateTimeNowProvider);
|
||||
|
||||
// Update remaining time value.
|
||||
_StateInfo.GetIsStillReserved(out _RemainingTime);
|
||||
|
||||
if (l_oLastState == _StateInfo.Value
|
||||
&& l_oLastRemainingTime == _RemainingTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// State has changed, notify clients.
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(State)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a state info object.
|
||||
/// </summary>
|
||||
/// <param name="state">State to load from.</param>
|
||||
private static StateInfo Create(
|
||||
IStateInfo state,
|
||||
Func<DateTime> dateTimeNowProvider)
|
||||
{
|
||||
switch (state != null ? state.Value : InUseStateEnum.Disposable)
|
||||
{
|
||||
case InUseStateEnum.Disposable:
|
||||
case InUseStateEnum.FeedbackPending:
|
||||
return new StateInfo(state != null ? state.Value == InUseStateEnum.FeedbackPending : false);
|
||||
|
||||
case InUseStateEnum.Reserved:
|
||||
return new StateInfo(
|
||||
state.From.HasValue ? dateTimeNowProvider : (() => DateTime.MaxValue),
|
||||
state.From.HasValue ? state.From.Value : DateTime.MaxValue,
|
||||
state.MaxReservationTimeSpan ?? StateRequestedInfo.UNKNOWNMAXRESERVATIONTIMESPAN,
|
||||
state.MailAddress,
|
||||
state.Code);
|
||||
|
||||
|
||||
case InUseStateEnum.Booked:
|
||||
// Todo: Handle p_oFrom == null here.
|
||||
// Todo: Clarify question: What to do if code changes form one value to another? This should never happen.
|
||||
// Todo: Clarify question: What to do if from time changes form one value to another? This should never happen.
|
||||
return new StateInfo(
|
||||
state.From.Value,
|
||||
state.MailAddress,
|
||||
state.Code);
|
||||
|
||||
default:
|
||||
// Todo: New state Busy has to be defined.
|
||||
throw new Exception(string.Format("Can not create new state info object. Unknown state {0} detected.", state.Value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state value of object.
|
||||
/// </summary>
|
||||
public InUseStateEnum Value
|
||||
=> _StateInfo.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Member for serialization purposes.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
private BaseState StateInfoObject
|
||||
{
|
||||
get { return _StateInfo.StateInfoObject; }
|
||||
set
|
||||
{
|
||||
var l_oStateOccupied = value as StateOccupiedInfo;
|
||||
if (l_oStateOccupied != null)
|
||||
{
|
||||
_StateInfo = new StateInfo(l_oStateOccupied.From, l_oStateOccupied.MailAddress, l_oStateOccupied.Code);
|
||||
return;
|
||||
}
|
||||
|
||||
var l_oStateRequested = value as StateRequestedInfo;
|
||||
if (l_oStateRequested != null)
|
||||
{
|
||||
_StateInfo = new StateInfo(_DateTimeNowProvider, l_oStateRequested.From, l_oStateRequested.MaxReservationTimeSpan, l_oStateRequested.MailAddress, l_oStateRequested.Code);
|
||||
return;
|
||||
}
|
||||
|
||||
_StateInfo = new StateInfo();
|
||||
|
||||
}
|
||||
}
|
||||
/// Transforms object to string.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return _StateInfo.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks and updates state if required.
|
||||
/// </summary>
|
||||
/// <returns>Value indicating whether state has changed</returns>
|
||||
public void UpdateOnTimeElapsed()
|
||||
{
|
||||
switch (_StateInfo.Value)
|
||||
{
|
||||
// State is disposable or booked. No need to update "OnTimeElapsed"
|
||||
case InUseStateEnum.Disposable:
|
||||
case InUseStateEnum.Booked:
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if maximum reserved time has elapsed.
|
||||
if (!_StateInfo.GetIsStillReserved(out _RemainingTime))
|
||||
{
|
||||
// Time has elapsed, switch state to disposable and notify client
|
||||
_StateInfo = new StateInfo();
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(State)));
|
||||
return;
|
||||
}
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RemainingTime)));
|
||||
}
|
||||
|
||||
/// <summary> Updates state from web server. </summary>
|
||||
/// <param name="state">State of the bike.</param>
|
||||
/// <param name="from">Date time when bike was reserved/ booked.</param>
|
||||
/// <param name="maxReservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
/// <param name="mailAddress">Mail address of the one which reserved/ booked.</param>
|
||||
/// <param name="code">Booking code if bike is booked or reserved.</param>
|
||||
/// <param name="supressNotifyPropertyChanged">Controls whether notify property changed events are fired or not.</param>
|
||||
public void Load(
|
||||
InUseStateEnum state,
|
||||
DateTime? from = null,
|
||||
TimeSpan? maxReservationTimeSpan = null,
|
||||
string mailAddress = null,
|
||||
string code = null,
|
||||
Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel notifyLevel = Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.All)
|
||||
{
|
||||
var lastState = _StateInfo.Value;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case InUseStateEnum.Disposable:
|
||||
_StateInfo = new StateInfo();
|
||||
|
||||
// Set value to null. Otherwise potentially obsolete value will be taken remaining time.
|
||||
_RemainingTime = null;
|
||||
break;
|
||||
|
||||
case InUseStateEnum.Reserved:
|
||||
_StateInfo = new StateInfo(
|
||||
from.HasValue ? _DateTimeNowProvider : (() => DateTime.MaxValue),
|
||||
from.HasValue ? from.Value : DateTime.MaxValue,
|
||||
maxReservationTimeSpan.HasValue ? maxReservationTimeSpan.Value : StateRequestedInfo.UNKNOWNMAXRESERVATIONTIMESPAN,
|
||||
mailAddress,
|
||||
code);
|
||||
|
||||
// Set value to null. Otherwise potentially obsolete value will be taken remaining time.
|
||||
_RemainingTime = null;
|
||||
break;
|
||||
|
||||
case InUseStateEnum.Booked:
|
||||
// Todo: Handle p_oFrom == null here.
|
||||
// Todo: Clearify question: What to do if code changes form one value to another? This should never happen.
|
||||
// Todo: Clearify question: What to do if from time changes form one value to another? This should never happen.
|
||||
_StateInfo = new StateInfo(
|
||||
from.Value,
|
||||
mailAddress,
|
||||
code);
|
||||
|
||||
// Set value to null. Otherwise potentially obsolete value will be taken remaining time.
|
||||
_RemainingTime = null;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Todo: New state Busy has to be defined.
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastState != _StateInfo.Value
|
||||
&& notifyLevel == Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.All)
|
||||
{
|
||||
// State has changed, notify clients.
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(State)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If bike is reserved time remaining while bike stays reserved, null otherwise.
|
||||
/// </summary>
|
||||
public TimeSpan? RemainingTime
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (_StateInfo.Value)
|
||||
{
|
||||
// State is either available or occupied.
|
||||
case InUseStateEnum.Disposable:
|
||||
case InUseStateEnum.Booked:
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_RemainingTime.HasValue == false)
|
||||
{
|
||||
// Value was not yet queried.
|
||||
// Do query before returning object.
|
||||
_StateInfo.GetIsStillReserved(out _RemainingTime);
|
||||
}
|
||||
|
||||
return _RemainingTime;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime? From
|
||||
{
|
||||
get
|
||||
{
|
||||
return _StateInfo.From;
|
||||
}
|
||||
}
|
||||
|
||||
public string MailAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
return _StateInfo.MailAddress;
|
||||
}
|
||||
}
|
||||
|
||||
public string Code
|
||||
{
|
||||
get
|
||||
{
|
||||
return _StateInfo.Code;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
80
SharedBusinessLogic/Model/State/StateOccupiedInfo.cs
Normal file
80
SharedBusinessLogic/Model/State/StateOccupiedInfo.cs
Normal file
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages state booked.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public sealed class StateOccupiedInfo : BaseState, IBaseState, INotAvailableState
|
||||
{
|
||||
/// <summary>
|
||||
/// Prevents an invalid instance to be created.
|
||||
/// </summary>
|
||||
private StateOccupiedInfo() : base(InUseStateEnum.Booked)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an object holding booked state info.
|
||||
/// </summary>
|
||||
/// <param name="p_oFrom">Date time when bike was booked</param>
|
||||
/// <param name="p_strMailAddress"></param>
|
||||
/// <param name="p_strCode"></param>
|
||||
public StateOccupiedInfo(
|
||||
DateTime p_oFrom,
|
||||
string p_strMailAddress,
|
||||
string p_strCode) : base(InUseStateEnum.Booked)
|
||||
{
|
||||
From = p_oFrom;
|
||||
MailAddress = p_strMailAddress;
|
||||
Code = p_strCode;
|
||||
}
|
||||
|
||||
/// <summary> Constructor for Json serialization. </summary>
|
||||
/// <param name="Value">Unused value.</param>
|
||||
/// <param name="From">Date time when bike was booked</param>
|
||||
/// <param name="MailAddress"></param>
|
||||
/// <param name="Code"></param>
|
||||
[JsonConstructor]
|
||||
private StateOccupiedInfo(
|
||||
InUseStateEnum Value,
|
||||
DateTime From,
|
||||
string MailAddress,
|
||||
string Code) : this(From, MailAddress, Code)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the info that state is reserved.
|
||||
/// Setter exists only for serialization purposes.
|
||||
/// </summary>
|
||||
public override InUseStateEnum Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return InUseStateEnum.Booked;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevents an invalid instance to be created.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime From { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Mail address of user who bookec the bike.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string MailAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Booking code.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Code { get; }
|
||||
}
|
||||
}
|
119
SharedBusinessLogic/Model/State/StateRequestedInfo.cs
Normal file
119
SharedBusinessLogic/Model/State/StateRequestedInfo.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ShareeBike.Model.State
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages state reserved.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public sealed class StateRequestedInfo : BaseState, IBaseState, INotAvailableState
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the value if time span is not known.
|
||||
/// </summary>
|
||||
/// <remarks> Default value see <see cref="TextToTypeHelper.DEFAULTMAXRESERVATIONTIMESPAN"/>. </remarks>
|
||||
public static TimeSpan UNKNOWNMAXRESERVATIONTIMESPAN = TimeSpan.Zero;
|
||||
|
||||
// Reference to date time provider.
|
||||
private readonly Func<DateTime> _DateTimeNowProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Time span for which a bike can be reserved. Default value is zero.
|
||||
/// </summary>
|
||||
public TimeSpan MaxReservationTimeSpan { get; private set; } = UNKNOWNMAXRESERVATIONTIMESPAN;
|
||||
|
||||
/// <summary>
|
||||
/// Prevents an invalid instance to be created.
|
||||
/// Used by serializer only.
|
||||
/// </summary>
|
||||
internal StateRequestedInfo() : base(InUseStateEnum.Reserved)
|
||||
{
|
||||
// Is called in context of JSON deserialization.
|
||||
_DateTimeNowProvider = () => DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reservation performed with other device/ before start of app.
|
||||
/// Date time info when bike was reserved has been received from web server.
|
||||
/// </summary>
|
||||
/// <param name="maxReservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
[JsonConstructor]
|
||||
private StateRequestedInfo(
|
||||
InUseStateEnum Value,
|
||||
DateTime From,
|
||||
TimeSpan maxReservationTimeSpan,
|
||||
string MailAddress,
|
||||
string Code) : this(() => DateTime.Now, From, maxReservationTimeSpan, MailAddress, Code)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reservation performed with other device/ before start of app.
|
||||
/// Date time info when bike was reserved has been received from web server.
|
||||
/// </summary>
|
||||
/// <param name="dateTimeNowProvider">
|
||||
/// Used to provide current date time information for potential calls of <seealso cref="GetIsStillReserved"/>.
|
||||
/// Not used to calculate remaining time because this duration would always be shorter as the one received from web server.
|
||||
/// </param>
|
||||
/// <param name="maxReservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
public StateRequestedInfo(
|
||||
Func<DateTime> dateTimeNowProvider,
|
||||
DateTime from,
|
||||
TimeSpan maxReservationTimeSpan,
|
||||
string mailAddress,
|
||||
string code) : base(InUseStateEnum.Reserved)
|
||||
{
|
||||
_DateTimeNowProvider = dateTimeNowProvider ?? (() => DateTime.Now);
|
||||
MaxReservationTimeSpan = maxReservationTimeSpan;
|
||||
From = from;
|
||||
MailAddress = mailAddress;
|
||||
Code = code;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries update
|
||||
/// </summary>
|
||||
/// <returns>True if reservation span has not exceeded and state remains reserved, false otherwise.</returns>
|
||||
/// <todo>Implement logging of time stamps.</todo>
|
||||
public bool GetIsStillReserved(out TimeSpan? remainingTime)
|
||||
{
|
||||
var timeReserved = _DateTimeNowProvider().Subtract(From);
|
||||
if (timeReserved > MaxReservationTimeSpan)
|
||||
|
||||
{
|
||||
// Reservation has elapsed. Do not update remaining time.
|
||||
remainingTime = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
remainingTime = MaxReservationTimeSpan - timeReserved;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State reserved.
|
||||
/// </summary>
|
||||
public override InUseStateEnum Value =>
|
||||
InUseStateEnum.Reserved;
|
||||
|
||||
/// <summary>
|
||||
/// Date time when bike was reserved.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime From { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Mail address of user who reserved the bike.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string MailAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Booking code.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Code { get; }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue