Beneficiaries export as XLSX

This commit is contained in:
Arnaud Delcasse
2026-02-25 15:38:05 +01:00
parent 092d1acfbd
commit a60466d891
5 changed files with 168 additions and 2 deletions

View File

@@ -0,0 +1,63 @@
package exports
import (
"encoding/json"
"net/http"
"strings"
xlsxrenderer "git.coopgo.io/coopgo-apps/parcoursmob/renderer/xlsx"
"github.com/paulmach/orb/geojson"
"github.com/rs/zerolog/log"
)
func (h *Handler) Beneficiaries(w http.ResponseWriter, r *http.Request) {
archivedFilter := r.URL.Query().Get("archived") == "true"
beneficiaryAddressGeo := r.URL.Query().Get("beneficiary_address_geo")
addressGeoLayer, addressGeoCode := "", ""
if beneficiaryAddressGeo != "" {
parts := strings.SplitN(beneficiaryAddressGeo, ":", 2)
if len(parts) == 2 {
addressGeoLayer, addressGeoCode = parts[0], parts[1]
}
}
result, err := h.applicationHandler.GetBeneficiaries(r.Context(), "", archivedFilter, addressGeoLayer, addressGeoCode)
if err != nil {
log.Error().Err(err).Msg("Failed to get beneficiaries")
w.WriteHeader(http.StatusInternalServerError)
return
}
// Resolve geographic layers (EPCI, Département, Région) for each beneficiary
geoInfoMap := map[string]xlsxrenderer.BeneficiaryGeoInfo{}
for _, account := range result.Accounts {
if addr, ok := account.Data["address"]; ok {
jsonAddr, err := json.Marshal(addr)
if err == nil {
addrFeature, err := geojson.UnmarshalFeature(jsonAddr)
if err == nil && addrFeature.Geometry != nil {
geo, err := h.services.Geography.GeoSearch(addrFeature)
if err == nil {
info := xlsxrenderer.BeneficiaryGeoInfo{}
if commune, ok := geo["communes"]; ok {
info.Commune = commune.Properties.MustString("nom")
}
if epci, ok := geo["epci"]; ok {
info.EPCI = epci.Properties.MustString("nom")
}
if dept, ok := geo["departements"]; ok {
info.Departement = dept.Properties.MustString("nom")
}
if region, ok := geo["regions"]; ok {
info.Region = region.Properties.MustString("nom")
}
geoInfoMap[account.ID] = info
}
}
}
}
}
h.renderer.XLSX.Beneficiaries(w, result.Accounts, geoInfoMap)
}

View File

@@ -6,6 +6,7 @@ import (
"git.coopgo.io/coopgo-apps/parcoursmob/core/application"
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/identification"
"git.coopgo.io/coopgo-apps/parcoursmob/renderer"
"git.coopgo.io/coopgo-apps/parcoursmob/services"
"github.com/spf13/viper"
)
@@ -14,14 +15,16 @@ type Handler struct {
applicationHandler *application.ApplicationHandler
idp *identification.IdentificationProvider
renderer *renderer.Renderer
services *services.ServicesHandler
}
func NewHandler(cfg *viper.Viper, applicationHandler *application.ApplicationHandler, idp *identification.IdentificationProvider, renderer *renderer.Renderer) *Handler {
func NewHandler(cfg *viper.Viper, applicationHandler *application.ApplicationHandler, idp *identification.IdentificationProvider, renderer *renderer.Renderer, services *services.ServicesHandler) *Handler {
return &Handler{
config: cfg,
applicationHandler: applicationHandler,
idp: idp,
renderer: renderer,
services: services,
}
}

View File

@@ -14,6 +14,7 @@ func (ws *WebServer) setupExportsRoutes(r *mux.Router) {
export.HandleFunc("/solidarity-transport/drivers.xlsx", ws.exportsHandler.SolidarityTransportDrivers)
export.HandleFunc("/organized-carpool/bookings.xlsx", ws.exportsHandler.OrganizedCarpoolBookings)
export.HandleFunc("/organized-carpool/drivers.xlsx", ws.exportsHandler.OrganizedCarpoolDrivers)
export.HandleFunc("/beneficiaries/beneficiaries.xlsx", ws.exportsHandler.Beneficiaries)
export.Use(ws.idp.Middleware)
export.Use(ws.idp.GroupsMiddleware)
}

View File

@@ -58,7 +58,7 @@ func Run(cfg *viper.Viper, services *services.ServicesHandler, renderer *rendere
// Initialize web handler subpackages
appHandler: webapplication.NewHandler(cfg, renderer, applicationHandler, idp, services),
authHandler: webauth.NewHandler(cfg, applicationHandler, idp, renderer),
exportsHandler: webexports.NewHandler(cfg, applicationHandler, idp, renderer),
exportsHandler: webexports.NewHandler(cfg, applicationHandler, idp, renderer, services),
extHandler: webexternal.NewHandler(cfg, applicationHandler, filestorage),
protectedAPIHandler: webprotectedapi.NewHandler(cfg, applicationHandler),
webAPIHandler: webapi.NewHandler(cfg, idp, applicationHandler, cacheHandler),