Compare commits

..

16 Commits

Author SHA1 Message Date
Habib Fatkhul Rohman fd664c5c3f feat: integrate logging and audit trail in inventory transaction service
Deploy Application / deploy (push) Failing after 16s Details
2025-12-04 15:05:15 +07:00
Habib Fatkhul Rohman e6b19a2478 feat: integrate logging and audit trail in inventory storage service 2025-12-04 15:00:43 +07:00
Habib Fatkhul Rohman bcc73a0f99 feat: integrate logging and audit trail in inventory return service 2025-12-04 14:54:54 +07:00
Habib Fatkhul Rohman 844a41eb78 feat: integrate logging and audit trail in inventory request service 2025-12-04 14:24:56 +07:00
Habib Fatkhul Rohman 7e4e7cc5a8 feat: integrate logging and audit trail in inventory receipt service 2025-12-04 14:11:55 +07:00
Habib Fatkhul Rohman f36380873c feat: integrate logging and audit trail in inventory movement service 2025-12-04 13:39:12 +07:00
Habib Fatkhul Rohman 41dacd0e3e feat: integrate logging and audit trail in inventory issue service 2025-12-04 13:20:14 +07:00
Habib Fatkhul Rohman e6c025f675 feat: enhance aisle service with logging and audit trail integration 2025-12-03 15:10:51 +07:00
Habib Fatkhul Rohman cf51d7f0c9 feat: integrate logging and audit trail in category service and DTOs 2025-12-03 14:58:00 +07:00
Habib Fatkhul Rohman 6c757e2065 feat: integrate logging and audit trail in client service operations 2025-12-03 14:51:01 +07:00
Habib Fatkhul Rohman cd60dc109f feat: refactor menu service to use ToMenuResponse for response mapping and integrate logging 2025-12-03 14:39:10 +07:00
Habib Fatkhul Rohman 6296fc623c feat: add logging and audit trail to vendor service operations 2025-12-03 14:22:52 +07:00
Habib Fatkhul Rohman b2b1067e00 feat: enhance product service with logging and audit trail functionality 2025-12-03 13:57:47 +07:00
Habib Fatkhul Rohman 8d852521c4 feat: add ToRoleResponse function and integrate logging in role service 2025-12-03 13:30:59 +07:00
Habib Fatkhul Rohman 02c3c97a76 feat: implement ZonaResponse conversion and enhance logging in Zona service 2025-12-03 12:03:48 +07:00
Habib Fatkhul Rohman db82ad3364 feat: refactor configuration management to use viper for environment variables 2025-12-03 11:43:00 +07:00
28 changed files with 1137 additions and 529 deletions

View File

@ -33,6 +33,7 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/warehouse"
"github.com/Caknoooo/go-gin-clean-starter/modules/zona"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
@ -58,13 +59,13 @@ func args(injector *do.Injector) bool {
func run(server *gin.Engine) {
server.Static("/assets", "./assets")
port := os.Getenv("GOLANG_PORT")
port := viper.GetString("GOLANG_PORT")
if port == "" {
port = "8888"
}
var serve string
if os.Getenv("APP_ENV") == "localhost" {
if viper.GetString("APP_ENV") == "localhost" {
serve = "0.0.0.0:" + port
} else {
serve = ":" + port
@ -102,6 +103,13 @@ func run(server *gin.Engine) {
// @externalDocs.description OpenAPI
// @externalDocs.url https://swagger.io/resources/open-api/
func main() {
viper.SetConfigFile(".env")
err := viper.ReadInConfig()
if err != nil {
log.Fatal("Error loading .env file")
}
viper.AutomaticEnv()
var (
injector = do.New()

View File

@ -2,10 +2,10 @@ package config
import (
"fmt"
"os"
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
"github.com/joho/godotenv"
"github.com/spf13/viper"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
@ -15,18 +15,18 @@ func RunExtension(db *gorm.DB) {
}
func SetUpDatabaseConnection() *gorm.DB {
if os.Getenv("APP_ENV") != constants.ENUM_RUN_PRODUCTION {
if viper.GetString("APP_ENV") != constants.ENUM_RUN_PRODUCTION {
err := godotenv.Load(".env")
if err != nil {
panic(err)
}
}
dbUser := os.Getenv("DB_USER")
dbPass := os.Getenv("DB_PASS")
dbHost := os.Getenv("DB_HOST")
dbName := os.Getenv("DB_NAME")
dbPort := os.Getenv("DB_PORT")
dbUser := viper.GetString("DB_USER")
dbPass := viper.GetString("DB_PASS")
dbHost := viper.GetString("DB_HOST")
dbName := viper.GetString("DB_NAME")
dbPort := viper.GetString("DB_PORT")
dsn := fmt.Sprintf("host=%v user=%v password=%v dbname=%v port=%v", dbHost, dbUser, dbPass, dbName, dbPort)

View File

@ -14,6 +14,7 @@ type EmailConfig struct {
func NewEmailConfig() (*EmailConfig, error) {
viper.SetConfigFile(".env")
if err := viper.ReadInConfig(); err != nil {
return nil, err

View File

@ -11,6 +11,7 @@ import (
amqp "github.com/rabbitmq/amqp091-go"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"gorm.io/gorm/logger"
)
@ -70,12 +71,12 @@ func SetupLoggerLogrus() *logrus.Logger {
// ✔️ Pasang RabbitMQ Hook kalau channel berhasil connect
if RabbitChannel != nil {
queue := os.Getenv("RABBITMQ_LOG_QUEUE") // contoh: log_queue
queue := viper.GetString("RABBITMQ_LOG_QUEUE") // contoh: log_queue
hook := NewRabbitMQHook(RabbitChannel, queue)
logger.AddHook(hook)
}
logLevel := strings.ToLower(os.Getenv("LOG_LEVEL"))
logLevel := strings.ToLower(viper.GetString("LOG_LEVEL"))
if logLevel == "production" {
logger.SetLevel(logrus.WarnLevel)
} else {

View File

@ -3,20 +3,20 @@ package config
import (
"fmt"
"log"
"os"
amqp "github.com/rabbitmq/amqp091-go"
"github.com/spf13/viper"
)
var RabbitConn *amqp.Connection
var RabbitChannel *amqp.Channel
func InitRabbitMQ() {
host := os.Getenv("RABBITMQ_HOST")
port := os.Getenv("RABBITMQ_PORT")
user := os.Getenv("RABBITMQ_USER")
pass := os.Getenv("RABBITMQ_PASSWORD")
queue := os.Getenv("RABBITMQ_LOG_QUEUE") // contoh: log_queue
host := viper.GetString("RABBITMQ_HOST")
port := viper.GetString("RABBITMQ_PORT")
user := viper.GetString("RABBITMQ_USER")
pass := viper.GetString("RABBITMQ_PASSWORD")
queue := viper.GetString("RABBITMQ_LOG_QUEUE") // contoh: log_queue
uri := fmt.Sprintf("amqp://%s:%s@%s:%s/",
user, pass, host, port,

View File

@ -3,7 +3,9 @@ package dto
import (
"errors"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/google/uuid"
)
const (
@ -75,3 +77,48 @@ type AisleResponse struct {
WeightUom pkgdto.IdNameResponse `json:"weight_uom_id"`
Client pkgdto.IdNameResponse `json:"client_id"`
}
func ToAisleResponse(e entities.MAisleEntity) AisleResponse {
zona := pkgdto.IdNameResponse{}
if e.Zona.ID != uuid.Nil {
zona.ID = e.Zona.ID.String()
zona.Name = e.Zona.Name
}
dimUom := pkgdto.IdNameResponse{}
if e.DimUom.ID != uuid.Nil {
dimUom.ID = e.DimUom.ID.String()
dimUom.Name = e.DimUom.Name
}
weightUom := pkgdto.IdNameResponse{}
if e.WeightUom.ID != uuid.Nil {
weightUom.ID = e.WeightUom.ID.String()
weightUom.Name = e.WeightUom.Name
}
client := pkgdto.IdNameResponse{}
if e.Client.ID != uuid.Nil {
client.ID = e.Client.ID.String()
client.Name = e.Client.Name
}
return AisleResponse{
ID: e.ID.String(),
Code: e.Code,
Name: e.Name,
IsleX: e.IsleX,
BinY: e.BinY,
LevelZ: e.LevelZ,
DimLength: e.DimLength,
DimWidth: e.DimWidth,
DimHeight: e.DimHeight,
Weight: e.Weight,
QrCodeAisle: e.QrCodeAisle,
IsActive: e.IsActive,
Zone: zona,
DimUom: dimUom,
WeightUom: weightUom,
Client: client,
}
}

View File

@ -7,8 +7,10 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/aisle/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/aisle/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/aisle/repository"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"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"
)
@ -23,51 +25,7 @@ type AisleService interface {
type aisleService struct {
db *gorm.DB
aisleRepo repository.AisleRepository
}
func toAisleResponse(e entities.MAisleEntity) dto.AisleResponse {
zona := pkgdto.IdNameResponse{}
if e.Zona.ID != uuid.Nil {
zona.ID = e.Zona.ID.String()
zona.Name = e.Zona.Name
}
dimUom := pkgdto.IdNameResponse{}
if e.DimUom.ID != uuid.Nil {
dimUom.ID = e.DimUom.ID.String()
dimUom.Name = e.DimUom.Name
}
weightUom := pkgdto.IdNameResponse{}
if e.WeightUom.ID != uuid.Nil {
weightUom.ID = e.WeightUom.ID.String()
weightUom.Name = e.WeightUom.Name
}
client := pkgdto.IdNameResponse{}
if e.Client.ID != uuid.Nil {
client.ID = e.Client.ID.String()
client.Name = e.Client.Name
}
return dto.AisleResponse{
ID: e.ID.String(),
Code: e.Code,
Name: e.Name,
IsleX: e.IsleX,
BinY: e.BinY,
LevelZ: e.LevelZ,
DimLength: e.DimLength,
DimWidth: e.DimWidth,
DimHeight: e.DimHeight,
Weight: e.Weight,
QrCodeAisle: e.QrCodeAisle,
IsActive: e.IsActive,
Zone: zona,
DimUom: dimUom,
WeightUom: weightUom,
Client: client,
}
log *logrus.Logger
}
func (s *aisleService) Create(ctx context.Context, req dto.AisleCreateRequest) (dto.AisleResponse, error) {
@ -98,21 +56,22 @@ func (s *aisleService) Create(ctx context.Context, req dto.AisleCreateRequest) (
return dto.AisleResponse{}, err
}
aisle := entities.MAisleEntity{
Code: req.Code,
Name: req.Name,
IsleX: req.IsleX,
BinY: req.BinY,
LevelZ: req.LevelZ,
DimLength: req.DimLength,
DimWidth: req.DimWidth,
DimHeight: req.DimHeight,
Weight: req.Weight,
QrCodeAisle: req.QrCodeAisle,
IsActive: req.IsActive,
ZoneID: zoneUUID,
DimUomID: dimUomUUID,
WeightUomID: weightUomUUID,
ClientID: clientUUID,
Code: req.Code,
Name: req.Name,
IsleX: req.IsleX,
BinY: req.BinY,
LevelZ: req.LevelZ,
DimLength: req.DimLength,
DimWidth: req.DimWidth,
DimHeight: req.DimHeight,
Weight: req.Weight,
QrCodeAisle: req.QrCodeAisle,
IsActive: req.IsActive,
ZoneID: zoneUUID,
DimUomID: dimUomUUID,
WeightUomID: weightUomUUID,
ClientID: clientUUID,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.aisleRepo.Create(ctx, tx, aisle)
if err != nil {
@ -124,7 +83,13 @@ func (s *aisleService) Create(ctx context.Context, req dto.AisleCreateRequest) (
if err != nil {
return dto.AisleResponse{}, err
}
return toAisleResponse(result), nil
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "create",
"entity": "aisle",
"entity_id": created.ID.String(),
}).Info("Aisle created")
return dto.ToAisleResponse(result), nil
}
func (s *aisleService) GetById(ctx context.Context, aisleId string) (dto.AisleResponse, error) {
@ -132,7 +97,7 @@ func (s *aisleService) GetById(ctx context.Context, aisleId string) (dto.AisleRe
if err != nil {
return dto.AisleResponse{}, err
}
return toAisleResponse(aisle), nil
return dto.ToAisleResponse(aisle), nil
}
func (s *aisleService) GetAll(ctx context.Context, filter query.AisleFilter) ([]dto.AisleResponse, int64, error) {
@ -142,7 +107,7 @@ func (s *aisleService) GetAll(ctx context.Context, filter query.AisleFilter) ([]
}
var responses []dto.AisleResponse
for _, e := range aisles {
responses = append(responses, toAisleResponse(e))
responses = append(responses, dto.ToAisleResponse(e))
}
if responses == nil {
responses = make([]dto.AisleResponse, 0)
@ -193,6 +158,7 @@ func (s *aisleService) Update(ctx context.Context, req dto.AisleUpdateRequest, a
aisle.QrCodeAisle = req.QrCodeAisle
}
aisle.IsActive = req.IsActive
aisle.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.aisleRepo.Update(ctx, tx, aisle)
if err != nil {
tx.Rollback()
@ -203,7 +169,13 @@ func (s *aisleService) Update(ctx context.Context, req dto.AisleUpdateRequest, a
if err != nil {
return dto.AisleResponse{}, err
}
return toAisleResponse(result), nil
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "update",
"entity": "aisle",
"entity_id": aisleId,
}).Info("Aisle updated")
return dto.ToAisleResponse(result), nil
}
func (s *aisleService) Delete(ctx context.Context, aisleId string) error {
@ -213,17 +185,34 @@ func (s *aisleService) Delete(ctx context.Context, aisleId string) error {
tx.Rollback()
}
}()
aisle, err := s.aisleRepo.GetById(ctx, tx, aisleId)
if err != nil {
tx.Rollback()
return err
}
aisle.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.aisleRepo.Update(ctx, tx, aisle); err != nil {
tx.Rollback()
return err
}
if err := s.aisleRepo.Delete(ctx, tx, aisleId); err != nil {
tx.Rollback()
return err
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "delete",
"entity": "aisle",
"entity_id": aisleId,
}).Info("Aisle deleted")
return nil
}
func NewAisleService(aisleRepo repository.AisleRepository, db *gorm.DB) AisleService {
func NewAisleService(aisleRepo repository.AisleRepository, db *gorm.DB, log *logrus.Logger) AisleService {
return &aisleService{
aisleRepo: aisleRepo,
db: db,
log: log,
}
}

View File

@ -5,10 +5,10 @@ import (
"encoding/base64"
"fmt"
"log"
"os"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/spf13/viper"
)
type UserTokenInfo struct {
@ -51,7 +51,7 @@ func NewJWTService() JWTService {
}
func getSecretKey() string {
secretKey := os.Getenv("JWT_SECRET")
secretKey := viper.GetString("JWT_SECRET")
if secretKey == "" {
secretKey = "WMS-WareifySecretKey"
}

View File

@ -3,8 +3,8 @@ package dto
import (
"errors"
// staticDto "github.com/Caknoooo/go-gin-clean-starter/modules/static/dto"
"github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
)
const (
@ -43,10 +43,24 @@ type CategoryUpdateRequest struct {
}
type CategoryResponse struct {
ID string `json:"id"`
Name string `json:"name"`
SearchKey string `json:"search_key"`
Description string `json:"description"`
IsActive bool `json:"is_active"`
Client dto.ClientResponse `json:"client"`
ID string `json:"id"`
Name string `json:"name"`
SearchKey string `json:"search_key"`
Description string `json:"description"`
IsActive bool `json:"is_active"`
Client pkgdto.IdNameResponse `json:"client"`
}
func ToCategoryResponse(e entities.MCategoryEntity) CategoryResponse {
return CategoryResponse{
ID: e.ID.String(),
Name: e.Name,
SearchKey: e.SearchKey,
Description: e.Description,
IsActive: e.IsActive,
Client: pkgdto.IdNameResponse{
ID: e.Client.ID.String(),
Name: e.Client.Name,
},
}
}

View File

@ -7,8 +7,10 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/category/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/category/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/category/repository"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"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"
)
@ -23,12 +25,14 @@ type CategoryService interface {
type categoryService struct {
db *gorm.DB
categoryRepo repository.CategoryRepository
log *logrus.Logger
}
func NewCategoryService(categoryRepo repository.CategoryRepository, db *gorm.DB) CategoryService {
func NewCategoryService(categoryRepo repository.CategoryRepository, db *gorm.DB, log *logrus.Logger) CategoryService {
return &categoryService{
categoryRepo: categoryRepo,
db: db,
log: log,
}
}
@ -40,10 +44,11 @@ func (s *categoryService) Create(ctx context.Context, req dto.CategoryCreateRequ
}
}()
category := entities.MCategoryEntity{
Name: req.Name,
SearchKey: req.SearchKey,
Description: req.Description,
IsActive: req.IsActive,
Name: req.Name,
SearchKey: req.SearchKey,
Description: req.Description,
IsActive: req.IsActive,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
clientUUID, err := uuid.Parse(req.ClientID)
if err != nil {
@ -62,7 +67,13 @@ func (s *categoryService) Create(ctx context.Context, req dto.CategoryCreateRequ
if err != nil {
return dto.CategoryResponse{}, err
}
return toCategoryResponse(result), nil
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "create",
"entity": "category",
"entity_id": created.ID.String(),
}).Info("Category created")
return dto.ToCategoryResponse(result), nil
}
func (s *categoryService) GetById(ctx context.Context, categoryId string) (dto.CategoryResponse, error) {
@ -70,7 +81,7 @@ func (s *categoryService) GetById(ctx context.Context, categoryId string) (dto.C
if err != nil {
return dto.CategoryResponse{}, err
}
return toCategoryResponse(category), nil
return dto.ToCategoryResponse(category), nil
}
func (s *categoryService) GetAll(ctx context.Context, filter query.CategoryFilter) ([]dto.CategoryResponse, int64, error) {
@ -80,7 +91,7 @@ func (s *categoryService) GetAll(ctx context.Context, filter query.CategoryFilte
}
var responses []dto.CategoryResponse
for _, c := range categories {
responses = append(responses, toCategoryResponse(c))
responses = append(responses, dto.ToCategoryResponse(c))
}
if responses == nil {
responses = make([]dto.CategoryResponse, 0)
@ -104,6 +115,7 @@ func (s *categoryService) Update(ctx context.Context, req dto.CategoryUpdateRequ
category.SearchKey = req.SearchKey
category.Description = req.Description
category.IsActive = req.IsActive
category.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.categoryRepo.Update(ctx, tx, category)
if err != nil {
tx.Rollback()
@ -115,7 +127,13 @@ func (s *categoryService) Update(ctx context.Context, req dto.CategoryUpdateRequ
if err != nil {
return dto.CategoryResponse{}, err
}
return toCategoryResponse(result), nil
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "update",
"entity": "category",
"entity_id": categoryId,
}).Info("Category updated")
return dto.ToCategoryResponse(result), nil
}
func (s *categoryService) Delete(ctx context.Context, categoryId string) error {
@ -125,24 +143,27 @@ func (s *categoryService) Delete(ctx context.Context, categoryId string) error {
tx.Rollback()
}
}()
category, err := s.categoryRepo.GetById(ctx, tx, categoryId)
if err != nil {
tx.Rollback()
return err
}
category.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.categoryRepo.Update(ctx, tx, category); err != nil {
tx.Rollback()
return err
}
if err := s.categoryRepo.Delete(ctx, tx, categoryId); err != nil {
tx.Rollback()
return err
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "delete",
"entity": "category",
"entity_id": categoryId,
}).Info("Category deleted")
return nil
}
func toCategoryResponse(e entities.MCategoryEntity) dto.CategoryResponse {
return dto.CategoryResponse{
ID: e.ID.String(),
Name: e.Name,
SearchKey: e.SearchKey,
Description: e.Description,
IsActive: e.IsActive,
Client: pkgdto.ClientResponse{
ID: e.Client.ID.String(),
Name: e.Client.Name,
},
}
}

View File

@ -7,6 +7,9 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/client/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/client/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/client/repository"
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
@ -24,6 +27,7 @@ type ClientService interface {
type clientService struct {
db *gorm.DB
clientRepo repository.ClientRepository
log *logrus.Logger
}
func (s *clientService) GetAll(ctx context.Context, filter query.ClientFilter) ([]dto.ClientResponse, int64, error) {
@ -63,13 +67,15 @@ func (s *clientService) Create(ctx context.Context, req dto.ClientCreateRequest)
}
}()
userID := utils.GetUserID(ctx)
client := entities.M_Client{
Name: req.Name,
PIC: req.PIC,
Phone: req.Phone,
Email: req.Email,
Address: req.Address,
Logo: req.Logo, // []byte, sudah benar untuk simpan file
Name: req.Name,
PIC: req.PIC,
Phone: req.Phone,
Email: req.Email,
Address: req.Address,
Logo: req.Logo,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
createdClient, err := s.clientRepo.Create(ctx, tx, client)
@ -83,11 +89,12 @@ func (s *clientService) Create(ctx context.Context, req dto.ClientCreateRequest)
return dto.ClientResponse{}, err
}
// Mapping entity ke response (Logo bisa dikonversi ke base64 jika perlu)
// logoBase64 := ""
// if len(createdClient.Logo) > 0 {
// logoBase64 = base64.StdEncoding.EncodeToString(createdClient.Logo)
// }
s.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "create",
"entity": "client",
"entity_id": createdClient.ID.String(),
}).Info("Client created")
result, err := s.GetById(ctx, createdClient.ID.String())
if err != nil {
@ -177,6 +184,8 @@ func (s *clientService) Update(ctx context.Context, req dto.ClientUpdateRequest,
if req.Logo != nil {
client.Logo = *req.Logo
}
userID := utils.GetUserID(ctx)
client.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updatedClient, err := s.clientRepo.Update(ctx, tx, client)
if err != nil {
tx.Rollback()
@ -187,10 +196,13 @@ func (s *clientService) Update(ctx context.Context, req dto.ClientUpdateRequest,
tx.Rollback()
return dto.ClientResponse{}, err
}
// logoBase64 := ""
// if len(updatedClient.Logo) > 0 {
// logoBase64 = base64.StdEncoding.EncodeToString(updatedClient.Logo)
// }
s.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "update",
"entity": "client",
"entity_id": clientId,
}).Info("Client updated")
result, err := s.GetById(ctx, updatedClient.ID.String())
if err != nil {
@ -206,7 +218,18 @@ func (s *clientService) Delete(ctx context.Context, clientId string) error {
tx.Rollback()
}
}()
err := s.clientRepo.Delete(ctx, tx, clientId)
client, err := s.clientRepo.GetById(ctx, tx, clientId)
if err != nil {
tx.Rollback()
return err
}
userID := utils.GetUserID(ctx)
client.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.clientRepo.Update(ctx, tx, client); err != nil {
tx.Rollback()
return err
}
err = s.clientRepo.Delete(ctx, tx, clientId)
if err != nil {
tx.Rollback()
return err
@ -216,6 +239,13 @@ func (s *clientService) Delete(ctx context.Context, clientId string) error {
tx.Rollback()
return err
}
s.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "delete",
"entity": "client",
"entity_id": clientId,
}).Info("Client deleted")
return nil
}
@ -237,9 +267,10 @@ func (s *clientService) RemoveMenusFromClient(ctx context.Context, clientId stri
return s.clientRepo.RemoveMenusFromClient(ctx, s.db, clientId, menuIds)
}
func NewClientService(clientRepo repository.ClientRepository, db *gorm.DB) ClientService {
func NewClientService(clientRepo repository.ClientRepository, db *gorm.DB, log *logrus.Logger) ClientService {
return &clientService{
clientRepo: clientRepo,
db: db,
log: log,
}
}

View File

@ -8,9 +8,11 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/repository"
sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service"
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
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"
)
@ -31,6 +33,7 @@ type inventoryIssueService struct {
issueRepo repository.InventoryIssueRepository
issueLineRepo repository.InventoryIssueLineRepository
sequenceService sequenceservice.SequenceService
log *logrus.Logger
}
// GetLinesByIssueId implements InventoryIssueService.
@ -42,8 +45,8 @@ func (s *inventoryIssueService) GetLinesByIssueId(ctx context.Context, issueId s
return dtodomain.ToInventoryIssueLineResponses(lines), nil
}
func NewInventoryIssueService(db *gorm.DB, issueRepo repository.InventoryIssueRepository, issueLineRepo repository.InventoryIssueLineRepository, sequenceService sequenceservice.SequenceService) InventoryIssueService {
return &inventoryIssueService{db: db, issueRepo: issueRepo, issueLineRepo: issueLineRepo, sequenceService: sequenceService}
func NewInventoryIssueService(db *gorm.DB, issueRepo repository.InventoryIssueRepository, issueLineRepo repository.InventoryIssueLineRepository, sequenceService sequenceservice.SequenceService, log *logrus.Logger) InventoryIssueService {
return &inventoryIssueService{db: db, issueRepo: issueRepo, issueLineRepo: issueLineRepo, sequenceService: sequenceService, log: log}
}
func (s *inventoryIssueService) Create(ctx context.Context, req dtodomain.InventoryIssueCreateRequest) (dtodomain.InventoryIssueResponse, error) {
@ -85,6 +88,7 @@ func (s *inventoryIssueService) Create(ctx context.Context, req dtodomain.Invent
InvRequestID: invRequestUUID,
ClientID: clientUUID,
Status: req.Status,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.issueRepo.Create(ctx, tx, issue)
if err != nil {
@ -129,6 +133,12 @@ func (s *inventoryIssueService) Create(ctx context.Context, req dtodomain.Invent
}
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "create",
"entity": "inventory_issue",
"entity_id": created.ID.String(),
}).Info("Inventory Issue created")
result, err := s.issueRepo.GetById(ctx, nil, created.ID.String())
if err != nil {
return dtodomain.InventoryIssueResponse{}, err
@ -171,19 +181,34 @@ func (s *inventoryIssueService) Update(ctx context.Context, req dtodomain.Invent
tx.Rollback()
return dtodomain.InventoryIssueResponse{}, err
}
before := issue
issue.DocumentDate = utils.StringToDateTime(req.DocumentDate)
issue.DueDate = utils.StringToDateTime(req.DueDate)
issue.Status = req.Status
issue.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.issueRepo.Update(ctx, tx, issue)
if err != nil {
tx.Rollback()
return dtodomain.InventoryIssueResponse{}, err
}
tx.Commit()
result, err := s.issueRepo.GetById(ctx, nil, updated.ID.String())
if err != nil {
return dtodomain.InventoryIssueResponse{}, err
}
changes := utils.GetChangedFields(before, result)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "update",
"entity": "inventory_issue",
"entity_id": id,
"changes": changes,
}).Info("Inventory Issue updated")
return dtodomain.ToInventoryIssueResponse(result), nil
}
@ -194,11 +219,27 @@ func (s *inventoryIssueService) Delete(ctx context.Context, id string) error {
tx.Rollback()
}
}()
issue, err := s.issueRepo.GetById(ctx, tx, id)
if err != nil {
tx.Rollback()
return err
}
issue.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.issueRepo.Update(ctx, tx, issue); err != nil {
tx.Rollback()
return err
}
if err := s.issueRepo.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_issue",
"entity_id": id,
}).Info("Inventory Issue deleted")
return nil
}

View File

@ -8,8 +8,10 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_movement/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_movement/repository"
sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service"
"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"
)
@ -30,6 +32,7 @@ type inventoryMovementService struct {
movementRepo repository.InventoryMovementRepository
movementLineRepo repository.InventoryMovementLineRepository
sequenceService sequenceservice.SequenceService
log *logrus.Logger
}
// GetLinesByMovementId implements InventoryMovementService.
@ -73,6 +76,7 @@ func (s *inventoryMovementService) Create(ctx context.Context, req dtodomain.Inv
Status: req.Status,
SourceLocationID: uuid.MustParse(req.SourceLocationID),
DestinationLocationID: uuid.MustParse(req.DestinationLocationID),
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.movementRepo.Create(ctx, tx, movement)
if err != nil {
@ -116,6 +120,14 @@ func (s *inventoryMovementService) Create(ctx context.Context, req dtodomain.Inv
if err != nil {
return dtodomain.InventoryMovementResponse{}, err
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "create",
"entity": "inventory_movement",
"entity_id": created.ID.String(),
}).Info("Inventory Movement created")
return dtodomain.ToInventoryMovementResponse(result), nil
}
@ -154,12 +166,14 @@ func (s *inventoryMovementService) Update(ctx context.Context, req dtodomain.Inv
tx.Rollback()
return dtodomain.InventoryMovementResponse{}, err
}
// if req.MovementNumber != "" {
// movement.MovementNumber = req.MovementNumber
// }
before := movement
movement.MovementDate = utils.StringToDateTime(req.MovementDate)
movement.MovementType = req.MovementType
movement.Status = req.Status
movement.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.movementRepo.Update(ctx, tx, movement)
if err != nil {
tx.Rollback()
@ -170,6 +184,15 @@ func (s *inventoryMovementService) Update(ctx context.Context, req dtodomain.Inv
if err != nil {
return dtodomain.InventoryMovementResponse{}, err
}
changes := utils.GetChangedFields(before, result)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "update",
"entity": "inventory_movement",
"entity_id": id,
"changes": changes,
}).Info("Inventory Movement updated")
return dtodomain.ToInventoryMovementResponse(result), nil
}
@ -180,11 +203,29 @@ func (s *inventoryMovementService) Delete(ctx context.Context, id string) error
tx.Rollback()
}
}()
movement, err := s.movementRepo.GetById(ctx, tx, id)
if err != nil {
tx.Rollback()
return err
}
movement.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.movementRepo.Update(ctx, tx, movement); err != nil {
tx.Rollback()
return err
}
if err := s.movementRepo.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_movement",
"entity_id": id,
}).Info("Inventory Movement deleted")
return nil
}
@ -205,17 +246,25 @@ func (s *inventoryMovementService) CreateLine(ctx context.Context, movementId st
return dtodomain.InventoryMovementLineResponse{}, err
}
line := entities.TInventoryMovementLineEntity{
MovedQuantity: req.MovedQuantity,
InvMovementID: movementUUID,
ProductID: productUUID,
StorageID: uuid.MustParse(req.StorageID),
ClientID: clientLineUUID,
Status: req.Status,
MovedQuantity: req.MovedQuantity,
InvMovementID: movementUUID,
ProductID: productUUID,
StorageID: uuid.MustParse(req.StorageID),
ClientID: clientLineUUID,
Status: req.Status,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.movementLineRepo.Create(ctx, nil, line)
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "create",
"entity": "inventory_movement_line",
"entity_id": created.ID.String(),
}).Info("Inventory Movement Line created")
return dtodomain.ToInventoryMovementLineResponse(created), nil
}
@ -224,6 +273,7 @@ func (s *inventoryMovementService) UpdateLine(ctx context.Context, lineId string
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
before := line
if req.MovedQuantity != nil {
line.MovedQuantity = *req.MovedQuantity
}
@ -234,18 +284,47 @@ func (s *inventoryMovementService) UpdateLine(ctx context.Context, lineId string
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
changes := utils.GetChangedFields(before, updated)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "update",
"entity": "inventory_movement_line",
"entity_id": lineId,
"changes": changes,
}).Info("Inventory Movement Line updated")
return dtodomain.ToInventoryMovementLineResponse(updated), nil
}
func (s *inventoryMovementService) DeleteLine(ctx context.Context, lineId string) error {
return s.movementLineRepo.Delete(ctx, nil, lineId)
line, err := s.movementLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return err
}
line.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.movementLineRepo.Update(ctx, nil, line); err != nil {
return err
}
result := s.movementLineRepo.Delete(ctx, nil, lineId)
if result != nil {
return result
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "delete",
"entity": "inventory_movement_line",
"entity_id": lineId,
}).Info("Inventory Movement Line deleted")
return nil
}
func NewInventoryMovementService(db *gorm.DB, movementRepo repository.InventoryMovementRepository, movementLineRepo repository.InventoryMovementLineRepository, sequenceService sequenceservice.SequenceService) InventoryMovementService {
func NewInventoryMovementService(db *gorm.DB, movementRepo repository.InventoryMovementRepository, movementLineRepo repository.InventoryMovementLineRepository, sequenceService sequenceservice.SequenceService, log *logrus.Logger) InventoryMovementService {
return &inventoryMovementService{
db: db,
movementRepo: movementRepo,
movementLineRepo: movementLineRepo,
sequenceService: sequenceService,
log: log,
}
}

View File

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

View File

@ -8,9 +8,11 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/repository"
sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service"
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
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"
)
@ -31,6 +33,7 @@ type inventoryRequestService struct {
requestRepo repository.InventoryRequestRepository
requestLineRepo repository.InventoryRequestLineRepository
sequenceService sequenceservice.SequenceService
log *logrus.Logger
}
// GetLinesByRequestId implements InventoryRequestService.
@ -43,7 +46,29 @@ func (s *inventoryRequestService) GetLinesByRequestId(ctx context.Context, reque
}
func (s *inventoryRequestService) DeleteLine(ctx context.Context, lineId string) error {
return s.requestLineRepo.Delete(ctx, nil, lineId)
line, err := s.requestLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return err
}
line.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
_, err = s.requestLineRepo.Update(ctx, nil, line)
if err != nil {
return err
}
result := s.requestLineRepo.Delete(ctx, nil, lineId)
if result != nil {
return result
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.DELETE,
"entity": "inventory_request_line",
"entity_id": lineId,
}).Info("Inventory Request Line deleted")
return nil
}
func (s *inventoryRequestService) UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryRequestLineUpdateRequest) (dtodomain.InventoryRequestLineResponse, error) {
@ -51,6 +76,10 @@ func (s *inventoryRequestService) UpdateLine(ctx context.Context, lineId string,
if err != nil {
return dtodomain.InventoryRequestLineResponse{}, err
}
before := line
line.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
if req.Quantity != nil {
line.Quantity = *req.Quantity
}
@ -69,6 +98,16 @@ func (s *inventoryRequestService) UpdateLine(ctx context.Context, lineId string,
if err != nil {
return dtodomain.InventoryRequestLineResponse{}, err
}
changes := utils.GetChangedFields(before, updated)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.UPDATE,
"entity": "inventory_request_line",
"entity_id": lineId,
"changes": changes,
}).Info("Inventory Request Line updated")
product := dtodomain.InventoryRequestLineProductResponse{}
if updated.Product.ID != uuid.Nil {
product = dtodomain.InventoryRequestLineProductResponse{
@ -119,6 +158,7 @@ func (s *inventoryRequestService) Create(ctx context.Context, req dtodomain.Inve
Note: req.Note,
ClientID: clientUUID,
Status: req.Status,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.requestRepo.Create(ctx, tx, request)
if err != nil {
@ -157,6 +197,15 @@ func (s *inventoryRequestService) Create(ctx context.Context, req dtodomain.Inve
}
}
tx.Commit()
// Log the creation of the inventory request
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.CREATE,
"entity": "inventory_request",
"entity_id": created.ID.String(),
}).Info("Inventory Request created")
result, err := s.requestRepo.GetById(ctx, nil, created.ID.String())
if err != nil {
return dtodomain.InventoryRequestResponse{}, err
@ -199,6 +248,11 @@ func (s *inventoryRequestService) Update(ctx context.Context, req dtodomain.Inve
tx.Rollback()
return dtodomain.InventoryRequestResponse{}, err
}
before := request
request.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
if req.ReferenceNumber != "" {
request.ReferenceNumber = req.ReferenceNumber
}
@ -217,6 +271,15 @@ func (s *inventoryRequestService) Update(ctx context.Context, req dtodomain.Inve
if err != nil {
return dtodomain.InventoryRequestResponse{}, err
}
changes := utils.GetChangedFields(before, result)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.UPDATE,
"entity": "inventory_request",
"entity_id": id,
"changes": changes,
}).Info("Inventory Request updated")
return dtodomain.ToInventoryRequestResponse(result), nil
}
@ -227,11 +290,31 @@ func (s *inventoryRequestService) Delete(ctx context.Context, id string) error {
tx.Rollback()
}
}()
request, err := s.requestRepo.GetById(ctx, tx, id)
if err != nil {
tx.Rollback()
return err
}
request.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.requestRepo.Update(ctx, tx, request); err != nil {
tx.Rollback()
return err
}
if err := s.requestRepo.Delete(ctx, tx, id); err != nil {
tx.Rollback()
return err
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.DELETE,
"entity": "inventory_request",
"entity_id": id,
}).Info("Inventory Request deleted")
return nil
}
@ -283,11 +366,12 @@ func (s *inventoryRequestService) CreateLine(ctx context.Context, requestId stri
}, nil
}
func NewInventoryRequestService(db *gorm.DB, requestRepo repository.InventoryRequestRepository, requestLineRepo repository.InventoryRequestLineRepository, sequenceService sequenceservice.SequenceService) InventoryRequestService {
func NewInventoryRequestService(db *gorm.DB, requestRepo repository.InventoryRequestRepository, requestLineRepo repository.InventoryRequestLineRepository, sequenceService sequenceservice.SequenceService, log *logrus.Logger) InventoryRequestService {
return &inventoryRequestService{
db: db,
requestRepo: requestRepo,
requestLineRepo: requestLineRepo,
sequenceService: sequenceService,
log: log,
}
}

View File

@ -11,9 +11,11 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_return/repository"
productrepository "github.com/Caknoooo/go-gin-clean-starter/modules/product/repository"
sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service"
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
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"
)
@ -36,6 +38,7 @@ type inventoryReturnService struct {
issueLineRepo issueRepository.InventoryIssueLineRepository
productRepo productrepository.ProductRepository
sequenceService sequenceservice.SequenceService
log *logrus.Logger
}
// GetLinesByReturnId implements InventoryReturnService.
@ -49,7 +52,29 @@ func (s *inventoryReturnService) GetLinesByReturnId(ctx context.Context, returnI
// DeleteLine implements InventoryReturnService.
func (s *inventoryReturnService) DeleteLine(ctx context.Context, lineId string) error {
return s.returnLineRepo.Delete(ctx, nil, lineId)
ireturn, err := s.returnLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return err
}
ireturn.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
_, err = s.returnLineRepo.Update(ctx, nil, ireturn)
if err != nil {
return err
}
result := s.returnLineRepo.Delete(ctx, nil, lineId)
if result != nil {
return result
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.DELETE,
"entity": "inventory_return_line",
"entity_id": lineId,
}).Info("Inventory Return Line deleted")
return nil
}
// UpdateLine implements InventoryReturnService.
@ -59,6 +84,8 @@ func (s *inventoryReturnService) UpdateLine(ctx context.Context, lineId string,
return dtodomain.InventoryReturnLineResponse{}, err
}
before := line
// Ambil product untuk cek returnable
product, err := s.productRepo.GetById(ctx, nil, line.ProductID.String())
if err != nil {
@ -87,11 +114,27 @@ func (s *inventoryReturnService) UpdateLine(ctx context.Context, lineId string,
if req.ClientID != nil {
line.ClientID = uuid.MustParse(*req.ClientID)
}
line.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updatedLine, err := s.returnLineRepo.Update(ctx, nil, line)
if err != nil {
return dtodomain.InventoryReturnLineResponse{}, err
}
return dtodomain.ToInventoryReturnLineResponse(updatedLine), nil
result, err := s.returnLineRepo.GetById(ctx, nil, updatedLine.ID.String())
if err != nil {
return dtodomain.InventoryReturnLineResponse{}, err
}
changes := utils.GetChangedFields(before, result)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.UPDATE,
"entity": "inventory_return_line",
"entity_id": lineId,
"changes": changes,
}).Info("Inventory Return Line updated")
return dtodomain.ToInventoryReturnLineResponse(result), nil
}
func (s *inventoryReturnService) Create(ctx context.Context, req dtodomain.InventoryReturnCreateRequest) (dtodomain.InventoryReturnResponse, error) {
@ -128,6 +171,7 @@ func (s *inventoryReturnService) Create(ctx context.Context, req dtodomain.Inven
Status: req.Status,
InvIssueID: invIssueId,
ClientID: clientUUID,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.returnRepo.Create(ctx, tx, entity)
if err != nil {
@ -169,6 +213,14 @@ func (s *inventoryReturnService) Create(ctx context.Context, req dtodomain.Inven
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.CREATE,
"entity": "inventory_return",
"entity_id": created.ID.String(),
}).Info("Inventory Return created")
result, err := s.returnRepo.GetById(ctx, nil, created.ID.String())
if err != nil {
return dtodomain.InventoryReturnResponse{}, err
@ -211,11 +263,13 @@ func (s *inventoryReturnService) Update(ctx context.Context, req dtodomain.Inven
tx.Rollback()
return dtodomain.InventoryReturnResponse{}, err
}
before := ret
ret.DocumentDate = utils.StringToDateTime(req.DocumentDate)
ret.Notes = req.Notes
ret.Status = req.Status
ret.InvIssueID = uuid.MustParse(req.InvIssueID)
ret.ClientID = uuid.MustParse(req.ClientID)
ret.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.returnRepo.Update(ctx, tx, ret)
if err != nil {
tx.Rollback()
@ -226,6 +280,15 @@ func (s *inventoryReturnService) Update(ctx context.Context, req dtodomain.Inven
if err != nil {
return dtodomain.InventoryReturnResponse{}, err
}
changes := utils.GetChangedFields(before, result)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.UPDATE,
"entity": "inventory_return",
"entity_id": id,
"changes": changes,
}).Info("Inventory Return updated")
return dtodomain.ToInventoryReturnResponse(result), nil
}
@ -236,11 +299,31 @@ func (s *inventoryReturnService) Delete(ctx context.Context, id string) error {
tx.Rollback()
}
}()
ret, err := s.returnRepo.GetById(ctx, tx, id)
if err != nil {
tx.Rollback()
return err
}
ret.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.returnRepo.Update(ctx, tx, ret); err != nil {
tx.Rollback()
return err
}
if err := s.returnRepo.Delete(ctx, tx, id); err != nil {
tx.Rollback()
return err
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.DELETE,
"entity": "inventory_return",
"entity_id": id,
}).Info("Inventory Return deleted")
return nil
}
@ -264,11 +347,18 @@ func (s *inventoryReturnService) CreateLine(ctx context.Context, returnId string
InvReturnID: invReturnUUID,
ProductID: productUUID,
ClientID: clientUUID,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.returnLineRepo.Create(ctx, nil, line)
if err != nil {
return dtodomain.InventoryReturnLineResponse{}, err
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.CREATE,
"entity": "inventory_return_line",
"entity_id": created.ID.String(),
}).Info("Inventory Return Line created")
return dtodomain.ToInventoryReturnLineResponse(created), nil
}
@ -279,6 +369,7 @@ func NewInventoryReturnService(
issueLineRepo issueRepository.InventoryIssueLineRepository,
productRepo productrepository.ProductRepository,
sequenceService sequenceservice.SequenceService,
log *logrus.Logger,
) InventoryReturnService {
return &inventoryReturnService{
db: db,
@ -287,5 +378,6 @@ func NewInventoryReturnService(
issueLineRepo: issueLineRepo,
productRepo: productRepo,
sequenceService: sequenceService,
log: log,
}
}

View File

@ -7,7 +7,10 @@ import (
dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_storage/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_storage/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_storage/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"
)
@ -22,6 +25,7 @@ type InventoryStorageService interface {
type inventoryStorageService struct {
db *gorm.DB
inventoryStorageRepo repository.InventoryStorageRepository
log *logrus.Logger
}
func (s *inventoryStorageService) Create(ctx context.Context, req dtodomain.InventoryStorageCreateRequest) (dtodomain.InventoryStorageResponse, error) {
@ -70,7 +74,7 @@ func (s *inventoryStorageService) Create(ctx context.Context, req dtodomain.Inve
} else {
InvReceiptID = uuid.Nil
}
inventoryStorage := entities.InventoryStorageEntity{
ProductID: productID,
AisleID: aisleID,
@ -80,6 +84,7 @@ func (s *inventoryStorageService) Create(ctx context.Context, req dtodomain.Inve
InvReceiptID: InvReceiptID,
OnHandQuantity: req.OnHandQuantity,
AvailableQuantity: req.AvailableQuantity,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.inventoryStorageRepo.Create(ctx, tx, inventoryStorage)
if err != nil {
@ -87,6 +92,14 @@ func (s *inventoryStorageService) Create(ctx context.Context, req dtodomain.Inve
return dtodomain.InventoryStorageResponse{}, err
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.CREATE,
"entity": "inventory_storage",
"entity_id": created.ID.String(),
}).Info("Inventory Storage created")
result, err := s.inventoryStorageRepo.GetById(ctx, nil, created.ID.String())
if err != nil {
return dtodomain.InventoryStorageResponse{}, err
@ -129,8 +142,10 @@ func (s *inventoryStorageService) Update(ctx context.Context, req dtodomain.Inve
tx.Rollback()
return dtodomain.InventoryStorageResponse{}, err
}
before := inventoryStorage
inventoryStorage.OnHandQuantity = req.OnHandQuantity
inventoryStorage.AvailableQuantity = req.AvailableQuantity
inventoryStorage.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.inventoryStorageRepo.Update(ctx, tx, inventoryStorage)
if err != nil {
tx.Rollback()
@ -141,6 +156,16 @@ func (s *inventoryStorageService) Update(ctx context.Context, req dtodomain.Inve
if err != nil {
return dtodomain.InventoryStorageResponse{}, err
}
changes := utils.GetChangedFields(before, inventoryStorage)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.UPDATE,
"entity": "inventory_storage",
"entity_id": inventoryStorageId,
"changes": changes,
}).Info("Inventory Storage updated")
return dtodomain.ToInventoryStorageResponse(result), nil
}
@ -151,17 +176,38 @@ func (s *inventoryStorageService) Delete(ctx context.Context, inventoryStorageId
tx.Rollback()
}
}()
invStorage, err := s.inventoryStorageRepo.GetById(ctx, tx, inventoryStorageId)
if err != nil {
tx.Rollback()
return err
}
invStorage.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.inventoryStorageRepo.Update(ctx, tx, invStorage); err != nil {
tx.Rollback()
return err
}
if err := s.inventoryStorageRepo.Delete(ctx, tx, inventoryStorageId); err != nil {
tx.Rollback()
return err
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": constants.DELETE,
"entity": "inventory_storage",
"entity_id": inventoryStorageId,
}).Info("Inventory Storage deleted")
return nil
}
func NewInventoryStorageService(db *gorm.DB, inventoryStorageRepo repository.InventoryStorageRepository) InventoryStorageService {
func NewInventoryStorageService(db *gorm.DB, inventoryStorageRepo repository.InventoryStorageRepository, log *logrus.Logger) InventoryStorageService {
return &inventoryStorageService{
db: db,
inventoryStorageRepo: inventoryStorageRepo,
log: log,
}
}

View File

@ -7,8 +7,10 @@ import (
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"
)
@ -23,6 +25,7 @@ type InventoryTransactionService interface {
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) {
@ -77,6 +80,7 @@ func (s *inventoryTransactionService) Create(ctx context.Context, req dtodomain.
InvReceiptID: invReceiptUUID,
InvIssueID: invIssueUUID,
InvMoveID: invMoveUUID,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.inventoryTransactionRepo.Create(ctx, tx, entity)
if err != nil {
@ -84,6 +88,12 @@ func (s *inventoryTransactionService) Create(ctx context.Context, req dtodomain.
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
@ -126,6 +136,9 @@ func (s *inventoryTransactionService) Update(ctx context.Context, req dtodomain.
tx.Rollback()
return dtodomain.InventoryTransactionResponse{}, err
}
before := entity
if req.TransactionType != "" {
entity.TransactionType = req.TransactionType
}
@ -163,12 +176,23 @@ func (s *inventoryTransactionService) Update(ctx context.Context, req dtodomain.
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
@ -183,17 +207,37 @@ func (s *inventoryTransactionService) Delete(ctx context.Context, inventoryTrans
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) InventoryTransactionService {
func NewInventoryTransactionService(db *gorm.DB, repo repository.InventoryTransactionRepository, log *logrus.Logger) InventoryTransactionService {
return &inventoryTransactionService{
db: db,
inventoryTransactionRepo: repo,
log: log,
}
}

View File

@ -4,7 +4,7 @@ import (
"errors"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
"github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/google/uuid"
)
@ -63,16 +63,16 @@ type (
}
MenuResponse struct {
ID string `json:"id"`
Name string `json:"name"`
IconUrl string `json:"icon_url"`
Url string `json:"url"`
Sequence int `json:"sequence"`
Mode string `json:"mode"`
Status string `json:"status"`
Parent *MenuParentResponse `json:"parent"`
Permissions []dto.PermissionResponse `json:"permissions,omitempty"`
Clients []dto.ClientResponse `json:"clients,omitempty"`
ID string `json:"id"`
Name string `json:"name"`
IconUrl string `json:"icon_url"`
Url string `json:"url"`
Sequence int `json:"sequence"`
Mode string `json:"mode"`
Status string `json:"status"`
Parent *MenuParentResponse `json:"parent"`
Permissions []pkgdto.PermissionResponse `json:"permissions,omitempty"`
Clients []pkgdto.ClientResponse `json:"clients,omitempty"`
}
MenuParentResponse struct {
@ -82,7 +82,7 @@ type (
GetAllMenuRepositoryResponse struct {
Menus []entities.M_Menu `json:"menus"`
dto.PaginationResponse
pkgdto.PaginationResponse
}
MenuUpdateRequest struct {
@ -96,3 +96,33 @@ type (
ParentID *uuid.UUID `json:"parent_id" form:"parent_id" binding:"omitempty"`
}
)
func ToMenuResponse(entity entities.M_Menu) MenuResponse {
res := MenuResponse{
ID: entity.ID.String(),
Name: entity.Name,
IconUrl: entity.IconUrl,
Url: entity.Url,
Sequence: entity.Sequence,
Mode: entity.Mode,
Status: entity.Status,
}
if entity.Parent != nil {
res.Parent = &MenuParentResponse{
ID: entity.Parent.ID.String(),
Name: entity.Parent.Name,
}
} else if entity.ParentID != nil {
res.Parent = &MenuParentResponse{ID: entity.ParentID.String()}
}
if len(entity.Permissions) > 0 {
res.Permissions = make([]pkgdto.PermissionResponse, 0, len(entity.Permissions))
for _, perm := range entity.Permissions {
res.Permissions = append(res.Permissions, pkgdto.PermissionResponse{
ID: perm.ID.String(),
Name: perm.Name,
})
}
}
return res
}

View File

@ -8,8 +8,8 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/auth/service"
"github.com/Caknoooo/go-gin-clean-starter/modules/menu/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/menu/repository"
staticDto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
@ -26,6 +26,7 @@ type menuService struct {
menuRepository repository.MenuRepository
jwtService service.JWTService
db *gorm.DB
log *logrus.Logger
}
// GetAll implements MenuService.
@ -37,38 +38,8 @@ func (m *menuService) GetAll(ctx context.Context) ([]dto.MenuResponse, error) {
responses := make([]dto.MenuResponse, 0, len(entities))
for _, entity := range entities {
res := dto.MenuResponse{
ID: entity.ID.String(),
Name: entity.Name,
IconUrl: entity.IconUrl,
Url: entity.Url,
Sequence: entity.Sequence,
Mode: entity.Mode,
Status: entity.Status,
}
if entity.Parent != nil {
res.Parent = &dto.MenuParentResponse{
ID: entity.Parent.ID.String(),
Name: entity.Parent.Name,
}
} else if entity.ParentID != nil {
res.Parent = &dto.MenuParentResponse{ID: entity.ParentID.String()}
}
if len(entity.Permissions) > 0 {
res.Permissions = make([]staticDto.PermissionResponse, 0, len(entity.Permissions))
for _, perm := range entity.Permissions {
res.Permissions = append(res.Permissions, staticDto.PermissionResponse{
ID: perm.ID.String(),
Name: perm.Name,
})
}
}
responses = append(responses, res)
responses = append(responses, dto.ToMenuResponse(entity))
}
return responses, nil
}
@ -111,25 +82,7 @@ func (m *menuService) Create(ctx context.Context, menu dto.MenuResponse) (dto.Me
return dto.MenuResponse{}, err
}
// map back to DTO
res := dto.MenuResponse{
ID: created.ID.String(),
Name: created.Name,
IconUrl: created.IconUrl,
Url: created.Url,
Sequence: created.Sequence,
Mode: created.Mode,
Status: created.Status,
}
if created.Parent != nil {
res.Parent = &dto.MenuParentResponse{
ID: created.Parent.ID.String(),
Name: created.Parent.Name,
}
} else if created.ParentID != nil {
res.Parent = &dto.MenuParentResponse{ID: created.ParentID.String()}
}
res := dto.ToMenuResponse(created)
return res, nil
}
@ -147,37 +100,7 @@ func (m *menuService) GetById(ctx context.Context, menuId string) (dto.MenuRespo
return dto.MenuResponse{}, err
}
res := dto.MenuResponse{
ID: entity.ID.String(),
Name: entity.Name,
IconUrl: entity.IconUrl,
Url: entity.Url,
Sequence: entity.Sequence,
Mode: entity.Mode,
Status: entity.Status,
}
if entity.Parent != nil {
res.Parent = &dto.MenuParentResponse{
ID: entity.Parent.ID.String(),
Name: entity.Parent.Name,
}
} else if entity.ParentID != nil {
res.Parent = &dto.MenuParentResponse{ID: entity.ParentID.String()}
}
if len(entity.Permissions) > 0 {
res.Permissions = make([]staticDto.PermissionResponse, 0, len(entity.Permissions))
for _, perm := range entity.Permissions {
res.Permissions = append(res.Permissions, staticDto.PermissionResponse{
ID: perm.ID.String(),
Name: perm.Name,
// Description: perm.Description,
// Code: perm.Code,
})
}
}
return res, nil
return dto.ToMenuResponse(entity), nil
}
// GetByName implements MenuService.
@ -187,24 +110,7 @@ func (m *menuService) GetByName(ctx context.Context, name string) (dto.MenuRespo
return dto.MenuResponse{}, err
}
res := dto.MenuResponse{
ID: entity.ID.String(),
Name: entity.Name,
IconUrl: entity.IconUrl,
Url: entity.Url,
Sequence: entity.Sequence,
Mode: entity.Mode,
Status: entity.Status,
}
if entity.Parent != nil {
res.Parent = &dto.MenuParentResponse{
ID: entity.Parent.ID.String(),
Name: entity.Parent.Name,
}
} else if entity.ParentID != nil {
res.Parent = &dto.MenuParentResponse{ID: entity.ParentID.String()}
}
res := dto.ToMenuResponse(entity)
return res, nil
}
@ -250,24 +156,7 @@ func (m *menuService) Update(ctx context.Context, menuId string, menu dto.MenuUp
return dto.MenuResponse{}, err
}
res := dto.MenuResponse{
ID: updated.ID.String(),
Name: updated.Name,
IconUrl: updated.IconUrl,
Url: updated.Url,
Sequence: updated.Sequence,
Mode: updated.Mode,
Status: updated.Status,
}
if updated.Parent != nil {
res.Parent = &dto.MenuParentResponse{
ID: updated.Parent.ID.String(),
Name: updated.Parent.Name,
}
} else if updated.ParentID != nil {
res.Parent = &dto.MenuParentResponse{ID: updated.ParentID.String()}
}
res := dto.ToMenuResponse(updated)
return res, nil
}
@ -276,10 +165,12 @@ func NewMenuService(
menuRepo repository.MenuRepository,
jwtService service.JWTService,
db *gorm.DB,
log *logrus.Logger,
) MenuService {
return &menuService{
menuRepository: menuRepo,
jwtService: jwtService,
db: db,
log: log,
}
}

View File

@ -3,6 +3,7 @@ package dto
import (
"errors"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
)
@ -52,3 +53,18 @@ type VendorResponse struct {
IsActive bool `json:"is_active"`
Client pkgdto.IdNameResponse `json:"client"`
}
func EntityToVendorResponse(e entities.MVendorEntity) VendorResponse {
return VendorResponse{
ID: e.ID.String(),
SearchKey: e.SearchKey,
Name: e.Name,
Address: e.Address,
ContactPerson: e.ContactPerson,
IsActive: e.IsActive,
Client: pkgdto.IdNameResponse{
ID: e.ClientID.String(),
Name: e.Client.Name,
},
}
}

View File

@ -8,9 +8,11 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/mvendor/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/mvendor/repository"
sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service"
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
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"
)
@ -26,13 +28,15 @@ type vendorService struct {
db *gorm.DB
vendorRepo repository.VendorRepository
sequenceService sequenceservice.SequenceService
log *logrus.Logger
}
func NewVendorService(vendorRepo repository.VendorRepository, sequenceService sequenceservice.SequenceService, db *gorm.DB) VendorService {
func NewVendorService(vendorRepo repository.VendorRepository, sequenceService sequenceservice.SequenceService, db *gorm.DB, log *logrus.Logger) VendorService {
return &vendorService{
vendorRepo: vendorRepo,
sequenceService: sequenceService,
db: db,
log: log,
}
}
@ -44,6 +48,8 @@ func (s *vendorService) Create(ctx context.Context, req dto.VendorCreateRequest)
}
}()
userID := utils.GetUserID(ctx)
suffix := utils.GetInitials(req.Name)
seqConfig := pkgdto.SequenceConfig{
@ -59,11 +65,12 @@ func (s *vendorService) Create(ctx context.Context, req dto.VendorCreateRequest)
}
vendor := entities.MVendorEntity{
SearchKey: searchKey,
Name: req.Name,
Address: req.Address,
ContactPerson: req.ContactPerson,
IsActive: req.IsActive,
SearchKey: searchKey,
Name: req.Name,
Address: req.Address,
ContactPerson: req.ContactPerson,
IsActive: req.IsActive,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
clientUUID, err := uuid.Parse(req.ClientID)
if err != nil {
@ -76,8 +83,16 @@ func (s *vendorService) Create(ctx context.Context, req dto.VendorCreateRequest)
tx.Rollback()
return dto.VendorResponse{}, err
}
s.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "create",
"entity": "vendor",
"entity_id": created.ID.String(),
}).Info("Vendor created")
tx.Commit()
return entityToVendorResponse(created), nil
return dto.EntityToVendorResponse(created), nil
}
func (s *vendorService) GetById(ctx context.Context, vendorId string) (dto.VendorResponse, error) {
@ -85,7 +100,7 @@ func (s *vendorService) GetById(ctx context.Context, vendorId string) (dto.Vendo
if err != nil {
return dto.VendorResponse{}, err
}
return entityToVendorResponse(vendor), nil
return dto.EntityToVendorResponse(vendor), nil
}
func (s *vendorService) GetAll(ctx context.Context, filter query.VendorFilter) ([]dto.VendorResponse, int64, error) {
@ -95,7 +110,7 @@ func (s *vendorService) GetAll(ctx context.Context, filter query.VendorFilter) (
}
responses := make([]dto.VendorResponse, len(vendors))
for i, v := range vendors {
responses[i] = entityToVendorResponse(v)
responses[i] = dto.EntityToVendorResponse(v)
}
return responses, total, nil
}
@ -107,6 +122,9 @@ func (s *vendorService) Update(ctx context.Context, req dto.VendorUpdateRequest,
tx.Rollback()
}
}()
userID := utils.GetUserID(ctx)
vendor, err := s.vendorRepo.GetById(ctx, tx, vendorId)
if err != nil {
tx.Rollback()
@ -130,13 +148,23 @@ func (s *vendorService) Update(ctx context.Context, req dto.VendorUpdateRequest,
}
vendor.ClientID = clientUUID
}
vendor.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.vendorRepo.Update(ctx, tx, vendor)
if err != nil {
tx.Rollback()
return dto.VendorResponse{}, err
}
s.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "update",
"entity": "vendor",
"entity_id": vendorId,
}).Info("Vendor updated")
tx.Commit()
return entityToVendorResponse(updated), nil
return dto.EntityToVendorResponse(updated), nil
}
func (s *vendorService) Delete(ctx context.Context, vendorId string) error {
@ -146,26 +174,35 @@ func (s *vendorService) Delete(ctx context.Context, vendorId string) error {
tx.Rollback()
}
}()
userID := utils.GetUserID(ctx)
vendor, err := s.vendorRepo.GetById(ctx, tx, vendorId)
if err != nil {
tx.Rollback()
return err
}
vendor.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
_, err = s.vendorRepo.Update(ctx, tx, vendor)
if err != nil {
tx.Rollback()
return err
}
if err := s.vendorRepo.Delete(ctx, tx, vendorId); err != nil {
tx.Rollback()
return err
}
s.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "delete",
"entity": "vendor",
"entity_id": vendorId,
}).Info("Vendor deleted")
tx.Commit()
return nil
}
func entityToVendorResponse(e entities.MVendorEntity) dto.VendorResponse {
return dto.VendorResponse{
ID: e.ID.String(),
SearchKey: e.SearchKey,
Name: e.Name,
Address: e.Address,
ContactPerson: e.ContactPerson,
IsActive: e.IsActive,
Client: pkgdto.IdNameResponse{
ID: e.ClientID.String(),
Name: e.Client.Name,
},
}
}

View File

@ -11,8 +11,11 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/product/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/product/repository"
sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service"
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
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"
)
@ -35,8 +38,8 @@ type productService struct {
inventoryTransactionRepo invtransactionrepo.InventoryTransactionRepository
inventoryStorageRepo invstoragerepo.InventoryStorageRepository
categoryRepo categoryrepo.CategoryRepository
sequenceService sequenceservice.SequenceService // tambahkan ini
sequenceService sequenceservice.SequenceService
log *logrus.Logger
}
// GetCrossReferencesByProductAndClient implements ProductService.
@ -119,7 +122,7 @@ func (s *productService) RemoveCrossReference(ctx context.Context, productId str
}
func NewProductService(productRepo repository.ProductRepository, db *gorm.DB, inventoryTransactionRepo invtransactionrepo.InventoryTransactionRepository,
inventoryStorageRepo invstoragerepo.InventoryStorageRepository, categoryRepo categoryrepo.CategoryRepository, sequenceService sequenceservice.SequenceService) ProductService {
inventoryStorageRepo invstoragerepo.InventoryStorageRepository, categoryRepo categoryrepo.CategoryRepository, sequenceService sequenceservice.SequenceService, log *logrus.Logger) ProductService {
return &productService{
productRepo: productRepo,
db: db,
@ -127,6 +130,7 @@ func NewProductService(productRepo repository.ProductRepository, db *gorm.DB, in
inventoryStorageRepo: inventoryStorageRepo,
categoryRepo: categoryRepo,
sequenceService: sequenceService,
log: log,
}
}
@ -176,15 +180,17 @@ func (s *productService) Create(ctx context.Context, req dto.ProductCreateReques
return dto.ProductResponse{}, err
}
product := entities.MProductEntity{
Name: req.Name,
RefNumber: refNumber,
SKU: req.SKU,
Description: req.Description,
Status: req.Status,
IsReturnable: req.IsReturnable,
CategoryID: &categoryUUID,
UomID: &uomUUID,
ClientID: clientUUID,
Name: req.Name,
RefNumber: refNumber,
SKU: req.SKU,
Description: req.Description,
Status: req.Status,
IsReturnable: req.IsReturnable,
CategoryID: &categoryUUID,
UomID: &uomUUID,
ClientID: clientUUID,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
// DimLength: req.DimLength,
// DimWidth: req.DimWidth,
// DimHeight: req.DimHeight,
@ -221,6 +227,12 @@ func (s *productService) Create(ctx context.Context, req dto.ProductCreateReques
tx.Rollback()
return dto.ProductResponse{}, err
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "create",
"entity": "product",
"entity_id": created.ID.String(),
}).Info("Product created")
return s.GetById(ctx, created.ID.String())
}
@ -362,6 +374,8 @@ func (s *productService) Update(ctx context.Context, req dto.ProductUpdateReques
id := parseUUID(*req.UomToUomID)
product.UomToUomID = &id
}
product.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.productRepo.Update(ctx, tx, product)
if err != nil {
tx.Rollback()
@ -372,6 +386,12 @@ func (s *productService) Update(ctx context.Context, req dto.ProductUpdateReques
tx.Rollback()
return dto.ProductResponse{}, err
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "delete",
"entity": "product",
"entity_id": productId,
}).Info("Product Updated")
return s.GetById(ctx, updated.ID.String())
}
@ -382,7 +402,18 @@ func (s *productService) Delete(ctx context.Context, productId string) error {
tx.Rollback()
}
}()
err := s.productRepo.Delete(ctx, tx, productId)
product, err := s.productRepo.GetById(ctx, tx, productId)
if err != nil {
tx.Rollback()
return err
}
product.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.productRepo.Update(ctx, tx, product); err != nil {
tx.Rollback()
return err
}
err = s.productRepo.Delete(ctx, tx, productId)
if err != nil {
tx.Rollback()
return err
@ -392,6 +423,12 @@ func (s *productService) Delete(ctx context.Context, productId string) error {
tx.Rollback()
return err
}
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "delete",
"entity": "product",
"entity_id": productId,
}).Info("Product Deleted")
return nil
}

View File

@ -3,7 +3,9 @@ package dto
import (
"errors"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/google/uuid"
)
const (
@ -145,3 +147,57 @@ type AssignMenuRequest struct {
type RemoveMenuRequest struct {
MenuID []string `json:"menu_ids" binding:"required,dive,uuid4"`
}
func ToRoleResponse(role entities.M_Role) RoleResponse {
var permissions []RolePermissionsResponse
for _, p := range role.Permissions {
permissions = append(permissions, RolePermissionsResponse{
ID: p.ID.String(),
Name: p.Name,
})
}
var client pkgdto.IdNameResponse
if role.Client.ID != uuid.Nil {
client = pkgdto.IdNameResponse{
ID: role.Client.ID.String(),
Name: role.Client.Name,
}
}
var menus []RoleMenuResponse
for _, m := range role.Menus {
var parent *RoleMenuResponse
if m.Parent != nil {
parent = &RoleMenuResponse{
ID: m.Parent.ID.String(),
Name: m.Parent.Name,
IconUrl: m.Parent.IconUrl,
Url: m.Parent.Url,
Sequence: m.Parent.Sequence,
Parent: nil,
}
}
menus = append(menus, RoleMenuResponse{
ID: m.ID.String(),
Name: m.Name,
IconUrl: m.IconUrl,
Url: m.Url,
Sequence: m.Sequence,
Parent: parent,
})
}
return RoleResponse{
ID: role.ID.String(),
Name: role.Name,
Description: role.Description,
IconUrl: role.IconUrl,
Type: role.Type,
HomeUrl: role.HomeUrl,
Level: role.Level,
Client: client,
Permissions: permissions,
Menus: menus,
}
}

View File

@ -11,7 +11,8 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/role/repository"
userDto "github.com/Caknoooo/go-gin-clean-starter/modules/user/dto"
userService "github.com/Caknoooo/go-gin-clean-starter/modules/user/service"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"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"
@ -40,6 +41,7 @@ type roleService struct {
jwtService service.JWTService
userService userService.UserService
db *gorm.DB
log *logrus.Logger
}
// GetAll implements RoleService.
@ -51,13 +53,12 @@ func (r *roleService) GetAll(ctx context.Context) ([]dto.RoleResponse, error) {
var responses []dto.RoleResponse
for _, role := range roles {
responses = append(responses, ToRoleResponse(role))
responses = append(responses, dto.ToRoleResponse(role))
}
return responses, nil
}
// AssignMenusToRole implements RoleService.
// AssignMenusToRole implements RoleService.
func (r *roleService) AssignMenusToRole(ctx context.Context, roleId string, menuIds []string) error {
if len(menuIds) == 0 {
@ -257,47 +258,65 @@ func (r *roleService) AssignRolesToUser(ctx context.Context, userId string, role
// CreateRole implements RoleService.
func (r *roleService) CreateRole(ctx context.Context, req dto.RoleCreateRequest) (dto.RoleResponse, error) {
// _, exists, err := r.roleRepo.CheckRoleName(ctx, r.db, req.Name)
// if err != nil && err != gorm.ErrRecordNotFound {
// return dto.RoleResponse{}, err
// }
// if exists {
// return dto.RoleResponse{}, dto.ErrRoleAlreadyExists
// }
userID := ""
if ctx != nil {
userID = utils.GetUserID(ctx)
}
clientUUID, err := uuid.Parse(req.ClientID)
if err != nil {
return dto.RoleResponse{}, err
}
role := entities.M_Role{
Name: req.Name,
Description: req.Description,
IconUrl: req.IconUrl,
Level: req.Level,
Type: req.Type,
HomeUrl: req.HomeUrl,
ClientID: clientUUID,
Name: req.Name,
Description: req.Description,
IconUrl: req.IconUrl,
Level: req.Level,
Type: req.Type,
HomeUrl: req.HomeUrl,
ClientID: clientUUID,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
createdRole, err := r.roleRepo.CreateRole(ctx, r.db, role)
if err != nil {
return dto.RoleResponse{}, err
}
result, err := r.roleRepo.GetRoleByID(ctx, r.db, createdRole.ID.String())
if err != nil {
return dto.RoleResponse{}, err
}
return ToRoleResponse(result), nil
r.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "create",
"entity": "role",
"entity_id": createdRole.ID.String(),
}).Info("Role created")
return dto.ToRoleResponse(result), nil
}
// DeleteRole implements RoleService.
func (r *roleService) DeleteRole(ctx context.Context, id string) error {
if _, err := r.roleRepo.GetRoleByID(ctx, r.db, id); err != nil {
role, err := r.roleRepo.GetRoleByID(ctx, r.db, id)
if err != nil {
return dto.ErrRoleNotFound
}
return r.roleRepo.DeleteRole(ctx, r.db, id)
role.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := r.roleRepo.UpdateRole(ctx, r.db, role); err != nil {
return err
}
if err := r.roleRepo.DeleteRole(ctx, r.db, id); err != nil {
return err
}
userID := ""
if ctx != nil {
userID = utils.GetUserID(ctx)
}
r.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "delete",
"entity": "role",
"entity_id": id,
}).Info("Role deleted")
return nil
}
// GetRoleByID implements RoleService.
@ -307,7 +326,7 @@ func (r *roleService) GetRoleByID(ctx context.Context, id string) (dto.RoleRespo
return dto.RoleResponse{}, err
}
return ToRoleResponse(role), nil
return dto.ToRoleResponse(role), nil
}
// GetRoles implements RoleService.
@ -316,44 +335,6 @@ func (r *roleService) GetRoles(ctx context.Context, filter query.RoleFilter) ([]
}
// GetRolesByUserID implements RoleService.
// func (r *roleService) GetRolesByUserID(ctx context.Context, userId string) ([]dto.RoleResponse, error) {
// if _, err := r.userService.GetUserById(ctx, userId); err != nil {
// return nil, userDto.ErrUserNotFound
// }
// roles, err := r.roleRepo.GetRolesByUserID(ctx, r.db, userId)
// if err != nil {
// logrus.Error("Error fetching roles for user ", userId, ": ", err)
// return nil, err
// }
// logrus.Info("Fetched ", len(roles), " roles for user ", userId)
// var responses []dto.RoleResponse
// for _, role := range roles {
// var permissions []dto.RolePermissionsResponse
// for _, p := range role.Permissions {
// permissions = append(permissions, dto.RolePermissionsResponse{
// ID: p.ID.String(),
// Name: p.Name,
// })
// }
// responses = append(responses, dto.RoleResponse{
// ID: role.ID.String(),
// Name: role.Name,
// Description: role.Description,
// IconUrl: role.IconUrl,
// Type: role.Type,
// HomeUrl: role.HomeUrl,
// ClientID: role.ClientID.String(),
// Permissions: permissions,
// })
// }
// return responses, nil
// }
func (r *roleService) GetRolesByUserID(ctx context.Context, userId string) ([]dto.RoleResponse, error) {
if _, err := r.userService.GetUserById(ctx, userId); err != nil {
return nil, userDto.ErrUserNotFound
@ -366,7 +347,7 @@ func (r *roleService) GetRolesByUserID(ctx context.Context, userId string) ([]dt
var responses []dto.RoleResponse
for _, role := range roles {
responses = append(responses, ToRoleResponse(role))
responses = append(responses, dto.ToRoleResponse(role))
}
return responses, nil
@ -470,16 +451,8 @@ func (r *roleService) UpdateRole(ctx context.Context, id string, req dto.RoleUpd
if err != nil {
return dto.RoleResponse{}, dto.ErrRoleNotFound
}
before := existingRole
if req.Name != "" {
// _, exists, err := r.roleRepo.CheckRoleName(ctx, r.db, req.Name)
// if err != nil {
// return dto.RoleResponse{}, err
// }
// if exists {
// return dto.RoleResponse{}, dto.ErrRoleAlreadyExists
// }
existingRole.Name = req.Name
}
if req.Description != "" {
@ -497,72 +470,28 @@ func (r *roleService) UpdateRole(ctx context.Context, id string, req dto.RoleUpd
if req.Level != 0 {
existingRole.Level = req.Level
}
existingRole.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updatedRole, err := r.roleRepo.UpdateRole(ctx, r.db, existingRole)
if err != nil {
return dto.RoleResponse{}, err
}
result, err := r.roleRepo.GetRoleByID(ctx, r.db, updatedRole.ID.String())
if err != nil {
return dto.RoleResponse{}, err
}
return ToRoleResponse(result), nil
}
func ToRoleResponse(role entities.M_Role) dto.RoleResponse {
var permissions []dto.RolePermissionsResponse
for _, p := range role.Permissions {
permissions = append(permissions, dto.RolePermissionsResponse{
ID: p.ID.String(),
Name: p.Name,
})
}
var client pkgdto.IdNameResponse
if role.Client.ID != uuid.Nil {
client = pkgdto.IdNameResponse{
ID: role.Client.ID.String(),
Name: role.Client.Name,
}
}
var menus []dto.RoleMenuResponse
for _, m := range role.Menus {
var parent *dto.RoleMenuResponse
if m.Parent != nil {
parent = &dto.RoleMenuResponse{
ID: m.Parent.ID.String(),
Name: m.Parent.Name,
IconUrl: m.Parent.IconUrl,
Url: m.Parent.Url,
Sequence: m.Parent.Sequence,
Parent: nil, // atau rekursif jika ingin nested lebih dalam
}
}
menus = append(menus, dto.RoleMenuResponse{
ID: m.ID.String(),
Name: m.Name,
IconUrl: m.IconUrl,
Url: m.Url,
Sequence: m.Sequence,
Parent: parent,
})
}
return dto.RoleResponse{
ID: role.ID.String(),
Name: role.Name,
Description: role.Description,
IconUrl: role.IconUrl,
Type: role.Type,
HomeUrl: role.HomeUrl,
Level: role.Level,
Client: client,
Permissions: permissions,
Menus: menus,
changes := utils.GetChangedFields(before, result)
userID := ""
if ctx != nil {
userID = utils.GetUserID(ctx)
}
r.log.WithFields(logrus.Fields{
"user_id": userID,
"action": "update",
"entity": "role",
"entity_id": id,
"changes": changes,
}).Info("Role updated")
return dto.ToRoleResponse(result), nil
}
func NewRoleService(
@ -571,6 +500,7 @@ func NewRoleService(
jwtService service.JWTService,
userService userService.UserService,
db *gorm.DB,
log *logrus.Logger,
) RoleService {
return &roleService{
roleRepo: roleRepo,
@ -578,5 +508,6 @@ func NewRoleService(
jwtService: jwtService,
userService: userService,
db: db,
log: log,
}
}

View File

@ -3,7 +3,9 @@ package dto
import (
"errors"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/google/uuid"
)
const (
@ -63,3 +65,34 @@ type ZonaResponse struct {
Warehouse pkgdto.IdNameResponse `json:"warehouse"`
Client pkgdto.IdNameResponse `json:"client"`
}
func ToZonaResponse(e entities.MZonaEntity) ZonaResponse {
warehouse := pkgdto.IdNameResponse{}
if e.Warehouse.ID != uuid.Nil {
warehouse = pkgdto.IdNameResponse{
ID: e.Warehouse.ID.String(),
Name: e.Warehouse.Name,
}
}
client := pkgdto.IdNameResponse{}
if e.Client.ID != uuid.Nil {
client = pkgdto.IdNameResponse{
ID: e.Client.ID.String(),
Name: e.Client.Name,
}
}
return ZonaResponse{
ID: e.ID.String(),
Code: e.Code,
Name: e.Name,
Type: e.Type,
Temperature: e.Temperature,
Hazardous: e.Hazardous,
QRCodeZone: e.QRCodeZone,
IsActive: e.IsActive,
Warehouse: warehouse,
Client: client,
}
}

View File

@ -7,8 +7,10 @@ import (
"github.com/Caknoooo/go-gin-clean-starter/modules/zona/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/zona/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/zona/repository"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"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"
)
@ -23,38 +25,7 @@ type ZonaService interface {
type zonaService struct {
db *gorm.DB
zonaRepo repository.ZonaRepository
}
func toZonaResponse(e entities.MZonaEntity) dto.ZonaResponse {
warehouse := pkgdto.IdNameResponse{}
if e.Warehouse.ID != uuid.Nil {
warehouse = pkgdto.IdNameResponse{
ID: e.Warehouse.ID.String(),
Name: e.Warehouse.Name,
}
}
client := pkgdto.IdNameResponse{}
if e.Client.ID != uuid.Nil {
client = pkgdto.IdNameResponse{
ID: e.Client.ID.String(),
Name: e.Client.Name,
}
}
return dto.ZonaResponse{
ID: e.ID.String(),
Code: e.Code,
Name: e.Name,
Type: e.Type,
Temperature: e.Temperature,
Hazardous: e.Hazardous,
QRCodeZone: e.QRCodeZone,
IsActive: e.IsActive,
Warehouse: warehouse,
Client: client,
}
log *logrus.Logger
}
func (s *zonaService) Create(ctx context.Context, req dto.ZonaCreateRequest) (dto.ZonaResponse, error) {
@ -75,15 +46,14 @@ func (s *zonaService) Create(ctx context.Context, req dto.ZonaCreateRequest) (dt
return dto.ZonaResponse{}, err
}
zona := entities.MZonaEntity{
Code: req.Code,
Name: req.Name,
Type: req.Type,
Temperature: req.Temperature,
Hazardous: req.Hazardous,
// QRCodeZone: req.QRCodeZone,
// IsActive: req.IsActive,
WarehouseID: warehouseUUID,
ClientID: clientUUID,
Code: req.Code,
Name: req.Name,
Type: req.Type,
Temperature: req.Temperature,
Hazardous: req.Hazardous,
WarehouseID: warehouseUUID,
ClientID: clientUUID,
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
}
created, err := s.zonaRepo.Create(ctx, tx, zona)
if err != nil {
@ -95,7 +65,13 @@ func (s *zonaService) Create(ctx context.Context, req dto.ZonaCreateRequest) (dt
if err != nil {
return dto.ZonaResponse{}, err
}
return toZonaResponse(result), nil
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "create",
"entity": "zona",
"entity_id": created.ID.String(),
}).Info("Zona created")
return dto.ToZonaResponse(result), nil
}
func (s *zonaService) GetById(ctx context.Context, zonaId string) (dto.ZonaResponse, error) {
@ -103,7 +79,7 @@ func (s *zonaService) GetById(ctx context.Context, zonaId string) (dto.ZonaRespo
if err != nil {
return dto.ZonaResponse{}, err
}
return toZonaResponse(zona), nil
return dto.ToZonaResponse(zona), nil
}
func (s *zonaService) GetAll(ctx context.Context, filter query.ZonaFilter) ([]dto.ZonaResponse, int64, error) {
@ -113,7 +89,7 @@ func (s *zonaService) GetAll(ctx context.Context, filter query.ZonaFilter) ([]dt
}
var responses []dto.ZonaResponse
for _, e := range zonas {
responses = append(responses, toZonaResponse(e))
responses = append(responses, dto.ToZonaResponse(e))
}
if responses == nil {
responses = make([]dto.ZonaResponse, 0)
@ -133,6 +109,7 @@ func (s *zonaService) Update(ctx context.Context, req dto.ZonaUpdateRequest, zon
tx.Rollback()
return dto.ZonaResponse{}, err
}
before := zona
if req.Code != "" {
zona.Code = req.Code
}
@ -144,20 +121,8 @@ func (s *zonaService) Update(ctx context.Context, req dto.ZonaUpdateRequest, zon
}
zona.Temperature = req.Temperature
zona.Hazardous = req.Hazardous
// zona.QRCodeZone = req.QRCodeZone
zona.IsActive = req.IsActive
// if req.WarehouseID != "" {
// warehouseUUID, err := uuid.Parse(req.WarehouseID)
// if err == nil {
// zona.WarehouseID = warehouseUUID
// }
// }
// if req.ClientID != "" {
// clientUUID, err := uuid.Parse(req.ClientID)
// if err == nil {
// zona.ClientID = clientUUID
// }
// }
zona.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
updated, err := s.zonaRepo.Update(ctx, tx, zona)
if err != nil {
tx.Rollback()
@ -168,7 +133,15 @@ func (s *zonaService) Update(ctx context.Context, req dto.ZonaUpdateRequest, zon
if err != nil {
return dto.ZonaResponse{}, err
}
return toZonaResponse(result), nil
changes := utils.GetChangedFields(before, result)
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "update",
"entity": "zona",
"entity_id": zonaId,
"changes": changes,
}).Info("Zona updated")
return dto.ToZonaResponse(result), nil
}
func (s *zonaService) Delete(ctx context.Context, zonaId string) error {
@ -178,17 +151,34 @@ func (s *zonaService) Delete(ctx context.Context, zonaId string) error {
tx.Rollback()
}
}()
zona, err := s.zonaRepo.GetById(ctx, tx, zonaId)
if err != nil {
tx.Rollback()
return err
}
zona.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
if _, err := s.zonaRepo.Update(ctx, tx, zona); err != nil {
tx.Rollback()
return err
}
if err := s.zonaRepo.Delete(ctx, tx, zonaId); err != nil {
tx.Rollback()
return err
}
tx.Commit()
s.log.WithFields(logrus.Fields{
"user_id": utils.GetUserID(ctx),
"action": "delete",
"entity": "zona",
"entity_id": zonaId,
}).Info("Zona deleted")
return nil
}
func NewZonaService(zonaRepo repository.ZonaRepository, db *gorm.DB) ZonaService {
func NewZonaService(zonaRepo repository.ZonaRepository, db *gorm.DB, log *logrus.Logger) ZonaService {
return &zonaService{
zonaRepo: zonaRepo,
db: db,
log: log,
}
}

View File

@ -175,26 +175,26 @@ func RegisterDependencies(injector *do.Injector) {
// Service
sequenceServ := sequenceService.NewSequenceService(sequenceRepository, db)
userServ := userService.NewUserService(userRepository, roleRepository, warehouseRepository, clientRepository, refreshTokenRepository, jwtService, db)
productService := productService.NewProductService(productRepository, db, inventoryTransactionRepository, inventoryStorageRepository, categoryRepository, sequenceServ)
roleServ := roleService.NewRoleService(roleRepository, refreshTokenRepository, jwtService, userServ, db)
menuSvc := menuService.NewMenuService(menuRepository, jwtService, db)
productService := productService.NewProductService(productRepository, db, inventoryTransactionRepository, inventoryStorageRepository, categoryRepository, sequenceServ, log)
roleServ := roleService.NewRoleService(roleRepository, refreshTokenRepository, jwtService, userServ, db, log)
menuSvc := menuService.NewMenuService(menuRepository, jwtService, db, log)
maintenanceGroupServ := maintGroupService.NewMaintenanceGroupService(maintenanceGroupRepository, maintenanceGroupRoleRepository, maintenanceGroupRoleUserRepository, db)
clientServ := clientService.NewClientService(clientRepository, db)
clientServ := clientService.NewClientService(clientRepository, db, log)
permissionsServ := permissionsService.NewPermissionsService(permissionsRepository, db)
categoryServ := categoryService.NewCategoryService(categoryRepository, db)
categoryServ := categoryService.NewCategoryService(categoryRepository, db, log)
uomServ := uomService.NewUomService(uomRepository, sequenceServ, db, log)
mvendorServ := mvendorService.NewVendorService(mvendorRepository, sequenceServ, db)
mvendorServ := mvendorService.NewVendorService(mvendorRepository, sequenceServ, db, log)
warehouseServ := warehouseService.NewWarehouseService(warehouseRepository, db, log)
zonaServ := zonaService.NewZonaService(zonaRepository, db)
aisleServ := aisleService.NewAisleService(aisleRepository, db)
inventoryReceiptServ := inventoryReceiptService.NewInventoryReceiptService(db, inventoryReceiptRepository, inventoryReceiptLineRepository, productRepository, uomRepository, inventoryStorageRepository, sequenceServ)
zonaServ := zonaService.NewZonaService(zonaRepository, db, log)
aisleServ := aisleService.NewAisleService(aisleRepository, db, log)
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)
inventoryReturnServ := inventoryReturnService.NewInventoryReturnService(db, inventoryReturnRepository, inventoryReturnLineRepository, inventoryIssueLineRepository, productRepository, sequenceServ)
inventoryMovementServ := inventoryMovementService.NewInventoryMovementService(db, inventoryMovementRepository, inventoryMovementLineRepository, sequenceServ)
inventoryStorageService := inventoryStorageService.NewInventoryStorageService(db, inventoryStorageRepository)
inventoryTransactionServ := inventoryTransactionService.NewInventoryTransactionService(db, inventoryTransactionRepository)
inventoryRequestServ := inventoryRequestService.NewInventoryRequestService(db, inventoryRequestRepository, inventoryRequestLineRepository, sequenceServ, log)
inventoryIssueServ := inventoryIssueService.NewInventoryIssueService(db, inventoryIssueRepository, inventoryIssueLineRepository, sequenceServ, log)
inventoryReturnServ := inventoryReturnService.NewInventoryReturnService(db, inventoryReturnRepository, inventoryReturnLineRepository, inventoryIssueLineRepository, productRepository, sequenceServ, log)
inventoryMovementServ := inventoryMovementService.NewInventoryMovementService(db, inventoryMovementRepository, inventoryMovementLineRepository, sequenceServ, log)
inventoryStorageService := inventoryStorageService.NewInventoryStorageService(db, inventoryStorageRepository, log)
inventoryTransactionServ := inventoryTransactionService.NewInventoryTransactionService(db, inventoryTransactionRepository, log)
quarantineServ := quarantineService.NewQuarantineService(db, quarantineRepository, quarantineLineRepository, productRepository, uomRepository, inventoryStorageRepository)
// Controller