diff --git a/src/database/Database.go b/src/database/Database.go index 1ef3b733ef12a291d93001137bb2fcddf929ef72..ff271cbb6f8f3e66d21f4f0ce671a42588d1ff98 100644 --- a/src/database/Database.go +++ b/src/database/Database.go @@ -40,6 +40,7 @@ func initialize() { dbInstance.AutoMigrate(&models.SystemLogs{}) dbInstance.AutoMigrate(&models.BimbinganLogs{}) + dbInstance.AutoMigrate(&models.Topics{}) dbInstance.AutoMigrate(&models.BatchSeminar{}) dbInstance.AutoMigrate(&models.BatchSidang{}) dbInstance.AutoMigrate(&models.JadwalSidang{}) diff --git a/src/handler/handler.go b/src/handler/handler.go index a232a8c59a01405f636b89b7a2d7da3a719814eb..d7c8ee8d99483060de631af54349d9a3eca63715 100644 --- a/src/handler/handler.go +++ b/src/handler/handler.go @@ -16,16 +16,19 @@ import ( statusMahasiswaTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/status_mahasiswa/transport" systemLogConfig "gitlab.informatika.org/k-01-11/graduit-be/src/module/system_log/config" systemLogTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/system_log/transport" + topicAllocationConfig "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/config" + topicAllocationTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/transport" ) type Service struct { - InternalSystemLogHandler *systemLogTransport.InternalSystemLogHandler - AdminSytemLogHandler *systemLogTransport.AdminSystemLogHandler + InternalSystemLogHandler *systemLogTransport.InternalSystemLogHandler + AdminSytemLogHandler *systemLogTransport.AdminSystemLogHandler + AdminBimbinganLogHandler *bimbinganLogTransport.AdminBimbinganLogHandler + AdminTopicAllocationHandler *topicAllocationTransport.AdminTopicAllocationHandler BatchSeminarHandler *batchSeminarTransport.AdminBatchSeminarHandler BatchSidangHandler *batchSidangTransport.AdminBatchSidangHandler JadwalSidangHandler *jadwalSidangTransport.AdminJadwalSidangHandler JadwalSeminarHandler *jadwalSeminarTransport.AdminJadwalSeminarHandler - AdminBimbinganLogHandler *bimbinganLogTransport.AdminBimbinganLogHandler AdminStatusMahasiswaHandler *statusMahasiswaTransport.AdminStatusMahasiswaHandler } @@ -45,6 +48,10 @@ func MakeHandler() *Service { DBWrite: dbWrite, DBRead: dbRead, }) + AdminTopicAllocationHandler := topicAllocationTransport.NewAdminTopicAllocationHandler(topicAllocationConfig.TopicAllocationTransportConfig{ + DBWrite: dbWrite, + DBRead: dbRead, + }) AdminBatchSeminarHandler := batchSeminarTransport.NewAdminBatchSeminarHandler(batchSeminarConfig.BatchSeminarTransportConfig{ DBWrite: dbWrite, DBRead: dbRead, @@ -65,15 +72,17 @@ func MakeHandler() *Service { DBWrite: dbWrite, DBRead: dbRead, }) - + return &Service{ - InternalSystemLogHandler: InternalSystemLogHandler, - AdminSytemLogHandler: AdminSystemLogHandler, - AdminBimbinganLogHandler: AdminBimbinganLogHandler, + InternalSystemLogHandler: InternalSystemLogHandler, + AdminSytemLogHandler: AdminSystemLogHandler, + AdminBimbinganLogHandler: AdminBimbinganLogHandler, + AdminTopicAllocationHandler: AdminTopicAllocationHandler, BatchSeminarHandler: AdminBatchSeminarHandler, BatchSidangHandler: AdminBatchSidangHandler, JadwalSidangHandler: AdminJadwalSidangHandler, JadwalSeminarHandler: AdminJadwalSeminarHandler, AdminStatusMahasiswaHandler: AdminStatusMahasiswaHandler, + } } diff --git a/src/handler/server.go b/src/handler/server.go index 005522dc8c8e8a799bd6bb7d148ae79eee9bf275..3fb18a9e2dd02bb812ad7e9f975d38c0ff603db0 100644 --- a/src/handler/server.go +++ b/src/handler/server.go @@ -23,6 +23,7 @@ func (s *Service) InitializeRoutes() *echo.Echo { adminGroup.Use(middleware.BearerAuth("TIMTA")) s.AdminSytemLogHandler.MountAdmin(adminGroup) s.AdminBimbinganLogHandler.MountAdmin(adminGroup) + s.AdminTopicAllocationHandler.MountAdmin(adminGroup) s.BatchSeminarHandler.MountAdmin(adminGroup) s.BatchSidangHandler.MountAdmin(adminGroup) s.JadwalSeminarHandler.MountAdmin(adminGroup) diff --git a/src/models/Topics.go b/src/models/Topics.go new file mode 100644 index 0000000000000000000000000000000000000000..b82cb698d787ff921bd20d14ff59ae9f33de8f7c --- /dev/null +++ b/src/models/Topics.go @@ -0,0 +1,10 @@ +package models + +type Topics struct { + ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"` + ImgUrl string `gorm:"column:img_url" json:"imgUrl"` + IDLecturer string `gorm:"column:id_lecturer" json:"id_lecturer"` + LectName string `gorm:"column:lect_name" json:"lect_name"` + Title string `gorm:"column:title" json:"Title"` + Description string `gorm:"column:description" json:"description"` +} \ No newline at end of file diff --git a/src/module/topic_allocation/config/common.go b/src/module/topic_allocation/config/common.go new file mode 100644 index 0000000000000000000000000000000000000000..a471c3472521bafe00e451e2b6ecc807c41f2cca --- /dev/null +++ b/src/module/topic_allocation/config/common.go @@ -0,0 +1,8 @@ +package config + +import "gorm.io/gorm" + +type TopicAllocationTransportConfig struct { + DBWrite *gorm.DB + DBRead *gorm.DB +} diff --git a/src/module/topic_allocation/entity/topic_allocation.go b/src/module/topic_allocation/entity/topic_allocation.go new file mode 100644 index 0000000000000000000000000000000000000000..339cf4f53530a1b71cb8a81e6b4c9ef33ced9add --- /dev/null +++ b/src/module/topic_allocation/entity/topic_allocation.go @@ -0,0 +1,13 @@ +package entity + +type Topic struct { + ID string `json:"id"` + IDLecturer string `json:"id_lecturer"` + Title string `json:"Title"` + Description string `json:"description"` +} + +type ParamValues struct { + Limit int + Offset int +} \ No newline at end of file diff --git a/src/module/topic_allocation/internal/repository/topic_allocation.go b/src/module/topic_allocation/internal/repository/topic_allocation.go new file mode 100644 index 0000000000000000000000000000000000000000..af99a75de91b8b5dea5e4e08a6ee68588473efbf --- /dev/null +++ b/src/module/topic_allocation/internal/repository/topic_allocation.go @@ -0,0 +1,98 @@ +package repository + +import ( + "github.com/google/uuid" + "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/entity" + "gorm.io/gorm" +) + +type TopicAllocationRepo struct { + DBWrite *gorm.DB + DBRead *gorm.DB +} + +func NewTopicAllocationRepository(dbWrite *gorm.DB, dbRead *gorm.DB) *TopicAllocationRepo { + return &TopicAllocationRepo{ + DBWrite: dbWrite, + DBRead: dbRead, + } +} + +func (repo *TopicAllocationRepo) NewTopic(topic entity.Topic) (output entity.Topic, err error) { + topic.ID = uuid.New().String() + + result := repo.DBWrite.Create(&topic) + if result.Error != nil { + return entity.Topic{}, result.Error + } + + return topic, nil +} + +func (repo *TopicAllocationRepo) GetTopic(page int, limit int, search string, id string) (output []entity.Topic, err error) { + var topics []entity.Topic + + result := repo.DBRead.Find(&topics) + if search != "" { + result = result.Where("Title LIKE ?", "%" + search + "%").Find(&topics) + if result.Error != nil { + return nil, result.Error + } + } + + if id != "" { + result = result.Where("id_lecturer = ?", id).Find(&topics) + if result.Error != nil { + return nil, result.Error + } + } + + if page != 0 { + result = result.Offset((page - 1) * limit).Find(&topics) + if result.Error != nil { + return nil, result.Error + } + } + + if limit != 0 { + result = result.Limit(limit).Find(&topics) + if result.Error != nil { + return nil, result.Error + } + } + + return topics, nil +} + +func (repo *TopicAllocationRepo) GetTopicByID(ID string) (output entity.Topic, err error) { + var topic entity.Topic + + result := repo.DBRead.Where("ID = ?", ID).First(&topic) + if result.Error != nil { + return entity.Topic{}, result.Error + } + + return topic, nil +} + +func (repo *TopicAllocationRepo) UpdateTopic(topic entity.Topic) (output entity.Topic, err error) { + result := repo.DBWrite.Save(&topic) + + if result.Error != nil { + return entity.Topic{}, result.Error + } + + return topic, nil +} + +func (repo *TopicAllocationRepo) DeleteTopic(ID string) (err error) { + var topic entity.Topic + + result := repo.DBWrite.Where("ID = ?", ID).Delete(&topic) + + if result.Error != nil { + return result.Error + } + + return nil +} diff --git a/src/module/topic_allocation/internal/usecase/repository.go b/src/module/topic_allocation/internal/usecase/repository.go new file mode 100644 index 0000000000000000000000000000000000000000..98ba932a1d467f344420be9dc05742990b942719 --- /dev/null +++ b/src/module/topic_allocation/internal/usecase/repository.go @@ -0,0 +1,11 @@ +package usecase + +import "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/entity" + +type TopicAllocationRepo interface { + NewTopic(topic entity.Topic) (output entity.Topic, err error) + GetTopic(page int, limit int, search string, id string) (output []entity.Topic, err error) + GetTopicByID(ID string) (output entity.Topic, err error) + UpdateTopic(topic entity.Topic) (output entity.Topic, err error) + DeleteTopic(ID string) (err error) +} \ No newline at end of file diff --git a/src/module/topic_allocation/internal/usecase/topic_allocation.go b/src/module/topic_allocation/internal/usecase/topic_allocation.go new file mode 100644 index 0000000000000000000000000000000000000000..8aef0b2bf3d77359c646fd0a578df84ac2fda7f4 --- /dev/null +++ b/src/module/topic_allocation/internal/usecase/topic_allocation.go @@ -0,0 +1,62 @@ +package usecase + +import ( + "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/entity" + "gitlab.informatika.org/k-01-11/graduit-be/src/utils" +) + +type TopicUsecase interface { + AddTopic(topic entity.Topic) (entity.Topic, error) + GetTopic(param utils.PageLimitSearchID) ([]entity.Topic, error) + GetTopicByID(param string) (entity.Topic, error) + UpdateTopic(topic entity.Topic) (entity.Topic, error) + DeleteTopic(param string) (error) +} + +type TopicUc struct { + topicAllocationRepo TopicAllocationRepo +} + +func NewTopicUc(topicAllocationRepo TopicAllocationRepo) *TopicUc { + return &TopicUc{ + topicAllocationRepo: topicAllocationRepo, + } +} + +func (uc *TopicUc) AddTopic(topic entity.Topic) (entity.Topic, error) { + newTopic, err := uc.topicAllocationRepo.NewTopic(topic) + + if err != nil { + return entity.Topic{}, err + } + + return newTopic, nil +} + +func (uc *TopicUc) GetTopic(param utils.PageLimitSearchID) ([]entity.Topic, error) { + return uc.topicAllocationRepo.GetTopic(param.Page, param.Limit, param.Search, param.ID) +} + +func (uc *TopicUc) GetTopicByID(param string) (entity.Topic, error) { + return uc.topicAllocationRepo.GetTopicByID(param) +} + +func (uc *TopicUc) UpdateTopic(topic entity.Topic) (entity.Topic, error) { + updatedTopic, err := uc.topicAllocationRepo.UpdateTopic(topic) + + if err != nil { + return entity.Topic{}, err + } + + return updatedTopic, nil +} + +func (uc *TopicUc) DeleteTopic(param string) (error) { + err := uc.topicAllocationRepo.DeleteTopic(param) + + if err != nil { + return err + } + + return nil +} \ No newline at end of file diff --git a/src/module/topic_allocation/transport/admin_handler.go b/src/module/topic_allocation/transport/admin_handler.go new file mode 100644 index 0000000000000000000000000000000000000000..d46d6993691c40329c90d5b41b4d768686fde199 --- /dev/null +++ b/src/module/topic_allocation/transport/admin_handler.go @@ -0,0 +1,115 @@ +package transport + +import ( + "net/http" + + "github.com/labstack/echo" + "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/entity" + "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/config" + "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/internal/repository" + "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/internal/usecase" + "gitlab.informatika.org/k-01-11/graduit-be/src/utils" +) + +type AdminTopicAllocationHandler struct { + topicUsecase usecase.TopicUsecase +} + +func NewAdminTopicAllocationHandler(cfg config.TopicAllocationTransportConfig) *AdminTopicAllocationHandler { + topicAllocationRepository := repository.NewTopicAllocationRepository(cfg.DBWrite, cfg.DBRead) + topicUseCase := usecase.NewTopicUc(topicAllocationRepository) + + return &AdminTopicAllocationHandler{ + topicUsecase: topicUseCase, + } +} + +func (admin *AdminTopicAllocationHandler) MountAdmin(group *echo.Group) { + group.GET("/alokasi-topik/:id", admin.GetTopicByID) + group.GET("/alokasi-topik", admin.GetTopics) + group.POST("/alokasi-topik", admin.AddTopic) + group.PUT("/alokasi-topik/:id", admin.UpdateTopic) + group.DELETE("/alokasi-topik/:id", admin.DeleteTopic) +} + +func (admin *AdminTopicAllocationHandler) GetTopics(c echo.Context) error { + param, err := utils.GetPageLimitSearchID(c.QueryParams()) + + if err != nil { + return c.JSON(http.StatusInternalServerError, utils.ResponseDetailOutput(false, http.StatusInternalServerError, err.Error(), nil)) + } + + list, err := admin.topicUsecase.GetTopic(param) + if err != nil { + return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, err.Error(), nil)) + } + + return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topics retreived", list)) +} + +func (admin *AdminTopicAllocationHandler) GetTopicByID(c echo.Context) error { + id := c.Param("id") + + if id != "" { + item, err := admin.topicUsecase.GetTopicByID(id) + + if err != nil { + return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, err.Error(), nil)) + } + + return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topics retreived", item)) + } else { + return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, "Incorrect URL", nil)) + } +} + +func (admin *AdminTopicAllocationHandler) AddTopic(c echo.Context) error { + topic := new(entity.Topic) + + if err := c.Bind(topic); err != nil { + return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, err.Error(), nil)) + } + + newTopic, err := admin.topicUsecase.AddTopic(*topic) + if err != nil { + return c.JSON(http.StatusInternalServerError, utils.ResponseDetailOutput(false, http.StatusInternalServerError, err.Error(), nil)) + } + + return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topic added successfully", newTopic)) +} + +func (admin *AdminTopicAllocationHandler) UpdateTopic(c echo.Context) error { + id := c.Param("id") + + if id != "" { + topic := new(entity.Topic) + c.Bind(topic) + topic.ID = id + + newItem, err := admin.topicUsecase.UpdateTopic(*topic) + + if err != nil { + return c.JSON(http.StatusInternalServerError, utils.ResponseDetailOutput(false, http.StatusInternalServerError, "Failed to update topic", nil)) + } + + return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topic updated", newItem)) + } else { + return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, "Please provide topic id", nil)) + } +} + +func (admin *AdminTopicAllocationHandler) DeleteTopic(c echo.Context) error { + id := c.Param("id") + + if id != "" { + err := admin.topicUsecase.DeleteTopic(id) + + if err != nil { + return c.JSON(http.StatusInternalServerError, utils.ResponseDetailOutput(false, http.StatusInternalServerError, "Failed to delete topic", nil)) + } + + return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topic deleted successfully", nil)) + } else { + return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, "Please provide topic id", nil)) + } +} \ No newline at end of file diff --git a/src/utils/helper.go b/src/utils/helper.go index 74fa2d891fe487d898764f1b2238e7b9ffeecf85..0212d684e82f165fa2f980230697d6736a8fb5f1 100644 --- a/src/utils/helper.go +++ b/src/utils/helper.go @@ -17,6 +17,13 @@ type ResponseDetail struct { Data interface{} `json:"data,omitempty"` } +type PageLimitSearchID struct { + Page int + Limit int + Search string + ID string +} + func ResponseDetailOutput(success bool, code int, message string, data interface{}) ResponseDetail { res := ResponseDetail{ Success: success, @@ -53,3 +60,50 @@ func GetLimitOffset(urlValues url.Values) (output LimitOffset, err error) { return *param, nil } + +func GetID(urlValues url.Values) (output string, err error) { + id := urlValues.Get("id") + if id != "" { + return id, nil + } else { + return "", nil + } +} + +func GetPageLimitSearchID(urlValues url.Values) (output PageLimitSearchID, err error) { + param := new(PageLimitSearchID) + page := urlValues.Get("page") + limit := urlValues.Get("limit") + search := urlValues.Get("search") + id := urlValues.Get("idPembimbing") + + if page != "" { + pageInt, err := strconv.Atoi(page) + + if err != nil { + return PageLimitSearchID{}, err + } + + param.Page = pageInt + } + + if limit != "" { + limitInt, err := strconv.Atoi(limit) + + if err != nil { + return PageLimitSearchID{}, err + } + + param.Limit = limitInt + } + + if search != "" { + param.Search = search + } + + if id != "" { + param.ID = id + } + + return *param, nil +} \ No newline at end of file