mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'feat/BE/US-334-Report-closing-hpp-expedisi' into 'feat/BE/Sprint-7'
[FEAT/BE][US#334] report closing hpp expedisi See merge request mbugroup/lti-api!100
This commit is contained in:
@@ -246,6 +246,68 @@ func (u *ClosingController) GetSapronakByKandang(c *fiber.Ctx) error {
|
||||
})
|
||||
}
|
||||
|
||||
func (u *ClosingController) GetExpeditionHPP(c *fiber.Ctx) error {
|
||||
param := c.Params("project_flock_id")
|
||||
|
||||
projectFlockID, err := strconv.Atoi(param)
|
||||
if err != nil || projectFlockID <= 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid project_flock_id")
|
||||
}
|
||||
|
||||
var projectFlockKandangID *uint
|
||||
if raw := c.Query("project_flock_kandang_id"); raw != "" {
|
||||
idInt, convErr := strconv.Atoi(raw)
|
||||
if convErr != nil || idInt <= 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid project_flock_kandang_id")
|
||||
}
|
||||
idUint := uint(idInt)
|
||||
projectFlockKandangID = &idUint
|
||||
}
|
||||
|
||||
result, err := u.ClosingService.GetExpeditionHPP(c, uint(projectFlockID), projectFlockKandangID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
JSON(response.Success{
|
||||
Code: fiber.StatusOK,
|
||||
Status: "success",
|
||||
Message: "Get expedition HPP successfully",
|
||||
Data: result,
|
||||
})
|
||||
}
|
||||
|
||||
func (u *ClosingController) GetExpeditionHPPByKandang(c *fiber.Ctx) error {
|
||||
projectParam := c.Params("project_flock_id")
|
||||
kandangParam := c.Params("project_flock_kandang_id")
|
||||
|
||||
projectFlockID, err := strconv.Atoi(projectParam)
|
||||
if err != nil || projectFlockID <= 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid project_flock_id")
|
||||
}
|
||||
|
||||
pfkID, err := strconv.Atoi(kandangParam)
|
||||
if err != nil || pfkID <= 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid project_flock_kandang_id")
|
||||
}
|
||||
|
||||
kandangID := uint(pfkID)
|
||||
|
||||
result, err := u.ClosingService.GetExpeditionHPP(c, uint(projectFlockID), &kandangID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
JSON(response.Success{
|
||||
Code: fiber.StatusOK,
|
||||
Status: "success",
|
||||
Message: "Get expedition HPP successfully",
|
||||
Data: result,
|
||||
})
|
||||
}
|
||||
|
||||
func (u *ClosingController) GetClosingDataProduksi(c *fiber.Ctx) error {
|
||||
param := c.Params("projectFlockId")
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package dto
|
||||
|
||||
// ExpeditionCostItemDTO merepresentasikan biaya ekspedisi per vendor.
|
||||
type ExpeditionCostItemDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
ExpeditionVendorName string `json:"expedition_vendor_name"`
|
||||
HPPAmount float64 `json:"hpp_amount"`
|
||||
}
|
||||
|
||||
// ExpeditionHPPDTO adalah struktur response utama untuk HPP Ekspedisi.
|
||||
type ExpeditionHPPDTO struct {
|
||||
ExpeditionCosts []ExpeditionCostItemDTO `json:"expedition_costs"`
|
||||
TotalHPPAmount float64 `json:"total_hpp_amount"`
|
||||
}
|
||||
@@ -22,6 +22,7 @@ type ClosingRepository interface {
|
||||
SumMarketingWeightAndQtyByProjectFlockKandangIDsAndFlagNames(ctx context.Context, projectFlockKandangIDs []uint, flagNames []string) (float64, float64, float64, error)
|
||||
SumRecordingEggQtyByProjectFlockKandangIDsAndFlagNames(ctx context.Context, projectFlockKandangIDs []uint, flagNames []string) (float64, error)
|
||||
GetFcrStandardsByFcrID(ctx context.Context, fcrID uint) ([]entity.FcrStandard, error)
|
||||
GetExpeditionHPP(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]ExpeditionHPPRow, error)
|
||||
FetchSapronakIncoming(ctx context.Context, kandangID uint) ([]SapronakIncomingRow, error)
|
||||
FetchSapronakIncomingDetails(ctx context.Context, kandangID uint) (map[uint][]SapronakDetailRow, error)
|
||||
FetchSapronakUsage(ctx context.Context, pfkID uint) ([]SapronakUsageRow, error)
|
||||
@@ -59,6 +60,11 @@ type SapronakRow struct {
|
||||
Notes string `gorm:"column:notes"`
|
||||
}
|
||||
|
||||
type ExpeditionHPPRow struct {
|
||||
SupplierName string `gorm:"column:supplier_name"`
|
||||
TotalAmount float64 `gorm:"column:total_amount"`
|
||||
}
|
||||
|
||||
type SapronakQueryParams struct {
|
||||
Type string
|
||||
WarehouseIDs []uint
|
||||
@@ -274,6 +280,45 @@ func (r *ClosingRepositoryImpl) GetFcrStandardsByFcrID(ctx context.Context, fcrI
|
||||
return standards, nil
|
||||
}
|
||||
|
||||
func (r *ClosingRepositoryImpl) GetExpeditionHPP(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]ExpeditionHPPRow, error) {
|
||||
db := r.DB().WithContext(ctx)
|
||||
|
||||
if projectFlockID == 0 {
|
||||
return nil, fmt.Errorf("invalid project flock id")
|
||||
}
|
||||
|
||||
query := db.
|
||||
Table("expense_realizations AS er").
|
||||
Joins("JOIN expense_nonstocks ens ON ens.id = er.expense_nonstock_id").
|
||||
Joins("JOIN expenses e ON e.id = ens.expense_id").
|
||||
Joins("JOIN project_flock_kandangs pfk ON pfk.id = ens.project_flock_kandang_id").
|
||||
Joins("JOIN nonstocks n ON n.id = ens.nonstock_id").
|
||||
Joins("JOIN flags f ON f.flagable_id = n.id AND f.flagable_type = ?", entity.FlagableTypeNonstock).
|
||||
Joins("JOIN suppliers s ON s.id = e.supplier_id").
|
||||
Where("pfk.project_flock_id = ?", projectFlockID).
|
||||
Where("e.category = ?", "BOP").
|
||||
Where("UPPER(f.name) = ?", strings.ToUpper(string(utils.FlagEkspedisi)))
|
||||
|
||||
if projectFlockKandangID != nil && *projectFlockKandangID != 0 {
|
||||
query = query.Where("pfk.id = ?", *projectFlockKandangID)
|
||||
}
|
||||
|
||||
var rows []ExpeditionHPPRow
|
||||
err := query.
|
||||
Select(
|
||||
"e.supplier_id AS supplier_id, " +
|
||||
"s.name AS supplier_name, " +
|
||||
"SUM(er.qty * er.price) AS total_amount",
|
||||
).
|
||||
Group("e.supplier_id, s.name").
|
||||
Scan(&rows).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
const (
|
||||
sapronakIncomingPurchasesSQL = `
|
||||
SELECT
|
||||
|
||||
@@ -27,5 +27,7 @@ func ClosingRoutes(v1 fiber.Router, u user.UserService, s closing.ClosingService
|
||||
route.Get("/:project_flock_id/perhitungan_sapronak", ctrl.GetSapronakByProject)
|
||||
route.Get("/:projectFlockId", ctrl.GetClosingSummary)
|
||||
route.Get("/:projectFlockId/sapronak", ctrl.GetClosingSapronak)
|
||||
route.Get("/:project_flock_id/expedition-hpp", ctrl.GetExpeditionHPP)
|
||||
route.Get("/:project_flock_id/:project_flock_kandang_id/expedition-hpp", ctrl.GetExpeditionHPPByKandang)
|
||||
route.Get("/:projectFlockId/data-produksi", ctrl.GetClosingDataProduksi)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ type ClosingService interface {
|
||||
GetOverhead(ctx *fiber.Ctx, projectFlockID uint) (*dto.OverheadListDTO, error)
|
||||
GetClosingDataProduksi(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingProductionReportDTO, error)
|
||||
GetClosingSapronak(ctx *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error)
|
||||
GetExpeditionHPP(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.ExpeditionHPPDTO, error)
|
||||
}
|
||||
|
||||
type closingService struct {
|
||||
@@ -383,6 +384,40 @@ func (s closingService) GetOverhead(c *fiber.Ctx, projectFlockID uint) (*dto.Ove
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// GetExpeditionHPP menghitung HPP ekspedisi per vendor untuk sebuah project flock.
|
||||
// Jika projectFlockKandangID tidak nil, maka hanya data untuk kandang tersebut yang dihitung.
|
||||
func (s closingService) GetExpeditionHPP(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.ExpeditionHPPDTO, error) {
|
||||
if projectFlockID == 0 {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
||||
}
|
||||
|
||||
rows, err := s.Repository.GetExpeditionHPP(c.Context(), projectFlockID, projectFlockKandangID)
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to get expedition HPP for project flock %d: %+v", projectFlockID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch expedition HPP")
|
||||
}
|
||||
|
||||
expeditionCosts := make([]dto.ExpeditionCostItemDTO, 0, len(rows))
|
||||
var totalHPP float64
|
||||
|
||||
for idx, row := range rows {
|
||||
expeditionCosts = append(expeditionCosts, dto.ExpeditionCostItemDTO{
|
||||
Id: uint64(idx + 1),
|
||||
ExpeditionVendorName: row.SupplierName,
|
||||
HPPAmount: row.TotalAmount,
|
||||
})
|
||||
|
||||
totalHPP += row.TotalAmount
|
||||
}
|
||||
|
||||
result := &dto.ExpeditionHPPDTO{
|
||||
ExpeditionCosts: expeditionCosts,
|
||||
TotalHPPAmount: totalHPP,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint) (*dto.ClosingProductionReportDTO, error) {
|
||||
if projectFlockID == 0 {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
||||
|
||||
Reference in New Issue
Block a user