237 lines
8.4 KiB
Go
237 lines
8.4 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"
|
|
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
|
|
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
|
|
}
|
|
|
|
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 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 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, 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 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 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 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 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
|
|
}
|
|
|
|
func mapQuarantineToResponse(entity entities.TInventoryQuarantineEntity, lines []entities.TInventoryQuarantineLineEntity) dtodomain.QuarantineResponse {
|
|
resp := dtodomain.QuarantineResponse{
|
|
ID: entity.ID.String(),
|
|
DocumentNumber: entity.DocumentNumber,
|
|
DocumentDate: entity.DocumentDate.Format("2006-01-02"),
|
|
Status: entity.Status,
|
|
WarehouseID: entity.WarehouseID.String(),
|
|
ZonaID: entity.ZonaID.String(),
|
|
ClientID: entity.ClientID.String(),
|
|
Warehouse: entity.Warehouse.Name,
|
|
Zona: entity.Zona.Name,
|
|
Client: entity.Client.Name,
|
|
}
|
|
for _, line := range lines {
|
|
resp.QuarantineLines = append(resp.QuarantineLines, mapQuarantineLineToResponse(line))
|
|
}
|
|
return resp
|
|
}
|
|
|
|
func mapQuarantineLineToResponse(line entities.TInventoryQuarantineLineEntity) dtodomain.QuarantineLineResponse {
|
|
return dtodomain.QuarantineLineResponse{
|
|
ID: line.ID.String(),
|
|
QuarantineID: line.QuarantineID.String(),
|
|
StorageID: line.StorageID.String(),
|
|
ProductID: line.ProductID.String(),
|
|
ClientID: line.ClientID.String(),
|
|
Product: line.Product.Name,
|
|
Storage: line.StorageID.String(), // gunakan StorageID, karena field Name tidak ada
|
|
Quarantine: line.Quarantine.DocumentNumber,
|
|
Client: line.Client.Name,
|
|
}
|
|
}
|