diff --git a/platform/lead.go b/platform/lead.go index 3ec2c209..fad130ad 100644 --- a/platform/lead.go +++ b/platform/lead.go @@ -5,13 +5,11 @@ import ( "fmt" "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/db" "github.com/Gleipnir-Technology/nidus-sync/db/enums" "github.com/Gleipnir-Technology/nidus-sync/db/models" - "github.com/Gleipnir-Technology/nidus-sync/platform/geocode" "github.com/Gleipnir-Technology/nidus-sync/platform/geom" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" @@ -63,42 +61,3 @@ func LeadCreate(ctx context.Context, user User, signal_id int32, site_id int32, txn.Commit(ctx) return &lead.ID, nil } - -func siteFromAddress(ctx context.Context, txn bob.Tx, user User, address_id int32) (*models.Site, error) { - site, err := models.Sites.Query( - models.SelectWhere.Sites.AddressID.EQ(address_id), - models.SelectWhere.Sites.OrganizationID.EQ(user.Organization.ID()), - ).One(ctx, txn) - if err == nil { - return site, nil - } - if err.Error() != "sql: no rows in result set" { - return nil, fmt.Errorf("query site: %w", err) - } - return SiteCreate(ctx, txn, user, address_id) -} -func siteFromAddressRaw(ctx context.Context, txn bob.Tx, user User, address string) (*models.Site, error) { - // Geocode - geo, err := geocode.GeocodeRaw(ctx, user.Organization.model, address) - if err != nil { - return nil, fmt.Errorf("geocode: %w", err) - } - a, err := geocode.EnsureAddress(ctx, txn, geo.Address, geo.Location) - if err != nil { - return nil, fmt.Errorf("ensure address: %w", err) - } - return siteFromAddress(ctx, txn, user, a.ID) -} -func siteFromLocation(ctx context.Context, txn bob.Tx, user User, location Location) (*models.Site, error) { - // Reverse geocode at the location - resp, err := geocode.ReverseGeocode(ctx, location) - if err != nil { - return nil, fmt.Errorf("reverse geocode: %w", err) - } - // Ensure we have an address at that newly created location - a, err := geocode.EnsureAddress(ctx, txn, resp.Address, resp.Location) - if err != nil { - return nil, fmt.Errorf("ensure address: %w", err) - } - return siteFromAddress(ctx, txn, user, a.ID) -} diff --git a/platform/signal.go b/platform/signal.go index 279ad0b8..383b1875 100644 --- a/platform/signal.go +++ b/platform/signal.go @@ -20,8 +20,8 @@ import ( //"github.com/Gleipnir-Technology/nidus-sync/platform/geom" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" + "github.com/rs/zerolog/log" "github.com/stephenafamo/scan" - //"github.com/rs/zerolog/log" ) type Signal struct { @@ -56,22 +56,33 @@ func SignalCreateFromPublicreport(ctx context.Context, user User, report_id stri // At this point we have a report. We need to decide where to put it based on either the address or // the location. var site_id int32 + var location string if report.AddressID.IsValue() { - site, err := siteFromAddress(ctx, txn, user, report.AddressID.MustGet()) + address_id := report.AddressID.MustGet() + address, err := models.FindAddress(ctx, txn, address_id) + if err != nil { + return nil, fmt.Errorf("find address: %w", err) + } + site, err := siteFromAddress(ctx, txn, user, address_id) if err != nil { return nil, fmt.Errorf("site from address: %w", err) } site_id = site.ID + lat := address.LocationX.GetOr(0.0) + lng := address.LocationX.GetOr(0.0) + location = fmt.Sprintf("POINT(%f %f)", lng, lat) } else if report.LocationLatitude.IsValue() && report.LocationLongitude.IsValue() { + lat := report.LocationLatitude.MustGet() + lng := report.LocationLongitude.MustGet() site, err := siteFromLocation(ctx, txn, user, Location{ - Latitude: report.LocationLatitude.MustGet(), - Longitude: report.LocationLongitude.MustGet(), + Latitude: lat, + Longitude: lng, }) if err != nil { return nil, fmt.Errorf("site from address: %w", err) } site_id = site.ID - + location = fmt.Sprintf("POINT(%f %f)", lng, lat) } else if report.AddressRaw != "" { // At this point we don't have an address, and we don't have GPS // We'll try geocoding and creating an address from that. @@ -79,11 +90,18 @@ func SignalCreateFromPublicreport(ctx context.Context, user User, report_id stri if err != nil { return nil, fmt.Errorf("site from address: %w", err) } + address, err := models.FindAddress(ctx, txn, site.AddressID) + if err != nil { + return nil, fmt.Errorf("find address from raw: %w", err) + } site_id = site.ID + lat := address.LocationX.GetOr(0.0) + lng := address.LocationX.GetOr(0.0) + location = fmt.Sprintf("POINT(%f %f)", lng, lat) } else { // We have no structured address, no GPS, no unstructued address. // There's really nothing we can make this lead from and have it be meaningful - return nil, errors.New("Refusing to create a lead with no location data.") + return nil, errors.New("Refusing to create a signal with no location data.") } var signal_type enums.Signaltype @@ -95,6 +113,7 @@ func SignalCreateFromPublicreport(ctx context.Context, user User, report_id stri default: return nil, fmt.Errorf("Unrecognized report type %s", string(report.ReportType)) } + log.Debug().Str("location", location).Msg("inserting signal") signal, err := models.Signals.Insert(&models.SignalSetter{ Addressed: omitnull.FromPtr[time.Time](nil), Addressor: omitnull.FromPtr[int32](nil), @@ -102,6 +121,7 @@ func SignalCreateFromPublicreport(ctx context.Context, user User, report_id stri Creator: omit.From(int32(user.ID)), // ID OrganizationID: omit.From(int32(user.Organization.ID())), + Location: omit.From(location), Species: omitnull.FromPtr[enums.Mosquitospecies](nil), SiteID: omitnull.From(site_id), Title: omit.From[string](""), @@ -160,13 +180,7 @@ func SignalList(ctx context.Context, user User, limit int) ([]Signal, error) { sm.Where(psql.Quote("signal", "addressed").IsNull()), sm.Limit(limit), ), scan.StructMapper[Signal]()) - - /* - rows, err := models.Signals.Query( - models.SelectWhere.Signals.OrganizationID.EQ(org.ID()), - sm.OrderBy("created").Desc(), - ).All(ctx, db.PGInstance.BobDB) - */ + log.Debug().Int("len", len(rows)).Msg("got signals") if err != nil { return nil, fmt.Errorf("failed to get signals: %w", err) } diff --git a/platform/site.go b/platform/site.go index 20c863b2..876ee9fb 100644 --- a/platform/site.go +++ b/platform/site.go @@ -13,6 +13,7 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/models" nhttp "github.com/Gleipnir-Technology/nidus-sync/http" + "github.com/Gleipnir-Technology/nidus-sync/platform/geocode" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" "github.com/stephenafamo/scan" @@ -62,3 +63,41 @@ func SiteCreate(ctx context.Context, txn bob.Tx, user User, address_id int32) (* Version: omit.From(int32(1)), }).One(ctx, txn) } +func siteFromAddress(ctx context.Context, txn bob.Tx, user User, address_id int32) (*models.Site, error) { + site, err := models.Sites.Query( + models.SelectWhere.Sites.AddressID.EQ(address_id), + models.SelectWhere.Sites.OrganizationID.EQ(user.Organization.ID()), + ).One(ctx, txn) + if err == nil { + return site, nil + } + if err.Error() != "sql: no rows in result set" { + return nil, fmt.Errorf("query site: %w", err) + } + return SiteCreate(ctx, txn, user, address_id) +} +func siteFromAddressRaw(ctx context.Context, txn bob.Tx, user User, address string) (*models.Site, error) { + // Geocode + geo, err := geocode.GeocodeRaw(ctx, user.Organization.model, address) + if err != nil { + return nil, fmt.Errorf("geocode: %w", err) + } + a, err := geocode.EnsureAddress(ctx, txn, geo.Address, geo.Location) + if err != nil { + return nil, fmt.Errorf("ensure address: %w", err) + } + return siteFromAddress(ctx, txn, user, a.ID) +} +func siteFromLocation(ctx context.Context, txn bob.Tx, user User, location Location) (*models.Site, error) { + // Reverse geocode at the location + resp, err := geocode.ReverseGeocode(ctx, location) + if err != nil { + return nil, fmt.Errorf("reverse geocode: %w", err) + } + // Ensure we have an address at that newly created location + a, err := geocode.EnsureAddress(ctx, txn, resp.Address, resp.Location) + if err != nil { + return nil, fmt.Errorf("ensure address: %w", err) + } + return siteFromAddress(ctx, txn, user, a.ID) +}