351 lines
10 KiB
Go
351 lines
10 KiB
Go
package xlsx
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
fleetsstorage "git.coopgo.io/coopgo-platform/fleets/storage"
|
|
groupsstorage "git.coopgo.io/coopgo-platform/groups-management/storage"
|
|
mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
func (r *XLSXRenderer) VehicleBookings(w http.ResponseWriter, bookings []fleetsstorage.Booking, vehiclesMap map[string]fleetsstorage.Vehicle, driversMap map[string]mobilityaccountsstorage.Account) {
|
|
// Create Excel spreadsheet
|
|
spreadsheet := r.NewSpreadsheet("Réservations véhicules")
|
|
|
|
// Build headers
|
|
headers := []string{
|
|
"ID Réservation",
|
|
"Statut",
|
|
"Type de véhicule",
|
|
"Nom du véhicule",
|
|
"Immatriculation",
|
|
}
|
|
|
|
// 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 booking date headers
|
|
headers = append(headers,
|
|
"Date de début",
|
|
"Date de fin",
|
|
"Durée (jours)",
|
|
"Commentaire",
|
|
"Raison d'annulation",
|
|
)
|
|
|
|
spreadsheet.SetHeaders(headers)
|
|
|
|
// Add data rows
|
|
for _, booking := range bookings {
|
|
vehicle := vehiclesMap[booking.Vehicleid]
|
|
beneficiary := driversMap[booking.Driver]
|
|
|
|
row := []interface{}{}
|
|
|
|
// Booking information
|
|
row = append(row, booking.ID)
|
|
|
|
// Status
|
|
status := ""
|
|
if booking.Deleted {
|
|
status = "Annulé"
|
|
} else {
|
|
switch booking.Status() {
|
|
case 1:
|
|
status = "A venir"
|
|
case 0:
|
|
status = "En cours"
|
|
case -1:
|
|
status = "Terminé"
|
|
}
|
|
}
|
|
row = append(row, status)
|
|
|
|
// Vehicle information
|
|
row = append(row, vehicle.Type)
|
|
if vehicleName, ok := vehicle.Data["name"].(string); ok {
|
|
row = append(row, vehicleName)
|
|
} else {
|
|
row = append(row, "")
|
|
}
|
|
if licencePlate, ok := vehicle.Data["licence_plate"].(string); ok {
|
|
row = append(row, licencePlate)
|
|
} else {
|
|
row = append(row, "")
|
|
}
|
|
|
|
// Beneficiary data (including other_properties)
|
|
for _, field := range beneficiaryFields {
|
|
value := ""
|
|
// First check direct field
|
|
if val, ok := beneficiary.Data[field]; ok && val != nil {
|
|
value = fmt.Sprint(val)
|
|
} else {
|
|
// Check in other_properties
|
|
if otherProps, ok := beneficiary.Data["other_properties"]; ok {
|
|
if otherPropsMap, ok := otherProps.(map[string]interface{}); ok {
|
|
if val, ok := otherPropsMap[field]; ok && val != nil {
|
|
value = fmt.Sprint(val)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
row = append(row, value)
|
|
}
|
|
|
|
// Booking dates
|
|
row = append(row, booking.Startdate.Format("2006-01-02"))
|
|
row = append(row, booking.Enddate.Format("2006-01-02"))
|
|
|
|
// Duration in days
|
|
duration := booking.Enddate.Sub(booking.Startdate).Hours() / 24
|
|
row = append(row, fmt.Sprintf("%.0f", duration))
|
|
|
|
// Comment
|
|
comment := ""
|
|
if booking.Data != nil {
|
|
if commentVal, ok := booking.Data["comment"]; ok && commentVal != nil {
|
|
comment = fmt.Sprint(commentVal)
|
|
}
|
|
}
|
|
row = append(row, comment)
|
|
|
|
// Cancellation reason
|
|
cancellationReason := ""
|
|
if booking.Deleted && booking.Data != nil {
|
|
if reasonVal, ok := booking.Data["reason"]; ok && reasonVal != nil {
|
|
cancellationReason = fmt.Sprint(reasonVal)
|
|
}
|
|
}
|
|
row = append(row, cancellationReason)
|
|
|
|
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-reservations-vehicules.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) VehicleBookingsAdmin(w http.ResponseWriter, bookings []fleetsstorage.Booking, vehiclesMap map[string]interface{}, driversMap map[string]interface{}, groupsMap map[string]any) {
|
|
// Create Excel spreadsheet
|
|
spreadsheet := r.NewSpreadsheet("Réservations véhicules")
|
|
|
|
// Build headers
|
|
headers := []string{
|
|
"ID Réservation",
|
|
"Statut",
|
|
"Date de début",
|
|
"Date de fin",
|
|
"Durée (jours)",
|
|
"Commentaire",
|
|
"Raison d'annulation",
|
|
"Type de véhicule",
|
|
"Nom du véhicule",
|
|
"Immatriculation",
|
|
"Gestionnaire véhicule",
|
|
}
|
|
|
|
// Add vehicle optional fields from config
|
|
vehicleOptionalFields := r.Config.Get("modules.fleets.vehicle_optional_fields")
|
|
vehicleFields := []string{}
|
|
vehicleHeaders := []string{}
|
|
|
|
if vehicleOptionalFieldsList, ok := vehicleOptionalFields.([]interface{}); ok {
|
|
for _, field := range vehicleOptionalFieldsList {
|
|
if fieldMap, ok := field.(map[string]interface{}); ok {
|
|
if name, ok := fieldMap["name"].(string); ok {
|
|
vehicleFields = append(vehicleFields, name)
|
|
label := name
|
|
if labelVal, ok := fieldMap["label"].(string); ok {
|
|
label = labelVal
|
|
}
|
|
vehicleHeaders = append(vehicleHeaders, fmt.Sprintf("Véhicule - %s", label))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
headers = append(headers, vehicleHeaders...)
|
|
|
|
// 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...)
|
|
|
|
spreadsheet.SetHeaders(headers)
|
|
|
|
// Add data rows
|
|
for _, booking := range bookings {
|
|
// Get vehicle from map
|
|
var vehicle fleetsstorage.Vehicle
|
|
if v, ok := vehiclesMap[booking.Vehicleid]; ok {
|
|
if vTyped, ok := v.(fleetsstorage.Vehicle); ok {
|
|
vehicle = vTyped
|
|
}
|
|
}
|
|
|
|
// Get beneficiary from map
|
|
var beneficiary mobilityaccountsstorage.Account
|
|
if d, ok := driversMap[booking.Driver]; ok {
|
|
if dTyped, ok := d.(mobilityaccountsstorage.Account); ok {
|
|
beneficiary = dTyped
|
|
}
|
|
}
|
|
|
|
row := []interface{}{}
|
|
|
|
// Booking information
|
|
row = append(row, booking.ID)
|
|
|
|
// Status
|
|
status := ""
|
|
if booking.Deleted {
|
|
status = "Annulé"
|
|
} else {
|
|
switch booking.Status() {
|
|
case 1:
|
|
status = "A venir"
|
|
case 0:
|
|
status = "En cours"
|
|
case -1:
|
|
status = "Terminé"
|
|
}
|
|
}
|
|
row = append(row, status)
|
|
|
|
// Booking dates
|
|
row = append(row, booking.Startdate.Format("2006-01-02"))
|
|
row = append(row, booking.Enddate.Format("2006-01-02"))
|
|
|
|
// Duration in days
|
|
duration := booking.Enddate.Sub(booking.Startdate).Hours() / 24
|
|
row = append(row, fmt.Sprintf("%.0f", duration))
|
|
|
|
// Comment
|
|
comment := ""
|
|
if booking.Data != nil {
|
|
if commentVal, ok := booking.Data["comment"]; ok && commentVal != nil {
|
|
comment = fmt.Sprint(commentVal)
|
|
}
|
|
}
|
|
row = append(row, comment)
|
|
|
|
// Cancellation reason
|
|
cancellationReason := ""
|
|
if booking.Deleted && booking.Data != nil {
|
|
if reasonVal, ok := booking.Data["reason"]; ok && reasonVal != nil {
|
|
cancellationReason = fmt.Sprint(reasonVal)
|
|
}
|
|
}
|
|
row = append(row, cancellationReason)
|
|
|
|
// Vehicle information
|
|
row = append(row, vehicle.Type)
|
|
if vehicleName, ok := vehicle.Data["name"].(string); ok {
|
|
row = append(row, vehicleName)
|
|
} else {
|
|
row = append(row, "")
|
|
}
|
|
if licencePlate, ok := vehicle.Data["licence_plate"].(string); ok {
|
|
row = append(row, licencePlate)
|
|
} else {
|
|
row = append(row, "")
|
|
}
|
|
|
|
// Vehicle administrator (group name)
|
|
administratorName := ""
|
|
if len(vehicle.Administrators) > 0 {
|
|
if group, ok := groupsMap[vehicle.Administrators[0]]; ok {
|
|
if groupTyped, ok := group.(groupsstorage.Group); ok {
|
|
if name, ok := groupTyped.Data["name"]; ok {
|
|
administratorName = fmt.Sprint(name)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
row = append(row, administratorName)
|
|
|
|
// Vehicle optional fields
|
|
for _, field := range vehicleFields {
|
|
value := ""
|
|
if val, ok := vehicle.Data[field]; ok && val != nil {
|
|
value = fmt.Sprint(val)
|
|
}
|
|
row = append(row, value)
|
|
}
|
|
|
|
// Beneficiary data (including other_properties)
|
|
for _, field := range beneficiaryFields {
|
|
value := ""
|
|
// First check direct field
|
|
if val, ok := beneficiary.Data[field]; ok && val != nil {
|
|
value = fmt.Sprint(val)
|
|
} else {
|
|
// Check in other_properties
|
|
if otherProps, ok := beneficiary.Data["other_properties"]; ok {
|
|
if otherPropsMap, ok := otherProps.(map[string]interface{}); ok {
|
|
if val, ok := otherPropsMap[field]; ok && val != nil {
|
|
value = fmt.Sprint(val)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
row = append(row, value)
|
|
}
|
|
|
|
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=\"all_bookings.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
|
|
}
|
|
}
|