parcoursmob/handlers/application/vehicles.go

379 lines
10 KiB
Go

package application
import (
"context"
"fmt"
"io"
"net/http"
"sort"
"strings"
"time"
"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
"git.coopgo.io/coopgo-apps/parcoursmob/utils/sorting"
filestorage "git.coopgo.io/coopgo-apps/parcoursmob/utils/storage"
fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
"git.coopgo.io/coopgo-platform/fleets/storage"
groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
groupsmanagementstorage "git.coopgo.io/coopgo-platform/groups-management/storage"
mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage"
"github.com/google/uuid"
"github.com/gorilla/mux"
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb"
)
func (h ApplicationHandler) VehiclesSearch(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var beneficiary mobilityaccountsstorage.Account
beneficiarydocuments := []filestorage.FileInfo{}
vehicles := []any{}
searched := false
start := r.FormValue("startdate")
end := r.FormValue("enddate")
startdate, _ := time.Parse("2006-01-02", start)
enddate, _ := time.Parse("2006-01-02", end)
automatic := (r.FormValue("automatic") == "on")
administrators := []string{}
if r.FormValue("beneficiaryid") != "" {
// Handler form
searched = true
requestbeneficiary := &mobilityaccounts.GetAccountRequest{
Id: r.FormValue("beneficiaryid"),
}
respbeneficiary, err := h.services.GRPC.MobilityAccounts.GetAccount(context.TODO(), requestbeneficiary)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
beneficiary = respbeneficiary.Account.ToStorageType()
request := &fleets.GetVehiclesRequest{
Namespaces: []string{"parcoursmob"},
AvailabilityFrom: timestamppb.New(startdate),
AvailabilityTo: timestamppb.New(enddate),
}
if r.FormValue("type") != "" {
request.Types = []string{r.FormValue("type")}
}
resp, err := h.services.GRPC.Fleets.GetVehicles(context.TODO(), request)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
}
for _, vehicle := range resp.Vehicles {
v := vehicle.ToStorageType()
if r.FormValue("type") == "Voiture" && automatic {
fmt.Println(v.Data["automatic"])
if auto, ok := v.Data["automatic"].(bool); !ok || !auto {
fmt.Println(v.Data["automatic"])
continue
}
}
adminfound := false
for _, a := range administrators {
if a == v.Administrators[0] {
adminfound = true
break
}
}
if !adminfound {
administrators = append(administrators, v.Administrators[0])
}
vehicles = append(vehicles, v)
}
beneficiarydocuments = h.filestorage.List(filestorage.PREFIX_BENEFICIARIES + "/" + beneficiary.ID)
}
accounts, err := h.beneficiaries(r)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
groups := map[string]any{}
if len(administrators) > 0 {
admingroups, err := h.services.GRPC.GroupsManagement.GetGroupsBatch(context.TODO(), &groupsmanagement.GetGroupsBatchRequest{
Groupids: administrators,
})
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
for _, g := range admingroups.Groups {
groups[g.Id] = g.ToStorageType()
}
}
sort.Sort(sorting.BeneficiariesByName(accounts))
mandatory_documents := h.config.GetStringSlice("modules.fleets.booking_documents.mandatory")
file_types_map := h.config.GetStringMapString("storage.files.file_types")
vehicles_types := h.config.GetStringSlice("modules.fleets.vehicle_types")
h.Renderer.VehiclesSearch(w, r, accounts, searched, vehicles, beneficiary, r.FormValue("startdate"), r.FormValue("enddate"), mandatory_documents, file_types_map, beneficiarydocuments, r.FormValue("type"), automatic, vehicles_types, groups)
}
func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) {
fmt.Println("Book")
current_group, err := h.currentGroup(r)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
current_user_token, current_user_claims, err := h.currentUser(r)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
vars := mux.Vars(r)
vehicleid := vars["vehicleid"]
beneficiaryid := vars["beneficiaryid"]
vehicle, err := h.services.GRPC.Fleets.GetVehicle(context.TODO(), &fleets.GetVehicleRequest{
Vehicleid: vehicleid,
})
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Vehicle not found"))
w.Write([]byte(err.Error()))
return
}
r.ParseMultipartForm(100 * 1024 * 1024)
start := r.FormValue("startdate")
end := r.FormValue("enddate")
startdate, _ := time.Parse("2006-01-02", start)
enddate, _ := time.Parse("2006-01-02", end)
data := map[string]any{
"booked_by": map[string]any{
"user": map[string]any{
"id": current_user_token.Subject,
"display_name": fmt.Sprintf("%s %s", current_user_claims["first_name"], current_user_claims["last_name"]),
},
"group": map[string]any{
"id": current_group.ID,
"name": current_group.Data["name"],
},
},
}
datapb, err := structpb.NewStruct(data)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
booking := &fleets.Booking{
Id: uuid.NewString(),
Vehicleid: vehicleid,
Driver: beneficiaryid,
Startdate: timestamppb.New(startdate),
Enddate: timestamppb.New(enddate),
Unavailablefrom: timestamppb.New(startdate),
Unavailableto: timestamppb.New(enddate.Add(72 * time.Hour)),
Data: datapb,
}
request := &fleets.CreateBookingRequest{
Booking: booking,
}
for _, v := range h.config.GetStringSlice("modules.fleets.booking_documents.mandatory") {
existing_file := r.FormValue("type-" + v)
if existing_file == "" {
file, header, err := r.FormFile("doc-" + v)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Document manquant : " + v))
return
}
defer file.Close()
fileid := uuid.NewString()
metadata := map[string]string{
"type": v,
"name": header.Filename,
}
if err := h.filestorage.Put(file, filestorage.PREFIX_BOOKINGS, fmt.Sprintf("%s/%s_%s", booking.Id, fileid, header.Filename), header.Size, metadata); err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
} else {
path := strings.Split(existing_file, "/")
if err := h.filestorage.Copy(existing_file, fmt.Sprintf("%s/%s/%s", filestorage.PREFIX_BOOKINGS, booking.Id, path[len(path)-1])); err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
}
_, err = h.services.GRPC.Fleets.CreateBooking(context.TODO(), request)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
//NOTIFY GROUP MEMBERS
members, _, err := h.groupmembers(vehicle.Vehicle.Administrators[0])
if err != nil {
fmt.Println(err)
} else {
for _, m := range members {
if email, ok := m.Data["email"].(string); ok {
h.emailing.Send("fleets.bookings.creation_admin_alert", email, map[string]string{
"bookingid": booking.Id,
})
}
}
}
http.Redirect(w, r, fmt.Sprintf("/app/vehicles/bookings/%s", booking.Id), http.StatusFound)
}
func (h ApplicationHandler) VehicleBookingDisplay(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bookingid := vars["bookingid"]
request := &fleets.GetBookingRequest{
Bookingid: bookingid,
}
resp, err := h.services.GRPC.Fleets.GetBooking(context.TODO(), request)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
booking := resp.Booking.ToStorageType()
beneficiaryrequest := &mobilityaccounts.GetAccountRequest{
Id: booking.Driver,
}
beneficiaryresp, err := h.services.GRPC.MobilityAccounts.GetAccount(context.TODO(), beneficiaryrequest)
if err != nil {
beneficiaryresp = &mobilityaccounts.GetAccountResponse{
Account: &mobilityaccounts.Account{},
}
}
grouprequest := &groupsmanagement.GetGroupRequest{
Id: booking.Vehicle.Administrators[0],
}
groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(context.TODO(), grouprequest)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
documents := h.filestorage.List(filestorage.PREFIX_BOOKINGS + "/" + bookingid)
file_types_map := h.config.GetStringMapString("storage.files.file_types")
h.Renderer.VehicleBookingDisplay(w, r, booking, booking.Vehicle, beneficiaryresp.Account.ToStorageType(), groupresp.Group.ToStorageType(), documents, file_types_map)
}
func (h ApplicationHandler) VehiclesBookingsList(w http.ResponseWriter, r *http.Request) {
g := r.Context().Value(identification.GroupKey)
if g == nil {
w.WriteHeader(http.StatusBadRequest)
return
}
group := g.(groupsmanagementstorage.Group)
request := &fleets.GetBookingsRequest{}
resp, err := h.services.GRPC.Fleets.GetBookings(context.TODO(), request)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusNotFound)
return
}
bookings := []storage.Booking{}
for _, b := range resp.Bookings {
booking := b.ToStorageType()
if b1, ok := booking.Data["booked_by"].(map[string]any); ok {
if b2, ok := b1["group"].(map[string]any); ok {
if b2["id"] == group.ID {
bookings = append(bookings, booking)
}
}
}
}
sort.Sort(sorting.BookingsByStartdate(bookings))
vehicles, _ := h.services.GetVehiclesMap()
groups, _ := h.services.GetGroupsMap()
h.Renderer.VehicleBookingsList(w, r, bookings, vehicles, groups)
}
func (h *ApplicationHandler) BookingDocumentDownload(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bookingid := vars["bookingid"]
document := vars["document"]
fmt.Println(fmt.Sprintf("%s/%s", bookingid, document))
file, info, err := h.filestorage.Get(filestorage.PREFIX_BOOKINGS, fmt.Sprintf("%s/%s", bookingid, document))
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", info.ContentType)
if _, err = io.Copy(w, file); err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
http.Redirect(w, r, fmt.Sprintf("/app/vehicles/bookings/%s", bookingid), http.StatusFound)
}