diff --git a/internal/middleware/permissions.go b/internal/middleware/permissions.go index 10741bff..9450d228 100644 --- a/internal/middleware/permissions.go +++ b/internal/middleware/permissions.go @@ -1,8 +1,9 @@ package middleware -const( +const ( P_DashboardGetAll = "lti.dashboard.list" ) + // project-flock const ( P_ProjectFlockKandangsClosing = "lti.production.project_flock_kandangs.closing" @@ -50,6 +51,7 @@ const ( P_ReportDebtSupplierGetAll = "lti.repport.debtsupplier.list" P_ReportHppPerKandangGetAll = "lti.repport.gethppperkandang.list" P_ReportProductionResultGetAll = "lti.repport.production_result.list" + P_ReportCustomerPaymentGetAll = "lti.repport.customerpayment.list" ) const ( @@ -150,7 +152,7 @@ const ( P_ProductsCreateOne = "lti.master.products.create" P_ProductsUpdateOne = "lti.master.products.update" P_ProductsDeleteOne = "lti.master.products.delete" - + P_SuppliersGetAll = "lti.master.suppliers.list" P_SuppliersGetOne = "lti.master.suppliers.detail" P_SuppliersCreateOne = "lti.master.suppliers.create" diff --git a/internal/modules/production/chickins/services/chickin.service.go b/internal/modules/production/chickins/services/chickin.service.go index eabe596c..84e98f2d 100644 --- a/internal/modules/production/chickins/services/chickin.service.go +++ b/internal/modules/production/chickins/services/chickin.service.go @@ -584,7 +584,6 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit return updated, nil } -// autoAddFlagToProduct adds target flag to product if not already present (idempotent) func (s *chickinService) autoAddFlagToProduct(ctx context.Context, tx *gorm.DB, productID uint, targetFlag utils.FlagType) error { if s.ProductRepo == nil { return nil diff --git a/internal/modules/repports/controllers/repport.controller.go b/internal/modules/repports/controllers/repport.controller.go index 22ff4acf..d89effa3 100644 --- a/internal/modules/repports/controllers/repport.controller.go +++ b/internal/modules/repports/controllers/repport.controller.go @@ -282,6 +282,33 @@ func (c *RepportController) GetProductionResult(ctx *fiber.Ctx) error { }) } +func (c *RepportController) GetCustomerPayment(ctx *fiber.Ctx) error { + page := ctx.QueryInt("page", 1) + limit := ctx.QueryInt("limit", 10) + + if page < 1 || limit < 1 { + return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0") + } + + // TODO: Implement service call + data := []dto.CustomerPaymentReportItem{} + totalResults := int64(0) + + return ctx.Status(fiber.StatusOK). + JSON(response.SuccessWithPaginate[dto.CustomerPaymentReportItem]{ + Code: fiber.StatusOK, + Status: "success", + Message: "Get customer payment report successfully", + Meta: response.Meta{ + Page: page, + Limit: limit, + TotalPages: int64(math.Ceil(float64(totalResults) / float64(limit))), + TotalResults: totalResults, + }, + Data: data, + }) +} + func parseCommaSeparatedInt64s(raw string) ([]int64, error) { raw = strings.TrimSpace(raw) if raw == "" { diff --git a/internal/modules/repports/dto/repportCustomerPayment.dto.go b/internal/modules/repports/dto/repportCustomerPayment.dto.go new file mode 100644 index 00000000..e0938b51 --- /dev/null +++ b/internal/modules/repports/dto/repportCustomerPayment.dto.go @@ -0,0 +1,63 @@ +package dto + +import ( + "time" +) + +// CustomerPaymentReportCustomer represents customer information in the report +type CustomerPaymentReportCustomer struct { + ID uint `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + AccountNumber string `json:"account_number"` + Balance float64 `json:"balance"` + Address string `json:"address"` +} + +// CustomerPaymentReportRow represents each transaction row +type CustomerPaymentReportRow struct { + ID uint `json:"id"` + DoDate time.Time `json:"do_date"` + RealizationDate time.Time `json:"realization_date"` + AgingDay int `json:"aging_day"` + Reference string `json:"reference"` + VehiclePlate []string `json:"vehicle_plate"` + Qty float64 `json:"qty"` + Weight float64 `json:"weight"` + AverageWeight float64 `json:"average_weight"` + Price float64 `json:"price"` + CreditNote float64 `json:"credit_note"` + FinalPrice float64 `json:"final_price"` + PPN float64 `json:"ppn"` + Total float64 `json:"total"` + Payment float64 `json:"payment"` + AccountsReceivable float64 `json:"accounts_receivable"` + Notes string `json:"notes"` + PickupInfo string `json:"pickup_info"` + SalesMarketing string `json:"sales_marketing"` +} + +// CustomerPaymentReportSummary represents summary calculations per customer +type CustomerPaymentReportSummary struct { + TotalQty float64 `json:"total_qty"` + TotalWeight float64 `json:"total_weight"` + TotalInitialAmount float64 `json:"total_initial_amount"` + TotalCreditNote float64 `json:"total_credit_note"` + TotalFinalAmount float64 `json:"total_final_amount"` + TotalPPN float64 `json:"total_ppn"` + TotalGrandAmount float64 `json:"total_grand_amount"` + TotalPayment float64 `json:"total_payment"` + TotalAccountsReceivable float64 `json:"total_accounts_receivable"` +} + +// CustomerPaymentReportItem represents data grouped by customer +type CustomerPaymentReportItem struct { + Customer CustomerPaymentReportCustomer `json:"customer"` + Rows []CustomerPaymentReportRow `json:"rows"` + Summary CustomerPaymentReportSummary `json:"summary"` +} + +// CustomerPaymentReportResponse represents the complete response +type CustomerPaymentReportResponse struct { + Data []CustomerPaymentReportItem `json:"data"` +} diff --git a/internal/modules/repports/route.go b/internal/modules/repports/route.go index 0a0cf8a3..2f5eceec 100644 --- a/internal/modules/repports/route.go +++ b/internal/modules/repports/route.go @@ -21,5 +21,5 @@ func RepportRoutes(v1 fiber.Router, u user.UserService, s repport.RepportService route.Get("/debt-supplier", m.RequirePermissions(m.P_ReportDebtSupplierGetAll), ctrl.GetDebtSupplier) route.Get("/hpp-per-kandang", m.RequirePermissions(m.P_ReportHppPerKandangGetAll), ctrl.GetHppPerKandang) route.Get("/production-result/:idProjectFlockKandang", m.RequirePermissions(m.P_ReportProductionResultGetAll), ctrl.GetProductionResult) - + route.Get("/customer-payment", m.RequirePermissions(m.P_ReportCustomerPaymentGetAll), ctrl.GetCustomerPayment) }