From 7e4e7cc5a85948f6f0f34c8c2b19f0f14e7fd8ab Mon Sep 17 00:00:00 2001 From: Habib Fatkhul Rohman Date: Thu, 4 Dec 2025 14:11:55 +0700 Subject: [PATCH] feat: integrate logging and audit trail in inventory receipt service --- .../service/inventory_receipt_service.go | 93 ++++++++++++++++++- providers/core.go | 2 +- 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/modules/inventory_receipt/service/inventory_receipt_service.go b/modules/inventory_receipt/service/inventory_receipt_service.go index 13b866e..1d3dfe2 100644 --- a/modules/inventory_receipt/service/inventory_receipt_service.go +++ b/modules/inventory_receipt/service/inventory_receipt_service.go @@ -16,6 +16,7 @@ import ( pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto" "github.com/Caknoooo/go-gin-clean-starter/pkg/utils" "github.com/google/uuid" + "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -40,6 +41,7 @@ type inventoryReceiptService struct { uomRepo uomrepository.UomRepository invStorageRepository invstoragerepository.InventoryStorageRepository sequenceService sequenceservice.SequenceService + log *logrus.Logger } func (s *inventoryReceiptService) GetLinesByReceiptId(ctx context.Context, id string) ([]dtodomain.InventoryReceiptLineResponse, error) { @@ -115,7 +117,28 @@ func (s *inventoryReceiptService) OnComplete(ctx context.Context, id string) (dt // DeleteLine implements InventoryReceiptService. func (s *inventoryReceiptService) DeleteLine(ctx context.Context, lineId string) error { - return s.receiptLineRepo.Delete(ctx, nil, lineId) + line, err := s.receiptLineRepo.GetById(ctx, nil, lineId) + if err != nil { + return err + } + line.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE) + _, err = s.receiptLineRepo.Update(ctx, nil, line) + if err != nil { + return err + } + result := s.receiptLineRepo.Delete(ctx, nil, lineId) + if result != nil { + return result + } + + s.log.WithFields(logrus.Fields{ + "user_id": utils.GetUserID(ctx), + "action": "delete", + "entity": "inventory_receipt_line", + "entity_id": lineId, + }).Info("Inventory Receipt Line deleted") + + return nil } // UpdateLine implements InventoryReceiptService. @@ -124,6 +147,9 @@ func (s *inventoryReceiptService) UpdateLine(ctx context.Context, lineId string, if err != nil { return dtodomain.InventoryReceiptLineResponse{}, err } + + before := line + if req.Quantity != nil { line.Quantity = *req.Quantity } @@ -155,10 +181,22 @@ func (s *inventoryReceiptService) UpdateLine(ctx context.Context, lineId string, line.ProductID = uuid.Nil } } + + line.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE) updated, err := s.receiptLineRepo.Update(ctx, nil, line) if err != nil { return dtodomain.InventoryReceiptLineResponse{}, err } + + changes := utils.GetChangedFields(before, updated) + s.log.WithFields(logrus.Fields{ + "user_id": utils.GetUserID(ctx), + "action": "update", + "entity": "inventory_receipt_line", + "entity_id": lineId, + "changes": changes, + }).Info("Inventory Receipt Line updated") + var repackUomID *string if updated.RepackUomID != nil { tmp := updated.RepackUomID.String() @@ -313,12 +351,14 @@ func (s *inventoryReceiptService) Create(ctx context.Context, req dtodomain.Inve QrCodeFile: req.QrCodeFile, ClientID: clientUUID, Status: req.Status, + FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE), } created, err := s.receiptRepo.Create(ctx, tx, receipt) if err != nil { tx.Rollback() return dtodomain.InventoryReceiptResponse{}, err } + // Bulk create lines var lines []entities.TInventoryReceiptLineEntity // var invStorages []entities.InventoryStorageEntity @@ -403,6 +443,14 @@ func (s *inventoryReceiptService) Create(ctx context.Context, req dtodomain.Inve // } // } tx.Commit() + + s.log.WithFields(logrus.Fields{ + "user_id": utils.GetUserID(ctx), + "action": "create", + "entity": "inventory_receipt", + "entity_id": created.ID.String(), + }).Info("Inventory Receipt created") + result, err := s.receiptRepo.GetById(ctx, nil, created.ID.String()) if err != nil { return dtodomain.InventoryReceiptResponse{}, err @@ -445,6 +493,7 @@ func (s *inventoryReceiptService) Update(ctx context.Context, req dtodomain.Inve tx.Rollback() return dtodomain.InventoryReceiptResponse{}, err } + before := receipt if req.ReferenceNumber != "" { receipt.ReferenceNumber = req.ReferenceNumber } @@ -452,16 +501,27 @@ func (s *inventoryReceiptService) Update(ctx context.Context, req dtodomain.Inve receipt.Source = req.Source receipt.QrCodeFile = req.QrCodeFile receipt.Status = req.Status + receipt.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE) updated, err := s.receiptRepo.Update(ctx, tx, receipt) if err != nil { tx.Rollback() return dtodomain.InventoryReceiptResponse{}, err } tx.Commit() + result, err := s.receiptRepo.GetById(ctx, nil, updated.ID.String()) if err != nil { return dtodomain.InventoryReceiptResponse{}, err } + changes := utils.GetChangedFields(before, result) + s.log.WithFields(logrus.Fields{ + "user_id": utils.GetUserID(ctx), + "action": "update", + "entity": "inventory_receipt", + "entity_id": id, + "changes": changes, + }).Info("Inventory Receipt updated") + return toInventoryReceiptResponse(result), nil } @@ -472,11 +532,30 @@ func (s *inventoryReceiptService) Delete(ctx context.Context, id string) error { tx.Rollback() } }() + receipt, err := s.receiptRepo.GetById(ctx, tx, id) + if err != nil { + tx.Rollback() + return err + } + receipt.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE) + _, err = s.receiptRepo.Update(ctx, tx, receipt) + if err != nil { + tx.Rollback() + return err + } + if err := s.receiptRepo.Delete(ctx, tx, id); err != nil { tx.Rollback() return err } tx.Commit() + + s.log.WithFields(logrus.Fields{ + "user_id": utils.GetUserID(ctx), + "action": "delete", + "entity": "inventory_receipt", + "entity_id": id, + }).Info("Inventory Receipt deleted") return nil } @@ -528,11 +607,20 @@ func (s *inventoryReceiptService) CreateLine(ctx context.Context, receiptId stri InvReceiptID: receiptUUID, ProductID: productUUID, ClientID: clientLineUUID, + FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE), } created, err := s.receiptLineRepo.Create(ctx, nil, line) if err != nil { return dtodomain.InventoryReceiptLineResponse{}, err } + + s.log.WithFields(logrus.Fields{ + "user_id": utils.GetUserID(ctx), + "action": "create", + "entity": "inventory_receipt_line", + "entity_id": created.ID.String(), + }).Info("Inventory Receipt Line created") + var repackUomID *string if created.RepackUomID != nil { tmp := created.RepackUomID.String() @@ -564,7 +652,7 @@ func NewInventoryReceiptService(db *gorm.DB, productRepo productrepository.ProductRepository, uomRepo uomrepository.UomRepository, invStorageRepository invstoragerepository.InventoryStorageRepository, - sequenceService sequenceservice.SequenceService) InventoryReceiptService { + sequenceService sequenceservice.SequenceService, log *logrus.Logger) InventoryReceiptService { return &inventoryReceiptService{ db: db, receiptRepo: receiptRepo, @@ -573,5 +661,6 @@ func NewInventoryReceiptService(db *gorm.DB, uomRepo: uomRepo, invStorageRepository: invStorageRepository, sequenceService: sequenceService, + log: log, } } diff --git a/providers/core.go b/providers/core.go index c829082..e10a4b8 100644 --- a/providers/core.go +++ b/providers/core.go @@ -187,7 +187,7 @@ func RegisterDependencies(injector *do.Injector) { warehouseServ := warehouseService.NewWarehouseService(warehouseRepository, db, log) zonaServ := zonaService.NewZonaService(zonaRepository, db, log) aisleServ := aisleService.NewAisleService(aisleRepository, db, log) - inventoryReceiptServ := inventoryReceiptService.NewInventoryReceiptService(db, inventoryReceiptRepository, inventoryReceiptLineRepository, productRepository, uomRepository, inventoryStorageRepository, sequenceServ) + inventoryReceiptServ := inventoryReceiptService.NewInventoryReceiptService(db, inventoryReceiptRepository, inventoryReceiptLineRepository, productRepository, uomRepository, inventoryStorageRepository, sequenceServ, log) assignmentServ := assignmentService.NewAssignmentService(db, assignmentRepository, assignmentUserRepository) inventoryRequestServ := inventoryRequestService.NewInventoryRequestService(db, inventoryRequestRepository, inventoryRequestLineRepository, sequenceServ) inventoryIssueServ := inventoryIssueService.NewInventoryIssueService(db, inventoryIssueRepository, inventoryIssueLineRepository, sequenceServ, log)