feat: add percentage loyalti setting mode
This commit is contained in:
+29
-10
@@ -5,6 +5,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"apskel-pos-be/internal/constants"
|
||||
)
|
||||
|
||||
// OutletLoyaltySettings are an outlet's loyalty settings (docs/prd-point-coin.md F1).
|
||||
@@ -15,15 +17,23 @@ type OutletLoyaltySettings struct {
|
||||
PointPayment LoyaltyPointPaymentSettings `json:"point_payment"`
|
||||
}
|
||||
|
||||
// LoyaltyEarnSettings is how much of one currency an order earns:
|
||||
// floor(basis / EarnPerAmount) × EarnValue, nothing below MinOrderAmount, and at most
|
||||
// MaxPerOrder when set.
|
||||
// LoyaltyEarnSettings is how much of one currency an order earns, nothing below
|
||||
// MinOrderAmount, and at most MaxPerOrder when set:
|
||||
//
|
||||
// - PER_AMOUNT: floor(basis / EarnPerAmount) × EarnValue;
|
||||
// - PERCENTAGE: floor(basis × EarnPercent / 100).
|
||||
//
|
||||
// The settings of the mode not in use are kept, so switching back restores them.
|
||||
type LoyaltyEarnSettings struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
EarnPerAmount int64 `json:"earn_per_amount"`
|
||||
EarnValue int64 `json:"earn_value"`
|
||||
MinOrderAmount int64 `json:"min_order_amount"`
|
||||
MaxPerOrder *int64 `json:"max_per_order"`
|
||||
Enabled bool `json:"enabled"`
|
||||
// PER_AMOUNT or PERCENTAGE.
|
||||
EarnMode string `json:"earn_mode"`
|
||||
EarnPerAmount int64 `json:"earn_per_amount"`
|
||||
EarnValue int64 `json:"earn_value"`
|
||||
// PERCENTAGE: percent of the basis earned, 0–100 with at most two decimals.
|
||||
EarnPercent float64 `json:"earn_percent"`
|
||||
MinOrderAmount int64 `json:"min_order_amount"`
|
||||
MaxPerOrder *int64 `json:"max_per_order"`
|
||||
}
|
||||
|
||||
type LoyaltyPointPaymentSettings struct {
|
||||
@@ -102,8 +112,8 @@ type OutletLoyaltySettingsView struct {
|
||||
// The organization's rupiah value of one EnakPoint, which the cashback depends on.
|
||||
PointValue int64 `json:"point_value"`
|
||||
// Effective EnakPoint cashback in percent: earn_value × point_value /
|
||||
// earn_per_amount × 100. Shown next to the setting so an owner cannot misread the
|
||||
// scale (F1).
|
||||
// earn_per_amount × 100, or earn_percent × point_value in PERCENTAGE mode. Shown
|
||||
// next to the setting so an owner cannot misread the scale (F1).
|
||||
PointCashbackPercent float64 `json:"point_cashback_percent"`
|
||||
// Set on PUT: the keys that changed.
|
||||
Changes []LoyaltySettingChange `json:"changes,omitempty"`
|
||||
@@ -168,6 +178,15 @@ type LoyaltySettingsImpact struct {
|
||||
CoinRupiahAfter int64 `json:"coin_rupiah_after"`
|
||||
}
|
||||
|
||||
// CashbackPercent is the rupiah value of what an order earns as a percentage of its
|
||||
// basis, in the mode the settings are in, rounded to two decimals.
|
||||
func (s LoyaltyEarnSettings) CashbackPercent(pointValue int64) float64 {
|
||||
if s.EarnMode == constants.LoyaltyEarnModePercentage {
|
||||
return math.Round(s.EarnPercent*float64(pointValue)*100) / 100
|
||||
}
|
||||
return LoyaltyCashbackPercent(s.EarnValue, pointValue, s.EarnPerAmount)
|
||||
}
|
||||
|
||||
// NewLoyaltySettingsImpact computes the impact of moving from one organization setting
|
||||
// to another on the balances in circulation.
|
||||
func NewLoyaltySettingsImpact(points, coins int64, before, after OrganizationLoyaltySettings) LoyaltySettingsImpact {
|
||||
|
||||
Reference in New Issue
Block a user