package rmo import ( "fmt" "net/http" "time" "github.com/Gleipnir-Technology/bob" "github.com/Gleipnir-Technology/bob/dialect/psql" "github.com/Gleipnir-Technology/bob/dialect/psql/um" "github.com/Gleipnir-Technology/nidus-sync/config" "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/enums" "github.com/Gleipnir-Technology/nidus-sync/db/models" "github.com/Gleipnir-Technology/nidus-sync/html" "github.com/Gleipnir-Technology/nidus-sync/platform/report" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" "github.com/rs/zerolog/log" ) type ContentPool struct { District *ContentDistrict MapboxToken string URL ContentURL } func getWater(w http.ResponseWriter, r *http.Request) { html.RenderOrError( w, "rmo/water.html", ContentPool{ District: nil, MapboxToken: config.MapboxToken, URL: makeContentURL(nil), }, ) } func getWaterDistrict(w http.ResponseWriter, r *http.Request) { district, err := districtBySlug(r) if err != nil { respondError(w, "Failed to lookup organization", err, http.StatusBadRequest) return } html.RenderOrError( w, "rmo/water.html", ContentPool{ District: newContentDistrict(district), MapboxToken: config.MapboxToken, URL: makeContentURL(district), }, ) } func postWater(w http.ResponseWriter, r *http.Request) { err := r.ParseMultipartForm(32 << 10) // 32 MB buffer if err != nil { respondError(w, "Failed to parse form", err, http.StatusBadRequest) return } access_comments := r.FormValue("access-comments") access_dog := boolFromForm(r, "access-dog") access_fence := boolFromForm(r, "access-fence") access_gate := boolFromForm(r, "access-gate") access_locked := boolFromForm(r, "access-locked") access_other := boolFromForm(r, "access-other") address := r.FormValue("address") address_country := r.FormValue("address-country") address_postcode := r.FormValue("address-postcode") address_place := r.FormValue("address-place") address_region := r.FormValue("address-region") address_street := r.FormValue("address-street") comments := r.FormValue("comments") has_adult := boolFromForm(r, "has-adult") has_backyard_permission := boolFromForm(r, "backyard-permission") has_larvae := boolFromForm(r, "has-larvae") has_pupae := boolFromForm(r, "has-pupae") is_reporter_confidential := boolFromForm(r, "reporter-confidential") is_reporter_owner := boolFromForm(r, "property-ownership") owner_email := r.FormValue("owner-email") owner_name := r.FormValue("owner-name") owner_phone := r.FormValue("owner-phone") latlng, err := parseLatLng(r) if err != nil { respondError(w, "Failed to parse lat lng for pool report", err, http.StatusInternalServerError) return } geospatial, err := geospatialFromForm(r) if err != nil { respondError(w, "Failed to handle geospatial data", err, http.StatusInternalServerError) return } public_id, err := report.GenerateReportID() if err != nil { respondError(w, "Failed to create pool report public ID", err, http.StatusInternalServerError) return } ctx := r.Context() tx, err := db.PGInstance.BobDB.BeginTx(ctx, nil) if err != nil { respondError(w, "Failed to create transaction", err, http.StatusInternalServerError) return } defer tx.Rollback(ctx) uploads, err := extractImageUploads(r) if err != nil { respondError(w, "Failed to extract image uploads", err, http.StatusInternalServerError) return } images, err := saveImageUploads(r.Context(), tx, uploads) if err != nil { respondError(w, "Failed to save image uploads", err, http.StatusInternalServerError) return } var organization_id *int32 organization_id, err = matchDistrict(ctx, latlng.Longitude, latlng.Latitude, uploads) if err != nil { log.Warn().Err(err).Msg("Failed to match district") } setter := models.PublicreportPoolSetter{ AccessComments: omit.From(access_comments), AccessDog: omit.From(access_dog), AccessFence: omit.From(access_fence), AccessGate: omit.From(access_gate), AccessLocked: omit.From(access_locked), AccessOther: omit.From(access_other), Address: omit.From(address), AddressCountry: omit.From(address_country), AddressPostCode: omit.From(address_postcode), AddressPlace: omit.From(address_place), AddressStreet: omit.From(address_street), AddressRegion: omit.From(address_region), Comments: omit.From(comments), Created: omit.From(time.Now()), //H3cell: omitnull.From(geospatial.Cell.String()), HasAdult: omit.From(has_adult), HasBackyardPermission: omit.From(has_backyard_permission), HasLarvae: omit.From(has_larvae), HasPupae: omit.From(has_pupae), IsReporterConfidential: omit.From(is_reporter_confidential), IsReporterOwner: omit.From(is_reporter_owner), //Location: add later MapZoom: omit.From(latlng.MapZoom), OrganizationID: omitnull.FromPtr(organization_id), OwnerEmail: omit.From(owner_email), OwnerName: omit.From(owner_name), OwnerPhone: omit.From(owner_phone), PublicID: omit.From(public_id), ReporterEmail: omit.From(""), ReporterName: omit.From(""), ReporterPhone: omit.From(""), Status: omit.From(enums.PublicreportReportstatustypeReported), } pool, err := models.PublicreportPools.Insert(&setter).One(ctx, tx) if err != nil { respondError(w, "Failed to create database record", err, http.StatusInternalServerError) return } if geospatial.Populated { _, err = psql.Update( um.Table("publicreport.pool"), um.SetCol("h3cell").ToArg(geospatial.Cell), um.SetCol("location").To(geospatial.GeometryQuery), um.Where(psql.Quote("id").EQ(psql.Arg(pool.ID))), ).Exec(ctx, tx) if err != nil { respondError(w, "Failed to update publicreport.pool geospatial", err, http.StatusInternalServerError) return } } log.Info().Int32("id", pool.ID).Str("public_id", pool.PublicID).Msg("Created pool report") setters := make([]*models.PublicreportPoolImageSetter, 0) for _, image := range images { setters = append(setters, &models.PublicreportPoolImageSetter{ ImageID: omit.From(int32(image.ID)), PoolID: omit.From(int32(pool.ID)), }) } if len(setters) > 0 { _, err = models.PublicreportPoolImages.Insert(bob.ToMods(setters...)).Exec(r.Context(), tx) if err != nil { respondError(w, "Failed to save upload relationships", err, http.StatusInternalServerError) return } } tx.Commit(ctx) http.Redirect(w, r, fmt.Sprintf("/submit-complete?report=%s", public_id), http.StatusFound) } func postWaterDistrict(w http.ResponseWriter, r *http.Request) { }