mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
adjust closing tap sapronak; add api summart total kuantitas per category and uom
This commit is contained in:
@@ -237,8 +237,7 @@ func (u *ClosingController) GetClosingSapronak(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
query := &validation.ClosingSapronakQuery{
|
query := &validation.ClosingSapronakQuery{
|
||||||
Type: strings.ToLower(c.Query("type")),
|
Type: strings.ToLower(c.Query("type")),
|
||||||
Page: c.QueryInt("page", 1),
|
Search: c.Query("search"),
|
||||||
Limit: c.QueryInt("limit", 10),
|
|
||||||
}
|
}
|
||||||
if raw := c.Query("kandang_id"); raw != "" {
|
if raw := c.Query("kandang_id"); raw != "" {
|
||||||
kandangInt, convErr := strconv.Atoi(raw)
|
kandangInt, convErr := strconv.Atoi(raw)
|
||||||
@@ -249,10 +248,6 @@ func (u *ClosingController) GetClosingSapronak(c *fiber.Ctx) error {
|
|||||||
query.KandangID = &kandangUint
|
query.KandangID = &kandangUint
|
||||||
}
|
}
|
||||||
|
|
||||||
if query.Page < 1 || query.Limit < 1 {
|
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
|
||||||
}
|
|
||||||
|
|
||||||
if query.Type != validation.SapronakTypeIncoming && query.Type != validation.SapronakTypeOutgoing {
|
if query.Type != validation.SapronakTypeIncoming && query.Type != validation.SapronakTypeOutgoing {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "type must be either incoming or outgoing")
|
return fiber.NewError(fiber.StatusBadRequest, "type must be either incoming or outgoing")
|
||||||
}
|
}
|
||||||
@@ -277,6 +272,51 @@ func (u *ClosingController) GetClosingSapronak(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ClosingController) GetClosingSapronakSummary(c *fiber.Ctx) error {
|
||||||
|
param := c.Params("projectFlockId")
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(param)
|
||||||
|
if err != nil || id <= 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid projectFlockId")
|
||||||
|
}
|
||||||
|
|
||||||
|
query := &validation.ClosingSapronakQuery{
|
||||||
|
Type: strings.ToLower(c.Query("type")),
|
||||||
|
Page: c.QueryInt("page", 1),
|
||||||
|
Limit: c.QueryInt("limit", 10),
|
||||||
|
Search: c.Query("search"),
|
||||||
|
}
|
||||||
|
if raw := c.Query("kandang_id"); raw != "" {
|
||||||
|
kandangInt, convErr := strconv.Atoi(raw)
|
||||||
|
if convErr != nil || kandangInt <= 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid kandang_id")
|
||||||
|
}
|
||||||
|
kandangUint := uint(kandangInt)
|
||||||
|
query.KandangID = &kandangUint
|
||||||
|
}
|
||||||
|
|
||||||
|
if query.Page < 1 || query.Limit < 1 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
if query.Type != validation.SapronakTypeIncoming && query.Type != validation.SapronakTypeOutgoing {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "type must be either incoming or outgoing")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := u.ClosingService.GetClosingSapronakSummary(c, uint(id), query)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).
|
||||||
|
JSON(response.Success{
|
||||||
|
Code: fiber.StatusOK,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Retrieved closing report (sapronak summary) successfully",
|
||||||
|
Data: result,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (u *ClosingController) GetSapronakByProject(c *fiber.Ctx) error {
|
func (u *ClosingController) GetSapronakByProject(c *fiber.Ctx) error {
|
||||||
param := c.Params("project_flock_id")
|
param := c.Params("project_flock_id")
|
||||||
flag := c.Query("flag", "")
|
flag := c.Query("flag", "")
|
||||||
|
|||||||
@@ -114,6 +114,17 @@ type ClosingSapronakDTO struct {
|
|||||||
OutgoingSapronak []ClosingSapronakItemDTO `json:"outgoing_sapronak"`
|
OutgoingSapronak []ClosingSapronakItemDTO `json:"outgoing_sapronak"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ClosingSapronakSummaryItemDTO struct {
|
||||||
|
Category string `json:"category"`
|
||||||
|
TotalQty int64 `json:"total_qty"`
|
||||||
|
Uom UomSummaryDTO `json:"uom"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UomSummaryDTO struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
// === Mapper Functions for Aggregated Sapronak Response ===
|
// === Mapper Functions for Aggregated Sapronak Response ===
|
||||||
|
|
||||||
func ToSapronakProjectAggregatedFromReports(reports []SapronakReportDTO, flag string) SapronakProjectAggregatedDTO {
|
func ToSapronakProjectAggregatedFromReports(reports []SapronakReportDTO, flag string) SapronakProjectAggregatedDTO {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
type ClosingRepository interface {
|
type ClosingRepository interface {
|
||||||
repository.BaseRepository[entity.ProjectFlock]
|
repository.BaseRepository[entity.ProjectFlock]
|
||||||
GetSapronak(ctx context.Context, params SapronakQueryParams) ([]SapronakRow, int64, error)
|
GetSapronak(ctx context.Context, params SapronakQueryParams) ([]SapronakRow, int64, error)
|
||||||
|
GetSapronakSummary(ctx context.Context, params SapronakQueryParams) ([]SapronakSummaryRow, error)
|
||||||
SumFeedPurchaseAndUsedByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) (float64, float64, error)
|
SumFeedPurchaseAndUsedByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) (float64, float64, error)
|
||||||
SumProjectChickinUsageByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) (float64, error)
|
SumProjectChickinUsageByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) (float64, error)
|
||||||
SumClaimCullingByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) (float64, error)
|
SumClaimCullingByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) (float64, error)
|
||||||
@@ -59,10 +60,18 @@ type SapronakRow struct {
|
|||||||
DestinationWarehouse string `gorm:"column:destination_warehouse"`
|
DestinationWarehouse string `gorm:"column:destination_warehouse"`
|
||||||
Destination string `gorm:"column:destination"`
|
Destination string `gorm:"column:destination"`
|
||||||
Quantity float64 `gorm:"column:quantity"`
|
Quantity float64 `gorm:"column:quantity"`
|
||||||
|
UnitID uint `gorm:"column:unit_id"`
|
||||||
Unit string `gorm:"column:unit"`
|
Unit string `gorm:"column:unit"`
|
||||||
Notes string `gorm:"column:notes"`
|
Notes string `gorm:"column:notes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SapronakSummaryRow struct {
|
||||||
|
Category string `gorm:"column:category"`
|
||||||
|
TotalQty int64 `gorm:"column:total_qty"`
|
||||||
|
UomID uint `gorm:"column:uom_id"`
|
||||||
|
UomName string `gorm:"column:uom_name"`
|
||||||
|
}
|
||||||
|
|
||||||
type ExpeditionHPPRow struct {
|
type ExpeditionHPPRow struct {
|
||||||
SupplierName string `gorm:"column:supplier_name"`
|
SupplierName string `gorm:"column:supplier_name"`
|
||||||
TotalAmount float64 `gorm:"column:total_amount"`
|
TotalAmount float64 `gorm:"column:total_amount"`
|
||||||
@@ -74,6 +83,7 @@ type SapronakQueryParams struct {
|
|||||||
ProjectFlockKandangIDs []uint
|
ProjectFlockKandangIDs []uint
|
||||||
Limit int
|
Limit int
|
||||||
Offset int
|
Offset int
|
||||||
|
Search string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ClosingRepositoryImpl) GetSapronak(ctx context.Context, params SapronakQueryParams) ([]SapronakRow, int64, error) {
|
func (r *ClosingRepositoryImpl) GetSapronak(ctx context.Context, params SapronakQueryParams) ([]SapronakRow, int64, error) {
|
||||||
@@ -109,14 +119,36 @@ func (r *ClosingRepositoryImpl) GetSapronak(ctx context.Context, params Sapronak
|
|||||||
|
|
||||||
unionSQL := strings.Join(unionParts, " UNION ALL ")
|
unionSQL := strings.Join(unionParts, " UNION ALL ")
|
||||||
|
|
||||||
|
search := strings.TrimSpace(params.Search)
|
||||||
|
searchClause := ""
|
||||||
|
var searchArgs []any
|
||||||
|
if search != "" {
|
||||||
|
searchClause = `
|
||||||
|
WHERE (
|
||||||
|
reference_number ILIKE ?
|
||||||
|
OR product_name ILIKE ?
|
||||||
|
OR product_category ILIKE ?
|
||||||
|
OR source_warehouse ILIKE ?
|
||||||
|
OR destination_warehouse ILIKE ?
|
||||||
|
OR CAST(quantity AS TEXT) ILIKE ?
|
||||||
|
OR unit ILIKE ?
|
||||||
|
OR notes ILIKE ?
|
||||||
|
OR transaction_type ILIKE ?
|
||||||
|
)`
|
||||||
|
like := "%" + search + "%"
|
||||||
|
searchArgs = append(searchArgs, like, like, like, like, like, like, like, like, like)
|
||||||
|
}
|
||||||
|
|
||||||
var totalResults int64
|
var totalResults int64
|
||||||
countSQL := fmt.Sprintf("SELECT COUNT(*) FROM (%s) AS combined", unionSQL)
|
countSQL := fmt.Sprintf("SELECT COUNT(*) FROM (%s) AS combined%s", unionSQL, searchClause)
|
||||||
if err := db.Raw(countSQL, args...).Scan(&totalResults).Error; err != nil {
|
countArgs := append(append([]any{}, args...), searchArgs...)
|
||||||
|
if err := db.Raw(countSQL, countArgs...).Scan(&totalResults).Error; err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dataArgs := append(append([]any{}, args...), params.Limit, params.Offset)
|
dataArgs := append(append([]any{}, args...), searchArgs...)
|
||||||
dataSQL := fmt.Sprintf("SELECT * FROM (%s) AS combined ORDER BY sort_date ASC, id ASC LIMIT ? OFFSET ?", unionSQL)
|
dataArgs = append(dataArgs, params.Limit, params.Offset)
|
||||||
|
dataSQL := fmt.Sprintf("SELECT * FROM (%s) AS combined%s ORDER BY sort_date ASC, id ASC LIMIT ? OFFSET ?", unionSQL, searchClause)
|
||||||
|
|
||||||
var rows []SapronakRow
|
var rows []SapronakRow
|
||||||
if err := db.Raw(dataSQL, dataArgs...).Scan(&rows).Error; err != nil {
|
if err := db.Raw(dataSQL, dataArgs...).Scan(&rows).Error; err != nil {
|
||||||
@@ -126,6 +158,79 @@ func (r *ClosingRepositoryImpl) GetSapronak(ctx context.Context, params Sapronak
|
|||||||
return rows, totalResults, nil
|
return rows, totalResults, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ClosingRepositoryImpl) GetSapronakSummary(ctx context.Context, params SapronakQueryParams) ([]SapronakSummaryRow, error) {
|
||||||
|
db := r.DB().WithContext(ctx)
|
||||||
|
|
||||||
|
var (
|
||||||
|
unionParts []string
|
||||||
|
args []any
|
||||||
|
)
|
||||||
|
|
||||||
|
switch params.Type {
|
||||||
|
case validation.SapronakTypeIncoming:
|
||||||
|
if len(params.WarehouseIDs) == 0 {
|
||||||
|
return []SapronakSummaryRow{}, nil
|
||||||
|
}
|
||||||
|
unionParts = append(unionParts, sapronakIncomingPurchasesSQL, sapronakIncomingTransfersSQL)
|
||||||
|
args = append(args, params.WarehouseIDs, params.WarehouseIDs)
|
||||||
|
case validation.SapronakTypeOutgoing:
|
||||||
|
if len(params.WarehouseIDs) > 0 {
|
||||||
|
unionParts = append(unionParts, sapronakOutgoingTransfersSQL)
|
||||||
|
args = append(args, params.WarehouseIDs)
|
||||||
|
}
|
||||||
|
if len(params.ProjectFlockKandangIDs) > 0 {
|
||||||
|
unionParts = append(unionParts, sapronakOutgoingMarketingsSQL)
|
||||||
|
args = append(args, params.ProjectFlockKandangIDs)
|
||||||
|
}
|
||||||
|
if len(unionParts) == 0 {
|
||||||
|
return []SapronakSummaryRow{}, nil
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid sapronak type: %s", params.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
unionSQL := strings.Join(unionParts, " UNION ALL ")
|
||||||
|
|
||||||
|
search := strings.TrimSpace(params.Search)
|
||||||
|
searchClause := ""
|
||||||
|
var searchArgs []any
|
||||||
|
if search != "" {
|
||||||
|
searchClause = `
|
||||||
|
WHERE (
|
||||||
|
reference_number ILIKE ?
|
||||||
|
OR product_name ILIKE ?
|
||||||
|
OR product_category ILIKE ?
|
||||||
|
OR source_warehouse ILIKE ?
|
||||||
|
OR destination_warehouse ILIKE ?
|
||||||
|
OR CAST(quantity AS TEXT) ILIKE ?
|
||||||
|
OR unit ILIKE ?
|
||||||
|
OR notes ILIKE ?
|
||||||
|
OR transaction_type ILIKE ?
|
||||||
|
)`
|
||||||
|
like := "%" + search + "%"
|
||||||
|
searchArgs = append(searchArgs, like, like, like, like, like, like, like, like, like)
|
||||||
|
}
|
||||||
|
|
||||||
|
querySQL := fmt.Sprintf(`
|
||||||
|
SELECT
|
||||||
|
product_category AS category,
|
||||||
|
CAST(COALESCE(SUM(quantity), 0) AS BIGINT) AS total_qty,
|
||||||
|
unit_id AS uom_id,
|
||||||
|
unit AS uom_name
|
||||||
|
FROM (%s) AS combined%s
|
||||||
|
GROUP BY product_category, unit_id, unit
|
||||||
|
ORDER BY product_category ASC, unit ASC
|
||||||
|
`, unionSQL, searchClause)
|
||||||
|
queryArgs := append(append([]any{}, args...), searchArgs...)
|
||||||
|
|
||||||
|
var rows []SapronakSummaryRow
|
||||||
|
if err := db.Raw(querySQL, queryArgs...).Scan(&rows).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ClosingRepositoryImpl) SumFeedPurchaseAndUsedByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) (float64, float64, error) {
|
func (r *ClosingRepositoryImpl) SumFeedPurchaseAndUsedByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) (float64, float64, error) {
|
||||||
if len(projectFlockKandangIDs) == 0 {
|
if len(projectFlockKandangIDs) == 0 {
|
||||||
return 0, 0, nil
|
return 0, 0, nil
|
||||||
@@ -379,6 +484,7 @@ SELECT
|
|||||||
w.name AS destination_warehouse,
|
w.name AS destination_warehouse,
|
||||||
'' AS destination,
|
'' AS destination,
|
||||||
pi.total_qty AS quantity,
|
pi.total_qty AS quantity,
|
||||||
|
u.id AS unit_id,
|
||||||
u.name AS unit,
|
u.name AS unit,
|
||||||
COALESCE(p.notes, '') AS notes
|
COALESCE(p.notes, '') AS notes
|
||||||
FROM purchase_items pi
|
FROM purchase_items pi
|
||||||
@@ -427,6 +533,7 @@ SELECT
|
|||||||
COALESCE(tw.name, '') AS destination_warehouse,
|
COALESCE(tw.name, '') AS destination_warehouse,
|
||||||
'' AS destination,
|
'' AS destination,
|
||||||
std.usage_qty AS quantity,
|
std.usage_qty AS quantity,
|
||||||
|
u.id AS unit_id,
|
||||||
u.name AS unit,
|
u.name AS unit,
|
||||||
'Stock Refill' AS notes
|
'Stock Refill' AS notes
|
||||||
FROM stock_transfer_details std
|
FROM stock_transfer_details std
|
||||||
@@ -476,6 +583,7 @@ SELECT
|
|||||||
COALESCE(tw.name, '') AS destination_warehouse,
|
COALESCE(tw.name, '') AS destination_warehouse,
|
||||||
'' AS destination,
|
'' AS destination,
|
||||||
std.usage_qty AS quantity,
|
std.usage_qty AS quantity,
|
||||||
|
u.id AS unit_id,
|
||||||
u.name AS unit,
|
u.name AS unit,
|
||||||
'Transfer to other unit' AS notes
|
'Transfer to other unit' AS notes
|
||||||
FROM stock_transfer_details std
|
FROM stock_transfer_details std
|
||||||
@@ -522,13 +630,15 @@ SELECT
|
|||||||
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
), '') AS product_sub_category,
|
), '') AS product_sub_category,
|
||||||
w.name AS source_warehouse,
|
w.name AS source_warehouse,
|
||||||
'RETAIL CUSTOMER' AS destination_warehouse,
|
COALESCE(c.name, '') AS destination_warehouse,
|
||||||
'' AS destination,
|
'' AS destination,
|
||||||
mp.qty AS quantity,
|
mp.qty AS quantity,
|
||||||
|
u.id AS unit_id,
|
||||||
u.name AS unit,
|
u.name AS unit,
|
||||||
m.notes AS notes
|
m.notes AS notes
|
||||||
FROM marketing_products mp
|
FROM marketing_products mp
|
||||||
JOIN marketings m ON m.id = mp.marketing_id
|
JOIN marketings m ON m.id = mp.marketing_id
|
||||||
|
LEFT JOIN customers c ON c.id = m.customer_id
|
||||||
JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id
|
JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id
|
||||||
JOIN products prod ON prod.id = pw.product_id
|
JOIN products prod ON prod.id = pw.product_id
|
||||||
JOIN uoms u ON u.id = prod.uom_id
|
JOIN uoms u ON u.id = prod.uom_id
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ type ClosingService interface {
|
|||||||
GetClosingDataProduksi(ctx *fiber.Ctx, projectFlockID uint, kandangID *uint) (*dto.ClosingProductionReportDTO, error)
|
GetClosingDataProduksi(ctx *fiber.Ctx, projectFlockID uint, kandangID *uint) (*dto.ClosingProductionReportDTO, error)
|
||||||
GetOverhead(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.OverheadListDTO, error)
|
GetOverhead(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.OverheadListDTO, error)
|
||||||
GetClosingSapronak(ctx *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error)
|
GetClosingSapronak(ctx *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error)
|
||||||
|
GetClosingSapronakSummary(ctx *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakSummaryItemDTO, error)
|
||||||
GetExpeditionHPP(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.ExpeditionHPPDTO, error)
|
GetExpeditionHPP(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.ExpeditionHPPDTO, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,6 +354,7 @@ func (s closingService) GetClosingSapronak(c *fiber.Ctx, projectFlockID uint, pa
|
|||||||
ProjectFlockKandangIDs: projectFlockKandangIDs,
|
ProjectFlockKandangIDs: projectFlockKandangIDs,
|
||||||
Limit: params.Limit,
|
Limit: params.Limit,
|
||||||
Offset: offset,
|
Offset: offset,
|
||||||
|
Search: params.Search,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Failed to fetch sapronak %s for project flock %d: %+v", params.Type, projectFlockID, err)
|
s.Log.Errorf("Failed to fetch sapronak %s for project flock %d: %+v", params.Type, projectFlockID, err)
|
||||||
@@ -387,6 +389,74 @@ func (s closingService) GetClosingSapronak(c *fiber.Ctx, projectFlockID uint, pa
|
|||||||
return items, totalResults, nil
|
return items, totalResults, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s closingService) GetClosingSapronakSummary(c *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakSummaryItemDTO, error) {
|
||||||
|
if projectFlockID == 0 {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
||||||
|
}
|
||||||
|
|
||||||
|
if params == nil {
|
||||||
|
params = &validation.ClosingSapronakQuery{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Validate.Struct(params); err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Type != validation.SapronakTypeIncoming && params.Type != validation.SapronakTypeOutgoing {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, "type must be either incoming or outgoing")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := s.Repository.GetByID(c.Context(), projectFlockID, nil); err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock tidak ditemukan")
|
||||||
|
}
|
||||||
|
s.Log.Errorf("Failed get project flock %d for sapronak closing summary: %+v", projectFlockID, err)
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock")
|
||||||
|
}
|
||||||
|
|
||||||
|
warehouseIDs, err := s.getWarehouseIDsByProjectFlock(c.Context(), projectFlockID)
|
||||||
|
if err != nil {
|
||||||
|
s.Log.Errorf("Failed to fetch warehouses for project flock %d: %+v", projectFlockID, err)
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch warehouses for project flock")
|
||||||
|
}
|
||||||
|
|
||||||
|
var projectFlockKandangIDs []uint
|
||||||
|
if params.KandangID != nil && *params.KandangID > 0 {
|
||||||
|
projectFlockKandangIDs = []uint{*params.KandangID}
|
||||||
|
} else if params.Type == validation.SapronakTypeOutgoing {
|
||||||
|
projectFlockKandangIDs, err = s.getProjectFlockKandangIDs(c.Context(), projectFlockID)
|
||||||
|
if err != nil {
|
||||||
|
s.Log.Errorf("Failed to fetch project flock kandang IDs for project flock %d: %+v", projectFlockID, err)
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock kandang")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := s.Repository.GetSapronakSummary(c.Context(), repository.SapronakQueryParams{
|
||||||
|
Type: params.Type,
|
||||||
|
WarehouseIDs: warehouseIDs,
|
||||||
|
ProjectFlockKandangIDs: projectFlockKandangIDs,
|
||||||
|
Search: params.Search,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
s.Log.Errorf("Failed to fetch sapronak %s summary for project flock %d: %+v", params.Type, projectFlockID, err)
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch sapronak summary data")
|
||||||
|
}
|
||||||
|
|
||||||
|
items := make([]dto.ClosingSapronakSummaryItemDTO, 0, len(rows))
|
||||||
|
for _, row := range rows {
|
||||||
|
items = append(items, dto.ClosingSapronakSummaryItemDTO{
|
||||||
|
Category: row.Category,
|
||||||
|
TotalQty: row.TotalQty,
|
||||||
|
Uom: dto.UomSummaryDTO{
|
||||||
|
ID: row.UomID,
|
||||||
|
Name: row.UomName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s closingService) getWarehouseIDsByProjectFlock(ctx context.Context, projectFlockID uint) ([]uint, error) {
|
func (s closingService) getWarehouseIDsByProjectFlock(ctx context.Context, projectFlockID uint) ([]uint, error) {
|
||||||
var kandangIDs []uint
|
var kandangIDs []uint
|
||||||
db := s.Repository.DB().WithContext(ctx)
|
db := s.Repository.DB().WithContext(ctx)
|
||||||
@@ -1030,4 +1100,3 @@ func closestFcrValues(standards []entity.FcrStandard, averageWeight float64) (fl
|
|||||||
|
|
||||||
return closest.Mortality, closest.FcrNumber
|
return closest.Mortality, closest.FcrNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,4 +24,5 @@ type ClosingSapronakQuery struct {
|
|||||||
Page int `query:"page" validate:"omitempty,number,min=1,gt=0"`
|
Page int `query:"page" validate:"omitempty,number,min=1,gt=0"`
|
||||||
Limit int `query:"limit" validate:"omitempty,number,min=1,max=100,gt=0"`
|
Limit int `query:"limit" validate:"omitempty,number,min=1,max=100,gt=0"`
|
||||||
KandangID *uint `query:"kandang_id" validate:"omitempty,gt=0"`
|
KandangID *uint `query:"kandang_id" validate:"omitempty,gt=0"`
|
||||||
|
Search string `query:"search" validate:"omitempty,max=100"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,6 @@ func (r *StockTransferRepositoryImpl) GenerateMovementNumber(ctx context.Context
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
movementNumber := fmt.Sprintf("ST-%05d", seq)
|
movementNumber := fmt.Sprintf("PND-LTI-%05d", seq)
|
||||||
return movementNumber, nil
|
return movementNumber, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user