mirror of
https://github.com/mblanke/Gov_Travel_App.git
synced 2026-03-01 14:10:22 -05:00
Add Python web scraper for NJC travel rates with currency extraction
- Implemented Python scraper using BeautifulSoup and pandas to automatically collect travel rates from official NJC website - Added currency extraction from table titles (supports EUR, USD, AUD, CAD, ARS, etc.) - Added country extraction from table titles for international rates - Flatten pandas MultiIndex columns for cleaner data structure - Default to CAD for domestic Canadian sources (accommodations and domestic tables) - Created SQLite database schema (raw_tables, rate_entries, exchange_rates, accommodations) - Successfully scraped 92 tables with 17,205 rate entries covering 25 international cities - Added migration script to convert scraped data to Node.js database format - Updated .gitignore for Python files (.venv/, __pycache__, *.pyc, *.sqlite3) - Fixed city validation and currency conversion in main app - Added comprehensive debug and verification scripts This replaces manual JSON maintenance with automated data collection from official government source.
This commit is contained in:
3704
data/accommodationRates.json
Normal file
3704
data/accommodationRates.json
Normal file
File diff suppressed because it is too large
Load Diff
363
data/accommodationRates.json.backup
Normal file
363
data/accommodationRates.json.backup
Normal file
@@ -0,0 +1,363 @@
|
||||
{
|
||||
"metadata": {
|
||||
"effectiveDate": "2025-10-30",
|
||||
"version": "1.0",
|
||||
"source": "Government Accommodation Directory (PWGSC)",
|
||||
"lastUpdated": "2025-10-30",
|
||||
"notes": "Sample rates for common Canadian cities. Actual rates should be verified at https://rehelv-acrd.tpsgc-pwgsc.gc.ca/lth-crl-eng.aspx"
|
||||
},
|
||||
"cities": {
|
||||
"ottawa": {
|
||||
"name": "Ottawa, ON",
|
||||
"province": "Ontario",
|
||||
"region": "canada",
|
||||
"standardRate": 165.00,
|
||||
"maxRate": 200.00,
|
||||
"currency": "CAD",
|
||||
"notes": "National Capital Region"
|
||||
},
|
||||
"toronto": {
|
||||
"name": "Toronto, ON",
|
||||
"province": "Ontario",
|
||||
"region": "canada",
|
||||
"standardRate": 180.00,
|
||||
"maxRate": 220.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Major urban center"
|
||||
},
|
||||
"montreal": {
|
||||
"name": "Montreal, QC",
|
||||
"province": "Quebec",
|
||||
"region": "canada",
|
||||
"standardRate": 170.00,
|
||||
"maxRate": 210.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Major urban center"
|
||||
},
|
||||
"vancouver": {
|
||||
"name": "Vancouver, BC",
|
||||
"province": "British Columbia",
|
||||
"region": "canada",
|
||||
"standardRate": 190.00,
|
||||
"maxRate": 240.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Major urban center, high cost area"
|
||||
},
|
||||
"calgary": {
|
||||
"name": "Calgary, AB",
|
||||
"province": "Alberta",
|
||||
"region": "canada",
|
||||
"standardRate": 160.00,
|
||||
"maxRate": 195.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Major urban center"
|
||||
},
|
||||
"edmonton": {
|
||||
"name": "Edmonton, AB",
|
||||
"province": "Alberta",
|
||||
"region": "canada",
|
||||
"standardRate": 155.00,
|
||||
"maxRate": 190.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Major urban center"
|
||||
},
|
||||
"winnipeg": {
|
||||
"name": "Winnipeg, MB",
|
||||
"province": "Manitoba",
|
||||
"region": "canada",
|
||||
"standardRate": 140.00,
|
||||
"maxRate": 175.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Urban center"
|
||||
},
|
||||
"halifax": {
|
||||
"name": "Halifax, NS",
|
||||
"province": "Nova Scotia",
|
||||
"region": "canada",
|
||||
"standardRate": 150.00,
|
||||
"maxRate": 185.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Regional center"
|
||||
},
|
||||
"quebec": {
|
||||
"name": "Quebec City, QC",
|
||||
"province": "Quebec",
|
||||
"region": "canada",
|
||||
"standardRate": 155.00,
|
||||
"maxRate": 190.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Provincial capital"
|
||||
},
|
||||
"victoria": {
|
||||
"name": "Victoria, BC",
|
||||
"province": "British Columbia",
|
||||
"region": "canada",
|
||||
"standardRate": 175.00,
|
||||
"maxRate": 215.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Provincial capital"
|
||||
},
|
||||
"whitehorse": {
|
||||
"name": "Whitehorse, YT",
|
||||
"province": "Yukon",
|
||||
"region": "yukon",
|
||||
"standardRate": 185.00,
|
||||
"maxRate": 230.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Territorial capital, limited availability"
|
||||
},
|
||||
"yellowknife": {
|
||||
"name": "Yellowknife, NT",
|
||||
"province": "Northwest Territories",
|
||||
"region": "nwt",
|
||||
"standardRate": 210.00,
|
||||
"maxRate": 270.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Territorial capital, high cost area, limited availability"
|
||||
},
|
||||
"iqaluit": {
|
||||
"name": "Iqaluit, NU",
|
||||
"province": "Nunavut",
|
||||
"region": "nunavut",
|
||||
"standardRate": 280.00,
|
||||
"maxRate": 350.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Territorial capital, very high cost area, very limited availability"
|
||||
},
|
||||
"newyork": {
|
||||
"name": "New York, NY",
|
||||
"state": "New York",
|
||||
"region": "usa",
|
||||
"standardRate": 250.00,
|
||||
"maxRate": 350.00,
|
||||
"currency": "USD",
|
||||
"notes": "Major metropolitan area, very high cost"
|
||||
},
|
||||
"washington": {
|
||||
"name": "Washington, DC",
|
||||
"state": "District of Columbia",
|
||||
"region": "usa",
|
||||
"standardRate": 220.00,
|
||||
"maxRate": 300.00,
|
||||
"currency": "USD",
|
||||
"notes": "Capital city, high cost area"
|
||||
},
|
||||
"chicago": {
|
||||
"name": "Chicago, IL",
|
||||
"state": "Illinois",
|
||||
"region": "usa",
|
||||
"standardRate": 180.00,
|
||||
"maxRate": 240.00,
|
||||
"currency": "USD",
|
||||
"notes": "Major metropolitan area"
|
||||
},
|
||||
"losangeles": {
|
||||
"name": "Los Angeles, CA",
|
||||
"state": "California",
|
||||
"region": "usa",
|
||||
"standardRate": 200.00,
|
||||
"maxRate": 280.00,
|
||||
"currency": "USD",
|
||||
"notes": "Major metropolitan area, high cost"
|
||||
},
|
||||
"sanfrancisco": {
|
||||
"name": "San Francisco, CA",
|
||||
"state": "California",
|
||||
"region": "usa",
|
||||
"standardRate": 240.00,
|
||||
"maxRate": 340.00,
|
||||
"currency": "USD",
|
||||
"notes": "Major metropolitan area, very high cost"
|
||||
},
|
||||
"seattle": {
|
||||
"name": "Seattle, WA",
|
||||
"state": "Washington",
|
||||
"region": "usa",
|
||||
"standardRate": 195.00,
|
||||
"maxRate": 260.00,
|
||||
"currency": "USD",
|
||||
"notes": "Major metropolitan area"
|
||||
},
|
||||
"boston": {
|
||||
"name": "Boston, MA",
|
||||
"state": "Massachusetts",
|
||||
"region": "usa",
|
||||
"standardRate": 210.00,
|
||||
"maxRate": 280.00,
|
||||
"currency": "USD",
|
||||
"notes": "Major metropolitan area, high cost"
|
||||
},
|
||||
"anchorage": {
|
||||
"name": "Anchorage, AK",
|
||||
"state": "Alaska",
|
||||
"region": "alaska",
|
||||
"standardRate": 180.00,
|
||||
"maxRate": 240.00,
|
||||
"currency": "USD",
|
||||
"notes": "Limited availability, seasonal variations"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"canada": {
|
||||
"standardRate": 150.00,
|
||||
"maxRate": 185.00,
|
||||
"currency": "CAD"
|
||||
},
|
||||
"yukon": {
|
||||
"standardRate": 185.00,
|
||||
"maxRate": 230.00,
|
||||
"currency": "CAD"
|
||||
},
|
||||
"nwt": {
|
||||
"standardRate": 210.00,
|
||||
"maxRate": 270.00,
|
||||
"currency": "CAD"
|
||||
},
|
||||
"nunavut": {
|
||||
"standardRate": 280.00,
|
||||
"maxRate": 350.00,
|
||||
"currency": "CAD"
|
||||
},
|
||||
"usa": {
|
||||
"standardRate": 150.00,
|
||||
"maxRate": 200.00,
|
||||
"currency": "USD"
|
||||
},
|
||||
"alaska": {
|
||||
"standardRate": 180.00,
|
||||
"maxRate": 240.00,
|
||||
"currency": "USD"
|
||||
},
|
||||
"international": {
|
||||
"standardRate": 200.00,
|
||||
"maxRate": 300.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Varies significantly by country and city"
|
||||
}
|
||||
},
|
||||
"internationalCities": {
|
||||
"london": {
|
||||
"name": "London, UK",
|
||||
"country": "United Kingdom",
|
||||
"region": "international",
|
||||
"standardRate": 280.00,
|
||||
"maxRate": 380.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost city, convert from GBP"
|
||||
},
|
||||
"paris": {
|
||||
"name": "Paris, France",
|
||||
"country": "France",
|
||||
"region": "international",
|
||||
"standardRate": 260.00,
|
||||
"maxRate": 350.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost city, convert from EUR"
|
||||
},
|
||||
"tokyo": {
|
||||
"name": "Tokyo, Japan",
|
||||
"country": "Japan",
|
||||
"region": "international",
|
||||
"standardRate": 240.00,
|
||||
"maxRate": 340.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost city, convert from JPY"
|
||||
},
|
||||
"beijing": {
|
||||
"name": "Beijing, China",
|
||||
"country": "China",
|
||||
"region": "international",
|
||||
"standardRate": 180.00,
|
||||
"maxRate": 250.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Convert from CNY"
|
||||
},
|
||||
"sydney": {
|
||||
"name": "Sydney, Australia",
|
||||
"country": "Australia",
|
||||
"region": "international",
|
||||
"standardRate": 220.00,
|
||||
"maxRate": 300.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost city, convert from AUD"
|
||||
},
|
||||
"dubai": {
|
||||
"name": "Dubai, UAE",
|
||||
"country": "United Arab Emirates",
|
||||
"region": "international",
|
||||
"standardRate": 200.00,
|
||||
"maxRate": 280.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Convert from AED"
|
||||
},
|
||||
"brussels": {
|
||||
"name": "Brussels, Belgium",
|
||||
"country": "Belgium",
|
||||
"region": "international",
|
||||
"standardRate": 210.00,
|
||||
"maxRate": 280.00,
|
||||
"currency": "CAD",
|
||||
"notes": "EU headquarters, convert from EUR"
|
||||
},
|
||||
"geneva": {
|
||||
"name": "Geneva, Switzerland",
|
||||
"country": "Switzerland",
|
||||
"region": "international",
|
||||
"standardRate": 320.00,
|
||||
"maxRate": 450.00,
|
||||
"currency": "CAD",
|
||||
"notes": "Very high cost city, convert from CHF"
|
||||
},
|
||||
"reykjavik": {
|
||||
"name": "Reykjavik, Iceland",
|
||||
"country": "Iceland",
|
||||
"region": "international",
|
||||
"standardRate": 240.00,
|
||||
"maxRate": 320.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost Nordic city, convert from ISK"
|
||||
},
|
||||
"oslo": {
|
||||
"name": "Oslo, Norway",
|
||||
"country": "Norway",
|
||||
"region": "international",
|
||||
"standardRate": 260.00,
|
||||
"maxRate": 350.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost Nordic city, convert from NOK"
|
||||
},
|
||||
"stockholm": {
|
||||
"name": "Stockholm, Sweden",
|
||||
"country": "Sweden",
|
||||
"region": "international",
|
||||
"standardRate": 230.00,
|
||||
"maxRate": 310.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost Nordic city, convert from SEK"
|
||||
},
|
||||
"copenhagen": {
|
||||
"name": "Copenhagen, Denmark",
|
||||
"country": "Denmark",
|
||||
"region": "international",
|
||||
"standardRate": 250.00,
|
||||
"maxRate": 330.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost Nordic city, convert from DKK"
|
||||
},
|
||||
"helsinki": {
|
||||
"name": "Helsinki, Finland",
|
||||
"country": "Finland",
|
||||
"region": "international",
|
||||
"standardRate": 220.00,
|
||||
"maxRate": 290.00,
|
||||
"currency": "CAD",
|
||||
"notes": "High cost Nordic city, convert from EUR"
|
||||
}
|
||||
},
|
||||
"rateNotes": {
|
||||
"standardRate": "Typical government-approved hotel rate",
|
||||
"maxRate": "Maximum allowable without additional authorization",
|
||||
"exceedingMax": "Rates exceeding max require justification and approval",
|
||||
"verification": "Always verify current rates at government accommodation directory before booking"
|
||||
}
|
||||
}
|
||||
924
data/internationalRates.json
Normal file
924
data/internationalRates.json
Normal file
@@ -0,0 +1,924 @@
|
||||
{
|
||||
"metadata": {
|
||||
"effectiveDate": "2026-01-01",
|
||||
"version": "2.0",
|
||||
"source": "NJC Travel Directive Appendix D - Module 4",
|
||||
"url": "https://www.njc-cnm.gc.ca/directive/app_d/en",
|
||||
"lastUpdated": "2026-01-12",
|
||||
"notes": "International travel allowances. C-Day = Commercial Accommodation, P-Day = Private/Non-commercial. Duration: 1-30, 31-120, 121+ days. All rates in original currencies as per NJC."
|
||||
},
|
||||
"countries": {
|
||||
"latvia": {
|
||||
"name": "Latvia",
|
||||
"currency": "EUR",
|
||||
"cities": {
|
||||
"riga": {
|
||||
"name": "Riga",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 23.85,
|
||||
"lunch": 41.60,
|
||||
"dinner": 55.15,
|
||||
"total": 120.60
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 17.89,
|
||||
"lunch": 31.20,
|
||||
"dinner": 41.36,
|
||||
"total": 90.45
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 11.93,
|
||||
"lunch": 20.80,
|
||||
"dinner": 27.58,
|
||||
"total": 60.30
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 23.85,
|
||||
"lunch": 41.60,
|
||||
"dinner": 55.15,
|
||||
"total": 120.60
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 17.89,
|
||||
"lunch": 31.20,
|
||||
"dinner": 41.36,
|
||||
"total": 90.45
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 11.93,
|
||||
"lunch": 20.80,
|
||||
"dinner": 27.58,
|
||||
"total": 60.30
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 38.59,
|
||||
"cDay_31_120": 28.94,
|
||||
"cDay_121_plus": 28.94,
|
||||
"pDay_1_30": 24.12,
|
||||
"pDay_31_120": 18.09,
|
||||
"pDay_121_plus": 18.09
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 159.19,
|
||||
"cDay_31_120": 119.39,
|
||||
"cDay_121_plus": 89.24,
|
||||
"pDay_1_30": 144.72,
|
||||
"pDay_31_120": 108.54,
|
||||
"pDay_121_plus": 78.39
|
||||
}
|
||||
},
|
||||
"other": {
|
||||
"name": "Other cities in Latvia",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 19.08,
|
||||
"lunch": 33.28,
|
||||
"dinner": 44.12,
|
||||
"total": 96.48
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 14.31,
|
||||
"lunch": 24.96,
|
||||
"dinner": 33.09,
|
||||
"total": 72.36
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 9.54,
|
||||
"lunch": 16.64,
|
||||
"dinner": 22.06,
|
||||
"total": 48.24
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 19.08,
|
||||
"lunch": 33.28,
|
||||
"dinner": 44.12,
|
||||
"total": 96.48
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 14.31,
|
||||
"lunch": 24.96,
|
||||
"dinner": 33.09,
|
||||
"total": 72.36
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 9.54,
|
||||
"lunch": 16.64,
|
||||
"dinner": 22.06,
|
||||
"total": 48.24
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 30.87,
|
||||
"cDay_31_120": 23.16,
|
||||
"cDay_121_plus": 23.16,
|
||||
"pDay_1_30": 19.30,
|
||||
"pDay_31_120": 14.47,
|
||||
"pDay_121_plus": 14.47
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 127.35,
|
||||
"cDay_31_120": 95.52,
|
||||
"cDay_121_plus": 71.40,
|
||||
"pDay_1_30": 115.78,
|
||||
"pDay_31_120": 86.83,
|
||||
"pDay_121_plus": 62.71
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"laos": {
|
||||
"name": "Laos",
|
||||
"currency": "USD",
|
||||
"cities": {
|
||||
"vientiane": {
|
||||
"name": "Vientiane",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 13.85,
|
||||
"lunch": 16.30,
|
||||
"dinner": 22.00,
|
||||
"total": 52.15
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 10.39,
|
||||
"lunch": 12.23,
|
||||
"dinner": 16.50,
|
||||
"total": 39.11
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 6.93,
|
||||
"lunch": 8.15,
|
||||
"dinner": 11.00,
|
||||
"total": 26.08
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 13.85,
|
||||
"lunch": 16.30,
|
||||
"dinner": 22.00,
|
||||
"total": 52.15
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 10.39,
|
||||
"lunch": 12.23,
|
||||
"dinner": 16.50,
|
||||
"total": 39.11
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 6.93,
|
||||
"lunch": 8.15,
|
||||
"dinner": 11.00,
|
||||
"total": 26.08
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 16.69,
|
||||
"cDay_31_120": 12.52,
|
||||
"cDay_121_plus": 12.52,
|
||||
"pDay_1_30": 10.43,
|
||||
"pDay_31_120": 7.82,
|
||||
"pDay_121_plus": 7.82
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 68.84,
|
||||
"cDay_31_120": 51.63,
|
||||
"cDay_121_plus": 38.59,
|
||||
"pDay_1_30": 62.58,
|
||||
"pDay_31_120": 46.94,
|
||||
"pDay_121_plus": 33.90
|
||||
}
|
||||
},
|
||||
"other": {
|
||||
"name": "Other cities in Laos",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 11.08,
|
||||
"lunch": 13.04,
|
||||
"dinner": 17.60,
|
||||
"total": 41.72
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 8.31,
|
||||
"lunch": 9.78,
|
||||
"dinner": 13.20,
|
||||
"total": 31.29
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 5.54,
|
||||
"lunch": 6.52,
|
||||
"dinner": 8.80,
|
||||
"total": 20.86
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 11.08,
|
||||
"lunch": 13.04,
|
||||
"dinner": 17.60,
|
||||
"total": 41.72
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 8.31,
|
||||
"lunch": 9.78,
|
||||
"dinner": 13.20,
|
||||
"total": 31.29
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 5.54,
|
||||
"lunch": 6.52,
|
||||
"dinner": 8.80,
|
||||
"total": 20.86
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 13.35,
|
||||
"cDay_31_120": 10.01,
|
||||
"cDay_121_plus": 10.01,
|
||||
"pDay_1_30": 8.34,
|
||||
"pDay_31_120": 6.26,
|
||||
"pDay_121_plus": 6.26
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 55.07,
|
||||
"cDay_31_120": 41.30,
|
||||
"cDay_121_plus": 30.87,
|
||||
"pDay_1_30": 50.06,
|
||||
"pDay_31_120": 37.55,
|
||||
"pDay_121_plus": 27.12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"lebanon": {
|
||||
"name": "Lebanon",
|
||||
"currency": "USD",
|
||||
"cities": {
|
||||
"beirut": {
|
||||
"name": "Beirut",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 25.35,
|
||||
"lunch": 41.75,
|
||||
"dinner": 53.30,
|
||||
"total": 120.40
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 19.01,
|
||||
"lunch": 31.31,
|
||||
"dinner": 39.98,
|
||||
"total": 90.30
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 12.68,
|
||||
"lunch": 20.88,
|
||||
"dinner": 26.65,
|
||||
"total": 60.20
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 25.35,
|
||||
"lunch": 41.75,
|
||||
"dinner": 53.30,
|
||||
"total": 120.40
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 19.01,
|
||||
"lunch": 31.31,
|
||||
"dinner": 39.98,
|
||||
"total": 90.30
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 12.68,
|
||||
"lunch": 20.88,
|
||||
"dinner": 26.65,
|
||||
"total": 60.20
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 38.53,
|
||||
"cDay_31_120": 28.90,
|
||||
"cDay_121_plus": 28.90,
|
||||
"pDay_1_30": 24.08,
|
||||
"pDay_31_120": 18.06,
|
||||
"pDay_121_plus": 18.06
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 158.93,
|
||||
"cDay_31_120": 119.20,
|
||||
"cDay_121_plus": 89.10,
|
||||
"pDay_1_30": 144.48,
|
||||
"pDay_31_120": 108.36,
|
||||
"pDay_121_plus": 78.26
|
||||
}
|
||||
},
|
||||
"other": {
|
||||
"name": "Other cities in Lebanon",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 20.28,
|
||||
"lunch": 33.40,
|
||||
"dinner": 42.64,
|
||||
"total": 96.32
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 15.21,
|
||||
"lunch": 25.05,
|
||||
"dinner": 31.98,
|
||||
"total": 72.24
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 10.14,
|
||||
"lunch": 16.70,
|
||||
"dinner": 21.32,
|
||||
"total": 48.16
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 20.28,
|
||||
"lunch": 33.40,
|
||||
"dinner": 42.64,
|
||||
"total": 96.32
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 15.21,
|
||||
"lunch": 25.05,
|
||||
"dinner": 31.98,
|
||||
"total": 72.24
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 10.14,
|
||||
"lunch": 16.70,
|
||||
"dinner": 21.32,
|
||||
"total": 48.16
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 30.82,
|
||||
"cDay_31_120": 23.12,
|
||||
"cDay_121_plus": 23.12,
|
||||
"pDay_1_30": 19.26,
|
||||
"pDay_31_120": 14.45,
|
||||
"pDay_121_plus": 14.45
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 127.14,
|
||||
"cDay_31_120": 95.36,
|
||||
"cDay_121_plus": 71.28,
|
||||
"pDay_1_30": 115.58,
|
||||
"pDay_31_120": 86.69,
|
||||
"pDay_121_plus": 62.61
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"lesotho": {
|
||||
"name": "Lesotho",
|
||||
"currency": "LSL",
|
||||
"cities": {
|
||||
"maseru": {
|
||||
"name": "Maseru",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 222.00,
|
||||
"lunch": 316.50,
|
||||
"dinner": 392.50,
|
||||
"total": 931.00
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 166.50,
|
||||
"lunch": 237.38,
|
||||
"dinner": 294.38,
|
||||
"total": 698.25
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 111.00,
|
||||
"lunch": 158.25,
|
||||
"dinner": 196.25,
|
||||
"total": 465.50
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 222.00,
|
||||
"lunch": 316.50,
|
||||
"dinner": 392.50,
|
||||
"total": 931.00
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 166.50,
|
||||
"lunch": 237.38,
|
||||
"dinner": 294.38,
|
||||
"total": 698.25
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 111.00,
|
||||
"lunch": 158.25,
|
||||
"dinner": 196.25,
|
||||
"total": 465.50
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 297.92,
|
||||
"cDay_31_120": 223.44,
|
||||
"cDay_121_plus": 223.44,
|
||||
"pDay_1_30": 186.20,
|
||||
"pDay_31_120": 139.65,
|
||||
"pDay_121_plus": 139.65
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 1228.92,
|
||||
"cDay_31_120": 921.69,
|
||||
"cDay_121_plus": 688.94,
|
||||
"pDay_1_30": 1117.20,
|
||||
"pDay_31_120": 837.90,
|
||||
"pDay_121_plus": 605.15
|
||||
}
|
||||
},
|
||||
"other": {
|
||||
"name": "Other cities in Lesotho",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 177.60,
|
||||
"lunch": 253.20,
|
||||
"dinner": 314.00,
|
||||
"total": 744.80
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 133.20,
|
||||
"lunch": 189.90,
|
||||
"dinner": 235.50,
|
||||
"total": 558.60
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 88.80,
|
||||
"lunch": 126.60,
|
||||
"dinner": 157.00,
|
||||
"total": 372.40
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 177.60,
|
||||
"lunch": 253.20,
|
||||
"dinner": 314.00,
|
||||
"total": 744.80
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 133.20,
|
||||
"lunch": 189.90,
|
||||
"dinner": 235.50,
|
||||
"total": 558.60
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 88.80,
|
||||
"lunch": 126.60,
|
||||
"dinner": 157.00,
|
||||
"total": 372.40
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 238.34,
|
||||
"cDay_31_120": 178.75,
|
||||
"cDay_121_plus": 178.75,
|
||||
"pDay_1_30": 148.96,
|
||||
"pDay_31_120": 111.72,
|
||||
"pDay_121_plus": 111.72
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 983.14,
|
||||
"cDay_31_120": 737.35,
|
||||
"cDay_121_plus": 551.15,
|
||||
"pDay_1_30": 893.76,
|
||||
"pDay_31_120": 670.32,
|
||||
"pDay_121_plus": 484.12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"liberia": {
|
||||
"name": "Liberia",
|
||||
"currency": "USD",
|
||||
"oneRateForCountry": true,
|
||||
"cities": {
|
||||
"monrovia": {
|
||||
"name": "Monrovia",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 23.60,
|
||||
"lunch": 34.05,
|
||||
"dinner": 43.05,
|
||||
"total": 100.70
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 17.70,
|
||||
"lunch": 25.54,
|
||||
"dinner": 32.29,
|
||||
"total": 75.53
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 11.80,
|
||||
"lunch": 17.03,
|
||||
"dinner": 21.53,
|
||||
"total": 50.35
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 23.60,
|
||||
"lunch": 34.05,
|
||||
"dinner": 43.05,
|
||||
"total": 100.70
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 17.70,
|
||||
"lunch": 25.54,
|
||||
"dinner": 32.29,
|
||||
"total": 75.53
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 11.80,
|
||||
"lunch": 17.03,
|
||||
"dinner": 21.53,
|
||||
"total": 50.35
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 32.22,
|
||||
"cDay_31_120": 24.17,
|
||||
"cDay_121_plus": 24.17,
|
||||
"pDay_1_30": 20.14,
|
||||
"pDay_31_120": 15.11,
|
||||
"pDay_121_plus": 15.11
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 132.92,
|
||||
"cDay_31_120": 99.69,
|
||||
"cDay_121_plus": 74.52,
|
||||
"pDay_1_30": 120.84,
|
||||
"pDay_31_120": 90.63,
|
||||
"pDay_121_plus": 65.46
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libya": {
|
||||
"name": "Libya",
|
||||
"currency": "LYD",
|
||||
"cities": {
|
||||
"tripoli": {
|
||||
"name": "Tripoli",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 82.50,
|
||||
"lunch": 104.50,
|
||||
"dinner": 148.50,
|
||||
"total": 335.50
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 61.88,
|
||||
"lunch": 78.38,
|
||||
"dinner": 111.38,
|
||||
"total": 251.63
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 41.25,
|
||||
"lunch": 52.25,
|
||||
"dinner": 74.25,
|
||||
"total": 167.75
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 82.50,
|
||||
"lunch": 104.50,
|
||||
"dinner": 148.50,
|
||||
"total": 335.50
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 61.88,
|
||||
"lunch": 78.38,
|
||||
"dinner": 111.38,
|
||||
"total": 251.63
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 41.25,
|
||||
"lunch": 52.25,
|
||||
"dinner": 74.25,
|
||||
"total": 167.75
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 107.36,
|
||||
"cDay_31_120": 80.52,
|
||||
"cDay_121_plus": 80.52,
|
||||
"pDay_1_30": 67.10,
|
||||
"pDay_31_120": 50.33,
|
||||
"pDay_121_plus": 50.33
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 442.86,
|
||||
"cDay_31_120": 332.15,
|
||||
"cDay_121_plus": 248.27,
|
||||
"pDay_1_30": 402.60,
|
||||
"pDay_31_120": 301.95,
|
||||
"pDay_121_plus": 218.08
|
||||
}
|
||||
},
|
||||
"other": {
|
||||
"name": "Other cities in Libya",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 66.00,
|
||||
"lunch": 83.60,
|
||||
"dinner": 118.80,
|
||||
"total": 268.40
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 49.50,
|
||||
"lunch": 62.70,
|
||||
"dinner": 89.10,
|
||||
"total": 201.30
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 33.00,
|
||||
"lunch": 41.80,
|
||||
"dinner": 59.40,
|
||||
"total": 134.20
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 66.00,
|
||||
"lunch": 83.60,
|
||||
"dinner": 118.80,
|
||||
"total": 268.40
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 49.50,
|
||||
"lunch": 62.70,
|
||||
"dinner": 89.10,
|
||||
"total": 201.30
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 33.00,
|
||||
"lunch": 41.80,
|
||||
"dinner": 59.40,
|
||||
"total": 134.20
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 85.89,
|
||||
"cDay_31_120": 64.42,
|
||||
"cDay_121_plus": 64.42,
|
||||
"pDay_1_30": 53.68,
|
||||
"pDay_31_120": 40.26,
|
||||
"pDay_121_plus": 40.26
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 354.29,
|
||||
"cDay_31_120": 265.72,
|
||||
"cDay_121_plus": 198.62,
|
||||
"pDay_1_30": 322.08,
|
||||
"pDay_31_120": 241.56,
|
||||
"pDay_121_plus": 174.46
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"liechtenstein": {
|
||||
"name": "Liechtenstein",
|
||||
"currency": "CHF",
|
||||
"oneRateForCountry": true,
|
||||
"cities": {
|
||||
"vaduz": {
|
||||
"name": "Vaduz",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 23.60,
|
||||
"lunch": 48.25,
|
||||
"dinner": 65.75,
|
||||
"total": 137.60
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 17.70,
|
||||
"lunch": 36.19,
|
||||
"dinner": 49.31,
|
||||
"total": 103.20
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 11.80,
|
||||
"lunch": 24.13,
|
||||
"dinner": 32.88,
|
||||
"total": 68.80
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 23.60,
|
||||
"lunch": 48.25,
|
||||
"dinner": 65.75,
|
||||
"total": 137.60
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 17.70,
|
||||
"lunch": 36.19,
|
||||
"dinner": 49.31,
|
||||
"total": 103.20
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 11.80,
|
||||
"lunch": 24.13,
|
||||
"dinner": 32.88,
|
||||
"total": 68.80
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 44.03,
|
||||
"cDay_31_120": 33.02,
|
||||
"cDay_121_plus": 33.02,
|
||||
"pDay_1_30": 27.52,
|
||||
"pDay_31_120": 20.64,
|
||||
"pDay_121_plus": 20.64
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 181.63,
|
||||
"cDay_31_120": 136.22,
|
||||
"cDay_121_plus": 101.82,
|
||||
"pDay_1_30": 165.12,
|
||||
"pDay_31_120": 123.84,
|
||||
"pDay_121_plus": 89.44
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"lithuania": {
|
||||
"name": "Lithuania",
|
||||
"currency": "EUR",
|
||||
"cities": {
|
||||
"vilnius": {
|
||||
"name": "Vilnius",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 23.90,
|
||||
"lunch": 50.25,
|
||||
"dinner": 69.35,
|
||||
"total": 143.50
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 17.93,
|
||||
"lunch": 37.69,
|
||||
"dinner": 52.01,
|
||||
"total": 107.63
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 11.95,
|
||||
"lunch": 25.13,
|
||||
"dinner": 34.68,
|
||||
"total": 71.75
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 23.90,
|
||||
"lunch": 50.25,
|
||||
"dinner": 69.35,
|
||||
"total": 143.50
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 17.93,
|
||||
"lunch": 37.69,
|
||||
"dinner": 52.01,
|
||||
"total": 107.63
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 11.95,
|
||||
"lunch": 25.13,
|
||||
"dinner": 34.68,
|
||||
"total": 71.75
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 45.92,
|
||||
"cDay_31_120": 34.44,
|
||||
"cDay_121_plus": 34.44,
|
||||
"pDay_1_30": 28.70,
|
||||
"pDay_31_120": 21.53,
|
||||
"pDay_121_plus": 21.53
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 189.42,
|
||||
"cDay_31_120": 142.07,
|
||||
"cDay_121_plus": 106.19,
|
||||
"pDay_1_30": 172.20,
|
||||
"pDay_31_120": 129.15,
|
||||
"pDay_121_plus": 93.28
|
||||
}
|
||||
},
|
||||
"other": {
|
||||
"name": "Other cities in Lithuania",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 19.12,
|
||||
"lunch": 40.20,
|
||||
"dinner": 55.48,
|
||||
"total": 114.80
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 14.34,
|
||||
"lunch": 30.15,
|
||||
"dinner": 41.61,
|
||||
"total": 86.10
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 9.56,
|
||||
"lunch": 20.10,
|
||||
"dinner": 27.74,
|
||||
"total": 57.40
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 19.12,
|
||||
"lunch": 40.20,
|
||||
"dinner": 55.48,
|
||||
"total": 114.80
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 14.34,
|
||||
"lunch": 30.15,
|
||||
"dinner": 41.61,
|
||||
"total": 86.10
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 9.56,
|
||||
"lunch": 20.10,
|
||||
"dinner": 27.74,
|
||||
"total": 57.40
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 36.74,
|
||||
"cDay_31_120": 27.55,
|
||||
"cDay_121_plus": 27.55,
|
||||
"pDay_1_30": 22.96,
|
||||
"pDay_31_120": 17.22,
|
||||
"pDay_121_plus": 17.22
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 151.54,
|
||||
"cDay_31_120": 113.65,
|
||||
"cDay_121_plus": 84.95,
|
||||
"pDay_1_30": 137.76,
|
||||
"pDay_31_120": 103.32,
|
||||
"pDay_121_plus": 74.62
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"luxembourg": {
|
||||
"name": "Luxembourg",
|
||||
"currency": "EUR",
|
||||
"oneRateForCountry": true,
|
||||
"cities": {
|
||||
"luxembourg": {
|
||||
"name": "Luxembourg",
|
||||
"meals": {
|
||||
"cDay_1_30": {
|
||||
"breakfast": 28.60,
|
||||
"lunch": 59.35,
|
||||
"dinner": 66.80,
|
||||
"total": 154.75
|
||||
},
|
||||
"cDay_31_120": {
|
||||
"breakfast": 21.45,
|
||||
"lunch": 44.51,
|
||||
"dinner": 50.10,
|
||||
"total": 116.06
|
||||
},
|
||||
"cDay_121_plus": {
|
||||
"breakfast": 14.30,
|
||||
"lunch": 29.68,
|
||||
"dinner": 33.40,
|
||||
"total": 77.38
|
||||
},
|
||||
"pDay_1_30": {
|
||||
"breakfast": 28.60,
|
||||
"lunch": 59.35,
|
||||
"dinner": 66.80,
|
||||
"total": 154.75
|
||||
},
|
||||
"pDay_31_120": {
|
||||
"breakfast": 21.45,
|
||||
"lunch": 44.51,
|
||||
"dinner": 50.10,
|
||||
"total": 116.06
|
||||
},
|
||||
"pDay_121_plus": {
|
||||
"breakfast": 14.30,
|
||||
"lunch": 29.68,
|
||||
"dinner": 33.40,
|
||||
"total": 77.38
|
||||
}
|
||||
},
|
||||
"accommodation": {
|
||||
"cDay_1_30": 49.52,
|
||||
"cDay_31_120": 37.14,
|
||||
"cDay_121_plus": 37.14,
|
||||
"pDay_1_30": 30.95,
|
||||
"pDay_31_120": 23.21,
|
||||
"pDay_121_plus": 23.21
|
||||
},
|
||||
"dailyTotal": {
|
||||
"cDay_1_30": 204.27,
|
||||
"cDay_31_120": 153.20,
|
||||
"cDay_121_plus": 114.52,
|
||||
"pDay_1_30": 185.70,
|
||||
"pDay_31_120": 139.28,
|
||||
"pDay_121_plus": 100.59
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
313
data/perDiemRates.json
Normal file
313
data/perDiemRates.json
Normal file
@@ -0,0 +1,313 @@
|
||||
{
|
||||
"metadata": {
|
||||
"effectiveDate": "2025-10-01",
|
||||
"version": "1.0",
|
||||
"source": "NJC Travel Directive Appendix C & D",
|
||||
"lastUpdated": "2025-10-30",
|
||||
"notes": "All rates in Canadian Dollars (CAD). US rates are same as Canada but paid in USD."
|
||||
},
|
||||
"regions": {
|
||||
"canada": {
|
||||
"name": "Canada (Provinces)",
|
||||
"currency": "CAD",
|
||||
"meals": {
|
||||
"breakfast": {
|
||||
"rate100": 29.05,
|
||||
"rate75": 21.80,
|
||||
"rate50": 14.55
|
||||
},
|
||||
"lunch": {
|
||||
"rate100": 29.60,
|
||||
"rate75": 22.20,
|
||||
"rate50": 14.80
|
||||
},
|
||||
"dinner": {
|
||||
"rate100": 60.75,
|
||||
"rate75": 45.55,
|
||||
"rate50": 30.40
|
||||
},
|
||||
"total": {
|
||||
"rate100": 119.40,
|
||||
"rate75": 89.55,
|
||||
"rate50": 59.75
|
||||
}
|
||||
},
|
||||
"incidentals": {
|
||||
"rate100": 17.30,
|
||||
"rate75": 13.00
|
||||
},
|
||||
"privateAccommodation": {
|
||||
"day1to120": 50.00,
|
||||
"day121onward": 25.00
|
||||
},
|
||||
"dailyTotal": {
|
||||
"rate100": 136.70,
|
||||
"rate75": 102.55,
|
||||
"rate50plus75": 72.75
|
||||
}
|
||||
},
|
||||
"yukon": {
|
||||
"name": "Yukon",
|
||||
"currency": "CAD",
|
||||
"meals": {
|
||||
"breakfast": {
|
||||
"rate100": 26.40,
|
||||
"rate75": 19.80,
|
||||
"rate50": 13.20
|
||||
},
|
||||
"lunch": {
|
||||
"rate100": 33.50,
|
||||
"rate75": 25.15,
|
||||
"rate50": 16.75
|
||||
},
|
||||
"dinner": {
|
||||
"rate100": 78.50,
|
||||
"rate75": 58.90,
|
||||
"rate50": 39.25
|
||||
},
|
||||
"total": {
|
||||
"rate100": 138.40,
|
||||
"rate75": 103.85,
|
||||
"rate50": 69.20
|
||||
}
|
||||
},
|
||||
"incidentals": {
|
||||
"rate100": 17.30,
|
||||
"rate75": 13.00
|
||||
},
|
||||
"privateAccommodation": {
|
||||
"day1to120": 50.00,
|
||||
"day121onward": 25.00
|
||||
},
|
||||
"dailyTotal": {
|
||||
"rate100": 155.70,
|
||||
"rate75": 116.85,
|
||||
"rate50plus75": 82.20
|
||||
}
|
||||
},
|
||||
"nwt": {
|
||||
"name": "Northwest Territories",
|
||||
"currency": "CAD",
|
||||
"meals": {
|
||||
"breakfast": {
|
||||
"rate100": 30.05,
|
||||
"rate75": 22.55,
|
||||
"rate50": 15.05
|
||||
},
|
||||
"lunch": {
|
||||
"rate100": 35.65,
|
||||
"rate75": 26.75,
|
||||
"rate50": 17.85
|
||||
},
|
||||
"dinner": {
|
||||
"rate100": 76.05,
|
||||
"rate75": 57.05,
|
||||
"rate50": 38.05
|
||||
},
|
||||
"total": {
|
||||
"rate100": 141.75,
|
||||
"rate75": 106.35,
|
||||
"rate50": 70.95
|
||||
}
|
||||
},
|
||||
"incidentals": {
|
||||
"rate100": 17.30,
|
||||
"rate75": 13.00
|
||||
},
|
||||
"privateAccommodation": {
|
||||
"day1to120": 50.00,
|
||||
"day121onward": 25.00
|
||||
},
|
||||
"dailyTotal": {
|
||||
"rate100": 159.05,
|
||||
"rate75": 119.35,
|
||||
"rate50plus75": 83.95
|
||||
}
|
||||
},
|
||||
"nunavut": {
|
||||
"name": "Nunavut",
|
||||
"currency": "CAD",
|
||||
"meals": {
|
||||
"breakfast": {
|
||||
"rate100": 35.05,
|
||||
"rate75": 26.30,
|
||||
"rate50": 17.55
|
||||
},
|
||||
"lunch": {
|
||||
"rate100": 41.60,
|
||||
"rate75": 31.20,
|
||||
"rate50": 20.80
|
||||
},
|
||||
"dinner": {
|
||||
"rate100": 100.45,
|
||||
"rate75": 75.35,
|
||||
"rate50": 50.25
|
||||
},
|
||||
"total": {
|
||||
"rate100": 177.10,
|
||||
"rate75": 132.85,
|
||||
"rate50": 88.60
|
||||
}
|
||||
},
|
||||
"incidentals": {
|
||||
"rate100": 17.30,
|
||||
"rate75": 13.00
|
||||
},
|
||||
"privateAccommodation": {
|
||||
"day1to120": 50.00,
|
||||
"day121onward": 25.00
|
||||
},
|
||||
"dailyTotal": {
|
||||
"rate100": 194.40,
|
||||
"rate75": 145.85,
|
||||
"rate50plus75": 101.60
|
||||
}
|
||||
},
|
||||
"usa": {
|
||||
"name": "Continental USA",
|
||||
"currency": "USD",
|
||||
"meals": {
|
||||
"breakfast": {
|
||||
"rate100": 29.05,
|
||||
"rate75": 21.80,
|
||||
"rate50": 14.55
|
||||
},
|
||||
"lunch": {
|
||||
"rate100": 29.60,
|
||||
"rate75": 22.20,
|
||||
"rate50": 14.80
|
||||
},
|
||||
"dinner": {
|
||||
"rate100": 60.75,
|
||||
"rate75": 45.55,
|
||||
"rate50": 30.40
|
||||
},
|
||||
"total": {
|
||||
"rate100": 119.40,
|
||||
"rate75": 89.55,
|
||||
"rate50": 59.75
|
||||
}
|
||||
},
|
||||
"incidentals": {
|
||||
"rate100": 17.30,
|
||||
"rate75": 13.00
|
||||
},
|
||||
"privateAccommodation": {
|
||||
"day1to120": 50.00,
|
||||
"day121onward": 25.00
|
||||
},
|
||||
"dailyTotal": {
|
||||
"rate100": 136.70,
|
||||
"rate75": 102.55,
|
||||
"rate50plus75": 72.75
|
||||
}
|
||||
},
|
||||
"alaska": {
|
||||
"name": "Alaska",
|
||||
"currency": "USD",
|
||||
"meals": {
|
||||
"breakfast": {
|
||||
"rate100": 26.40,
|
||||
"rate75": 19.80,
|
||||
"rate50": 13.20
|
||||
},
|
||||
"lunch": {
|
||||
"rate100": 33.50,
|
||||
"rate75": 25.15,
|
||||
"rate50": 16.75
|
||||
},
|
||||
"dinner": {
|
||||
"rate100": 78.50,
|
||||
"rate75": 58.90,
|
||||
"rate50": 39.25
|
||||
},
|
||||
"total": {
|
||||
"rate100": 138.40,
|
||||
"rate75": 103.85,
|
||||
"rate50": 69.20
|
||||
}
|
||||
},
|
||||
"incidentals": {
|
||||
"rate100": 17.30,
|
||||
"rate75": 13.00
|
||||
},
|
||||
"privateAccommodation": {
|
||||
"day1to120": 50.00,
|
||||
"day121onward": 25.00
|
||||
},
|
||||
"dailyTotal": {
|
||||
"rate100": 155.70,
|
||||
"rate75": 116.85,
|
||||
"rate50plus75": 82.20
|
||||
}
|
||||
},
|
||||
"international": {
|
||||
"name": "International (Outside Canada/USA)",
|
||||
"currency": "CAD",
|
||||
"notes": "Rates vary by country. See Appendix D for specific country rates. These are average estimates.",
|
||||
"meals": {
|
||||
"breakfast": {
|
||||
"rate100": 35.00,
|
||||
"rate75": 26.25,
|
||||
"rate50": 17.50
|
||||
},
|
||||
"lunch": {
|
||||
"rate100": 40.00,
|
||||
"rate75": 30.00,
|
||||
"rate50": 20.00
|
||||
},
|
||||
"dinner": {
|
||||
"rate100": 85.00,
|
||||
"rate75": 63.75,
|
||||
"rate50": 42.50
|
||||
},
|
||||
"total": {
|
||||
"rate100": 160.00,
|
||||
"rate75": 120.00,
|
||||
"rate50": 80.00
|
||||
}
|
||||
},
|
||||
"incidentals": {
|
||||
"rate100": 20.00,
|
||||
"rate75": 15.00
|
||||
},
|
||||
"privateAccommodation": {
|
||||
"day1to120": 60.00,
|
||||
"day121onward": 30.00
|
||||
},
|
||||
"dailyTotal": {
|
||||
"rate100": 180.00,
|
||||
"rate75": 135.00,
|
||||
"rate50plus75": 95.00
|
||||
}
|
||||
}
|
||||
},
|
||||
"rateRules": {
|
||||
"day1to30": "rate100",
|
||||
"day31to120": "rate75",
|
||||
"day121onward": "rate50",
|
||||
"description": "75% of meal and incidental allowances paid starting day 31. 50% of meals paid starting day 121. Incidentals remain at 75% after day 31."
|
||||
},
|
||||
"specialRates": {
|
||||
"hawaii": {
|
||||
"reference": "See Appendix D for specific rates",
|
||||
"currency": "USD"
|
||||
},
|
||||
"guam": {
|
||||
"reference": "See Appendix D for specific rates",
|
||||
"currency": "USD"
|
||||
},
|
||||
"puertoRico": {
|
||||
"reference": "See Appendix D for specific rates",
|
||||
"currency": "USD"
|
||||
},
|
||||
"virginIslands": {
|
||||
"reference": "See Appendix D for specific rates",
|
||||
"currency": "USD"
|
||||
},
|
||||
"northernMarianas": {
|
||||
"reference": "See Appendix D for specific rates",
|
||||
"currency": "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
46
data/sampleFlights.json
Normal file
46
data/sampleFlights.json
Normal file
@@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"price": 1295.00,
|
||||
"currency": "CAD",
|
||||
"duration": "PT16H10M",
|
||||
"durationHours": 16.2,
|
||||
"businessClassEligible": true,
|
||||
"stops": 1,
|
||||
"carrier": "AC",
|
||||
"departureTime": "2025-11-15T08:00:00",
|
||||
"arrivalTime": "2025-11-15T16:10:00"
|
||||
},
|
||||
{
|
||||
"price": 1420.50,
|
||||
"currency": "CAD",
|
||||
"duration": "PT14H25M",
|
||||
"durationHours": 14.4,
|
||||
"businessClassEligible": true,
|
||||
"stops": 2,
|
||||
"carrier": "BA",
|
||||
"departureTime": "2025-11-15T09:30:00",
|
||||
"arrivalTime": "2025-11-15T16:55:00"
|
||||
},
|
||||
{
|
||||
"price": 980.25,
|
||||
"currency": "CAD",
|
||||
"duration": "PT20H05M",
|
||||
"durationHours": 20.1,
|
||||
"businessClassEligible": true,
|
||||
"stops": 2,
|
||||
"carrier": "QF",
|
||||
"departureTime": "2025-11-15T07:15:00",
|
||||
"arrivalTime": "2025-11-15T16:20:00"
|
||||
},
|
||||
{
|
||||
"price": 875.75,
|
||||
"currency": "CAD",
|
||||
"duration": "PT18H40M",
|
||||
"durationHours": 18.7,
|
||||
"businessClassEligible": true,
|
||||
"stops": 3,
|
||||
"carrier": "SQ",
|
||||
"departureTime": "2025-11-15T06:45:00",
|
||||
"arrivalTime": "2025-11-15T15:25:00"
|
||||
}
|
||||
]
|
||||
194
data/transportationRates.json
Normal file
194
data/transportationRates.json
Normal file
@@ -0,0 +1,194 @@
|
||||
{
|
||||
"metadata": {
|
||||
"effectiveDate": "2025-10-01",
|
||||
"version": "1.0",
|
||||
"source": "NJC Travel Directive Appendix B",
|
||||
"lastUpdated": "2025-10-30",
|
||||
"notes": "Kilometric rates for personal vehicle use. All rates in Canadian Dollars (CAD)."
|
||||
},
|
||||
"kilometricRates": {
|
||||
"description": "Rates per kilometre for use of personal vehicle on government business",
|
||||
"modules": {
|
||||
"module1and2": {
|
||||
"name": "Modules 1 and 2 - Local and day travel",
|
||||
"rates": {
|
||||
"perKm": 0.68,
|
||||
"notes": "For travel within headquarters area or day trips"
|
||||
}
|
||||
},
|
||||
"module3": {
|
||||
"name": "Module 3 - Travel in Canada and Continental USA with overnight stay",
|
||||
"rates": {
|
||||
"tier1": {
|
||||
"description": "First 5,000 km per year",
|
||||
"perKm": 0.68
|
||||
},
|
||||
"tier2": {
|
||||
"description": "Over 5,000 km per year",
|
||||
"perKm": 0.58
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalExpenses": {
|
||||
"parking": {
|
||||
"description": "Reasonable parking expenses",
|
||||
"reimbursable": true,
|
||||
"requiresReceipt": true
|
||||
},
|
||||
"tolls": {
|
||||
"description": "Highway tolls and ferry fees",
|
||||
"reimbursable": true,
|
||||
"requiresReceipt": true
|
||||
},
|
||||
"tunnel": {
|
||||
"description": "Tunnel fees",
|
||||
"reimbursable": true,
|
||||
"requiresReceipt": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"trainTravel": {
|
||||
"description": "Rail travel within Canada and USA",
|
||||
"policy": {
|
||||
"domesticCanada": {
|
||||
"class": "Economy class",
|
||||
"provider": "VIA Rail or equivalent",
|
||||
"notes": "Business class may be authorized with approval"
|
||||
},
|
||||
"usa": {
|
||||
"class": "Economy class",
|
||||
"provider": "Amtrak or equivalent",
|
||||
"notes": "Business class may be authorized with approval"
|
||||
},
|
||||
"businessClassCriteria": {
|
||||
"duration": "Extended travel periods",
|
||||
"workRequirement": "Need to work during travel",
|
||||
"authorization": "Requires prior approval"
|
||||
}
|
||||
},
|
||||
"commonRoutes": {
|
||||
"ottawaToMontreal": {
|
||||
"distance": 200,
|
||||
"estimatedCost": {
|
||||
"economy": 45,
|
||||
"business": 90
|
||||
},
|
||||
"provider": "VIA Rail"
|
||||
},
|
||||
"ottawaToToronto": {
|
||||
"distance": 450,
|
||||
"estimatedCost": {
|
||||
"economy": 85,
|
||||
"business": 170
|
||||
},
|
||||
"provider": "VIA Rail"
|
||||
},
|
||||
"torontoToMontreal": {
|
||||
"distance": 550,
|
||||
"estimatedCost": {
|
||||
"economy": 95,
|
||||
"business": 190
|
||||
},
|
||||
"provider": "VIA Rail"
|
||||
},
|
||||
"vancouverToSeattle": {
|
||||
"distance": 230,
|
||||
"estimatedCost": {
|
||||
"economy": 55,
|
||||
"business": 110
|
||||
},
|
||||
"provider": "Amtrak Cascades"
|
||||
}
|
||||
}
|
||||
},
|
||||
"comparativeAnalysis": {
|
||||
"description": "When choosing transportation mode, consider:",
|
||||
"factors": [
|
||||
"Total cost (transportation + time)",
|
||||
"Travel duration",
|
||||
"Accommodation needs",
|
||||
"Meal allowances during travel",
|
||||
"Work productivity during travel",
|
||||
"Environmental impact"
|
||||
],
|
||||
"costComparison": {
|
||||
"ottawaToToronto": {
|
||||
"flight": {
|
||||
"cost": 250,
|
||||
"duration": "1 hour flight + 2 hours airport",
|
||||
"notes": "Fastest option"
|
||||
},
|
||||
"train": {
|
||||
"cost": 85,
|
||||
"duration": "4-5 hours",
|
||||
"notes": "Can work during travel"
|
||||
},
|
||||
"vehicle": {
|
||||
"cost": 306,
|
||||
"calculation": "450 km × $0.68/km",
|
||||
"duration": "4.5-5 hours",
|
||||
"notes": "Plus parking, tolls"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vehicleInsurance": {
|
||||
"description": "Insurance coverage for personal vehicles on government business",
|
||||
"coverage": {
|
||||
"liability": "Covered by government if employee has minimum provincial insurance",
|
||||
"collision": "Employee responsible for deductible",
|
||||
"comprehensive": "Employee responsible for deductible"
|
||||
},
|
||||
"requirements": {
|
||||
"minimumInsurance": "Must maintain minimum provincial/territorial insurance",
|
||||
"proof": "May be required to provide proof of insurance",
|
||||
"condition": "Vehicle must be in safe operating condition"
|
||||
}
|
||||
},
|
||||
"calculationExamples": {
|
||||
"example1": {
|
||||
"scenario": "Day trip Ottawa to Kingston (180 km each way)",
|
||||
"calculation": {
|
||||
"totalDistance": 360,
|
||||
"rate": 0.68,
|
||||
"totalCost": 244.80,
|
||||
"formula": "360 km × $0.68/km = $244.80"
|
||||
}
|
||||
},
|
||||
"example2": {
|
||||
"scenario": "Multi-day trip with 2,000 km total",
|
||||
"calculation": {
|
||||
"totalDistance": 2000,
|
||||
"rate": 0.68,
|
||||
"totalCost": 1360.00,
|
||||
"formula": "2,000 km × $0.68/km = $1,360.00",
|
||||
"notes": "All at tier 1 rate (under 5,000 km/year)"
|
||||
}
|
||||
},
|
||||
"example3": {
|
||||
"scenario": "Trip after already driving 5,500 km this year, new trip is 1,000 km",
|
||||
"calculation": {
|
||||
"totalDistance": 1000,
|
||||
"rate": 0.58,
|
||||
"totalCost": 580.00,
|
||||
"formula": "1,000 km × $0.58/km = $580.00",
|
||||
"notes": "At tier 2 rate (over 5,000 km/year)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"specialConsiderations": {
|
||||
"winterTravel": {
|
||||
"recommendation": "Consider safety and weather conditions",
|
||||
"allowances": "Additional travel time may be justified"
|
||||
},
|
||||
"remoteLocations": {
|
||||
"recommendation": "Personal vehicle may be necessary if no public transit",
|
||||
"considerations": "Check accommodation parking availability"
|
||||
},
|
||||
"multiplePassengers": {
|
||||
"carPooling": "Kilometric rate covers multiple passengers",
|
||||
"efficiency": "Cost-effective for group travel"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user