diff --git a/internal/server/routes.go b/internal/server/routes.go index e413188..0ff08bd 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -8,11 +8,25 @@ import ( "log" "net/http" LoginHandler "template_blueprint/pkg/handlers/login" + MenuHandler "template_blueprint/pkg/handlers/menu" "time" ) func (s *Server) RegisterRoutes() http.Handler { r := gin.Default() + //r.Use(cors.New(cors.Config{ + // AllowOrigins: []string{"*"}, // Sesuaikan dengan FE Nuxt + // AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, + // AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization"}, + // AllowCredentials: true, + // MaxAge: 12 * time.Hour, + //})) + r.Use(cors.New(cors.Config{ + AllowOrigins: []string{"*"}, // or specific domains like "http://example.com" + AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, + AllowHeaders: []string{"Origin", "Content-Type"}, + AllowCredentials: true, + })) r.GET("/", s.HelloWorldHandler) @@ -24,13 +38,27 @@ func (s *Server) RegisterRoutes() http.Handler { login.GET("/get", LoginHandler.Getlogin) login.GET("/:id", LoginHandler.GetloginbyID) } + keuangan := api.Group("/menu") + { + keuangan.GET("/getlist", MenuHandler.Getmenukeuangan) + keuangan.GET("/role", MenuHandler.Getrole) + keuangan.GET("/role/type/:id", MenuHandler.GetroleByType) + keuangan.GET("/id/:id", MenuHandler.GetmenuByID) + keuangan.GET("/typeuser/id/:id", MenuHandler.GettypeByID) + keuangan.GET("/type/:id", MenuHandler.GetroleByTypeWithUserInfo) + keuangan.GET("/type", MenuHandler.Gettype) + //keuangan.DELETE("/delete/:id", MenuHandler.GetBytypeIDdelete) + //keuangan.POST("/role/insert", MenuHandler.InsertRoles) + keuangan.POST("/update/rolemenu", MenuHandler.GabunganApi) + } - r.Use(cors.New(cors.Config{ - AllowOrigins: []string{"*"}, // or specific domains like "http://example.com" - AllowMethods: []string{"GET", "POST", "PUT", "DELETE"}, - AllowHeaders: []string{"Origin", "Content-Type"}, - AllowCredentials: true, - })) + // Contoh route + r.GET("/api/test", func(c *gin.Context) { + c.JSON(200, gin.H{"message": "CORS berhasil"}) + }) + + // Start server + r.Run(":8080") return r } diff --git a/pkg/database/mongo/menu.go b/pkg/database/mongo/menu.go new file mode 100644 index 0000000..637f1f9 --- /dev/null +++ b/pkg/database/mongo/menu.go @@ -0,0 +1,299 @@ +package mongo + +import ( + "context" + "fmt" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "log" + MenuHandler "template_blueprint/pkg/models/menu" + "time" +) + +func (s *DatabaseService) GetMenu() ([]*MenuHandler.Menu, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + datalogin, err := s.DBMongo.Collection("menu").Find(ctx, bson.D{}) + if err != nil { + log.Println(err) + } + var menu []*MenuHandler.Menu + err = datalogin.All(ctx, &menu) + if err != nil { + log.Println(err) + return nil, err + } + return menu, nil +} + +func (s *DatabaseService) Getrole() ([]*MenuHandler.Rolemenu, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + datarole, err := s.DBMongo.Collection("role_menu").Find(ctx, bson.D{}) + if err != nil { + log.Println(err) + } + var role []*MenuHandler.Rolemenu + err = datarole.All(ctx, &role) + if err != nil { + log.Println(err) + return nil, err + } + return role, nil +} + +func (s *DatabaseService) Gettype() ([]*MenuHandler.TypeUser, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + datatype, err := s.DBMongo.Collection("type_user").Find(ctx, bson.D{}) + if err != nil { + log.Println(err) + } + var typeuser []*MenuHandler.TypeUser + err = datatype.All(ctx, &typeuser) + if err != nil { + log.Println(err) + return nil, err + } + return typeuser, nil +} + +func (s *DatabaseService) GetBytypeID(id string) ([]*MenuHandler.Rolemenu, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + filter := bson.M{ + "type_user_id": id, + } + + cursor, err := s.DBMongo.Collection("role_menu").Find(ctx, filter) + if err != nil { + log.Println(err) + return nil, err + } + defer cursor.Close(ctx) + var results []*MenuHandler.Rolemenu + if err = cursor.All(ctx, &results); err != nil { + log.Println(err) + return nil, err + } + return results, nil +} + +func (s *DatabaseService) GetmenuByID(id string) ([]*MenuHandler.Menu, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + objectID, err := primitive.ObjectIDFromHex(id) + filter := bson.M{ + "_id": objectID, + } + + cursor, err := s.DBMongo.Collection("menu").Find(ctx, filter) + if err != nil { + log.Println(err) + return nil, err + } + defer cursor.Close(ctx) + var results []*MenuHandler.Menu + if err = cursor.All(ctx, &results); err != nil { + log.Println(err) + return nil, err + } + return results, nil +} + +func (s *DatabaseService) GettypeByID(id string) ([]*MenuHandler.TypeUser, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + objectID, err := primitive.ObjectIDFromHex(id) + filter := bson.M{ + "_id": objectID, + } + + cursor, err := s.DBMongo.Collection("type_user").Find(ctx, filter) + if err != nil { + log.Println(err) + return nil, err + } + defer cursor.Close(ctx) + var results []*MenuHandler.TypeUser + if err = cursor.All(ctx, &results); err != nil { + log.Println(err) + return nil, err + } + return results, nil +} + +func (s *DatabaseService) GetGroupedBytypeIDFlatWithMenu(id string) (*MenuHandler.GroupedRoleMenuFlatWithMenu, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + objectID, err := primitive.ObjectIDFromHex(id) + if err != nil { + return nil, fmt.Errorf("invalid ObjectID format: %v", err) + } + + pipeline := []bson.M{ + { + "$match": bson.M{ + "type_user_id": id, + }, + }, + { + "$group": bson.M{ + "_id": "$type_user_id", + "menu_id": bson.M{ + "$push": "$menu_id", + }, + }, + }, + { + "$lookup": bson.M{ + "from": "type_user", + "let": bson.M{"user_id": objectID}, + "pipeline": []bson.M{ + { + "$match": bson.M{ + "$expr": bson.M{ + "$eq": []interface{}{"$_id", "$$user_id"}, + }, + }, + }, + { + "$project": bson.M{ + "_id": 0, + "display": 1, + }, + }, + }, + "as": "user_info", + }, + }, + { + "$unwind": "$menu_id", + }, + { + "$lookup": bson.M{ + "from": "menu", + "let": bson.M{"menu_id_str": "$menu_id"}, + "pipeline": []bson.M{ + { + "$addFields": bson.M{ + "menu_id_as_string": bson.M{"$toString": "$_id"}, + }, + }, + { + "$match": bson.M{ + "$expr": bson.M{ + "$eq": []interface{}{"$menu_id_as_string", "$$menu_id_str"}, + }, + }, + }, + { + "$project": bson.M{ + "_id": 0, + "display": 1, + "icon": 1, + "link": 1, + }, + }, + }, + "as": "menu_details", + }, + }, + { + "$unwind": bson.M{ + "path": "$menu_details", + "preserveNullAndEmptyArrays": true, + }, + }, + { + "$group": bson.M{ + "_id": "$_id", + "user_info": bson.M{"$first": "$user_info"}, + "menus": bson.M{ + "$push": bson.M{ + "menu_id": "$menu_id", + "menu_display": "$menu_details.display", + "menu_icon": "$menu_details.icon", + "menu_link": "$menu_details.link", + }, + }, + }, + }, + { + "$project": bson.M{ + "_id": 0, + "type_user_id": "$_id", + "display": bson.M{ + "$ifNull": []interface{}{ + bson.M{"$arrayElemAt": []interface{}{"$user_info.display", 0}}, + "", + }, + }, + "menus": 1, + }, + }, + } + + cursor, err := s.DBMongo.Collection("role_menu").Aggregate(ctx, pipeline) + if err != nil { + log.Println(err) + return nil, err + } + defer cursor.Close(ctx) + + var results []MenuHandler.GroupedRoleMenuFlatWithMenu + if err = cursor.All(ctx, &results); err != nil { + log.Println(err) + return nil, err + } + + if len(results) == 0 { + return &MenuHandler.GroupedRoleMenuFlatWithMenu{ + TypeUserID: id, + Display: "", + Menus: []MenuHandler.FlatMenu{}, + }, nil + } + + return &results[0], nil +} + +func (s *DatabaseService) GetBytypeIDdelete(id string) error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + filter := bson.M{ + "type_user_id": id, + } + + _, err := s.DBMongo.Collection("role_menu").DeleteMany(ctx, filter) + if err != nil { + log.Println(err) + return err + } + + return nil +} + +func (s *DatabaseService) InsertRole(req []MenuHandler.Rolemenu) error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + var interfaceArray []interface{} + + for _, role := range req { + if role.ID.IsZero() { + role.ID = primitive.NewObjectID() + } + interfaceArray = append(interfaceArray, role) + } + _, err := s.DBMongo.Collection("role_menu").InsertMany(ctx, interfaceArray) + if err != nil { + log.Println(err) + return err + } + + return nil +} diff --git a/pkg/handlers/menu/menu.go b/pkg/handlers/menu/menu.go new file mode 100644 index 0000000..72cc705 --- /dev/null +++ b/pkg/handlers/menu/menu.go @@ -0,0 +1,260 @@ +package menu + +import ( + "github.com/gin-gonic/gin" + "net/http" + "os" + "template_blueprint/internal/database" + "template_blueprint/pkg/database/mongo" + MenuHandler "template_blueprint/pkg/models/menu" +) + +func Getmenukeuangan(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_KEUANGAN") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + menu, errSelect := mongoDB.GetMenu() + if errSelect != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": errSelect.Error()}) + return + } + c.JSON(http.StatusOK, menu) +} + +func Getrole(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_KEUANGAN") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + role, errSelect := mongoDB.Getrole() + if errSelect != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": errSelect.Error()}) + return + } + c.JSON(http.StatusOK, role) +} + +func Gettype(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_KEUANGAN") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + typeuser, errSelect := mongoDB.Gettype() + if errSelect != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": errSelect.Error()}) + return + } + c.JSON(http.StatusOK, typeuser) +} + +func GetroleByType(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_KEUANGAN") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + id := c.Param("id") + + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"message": "Parameter 'id' dibutuhkan"}) + return + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + dataID, err := mongoDB.GetBytypeID(id) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "data": dataID, + "message": "ID berhasil di cari", + }) +} + +func GetmenuByID(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_KEUANGAN") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + id := c.Param("id") + + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"message": "Parameter 'id' dibutuhkan"}) + return + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + dataID, err := mongoDB.GetmenuByID(id) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "data": dataID, + "message": "ID berhasil di cari", + }) +} + +func GettypeByID(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_KEUANGAN") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + id := c.Param("id") + + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"message": "Parameter 'id' dibutuhkan"}) + return + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + dataID, err := mongoDB.GettypeByID(id) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "data": dataID, + "message": "ID berhasil di cari", + }) +} + +func GetroleByTypeWithUserInfo(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_KEUANGAN") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + id := c.Param("id") + + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"message": "Parameter 'id' dibutuhkan"}) + return + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + dataID, err := mongoDB.GetGroupedBytypeIDFlatWithMenu(id) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "data": dataID, + "message": "ID berhasil di cari", + }) +} + +//func GetBytypeIDdelete(c *gin.Context) { +// local := os.Getenv("MONGODB_DEV_KEUANGAN") +// db := database.New(local).GetMongoDB() +// if db == nil { +// c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) +// return +// } +// +// id := c.Param("id") +// +// if id == "" { +// c.JSON(http.StatusBadRequest, gin.H{"message": "Parameter 'id' dibutuhkan"}) +// return +// } +// +// mongoDB := mongo.NewDatabaseServiceMongo(db) +// err := mongoDB.GetBytypeIDdelete(id) +// if err != nil { +// c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) +// return +// } +// +// c.JSON(http.StatusOK, gin.H{ +// "message": "ID berhasil di delete", +// }) +//} +// +//func InsertRoles(c *gin.Context) { +// local := os.Getenv("MONGODB_DEV_KEUANGAN") +// db := database.New(local).GetMongoDB() +// if db == nil { +// c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) +// return +// } +// mongoDB := mongo.NewDatabaseServiceMongo(db) +// var req []MenuHandler.Rolemenu +// if err := c.ShouldBindJSON(&req); err != nil { +// c.JSON(http.StatusBadRequest, gin.H{"message": "Invalid request format"}) +// return +// } +// errInsert := mongoDB.InsertRole(req) +// if errInsert != nil { +// c.JSON(http.StatusInternalServerError, gin.H{"message": errInsert.Error()}) +// return +// } +// c.JSON(http.StatusOK, gin.H{"message": "Role berhasil di Buat"}) +//} + +func GabunganApi(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_KEUANGAN") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + + var req []MenuHandler.Rolemenu + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"message": "Invalid request format"}) + return + } + + id := c.DefaultQuery("id", "") + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"message": "Parameter 'id' dibutuhkan"}) + return + } + + err := mongoDB.GetBytypeIDdelete(id) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) + return + } + + errInsert := mongoDB.InsertRole(req) + if errInsert != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": errInsert.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "Update berhasil", + }) +} diff --git a/pkg/models/menu/menu.go b/pkg/models/menu/menu.go new file mode 100644 index 0000000..cd295e0 --- /dev/null +++ b/pkg/models/menu/menu.go @@ -0,0 +1,48 @@ +package menu + +import ( + "go.mongodb.org/mongo-driver/bson/primitive" +) + +type Menu struct { + ID primitive.ObjectID `bson:"_id" json:"_id"` + Display string `bson:"display" json:"display"` + Child string `bson:"child" json:"child"` + Ordered int `bson:"ordered" json:"ordered"` + Parent string `bson:"parent" json:"parent"` + Icon string `bson:"icon" json:"icon"` + Link string `bson:"link" json:"link"` +} + +type TypeUser struct { + ID primitive.ObjectID `bson:"_id" json:"_id"` + Display string `bson:"display" json:"display"` + Status bool `bson:"status" json:"status"` +} + +type Rolemenu struct { + ID primitive.ObjectID `bson:"_id" json:"_id"` + TypeUser string `bson:"type_user_id" json:"type_user_id"` + MenuID string `json:"menu_id" bson:"menu_id"` + Access []Access `bson:"access" json:"access"` +} + +type Access struct { + Add int `bson:"add" json:"add"` + Update int `bson:"update" json:"update"` + Read int `bson:"read" json:"read"` + Delete int `bson:"delete" json:"delete"` +} + +type GroupedRoleMenuFlatWithMenu struct { + TypeUserID string `json:"type_user_id" bson:"type_user_id"` + Display string `json:"display" bson:"display"` + Menus []FlatMenu `json:"menus" bson:"menus"` +} + +type FlatMenu struct { + MenuID string `json:"menu_id" bson:"menu_id"` + MenuDisplay string `json:"display" bson:"menu_display"` + MenuIcon string `json:"icon" bson:"menu_icon"` + MenuLink string `json:"link" bson:"menu_link"` +}