import { writeFile, utils, type WorkSheet } from 'xlsx'; import { fetchCurrentPatient, formatDate, getConfig } from '@openmrs/esm-framework'; import { type Appointment } from '../types'; import { type ConfigObject } from '../config-schema'; import { moduleName } from '../constants'; type RowData = { id: string; // Corresponds to the UUID of an appointment identifier?: string; // Optional identifier property } & Record; // Allow for other dynamic properties /** * Exports the provided appointments as an Excel spreadsheet. * @param {Array} appointments - The list of appointments to export. * @param {Array} rowData - The current rows of the table as rendered in the UI. * @param {string} [fileName] - The name of the downloaded file */ export async function exportAppointmentsToSpreadsheet( appointments: Array, rowData: Array, fileName = 'Appointments', ) { const config = await getConfig(moduleName); const includePhoneNumbers = config.includePhoneNumberInExcelSpreadsheet ?? false; const appointmentsJSON = await Promise.all( appointments.map(async (appointment: Appointment) => { const matchingAppointment = rowData.find((row) => row.id === appointment.uuid); //const identifier = matchingAppointment?.identifier ?? appointment.appointmentId; const identifier = appointment.patient.identifiers && appointment.patient.identifiers.length > 0 ? appointment.patient.identifiers[0].identifier : '--'; const patientInfo = await fetchCurrentPatient(appointment.patient.uuid); const phoneNumber = includePhoneNumbers && patientInfo?.telecom ? patientInfo.telecom.map((telecomObj) => telecomObj?.value).join(', ') : ''; return { Identifier: identifier, 'Patient name': appointment.patient.name, 'Date of birth': formatDate(new Date(appointment.patient.person.birthdate), { mode: 'wide' }), Gender: appointment.patient.person.gender === 'F' ? 'Female' : 'Male', Location: appointment.location ? appointment.location.name : '--', 'Service type': appointment.service ? appointment.service.name : appointment.appointmentService?.name ?? '--', 'Date of appointment': formatDate(new Date(appointment.appointmentDate), { mode: 'wide' }), 'Reason of Appointment': appointment.reason?.value?.display ?? '--', Status: appointment.appointmentState ?? '--', }; }), ); const worksheet = createWorksheet(appointmentsJSON); const workbook = createWorkbook(worksheet, 'Appointment list'); writeFile(workbook, `${fileName}.xlsx`, { compression: true }); } /** Exports unscheduled appointments as an Excel spreadsheet. @param {Array} unscheduledAppointments - The list of unscheduled appointments to export. @param {string} fileName - The name of the file to download. Defaults to 'Unscheduled appointments {current date and time}'. */ export function exportUnscheduledAppointmentsToSpreadsheet( unscheduledAppointments: Array, fileName: string = `Unscheduled appointments ${formatDate(new Date(), { year: true, time: true })}`, ) { const appointmentsJSON = unscheduledAppointments?.map((appointment) => ({ 'Patient name': appointment.name, Gender: appointment.gender === 'F' ? 'Female' : 'Male', Age: appointment.age, 'Phone Number': appointment.phoneNumber ?? '--', Identifier: appointment.identifier ?? '--', })); const worksheet = createWorksheet(appointmentsJSON); const workbook = createWorkbook(worksheet, 'Appointment list'); writeFile(workbook, `${fileName}.xlsx`, { compression: true, }); } function createWorksheet(data: any[]) { const max_width = data.reduce((w, r) => Math.max(w, r['Patient name'].length), 30); const worksheet = utils.json_to_sheet(data); worksheet['!cols'] = [{ wch: max_width }]; return worksheet; } function createWorkbook(worksheet: WorkSheet, sheetName: string) { const workbook = utils.book_new(); utils.book_append_sheet(workbook, worksheet, sheetName); return workbook; }