Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix flight date estimation #669

Merged
merged 1 commit into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading