private long StreamToFile(List<EUSaleWithoutVAT> listOfImportExport, StreamWriter sw)
        {
            long sumOfAmount = 0;

            foreach (var rec in listOfImportExport)
            {
                string countryStr = null;
                if (rec.Country == CountryCode.Greece)
                    countryStr = "EL";
                else
                    countryStr = Enum.GetName(typeof(CountryISOCode), ((int)rec.Country));

                var itemAmount = NumberConvert.ToLong(rec.ItemAmount);
                var serviceAmount = NumberConvert.ToLong(rec.ServiceAmount);
                var triangularTradeAmount = NumberConvert.ToLong(rec.TriangularTradeAmount);
                sumOfAmount += itemAmount + serviceAmount + triangularTradeAmount;

                rec.SystemInfo = Localization.lookup("Exported");

                sw.Write(rec.RecordType); sw.Write(';');
                sw.Write(rec.ReferenceNumber); sw.Write(';');
                sw.Write(rec.Date.ToString("yyyy-MM-dd")); sw.Write(';');
                sw.Write(rec.CompanyRegNo); sw.Write(';');
                sw.Write(countryStr); sw.Write(';');
                sw.Write(rec._DebtorRegNoFile); sw.Write(';');
                NumberConvert.ToStream(sw, itemAmount); sw.Write(';');
                NumberConvert.ToStream(sw, triangularTradeAmount); sw.Write(';');
                NumberConvert.ToStream(sw, serviceAmount);
                sw.WriteLine();
            }

            return sumOfAmount;
        }
        public static void CreateStartAndEnd(List <DanishFormatFieldBase> listofBankProperties, StreamWriter sw, bool isStartOrEnd)
        {
            var endObject = new BankDataFormatFields();

            endObject.TransferDate = BasePage.GetSystemDefaultDate().Date;

            var listOfBankData = listofBankProperties.OfType <BankDataFormatFields>().Where(bankData => bankData.Index == INDEX01).ToList();

            endObject.TotalPayments = listOfBankData.Count;

            var totalAmount   = listofBankProperties.OfType <BankDataFormatFields>().Aggregate(0.0, (current, bp) => current + bp.AmountLong);
            var lineamountint = NumberConvert.ToLong(totalAmount);

            endObject.TotalAmount = lineamountint;

            string stringWithEmpty;

            if (isStartOrEnd)
            {
                endObject.TransTypeCommand = TRANSTYPE_IB000000000000;
                stringWithEmpty            = new string(' ', 90);
            }
            else
            {
                endObject.TransTypeCommand = TRANSTYPE_IB999999999999;
                stringWithEmpty            = new string(' ', 64);
            }

            endObject.OtherTransfers = new List <string>()
            {
                stringWithEmpty,
                new string(' ', 255),
                new string(' ', 255),
                new string(' ', 255)
            };

            const char seperator = ',';

            sw.Write("\"{0}\",", endObject.TransTypeCommand);
            sw.Write("\"{0:yyyyMMdd}\"", endObject.TransferDate);
            if (!isStartOrEnd)
            {
                sw.Write(seperator);
                sw.Write("\"{0:D6}\",", endObject.TotalPayments);
                sw.Write("\"{0:D13}+\"", endObject.TotalAmount);
            }
            foreach (var oT in endObject.OtherTransfers)
            {
                sw.Write(seperator);
                sw.Write('"');
                sw.Write(oT);
                sw.Write('"');
            }
            sw.WriteLine();
        }
        private void StreamToFileDE(List<EUSaleWithoutVAT> listOfImportExport, StreamWriter sw)
        {
            sw.Write("Laenderkennzeichen"); sw.Write(';');
            sw.Write("USt-IdNr."); sw.Write(';');
            sw.Write("Betrag(EUR)"); sw.Write(';');
            sw.Write("Art der Leistung");
            sw.WriteLine();

            long amount = 0;
            var exp = Localization.lookup("Exported");
            foreach (var rec in listOfImportExport)
            {
                string countryStr;
                if (rec.Country == CountryCode.Greece)
                    countryStr = "EL";
                else
                    countryStr = ((CountryISOCode)rec.Country).ToString();

                sw.Write(countryStr); sw.Write(';');
                sw.Write(rec._DebtorRegNoFile); sw.Write(';');

                string type = null;
                switch (rec.DeType)
                {
                    case 1: type = "L"; amount = NumberConvert.ToLong(rec.ItemAmount);  break;
                    case 2: type = "S"; amount = NumberConvert.ToLong(rec.ServiceAmount); break;
                    case 3: type = "D"; amount = NumberConvert.ToLong(rec.TriangularTradeAmount); break;
                    default: type = ""; break;
                }

                NumberConvert.ToStream(sw, amount); sw.Write(';');
                sw.Write(type);
                sw.WriteLine();

                rec.SystemInfo = exp;
            }
        }
        void buildRecordType999()
        {
            var lsField = new LSFieldsOUT();

            lineNumber++;
            lsField.LineNumber = lineNumber;

            var amountCollectionTotalStr   = NumberConvert.ToLong(Math.Abs(amountCollectionTotal) * 100d).ToString();
            var amountDisbursementTotalStr = NumberConvert.ToLong(Math.Abs(amountDisbursementTotal) * 100d).ToString();

            lsField.RecordType = DirectDebitPaymentHelper.RECORDTYPE_999;

            lsField.CreditorNo = DirectDebitPaymentHelper.processStringNum(5, DirectDebitPaymentHelper.CREDITORNUMBER);

            lsField.Filler01 = DirectDebitPaymentHelper.processStringAlpha(15);

            lsField.NumberOfDebtorsStr    = DirectDebitPaymentHelper.processStringNum(7, countDebtors.ToString());
            lsField.AmountCollectionStr   = DirectDebitPaymentHelper.processStringNum(13, amountCollectionTotalStr);
            lsField.AmountDisbursementStr = DirectDebitPaymentHelper.processStringNum(13, amountDisbursementTotalStr);

            lsField.Filler02 = DirectDebitPaymentHelper.processStringAlpha(24);

            listOfTrans.Add(lsField);
        }
        public DanishFormatFieldBase CreateIndbetalingskortFormatField(CreditorTransPayment tran,
                                                                       CreditorPaymentFormat paymentFormat,
                                                                       BankStatement bankAccount,
                                                                       Uniconta.DataModel.Creditor creditor,
                                                                       Company company,
                                                                       bool glJournalGenerated = false)
        {
            var danishFields = new BankDataFormatFields();

            SharedCodeForCreateBankFormatFields(company, tran, paymentFormat, bankAccount, danishFields);
            SharedFIKPayment(danishFields, tran);

            danishFields.TransTypeCommand = BankDataPayFormat.TRANSTYPE_IB030207000002;
            danishFields.Index            = BankDataPayFormat.INDEX01;

            var lineamountint = NumberConvert.ToLong(tran.PaymentAmount * 100d);

            danishFields.AmountLong = lineamountint;

            danishFields.FromAccountType = 2;
            danishFields.GiroReg         = NETSNorge.processString(string.Empty, 4, false);

            if (danishFields.FormType == BankFormatBase.FIK04)
            {
                danishFields.ToAccountGiro     = NETSNorge.processString(danishFields.ToAccountNumber, 10, false);
                danishFields.ToAccountCreditor = NETSNorge.processString(string.Empty, 8, false);
            }
            else
            {
                danishFields.ToAccountGiro     = NETSNorge.processString(string.Empty, 10, false);
                danishFields.ToAccountCreditor = NETSNorge.processString(danishFields.ToAccountNumber, 8, false);
            }
            string credName = glJournalGenerated ? string.Empty : tran.Creditor.Name;

            danishFields.NameOfReceiver   = NETSNorge.processString(credName, 32, false);
            danishFields.AlternativSender = NETSNorge.processString(string.Empty, 32, false);

            var internalAdvText = StandardPaymentFunctions.InternalMessage(paymentFormat._OurMessage, tran, company, creditor);

            danishFields.OwnVoucherNumber = NETSNorge.processString(internalAdvText, 35, false);

            danishFields.SenderName     = NETSNorge.processString(company._Name, 35, false);
            danishFields.SenderAddress1 = NETSNorge.processString(company._Address1, 35, false);
            danishFields.SenderAddress2 = NETSNorge.processString(company._Address2, 35, false);
            danishFields.SenderAddress3 = NETSNorge.processString(company._Address3, 35, false);
            danishFields.Blanks         = NETSNorge.processString(string.Empty, 35, false);

            if (danishFields.FormType == BankFormatBase.FIK73 || danishFields.FormType == BankFormatBase.FIK75)
            {
                var externalAdvText = StandardPaymentFunctions.ExternalMessage(paymentFormat._Message, tran, company, creditor);
                var message         = externalAdvText;

                message = NETSNorge.processString(message, 210, false);

                int maxStrLen = 35;
                int maxLines  = 6;

                List <string> messageList = new List <string>();

                if (message != string.Empty)
                {
                    if (message.Length > maxLines * maxStrLen)
                    {
                        message = message.Substring(0, maxLines * maxStrLen);
                    }

                    messageList = message.Select((x, i) => i)
                                  .Where(i => i % maxStrLen == 0)
                                  .Select(i => message.Substring(i, message.Length - i >= maxStrLen ? maxStrLen : message.Length - i)).ToList <string>();
                }

                danishFields.ReceiverAccountInfo = messageList;
            }
            else
            {
                danishFields.ReceiverAccountInfo = new List <string>()
                {
                    NETSNorge.processString(string.Empty, 35, false),
                    NETSNorge.processString(string.Empty, 35, false),
                    NETSNorge.processString(string.Empty, 35, false),
                    NETSNorge.processString(string.Empty, 35, false),
                    NETSNorge.processString(string.Empty, 35, false),
                    NETSNorge.processString(string.Empty, 35, false),
                };
            }

            danishFields.Blanks2  = NETSNorge.processString(string.Empty, 16, false);
            danishFields.Reserved = NETSNorge.processString(string.Empty, 215, false);

            danishFields.UniquePaymRef = tran.PaymentEndToEndId.ToString();

            return(danishFields);
        }
        public DanishFormatFieldBase CreateForeignFormatField(CreditorTransPayment tran,
                                                              CreditorPaymentFormat paymentFormat,
                                                              BankStatement bankAccount,
                                                              Uniconta.DataModel.Creditor creditor,
                                                              Company company,
                                                              bool glJournalGenerated = false)
        {
            var danishFields = new BankDataFormatFields();

            SharedCodeForCreateBankFormatFields(company, tran, paymentFormat, bankAccount, danishFields);
            SharedForeignReceiverBankInfo(danishFields, tran);

            var externalAdvText = StandardPaymentFunctions.ExternalMessage(paymentFormat._Message, tran, company, creditor);
            var message         = externalAdvText;

            message = NETSNorge.processString(message, 140, false);

            int maxStrLen = 35;
            int maxLines  = 4;

            List <string> messageList = new List <string>();

            if (message != string.Empty)
            {
                if (message.Length > maxLines * maxStrLen)
                {
                    message = message.Substring(0, maxLines * maxStrLen);
                }

                messageList = message.Select((x, i) => i)
                              .Where(i => i % maxStrLen == 0)
                              .Select(i => message.Substring(i, message.Length - i >= maxStrLen ? maxStrLen : message.Length - i)).ToList <string>();
            }

            danishFields.DescriptionOfPayment = messageList;

            danishFields.TransTypeCommand = BankDataPayFormat.TRANSTYPE_IB030204000003;
            danishFields.Index            = BankDataPayFormat.INDEX01;

            var lineamountint = NumberConvert.ToLong(tran.PaymentAmount * 100d);

            danishFields.AmountLong = lineamountint;

            danishFields.FromAccountType = 2;

            danishFields.TransferCoin = new string(' ', 3);

            var paymentType = ISOPaymentType(tran.CurrencyLocalStr, bankAccount, danishFields.ReceiverIBAN, company);

            danishFields.TransferType = paymentType == UnicontaISO20022CreditTransfer.ISO20022PaymentTypes.SEPA ? BankDataPayFormat.FOREIGN_SEPATRANSFER : BankDataPayFormat.FOREIGN_STANDARDTRANSFER;

            if (glJournalGenerated)
            {
                danishFields.NameOfReceiver     = NETSNorge.processString(string.Empty, 35, false);
                danishFields.AddressOfReceiver  = NETSNorge.processString(string.Empty, 35, false);
                danishFields.AddressOfReceiver2 = NETSNorge.processString(string.Empty, 35, false);
            }
            else
            {
                danishFields.NameOfReceiver     = NETSNorge.processString(tran.Creditor.Name, 35, false);
                danishFields.AddressOfReceiver  = NETSNorge.processString(tran.Creditor.Address1 + ", " + tran.Creditor.ZipCode + " " + tran.Creditor.City, 35, false);
                danishFields.AddressOfReceiver2 = NETSNorge.processString(tran.Creditor.Address2, 35, false);
            }

            danishFields.OtherTransfers = new List <string>()
            {
                NETSNorge.processString(string.Empty, 35, false),
                NETSNorge.processString(string.Empty, 4, false),
                NETSNorge.processString(string.Empty, 6, false),
                NETSNorge.processString(string.Empty, 2, false),
                NETSNorge.processString(string.Empty, 75, false),
                NETSNorge.processString(string.Empty, 75, false),
                NETSNorge.processString(string.Empty, 75, false),
                NETSNorge.processString(string.Empty, 24, false),
                NETSNorge.processString(string.Empty, 215, false)
            };

            danishFields.UniquePaymRef = tran.PaymentEndToEndId.ToString();

            return(danishFields);
        }
        async Task <List <BalanceClient> > GenerateTemplateGrid(int Cols)
        {
            GLReportTemplate template;
            var templateCache = api.GetCache(typeof(GLReportTemplate));

            if (templateCache != null)
            {
                template = (GLReportTemplate)templateCache.Get(AppliedTemplate);
            }
            else
            {
                template = new GLReportTemplate()
                {
                    _Name = AppliedTemplate
                };
                await api.Read(template);
            }
            if (template == null || template.RowId == 0)
            {
                return(null);
            }

            var reportline = await api.Query <GLReportLine>(template);

            var items = new TemplateDataContext();
            var TemplateReportlist = items.TemplateReportlist;

            TemplateReportlist.Capacity = reportline.Length;

            var newBalance = new List <BalanceClient>(reportline.Length);

            var  SumContext = new TemplateSumContext(Cols);
            var  colCount = PassedCriteria.selectedCriteria.Count;
            bool AnyHidden = false;
            int  i, j;

            for (j = 0; (j < reportline.Length); j++)
            {
                var line    = reportline[j];
                var amounts = new long[colCount];
                if (line._Accounts != null && !line._ExpressionSum)
                {
                    var SumAccounts = PropValuePair.GenereteWhereElements("Account", typeof(string), line._Accounts);
                    foreach (var balSum in balanceClient)
                    {
                        if (balSum.AccountTypeEnum > GLAccountTypes.CalculationExpression && AccountSum.IsIncluded(SumAccounts, balSum.AccountNo))
                        {
                            balSum.SumUpAmount(amounts);
                        }
                    }
                    if (Skip0Account)
                    {
                        bool found = false;
                        for (i = 0; (i < Cols); i++)
                        {
                            if (amounts[i] != 0)
                            {
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                        {
                            continue;
                        }
                    }
                }
                if (line._InvertSign)
                {
                    for (i = 0; (i < Cols); i++)
                    {
                        amounts[i] = -amounts[i];
                    }
                }
                if (line._SaveTotal != 0)
                {
                    SumContext.CalcMethod.AddSum(line._SaveTotal, amounts);
                }
                if (line._Hide)
                {
                    AnyHidden = true;
                }

                var newBalanceCol = new BalanceClient(amounts);
                newBalanceCol.Acc._Name = line._Text;
                newBalance.Add(newBalanceCol);
                TemplateReportlist.Add(new TemplateDataItems(newBalanceCol, hdrData, line)
                {
                    Masterfontsize = template._FontSize
                });
            }

            // Now we will take all expressions and update.
            var pars = new parser(SumContext);

            for (j = 0; (j < TemplateReportlist.Count); j++)
            {
                var item = TemplateReportlist[j];
                var line = item.line;
                if (line._ExpressionSum)
                {
                    var InvertSign = line._InvertSign;
                    var e          = pars.parse(line._Accounts, Uniconta.Script.ValueType.Double);
                    if (e != null)
                    {
                        var amounts = item.blc.amount;
                        for (i = 0; (i < Cols); i++)
                        {
                            SumContext.CurIndex = i;
                            var val = NumberConvert.ToLong(e.Value());
                            amounts[i] = !InvertSign ? val : -val;
                        }
                        if (line._SaveTotal != 0)
                        {
                            SumContext.CalcMethod.AddSum(line._SaveTotal, amounts);
                        }
                    }
                }
            }

            if (AnyHidden)
            {
                for (i = TemplateReportlist.Count; (--i >= 0);)
                {
                    if (TemplateReportlist[i].line._Hide)
                    {
                        TemplateReportlist.RemoveAt(i);
                    }
                }
            }

            AccountName.Visible         = AccountNo.Visible = false;
            Text.Visible                = true;
            dgBalanceReport.ItemsSource = TemplateReportlist;
            templateReportData          = new object[] { items, hdrData, PassedCriteria.ObjBalance, null };
            return(newBalance);
        }
        public DanishFormatFieldBase CreateDomesticFormatField(CreditorTransPayment tran, CreditorPaymentFormat paymentFormat,
                                                               BankStatement bankAccount, Uniconta.DataModel.Creditor creditor, Company company, bool glJournalGenerated = false)
        {
            var danishFields = new BankDataFormatFields();

            SharedCodeForCreateBankFormatFields(company, tran, paymentFormat, bankAccount, danishFields);
            DomesticPaymentType(danishFields, tran);

            danishFields.TransTypeCommand = BankDataPayFormat.TRANSTYPE_IB030202000005;
            danishFields.Index            = BankDataPayFormat.INDEX01;

            var lineamountint = NumberConvert.ToLong(tran.PaymentAmount * 100d);

            danishFields.AmountLong = lineamountint;

            danishFields.FromAccountType     = 2;
            danishFields.TransferType        = 2;
            danishFields.ClearingTypeChannel = "0";

            if (glJournalGenerated)
            {
                danishFields.NameOfReceiver     = NETSNorge.processString(string.Empty, 32, false);
                danishFields.AddressOfReceiver  = NETSNorge.processString(string.Empty, 32, false);
                danishFields.AddressOfReceiver2 = NETSNorge.processString(string.Empty, 32, false);
                danishFields.ZipCodeOfReceiver  = NETSNorge.processString(string.Empty, 4, false);
                danishFields.CityOfReceiver     = NETSNorge.processString(string.Empty, 32, false);
            }
            else
            {
                danishFields.NameOfReceiver     = NETSNorge.processString(tran.Creditor.Name, 32, false);
                danishFields.AddressOfReceiver  = NETSNorge.processString(tran.Creditor.Address1, 32, false);
                danishFields.AddressOfReceiver2 = NETSNorge.processString(tran.Creditor.Address2, 32, false);
                danishFields.ZipCodeOfReceiver  = NETSNorge.processString(tran.Creditor.ZipCode, 4, false);
                danishFields.CityOfReceiver     = NETSNorge.processString(tran.Creditor.City, 32, false);
            }

            var internalAdvText = StandardPaymentFunctions.InternalMessage(paymentFormat._OurMessage, tran, company, creditor);

            danishFields.OwnVoucherNumber = NETSNorge.processString(internalAdvText, 35, false);

            //Message to Beneficiary >>
            var externalAdvText = StandardPaymentFunctions.ExternalMessage(paymentFormat._Message, tran, company, creditor);
            var message         = externalAdvText;

            danishFields.ReceiverAccountStatement = NETSNorge.processString(externalAdvText, 35, false);

            //Extended notification
            if (paymentFormat._ExtendedText)
            {
                if (message == null || message.Length <= 35)
                {
                    message = string.Empty;
                }
            }
            else
            {
                message = string.Empty;
            }

            message = NETSNorge.processString(message, 315, false);

            int maxStrLen = 35;
            int maxLines  = 9;

            List <string> messageList = new List <string>();

            if (message != string.Empty)
            {
                if (message.Length > maxLines * maxStrLen)
                {
                    message = message.Substring(0, maxLines * maxStrLen);
                }

                messageList = message.Select((x, i) => i)
                              .Where(i => i % maxStrLen == 0)
                              .Select(i => message.Substring(i, message.Length - i >= maxStrLen ? maxStrLen : message.Length - i)).ToList <string>();
            }

            //danishFields.ReceiverAccountStatement = NETSNorge.processString(message, 35, false);
            danishFields.AdviceText = messageList;
            //Message to Beneficiary <<

            danishFields.Blanks  = NETSNorge.processString(string.Empty, 1, false);
            danishFields.Blanks2 = NETSNorge.processString(string.Empty, 215, false);

            danishFields.UniquePaymRef = tran.PaymentEndToEndId.ToString();

            return(danishFields);
        }
        //TODO:Validering skal checke om PaymentType er angivet til VendorBankAccount
        //TODO:Der skal valideres for at Debtor CVR nummer er udfyldt
        //Hvad sker der hvis bankkonto ændres uden at NETS har fået besked - der kommer sandsynligvis fejlmelding. Kan det fanges inden ved at kigge i NETS oplysninger angående kunden?
        //TODO:Der må kun være en Collection or Disbursement pr. Debitor pr. dag - det skal der valideres for


        /// <summary>
        /// Creates a NETS Leverandørservice file.
        /// </summary>
        internal void /*DirectDebitGenerateResult*/ StreamToFile(Company company, IEnumerable <DebtorTransDirectDebit> lstDebtorTransDirectDebit, SQLCache DebtorCache, StreamWriter sw)
        {
            comp = company;
            var oldPaymentDate = DateTime.MinValue;

            buildRecordType000();
            foreach (var trans in lstDebtorTransDirectDebit.OrderBy(s => s._PaymentDate).ThenBy(s => s._PaymentAmount).ThenBy(s => s.Account))
            {
                paymentDate   = trans.PaymentDate;
                debtorAccount = trans.Account;
                var debtor = (Debtor)DebtorCache.Get(trans.Account);

                debtorRegNum      = DirectDebitPaymentHelper.DebtorBBAN(debtor._PaymentId).Item1;
                debtorBankAccount = DirectDebitPaymentHelper.DebtorBBAN(debtor._PaymentId).Item2;
                debtorCvrNumber   = debtor?._LegalIdent == null ? "99999999" : Regex.Replace(debtor?._LegalIdent, "[^0-9]", ""); //TODO:SKAL RETTES
                paymentAmountStr  = NumberConvert.ToLong(Math.Abs(trans._PaymentAmount) * 100d).ToString();

                paymentAmountTotal += trans._PaymentAmount;
                countDebtors++;

                if (trans.PaymentDate != oldPaymentDate)
                {
                    buildRecordType001();
                }

                //TODO: Registration and Cancellation of mandate - skal håndteres i egen sektion
                //ls.buildRecordType510();
                //ls.buildRecordType540();

                if (trans._PaymentAmount > 0)
                {
                    amountCollectionTotal += trans._PaymentAmount;
                    buildRecordType580();
                }
                else
                {
                    amountDisbursementTotal += trans._PaymentAmount;
                    buildRecordType585();
                }

                //TODO: Change of mandate - skal håndteres i egen sektion
                //ls.buildRecordType595();

                oldPaymentDate = trans.PaymentDate;
            }
            buildRecordType999();

            if (listOfTrans.Count > 0)
            {
                IEnumerable <LSFieldsOUT> queryTrans = listOfTrans.AsEnumerable();//.OrderBy(s => s.LineNumber);

                foreach (var trans in queryTrans)
                {
                    writeRecordType000(sw, trans);
                    writeRecordType001(sw, trans);
                    //ls.writeRecordType510(writer, trans);
                    //ls.writeRecordType540(writer, trans);
                    writeRecordType580(sw, trans);
                    writeRecordType585(sw, trans);
                    writeRecordType595(sw, trans);
                    writeRecordType999(sw, trans);
                }
            }

            //return new DirectDebitGenerateResult(sw, countDebtors);
        }
        async void aggregate(bool aggregateItem, bool aggregateEmployee, bool aggregateCategory)
        {
            var result = await dgProjectTransClientInvoiceGrid.SaveData();

            if (result != ErrorCodes.Succes)
            {
                return;
            }

            if (mainList == null)
            {
                mainList = (IEnumerable <ProjectTransInvoiceClient>)dgProjectTransClientInvoiceGrid.ItemsSource;
            }
            if (mainList == null || mainList.Count() == 0)
            {
                UnicontaMessageBox.Show(Uniconta.ClientTools.Localization.lookup("NoDataCollected"), Uniconta.ClientTools.Localization.lookup("Information"), MessageBoxButton.OK);
                return;
            }

            IEnumerable <ProjectTransInvoiceClient> lst;

            if (!aggregateCategory && !aggregateEmployee && !aggregateItem)
            {
                lst = mainList;
            }
            else
            {
                var categoryCache = this.CategoryCache;

                var dict = new Dictionary <string, ProjectTransInvoiceClient>();
                List <ProjectTransInvoiceClient> NoAggregate = null;

                var sb = StringBuilderReuse.Create();
                foreach (var rec in mainList)
                {
                    if (!rec._canInvoice)
                    {
                        continue;
                    }

                    var cat = (PrCategory)categoryCache.Get(rec._PrCategory);
                    if ((cat != null && !cat._CanAggregate) ||
                        ((aggregateItem || aggregateEmployee) && rec._Employee == null && rec._Item == null))
                    {
                        if (NoAggregate == null)
                        {
                            NoAggregate = new List <ProjectTransInvoiceClient>();
                        }
                        NoAggregate.Add(rec);
                        continue;
                    }

                    sb.Clear();
                    if (aggregateCategory)
                    {
                        sb.Append(rec._PrCategory);
                    }
                    if (aggregateEmployee)
                    {
                        sb.Append('\n').Append(rec._Employee ?? "?");
                    }
                    if (aggregateItem)
                    {
                        sb.Append('\n').Append(rec._Item ?? "?");
                    }

                    var key = sb.ToString();
                    ProjectTransInvoiceClient val;
                    if (dict.TryGetValue(key, out val))
                    {
                        val._Qty            += rec._Qty;
                        val._SalesAmountAgr += rec._SalesAmountAgr;
                        if (NumberConvert.ToLong(val._SalesAmountAgr * 100d) == 0)
                        {
                            val._SalesPrice = 0;
                            val._Qty        = 0;
                        }
                        val._CostAmountAgr += rec._CostAmountAgr;
                        if (NumberConvert.ToLong(val._CostAmountAgr * 100d) == 0)
                        {
                            val._CostPrice = 0;
                        }

                        if (!aggregateCategory && val._PrCategory != rec._PrCategory)
                        {
                            val._PrCategory = null;
                            if (val._Unit == 0)
                            {
                                val._Unit = (byte)cat._Unit;
                            }
                        }
                        if (!aggregateEmployee && val._Employee != rec._Employee)
                        {
                            val._Employee = null;
                        }
                        if (!aggregateItem && val._Item != rec._Item)
                        {
                            if (val._Unit == 0)
                            {
                                var itm = (InvItem)ItemCache.Get(val._Item ?? rec._Item);
                                if (itm != null)
                                {
                                    val._Unit = (byte)itm._Unit;
                                }
                            }
                            val._Item = null;
                        }
                        if (val._Dim1 != rec._Dim1)
                        {
                            val._Dim1 = null;
                        }
                        if (val._Dim2 != rec._Dim2)
                        {
                            val._Dim2 = null;
                        }
                        if (val._Dim3 != rec._Dim3)
                        {
                            val._Dim3 = null;
                        }
                        if (val._Dim4 != rec._Dim4)
                        {
                            val._Dim4 = null;
                        }
                        if (val._Dim5 != rec._Dim5)
                        {
                            val._Dim5 = null;
                        }
                    }
                    else
                    {
                        val = new ProjectTransInvoiceClient();
                        StreamingManager.Copy(rec, val);
                        val._SalesAmountAgr = rec._SalesAmountAgr;
                        val._CostAmountAgr  = rec._CostAmountAgr;

                        dict.Add(key, val);
                    }
                }
                sb.Release();
                sb = null;

                lst = dict.Values;
                foreach (var rec in lst)
                {
                    if (rec._Qty != 0)
                    {
                        rec._SalesPrice  = Math.Round(Math.Abs(rec._SalesAmountAgr) / rec._Qty, 2);
                        rec._CostPrice   = Math.Round(Math.Abs(rec._CostAmountAgr) / rec._Qty, 2);
                        rec._DiscountPct = 0;
                    }
                }
                if (NoAggregate != null)
                {
                    NoAggregate.AddRange(lst);
                    lst = NoAggregate;
                }

                var sortedLst = lst.ToList();
                sortedLst.Sort(new sortTrans(categoryCache));
                lst = sortedLst;
            }

            dgProjectTransClientInvoiceGrid.ItemsSource = lst;
        }