MIF_E31222379_BE/internal/services/collector_service.go

225 lines
6.5 KiB
Go

package services
import (
"context"
"errors"
"rijig/dto"
"rijig/internal/repositories"
"rijig/model"
)
type CollectorService interface {
CreateCollector(ctx context.Context, userID string, req dto.RequestCollectorDTO) error
AddTrashToCollector(ctx context.Context, collectorID string, req dto.RequestAddAvaibleTrash) error
GetCollectorByID(ctx context.Context, collectorID string) (*dto.ResponseCollectorDTO, error)
GetCollectorByUserID(ctx context.Context, userID string) (*dto.ResponseCollectorDTO, error)
UpdateCollector(ctx context.Context, collectorID string, jobStatus *string, rating float32, addressID string) error
UpdateAvaibleTrashByCollector(ctx context.Context, collectorID string, updatedTrash []dto.RequestAvaibleTrashbyCollector) error
DeleteAvaibleTrash(ctx context.Context, trashID string) error
}
type collectorService struct {
repo repositories.CollectorRepository
trashRepo repositories.TrashRepository
}
func NewCollectorService(repo repositories.CollectorRepository, trashRepo repositories.TrashRepository,
) CollectorService {
return &collectorService{repo: repo, trashRepo: trashRepo}
}
func (s *collectorService) CreateCollector(ctx context.Context, userID string, req dto.RequestCollectorDTO) error {
collector := &model.Collector{
UserID: userID,
AddressID: req.AddressId,
JobStatus: "inactive",
Rating: 5,
}
if err := s.repo.CreateCollector(ctx, collector); err != nil {
return err
}
var trashItems []model.AvaibleTrashByCollector
for _, item := range req.AvaibleTrashbyCollector {
trashItems = append(trashItems, model.AvaibleTrashByCollector{
CollectorID: collector.ID,
TrashCategoryID: item.TrashId,
Price: item.TrashPrice,
})
}
if err := s.repo.AddAvaibleTrash(ctx, trashItems); err != nil {
return err
}
for _, t := range trashItems {
_ = s.trashRepo.UpdateEstimatedPrice(ctx, t.TrashCategoryID)
}
return nil
}
func (s *collectorService) AddTrashToCollector(ctx context.Context, collectorID string, req dto.RequestAddAvaibleTrash) error {
var trashItems []model.AvaibleTrashByCollector
for _, item := range req.AvaibleTrash {
trashItems = append(trashItems, model.AvaibleTrashByCollector{
CollectorID: collectorID,
TrashCategoryID: item.TrashId,
Price: item.TrashPrice,
})
}
if err := s.repo.AddAvaibleTrash(ctx, trashItems); err != nil {
return err
}
for _, t := range trashItems {
_ = s.trashRepo.UpdateEstimatedPrice(ctx, t.TrashCategoryID)
}
return nil
}
func (s *collectorService) GetCollectorByID(ctx context.Context, collectorID string) (*dto.ResponseCollectorDTO, error) {
collector, err := s.repo.GetCollectorByID(ctx, collectorID)
if err != nil {
return nil, err
}
response := &dto.ResponseCollectorDTO{
ID: collector.ID,
UserId: collector.UserID,
AddressId: collector.AddressID,
JobStatus: &collector.JobStatus,
Rating: collector.Rating,
User: &dto.UserResponseDTO{
ID: collector.User.ID,
Name: collector.User.Name,
Phone: collector.User.Phone,
},
Address: &dto.AddressResponseDTO{
Province: collector.Address.Province,
District: collector.Address.District,
Regency: collector.Address.Regency,
Village: collector.Address.Village,
PostalCode: collector.Address.PostalCode,
Latitude: collector.Address.Latitude,
Longitude: collector.Address.Longitude,
},
}
for _, item := range collector.AvaibleTrashByCollector {
response.AvaibleTrashbyCollector = append(response.AvaibleTrashbyCollector, dto.ResponseAvaibleTrashByCollector{
ID: item.ID,
TrashId: item.TrashCategory.ID,
TrashName: item.TrashCategory.Name,
TrashIcon: item.TrashCategory.Icon,
TrashPrice: item.Price,
})
}
return response, nil
}
func (s *collectorService) GetCollectorByUserID(ctx context.Context, userID string) (*dto.ResponseCollectorDTO, error) {
collector, err := s.repo.GetCollectorByUserID(ctx, userID)
if err != nil {
return nil, err
}
response := &dto.ResponseCollectorDTO{
ID: collector.ID,
UserId: collector.UserID,
AddressId: collector.AddressID,
JobStatus: &collector.JobStatus,
Rating: collector.Rating,
User: &dto.UserResponseDTO{
ID: collector.User.ID,
Name: collector.User.Name,
Phone: collector.User.Phone,
},
Address: &dto.AddressResponseDTO{
Province: collector.Address.Province,
District: collector.Address.District,
Regency: collector.Address.Regency,
Village: collector.Address.Village,
PostalCode: collector.Address.PostalCode,
Latitude: collector.Address.Latitude,
Longitude: collector.Address.Longitude,
},
}
for _, item := range collector.AvaibleTrashByCollector {
response.AvaibleTrashbyCollector = append(response.AvaibleTrashbyCollector, dto.ResponseAvaibleTrashByCollector{
ID: item.ID,
TrashId: item.TrashCategory.ID,
TrashName: item.TrashCategory.Name,
TrashIcon: item.TrashCategory.Icon,
TrashPrice: item.Price,
})
}
return response, nil
}
func (s *collectorService) UpdateCollector(ctx context.Context, collectorID string, jobStatus *string, rating float32, addressID string) error {
updates := make(map[string]interface{})
if jobStatus != nil {
updates["job_status"] = *jobStatus
}
if rating > 0 {
updates["rating"] = rating
}
if addressID != "" {
updates["address_id"] = addressID
}
if len(updates) == 0 {
return errors.New("tidak ada data yang diubah")
}
return s.repo.UpdateCollector(ctx, &model.Collector{ID: collectorID}, updates)
}
func (s *collectorService) UpdateAvaibleTrashByCollector(ctx context.Context, collectorID string, updatedTrash []dto.RequestAvaibleTrashbyCollector) error {
var updated []model.AvaibleTrashByCollector
for _, item := range updatedTrash {
updated = append(updated, model.AvaibleTrashByCollector{
CollectorID: collectorID,
TrashCategoryID: item.TrashId,
Price: item.TrashPrice,
})
}
if err := s.repo.UpdateAvaibleTrashByCollector(ctx, collectorID, updated); err != nil {
return err
}
for _, item := range updated {
_ = s.trashRepo.UpdateEstimatedPrice(ctx, item.TrashCategoryID)
}
return nil
}
func (s *collectorService) DeleteAvaibleTrash(ctx context.Context, trashID string) error {
if trashID == "" {
return errors.New("trash_id tidak boleh kosong")
}
item, err := s.repo.GetTrashItemByID(ctx, trashID)
if err != nil {
return err
}
if err := s.repo.DeleteAvaibleTrash(ctx, trashID); err != nil {
return err
}
return s.trashRepo.UpdateEstimatedPrice(ctx, item.TrashCategoryID)
}