wms-be/modules/warehouse/service/warehouse_service.go

230 lines
6.8 KiB
Go

package service
import (
"context"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/warehouse/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/warehouse/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/warehouse/repository"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
"github.com/google/uuid"
"gorm.io/gorm"
)
type WarehouseService interface {
Create(ctx context.Context, req dtodomain.WarehouseCreateRequest) (dtodomain.WarehouseResponse, error)
GetById(ctx context.Context, warehouseId string) (dtodomain.WarehouseResponse, error)
GetAll(ctx context.Context, filter query.WarehouseFilter) ([]dtodomain.WarehouseResponse, int64, error)
Update(ctx context.Context, req dtodomain.WarehouseUpdateRequest, warehouseId string) (dtodomain.WarehouseResponse, error)
Delete(ctx context.Context, warehouseId string) error
}
type warehouseService struct {
db *gorm.DB
warehouseRepo repository.WarehouseRepository
}
func toWarehouseResponse(e entities.MWarehouseEntity) dtodomain.WarehouseResponse {
client := pkgdto.IdNameResponse{}
if e.Client.ID != uuid.Nil {
client = pkgdto.IdNameResponse{
ID: e.Client.ID.String(),
Name: e.Client.Name,
}
}
pic := pkgdto.IdNameResponse{}
if e.PIC.ID != uuid.Nil {
pic = pkgdto.IdNameResponse{
ID: e.PIC.ID.String(),
Name: e.PIC.Name,
}
}
zonas := make([]dtodomain.WarehouseZonaResponse, 0)
for _, zona := range e.Zonas {
zonas = append(zonas, dtodomain.WarehouseZonaResponse{
ID: zona.ID.String(),
Code: zona.Code,
Name: zona.Name,
Type: zona.Type,
Temperature: zona.Temperature,
Hazardous: zona.Hazardous,
QRCodeZone: zona.QRCodeZone,
IsActive: zona.IsActive,
Client: pkgdto.IdNameResponse{
ID: zona.Client.ID.String(),
Name: zona.Client.Name,
},
Aisles: make([]dtodomain.ZonaAisleResponse, 0),
})
for _, aisle := range zona.Aisles {
zonas[len(zonas)-1].Aisles = append(zonas[len(zonas)-1].Aisles, dtodomain.ZonaAisleResponse{
ID: aisle.ID.String(),
Code: aisle.Code,
Name: aisle.Name,
IsleX: aisle.IsleX,
BinY: aisle.BinY,
LevelZ: aisle.LevelZ,
DimLength: aisle.DimLength,
DimWidth: aisle.DimWidth,
DimHeight: aisle.DimHeight,
Weight: aisle.Weight,
QrCodeAisle: aisle.QrCodeAisle,
IsActive: aisle.IsActive,
Zone: pkgdto.IdNameResponse{
ID: aisle.Zona.ID.String(),
Name: aisle.Zona.Name,
},
DimUom: pkgdto.IdNameResponse{
ID: aisle.DimUom.ID.String(),
Name: aisle.DimUom.Name,
},
WeightUom: pkgdto.IdNameResponse{
ID: aisle.WeightUom.ID.String(),
Name: aisle.WeightUom.Name,
},
Client: pkgdto.IdNameResponse{
ID: aisle.Client.ID.String(),
Name: aisle.Client.Name,
},
})
}
}
return dtodomain.WarehouseResponse{
ID: e.ID.String(),
Code: e.Code,
Name: e.Name,
Description: e.Description,
Status: e.Status,
DissallowNegativeInventory: e.DissallowNegativeInventory,
Client: client,
PIC: &pic,
Zonas: zonas,
}
}
func (w *warehouseService) Create(ctx context.Context, req dtodomain.WarehouseCreateRequest) (dtodomain.WarehouseResponse, error) {
tx := w.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
clientUUID, err := uuid.Parse(req.ClientID)
if err != nil {
tx.Rollback()
return dtodomain.WarehouseResponse{}, err
}
warehouse := entities.MWarehouseEntity{
Code: req.Code,
Name: req.Name,
Description: req.Description,
Status: req.Status,
DissallowNegativeInventory: req.DissallowNegativeInventory,
PICID: utils.ParseNullableUUID(req.PICID),
ClientID: clientUUID,
}
created, err := w.warehouseRepo.Create(ctx, tx, warehouse)
if err != nil {
tx.Rollback()
return dtodomain.WarehouseResponse{}, err
}
tx.Commit()
result, err := w.warehouseRepo.GetById(ctx, nil, created.ID.String())
if err != nil {
return dtodomain.WarehouseResponse{}, err
}
return toWarehouseResponse(result), nil
}
func (w *warehouseService) GetById(ctx context.Context, warehouseId string) (dtodomain.WarehouseResponse, error) {
warehouse, err := w.warehouseRepo.GetById(ctx, nil, warehouseId)
if err != nil {
return dtodomain.WarehouseResponse{}, err
}
return toWarehouseResponse(warehouse), nil
}
func (w *warehouseService) GetAll(ctx context.Context, filter query.WarehouseFilter) ([]dtodomain.WarehouseResponse, int64, error) {
warehouses, total, err := w.warehouseRepo.GetAll(ctx, filter)
if err != nil {
return nil, 0, err
}
var responses []dtodomain.WarehouseResponse
for _, e := range warehouses {
responses = append(responses, toWarehouseResponse(e))
}
if responses == nil {
responses = make([]dtodomain.WarehouseResponse, 0)
}
return responses, total, nil
}
func (w *warehouseService) Update(ctx context.Context, req dtodomain.WarehouseUpdateRequest, warehouseId string) (dtodomain.WarehouseResponse, error) {
tx := w.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
warehouse, err := w.warehouseRepo.GetById(ctx, tx, warehouseId)
if err != nil {
tx.Rollback()
return dtodomain.WarehouseResponse{}, err
}
if req.Code != "" {
warehouse.Code = req.Code
}
if req.Name != "" {
warehouse.Name = req.Name
}
warehouse.Description = req.Description
warehouse.Status = req.Status
warehouse.DissallowNegativeInventory = req.DissallowNegativeInventory
if req.ClientID != "" {
clientUUID, err := uuid.Parse(req.ClientID)
if err == nil {
warehouse.ClientID = clientUUID
}
}
warehouse.PICID = utils.ParseNullableUUID(req.PICID)
updated, err := w.warehouseRepo.Update(ctx, tx, warehouse)
if err != nil {
tx.Rollback()
return dtodomain.WarehouseResponse{}, err
}
tx.Commit()
result, err := w.warehouseRepo.GetById(ctx, nil, updated.ID.String())
if err != nil {
return dtodomain.WarehouseResponse{}, err
}
return toWarehouseResponse(result), nil
}
func (w *warehouseService) Delete(ctx context.Context, warehouseId string) error {
tx := w.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := w.warehouseRepo.Delete(ctx, tx, warehouseId); err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
func NewWarehouseService(warehouseRepo repository.WarehouseRepository, db *gorm.DB) WarehouseService {
return &warehouseService{
warehouseRepo: warehouseRepo,
db: db,
}
}