129 lines
3.6 KiB
Go
129 lines
3.6 KiB
Go
package cif
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"git.fjla.uk/owlboard/go-types/pkg/database"
|
|
"git.fjla.uk/owlboard/go-types/pkg/upstreamApi"
|
|
"git.fjla.uk/owlboard/timetable-mgr/helpers"
|
|
"git.fjla.uk/owlboard/timetable-mgr/log"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func ConvertServiceType(input *upstreamApi.JsonScheduleV1, vstp bool) (*database.Service, error) {
|
|
output := database.Service{
|
|
//TransactionType: input.TransactionType,
|
|
StpIndicator: input.CifStpIndicator,
|
|
Operator: input.AtocCode,
|
|
TrainUid: input.CifTrainUid,
|
|
Headcode: input.ScheduleSegment.SignallingId,
|
|
PowerType: input.ScheduleSegment.CifPowerType,
|
|
PlanSpeed: parseSpeed(&input.ScheduleSegment.CifSpeed),
|
|
ScheduleStartDate: ParseCifDate(&input.ScheduleStartDate, "start"),
|
|
ScheduleEndDate: ParseCifDate(&input.ScheduleEndDate, "end"),
|
|
ServiceDetail: generateServiceDetail(&input.ScheduleSegment.CifTrainClass, &input.ScheduleSegment.SignallingId, &input.ScheduleSegment.CifCateringCode, &input.ScheduleSegment.CifSleepers, vstp),
|
|
DaysRun: parseDaysRun(&input.ScheduleDaysRun),
|
|
Stops: parseStops(&input.ScheduleSegment.ScheduleLocation),
|
|
}
|
|
|
|
return &output, nil
|
|
}
|
|
|
|
// Converts CifSpeed input string to an int32, automatically corrects VSTP speeds which are not actual speed values
|
|
func parseSpeed(CIFSpeed *string) int32 {
|
|
if CIFSpeed == nil {
|
|
return 0
|
|
}
|
|
if *CIFSpeed == "" {
|
|
return int32(0)
|
|
}
|
|
actualSpeed, exists := helpers.SpeedMap[*CIFSpeed]
|
|
if !exists {
|
|
actualSpeed = *CIFSpeed
|
|
}
|
|
|
|
speed, err := strconv.ParseInt(actualSpeed, 10, 32)
|
|
if err != nil {
|
|
log.Warn("Unable to parse speed", zap.String("input-value", *CIFSpeed))
|
|
return int32(0)
|
|
}
|
|
return int32(speed)
|
|
}
|
|
|
|
// Not tested
|
|
func parseStops(input *[]upstreamApi.CifScheduleLocation) []database.Stop {
|
|
output := make([]database.Stop, 0, len(*input))
|
|
|
|
for _, item := range *input {
|
|
stop := database.Stop{
|
|
PublicDeparture: item.PublicDeparture,
|
|
PublicArrival: item.PublicArrival,
|
|
WttDeparture: item.Departure,
|
|
WttArrival: item.Arrival,
|
|
Pass: item.Pass,
|
|
Platform: item.Platform,
|
|
ArrLine: item.Path,
|
|
DepLine: item.Line,
|
|
Tiploc: item.TiplocCode,
|
|
IsPublic: isPublic(&item),
|
|
}
|
|
|
|
output = append(output, stop)
|
|
}
|
|
|
|
return output
|
|
}
|
|
|
|
// Ascertains whether a given location is a public stop or not
|
|
func isPublic(input *upstreamApi.CifScheduleLocation) bool {
|
|
if input.PublicArrival == "" && input.PublicDeparture == "" {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Generates a ServiceDetail struct based on the input
|
|
func generateServiceDetail(
|
|
cifTrainClass, signallingId,
|
|
cateringCode, sleepers *string,
|
|
vstp bool,
|
|
) database.ServiceDetail {
|
|
return database.ServiceDetail{
|
|
FirstClass: hasFirstClass(cifTrainClass, signallingId),
|
|
Catering: hasCatering(cateringCode),
|
|
Sleeper: hasSleeper(sleepers),
|
|
Vstp: vstp,
|
|
}
|
|
}
|
|
|
|
// Ascertains whether the service offers first class
|
|
func hasFirstClass(input, signallingId *string) bool {
|
|
if input == nil || signallingId == nil {
|
|
return false
|
|
}
|
|
|
|
// Handle non passenger headcodes and ensure first class is not shown as available
|
|
firstChar := (*signallingId)[0]
|
|
if firstChar == '3' || firstChar == '4' || firstChar == '5' || firstChar == '6' || firstChar == '7' || firstChar == '8' || firstChar == '0' {
|
|
return false
|
|
}
|
|
|
|
return *input != "S"
|
|
}
|
|
|
|
// Ascertains whether the service offers catering
|
|
func hasCatering(input *string) bool {
|
|
if input == nil {
|
|
return false
|
|
}
|
|
return *input != ""
|
|
}
|
|
|
|
// Ascertains whether the service offers sleeping berths
|
|
func hasSleeper(input *string) bool {
|
|
if input == nil {
|
|
return false
|
|
}
|
|
return *input != ""
|
|
}
|