Properly record and display pool reports

This commit is contained in:
Eli Ribble 2026-02-05 21:43:29 +00:00
parent 47c3f7320c
commit 9328e7a2f8
No known key found for this signature in database
15 changed files with 895 additions and 446 deletions

View file

@ -197,7 +197,7 @@ var PublicreportPools = Table[
},
MapZoom: column{
Name: "map_zoom",
DBType: "double precision",
DBType: "real",
Default: "",
Comment: "",
Nullable: false,
@ -267,15 +267,6 @@ var PublicreportPools = Table[
Generated: false,
AutoIncr: false,
},
Subscribe: column{
Name: "subscribe",
DBType: "boolean",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Status: column{
Name: "status",
DBType: "publicreport.reportstatustype",
@ -294,6 +285,33 @@ var PublicreportPools = Table[
Generated: false,
AutoIncr: false,
},
HasBackyardPermission: column{
Name: "has_backyard_permission",
DBType: "boolean",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
IsReporterConfidential: column{
Name: "is_reporter_confidential",
DBType: "boolean",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
IsReporterOwner: column{
Name: "is_reporter_owner",
DBType: "boolean",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: publicreportPoolIndexes{
PoolPkey: index{
@ -387,14 +405,16 @@ type publicreportPoolColumns struct {
ReporterEmail column
ReporterName column
ReporterPhone column
Subscribe column
Status column
OrganizationID column
HasBackyardPermission column
IsReporterConfidential column
IsReporterOwner column
}
func (c publicreportPoolColumns) AsSlice() []column {
return []column{
c.ID, c.AccessComments, c.AccessGate, c.AccessFence, c.AccessLocked, c.AccessDog, c.AccessOther, c.Address, c.AddressCountry, c.AddressPostCode, c.AddressPlace, c.AddressStreet, c.AddressRegion, c.Comments, c.Created, c.H3cell, c.HasAdult, c.HasLarvae, c.HasPupae, c.Location, c.MapZoom, c.OwnerEmail, c.OwnerName, c.OwnerPhone, c.PublicID, c.ReporterEmail, c.ReporterName, c.ReporterPhone, c.Subscribe, c.Status, c.OrganizationID,
c.ID, c.AccessComments, c.AccessGate, c.AccessFence, c.AccessLocked, c.AccessDog, c.AccessOther, c.Address, c.AddressCountry, c.AddressPostCode, c.AddressPlace, c.AddressStreet, c.AddressRegion, c.Comments, c.Created, c.H3cell, c.HasAdult, c.HasLarvae, c.HasPupae, c.Location, c.MapZoom, c.OwnerEmail, c.OwnerName, c.OwnerPhone, c.PublicID, c.ReporterEmail, c.ReporterName, c.ReporterPhone, c.Status, c.OrganizationID, c.HasBackyardPermission, c.IsReporterConfidential, c.IsReporterOwner,
}
}

View file

@ -3050,7 +3050,7 @@ func (f *Factory) FromExistingPublicreportPool(m *models.PublicreportPool) *Publ
o.HasLarvae = func() bool { return m.HasLarvae }
o.HasPupae = func() bool { return m.HasPupae }
o.Location = func() null.Val[string] { return m.Location }
o.MapZoom = func() float64 { return m.MapZoom }
o.MapZoom = func() float32 { return m.MapZoom }
o.OwnerEmail = func() string { return m.OwnerEmail }
o.OwnerName = func() string { return m.OwnerName }
o.OwnerPhone = func() string { return m.OwnerPhone }
@ -3058,9 +3058,11 @@ func (f *Factory) FromExistingPublicreportPool(m *models.PublicreportPool) *Publ
o.ReporterEmail = func() string { return m.ReporterEmail }
o.ReporterName = func() string { return m.ReporterName }
o.ReporterPhone = func() string { return m.ReporterPhone }
o.Subscribe = func() bool { return m.Subscribe }
o.Status = func() enums.PublicreportReportstatustype { return m.Status }
o.OrganizationID = func() null.Val[int32] { return m.OrganizationID }
o.HasBackyardPermission = func() bool { return m.HasBackyardPermission }
o.IsReporterConfidential = func() bool { return m.IsReporterConfidential }
o.IsReporterOwner = func() bool { return m.IsReporterOwner }
ctx := context.Background()
if m.R.Organization != nil {

View file

@ -58,7 +58,7 @@ type PublicreportPoolTemplate struct {
HasLarvae func() bool
HasPupae func() bool
Location func() null.Val[string]
MapZoom func() float64
MapZoom func() float32
OwnerEmail func() string
OwnerName func() string
OwnerPhone func() string
@ -66,9 +66,11 @@ type PublicreportPoolTemplate struct {
ReporterEmail func() string
ReporterName func() string
ReporterPhone func() string
Subscribe func() bool
Status func() enums.PublicreportReportstatustype
OrganizationID func() null.Val[int32]
HasBackyardPermission func() bool
IsReporterConfidential func() bool
IsReporterOwner func() bool
r publicreportPoolR
f *Factory
@ -236,10 +238,6 @@ func (o PublicreportPoolTemplate) BuildSetter() *models.PublicreportPoolSetter {
val := o.ReporterPhone()
m.ReporterPhone = omit.From(val)
}
if o.Subscribe != nil {
val := o.Subscribe()
m.Subscribe = omit.From(val)
}
if o.Status != nil {
val := o.Status()
m.Status = omit.From(val)
@ -248,6 +246,18 @@ func (o PublicreportPoolTemplate) BuildSetter() *models.PublicreportPoolSetter {
val := o.OrganizationID()
m.OrganizationID = omitnull.FromNull(val)
}
if o.HasBackyardPermission != nil {
val := o.HasBackyardPermission()
m.HasBackyardPermission = omit.From(val)
}
if o.IsReporterConfidential != nil {
val := o.IsReporterConfidential()
m.IsReporterConfidential = omit.From(val)
}
if o.IsReporterOwner != nil {
val := o.IsReporterOwner()
m.IsReporterOwner = omit.From(val)
}
return m
}
@ -354,15 +364,21 @@ func (o PublicreportPoolTemplate) Build() *models.PublicreportPool {
if o.ReporterPhone != nil {
m.ReporterPhone = o.ReporterPhone()
}
if o.Subscribe != nil {
m.Subscribe = o.Subscribe()
}
if o.Status != nil {
m.Status = o.Status()
}
if o.OrganizationID != nil {
m.OrganizationID = o.OrganizationID()
}
if o.HasBackyardPermission != nil {
m.HasBackyardPermission = o.HasBackyardPermission()
}
if o.IsReporterConfidential != nil {
m.IsReporterConfidential = o.IsReporterConfidential()
}
if o.IsReporterOwner != nil {
m.IsReporterOwner = o.IsReporterOwner()
}
o.setModelRels(m)
@ -452,7 +468,7 @@ func ensureCreatablePublicreportPool(m *models.PublicreportPoolSetter) {
m.HasPupae = omit.From(val)
}
if !(m.MapZoom.IsValue()) {
val := random_float64(nil)
val := random_float32(nil)
m.MapZoom = omit.From(val)
}
if !(m.OwnerEmail.IsValue()) {
@ -483,14 +499,22 @@ func ensureCreatablePublicreportPool(m *models.PublicreportPoolSetter) {
val := random_string(nil)
m.ReporterPhone = omit.From(val)
}
if !(m.Subscribe.IsValue()) {
val := random_bool(nil)
m.Subscribe = omit.From(val)
}
if !(m.Status.IsValue()) {
val := random_enums_PublicreportReportstatustype(nil)
m.Status = omit.From(val)
}
if !(m.HasBackyardPermission.IsValue()) {
val := random_bool(nil)
m.HasBackyardPermission = omit.From(val)
}
if !(m.IsReporterConfidential.IsValue()) {
val := random_bool(nil)
m.IsReporterConfidential = omit.From(val)
}
if !(m.IsReporterOwner.IsValue()) {
val := random_bool(nil)
m.IsReporterOwner = omit.From(val)
}
}
// insertOptRels creates and inserts any optional the relationships on *models.PublicreportPool
@ -658,9 +682,11 @@ func (m publicreportPoolMods) RandomizeAllColumns(f *faker.Faker) PublicreportPo
PublicreportPoolMods.RandomReporterEmail(f),
PublicreportPoolMods.RandomReporterName(f),
PublicreportPoolMods.RandomReporterPhone(f),
PublicreportPoolMods.RandomSubscribe(f),
PublicreportPoolMods.RandomStatus(f),
PublicreportPoolMods.RandomOrganizationID(f),
PublicreportPoolMods.RandomHasBackyardPermission(f),
PublicreportPoolMods.RandomIsReporterConfidential(f),
PublicreportPoolMods.RandomIsReporterOwner(f),
}
}
@ -1329,14 +1355,14 @@ func (m publicreportPoolMods) RandomLocationNotNull(f *faker.Faker) Publicreport
}
// Set the model columns to this value
func (m publicreportPoolMods) MapZoom(val float64) PublicreportPoolMod {
func (m publicreportPoolMods) MapZoom(val float32) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.MapZoom = func() float64 { return val }
o.MapZoom = func() float32 { return val }
})
}
// Set the Column from the function
func (m publicreportPoolMods) MapZoomFunc(f func() float64) PublicreportPoolMod {
func (m publicreportPoolMods) MapZoomFunc(f func() float32) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.MapZoom = f
})
@ -1353,8 +1379,8 @@ func (m publicreportPoolMods) UnsetMapZoom() PublicreportPoolMod {
// if faker is nil, a default faker is used
func (m publicreportPoolMods) RandomMapZoom(f *faker.Faker) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.MapZoom = func() float64 {
return random_float64(f)
o.MapZoom = func() float32 {
return random_float32(f)
}
})
}
@ -1576,37 +1602,6 @@ func (m publicreportPoolMods) RandomReporterPhone(f *faker.Faker) PublicreportPo
})
}
// Set the model columns to this value
func (m publicreportPoolMods) Subscribe(val bool) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.Subscribe = func() bool { return val }
})
}
// Set the Column from the function
func (m publicreportPoolMods) SubscribeFunc(f func() bool) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.Subscribe = f
})
}
// Clear any values for the column
func (m publicreportPoolMods) UnsetSubscribe() PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.Subscribe = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m publicreportPoolMods) RandomSubscribe(f *faker.Faker) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.Subscribe = func() bool {
return random_bool(f)
}
})
}
// Set the model columns to this value
func (m publicreportPoolMods) Status(val enums.PublicreportReportstatustype) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
@ -1691,6 +1686,99 @@ func (m publicreportPoolMods) RandomOrganizationIDNotNull(f *faker.Faker) Public
})
}
// Set the model columns to this value
func (m publicreportPoolMods) HasBackyardPermission(val bool) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.HasBackyardPermission = func() bool { return val }
})
}
// Set the Column from the function
func (m publicreportPoolMods) HasBackyardPermissionFunc(f func() bool) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.HasBackyardPermission = f
})
}
// Clear any values for the column
func (m publicreportPoolMods) UnsetHasBackyardPermission() PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.HasBackyardPermission = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m publicreportPoolMods) RandomHasBackyardPermission(f *faker.Faker) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.HasBackyardPermission = func() bool {
return random_bool(f)
}
})
}
// Set the model columns to this value
func (m publicreportPoolMods) IsReporterConfidential(val bool) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.IsReporterConfidential = func() bool { return val }
})
}
// Set the Column from the function
func (m publicreportPoolMods) IsReporterConfidentialFunc(f func() bool) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.IsReporterConfidential = f
})
}
// Clear any values for the column
func (m publicreportPoolMods) UnsetIsReporterConfidential() PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.IsReporterConfidential = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m publicreportPoolMods) RandomIsReporterConfidential(f *faker.Faker) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.IsReporterConfidential = func() bool {
return random_bool(f)
}
})
}
// Set the model columns to this value
func (m publicreportPoolMods) IsReporterOwner(val bool) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.IsReporterOwner = func() bool { return val }
})
}
// Set the Column from the function
func (m publicreportPoolMods) IsReporterOwnerFunc(f func() bool) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.IsReporterOwner = f
})
}
// Clear any values for the column
func (m publicreportPoolMods) UnsetIsReporterOwner() PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.IsReporterOwner = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m publicreportPoolMods) RandomIsReporterOwner(f *faker.Faker) PublicreportPoolMod {
return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) {
o.IsReporterOwner = func() bool {
return random_bool(f)
}
})
}
func (m publicreportPoolMods) WithParentsCascading() PublicreportPoolMod {
return PublicreportPoolModFunc(func(ctx context.Context, o *PublicreportPoolTemplate) {
if isDone, _ := publicreportPoolWithParentsCascadingCtx.Value(ctx); isDone {

View file

@ -0,0 +1,24 @@
-- +goose Up
ALTER TABLE publicreport.pool ADD COLUMN has_backyard_permission BOOLEAN;
ALTER TABLE publicreport.pool ADD COLUMN is_reporter_confidential BOOLEAN;
ALTER TABLE publicreport.pool ADD COLUMN is_reporter_owner BOOLEAN;
UPDATE publicreport.pool SET has_backyard_permission=false;
UPDATE publicreport.pool SET is_reporter_confidential=false;
UPDATE publicreport.pool SET is_reporter_owner=false;
ALTER TABLE publicreport.pool ALTER COLUMN has_backyard_permission SET NOT NULL;
ALTER TABLE publicreport.pool ALTER COLUMN is_reporter_confidential SET NOT NULL;
ALTER TABLE publicreport.pool ALTER COLUMN is_reporter_owner SET NOT NULL;
ALTER TABLE publicreport.pool ALTER COLUMN map_zoom TYPE REAL;
ALTER TABLE publicreport.pool DROP COLUMN subscribe;
-- +goose Down
ALTER TABLE publicreport.pool ADD COLUMN subscribe BOOLEAN;
ALTER TABLE publicreport.pool ALTER COLUMN map_zoom TYPE FLOAT;
ALTER TABLE publicreport.pool DROP COLUMN has_backyard_permission;
ALTER TABLE publicreport.pool DROP COLUMN is_reporter_confidential;
ALTER TABLE publicreport.pool DROP COLUMN is_reporter_owner;

View file

@ -49,7 +49,7 @@ type PublicreportPool struct {
HasLarvae bool `db:"has_larvae" `
HasPupae bool `db:"has_pupae" `
Location null.Val[string] `db:"location" `
MapZoom float64 `db:"map_zoom" `
MapZoom float32 `db:"map_zoom" `
OwnerEmail string `db:"owner_email" `
OwnerName string `db:"owner_name" `
OwnerPhone string `db:"owner_phone" `
@ -57,9 +57,11 @@ type PublicreportPool struct {
ReporterEmail string `db:"reporter_email" `
ReporterName string `db:"reporter_name" `
ReporterPhone string `db:"reporter_phone" `
Subscribe bool `db:"subscribe" `
Status enums.PublicreportReportstatustype `db:"status" `
OrganizationID null.Val[int32] `db:"organization_id" `
HasBackyardPermission bool `db:"has_backyard_permission" `
IsReporterConfidential bool `db:"is_reporter_confidential" `
IsReporterOwner bool `db:"is_reporter_owner" `
R publicreportPoolR `db:"-" `
@ -85,7 +87,7 @@ type publicreportPoolR struct {
func buildPublicreportPoolColumns(alias string) publicreportPoolColumns {
return publicreportPoolColumns{
ColumnsExpr: expr.NewColumnsExpr(
"id", "access_comments", "access_gate", "access_fence", "access_locked", "access_dog", "access_other", "address", "address_country", "address_post_code", "address_place", "address_street", "address_region", "comments", "created", "h3cell", "has_adult", "has_larvae", "has_pupae", "location", "map_zoom", "owner_email", "owner_name", "owner_phone", "public_id", "reporter_email", "reporter_name", "reporter_phone", "subscribe", "status", "organization_id",
"id", "access_comments", "access_gate", "access_fence", "access_locked", "access_dog", "access_other", "address", "address_country", "address_post_code", "address_place", "address_street", "address_region", "comments", "created", "h3cell", "has_adult", "has_larvae", "has_pupae", "location", "map_zoom", "owner_email", "owner_name", "owner_phone", "public_id", "reporter_email", "reporter_name", "reporter_phone", "status", "organization_id", "has_backyard_permission", "is_reporter_confidential", "is_reporter_owner",
).WithParent("publicreport.pool"),
tableAlias: alias,
ID: psql.Quote(alias, "id"),
@ -116,9 +118,11 @@ func buildPublicreportPoolColumns(alias string) publicreportPoolColumns {
ReporterEmail: psql.Quote(alias, "reporter_email"),
ReporterName: psql.Quote(alias, "reporter_name"),
ReporterPhone: psql.Quote(alias, "reporter_phone"),
Subscribe: psql.Quote(alias, "subscribe"),
Status: psql.Quote(alias, "status"),
OrganizationID: psql.Quote(alias, "organization_id"),
HasBackyardPermission: psql.Quote(alias, "has_backyard_permission"),
IsReporterConfidential: psql.Quote(alias, "is_reporter_confidential"),
IsReporterOwner: psql.Quote(alias, "is_reporter_owner"),
}
}
@ -153,9 +157,11 @@ type publicreportPoolColumns struct {
ReporterEmail psql.Expression
ReporterName psql.Expression
ReporterPhone psql.Expression
Subscribe psql.Expression
Status psql.Expression
OrganizationID psql.Expression
HasBackyardPermission psql.Expression
IsReporterConfidential psql.Expression
IsReporterOwner psql.Expression
}
func (c publicreportPoolColumns) Alias() string {
@ -190,7 +196,7 @@ type PublicreportPoolSetter struct {
HasLarvae omit.Val[bool] `db:"has_larvae" `
HasPupae omit.Val[bool] `db:"has_pupae" `
Location omitnull.Val[string] `db:"location" `
MapZoom omit.Val[float64] `db:"map_zoom" `
MapZoom omit.Val[float32] `db:"map_zoom" `
OwnerEmail omit.Val[string] `db:"owner_email" `
OwnerName omit.Val[string] `db:"owner_name" `
OwnerPhone omit.Val[string] `db:"owner_phone" `
@ -198,13 +204,15 @@ type PublicreportPoolSetter struct {
ReporterEmail omit.Val[string] `db:"reporter_email" `
ReporterName omit.Val[string] `db:"reporter_name" `
ReporterPhone omit.Val[string] `db:"reporter_phone" `
Subscribe omit.Val[bool] `db:"subscribe" `
Status omit.Val[enums.PublicreportReportstatustype] `db:"status" `
OrganizationID omitnull.Val[int32] `db:"organization_id" `
HasBackyardPermission omit.Val[bool] `db:"has_backyard_permission" `
IsReporterConfidential omit.Val[bool] `db:"is_reporter_confidential" `
IsReporterOwner omit.Val[bool] `db:"is_reporter_owner" `
}
func (s PublicreportPoolSetter) SetColumns() []string {
vals := make([]string, 0, 31)
vals := make([]string, 0, 33)
if s.ID.IsValue() {
vals = append(vals, "id")
}
@ -289,15 +297,21 @@ func (s PublicreportPoolSetter) SetColumns() []string {
if s.ReporterPhone.IsValue() {
vals = append(vals, "reporter_phone")
}
if s.Subscribe.IsValue() {
vals = append(vals, "subscribe")
}
if s.Status.IsValue() {
vals = append(vals, "status")
}
if !s.OrganizationID.IsUnset() {
vals = append(vals, "organization_id")
}
if s.HasBackyardPermission.IsValue() {
vals = append(vals, "has_backyard_permission")
}
if s.IsReporterConfidential.IsValue() {
vals = append(vals, "is_reporter_confidential")
}
if s.IsReporterOwner.IsValue() {
vals = append(vals, "is_reporter_owner")
}
return vals
}
@ -386,15 +400,21 @@ func (s PublicreportPoolSetter) Overwrite(t *PublicreportPool) {
if s.ReporterPhone.IsValue() {
t.ReporterPhone = s.ReporterPhone.MustGet()
}
if s.Subscribe.IsValue() {
t.Subscribe = s.Subscribe.MustGet()
}
if s.Status.IsValue() {
t.Status = s.Status.MustGet()
}
if !s.OrganizationID.IsUnset() {
t.OrganizationID = s.OrganizationID.MustGetNull()
}
if s.HasBackyardPermission.IsValue() {
t.HasBackyardPermission = s.HasBackyardPermission.MustGet()
}
if s.IsReporterConfidential.IsValue() {
t.IsReporterConfidential = s.IsReporterConfidential.MustGet()
}
if s.IsReporterOwner.IsValue() {
t.IsReporterOwner = s.IsReporterOwner.MustGet()
}
}
func (s *PublicreportPoolSetter) Apply(q *dialect.InsertQuery) {
@ -403,7 +423,7 @@ func (s *PublicreportPoolSetter) Apply(q *dialect.InsertQuery) {
})
q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) {
vals := make([]bob.Expression, 31)
vals := make([]bob.Expression, 33)
if s.ID.IsValue() {
vals[0] = psql.Arg(s.ID.MustGet())
} else {
@ -572,24 +592,36 @@ func (s *PublicreportPoolSetter) Apply(q *dialect.InsertQuery) {
vals[27] = psql.Raw("DEFAULT")
}
if s.Subscribe.IsValue() {
vals[28] = psql.Arg(s.Subscribe.MustGet())
if s.Status.IsValue() {
vals[28] = psql.Arg(s.Status.MustGet())
} else {
vals[28] = psql.Raw("DEFAULT")
}
if s.Status.IsValue() {
vals[29] = psql.Arg(s.Status.MustGet())
if !s.OrganizationID.IsUnset() {
vals[29] = psql.Arg(s.OrganizationID.MustGetNull())
} else {
vals[29] = psql.Raw("DEFAULT")
}
if !s.OrganizationID.IsUnset() {
vals[30] = psql.Arg(s.OrganizationID.MustGetNull())
if s.HasBackyardPermission.IsValue() {
vals[30] = psql.Arg(s.HasBackyardPermission.MustGet())
} else {
vals[30] = psql.Raw("DEFAULT")
}
if s.IsReporterConfidential.IsValue() {
vals[31] = psql.Arg(s.IsReporterConfidential.MustGet())
} else {
vals[31] = psql.Raw("DEFAULT")
}
if s.IsReporterOwner.IsValue() {
vals[32] = psql.Arg(s.IsReporterOwner.MustGet())
} else {
vals[32] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
@ -599,7 +631,7 @@ func (s PublicreportPoolSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
}
func (s PublicreportPoolSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 31)
exprs := make([]bob.Expression, 0, 33)
if s.ID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
@ -797,13 +829,6 @@ func (s PublicreportPoolSetter) Expressions(prefix ...string) []bob.Expression {
}})
}
if s.Subscribe.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "subscribe")...),
psql.Arg(s.Subscribe),
}})
}
if s.Status.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "status")...),
@ -818,6 +843,27 @@ func (s PublicreportPoolSetter) Expressions(prefix ...string) []bob.Expression {
}})
}
if s.HasBackyardPermission.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "has_backyard_permission")...),
psql.Arg(s.HasBackyardPermission),
}})
}
if s.IsReporterConfidential.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "is_reporter_confidential")...),
psql.Arg(s.IsReporterConfidential),
}})
}
if s.IsReporterOwner.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "is_reporter_owner")...),
psql.Arg(s.IsReporterOwner),
}})
}
return exprs
}
@ -1231,7 +1277,7 @@ type publicreportPoolWhere[Q psql.Filterable] struct {
HasLarvae psql.WhereMod[Q, bool]
HasPupae psql.WhereMod[Q, bool]
Location psql.WhereNullMod[Q, string]
MapZoom psql.WhereMod[Q, float64]
MapZoom psql.WhereMod[Q, float32]
OwnerEmail psql.WhereMod[Q, string]
OwnerName psql.WhereMod[Q, string]
OwnerPhone psql.WhereMod[Q, string]
@ -1239,9 +1285,11 @@ type publicreportPoolWhere[Q psql.Filterable] struct {
ReporterEmail psql.WhereMod[Q, string]
ReporterName psql.WhereMod[Q, string]
ReporterPhone psql.WhereMod[Q, string]
Subscribe psql.WhereMod[Q, bool]
Status psql.WhereMod[Q, enums.PublicreportReportstatustype]
OrganizationID psql.WhereNullMod[Q, int32]
HasBackyardPermission psql.WhereMod[Q, bool]
IsReporterConfidential psql.WhereMod[Q, bool]
IsReporterOwner psql.WhereMod[Q, bool]
}
func (publicreportPoolWhere[Q]) AliasedAs(alias string) publicreportPoolWhere[Q] {
@ -1270,7 +1318,7 @@ func buildPublicreportPoolWhere[Q psql.Filterable](cols publicreportPoolColumns)
HasLarvae: psql.Where[Q, bool](cols.HasLarvae),
HasPupae: psql.Where[Q, bool](cols.HasPupae),
Location: psql.WhereNull[Q, string](cols.Location),
MapZoom: psql.Where[Q, float64](cols.MapZoom),
MapZoom: psql.Where[Q, float32](cols.MapZoom),
OwnerEmail: psql.Where[Q, string](cols.OwnerEmail),
OwnerName: psql.Where[Q, string](cols.OwnerName),
OwnerPhone: psql.Where[Q, string](cols.OwnerPhone),
@ -1278,9 +1326,11 @@ func buildPublicreportPoolWhere[Q psql.Filterable](cols publicreportPoolColumns)
ReporterEmail: psql.Where[Q, string](cols.ReporterEmail),
ReporterName: psql.Where[Q, string](cols.ReporterName),
ReporterPhone: psql.Where[Q, string](cols.ReporterPhone),
Subscribe: psql.Where[Q, bool](cols.Subscribe),
Status: psql.Where[Q, enums.PublicreportReportstatustype](cols.Status),
OrganizationID: psql.WhereNull[Q, int32](cols.OrganizationID),
HasBackyardPermission: psql.Where[Q, bool](cols.HasBackyardPermission),
IsReporterConfidential: psql.Where[Q, bool](cols.IsReporterConfidential),
IsReporterOwner: psql.Where[Q, bool](cols.IsReporterOwner),
}
}

View file

@ -4,7 +4,7 @@ SELECT
"publicreport.image"."content_type" AS "content_type",
"publicreport.image"."created" AS "created",
"publicreport.image"."location" AS "location",
ST_AsGeoJSON("publicreport.image"."location") AS "location_json",
COALESCE(ST_AsGeoJSON("publicreport.image"."location"), '{}') AS "location_json",
"publicreport.image"."resolution_x" AS "resolution_x",
"publicreport.image"."resolution_y" AS "resolution_y",
"publicreport.image"."storage_uuid" AS "storage_uuid",

View file

@ -0,0 +1,112 @@
// Code generated by BobGen psql v0.42.5. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package sql
import (
"context"
_ "embed"
"io"
"iter"
"time"
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/dialect"
"github.com/Gleipnir-Technology/bob/orm"
"github.com/aarondl/opt/null"
"github.com/google/uuid"
"github.com/stephenafamo/scan"
)
//go:embed publicreport_image_with_json_by_pool_id.bob.sql
var formattedQueries_publicreport_image_with_json_by_pool_id string
var publicreportImageWithJSONByPoolIDSQL = formattedQueries_publicreport_image_with_json_by_pool_id[171:975]
type PublicreportImageWithJSONByPoolIDQuery = orm.ModQuery[*dialect.SelectQuery, publicreportImageWithJSONByPoolID, PublicreportImageWithJSONByPoolIDRow, []PublicreportImageWithJSONByPoolIDRow, publicreportImageWithJSONByPoolIDTransformer]
func PublicreportImageWithJSONByPoolID(PoolID int32) *PublicreportImageWithJSONByPoolIDQuery {
var expressionTypArgs publicreportImageWithJSONByPoolID
expressionTypArgs.PoolID = psql.Arg(PoolID)
return &PublicreportImageWithJSONByPoolIDQuery{
Query: orm.Query[publicreportImageWithJSONByPoolID, PublicreportImageWithJSONByPoolIDRow, []PublicreportImageWithJSONByPoolIDRow, publicreportImageWithJSONByPoolIDTransformer]{
ExecQuery: orm.ExecQuery[publicreportImageWithJSONByPoolID]{
BaseQuery: bob.BaseQuery[publicreportImageWithJSONByPoolID]{
Expression: expressionTypArgs,
Dialect: dialect.Dialect,
QueryType: bob.QueryTypeSelect,
},
},
Scanner: func(context.Context, []string) (func(*scan.Row) (any, error), func(any) (PublicreportImageWithJSONByPoolIDRow, error)) {
return func(row *scan.Row) (any, error) {
var t PublicreportImageWithJSONByPoolIDRow
row.ScheduleScanByIndex(0, &t.ID)
row.ScheduleScanByIndex(1, &t.ContentType)
row.ScheduleScanByIndex(2, &t.Created)
row.ScheduleScanByIndex(3, &t.Location)
row.ScheduleScanByIndex(4, &t.LocationJSON)
row.ScheduleScanByIndex(5, &t.ResolutionX)
row.ScheduleScanByIndex(6, &t.ResolutionY)
row.ScheduleScanByIndex(7, &t.StorageUUID)
row.ScheduleScanByIndex(8, &t.StorageSize)
row.ScheduleScanByIndex(9, &t.UploadedFilename)
return &t, nil
}, func(v any) (PublicreportImageWithJSONByPoolIDRow, error) {
return *(v.(*PublicreportImageWithJSONByPoolIDRow)), nil
}
},
},
Mod: bob.ModFunc[*dialect.SelectQuery](func(q *dialect.SelectQuery) {
q.AppendSelect(expressionTypArgs.subExpr(9, 565))
q.SetTable(expressionTypArgs.subExpr(571, 755))
q.AppendWhere(expressionTypArgs.subExpr(763, 803))
}),
}
}
type PublicreportImageWithJSONByPoolIDRow = struct {
ID int32 `db:"id"`
ContentType string `db:"content_type"`
Created time.Time `db:"created"`
Location null.Val[string] `db:"location"`
LocationJSON string `db:"location_json"`
ResolutionX int32 `db:"resolution_x"`
ResolutionY int32 `db:"resolution_y"`
StorageUUID uuid.UUID `db:"storage_uuid"`
StorageSize int64 `db:"storage_size"`
UploadedFilename string `db:"uploaded_filename"`
}
type publicreportImageWithJSONByPoolIDTransformer = bob.SliceTransformer[PublicreportImageWithJSONByPoolIDRow, []PublicreportImageWithJSONByPoolIDRow]
type publicreportImageWithJSONByPoolID struct {
PoolID bob.Expression
}
func (o publicreportImageWithJSONByPoolID) args() iter.Seq[orm.ArgWithPosition] {
return func(yield func(arg orm.ArgWithPosition) bool) {
if !yield(orm.ArgWithPosition{
Name: "poolID",
Start: 801,
Stop: 803,
Expression: o.PoolID,
}) {
return
}
}
}
func (o publicreportImageWithJSONByPoolID) raw(from, to int) string {
return publicreportImageWithJSONByPoolIDSQL[from:to]
}
func (o publicreportImageWithJSONByPoolID) subExpr(from, to int) bob.Expression {
return orm.ArgsToExpression(publicreportImageWithJSONByPoolIDSQL, from, to, o.args())
}
func (o publicreportImageWithJSONByPoolID) WriteSQL(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) {
return o.subExpr(0, len(publicreportImageWithJSONByPoolIDSQL)).WriteSQL(ctx, w, d, start)
}

View file

@ -0,0 +1,18 @@
-- Code generated by BobGen psql v0.42.5. DO NOT EDIT.
-- This file is meant to be re-generated in place and/or deleted at any time.
-- PublicreportImageWithJSONByPoolID
SELECT
"publicreport.image"."id" AS "id",
"publicreport.image"."content_type" AS "content_type",
"publicreport.image"."created" AS "created",
"publicreport.image"."location" AS "location",
COALESCE(ST_AsGeoJSON("publicreport.image"."location"), '{}') AS "location_json",
"publicreport.image"."resolution_x" AS "resolution_x",
"publicreport.image"."resolution_y" AS "resolution_y",
"publicreport.image"."storage_uuid" AS "storage_uuid",
"publicreport.image"."storage_size" AS "storage_size",
"publicreport.image"."uploaded_filename" AS "uploaded_filename"
FROM "publicreport"."image" AS "publicreport.image"
INNER JOIN "publicreport"."pool_image" AS "publicreport.pool_image" ON ("publicreport.image"."id" = "publicreport.pool_image"."image_id")
WHERE ("publicreport.pool_image"."pool_id" = $1);

View file

@ -0,0 +1,15 @@
-- PublicreportImageWithJSONByPoolID
SELECT
"publicreport.image"."id" AS "id",
"publicreport.image"."content_type" AS "content_type",
"publicreport.image"."created" AS "created",
"publicreport.image"."location" AS "location",
COALESCE(ST_AsGeoJSON("publicreport.image"."location"), '{}') AS "location_json",
"publicreport.image"."resolution_x" AS "resolution_x",
"publicreport.image"."resolution_y" AS "resolution_y",
"publicreport.image"."storage_uuid" AS "storage_uuid",
"publicreport.image"."storage_size" AS "storage_size",
"publicreport.image"."uploaded_filename" AS "uploaded_filename"
FROM "publicreport"."image" AS "publicreport.image"
INNER JOIN "publicreport"."pool_image" AS "publicreport.pool_image" ON ("publicreport.image"."id" = "publicreport.pool_image"."image_id")
WHERE ("publicreport.pool_image"."pool_id" = $1)

View file

@ -40,7 +40,7 @@ type ExifCollection struct {
type ImageUpload struct {
Bounds image.Rectangle
ContentType string
Exif ExifCollection
Exif *ExifCollection
Format string
UploadFilesize int
@ -48,7 +48,7 @@ type ImageUpload struct {
UUID uuid.UUID
}
func extractExif(content_type string, file_bytes []byte) (result ExifCollection, err error) {
func extractExif(content_type string, file_bytes []byte) (result *ExifCollection, err error) {
/*
Using "github.com/evanoberholster/imagemeta"
meta, err := imagemeta.Decode(bytes.NewReader(file_bytes))
@ -64,7 +64,10 @@ func extractExif(content_type string, file_bytes []byte) (result ExifCollection,
exif, err := exif.Decode(bytes.NewReader(file_bytes))
if err != nil {
return result, fmt.Errorf("Failed to decode image meta: %w", err)
if err.Error() == "exif: failed to find exif intro marker" {
return nil, nil
}
return nil, fmt.Errorf("Failed to decode image meta: %w", err)
}
lat, lng, _ := exif.LatLong()
result.GPS = &GPS{
@ -86,11 +89,8 @@ func extractImageUpload(headers *multipart.FileHeader) (upload ImageUpload, err
exif, err := extractExif(content_type, file_bytes)
if err != nil {
//return upload, fmt.Errorf("Failed to extract EXIF data: %w", err)
log.Warn().Err(err).Msg("Failed to extract EXIF data")
return upload, fmt.Errorf("Failed to extract EXIF data: %w", err)
}
log.Debug().Float64("lat", exif.GPS.Latitude).Float64("lng", exif.GPS.Longitude).Msg("extracted GPS from exif")
i, format, err := image.Decode(bytes.NewReader(file_bytes))
if err != nil {
return upload, fmt.Errorf("Failed to decode image file: %w", err)
@ -150,6 +150,7 @@ func saveImageUploads(ctx context.Context, tx bob.Tx, uploads []ImageUpload) (mo
}
// TODO: figure out how to do this via the setter...?
if u.Exif != nil {
if u.Exif.GPS != nil {
_, err = psql.Update(
um.Table("publicreport.image"),
@ -172,8 +173,11 @@ func saveImageUploads(ctx context.Context, tx bob.Tx, uploads []ImageUpload) (mo
return images, fmt.Errorf("Failed to create photo exif records: %w", err)
}
}
images = append(images, image)
log.Info().Int32("id", image.ID).Int("tags", len(u.Exif.Tags)).Msg("Saved an uploaded file to the database")
} else {
log.Info().Int32("id", image.ID).Int("tags", 0).Msg("Saved an uploaded file without EXIF data")
}
images = append(images, image)
}
return images, nil
}

View file

@ -4,7 +4,6 @@ import (
"fmt"
"net/http"
"slices"
"strconv"
"time"
"github.com/Gleipnir-Technology/bob"
@ -20,6 +19,7 @@ import (
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/rs/zerolog/log"
"github.com/uber/h3-go/v4"
)
type ContentNuisance struct {
@ -97,11 +97,6 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
address_region := r.PostFormValue("address-region")
address_street := r.PostFormValue("address-street")
duration_str := postFormValueOrNone(r, "duration")
lat := r.FormValue("latitude")
lng := r.FormValue("longitude")
latlng_accuracy_type_str := r.PostFormValue("latlng-accuracy-type")
latlng_accuracy_value_str := r.PostFormValue("latlng-accuracy-value")
map_zoom_str := r.PostFormValue("map-zoom")
source_stagnant := boolFromForm(r, "source-stagnant")
source_container := boolFromForm(r, "source-container")
source_description := r.PostFormValue("source-description")
@ -118,20 +113,14 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
is_location_garden := false
is_location_pool := false
is_location_other := false
latlng_accuracy_value := float32(0.0)
map_zoom := float32(0.0)
latlng, err := parseLatLng(r)
err = duration.Scan(duration_str)
if err != nil {
log.Warn().Err(err).Str("duration_str", duration_str).Msg("Failed to interpret 'duration'")
}
latlng_accuracy_type := enums.PublicreportAccuracytypeNone
err = latlng_accuracy_type.Scan(latlng_accuracy_type_str)
if err != nil {
log.Warn().Err(err).Str("latlng_accuracy_type_str", latlng_accuracy_type_str).Msg("Failed to parse accuracy type")
}
log.Debug().Strs("source_locations", source_locations).Msg("parsing")
if slices.Contains(source_locations, "backyard") {
is_location_backyard = true
@ -148,31 +137,7 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
if slices.Contains(source_locations, "pool-area") {
is_location_pool = true
}
log.Debug().Bool("is_location_backyard", is_location_backyard).Bool("is_location_frontyard", is_location_frontyard).Bool("is_location_garden", is_location_garden).Bool("is_location_other", is_location_other).Bool("is_location_pool", is_location_pool).Msg("parsed")
var temp float64
temp, err = strconv.ParseFloat(latlng_accuracy_value_str, 32)
if err != nil {
log.Warn().Err(err).Str("latlng_accuracy_value_str", latlng_accuracy_value_str).Msg("Failed to parse latlng_accuracy_value")
} else {
latlng_accuracy_value = float32(temp)
}
latitude, err := strconv.ParseFloat(lat, 64)
if err != nil {
log.Warn().Err(err).Str("lat", lat).Msg("Failed to parse lat")
}
longitude, err := strconv.ParseFloat(lng, 64)
if err != nil {
log.Warn().Err(err).Str("lng", lng).Msg("Failed to parse lng")
}
temp, err = strconv.ParseFloat(map_zoom_str, 32)
if err != nil {
log.Warn().Err(err).Str("map_zoom_str", map_zoom_str).Msg("Failed to parse map_zoom_str")
} else {
map_zoom = float32(temp)
}
//log.Debug().Bool("is_location_backyard", is_location_backyard).Bool("is_location_frontyard", is_location_frontyard).Bool("is_location_garden", is_location_garden).Bool("is_location_other", is_location_other).Bool("is_location_pool", is_location_pool).Msg("parsed")
public_id, err := report.GenerateReportID()
if err != nil {
@ -198,14 +163,18 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
respondError(w, "Failed to save image uploads", err, http.StatusInternalServerError)
return
}
organization_id, err := matchDistrict(ctx, longitude, latitude, uploads)
var organization_id *int32
var h3cell h3.Cell
if latlng.Latitude != nil && latlng.Longitude != nil {
organization_id, err = matchDistrict(ctx, *latlng.Longitude, *latlng.Latitude, uploads)
if err != nil {
log.Warn().Err(err).Msg("Failed to match district")
}
c, err := h3utils.GetCell(longitude, latitude, 15)
h3cell, err = h3utils.GetCell(*latlng.Longitude, *latlng.Latitude, 15)
if err != nil {
respondError(w, "Failedt o get h3 cell", err, http.StatusInternalServerError)
}
}
setter := models.PublicreportNuisanceSetter{
AdditionalInfo: omit.From(additional_info),
@ -217,17 +186,17 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
AddressStreet: omit.From(address_street),
Created: omit.From(time.Now()),
Duration: omit.From(duration),
H3cell: omitnull.From(c.String()),
H3cell: omitnull.From(h3cell.String()),
IsLocationBackyard: omit.From(is_location_backyard),
IsLocationFrontyard: omit.From(is_location_frontyard),
IsLocationGarden: omit.From(is_location_garden),
IsLocationOther: omit.From(is_location_other),
IsLocationPool: omit.From(is_location_pool),
LatlngAccuracyType: omit.From(latlng_accuracy_type),
LatlngAccuracyValue: omit.From(latlng_accuracy_value),
LatlngAccuracyType: omit.From(latlng.AccuracyType),
LatlngAccuracyValue: omit.From(latlng.AccuracyValue),
//Location: omitnull.From(fmt.Sprintf("ST_GeometryFromText(Point(%s %s))", longitude, latitude)),
Location: omitnull.FromPtr[string](nil),
MapZoom: omit.From(map_zoom),
MapZoom: omit.From(latlng.MapZoom),
OrganizationID: omitnull.FromPtr(organization_id),
PublicID: omit.From(public_id),
ReporterEmail: omitnull.FromPtr[string](nil),
@ -248,15 +217,17 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
respondError(w, "Failed to create database record", err, http.StatusInternalServerError)
return
}
if latlng.Latitude != nil && latlng.Longitude != nil {
_, err = psql.Update(
um.Table("publicreport.nuisance"),
um.SetCol("location").To(fmt.Sprintf("ST_GeometryFromText('Point(%f %f)')", longitude, latitude)),
um.SetCol("location").To(fmt.Sprintf("ST_GeometryFromText('Point(%f %f)')", *latlng.Longitude, *latlng.Latitude)),
um.Where(psql.Quote("id").EQ(psql.Arg(nuisance.ID))),
).Exec(ctx, txn)
if err != nil {
respondError(w, "Failed to insert publicreport", err, http.StatusInternalServerError)
return
}
}
log.Info().Str("public_id", public_id).Int32("id", nuisance.ID).Msg("Created nuisance report")
if len(images) > 0 {
setters := make([]*models.PublicreportNuisanceImageSetter, 0)

View file

@ -2,11 +2,14 @@ package rmo
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
//"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/sql"
//"github.com/go-chi/chi/v5"
//"github.com/rs/zerolog/log"
@ -63,3 +66,70 @@ func getReportSuggestion(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write(jsonBody)
}
type LatLngForm struct {
Latitude *float64
Longitude *float64
MapZoom float32
AccuracyValue float32
AccuracyType enums.PublicreportAccuracytype
}
func parseLatLng(r *http.Request) (LatLngForm, error) {
result := LatLngForm{
AccuracyType: enums.PublicreportAccuracytypeNone,
AccuracyValue: 0.0,
Latitude: nil,
Longitude: nil,
MapZoom: 0.0,
}
latitude_str := r.FormValue("latitude")
longitude_str := r.FormValue("longitude")
latlng_accuracy_type_str := r.PostFormValue("latlng-accuracy-type")
latlng_accuracy_value_str := r.PostFormValue("latlng-accuracy-value")
map_zoom_str := r.PostFormValue("map-zoom")
var err error
if latlng_accuracy_type_str != "" {
err := result.AccuracyType.Scan(latlng_accuracy_type_str)
if err != nil {
return result, fmt.Errorf("Failed to parse accuracy type '%s': %w", latlng_accuracy_type_str, err)
}
}
if latlng_accuracy_value_str != "" {
var t float64
t, err = strconv.ParseFloat(latlng_accuracy_value_str, 32)
if err != nil {
return result, fmt.Errorf("Failed to parse latlng_accuracy_value '%s': %w", latlng_accuracy_value_str, err)
}
result.AccuracyValue = float32(t)
}
if latitude_str != "" {
var t float64
t, err = strconv.ParseFloat(latitude_str, 64)
if err != nil {
return result, fmt.Errorf("Failed to parse latitude '%s': %w", latitude_str, err)
}
result.Latitude = &t
}
if longitude_str != "" {
var t float64
t, err := strconv.ParseFloat(longitude_str, 64)
if err != nil {
return result, fmt.Errorf("Failed to parse longitude '%s': %w", longitude_str, err)
}
result.Longitude = &t
}
if map_zoom_str != "" {
var t float64
t, err = strconv.ParseFloat(map_zoom_str, 32)
if err != nil {
return result, fmt.Errorf("Failed to parse map_zoom_str '%s': %w", map_zoom_str, err)
} else {
result.MapZoom = float32(t)
}
}
return result, nil
}

View file

@ -17,7 +17,7 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/db/sql"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
//"github.com/rs/zerolog/log"
"github.com/stephenafamo/scan"
/*
"github.com/Gleipnir-Technology/nidus-sync/db"
@ -203,8 +203,79 @@ func contentFromNuisance(ctx context.Context, report_id string) (result ContentS
return result, err
}
func contentFromPool(ctx context.Context, report_id string) (result ContentStatusByID, err error) {
pool, err := models.PublicreportPools.Query(
models.SelectWhere.PublicreportPools.PublicID.EQ(report_id),
).One(ctx, db.PGInstance.BobDB)
if err != nil {
return result, fmt.Errorf("Failed to query pool %s: %w", report_id, err)
}
images, err := sql.PublicreportImageWithJSONByPoolID(pool.ID).All(ctx, db.PGInstance.BobDB)
if err != nil {
return result, fmt.Errorf("Failed to get images %s: %w", report_id, err)
}
result.Report.ID = report_id
result.Report.Address = pool.Address
result.Report.Created = pool.Created
result.Report.ImageCount = len(images)
result.Report.Status = strings.Title(pool.Status.String())
result.Report.Type = "Mosquito Nuisance"
result.Report.Details = []DetailEntry{
DetailEntry{
Name: "Has a gate that affects access?",
Value: strconv.FormatBool(pool.AccessGate),
},
DetailEntry{
Name: "Has dog that affects access?",
Value: strconv.FormatBool(pool.AccessDog),
},
DetailEntry{
Name: "Has a fence that affects access?",
Value: strconv.FormatBool(pool.AccessFence),
},
DetailEntry{
Name: "Has a locked entrace that affects access?",
Value: strconv.FormatBool(pool.AccessLocked),
},
DetailEntry{
Name: "Reporter observed larvae (wigglers)?",
Value: strconv.FormatBool(pool.HasLarvae),
},
DetailEntry{
Name: "Reporter observed pupae (tumblers)?",
Value: strconv.FormatBool(pool.HasPupae),
},
DetailEntry{
Name: "Reporter observed adult mosquitoes?",
Value: strconv.FormatBool(pool.HasAdult),
},
}
result.Timeline = []TimelineEntry{
TimelineEntry{
At: pool.Created,
Detail: "Initial report was submitted",
Title: "Created",
},
}
type LocationGeoJSON struct {
Location string
}
location, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
psql.F("ST_AsGeoJSON", "location"),
),
sm.From("publicreport.pool"),
sm.Where(psql.Quote("public_id").EQ(psql.Arg(report_id))),
), scan.SingleColumnMapper[string])
if err != nil {
return result, fmt.Errorf("Failed to query pool %s: %w", report_id, err)
}
result.Report.Location = location
return result, err
}
func contentFromQuick(ctx context.Context, report_id string) (result ContentStatusByID, err error) {
quick, err := models.PublicreportQuicks.Query(
models.SelectWhere.PublicreportQuicks.PublicID.EQ(report_id),
@ -254,6 +325,10 @@ func getStatusByID(w http.ResponseWriter, r *http.Request) {
case "pool":
content, err = contentFromPool(ctx, report_id)
}
if err != nil {
respondError(w, "Failed to generate report content", err, http.StatusInternalServerError)
return
}
content.MapboxToken = config.MapboxToken
content.URL = makeContentURL(nil)
html.RenderOrError(

View file

@ -98,7 +98,7 @@ document.addEventListener("DOMContentLoaded", onLoad);
</div>
{{range .Report.Details}}
<div class="row">
<div class="col-md-3">
<div class="col-md-4">
<strong>{{.Name}}</strong>
</div>
<div class="col-md-6">

View file

@ -3,7 +3,6 @@ package rmo
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/Gleipnir-Technology/bob"
@ -62,11 +61,12 @@ func postWater(w http.ResponseWriter, r *http.Request) {
respondError(w, "Failed to parse form", err, http.StatusBadRequest)
return
}
access_comments := r.FormValue("access-comments")
access_gate := boolFromForm(r, "access-gate")
access_fence := boolFromForm(r, "access-fence")
access_locked := boolFromForm(r, "access-locked")
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")
@ -76,20 +76,18 @@ func postWater(w http.ResponseWriter, r *http.Request) {
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")
map_zoom_str := r.FormValue("map-zoom")
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")
reporter_email := r.FormValue("reporter-email")
reporter_name := r.FormValue("reporter-name")
reporter_phone := r.FormValue("reporter-phone")
subscribe := boolFromForm(r, "subscribe")
map_zoom, err := strconv.ParseFloat(map_zoom_str, 32)
latlng, err := parseLatLng(r)
if err != nil {
respondError(w, "Failed to parse zoom level", err, http.StatusBadRequest)
respondError(w, "Failed to parse lat lng for pool report", err, http.StatusInternalServerError)
return
}
public_id, err := report.GenerateReportID()
@ -108,10 +106,10 @@ func postWater(w http.ResponseWriter, r *http.Request) {
setter := models.PublicreportPoolSetter{
AccessComments: omit.From(access_comments),
AccessGate: omit.From(access_gate),
AccessFence: omit.From(access_fence),
AccessLocked: omit.From(access_locked),
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),
@ -123,19 +121,21 @@ func postWater(w http.ResponseWriter, r *http.Request) {
Created: omit.From(time.Now()),
//H3cell: add later
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(map_zoom),
MapZoom: omit.From(latlng.MapZoom),
OwnerEmail: omit.From(owner_email),
OwnerName: omit.From(owner_name),
OwnerPhone: omit.From(owner_phone),
PublicID: omit.From(public_id),
ReporterEmail: omit.From(reporter_email),
ReporterName: omit.From(reporter_name),
ReporterPhone: omit.From(reporter_phone),
ReporterEmail: omit.From(""),
ReporterName: omit.From(""),
ReporterPhone: omit.From(""),
Status: omit.From(enums.PublicreportReportstatustypeReported),
Subscribe: omit.From(subscribe),
}
pool, err := models.PublicreportPools.Insert(&setter).One(ctx, tx)
if err != nil {