Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

public partial class App : Application
{
public static IServiceProvider ServiceProvider { get; private set; }

public App()
{
InitializeComponent();
MainPage = new AppShell();
}
protected override void OnStart()
{
base.OnStart();
ServiceProvider = MauiProgram.CreateMauiApp().Services;
}

protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new AppShell());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace LibraryAppInteractive.Business_Logic;

public enum AssetStatus
{
NotAvailable = 0,
Available = 1,
Loaned,
Reserved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
namespace LibraryAppInteractive.Business_Logic;

public class Book
{
private string _bookName;
private string _bookISBN;
private List<string> _bookAuthorList;
private List<LibraryAsset> _libAssetList;
private BookType _bookType;

public string Name
{
get => _bookName;
set => _bookName = value;
}

public string ISBN
{
get => _bookISBN;
set => _bookISBN = value;
}

public List<string> Authors
{
get => _bookAuthorList;
set => _bookAuthorList = value;
}

public List<LibraryAsset> Assets
{
get => _libAssetList;
set => _libAssetList = value;
}

public BookType BookType
{
get => _bookType;
set => _bookType = value;
}

public Book(string bookName, string bookISBN, BookType bookType = BookType.Paper)
{
_bookName = bookName;
_bookISBN = bookISBN;
_bookType = bookType;
_bookAuthorList = new List<string>();
_libAssetList = new List<LibraryAsset>();
}

/// <summary>
/// Checks the availability of the book by checking if there are any library assets
/// for this book that are available to borrow.
/// Returns:
/// (true, null) - an asset is available and could be loaned
/// (false, DateTime) - all assets are loaned or reserved. Returns the earliest available date.
/// </summary>
public (bool, DateTime?) CheckAvailability()
{
LibraryAsset nextAvailAsset = FindNextAvailableAsset();

if (nextAvailAsset?.Status == AssetStatus.Available)
{
return (true, null);
}
else
{
return (false, nextAvailAsset?.DueDate);
}
}

/// <summary>
/// Attempts to find an available asset and loans it to the user.
/// If no book asset is available, throws an exception.
/// </summary>
public virtual LibraryAsset BorrowBook()
{
LibraryAsset libraryAsset = FindNextAvailableAsset();

if (libraryAsset?.Status != AssetStatus.Available)
{
throw new InvalidOperationException("The requested book is not available. You can check for availability first and reserve it.");
}

libraryAsset.BorrowedOn = DateTime.Now;
libraryAsset.Status = AssetStatus.Loaned;

// Set default due date (14 days). Derived classes can override this.
libraryAsset.DueDate = DateTime.Now.AddDays(14);

return libraryAsset;
}

/// <summary>
/// Returns a borrowed asset back to the library using the ID of the library asset.
/// </summary>
public virtual (TimeSpan, int, decimal) ReturnBook(int libID)
{
LibraryAsset libraryAsset = FindLibraryAsset(libID);
libraryAsset.ReturnedOn = DateTime.Now;

TimeSpan loanDuration = libraryAsset.GetLoanDuration();
TimeSpan latePeriod = libraryAsset.GetLatePeriod();

libraryAsset.Status = AssetStatus.Available;

// Base method does not calculate late penalties. Derived classes must perform this.
return (loanDuration, latePeriod.Days, 0.0m);
}

/// <summary>
/// Finds and reserves the earliest available asset for this book.
/// </summary>
public LibraryAsset ReserveBook()
{
LibraryAsset nextAvailAsset = FindNextAvailableAsset();
nextAvailAsset.Status = AssetStatus.Reserved;
return nextAvailAsset;
}

/// <summary>
/// Finds the library asset with the given ID.
/// Throws an exception if no asset is found.
/// </summary>
private LibraryAsset FindLibraryAsset(int libID)
{
foreach (LibraryAsset asset in _libAssetList)
{
if (asset.LibId == libID)
{
return asset;
}
}

throw new InvalidOperationException($"An asset with ID = {libID} was not found for book {Name}");
}

/// <summary>
/// Finds the next available asset for this book.
/// If an asset is available immediately, it returns that one.
/// Otherwise, returns the asset with the earliest due date.
/// </summary>
private LibraryAsset FindNextAvailableAsset()
{
LibraryAsset nextAvailAsset = null;

foreach (LibraryAsset asset in _libAssetList)
{
// Check if asset is available immediately
if (asset.Status == AssetStatus.Available)
{
return asset;
}

// Find asset with the earliest due date
if (nextAvailAsset == null ||
(nextAvailAsset.DueDate > asset.DueDate && nextAvailAsset.Status != AssetStatus.Reserved))
{
nextAvailAsset = asset;
}
}

return nextAvailAsset;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace LibraryAppInteractive.Business_Logic;

public enum BookType
{
Paper = 1,
Digital,
Audio
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
namespace LibraryAppInteractive.Business_Logic;

public class DigitalBook : Book
{
private int _maxBorrowDays;
private float _latePenaltyPerDay;
private Random _random = new Random();

public DigitalBook(string bookName, string bookISBN) : base(bookName, bookISBN, BookType.Digital)
{
_maxBorrowDays = 0;
_latePenaltyPerDay = 0.0f;

DetermineLoanLicense();
}

/// <summary>
/// Determine the values for maximum loan duration and late penalty according to license agreement using randomly generated values.
/// Maximum loan duration: 2-8 weeks (randomly)
/// Late penalty: 0.1 - 0.5 per day (randomly)
/// </summary>
private void DetermineLoanLicense()
{
_maxBorrowDays = _random.Next(2 * 7, 8 * 7 + 1); // 2-8 weeks in days
_latePenaltyPerDay = 0.1f + (float)_random.NextDouble() * 0.4f; // 0.1 to 0.5
}

/// <summary>
/// Overrides the base implementation to use the deadline for digital books.
/// </summary>
public override LibraryAsset BorrowBook()
{
LibraryAsset libAsset = base.BorrowBook();

// Adjust due date according to digital book policy
libAsset.DueDate = DateTime.Now.AddDays(_maxBorrowDays);

return libAsset;
}

/// <summary>
/// Returns a borrowed asset and calculates late fees according to digital book policy.
/// </summary>
public override (TimeSpan, int, decimal) ReturnBook(int libID)
{
(TimeSpan loanDuration, int daysLate, decimal lateFees) = base.ReturnBook(libID);

return (loanDuration, daysLate, (decimal)(daysLate * _latePenaltyPerDay));
}
}
Loading