public PaymentMethodAccounting Calculate(Func <PaymentEntity, bool> paymentPredicate = null) { paymentPredicate = paymentPredicate ?? new Func <PaymentEntity, bool>((p) => true); var paymentMethods = ParentEntity.GetPaymentMethods(null); var totalDue = ParentEntity.ProductInformation.Price / Rate; var paid = 0m; var cryptoPaid = 0.0m; int precision = 8; var totalDueNoNetworkCost = Money.Coins(Extensions.RoundUp(totalDue, precision)); bool paidEnough = paid >= Extensions.RoundUp(totalDue, precision); int txRequired = 0; var payments = ParentEntity.GetPayments() .Where(p => p.Accounted && paymentPredicate(p)) .OrderBy(p => p.ReceivedTime) .Select(_ => { var txFee = _.GetValue(paymentMethods, GetId(), paymentMethods[_.GetPaymentMethodId()].GetTxFee()); paid += _.GetValue(paymentMethods, GetId()); if (!paidEnough) { totalDue += txFee; } paidEnough |= Extensions.RoundUp(paid, precision) >= Extensions.RoundUp(totalDue, precision); if (GetId() == _.GetPaymentMethodId()) { cryptoPaid += _.GetCryptoPaymentData().GetValue(); txRequired++; } return(_); }) .ToArray(); var accounting = new PaymentMethodAccounting(); accounting.TxCount = txRequired; if (!paidEnough) { txRequired++; totalDue += GetTxFee(); } accounting.TotalDue = Money.Coins(Extensions.RoundUp(totalDue, precision)); accounting.Paid = Money.Coins(Extensions.RoundUp(paid, precision)); accounting.TxRequired = txRequired; accounting.CryptoPaid = Money.Coins(Extensions.RoundUp(cryptoPaid, precision)); accounting.Due = Money.Max(accounting.TotalDue - accounting.Paid, Money.Zero); accounting.DueUncapped = accounting.TotalDue - accounting.Paid; accounting.NetworkFee = accounting.TotalDue - totalDueNoNetworkCost; accounting.MinimumTotalDue = Money.Max(Money.Satoshis(1), Money.Satoshis(accounting.TotalDue.Satoshi * (1.0m - ((decimal)ParentEntity.PaymentTolerance / 100.0m)))); return(accounting); }
public PaymentMethodAccounting Calculate(Func <PaymentEntity, bool> paymentPredicate = null) { paymentPredicate = paymentPredicate ?? new Func <PaymentEntity, bool>((p) => true); var paymentMethods = ParentEntity.GetPaymentMethods(); var totalDue = ParentEntity.ProductInformation.Price / Rate; var paid = 0m; var bitcoinPaid = 0.0m; int precision = Network?.Divisibility ?? 8; var totalDueNoNetworkCost = Money.Coins(Extensions.RoundUp(totalDue, precision)); bool paidEnough = paid >= Extensions.RoundUp(totalDue, precision); int txRequired = 0; _ = ParentEntity.GetPayments() .Where(p => p.Accounted && paymentPredicate(p)) .OrderBy(p => p.ReceivedTime) .Select(_ => { var txFee = _.GetValue(paymentMethods, GetId(), _.NetworkFee, precision); paid += _.GetValue(paymentMethods, GetId(), null, precision); if (!paidEnough) { totalDue += txFee; } paidEnough |= Extensions.RoundUp(paid, precision) >= Extensions.RoundUp(totalDue, precision); if (GetId() == _.GetPaymentMethodId()) { bitcoinPaid += _.GetbitcoinPaymentData().GetValue(); txRequired++; } return(_); }).ToArray(); var accounting = new PaymentMethodAccounting(); accounting.TxCount = txRequired; if (!paidEnough) { txRequired++; totalDue += GetTxFee(); } accounting.TotalDue = Money.Coins(Extensions.RoundUp(totalDue, precision)); accounting.Paid = Money.Coins(Extensions.RoundUp(paid, precision)); accounting.TxRequired = txRequired; accounting.bitcoinPaid = Money.Coins(Extensions.RoundUp(bitcoinPaid, precision)); accounting.Due = Money.Max(accounting.TotalDue - accounting.Paid, Money.Zero); accounting.DueUncapped = accounting.TotalDue - accounting.Paid; accounting.NetworkFee = accounting.TotalDue - totalDueNoNetworkCost; // If the total due is 0, there is no payment tolerance to calculate var minimumTotalDueSatoshi = accounting.TotalDue.Satoshi == 0 ? 0 : Math.Max(1.0m, accounting.TotalDue.Satoshi * (1.0m - ((decimal)ParentEntity.PaymentTolerance / 100.0m))); accounting.MinimumTotalDue = Money.Satoshis(minimumTotalDueSatoshi); return(accounting); }