MIF_E31222379_BE/internal/services/collector_service.go

109 lines
3.3 KiB
Go

package services
import (
"fmt"
"rijig/dto"
"rijig/internal/repositories"
"rijig/utils"
)
type CollectorService interface {
FindCollectorsNearby(userId string) ([]dto.ResponseCollectorDTO, error)
ConfirmRequestPickup(requestId, collectorId string) (*dto.ResponseRequestPickup, error)
}
type collectorService struct {
repo repositories.CollectorRepository
repoReq repositories.RequestPickupRepository
repoAddress repositories.AddressRepository
}
func NewCollectorService(repo repositories.CollectorRepository,
repoReq repositories.RequestPickupRepository,
repoAddress repositories.AddressRepository) CollectorService {
return &collectorService{repo: repo, repoReq: repoReq, repoAddress: repoAddress}
}
func (s *collectorService) FindCollectorsNearby(userId string) ([]dto.ResponseCollectorDTO, error) {
collectors, err := s.repo.FindActiveCollectors()
if err != nil {
return nil, fmt.Errorf("error fetching active collectors: %v", err)
}
request, err := s.repoReq.FindRequestPickupByAddressAndStatus(userId, "waiting_collector")
if err != nil {
return nil, fmt.Errorf("gagal mendapatkan data request pickup dengan userid: %v", err)
}
reqpickaddress, err := s.repoAddress.FindAddressByID(request.AddressId)
if err != nil {
return nil, fmt.Errorf("error fetching address for request pickup %s: %v", request.ID, err)
}
var nearbyCollectorsResponse []dto.ResponseCollectorDTO
var maxDistance = 10.0
for _, collector := range collectors {
address, err := s.repoAddress.FindAddressByID(collector.AddressId)
if err != nil {
return nil, fmt.Errorf("error fetching address for collector %s: %v", collector.ID, err)
}
collectorCoord := utils.Coord{Lat: reqpickaddress.Latitude, Lon: reqpickaddress.Longitude}
userCoord := utils.Coord{Lat: address.Latitude, Lon: address.Longitude}
_, km := utils.Distance(collectorCoord, userCoord)
if km <= maxDistance {
nearbyCollectorsResponse = append(nearbyCollectorsResponse, dto.ResponseCollectorDTO{
ID: collector.ID,
AddressId: collector.User.Name,
Rating: collector.Rating,
})
}
}
if len(nearbyCollectorsResponse) == 0 {
return nil, fmt.Errorf("no request pickups found within %v km", maxDistance)
}
return nearbyCollectorsResponse, nil
}
func (s *collectorService) ConfirmRequestPickup(requestId, collectorId string) (*dto.ResponseRequestPickup, error) {
request, err := s.repoReq.FindRequestPickupByID(requestId)
if err != nil {
return nil, fmt.Errorf("request pickup not found: %v", err)
}
if request.StatusPickup != "waiting_collector" {
return nil, fmt.Errorf("pickup request is not in 'waiting_collector' status")
}
collector, err := s.repo.FindCollectorById(collectorId)
if err != nil {
return nil, fmt.Errorf("collector tidak ditemukan: %v", err)
}
request.StatusPickup = "confirmed"
request.CollectorID = &collector.ID
err = s.repoReq.UpdateRequestPickup(requestId, request)
if err != nil {
return nil, fmt.Errorf("failed to update request pickup: %v", err)
}
confirmedAt, _ := utils.FormatDateToIndonesianFormat(request.ConfirmedByCollectorAt)
response := dto.ResponseRequestPickup{
StatusPickup: request.StatusPickup,
CollectorID: *request.CollectorID,
ConfirmedByCollectorAt: confirmedAt,
}
return &response, nil
}