codex: initiated changes

This commit is contained in:
Adnan Zahir
2026-03-30 13:40:29 +07:00
parent d76f72050e
commit be00837148
22 changed files with 1762 additions and 328 deletions
@@ -44,6 +44,7 @@ type PenjualanRealisasiResponseDTO struct {
// === Mapper Functions ===
func ToSalesDTO(e entity.MarketingDeliveryProduct) SalesDTO {
projectFlockKandang := resolveMarketingDeliveryProjectFlockKandang(e)
productFlags := make([]string, len(e.MarketingProduct.ProductWarehouse.Product.Flags))
for i, f := range e.MarketingProduct.ProductWarehouse.Product.Flags {
@@ -51,11 +52,11 @@ func ToSalesDTO(e entity.MarketingDeliveryProduct) SalesDTO {
}
var category string
if e.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil {
category = e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.ProjectFlock.Category
if projectFlockKandang != nil {
category = projectFlockKandang.ProjectFlock.Category
}
ageInDay, ageInWeeks := calculateAgeFromChickin(e.MarketingProduct.ProductWarehouse.ProjectFlockKandang, e.DeliveryDate, productFlags, category)
ageInDay, ageInWeeks := calculateAgeFromChickin(projectFlockKandang, e.DeliveryDate, productFlags, category)
var product *productDTO.ProductRelationDTO
if e.MarketingProduct.ProductWarehouse.Product.Id != 0 {
@@ -70,8 +71,8 @@ func ToSalesDTO(e entity.MarketingDeliveryProduct) SalesDTO {
}
var kandang *kandangDTO.KandangRelationDTO
if e.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil && e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang.Id != 0 {
mapped := kandangDTO.ToKandangRelationDTO(e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang)
if projectFlockKandang != nil && projectFlockKandang.Kandang.Id != 0 {
mapped := kandangDTO.ToKandangRelationDTO(projectFlockKandang.Kandang)
kandang = &mapped
}
@@ -102,6 +103,7 @@ func ToSalesDTO(e entity.MarketingDeliveryProduct) SalesDTO {
}
func ToSalesAgeDTO(e entity.MarketingDeliveryProduct) SalesDTO {
projectFlockKandang := resolveMarketingDeliveryProjectFlockKandang(e)
productFlags := make([]string, len(e.MarketingProduct.ProductWarehouse.Product.Flags))
for i, f := range e.MarketingProduct.ProductWarehouse.Product.Flags {
@@ -109,11 +111,11 @@ func ToSalesAgeDTO(e entity.MarketingDeliveryProduct) SalesDTO {
}
var category string
if e.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil {
category = e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.ProjectFlock.Category
if projectFlockKandang != nil {
category = projectFlockKandang.ProjectFlock.Category
}
ageInDay, _ := calculateAgeFromChickin(e.MarketingProduct.ProductWarehouse.ProjectFlockKandang, e.DeliveryDate, productFlags, category)
ageInDay, _ := calculateAgeFromChickin(projectFlockKandang, e.DeliveryDate, productFlags, category)
return SalesDTO{
Age: ageInDay,
@@ -164,6 +166,13 @@ func ToPenjualanRealisasiResponseDTO(e []entity.MarketingDeliveryProduct) Penjua
}
}
func resolveMarketingDeliveryProjectFlockKandang(e entity.MarketingDeliveryProduct) *entity.ProjectFlockKandang {
if e.AttributedProjectFlockKandang != nil {
return e.AttributedProjectFlockKandang
}
return e.MarketingProduct.ProductWarehouse.ProjectFlockKandang
}
func calculateAgeFromChickin(projectFlockKandang *entity.ProjectFlockKandang, deliveryDate *time.Time, productFlags []string, category string) (int, int) {
if projectFlockKandang == nil || deliveryDate == nil || len(projectFlockKandang.Chickins) == 0 {
return 0, 0
@@ -298,10 +298,11 @@ func (r *ClosingRepositoryImpl) SumFeedPurchaseAndUsedByProjectFlockKandangIDs(c
err = r.DB().WithContext(ctx).
Table("recording_stocks rs").
Joins("JOIN recordings rec ON rec.id = rs.recording_id").
Joins("JOIN product_warehouses pw ON pw.id = rs.product_warehouse_id").
Joins("JOIN products prod ON prod.id = pw.product_id").
Joins("JOIN flags f ON f.flagable_id = prod.id AND f.flagable_type = ?", "products").
Where("pw.project_flock_kandang_id IN ?", projectFlockKandangIDs).
Where("rec.project_flock_kandangs_id IN ?", projectFlockKandangIDs).
Where("f.name = ?", "PAKAN").
Select("COALESCE(SUM(COALESCE(rs.usage_qty, 0) + COALESCE(rs.pending_qty, 0)), 0) AS total_used").
Scan(&usageAgg).Error
@@ -340,10 +341,11 @@ func (r *ClosingRepositoryImpl) SumClaimCullingByProjectFlockKandangIDs(ctx cont
err := r.DB().WithContext(ctx).
Table("recording_depletions rd").
Joins("JOIN recordings rec ON rec.id = rd.recording_id").
Joins("JOIN product_warehouses pw ON pw.id = rd.product_warehouse_id").
Joins("JOIN products prod ON prod.id = pw.product_id").
Joins("JOIN flags f ON f.flagable_id = prod.id AND f.flagable_type = ?", "products").
Where("pw.project_flock_kandang_id IN ?", projectFlockKandangIDs).
Where("COALESCE(rd.source_project_flock_kandang_id, rec.project_flock_kandangs_id) IN ?", projectFlockKandangIDs).
Where("f.name = ?", utils.FlagAyamCulling).
Select("COALESCE(SUM(rd.qty), 0) AS total_culling").
Scan(&agg).Error
@@ -358,52 +360,14 @@ func (r *ClosingRepositoryImpl) SumMarketingWeightAndQtyByProjectFlockKandangIDs
if len(projectFlockKandangIDs) == 0 {
return 0, 0, 0, nil
}
var agg struct {
TotalWeight float64 `gorm:"column:total_weight"`
TotalQty float64 `gorm:"column:total_qty"`
TotalPrice float64 `gorm:"column:total_price"`
}
err := r.DB().WithContext(ctx).
Table("marketing_products mp").
Joins("JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id").
Where("pw.project_flock_kandang_id IN ?", projectFlockKandangIDs).
Select("COALESCE(SUM(mp.total_weight), 0) AS total_weight, COALESCE(SUM(mp.qty), 0) AS total_qty, COALESCE(SUM(mp.total_price), 0) AS total_price").
Scan(&agg).Error
if err != nil {
return 0, 0, 0, err
}
return agg.TotalWeight, agg.TotalQty, agg.TotalPrice, nil
return r.sumMarketingAttributedByProjectFlockKandangIDs(ctx, projectFlockKandangIDs, nil)
}
func (r *ClosingRepositoryImpl) SumMarketingWeightAndQtyByProjectFlockKandangIDsAndFlagNames(ctx context.Context, projectFlockKandangIDs []uint, flagNames []string) (float64, float64, float64, error) {
if len(projectFlockKandangIDs) == 0 || len(flagNames) == 0 {
return 0, 0, 0, nil
}
var agg struct {
TotalWeight float64 `gorm:"column:total_weight"`
TotalQty float64 `gorm:"column:total_qty"`
TotalPrice float64 `gorm:"column:total_price"`
}
err := r.DB().WithContext(ctx).
Table("marketing_products mp").
Joins("JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id").
Joins("JOIN products prod ON prod.id = pw.product_id").
Joins("JOIN flags f ON f.flagable_id = prod.id AND f.flagable_type = ?", "products").
Joins("JOIN marketing_delivery_products mdp ON mdp.marketing_product_id = mp.id").
Where("pw.project_flock_kandang_id IN ?", projectFlockKandangIDs).
Where("f.name IN ?", flagNames).
Select("COALESCE(SUM(mdp.total_weight), 0) AS total_weight, COALESCE(SUM(mdp.usage_qty), 0) AS total_qty, COALESCE(SUM(mdp.total_price), 0) AS total_price").
Scan(&agg).Error
if err != nil {
return 0, 0, 0, err
}
return agg.TotalWeight, agg.TotalQty, agg.TotalPrice, nil
return r.sumMarketingAttributedByProjectFlockKandangIDs(ctx, projectFlockKandangIDs, flagNames)
}
func (r *ClosingRepositoryImpl) SumRecordingEggQtyByProjectFlockKandangIDsAndFlagNames(ctx context.Context, projectFlockKandangIDs []uint, flagNames []string) (float64, error) {
@@ -417,10 +381,11 @@ func (r *ClosingRepositoryImpl) SumRecordingEggQtyByProjectFlockKandangIDsAndFla
err := r.DB().WithContext(ctx).
Table("recording_eggs re").
Joins("JOIN recordings rec ON rec.id = re.recording_id").
Joins("JOIN product_warehouses pw ON pw.id = re.product_warehouse_id").
Joins("JOIN products prod ON prod.id = pw.product_id").
Joins("JOIN flags f ON f.flagable_id = prod.id AND f.flagable_type = ?", "products").
Where("pw.project_flock_kandang_id IN ?", projectFlockKandangIDs).
Where("COALESCE(re.project_flock_kandang_id, rec.project_flock_kandangs_id) IN ?", projectFlockKandangIDs).
Where("f.name IN ?", flagNames).
Select("COALESCE(SUM(re.qty), 0) AS total_qty").
Scan(&agg).Error
@@ -817,6 +782,52 @@ type SapronakDetailRow struct {
func (r *ClosingRepositoryImpl) withCtx(ctx context.Context) *gorm.DB { return r.DB().WithContext(ctx) }
func (r *ClosingRepositoryImpl) sumMarketingAttributedByProjectFlockKandangIDs(
ctx context.Context,
projectFlockKandangIDs []uint,
flagNames []string,
) (float64, float64, float64, error) {
var agg struct {
TotalWeight float64 `gorm:"column:total_weight"`
TotalQty float64 `gorm:"column:total_qty"`
TotalPrice float64 `gorm:"column:total_price"`
}
query := r.withCtx(ctx).
Table("(?) AS mda", repository.MarketingDeliveryAttributionRowsQuery(r.withCtx(ctx))).
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_kandang_id IN ?", projectFlockKandangIDs).
Where("mdp.delivery_date IS NOT NULL")
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)
}
err := query.
Select(`
COALESCE(SUM(CASE
WHEN COALESCE(mdp.usage_qty, 0) > 0 THEN mdp.total_weight * (mda.allocated_qty / mdp.usage_qty)
ELSE 0
END), 0) AS total_weight,
COALESCE(SUM(mda.allocated_qty), 0) AS total_qty,
COALESCE(SUM(CASE
WHEN COALESCE(mdp.usage_qty, 0) > 0 THEN mdp.total_price * (mda.allocated_qty / mdp.usage_qty)
ELSE 0
END), 0) AS total_price
`).
Scan(&agg).Error
if err != nil {
return 0, 0, 0, err
}
return agg.TotalWeight, agg.TotalQty, agg.TotalPrice, nil
}
func applyDateRange(db *gorm.DB, column string, start, end *time.Time) *gorm.DB {
if start != nil {
db = db.Where(column+"::date >= ?", start)
@@ -1453,6 +1464,16 @@ func (r *ClosingRepositoryImpl) FetchSapronakTransfers(ctx context.Context, kand
}
func (r *ClosingRepositoryImpl) FetchSapronakSales(ctx context.Context, projectFlockKandangID uint, start, end *time.Time) (map[uint][]SapronakDetailRow, error) {
attributedProjectFlockKandangExpr := `
COALESCE(
pc.project_flock_kandang_id,
pi.project_flock_kandang_id,
source_pw.project_flock_kandang_id,
ltt.target_project_flock_kandang_id,
pw.project_flock_kandang_id
)
`
query := r.withCtx(ctx).
Table("stock_allocations AS sa").
Select(`
@@ -1470,9 +1491,15 @@ func (r *ClosingRepositoryImpl) FetchSapronakSales(ctx context.Context, projectF
Joins("JOIN marketings m ON m.id = mp.marketing_id").
Joins("JOIN product_warehouses pw ON pw.id = sa.product_warehouse_id").
Joins("JOIN products p ON p.id = pw.product_id").
Joins("LEFT JOIN purchase_items pi ON pi.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyPurchaseItems.String()).
Joins("LEFT JOIN stock_transfer_details std ON std.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyStockTransferIn.String()).
Joins("LEFT JOIN product_warehouses source_pw ON source_pw.id = std.source_product_warehouse_id").
Joins("LEFT JOIN laying_transfer_targets ltt ON ltt.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyTransferToLayingIn.String()).
Joins("LEFT JOIN project_flock_populations pfp ON pfp.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyProjectFlockPopulation.String()).
Joins("LEFT JOIN project_chickins pc ON pc.id = pfp.project_chickin_id").
Where("sa.status = ?", entity.StockAllocationStatusActive).
Where("sa.allocation_purpose = ?", entity.StockAllocationPurposeConsume).
Where("pw.project_flock_kandang_id = ?", projectFlockKandangID).
Where(attributedProjectFlockKandangExpr+" = ?", projectFlockKandangID).
Where("f.name IN ?", sapronakFlagsAll).
Group("mdp.id, pw.product_id, p.name, f.name, mdp.delivery_date, mdp.created_at, m.so_number, mdp.unit_price, mp.unit_price")
@@ -1548,6 +1575,16 @@ func (r *ClosingRepositoryImpl) FetchSapronakSalesAllocatedDetails(ctx context.C
END
`, pfpType)
attributedProjectFlockKandangExpr := `
COALESCE(
pc.project_flock_kandang_id,
pi.project_flock_kandang_id,
source_pw.project_flock_kandang_id,
ltt.target_project_flock_kandang_id,
pw_sales.project_flock_kandang_id
)
`
query := r.withCtx(ctx).
Table("stock_allocations AS sa").
Select(fmt.Sprintf(`
@@ -1600,6 +1637,7 @@ func (r *ClosingRepositoryImpl) FetchSapronakSalesAllocatedDetails(ctx context.C
Joins("LEFT JOIN purchases po ON po.id = pi.purchase_id").
Joins("LEFT JOIN stock_transfer_details std ON std.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyStockTransferIn.String()).
Joins("LEFT JOIN stock_transfers st ON st.id = std.stock_transfer_id").
Joins("LEFT JOIN product_warehouses source_pw ON source_pw.id = std.source_product_warehouse_id").
Joins("LEFT JOIN laying_transfer_targets ltt ON ltt.id = sa.stockable_id AND sa.stockable_type = ?", fifo.StockableKeyTransferToLayingIn.String()).
Joins("LEFT JOIN laying_transfers lt ON lt.id = ltt.laying_transfer_id").
Joins("LEFT JOIN product_warehouses pw_ltt ON pw_ltt.id = ltt.product_warehouse_id").
@@ -1619,7 +1657,7 @@ func (r *ClosingRepositoryImpl) FetchSapronakSalesAllocatedDetails(ctx context.C
Where("sa.status = ?", entity.StockAllocationStatusActive).
Where("sa.allocation_purpose = ?", entity.StockAllocationPurposeConsume).
Where("sa.stockable_type <> ?", fifo.StockableKeyProjectFlockPopulation.String()).
Where("pw.project_flock_kandang_id = ?", projectFlockKandangID).
Where(attributedProjectFlockKandangExpr+" = ?", projectFlockKandangID).
Where("f.name IN ?", sapronakFlagsAll).
Group(`
p_resolve.id, p_resolve.name, f.name,