wms-be/modules/inventory_movement/service/inventory_movement_service.go

232 lines
7.9 KiB
Go

package service
import (
"context"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_movement/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_movement/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_movement/repository"
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
"github.com/google/uuid"
"gorm.io/gorm"
)
type InventoryMovementService interface {
Create(ctx context.Context, req dtodomain.InventoryMovementCreateRequest) (dtodomain.InventoryMovementResponse, error)
GetById(ctx context.Context, id string) (dtodomain.InventoryMovementResponse, error)
GetAll(ctx context.Context, filter query.InventoryMovementFilter) ([]dtodomain.InventoryMovementResponse, int64, error)
Update(ctx context.Context, req dtodomain.InventoryMovementUpdateRequest, id string) (dtodomain.InventoryMovementResponse, error)
Delete(ctx context.Context, id string) error
CreateLine(ctx context.Context, movementId string, req dtodomain.InventoryMovementLineCreateRequest) (dtodomain.InventoryMovementLineResponse, error)
UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryMovementLineUpdateRequest) (dtodomain.InventoryMovementLineResponse, error)
DeleteLine(ctx context.Context, lineId string) error
}
type inventoryMovementService struct {
db *gorm.DB
movementRepo repository.InventoryMovementRepository
movementLineRepo repository.InventoryMovementLineRepository
}
func (s *inventoryMovementService) Create(ctx context.Context, req dtodomain.InventoryMovementCreateRequest) (dtodomain.InventoryMovementResponse, error) {
tx := s.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
clientUUID, err := uuid.Parse(req.ClientID)
if err != nil {
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
movNumber, err := entities.GenerateDocumentNumberInvMovement(s.db, req.ClientID)
if err != nil {
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
movement := entities.TInventoryMovementEntity{
MovementNumber: movNumber,
MovementDate: utils.StringToDateTime(req.MovementDate),
MovementType: req.MovementType,
ClientID: clientUUID,
Status: req.Status,
SourceLocationID: uuid.MustParse(req.SourceLocationID),
DestinationLocationID: uuid.MustParse(req.DestinationLocationID),
}
created, err := s.movementRepo.Create(ctx, tx, movement)
if err != nil {
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
// Bulk create lines
var lines []entities.TInventoryMovementLineEntity
for _, lineReq := range req.MovementLines {
productUUID := uuid.Nil
if lineReq.ProductID != "" {
productUUID, err = uuid.Parse(lineReq.ProductID)
if err != nil {
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
}
clientLineUUID, err := uuid.Parse(lineReq.ClientID)
if err != nil {
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
lines = append(lines, entities.TInventoryMovementLineEntity{
MovedQuantity: lineReq.MovedQuantity,
InvMovementID: created.ID,
ProductID: productUUID,
StorageID: uuid.MustParse(lineReq.StorageID),
ClientID: clientLineUUID,
Status: lineReq.Status,
})
}
if len(lines) > 0 {
err = s.movementLineRepo.BulkCreate(ctx, tx, lines)
if err != nil {
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
}
tx.Commit()
result, err := s.movementRepo.GetById(ctx, nil, created.ID.String())
if err != nil {
return dtodomain.InventoryMovementResponse{}, err
}
return dtodomain.ToInventoryMovementResponse(result), nil
}
func (s *inventoryMovementService) GetById(ctx context.Context, id string) (dtodomain.InventoryMovementResponse, error) {
movement, err := s.movementRepo.GetById(ctx, nil, id)
if err != nil {
return dtodomain.InventoryMovementResponse{}, err
}
return dtodomain.ToInventoryMovementResponse(movement), nil
}
func (s *inventoryMovementService) GetAll(ctx context.Context, filter query.InventoryMovementFilter) ([]dtodomain.InventoryMovementResponse, int64, error) {
movements, total, err := s.movementRepo.GetAll(ctx, filter)
if err != nil {
return nil, 0, err
}
var responses []dtodomain.InventoryMovementResponse
for _, e := range movements {
responses = append(responses, dtodomain.ToInventoryMovementResponse(e))
}
if responses == nil {
responses = make([]dtodomain.InventoryMovementResponse, 0)
}
return responses, total, nil
}
func (s *inventoryMovementService) Update(ctx context.Context, req dtodomain.InventoryMovementUpdateRequest, id string) (dtodomain.InventoryMovementResponse, error) {
tx := s.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
movement, err := s.movementRepo.GetById(ctx, tx, id)
if err != nil {
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
// if req.MovementNumber != "" {
// movement.MovementNumber = req.MovementNumber
// }
movement.MovementDate = utils.StringToDateTime(req.MovementDate)
movement.MovementType = req.MovementType
movement.Status = req.Status
updated, err := s.movementRepo.Update(ctx, tx, movement)
if err != nil {
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
tx.Commit()
result, err := s.movementRepo.GetById(ctx, nil, updated.ID.String())
if err != nil {
return dtodomain.InventoryMovementResponse{}, err
}
return dtodomain.ToInventoryMovementResponse(result), nil
}
func (s *inventoryMovementService) Delete(ctx context.Context, id string) error {
tx := s.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := s.movementRepo.Delete(ctx, tx, id); err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
func (s *inventoryMovementService) CreateLine(ctx context.Context, movementId string, req dtodomain.InventoryMovementLineCreateRequest) (dtodomain.InventoryMovementLineResponse, error) {
movementUUID, err := uuid.Parse(movementId)
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
productUUID := uuid.Nil
if req.ProductID != "" {
productUUID, err = uuid.Parse(req.ProductID)
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
}
clientLineUUID, err := uuid.Parse(req.ClientID)
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
line := entities.TInventoryMovementLineEntity{
MovedQuantity: req.MovedQuantity,
InvMovementID: movementUUID,
ProductID: productUUID,
StorageID: uuid.MustParse(req.StorageID),
ClientID: clientLineUUID,
Status: req.Status,
}
created, err := s.movementLineRepo.Create(ctx, nil, line)
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
return dtodomain.ToInventoryMovementLineResponse(created), nil
}
func (s *inventoryMovementService) UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryMovementLineUpdateRequest) (dtodomain.InventoryMovementLineResponse, error) {
line, err := s.movementLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
if req.MovedQuantity != nil {
line.MovedQuantity = *req.MovedQuantity
}
if req.Status != nil {
line.Status = *req.Status
}
updated, err := s.movementLineRepo.Update(ctx, nil, line)
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
return dtodomain.ToInventoryMovementLineResponse(updated), nil
}
func (s *inventoryMovementService) DeleteLine(ctx context.Context, lineId string) error {
return s.movementLineRepo.Delete(ctx, nil, lineId)
}
func NewInventoryMovementService(db *gorm.DB, movementRepo repository.InventoryMovementRepository, movementLineRepo repository.InventoryMovementLineRepository) InventoryMovementService {
return &inventoryMovementService{
db: db,
movementRepo: movementRepo,
movementLineRepo: movementLineRepo,
}
}