internal List <TrialBalanceEntry> GenerateTotalSummaryConsolidatedByLedger(
            List <TrialBalanceEntry> summaryCurrencies)
        {
            var summaryConsolidatedByLedger = new EmpiriaHashTable <TrialBalanceEntry>(summaryCurrencies.Count);
            List <TrialBalanceEntry> returnedListEntries = new List <TrialBalanceEntry>();

            if (_command.TrialBalanceType == TrialBalanceType.Balanza && _command.ShowCascadeBalances)
            {
                foreach (var currencyEntry in summaryCurrencies.Where(
                             a => a.ItemType == TrialBalanceItemType.BalanceTotalCurrency))
                {
                    TrialBalanceEntry entry = TrialBalanceMapper.MapToTrialBalanceEntry(currencyEntry);

                    entry.GroupName = $"TOTAL CONSOLIDADO {entry.Ledger.FullName}";
                    entry.Currency  = Currency.Empty;
                    string hash = $"{entry.Ledger.Id}||{entry.GroupName}||{Sector.Empty.Code}";

                    GenerateOrIncreaseEntries(summaryConsolidatedByLedger, entry, StandardAccount.Empty, Sector.Empty,
                                              TrialBalanceItemType.BalanceTotalConsolidatedByLedger, hash);
                }

                returnedListEntries.AddRange(summaryConsolidatedByLedger.Values.ToList());
            }
            return(returnedListEntries.OrderBy(a => a.Ledger.Number).ToList());
        }
        internal void SummaryByCurrencyEntries(EmpiriaHashTable <TrialBalanceEntry> summaryEntries,
                                               TrialBalanceEntry balanceEntry,
                                               StandardAccount targetAccount, Sector targetSector,
                                               TrialBalanceItemType itemType)
        {
            TrialBalanceEntry entry = TrialBalanceMapper.MapToTrialBalanceEntry(balanceEntry);

            if (_command.TrialBalanceType != TrialBalanceType.SaldosPorCuentaYMayor &&
                entry.ItemType == TrialBalanceItemType.BalanceTotalCreditor)
            {
                entry.InitialBalance = -1 * entry.InitialBalance;
                entry.CurrentBalance = -1 * entry.CurrentBalance;
            }

            entry.GroupName = "TOTAL MONEDA " + entry.Currency.FullName;
            string hash;

            if (_command.TrialBalanceType == TrialBalanceType.SaldosPorCuentaYMayor)
            {
                entry.GroupNumber = "";
                hash = $"{entry.GroupName}||{entry.Currency.Id}";
            }
            else
            {
                hash = $"{entry.GroupName}||{targetSector.Code}||{entry.Currency.Id}||{entry.Ledger.Id}";
            }
            GenerateOrIncreaseEntries(summaryEntries, entry, targetAccount, targetSector, itemType, hash);
        }
        internal List <TrialBalanceEntry> GenerateTotalSummaryConsolidated(List <TrialBalanceEntry> balanceEntries)
        {
            var totalSummaryConsolidated = new EmpiriaHashTable <TrialBalanceEntry>(balanceEntries.Count);

            foreach (var currencyEntry in balanceEntries.Where(
                         a => a.ItemType == TrialBalanceItemType.BalanceTotalCurrency))
            {
                TrialBalanceEntry entry = TrialBalanceMapper.MapToTrialBalanceEntry(currencyEntry);

                entry.GroupName = "TOTAL CONSOLIDADO GENERAL";

                string hash;
                if (_command.TrialBalanceType == TrialBalanceType.SaldosPorCuentaYMayor ||
                    (_command.TrialBalanceType == TrialBalanceType.Balanza && _command.ShowCascadeBalances))
                {
                    hash = $"{entry.GroupName}";
                    entry.GroupNumber = "";
                }
                else
                {
                    hash = $"{entry.GroupName}||{Sector.Empty.Code}||{entry.Ledger.Id}";
                }

                GenerateOrIncreaseEntries(totalSummaryConsolidated, entry, StandardAccount.Empty, Sector.Empty,
                                          TrialBalanceItemType.BalanceTotalConsolidated, hash);
            }

            balanceEntries.AddRange(totalSummaryConsolidated.Values.ToList());

            return(balanceEntries);
        }
        private void SummaryByGroupEntries(EmpiriaHashTable <TrialBalanceEntry> summaryEntries,
                                           TrialBalanceEntry balanceEntry)
        {
            TrialBalanceEntry groupEntry = TrialBalanceMapper.MapToTrialBalanceEntry(balanceEntry);

            groupEntry.GroupName      = $"TOTAL GRUPO {balanceEntry.Account.GroupNumber}";
            groupEntry.GroupNumber    = balanceEntry.Account.GroupNumber;
            groupEntry.Account        = StandardAccount.Empty;
            groupEntry.Sector         = Sector.Empty;
            groupEntry.DebtorCreditor = balanceEntry.Account.DebtorCreditor;

            string hash;

            if (groupEntry.DebtorCreditor == DebtorCreditorType.Deudora)
            {
                hash = $"{balanceEntry.Ledger.Id}||{balanceEntry.Currency.Id}||{balanceEntry.Account.GroupNumber}||D";

                GenerateOrIncreaseEntries(summaryEntries, groupEntry, StandardAccount.Empty, Sector.Empty,
                                          TrialBalanceItemType.BalanceTotalGroupDebtor, hash);
            }
            else
            {
                hash = $"{balanceEntry.Ledger.Id}||{balanceEntry.Currency.Id}||{balanceEntry.Account.GroupNumber}||A";

                GenerateOrIncreaseEntries(summaryEntries, groupEntry, StandardAccount.Empty, Sector.Empty,
                                          TrialBalanceItemType.BalanceTotalGroupCreditor, hash);
            }
        }
        private List <TrialBalanceEntry> AddSummaryAccounts(List <TrialBalanceEntry> summaryEntries,
                                                            List <TrialBalanceEntry> returnedEntries,
                                                            TrialBalanceEntry entry)
        {
            var helper = new TrialBalanceHelper(_command);

            var summaryAccounts = summaryEntries.Where(
                a => a.Account.GroupNumber == entry.Account.GroupNumber &&
                a.SubledgerAccountId == 0 &&
                a.SubledgerAccountIdParent == entry.SubledgerAccountIdParent &&
                a.Ledger.Number == entry.Ledger.Number &&
                a.Currency.Code == entry.Currency.Code &&
                a.ItemType == TrialBalanceItemType.BalanceEntry).ToList();

            foreach (var summary in summaryAccounts)
            {
                var existSummaryAccount = returnedEntries.FirstOrDefault(
                    a => a.SubledgerAccountIdParent == entry.SubledgerAccountIdParent &&
                    a.Account.Number == summary.Account.Number &&
                    a.Ledger.Number == summary.Ledger.Number &&
                    a.Currency.Code == summary.Currency.Code &&
                    a.Sector.Code == summary.Sector.Code);
                if (existSummaryAccount == null)
                {
                    returnedEntries.Add(summary);
                }
            }

            return(returnedEntries);
        }
        private void GenerateOrIncreaseEntries(EmpiriaHashTable <TrialBalanceEntry> summaryEntries,
                                               TrialBalanceEntry entry,
                                               StandardAccount targetAccount, Sector targetSector,
                                               TrialBalanceItemType itemType, string hash)
        {
            TrialBalanceEntry summaryEntry;

            summaryEntries.TryGetValue(hash, out summaryEntry);

            if (summaryEntry == null)
            {
                summaryEntry = new TrialBalanceEntry {
                    Ledger                   = entry.Ledger,
                    Currency                 = entry.Currency,
                    Sector                   = targetSector,
                    Account                  = targetAccount,
                    ItemType                 = itemType,
                    GroupNumber              = entry.GroupNumber,
                    GroupName                = entry.GroupName,
                    DebtorCreditor           = entry.DebtorCreditor,
                    SubledgerAccountIdParent = entry.SubledgerAccountIdParent
                };
                summaryEntry.Sum(entry);

                summaryEntries.Insert(hash, summaryEntry);
            }
            else
            {
                summaryEntry.Sum(entry);
            }
        }
        private List <TrialBalanceEntry> CreateOrAccumulateTotalBySubsidiaryEntry(
            List <TrialBalanceEntry> returnedEntries,
            TrialBalanceEntry entry)
        {
            var helper = new TrialBalanceHelper(_command);

            var parentEntries = new EmpiriaHashTable <TrialBalanceEntry>();

            var existTotalByAccount = returnedEntries.FirstOrDefault(
                a => a.SubledgerAccountId == entry.SubledgerAccountIdParent &&
                a.Ledger.Number == entry.Ledger.Number &&
                a.Currency.Code == entry.Currency.Code);

            if (existTotalByAccount == null)
            {
                helper.SummaryBySubsidiaryEntry(parentEntries, entry, TrialBalanceItemType.BalanceSummary);

                var parent = parentEntries.Values.FirstOrDefault();
                parent.SubledgerAccountId     = parent.SubledgerAccountIdParent;
                parent.SubledgerAccountNumber = SubsidiaryAccount.Parse(entry.SubledgerAccountIdParent).Number ?? "";
                returnedEntries.Add(parent);
            }
            else
            {
                existTotalByAccount.Sum(entry);
            }

            return(returnedEntries);
        }
        private void CreateOrAccumulateParentWithoutSector(
            List <TrialBalanceEntry> returnedEntries,
            TrialBalanceEntry entry,
            EmpiriaHashTable <TrialBalanceEntry> summaryParentEntries,
            StandardAccount currentParent)
        {
            var helper = new TrialBalanceHelper(_command);

            var entryWithoutSector = returnedEntries.FirstOrDefault(
                a => a.Ledger.Number == entry.Ledger.Number &&
                a.Currency.Code == entry.Currency.Code &&
                a.SubledgerAccountIdParent == entry.SubledgerAccountId &&
                a.Account.Number == currentParent.Number &&
                a.NotHasSector);


            if (entryWithoutSector == null)
            {
                helper.SummaryByEntry(summaryParentEntries, entry, currentParent, Sector.Empty,
                                      TrialBalanceItemType.BalanceSummary);
            }
            else
            {
                entryWithoutSector.Sum(entry);
            }
        }
 internal void Sum(TrialBalanceEntry entry)
 {
     this.InitialBalance += entry.InitialBalance;
     this.Credit         += entry.Credit;
     this.Debit          += entry.Debit;
     this.CurrentBalance += entry.CurrentBalance;
     this.ExchangeRate    = entry.ExchangeRate;
 }
        internal void SummaryByEntry(EmpiriaHashTable <TrialBalanceEntry> summaryEntries,
                                     TrialBalanceEntry entry,
                                     StandardAccount targetAccount, Sector targetSector,
                                     TrialBalanceItemType itemType)
        {
            string hash = $"{targetAccount.Number}||{targetSector.Code}||{entry.Currency.Id}||{entry.Ledger.Id}";

            GenerateOrIncreaseEntries(summaryEntries, entry, targetAccount, targetSector, itemType, hash);
        }
        internal void SummaryBySubsidiaryEntry(EmpiriaHashTable <TrialBalanceEntry> summaryEntries,
                                               TrialBalanceEntry entry, TrialBalanceItemType itemType)
        {
            TrialBalanceEntry balanceEntry = TrialBalanceMapper.MapToTrialBalanceEntry(entry);

            balanceEntry.SubledgerAccountIdParent = entry.SubledgerAccountIdParent;

            string hash = $"{entry.Account.Number}||{entry.Sector.Code}||{entry.Currency.Id}||{entry.Ledger.Id}";

            GenerateOrIncreaseEntries(summaryEntries, balanceEntry,
                                      StandardAccount.Empty, Sector.Empty, itemType, hash);
        }
        private void AccumulateSubledgerAccount(List <TrialBalanceEntry> returnedEntries,
                                                TrialBalanceEntry entry,
                                                StandardAccount currentParent)
        {
            var existTotalBySubledger = returnedEntries.FirstOrDefault(
                a => a.SubledgerAccountIdParent == entry.SubledgerAccountId &&
                a.Currency.Code == entry.Currency.Code &&
                a.Account.Number == currentParent.Number &&
                a.NotHasSector);

            if (existTotalBySubledger != null)
            {
                existTotalBySubledger.Sum(entry);
            }
        }
        internal void SummaryByLedgersGroupEntries(EmpiriaHashTable <TrialBalanceEntry> totalsListByGroupEntries,
                                                   TrialBalanceEntry balanceEntry)
        {
            TrialBalanceEntry groupEntry = TrialBalanceMapper.MapToTrialBalanceEntry(balanceEntry);

            groupEntry.GroupName      = $"TOTAL GRUPO {balanceEntry.Account.GroupNumber}";
            groupEntry.GroupNumber    = balanceEntry.Account.GroupNumber;
            groupEntry.Account        = StandardAccount.Empty;
            groupEntry.Sector         = Sector.Empty;
            groupEntry.DebtorCreditor = balanceEntry.Account.DebtorCreditor;

            string hash = $"{balanceEntry.Account.GroupNumber}||{balanceEntry.Currency.Id}||{balanceEntry.Sector.Code}";

            GenerateOrIncreaseEntries(totalsListByGroupEntries, groupEntry, StandardAccount.Empty, Sector.Empty,
                                      TrialBalanceItemType.BalanceTotalGroupDebtor, hash);
        }
        internal StoredBalance(StoredBalanceSet storedBalanceSet, TrialBalanceEntry entry)
        {
            var subsidiaryAccount = SubsidiaryAccount.Parse(entry.SubledgerAccountId);

            this.StoredBalanceSet        = storedBalanceSet;
            this.StandardAccountId       = entry.Account.Id;
            this.AccountNumber           = entry.Account.Number;
            this.AccountName             = entry.Account.Name;
            this.Ledger                  = entry.Ledger;
            this.LedgerAccountId         = entry.AccountId;
            this.Currency                = entry.Currency;
            this.Sector                  = entry.Sector;
            this.SubsidiaryAccountId     = entry.SubledgerAccountId;
            this.SubsidiaryAccountName   = subsidiaryAccount.Name;
            this.SubsidiaryAccountNumber = subsidiaryAccount.Number;
            this.Balance                 = entry.CurrentBalance;
        }
        internal void SummaryByAccount(EmpiriaHashTable <TrialBalanceEntry> summaryEntries,
                                       TrialBalanceEntry balanceEntry,
                                       StandardAccount targetAccount, Sector targetSector,
                                       TrialBalanceItemType itemType)
        {
            TrialBalanceEntry entry = TrialBalanceMapper.MapToTrialBalanceEntry(balanceEntry);

            entry.Ledger         = Ledger.Empty;
            entry.GroupName      = entry.Account.Name.ToUpper();
            entry.InitialBalance = 0;
            entry.Debit          = 0;
            entry.Credit         = 0;
            entry.CurrentBalance = 0;

            string hash = $"{targetAccount.Number}||{targetSector.Code}||{entry.Currency.Id}||{entry.Ledger.Id}";

            GenerateOrIncreaseEntries(summaryEntries, entry, targetAccount, targetSector, itemType, hash);
        }
        private void SummaryByDebtorCreditorEntries(EmpiriaHashTable <TrialBalanceEntry> summaryEntries,
                                                    TrialBalanceEntry balanceEntry,
                                                    StandardAccount targetAccount, Sector targetSector,
                                                    TrialBalanceItemType itemType)
        {
            TrialBalanceEntry entry = TrialBalanceMapper.MapToTrialBalanceEntry(balanceEntry);

            if (itemType == TrialBalanceItemType.BalanceTotalDebtor)
            {
                entry.GroupName = "TOTAL DEUDORAS " + entry.Currency.FullName;
            }
            else if (itemType == TrialBalanceItemType.BalanceTotalCreditor)
            {
                entry.GroupName = "TOTAL ACREEDORAS " + entry.Currency.FullName;
            }

            string hash = $"{entry.GroupName}||{targetSector.Code}||{entry.Currency.Id}||{entry.Ledger.Id}";

            GenerateOrIncreaseEntries(summaryEntries, entry, targetAccount, targetSector, itemType, hash);
        }
        private void GetDetailSummaryEntries(List <TrialBalanceEntry> detailSummaryEntries,
                                             EmpiriaHashTable <TrialBalanceEntry> summaryEntries,
                                             StandardAccount currentParent, TrialBalanceEntry entry)
        {
            TrialBalanceEntry detailsEntry;
            string            key = $"{currentParent.Number}||{entry.Sector.Code}||{entry.Currency.Id}||{entry.Ledger.Id}";

            summaryEntries.TryGetValue(key, out detailsEntry);
            if (detailsEntry != null)
            {
                var existEntry = detailSummaryEntries.FirstOrDefault(a => a.Ledger.Id == detailsEntry.Ledger.Id &&
                                                                     a.Currency.Id == detailsEntry.Currency.Id &&
                                                                     a.Account.Number == detailsEntry.Account.Number &&
                                                                     a.Sector.Code == detailsEntry.Sector.Code);
                if (existEntry == null)
                {
                    detailSummaryEntries.Add(detailsEntry);
                }
            }
        }