ex-inh-05-transport/Transport/Vehicle.cs
github-classroom[bot] dcabbbaf15
Initial commit
2025-02-25 17:10:54 +00:00

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);
}