feat(distribution): 补齐退款加价回退、本站自卖与开通默认规则
退款时压缩卖方加价,人工/自动批次仅完结单可入账,号主收入进主站钱包;仲裁后重算释放并支持作废未入账 DS。开通时四种模式按默认生效,对外口径合并为 35/40/25,不再单独展示通道费。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -97,13 +97,46 @@ func DefaultRule(mode string) (Rule, error) {
|
||||
base.DistributorARatio = DefaultReceivePercent
|
||||
base.DistributorBRatio = DefaultSellPercent
|
||||
case ModeSiteSelfSell:
|
||||
return Rule{}, ErrUnsupportedMode
|
||||
base.DistributorSellRatio = DefaultReceivePercent + DefaultSellPercent
|
||||
default:
|
||||
return Rule{}, ErrUnsupportedMode
|
||||
}
|
||||
return base, nil
|
||||
}
|
||||
|
||||
// ValidateRule 校验模式,并在百分比服务费下要求收号+卖出+服务费合计为 100。
|
||||
func ValidateRule(rule Rule) error {
|
||||
normalizeRulePercents(&rule)
|
||||
if _, err := DefaultRule(rule.Mode); err != nil {
|
||||
return ErrUnsupportedMode
|
||||
}
|
||||
unit := rule.ServiceFeeUnit
|
||||
if unit == "" || unit == ServiceFeeUnitRatio {
|
||||
unit = ServiceFeeUnitPercent
|
||||
}
|
||||
if unit != ServiceFeeUnitPercent && unit != ServiceFeeUnitFixedAmount {
|
||||
return ErrInvalidServiceUnit
|
||||
}
|
||||
if unit != ServiceFeeUnitPercent {
|
||||
return nil
|
||||
}
|
||||
var sum float64
|
||||
switch rule.Mode {
|
||||
case ModeTwoPartyDistributorReceive:
|
||||
sum = rule.DistributorReceiveRatio + rule.PlatformSellRatio + rule.ServiceFeeValue
|
||||
case ModeTwoPartyPlatformReceive:
|
||||
sum = rule.PlatformReceiveRatio + rule.DistributorSellRatio + rule.ServiceFeeValue
|
||||
case ModeThreeParty:
|
||||
sum = rule.DistributorARatio + rule.DistributorBRatio + rule.ServiceFeeValue
|
||||
case ModeSiteSelfSell:
|
||||
sum = rule.DistributorSellRatio + rule.ServiceFeeValue
|
||||
}
|
||||
if math.Abs(sum-100) > 0.15 {
|
||||
return ErrInvalidRate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NormalizeSplitPercent 把口头 3.5/4/2.5 换成 35/40/25;已经是百分数的原样保留。
|
||||
func NormalizeSplitPercent(value float64) float64 {
|
||||
if value <= 0 || math.IsNaN(value) || math.IsInf(value, 0) {
|
||||
@@ -147,7 +180,8 @@ func CalculateSettlement(rule Rule, input SettlementInput) (SettlementResult, er
|
||||
}
|
||||
netPaid := input.GrossPaidAmountCent - input.RefundAmountCent
|
||||
paymentFee := roundHalfUp(float64(netPaid) * float64(rule.PaymentFeeBPS) / 10000)
|
||||
profit := netPaid - input.OwnerRentAmountCent - input.MarkupAmountCent
|
||||
effectiveMarkup := EffectiveMarkupCent(netPaid, input.OwnerRentAmountCent, input.MarkupAmountCent)
|
||||
profit := netPaid - input.OwnerRentAmountCent - effectiveMarkup
|
||||
if profit < 0 {
|
||||
profit = 0
|
||||
}
|
||||
@@ -164,7 +198,7 @@ func CalculateSettlement(rule Rule, input SettlementInput) (SettlementResult, er
|
||||
NetPaidAmountCent: netPaid,
|
||||
PaymentFeeCent: paymentFee,
|
||||
ServiceFeeCent: serviceFee,
|
||||
MarkupAmountCent: input.MarkupAmountCent,
|
||||
MarkupAmountCent: effectiveMarkup,
|
||||
SplitBaseAmountCent: profit,
|
||||
}
|
||||
if rule.TaxEnabled {
|
||||
@@ -206,6 +240,25 @@ func maxInt64(a, b int64) int64 {
|
||||
return b
|
||||
}
|
||||
|
||||
func minInt64(a, b int64) int64 {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// EffectiveMarkupCent 按剩余净付款压缩加价:全额退租金后卖方不得再留加价。
|
||||
func EffectiveMarkupCent(netPaid, ownerRent, markup int64) int64 {
|
||||
if markup <= 0 {
|
||||
return 0
|
||||
}
|
||||
remain := netPaid - ownerRent
|
||||
if remain <= 0 {
|
||||
return 0
|
||||
}
|
||||
return minInt64(markup, remain)
|
||||
}
|
||||
|
||||
// PartySplit 是一次分成拆分中单个参与方的金额。
|
||||
type PartySplit struct {
|
||||
PartyRole string
|
||||
@@ -236,6 +289,11 @@ func SplitSettlement(rule Rule, profitCent int64, markupCent int64) []PartySplit
|
||||
role string
|
||||
ratio float64
|
||||
}{{"distributor_a", rule.DistributorARatio}, {"distributor_b", rule.DistributorBRatio}}
|
||||
case ModeSiteSelfSell:
|
||||
roles = []struct {
|
||||
role string
|
||||
ratio float64
|
||||
}{{"distributor_sell", rule.DistributorSellRatio}}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user