aboutsummaryrefslogtreecommitdiff
path: root/src/Costasdev.Busurbano.Backend/Services/Providers/XuntaFareProvider.cs
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2025-12-28 00:17:11 +0100
committerAriel Costas Guerrero <ariel@costas.dev>2025-12-28 00:17:11 +0100
commit1fd17d4d07d25a810816e4e38ddc31ae72b8c91a (patch)
treeacd8e54ac1abea4fa9ba23430f4a80aba743aa11 /src/Costasdev.Busurbano.Backend/Services/Providers/XuntaFareProvider.cs
parentfbd2c1aa2dd25dd61483553d114c484060f71bd6 (diff)
Basic fare calculations for Galicia (Xunta)
Diffstat (limited to 'src/Costasdev.Busurbano.Backend/Services/Providers/XuntaFareProvider.cs')
-rw-r--r--src/Costasdev.Busurbano.Backend/Services/Providers/XuntaFareProvider.cs57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/Costasdev.Busurbano.Backend/Services/Providers/XuntaFareProvider.cs b/src/Costasdev.Busurbano.Backend/Services/Providers/XuntaFareProvider.cs
new file mode 100644
index 0000000..7536c69
--- /dev/null
+++ b/src/Costasdev.Busurbano.Backend/Services/Providers/XuntaFareProvider.cs
@@ -0,0 +1,57 @@
+using System.Collections.Frozen;
+using System.Globalization;
+using CsvHelper;
+using CsvHelper.Configuration.Attributes;
+
+namespace Costasdev.Busurbano.Backend.Services.Providers;
+
+public class PriceRecord
+{
+ [Name("conc_inicio")] public string Origin { get; set; }
+ [Name("conc_fin")] public string Destination { get; set; }
+ [Name("bonificacion")] public string? MetroArea { get; set; }
+ [Name("efectivo")] public decimal PriceCash { get; set; }
+ [Name("tpg")] public decimal PriceCard { get; set; }
+}
+
+public class XuntaFareProvider
+{
+ private readonly FrozenDictionary<(string, string), PriceRecord> _priceMatrix;
+
+ public XuntaFareProvider(IWebHostEnvironment env)
+ {
+ var filePath = Path.Combine(env.ContentRootPath, "Data", "xunta_fares.csv");
+
+ using var reader = new StreamReader(filePath);
+ using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
+
+ // We do GroupBy first to prevent duplicates from throwing an exception
+ _priceMatrix = csv.GetRecords<PriceRecord>()
+ .GroupBy(record => (record.Origin, record.Destination))
+ .ToFrozenDictionary(
+ group => group.Key,
+ group => group.First()
+ );
+ }
+
+ public PriceRecord? GetPrice(string origin, string destination)
+ {
+ var originMunicipality = origin[..5];
+ var destinationMunicipality = destination[..5];
+
+ var valueOrDefault = _priceMatrix.GetValueOrDefault((originMunicipality, destinationMunicipality));
+
+ /* This happens in cases where traffic is forbidden (like inside municipalities with urban transit */
+ if (valueOrDefault?.PriceCash == 0.0M)
+ {
+ valueOrDefault.PriceCash = 100;
+ }
+
+ if (valueOrDefault?.PriceCard == 0.0M)
+ {
+ valueOrDefault.PriceCard = 100;
+ }
+
+ return valueOrDefault;
+ }
+}