package xlsx import ( "fmt" "net/http" "git.coopgo.io/coopgo-apps/parcoursmob/core/application" "git.coopgo.io/coopgo-apps/parcoursmob/core/utils/gender" "github.com/rs/zerolog/log" ) func (r *XLSXRenderer) OrganizedCarpoolBookings(w http.ResponseWriter, result *application.OrganizedCarpoolBookingsResult) { // Create Excel spreadsheet spreadsheet := r.NewSpreadsheet("Covoiturage solidaire") // Build headers dynamically based on configuration headers := []string{ "ID Réservation", "Statut", "Motif de réservation", "Date de prise en charge", "Heure de prise en charge", } // Add driver fields from config driverOptionalFields := r.Config.Get("modules.organized_carpool.profile_optional_fields") driverFields := []string{"last_name", "first_name", "email", "phone_number"} driverHeaders := []string{"Conducteur - Nom", "Conducteur - Prénom", "Conducteur - Email", "Conducteur - Téléphone"} if driverOptionalFieldsList, ok := driverOptionalFields.([]interface{}); ok { for _, field := range driverOptionalFieldsList { if fieldMap, ok := field.(map[string]interface{}); ok { if name, ok := fieldMap["name"].(string); ok { driverFields = append(driverFields, name) label := name if labelVal, ok := fieldMap["label"].(string); ok { label = labelVal } driverHeaders = append(driverHeaders, fmt.Sprintf("Conducteur - %s", label)) } } } } headers = append(headers, driverHeaders...) // Add beneficiary fields from config beneficiaryOptionalFields := r.Config.Get("modules.beneficiaries.profile_optional_fields") beneficiaryFields := []string{"last_name", "first_name", "email", "phone_number"} beneficiaryHeaders := []string{"Bénéficiaire - Nom", "Bénéficiaire - Prénom", "Bénéficiaire - Email", "Bénéficiaire - Téléphone"} if beneficiaryOptionalFieldsList, ok := beneficiaryOptionalFields.([]interface{}); ok { for _, field := range beneficiaryOptionalFieldsList { if fieldMap, ok := field.(map[string]interface{}); ok { if name, ok := fieldMap["name"].(string); ok { beneficiaryFields = append(beneficiaryFields, name) label := name if labelVal, ok := fieldMap["label"].(string); ok { label = labelVal } beneficiaryHeaders = append(beneficiaryHeaders, fmt.Sprintf("Bénéficiaire - %s", label)) } } } } headers = append(headers, beneficiaryHeaders...) // Add journey information headers headers = append(headers, "Lieu de départ - Adresse", "Destination - Adresse", "Distance passager (km)", "Durée trajet (minutes)", "Prix passager", "Devise prix passager", "Compensation conducteur", "Devise compensation", ) spreadsheet.SetHeaders(headers) // Add data rows for _, booking := range result.Bookings { driver := result.DriversMap[booking.Driver.Id] beneficiary := result.BeneficiariesMap[booking.Passenger.Id] row := []interface{}{} // Booking information row = append(row, booking.Id) row = append(row, booking.Status.String()) // Motivation motivation := "" if booking.Motivation != nil { motivation = *booking.Motivation } row = append(row, motivation) // Journey date and time row = append(row, booking.PassengerPickupDate.AsTime().Format("2006-01-02")) row = append(row, booking.PassengerPickupDate.AsTime().Format("15:04")) // Driver data for _, field := range driverFields { row = append(row, getAccountFieldValue(driver.Data, field)) } // Beneficiary data for _, field := range beneficiaryFields { row = append(row, getAccountFieldValue(beneficiary.Data, field)) } // Journey information if booking.PassengerPickupAddress != nil { row = append(row, *booking.PassengerPickupAddress) } else { row = append(row, "") } if booking.PassengerDropAddress != nil { row = append(row, *booking.PassengerDropAddress) } else { row = append(row, "") } // Distance if booking.Distance != nil { row = append(row, *booking.Distance) } else { row = append(row, "") } // Duration if booking.Duration != nil { row = append(row, *booking.Duration) } else { row = append(row, "") } // Pricing if booking.Price != nil && booking.Price.Amount != nil { row = append(row, fmt.Sprintf("%.2f", *booking.Price.Amount)) if booking.Price.Currency != nil { row = append(row, *booking.Price.Currency) } else { row = append(row, "") } } else { row = append(row, "", "") } // Driver compensation if booking.DriverCompensationAmount != nil { row = append(row, fmt.Sprintf("%.2f", *booking.DriverCompensationAmount)) if booking.DriverCompensationCurrency != nil { row = append(row, *booking.DriverCompensationCurrency) } else { row = append(row, "") } } else { row = append(row, "", "") } spreadsheet.AddRow(row) } // Write Excel to response w.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") w.Header().Set("Content-Disposition", "attachment; filename=\"export-covoiturage-solidaire.xlsx\"") if err := spreadsheet.GetFile().Write(w); err != nil { log.Error().Err(err).Msg("Error generating Excel file") http.Error(w, "Error generating Excel file", http.StatusInternalServerError) return } } func (r *XLSXRenderer) OrganizedCarpoolDrivers(w http.ResponseWriter, result *application.OrganizedCarpoolOverviewResult) { // Create Excel spreadsheet spreadsheet := r.NewSpreadsheet("Covoitureurs solidaires") // Build headers dynamically based on configuration driverOptionalFields := r.Config.Get("modules.organized_carpool.drivers.profile_optional_fields") driverFields := []string{"last_name", "first_name", "email", "phone_number", "birthdate", "gender", "file_number"} headers := []string{"ID", "Nom", "Prénom", "Email", "Téléphone", "Date de naissance", "Genre", "Numéro de dossier"} if driverOptionalFieldsList, ok := driverOptionalFields.([]interface{}); ok { for _, field := range driverOptionalFieldsList { if fieldMap, ok := field.(map[string]interface{}); ok { if name, ok := fieldMap["name"].(string); ok { driverFields = append(driverFields, name) label := name if labelVal, ok := fieldMap["label"].(string); ok { label = labelVal } headers = append(headers, label) } } } } // Add address columns headers = append(headers, "Adresse départ", "Adresse destination", "Archivé") spreadsheet.SetHeaders(headers) // Add data rows for _, driver := range result.Accounts { row := []interface{}{} // Driver ID row = append(row, driver.ID) // Driver data for _, field := range driverFields { value := getAccountFieldValue(driver.Data, field) // Convert gender code to text if field == "gender" && value != "" { value = gender.ISO5218ToString(value) } row = append(row, value) } // Address departure addressDeparture := "" if addr, ok := driver.Data["address"]; ok { if addrMap, ok := addr.(map[string]interface{}); ok { if props, ok := addrMap["properties"]; ok { if propsMap, ok := props.(map[string]interface{}); ok { if label, ok := propsMap["label"].(string); ok { addressDeparture = label } } } } } row = append(row, addressDeparture) // Address destination addressDestination := "" if addr, ok := driver.Data["address_destination"]; ok { if addrMap, ok := addr.(map[string]interface{}); ok { if props, ok := addrMap["properties"]; ok { if propsMap, ok := props.(map[string]interface{}); ok { if label, ok := propsMap["label"].(string); ok { addressDestination = label } } } } } row = append(row, addressDestination) // Archived status archived := "Non" if archivedVal, ok := driver.Data["archived"].(bool); ok && archivedVal { archived = "Oui" } row = append(row, archived) spreadsheet.AddRow(row) } // Write Excel to response w.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") w.Header().Set("Content-Disposition", "attachment; filename=\"export-covoitureurs-solidaires.xlsx\"") if err := spreadsheet.GetFile().Write(w); err != nil { log.Error().Err(err).Msg("Error generating Excel file") http.Error(w, "Error generating Excel file", http.StatusInternalServerError) return } }