wms-be/modules/quarantine/service/quarantine_service.go

215 lines
7.7 KiB
Go

package service
import (
"context"
"time"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
invstoragerepository "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_storage/repository"
productrepository "github.com/Caknoooo/go-gin-clean-starter/modules/product/repository"
dto "github.com/Caknoooo/go-gin-clean-starter/modules/quarantine/dto"
dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/quarantine/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/quarantine/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/quarantine/repository"
uomrepository "github.com/Caknoooo/go-gin-clean-starter/modules/uom/repository"
"github.com/google/uuid"
"gorm.io/gorm"
)
type QuarantineService interface {
Create(ctx context.Context, req dtodomain.QuarantineCreateRequest) (dtodomain.QuarantineResponse, error)
GetById(ctx context.Context, id string) (dtodomain.QuarantineResponse, error)
GetAll(ctx context.Context, filter query.QuarantineFilter) ([]dtodomain.QuarantineResponse, int64, error)
Update(ctx context.Context, req dtodomain.QuarantineUpdateRequest, id string) (dtodomain.QuarantineResponse, error)
Delete(ctx context.Context, id string) error
GetLinesByQuarantineId(ctx context.Context, quarantineId string) ([]dtodomain.QuarantineLineResponse, error)
CreateLine(ctx context.Context, quarantineId string, req dtodomain.QuarantineLineCreateRequest) (dtodomain.QuarantineLineResponse, error)
UpdateLine(ctx context.Context, lineId string, req dtodomain.QuarantineLineUpdateRequest) (dtodomain.QuarantineLineResponse, error)
DeleteLine(ctx context.Context, lineId string) error
OnComplete(ctx context.Context, id string) (dtodomain.QuarantineResponse, error)
}
type quarantineService struct {
db *gorm.DB
quarantineRepo repository.QuarantineRepository
quarantineLineRepo repository.QuarantineLineRepository
productRepo productrepository.ProductRepository
}
// GetLinesByQuarantineId implements QuarantineService.
func (s *quarantineService) GetLinesByQuarantineId(ctx context.Context, quarantineId string) ([]dtodomain.QuarantineLineResponse, error) {
lines, err := s.quarantineLineRepo.GetAllByQuarantineId(ctx, quarantineId)
if err != nil {
return nil, err
}
return dto.MapQuarantineLinesToResponse(lines), nil
}
func NewQuarantineService(db *gorm.DB, quarantineRepo repository.QuarantineRepository, quarantineLineRepo repository.QuarantineLineRepository, productRepo productrepository.ProductRepository, uomRepo uomrepository.UomRepository, invStorageRepository invstoragerepository.InventoryStorageRepository) QuarantineService {
return &quarantineService{
db: db,
quarantineRepo: quarantineRepo,
quarantineLineRepo: quarantineLineRepo,
productRepo: productRepo,
}
}
func (s *quarantineService) Create(ctx context.Context, req dtodomain.QuarantineCreateRequest) (dtodomain.QuarantineResponse, error) {
tx := s.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
entity := entities.TInventoryQuarantineEntity{
DocumentNumber: req.ReferenceNumber,
DocumentDate: parseDate(req.DocumentDate),
Status: req.Status,
ClientID: parseUUID(req.ClientID),
}
created, err := s.quarantineRepo.Create(ctx, tx, entity)
if err != nil {
tx.Rollback()
return dtodomain.QuarantineResponse{}, err
}
var lines []entities.TInventoryQuarantineLineEntity
for _, lineReq := range req.QuarantineLines {
line := entities.TInventoryQuarantineLineEntity{
QuarantineID: created.ID,
ProductID: parseUUID(lineReq.ProductID),
ClientID: parseUUID(lineReq.ClientID),
}
lines = append(lines, line)
}
if len(lines) > 0 {
err = s.quarantineLineRepo.BulkCreate(ctx, tx, lines)
if err != nil {
tx.Rollback()
return dtodomain.QuarantineResponse{}, err
}
}
tx.Commit()
return dto.MapQuarantineToResponse(created, lines), nil
}
func (s *quarantineService) GetById(ctx context.Context, id string) (dtodomain.QuarantineResponse, error) {
entity, err := s.quarantineRepo.GetById(ctx, nil, id)
if err != nil {
return dtodomain.QuarantineResponse{}, err
}
lines, _ := s.quarantineLineRepo.GetAllByQuarantineId(ctx, id)
return dto.MapQuarantineToResponse(entity, lines), nil
}
func (s *quarantineService) GetAll(ctx context.Context, filter query.QuarantineFilter) ([]dtodomain.QuarantineResponse, int64, error) {
entities, total, err := s.quarantineRepo.GetAll(ctx, filter)
if err != nil {
return nil, 0, err
}
var responses []dtodomain.QuarantineResponse
for _, entity := range entities {
lines, _ := s.quarantineLineRepo.GetAllByQuarantineId(ctx, entity.ID.String())
responses = append(responses, dto.MapQuarantineToResponse(entity, lines))
}
return responses, total, nil
}
func (s *quarantineService) Update(ctx context.Context, req dtodomain.QuarantineUpdateRequest, id string) (dtodomain.QuarantineResponse, error) {
tx := s.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
entity, err := s.quarantineRepo.GetById(ctx, tx, id)
if err != nil {
tx.Rollback()
return dtodomain.QuarantineResponse{}, err
}
entity.DocumentNumber = req.ReferenceNumber
entity.DocumentDate = parseDate(req.DocumentDate)
entity.Status = req.Status
updated, err := s.quarantineRepo.Update(ctx, tx, entity)
if err != nil {
tx.Rollback()
return dtodomain.QuarantineResponse{}, err
}
tx.Commit()
lines, _ := s.quarantineLineRepo.GetAllByQuarantineId(ctx, id)
return dto.MapQuarantineToResponse(updated, lines), nil
}
func (s *quarantineService) Delete(ctx context.Context, id string) error {
tx := s.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := s.quarantineLineRepo.DeleteByQuarantineId(ctx, tx, id); err != nil {
tx.Rollback()
return err
}
if err := s.quarantineRepo.Delete(ctx, tx, id); err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
func (s *quarantineService) CreateLine(ctx context.Context, quarantineId string, req dtodomain.QuarantineLineCreateRequest) (dtodomain.QuarantineLineResponse, error) {
line := entities.TInventoryQuarantineLineEntity{
QuarantineID: parseUUID(quarantineId),
ProductID: parseUUID(req.ProductID),
ClientID: parseUUID(req.ClientID),
}
created, err := s.quarantineLineRepo.Create(ctx, nil, line)
if err != nil {
return dtodomain.QuarantineLineResponse{}, err
}
return dto.MapQuarantineLineToResponse(created), nil
}
func (s *quarantineService) UpdateLine(ctx context.Context, lineId string, req dtodomain.QuarantineLineUpdateRequest) (dtodomain.QuarantineLineResponse, error) {
line, err := s.quarantineLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return dtodomain.QuarantineLineResponse{}, err
}
line.ProductID = parseUUID(req.ProductID)
line.ClientID = parseUUID(req.ClientID)
updated, err := s.quarantineLineRepo.Update(ctx, nil, line)
if err != nil {
return dtodomain.QuarantineLineResponse{}, err
}
return dto.MapQuarantineLineToResponse(updated), nil
}
func (s *quarantineService) DeleteLine(ctx context.Context, lineId string) error {
return s.quarantineLineRepo.Delete(ctx, nil, lineId)
}
func (s *quarantineService) OnComplete(ctx context.Context, id string) (dtodomain.QuarantineResponse, error) {
entity, err := s.quarantineRepo.GetById(ctx, nil, id)
if err != nil {
return dtodomain.QuarantineResponse{}, err
}
entity.Status = "completed"
updated, err := s.quarantineRepo.Update(ctx, nil, entity)
if err != nil {
return dtodomain.QuarantineResponse{}, err
}
lines, _ := s.quarantineLineRepo.GetAllByQuarantineId(ctx, id)
return dto.MapQuarantineToResponse(updated, lines), nil
}
func parseUUID(id string) uuid.UUID {
uid, _ := uuid.Parse(id)
return uid
}
func parseDate(dateStr string) time.Time {
t, _ := time.Parse("2006-01-02", dateStr)
return t
}