private void RecursiveSolveCombinations(JournalEntryLineModel targetLine, double currentSum, List <JournalEntryLineModel> included, List <JournalEntryLineModel> notIncluded, int startIndex, int milliseconds) { for (int index = startIndex; index < notIncluded.Count; index++) { if (_stopwatch.ElapsedMilliseconds > milliseconds) { return; } double goal = targetLine.Debit == 0 ? targetLine.Credit : targetLine.Debit; JournalEntryLineModel nextLine = notIncluded[index]; double nextAmount = nextLine.Debit == 0 ? nextLine.Credit : nextLine.Debit; double amountToCompare = Math.Round(currentSum + nextAmount, _roundAccuracy); if (amountToCompare == goal) { List <JournalEntryLineModel> newResult = new List <JournalEntryLineModel>(included) { nextLine }; _sourceLines = newResult; return; } else if (Math.Abs(amountToCompare) < Math.Abs(goal)) { List <JournalEntryLineModel> nextIncuded = new List <JournalEntryLineModel>(included) { nextLine }; List <JournalEntryLineModel> nextNonIncluded = new List <JournalEntryLineModel>(notIncluded); nextNonIncluded.Remove(nextLine); RecursiveSolveCombinations(targetLine, amountToCompare, nextIncuded, nextNonIncluded, startIndex++, milliseconds); } } }
private void RecursiveSolveCombinationsNegative(JournalEntryLineModel targetLine, double currentSum, List <JournalEntryLineModel> included, List <JournalEntryLineModel> notIncluded, int startIndex) { var roundTotalsAccuracy = _company.GetCompanyService().GetAdminInfo().TotalsAccuracy; for (int index = startIndex; index < notIncluded.Count; index++) { double goal = targetLine.Debit == 0 ? targetLine.Credit : targetLine.Debit; JournalEntryLineModel nextLine = notIncluded[index]; double nextAmount = nextLine.Debit == 0 ? nextLine.Credit : nextLine.Debit; double amountToCompare = Math.Round(currentSum + nextAmount, roundTotalsAccuracy); if (amountToCompare + goal == 0) { List <JournalEntryLineModel> newResult = new List <JournalEntryLineModel>(included) { nextLine }; _sourceLines = newResult; } else if (Math.Abs(amountToCompare) < Math.Abs(goal)) { List <JournalEntryLineModel> nextIncuded = new List <JournalEntryLineModel>(included) { nextLine }; List <JournalEntryLineModel> nextNonIncluded = new List <JournalEntryLineModel>(notIncluded); nextNonIncluded.Remove(nextLine); RecursiveSolveCombinationsNegative(targetLine, amountToCompare, nextIncuded, nextNonIncluded, startIndex++); } } }
public List <JournalEntryLineModel> SolveCombinations(JournalEntryLineModel targetLine, List <JournalEntryLineModel> searchLines, int milliseconds) { _stopwatch = new Stopwatch(); _stopwatch.Start(); _sourceLines = new List <JournalEntryLineModel>(); RecursiveSolveCombinations(targetLine, 0, new List <JournalEntryLineModel>(), searchLines, 0, milliseconds); return(_sourceLines); }
private List <JournalEntryLineModel> JournalEntryLineModelsFromRecordset(Recordset recSet) { List <JournalEntryLineModel> jdtLines = new List <JournalEntryLineModel>(); while (!recSet.EoF) { JournalEntryLineModel model = new JournalEntryLineModel(_company) { Account = recSet.Fields.Item("Account").Value.ToString(), ContraAccount = recSet.Fields.Item("ContraAct").Value.ToString(), Credit = double.Parse(recSet.Fields.Item("Credit").Value.ToString()), Debit = double.Parse(recSet.Fields.Item("Debit").Value.ToString()), SortName = recSet.Fields.Item("ShortName").Value.ToString(), TransId = int.Parse(recSet.Fields.Item("TransId").Value.ToString()), LineId = int.Parse(recSet.Fields.Item("Line_ID").Value.ToString()) }; jdtLines.Add(model); recSet.MoveNext(); } return(jdtLines); }
public List <JournalEntryLineModel> SolveCombinationsNegative(JournalEntryLineModel targetLine, List <JournalEntryLineModel> searchLines) { _sourceLines = new List <JournalEntryLineModel>(); RecursiveSolveCombinationsNegative(targetLine, 0, new List <JournalEntryLineModel>(), searchLines, 0); return(_sourceLines); }
private void MainLogicSecond(List <JournalEntryLineModel> jdtLines, int waitingTime) { Stopwatch st = new Stopwatch(); st.Start(); //ვაჯგუფებთ ტრანზაქციის ID-ს მიხედვით (ამოვაგდებთ სადაც დებიტი და კრედიტი 0 ის ტოლია) IEnumerable <IGrouping <int, JournalEntryLineModel> > groupBy = jdtLines .Where(y => y.Debit != 0 || y.Credit != 0) .GroupBy(x => x.TransId); int increment = 0; int total = groupBy.Count(); foreach (IGrouping <int, JournalEntryLineModel> journalEntryLineModels in groupBy) { int transId = journalEntryLineModels.Key; //ტრანზაქციის ID List <JournalEntryLineModel> debitLines = journalEntryLineModels.Where(x => x.Debit != 0).Select(x => x) .ToList(); // სტრიქონები სადაც დებიტი არაა 0 List <JournalEntryLineModel> creditLines = journalEntryLineModels.Where(x => x.Credit != 0).Select(x => x).ToList(); // სტრიქონები სადაც კრედიტი არაა 0 var negativeCredits = creditLines.Where(x => x.Credit > 0); List <JournalEntryLineModel> asd = new List <JournalEntryLineModel>(negativeCredits); foreach (JournalEntryLineModel journalEntryLineModel in asd) { creditLines.Remove(creditLines.FirstOrDefault(y => y.Credit == journalEntryLineModel.Credit && y.LineId == journalEntryLineModel.LineId)); creditLines.Add(journalEntryLineModel); } var negativeDebits = debitLines.Where(x => x.Credit > 0); foreach (JournalEntryLineModel journalEntryLineModel in negativeDebits) { debitLines.Remove(debitLines.FirstOrDefault(y => y.Debit == journalEntryLineModel.Debit && y.LineId == journalEntryLineModel.LineId)); debitLines.Add(journalEntryLineModel); } // ლოგიკა რომელიც გვიბრუნებს საჟურნალო გატარების სტრიქონებს რომლის ჯამიც გვაძლებს გადაცემული სტრიქონის თანხას while (debitLines.Count > 0 || creditLines.Count > 0) { JournalEntryLineModel maxDebitLine = debitLines .Where(x => Math.Abs(x.Debit) == debitLines.Max(y => Math.Abs(y.Debit))).ToList() .FirstOrDefault(); // მაქსიმალური დებიტის თანხა JournalEntryLineModel maxCreditLine = creditLines .Where(x => Math.Abs(x.Credit) == creditLines.Max(y => Math.Abs(y.Credit))).ToList() .FirstOrDefault(); // მაქსიმალური კრედიტის თანხა bool creditRecalc = false; bool debitRecalc = false; if (maxCreditLine == null) { creditRecalc = true; foreach (var xz in debitLines.Except(new[] { maxDebitLine })) { xz.Debit = -1 * xz.Debit; xz.Credit = -1 * xz.Credit; } creditLines.AddRange(debitLines.Except(new[] { maxDebitLine })); debitLines = new List <JournalEntryLineModel>() { maxDebitLine }; maxCreditLine = creditLines.Where(x => Math.Abs(x.Credit) == creditLines.Max(y => Math.Abs(y.Credit))) .ToList().FirstOrDefault(); // მაქსიმალური კრედიტის თანხა } if (maxDebitLine == null) { debitRecalc = true; foreach (var xz in creditLines.Except(new[] { maxCreditLine })) { xz.Debit = -1 * xz.Debit; xz.Credit = -1 * xz.Credit; } debitLines.AddRange(creditLines.Except(new[] { maxCreditLine })); creditLines = new List <JournalEntryLineModel>() { maxCreditLine }; maxDebitLine = debitLines.Where(x => Math.Abs(x.Debit) == debitLines.Max(y => Math.Abs(y.Debit))) .ToList().FirstOrDefault(); // მაქსიმალური დებიტის თანხა, ეს იწვევს პრობლემას როდესაც გატარება ხელით არს გაკეთებული. FirstOrDefault აბრუნებს ნალს. } if (Math.Abs(maxCreditLine.Credit) == Math.Abs(maxDebitLine.Debit)) { maxDebitLine.CorrectContraAccount = maxCreditLine.Account; maxDebitLine.ContraAccountLineId = maxCreditLine.LineId; maxDebitLine.CorrectContraShortName = maxCreditLine.SortName; maxDebitLine.UpdateSql(); maxCreditLine.CorrectContraAccount = "SourceSimple"; maxCreditLine.ContraAccountLineId = -1; maxCreditLine.UpdateSql(); creditLines.Remove(maxCreditLine); debitLines.Remove(maxDebitLine); } if (Math.Abs(maxCreditLine.Credit) > Math.Abs(maxDebitLine.Debit)) { if (!debitRecalc) { foreach (var xz in creditLines.Except(new[] { maxCreditLine })) { xz.Debit = -1 * xz.Debit; xz.Credit = -1 * xz.Credit; } debitLines.AddRange(creditLines.Except(new[] { maxCreditLine })); creditLines = new List <JournalEntryLineModel>() { maxCreditLine }; } List <JournalEntryLineModel> sources = _solver.SolveCombinations(maxCreditLine, debitLines, waitingTime * 1000); foreach (JournalEntryLineModel journalEntryLineModel in sources) { journalEntryLineModel.CorrectContraAccount = maxCreditLine.Account; journalEntryLineModel.CorrectContraShortName = maxCreditLine.SortName; journalEntryLineModel.ContraAccountLineId = maxCreditLine.LineId; journalEntryLineModel.UpdateSql(); } maxCreditLine.CorrectContraAccount = "SourceComplex"; maxCreditLine.ContraAccountLineId = -1; maxCreditLine.UpdateSql(); creditLines.Remove(maxCreditLine); debitLines = debitLines.Except(sources).ToList(); } else if (Math.Abs(maxDebitLine.Debit) > Math.Abs(maxCreditLine.Credit)) { if (!creditRecalc) { foreach (var xz in debitLines.Except(new[] { maxDebitLine })) { xz.Debit = -1 * xz.Debit; xz.Credit = -1 * xz.Credit; } creditLines.AddRange(debitLines.Except(new[] { maxDebitLine })); debitLines = new List <JournalEntryLineModel>() { maxDebitLine }; } List <JournalEntryLineModel> sources = _solver.SolveCombinations(maxDebitLine, creditLines, waitingTime * 1000); foreach (JournalEntryLineModel journalEntryLineModel in sources) { journalEntryLineModel.CorrectContraAccount = maxDebitLine.Account; journalEntryLineModel.CorrectContraShortName = maxDebitLine.SortName; journalEntryLineModel.ContraAccountLineId = maxDebitLine.LineId; journalEntryLineModel.UpdateSql(); } maxDebitLine.CorrectContraAccount = "SourceComplex"; maxDebitLine.ContraAccountLineId = -1; maxDebitLine.UpdateSql(); debitLines.Remove(maxDebitLine); creditLines = creditLines.Except(sources).ToList(); } } increment++; } var wastedMinutes = st.ElapsedMilliseconds / 60000; st.Stop(); }
private void MainLogicFirst(List <JournalEntryLineModel> jdtLines, int waitingTime) { //ვაჯგუფებთ ტრანზაქციის ID-ს მიხედვით (ამოვაგდებთ სადაც დებიტი და კრედიტი 0 ის ტოლია) IEnumerable <IGrouping <int, JournalEntryLineModel> > groupBy = jdtLines .Where(y => y.Debit != 0 || y.Credit != 0) .GroupBy(x => x.TransId); foreach (IGrouping <int, JournalEntryLineModel> journalEntryLineModels in groupBy) { int transId = journalEntryLineModels.Key; //ტრანზაქციის ID List <JournalEntryLineModel> debitLines = journalEntryLineModels.Where(x => x.Debit != 0) .Select(x => x) .ToList(); // სტრიქონები სადაც დებიტი არაა 0 List <JournalEntryLineModel> creditLines = journalEntryLineModels.Where(x => x.Credit != 0) .Select(x => x) .ToList(); // სტრიქონები სადაც კრედიტი არაა 0 // ლოგიკა რომელიც გვიბრუნებს საჟურნალო გატარების სტრიქონებს რომლის ჯამიც გვაძლებს გადაცემული სტრიქონის თანხას while (debitLines.Count > 0 && creditLines.Count > 0) { JournalEntryLineModel maxDebitLine = debitLines .Where(x => Math.Abs(x.Debit) == debitLines.Max(y => Math.Abs(y.Debit))).ToList() .First(); // მაქსიმალური დებიტის თანხა JournalEntryLineModel maxCreditLine = creditLines .Where(x => Math.Abs(x.Credit) == creditLines.Max(y => Math.Abs(y.Credit))).ToList() .First(); // მაქსიმალური კრედიტის თანხა var positiveDr = debitLines.Count(x => x.Debit > 0); var negatviveDr = debitLines.Count(x => x.Debit < 0); var positiveCr = creditLines.Count(x => x.Credit > 0); var negatviveCr = creditLines.Count(x => x.Credit < 0); if ((positiveDr > 0 && negatviveDr > 0) || (positiveCr > 0 && negatviveCr > 0) || (positiveDr > 0 && negatviveCr > 0) || (positiveCr > 0 && negatviveDr > 0)) { break; } if (maxCreditLine.Credit == maxDebitLine.Debit) { maxDebitLine.CorrectContraAccount = maxCreditLine.Account; maxDebitLine.ContraAccountLineId = maxCreditLine.LineId; maxDebitLine.CorrectContraShortName = maxCreditLine.SortName; maxDebitLine.UpdateSql(); maxCreditLine.CorrectContraAccount = "SourceSimple"; maxCreditLine.ContraAccountLineId = -1; maxCreditLine.UpdateSql(); creditLines.Remove(maxCreditLine); debitLines.Remove(maxDebitLine); } if (Math.Abs(maxCreditLine.Credit) > Math.Abs(maxDebitLine.Debit)) { List <JournalEntryLineModel> sources = _solver.SolveCombinations(maxCreditLine, debitLines, waitingTime * 1000); foreach (JournalEntryLineModel journalEntryLineModel in sources) { journalEntryLineModel.CorrectContraAccount = maxCreditLine.Account; journalEntryLineModel.CorrectContraShortName = maxCreditLine.SortName; journalEntryLineModel.ContraAccountLineId = maxCreditLine.LineId; journalEntryLineModel.UpdateSql(); } maxCreditLine.CorrectContraAccount = "SourceComplex"; maxCreditLine.ContraAccountLineId = -1; maxCreditLine.UpdateSql(); creditLines.Remove(maxCreditLine); debitLines = debitLines.Except(sources).ToList(); } else if (Math.Abs(maxDebitLine.Debit) > Math.Abs(maxCreditLine.Credit)) { List <JournalEntryLineModel> sources = _solver.SolveCombinations(maxDebitLine, creditLines, waitingTime * 1000); foreach (JournalEntryLineModel journalEntryLineModel in sources) { journalEntryLineModel.CorrectContraAccount = maxDebitLine.Account; journalEntryLineModel.CorrectContraShortName = maxDebitLine.SortName; journalEntryLineModel.ContraAccountLineId = maxDebitLine.LineId; journalEntryLineModel.UpdateSql(); } maxDebitLine.CorrectContraAccount = "SourceComplex"; maxDebitLine.ContraAccountLineId = -1; maxDebitLine.UpdateSql(); debitLines.Remove(maxDebitLine); creditLines = creditLines.Except(sources).ToList(); } } } }