Skip to content

Commit

Permalink
Merge pull request #669 from georgesmith46/fix-flight-date-estimation
Browse files Browse the repository at this point in the history
Fix flight date estimation
  • Loading branch information
georgesmith46 committed Jan 4, 2024
2 parents 17cf84e + b20799a commit 6e06ff4
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 42 deletions.
23 changes: 17 additions & 6 deletions src/decode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe("decode", () => {
"M1DESMARAIS/LUC EABC123 FRAAC 226F001A 3B>60B1W 6225BAC 2A 1234567890 1AC AC 1234567890123 20KY^164GIWVC5EH7JNT684FVNJ91W2QA4DVN5J8K4F0L0GEQ3DF5TGBN8709HKT5D3DW3GBHFCVHMY7J5T6HFR41W2QA4DVN5J8K4F0L0GE";

it("should have the expected output", () => {
expect(decode(input)).toEqual({
expect(decode(input, 2016)).toEqual({
meta: {
formatCode: "M",
numberOfLegs: 1,
Expand Down Expand Up @@ -87,7 +87,7 @@ describe("decode", () => {
"M2DESMARAIS/LUC EABC123 YULFRAAC 0834 226F001A0025 14D>6181WW6225BAC 00141234560032A0141234567890 1AC AC 1234567890123 20KYLX58ZDEF456 FRAGVALH 3664 227C012C0002 12E2A0140987654321 1AC AC 1234567890123 2PCNWQ^164GIWVC5EH7JNT684FVNJ91W2QA4DVN5J8K4F0L0GEQ3DF5TGBN8709HKT5D3DW3GBHFCVHMY7J5T6HFR41W2QA4DVN5J8K4F0L0GE";

it("should have the expected output", () => {
expect(decode(input)).toEqual({
expect(decode(input, 2016)).toEqual({
meta: {
formatCode: "M",
numberOfLegs: 2,
Expand Down Expand Up @@ -193,10 +193,9 @@ describe("decode", () => {
});
});
describe("reference year", () => {
const input =
"M1DESMARAIS/LUC EABC123 FRAAC 226F001A 3B>60B1W 6225BAC 2A 1234567890 1AC AC 1234567890123 20KY^164GIWVC5EH7JNT684FVNJ91W2QA4DVN5J8K4F0L0GEQ3DF5TGBN8709HKT5D3DW3GBHFCVHMY7J5T6HFR41W2QA4DVN5J8K4F0L0GE";

it("should have the expected output when reference year is 2010", () => {
const input =
"M1DESMARAIS/LUC EABC123 FRAAC 226F001A 3B>60B1W 0225BAC 2A 1234567890 1AC AC 1234567890123 20KY^164GIWVC5EH7JNT684FVNJ91W2QA4DVN5J8K4F0L0GEQ3DF5TGBN8709HKT5D3DW3GBHFCVHMY7J5T6HFR41W2QA4DVN5J8K4F0L0GE";
expect(decode(input, 2010)).toEqual({
meta: {
formatCode: "M",
Expand Down Expand Up @@ -227,7 +226,7 @@ describe("decode", () => {
passengerName: "DESMARAIS/LUC",
passengerDescription: "1",
checkInSource: "W",
issuanceDate: new Date("2006-08-13T00:00:00.000Z"),
issuanceDate: new Date("2010-08-13T00:00:00.000Z"),
documentType: "B",
boardingPassIssuerDesignator: "AC",
securityDataType: "1",
Expand All @@ -238,6 +237,8 @@ describe("decode", () => {
});

it("should have the expected output when reference year is 2006", () => {
const input =
"M1DESMARAIS/LUC EABC123 FRAAC 226F001A 3B>60B1W 6225BAC 2A 1234567890 1AC AC 1234567890123 20KY^164GIWVC5EH7JNT684FVNJ91W2QA4DVN5J8K4F0L0GEQ3DF5TGBN8709HKT5D3DW3GBHFCVHMY7J5T6HFR41W2QA4DVN5J8K4F0L0GE";
expect(decode(input, 2006)).toEqual({
meta: {
formatCode: "M",
Expand Down Expand Up @@ -278,4 +279,14 @@ describe("decode", () => {
});
});
});
describe("flight date estimation", () => {
it("it should estimate the flight date year based on the issuance date", () => {
const input =
"M1DESMARAIS/LUC EABC123 YULFRAAC 0834 001F001A0025 10D>607 136400";

expect(decode(input, 2023).data.legs[0].flightDate).toEqual(
new Date("2022-01-01T00:00:00.000Z"),
);
});
});
});
64 changes: 32 additions & 32 deletions src/decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const decode = (barcodeString: string, referenceYear?: number) => {
mainSection.getNextNumber(LENGTHS.NUMBER_OF_LEGS) ?? 0;
bcbp.data.passengerName = mainSection.getNextString(LENGTHS.PASSENGER_NAME);
bcbp.meta.electronicTicketIndicator = mainSection.getNextString(
LENGTHS.ELECTRONIC_TICKET_INDICATOR
LENGTHS.ELECTRONIC_TICKET_INDICATOR,
);

bcbp.data.legs = [];
Expand All @@ -91,96 +91,96 @@ export const decode = (barcodeString: string, referenceYear?: number) => {
for (let legIndex = 0; legIndex < bcbp.meta.numberOfLegs; legIndex++) {
const leg: Leg = {};
leg.operatingCarrierPNR = mainSection.getNextString(
LENGTHS.OPERATING_CARRIER_PNR
LENGTHS.OPERATING_CARRIER_PNR,
);
leg.departureAirport = mainSection.getNextString(LENGTHS.DEPARTURE_AIRPORT);
leg.arrivalAirport = mainSection.getNextString(LENGTHS.ARRIVAL_AIRPORT);
leg.operatingCarrierDesignator = mainSection.getNextString(
LENGTHS.OPERATING_CARRIER_DESIGNATOR
LENGTHS.OPERATING_CARRIER_DESIGNATOR,
);
leg.flightNumber = mainSection.getNextString(LENGTHS.FLIGHT_NUMBER);
leg.flightDate = mainSection.getNextDate(
LENGTHS.FLIGHT_DATE,
false,
referenceYear
referenceYear,
);
leg.compartmentCode = mainSection.getNextString(LENGTHS.COMPARTMENT_CODE);
leg.seatNumber = mainSection.getNextString(LENGTHS.SEAT_NUMBER);
leg.checkInSequenceNumber = mainSection.getNextString(
LENGTHS.CHECK_IN_SEQUENCE_NUMBER
LENGTHS.CHECK_IN_SEQUENCE_NUMBER,
);
leg.passengerStatus = mainSection.getNextString(LENGTHS.PASSENGER_STATUS);

const conditionalSectionSize = mainSection.getNextSectionSize();
const conditionalSection = new SectionDecoder(
mainSection.getNextString(conditionalSectionSize)
mainSection.getNextString(conditionalSectionSize),
);

if (!addedUniqueFields) {
bcbp.meta.versionNumberIndicator = conditionalSection.getNextString(
LENGTHS.VERSION_NUMBER_INDICATOR
LENGTHS.VERSION_NUMBER_INDICATOR,
);
bcbp.meta.versionNumber = conditionalSection.getNextNumber(
LENGTHS.VERSION_NUMBER
LENGTHS.VERSION_NUMBER,
);

const sectionASize = conditionalSection.getNextSectionSize();
const sectionA = new SectionDecoder(
conditionalSection.getNextString(sectionASize)
conditionalSection.getNextString(sectionASize),
);
bcbp.data.passengerDescription = sectionA.getNextString(
LENGTHS.PASSENGER_DESCRIPTION
LENGTHS.PASSENGER_DESCRIPTION,
);
bcbp.data.checkInSource = sectionA.getNextString(LENGTHS.CHECK_IN_SOURCE);
bcbp.data.boardingPassIssuanceSource = sectionA.getNextString(
LENGTHS.BOARDING_PASS_ISSUANCE_SOURCE
LENGTHS.BOARDING_PASS_ISSUANCE_SOURCE,
);
bcbp.data.issuanceDate = sectionA.getNextDate(
LENGTHS.ISSUANCE_DATE,
true,
referenceYear
referenceYear,
);
bcbp.data.documentType = sectionA.getNextString(LENGTHS.DOCUMENT_TYPE);
bcbp.data.boardingPassIssuerDesignator = sectionA.getNextString(
LENGTHS.BOARDING_PASS_ISSUER_DESIGNATOR
LENGTHS.BOARDING_PASS_ISSUER_DESIGNATOR,
);
bcbp.data.baggageTagNumber = sectionA.getNextString(
LENGTHS.BAGGAGE_TAG_NUMBER
LENGTHS.BAGGAGE_TAG_NUMBER,
);
bcbp.data.firstBaggageTagNumber = sectionA.getNextString(
LENGTHS.FIRST_BAGGAGE_TAG_NUMBER
LENGTHS.FIRST_BAGGAGE_TAG_NUMBER,
);
bcbp.data.secondBaggageTagNumber = sectionA.getNextString(
LENGTHS.SECOND_BAGGAGE_TAG_NUMBER
LENGTHS.SECOND_BAGGAGE_TAG_NUMBER,
);

addedUniqueFields = true;
}

const sectionBSize = conditionalSection.getNextSectionSize();
const sectionB = new SectionDecoder(
conditionalSection.getNextString(sectionBSize)
conditionalSection.getNextString(sectionBSize),
);
leg.airlineNumericCode = sectionB.getNextString(
LENGTHS.AIRLINE_NUMERIC_CODE
LENGTHS.AIRLINE_NUMERIC_CODE,
);
leg.serialNumber = sectionB.getNextString(LENGTHS.SERIAL_NUMBER);
leg.selecteeIndicator = sectionB.getNextString(LENGTHS.SELECTEE_INDICATOR);
leg.internationalDocumentationVerification = sectionB.getNextString(
LENGTHS.INTERNATIONAL_DOCUMENTATION_VERIFICATION
LENGTHS.INTERNATIONAL_DOCUMENTATION_VERIFICATION,
);
leg.marketingCarrierDesignator = sectionB.getNextString(
LENGTHS.MARKETING_CARRIER_DESIGNATOR
LENGTHS.MARKETING_CARRIER_DESIGNATOR,
);
leg.frequentFlyerAirlineDesignator = sectionB.getNextString(
LENGTHS.FREQUENT_FLYER_AIRLINE_DESIGNATOR
LENGTHS.FREQUENT_FLYER_AIRLINE_DESIGNATOR,
);
leg.frequentFlyerNumber = sectionB.getNextString(
LENGTHS.FREQUENT_FLYER_NUMBER
LENGTHS.FREQUENT_FLYER_NUMBER,
);
leg.idIndicator = sectionB.getNextString(LENGTHS.ID_INDICATOR);
leg.freeBaggageAllowance = sectionB.getNextString(
LENGTHS.FREE_BAGGAGE_ALLOWANCE
LENGTHS.FREE_BAGGAGE_ALLOWANCE,
);
leg.fastTrack = sectionB.getNextBoolean();

Expand All @@ -190,27 +190,27 @@ export const decode = (barcodeString: string, referenceYear?: number) => {
}

bcbp.meta.securityDataIndicator = mainSection.getNextString(
LENGTHS.SECURITY_DATA_INDICATOR
LENGTHS.SECURITY_DATA_INDICATOR,
);
bcbp.data.securityDataType = mainSection.getNextString(
LENGTHS.SECURITY_DATA_TYPE
LENGTHS.SECURITY_DATA_TYPE,
);

const securitySectionSize = mainSection.getNextSectionSize();
const securitySection = new SectionDecoder(
mainSection.getNextString(securitySectionSize)
mainSection.getNextString(securitySectionSize),
);
bcbp.data.securityData = securitySection.getNextString(LENGTHS.SECURITY_DATA);

if (bcbp.data.issuanceDate !== undefined && referenceYear === undefined) {
if (bcbp.data.issuanceDate !== undefined) {
const issuanceYear = bcbp.data.issuanceDate.getFullYear();
for (let leg of bcbp.data.legs) {
if (leg.flightDate !== undefined) {
const dayOfYear = dateToDayOfYear(leg.flightDate);
leg.flightDate = dayOfYearToDate(
dayOfYear,
false,
bcbp.data.issuanceDate.getFullYear()
);
leg.flightDate = dayOfYearToDate(dayOfYear, false, issuanceYear);
if (leg.flightDate < bcbp.data.issuanceDate) {
leg.flightDate = dayOfYearToDate(dayOfYear, false, issuanceYear + 1);
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/encode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe("encode", () => {
});
describe("basic", () => {
const expected =
"M1DESMARAIS/LUC EABC123 YULFRAAC 0834 226F001A0025 106>60000",
"M1DESMARAIS/LUC EABC123 YULFRAAC 0834 001F001A0025 106>60000",
input = {
data: {
passengerName: "DESMARAIS/LUC",
Expand All @@ -33,7 +33,7 @@ describe("encode", () => {
arrivalAirport: "FRA",
operatingCarrierDesignator: "AC",
flightNumber: "0834",
flightDate: new Date("2016-08-13T00:00:00.000Z"),
flightDate: new Date("2016-01-01T00:00:00.000Z"),
compartmentCode: "F",
seatNumber: "001A",
checkInSequenceNumber: "0025",
Expand Down
4 changes: 2 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ export const dateToDayOfYear = (date: Date, addYearPrefix = false) => {
if (addYearPrefix) {
yearPrefix = date.getUTCFullYear().toString().slice(-1);
}
return `${yearPrefix}${dayOfYear.toString()}`;
return `${yearPrefix}${dayOfYear.toString().padStart(3, "0")}`;
};

export const dayOfYearToDate = (
dayOfYear: string,
hasYearPrefix: boolean,
referenceYear?: number
referenceYear?: number,
) => {
const currentYear = referenceYear ?? new Date(Date.now()).getUTCFullYear();
let year = currentYear.toString();
Expand Down

0 comments on commit 6e06ff4

Please sign in to comment.