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" "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 { return dtodomain.WarehouseResponse{ ID: e.ID.String(), Code: e.Code, Name: e.Name, Description: e.Description, Status: e.Status, DissallowNegativeInventory: e.DissallowNegativeInventory, ClientID: e.ClientID.String(), } } 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, 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 } } updated, err := w.warehouseRepo.Update(ctx, tx, warehouse) if err != nil { tx.Rollback() return dtodomain.WarehouseResponse{}, err } tx.Commit() return toWarehouseResponse(updated), 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, } }