evol: filter geography on beneficiaries
This commit is contained in:
@@ -31,6 +31,8 @@ import (
|
||||
solidaritytransformers "git.coopgo.io/coopgo-platform/solidarity-transport/servers/grpc/transformers"
|
||||
solidaritytypes "git.coopgo.io/coopgo-platform/solidarity-transport/types"
|
||||
"github.com/google/uuid"
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"github.com/rs/zerolog/log"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
@@ -41,12 +43,38 @@ type BeneficiariesResult struct {
|
||||
CacheID string
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetBeneficiaries(ctx context.Context, searchFilter string, archivedFilter bool) (*BeneficiariesResult, error) {
|
||||
func (h *ApplicationHandler) GetBeneficiaries(ctx context.Context, searchFilter string, archivedFilter bool, addressGeoLayer, addressGeoCode string) (*BeneficiariesResult, error) {
|
||||
accounts, err := h.getBeneficiariesWithFilters(ctx, searchFilter, archivedFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Apply address geography filtering
|
||||
if addressGeoLayer != "" && addressGeoCode != "" {
|
||||
addressPolygons, err := h.loadGeographyPolygon(addressGeoLayer, addressGeoCode)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("failed to load beneficiary address geography filter")
|
||||
} else {
|
||||
filtered := []mobilityaccountsstorage.Account{}
|
||||
for _, account := range accounts {
|
||||
if addr, ok := account.Data["address"]; ok {
|
||||
jsonAddr, err := json.Marshal(addr)
|
||||
if err == nil {
|
||||
addrGeojson, err := geojson.UnmarshalFeature(jsonAddr)
|
||||
if err == nil && addrGeojson.Geometry != nil {
|
||||
if point, ok := addrGeojson.Geometry.(orb.Point); ok {
|
||||
if isPointInGeographies(point, addressPolygons) {
|
||||
filtered = append(filtered, account)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
accounts = filtered
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(sorting.BeneficiariesByName(accounts))
|
||||
|
||||
cacheID := uuid.NewString()
|
||||
|
||||
@@ -30,15 +30,25 @@ func (s BeneficiariesListState) JSONWithLimits(a int, b int) template.JS {
|
||||
return s.JSON()
|
||||
}
|
||||
|
||||
func (renderer *Renderer) BeneficiariesList(w http.ResponseWriter, r *http.Request, accounts []mobilityaccountsstorage.Account, cacheid string, archived bool) {
|
||||
func (renderer *Renderer) BeneficiariesList(w http.ResponseWriter, r *http.Request, accounts []mobilityaccountsstorage.Account, cacheid string, archived bool, enrichedGeoFilters []map[string]string, selectedAddressGeo string) {
|
||||
files := renderer.ThemeConfig.GetStringSlice("views.beneficiaries.list.files")
|
||||
|
||||
geoFiltersEnabled := len(enrichedGeoFilters) > 0
|
||||
|
||||
state := NewState(r, renderer.ThemeConfig, beneficiariesMenu)
|
||||
state.ViewState = BeneficiariesListState{
|
||||
state.ViewState = map[string]any{
|
||||
"list": BeneficiariesListState{
|
||||
Count: len(accounts),
|
||||
CacheId: cacheid,
|
||||
Beneficiaries: accounts,
|
||||
Archived: archived,
|
||||
},
|
||||
"geography_filters_enabled": geoFiltersEnabled,
|
||||
"geography_filters_list": enrichedGeoFilters,
|
||||
"archived": archived,
|
||||
"filters": map[string]any{
|
||||
"beneficiary_address_geo": selectedAddressGeo,
|
||||
},
|
||||
}
|
||||
|
||||
renderer.Render("beneficiaries_list", w, r, files, state)
|
||||
|
||||
@@ -5,7 +5,9 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
formvalidators "git.coopgo.io/coopgo-apps/parcoursmob/core/utils/form-validators"
|
||||
@@ -83,14 +85,64 @@ func (h *Handler) BeneficiariesListHTTPHandler() http.HandlerFunc {
|
||||
archivedFilter = true
|
||||
}
|
||||
|
||||
result, err := h.applicationHandler.GetBeneficiaries(r.Context(), searchFilter, archivedFilter)
|
||||
// Extract beneficiary address geography filter
|
||||
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(), searchFilter, archivedFilter, addressGeoLayer, addressGeoCode)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error retrieving beneficiaries")
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
h.renderer.BeneficiariesList(w, r, result.Accounts, result.CacheID, archivedFilter)
|
||||
// Enrich geography filters with names from geography service
|
||||
var enrichedGeoFilters []map[string]string
|
||||
if h.cfg.GetBool("geography.filters.enabled") {
|
||||
geoFilters := h.cfg.Get("geography.filters.geographies")
|
||||
if geoList, ok := geoFilters.([]any); ok {
|
||||
for _, geoItem := range geoList {
|
||||
if geoMap, ok := geoItem.(map[string]any); ok {
|
||||
layer := ""
|
||||
code := ""
|
||||
if l, ok := geoMap["layer"].(string); ok {
|
||||
layer = l
|
||||
}
|
||||
if c, ok := geoMap["code"].(string); ok {
|
||||
code = c
|
||||
}
|
||||
|
||||
enrichedGeo := map[string]string{
|
||||
"layer": layer,
|
||||
"code": code,
|
||||
"name": code,
|
||||
}
|
||||
|
||||
if layer != "" && code != "" {
|
||||
if geoFeature, err := h.services.Geography.Find(layer, code); err == nil {
|
||||
if name := geoFeature.Properties.MustString("nom"); name != "" {
|
||||
enrichedGeo["name"] = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enrichedGeoFilters = append(enrichedGeoFilters, enrichedGeo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(enrichedGeoFilters, func(i, j int) bool {
|
||||
return enrichedGeoFilters[i]["name"] < enrichedGeoFilters[j]["name"]
|
||||
})
|
||||
}
|
||||
|
||||
h.renderer.BeneficiariesList(w, r, result.Accounts, result.CacheID, archivedFilter, enrichedGeoFilters, beneficiaryAddressGeo)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user