37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# File 'lib/exocrypto/crypto_calc.rb', line 37
def self.do_partial_payments(request, payments)
epoch = ExoBasic::Timer::EPOCH.to_datetime
xs = payments.map do |payment|
if payment[:paid]
precision = Bip44WalletProvider.precision_of(payment[:currency])
satoshis = BigDecimal(payment[:amount_paid]) * BigDecimal(payment[:exchange_rate])
[satoshis / BigDecimal(10 ** precision), payment[:date]]
else
[BigDecimal(0), epoch]
end
end
total_paid = xs.map { |x| x[0] }.sum
paid_date = xs.map { |x| x[1] }.max
if paid_date == epoch
paid_date = nil
end
request_amount = request[:amount]
request_precision = request[:precision]
total_paid_rounded_s = CryptoCalc.fixed_length_to_s(total_paid.round(request_precision),
request_precision)
remaining = BigDecimal(request[:amount]) - BigDecimal(total_paid_rounded_s)
remaining_rounded_s = CryptoCalc.fixed_length_to_s(remaining.round(request_precision),
request_precision)
n_paid = payments.select { |payment| payment[:paid] == true }.length
n_unpaid = payments.length - n_paid
remaining_rounded = BigDecimal(remaining_rounded_s)
needs_change = remaining_rounded < BigDecimal(0)
is_fully_paid = remaining_rounded.zero? || needs_change
is_partially_paid = !is_fully_paid && remaining_rounded < BigDecimal(request_amount)
{
:n_paid => n_paid,
:n_unpaid => n_unpaid,
:paid_date => paid_date,
:amount_paid => total_paid_rounded_s,
:amount_remaining => remaining_rounded_s,
:overpaid => needs_change,
:is_fully_paid => is_fully_paid,
:is_partially_paid => is_partially_paid
}
end
|