mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
add common service hpp v2; adjust query marketing without stock allocation
This commit is contained in:
@@ -0,0 +1,431 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
|
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||||
|
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HppV2CostRepository interface {
|
||||||
|
GetProjectFlockKandangIDs(ctx context.Context, projectFlockId uint) ([]uint, error)
|
||||||
|
GetFeedUsageCost(ctx context.Context, projectFlockKandangIDs []uint, date *time.Time) (float64, error)
|
||||||
|
GetTotalPopulation(ctx context.Context, projectFlockKandangIDs []uint) (float64, error)
|
||||||
|
GetEggProduksiPiecesAndWeightKgByProjectFlockKandangIds(ctx context.Context, projectFlockKandangIDs []uint, date *time.Time) (float64, float64, error)
|
||||||
|
GetEggTerjualPiecesAndWeightKgByProjectFlockKandangIds(ctx context.Context, projectFlockKandangIDs []uint, startDate *time.Time, endDate *time.Time) (float64, float64, error)
|
||||||
|
GetTransferSourceSummary(ctx context.Context, projectFlockKandangId uint) (uint, float64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type HppV2RepositoryImpl struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHppV2CostRepository(db *gorm.DB) HppV2CostRepository {
|
||||||
|
return &HppV2RepositoryImpl{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *HppV2RepositoryImpl) GetProjectFlockKandangIDs(ctx context.Context, projectFlockId uint) ([]uint, error) {
|
||||||
|
var ids []uint
|
||||||
|
err := r.db.WithContext(ctx).
|
||||||
|
Table("project_flock_kandangs").
|
||||||
|
Select("id").
|
||||||
|
Where("project_flock_id = ?", projectFlockId).
|
||||||
|
Scan(&ids).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *HppV2RepositoryImpl) GetFeedUsageCost(ctx context.Context, projectFlockKandangIDs []uint, date *time.Time) (float64, error) {
|
||||||
|
if date == nil {
|
||||||
|
now := time.Now()
|
||||||
|
date = &now
|
||||||
|
}
|
||||||
|
|
||||||
|
stockablePurchase := fifo.StockableKeyPurchaseItems.String()
|
||||||
|
stockableAdjustment := fifo.StockableKeyAdjustmentIn.String()
|
||||||
|
usableRecordingStock := fifo.UsableKeyRecordingStock.String()
|
||||||
|
|
||||||
|
var total float64
|
||||||
|
err := r.db.WithContext(ctx).
|
||||||
|
Table("recordings AS r").
|
||||||
|
Select(`
|
||||||
|
COALESCE(SUM(sa.qty * CASE
|
||||||
|
WHEN sa.stockable_type = ? THEN COALESCE(pi.price, 0)
|
||||||
|
WHEN sa.stockable_type = ? THEN COALESCE(ast.price, 0)
|
||||||
|
ELSE 0
|
||||||
|
END), 0)`,
|
||||||
|
stockablePurchase,
|
||||||
|
stockableAdjustment,
|
||||||
|
).
|
||||||
|
Joins("JOIN recording_stocks AS rs ON rs.recording_id = r.id").
|
||||||
|
Joins("JOIN product_warehouses AS pw ON pw.id = rs.product_warehouse_id").
|
||||||
|
Joins("JOIN flags AS f ON f.flagable_id = pw.product_id AND f.flagable_type = ?", entity.FlagableTypeProduct).
|
||||||
|
Joins(
|
||||||
|
"JOIN stock_allocations AS sa ON sa.usable_type = ? AND sa.usable_id = rs.id AND (sa.stockable_type = ? OR sa.stockable_type = ?) AND sa.status = ? AND sa.allocation_purpose = ?",
|
||||||
|
usableRecordingStock,
|
||||||
|
stockablePurchase,
|
||||||
|
stockableAdjustment,
|
||||||
|
entity.StockAllocationStatusActive,
|
||||||
|
entity.StockAllocationPurposeConsume,
|
||||||
|
).
|
||||||
|
Joins("LEFT JOIN purchase_items AS pi ON pi.id = sa.stockable_id AND sa.stockable_type = ?", stockablePurchase).
|
||||||
|
Joins("LEFT JOIN adjustment_stocks AS ast ON ast.id = sa.stockable_id AND sa.stockable_type = ?", stockableAdjustment).
|
||||||
|
Where("r.project_flock_kandangs_id IN (?)", projectFlockKandangIDs).
|
||||||
|
Where("r.record_datetime <= ?", *date).
|
||||||
|
Where("f.name = ?", utils.FlagPakan).
|
||||||
|
Scan(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *HppV2RepositoryImpl) GetTotalPopulation(ctx context.Context, projectFlockKandangIDs []uint) (float64, error) {
|
||||||
|
var total float64
|
||||||
|
err := r.db.WithContext(ctx).
|
||||||
|
Table("project_chickins AS pc").
|
||||||
|
Select("COALESCE(SUM(pc.usage_qty), 0)").
|
||||||
|
Where("pc.project_flock_kandang_id IN (?)", projectFlockKandangIDs).
|
||||||
|
Scan(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *HppV2RepositoryImpl) GetEggProduksiPiecesAndWeightKgByProjectFlockKandangIds(ctx context.Context, projectFlockKandangIDs []uint, date *time.Time) (float64, float64, error) {
|
||||||
|
if date == nil {
|
||||||
|
now := time.Now()
|
||||||
|
date = &now
|
||||||
|
}
|
||||||
|
|
||||||
|
var totals struct {
|
||||||
|
TotalPieces float64
|
||||||
|
TotalWeightKg float64
|
||||||
|
}
|
||||||
|
err := r.db.WithContext(ctx).
|
||||||
|
Table("recordings AS r").
|
||||||
|
Select("COALESCE(SUM(re.qty), 0) AS total_pieces, COALESCE(SUM(re.weight), 0)AS total_weight_kg").
|
||||||
|
Joins("JOIN recording_eggs AS re ON re.recording_id = r.id").
|
||||||
|
Where("r.project_flock_kandangs_id IN (?)", projectFlockKandangIDs).
|
||||||
|
Where("r.record_datetime <= ?", *date).
|
||||||
|
Scan(&totals).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var adjustmentTotalWeight float64
|
||||||
|
adjustmentSubQuery := r.db.WithContext(ctx).
|
||||||
|
Table("recordings AS r").
|
||||||
|
Select("DISTINCT ast.id AS adjustment_id, ast.price AS price").
|
||||||
|
Joins("JOIN recording_eggs AS re ON re.recording_id = r.id").
|
||||||
|
Joins("JOIN stock_transfer_details AS std ON std.dest_product_warehouse_id = re.product_warehouse_id").
|
||||||
|
Joins(
|
||||||
|
"JOIN stock_allocations AS sa ON sa.usable_type = ? AND sa.usable_id = std.id AND sa.stockable_type = ? AND sa.status = ? AND sa.allocation_purpose = ?",
|
||||||
|
fifo.UsableKeyStockTransferOut.String(),
|
||||||
|
fifo.StockableKeyAdjustmentIn.String(),
|
||||||
|
entity.StockAllocationStatusActive,
|
||||||
|
entity.StockAllocationPurposeConsume,
|
||||||
|
).
|
||||||
|
Joins("JOIN adjustment_stocks AS ast ON ast.id = sa.stockable_id AND ast.product_warehouse_id = std.source_product_warehouse_id").
|
||||||
|
Where("r.project_flock_kandangs_id IN (?)", projectFlockKandangIDs).
|
||||||
|
Where("r.record_datetime <= ?", *date)
|
||||||
|
|
||||||
|
err = r.db.WithContext(ctx).
|
||||||
|
Table("(?) AS adjustment_sources", adjustmentSubQuery).
|
||||||
|
Select("COALESCE(SUM(adjustment_sources.price), 0)").
|
||||||
|
Scan(&adjustmentTotalWeight).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
totals.TotalWeightKg += adjustmentTotalWeight
|
||||||
|
|
||||||
|
return totals.TotalPieces, totals.TotalWeightKg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *HppV2RepositoryImpl) GetEggTerjualPiecesAndWeightKgByProjectFlockKandangIds(
|
||||||
|
ctx context.Context,
|
||||||
|
projectFlockKandangIDs []uint,
|
||||||
|
startDate *time.Time,
|
||||||
|
endDate *time.Time,
|
||||||
|
) (float64, float64, error) {
|
||||||
|
if len(projectFlockKandangIDs) == 0 {
|
||||||
|
return 0, 0, nil
|
||||||
|
}
|
||||||
|
if endDate == nil {
|
||||||
|
now := time.Now()
|
||||||
|
endDate = &now
|
||||||
|
}
|
||||||
|
if startDate == nil {
|
||||||
|
startDate = endDate
|
||||||
|
}
|
||||||
|
|
||||||
|
eggFlags := []string{
|
||||||
|
string(utils.FlagTelur),
|
||||||
|
string(utils.FlagTelurUtuh),
|
||||||
|
string(utils.FlagTelurPecah),
|
||||||
|
string(utils.FlagTelurPutih),
|
||||||
|
string(utils.FlagTelurRetak),
|
||||||
|
string(utils.FlagTelurPapacal),
|
||||||
|
string(utils.FlagTelurJumbo),
|
||||||
|
}
|
||||||
|
|
||||||
|
query := `
|
||||||
|
WITH selected_pfk AS (
|
||||||
|
SELECT pfk.id, k.location_id
|
||||||
|
FROM project_flock_kandangs pfk
|
||||||
|
JOIN kandangs k ON k.id = pfk.kandang_id
|
||||||
|
WHERE pfk.id IN ?
|
||||||
|
),
|
||||||
|
selected_locations AS (
|
||||||
|
SELECT DISTINCT location_id
|
||||||
|
FROM selected_pfk
|
||||||
|
),
|
||||||
|
sales_kandang AS (
|
||||||
|
SELECT DISTINCT
|
||||||
|
mdp.id AS mdp_id,
|
||||||
|
COALESCE(mdp.usage_qty, 0) AS usage_qty,
|
||||||
|
COALESCE(mdp.total_weight, 0) AS total_weight
|
||||||
|
FROM marketing_delivery_products mdp
|
||||||
|
JOIN marketing_products mp ON mp.id = mdp.marketing_product_id
|
||||||
|
JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id
|
||||||
|
JOIN warehouses w ON w.id = pw.warehouse_id
|
||||||
|
WHERE mdp.delivery_date IS NOT NULL
|
||||||
|
AND mdp.delivery_date <= ?
|
||||||
|
AND UPPER(COALESCE(w.type, '')) = 'KANDANG'
|
||||||
|
AND pw.project_flock_kandang_id IN (SELECT id FROM selected_pfk)
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM recording_eggs re
|
||||||
|
JOIN recordings rr ON rr.id = re.recording_id
|
||||||
|
WHERE re.product_warehouse_id = mp.product_warehouse_id
|
||||||
|
AND COALESCE(re.project_flock_kandang_id, rr.project_flock_kandangs_id) IN (SELECT id FROM selected_pfk)
|
||||||
|
AND rr.deleted_at IS NULL
|
||||||
|
AND DATE(rr.record_datetime) <= DATE(mdp.delivery_date)
|
||||||
|
)
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM flags f
|
||||||
|
WHERE f.flagable_type = ?
|
||||||
|
AND f.flagable_id = pw.product_id
|
||||||
|
AND f.name IN ?
|
||||||
|
)
|
||||||
|
),
|
||||||
|
sales_lokasi AS (
|
||||||
|
SELECT DISTINCT
|
||||||
|
mdp.id AS mdp_id,
|
||||||
|
COALESCE(mdp.usage_qty, 0) AS usage_qty,
|
||||||
|
COALESCE(mdp.total_weight, 0) AS total_weight,
|
||||||
|
mdp.delivery_date AS delivery_date,
|
||||||
|
pw.id AS lokasi_pw_id,
|
||||||
|
pw.product_id AS product_id,
|
||||||
|
w.location_id AS location_id
|
||||||
|
FROM marketing_delivery_products mdp
|
||||||
|
JOIN marketing_products mp ON mp.id = mdp.marketing_product_id
|
||||||
|
JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id
|
||||||
|
JOIN warehouses w ON w.id = pw.warehouse_id
|
||||||
|
WHERE mdp.delivery_date IS NOT NULL
|
||||||
|
AND mdp.delivery_date <= ?
|
||||||
|
AND UPPER(COALESCE(w.type, '')) = 'LOKASI'
|
||||||
|
AND w.location_id IN (SELECT location_id FROM selected_locations)
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM flags f
|
||||||
|
WHERE f.flagable_type = ?
|
||||||
|
AND f.flagable_id = pw.product_id
|
||||||
|
AND f.name IN ?
|
||||||
|
)
|
||||||
|
),
|
||||||
|
transfer_pairs AS (
|
||||||
|
SELECT
|
||||||
|
std.source_product_warehouse_id AS source_pw_id,
|
||||||
|
std.dest_product_warehouse_id AS dest_pw_id,
|
||||||
|
MIN(st.transfer_date) AS first_transfer_date
|
||||||
|
FROM stock_transfer_details std
|
||||||
|
JOIN stock_transfers st ON st.id = std.stock_transfer_id
|
||||||
|
WHERE std.source_product_warehouse_id IS NOT NULL
|
||||||
|
AND std.dest_product_warehouse_id IS NOT NULL
|
||||||
|
GROUP BY std.source_product_warehouse_id, std.dest_product_warehouse_id
|
||||||
|
),
|
||||||
|
adj_pool AS (
|
||||||
|
SELECT
|
||||||
|
sl.mdp_id,
|
||||||
|
SUM(CASE
|
||||||
|
WHEN spw.project_flock_kandang_id IN (SELECT id FROM selected_pfk)
|
||||||
|
THEN COALESCE(ast.usage_qty, 0)
|
||||||
|
ELSE 0
|
||||||
|
END) AS sel_usage_qty,
|
||||||
|
SUM(COALESCE(ast.usage_qty, 0)) AS farm_usage_qty,
|
||||||
|
SUM(CASE
|
||||||
|
WHEN spw.project_flock_kandang_id IN (SELECT id FROM selected_pfk)
|
||||||
|
THEN COALESCE(ast.price, 0)
|
||||||
|
ELSE 0
|
||||||
|
END) AS sel_price_sum,
|
||||||
|
SUM(COALESCE(ast.price, 0)) AS farm_price_sum
|
||||||
|
FROM sales_lokasi sl
|
||||||
|
JOIN transfer_pairs tf
|
||||||
|
ON tf.dest_pw_id = sl.lokasi_pw_id
|
||||||
|
AND DATE(tf.first_transfer_date) <= DATE(sl.delivery_date)
|
||||||
|
JOIN product_warehouses spw
|
||||||
|
ON spw.id = tf.source_pw_id
|
||||||
|
AND spw.product_id = sl.product_id
|
||||||
|
JOIN warehouses sw ON sw.id = spw.warehouse_id
|
||||||
|
JOIN adjustment_stocks ast ON ast.product_warehouse_id = tf.source_pw_id
|
||||||
|
WHERE UPPER(COALESCE(sw.type, '')) = 'KANDANG'
|
||||||
|
AND sw.location_id = sl.location_id
|
||||||
|
AND UPPER(COALESCE(ast.function_code, '')) = UPPER(?)
|
||||||
|
AND UPPER(COALESCE(ast.transaction_type, '')) = UPPER(?)
|
||||||
|
AND DATE(ast.created_at) <= DATE(sl.delivery_date)
|
||||||
|
GROUP BY sl.mdp_id
|
||||||
|
),
|
||||||
|
sales_lokasi_adj AS (
|
||||||
|
SELECT sl.*
|
||||||
|
FROM sales_lokasi sl
|
||||||
|
JOIN adj_pool ap ON ap.mdp_id = sl.mdp_id
|
||||||
|
WHERE COALESCE(ap.farm_usage_qty, 0) > 0
|
||||||
|
OR COALESCE(ap.farm_price_sum, 0) > 0
|
||||||
|
),
|
||||||
|
sales_lokasi_rec AS (
|
||||||
|
SELECT sl.*
|
||||||
|
FROM sales_lokasi sl
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM sales_lokasi_adj sla WHERE sla.mdp_id = sl.mdp_id
|
||||||
|
)
|
||||||
|
),
|
||||||
|
rec_pool AS (
|
||||||
|
SELECT
|
||||||
|
sl.mdp_id,
|
||||||
|
SUM(CASE
|
||||||
|
WHEN COALESCE(re.project_flock_kandang_id, r.project_flock_kandangs_id) IN (SELECT id FROM selected_pfk)
|
||||||
|
THEN COALESCE(re.qty, 0)
|
||||||
|
ELSE 0
|
||||||
|
END) AS sel_qty,
|
||||||
|
SUM(COALESCE(re.qty, 0)) AS farm_qty,
|
||||||
|
SUM(CASE
|
||||||
|
WHEN COALESCE(re.project_flock_kandang_id, r.project_flock_kandangs_id) IN (SELECT id FROM selected_pfk)
|
||||||
|
THEN COALESCE(re.weight, 0)
|
||||||
|
ELSE 0
|
||||||
|
END) AS sel_weight,
|
||||||
|
SUM(COALESCE(re.weight, 0)) AS farm_weight
|
||||||
|
FROM sales_lokasi_rec sl
|
||||||
|
JOIN recordings r
|
||||||
|
ON r.deleted_at IS NULL
|
||||||
|
AND DATE(r.record_datetime) <= DATE(sl.delivery_date)
|
||||||
|
JOIN recording_eggs re
|
||||||
|
ON re.recording_id = r.id
|
||||||
|
AND re.product_warehouse_id = sl.lokasi_pw_id
|
||||||
|
JOIN project_flock_kandangs pfk
|
||||||
|
ON pfk.id = COALESCE(re.project_flock_kandang_id, r.project_flock_kandangs_id)
|
||||||
|
JOIN kandangs k ON k.id = pfk.kandang_id
|
||||||
|
WHERE k.location_id = sl.location_id
|
||||||
|
GROUP BY sl.mdp_id
|
||||||
|
),
|
||||||
|
kandang_totals AS (
|
||||||
|
SELECT
|
||||||
|
COALESCE(SUM(sk.usage_qty), 0) AS total_pieces,
|
||||||
|
COALESCE(SUM(sk.total_weight), 0) AS total_weight
|
||||||
|
FROM sales_kandang sk
|
||||||
|
),
|
||||||
|
lokasi_adj_totals AS (
|
||||||
|
SELECT
|
||||||
|
COALESCE(SUM(
|
||||||
|
sla.usage_qty *
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(ap.farm_usage_qty, 0) > 0 THEN (COALESCE(ap.sel_usage_qty, 0) * 1.0) / NULLIF(ap.farm_usage_qty, 0)
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
), 0) AS total_pieces,
|
||||||
|
COALESCE(SUM(
|
||||||
|
sla.total_weight *
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(ap.farm_price_sum, 0) > 0 THEN (COALESCE(ap.sel_price_sum, 0) * 1.0) / NULLIF(ap.farm_price_sum, 0)
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
), 0) AS total_weight
|
||||||
|
FROM sales_lokasi_adj sla
|
||||||
|
JOIN adj_pool ap ON ap.mdp_id = sla.mdp_id
|
||||||
|
),
|
||||||
|
lokasi_rec_totals AS (
|
||||||
|
SELECT
|
||||||
|
COALESCE(SUM(
|
||||||
|
slr.usage_qty *
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(rp.farm_qty, 0) > 0 THEN (COALESCE(rp.sel_qty, 0) * 1.0) / NULLIF(rp.farm_qty, 0)
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
), 0) AS total_pieces,
|
||||||
|
COALESCE(SUM(
|
||||||
|
slr.total_weight *
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(rp.farm_weight, 0) > 0 THEN (COALESCE(rp.sel_weight, 0) * 1.0) / NULLIF(rp.farm_weight, 0)
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
), 0) AS total_weight
|
||||||
|
FROM sales_lokasi_rec slr
|
||||||
|
LEFT JOIN rec_pool rp ON rp.mdp_id = slr.mdp_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
COALESCE(kt.total_pieces, 0) + COALESCE(lat.total_pieces, 0) + COALESCE(lrt.total_pieces, 0) AS total_pieces,
|
||||||
|
COALESCE(kt.total_weight, 0) + COALESCE(lat.total_weight, 0) + COALESCE(lrt.total_weight, 0) AS total_weight
|
||||||
|
FROM kandang_totals kt
|
||||||
|
CROSS JOIN lokasi_adj_totals lat
|
||||||
|
CROSS JOIN lokasi_rec_totals lrt
|
||||||
|
`
|
||||||
|
|
||||||
|
var totals struct {
|
||||||
|
TotalPieces float64
|
||||||
|
TotalWeight float64
|
||||||
|
}
|
||||||
|
|
||||||
|
err := r.db.WithContext(ctx).
|
||||||
|
Raw(
|
||||||
|
query,
|
||||||
|
projectFlockKandangIDs,
|
||||||
|
*startDate,
|
||||||
|
entity.FlagableTypeProduct,
|
||||||
|
eggFlags,
|
||||||
|
*startDate,
|
||||||
|
entity.FlagableTypeProduct,
|
||||||
|
eggFlags,
|
||||||
|
string(utils.AdjustmentTransactionSubtypeRecordingEggIn),
|
||||||
|
string(utils.AdjustmentTransactionTypeRecording),
|
||||||
|
).
|
||||||
|
Scan(&totals).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return totals.TotalPieces, totals.TotalWeight, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *HppV2RepositoryImpl) GetTransferSourceSummary(ctx context.Context, projectFlockKandangId uint) (uint, float64, error) {
|
||||||
|
var summary struct {
|
||||||
|
ProjectFlockID uint
|
||||||
|
TotalQty float64
|
||||||
|
}
|
||||||
|
err := r.db.WithContext(ctx).
|
||||||
|
Table("laying_transfer_targets AS ltt").
|
||||||
|
Select("lt.from_project_flock_id AS project_flock_id, COALESCE(SUM(ltt.total_qty), 0) AS total_qty").
|
||||||
|
Joins("JOIN laying_transfers AS lt ON lt.id = ltt.laying_transfer_id").
|
||||||
|
Where("lt.deleted_at IS NULL").
|
||||||
|
Where("ltt.deleted_at IS NULL").
|
||||||
|
Where("lt.executed_at IS NOT NULL").
|
||||||
|
Where("ltt.target_project_flock_kandang_id = ?", projectFlockKandangId).
|
||||||
|
Group("lt.from_project_flock_id").
|
||||||
|
Scan(&summary).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return summary.ProjectFlockID, summary.TotalQty, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HppV2Service interface {
|
||||||
|
CalculateHppCost(projectFlockKandangId uint, date *time.Time) (*HppCostResponse, error)
|
||||||
|
GetCostPakan(projectFlockKandangId uint, endDate *time.Time) (float64, error)
|
||||||
|
GetFeedGrowing(projectFlockKandangId uint, endDate *time.Time) (float64, error)
|
||||||
|
GetFeedLaying(projectFlockKandangId uint, endDate *time.Time) (float64, error)
|
||||||
|
GetHppEstimationDanRealisasi(totalProductionCost float64, projectFlockKandangId uint, startDate *time.Time, endDate *time.Time) (*HppCostResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type hppV2Service struct {
|
||||||
|
hppRepo commonRepo.HppV2CostRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHppV2Service(hppRepo commonRepo.HppV2CostRepository) HppV2Service {
|
||||||
|
return &hppV2Service{hppRepo: hppRepo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hppV2Service) CalculateHppCost(projectFlockKandangId uint, date *time.Time) (*HppCostResponse, error) {
|
||||||
|
if date == nil {
|
||||||
|
now := time.Now()
|
||||||
|
date = &now
|
||||||
|
}
|
||||||
|
|
||||||
|
location, err := time.LoadLocation("Asia/Jakarta")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
startOfDay := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, location)
|
||||||
|
endOfDay := startOfDay.Add(24 * time.Hour)
|
||||||
|
|
||||||
|
pakan, err := s.GetCostPakan(projectFlockKandangId, &endOfDay)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := s.GetHppEstimationDanRealisasi(pakan, projectFlockKandangId, &startOfDay, &endOfDay)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hppV2Service) GetCostPakan(projectFlockKandangId uint, endDate *time.Time) (float64, error) {
|
||||||
|
feedGrowing, err := s.GetFeedGrowing(projectFlockKandangId, endDate)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
feedLaying, err := s.GetFeedLaying(projectFlockKandangId, endDate)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pakan := feedGrowing + feedLaying
|
||||||
|
return pakan, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hppV2Service) GetFeedGrowing(projectFlockKandangId uint, endDate *time.Time) (float64, error) {
|
||||||
|
if s.hppRepo == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceProjectFlockID, transferTotalQty, err := s.hppRepo.GetTransferSourceSummary(context.Background(), projectFlockKandangId)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if sourceProjectFlockID == 0 || transferTotalQty <= 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
kandangIDsGrowing, err := s.hppRepo.GetProjectFlockKandangIDs(context.Background(), sourceProjectFlockID)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if len(kandangIDsGrowing) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
feedUsageCostGrowing, err := s.hppRepo.GetFeedUsageCost(context.Background(), kandangIDsGrowing, endDate)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
totalPopulationFlockGrowing, err := s.hppRepo.GetTotalPopulation(context.Background(), kandangIDsGrowing)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if totalPopulationFlockGrowing == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
result := feedUsageCostGrowing * (transferTotalQty / totalPopulationFlockGrowing)
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hppV2Service) GetFeedLaying(projectFlockKandangId uint, endDate *time.Time) (float64, error) {
|
||||||
|
if s.hppRepo == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := s.hppRepo.GetFeedUsageCost(context.Background(), []uint{projectFlockKandangId}, endDate)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hppV2Service) GetHppEstimationDanRealisasi(totalProductionCost float64, projectFlockKandangId uint, startDate *time.Time, endDate *time.Time) (*HppCostResponse, error) {
|
||||||
|
if s.hppRepo == nil {
|
||||||
|
return &HppCostResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
estimPieces, estimWeightKg, err := s.hppRepo.GetEggProduksiPiecesAndWeightKgByProjectFlockKandangIds(context.Background(), []uint{projectFlockKandangId}, endDate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
realPieces, realWeightKg, err := s.hppRepo.GetEggTerjualPiecesAndWeightKgByProjectFlockKandangIds(context.Background(), []uint{projectFlockKandangId}, startDate, endDate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
estimation := HppCostDetail{
|
||||||
|
Total: totalProductionCost,
|
||||||
|
Kg: estimWeightKg,
|
||||||
|
Butir: estimPieces,
|
||||||
|
}
|
||||||
|
if estimWeightKg > 0 {
|
||||||
|
estimation.HargaKg = roundToTwoDecimals(totalProductionCost / estimWeightKg)
|
||||||
|
}
|
||||||
|
if estimPieces > 0 {
|
||||||
|
estimation.HargaButir = roundToTwoDecimals(totalProductionCost / estimPieces)
|
||||||
|
}
|
||||||
|
|
||||||
|
real := HppCostDetail{
|
||||||
|
Total: totalProductionCost,
|
||||||
|
Kg: realWeightKg,
|
||||||
|
Butir: realPieces,
|
||||||
|
}
|
||||||
|
if realWeightKg > 0 {
|
||||||
|
real.HargaKg = roundToTwoDecimals(totalProductionCost / realWeightKg)
|
||||||
|
}
|
||||||
|
if realPieces > 0 {
|
||||||
|
real.HargaButir = roundToTwoDecimals(totalProductionCost / realPieces)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &HppCostResponse{
|
||||||
|
Estimation: estimation,
|
||||||
|
Real: real,
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
@@ -33,6 +33,7 @@ func (RepportModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *
|
|||||||
recordingRepository := recordingRepo.NewRecordingRepository(db)
|
recordingRepository := recordingRepo.NewRecordingRepository(db)
|
||||||
approvalRepository := commonRepo.NewApprovalRepository(db)
|
approvalRepository := commonRepo.NewApprovalRepository(db)
|
||||||
hppCostRepository := commonRepo.NewHppCostRepository(db)
|
hppCostRepository := commonRepo.NewHppCostRepository(db)
|
||||||
|
hppV2CostRepository := commonRepo.NewHppV2CostRepository(db)
|
||||||
purchaseSupplierRepository := repportRepo.NewPurchaseSupplierRepository(db)
|
purchaseSupplierRepository := repportRepo.NewPurchaseSupplierRepository(db)
|
||||||
debtSupplierRepository := repportRepo.NewDebtSupplierRepository(db)
|
debtSupplierRepository := repportRepo.NewDebtSupplierRepository(db)
|
||||||
hppPerKandangRepository := repportRepo.NewHppPerKandangRepository(db)
|
hppPerKandangRepository := repportRepo.NewHppPerKandangRepository(db)
|
||||||
@@ -46,6 +47,7 @@ func (RepportModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *
|
|||||||
|
|
||||||
approvalSvc := approvalService.NewApprovalService(approvalRepository)
|
approvalSvc := approvalService.NewApprovalService(approvalRepository)
|
||||||
hppSvc := approvalService.NewHppService(hppCostRepository)
|
hppSvc := approvalService.NewHppService(hppCostRepository)
|
||||||
|
hppV2Svc := approvalService.NewHppV2Service(hppV2CostRepository)
|
||||||
repportService := sRepport.NewRepportService(
|
repportService := sRepport.NewRepportService(
|
||||||
db,
|
db,
|
||||||
validate,
|
validate,
|
||||||
@@ -57,6 +59,7 @@ func (RepportModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *
|
|||||||
recordingRepository,
|
recordingRepository,
|
||||||
approvalSvc,
|
approvalSvc,
|
||||||
hppSvc,
|
hppSvc,
|
||||||
|
hppV2Svc,
|
||||||
hppCostRepository,
|
hppCostRepository,
|
||||||
purchaseSupplierRepository,
|
purchaseSupplierRepository,
|
||||||
debtSupplierRepository,
|
debtSupplierRepository,
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ type repportService struct {
|
|||||||
RecordingRepo recordingRepo.RecordingRepository
|
RecordingRepo recordingRepo.RecordingRepository
|
||||||
ApprovalSvc approvalService.ApprovalService
|
ApprovalSvc approvalService.ApprovalService
|
||||||
HppSvc approvalService.HppService
|
HppSvc approvalService.HppService
|
||||||
|
HppV2Svc approvalService.HppV2Service
|
||||||
HppCostRepo commonRepo.HppCostRepository
|
HppCostRepo commonRepo.HppCostRepository
|
||||||
PurchaseSupplierRepo repportRepo.PurchaseSupplierRepository
|
PurchaseSupplierRepo repportRepo.PurchaseSupplierRepository
|
||||||
DebtSupplierRepo repportRepo.DebtSupplierRepository
|
DebtSupplierRepo repportRepo.DebtSupplierRepository
|
||||||
@@ -97,6 +98,7 @@ func NewRepportService(
|
|||||||
recordingRepo recordingRepo.RecordingRepository,
|
recordingRepo recordingRepo.RecordingRepository,
|
||||||
approvalSvc approvalService.ApprovalService,
|
approvalSvc approvalService.ApprovalService,
|
||||||
hppSvc approvalService.HppService,
|
hppSvc approvalService.HppService,
|
||||||
|
hppV2Svc approvalService.HppV2Service,
|
||||||
hppCostRepo commonRepo.HppCostRepository,
|
hppCostRepo commonRepo.HppCostRepository,
|
||||||
purchaseSupplierRepo repportRepo.PurchaseSupplierRepository,
|
purchaseSupplierRepo repportRepo.PurchaseSupplierRepository,
|
||||||
debtSupplierRepo repportRepo.DebtSupplierRepository,
|
debtSupplierRepo repportRepo.DebtSupplierRepository,
|
||||||
@@ -119,6 +121,7 @@ func NewRepportService(
|
|||||||
RecordingRepo: recordingRepo,
|
RecordingRepo: recordingRepo,
|
||||||
ApprovalSvc: approvalSvc,
|
ApprovalSvc: approvalSvc,
|
||||||
HppSvc: hppSvc,
|
HppSvc: hppSvc,
|
||||||
|
HppV2Svc: hppV2Svc,
|
||||||
HppCostRepo: hppCostRepo,
|
HppCostRepo: hppCostRepo,
|
||||||
PurchaseSupplierRepo: purchaseSupplierRepo,
|
PurchaseSupplierRepo: purchaseSupplierRepo,
|
||||||
DebtSupplierRepo: debtSupplierRepo,
|
DebtSupplierRepo: debtSupplierRepo,
|
||||||
@@ -2289,8 +2292,8 @@ func (s *repportService) GetHppPerKandang(ctx *fiber.Ctx) (*dto.HppPerKandangRes
|
|||||||
var eggWeightFloat float64
|
var eggWeightFloat float64
|
||||||
var avgWeight float64
|
var avgWeight float64
|
||||||
eggHpp := 0.0
|
eggHpp := 0.0
|
||||||
if s.HppSvc != nil {
|
if s.HppV2Svc != nil {
|
||||||
hppCost, err := s.HppSvc.CalculateHppCost(row.ProjectFlockKandangID, &periodDate)
|
hppCost, err := s.HppV2Svc.CalculateHppCost(row.ProjectFlockKandangID, &periodDate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user