1
0
mirror of https://github.com/moshix/mvs.git synced 2026-03-03 01:48:12 +00:00

updated SABRE for VM REXX compatibility

This commit is contained in:
moshix
2025-06-26 09:48:59 +02:00
committed by GitHub
parent a8667ef93f
commit e0a32eadbb

View File

@@ -1,19 +1,18 @@
/* SABRE CRS DEMO IN REXX FOR CMS BY ERNIETECH - ENHANCED VERSION */
/* EXPANDED WITH DYNAMIC DATA AND MORE SABRE COMMANDS
- JUNE2025 MOSHIX - AUSTRIA
- V0.2 with new commands and more realistic seat maps
*/
/* SABRE CRS DEMO IN BREXX FOR VM/370 CMS BY ERNIETECH - ENHANCED VERSION */
/* EXPANDED WITH DYNAMIC DATA AND MORE SABRE COMMANDS */
/* - JUNE2025 MOSHIX - AUSTRIA */
/* Clear screen in a cross-platform way */
address command
'clear'
if rc \= 0 then 'cls'
address
/* z/VM compatible screen initialization */
do i = 1 to 5
say ''
end
say center('-------------- SABRE Computer Reservation System (CRS)-----------',78)
title = '---------- SABRE Computer Reservation System (CRS) --------'
spaces = (78 - length(title)) % 2
say copies(' ', spaces)||title
/* Display date and WAFL:CONE */
today = date('S') /* YYYYMMDD */
today = date('S') /* YYYYMMDD */
ddmmyyyy = substr(today,7,2)'.'substr(today,5,2)'.'substr(today,1,4)
say ddmmyyyy "WAFL:CONE"
@@ -125,16 +124,16 @@ eqDesc.B757 = 'Boeing 757-200'
eqDesc.MD981 = 'MD-8-81'
/* Seat map configurations */
/* Format: ROWS|LAYOUT|EXIT ROWS|FIRST CLASS ROWS|WHEELCHAIR ROWS|BASSINET ROWS|BLOCKED SEATS */
seatConfig.A320 = '27|ABC DEF|11 12|1-4|1 27|12|14B 14E' /* 3-3 config, 158 seats */
seatConfig.B738 = '28|ABC DEF|14 15|1-4|1 28|15|16B 16E' /* 3-3 config, 162 seats */
seatConfig.B789 = '42|ABC DEF GHJ|24 25|1-5|1 42|25|26E 26F' /* 3-3-3 config, 290 seats */
seatConfig.A350 = '44|ABC DEF GHJ|24 25|1-5|1 44|25|26E 26F' /* 3-3-3 config, 308 seats */
seatConfig.B77W = '51|ABC DEFG HJK|24 25|1-4|1 51|25|26E 26F' /* 3-4-3 config, 357 seats */
seatConfig.B747 = '58|ABC DEFG HJK|24 25|1-4|1 58|25|26E 26F' /* 3-4-3 config, 412 seats */
seatConfig.B767 = '34|ABC DEF GH|20 21|1-3|1 34|21|22D 22E' /* 2-3-2 config, 203 seats */
seatConfig.B757 = '25|ABC DEF|14 15|1-3|1 25|15|16B 16E' /* 3-3 config, 152 seats */
seatConfig.MD981 = '23|ABC DE|10 11|1-2|1 23|11|12B 12D' /* 2-3 config, 109 seats */
/* Format: ROWS|LAYOUT|EXIT ROWS|FIRST CLASS ROWS|WHEELCHAIR|BASSINET|BLOCK */
seatConfig.A320 = '27|ABC DEF|11 12|1-4|1 27|12|14B 14E'
seatConfig.B738 = '28|ABC DEF|14 15|1-4|1 28|15|16B 16E'
seatConfig.B789 = '42|ABC DEF GHJ|24 25|1-5|1 42|25|26E 26F'
seatConfig.A350 = '44|ABC DEF GHJ|24 25|1-5|1 44|25|26E 26F'
seatConfig.B77W = '51|ABC DEFG HJK|24 25|1-4|1 51|25|26E 26F'
seatConfig.B747 = '58|ABC DEFG HJK|24 25|1-4|1 58|25|26E 26F'
seatConfig.B767 = '34|ABC DEF GH|20 21|1-3|1 34|21|22D 22E'
seatConfig.B757 = '25|ABC DEF|14 15|1-3|1 25|15|16B 16E'
seatConfig.MD981 = '23|ABC DE|10 11|1-2|1 23|11|12B 12D'
/* Seat map legend */
seatLegend.A = 'Available'
@@ -219,7 +218,7 @@ flightMaxSeats. = 0
/* --- Main Loop --- */
say
say "* SABRE DEMO: Type HELP for instructions"
say "* SABRE CRS: Type HELP for instructions"
say
/* Initialize flight seat tracking */
@@ -236,16 +235,16 @@ do forever
/* HELP & SIGN-OUT */
if cmd = 'HELP' then do
say "QUERY FORMAT: 18OCT JFK ZRH (optional: 9A)"
say "BOOK <n> Book flight Index number <n> (e.g. BOOK 1 or BOOK 3)"
say "CANCEL <PNR> Cancel booking (e.g. CANCEL 001 or CANCEL PNR001)"
say "PNR <loc> Display booking details (e.g. PNR 001 or PNR PNR001)"
say "W/EQ*<code> Filter flights by equipment code (e.g. A320 or B738)"
say "FF<pnr> Display FF info for PNR (e.g. FF001 or FFPNR001)"
say "BOOK <n> Book flight Index number <n> (e.g. BOOK 1/3)"
say "CANCEL <PNR> Cancel booking (e.g. CANCEL 001 or PNR001)"
say "PNR <loc> Display booking details (e.g. PNR 001)"
say "W/EQ*<code> Filter flights by equipment (e.g. A320/B738)"
say "FF<pnr> Display FF info for PNR (e.g. FF001)"
say "FF<pnr>/<num> Add FF number to PNR (e.g. FF001/AA123456)"
say "FF<pnr>/* Delete FF number from PNR"
say "Q/C Display queue counts"
say "Q/P/<n>/<pnr> Place PNR in queue n"
say "WP/NCB <n> Price and book lowest available fare for segment n"
say "WP/NCB <n> Price/book lowest fare for segment n"
say "WP/NI Display alternate fare options"
say "N/ADD-<n> Add passenger name (N/ADD-1 DOE/JOHN ADT)"
say "N/CHG-<n> Change passenger name (N/CHG-1 DOE/JANE)"
@@ -321,7 +320,8 @@ do forever
do j = 1 to PNRdata.0
parse var PNRdata.j pnrEntry pname oldSeat flightNum
if pnrEntry = currentPNR then do
parse var matchList.flightNum airline flight depc depd dept arrt arrc avst eqmt
parse var matchList.flightNum airline flight depc depd,
dept arrt arrc avst eqmt
flightKey = airline||flight||depc||arrc||depd||dept
found = 1
leave
@@ -334,7 +334,8 @@ do forever
end
/* Get seat configuration */
parse var seatConfig.eqmt rows '|' layout '|' exitRows '|' firstRows '|' wheelRows '|' bassRows '|' blockSeats
parse var seatConfig.eqmt rows '|' layout '|' exitRows '|',
firstRows '|' wheelRows '|' bassRows '|' blockSeats
/* Validate seat exists in configuration */
if seatRow < 1 | seatRow > (rows + 0) then do
@@ -426,7 +427,8 @@ do forever
do j = 1 to PNRdata.0
parse var PNRdata.j pnrEntry pname seat flightNum
if pnrEntry = currentPNR then do
parse var matchList.flightNum airline flight depc depd dept arrt arrc avst eqmt
parse var matchList.flightNum airline flight depc,
depd dept arrt arrc avst eqmt
flightKey = airline||flight||depc||arrc||depd||dept
found = 1
leave
@@ -444,7 +446,8 @@ do forever
end
/* Get seat configuration */
parse var seatConfig.eqmt rows '|' layout '|' exitRows '|' firstRows '|' wheelRows '|' bassRows '|' blockSeats
parse var seatConfig.eqmt rows '|' layout '|' exitRows '|',
firstRows '|' wheelRows '|' bassRows '|' blockSeats
if rows = '' then do
say '*** Invalid equipment type:' eqmt
say
@@ -575,7 +578,8 @@ do forever
parse var PNRdata.j pnrEntry pname seat flightRec
if pnrEntry = pnr then do
currentPNR = pnr /* Set as current PNR */
say 'PNR '||pnrEntry||' => '||pname||' SEAT '||seat||' '||flightRec
say 'PNR '||pnrEntry||' => '||pname||' SEAT '||seat
say ' '||flightRec
/* Display passenger type if exists */
if paxType.j \= '' then
say ' Type: '||paxTypes.paxType.j
@@ -598,7 +602,8 @@ do forever
iterate
end
parse var matchList.num airline flight depc depd dept arrt arrc avst eqmt
parse var matchList.num airline flight depc depd,
dept arrt arrc avst eqmt
flightKey = airline||flight||depc||arrc||depd||dept
/* Get current seat count */
@@ -621,11 +626,13 @@ do forever
pnr = 'PNR'||substr('000'||pnrnum,length('000'||pnrnum)-2,3)
/* prompt for passenger name */
say "* Enter passenger name as <first initial><last name> (no spaces):"
say "* Enter passenger name as <first initial><last name>"
say "* (no spaces):"
pull pname
/* Get seat configuration */
parse var seatConfig.eqmt rows '|' layout '|' exitRows '|' firstRows '|' wheelRows '|' bassRows '|' blockSeats
parse var seatConfig.eqmt rows '|' layout '|' exitRows '|',
firstRows '|' wheelRows '|' bassRows '|' blockSeats
/* Find next available seat */
seatFound = 0
@@ -780,7 +787,9 @@ do forever
say 'Searching for lowest available fare...'
do i = 1 to words(fareTypes)
fare = word(fareTypes, i)
say right(fare,1) 'class ('||fareTypes.fare||'): $'||format(genRandomNum(100,1000),3)||'.00'
price = format(genRandomNum(100,1000),3)
say right(fare,1) 'class ('||fareTypes.fare||'):',
'$'||price||'.00'
end
end
when pcmd = 'NI' then do
@@ -788,11 +797,14 @@ do forever
say 'Searching for alternative fares...'
do i = 1 to words(fareTypes)
fare = word(fareTypes, i)
say right(fare,1) 'class ('||fareTypes.fare||'): $'||format(genRandomNum(100,1000),3)||'.00'
price = format(genRandomNum(100,1000),3)
say right(fare,1) 'class ('||fareTypes.fare||'):',
'$'||price||'.00'
end
end
otherwise
say '*** Invalid pricing command. Use WP/NCB <segment> or WP/NI'
say '*** Invalid pricing command.'
say '*** Use WP/NCB <segment> or WP/NI'
end
iterate
end
@@ -829,7 +841,8 @@ do forever
PNRdata.paxnum = pnrEntry newname seat flightRec
paxName.paxnum = newname
paxType.paxnum = type
say 'Added passenger:' newname 'Type:' paxTypes.type 'to' pnrEntry
say 'Added passenger:' newname 'Type:' paxTypes.type
say ' to' pnrEntry
end
when cmd_type = 'CHG' then do
/* Change passenger name */
@@ -874,7 +887,8 @@ do forever
parse var PNRdata.j pnrEntry restInfo
if pnrEntry = pnr then do
parse var PNRdata.j pnrEntry pname seat flightNum
parse var matchList.flightNum airline flight depc depd dept arrt arrc avst eqmt
parse var matchList.flightNum airline flight depc,
depd dept arrt arrc avst eqmt
flightKey = airline||flight||depc||arrc||depd||dept
/* Handle seat inventory safely */
@@ -882,7 +896,8 @@ do forever
flightSeats.flightKey = 0
currSeats = flightSeats.flightKey + 0 /* Force numeric */
if \datatype(currSeats, 'W') then currSeats = 0
flightSeats.flightKey = currSeats + 1 /* Return seat to inventory */
/* Return seat to inventory */
flightSeats.flightKey = currSeats + 1
/* Mark PNR as cancelled */
PNRdata.j = pnrEntry||' '||restInfo||' CANCELLED'
@@ -905,7 +920,8 @@ do forever
say '------------------------'
do i = 1 to words(eqDesc)
eq = word(eqDesc, i)
say left(eq,5) '-' left(eqDesc.eq,20) right(eqSeats.eq,4) 'seats'
say left(eq,5) '-' left(eqDesc.eq,20),
right(eqSeats.eq,4) 'seats'
end
iterate
end
@@ -915,11 +931,12 @@ do forever
eqName = eqDesc.eqQuery
if eqName = '' then eqName = 'Unknown'
say 'Flights with equipment '||eqQuery||' - '||eqName
say ' # ARLN FLTN DEPC/ARVC DEPT ARRT AVST EQTYP'
say '-----------------------------------------------------------------------'
say ' # ARLN FLTN DEPC/ARVC DEPT ARRT AVST EQTYP'
say '--------------------------------------------------------------'
idx = 0
do i = 1 to matchList.0
parse var matchList.i airline flight depc depd dept arrt arrc avst eqmt
parse var matchList.i airline flight depc depd,
dept arrt arrc avst eqmt
if eqmt \= eqQuery then iterate
idx = idx + 1
out = right(idx,2)
@@ -949,13 +966,15 @@ do forever
/* Validate airport codes */
if \isValidAirport(from) then do
say '*** Invalid departure airport code: '||from
say '*** Please use a valid 3-letter airport code (e.g. JFK, LHR, SIN)'
say '*** Please use a valid 3-letter airport code'
say '*** (e.g. JFK, LHR, SIN)'
iterate
end
if \isValidAirport(to) then do
say '*** Invalid arrival airport code: '||to
say '*** Please use a valid 3-letter airport code (e.g. JFK, LHR, SIN)'
say '*** Please use a valid 3-letter airport code'
say '*** (e.g. JFK, LHR, SIN)'
iterate
end
@@ -965,7 +984,9 @@ do forever
end
/* Show route information */
say 'Route: '||from||' ('||getAirportName(from)||') to '||to||' ('||getAirportName(to)||')'
fromName = getAirportName(from)
toName = getAirportName(to)
say 'Route: '||from||' ('||fromName||') to '||to||' ('||toName||')'
/* Generate flights for this query */
call generateFlights date, from, to, time
@@ -1029,18 +1050,21 @@ getRouteEquipment:
if depRegion = arrRegion then do
/* Short-haul domestic/regional */
if depRegion = 'NA' then
return 'A320 A320 B738 B738 B738' /* Favor narrowbodies for domestic */
/* Favor narrowbodies for domestic */
return 'A320 A320 B738 B738 B738'
else
return 'A320 B738 A320 B738 A320' /* Regional mix */
end
/* Check if transatlantic */
if (depRegion = 'NA' & arrRegion = 'EU') | (depRegion = 'EU' & arrRegion = 'NA') then
return 'B789 A350 B77W B789 A350' /* Widebodies for transatlantic */
if (depRegion = 'NA' & arrRegion = 'EU') |,
(depRegion = 'EU' & arrRegion = 'NA') then
return 'B789 A350 B77W B789 A350'
/* Check if transpacific */
if (depRegion = 'NA' & arrRegion = 'AP') | (depRegion = 'AP' & arrRegion = 'NA') then
return 'B789 B77W B77W B789 B77W' /* Favor larger widebodies */
if (depRegion = 'NA' & arrRegion = 'AP') |,
(depRegion = 'AP' & arrRegion = 'NA') then
return 'B789 B77W B77W B789 B77W'
/* Default long-haul mix */
return 'B789 A350 B77W A350 B789'
@@ -1049,11 +1073,19 @@ getRouteEquipment:
getAirportRegion:
parse arg code
select
when wordpos(code, 'JFK LAX ORD DFW DEN SFO LAS SEA MCO EWR MIA PHX IAH BOS MSP DTW FLL CLT LGA BWI SLC YYZ YVR YUL') > 0 then return 'NA'
when wordpos(code, 'LHR CDG AMS FRA IST MAD BCN LGW MUC FCO SVO DME DUB ZRH CPH OSL ARN VIE BRU MXP') > 0 then return 'EU'
when wordpos(code, 'PEK HND HKG ICN BKK SIN CGK KUL DEL BOM SYD MEL AKL KIX TPE MNL CAN PVG NRT') > 0 then return 'AP'
when wordpos(code, 'DXB DOH AUH CAI JNB CPT TLV BAH RUH JED MCT') > 0 then return 'ME'
when wordpos(code, 'GRU MEX BOG LIM SCL GIG EZE PTY CUN UIO') > 0 then return 'LA'
when wordpos(code, 'JFK LAX ORD DFW DEN SFO LAS SEA MCO' ||,
' EWR MIA PHX IAH BOS MSP DTW FLL CLT' ||,
' LGA BWI SLC YYZ YVR YUL') > 0 then return 'NA'
when wordpos(code, 'LHR CDG AMS FRA IST MAD BCN LGW MUC' ||,
' FCO SVO DME DUB ZRH CPH OSL ARN VIE BRU MXP') > 0,
then return 'EU'
when wordpos(code, 'PEK HND HKG ICN BKK SIN CGK KUL DEL' ||,
' BOM SYD MEL AKL KIX TPE MNL CAN PVG NRT') > 0,
then return 'AP'
when wordpos(code, 'DXB DOH AUH CAI JNB CPT TLV BAH' ||,
' RUH JED MCT') > 0 then return 'ME'
when wordpos(code, 'GRU MEX BOG LIM SCL GIG EZE' ||,
' PTY CUN UIO') > 0 then return 'LA'
otherwise return 'OT'
end
@@ -1100,7 +1132,8 @@ generateFlights:
do f = 1 to numFlights
/* Get unique flight number */
flightNumStr = getUniqueFlightNum(airline, minFlt, maxFlt, usedNums)
flightNumStr = getUniqueFlightNum(airline, minFlt,,
maxFlt, usedNums)
usedNums = usedNums airline||flightNumStr
/* Generate departure time - spread throughout the day */
@@ -1123,18 +1156,21 @@ generateFlights:
/* Get seats for this equipment type */
maxSeats = eqSeats.eqType
if \datatype(maxSeats,'W') then maxSeats = 150 /* Default if not found */
/* Default if not found */
if \datatype(maxSeats,'W') then maxSeats = 150
/* Generate random available seats */
do i = 1 to 100; nop; end /* Force time change */
minSeats = trunc(maxSeats * 0.2) /* At least 20% seats available */
/* At least 20% seats available */
minSeats = trunc(maxSeats * 0.2)
maxAvail = trunc(maxSeats * 0.95) /* Up to 95% seats available */
availSeats = getRandomNum(minSeats, maxAvail)
/* Add to flights stem */
idx = flights.0 + 1
flights.0 = idx
flights.idx = airline flightNumStr depApt date depTimeStr arrTimeStr arrApt availSeats eqType
flights.idx = airline flightNumStr depApt date,
depTimeStr arrTimeStr arrApt availSeats eqType
end
end
@@ -1181,8 +1217,8 @@ displayFlights:
parse arg date, from, to
say
say date||' '||from||'/'||to||' ----------------------'
say ' # ARLN FLTN DEPC/ARVC DEPT ARRT AVST EQTYP'
say '-----------------------------------------------------------------------'
say ' # ARLN FLTN DEPC/ARVC DEPT ARRT AVST EQTYP'
say '--------------------------------------------------------------'
/* Initialize matchList stem */
drop matchList.
@@ -1209,7 +1245,8 @@ displayFlights:
timeAP = right(time,1)
if \datatype(timeHr,'W') then iterate
targetMins = (timeHr * 60)
if timeAP = 'P' & timeHr \= 12 then targetMins = targetMins + (12 * 60)
if timeAP = 'P' & timeHr \= 12 then,
targetMins = targetMins + (12 * 60)
if timeAP = 'A' & timeHr = 12 then targetMins = 0
/* Allow 2 hour window around requested time */