From f81ff82f2a07f87f6eb4f43de49ede64215519e5 Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Sat, 27 Dec 2025 16:39:09 +0100 Subject: Refactor route planner to use new GraphQL backend --- .../Services/FareService.cs | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/Costasdev.Busurbano.Backend/Services/FareService.cs (limited to 'src/Costasdev.Busurbano.Backend/Services/FareService.cs') diff --git a/src/Costasdev.Busurbano.Backend/Services/FareService.cs b/src/Costasdev.Busurbano.Backend/Services/FareService.cs new file mode 100644 index 0000000..0e4fefc --- /dev/null +++ b/src/Costasdev.Busurbano.Backend/Services/FareService.cs @@ -0,0 +1,49 @@ +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 config) + { + _config = config.Value; + } + + public FareResult CalculateFare(IEnumerable legs) + { + var busLegs = legs.Where(l => l.Mode != null && l.Mode.ToUpper() != "WALK").ToList(); + + // Cash fare logic + // TODO: In the future, this should depend on the operator/feed + var cashFare = busLegs.Count * 1.63; // Defaulting to Vitrasa for now + + // Card fare logic (45-min transfer window) + int cardTicketsRequired = 0; + DateTime? lastTicketPurchased = null; + int tripsPaidWithTicket = 0; + + foreach (var leg in busLegs) + { + if (lastTicketPurchased == null || + (leg.StartTime - lastTicketPurchased.Value).TotalMinutes > 45 || + tripsPaidWithTicket >= 3) + { + cardTicketsRequired++; + lastTicketPurchased = leg.StartTime; + tripsPaidWithTicket = 1; + } + else + { + tripsPaidWithTicket++; + } + } + + return new FareResult(cashFare, cardTicketsRequired * 0.67); + } +} -- cgit v1.3