2024-08-04 01:16:25 +07:00

166 lines
4.1 KiB
Go

package discovery
import (
"context"
"errors"
"furtuna-be/config"
"gorm.io/gorm"
"furtuna-be/internal/entity"
"furtuna-be/internal/repository"
)
const (
defaultLatitude = -6.2088
defaultLongitude = 106.8456
radius = 10000
)
type DiscoveryService struct {
repo repository.SiteRepository
cfg config.Discovery
product repository.Product
}
func NewDiscoveryService(repo repository.SiteRepository, cfg config.Discovery, product repository.Product) *DiscoveryService {
return &DiscoveryService{
repo: repo,
cfg: cfg,
product: product,
}
}
func (s *DiscoveryService) Home(ctx context.Context, search *entity.DiscoverySearch) (*entity.DiscoverySearchResp, error) {
if search.Lat == 0 || search.Long == 0 {
search.Lat = defaultLatitude
search.Long = defaultLongitude
}
siteProducts, err := s.repo.GetNearestSites(ctx, search.Lat, search.Long, radius)
if err != nil {
return nil, err
}
exploreDestinations := []entity.ExploreDestination{}
for _, exploreDestination := range s.cfg.ExploreDestinations {
exploreDestinations = append(exploreDestinations, entity.ExploreDestination{
Name: exploreDestination.Name,
ImageURL: exploreDestination.ImageURL,
})
}
exploreRegions := []entity.ExploreRegion{}
for _, exploreRegion := range s.cfg.ExploreRegions {
exploreRegions = append(exploreRegions, entity.ExploreRegion{
Name: exploreRegion.Name,
})
}
mustVisits := []entity.MustVisit{}
for _, siteProduct := range siteProducts {
mustVisits = append(mustVisits, entity.MustVisit{
Name: siteProduct.SiteName,
Price: siteProduct.ProductPrice,
Region: siteProduct.Region,
SiteID: siteProduct.SiteID,
ImageURL: siteProduct.Image,
})
}
response := &entity.DiscoverySearchResp{
ExploreRegions: exploreRegions,
ExploreDestinations: exploreDestinations,
MustVisit: mustVisits,
}
return response, nil
}
func (s *DiscoveryService) Search(ctx context.Context, search *entity.DiscoverySearch) (*entity.DiscoverySearchResp, int64, error) {
if search.Lat == 0 || search.Long == 0 {
search.Lat = defaultLatitude
search.Long = defaultLongitude
search.Radius = radius
}
siteProducts, total, err := s.repo.SearchSites(ctx, search)
if err != nil {
return nil, 0, err
}
exploreDestinations := []entity.ExploreDestination{}
for _, exploreDestination := range s.cfg.ExploreDestinations {
exploreDestinations = append(exploreDestinations, entity.ExploreDestination{
Name: exploreDestination.Name,
ImageURL: exploreDestination.ImageURL,
})
}
exploreRegions := []entity.ExploreRegion{}
for _, exploreRegion := range s.cfg.ExploreRegions {
exploreRegions = append(exploreRegions, entity.ExploreRegion{
Name: exploreRegion.Name,
})
}
mustVisits := []entity.MustVisit{}
for _, siteProduct := range siteProducts {
mustVisits = append(mustVisits, entity.MustVisit{
Name: siteProduct.SiteName,
Price: siteProduct.ProductPrice,
Region: siteProduct.Region,
SiteID: siteProduct.SiteID,
ImageURL: siteProduct.Image,
Regency: siteProduct.Regency,
})
}
response := &entity.DiscoverySearchResp{
ExploreRegions: exploreRegions,
ExploreDestinations: exploreDestinations,
MustVisit: mustVisits,
}
return response, total, nil
}
func (s *DiscoveryService) GetByID(ctx context.Context, id int64) (*entity.Site, error) {
site, err := s.repo.GetByID(ctx, id)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
if site.Status == "Inactive" {
return nil, nil
}
return site.ToSite(), nil
}
func (s *DiscoveryService) GetProductsByID(ctx context.Context, id int64) ([]*entity.Product, error) {
site, err := s.repo.GetByID(ctx, id)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
if site.Status == "Inactive" {
return nil, nil
}
product, err := s.product.GetProductsBySiteID(ctx, site.ID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return product.ToProductList(), nil
}