saveinmed/backend/internal/usecase/company_usecase.go
caio-machado-dev bf85072bff chore: remove legacy services and restructure monorepo
- remove backend-old (Medusa), saveinmed-frontend (Next.js/Appwrite) and marketplace dirs
- split Go usecases by domain and move notifications/payments to infrastructure
- reorganize frontend pages into auth, dashboard and marketplace modules
- add Makefile, docker-compose.yml and architecture docs
2026-02-25 16:51:34 -03:00

131 lines
3.8 KiB
Go

package usecase
import (
"context"
"errors"
"math"
"github.com/gofrs/uuid/v5"
"github.com/saveinmed/backend-go/internal/domain"
)
// RegisterCompany persists a new company and sets a new UUID.
func (s *Service) RegisterCompany(ctx context.Context, company *domain.Company) error {
company.ID = uuid.Must(uuid.NewV7())
return s.repo.CreateCompany(ctx, company)
}
// ListCompanies returns a paginated list of companies matching the filter.
func (s *Service) ListCompanies(ctx context.Context, filter domain.CompanyFilter, page, pageSize int) (*domain.CompanyPage, error) {
if pageSize <= 0 {
pageSize = 20
}
if page <= 0 {
page = 1
}
filter.Limit = pageSize
filter.Offset = (page - 1) * pageSize
companies, total, err := s.repo.ListCompanies(ctx, filter)
if err != nil {
return nil, err
}
return &domain.CompanyPage{Companies: companies, Total: total, Page: page, PageSize: pageSize}, nil
}
// GetCompany retrieves a company by ID.
func (s *Service) GetCompany(ctx context.Context, id uuid.UUID) (*domain.Company, error) {
return s.repo.GetCompany(ctx, id)
}
// UpdateCompany persists changes to an existing company.
func (s *Service) UpdateCompany(ctx context.Context, company *domain.Company) error {
return s.repo.UpdateCompany(ctx, company)
}
// DeleteCompany removes a company by ID.
func (s *Service) DeleteCompany(ctx context.Context, id uuid.UUID) error {
return s.repo.DeleteCompany(ctx, id)
}
// VerifyCompany marks the company account as KYC-verified.
func (s *Service) VerifyCompany(ctx context.Context, id uuid.UUID) (*domain.Company, error) {
company, err := s.repo.GetCompany(ctx, id)
if err != nil {
return nil, err
}
company.IsVerified = true
if err := s.repo.UpdateCompany(ctx, company); err != nil {
return nil, err
}
return company, nil
}
// CalculateShippingOptions returns available delivery/pickup options for a vendor,
// based on the buyer's location and cart total.
func (s *Service) CalculateShippingOptions(ctx context.Context, vendorID uuid.UUID, buyerLat, buyerLng float64, cartTotalCents int64) ([]domain.ShippingOption, error) {
company, err := s.repo.GetCompany(ctx, vendorID)
if err != nil {
return nil, err
}
if company == nil {
return nil, errors.New("vendor not found")
}
settings, err := s.repo.GetShippingSettings(ctx, vendorID)
if err != nil {
return []domain.ShippingOption{}, nil
}
if settings == nil {
return []domain.ShippingOption{}, nil
}
distance := domain.HaversineDistance(company.Latitude, company.Longitude, buyerLat, buyerLng)
var options []domain.ShippingOption
// Delivery option
if settings.Active {
if settings.MaxRadiusKm > 0 && distance <= settings.MaxRadiusKm {
variableCost := int64(math.Round(distance * float64(settings.PricePerKmCents)))
price := settings.MinFeeCents
if variableCost > price {
price = variableCost
}
if settings.FreeShippingThresholdCents != nil && *settings.FreeShippingThresholdCents > 0 && cartTotalCents >= *settings.FreeShippingThresholdCents {
price = 0
}
estMins := 30 + int(math.Round(distance*5))
options = append(options, domain.ShippingOption{
Type: domain.ShippingOptionTypeDelivery,
ValueCents: price,
EstimatedMinutes: estMins,
Description: "Entrega Própria",
DistanceKm: distance,
})
}
}
// Pickup option
if settings.PickupActive {
desc := "Retirada na loja"
if settings.PickupAddress != "" {
desc = "Retirada em: " + settings.PickupAddress
}
if settings.PickupHours != "" {
desc += " (" + settings.PickupHours + ")"
}
options = append(options, domain.ShippingOption{
Type: domain.ShippingOptionTypePickup,
ValueCents: 0,
EstimatedMinutes: 60,
Description: desc,
DistanceKm: distance,
})
}
return options, nil
}