409 lines
13 KiB
Go
409 lines
13 KiB
Go
package application
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/identification"
|
|
"git.coopgo.io/coopgo-platform/groups-management/storage"
|
|
"github.com/coreos/go-oidc/v3/oidc"
|
|
"github.com/gorilla/mux"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
func (h *Handler) VehiclesManagementOverviewHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
// Extract filter parameters from request
|
|
groupID := ""
|
|
if g := r.Context().Value(identification.GroupKey); g != nil {
|
|
group := g.(storage.Group)
|
|
groupID = group.ID
|
|
}
|
|
|
|
result, err := h.applicationHandler.GetVehiclesManagementOverview(r.Context(), groupID)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error retrieving vehicles management overview")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
h.renderer.VehiclesManagementOverview(w, r, result.Vehicles, result.VehiclesMap, result.DriversMap, result.Bookings)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) VehiclesManagementBookingsListHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
// Extract filter parameters from request
|
|
groupID := ""
|
|
if g := r.Context().Value(identification.GroupKey); g != nil {
|
|
group := g.(storage.Group)
|
|
groupID = group.ID
|
|
}
|
|
|
|
// Extract filter parameters from query
|
|
status := r.URL.Query().Get("status")
|
|
dateStart := r.URL.Query().Get("date_start")
|
|
dateEnd := r.URL.Query().Get("date_end")
|
|
|
|
// Default to last month if no dates specified
|
|
if dateStart == "" {
|
|
dateStart = time.Now().AddDate(0, -1, 0).Format("2006-01-02")
|
|
}
|
|
if dateEnd == "" {
|
|
dateEnd = time.Now().Format("2006-01-02")
|
|
}
|
|
|
|
result, err := h.applicationHandler.GetVehiclesManagementBookingsList(r.Context(), groupID, status, dateStart, dateEnd)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error retrieving vehicles management bookings list")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Prepare filters map for template
|
|
filters := map[string]string{
|
|
"status": status,
|
|
"date_start": dateStart,
|
|
"date_end": dateEnd,
|
|
}
|
|
|
|
h.renderer.VehiclesManagementBookingsList(w, r, result.VehiclesMap, result.DriversMap, result.Bookings, result.CacheID, filters)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) VehiclesFleetAddHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == "POST" {
|
|
// Get group from context
|
|
g := r.Context().Value(identification.GroupKey)
|
|
if g == nil {
|
|
http.Error(w, "Bad Request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Parse form data
|
|
if err := r.ParseForm(); err != nil {
|
|
log.Error().Err(err).Msg("error parsing form")
|
|
http.Error(w, "Bad Request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Parse address JSON
|
|
var address map[string]any
|
|
if addressStr := r.FormValue("address"); addressStr != "" {
|
|
if err := json.Unmarshal([]byte(addressStr), &address); err != nil {
|
|
log.Error().Err(err).Msg("error parsing address JSON")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
// Parse other_properties from form fields
|
|
otherProperties := make(map[string]any)
|
|
vehicleOptionalFields := h.cfg.Get("modules.fleets.vehicle_optional_fields")
|
|
log.Debug().Msgf("CREATE: vehicleOptionalFields type: %T, value: %+v", vehicleOptionalFields, vehicleOptionalFields)
|
|
if fields, ok := vehicleOptionalFields.([]map[string]any); ok {
|
|
log.Debug().Msgf("CREATE: Successfully cast to []map[string]any, length: %d", len(fields))
|
|
for _, field := range fields {
|
|
log.Debug().Any("field", field).Msg("vehicle other properties field handling")
|
|
if fieldName, ok := field["name"].(string); ok {
|
|
value := r.FormValue(fieldName)
|
|
log.Debug().Msgf("CREATE: Field %s: value='%s'", fieldName, value)
|
|
if value != "" {
|
|
otherProperties[fieldName] = value
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
log.Debug().Msg("CREATE: Failed to cast vehicleOptionalFields to []map[string]any")
|
|
}
|
|
log.Debug().Msgf("CREATE: Final otherProperties: %+v", otherProperties)
|
|
|
|
vehicleID, err := h.applicationHandler.CreateVehicle(r.Context(),
|
|
r.FormValue("name"),
|
|
r.FormValue("type"),
|
|
r.FormValue("informations"),
|
|
r.FormValue("licence_plate"),
|
|
r.FormValue("kilometers"),
|
|
r.FormValue("automatic") == "on",
|
|
address,
|
|
otherProperties,
|
|
)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error creating vehicle")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, fmt.Sprintf("/app/vehicles-management/fleet/%s", vehicleID), http.StatusFound)
|
|
return
|
|
}
|
|
|
|
// GET request - show form
|
|
vehicleTypes, err := h.applicationHandler.GetVehicleTypes(r.Context())
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error getting vehicle types")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
h.renderer.VehiclesFleetAdd(w, r, vehicleTypes)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) VehiclesFleetDisplayHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
vehicleID := vars["vehicleid"]
|
|
|
|
result, err := h.applicationHandler.GetVehicleDisplay(r.Context(), vehicleID)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error retrieving vehicle display")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
h.renderer.VehiclesFleetDisplay(w, r, result.Vehicle, result.Beneficiaries)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) VehicleManagementBookingDisplayHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
bookingID := vars["bookingid"]
|
|
|
|
if r.Method == "POST" {
|
|
// Parse form data
|
|
r.ParseForm()
|
|
|
|
err := h.applicationHandler.UpdateBooking(r.Context(), bookingID,
|
|
r.FormValue("startdate"),
|
|
r.FormValue("enddate"),
|
|
r.FormValue("unavailablefrom"),
|
|
r.FormValue("unavailableto"),
|
|
)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error updating booking")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
result, err := h.applicationHandler.GetBookingDisplay(r.Context(), bookingID)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error retrieving booking display")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
h.renderer.VehicleManagementBookingDisplay(w, r, result.Booking, result.Vehicle, result.Beneficiary, result.Group, result.Documents, result.FileTypesMap, result.Alternatives)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) VehicleManagementBookingChangeVehicleHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
bookingID := vars["bookingid"]
|
|
|
|
r.ParseForm()
|
|
newVehicle := r.FormValue("vehicle")
|
|
|
|
err := h.applicationHandler.ChangeBookingVehicle(r.Context(), bookingID, newVehicle)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error changing booking vehicle")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, fmt.Sprintf("/app/vehicles-management/bookings/%s", bookingID), http.StatusFound)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) VehiclesFleetMakeUnavailableHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
// Get context values
|
|
g := r.Context().Value(identification.GroupKey)
|
|
if g == nil {
|
|
log.Error().Msg("no current group")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
u := r.Context().Value(identification.IdtokenKey)
|
|
if u == nil {
|
|
log.Error().Msg("no current user")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
currentUserToken := u.(*oidc.IDToken)
|
|
|
|
c := r.Context().Value(identification.ClaimsKey)
|
|
if c == nil {
|
|
log.Error().Msg("no current user claims")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
currentUserClaims := c.(map[string]any)
|
|
|
|
vars := mux.Vars(r)
|
|
vehicleID := vars["vehicleid"]
|
|
|
|
r.ParseForm()
|
|
|
|
err := h.applicationHandler.MakeVehicleUnavailable(r.Context(), vehicleID,
|
|
r.FormValue("unavailablefrom"),
|
|
r.FormValue("unavailableto"),
|
|
r.FormValue("comment"),
|
|
currentUserToken.Subject,
|
|
currentUserClaims,
|
|
)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error making vehicle unavailable")
|
|
http.Error(w, "Bad Request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, fmt.Sprintf("/app/vehicles-management/fleet/%s", vehicleID), http.StatusFound)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) DeleteBookingHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
bookingID := vars["bookingid"]
|
|
|
|
// Get form data
|
|
motif := r.FormValue("motif")
|
|
|
|
// Get current user information
|
|
currentUserToken := r.Context().Value(identification.IdtokenKey).(*oidc.IDToken)
|
|
currentUserClaims := r.Context().Value(identification.ClaimsKey).(map[string]any)
|
|
currentGroup := r.Context().Value(identification.GroupKey)
|
|
|
|
err := h.applicationHandler.UnbookVehicle(r.Context(), bookingID, motif, currentUserToken.Subject, currentUserClaims, currentGroup)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error unbooking vehicle")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, "/app/vehicles-management/bookings/", http.StatusSeeOther)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) UnbookingVehicleHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
bookingID := vars["bookingid"]
|
|
|
|
if r.Method == "POST" {
|
|
// Extract user and group info from context
|
|
currentUserToken := r.Context().Value(identification.IdtokenKey).(*oidc.IDToken)
|
|
currentUserClaims := r.Context().Value(identification.ClaimsKey).(map[string]any)
|
|
currentGroup := r.Context().Value(identification.GroupKey)
|
|
|
|
motif := r.FormValue("motif")
|
|
|
|
err := h.applicationHandler.UnbookVehicle(r.Context(), bookingID, motif,
|
|
currentUserToken.Subject, currentUserClaims, currentGroup)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error unbooking vehicle")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, "/app/vehicles-management/", http.StatusFound)
|
|
return
|
|
}
|
|
|
|
// GET request - show form
|
|
booking, err := h.applicationHandler.GetBookingForUnbooking(r.Context(), bookingID)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error retrieving booking for unbooking")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
h.renderer.UnbookingVehicle(w, r, booking)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) VehiclesFleetUpdateHTTPHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
vehicleID := vars["vehicleid"]
|
|
|
|
if r.Method == "POST" {
|
|
if err := r.ParseForm(); err != nil {
|
|
log.Error().Err(err).Msg("error parsing form")
|
|
http.Error(w, "Bad Request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Parse address JSON
|
|
var address map[string]any
|
|
if addressStr := r.FormValue("address"); addressStr != "" {
|
|
if err := json.Unmarshal([]byte(addressStr), &address); err != nil {
|
|
log.Error().Err(err).Msg("error parsing address JSON")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
// Parse other_properties from form fields
|
|
otherProperties := make(map[string]any)
|
|
vehicleOptionalFields := h.cfg.Get("modules.fleets.vehicle_optional_fields")
|
|
log.Debug().Msgf("UPDATE: vehicleOptionalFields type: %T, value: %+v", vehicleOptionalFields, vehicleOptionalFields)
|
|
if fields, ok := vehicleOptionalFields.([]any); ok {
|
|
log.Debug().Msgf("UPDATE: Successfully cast to []map[string]any, length: %d", len(fields))
|
|
for _, f := range fields {
|
|
if field, ok := f.(map[string]any); ok {
|
|
log.Debug().Any("field", field).Msg("vehicle other properties field handling (update)")
|
|
if fieldName, ok := field["name"].(string); ok {
|
|
value := r.FormValue(fieldName)
|
|
log.Debug().Msgf("UPDATE: Field %s: value='%s'", fieldName, value)
|
|
if value != "" {
|
|
otherProperties[fieldName] = value
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
log.Debug().Msg("UPDATE: Failed to cast vehicleOptionalFields to []map[string]any")
|
|
}
|
|
log.Debug().Msgf("UPDATE: Final otherProperties: %+v", otherProperties)
|
|
|
|
updatedVehicleID, err := h.applicationHandler.UpdateVehicle(r.Context(), vehicleID,
|
|
r.FormValue("name"),
|
|
r.FormValue("type"),
|
|
r.FormValue("informations"),
|
|
r.FormValue("licence_plate"),
|
|
r.FormValue("kilometers"),
|
|
r.FormValue("automatic") == "on",
|
|
address,
|
|
otherProperties,
|
|
)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error updating vehicle")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, fmt.Sprintf("/app/vehicles-management/fleet/%s", updatedVehicleID), http.StatusFound)
|
|
return
|
|
}
|
|
|
|
// GET request - show form
|
|
result, err := h.applicationHandler.GetVehicleForUpdate(r.Context(), vehicleID)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error retrieving vehicle for update")
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
h.renderer.VehiclesFleetUpdate(w, r, result.Vehicle, result.VehicleTypes)
|
|
}
|
|
}
|