我正在使用Ruby on Rails构建一个复杂的计费系统。我有Invoice
模型,其中包含许多项目和付款。当paid_cents
大于或等于total_cents
时,会将发票视为已付款。
一切正常,直到我加入对滞纳金的支持。显然,这些费用只应在未支付发票时计算。例如,如果发票在2014-01-01到期,已在2014-01-05支付,今天是2014-01-24,则费用应仅计算4天。
为了实现这一目标,我在late_days
方法中添加了一项检查,如果paid_cents
大于或等于total_cents
,则返回0并且之前已付款发票到期日。
问题在于:total_cents
计算项目的金额和滞纳金。反过来,late_fee_cents
方法调用late_days
依赖total_cents
来检查发票是否已付款。
这会产生一个无限循环,其中方法会相互调用直到时间结束(或有人拉动插件)。
以下是我的模型中的一些代码:
def daily_late_fee_percentage
return 0 unless late_fee_percentage && late_fee_interval
late_fee_percentage.to_f / late_fee_interval.to_f
end
def daily_late_fee_cents
incomplete_total_cents.to_f / 100.0 * daily_late_fee_percentage
end
def late_days
return 0 unless due_at
days = Date.today - due_at
days = 0 if days < 0
days.to_i
end
def late_fee_cents
daily_late_fee_cents * late_days
end
def total_cents
incomplete_total_cents + late_fee_cents
end
我觉得我完全错过了一些明显的东西。
非常感谢任何帮助!
答案 0 :(得分:1)
应该如何计算late_fee_cents
?它只是发票初始“总分”的一小部分,不包括“延迟费用”乘以发票逾期的天数,还是初始总分加上滞纳金乘以发票逾期天数的一小部分? / p>
如果前者是真的,那么这可能有效:
我们可以像这样定义total_cents
:
def total_cents(include_late_fees = true)
include_late_fees ? incomplete_total_cents + late_fee_cents : incomplete_total_cents
end
late_days
就像这样:
def late_days
return 0 unless due_at
return 0 if paid_cents >= total_cents(false) && (payments.last.try(:delivered_at) || due_at) <= due_at
days = Date.today - due_at
days = 0 if days < 0
days.to_i
end
请注意,late_days
我们正在使用total_cents(false)
。
这应该消除infitie循环。
如果后者属实,那么首先写下计算总发票费用的确切数学公式,包括滞纳金并确保 它没有无限递归。公式可能包含sigma(Σ)或(Π)表达式。
然后将其转换为代码应该很容易。
我认为你想要实现的目的主要是收取债务利息(逾期费用)。这类似于计算compound interest。