mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-24 07:15:43 +00:00
codex: initiated changes
This commit is contained in:
+235
-127
@@ -2,9 +2,10 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/repports/validations"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
@@ -12,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
type MarketingDeliveryProductRepository interface {
|
||||
repository.BaseRepository[entity.MarketingDeliveryProduct]
|
||||
commonRepo.BaseRepository[entity.MarketingDeliveryProduct]
|
||||
GetDeliveryProductsByProjectFlockID(ctx context.Context, projectFlockID uint, callback func(*gorm.DB) *gorm.DB) ([]entity.MarketingDeliveryProduct, error)
|
||||
GetClosingPenjualan(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error)
|
||||
GetClosingPenjualanByCategory(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint, category string) ([]entity.MarketingDeliveryProduct, error)
|
||||
@@ -23,26 +24,27 @@ type MarketingDeliveryProductRepository interface {
|
||||
GetUsageQty(ctx context.Context, id uint) (float64, error)
|
||||
ResetFifoFields(ctx context.Context, id uint) error
|
||||
GetClosingPenjualanForAgeChickDataProduction(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error)
|
||||
GetAttributionRowsByDeliveryProductIDs(ctx context.Context, deliveryProductIDs []uint) ([]commonRepo.MarketingDeliveryAttributionRow, error)
|
||||
}
|
||||
|
||||
type MarketingDeliveryProductRepositoryImpl struct {
|
||||
*repository.BaseRepositoryImpl[entity.MarketingDeliveryProduct]
|
||||
*commonRepo.BaseRepositoryImpl[entity.MarketingDeliveryProduct]
|
||||
}
|
||||
|
||||
func NewMarketingDeliveryProductRepository(db *gorm.DB) MarketingDeliveryProductRepository {
|
||||
return &MarketingDeliveryProductRepositoryImpl{
|
||||
BaseRepositoryImpl: repository.NewBaseRepository[entity.MarketingDeliveryProduct](db),
|
||||
BaseRepositoryImpl: commonRepo.NewBaseRepository[entity.MarketingDeliveryProduct](db),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetDeliveryProductsByProjectFlockID(ctx context.Context, projectFlockID uint, callback func(*gorm.DB) *gorm.DB) ([]entity.MarketingDeliveryProduct, error) {
|
||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||
|
||||
attributionQuery := commonRepo.MarketingDeliveryAttributionRowsQuery(r.DB().WithContext(ctx))
|
||||
|
||||
db := r.DB().WithContext(ctx).
|
||||
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||
Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id").
|
||||
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id").
|
||||
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
|
||||
Joins("JOIN (?) AS mda ON mda.marketing_delivery_product_id = marketing_delivery_products.id", attributionQuery).
|
||||
Where("mda.project_flock_id = ?", projectFlockID).
|
||||
Distinct("marketing_delivery_products.*")
|
||||
|
||||
if callback != nil {
|
||||
@@ -57,139 +59,50 @@ func (r *MarketingDeliveryProductRepositoryImpl) GetDeliveryProductsByProjectFlo
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetClosingPenjualan(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) {
|
||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||
|
||||
db := r.DB().WithContext(ctx).
|
||||
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||
Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id").
|
||||
Joins("JOIN products ON products.id = product_warehouses.product_id").
|
||||
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id").
|
||||
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
|
||||
Where("marketing_delivery_products.delivery_date IS NOT NULL").
|
||||
Distinct("marketing_delivery_products.*")
|
||||
|
||||
if projectFlockKandangID != nil {
|
||||
db = db.Where("product_warehouses.project_flock_kandang_id = ?", *projectFlockKandangID)
|
||||
}
|
||||
|
||||
db = db.
|
||||
Preload("MarketingProduct").
|
||||
Preload("MarketingProduct.ProductWarehouse").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.ProductCategory").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.Uom").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.Flags").
|
||||
Preload("MarketingProduct.ProductWarehouse.Warehouse").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Chickins").
|
||||
Preload("MarketingProduct.Marketing").
|
||||
Preload("MarketingProduct.Marketing.Customer").
|
||||
Order("marketing_delivery_products.delivery_date DESC")
|
||||
|
||||
if err := db.Find(&deliveryProducts).Error; err != nil {
|
||||
attributionRows, err := r.getClosingAttributionRows(ctx, projectFlockID, projectFlockKandangID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return deliveryProducts, nil
|
||||
return r.fetchClosingDeliveryProducts(ctx, attributionRows, projectFlockKandangID)
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetClosingPenjualanForAgeChickDataProduction(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) {
|
||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||
|
||||
db := r.DB().WithContext(ctx).
|
||||
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||
Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id").
|
||||
Joins("JOIN products ON products.id = product_warehouses.product_id").
|
||||
Joins("JOIN flags ON flags.flagable_id = products.id AND flags.flagable_type = 'products'").
|
||||
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id").
|
||||
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
|
||||
Where("flags.name IN (?)", []string{
|
||||
string(utils.FlagAyamAfkir),
|
||||
string(utils.FlagAyamCulling),
|
||||
string(utils.FlagPullet),
|
||||
string(utils.FlagLayer),
|
||||
}).
|
||||
Where("marketing_delivery_products.delivery_date IS NOT NULL").
|
||||
Distinct("marketing_delivery_products.*")
|
||||
|
||||
if projectFlockKandangID != nil {
|
||||
db = db.Where("product_warehouses.project_flock_kandang_id = ?", *projectFlockKandangID)
|
||||
}
|
||||
|
||||
db = db.
|
||||
Preload("MarketingProduct").
|
||||
Preload("MarketingProduct.ProductWarehouse").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.ProductCategory").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.Flags").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Chickins").
|
||||
Order("marketing_delivery_products.delivery_date DESC")
|
||||
|
||||
if err := db.Find(&deliveryProducts).Error; err != nil {
|
||||
attributionRows, err := r.getClosingAttributionRows(ctx, projectFlockID, projectFlockKandangID, []string{
|
||||
string(utils.FlagAyamAfkir),
|
||||
string(utils.FlagAyamCulling),
|
||||
string(utils.FlagPullet),
|
||||
string(utils.FlagLayer),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return deliveryProducts, nil
|
||||
return r.fetchClosingDeliveryProducts(ctx, attributionRows, projectFlockKandangID)
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetClosingPenjualanByCategory(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint, category string) ([]entity.MarketingDeliveryProduct, error) {
|
||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||
|
||||
db := r.DB().WithContext(ctx).
|
||||
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||
Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id").
|
||||
Joins("JOIN products ON products.id = product_warehouses.product_id").
|
||||
Joins("JOIN flags ON flags.flagable_id = products.id AND flags.flagable_type = 'products'").
|
||||
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id").
|
||||
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
|
||||
Where("marketing_delivery_products.delivery_date IS NOT NULL").
|
||||
Distinct("marketing_delivery_products.*")
|
||||
|
||||
if projectFlockKandangID != nil {
|
||||
db = db.Where("product_warehouses.project_flock_kandang_id = ?", *projectFlockKandangID)
|
||||
flagNames := []string{
|
||||
string(utils.FlagDOC),
|
||||
string(utils.FlagPullet),
|
||||
string(utils.FlagLayer),
|
||||
string(utils.FlagAyamAfkir),
|
||||
string(utils.FlagAyamCulling),
|
||||
string(utils.FlagAyamMati),
|
||||
}
|
||||
|
||||
if category == string(utils.ProjectFlockCategoryLaying) {
|
||||
db = db.Where("flags.name IN (?)", []string{
|
||||
flagNames = []string{
|
||||
string(utils.FlagTelur),
|
||||
string(utils.FlagTelurUtuh),
|
||||
string(utils.FlagTelurPecah),
|
||||
string(utils.FlagTelurPutih),
|
||||
string(utils.FlagTelurRetak),
|
||||
})
|
||||
} else {
|
||||
db = db.Where("flags.name IN (?)", []string{
|
||||
string(utils.FlagDOC),
|
||||
string(utils.FlagPullet),
|
||||
string(utils.FlagLayer),
|
||||
string(utils.FlagAyamAfkir),
|
||||
string(utils.FlagAyamCulling),
|
||||
string(utils.FlagAyamMati),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
db = db.
|
||||
Preload("MarketingProduct").
|
||||
Preload("MarketingProduct.ProductWarehouse").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.ProductCategory").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.Uom").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.Flags").
|
||||
Preload("MarketingProduct.ProductWarehouse.Warehouse").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Chickins").
|
||||
Preload("MarketingProduct.Marketing").
|
||||
Preload("MarketingProduct.Marketing.Customer").
|
||||
Order("marketing_delivery_products.delivery_date DESC")
|
||||
|
||||
if err := db.Find(&deliveryProducts).Error; err != nil {
|
||||
attributionRows, err := r.getClosingAttributionRows(ctx, projectFlockID, projectFlockKandangID, flagNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return deliveryProducts, nil
|
||||
return r.fetchClosingDeliveryProducts(ctx, attributionRows, projectFlockKandangID)
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error) {
|
||||
@@ -219,12 +132,199 @@ func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingProductID(ctx con
|
||||
return &deliveryProduct, nil
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetAttributionRowsByDeliveryProductIDs(ctx context.Context, deliveryProductIDs []uint) ([]commonRepo.MarketingDeliveryAttributionRow, error) {
|
||||
if len(deliveryProductIDs) == 0 {
|
||||
return []commonRepo.MarketingDeliveryAttributionRow{}, nil
|
||||
}
|
||||
|
||||
var rows []commonRepo.MarketingDeliveryAttributionRow
|
||||
query := r.DB().WithContext(ctx).
|
||||
Table("(?) AS mda", commonRepo.MarketingDeliveryAttributionRowsQuery(r.DB().WithContext(ctx))).
|
||||
Where("mda.marketing_delivery_product_id IN ?", deliveryProductIDs).
|
||||
Order("mda.marketing_delivery_product_id ASC, mda.project_flock_kandang_id ASC")
|
||||
|
||||
if err := query.Scan(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) getClosingAttributionRows(
|
||||
ctx context.Context,
|
||||
projectFlockID uint,
|
||||
projectFlockKandangID *uint,
|
||||
flagNames []string,
|
||||
) ([]commonRepo.MarketingDeliveryAttributionRow, error) {
|
||||
var rows []commonRepo.MarketingDeliveryAttributionRow
|
||||
|
||||
attributionQuery := commonRepo.MarketingDeliveryAttributionRowsQuery(r.DB().WithContext(ctx))
|
||||
query := r.DB().WithContext(ctx).
|
||||
Table("(?) AS mda", attributionQuery).
|
||||
Joins("JOIN marketing_delivery_products mdp ON mdp.id = mda.marketing_delivery_product_id").
|
||||
Joins("JOIN marketing_products mp ON mp.id = mdp.marketing_product_id").
|
||||
Joins("JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id").
|
||||
Joins("JOIN products prod ON prod.id = pw.product_id").
|
||||
Where("mda.project_flock_id = ?", projectFlockID).
|
||||
Where("mdp.delivery_date IS NOT NULL")
|
||||
|
||||
if projectFlockKandangID != nil {
|
||||
query = query.Where("mda.project_flock_kandang_id = ?", *projectFlockKandangID)
|
||||
}
|
||||
if len(flagNames) > 0 {
|
||||
query = query.
|
||||
Joins("JOIN flags f ON f.flagable_id = prod.id AND f.flagable_type = ?", entity.FlagableTypeProduct).
|
||||
Where("f.name IN ?", flagNames)
|
||||
}
|
||||
|
||||
query = query.
|
||||
Select(`
|
||||
mda.marketing_delivery_product_id,
|
||||
mda.project_flock_kandang_id,
|
||||
mda.project_flock_id,
|
||||
mda.project_flock_category,
|
||||
SUM(mda.allocated_qty) AS allocated_qty
|
||||
`).
|
||||
Group(`
|
||||
mda.marketing_delivery_product_id,
|
||||
mda.project_flock_kandang_id,
|
||||
mda.project_flock_id,
|
||||
mda.project_flock_category
|
||||
`).
|
||||
Order("mda.marketing_delivery_product_id ASC, mda.project_flock_kandang_id ASC")
|
||||
|
||||
if err := query.Scan(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) fetchClosingDeliveryProducts(
|
||||
ctx context.Context,
|
||||
attributionRows []commonRepo.MarketingDeliveryAttributionRow,
|
||||
projectFlockKandangID *uint,
|
||||
) ([]entity.MarketingDeliveryProduct, error) {
|
||||
deliveryIDs := orderedDeliveryProductIDs(attributionRows)
|
||||
if len(deliveryIDs) == 0 {
|
||||
return []entity.MarketingDeliveryProduct{}, nil
|
||||
}
|
||||
|
||||
query := r.closingDeliveryProductsQuery(ctx).
|
||||
Where("marketing_delivery_products.id IN ?", deliveryIDs).
|
||||
Order("marketing_delivery_products.delivery_date DESC")
|
||||
|
||||
if projectFlockKandangID == nil {
|
||||
query = query.Joins(
|
||||
"LEFT JOIN (?) AS mda_single ON mda_single.marketing_delivery_product_id = marketing_delivery_products.id",
|
||||
commonRepo.MarketingDeliverySingleAttributionQuery(r.DB().WithContext(ctx)),
|
||||
).Select("marketing_delivery_products.*, mda_single.attributed_project_flock_kandang_id")
|
||||
}
|
||||
|
||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||
if err := query.Find(&deliveryProducts).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if projectFlockKandangID == nil {
|
||||
return deliveryProducts, nil
|
||||
}
|
||||
|
||||
return scaleDeliveryProductsByAttribution(deliveryProducts, attributionRows, *projectFlockKandangID), nil
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) closingDeliveryProductsQuery(ctx context.Context) *gorm.DB {
|
||||
return r.DB().WithContext(ctx).
|
||||
Model(&entity.MarketingDeliveryProduct{}).
|
||||
Preload("MarketingProduct").
|
||||
Preload("MarketingProduct.ProductWarehouse").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.ProductCategory").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.Uom").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product.Flags").
|
||||
Preload("MarketingProduct.ProductWarehouse.Warehouse").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.ProjectFlock").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang").
|
||||
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Chickins").
|
||||
Preload("MarketingProduct.Marketing").
|
||||
Preload("MarketingProduct.Marketing.Customer").
|
||||
Preload("AttributedProjectFlockKandang").
|
||||
Preload("AttributedProjectFlockKandang.ProjectFlock").
|
||||
Preload("AttributedProjectFlockKandang.Kandang").
|
||||
Preload("AttributedProjectFlockKandang.Chickins")
|
||||
}
|
||||
|
||||
func orderedDeliveryProductIDs(rows []commonRepo.MarketingDeliveryAttributionRow) []uint {
|
||||
seen := make(map[uint]struct{}, len(rows))
|
||||
ids := make([]uint, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
if row.MarketingDeliveryProductID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[row.MarketingDeliveryProductID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[row.MarketingDeliveryProductID] = struct{}{}
|
||||
ids = append(ids, row.MarketingDeliveryProductID)
|
||||
}
|
||||
sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] })
|
||||
return ids
|
||||
}
|
||||
|
||||
func scaleDeliveryProductsByAttribution(
|
||||
deliveryProducts []entity.MarketingDeliveryProduct,
|
||||
rows []commonRepo.MarketingDeliveryAttributionRow,
|
||||
projectFlockKandangID uint,
|
||||
) []entity.MarketingDeliveryProduct {
|
||||
if len(deliveryProducts) == 0 || projectFlockKandangID == 0 {
|
||||
return deliveryProducts
|
||||
}
|
||||
|
||||
totalByDelivery := make(map[uint]float64, len(rows))
|
||||
selectedByDelivery := make(map[uint]float64, len(rows))
|
||||
for _, row := range rows {
|
||||
totalByDelivery[row.MarketingDeliveryProductID] += row.AllocatedQty
|
||||
if row.ProjectFlockKandangID == projectFlockKandangID {
|
||||
selectedByDelivery[row.MarketingDeliveryProductID] += row.AllocatedQty
|
||||
}
|
||||
}
|
||||
|
||||
filtered := make([]entity.MarketingDeliveryProduct, 0, len(deliveryProducts))
|
||||
for _, delivery := range deliveryProducts {
|
||||
selectedQty := selectedByDelivery[delivery.Id]
|
||||
totalQty := totalByDelivery[delivery.Id]
|
||||
if selectedQty <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
share := 1.0
|
||||
if totalQty > 0 {
|
||||
share = selectedQty / totalQty
|
||||
}
|
||||
|
||||
cloned := delivery
|
||||
cloned.AttributedProjectFlockKandangId = &projectFlockKandangID
|
||||
cloned.UsageQty = selectedQty
|
||||
cloned.PendingQty = 0
|
||||
cloned.TotalWeight = delivery.TotalWeight * share
|
||||
cloned.TotalPrice = delivery.TotalPrice * share
|
||||
filtered = append(filtered, cloned)
|
||||
}
|
||||
|
||||
return filtered
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetAllWithFilters(ctx context.Context, offset, limit int, filters *validation.MarketingQuery) ([]entity.MarketingDeliveryProduct, int64, error) {
|
||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||
var total int64
|
||||
|
||||
baseDB := r.DB().WithContext(ctx)
|
||||
singleAttributionQuery := commonRepo.MarketingDeliverySingleAttributionQuery(baseDB)
|
||||
db := r.DB().WithContext(ctx).
|
||||
Model(&entity.MarketingDeliveryProduct{}).
|
||||
Select("marketing_delivery_products.*, mda_single.attributed_project_flock_kandang_id").
|
||||
Joins("LEFT JOIN (?) AS mda_single ON mda_single.marketing_delivery_product_id = marketing_delivery_products.id", singleAttributionQuery).
|
||||
Preload("MarketingProduct", func(db *gorm.DB) *gorm.DB {
|
||||
return db.
|
||||
Preload("Marketing").
|
||||
@@ -237,6 +337,9 @@ func (r *MarketingDeliveryProductRepositoryImpl) GetAllWithFilters(ctx context.C
|
||||
Preload("ProductWarehouse.ProjectFlockKandang").
|
||||
Preload("ProductWarehouse.ProjectFlockKandang.ProjectFlock")
|
||||
}).
|
||||
Preload("AttributedProjectFlockKandang").
|
||||
Preload("AttributedProjectFlockKandang.ProjectFlock").
|
||||
Preload("AttributedProjectFlockKandang.Kandang").
|
||||
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||
Joins("JOIN marketings ON marketings.id = marketing_products.marketing_id").
|
||||
Where("marketing_delivery_products.delivery_date IS NOT NULL")
|
||||
@@ -292,22 +395,27 @@ func (r *MarketingDeliveryProductRepositoryImpl) GetAllWithFilters(ctx context.C
|
||||
}
|
||||
|
||||
if filters.AreaId > 0 || filters.LocationId > 0 || filters.AllowedAreaIDs != nil || filters.AllowedLocationIDs != nil {
|
||||
db = db.Joins("LEFT JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id").
|
||||
Joins("LEFT JOIN project_flocks ON project_flocks.id = project_flock_kandangs.project_flock_id")
|
||||
|
||||
buildAttrFilter := func() *gorm.DB {
|
||||
return r.DB().WithContext(ctx).
|
||||
Table("(?) AS mda", commonRepo.MarketingDeliveryAttributionRowsQuery(r.DB().WithContext(ctx))).
|
||||
Select("1").
|
||||
Joins("JOIN project_flock_kandangs pfk ON pfk.id = mda.project_flock_kandang_id").
|
||||
Joins("JOIN project_flocks pf ON pf.id = pfk.project_flock_id").
|
||||
Where("mda.marketing_delivery_product_id = marketing_delivery_products.id")
|
||||
}
|
||||
if filters.AreaId > 0 {
|
||||
db = db.Where("project_flocks.area_id = ?", filters.AreaId)
|
||||
db = db.Where("EXISTS (?)", buildAttrFilter().Where("pf.area_id = ?", filters.AreaId))
|
||||
}
|
||||
|
||||
if filters.LocationId > 0 {
|
||||
db = db.Where("project_flocks.location_id = ?", filters.LocationId)
|
||||
db = db.Where("EXISTS (?)", buildAttrFilter().Where("pf.location_id = ?", filters.LocationId))
|
||||
}
|
||||
|
||||
if filters.AllowedAreaIDs != nil {
|
||||
if len(filters.AllowedAreaIDs) == 0 {
|
||||
db = db.Where("1 = 0")
|
||||
} else {
|
||||
db = db.Where("project_flocks.area_id IN ?", filters.AllowedAreaIDs)
|
||||
db = db.Where("EXISTS (?)", buildAttrFilter().Where("pf.area_id IN ?", filters.AllowedAreaIDs))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,7 +423,7 @@ func (r *MarketingDeliveryProductRepositoryImpl) GetAllWithFilters(ctx context.C
|
||||
if len(filters.AllowedLocationIDs) == 0 {
|
||||
db = db.Where("1 = 0")
|
||||
} else {
|
||||
db = db.Where("project_flocks.location_id IN ?", filters.AllowedLocationIDs)
|
||||
db = db.Where("EXISTS (?)", buildAttrFilter().Where("pf.location_id IN ?", filters.AllowedLocationIDs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
)
|
||||
|
||||
func TestScaleDeliveryProductsByAttribution(t *testing.T) {
|
||||
projectFlockKandangID := uint(101)
|
||||
|
||||
deliveryProducts := []entity.MarketingDeliveryProduct{
|
||||
{
|
||||
Id: 55,
|
||||
UsageQty: 100,
|
||||
TotalWeight: 180,
|
||||
TotalPrice: 3600,
|
||||
},
|
||||
}
|
||||
attributionRows := []commonRepo.MarketingDeliveryAttributionRow{
|
||||
{MarketingDeliveryProductID: 55, ProjectFlockKandangID: 101, AllocatedQty: 60},
|
||||
{MarketingDeliveryProductID: 55, ProjectFlockKandangID: 102, AllocatedQty: 40},
|
||||
}
|
||||
|
||||
got := scaleDeliveryProductsByAttribution(deliveryProducts, attributionRows, projectFlockKandangID)
|
||||
if len(got) != 1 {
|
||||
t.Fatalf("expected 1 scaled delivery, got %d", len(got))
|
||||
}
|
||||
if got[0].UsageQty != 60 {
|
||||
t.Fatalf("expected usage qty 60, got %.2f", got[0].UsageQty)
|
||||
}
|
||||
if got[0].TotalWeight != 108 {
|
||||
t.Fatalf("expected total weight 108, got %.2f", got[0].TotalWeight)
|
||||
}
|
||||
if got[0].TotalPrice != 2160 {
|
||||
t.Fatalf("expected total price 2160, got %.2f", got[0].TotalPrice)
|
||||
}
|
||||
if got[0].AttributedProjectFlockKandangId == nil || *got[0].AttributedProjectFlockKandangId != projectFlockKandangID {
|
||||
t.Fatalf("expected attributed kandang id %d, got %+v", projectFlockKandangID, got[0].AttributedProjectFlockKandangId)
|
||||
}
|
||||
}
|
||||
@@ -643,6 +643,11 @@ func (s deliveryOrdersService) releaseDeliveryStock(ctx context.Context, tx *gor
|
||||
return nil
|
||||
}
|
||||
|
||||
affectedKandangIDs, err := s.marketingPopulationKandangIDsFromActiveAllocations(ctx, tx, deliveryProduct.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deliveryProduct.UsageQty = 0
|
||||
deliveryProduct.PendingQty = 0
|
||||
if err := deliveryProductRepo.UpdateOne(ctx, deliveryProduct.Id, deliveryProduct, nil); err != nil {
|
||||
@@ -670,6 +675,9 @@ func (s deliveryOrdersService) releaseDeliveryStock(ctx context.Context, tx *gor
|
||||
if err := fifoV2.ReleasePopulationConsumptionByUsable(ctx, tx, fifo.UsableKeyMarketingDelivery.String(), deliveryProduct.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.resyncPopulationUsageByKandangIDs(ctx, tx, affectedKandangIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
releasedUsage := currentUsage - deliveryProduct.UsageQty
|
||||
if actorID > 0 && releasedUsage > 0 {
|
||||
@@ -725,29 +733,378 @@ func (s deliveryOrdersService) allocatePopulationForMarketingDelivery(
|
||||
return nil
|
||||
}
|
||||
|
||||
pw, err := s.ProductWarehouseRepo.WithTx(tx).GetByID(ctx, productWarehouseID, nil)
|
||||
exactAllocations, err := s.findDirectPopulationAllocationsForMarketing(ctx, tx, deliveryProduct.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if pw.ProjectFlockKandangId == nil || *pw.ProjectFlockKandangId == 0 {
|
||||
if len(exactAllocations) > 0 {
|
||||
if err := fifoV2.ReleasePopulationConsumptionByUsable(ctx, tx, fifo.UsableKeyMarketingDelivery.String(), deliveryProduct.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.applyDirectPopulationAllocationsForMarketing(ctx, tx, productWarehouseID, deliveryProduct.Id, exactAllocations); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.resyncPopulationUsageByKandangIDs(ctx, tx, marketingAllocationKandangIDs(exactAllocations))
|
||||
}
|
||||
|
||||
sourceGroups, err := s.findPopulationSourceGroupsForMarketing(ctx, tx, deliveryProduct.Id, productWarehouseID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(sourceGroups) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
populations, err := s.ProjectFlockPopulationRepo.WithTx(tx).GetByProjectFlockKandangIDAndProductWarehouseID(ctx, *pw.ProjectFlockKandangId, productWarehouseID)
|
||||
if err != nil {
|
||||
if err := fifoV2.ReleasePopulationConsumptionByUsable(ctx, tx, fifo.UsableKeyMarketingDelivery.String(), deliveryProduct.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(populations) == 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Populasi tidak ditemukan untuk delivery")
|
||||
for _, group := range sourceGroups {
|
||||
populations, err := s.ProjectFlockPopulationRepo.WithTx(tx).GetByProjectFlockKandangIDAndProductWarehouseID(
|
||||
ctx,
|
||||
group.ProjectFlockKandangID,
|
||||
group.ProductWarehouseID,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(populations) == 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Populasi tidak ditemukan untuk delivery")
|
||||
}
|
||||
if err := s.allocatePopulationConsumptionWithoutRelease(
|
||||
ctx,
|
||||
tx,
|
||||
populations,
|
||||
productWarehouseID,
|
||||
deliveryProduct.Id,
|
||||
group.Qty,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return s.resyncPopulationUsageByKandangIDs(ctx, tx, marketingSourceGroupKandangIDs(sourceGroups))
|
||||
}
|
||||
|
||||
type marketingPopulationAllocation struct {
|
||||
ProjectFlockPopulationID uint `gorm:"column:project_flock_population_id"`
|
||||
ProjectFlockKandangID uint `gorm:"column:project_flock_kandang_id"`
|
||||
Qty float64 `gorm:"column:qty"`
|
||||
}
|
||||
|
||||
type marketingPopulationSourceGroup struct {
|
||||
ProjectFlockKandangID uint `gorm:"column:project_flock_kandang_id"`
|
||||
ProductWarehouseID uint `gorm:"column:product_warehouse_id"`
|
||||
Qty float64 `gorm:"column:qty"`
|
||||
}
|
||||
|
||||
func (s deliveryOrdersService) findDirectPopulationAllocationsForMarketing(
|
||||
ctx context.Context,
|
||||
tx *gorm.DB,
|
||||
deliveryProductID uint,
|
||||
) ([]marketingPopulationAllocation, error) {
|
||||
var rows []marketingPopulationAllocation
|
||||
err := tx.WithContext(ctx).
|
||||
Table("stock_allocations sa").
|
||||
Select(`
|
||||
pfp.id AS project_flock_population_id,
|
||||
pc.project_flock_kandang_id AS project_flock_kandang_id,
|
||||
SUM(sa.qty) AS qty
|
||||
`).
|
||||
Joins("JOIN project_flock_populations pfp ON pfp.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyProjectFlockPopulation.String()).
|
||||
Joins("JOIN project_chickins pc ON pc.id = pfp.project_chickin_id").
|
||||
Where("sa.usable_type = ? AND sa.usable_id = ? AND sa.status = ? AND sa.allocation_purpose = ?",
|
||||
fifo.UsableKeyMarketingDelivery.String(),
|
||||
deliveryProductID,
|
||||
entity.StockAllocationStatusActive,
|
||||
entity.StockAllocationPurposeConsume,
|
||||
).
|
||||
Group("pfp.id, pc.project_flock_kandang_id").
|
||||
Order("pfp.id ASC").
|
||||
Scan(&rows).Error
|
||||
return rows, err
|
||||
}
|
||||
|
||||
func (s deliveryOrdersService) findPopulationSourceGroupsForMarketing(
|
||||
ctx context.Context,
|
||||
tx *gorm.DB,
|
||||
deliveryProductID uint,
|
||||
productWarehouseID uint,
|
||||
) ([]marketingPopulationSourceGroup, error) {
|
||||
groups := make(map[string]marketingPopulationSourceGroup)
|
||||
|
||||
appendGroup := func(projectFlockKandangID uint, sourceProductWarehouseID uint, qty float64) {
|
||||
if projectFlockKandangID == 0 || sourceProductWarehouseID == 0 || qty <= 0 {
|
||||
return
|
||||
}
|
||||
key := fmt.Sprintf("%d:%d", projectFlockKandangID, sourceProductWarehouseID)
|
||||
current := groups[key]
|
||||
current.ProjectFlockKandangID = projectFlockKandangID
|
||||
current.ProductWarehouseID = sourceProductWarehouseID
|
||||
current.Qty += qty
|
||||
groups[key] = current
|
||||
}
|
||||
|
||||
return fifoV2.AllocatePopulationConsumption(
|
||||
ctx,
|
||||
tx,
|
||||
populations,
|
||||
productWarehouseID,
|
||||
fifo.UsableKeyMarketingDelivery.String(),
|
||||
deliveryProduct.Id,
|
||||
deliveryProduct.UsageQty,
|
||||
)
|
||||
var transferRows []marketingPopulationSourceGroup
|
||||
if err := tx.WithContext(ctx).
|
||||
Table("stock_allocations sa").
|
||||
Select(`
|
||||
source_pw.project_flock_kandang_id AS project_flock_kandang_id,
|
||||
std.source_product_warehouse_id AS product_warehouse_id,
|
||||
SUM(sa.qty) AS qty
|
||||
`).
|
||||
Joins("JOIN stock_transfer_details std ON std.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyStockTransferIn.String()).
|
||||
Joins("JOIN product_warehouses source_pw ON source_pw.id = std.source_product_warehouse_id").
|
||||
Where("sa.usable_type = ? AND sa.usable_id = ? AND sa.status = ? AND sa.allocation_purpose = ?",
|
||||
fifo.UsableKeyMarketingDelivery.String(),
|
||||
deliveryProductID,
|
||||
entity.StockAllocationStatusActive,
|
||||
entity.StockAllocationPurposeConsume,
|
||||
).
|
||||
Where("source_pw.project_flock_kandang_id IS NOT NULL").
|
||||
Group("source_pw.project_flock_kandang_id, std.source_product_warehouse_id").
|
||||
Scan(&transferRows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range transferRows {
|
||||
appendGroup(row.ProjectFlockKandangID, row.ProductWarehouseID, row.Qty)
|
||||
}
|
||||
|
||||
var purchaseRows []marketingPopulationSourceGroup
|
||||
if err := tx.WithContext(ctx).
|
||||
Table("stock_allocations sa").
|
||||
Select(`
|
||||
pi.project_flock_kandang_id AS project_flock_kandang_id,
|
||||
pi.product_warehouse_id AS product_warehouse_id,
|
||||
SUM(sa.qty) AS qty
|
||||
`).
|
||||
Joins("JOIN purchase_items pi ON pi.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyPurchaseItems.String()).
|
||||
Where("sa.usable_type = ? AND sa.usable_id = ? AND sa.status = ? AND sa.allocation_purpose = ?",
|
||||
fifo.UsableKeyMarketingDelivery.String(),
|
||||
deliveryProductID,
|
||||
entity.StockAllocationStatusActive,
|
||||
entity.StockAllocationPurposeConsume,
|
||||
).
|
||||
Where("pi.project_flock_kandang_id IS NOT NULL").
|
||||
Where("pi.product_warehouse_id IS NOT NULL").
|
||||
Group("pi.project_flock_kandang_id, pi.product_warehouse_id").
|
||||
Scan(&purchaseRows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range purchaseRows {
|
||||
appendGroup(row.ProjectFlockKandangID, row.ProductWarehouseID, row.Qty)
|
||||
}
|
||||
|
||||
var layingRows []marketingPopulationSourceGroup
|
||||
if err := tx.WithContext(ctx).
|
||||
Table("stock_allocations sa").
|
||||
Select(`
|
||||
ltt.target_project_flock_kandang_id AS project_flock_kandang_id,
|
||||
ltt.product_warehouse_id AS product_warehouse_id,
|
||||
SUM(sa.qty) AS qty
|
||||
`).
|
||||
Joins("JOIN laying_transfer_targets ltt ON ltt.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyTransferToLayingIn.String()).
|
||||
Where("sa.usable_type = ? AND sa.usable_id = ? AND sa.status = ? AND sa.allocation_purpose = ?",
|
||||
fifo.UsableKeyMarketingDelivery.String(),
|
||||
deliveryProductID,
|
||||
entity.StockAllocationStatusActive,
|
||||
entity.StockAllocationPurposeConsume,
|
||||
).
|
||||
Where("ltt.product_warehouse_id IS NOT NULL").
|
||||
Group("ltt.target_project_flock_kandang_id, ltt.product_warehouse_id").
|
||||
Scan(&layingRows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range layingRows {
|
||||
appendGroup(row.ProjectFlockKandangID, row.ProductWarehouseID, row.Qty)
|
||||
}
|
||||
|
||||
if len(groups) == 0 {
|
||||
pw, err := s.ProductWarehouseRepo.WithTx(tx).GetByID(ctx, productWarehouseID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if pw.ProjectFlockKandangId != nil && *pw.ProjectFlockKandangId != 0 {
|
||||
appendGroup(*pw.ProjectFlockKandangId, productWarehouseID, 0)
|
||||
}
|
||||
}
|
||||
|
||||
result := make([]marketingPopulationSourceGroup, 0, len(groups))
|
||||
for _, group := range groups {
|
||||
if group.Qty == 0 {
|
||||
group.Qty = s.resolveMarketingRequestedUsageQty(ctx, tx, deliveryProductID)
|
||||
}
|
||||
if group.Qty > 0 {
|
||||
result = append(result, group)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s deliveryOrdersService) applyDirectPopulationAllocationsForMarketing(
|
||||
ctx context.Context,
|
||||
tx *gorm.DB,
|
||||
productWarehouseID uint,
|
||||
deliveryProductID uint,
|
||||
allocations []marketingPopulationAllocation,
|
||||
) error {
|
||||
stockAllocationRepo := commonRepo.NewStockAllocationRepository(tx)
|
||||
for _, allocation := range allocations {
|
||||
if allocation.ProjectFlockPopulationID == 0 || allocation.Qty <= 0 {
|
||||
continue
|
||||
}
|
||||
record := &entity.StockAllocation{
|
||||
ProductWarehouseId: productWarehouseID,
|
||||
StockableType: fifo.StockableKeyProjectFlockPopulation.String(),
|
||||
StockableId: allocation.ProjectFlockPopulationID,
|
||||
UsableType: fifo.UsableKeyMarketingDelivery.String(),
|
||||
UsableId: deliveryProductID,
|
||||
Qty: allocation.Qty,
|
||||
Status: entity.StockAllocationStatusActive,
|
||||
AllocationPurpose: entity.StockAllocationPurposeConsume,
|
||||
}
|
||||
if err := stockAllocationRepo.CreateOne(ctx, record, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.WithContext(ctx).
|
||||
Model(&entity.ProjectFlockPopulation{}).
|
||||
Where("id = ?", allocation.ProjectFlockPopulationID).
|
||||
Update("total_used_qty", gorm.Expr("total_used_qty + ?", allocation.Qty)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s deliveryOrdersService) allocatePopulationConsumptionWithoutRelease(
|
||||
ctx context.Context,
|
||||
tx *gorm.DB,
|
||||
populations []entity.ProjectFlockPopulation,
|
||||
productWarehouseID uint,
|
||||
deliveryProductID uint,
|
||||
consumeQty float64,
|
||||
) error {
|
||||
if consumeQty <= 0 {
|
||||
return nil
|
||||
}
|
||||
remaining := consumeQty
|
||||
stockAllocationRepo := commonRepo.NewStockAllocationRepository(tx)
|
||||
for _, population := range populations {
|
||||
available := population.TotalQty - population.TotalUsedQty
|
||||
if available <= 0 {
|
||||
continue
|
||||
}
|
||||
portion := available
|
||||
if remaining < portion {
|
||||
portion = remaining
|
||||
}
|
||||
if portion <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
record := &entity.StockAllocation{
|
||||
ProductWarehouseId: productWarehouseID,
|
||||
StockableType: fifo.StockableKeyProjectFlockPopulation.String(),
|
||||
StockableId: population.Id,
|
||||
UsableType: fifo.UsableKeyMarketingDelivery.String(),
|
||||
UsableId: deliveryProductID,
|
||||
Qty: portion,
|
||||
Status: entity.StockAllocationStatusActive,
|
||||
AllocationPurpose: entity.StockAllocationPurposeConsume,
|
||||
}
|
||||
if err := stockAllocationRepo.CreateOne(ctx, record, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.WithContext(ctx).
|
||||
Model(&entity.ProjectFlockPopulation{}).
|
||||
Where("id = ?", population.Id).
|
||||
Update("total_used_qty", gorm.Expr("total_used_qty + ?", portion)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remaining -= portion
|
||||
if remaining <= 0.000001 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if remaining > 0.000001 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Populasi tidak mencukupi")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s deliveryOrdersService) marketingPopulationKandangIDsFromActiveAllocations(
|
||||
ctx context.Context,
|
||||
tx *gorm.DB,
|
||||
deliveryProductID uint,
|
||||
) ([]uint, error) {
|
||||
var ids []uint
|
||||
err := tx.WithContext(ctx).
|
||||
Table("stock_allocations sa").
|
||||
Distinct("pc.project_flock_kandang_id").
|
||||
Joins("JOIN project_flock_populations pfp ON pfp.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyProjectFlockPopulation.String()).
|
||||
Joins("JOIN project_chickins pc ON pc.id = pfp.project_chickin_id").
|
||||
Where("sa.usable_type = ? AND sa.usable_id = ? AND sa.status = ? AND sa.allocation_purpose = ?",
|
||||
fifo.UsableKeyMarketingDelivery.String(),
|
||||
deliveryProductID,
|
||||
entity.StockAllocationStatusActive,
|
||||
entity.StockAllocationPurposeConsume,
|
||||
).
|
||||
Pluck("pc.project_flock_kandang_id", &ids).Error
|
||||
return ids, err
|
||||
}
|
||||
|
||||
func (s deliveryOrdersService) resyncPopulationUsageByKandangIDs(ctx context.Context, tx *gorm.DB, kandangIDs []uint) error {
|
||||
for _, kandangID := range uniqueUintIDs(kandangIDs) {
|
||||
if kandangID == 0 {
|
||||
continue
|
||||
}
|
||||
if err := s.ProjectFlockPopulationRepo.WithTx(tx).ResyncUsageByProjectFlockKandangID(ctx, tx, kandangID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s deliveryOrdersService) resolveMarketingRequestedUsageQty(ctx context.Context, tx *gorm.DB, deliveryProductID uint) float64 {
|
||||
var usageQty float64
|
||||
if err := tx.WithContext(ctx).
|
||||
Table("marketing_delivery_products").
|
||||
Select("usage_qty").
|
||||
Where("id = ?", deliveryProductID).
|
||||
Scan(&usageQty).Error; err != nil {
|
||||
return 0
|
||||
}
|
||||
return usageQty
|
||||
}
|
||||
|
||||
func marketingAllocationKandangIDs(rows []marketingPopulationAllocation) []uint {
|
||||
ids := make([]uint, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
ids = append(ids, row.ProjectFlockKandangID)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
func marketingSourceGroupKandangIDs(rows []marketingPopulationSourceGroup) []uint {
|
||||
ids := make([]uint, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
ids = append(ids, row.ProjectFlockKandangID)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
func uniqueUintIDs(ids []uint) []uint {
|
||||
seen := make(map[uint]struct{}, len(ids))
|
||||
result := make([]uint, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
result = append(result, id)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user