public bool UpdateProfile(Data.Entities.Profile editedProfile)
        {
            Data.Entities.Profile profileToUpdate = new Data.Entities.Profile();
            int updateCount = 0;

            try
            {
                IQueryable <Data.Entities.Profile> existingProfile = _ctx.Profile.Where(p => p.TickerSymbol == editedProfile.TickerSymbol).AsQueryable();

                existingProfile.First().TickerDescription = editedProfile.TickerDescription;
                existingProfile.First().DividendRate      = editedProfile.DividendRate;
                existingProfile.First().DividendYield     = editedProfile.DividendYield;
                existingProfile.First().PERatio           = editedProfile.PERatio;
                existingProfile.First().DividendMonths    = editedProfile.DividendMonths;
                existingProfile.First().DividendPayDay    = editedProfile.DividendPayDay;
                existingProfile.First().UnitPrice         = editedProfile.UnitPrice;
                existingProfile.First().LastUpdate        = Convert.ToDateTime(editedProfile.LastUpdate);

                _ctx.UpdateRange(existingProfile);
                updateCount = _ctx.SaveChanges();
            }
            catch (Exception)
            {
                return(false);
            }

            return(updateCount == 1 ? true : false);
        }
        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);
        }