aboutsummaryrefslogtreecommitdiff
path: root/src/Enmarcha.Backend/Services/Providers/XuntaFareProvider.cs
blob: 4bb60e2302f5a9fd8cb2cfdf91a82c45d23b1773 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System.Collections.Frozen;
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration.Attributes;

namespace Enmarcha.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;
    }
}