95 lines
2.9 KiB
Go
95 lines
2.9 KiB
Go
package usecase
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/gofrs/uuid/v5"
|
|
|
|
"github.com/saveinmed/backend-go/internal/domain"
|
|
)
|
|
|
|
// CreateAddress generates an ID and persists a new address.
|
|
func (s *Service) CreateAddress(ctx context.Context, address *domain.Address) error {
|
|
// Auto-geocode based on ZIP and Street
|
|
if address.ZipCode != "" {
|
|
searchQuery := address.ZipCode + ", " + address.Street + ", " + address.City + ", " + address.State + ", Brazil"
|
|
lat, lon, err := s.mapbox.Geocode(searchQuery)
|
|
if err == nil {
|
|
address.Latitude = lat
|
|
address.Longitude = lon
|
|
}
|
|
}
|
|
|
|
address.ID = uuid.Must(uuid.NewV7())
|
|
return s.repo.CreateAddress(ctx, address)
|
|
}
|
|
|
|
// ListAddresses returns all addresses associated with an entity (user or company).
|
|
func (s *Service) ListAddresses(ctx context.Context, entityID uuid.UUID) ([]domain.Address, error) {
|
|
return s.repo.ListAddresses(ctx, entityID)
|
|
}
|
|
|
|
// UpdateAddress verifies ownership and persists address changes.
|
|
func (s *Service) UpdateAddress(ctx context.Context, addr *domain.Address, requester *domain.User) error {
|
|
existing, err := s.repo.GetAddress(ctx, addr.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if requester.Role != "Admin" && existing.EntityID != requester.ID && (requester.CompanyID == uuid.Nil || existing.EntityID != requester.CompanyID) {
|
|
return errors.New("unauthorized to update this address")
|
|
}
|
|
|
|
// If address details changed, re-geocode
|
|
if existing.ZipCode != addr.ZipCode || existing.Street != addr.Street || existing.Number != addr.Number {
|
|
searchQuery := addr.ZipCode + ", " + addr.Street + ", " + addr.City + ", " + addr.State + ", Brazil"
|
|
lat, lon, err := s.mapbox.Geocode(searchQuery)
|
|
if err == nil {
|
|
existing.Latitude = lat
|
|
existing.Longitude = lon
|
|
}
|
|
}
|
|
|
|
existing.Title = addr.Title
|
|
existing.ZipCode = addr.ZipCode
|
|
existing.Street = addr.Street
|
|
existing.Number = addr.Number
|
|
existing.Complement = addr.Complement
|
|
existing.District = addr.District
|
|
existing.City = addr.City
|
|
existing.State = addr.State
|
|
|
|
return s.repo.UpdateAddress(ctx, existing)
|
|
}
|
|
|
|
// DeleteAddress removes an address by ID.
|
|
func (s *Service) DeleteAddress(ctx context.Context, id uuid.UUID) error {
|
|
return s.repo.DeleteAddress(ctx, id)
|
|
}
|
|
|
|
// GeocodeAllAddresses resolves coordinates for all addresses missing them.
|
|
func (s *Service) GeocodeAllAddresses(ctx context.Context) (int, error) {
|
|
addresses, err := s.repo.ListAllAddresses(ctx)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
count := 0
|
|
for _, addr := range addresses {
|
|
if addr.Latitude == 0 && addr.Longitude == 0 {
|
|
searchQuery := addr.ZipCode + ", " + addr.Street + ", " + addr.City + ", " + addr.State + ", Brazil"
|
|
lat, lon, err := s.mapbox.Geocode(searchQuery)
|
|
if err == nil {
|
|
addr.Latitude = lat
|
|
addr.Longitude = lon
|
|
_ = s.repo.UpdateAddress(ctx, &addr)
|
|
count++
|
|
// Respect rate limits
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
}
|
|
}
|
|
|
|
return count, nil
|
|
}
|