merch-api/internal/merch/service.go

322 lines
7.3 KiB
Go
Raw Normal View History

2026-02-23 20:02:17 +03:00
package merch
2026-03-01 22:13:39 +03:00
import (
2026-03-04 17:02:11 +03:00
"context"
2026-03-10 23:44:24 +03:00
"errors"
"fmt"
"github.com/google/uuid"
2026-03-04 17:02:11 +03:00
"merch-api/internal/user"
2026-03-01 22:13:39 +03:00
"merch-api/pkg/utils"
)
2026-03-08 15:12:17 +03:00
const serviceLogHeader string = "[Service]"
2026-02-23 20:02:17 +03:00
type service struct {
2026-03-04 17:02:11 +03:00
repo Repository
utils utils.Utils
userProvider user.Provider
2026-02-23 20:02:17 +03:00
}
2026-03-04 17:02:11 +03:00
func newService(repo Repository, u utils.Utils, up user.Provider) *service {
2026-02-23 20:02:17 +03:00
return &service{
2026-03-04 17:02:11 +03:00
repo: repo,
utils: u,
userProvider: up,
2026-03-01 22:13:39 +03:00
}
}
2026-03-04 17:02:11 +03:00
//origins
func (s *service) createOrigin(ctx context.Context, o *newOriginDTO) error {
2026-03-01 22:13:39 +03:00
newOrigin := &Origin{
CreatedAt: s.utils.TimeNowUTC(),
DeletedAt: s.utils.DeletedNullTime(),
Name: o.Name,
}
2026-03-08 15:12:17 +03:00
logDebug(serviceLogHeader, "create origin success")
2026-03-04 17:02:11 +03:00
return s.repo.createOrigin(ctx, newOrigin)
2026-03-01 22:13:39 +03:00
}
2026-03-04 17:02:11 +03:00
func (s *service) getOrigins(ctx context.Context) (*originsDTO, error) {
data, err := s.repo.getOrigins(ctx)
2026-03-01 22:13:39 +03:00
if err != nil {
2026-03-08 15:12:17 +03:00
logErr(serviceLogHeader, err)
2026-03-01 22:13:39 +03:00
return nil, err
2026-02-23 20:02:17 +03:00
}
2026-03-01 22:13:39 +03:00
var origins []originItem
for _, item := range data {
origins = append(origins, originItem{
Id: item.Id,
Name: item.Name,
})
}
response := &originsDTO{
Origins: origins,
}
2026-03-08 15:12:17 +03:00
logDebug(serviceLogHeader, "get origins success")
2026-03-01 22:13:39 +03:00
return response, nil
}
2026-03-04 17:02:11 +03:00
func (s *service) deleteOrigin(ctx context.Context, origin *deleteOriginDTO) error {
2026-03-08 15:12:17 +03:00
logDebug(serviceLogHeader, "delete origin success")
2026-03-04 17:02:11 +03:00
return s.repo.deleteOriginByName(ctx, origin.Name, s.utils.NullTimeNowUTC())
}
// merch
2026-03-07 15:49:54 +03:00
func (s *service) createMerch(ctx context.Context, userId int64, payload *newMerchDTO) error {
2026-03-04 17:02:11 +03:00
now := s.utils.TimeNowUTC()
nullNow := s.utils.NullTimeFromNow(now)
empty := s.utils.DeletedNullTime()
merchUuid, err := uuid.NewV7()
if err != nil {
2026-03-08 15:12:17 +03:00
logErr(serviceLogHeader, err)
2026-03-04 17:02:11 +03:00
return err
}
newMerch := &Merch{
CreatedAt: now,
UpdatedAt: nullNow,
DeletedAt: empty,
MerchUuid: merchUuid.String(),
UserId: userId,
Name: payload.Name,
}
var merchExtra []ExtraData
if payload.Links != nil {
2026-03-07 15:49:54 +03:00
originsMap, _, err := s.getOriginsMaps(ctx)
2026-03-04 17:02:11 +03:00
if err != nil {
2026-03-08 15:12:17 +03:00
logErr(serviceLogHeader, err)
2026-03-04 17:02:11 +03:00
return err
}
for _, item := range payload.Links {
merchExtra = append(merchExtra, ExtraData{
CreatedAt: now,
UpdatedAt: nullNow,
DeletedAt: empty,
MerchId: 0,
2026-03-07 15:49:54 +03:00
OriginId: originsMap[item.Origin],
2026-03-04 17:02:11 +03:00
URL: item.Link,
})
}
}
return s.repo.createMerch(ctx, newMerch, merchExtra)
}
2026-03-10 23:44:24 +03:00
// getOriginsMaps
// first return name:id
// second id:name
2026-03-07 15:49:54 +03:00
func (s *service) getOriginsMaps(ctx context.Context) (map[string]int64, map[int64]string, error) {
2026-03-04 17:02:11 +03:00
origins, err := s.repo.getOrigins(ctx)
if err != nil {
2026-03-08 15:12:17 +03:00
logErr(serviceLogHeader, err)
2026-03-07 15:49:54 +03:00
return nil, nil, err
2026-03-04 17:02:11 +03:00
}
2026-03-07 15:49:54 +03:00
namesMap := make(map[string]int64, len(origins))
idsMap := make(map[int64]string, len(origins))
2026-03-04 17:02:11 +03:00
for _, origin := range origins {
2026-03-07 15:49:54 +03:00
namesMap[origin.Name] = origin.Id
idsMap[origin.Id] = origin.Name
2026-03-04 17:02:11 +03:00
}
2026-03-07 15:49:54 +03:00
return namesMap, idsMap, nil
2026-02-23 20:02:17 +03:00
}
2026-03-04 17:59:46 +03:00
2026-03-08 15:12:17 +03:00
func (s *service) getMerchUuidMap(ctx context.Context, uuids []string) (map[string]int64, error) {
return s.repo.getMerchUuidMap(ctx, uuids)
}
2026-03-07 15:49:54 +03:00
func (s *service) getMany(ctx context.Context, userId int64) ([]merchDTO, error) {
return s.repo.getMany(ctx, userId)
}
func (s *service) updateMerch(ctx context.Context, userId int64, payload *updateMerchDTO) (*merchDTO, error) {
return s.repo.updateMerch(ctx, userId, payload)
}
func (s *service) updateExtraData(ctx context.Context, userId int64, payload *extraDataDTO) (*extraDataDTO, error) {
merchId, err := s.repo.getMerchIdByUuid(ctx, userId, payload.MerchUuid)
2026-03-04 17:59:46 +03:00
if err != nil {
2026-03-08 15:12:17 +03:00
logErr(serviceLogHeader, err)
2026-03-04 17:59:46 +03:00
return nil, err
}
2026-03-07 15:49:54 +03:00
origins, ids, err := s.getOriginsMaps(ctx)
if err != nil {
2026-03-08 15:12:17 +03:00
logErr(serviceLogHeader, err)
2026-03-07 15:49:54 +03:00
return nil, err
}
var insertData []ExtraData
for _, item := range payload.Links {
if _, ok := origins[item.Origin]; !ok {
continue
}
now := s.utils.TimeNowUTC()
2026-03-04 17:59:46 +03:00
2026-03-07 15:49:54 +03:00
insertData = append(insertData, ExtraData{
CreatedAt: now,
UpdatedAt: s.utils.NullTimeFromNow(now),
OriginId: origins[item.Origin],
URL: item.Link,
})
}
result, err := s.repo.updateExtraData(ctx, merchId, insertData)
2026-03-04 17:59:46 +03:00
if err != nil {
2026-03-08 15:12:17 +03:00
logErr(serviceLogHeader, err)
2026-03-07 15:49:54 +03:00
return nil, err
}
if result == nil || len(result) == 0 {
return nil, nil
}
var ol []originLink
for _, item := range result {
ol = append(ol, originLink{
Origin: ids[item.OriginId],
Link: item.URL,
})
2026-03-04 17:59:46 +03:00
}
2026-03-07 15:49:54 +03:00
return &extraDataDTO{
MerchUuid: payload.MerchUuid,
Links: ol,
}, nil
}
func (s *service) deleteOneMerchRecord(ctx context.Context, userId int64, merchUuid string) error {
2026-03-04 17:59:46 +03:00
return s.repo.deleteOneMerchRecord(ctx, userId, merchUuid, s.utils.TimeNowUTC())
}
2026-03-10 23:44:24 +03:00
func (s *service) getPrices(ctx context.Context, userId int64, days int) ([]PricesResponse, error) {
fmt.Println("Enter service")
merchList, err := s.repo.getAllUserMerch(ctx, userId)
if err != nil {
logErr(serviceLogHeader, err)
return nil, err
}
if len(merchList) == 0 {
errMsg := errors.New("no merch found")
logErr(serviceLogHeader, errMsg)
return nil, errMsg
}
merchMap := make(map[int64]Merch, len(merchList))
for _, merch := range merchList {
merchMap[merch.Id] = merch
}
var response []PricesResponse
for _, item := range merchList {
response = append(response, PricesResponse{
MerchUuid: item.MerchUuid,
Name: item.Name,
Origins: []OriginWithPrices{},
})
}
pricesList, err := s.repo.getPricesWithDays(ctx, userId, getPeriod(days))
if err != nil {
logErr(serviceLogHeader, err)
return nil, err
}
_, originNamesMap, err := s.getOriginsMaps(ctx)
if err != nil {
logErr(serviceLogHeader, err)
return nil, err
}
pricesMap := make(map[string]map[string][]PriceEntry)
for _, item := range pricesList {
merchUuid := merchMap[item.MerchId].MerchUuid
if _, ok := pricesMap[merchUuid]; !ok {
pricesMap[merchUuid] = make(map[string][]PriceEntry)
}
originName := originNamesMap[item.OriginId]
pricesMap[merchUuid][originName] = append(pricesMap[merchUuid][originName], PriceEntry{
CreatedAt: item.CreatedAt.Unix(),
Value: item.Price,
})
}
for i := range response {
for _, name := range originNamesMap {
prices := pricesMap[response[i].MerchUuid][name]
if prices == nil {
continue
}
response[i].Origins = append(response[i].Origins, OriginWithPrices{
Origin: name,
Prices: prices,
})
}
}
return response, nil
}
func (s *service) getDistinctPrices(ctx context.Context, userId int64, merchUuid string, days int) (*PricesResponse, error) {
result, err := s.repo.getDistinctPrices(ctx, userId, merchUuid, getPeriod(days))
if err != nil {
logErr(serviceLogHeader, err)
return nil, err
}
if result == nil {
return nil, nil
}
_, originNamesMap, err := s.getOriginsMaps(ctx)
if err != nil {
logErr(serviceLogHeader, err)
return nil, err
}
response := PricesResponse{
MerchUuid: merchUuid,
Origins: []OriginWithPrices{},
}
pricesMap := make(map[string][]PriceEntry)
for _, item := range result {
originName := originNamesMap[item.OriginId]
if _, ok := pricesMap[originName]; !ok {
pricesMap[originName] = make([]PriceEntry, 0)
}
pricesMap[originName] = append(pricesMap[originName], PriceEntry{
CreatedAt: item.CreatedAt.Unix(),
Value: item.Price,
})
}
for key, item := range pricesMap {
response.Origins = append(response.Origins, OriginWithPrices{
Origin: key,
Prices: item,
})
}
return &response, nil
}