feat(loyalty): report EnakPoint apart from money received

Keeps EnakPoint out of the money in on the payment method analytics
(docs/prd-point-coin.md F9, K7, PC-308), the one report that sums payments;
the daily transaction and profit-loss PDFs do not break payments down by
method.

summary.total_amount is now only money actually received. EnakPoint stays
listed as its own method, with points_used, and the summary adds
point_amount, points_used and total_with_points. Each method row says
whether it counts_as_cash_in, and the shares are of the money received, 0
for EnakPoint. The average order value still includes what EnakPoint paid,
since that is part of what the orders were worth. How EnakPoint is booked
waits on note N2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
efrilm
2026-09-30 11:59:33 +07:00
co-authored by Claude Opus 5.5
parent d7138b8f87
commit 0b52edf84e
8 changed files with 136 additions and 35 deletions
+19 -8
View File
@@ -33,7 +33,14 @@ type PaymentMethodAnalyticsResponse struct {
// PaymentMethodSummary represents the summary of payment method analytics
type PaymentMethodSummary struct {
TotalAmount float64 `json:"total_amount"`
// Money actually received. EnakPoint is not money in (docs/prd-point-coin.md F9,
// K7) and is reported apart; its accounting treatment waits on note N2.
TotalAmount float64 `json:"total_amount"`
// Rupiah paid with EnakPoint, and how many EnakPoint that was.
PointAmount float64 `json:"point_amount"`
PointsUsed int64 `json:"points_used"`
// TotalAmount plus PointAmount: the value of the orders paid.
TotalWithPoints float64 `json:"total_with_points"`
TotalOrders int64 `json:"total_orders"`
TotalPayments int64 `json:"total_payments"`
AverageOrderValue float64 `json:"average_order_value"`
@@ -47,7 +54,11 @@ type PaymentMethodAnalyticsData struct {
TotalAmount float64 `json:"total_amount"`
OrderCount int64 `json:"order_count"`
PaymentCount int64 `json:"payment_count"`
Percentage float64 `json:"percentage"`
// Share of the money received; 0 for EnakPoint, which is not money in.
Percentage float64 `json:"percentage"`
PointsUsed int64 `json:"points_used"`
// False for EnakPoint.
CountsAsCashIn bool `json:"counts_as_cash_in"`
}
// SalesAnalyticsRequest represents the request for sales analytics
@@ -464,12 +475,12 @@ type ProfitLossAnalyticsResponse struct {
}
type ProfitLossPurchasing struct {
TodayTotal float64 `json:"today_total"`
MtdTotal float64 `json:"mtd_total"`
TodayRawMaterial float64 `json:"today_raw_material"`
MtdRawMaterial float64 `json:"mtd_raw_material"`
TodayExpense float64 `json:"today_expense"`
MtdExpense float64 `json:"mtd_expense"`
TodayTotal float64 `json:"today_total"`
MtdTotal float64 `json:"mtd_total"`
TodayRawMaterial float64 `json:"today_raw_material"`
MtdRawMaterial float64 `json:"mtd_raw_material"`
TodayExpense float64 `json:"today_expense"`
MtdExpense float64 `json:"mtd_expense"`
Items []ProfitLossPurchasingItem `json:"items"`
}