mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 21:41:55 +00:00
feat[BE]: enhance customer payment report with vehicle numbers and pickup info, add date filtering
This commit is contained in:
@@ -359,7 +359,7 @@ func (s *repportService) GetCustomerPayment(ctx *fiber.Ctx, params *validation.C
|
||||
// Process each customer
|
||||
var result []dto.CustomerPaymentReportItem
|
||||
for _, customerID := range customerIDs {
|
||||
item, err := s.processCustomerPayment(ctx.Context(), customerID)
|
||||
item, err := s.processCustomerPayment(ctx.Context(), customerID, params)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@@ -369,7 +369,7 @@ func (s *repportService) GetCustomerPayment(ctx *fiber.Ctx, params *validation.C
|
||||
return result, totalCustomers, nil
|
||||
}
|
||||
|
||||
func (s *repportService) processCustomerPayment(ctx context.Context, customerID uint) (dto.CustomerPaymentReportItem, error) {
|
||||
func (s *repportService) processCustomerPayment(ctx context.Context, customerID uint, params *validation.CustomerPaymentQuery) (dto.CustomerPaymentReportItem, error) {
|
||||
customer := entity.Customer{}
|
||||
if err := s.DB.WithContext(ctx).
|
||||
Where("id = ?", customerID).
|
||||
@@ -392,28 +392,11 @@ func (s *repportService) processCustomerPayment(ctx context.Context, customerID
|
||||
runningBalance := initialBalance
|
||||
|
||||
for i, tx := range transactions {
|
||||
row := dto.CustomerPaymentReportRow{
|
||||
TransactionType: tx.TransactionType,
|
||||
TransactionID: tx.TransactionID,
|
||||
TransDate: tx.TransDate,
|
||||
DeliveryDate: tx.DeliveryDate,
|
||||
Reference: tx.Reference,
|
||||
VehicleNumbers: tx.VehicleNumbers,
|
||||
Qty: tx.Qty,
|
||||
Weight: tx.Weight,
|
||||
AverageWeight: tx.AverageWeight,
|
||||
Price: tx.Price,
|
||||
CreditNote: tx.CreditNote,
|
||||
FinalPrice: tx.FinalPrice,
|
||||
PPN: tx.PPN,
|
||||
TotalPrice: tx.TotalPrice,
|
||||
PaymentAmount: tx.PaymentAmount,
|
||||
PickupInfo: tx.PickupInfo,
|
||||
SalesPerson: tx.SalesPerson,
|
||||
}
|
||||
|
||||
previousBalance := runningBalance
|
||||
|
||||
row := dto.ToCustomerPaymentReportRow(tx)
|
||||
|
||||
if tx.TransactionType == "SALES" {
|
||||
runningBalance -= tx.TotalPrice
|
||||
status, paymentDate := s.determineSalesStatusAndPaymentDate(transactions, i, previousBalance, runningBalance)
|
||||
@@ -452,51 +435,58 @@ func (s *repportService) processCustomerPayment(ctx context.Context, customerID
|
||||
rows = append(rows, row)
|
||||
}
|
||||
|
||||
summary := s.calculateSummary(rows, initialBalance)
|
||||
if params.StartDate != "" || params.EndDate != "" {
|
||||
filteredRows := make([]dto.CustomerPaymentReportRow, 0, len(rows))
|
||||
location, err := time.LoadLocation("Asia/Jakarta")
|
||||
if err != nil {
|
||||
return dto.CustomerPaymentReportItem{}, err
|
||||
}
|
||||
|
||||
customerDTO := customerDTO.CustomerRelationDTO{
|
||||
Id: customer.Id,
|
||||
Name: customer.Name,
|
||||
Type: customer.Type,
|
||||
AccountNumber: customer.AccountNumber,
|
||||
Balance: customer.Balance,
|
||||
var startDate, endDate *time.Time
|
||||
if params.StartDate != "" {
|
||||
parsed, err := time.ParseInLocation("2006-01-02", params.StartDate, location)
|
||||
if err != nil {
|
||||
return dto.CustomerPaymentReportItem{}, err
|
||||
}
|
||||
startDate = &parsed
|
||||
}
|
||||
if params.EndDate != "" {
|
||||
parsed, err := time.ParseInLocation("2006-01-02", params.EndDate, location)
|
||||
if err != nil {
|
||||
return dto.CustomerPaymentReportItem{}, err
|
||||
}
|
||||
// End date should be inclusive, so set to end of day
|
||||
endOfDay := time.Date(parsed.Year(), parsed.Month(), parsed.Day(), 23, 59, 59, 999999999, location)
|
||||
endDate = &endOfDay
|
||||
}
|
||||
|
||||
for _, row := range rows {
|
||||
transDate := row.TransDate.In(location)
|
||||
|
||||
// Check if transaction date is within range
|
||||
if startDate != nil && transDate.Before(*startDate) {
|
||||
continue
|
||||
}
|
||||
if endDate != nil && transDate.After(*endDate) {
|
||||
continue
|
||||
}
|
||||
|
||||
filteredRows = append(filteredRows, row)
|
||||
}
|
||||
|
||||
rows = filteredRows
|
||||
}
|
||||
|
||||
summary := dto.CalculateCustomerPaymentSummary(rows, initialBalance)
|
||||
|
||||
return dto.CustomerPaymentReportItem{
|
||||
Customer: customerDTO,
|
||||
Customer: customerDTO.ToCustomerRelationDTO(customer),
|
||||
InitialBalance: initialBalance,
|
||||
Rows: rows,
|
||||
Summary: summary,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *repportService) calculateSummary(rows []dto.CustomerPaymentReportRow, initialBalance float64) dto.CustomerPaymentReportSummary {
|
||||
summary := dto.CustomerPaymentReportSummary{}
|
||||
|
||||
for _, row := range rows {
|
||||
summary.TotalQty += row.Qty
|
||||
summary.TotalWeight += row.Weight
|
||||
summary.TotalCreditNote += row.CreditNote
|
||||
summary.TotalPPN += row.PPN
|
||||
|
||||
if row.TransactionType == "SALES" {
|
||||
summary.TotalInitialAmount += row.TotalPrice
|
||||
summary.TotalFinalAmount += row.FinalPrice
|
||||
summary.TotalGrandAmount += row.TotalPrice
|
||||
} else if row.TransactionType == "PAYMENT" {
|
||||
summary.TotalPayment += row.PaymentAmount
|
||||
}
|
||||
}
|
||||
|
||||
// Formula: Total AR = Initial Balance - Total Sales + Total Payment
|
||||
// - Initial balance: positive (customer deposit)
|
||||
// - Sales: reduces balance (customer debt)
|
||||
// - Payment: increases balance (customer pays)
|
||||
summary.TotalAccountsReceivable = initialBalance - summary.TotalGrandAmount + summary.TotalPayment
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func (s *repportService) determineSalesStatusAndPaymentDate(transactions []repportRepo.CustomerPaymentTransaction, currentIndex int, previousBalance, currentBalance float64) (string, *time.Time) {
|
||||
currentSales := transactions[currentIndex]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user