blob: 9a11a569a702f3ee27ef01d0f852d88582a2b8f3 (
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
58
59
60
61
62
63
64
65
|
using Costasdev.Busurbano.Backend.Configuration;
using Costasdev.Busurbano.Backend.Types.Planner;
using Microsoft.Extensions.Options;
namespace Costasdev.Busurbano.Backend.Services;
public record FareResult(double CashFareEuro, double CardFareEuro);
public class FareService
{
private readonly AppConfiguration _config;
public FareService(IOptions<AppConfiguration> config)
{
_config = config.Value;
}
public FareResult CalculateFare(IEnumerable<Leg> legs)
{
var busLegs = legs.Where(l => l.Mode != null && l.Mode.ToUpper() != "WALK").ToList();
// Cash fare logic
double cashFare = 0;
foreach (var leg in busLegs)
{
// TODO: In the future, this should depend on the operator/feed
if (leg.FeedId == "vitrasa")
{
cashFare += 1.63;
}
else
{
cashFare += 1.63; // Default fallback
}
}
// Card fare logic (45-min transfer window)
int cardTicketsRequired = 0;
DateTime? lastTicketPurchased = null;
int tripsPaidWithTicket = 0;
string? lastFeedId = null;
foreach (var leg in busLegs)
{
// If no ticket purchased, ticket expired (no free transfers after 45 mins), or max trips with ticket reached
// Also check if we changed operator (assuming no free transfers between different operators for now)
if (lastTicketPurchased == null ||
(leg.StartTime - lastTicketPurchased.Value).TotalMinutes > 45 ||
tripsPaidWithTicket >= 3 ||
leg.FeedId != lastFeedId)
{
cardTicketsRequired++;
lastTicketPurchased = leg.StartTime;
tripsPaidWithTicket = 1;
lastFeedId = leg.FeedId;
}
else
{
tripsPaidWithTicket++;
}
}
return new FareResult(cashFare, cardTicketsRequired * 0.67);
}
}
|