public void WithDraw(decimal value, DateTime date, string description, int fundID, int reserveID, string userId) { // verify balance using (FinancialQueries queries = new FinancialQueries(Context)) { decimal balance = queries.GetBalance(date, userId, fundID, reserveID); if (balance - value < 0) { throw new Exception("There is no balance for this transaction."); } } Operation operation = new Operation() { TotalValue = -value, Description = description, Date = date, Type = EOperationType.Withdraw, UserId = userId, Transactions = new List <Transaction>() }; Transaction trans = new Transaction() { ReserveID = reserveID, FundID = fundID, Value = -value }; operation.Transactions.Add(trans); Context.Operations.Add(operation); Context.SaveChanges(); }
public void Deposit(decimal value, Dictionary <int, decimal> balancesBeforeDeposit, DateTime date, string description, int?fundId, int?reserveId, int?distributionRuleId, string userId) { if (balancesBeforeDeposit != null) { foreach (var balancefund in balancesBeforeDeposit) { var q = new FinancialQueries(Context); var fundBal = q.GetBalance(date, userId, balancefund.Key); UpdateBalance(balancefund.Value - fundBal, balancefund.Key, date, userId); } } IEnumerable <DistributionPercentage> dp = (distributionRuleId.HasValue && distributionRuleId != -1) ? Context.DistributionPercentages.Where(d => d.DistributionRuleId == distributionRuleId) : null; Operation operation = new Operation() { TotalValue = value, Description = description, Date = date, Type = EOperationType.Deposit, UserId = userId, Transactions = new List <Transaction>() }; if (dp == null) { Transaction trans = new Transaction() { ReserveID = reserveId.Value, FundID = fundId.Value, Value = value }; operation.Transactions.Add(trans); } else { List <Transaction> transactionList = new List <Transaction>(); foreach (var percentageRule in dp) { Transaction trans = new Transaction() { ReserveID = percentageRule.ReserveID, FundID = percentageRule.FundID.HasValue ? percentageRule.FundID.Value : fundId.Value, Value = value * percentageRule.Percentage }; operation.Transactions.Add(trans); } } Context.Operations.Add(operation); Context.SaveChanges(); }
public void UpdateBalance(decimal profitAmount, int fundId, DateTime updateDate, string userId) { Dictionary <int, decimal> profitPerReserve = new Dictionary <int, decimal>(); using (FinancialQueries queries = new FinancialQueries(Context)) { List <Reserve> existingReserves = queries.GetReserves(userId); foreach (var reserve in existingReserves) { profitPerReserve.Add(reserve.ID, 0); } decimal currentBalance = queries.GetBalance(updateDate, userId, fundId: fundId); if (profitAmount == 0) { return; } DateTime?lastBalanceUpdate = queries.GetLastBalanceUpdate(fundId); if (lastBalanceUpdate == null) { throw new Exception("It's not possible to update the balance without any transaction."); } if (lastBalanceUpdate >= updateDate) { throw new Exception("It's not possible to update the balance before the last balance update date."); } int profitActionInterval = (int)updateDate.Date.Subtract(lastBalanceUpdate.Value.Date).TotalDays; List <DateTime> thresholds = Context.Transactions.Where(t => t.Operation.Date > lastBalanceUpdate && t.Operation.Date < updateDate && t.FundID == fundId).Select(t => t.Operation.Date).Distinct().ToList(); for (int i = 0; i <= thresholds.Count; i++) { DateTime ini = i == 0 ? lastBalanceUpdate.Value : thresholds[i - 1]; DateTime fim = i == thresholds.Count ? updateDate : thresholds[i]; int interv = (int)fim.Subtract(ini).TotalDays; decimal fundBalance = queries.GetBalance(ini, userId, fundId); foreach (var reserve in existingReserves) { decimal reserveBalance = queries.GetBalance(ini, userId, fundId, reserve.ID); decimal reserveProportion = fundBalance > 0 ? (reserveBalance / fundBalance) : ((decimal)1 / existingReserves.Count); profitPerReserve[reserve.ID] += profitAmount * reserveProportion * ((decimal)interv / profitActionInterval); } } } Operation operation = new Operation() { TotalValue = profitAmount, Date = updateDate, Type = EOperationType.BalanceUpdate, UserId = userId, Transactions = new List <Transaction>() }; foreach (var reserveProfit in profitPerReserve) { if (reserveProfit.Value == 0) { continue; } Transaction trans = new Transaction() { ReserveID = reserveProfit.Key, FundID = fundId, Value = reserveProfit.Value }; operation.Transactions.Add(trans); } Context.Operations.Add(operation); Context.SaveChanges(); }