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, } }