public Progress ReadPayments(string contractAddress) { PensionFund pensionFund = PensionFundBusiness.GetByContract(contractAddress); string cacheKey = GetCachePaymentKey(contractAddress); List <Payment> cachedPayment = MemoryCache.Get <List <Payment> >(cacheKey); if (cachedPayment != null && cachedPayment.Count == 120) { return(PensionFundBusiness.GetProgress(pensionFund, cachedPayment)); } SmartContract smartContract = SmartContractBusiness.GetDefaultDemonstrationPensionFund(); IEnumerable <PensionFundTransaction> transactions = Data.List(pensionFund.Option.PensionFundContract.TransactionHash). Where(c => c.FunctionType == FunctionType.EmployeeBuy || c.FunctionType == FunctionType.CompanyBuy); IEnumerable <PensionFundTransaction> pendingCreateTransactions = transactions.Where(c => string.IsNullOrEmpty(c.TransactionHash)); IEnumerable <PensionFundTransaction> pendingCompleteTransactions = transactions.Where(c => !c.BlockNumber.HasValue && !string.IsNullOrEmpty(c.TransactionHash)); if (!transactions.Any()) { return(PensionFundBusiness.GetProgress(pensionFund, new List <Payment>())); } else if (cachedPayment != null && cachedPayment.Count == transactions.Count()) { return(PensionFundBusiness.GetProgress(pensionFund, cachedPayment)); } else if (cachedPayment != null && (cachedPayment.Count + pendingCreateTransactions.Count()) == transactions.Count()) { transactions = HandleTransactions(smartContract, pensionFund, transactions, pendingCreateTransactions, pendingCompleteTransactions, new BaseEventInfo[] { }); return(PensionFundBusiness.GetProgress(pensionFund, pendingCreateTransactions.Select(c => new Payment() { CreatedDate = c.CreationDate, Responsable = c.WalletAddress }).Concat(cachedPayment))); } List <BuyInfo> buyEvents = EthereumManager.ReadBuyFromDefaultPensionFund(contractAddress); transactions = HandleTransactions(smartContract, pensionFund, transactions, pendingCreateTransactions, pendingCompleteTransactions, buyEvents.Select(c => new BaseEventInfo() { BlockNumber = c.BlockNumber, TransactionHash = c.TransactionHash })); List <Payment> completedPayments = new List <Payment>(); if (buyEvents.Count > 0) { foreach (PensionFundTransaction trans in transactions) { BuyInfo buyInfo = buyEvents.SingleOrDefault(c => c.TransactionHash == trans.TransactionHash); if (buyInfo != null) { completedPayments.Add(new Payment() { TransactionHash = trans.TransactionHash, CreatedDate = trans.CreationDate, Responsable = trans.WalletAddress, BlockNumber = buyInfo.BlockNumber, Period = buyInfo.Period, AuctusFee = buyInfo.AuctusFee, LatePenalty = buyInfo.LatePenalty, PensionFundFee = buyInfo.PensionFundFee, SzaboInvested = buyInfo.SzaboInvested, TokenAmount = buyInfo.TokenAmount, DaysOverdue = buyInfo.DaysOverdue, ReferenceDate = pensionFund.Option.PensionFundContract.CreationDate.AddMonths(buyInfo.Period).Date }); } } if (completedPayments.Count > 0) { MemoryCache.Set <List <Payment> >(cacheKey, completedPayments); } } IEnumerable <Payment> remainingPayments = transactions.Where(c => string.IsNullOrEmpty(c.TransactionHash) || !completedPayments.Any(l => l.TransactionHash == c.TransactionHash)).Select(c => new Payment() { TransactionHash = c.TransactionHash, CreatedDate = c.CreationDate, Responsable = c.WalletAddress }); return(PensionFundBusiness.GetProgress(pensionFund, remainingPayments.Concat(completedPayments))); }
public Progress GeneratePayment(string contractAddress, int monthsAmount) { if (monthsAmount < 1 || monthsAmount > 60) { throw new InvalidOperationException("Invalid months amount."); } PensionFund pensionFund = PensionFundBusiness.GetByContract(contractAddress); SmartContract smartContract = SmartContractBusiness.GetDefaultDemonstrationPensionFund(); List <PensionFundTransaction> transactions = Data.List(pensionFund.Option.PensionFundContract.TransactionHash); int payments = transactions.Count(c => c.ContractFunctionId == FunctionType.CompanyBuy.Type || c.ContractFunctionId == FunctionType.EmployeeBuy.Type); if (payments == 120) { throw new InvalidOperationException("All payments already been made."); } else if (payments + (monthsAmount * 2) > 120) { throw new InvalidOperationException("Too many payments."); } else if (transactions.Any(c => c.FunctionType == FunctionType.CompleteWithdrawal)) { throw new InvalidOperationException("Withdrawal already made."); } List <PensionFundTransaction> newTransactions = new List <PensionFundTransaction>(); Parallel.For(1, monthsAmount + 1, new ParallelOptions() { MaxDegreeOfParallelism = 5 }, month => { DateTime date = DateTime.UtcNow; newTransactions.Add(CreateTransaction(date, FunctionType.EmployeeBuy, pensionFund.Option.Company.Employee.Address, pensionFund.Option.PensionFundContract.TransactionHash)); newTransactions.Add(CreateTransaction(date, FunctionType.CompanyBuy, pensionFund.Option.Company.Address, pensionFund.Option.PensionFundContract.TransactionHash)); }); GeneratePaymentContractTransaction(newTransactions, pensionFund, smartContract); IEnumerable <Payment> newPayments = newTransactions.Select(c => new Payment() { CreatedDate = c.CreationDate, Responsable = c.WalletAddress }); if (payments == 0) { return(PensionFundBusiness.GetProgress(pensionFund, newPayments.ToList())); } else { List <Payment> cachedPayment = MemoryCache.Get <List <Payment> >(GetCachePaymentKey(contractAddress)); if (cachedPayment != null && cachedPayment.Count == payments) { return(PensionFundBusiness.GetProgress(pensionFund, newPayments.Concat(cachedPayment))); } else { return(ReadPayments(contractAddress)); } } }