Reporting and TZ updates

This commit is contained in:
2026-06-28 07:37:41 -04:00
parent 5e12561fb2
commit c2e4d2adeb
18 changed files with 719 additions and 268 deletions
+103 -59
View File
@@ -590,33 +590,104 @@
return response;
}
// Load PPR records - now loads all tables
function formatTimeOnly(dateStr) {
if (!dateStr) return '-';
// Ensure the datetime string is treated as UTC
let utcDateStr = dateStr;
function normalizeUtcDateString(dateStr) {
if (!dateStr) return null;
let utcDateStr = String(dateStr).trim();
if (!utcDateStr.includes('T')) {
utcDateStr = utcDateStr.replace(' ', 'T');
}
if (!utcDateStr.includes('Z')) {
if (!/[zZ]|[+-]\d{2}:?\d{2}$/.test(utcDateStr)) {
utcDateStr += 'Z';
}
const date = new Date(utcDateStr);
return utcDateStr;
}
function parseUtcDate(dateStr) {
const normalized = normalizeUtcDateString(dateStr);
return normalized ? new Date(normalized) : null;
}
function utcDateOnly(dateStr) {
const date = parseUtcDate(dateStr);
return date && !Number.isNaN(date.getTime()) ? date.toISOString().slice(0, 10) : '';
}
function formatUtcDateInput(date) {
return date.toISOString().slice(0, 10);
}
function formatUtcTimeInput(date) {
return date.toISOString().slice(11, 16);
}
function formatUtcDayMonth(dateStr) {
const isoDate = utcDateOnly(dateStr);
return isoDate ? `${isoDate.slice(8, 10)}/${isoDate.slice(5, 7)}` : '-';
}
function formatUtcWeekdayDayMonth(dateStr) {
const date = parseUtcDate(dateStr);
if (!date || Number.isNaN(date.getTime())) return '-';
const dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][date.getUTCDay()];
return `${dayName} ${formatUtcDayMonth(dateStr)}`;
}
function combineUtcDateTimeInput(dateStr, timeStr) {
return `${dateStr}T${timeStr}:00Z`;
}
async function autoSaveUnsavedAircraft(form) {
if (!form || !form.hasAttribute('data-unsaved-aircraft') || !accessToken) return;
const formData = new FormData(form);
const registration = (
formData.get('ac_reg') ||
formData.get('registration') ||
formData.get('local_registration') ||
formData.get('book_in_registration') ||
formData.get('overflight_registration') ||
''
).trim();
const typeCode = (
formData.get('ac_type') ||
formData.get('type') ||
formData.get('local_type') ||
formData.get('book_in_type') ||
formData.get('overflight_type') ||
''
).trim();
if (!registration || !typeCode) return;
try {
const response = await authenticatedFetch('/api/v1/aircraft/user-aircraft', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
registration,
type_code: typeCode
})
});
if (response.ok) {
form.removeAttribute('data-unsaved-aircraft');
}
} catch (error) {
console.warn('Could not save user aircraft type:', error);
}
}
// Load PPR records - now loads all tables
function formatTimeOnly(dateStr) {
if (!dateStr) return '-';
const date = parseUtcDate(dateStr);
return date && !Number.isNaN(date.getTime()) ? formatUtcTimeInput(date) : '-';
}
function formatDateTime(dateStr) {
if (!dateStr) return '-';
// Ensure the datetime string is treated as UTC
let utcDateStr = dateStr;
if (!utcDateStr.includes('T')) {
utcDateStr = utcDateStr.replace(' ', 'T');
}
if (!utcDateStr.includes('Z')) {
utcDateStr += 'Z';
}
const date = new Date(utcDateStr);
return date.toISOString().slice(0, 10) + ' ' + date.toISOString().slice(11, 16);
const date = parseUtcDate(dateStr);
return date && !Number.isNaN(date.getTime()) ? `${formatUtcDateInput(date)} ${formatUtcTimeInput(date)}` : '-';
}
// Modal functions
@@ -640,24 +711,10 @@
const eta = new Date(now.getTime() + 60 * 60 * 1000); // +1 hour
const etd = new Date(now.getTime() + 2 * 60 * 60 * 1000); // +2 hours
// Format date and time for separate inputs
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
function formatTime(date) {
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(Math.ceil(date.getMinutes() / 15) * 15 % 60).padStart(2, '0'); // Round up to next 15-minute interval
return `${hours}:${minutes}`;
}
document.getElementById('eta-date').value = formatDate(eta);
document.getElementById('eta-time').value = formatTime(eta);
document.getElementById('etd-date').value = formatDate(etd);
document.getElementById('etd-time').value = formatTime(etd);
document.getElementById('eta-date').value = formatUtcDateInput(eta);
document.getElementById('eta-time').value = formatUtcTimeInput(eta);
document.getElementById('etd-date').value = formatUtcDateInput(etd);
document.getElementById('etd-time').value = formatUtcTimeInput(etd);
// Clear aircraft lookup results
clearAircraftLookup();
@@ -683,15 +740,14 @@
const etaTime = document.getElementById('eta-time').value;
if (etaDate && etaTime) {
// Parse ETA
const eta = new Date(`${etaDate}T${etaTime}`);
const eta = parseUtcDate(combineUtcDateTimeInput(etaDate, etaTime));
// Calculate ETD (2 hours after ETA)
const etd = new Date(eta.getTime() + 2 * 60 * 60 * 1000);
// Format ETD
const etdDateStr = `${etd.getFullYear()}-${String(etd.getMonth() + 1).padStart(2, '0')}-${String(etd.getDate()).padStart(2, '0')}`;
const etdTimeStr = `${String(etd.getHours()).padStart(2, '0')}:${String(etd.getMinutes()).padStart(2, '0')}`;
const etdDateStr = formatUtcDateInput(etd);
const etdTimeStr = formatUtcTimeInput(etd);
// Update ETD fields
document.getElementById('etd-date').value = etdDateStr;
@@ -754,31 +810,19 @@
Object.keys(ppr).forEach(key => {
if (key === 'eta' || key === 'etd') {
if (ppr[key]) {
// ppr[key] is UTC datetime string from API (naive, assume UTC)
let utcDateStr = ppr[key];
if (!utcDateStr.includes('T')) {
utcDateStr = utcDateStr.replace(' ', 'T');
}
if (!utcDateStr.includes('Z')) {
utcDateStr += 'Z';
}
const date = new Date(utcDateStr); // Now correctly parsed as UTC
const date = parseUtcDate(ppr[key]);
// Split into date and time components for separate inputs
const dateField = document.getElementById(`${key}-date`);
const timeField = document.getElementById(`${key}-time`);
if (dateField && timeField) {
// Format date
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const dateValue = `${year}-${month}-${day}`;
const dateValue = formatUtcDateInput(date);
dateField.value = dateValue;
// Format time (round to nearest 15-minute interval)
const hours = String(date.getHours()).padStart(2, '0');
const rawMinutes = date.getMinutes();
const hours = String(date.getUTCHours()).padStart(2, '0');
const rawMinutes = date.getUTCMinutes();
const roundedMinutes = Math.round(rawMinutes / 15) * 15 % 60;
const minutes = String(roundedMinutes).padStart(2, '0');
const timeValue = `${hours}:${minutes}`;
@@ -1089,12 +1133,12 @@
// Combine date and time for ETA
const dateStr = formData.get('eta-date');
const timeStr = formData.get('eta-time');
pprData.eta = new Date(`${dateStr}T${timeStr}`).toISOString();
pprData.eta = combineUtcDateTimeInput(dateStr, timeStr);
} else if (key === 'etd-date' && formData.get('etd-time')) {
// Combine date and time for ETD
const dateStr = formData.get('etd-date');
const timeStr = formData.get('etd-time');
pprData.etd = new Date(`${dateStr}T${timeStr}`).toISOString();
pprData.etd = combineUtcDateTimeInput(dateStr, timeStr);
} else if (key !== 'eta-time' && key !== 'etd-time') {
// Skip the time fields as they're handled above
pprData[key] = value;
@@ -1856,13 +1900,13 @@
// Parse and populate call_dt
if (overflight.call_dt) {
const callDt = new Date(overflight.call_dt);
const callDt = parseUtcDate(overflight.call_dt);
document.getElementById('overflight_edit_call_dt').value = callDt.toISOString().slice(0, 16);
}
// Parse and populate qsy_dt if exists
if (overflight.qsy_dt) {
const qsyDt = new Date(overflight.qsy_dt);
const qsyDt = parseUtcDate(overflight.qsy_dt);
document.getElementById('overflight_edit_qsy_dt').value = qsyDt.toISOString().slice(0, 16);
} else {
document.getElementById('overflight_edit_qsy_dt').value = '';