Merge branch 'feat/BE/Sprint-7' of https://gitlab.com/mbugroup/lti-api into feat/BE/US-304/permission-middleware-adjustment

This commit is contained in:
ragilap
2025-12-19 14:19:40 +07:00
87 changed files with 4782 additions and 1261 deletions
@@ -33,10 +33,8 @@ type ProductWarehouseDTO struct {
type AdjustmentRelationDTO struct {
Id uint `json:"id"`
TransactionType string `json:"transaction_type"`
Quantity float64 `json:"quantity"`
BeforeQuantity float64 `json:"before_quantity"`
AfterQuantity float64 `json:"after_quantity"`
Increase float64 `json:"increase"`
Decrease float64 `json:"decrease"`
Note string `json:"note,omitempty"`
ProductWarehouseId uint `json:"product_warehouse_id"`
ProductWarehouse *ProductWarehouseDTO `json:"product_warehouse,omitempty"`
@@ -104,12 +102,10 @@ func ToProductWarehouseDTO(e *entity.ProductWarehouse) *ProductWarehouseDTO {
func ToAdjustmentRelationDTO(e *entity.StockLog) AdjustmentRelationDTO {
return AdjustmentRelationDTO{
Id: e.Id,
// TransactionType: e.LoggableType,
// Quantity: e.Q,
// BeforeQuantity: e.BeforeQuantity,
// AfterQuantity: e.AfterQuantity,
Id: e.Id,
Note: e.Notes,
Increase: e.Increase,
Decrease: e.Decrease,
ProductWarehouseId: e.ProductWarehouseId,
ProductWarehouse: ToProductWarehouseDTO(e.ProductWarehouse),
}
@@ -9,8 +9,8 @@ import (
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
rproduct "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/repositories"
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
rProjectFlockKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
rStockLogs "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/repositories"
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
sUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
)
@@ -21,10 +21,11 @@ func (AdjustmentModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validat
stockLogsRepo := rStockLogs.NewStockLogRepository(db)
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
projectFlockKandangRepo := rProjectFlockKandang.NewProjectFlockKandangRepository(db)
userRepo := rUser.NewUserRepository(db)
productRepo := rproduct.NewProductRepository(db)
adjustmentService := sAdjustment.NewAdjustmentService(productRepo, stockLogsRepo, warehouseRepo, productWarehouseRepo, validate)
adjustmentService := sAdjustment.NewAdjustmentService(productRepo, stockLogsRepo, warehouseRepo, productWarehouseRepo, validate, projectFlockKandangRepo)
userService := sUser.NewUserService(userRepo, validate)
AdjustmentRoutes(router, userService, adjustmentService)
@@ -1,9 +1,14 @@
package service
import (
"context"
"errors"
"fmt"
"strings"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
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"
@@ -11,13 +16,10 @@ import (
ProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
productRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/repositories"
warehouseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
projectFlockKandangRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
stockLogsRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/repositories"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
"gorm.io/gorm"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
)
type AdjustmentService interface {
@@ -27,22 +29,24 @@ type AdjustmentService interface {
}
type adjustmentService struct {
Log *logrus.Logger
Validate *validator.Validate
StockLogsRepository stockLogsRepo.StockLogRepository
WarehouseRepo warehouseRepo.WarehouseRepository
ProductWarehouseRepo ProductWarehouse.ProductWarehouseRepository
ProductRepo productRepo.ProductRepository
Log *logrus.Logger
Validate *validator.Validate
StockLogsRepository stockLogsRepo.StockLogRepository
WarehouseRepo warehouseRepo.WarehouseRepository
ProductWarehouseRepo ProductWarehouse.ProductWarehouseRepository
ProductRepo productRepo.ProductRepository
ProjectFlockKandangRepo projectFlockKandangRepo.ProjectFlockKandangRepository
}
func NewAdjustmentService(productRepo productRepo.ProductRepository, stockLogsRepo stockLogsRepo.StockLogRepository, warehouseRepo warehouseRepo.WarehouseRepository, productWarehouseRepo ProductWarehouse.ProductWarehouseRepository, validate *validator.Validate) AdjustmentService {
func NewAdjustmentService(productRepo productRepo.ProductRepository, stockLogsRepo stockLogsRepo.StockLogRepository, warehouseRepo warehouseRepo.WarehouseRepository, productWarehouseRepo ProductWarehouse.ProductWarehouseRepository, validate *validator.Validate, projectFlockKandangRepo projectFlockKandangRepo.ProjectFlockKandangRepository) AdjustmentService {
return &adjustmentService{
Log: utils.Log,
Validate: validate,
StockLogsRepository: stockLogsRepo,
WarehouseRepo: warehouseRepo,
ProductWarehouseRepo: productWarehouseRepo,
ProductRepo: productRepo,
Log: utils.Log,
Validate: validate,
StockLogsRepository: stockLogsRepo,
WarehouseRepo: warehouseRepo,
ProductWarehouseRepo: productWarehouseRepo,
ProductRepo: productRepo,
ProjectFlockKandangRepo: projectFlockKandangRepo,
}
}
@@ -105,11 +109,15 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate product warehouse")
}
if !isProductWarehouseExist {
projectFlockKandangID, err := s.getActiveProjectFlockKandangID(ctx, uint(req.WarehouseID))
if err != nil {
return nil, err
}
newPW := &entity.ProductWarehouse{
ProductId: uint(req.ProductID),
WarehouseId: uint(req.WarehouseID),
Quantity: 0,
ProductId: uint(req.ProductID),
WarehouseId: uint(req.WarehouseID),
Quantity: 0,
ProjectFlockKandangId: &projectFlockKandangID,
// CreatedBy: 1, // TODO: should Get from auth middleware
}
@@ -120,6 +128,23 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
s.Log.Infof("Product warehouse created: %+v", newPW.Id)
}
pw, err := s.ProductWarehouseRepo.GetProductWarehouseByProductAndWarehouseID(
ctx,
uint(req.ProductID),
uint(req.WarehouseID),
)
if err != nil {
s.Log.Errorf("Failed to get product warehouse for project flock check: %+v", err)
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate product warehouse")
}
if err := common.EnsureProjectFlockNotClosedForProductWarehouses(
ctx,
s.StockLogsRepository.DB(),
[]uint{pw.Id},
); err != nil {
return nil, err
}
err = s.StockLogsRepository.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
productWarehouse, err := s.ProductWarehouseRepo.GetProductWarehouseByProductAndWarehouseID(ctx, uint(req.ProductID), uint(req.WarehouseID))
if err != nil {
@@ -170,6 +195,32 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
return s.GetOne(c, createdLogId)
}
func (s *adjustmentService) getActiveProjectFlockKandangID(ctx context.Context, warehouseID uint) (uint, error) {
warehouse, err := s.WarehouseRepo.GetByID(ctx, warehouseID, nil)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return 0, fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Gudang dengan ID %d tidak ditemukan", warehouseID))
}
s.Log.Errorf("Failed to get warehouse %d: %+v", warehouseID, err)
return 0, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil data gudang")
}
if warehouse.KandangId == nil || *warehouse.KandangId == 0 {
return 0, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Gudang %d belum terhubung ke kandang", warehouseID))
}
projectFlockKandang, err := s.ProjectFlockKandangRepo.GetActiveByKandangID(ctx, uint(*warehouse.KandangId))
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return 0, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Kandang %d belum memiliki project flock aktif", *warehouse.KandangId))
}
s.Log.Errorf("Failed to get active project flock for kandang %d: %+v", *warehouse.KandangId, err)
return 0, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil project flock kandang")
}
return uint(projectFlockKandang.Id), nil
}
func (s *adjustmentService) AdjustmentHistory(c *fiber.Ctx, query *validation.Query) ([]*entity.StockLog, int64, error) {
if err := s.Validate.Struct(query); err != nil {
return nil, 0, err
@@ -178,7 +229,6 @@ func (s *adjustmentService) AdjustmentHistory(c *fiber.Ctx, query *validation.Qu
isWarehousesExist, err := s.WarehouseRepo.IdExists(c.Context(), uint(query.WarehouseID))
if err != nil {
s.Log.Errorf("Failed to check warehouse existence: %+v", err)
return nil, 0, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate warehouse")
}
if query.WarehouseID > 0 && !isWarehousesExist {