mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-24 15:25:43 +00:00
first commit add master data kandang group
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE daily_checklists
|
||||||
|
DROP CONSTRAINT IF EXISTS fk_daily_checklists_kandang;
|
||||||
|
|
||||||
|
UPDATE daily_checklists dc
|
||||||
|
SET kandang_id = k.id
|
||||||
|
FROM kandangs k
|
||||||
|
WHERE
|
||||||
|
dc.kandang_id = k.kandang_group_id;
|
||||||
|
|
||||||
|
ALTER TABLE daily_checklists
|
||||||
|
ADD CONSTRAINT fk_daily_checklists_kandang
|
||||||
|
FOREIGN KEY (kandang_id) REFERENCES kandangs (id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS idx_kandangs_kandang_group_id;
|
||||||
|
|
||||||
|
ALTER TABLE kandangs
|
||||||
|
DROP CONSTRAINT IF EXISTS fk_kandangs_kandang_group;
|
||||||
|
|
||||||
|
ALTER TABLE kandangs
|
||||||
|
DROP COLUMN IF EXISTS kandang_group_id;
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS kandang_groups_name_unique;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS kandang_groups;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE kandang_groups (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR(50) NOT NULL,
|
||||||
|
status VARCHAR(20) NOT NULL,
|
||||||
|
location_id BIGINT NOT NULL REFERENCES locations (id) ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||||
|
pic_id BIGINT REFERENCES users (id) ON DELETE SET NULL ON UPDATE CASCADE,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW (),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW (),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT REFERENCES users (id) ON DELETE SET NULL ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX kandang_groups_name_unique ON kandang_groups (name)
|
||||||
|
WHERE
|
||||||
|
deleted_at IS NULL;
|
||||||
|
|
||||||
|
ALTER TABLE kandangs
|
||||||
|
ADD COLUMN kandang_group_id BIGINT;
|
||||||
|
|
||||||
|
CREATE TEMP TABLE tmp_kandang_group_map (
|
||||||
|
kandang_id BIGINT PRIMARY KEY,
|
||||||
|
kandang_group_id BIGINT NOT NULL
|
||||||
|
) ON COMMIT DROP;
|
||||||
|
|
||||||
|
INSERT INTO tmp_kandang_group_map (kandang_id, kandang_group_id)
|
||||||
|
SELECT
|
||||||
|
k.id,
|
||||||
|
nextval(pg_get_serial_sequence('kandang_groups', 'id'))
|
||||||
|
FROM kandangs k
|
||||||
|
ORDER BY
|
||||||
|
k.id;
|
||||||
|
|
||||||
|
INSERT INTO kandang_groups (
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
status,
|
||||||
|
location_id,
|
||||||
|
pic_id,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
deleted_at,
|
||||||
|
created_by
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
m.kandang_group_id,
|
||||||
|
k.name,
|
||||||
|
k.status,
|
||||||
|
k.location_id,
|
||||||
|
CASE WHEN pic.id IS NOT NULL THEN k.pic_id ELSE NULL END,
|
||||||
|
k.created_at,
|
||||||
|
k.updated_at,
|
||||||
|
k.deleted_at,
|
||||||
|
CASE WHEN creator.id IS NOT NULL THEN k.created_by ELSE NULL END
|
||||||
|
FROM kandangs k
|
||||||
|
JOIN tmp_kandang_group_map m ON m.kandang_id = k.id
|
||||||
|
LEFT JOIN users pic ON pic.id = k.pic_id
|
||||||
|
LEFT JOIN users creator ON creator.id = k.created_by
|
||||||
|
ORDER BY
|
||||||
|
k.id;
|
||||||
|
|
||||||
|
UPDATE kandangs k
|
||||||
|
SET kandang_group_id = m.kandang_group_id
|
||||||
|
FROM tmp_kandang_group_map m
|
||||||
|
WHERE
|
||||||
|
m.kandang_id = k.id;
|
||||||
|
|
||||||
|
ALTER TABLE daily_checklists
|
||||||
|
DROP CONSTRAINT IF EXISTS fk_daily_checklists_kandang;
|
||||||
|
|
||||||
|
UPDATE daily_checklists dc
|
||||||
|
SET kandang_id = m.kandang_group_id
|
||||||
|
FROM tmp_kandang_group_map m
|
||||||
|
WHERE
|
||||||
|
dc.kandang_id = m.kandang_id;
|
||||||
|
|
||||||
|
ALTER TABLE daily_checklists
|
||||||
|
ADD CONSTRAINT fk_daily_checklists_kandang
|
||||||
|
FOREIGN KEY (kandang_id) REFERENCES kandang_groups (id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
ALTER TABLE kandangs
|
||||||
|
ALTER COLUMN kandang_group_id SET NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE kandangs
|
||||||
|
ADD CONSTRAINT fk_kandangs_kandang_group
|
||||||
|
FOREIGN KEY (kandang_group_id) REFERENCES kandang_groups (id) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
CREATE INDEX idx_kandangs_kandang_group_id ON kandangs (kandang_group_id);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -11,6 +11,7 @@ type Kandang struct {
|
|||||||
Name string `gorm:"type:varchar(50);not null;uniqueIndex:kandangs_name_unique,where:deleted_at IS NULL"`
|
Name string `gorm:"type:varchar(50);not null;uniqueIndex:kandangs_name_unique,where:deleted_at IS NULL"`
|
||||||
Status string `gorm:"type:varchar(50);not null"`
|
Status string `gorm:"type:varchar(50);not null"`
|
||||||
LocationId uint `gorm:"not null"`
|
LocationId uint `gorm:"not null"`
|
||||||
|
KandangGroupId uint `gorm:"not null"`
|
||||||
Capacity float64 `gorm:"not null"`
|
Capacity float64 `gorm:"not null"`
|
||||||
PicId uint `gorm:"not null"`
|
PicId uint `gorm:"not null"`
|
||||||
CreatedBy uint `gorm:"not null"`
|
CreatedBy uint `gorm:"not null"`
|
||||||
@@ -19,6 +20,7 @@ type Kandang struct {
|
|||||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||||
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
||||||
Location Location `gorm:"foreignKey:LocationId;references:Id"`
|
Location Location `gorm:"foreignKey:LocationId;references:Id"`
|
||||||
|
KandangGroup KandangGroup `gorm:"foreignKey:KandangGroupId;references:Id"`
|
||||||
Pic User `gorm:"foreignKey:PicId;references:Id"`
|
Pic User `gorm:"foreignKey:PicId;references:Id"`
|
||||||
Warehouses []Warehouse `gorm:"foreignKey:KandangId;references:Id"`
|
Warehouses []Warehouse `gorm:"foreignKey:KandangId;references:Id"`
|
||||||
ProjectFlockKandangs []ProjectFlockKandang `gorm:"foreignKey:KandangId;references:Id" json:"-"`
|
ProjectFlockKandangs []ProjectFlockKandang `gorm:"foreignKey:KandangId;references:Id" json:"-"`
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package entities
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KandangGroup struct {
|
||||||
|
Id uint `gorm:"primaryKey"`
|
||||||
|
Name string `gorm:"type:varchar(50);not null;uniqueIndex:kandang_groups_name_unique,where:deleted_at IS NULL"`
|
||||||
|
Status string `gorm:"type:varchar(50);not null"`
|
||||||
|
LocationId uint `gorm:"not null"`
|
||||||
|
PicId uint `gorm:"not null"`
|
||||||
|
CreatedBy uint `gorm:"not null"`
|
||||||
|
CreatedAt time.Time `gorm:"autoCreateTime"`
|
||||||
|
UpdatedAt time.Time `gorm:"autoUpdateTime"`
|
||||||
|
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||||
|
|
||||||
|
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
||||||
|
Location Location `gorm:"foreignKey:LocationId;references:Id"`
|
||||||
|
Pic User `gorm:"foreignKey:PicId;references:Id"`
|
||||||
|
Kandangs []Kandang `gorm:"foreignKey:KandangGroupId;references:Id"`
|
||||||
|
}
|
||||||
@@ -130,6 +130,12 @@ const (
|
|||||||
P_KandangsUpdateOne = "lti.master.kandangs.update"
|
P_KandangsUpdateOne = "lti.master.kandangs.update"
|
||||||
P_KandangsDeleteOne = "lti.master.kandangs.delete"
|
P_KandangsDeleteOne = "lti.master.kandangs.delete"
|
||||||
|
|
||||||
|
P_KandangGroupsGetAll = "lti.master.kandang_groups.list"
|
||||||
|
P_KandangGroupsGetOne = "lti.master.kandang_groups.detail"
|
||||||
|
P_KandangGroupsCreateOne = "lti.master.kandang_groups.create"
|
||||||
|
P_KandangGroupsUpdateOne = "lti.master.kandang_groups.update"
|
||||||
|
P_KandangGroupsDeleteOne = "lti.master.kandang_groups.delete"
|
||||||
|
|
||||||
P_LocationsGetAll = "lti.master.locations.list"
|
P_LocationsGetAll = "lti.master.locations.list"
|
||||||
P_LocationsGetOne = "lti.master.locations.detail"
|
P_LocationsGetOne = "lti.master.locations.detail"
|
||||||
P_LocationsCreateOne = "lti.master.locations.create"
|
P_LocationsCreateOne = "lti.master.locations.create"
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
|
||||||
|
"gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/dto"
|
||||||
|
service "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/services"
|
||||||
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/validations"
|
||||||
|
"gitlab.com/mbugroup/lti-api.git/internal/response"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KandangGroupController struct {
|
||||||
|
KandangGroupService service.KandangGroupService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKandangGroupController(kandangGroupService service.KandangGroupService) *KandangGroupController {
|
||||||
|
return &KandangGroupController{
|
||||||
|
KandangGroupService: kandangGroupService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *KandangGroupController) GetAll(c *fiber.Ctx) error {
|
||||||
|
query := &validation.Query{
|
||||||
|
Page: c.QueryInt("page", 1),
|
||||||
|
Limit: c.QueryInt("limit", 10),
|
||||||
|
Search: c.Query("search", ""),
|
||||||
|
LocationId: c.QueryInt("location_id", 0),
|
||||||
|
PicId: c.QueryInt("pic_id", 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
if query.Page < 1 || query.Limit < 1 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, totalResults, err := u.KandangGroupService.GetAll(c, query)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).
|
||||||
|
JSON(response.SuccessWithPaginate[dto.KandangGroupListDTO]{
|
||||||
|
Code: fiber.StatusOK,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Get all kandang groups successfully",
|
||||||
|
Meta: response.Meta{
|
||||||
|
Page: query.Page,
|
||||||
|
Limit: query.Limit,
|
||||||
|
TotalPages: int64(math.Ceil(float64(totalResults) / float64(query.Limit))),
|
||||||
|
TotalResults: totalResults,
|
||||||
|
},
|
||||||
|
Data: dto.ToKandangGroupListDTOs(result),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *KandangGroupController) GetOne(c *fiber.Ctx) error {
|
||||||
|
param := c.Params("id")
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(param)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid Id")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := u.KandangGroupService.GetOne(c, uint(id))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).
|
||||||
|
JSON(response.Success{
|
||||||
|
Code: fiber.StatusOK,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Get kandang group successfully",
|
||||||
|
Data: dto.ToKandangGroupListDTO(*result),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *KandangGroupController) CreateOne(c *fiber.Ctx) error {
|
||||||
|
req := new(validation.Create)
|
||||||
|
|
||||||
|
if err := c.BodyParser(req); err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := u.KandangGroupService.CreateOne(c, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusCreated).
|
||||||
|
JSON(response.Success{
|
||||||
|
Code: fiber.StatusCreated,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Create kandang group successfully",
|
||||||
|
Data: dto.ToKandangGroupListDTO(*result),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *KandangGroupController) UpdateOne(c *fiber.Ctx) error {
|
||||||
|
req := new(validation.Update)
|
||||||
|
param := c.Params("id")
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(param)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid Id")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.BodyParser(req); err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := u.KandangGroupService.UpdateOne(c, req, uint(id))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).
|
||||||
|
JSON(response.Success{
|
||||||
|
Code: fiber.StatusOK,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Update kandang group successfully",
|
||||||
|
Data: dto.ToKandangGroupListDTO(*result),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *KandangGroupController) DeleteOne(c *fiber.Ctx) error {
|
||||||
|
param := c.Params("id")
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(param)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid Id")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := u.KandangGroupService.DeleteOne(c, uint(id)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).
|
||||||
|
JSON(response.Common{
|
||||||
|
Code: fiber.StatusOK,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Delete kandang group successfully",
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
|
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
||||||
|
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KandangGroupRelationDTO struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
||||||
|
Pic *userDTO.UserRelationDTO `json:"pic,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RecordingKandangDTO struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KandangGroupListDTO struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Location locationDTO.LocationRelationDTO `json:"location"`
|
||||||
|
Pic userDTO.UserRelationDTO `json:"pic"`
|
||||||
|
CreatedUser userDTO.UserRelationDTO `json:"created_user"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
RecordingKandangs []RecordingKandangDTO `json:"recording_kandangs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KandangGroupDetailDTO struct {
|
||||||
|
KandangGroupListDTO
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToKandangGroupRelationDTO(e entity.KandangGroup) KandangGroupRelationDTO {
|
||||||
|
var location *locationDTO.LocationRelationDTO
|
||||||
|
if e.Location.Id != 0 {
|
||||||
|
mapped := locationDTO.ToLocationRelationDTO(e.Location)
|
||||||
|
location = &mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
var pic *userDTO.UserRelationDTO
|
||||||
|
if e.Pic.Id != 0 {
|
||||||
|
mapped := userDTO.ToUserRelationDTO(e.Pic)
|
||||||
|
pic = &mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
return KandangGroupRelationDTO{
|
||||||
|
Id: e.Id,
|
||||||
|
Name: e.Name,
|
||||||
|
Status: e.Status,
|
||||||
|
Location: location,
|
||||||
|
Pic: pic,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToKandangGroupListDTO(e entity.KandangGroup) KandangGroupListDTO {
|
||||||
|
var location locationDTO.LocationRelationDTO
|
||||||
|
if e.Location.Id != 0 {
|
||||||
|
mapped := locationDTO.ToLocationRelationDTO(e.Location)
|
||||||
|
location = mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
var pic userDTO.UserRelationDTO
|
||||||
|
if e.Pic.Id != 0 {
|
||||||
|
mapped := userDTO.ToUserRelationDTO(e.Pic)
|
||||||
|
pic = mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
var createdUser userDTO.UserRelationDTO
|
||||||
|
if e.CreatedUser.Id != 0 {
|
||||||
|
mapped := userDTO.ToUserRelationDTO(e.CreatedUser)
|
||||||
|
createdUser = mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
recordingKandangs := make([]RecordingKandangDTO, 0, len(e.Kandangs))
|
||||||
|
for _, kandang := range e.Kandangs {
|
||||||
|
recordingKandangs = append(recordingKandangs, RecordingKandangDTO{
|
||||||
|
Id: kandang.Id,
|
||||||
|
Name: kandang.Name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return KandangGroupListDTO{
|
||||||
|
Id: e.Id,
|
||||||
|
Name: e.Name,
|
||||||
|
Status: e.Status,
|
||||||
|
Location: location,
|
||||||
|
Pic: pic,
|
||||||
|
CreatedAt: e.CreatedAt,
|
||||||
|
UpdatedAt: e.UpdatedAt,
|
||||||
|
CreatedUser: createdUser,
|
||||||
|
RecordingKandangs: recordingKandangs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToKandangGroupListDTOs(e []entity.KandangGroup) []KandangGroupListDTO {
|
||||||
|
result := make([]KandangGroupListDTO, len(e))
|
||||||
|
for i, r := range e {
|
||||||
|
result[i] = ToKandangGroupListDTO(r)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToKandangGroupDetailDTO(e entity.KandangGroup) KandangGroupDetailDTO {
|
||||||
|
return KandangGroupDetailDTO{
|
||||||
|
KandangGroupListDTO: ToKandangGroupListDTO(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package kandanggroups
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
rKandangGroup "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/repositories"
|
||||||
|
sKandangGroup "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/services"
|
||||||
|
|
||||||
|
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
|
||||||
|
sUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KandangGroupModule struct{}
|
||||||
|
|
||||||
|
func (KandangGroupModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
|
||||||
|
kandangGroupRepo := rKandangGroup.NewKandangGroupRepository(db)
|
||||||
|
userRepo := rUser.NewUserRepository(db)
|
||||||
|
|
||||||
|
kandangGroupService := sKandangGroup.NewKandangGroupService(kandangGroupRepo, validate)
|
||||||
|
userService := sUser.NewUserService(userRepo, validate)
|
||||||
|
|
||||||
|
KandangGroupRoutes(router, userService, kandangGroupService)
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||||
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KandangGroupRepository interface {
|
||||||
|
repository.BaseRepository[entity.KandangGroup]
|
||||||
|
LocationExists(ctx context.Context, locationId uint) (bool, error)
|
||||||
|
PicExists(ctx context.Context, picId uint) (bool, error)
|
||||||
|
NameExists(ctx context.Context, name string, excludeID *uint) (bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type KandangGroupRepositoryImpl struct {
|
||||||
|
*repository.BaseRepositoryImpl[entity.KandangGroup]
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKandangGroupRepository(db *gorm.DB) KandangGroupRepository {
|
||||||
|
return &KandangGroupRepositoryImpl{
|
||||||
|
BaseRepositoryImpl: repository.NewBaseRepository[entity.KandangGroup](db),
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *KandangGroupRepositoryImpl) LocationExists(ctx context.Context, locationId uint) (bool, error) {
|
||||||
|
return repository.Exists[entity.Location](ctx, r.db, locationId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *KandangGroupRepositoryImpl) PicExists(ctx context.Context, picId uint) (bool, error) {
|
||||||
|
return repository.Exists[entity.User](ctx, r.db, picId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *KandangGroupRepositoryImpl) NameExists(ctx context.Context, name string, excludeID *uint) (bool, error) {
|
||||||
|
return repository.ExistsByName[entity.KandangGroup](ctx, r.db, name, excludeID)
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package kandanggroups
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
|
||||||
|
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||||
|
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/controllers"
|
||||||
|
kandanggroup "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/services"
|
||||||
|
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
func KandangGroupRoutes(v1 fiber.Router, u user.UserService, s kandanggroup.KandangGroupService) {
|
||||||
|
ctrl := controller.NewKandangGroupController(s)
|
||||||
|
|
||||||
|
route := v1.Group("/kandang-groups")
|
||||||
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
|
route.Get("/", m.RequirePermissions(m.P_KandangGroupsGetAll), ctrl.GetAll)
|
||||||
|
route.Post("/", m.RequirePermissions(m.P_KandangGroupsCreateOne), ctrl.CreateOne)
|
||||||
|
route.Get("/:id", m.RequirePermissions(m.P_KandangGroupsGetOne), ctrl.GetOne)
|
||||||
|
route.Get("/:id", ctrl.GetOne)
|
||||||
|
route.Patch("/:id", m.RequirePermissions(m.P_KandangGroupsUpdateOne), ctrl.UpdateOne)
|
||||||
|
route.Delete("/:id", m.RequirePermissions(m.P_KandangGroupsDeleteOne), ctrl.DeleteOne)
|
||||||
|
}
|
||||||
@@ -0,0 +1,238 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
common "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||||
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
|
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||||
|
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/repositories"
|
||||||
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups/validations"
|
||||||
|
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KandangGroupService interface {
|
||||||
|
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.KandangGroup, int64, error)
|
||||||
|
GetOne(ctx *fiber.Ctx, id uint) (*entity.KandangGroup, error)
|
||||||
|
CreateOne(ctx *fiber.Ctx, req *validation.Create) (*entity.KandangGroup, error)
|
||||||
|
UpdateOne(ctx *fiber.Ctx, req *validation.Update, id uint) (*entity.KandangGroup, error)
|
||||||
|
DeleteOne(ctx *fiber.Ctx, id uint) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type kandangGroupService struct {
|
||||||
|
Log *logrus.Logger
|
||||||
|
Validate *validator.Validate
|
||||||
|
Repository repository.KandangGroupRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKandangGroupService(repo repository.KandangGroupRepository, validate *validator.Validate) KandangGroupService {
|
||||||
|
return &kandangGroupService{
|
||||||
|
Log: utils.Log,
|
||||||
|
Validate: validate,
|
||||||
|
Repository: repo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s kandangGroupService) withRelations(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.
|
||||||
|
Preload("CreatedUser").
|
||||||
|
Preload("Location").
|
||||||
|
Preload("Pic").
|
||||||
|
Preload("Kandangs", func(tx *gorm.DB) *gorm.DB {
|
||||||
|
return tx.Select("id", "name", "kandang_group_id").Order("name ASC")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s kandangGroupService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.KandangGroup, int64, error) {
|
||||||
|
if err := s.Validate.Struct(params); err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var scopeErr error
|
||||||
|
offset := (params.Page - 1) * params.Limit
|
||||||
|
|
||||||
|
kandangGroups, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||||
|
db = s.withRelations(db)
|
||||||
|
db, scopeErr = m.ApplyLocationScope(c, db, "kandang_groups.location_id")
|
||||||
|
if params.Search != "" {
|
||||||
|
db = db.Where("kandang_groups.name ILIKE ?", "%"+params.Search+"%")
|
||||||
|
}
|
||||||
|
if params.LocationId != 0 {
|
||||||
|
db = db.Where("kandang_groups.location_id = ?", params.LocationId)
|
||||||
|
}
|
||||||
|
if params.PicId != 0 {
|
||||||
|
db = db.Where("kandang_groups.pic_id = ?", params.PicId)
|
||||||
|
}
|
||||||
|
return db.Order("kandang_groups.created_at DESC").Order("kandang_groups.updated_at DESC")
|
||||||
|
})
|
||||||
|
|
||||||
|
if scopeErr != nil {
|
||||||
|
return nil, 0, scopeErr
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
s.Log.Errorf("Failed to get kandang groups: %+v", err)
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return kandangGroups, total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s kandangGroupService) GetOne(c *fiber.Ctx, id uint) (*entity.KandangGroup, error) {
|
||||||
|
var scopeErr error
|
||||||
|
|
||||||
|
kandangGroup, err := s.Repository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
||||||
|
db = s.withRelations(db)
|
||||||
|
db, scopeErr = m.ApplyLocationScope(c, db, "kandang_groups.location_id")
|
||||||
|
return db
|
||||||
|
})
|
||||||
|
if scopeErr != nil {
|
||||||
|
return nil, scopeErr
|
||||||
|
}
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Kandang group not found")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
s.Log.Errorf("Failed to get kandang group by id: %+v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return kandangGroup, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *kandangGroupService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entity.KandangGroup, error) {
|
||||||
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := m.EnsureLocationAccess(c, s.Repository.DB(), req.LocationId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists, err := s.Repository.NameExists(c.Context(), req.Name, nil); err != nil {
|
||||||
|
s.Log.Errorf("Failed to check kandang group name: %+v", err)
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to check kandang group name")
|
||||||
|
} else if exists {
|
||||||
|
return nil, fiber.NewError(fiber.StatusConflict, fmt.Sprintf("Kandang group with name %s already exists", req.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := common.EnsureRelations(c.Context(),
|
||||||
|
common.RelationCheck{Name: "Location", ID: &req.LocationId, Exists: s.Repository.LocationExists},
|
||||||
|
common.RelationCheck{Name: "Pic", ID: &req.PicId, Exists: s.Repository.PicExists},
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
status := strings.ToUpper(strings.TrimSpace(req.Status))
|
||||||
|
if status == "" {
|
||||||
|
status = string(utils.KandangStatusNonActive)
|
||||||
|
}
|
||||||
|
if !utils.IsValidKandangStatus(status) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid kandang group status")
|
||||||
|
}
|
||||||
|
|
||||||
|
actorID, err := m.ActorIDFromContext(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
createBody := &entity.KandangGroup{
|
||||||
|
Name: req.Name,
|
||||||
|
Status: status,
|
||||||
|
LocationId: req.LocationId,
|
||||||
|
PicId: req.PicId,
|
||||||
|
CreatedBy: actorID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Repository.CreateOne(c.Context(), createBody, nil); err != nil {
|
||||||
|
s.Log.Errorf("Failed to create kandang group: %+v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.GetOne(c, createBody.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s kandangGroupService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.KandangGroup, error) {
|
||||||
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
existing, err := s.GetOne(c, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.LocationId != nil {
|
||||||
|
if err := m.EnsureLocationAccess(c, s.Repository.DB(), *req.LocationId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBody := make(map[string]any)
|
||||||
|
|
||||||
|
if req.Name != nil {
|
||||||
|
if exists, err := s.Repository.NameExists(c.Context(), *req.Name, &id); err != nil {
|
||||||
|
s.Log.Errorf("Failed to check kandang group name: %+v", err)
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to check kandang group name")
|
||||||
|
} else if exists {
|
||||||
|
return nil, fiber.NewError(fiber.StatusConflict, fmt.Sprintf("Kandang group with name %s already exists", *req.Name))
|
||||||
|
}
|
||||||
|
updateBody["name"] = *req.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := common.EnsureRelations(c.Context(),
|
||||||
|
common.RelationCheck{Name: "Location", ID: req.LocationId, Exists: s.Repository.LocationExists},
|
||||||
|
common.RelationCheck{Name: "Pic", ID: req.PicId, Exists: s.Repository.PicExists},
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.LocationId != nil {
|
||||||
|
updateBody["location_id"] = *req.LocationId
|
||||||
|
}
|
||||||
|
if req.PicId != nil {
|
||||||
|
updateBody["pic_id"] = *req.PicId
|
||||||
|
}
|
||||||
|
if req.Status != nil {
|
||||||
|
status := strings.ToUpper(strings.TrimSpace(*req.Status))
|
||||||
|
if !utils.IsValidKandangStatus(status) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid kandang group status")
|
||||||
|
}
|
||||||
|
updateBody["status"] = status
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(updateBody) == 0 {
|
||||||
|
return existing, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Repository.PatchOne(c.Context(), id, updateBody, nil); err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Kandang group not found")
|
||||||
|
}
|
||||||
|
s.Log.Errorf("Failed to update kandang group: %+v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.GetOne(c, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s kandangGroupService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||||
|
if _, err := s.GetOne(c, id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Repository.DeleteOne(c.Context(), id); err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Kandang group not found")
|
||||||
|
}
|
||||||
|
s.Log.Errorf("Failed to delete kandang group: %+v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package validation
|
||||||
|
|
||||||
|
type Create struct {
|
||||||
|
Name string `json:"name" validate:"required_strict,min=3,max=50"`
|
||||||
|
Status string `json:"status,omitempty" validate:"omitempty,min=3,max=50"`
|
||||||
|
LocationId uint `json:"location_id" validate:"required_strict,number,gt=0"`
|
||||||
|
PicId uint `json:"pic_id" validate:"required_strict,number,gt=0"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Update struct {
|
||||||
|
Name *string `json:"name,omitempty" validate:"omitempty,max=50"`
|
||||||
|
Status *string `json:"status,omitempty" validate:"omitempty,min=3,max=50"`
|
||||||
|
LocationId *uint `json:"location_id,omitempty" validate:"omitempty,number,gt=0"`
|
||||||
|
PicId *uint `json:"pic_id,omitempty" validate:"omitempty,number,gt=0"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query struct {
|
||||||
|
Page int `query:"page" validate:"omitempty,number,min=1"`
|
||||||
|
Limit int `query:"limit" validate:"omitempty,number,min=1,max=500"`
|
||||||
|
Search string `query:"search" validate:"omitempty,max=50"`
|
||||||
|
LocationId int `query:"location_id" validate:"omitempty,number,gt=0"`
|
||||||
|
PicId int `query:"pic_id" validate:"omitempty,number,gt=0"`
|
||||||
|
}
|
||||||
@@ -9,10 +9,12 @@ import (
|
|||||||
|
|
||||||
areas "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas"
|
areas "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas"
|
||||||
banks "gitlab.com/mbugroup/lti-api.git/internal/modules/master/banks"
|
banks "gitlab.com/mbugroup/lti-api.git/internal/modules/master/banks"
|
||||||
|
configChecklists "gitlab.com/mbugroup/lti-api.git/internal/modules/master/config-checklists"
|
||||||
customers "gitlab.com/mbugroup/lti-api.git/internal/modules/master/customers"
|
customers "gitlab.com/mbugroup/lti-api.git/internal/modules/master/customers"
|
||||||
employeess "gitlab.com/mbugroup/lti-api.git/internal/modules/master/employees"
|
employeess "gitlab.com/mbugroup/lti-api.git/internal/modules/master/employees"
|
||||||
fcrs "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs"
|
fcrs "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs"
|
||||||
flocks "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks"
|
flocks "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks"
|
||||||
|
kandanggroups "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandang-groups"
|
||||||
kandangs "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs"
|
kandangs "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs"
|
||||||
locations "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations"
|
locations "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations"
|
||||||
nonstocks "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks"
|
nonstocks "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks"
|
||||||
@@ -24,7 +26,6 @@ import (
|
|||||||
suppliers "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers"
|
suppliers "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers"
|
||||||
uoms "gitlab.com/mbugroup/lti-api.git/internal/modules/master/uoms"
|
uoms "gitlab.com/mbugroup/lti-api.git/internal/modules/master/uoms"
|
||||||
warehouses "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses"
|
warehouses "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses"
|
||||||
configChecklists "gitlab.com/mbugroup/lti-api.git/internal/modules/master/config-checklists"
|
|
||||||
// MODULE IMPORTS
|
// MODULE IMPORTS
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ func RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Valida
|
|||||||
uoms.UomModule{},
|
uoms.UomModule{},
|
||||||
areas.AreaModule{},
|
areas.AreaModule{},
|
||||||
locations.LocationModule{},
|
locations.LocationModule{},
|
||||||
|
kandanggroups.KandangGroupModule{},
|
||||||
kandangs.KandangModule{},
|
kandangs.KandangModule{},
|
||||||
warehouses.WarehouseModule{},
|
warehouses.WarehouseModule{},
|
||||||
customers.CustomerModule{},
|
customers.CustomerModule{},
|
||||||
|
|||||||
Reference in New Issue
Block a user