import { DateTime } from "luxon"; import { sdkLogger as logger } from "../services/reporting-service/logger.js"; import { getCachedTimezoneName } from "../services/mm-api-service/company-info.js"; /** * Retrieves the ERP timezone name that should have been cached during initialization. * @throws Error when the timezone cache has not been populated. */ export function getERPTimezone(): string { const timezone = getCachedTimezoneName(); if (!timezone) { throw new Error( "ERP timezone is not cached. Run getTimezoneOffsetAndPersist() to populate it." ); } return timezone; } /** * Converts a UTC ISO-8601 datetime string to the ERP's local timezone (also ISO-8601). * @param utcDateTime ISO-8601 datetime string representing UTC time. * @param timezone Optional timezone override; defaults to the cached ERP timezone. * @returns ISO-8601 string in the ERP timezone. */ export function convertUtcDateTimeToErpLocal( utcDateTime: string, timezone?: string ): string { if (!utcDateTime) { throw new Error("convertUtcDateTimeToErpLocal requires a non-empty UTC datetime string"); } try { const targetZone = timezone ?? getERPTimezone(); const parsedUtc = DateTime.fromISO(utcDateTime, { zone: "utc" }); if (!parsedUtc.isValid) { throw new Error( `Invalid UTC datetime "${utcDateTime}": ${parsedUtc.invalidReason}` ); } const localized = parsedUtc.setZone(targetZone); if (!localized.isValid) { throw new Error( `Unable to convert UTC datetime "${utcDateTime}" to target zone "${targetZone}": ${localized.invalidReason}` ); } return localized.toISO(); } catch (error) { logger.error("convertUtcDateTimeToErpLocal: Failed to convert datetime", { utcDateTime, error, }); throw new Error( "Failed to convert UTC datetime to ERP local timezone. See logs for details." ); } } /** * Converts an ERP-local ISO-8601 datetime string to UTC (still ISO-8601). * @param localDateTime ISO-8601 datetime string representing ERP local time. * @param timezone Optional timezone override; defaults to the cached ERP timezone. * @returns ISO-8601 string in UTC. */ export function convertErpLocalDateTimeToUtc( localDateTime: string, timezone?: string ): string { if (!localDateTime) { throw new Error("convertErpLocalDateTimeToUtc requires a non-empty local datetime string"); } try { const sourceZone = timezone ?? getERPTimezone(); const parsedLocal = DateTime.fromISO(localDateTime, { zone: sourceZone }); if (!parsedLocal.isValid) { throw new Error( `Invalid ERP local datetime "${localDateTime}" for zone "${sourceZone}": ${parsedLocal.invalidReason}` ); } const utcDateTime = parsedLocal.setZone("utc"); if (!utcDateTime.isValid) { throw new Error( `Unable to convert ERP local datetime "${localDateTime}" to UTC: ${utcDateTime.invalidReason}` ); } return utcDateTime.toISO(); } catch (error) { logger.error("convertErpLocalDateTimeToUtc: Failed to convert datetime", { localDateTime, error, }); throw new Error( "Failed to convert ERP local datetime to UTC. See logs for details." ); } }