Move data out of import.district and in to organization

Then get the organization settings page to work again.

Tons of other stuff is broken now.
This commit is contained in:
Eli Ribble 2026-02-17 05:33:12 +00:00
parent b786c88f52
commit 5a7c9fd090
No known key found for this signature in database
31 changed files with 2001 additions and 4340 deletions

View file

@ -33,20 +33,20 @@ func apiGetDistrict(w http.ResponseWriter, r *http.Request) {
render.Render(w, r, errRender(fmt.Errorf("Failed to parse lng as float: %w", err)))
return
}
district, _, err := platform.DistrictForLocation(r.Context(), lng, lat)
org, err := platform.DistrictForLocation(r.Context(), lng, lat)
if err != nil {
render.Render(w, r, errRender(fmt.Errorf("Failed to get district: %w", err)))
return
}
if district == nil {
if org == nil {
http.NotFound(w, r)
return
}
d := ResponseDistrict{
Agency: district.Agency.GetOr(""),
Manager: district.GeneralMG.GetOr(""),
Phone: district.Phone1.GetOr(""),
Website: district.Website.GetOr(""),
Agency: org.Name,
Manager: org.GeneralManagerName.GetOr(""),
Phone: org.OfficePhone.GetOr(""),
Website: org.Website.GetOr(""),
}
if err := render.Render(w, r, d); err != nil {
render.Render(w, r, errRender(err))

View file

@ -19,7 +19,6 @@ psql:
- "arcgis"
- "comms"
- "fileupload"
- "import"
- "public"
- "publicreport"
- "fieldseeker"

View file

@ -1,17 +0,0 @@
// 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 dberrors
var ImportDistrictErrors = &importDistrictErrors{
ErrUniqueDistrictPkey: &UniqueConstraintError{
schema: "import",
table: "district",
columns: []string{"gid"},
s: "district_pkey",
},
}
type importDistrictErrors struct {
ErrUniqueDistrictPkey *UniqueConstraintError
}

View file

@ -24,13 +24,6 @@ var OrganizationErrors = &organizationErrors{
columns: []string{"slug"},
s: "organization_slug_key",
},
ErrUniqueOrganizationWebsiteKey: &UniqueConstraintError{
schema: "",
table: "organization",
columns: []string{"website"},
s: "organization_website_key",
},
}
type organizationErrors struct {
@ -39,6 +32,4 @@ type organizationErrors struct {
ErrUniqueOrganizationImportDistrictGidKey *UniqueConstraintError
ErrUniqueOrganizationSlugKey *UniqueConstraintError
ErrUniqueOrganizationWebsiteKey *UniqueConstraintError
}

View file

@ -1,360 +0,0 @@
// 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 dbinfo
import "github.com/aarondl/opt/null"
var ImportDistricts = Table[
importDistrictColumns,
importDistrictIndexes,
importDistrictForeignKeys,
importDistrictUniques,
importDistrictChecks,
]{
Schema: "import",
Name: "district",
Columns: importDistrictColumns{
Gid: column{
Name: "gid",
DBType: "integer",
Default: "nextval('import.district_gid_seq'::regclass)",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
ID: column{
Name: "id",
DBType: "numeric",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Website: column{
Name: "website",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Contact: column{
Name: "contact",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Address: column{
Name: "address",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Regionid: column{
Name: "regionid",
DBType: "numeric",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
PostalCod: column{
Name: "postal_cod",
DBType: "numeric",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Phone1: column{
Name: "phone1",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Fax1: column{
Name: "fax1",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Agency: column{
Name: "agency",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Code1: column{
Name: "code1",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
City1: column{
Name: "city1",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ShapeLeng: column{
Name: "shape_leng",
DBType: "numeric",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Address2: column{
Name: "address2",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
GeneralMG: column{
Name: "general_mg",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
City2: column{
Name: "city2",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
PostalC1: column{
Name: "postal_c_1",
DBType: "numeric",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Fax2: column{
Name: "fax2",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Phone2: column{
Name: "phone2",
DBType: "character varying",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ShapeLe1: column{
Name: "shape_le_1",
DBType: "numeric",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ShapeArea: column{
Name: "shape_area",
DBType: "numeric",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Geom: column{
Name: "geom",
DBType: "geometry",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Geom4326: column{
Name: "geom_4326",
DBType: "geometry",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
Centroid4326: column{
Name: "centroid_4326",
DBType: "geometry",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
Extent4326: column{
Name: "extent_4326",
DBType: "geometry",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
Area4326SQM: column{
Name: "area_4326_sqm",
DBType: "numeric",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
},
Indexes: importDistrictIndexes{
DistrictPkey: index{
Type: "btree",
Name: "district_pkey",
Columns: []indexColumn{
{
Name: "gid",
Desc: null.FromCond(false, true),
IsExpression: false,
},
},
Unique: true,
Comment: "",
NullsFirst: []bool{false},
NullsDistinct: false,
Where: "",
Include: []string{},
},
DistrictGeomIdx: index{
Type: "gist",
Name: "district_geom_idx",
Columns: []indexColumn{
{
Name: "geom",
Desc: null.FromCond(false, true),
IsExpression: false,
},
},
Unique: false,
Comment: "",
NullsFirst: []bool{false},
NullsDistinct: false,
Where: "",
Include: []string{},
},
},
PrimaryKey: &constraint{
Name: "district_pkey",
Columns: []string{"gid"},
Comment: "",
},
Comment: "",
}
type importDistrictColumns struct {
Gid column
ID column
Website column
Contact column
Address column
Regionid column
PostalCod column
Phone1 column
Fax1 column
Agency column
Code1 column
City1 column
ShapeLeng column
Address2 column
GeneralMG column
City2 column
PostalC1 column
Fax2 column
Phone2 column
ShapeLe1 column
ShapeArea column
Geom column
Geom4326 column
Centroid4326 column
Extent4326 column
Area4326SQM column
}
func (c importDistrictColumns) AsSlice() []column {
return []column{
c.Gid, c.ID, c.Website, c.Contact, c.Address, c.Regionid, c.PostalCod, c.Phone1, c.Fax1, c.Agency, c.Code1, c.City1, c.ShapeLeng, c.Address2, c.GeneralMG, c.City2, c.PostalC1, c.Fax2, c.Phone2, c.ShapeLe1, c.ShapeArea, c.Geom, c.Geom4326, c.Centroid4326, c.Extent4326, c.Area4326SQM,
}
}
type importDistrictIndexes struct {
DistrictPkey index
DistrictGeomIdx index
}
func (i importDistrictIndexes) AsSlice() []index {
return []index{
i.DistrictPkey, i.DistrictGeomIdx,
}
}
type importDistrictForeignKeys struct{}
func (f importDistrictForeignKeys) AsSlice() []foreignKey {
return []foreignKey{}
}
type importDistrictUniques struct{}
func (u importDistrictUniques) AsSlice() []constraint {
return []constraint{}
}
type importDistrictChecks struct{}
func (c importDistrictChecks) AsSlice() []check {
return []check{}
}

View file

@ -96,6 +96,168 @@ var Organizations = Table[
Generated: false,
AutoIncr: false,
},
GeneralManagerName: column{
Name: "general_manager_name",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
MailingAddressCity: column{
Name: "mailing_address_city",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
MailingAddressPostalCode: column{
Name: "mailing_address_postal_code",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
MailingAddressStreet: column{
Name: "mailing_address_street",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
OfficeAddressCity: column{
Name: "office_address_city",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
OfficeAddressPostalCode: column{
Name: "office_address_postal_code",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
OfficeAddressStreet: column{
Name: "office_address_street",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ServiceAreaGeometry: column{
Name: "service_area_geometry",
DBType: "geometry",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ServiceAreaSquareMeters: column{
Name: "service_area_square_meters",
DBType: "numeric",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
ServiceAreaCentroid: column{
Name: "service_area_centroid",
DBType: "geometry",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
ServiceAreaExtent: column{
Name: "service_area_extent",
DBType: "geometry",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
OfficeFax: column{
Name: "office_fax",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
OfficePhone: column{
Name: "office_phone",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ServiceAreaXmin: column{
Name: "service_area_xmin",
DBType: "double precision",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
ServiceAreaYmin: column{
Name: "service_area_ymin",
DBType: "double precision",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
ServiceAreaXmax: column{
Name: "service_area_xmax",
DBType: "double precision",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
ServiceAreaYmax: column{
Name: "service_area_ymax",
DBType: "double precision",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
ServiceAreaCentroidGeojson: column{
Name: "service_area_centroid_geojson",
DBType: "text",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
},
Indexes: organizationIndexes{
OrganizationPkey: index{
@ -149,23 +311,6 @@ var Organizations = Table[
Where: "",
Include: []string{},
},
OrganizationWebsiteKey: index{
Type: "btree",
Name: "organization_website_key",
Columns: []indexColumn{
{
Name: "website",
Desc: null.FromCond(false, true),
IsExpression: false,
},
},
Unique: true,
Comment: "",
NullsFirst: []bool{false},
NullsDistinct: false,
Where: "",
Include: []string{},
},
},
PrimaryKey: &constraint{
Name: "organization_pkey",
@ -194,11 +339,6 @@ var Organizations = Table[
Columns: []string{"slug"},
Comment: "",
},
OrganizationWebsiteKey: constraint{
Name: "organization_website_key",
Columns: []string{"website"},
Comment: "",
},
},
Comment: "",
@ -214,11 +354,29 @@ type organizationColumns struct {
Website column
LogoUUID column
Slug column
GeneralManagerName column
MailingAddressCity column
MailingAddressPostalCode column
MailingAddressStreet column
OfficeAddressCity column
OfficeAddressPostalCode column
OfficeAddressStreet column
ServiceAreaGeometry column
ServiceAreaSquareMeters column
ServiceAreaCentroid column
ServiceAreaExtent column
OfficeFax column
OfficePhone column
ServiceAreaXmin column
ServiceAreaYmin column
ServiceAreaXmax column
ServiceAreaYmax column
ServiceAreaCentroidGeojson column
}
func (c organizationColumns) AsSlice() []column {
return []column{
c.ID, c.Name, c.ArcgisID, c.ArcgisName, c.FieldseekerURL, c.ImportDistrictGid, c.Website, c.LogoUUID, c.Slug,
c.ID, c.Name, c.ArcgisID, c.ArcgisName, c.FieldseekerURL, c.ImportDistrictGid, c.Website, c.LogoUUID, c.Slug, c.GeneralManagerName, c.MailingAddressCity, c.MailingAddressPostalCode, c.MailingAddressStreet, c.OfficeAddressCity, c.OfficeAddressPostalCode, c.OfficeAddressStreet, c.ServiceAreaGeometry, c.ServiceAreaSquareMeters, c.ServiceAreaCentroid, c.ServiceAreaExtent, c.OfficeFax, c.OfficePhone, c.ServiceAreaXmin, c.ServiceAreaYmin, c.ServiceAreaXmax, c.ServiceAreaYmax, c.ServiceAreaCentroidGeojson,
}
}
@ -226,12 +384,11 @@ type organizationIndexes struct {
OrganizationPkey index
OrganizationImportDistrictGidKey index
OrganizationSlugKey index
OrganizationWebsiteKey index
}
func (i organizationIndexes) AsSlice() []index {
return []index{
i.OrganizationPkey, i.OrganizationImportDistrictGidKey, i.OrganizationSlugKey, i.OrganizationWebsiteKey,
i.OrganizationPkey, i.OrganizationImportDistrictGidKey, i.OrganizationSlugKey,
}
}
@ -248,12 +405,11 @@ func (f organizationForeignKeys) AsSlice() []foreignKey {
type organizationUniques struct {
OrganizationImportDistrictGidKey constraint
OrganizationSlugKey constraint
OrganizationWebsiteKey constraint
}
func (u organizationUniques) AsSlice() []constraint {
return []constraint{
u.OrganizationImportDistrictGidKey, u.OrganizationSlugKey, u.OrganizationWebsiteKey,
u.OrganizationImportDistrictGidKey, u.OrganizationSlugKey,
}
}

View file

@ -219,10 +219,6 @@ var (
h3AggregationWithParentsCascadingCtx = newContextual[bool]("h3AggregationWithParentsCascading")
h3AggregationRelOrganizationCtx = newContextual[bool]("h3_aggregation.organization.h3_aggregation.h3_aggregation_organization_id_fkey")
// Relationship Contexts for import.district
importDistrictWithParentsCascadingCtx = newContextual[bool]("importDistrictWithParentsCascading")
importDistrictRelImportDistrictGidOrganizationCtx = newContextual[bool]("import.district.organization.organization.organization_import_district_gid_fkey")
// Relationship Contexts for note_audio
noteAudioWithParentsCascadingCtx = newContextual[bool]("noteAudioWithParentsCascading")
noteAudioRelCreatorUserCtx = newContextual[bool]("note_audio.user_.note_audio.note_audio_creator_id_fkey")
@ -300,7 +296,6 @@ var (
organizationRelH3AggregationsCtx = newContextual[bool]("h3_aggregation.organization.h3_aggregation.h3_aggregation_organization_id_fkey")
organizationRelNoteAudiosCtx = newContextual[bool]("note_audio.organization.note_audio.note_audio_organization_id_fkey")
organizationRelNoteImagesCtx = newContextual[bool]("note_image.organization.note_image.note_image_organization_id_fkey")
organizationRelImportDistrictGidDistrictCtx = newContextual[bool]("import.district.organization.organization.organization_import_district_gid_fkey")
organizationRelNuisancesCtx = newContextual[bool]("organization.publicreport.nuisance.publicreport.nuisance.nuisance_organization_id_fkey")
organizationRelPublicreportPoolCtx = newContextual[bool]("organization.publicreport.pool.publicreport.pool.pool_organization_id_fkey")
organizationRelQuicksCtx = newContextual[bool]("organization.publicreport.quick.publicreport.quick.quick_organization_id_fkey")

View file

@ -66,7 +66,6 @@ type Factory struct {
baseGeometryColumnMods GeometryColumnModSlice
baseGooseDBVersionMods GooseDBVersionModSlice
baseH3AggregationMods H3AggregationModSlice
baseImportDistrictMods ImportDistrictModSlice
baseNoteAudioMods NoteAudioModSlice
baseNoteAudioBreadcrumbMods NoteAudioBreadcrumbModSlice
baseNoteAudioDatumMods NoteAudioDatumModSlice
@ -2581,60 +2580,6 @@ func (f *Factory) FromExistingH3Aggregation(m *models.H3Aggregation) *H3Aggregat
return o
}
func (f *Factory) NewImportDistrict(mods ...ImportDistrictMod) *ImportDistrictTemplate {
return f.NewImportDistrictWithContext(context.Background(), mods...)
}
func (f *Factory) NewImportDistrictWithContext(ctx context.Context, mods ...ImportDistrictMod) *ImportDistrictTemplate {
o := &ImportDistrictTemplate{f: f}
if f != nil {
f.baseImportDistrictMods.Apply(ctx, o)
}
ImportDistrictModSlice(mods).Apply(ctx, o)
return o
}
func (f *Factory) FromExistingImportDistrict(m *models.ImportDistrict) *ImportDistrictTemplate {
o := &ImportDistrictTemplate{f: f, alreadyPersisted: true}
o.Gid = func() int32 { return m.Gid }
o.ID = func() null.Val[decimal.Decimal] { return m.ID }
o.Website = func() null.Val[string] { return m.Website }
o.Contact = func() null.Val[string] { return m.Contact }
o.Address = func() null.Val[string] { return m.Address }
o.Regionid = func() null.Val[decimal.Decimal] { return m.Regionid }
o.PostalCod = func() null.Val[decimal.Decimal] { return m.PostalCod }
o.Phone1 = func() null.Val[string] { return m.Phone1 }
o.Fax1 = func() null.Val[string] { return m.Fax1 }
o.Agency = func() null.Val[string] { return m.Agency }
o.Code1 = func() null.Val[string] { return m.Code1 }
o.City1 = func() null.Val[string] { return m.City1 }
o.ShapeLeng = func() null.Val[decimal.Decimal] { return m.ShapeLeng }
o.Address2 = func() null.Val[string] { return m.Address2 }
o.GeneralMG = func() null.Val[string] { return m.GeneralMG }
o.City2 = func() null.Val[string] { return m.City2 }
o.PostalC1 = func() null.Val[decimal.Decimal] { return m.PostalC1 }
o.Fax2 = func() null.Val[string] { return m.Fax2 }
o.Phone2 = func() null.Val[string] { return m.Phone2 }
o.ShapeLe1 = func() null.Val[decimal.Decimal] { return m.ShapeLe1 }
o.ShapeArea = func() null.Val[decimal.Decimal] { return m.ShapeArea }
o.Geom = func() null.Val[string] { return m.Geom }
o.Geom4326 = func() null.Val[string] { return m.Geom4326 }
o.Centroid4326 = func() null.Val[string] { return m.Centroid4326 }
o.Extent4326 = func() null.Val[string] { return m.Extent4326 }
o.Area4326SQM = func() null.Val[decimal.Decimal] { return m.Area4326SQM }
ctx := context.Background()
if m.R.ImportDistrictGidOrganization != nil {
ImportDistrictMods.WithExistingImportDistrictGidOrganization(m.R.ImportDistrictGidOrganization).Apply(ctx, o)
}
return o
}
func (f *Factory) NewNoteAudio(mods ...NoteAudioMod) *NoteAudioTemplate {
return f.NewNoteAudioWithContext(context.Background(), mods...)
}
@ -2966,6 +2911,24 @@ func (f *Factory) FromExistingOrganization(m *models.Organization) *Organization
o.Website = func() null.Val[string] { return m.Website }
o.LogoUUID = func() null.Val[uuid.UUID] { return m.LogoUUID }
o.Slug = func() null.Val[string] { return m.Slug }
o.GeneralManagerName = func() null.Val[string] { return m.GeneralManagerName }
o.MailingAddressCity = func() null.Val[string] { return m.MailingAddressCity }
o.MailingAddressPostalCode = func() null.Val[string] { return m.MailingAddressPostalCode }
o.MailingAddressStreet = func() null.Val[string] { return m.MailingAddressStreet }
o.OfficeAddressCity = func() null.Val[string] { return m.OfficeAddressCity }
o.OfficeAddressPostalCode = func() null.Val[string] { return m.OfficeAddressPostalCode }
o.OfficeAddressStreet = func() null.Val[string] { return m.OfficeAddressStreet }
o.ServiceAreaGeometry = func() null.Val[string] { return m.ServiceAreaGeometry }
o.ServiceAreaSquareMeters = func() null.Val[decimal.Decimal] { return m.ServiceAreaSquareMeters }
o.ServiceAreaCentroid = func() null.Val[string] { return m.ServiceAreaCentroid }
o.ServiceAreaExtent = func() null.Val[string] { return m.ServiceAreaExtent }
o.OfficeFax = func() null.Val[string] { return m.OfficeFax }
o.OfficePhone = func() null.Val[string] { return m.OfficePhone }
o.ServiceAreaXmin = func() null.Val[float64] { return m.ServiceAreaXmin }
o.ServiceAreaYmin = func() null.Val[float64] { return m.ServiceAreaYmin }
o.ServiceAreaXmax = func() null.Val[float64] { return m.ServiceAreaXmax }
o.ServiceAreaYmax = func() null.Val[float64] { return m.ServiceAreaYmax }
o.ServiceAreaCentroidGeojson = func() null.Val[string] { return m.ServiceAreaCentroidGeojson }
ctx := context.Background()
if len(m.R.EmailContacts) > 0 {
@ -3073,9 +3036,6 @@ func (f *Factory) FromExistingOrganization(m *models.Organization) *Organization
if len(m.R.NoteImages) > 0 {
OrganizationMods.AddExistingNoteImages(m.R.NoteImages...).Apply(ctx, o)
}
if m.R.ImportDistrictGidDistrict != nil {
OrganizationMods.WithExistingImportDistrictGidDistrict(m.R.ImportDistrictGidDistrict).Apply(ctx, o)
}
if len(m.R.Nuisances) > 0 {
OrganizationMods.AddExistingNuisances(m.R.Nuisances...).Apply(ctx, o)
}
@ -4256,14 +4216,6 @@ func (f *Factory) AddBaseH3AggregationMod(mods ...H3AggregationMod) {
f.baseH3AggregationMods = append(f.baseH3AggregationMods, mods...)
}
func (f *Factory) ClearBaseImportDistrictMods() {
f.baseImportDistrictMods = nil
}
func (f *Factory) AddBaseImportDistrictMod(mods ...ImportDistrictMod) {
f.baseImportDistrictMods = append(f.baseImportDistrictMods, mods...)
}
func (f *Factory) ClearBaseNoteAudioMods() {
f.baseNoteAudioMods = nil
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,24 @@
-- +goose Up
ALTER TABLE organization ADD COLUMN general_manager_name TEXT;
ALTER TABLE organization ADD COLUMN mailing_address_city TEXT;
ALTER TABLE organization ADD COLUMN mailing_address_postal_code TEXT;
ALTER TABLE organization ADD COLUMN mailing_address_street TEXT;
ALTER TABLE organization ADD COLUMN office_address_city TEXT;
ALTER TABLE organization ADD COLUMN office_address_postal_code TEXT;
ALTER TABLE organization ADD COLUMN office_address_street TEXT;
ALTER TABLE organization ADD COLUMN office_fax TEXT;
ALTER TABLE organization ADD COLUMN office_phone TEXT;
ALTER TABLE organization ADD COLUMN service_area_geometry geometry(MultiPolygon,4326);
ALTER TABLE organization ADD COLUMN service_area_square_meters numeric GENERATED ALWAYS AS (ST_Area(service_area_geometry)) STORED;
ALTER TABLE organization ADD COLUMN service_area_centroid geometry(Point,4326) GENERATED ALWAYS AS (ST_Centroid(service_area_geometry)) STORED;
ALTER TABLE organization ADD COLUMN service_area_centroid_geojson TEXT GENERATED ALWAYS AS (ST_AsGeoJSON(ST_Centroid(service_area_geometry))) STORED;
ALTER TABLE organization ADD COLUMN service_area_extent geometry(Polygon,4326) GENERATED ALWAYS AS (ST_Envelope(service_area_geometry)) STORED;
ALTER TABLE organization ADD COLUMN service_area_xmin DOUBLE PRECISION GENERATED ALWAYS AS (ST_XMin(ST_Envelope(service_area_geometry))) STORED;
ALTER TABLE organization ADD COLUMN service_area_ymin DOUBLE PRECISION GENERATED ALWAYS AS (ST_YMin(ST_Envelope(service_area_geometry))) STORED;
ALTER TABLE organization ADD COLUMN service_area_xmax DOUBLE PRECISION GENERATED ALWAYS AS (ST_XMax(ST_Envelope(service_area_geometry))) STORED;
ALTER TABLE organization ADD COLUMN service_area_ymax DOUBLE PRECISION GENERATED ALWAYS AS (ST_YMax(ST_Envelope(service_area_geometry))) STORED;
ALTER TABLE organization DROP CONSTRAINT organization_website_key;
-- +goose Down

View file

@ -76,7 +76,6 @@ type joins[Q dialect.Joinable] struct {
FileuploadFiles joinSet[fileuploadFileJoins[Q]]
FileuploadPools joinSet[fileuploadPoolJoins[Q]]
H3Aggregations joinSet[h3AggregationJoins[Q]]
ImportDistricts joinSet[importDistrictJoins[Q]]
NoteAudios joinSet[noteAudioJoins[Q]]
NoteAudioBreadcrumbs joinSet[noteAudioBreadcrumbJoins[Q]]
NoteAudioData joinSet[noteAudioDatumJoins[Q]]
@ -157,7 +156,6 @@ func getJoins[Q dialect.Joinable]() joins[Q] {
FileuploadFiles: buildJoinSet[fileuploadFileJoins[Q]](FileuploadFiles.Columns, buildFileuploadFileJoins),
FileuploadPools: buildJoinSet[fileuploadPoolJoins[Q]](FileuploadPools.Columns, buildFileuploadPoolJoins),
H3Aggregations: buildJoinSet[h3AggregationJoins[Q]](H3Aggregations.Columns, buildH3AggregationJoins),
ImportDistricts: buildJoinSet[importDistrictJoins[Q]](ImportDistricts.Columns, buildImportDistrictJoins),
NoteAudios: buildJoinSet[noteAudioJoins[Q]](NoteAudios.Columns, buildNoteAudioJoins),
NoteAudioBreadcrumbs: buildJoinSet[noteAudioBreadcrumbJoins[Q]](NoteAudioBreadcrumbs.Columns, buildNoteAudioBreadcrumbJoins),
NoteAudioData: buildJoinSet[noteAudioDatumJoins[Q]](NoteAudioData.Columns, buildNoteAudioDatumJoins),

View file

@ -61,7 +61,6 @@ type preloaders struct {
FileuploadFile fileuploadFilePreloader
FileuploadPool fileuploadPoolPreloader
H3Aggregation h3AggregationPreloader
ImportDistrict importDistrictPreloader
NoteAudio noteAudioPreloader
NoteAudioBreadcrumb noteAudioBreadcrumbPreloader
NoteAudioDatum noteAudioDatumPreloader
@ -134,7 +133,6 @@ func getPreloaders() preloaders {
FileuploadFile: buildFileuploadFilePreloader(),
FileuploadPool: buildFileuploadPoolPreloader(),
H3Aggregation: buildH3AggregationPreloader(),
ImportDistrict: buildImportDistrictPreloader(),
NoteAudio: buildNoteAudioPreloader(),
NoteAudioBreadcrumb: buildNoteAudioBreadcrumbPreloader(),
NoteAudioDatum: buildNoteAudioDatumPreloader(),
@ -213,7 +211,6 @@ type thenLoaders[Q orm.Loadable] struct {
FileuploadFile fileuploadFileThenLoader[Q]
FileuploadPool fileuploadPoolThenLoader[Q]
H3Aggregation h3AggregationThenLoader[Q]
ImportDistrict importDistrictThenLoader[Q]
NoteAudio noteAudioThenLoader[Q]
NoteAudioBreadcrumb noteAudioBreadcrumbThenLoader[Q]
NoteAudioDatum noteAudioDatumThenLoader[Q]
@ -286,7 +283,6 @@ func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] {
FileuploadFile: buildFileuploadFileThenLoader[Q](),
FileuploadPool: buildFileuploadPoolThenLoader[Q](),
H3Aggregation: buildH3AggregationThenLoader[Q](),
ImportDistrict: buildImportDistrictThenLoader[Q](),
NoteAudio: buildNoteAudioThenLoader[Q](),
NoteAudioBreadcrumb: buildNoteAudioBreadcrumbThenLoader[Q](),
NoteAudioDatum: buildNoteAudioDatumThenLoader[Q](),

View file

@ -64,7 +64,6 @@ func Where[Q psql.Filterable]() struct {
GeometryColumns geometryColumnWhere[Q]
GooseDBVersions gooseDBVersionWhere[Q]
H3Aggregations h3AggregationWhere[Q]
ImportDistricts importDistrictWhere[Q]
NoteAudios noteAudioWhere[Q]
NoteAudioBreadcrumbs noteAudioBreadcrumbWhere[Q]
NoteAudioData noteAudioDatumWhere[Q]
@ -143,7 +142,6 @@ func Where[Q psql.Filterable]() struct {
GeometryColumns geometryColumnWhere[Q]
GooseDBVersions gooseDBVersionWhere[Q]
H3Aggregations h3AggregationWhere[Q]
ImportDistricts importDistrictWhere[Q]
NoteAudios noteAudioWhere[Q]
NoteAudioBreadcrumbs noteAudioBreadcrumbWhere[Q]
NoteAudioData noteAudioDatumWhere[Q]
@ -221,7 +219,6 @@ func Where[Q psql.Filterable]() struct {
GeometryColumns: buildGeometryColumnWhere[Q](GeometryColumns.Columns),
GooseDBVersions: buildGooseDBVersionWhere[Q](GooseDBVersions.Columns),
H3Aggregations: buildH3AggregationWhere[Q](H3Aggregations.Columns),
ImportDistricts: buildImportDistrictWhere[Q](ImportDistricts.Columns),
NoteAudios: buildNoteAudioWhere[Q](NoteAudios.Columns),
NoteAudioBreadcrumbs: buildNoteAudioBreadcrumbWhere[Q](NoteAudioBreadcrumbs.Columns),
NoteAudioData: buildNoteAudioDatumWhere[Q](NoteAudioData.Columns),

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@ import (
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/google/uuid"
"github.com/shopspring/decimal"
"github.com/stephenafamo/scan"
)
@ -37,6 +38,24 @@ type Organization struct {
Website null.Val[string] `db:"website" `
LogoUUID null.Val[uuid.UUID] `db:"logo_uuid" `
Slug null.Val[string] `db:"slug" `
GeneralManagerName null.Val[string] `db:"general_manager_name" `
MailingAddressCity null.Val[string] `db:"mailing_address_city" `
MailingAddressPostalCode null.Val[string] `db:"mailing_address_postal_code" `
MailingAddressStreet null.Val[string] `db:"mailing_address_street" `
OfficeAddressCity null.Val[string] `db:"office_address_city" `
OfficeAddressPostalCode null.Val[string] `db:"office_address_postal_code" `
OfficeAddressStreet null.Val[string] `db:"office_address_street" `
ServiceAreaGeometry null.Val[string] `db:"service_area_geometry" `
ServiceAreaSquareMeters null.Val[decimal.Decimal] `db:"service_area_square_meters,generated" `
ServiceAreaCentroid null.Val[string] `db:"service_area_centroid,generated" `
ServiceAreaExtent null.Val[string] `db:"service_area_extent,generated" `
OfficeFax null.Val[string] `db:"office_fax" `
OfficePhone null.Val[string] `db:"office_phone" `
ServiceAreaXmin null.Val[float64] `db:"service_area_xmin,generated" `
ServiceAreaYmin null.Val[float64] `db:"service_area_ymin,generated" `
ServiceAreaXmax null.Val[float64] `db:"service_area_xmax,generated" `
ServiceAreaYmax null.Val[float64] `db:"service_area_ymax,generated" `
ServiceAreaCentroidGeojson null.Val[string] `db:"service_area_centroid_geojson,generated" `
R organizationR `db:"-" `
@ -90,7 +109,6 @@ type organizationR struct {
H3Aggregations H3AggregationSlice // h3_aggregation.h3_aggregation_organization_id_fkey
NoteAudios NoteAudioSlice // note_audio.note_audio_organization_id_fkey
NoteImages NoteImageSlice // note_image.note_image_organization_id_fkey
ImportDistrictGidDistrict *ImportDistrict // organization.organization_import_district_gid_fkey
Nuisances PublicreportNuisanceSlice // publicreport.nuisance.nuisance_organization_id_fkey
PublicreportPool PublicreportPoolSlice // publicreport.pool.pool_organization_id_fkey
Quicks PublicreportQuickSlice // publicreport.quick.quick_organization_id_fkey
@ -100,7 +118,7 @@ type organizationR struct {
func buildOrganizationColumns(alias string) organizationColumns {
return organizationColumns{
ColumnsExpr: expr.NewColumnsExpr(
"id", "name", "arcgis_id", "arcgis_name", "fieldseeker_url", "import_district_gid", "website", "logo_uuid", "slug",
"id", "name", "arcgis_id", "arcgis_name", "fieldseeker_url", "import_district_gid", "website", "logo_uuid", "slug", "general_manager_name", "mailing_address_city", "mailing_address_postal_code", "mailing_address_street", "office_address_city", "office_address_postal_code", "office_address_street", "service_area_geometry", "service_area_square_meters", "service_area_centroid", "service_area_extent", "office_fax", "office_phone", "service_area_xmin", "service_area_ymin", "service_area_xmax", "service_area_ymax", "service_area_centroid_geojson",
).WithParent("organization"),
tableAlias: alias,
ID: psql.Quote(alias, "id"),
@ -112,6 +130,24 @@ func buildOrganizationColumns(alias string) organizationColumns {
Website: psql.Quote(alias, "website"),
LogoUUID: psql.Quote(alias, "logo_uuid"),
Slug: psql.Quote(alias, "slug"),
GeneralManagerName: psql.Quote(alias, "general_manager_name"),
MailingAddressCity: psql.Quote(alias, "mailing_address_city"),
MailingAddressPostalCode: psql.Quote(alias, "mailing_address_postal_code"),
MailingAddressStreet: psql.Quote(alias, "mailing_address_street"),
OfficeAddressCity: psql.Quote(alias, "office_address_city"),
OfficeAddressPostalCode: psql.Quote(alias, "office_address_postal_code"),
OfficeAddressStreet: psql.Quote(alias, "office_address_street"),
ServiceAreaGeometry: psql.Quote(alias, "service_area_geometry"),
ServiceAreaSquareMeters: psql.Quote(alias, "service_area_square_meters"),
ServiceAreaCentroid: psql.Quote(alias, "service_area_centroid"),
ServiceAreaExtent: psql.Quote(alias, "service_area_extent"),
OfficeFax: psql.Quote(alias, "office_fax"),
OfficePhone: psql.Quote(alias, "office_phone"),
ServiceAreaXmin: psql.Quote(alias, "service_area_xmin"),
ServiceAreaYmin: psql.Quote(alias, "service_area_ymin"),
ServiceAreaXmax: psql.Quote(alias, "service_area_xmax"),
ServiceAreaYmax: psql.Quote(alias, "service_area_ymax"),
ServiceAreaCentroidGeojson: psql.Quote(alias, "service_area_centroid_geojson"),
}
}
@ -127,6 +163,24 @@ type organizationColumns struct {
Website psql.Expression
LogoUUID psql.Expression
Slug psql.Expression
GeneralManagerName psql.Expression
MailingAddressCity psql.Expression
MailingAddressPostalCode psql.Expression
MailingAddressStreet psql.Expression
OfficeAddressCity psql.Expression
OfficeAddressPostalCode psql.Expression
OfficeAddressStreet psql.Expression
ServiceAreaGeometry psql.Expression
ServiceAreaSquareMeters psql.Expression
ServiceAreaCentroid psql.Expression
ServiceAreaExtent psql.Expression
OfficeFax psql.Expression
OfficePhone psql.Expression
ServiceAreaXmin psql.Expression
ServiceAreaYmin psql.Expression
ServiceAreaXmax psql.Expression
ServiceAreaYmax psql.Expression
ServiceAreaCentroidGeojson psql.Expression
}
func (c organizationColumns) Alias() string {
@ -150,10 +204,20 @@ type OrganizationSetter struct {
Website omitnull.Val[string] `db:"website" `
LogoUUID omitnull.Val[uuid.UUID] `db:"logo_uuid" `
Slug omitnull.Val[string] `db:"slug" `
GeneralManagerName omitnull.Val[string] `db:"general_manager_name" `
MailingAddressCity omitnull.Val[string] `db:"mailing_address_city" `
MailingAddressPostalCode omitnull.Val[string] `db:"mailing_address_postal_code" `
MailingAddressStreet omitnull.Val[string] `db:"mailing_address_street" `
OfficeAddressCity omitnull.Val[string] `db:"office_address_city" `
OfficeAddressPostalCode omitnull.Val[string] `db:"office_address_postal_code" `
OfficeAddressStreet omitnull.Val[string] `db:"office_address_street" `
ServiceAreaGeometry omitnull.Val[string] `db:"service_area_geometry" `
OfficeFax omitnull.Val[string] `db:"office_fax" `
OfficePhone omitnull.Val[string] `db:"office_phone" `
}
func (s OrganizationSetter) SetColumns() []string {
vals := make([]string, 0, 9)
vals := make([]string, 0, 19)
if s.ID.IsValue() {
vals = append(vals, "id")
}
@ -181,6 +245,36 @@ func (s OrganizationSetter) SetColumns() []string {
if !s.Slug.IsUnset() {
vals = append(vals, "slug")
}
if !s.GeneralManagerName.IsUnset() {
vals = append(vals, "general_manager_name")
}
if !s.MailingAddressCity.IsUnset() {
vals = append(vals, "mailing_address_city")
}
if !s.MailingAddressPostalCode.IsUnset() {
vals = append(vals, "mailing_address_postal_code")
}
if !s.MailingAddressStreet.IsUnset() {
vals = append(vals, "mailing_address_street")
}
if !s.OfficeAddressCity.IsUnset() {
vals = append(vals, "office_address_city")
}
if !s.OfficeAddressPostalCode.IsUnset() {
vals = append(vals, "office_address_postal_code")
}
if !s.OfficeAddressStreet.IsUnset() {
vals = append(vals, "office_address_street")
}
if !s.ServiceAreaGeometry.IsUnset() {
vals = append(vals, "service_area_geometry")
}
if !s.OfficeFax.IsUnset() {
vals = append(vals, "office_fax")
}
if !s.OfficePhone.IsUnset() {
vals = append(vals, "office_phone")
}
return vals
}
@ -212,6 +306,36 @@ func (s OrganizationSetter) Overwrite(t *Organization) {
if !s.Slug.IsUnset() {
t.Slug = s.Slug.MustGetNull()
}
if !s.GeneralManagerName.IsUnset() {
t.GeneralManagerName = s.GeneralManagerName.MustGetNull()
}
if !s.MailingAddressCity.IsUnset() {
t.MailingAddressCity = s.MailingAddressCity.MustGetNull()
}
if !s.MailingAddressPostalCode.IsUnset() {
t.MailingAddressPostalCode = s.MailingAddressPostalCode.MustGetNull()
}
if !s.MailingAddressStreet.IsUnset() {
t.MailingAddressStreet = s.MailingAddressStreet.MustGetNull()
}
if !s.OfficeAddressCity.IsUnset() {
t.OfficeAddressCity = s.OfficeAddressCity.MustGetNull()
}
if !s.OfficeAddressPostalCode.IsUnset() {
t.OfficeAddressPostalCode = s.OfficeAddressPostalCode.MustGetNull()
}
if !s.OfficeAddressStreet.IsUnset() {
t.OfficeAddressStreet = s.OfficeAddressStreet.MustGetNull()
}
if !s.ServiceAreaGeometry.IsUnset() {
t.ServiceAreaGeometry = s.ServiceAreaGeometry.MustGetNull()
}
if !s.OfficeFax.IsUnset() {
t.OfficeFax = s.OfficeFax.MustGetNull()
}
if !s.OfficePhone.IsUnset() {
t.OfficePhone = s.OfficePhone.MustGetNull()
}
}
func (s *OrganizationSetter) Apply(q *dialect.InsertQuery) {
@ -220,7 +344,7 @@ func (s *OrganizationSetter) 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, 9)
vals := make([]bob.Expression, 19)
if s.ID.IsValue() {
vals[0] = psql.Arg(s.ID.MustGet())
} else {
@ -275,6 +399,66 @@ func (s *OrganizationSetter) Apply(q *dialect.InsertQuery) {
vals[8] = psql.Raw("DEFAULT")
}
if !s.GeneralManagerName.IsUnset() {
vals[9] = psql.Arg(s.GeneralManagerName.MustGetNull())
} else {
vals[9] = psql.Raw("DEFAULT")
}
if !s.MailingAddressCity.IsUnset() {
vals[10] = psql.Arg(s.MailingAddressCity.MustGetNull())
} else {
vals[10] = psql.Raw("DEFAULT")
}
if !s.MailingAddressPostalCode.IsUnset() {
vals[11] = psql.Arg(s.MailingAddressPostalCode.MustGetNull())
} else {
vals[11] = psql.Raw("DEFAULT")
}
if !s.MailingAddressStreet.IsUnset() {
vals[12] = psql.Arg(s.MailingAddressStreet.MustGetNull())
} else {
vals[12] = psql.Raw("DEFAULT")
}
if !s.OfficeAddressCity.IsUnset() {
vals[13] = psql.Arg(s.OfficeAddressCity.MustGetNull())
} else {
vals[13] = psql.Raw("DEFAULT")
}
if !s.OfficeAddressPostalCode.IsUnset() {
vals[14] = psql.Arg(s.OfficeAddressPostalCode.MustGetNull())
} else {
vals[14] = psql.Raw("DEFAULT")
}
if !s.OfficeAddressStreet.IsUnset() {
vals[15] = psql.Arg(s.OfficeAddressStreet.MustGetNull())
} else {
vals[15] = psql.Raw("DEFAULT")
}
if !s.ServiceAreaGeometry.IsUnset() {
vals[16] = psql.Arg(s.ServiceAreaGeometry.MustGetNull())
} else {
vals[16] = psql.Raw("DEFAULT")
}
if !s.OfficeFax.IsUnset() {
vals[17] = psql.Arg(s.OfficeFax.MustGetNull())
} else {
vals[17] = psql.Raw("DEFAULT")
}
if !s.OfficePhone.IsUnset() {
vals[18] = psql.Arg(s.OfficePhone.MustGetNull())
} else {
vals[18] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
@ -284,7 +468,7 @@ func (s OrganizationSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
}
func (s OrganizationSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 9)
exprs := make([]bob.Expression, 0, 19)
if s.ID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
@ -349,6 +533,76 @@ func (s OrganizationSetter) Expressions(prefix ...string) []bob.Expression {
}})
}
if !s.GeneralManagerName.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "general_manager_name")...),
psql.Arg(s.GeneralManagerName),
}})
}
if !s.MailingAddressCity.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "mailing_address_city")...),
psql.Arg(s.MailingAddressCity),
}})
}
if !s.MailingAddressPostalCode.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "mailing_address_postal_code")...),
psql.Arg(s.MailingAddressPostalCode),
}})
}
if !s.MailingAddressStreet.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "mailing_address_street")...),
psql.Arg(s.MailingAddressStreet),
}})
}
if !s.OfficeAddressCity.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "office_address_city")...),
psql.Arg(s.OfficeAddressCity),
}})
}
if !s.OfficeAddressPostalCode.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "office_address_postal_code")...),
psql.Arg(s.OfficeAddressPostalCode),
}})
}
if !s.OfficeAddressStreet.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "office_address_street")...),
psql.Arg(s.OfficeAddressStreet),
}})
}
if !s.ServiceAreaGeometry.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "service_area_geometry")...),
psql.Arg(s.ServiceAreaGeometry),
}})
}
if !s.OfficeFax.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "office_fax")...),
psql.Arg(s.OfficeFax),
}})
}
if !s.OfficePhone.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "office_phone")...),
psql.Arg(s.OfficePhone),
}})
}
return exprs
}
@ -1425,30 +1679,6 @@ func (os OrganizationSlice) NoteImages(mods ...bob.Mod[*dialect.SelectQuery]) No
)...)
}
// ImportDistrictGidDistrict starts a query for related objects on import.district
func (o *Organization) ImportDistrictGidDistrict(mods ...bob.Mod[*dialect.SelectQuery]) ImportDistrictsQuery {
return ImportDistricts.Query(append(mods,
sm.Where(ImportDistricts.Columns.Gid.EQ(psql.Arg(o.ImportDistrictGid))),
)...)
}
func (os OrganizationSlice) ImportDistrictGidDistrict(mods ...bob.Mod[*dialect.SelectQuery]) ImportDistrictsQuery {
pkImportDistrictGid := make(pgtypes.Array[null.Val[int32]], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkImportDistrictGid = append(pkImportDistrictGid, o.ImportDistrictGid)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkImportDistrictGid), "integer[]")),
))
return ImportDistricts.Query(append(mods,
sm.Where(psql.Group(ImportDistricts.Columns.Gid).OP("IN", PKArgExpr)),
)...)
}
// Nuisances starts a query for related objects on publicreport.nuisance
func (o *Organization) Nuisances(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportNuisancesQuery {
return PublicreportNuisances.Query(append(mods,
@ -3919,54 +4149,6 @@ func (organization0 *Organization) AttachNoteImages(ctx context.Context, exec bo
return nil
}
func attachOrganizationImportDistrictGidDistrict0(ctx context.Context, exec bob.Executor, count int, organization0 *Organization, importDistrict1 *ImportDistrict) (*Organization, error) {
setter := &OrganizationSetter{
ImportDistrictGid: omitnull.From(importDistrict1.Gid),
}
err := organization0.Update(ctx, exec, setter)
if err != nil {
return nil, fmt.Errorf("attachOrganizationImportDistrictGidDistrict0: %w", err)
}
return organization0, nil
}
func (organization0 *Organization) InsertImportDistrictGidDistrict(ctx context.Context, exec bob.Executor, related *ImportDistrictSetter) error {
var err error
importDistrict1, err := ImportDistricts.Insert(related).One(ctx, exec)
if err != nil {
return fmt.Errorf("inserting related objects: %w", err)
}
_, err = attachOrganizationImportDistrictGidDistrict0(ctx, exec, 1, organization0, importDistrict1)
if err != nil {
return err
}
organization0.R.ImportDistrictGidDistrict = importDistrict1
importDistrict1.R.ImportDistrictGidOrganization = organization0
return nil
}
func (organization0 *Organization) AttachImportDistrictGidDistrict(ctx context.Context, exec bob.Executor, importDistrict1 *ImportDistrict) error {
var err error
_, err = attachOrganizationImportDistrictGidDistrict0(ctx, exec, 1, organization0, importDistrict1)
if err != nil {
return err
}
organization0.R.ImportDistrictGidDistrict = importDistrict1
importDistrict1.R.ImportDistrictGidOrganization = organization0
return nil
}
func insertOrganizationNuisances0(ctx context.Context, exec bob.Executor, publicreportNuisances1 []*PublicreportNuisanceSetter, organization0 *Organization) (PublicreportNuisanceSlice, error) {
for i := range publicreportNuisances1 {
publicreportNuisances1[i].OrganizationID = omitnull.From(organization0.ID)
@ -4249,6 +4431,24 @@ type organizationWhere[Q psql.Filterable] struct {
Website psql.WhereNullMod[Q, string]
LogoUUID psql.WhereNullMod[Q, uuid.UUID]
Slug psql.WhereNullMod[Q, string]
GeneralManagerName psql.WhereNullMod[Q, string]
MailingAddressCity psql.WhereNullMod[Q, string]
MailingAddressPostalCode psql.WhereNullMod[Q, string]
MailingAddressStreet psql.WhereNullMod[Q, string]
OfficeAddressCity psql.WhereNullMod[Q, string]
OfficeAddressPostalCode psql.WhereNullMod[Q, string]
OfficeAddressStreet psql.WhereNullMod[Q, string]
ServiceAreaGeometry psql.WhereNullMod[Q, string]
ServiceAreaSquareMeters psql.WhereNullMod[Q, decimal.Decimal]
ServiceAreaCentroid psql.WhereNullMod[Q, string]
ServiceAreaExtent psql.WhereNullMod[Q, string]
OfficeFax psql.WhereNullMod[Q, string]
OfficePhone psql.WhereNullMod[Q, string]
ServiceAreaXmin psql.WhereNullMod[Q, float64]
ServiceAreaYmin psql.WhereNullMod[Q, float64]
ServiceAreaXmax psql.WhereNullMod[Q, float64]
ServiceAreaYmax psql.WhereNullMod[Q, float64]
ServiceAreaCentroidGeojson psql.WhereNullMod[Q, string]
}
func (organizationWhere[Q]) AliasedAs(alias string) organizationWhere[Q] {
@ -4266,6 +4466,24 @@ func buildOrganizationWhere[Q psql.Filterable](cols organizationColumns) organiz
Website: psql.WhereNull[Q, string](cols.Website),
LogoUUID: psql.WhereNull[Q, uuid.UUID](cols.LogoUUID),
Slug: psql.WhereNull[Q, string](cols.Slug),
GeneralManagerName: psql.WhereNull[Q, string](cols.GeneralManagerName),
MailingAddressCity: psql.WhereNull[Q, string](cols.MailingAddressCity),
MailingAddressPostalCode: psql.WhereNull[Q, string](cols.MailingAddressPostalCode),
MailingAddressStreet: psql.WhereNull[Q, string](cols.MailingAddressStreet),
OfficeAddressCity: psql.WhereNull[Q, string](cols.OfficeAddressCity),
OfficeAddressPostalCode: psql.WhereNull[Q, string](cols.OfficeAddressPostalCode),
OfficeAddressStreet: psql.WhereNull[Q, string](cols.OfficeAddressStreet),
ServiceAreaGeometry: psql.WhereNull[Q, string](cols.ServiceAreaGeometry),
ServiceAreaSquareMeters: psql.WhereNull[Q, decimal.Decimal](cols.ServiceAreaSquareMeters),
ServiceAreaCentroid: psql.WhereNull[Q, string](cols.ServiceAreaCentroid),
ServiceAreaExtent: psql.WhereNull[Q, string](cols.ServiceAreaExtent),
OfficeFax: psql.WhereNull[Q, string](cols.OfficeFax),
OfficePhone: psql.WhereNull[Q, string](cols.OfficePhone),
ServiceAreaXmin: psql.WhereNull[Q, float64](cols.ServiceAreaXmin),
ServiceAreaYmin: psql.WhereNull[Q, float64](cols.ServiceAreaYmin),
ServiceAreaXmax: psql.WhereNull[Q, float64](cols.ServiceAreaXmax),
ServiceAreaYmax: psql.WhereNull[Q, float64](cols.ServiceAreaYmax),
ServiceAreaCentroidGeojson: psql.WhereNull[Q, string](cols.ServiceAreaCentroidGeojson),
}
}
@ -4765,18 +4983,6 @@ func (o *Organization) Preload(name string, retrieved any) error {
}
}
return nil
case "ImportDistrictGidDistrict":
rel, ok := retrieved.(*ImportDistrict)
if !ok {
return fmt.Errorf("organization cannot load %T as %q", retrieved, name)
}
o.R.ImportDistrictGidDistrict = rel
if rel != nil {
rel.R.ImportDistrictGidOrganization = o
}
return nil
case "Nuisances":
rels, ok := retrieved.(PublicreportNuisanceSlice)
if !ok {
@ -4838,26 +5044,10 @@ func (o *Organization) Preload(name string, retrieved any) error {
}
}
type organizationPreloader struct {
ImportDistrictGidDistrict func(...psql.PreloadOption) psql.Preloader
}
type organizationPreloader struct{}
func buildOrganizationPreloader() organizationPreloader {
return organizationPreloader{
ImportDistrictGidDistrict: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*ImportDistrict, ImportDistrictSlice](psql.PreloadRel{
Name: "ImportDistrictGidDistrict",
Sides: []psql.PreloadSide{
{
From: Organizations,
To: ImportDistricts,
FromColumns: []string{"import_district_gid"},
ToColumns: []string{"gid"},
},
},
}, ImportDistricts.Columns.Names(), opts...)
},
}
return organizationPreloader{}
}
type organizationThenLoader[Q orm.Loadable] struct {
@ -4896,7 +5086,6 @@ type organizationThenLoader[Q orm.Loadable] struct {
H3Aggregations func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
NoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
NoteImages func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
ImportDistrictGidDistrict func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Nuisances func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
PublicreportPool func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Quicks func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
@ -5009,9 +5198,6 @@ func buildOrganizationThenLoader[Q orm.Loadable]() organizationThenLoader[Q] {
type NoteImagesLoadInterface interface {
LoadNoteImages(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type ImportDistrictGidDistrictLoadInterface interface {
LoadImportDistrictGidDistrict(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type NuisancesLoadInterface interface {
LoadNuisances(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -5236,12 +5422,6 @@ func buildOrganizationThenLoader[Q orm.Loadable]() organizationThenLoader[Q] {
return retrieved.LoadNoteImages(ctx, exec, mods...)
},
),
ImportDistrictGidDistrict: thenLoadBuilder[Q](
"ImportDistrictGidDistrict",
func(ctx context.Context, exec bob.Executor, retrieved ImportDistrictGidDistrictLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadImportDistrictGidDistrict(ctx, exec, mods...)
},
),
Nuisances: thenLoadBuilder[Q](
"Nuisances",
func(ctx context.Context, exec bob.Executor, retrieved NuisancesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -7444,61 +7624,6 @@ func (os OrganizationSlice) LoadNoteImages(ctx context.Context, exec bob.Executo
return nil
}
// LoadImportDistrictGidDistrict loads the organization's ImportDistrictGidDistrict into the .R struct
func (o *Organization) LoadImportDistrictGidDistrict(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.ImportDistrictGidDistrict = nil
related, err := o.ImportDistrictGidDistrict(mods...).One(ctx, exec)
if err != nil {
return err
}
related.R.ImportDistrictGidOrganization = o
o.R.ImportDistrictGidDistrict = related
return nil
}
// LoadImportDistrictGidDistrict loads the organization's ImportDistrictGidDistrict into the .R struct
func (os OrganizationSlice) LoadImportDistrictGidDistrict(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
importDistricts, err := os.ImportDistrictGidDistrict(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range importDistricts {
if !o.ImportDistrictGid.IsValue() {
continue
}
if !(o.ImportDistrictGid.IsValue() && o.ImportDistrictGid.MustGet() == rel.Gid) {
continue
}
rel.R.ImportDistrictGidOrganization = o
o.R.ImportDistrictGidDistrict = rel
break
}
}
return nil
}
// LoadNuisances loads the organization's Nuisances into the .R struct
func (o *Organization) LoadNuisances(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -10206,7 +10331,6 @@ type organizationJoins[Q dialect.Joinable] struct {
H3Aggregations modAs[Q, h3AggregationColumns]
NoteAudios modAs[Q, noteAudioColumns]
NoteImages modAs[Q, noteImageColumns]
ImportDistrictGidDistrict modAs[Q, importDistrictColumns]
Nuisances modAs[Q, publicreportNuisanceColumns]
PublicreportPool modAs[Q, publicreportPoolColumns]
Quicks modAs[Q, publicreportQuickColumns]
@ -10726,20 +10850,6 @@ func buildOrganizationJoins[Q dialect.Joinable](cols organizationColumns, typ st
return mods
},
},
ImportDistrictGidDistrict: modAs[Q, importDistrictColumns]{
c: ImportDistricts.Columns,
f: func(to importDistrictColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, ImportDistricts.Name().As(to.Alias())).On(
to.Gid.EQ(cols.ImportDistrictGid),
))
}
return mods
},
},
Nuisances: modAs[Q, publicreportNuisanceColumns]{
c: PublicreportNuisances.Columns,
f: func(to publicreportNuisanceColumns) bob.Mod[Q] {

View file

@ -1,5 +1,5 @@
// A test of maplibre-gl in a custom element
class MapDistrict extends HTMLElement {
class MapServiceArea extends HTMLElement {
constructor() {
super();
@ -31,7 +31,7 @@ class MapDistrict extends HTMLElement {
const apiKey = this.getAttribute("api-key");
const centroid = JSON.parse(this.getAttribute("centroid"));
const csv_file = this.getAttribute("csv-file");
const district_id = this.getAttribute("district-id");
const organization_id = this.getAttribute("organization-id");
const lat = Number(this.getAttribute("latitude") || 36.2);
const lng = Number(this.getAttribute("longitude") || -119.2);
const mapElement = this.shadowRoot.querySelector("#map");
@ -55,14 +55,12 @@ class MapDistrict extends HTMLElement {
this._map.on("load", () => {
this._map.addSource("tegola-nidus", {
type: "vector",
tiles: [
`${tegola}maps/district/{z}/{x}/{y}?district_id=${district_id}`,
],
tiles: [`${tegola}maps/nidus/{z}/{x}/{y}?id=${organization_id}`],
});
this._map.addLayer({
id: "bounds",
id: "service-area",
source: "tegola-nidus",
"source-layer": "bounds",
"source-layer": "service-area-bounds",
type: "fill",
paint: {
"fill-opacity": 0.4,
@ -132,4 +130,4 @@ class MapDistrict extends HTMLElement {
}
}
customElements.define("map-district", MapDistrict);
customElements.define("map-service-area", MapServiceArea);

View file

@ -6,7 +6,7 @@
type="text/javascript"
src="//unpkg.com/maplibre-gl@5.0.1/dist/maplibre-gl.js"
></script>
<script src="/static/js/map-district.js"></script>
<script src="/static/js/map-service-area.js"></script>
<style>
.settings-card {
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
@ -28,15 +28,18 @@
</button>
</div>
<map-district
district-id="{{ .District.GID }}"
centroid="{{ .District.Centroid|json }}"
xmin="{{ .District.XMin }}"
ymin="{{ .District.YMin }}"
xmax="{{ .District.XMax }}"
ymax="{{ .District.YMax }}"
{{ if .Organization.ServiceAreaCentroidGeojson.IsValue }}
<map-service-area
organization-id="{{ .Organization.ID }}"
centroid="{{ .Organization.ServiceAreaCentroidGeojson.MustGet|json }}"
xmin="{{ .Organization.ServiceAreaXmin.GetOr 0 }}"
ymin="{{ .Organization.ServiceAreaYmin.GetOr 0 }}"
xmax="{{ .Organization.ServiceAreaXmax.GetOr 0 }}"
ymax="{{ .Organization.ServiceAreaYmax.GetOr 0 }}"
tegola="{{ .URL.Tegola }}"
></map-district>
></map-service-area>
{{ end }}
<div class="row">
<!-- Basic Information -->
@ -55,8 +58,8 @@
<input
type="text"
class="form-control"
id="agencyName"
value="{{ .District.Agency }}"
id="name"
value="{{ .Organization.Name }}"
/>
</div>
<div class="mb-3">
@ -67,7 +70,7 @@
type="url"
class="form-control"
id="website"
value="{{ .District.Website }}"
value="{{ .Organization.Website.GetOr "" }}"
/>
</div>
<div class="mb-3">
@ -79,18 +82,7 @@
type="text"
class="form-control"
id="generalManager"
value="{{ .District.GeneralManager }}"
/>
</div>
<div class="mb-3">
<label for="contactPerson" class="form-label"
><i class="bi bi-person me-1"></i> Contact Person</label
>
<input
type="text"
class="form-control"
id="contactPerson"
value="{{ .District.Contact }}"
value="{{ .Organization.GeneralManagerName.GetOr "" }}"
/>
</div>
</div>
@ -108,13 +100,13 @@
<div class="card-body">
<div class="mb-3">
<label for="address" class="form-label"
><i class="bi bi-geo me-1"></i> Address</label
><i class="bi bi-geo me-1"></i> Street</label
>
<input
type="text"
class="form-control"
id="address"
value="{{ .District.Address }}"
value="{{ .Organization.OfficeAddressStreet.GetOr "" }}"
/>
</div>
<div class="row">
@ -126,7 +118,7 @@
type="text"
class="form-control"
id="city"
value="{{ .District.City1 }},{{ .District.City2 }}"
value="{{ .Organization.OfficeAddressCity.GetOr "" }}"
/>
</div>
<div class="col-md-6 mb-3">
@ -137,32 +129,19 @@
type="text"
class="form-control"
id="postalCode"
value="{{ .District.PostalCode }}"
value="{{ .Organization.OfficeAddressPostalCode.GetOr "" }}"
/>
</div>
</div>
<div class="mb-3">
<label for="phoneNumber" class="form-label"
><i class="bi bi-telephone me-1"></i> Phone Number
(Primary)</label
>
</label>
<input
type="tel"
class="form-control"
id="phoneNumber"
value="{{ .District.Phone1 }}"
/>
</div>
<div class="mb-3">
<label for="secondaryPhone" class="form-label"
><i class="bi bi-telephone-plus me-1"></i> Phone Number
(Secondary)</label
>
<input
type="tel"
class="form-control"
id="secondaryPhone"
value="{{ .District.Phone2 }}"
value="{{ .Organization.OfficePhone.GetOr "" }}"
/>
</div>
<div class="mb-3">
@ -173,18 +152,18 @@
type="tel"
class="form-control"
id="faxNumber"
value="{{ .District.Fax }}"
value="{{ .Organization.OfficeFax.GetOr "" }}"
/>
</div>
</div>
</div>
</div>
<!-- District Coverage Information -->
<!-- Organization Coverage Information -->
<div class="col-12">
<div class="card settings-card">
<div class="card-header bg-light">
<h5><i class="bi bi-map me-2"></i> District Coverage</h5>
<h5><i class="bi bi-map me-2"></i> Service Area Coverage</h5>
</div>
<div class="card-body">
<div class="row">
@ -197,7 +176,9 @@
type="number"
class="form-control"
id="totalArea"
value="{{ .District.SurfaceAreaMetersSquare }}"
value="{{ if .Organization.ServiceAreaSquareMeters.IsValue }}
{{ .Organization.ServiceAreaSquareMeters.MustGet }}
{{ end }}"
/>
</div>
</div>

View file

@ -86,23 +86,23 @@
</div>
</div>
<!-- District Card -->
<!-- Organization Card -->
<div class="col-12 col-md-6 col-lg-4">
<div class="card settings-card border-0 shadow-sm">
<div class="card-body p-4">
<div class="settings-icon icon-equipment">
<i class="bi bi-globe-europe-africa"></i>
</div>
<h2 class="h4 mb-2">District</h2>
<h2 class="h4 mb-2">Organization</h2>
<p class="text-muted mb-4">
Manage your district location and information.
Manage your organization service area and information.
</p>
<div class="d-flex justify-content-between align-items-center">
<a
href="{{ .URL.SettingDistrict }}"
href="{{ .URL.SettingOrganization }}"
class="btn btn-outline-danger"
>
Manage District
Manage Organization
<i class="bi bi-arrow-right ms-1"></i>
</a>
</div>

View file

@ -38,6 +38,7 @@
</div>
<form method="POST" action="/signin">
<input type="hidden" name="next" value="{{ .Next }}" />
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input

View file

@ -13,39 +13,24 @@ import (
"github.com/rs/zerolog/log"
)
func DistrictForLocation(ctx context.Context, lng float64, lat float64) (*models.ImportDistrict, *models.Organization, error) {
districts, err := models.ImportDistricts.Query(
func DistrictForLocation(ctx context.Context, lng float64, lat float64) (*models.Organization, error) {
organizations, err := models.Organizations.Query(
sm.Where(
psql.F("ST_Contains", psql.Raw("geom_4326"), psql.F("ST_SetSRID", psql.F("ST_MakePoint", psql.Arg(lng), psql.Arg(lat)), psql.Arg(4326))),
psql.F("ST_Contains", psql.Raw("service_area_geometry"), psql.F("ST_SetSRID", psql.F("ST_MakePoint", psql.Arg(lng), psql.Arg(lat)), psql.Arg(4326))),
),
).All(ctx, db.PGInstance.BobDB)
log.Debug().Int("len", len(districts)).Float64("lng", lng).Float64("lat", lat).Msg("Attempting district match")
log.Debug().Int("len", len(organizations)).Float64("lng", lng).Float64("lat", lat).Msg("Attempting district match")
if err != nil {
return nil, nil, fmt.Errorf("failed to query district: %w", err)
}
switch len(districts) {
case 0:
return nil, nil, nil
case 1:
district := districts[0]
organizations, err := models.Organizations.Query(
sm.Where(
models.Organizations.Columns.ImportDistrictGid.EQ(psql.Arg(district.Gid)),
),
).All(ctx, db.PGInstance.BobDB)
if err != nil {
return nil, nil, fmt.Errorf("failed to query organization: %w", err)
return nil, fmt.Errorf("failed to query organization: %w", err)
}
switch len(organizations) {
case 0:
return nil, nil, nil
return nil, nil
case 1:
return district, organizations[0], nil
org := organizations[0]
return org, nil
default:
return nil, nil, errors.New("too many organizations")
}
default:
return nil, nil, errors.New("too many districts")
return nil, errors.New("too many organizations")
}
}

View file

@ -64,7 +64,7 @@ func matchDistrict(ctx context.Context, longitude, latitude *float64, images []I
if image.Exif.GPS == nil {
continue
}
_, org, err = platform.DistrictForLocation(ctx, image.Exif.GPS.Longitude, image.Exif.GPS.Latitude)
org, err = platform.DistrictForLocation(ctx, image.Exif.GPS.Longitude, image.Exif.GPS.Latitude)
if err != nil {
log.Warn().Err(err).Msg("Failed to get district for location")
continue
@ -77,7 +77,7 @@ func matchDistrict(ctx context.Context, longitude, latitude *float64, images []I
log.Debug().Msg("No location from images, no latlng for the report itself, cannot match")
return nil, nil
}
_, org, err = platform.DistrictForLocation(ctx, *longitude, *latitude)
org, err = platform.DistrictForLocation(ctx, *longitude, *latitude)
if err != nil {
log.Warn().Err(err).Msg("Failed to get district for location")
return nil, fmt.Errorf("Failed to get district for location: %w", err)

View file

@ -1,31 +1,11 @@
package rmo
import (
"fmt"
"net/http"
"strconv"
"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/h3utils"
"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 ContentQuick struct{}
type ContentQuickSubmitComplete struct {
District *District
ReportID string
}
type ContentRegisterNotificationsComplete struct {
ReportID string
}
@ -34,52 +14,6 @@ type District struct {
Name string
}
func getQuick(w http.ResponseWriter, r *http.Request) {
html.RenderOrError(
w,
"rmo/quick.html",
ContentQuick{},
)
}
func getQuickSubmitComplete(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
report_id := r.URL.Query().Get("report")
report, err := models.PublicreportQuicks.Query(
models.SelectWhere.PublicreportQuicks.PublicID.EQ(report_id),
).One(ctx, db.PGInstance.BobDB)
if err != nil {
respondError(w, "Failed to get report", err, http.StatusInternalServerError)
return
}
var district *District
if !report.OrganizationID.IsNull() {
org_id := report.OrganizationID.MustGet()
org, err := models.Organizations.Query(
models.Preload.Organization.ImportDistrictGidDistrict(),
models.SelectWhere.Organizations.ID.EQ(org_id),
).One(ctx, db.PGInstance.BobDB)
if err != nil {
respondError(w, "Failed to get org", err, http.StatusInternalServerError)
return
}
d := org.R.ImportDistrictGidDistrict
log.Debug().Int32("org_id", org.ID).Int32("d_gid", d.Gid).Msg("Getting district")
if d != nil {
district = &District{
LogoURL: config.MakeURLNidus("/api/district/%s/logo", org.Slug.GetOr("placeholder")),
Name: d.Agency.GetOr("Unknown"),
}
}
}
html.RenderOrError(
w,
"rmo/quick-submit-complete.html",
ContentQuickSubmitComplete{
District: district,
ReportID: report.PublicID,
},
)
}
func getRegisterNotificationsComplete(w http.ResponseWriter, r *http.Request) {
report := r.URL.Query().Get("report")
html.RenderOrError(
@ -90,109 +24,3 @@ func getRegisterNotificationsComplete(w http.ResponseWriter, r *http.Request) {
},
)
}
func postQuick(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
}
lat := r.FormValue("latitude")
lng := r.FormValue("longitude")
comments := r.FormValue("comments")
var latitude float64
if lat != "" {
latitude, err = strconv.ParseFloat(lat, 64)
if err != nil {
respondError(w, "Failed to parse latitude", err, http.StatusBadRequest)
return
}
}
var longitude float64
if lng != "" {
longitude, err = strconv.ParseFloat(lng, 64)
if err != nil {
respondError(w, "Failed to parse longitude", err, http.StatusBadRequest)
return
}
}
u, err := report.GenerateReportID()
if err != nil {
respondError(w, "Failed to create quick 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)
log.Info().Int("len", len(uploads)).Msg("extracted uploads")
if err != nil {
respondError(w, "Failed to extract image uploads", err, http.StatusInternalServerError)
return
}
images, err := saveImageUploads(ctx, tx, uploads)
if err != nil {
respondError(w, "Failed to save image uploads", err, http.StatusInternalServerError)
return
}
organization_id, err := matchDistrict(ctx, &longitude, &latitude, uploads)
if err != nil {
log.Warn().Err(err).Msg("Failed to match district")
}
log.Info().Int("len", len(images)).Msg("saved uploads")
c, err := h3utils.GetCell(longitude, latitude, 15)
if err != nil {
respondError(w, "Failedt o get h3 cell", err, http.StatusInternalServerError)
}
setter := models.PublicreportQuickSetter{
Address: omit.From(""),
Created: omit.From(time.Now()),
Comments: omit.From(comments),
OrganizationID: omitnull.FromPtr(organization_id),
//Location: omitnull.From(fmt.Sprintf("ST_GeometryFromText(Point(%s %s))", longitude, latitude)),
H3cell: omitnull.From(c.String()),
PublicID: omit.From(u),
ReporterEmail: omit.From(""),
ReporterPhone: omit.From(""),
Status: omit.From(enums.PublicreportReportstatustypeReported),
}
quick, err := models.PublicreportQuicks.Insert(&setter).One(ctx, tx)
if err != nil {
respondError(w, "Failed to create database record", err, http.StatusInternalServerError)
return
}
_, err = psql.Update(
um.Table("publicreport.quick"),
um.SetCol("location").To(fmt.Sprintf("ST_GeometryFromText('Point(%f %f)')", longitude, latitude)),
um.Where(psql.Quote("id").EQ(psql.Arg(quick.ID))),
).Exec(ctx, tx)
if err != nil {
respondError(w, "Failed to insert publicreport", err, http.StatusInternalServerError)
return
}
log.Info().Float64("latitude", latitude).Float64("longitude", longitude).Msg("Got upload")
if len(images) > 0 {
setters := make([]*models.PublicreportQuickImageSetter, 0)
for _, image := range images {
setters = append(setters, &models.PublicreportQuickImageSetter{
ImageID: omit.From(int32(image.ID)),
QuickID: omit.From(int32(quick.ID)),
})
}
_, err = models.PublicreportQuickImages.Insert(bob.ToMods(setters...)).Exec(ctx, tx)
if err != nil {
respondError(w, "Failed to save reference to images", err, http.StatusInternalServerError)
return
}
log.Info().Int("len", len(images)).Msg("saved uploads")
}
tx.Commit(ctx)
http.Redirect(w, r, fmt.Sprintf("/quick-submit-complete?report=%s", u), http.StatusFound)
}

View file

@ -33,9 +33,6 @@ func Router() chi.Router {
r.Get("/email/unsubscribe/report/{report_id}", getEmailReportUnsubscribe)
r.Get("/image/{uuid}", getImageByUUID)
r.Route("/mock", addMockRoutes)
r.Get("/quick", getQuick)
r.Post("/quick-submit", postQuick)
r.Get("/quick-submit-complete", getQuickSubmitComplete)
r.Post("/register-notifications", postRegisterNotifications)
r.Get("/register-notifications-complete", getRegisterNotificationsComplete)
r.Get("/report/suggest", getReportSuggestion)

View file

@ -89,7 +89,7 @@ func getRoot(w http.ResponseWriter, r *http.Request) {
}
if user == nil {
errorCode := r.URL.Query().Get("error")
signin(w, errorCode)
signin(w, errorCode, "/")
return
} else {
has, err := background.HasFieldseekerConnection(r.Context(), user)

View file

@ -56,7 +56,7 @@ func Router() chi.Router {
r.Method("POST", "/pool/upload", auth.NewEnsureAuth(postPoolUpload))
r.Method("GET", "/radar", auth.NewEnsureAuth(getRadar))
r.Method("GET", "/setting", auth.NewEnsureAuth(getSetting))
r.Method("GET", "/setting/district", auth.NewEnsureAuth(getSettingDistrict))
r.Method("GET", "/setting/organization", auth.NewEnsureAuth(getSettingOrganization))
r.Method("GET", "/setting/integration", auth.NewEnsureAuth(getSettingIntegration))
r.Method("GET", "/setting/pesticide", authenticatedHandler(getSettingPesticide))
r.Method("GET", "/setting/pesticide/add", authenticatedHandler(getSettingPesticideAdd))

View file

@ -4,40 +4,15 @@ import (
"context"
"net/http"
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/sm"
"github.com/Gleipnir-Technology/nidus-sync/arcgis"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/html"
//"github.com/rs/zerolog/log"
"github.com/stephenafamo/scan"
)
type contentDistrict struct {
Address string `db:"address"`
Agency string `db:"agency"`
Centroid string `db:"st_asgeojson"`
Contact string `db:"contact"`
City1 string `db:"city1"`
City2 string `db:"city2"`
Fax string `db:"fax1"`
GID int32 `db:"gid"`
Phone1 string `db:"phone1"`
Phone2 string `db:"phone2"`
GeneralManager string `db:"general_mg"`
PostalCode string `db:"postal_c_1"`
ShapeArea string `db:"shape_area"`
SurfaceAreaMetersSquare string `db:"area_4326_sqm"`
Website string `db:"website"`
XMin float32 `db:"st_xmin"`
XMax float32 `db:"st_xmax"`
YMin float32 `db:"st_ymin"`
YMax float32 `db:"st_ymax"`
}
type contentSettingDistrict struct {
District contentDistrict
type contentSettingOrganization struct {
Organization *models.Organization
URL ContentURL
User User
}
@ -60,7 +35,7 @@ func getSetting(w http.ResponseWriter, r *http.Request, u *models.User) {
}
html.RenderOrError(w, "sync/settings.html", data)
}
func getSettingDistrict(w http.ResponseWriter, r *http.Request, u *models.User) {
func getSettingOrganization(w http.ResponseWriter, r *http.Request, u *models.User) {
ctx := r.Context()
userContent, err := contentForUser(ctx, u)
if err != nil {
@ -68,10 +43,8 @@ func getSettingDistrict(w http.ResponseWriter, r *http.Request, u *models.User)
return
}
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
/*
var district contentDistrict
gid := int32(0)
if org.ImportDistrictGid.IsValue() {
gid = org.ImportDistrictGid.MustGet()
district, err = bob.One[contentDistrict](ctx, db.PGInstance.BobDB, psql.Select(
sm.From("import.district"),
sm.Columns(
@ -100,13 +73,13 @@ func getSettingDistrict(w http.ResponseWriter, r *http.Request, u *models.User)
respondError(w, "Failed to get extents", err, http.StatusInternalServerError)
return
}
}
data := contentSettingDistrict{
District: district,
*/
data := contentSettingOrganization{
Organization: org,
URL: newContentURL(),
User: userContent,
}
html.RenderOrError(w, "sync/setting-district.html", data)
html.RenderOrError(w, "sync/setting-organization.html", data)
}
func getSettingIntegration(w http.ResponseWriter, r *http.Request, u *models.User) {
ctx := r.Context()

View file

@ -6,14 +6,22 @@ import (
"strings"
"github.com/Gleipnir-Technology/nidus-sync/auth"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/rs/zerolog/log"
)
type ContentSignin struct {
InvalidCredentials bool
Next string
}
type ContentSignup struct{}
func getSignin(w http.ResponseWriter, r *http.Request) {
errorCode := r.URL.Query().Get("error")
signin(w, errorCode)
next := r.URL.Query().Get("next")
signin(w, errorCode, next)
}
func getSignout(w http.ResponseWriter, r *http.Request, user *models.User) {
@ -31,10 +39,11 @@ func postSignin(w http.ResponseWriter, r *http.Request) {
return
}
next := r.FormValue("next")
username := r.FormValue("username")
password := r.FormValue("password")
log.Info().Str("username", username).Msg("HTML Signin")
log.Info().Str("username", username).Str("next", next).Msg("HTML Signin")
_, err := auth.SigninUser(r, username, password)
if err != nil {
@ -49,8 +58,11 @@ func postSignin(w http.ResponseWriter, r *http.Request) {
respondError(w, "Failed to signin user", err, http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/", http.StatusFound)
if next == "" {
next = "/"
}
location := config.MakeURLNidus(next)
http.Redirect(w, r, location, http.StatusFound)
}
func postSignup(w http.ResponseWriter, r *http.Request) {
@ -83,9 +95,13 @@ func postSignup(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusFound)
}
func signin(w http.ResponseWriter, errorCode string) {
func signin(w http.ResponseWriter, errorCode string, next string) {
if next == "" {
next = "/"
}
data := ContentSignin{
InvalidCredentials: errorCode == "invalid-credentials",
Next: next,
}
html.RenderOrError(w, "sync/signin.html", data)
}

View file

@ -60,10 +60,6 @@ type ContentDashboardLoading struct {
User User
}
type ContentSignin struct {
InvalidCredentials bool
}
type ContentSignup struct{}
type Inspection struct {
Action string
Date *time.Time

View file

@ -9,8 +9,8 @@ type ContentURL struct {
PoolCSVUpload string
SamplePoolCSV string
Setting string
SettingDistrict string
SettingIntegration string
SettingOrganization string
SettingPesticide string
SettingPesticideAdd string
SettingUser string
@ -24,8 +24,8 @@ func newContentURL() ContentURL {
PoolCSVUpload: config.MakeURLNidus("/pool/upload"),
SamplePoolCSV: config.MakeURLNidus("/static/file/sample-pool.csv"),
Setting: config.MakeURLNidus("/setting"),
SettingDistrict: config.MakeURLNidus("/setting/district"),
SettingIntegration: config.MakeURLNidus("/setting/integration"),
SettingOrganization: config.MakeURLNidus("/setting/organization"),
SettingPesticide: config.MakeURLNidus("/setting/pesticide"),
SettingPesticideAdd: config.MakeURLNidus("/setting/pesticide/add"),
SettingUser: config.MakeURLNidus("/setting/user"),

View file

@ -13,7 +13,7 @@ GRANT USAGE ON SCHEMA import TO "tegola";
GRANT USAGE ON SCHEMA publicreport TO "tegola";
GRANT SELECT ON fileupload.pool TO "tegola";
GRANT SELECT ON h3_aggregation to "tegola";
GRANT SELECT ON import.district TO "tegola";
GRANT SELECT ON organization TO "tegola";
GRANT SELECT ON publicreport.report_location TO "tegola";
GRANT ALL PRIVILEGES ON SCHEMA public TO $1;
-- do import of district data
@ -21,3 +21,20 @@ ALTER TABLE import.district ADD COLUMN geom_4326 geometry(MultiPolygon,4326) GEN
ALTER TABLE import.district ADD COLUMN centroid_4326 geometry(Point,4326) GENERATED ALWAYS AS (ST_Transform(ST_Centroid(geom), 4326)) STORED;
ALTER TABLE import.district ADD COLUMN extent_4326 geometry(Polygon,4326) GENERATED ALWAYS AS (ST_Transform(ST_Envelope(geom), 4326)) STORED;
ALTER TABLE import.district ADD COLUMN area_4326_sqm numeric GENERATED ALWAYS AS (ST_Area(ST_Transform(geom, 4326)::geography)) STORED;
UPDATE organization AS org
SET
website = dist.website,
general_manager_name = dist.general_mg,
mailing_address_city = dist.city2,
mailing_address_postal_code = dist.postal_c_1::text,
mailing_address_street = dist.address2,
office_address_city = dist.city1,
office_address_postal_code = dist.postal_cod::text,
office_address_street = dist.address,
office_phone = dist.phone1,
office_fax = dist.fax1,
service_area_geometry = dist.geom_4326
FROM import.district AS dist
WHERE org.import_district_gid = dist.gid;