package service import ( "context" "github.com/Caknoooo/go-gin-clean-starter/database/entities" dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_transaction/dto" "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_transaction/query" "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_transaction/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 InventoryTransactionService interface { Create(ctx context.Context, req dtodomain.InventoryTransactionCreateRequest) (dtodomain.InventoryTransactionResponse, error) GetById(ctx context.Context, inventoryTransactionId string) (dtodomain.InventoryTransactionResponse, error) GetAll(ctx context.Context, filter query.InventoryTransactionFilter) ([]dtodomain.InventoryTransactionResponse, int64, error) Update(ctx context.Context, req dtodomain.InventoryTransactionUpdateRequest, inventoryTransactionId string) (dtodomain.InventoryTransactionResponse, error) Delete(ctx context.Context, inventoryTransactionId string) error } type inventoryTransactionService struct { db *gorm.DB inventoryTransactionRepo repository.InventoryTransactionRepository log *logrus.Logger } func (s *inventoryTransactionService) Create(ctx context.Context, req dtodomain.InventoryTransactionCreateRequest) (dtodomain.InventoryTransactionResponse, 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.InventoryTransactionResponse{}, err } productUUID, err := uuid.Parse(req.ProductID) if err != nil { tx.Rollback() return dtodomain.InventoryTransactionResponse{}, err } var aisleUUID, invReceiptUUID, invIssueUUID, invMoveUUID *uuid.UUID if req.AisleID != "" { tmp, err := uuid.Parse(req.AisleID) if err == nil { aisleUUID = &tmp } } if req.InvReceiptID != "" { tmp, err := uuid.Parse(req.InvReceiptID) if err == nil { invReceiptUUID = &tmp } } if req.InvIssueID != "" { tmp, err := uuid.Parse(req.InvIssueID) if err == nil { invIssueUUID = &tmp } } if req.InvMoveID != "" { tmp, err := uuid.Parse(req.InvMoveID) if err == nil { invMoveUUID = &tmp } } transactionDate := utils.StringToDateTime(req.TransactionDate) entity := entities.InventoryTransactionEntity{ TransactionType: req.TransactionType, TransactionDate: transactionDate, ProductID: productUUID, AisleID: aisleUUID, ClientID: clientUUID, InvReceiptID: invReceiptUUID, InvIssueID: invIssueUUID, InvMoveID: invMoveUUID, FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE), } created, err := s.inventoryTransactionRepo.Create(ctx, tx, entity) if err != nil { tx.Rollback() return dtodomain.InventoryTransactionResponse{}, err } tx.Commit() s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": constants.CREATE, "entity": "inventory_transaction", "entity_id": created.ID.String(), }).Info("Inventory Transaction created") result, err := s.inventoryTransactionRepo.GetById(ctx, nil, created.ID.String()) if err != nil { return dtodomain.InventoryTransactionResponse{}, err } return dtodomain.ToInventoryTransactionResponse(result), nil } func (s *inventoryTransactionService) GetById(ctx context.Context, inventoryTransactionId string) (dtodomain.InventoryTransactionResponse, error) { entity, err := s.inventoryTransactionRepo.GetById(ctx, nil, inventoryTransactionId) if err != nil { return dtodomain.InventoryTransactionResponse{}, err } return dtodomain.ToInventoryTransactionResponse(entity), nil } func (s *inventoryTransactionService) GetAll(ctx context.Context, filter query.InventoryTransactionFilter) ([]dtodomain.InventoryTransactionResponse, int64, error) { entities, total, err := s.inventoryTransactionRepo.GetAll(ctx, filter) if err != nil { return nil, 0, err } var responses []dtodomain.InventoryTransactionResponse for _, e := range entities { responses = append(responses, dtodomain.ToInventoryTransactionResponse(e)) } if responses == nil { responses = make([]dtodomain.InventoryTransactionResponse, 0) } return responses, total, nil } func (s *inventoryTransactionService) Update(ctx context.Context, req dtodomain.InventoryTransactionUpdateRequest, inventoryTransactionId string) (dtodomain.InventoryTransactionResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() entity, err := s.inventoryTransactionRepo.GetById(ctx, tx, inventoryTransactionId) if err != nil { tx.Rollback() return dtodomain.InventoryTransactionResponse{}, err } before := entity if req.TransactionType != "" { entity.TransactionType = req.TransactionType } if req.TransactionDate != "" { transactionDate := utils.StringToDateTime(req.TransactionDate) entity.TransactionDate = transactionDate } if req.ProductID != "" { productUUID, err := uuid.Parse(req.ProductID) if err == nil { entity.ProductID = productUUID } } if req.AisleID != "" { aisleUUID, err := uuid.Parse(req.AisleID) if err == nil { entity.AisleID = &aisleUUID } } if req.InvReceiptID != "" { invReceiptUUID, err := uuid.Parse(req.InvReceiptID) if err == nil { entity.InvReceiptID = &invReceiptUUID } } if req.InvIssueID != "" { invIssueUUID, err := uuid.Parse(req.InvIssueID) if err == nil { entity.InvIssueID = &invIssueUUID } } if req.InvMoveID != "" { invMoveUUID, err := uuid.Parse(req.InvMoveID) if err == nil { entity.InvMoveID = &invMoveUUID } } entity.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE) updated, err := s.inventoryTransactionRepo.Update(ctx, tx, entity) if err != nil { tx.Rollback() return dtodomain.InventoryTransactionResponse{}, err } tx.Commit() changes := utils.GetChangedFields(before, updated) s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": constants.UPDATE, "entity": "inventory_transaction", "entity_id": updated.ID.String(), "changes": changes, }).Info("Inventory Transaction updated") result, err := s.inventoryTransactionRepo.GetById(ctx, nil, updated.ID.String()) if err != nil { return dtodomain.InventoryTransactionResponse{}, err } return dtodomain.ToInventoryTransactionResponse(result), nil } func (s *inventoryTransactionService) Delete(ctx context.Context, inventoryTransactionId string) error { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() invTransaction, err := s.inventoryTransactionRepo.GetById(ctx, tx, inventoryTransactionId) if err != nil { tx.Rollback() return err } invTransaction.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE) if _, err := s.inventoryTransactionRepo.Update(ctx, tx, invTransaction); err != nil { tx.Rollback() return err } if err := s.inventoryTransactionRepo.Delete(ctx, tx, inventoryTransactionId); err != nil { tx.Rollback() return err } tx.Commit() s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": constants.DELETE, "entity": "inventory_transaction", "entity_id": inventoryTransactionId, }).Info("Inventory Transaction deleted") return nil } func NewInventoryTransactionService(db *gorm.DB, repo repository.InventoryTransactionRepository, log *logrus.Logger) InventoryTransactionService { return &inventoryTransactionService{ db: db, inventoryTransactionRepo: repo, log: log, } }