示例#1
0
        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);
        }
示例#2
0
        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);
        }