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/Caknoooo/go-gin-clean-starter/pkg/constants" "github.com/Caknoooo/go-gin-clean-starter/pkg/utils" "github.com/google/uuid" "github.com/sirupsen/logrus" "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 log *logrus.Logger } 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, FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE), } 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 } w.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "create", "entity": "warehouse", "entity_id": created.ID.String(), }).Info("Warehouse created") return dtodomain.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 dtodomain.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, dtodomain.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 } before := warehouse 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) warehouse.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE) 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 } changes := utils.GetChangedFields(before, result) w.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "update", "entity": "warehouse", "entity_id": warehouseId, "changes": changes, }).Info("Warehouse updated") return dtodomain.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() } }() warehouse, err := w.warehouseRepo.GetById(ctx, tx, warehouseId) if err != nil { tx.Rollback() return err } warehouse.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE) if _, err := w.warehouseRepo.Update(ctx, tx, warehouse); err != nil { tx.Rollback() return err } if err := w.warehouseRepo.Delete(ctx, tx, warehouseId); err != nil { tx.Rollback() return err } tx.Commit() w.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "delete", "entity": "warehouse", "entity_id": warehouseId, }).Info("Warehouse deleted") return nil } func NewWarehouseService(warehouseRepo repository.WarehouseRepository, db *gorm.DB, log *logrus.Logger) WarehouseService { return &warehouseService{ warehouseRepo: warehouseRepo, db: db, log: log, } }