199 lines
6.4 KiB
C#
199 lines
6.4 KiB
C#
using System.Globalization;
|
|
|
|
namespace Transport;
|
|
|
|
/// <summary>
|
|
/// Represents a vehicle which can be rented for a ride
|
|
/// </summary>
|
|
public abstract class Vehicle
|
|
{
|
|
private readonly List<Ride> _rides;
|
|
private RentalInfo? _rentalInfo;
|
|
|
|
protected Vehicle(int id, Color color, int weight, double initialMileage)
|
|
{
|
|
Id = id;
|
|
Color = color;
|
|
Weight = weight;
|
|
Mileage = initialMileage;
|
|
_rides = [];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the base price of the vehicle per rental
|
|
/// </summary>
|
|
public abstract decimal BasePrice { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the price per km
|
|
/// </summary>
|
|
public abstract decimal PricePerKM { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the cost per km
|
|
/// </summary>
|
|
public abstract decimal CostPerKM { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the color of the vehicle
|
|
/// </summary>
|
|
public Color Color { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the weight of the vehicle
|
|
/// </summary>
|
|
public int Weight { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the unique id of the vehicle
|
|
/// </summary>
|
|
public int Id { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the current mileage of the vehicle
|
|
/// </summary>
|
|
public double Mileage { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets if the vehicle is available for rent
|
|
/// </summary>
|
|
public bool IsFree => _rentalInfo is null;
|
|
|
|
/// <summary>
|
|
/// Rents the vehicle for a ride of the specified distance
|
|
/// </summary>
|
|
/// <param name="customerName">Name of the customer renting the vehicle</param>
|
|
/// <param name="distance">Distance of the ride</param>
|
|
/// <returns>True if the vehicle could be rented; false otherwise</returns>
|
|
public bool Rent(string customerName, double distance)
|
|
{
|
|
// TODO
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ends the current (rental) ride.
|
|
/// A ride can only be ended if the vehicle was rented in the first place.
|
|
/// </summary>
|
|
/// <returns>A flag indicating if the ride was ended and the total price to pay for it</returns>
|
|
public (bool success, decimal? price) EndRide()
|
|
{
|
|
// TODO
|
|
return (false, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds the travel log sheet for this vehicle to the supplied workbook.
|
|
/// Only creates the sheet if the vehicle has been used at least one ride.
|
|
/// </summary>
|
|
/// <param name="workbook">The workbook to add to</param>
|
|
public void AddTravelLogSheet(IXLWorkbook workbook)
|
|
{
|
|
// TODO
|
|
|
|
// static string FormatCurrency(decimal v) => Format((double) v);
|
|
// static string Format(double v) => v.ToString("F2", NumberFormatInfo.InvariantInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads data in the given excel row and turns it into an easier to process instance of <see cref="ExcelData" />
|
|
/// </summary>
|
|
/// <param name="row">Row to process</param>
|
|
/// <param name="columnCount">Number of columns to process</param>
|
|
/// <returns>Data of the row, if it could be parsed</returns>
|
|
protected static ExcelData? ProcessExcelRow(IXLRow row, int columnCount)
|
|
{
|
|
// TODO
|
|
return null;
|
|
|
|
/*
|
|
string? GetValue(int col)
|
|
{
|
|
string? val = row.Cell(col).GetValue<string?>();
|
|
|
|
return string.IsNullOrWhiteSpace(val) ? null : val;
|
|
}
|
|
*/
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets all rows from the given worksheet, excluding the header row
|
|
/// </summary>
|
|
/// <param name="worksheet">Worksheet to process</param>
|
|
/// <returns>Rows in the worksheet</returns>
|
|
protected static List<IXLRow> GetRowsFromWorksheet(IXLWorksheet worksheet) =>
|
|
worksheet.Rows().ToArray()[1..].ToList();
|
|
|
|
/// <summary>
|
|
/// Tries to parse the given string as a double, using the invariant culture
|
|
/// </summary>
|
|
/// <param name="value">Value to parse</param>
|
|
/// <param name="result">Parsed value</param>
|
|
/// <returns>True if parsing succeeded; false otherwise</returns>
|
|
protected static bool TryParseDoubleInvariant(string? value, out double result)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
result = 0D;
|
|
|
|
return false;
|
|
}
|
|
|
|
return double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the number of used columns in the given worksheet
|
|
/// </summary>
|
|
/// <param name="worksheet">Worksheet to process</param>
|
|
/// <returns>The number of columns</returns>
|
|
protected static int GetColumnsOfWorksheet(IXLWorksheet worksheet) => worksheet.ColumnsUsed().Count();
|
|
|
|
protected bool Equals(Vehicle other) =>
|
|
Color == other.Color && Weight == other.Weight && Id == other.Id && Mileage.Equals(other.Mileage);
|
|
|
|
public override bool Equals(object? obj)
|
|
{
|
|
if (ReferenceEquals(null, obj))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (ReferenceEquals(this, obj))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (obj.GetType() != GetType())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return Equals((Vehicle) obj);
|
|
}
|
|
|
|
public override int GetHashCode() => HashCode.Combine((int) Color, Weight, Id);
|
|
|
|
public static bool operator ==(Vehicle? left, Vehicle? right) => Equals(left, right);
|
|
|
|
public static bool operator !=(Vehicle? left, Vehicle? right) => !Equals(left, right);
|
|
|
|
/// <summary>
|
|
/// Contains the already parsed common properties of each vehicle.
|
|
/// May contain additional columns for properties of more specialized vehicles.
|
|
/// </summary>
|
|
/// <param name="Id">Unique id of the vehicle</param>
|
|
/// <param name="Color">Color of the vehicle</param>
|
|
/// <param name="Weight">Weight of the vehicle in kg</param>
|
|
/// <param name="InitialMileage">Mileage of the vehicle before the first ride</param>
|
|
/// <param name="AdditionalCellValues">Optional additional (raw) values</param>
|
|
protected sealed record ExcelData(int Id, Color Color, int Weight, double InitialMileage,
|
|
List<string?> AdditionalCellValues);
|
|
|
|
/// <summary>
|
|
/// Represents basic information about a rental
|
|
/// </summary>
|
|
/// <param name="CustomerName">Name of the customer who rented the vehicle</param>
|
|
/// <param name="Distance">Distance of the ride</param>
|
|
protected sealed record RentalInfo(string CustomerName, double Distance);
|
|
}
|