public bool UpdatePositionPymtDueFlags(List <PositionsForPaymentDueVm> sourcePositionsInfo, bool isPersisted = false) { // Received sourcePositionsInfo may contain either: // 1. data-imported month-end XLSX revenue processed Position Ids, OR // 2. selected 'Income Due' Positions marked for pending payment processing; selection(s) may also include * delinquent positions *. bool updatesAreOk = false; List <Data.Entities.Position> targetPositionsToUpdate = new List <Data.Entities.Position>(); IList <DelinquentIncome> delinquentPositions = new List <DelinquentIncome>(); int positionsUpdatedCount = 0; // Parameter context: // isPersisted: false - income received, but not yet recorded/saved, e.g., processing payment(s) via 'Income Due'. // isPersisted: true - income received & recorded/saved, and is now eligible for next receivable cycle, e.g., XLSX via 'Data Import'. if (!isPersisted) { // Any delinquent records will appear first. var sourcePositionsInfoSorted = sourcePositionsInfo.OrderBy(p => p.TickerSymbol).ThenBy(p => p.MonthDue); foreach (var selectedPosition in sourcePositionsInfoSorted) { // If selected Position is overdue, then -> delete from 'DelinquentIncome' table. if (int.Parse(selectedPosition.MonthDue) < DateTime.Now.Month) { DelinquentIncome delinquentIncomeToDelete = new DelinquentIncome { PositionId = selectedPosition.PositionId, TickerSymbol = selectedPosition.TickerSymbol, MonthDue = selectedPosition.MonthDue, InvestorId = FetchInvestorId(selectedPosition.PositionId) }; // If we have *duplicate* selected PositionIds, e.g., 1 current & 1 delinquent, then delete the delinquent record // first, so that 'DelinquentIncome' table is updated real-time. int duplicatePositionIdCount = sourcePositionsInfoSorted.Where(di => di.PositionId == selectedPosition.PositionId).Count(); if (duplicatePositionIdCount == 1) { delinquentPositions.Add(delinquentIncomeToDelete); } else { IList <DelinquentIncome> tempDelinquentPositions = new List <DelinquentIncome> { delinquentIncomeToDelete }; RemoveDelinquency(tempDelinquentPositions); } } else { // Mark Position(s) as paid, if no outstanding delinquencies. IList <DelinquentIncome> delinquentPositionsFound = _ctx.DelinquentIncome.Where(d => d.PositionId == selectedPosition.PositionId).ToList(); if (!delinquentPositionsFound.Any()) { Data.Entities.Position targetPositionToUpdate = _ctx.Position.Where(p => p.PositionId == selectedPosition.PositionId).First(); targetPositionToUpdate.PymtDue = false; targetPositionToUpdate.LastUpdate = DateTime.Now; targetPositionsToUpdate.Add(targetPositionToUpdate); } } } if (delinquentPositions.Any()) { updatesAreOk = RemoveDelinquency(delinquentPositions); } if (targetPositionsToUpdate.Any()) { updatesAreOk = UpdateTargetPositions(targetPositionsToUpdate); } } else { string currentInvestorId = FetchInvestorId(sourcePositionsInfo.First().PositionId); delinquentPositions = GetSavedDelinquentRecords(currentInvestorId, ""); int positionsNotUpdatedCount = 0; // Loop thru each XLSX position within the month-end collection & determine if it's eligible for updating its' 'PymtDue' flag. // debug -> existing PosId delinquency: 0481727F-737E-4775-870A-A8F20118F977 for PICB foreach (PositionsForPaymentDueVm xlsxPosition in sourcePositionsInfo) { IList <DelinquentIncome> existingDelinquentPositions = delinquentPositions.Where(p => p.PositionId == xlsxPosition.PositionId).ToList(); if (existingDelinquentPositions.Any()) { positionsNotUpdatedCount++; continue; } else { Data.Entities.Position positionToUpdate = _ctx.Position.Where(p => p.PositionId == xlsxPosition.PositionId).First(); positionToUpdate.PymtDue = true; positionToUpdate.LastUpdate = DateTime.Now; targetPositionsToUpdate.Add(positionToUpdate); } } if (targetPositionsToUpdate.Any()) { _ctx.UpdateRange(targetPositionsToUpdate); positionsUpdatedCount = _ctx.SaveChanges(); if (positionsUpdatedCount + positionsNotUpdatedCount == sourcePositionsInfo.Count()) { updatesAreOk = true; } } } return(updatesAreOk); }
private object MapVmToEntities(dynamic entityToMap) { dynamic currentType = null; switch (entityToMap.GetType().Name) { case "Profile": currentType = new Data.Entities.Profile { ProfileId = entityToMap.ProfileId, CreatedBy = entityToMap.CreatedBy ?? string.Empty, DividendFreq = entityToMap.DividendFreq, DividendMonths = "NA", DividendPayDay = entityToMap.DividendPayDay, DividendRate = entityToMap.DividendRate, DividendYield = entityToMap.DividendYield > 0 ? entityToMap.DividendYield : 0M, EarningsPerShare = entityToMap.EarningsPerShare > 0 ? entityToMap.EarningsPerShare : 0M, LastUpdate = entityToMap.LastUpdate ?? DateTime.Now, PERatio = entityToMap.PERatio > 0 ? entityToMap.PERatio : 0M, TickerDescription = entityToMap.TickerDescription, TickerSymbol = entityToMap.TickerSymbol, UnitPrice = entityToMap.UnitPrice }; break; case "AssetCreationVm": currentType = new Data.Entities.Asset { AssetId = entityToMap.AssetId, AssetClassId = entityToMap.AssetClassId, InvestorId = entityToMap.InvestorId, LastUpdate = entityToMap.LastUpdate ?? DateTime.Now, ProfileId = entityToMap.ProfileId, Positions = new List <Data.Entities.Position>() }; break; case "Position": currentType = new Data.Entities.Position { PositionId = entityToMap.PositionId, AccountTypeId = entityToMap.AccountTypeId, AssetId = entityToMap.AssetId, // value needed Fees = entityToMap.Fees > 0 ? entityToMap.Fees : 0M, LastUpdate = entityToMap.LastUpdate ?? DateTime.Now, PositionDate = entityToMap.PositionDate ?? DateTime.Now, Quantity = entityToMap.Quantity, Status = "A", UnitCost = entityToMap.UnitCost }; break; default: break; } return(currentType); }