diff --git a/internal/db/db.go b/internal/db/db.go index b02168c..57a62ea 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -20,11 +20,12 @@ func InitDb(dsn string) (*gorm.DB, error) { if err == nil { db.AutoMigrate( - &models.User{}, - &models.Interest{}, &models.AvailableFlight{}, - &models.Offer{}, + &models.Interest{}, &models.Journey{}, + &models.Offer{}, + &models.Rent{}, + &models.User{}, ) } diff --git a/internal/handlers/acmesky/tm_compute_distance_user_airport.go b/internal/handlers/acmesky/tm_compute_distance_user_airport.go index 43d94cc..97196a3 100644 --- a/internal/handlers/acmesky/tm_compute_distance_user_airport.go +++ b/internal/handlers/acmesky/tm_compute_distance_user_airport.go @@ -84,7 +84,7 @@ func TMComputeDistanceUserAirport(client worker.JobClient, job entities.Job) { return } variables["distance"] = distance.GetDistance() / 1000 - log.Info("[%s] [%d] Found a distance of: %d km", job.Type, jobKey, variables["distance"]) + log.Infof("[%s] [%d] Found a distance of: %d km", job.Type, jobKey, variables["distance"]) request, err := client.NewCompleteJobCommand().JobKey(jobKey).VariablesFromMap(variables) if err != nil { diff --git a/internal/handlers/acmesky/tm_find_nearest_available_rent_company.go b/internal/handlers/acmesky/tm_find_nearest_available_rent_company.go index a0bc1aa..3d3c877 100644 --- a/internal/handlers/acmesky/tm_find_nearest_available_rent_company.go +++ b/internal/handlers/acmesky/tm_find_nearest_available_rent_company.go @@ -2,13 +2,22 @@ package handlers import ( "context" + "time" + "github.com/charmbracelet/log" + pb "github.com/acme-sky/geodistance-api/pkg/distance/proto" + "github.com/acme-sky/workers/internal/config" + "github.com/acme-sky/workers/internal/db" acmejob "github.com/acme-sky/workers/internal/job" + "github.com/acme-sky/workers/internal/models" "github.com/camunda/zeebe/clients/go/v8/pkg/entities" "github.com/camunda/zeebe/clients/go/v8/pkg/worker" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) +// Task used to find the nearest rent company to the user' address func TMFindNearestAvailableRentCompany(client worker.JobClient, job entities.Job) { jobKey := job.GetKey() @@ -18,15 +27,88 @@ func TMFindNearestAvailableRentCompany(client worker.JobClient, job entities.Job return } - request, err := client.NewCompleteJobCommand().JobKey(jobKey).VariablesFromMap(variables) + db, _ := db.GetDb() + var offer models.Offer + + if err := db.Where("id = ?", int(variables["offer_id"].(float64))).Preload("User").Preload("Journey").Preload("Journey.Flight1").First(&offer).Error; err != nil { + log.Errorf("[%s] [%d] Error on getting offer %s", job.Type, jobKey, err.Error()) + } + + if offer.User.Address == nil { + log.Warnf("[%s] [%d] User does not have an address", job.Type, jobKey) + acmejob.FailJob(client, job) + return + } + + conf, _ := config.GetConfig() + + conn, err := grpc.Dial(conf.String("geodistance.api"), grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { + log.Errorf("[%s] [%d] Can't connect to Geodistance url: %s", job.Type, jobKey, err.Error()) acmejob.FailJob(client, job) return } - log.Debug("Processing data:", variables) + defer conn.Close() + c := pb.NewDistanceClient(conn) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + userGeometry, err := c.FindGeometry(ctx, &pb.AddressRequest{ + Address: *offer.User.Address, + }) + if err != nil { + log.Errorf("[%s] [%d] Can't find geometry for user: %s", job.Type, jobKey, err.Error()) + acmejob.FailJob(client, job) + return + } + + var rents []models.Rent + if err := db.Find(&rents).Error; err != nil { + log.Errorf("[%s] [%d] Rents not found %s", job.Type, jobKey, err.Error()) + acmejob.FailJob(client, job) + return + } + var distances []int + + for _, rent := range rents { + distance, err := c.FindDistance(ctx, &pb.DistanceRequest{ + Origin: &pb.MapPosition{Latitude: userGeometry.Latitude, Longitude: userGeometry.Longitude}, + Destination: &pb.MapPosition{Latitude: rent.Latitude, Longitude: rent.Longitude}, + }) + if err != nil { + log.Warn("[%s] [%d] Can't find distance for %s: %s", job.Type, jobKey, rent.Name, err.Error()) + distances = append(distances, 9999999) + continue + } + distances = append(distances, int(distance.GetDistance())) + } + + if len(distances) == 0 { + log.Errorf("[%s] [%d] There is no available rent company: %s", job.Type, jobKey, err.Error()) + acmejob.FailJob(client, job) + return + } + + var selectRentIndex = 0 + var minRentDistance = distances[0] + for i := 1; i < len(distances); { + if distances[i] < minRentDistance { + minRentDistance = distances[i] + selectRentIndex = i + } + } + + variables["rent_company"] = rents[selectRentIndex] + + request, err := client.NewCompleteJobCommand().JobKey(jobKey).VariablesFromMap(variables) + if err != nil { + acmejob.FailJob(client, job) + return + } - ctx := context.Background() + ctx = context.Background() _, err = request.Send(ctx) if err != nil { acmejob.FailJob(client, job) diff --git a/internal/models/rent.go b/internal/models/rent.go new file mode 100644 index 0000000..103cf6c --- /dev/null +++ b/internal/models/rent.go @@ -0,0 +1,15 @@ +package models + +import ( + "time" +) + +// Rent model +type Rent struct { + Id uint `gorm:"column:id" json:"id"` + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + Name string `gorm:"name" json:"name"` + Latitude float32 `gorm:"latitude" json:"latitude"` + Longitude float32 `gorm:"longitude" json:"longitude"` + Endpoint string `gorm:"endpoint" json:"endpoint"` +}