FIX[BE]: fix logic on Chickin Laying not convert to layer but still Pullet, and inisiate laying transfer migration and base basic API

This commit is contained in:
aguhh18
2025-11-04 08:24:38 +07:00
parent c72db5bd18
commit 8220e34302
22 changed files with 587 additions and 163 deletions
@@ -41,12 +41,12 @@ type KandangCustomDTO struct {
type ProductWarehouseDTO struct {
Id uint `json:"id"`
Quantity float64 `json:"quantity"`
Product *productDTO.ProductBaseDTO `json:"product,omitempty"`
Warehouse *warehouseDTO.WarehouseBaseDTO `json:"warehouse,omitempty"`
}
type AvailableQtyDTO struct {
AvailableQty float64 `json:"available_qty"`
ProductWarehouse *ProductWarehouseDTO `json:"product_warehouse,omitempty"`
}
@@ -171,10 +171,6 @@ func buildProductWarehouseFromMap(pwData map[string]interface{}) *ProductWarehou
dto.Id = id
}
if qty, ok := pwData["quantity"].(float64); ok {
dto.Quantity = qty
}
if pData, ok := pwData["product"].(map[string]interface{}); ok {
dto.Product = buildProductFromMap(pData)
}
@@ -276,8 +272,7 @@ func buildAvailableQtys(chickins []entity.ProjectChickin) []AvailableQtyDTO {
}
pwDTO := &ProductWarehouseDTO{
Id: ch.ProductWarehouse.Id,
Quantity: ch.ProductWarehouse.Quantity,
Id: ch.ProductWarehouse.Id,
}
if ch.ProductWarehouse.Product.Id != 0 {
@@ -324,7 +319,13 @@ func buildAvailableQtysFromRaw(availableQtysRaw []map[string]interface{}) []Avai
}
pwDTO := buildProductWarehouseFromMap(pwData)
availableQty := 0.0
if qty, ok := v["available_qty"].(float64); ok {
availableQty = qty
}
result[i] = AvailableQtyDTO{
AvailableQty: availableQty,
ProductWarehouse: pwDTO,
}
}
@@ -24,6 +24,7 @@ type ProjectFlockKandangModule struct{}
func (ProjectFlockKandangModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
projectFlockKandangRepo := rProjectFlockKandang.NewProjectFlockKandangRepository(db)
projectFlockPopulationRepo := rProjectFlockKandang.NewProjectFlockPopulationRepository(db)
userRepo := rUser.NewUserRepository(db)
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
@@ -35,7 +36,7 @@ func (ProjectFlockKandangModule) RegisterRoutes(router fiber.Router, db *gorm.DB
panic(fmt.Sprintf("failed to register project flock kandang approval workflow: %v", err))
}
projectFlockKandangService := sProjectFlockKandang.NewProjectFlockKandangService(projectFlockKandangRepo, approvalService, warehouseRepo, productWarehouseRepo, validate)
projectFlockKandangService := sProjectFlockKandang.NewProjectFlockKandangService(projectFlockKandangRepo, approvalService, warehouseRepo, productWarehouseRepo, projectFlockPopulationRepo, validate)
userService := sUser.NewUserService(userRepo, validate)
ProjectFlockKandangRoutes(router, userService, projectFlockKandangService)
@@ -29,9 +29,10 @@ type projectFlockKandangService struct {
ApprovalSvc commonSvc.ApprovalService
WarehouseRepo rWarehouse.WarehouseRepository
ProductWarehouseRepo rProductWarehouse.ProductWarehouseRepository
PopulationRepo repository.ProjectFlockPopulationRepository
}
func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository, approvalSvc commonSvc.ApprovalService, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, validate *validator.Validate) ProjectFlockKandangService {
func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository, approvalSvc commonSvc.ApprovalService, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, populationRepo repository.ProjectFlockPopulationRepository, validate *validator.Validate) ProjectFlockKandangService {
return &projectFlockKandangService{
Log: utils.Log,
Validate: validate,
@@ -39,6 +40,7 @@ func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository
ApprovalSvc: approvalSvc,
WarehouseRepo: warehouseRepo,
ProductWarehouseRepo: productWarehouseRepo,
PopulationRepo: populationRepo,
}
}
@@ -114,32 +116,80 @@ func (s projectFlockKandangService) getAvailableQuantities(c *fiber.Ctx, project
var result []map[string]interface{}
for _, pw := range products {
if pw.Quantity > 0 {
productData := map[string]interface{}{
"id": pw.Product.Id,
"name": pw.Product.Name,
}
warehouseData := map[string]interface{}{
"id": pw.Warehouse.Id,
"name": pw.Warehouse.Name,
"type": pw.Warehouse.Type,
}
productWarehouseData := map[string]interface{}{
"id": pw.Id,
"quantity": pw.Quantity,
"product": productData,
"warehouse": warehouseData,
}
result = append(result, map[string]interface{}{
"available_qty": pw.Quantity,
"product_warehouse": productWarehouseData,
})
availableQty, err := s.calculateAvailableQuantityForProductWarehouse(c, projectFlockKandang, &pw)
if err != nil {
s.Log.Warnf("Failed to calculate available quantity for product warehouse %d: %v", pw.Id, err)
}
// Only include product warehouse if available_qty > 0
if availableQty <= 0 {
continue
}
productData := map[string]interface{}{
"id": pw.Product.Id,
"name": pw.Product.Name,
}
warehouseData := map[string]interface{}{
"id": pw.Warehouse.Id,
"name": pw.Warehouse.Name,
"type": pw.Warehouse.Type,
}
productWarehouseData := map[string]interface{}{
"id": pw.Id,
"product": productData,
"warehouse": warehouseData,
}
result = append(result, map[string]interface{}{
"available_qty": availableQty,
"product_warehouse": productWarehouseData,
})
}
return result, nil
}
func (s projectFlockKandangService) calculateAvailableQuantityForProductWarehouse(c *fiber.Ctx, projectFlockKandang *entity.ProjectFlockKandang, productWarehouse *entity.ProductWarehouse) (float64, error) {
availableQty := productWarehouse.Quantity
if projectFlockKandang.ProjectFlock.Category == string(utils.ProjectFlockCategoryGrowing) {
var totalPendingQty float64
for _, chickin := range projectFlockKandang.Chickins {
if chickin.ProductWarehouseId == productWarehouse.Id && chickin.DeletedAt.Time.IsZero() && chickin.PendingUsageQty > 0 {
totalPendingQty += chickin.PendingUsageQty
}
}
availableQty = productWarehouse.Quantity - totalPendingQty
if availableQty < 0 {
availableQty = 0
}
} else if projectFlockKandang.ProjectFlock.Category == string(utils.ProjectFlockCategoryLaying) {
var totalPopulation float64
var totalPendingQty float64
populations, err := s.PopulationRepo.GetByProjectFlockKandangIDAndProductWarehouseID(c.Context(), projectFlockKandang.Id, productWarehouse.Id)
if err == nil {
for _, pop := range populations {
totalPopulation += pop.TotalQty
}
}
for _, chickin := range projectFlockKandang.Chickins {
if chickin.ProductWarehouseId == productWarehouse.Id && chickin.DeletedAt.Time.IsZero() && chickin.PendingUsageQty > 0 {
totalPendingQty += chickin.PendingUsageQty
}
}
availableQty = productWarehouse.Quantity - totalPopulation - totalPendingQty
if availableQty < 0 {
availableQty = 0
}
}
return availableQty, nil
}