Load <TThirdPartyType, TOwnedType>( ISpreadsheet spreadsheet, IFileIO <TOwnedType> pending_file_io, ICSVFile <TOwnedType> pending_file, IFileIO <TThirdPartyType> third_party_file_io, IFileIO <TOwnedType> owned_file_io, BudgetingMonths budgeting_months, DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info, IMatcher matcher) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { Load_pending_data(pending_file_io, pending_file, data_loading_info); Merge_budget_data(spreadsheet, pending_file, budgeting_months, data_loading_info); Merge_other_data(spreadsheet, pending_file, budgeting_months, data_loading_info); Generate_ad_hoc_data(spreadsheet, pending_file, budgeting_months, data_loading_info); Merge_unreconciled_data(spreadsheet, pending_file, data_loading_info); var reconciliator = Load_third_party_and_owned_files_into_reconciliator <TThirdPartyType, TOwnedType>( data_loading_info, third_party_file_io, owned_file_io, spreadsheet); var reconciliation_interface = Create_reconciliation_interface(data_loading_info, reconciliator, matcher); return(reconciliation_interface); }
public void Merge_bespoke_data_with_pending_file( IInputOutput input_output, ISpreadsheet spreadsheet, ICSVFile <BankRecord> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <ActualBankRecord, BankRecord> data_loading_info) { }
public void Generate_ad_hoc_data( IInputOutput input_output, ISpreadsheet spreadsheet, ICSVFile <BankRecord> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <ActualBankRecord, BankRecord> data_loading_info) { }
public void Generate_ad_hoc_data( IInputOutput input_output, ISpreadsheet spreadsheet, ICSVFile <CredCard2InOutRecord> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <CredCard2Record, CredCard2InOutRecord> data_loading_info) { }
public void Merge_bespoke_data_with_pending_file( IInputOutput input_output, ISpreadsheet spreadsheet, ICSVFile <CredCard2InOutRecord> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <CredCard2Record, CredCard2InOutRecord> data_loading_info) { var most_recent_cred_card_direct_debit = spreadsheet.Get_most_recent_row_containing_text <BankRecord>( MainSheetNames.Bank_out, ReconConsts.Cred_card2_dd_description, new List <int> { ReconConsts.DescriptionColumn, ReconConsts.DdDescriptionColumn }); var statement_date = new DateTime(); var next_date = most_recent_cred_card_direct_debit.Date.AddMonths(1); var input = input_output.Get_input(string.Format( ReconConsts.AskForCredCardDirectDebit, ReconConsts.Cred_card2_name, next_date.ToShortDateString())); double new_balance = 0; while (input != "0") { if (double.TryParse(input, out new_balance)) { new_balance = new_balance * -1; pending_file.Records.Add(new CredCard2InOutRecord { Date = next_date, Description = ReconConsts.Cred_card2_regular_pymt_description, Unreconciled_amount = new_balance }); } statement_date = next_date.AddMonths(-1); next_date = next_date.Date.AddMonths(1); input = input_output.Get_input(string.Format( ReconConsts.AskForCredCardDirectDebit, ReconConsts.Cred_card2_name, next_date.ToShortDateString())); } if (!new_balance.Double_equals(0)) { spreadsheet.Update_balance_on_totals_sheet( Codes.Cred_card2_bal, new_balance, string.Format( ReconConsts.CredCardBalanceDescription, ReconConsts.Cred_card2_name, $"{statement_date.ToString("MMM")} {statement_date.Year}"), balance_column: 5, text_column: 6, code_column: 4, input_output: input_output); } }
private void Merge_other_data <TThirdPartyType, TOwnedType>( ISpreadsheet spreadsheet, ICSVFile <TOwnedType> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { data_loading_info.Loader.Merge_bespoke_data_with_pending_file(_input_output, spreadsheet, pending_file, budgeting_months, data_loading_info); }
public void M_WhenDoingExpenseMatchingWillFilterOwnedFileForWagesRowsAndExpenseTransactionsOnly() { // Arrange var mock_bank_and_bank_in_loader = new Mock <IBankAndBankInLoader>(); var mock_bank_in_file_io = new Mock <IFileIO <BankRecord> >(); var wages_description = $"Wages ({ReconConsts.Employer_expense_description}) (!! in an inestimable manner, not forthwith - forever 1st outstanding)"; mock_bank_in_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)) .Returns(new List <BankRecord> { new BankRecord { Type = Codes.Expenses, Description = Codes.Expenses + "1" }, new BankRecord { Type = "Chq", Description = "something" }, new BankRecord { Type = Codes.Expenses, Description = Codes.Expenses + "2" }, new BankRecord { Type = Codes.Expenses, Description = Codes.Expenses + "3" }, new BankRecord { Type = "Chq", Description = "something" }, new BankRecord { Type = "PCL", Description = wages_description } }); var bank_in_file = new GenericFile <BankRecord>(new CSVFile <BankRecord>(mock_bank_in_file_io.Object)); var mock_actual_bank_file_io = new Mock <IFileIO <ActualBankRecord> >(); mock_actual_bank_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)) .Returns(new List <ActualBankRecord> { new ActualBankRecord { Description = $"\"'{ReconConsts.Employer_expense_description}\"" } }); var actual_bank_file = new ActualBankInFile(new CSVFile <ActualBankRecord>(mock_actual_bank_file_io.Object)); var data_loading_info = new DataLoadingInformation <ActualBankRecord, BankRecord> { Sheet_name = MainSheetNames.Bank_in }; var reconciliator = new Reconciliator <ActualBankRecord, BankRecord>(data_loading_info, actual_bank_file, bank_in_file); var matcher = new BankAndBankInMatcher(this, new FakeSpreadsheetRepoFactory(), mock_bank_and_bank_in_loader.Object); // Act matcher.Filter_for_all_wages_rows_and_expense_transactions_from_expected_in(reconciliator); // Assert Assert.AreEqual(4, reconciliator.Owned_file.Records.Count); Assert.AreEqual(Codes.Expenses + "1", reconciliator.Owned_file.Records[0].Description); Assert.AreEqual(Codes.Expenses + "2", reconciliator.Owned_file.Records[1].Description); Assert.AreEqual(Codes.Expenses + "3", reconciliator.Owned_file.Records[2].Description); Assert.AreEqual(wages_description, reconciliator.Owned_file.Records[3].Description); }
private void Generate_ad_hoc_data <TThirdPartyType, TOwnedType>( ISpreadsheet spreadsheet, ICSVFile <TOwnedType> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { _input_output.Output_line("Generating ad hoc data..."); data_loading_info.Loader.Generate_ad_hoc_data(_input_output, spreadsheet, pending_file, budgeting_months, data_loading_info); }
public void Load_pending_data <TThirdPartyType, TOwnedType>( IFileIO <TOwnedType> pending_file_io, ICSVFile <TOwnedType> pending_file, DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { _input_output.Output_line( "Loading data from pending file (which you should have already split out, if necessary)..."); pending_file_io.Set_file_paths(data_loading_info.File_paths.Main_path, data_loading_info.Pending_file_name); pending_file.Load(true, data_loading_info.Default_separator); // The separator we loaded with had to match the source. Then we convert it here to match its destination. pending_file.Convert_source_line_separators(data_loading_info.Default_separator, data_loading_info.Loading_separator); }
public void M_WillFilterOwnedFileForSpecifiedTransactionsOnly() { // Arrange var mock_cred_card2_in_out_file_io = new Mock <IFileIO <CredCard2InOutRecord> >(); mock_cred_card2_in_out_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)) .Returns(new List <CredCard2InOutRecord> { new CredCard2InOutRecord { Description = ReconConsts.iTunes_description + "1" }, new CredCard2InOutRecord { Description = "something" }, new CredCard2InOutRecord { Description = ReconConsts.iTunes_description + "2" }, new CredCard2InOutRecord { Description = ReconConsts.iTunes_description + "3" }, new CredCard2InOutRecord { Description = "something else" } }); var cred_card2_in_out_file = new GenericFile <CredCard2InOutRecord>(new CSVFile <CredCard2InOutRecord>(mock_cred_card2_in_out_file_io.Object)); var mock_cred_card2_file_io = new Mock <IFileIO <CredCard2Record> >(); mock_cred_card2_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)) .Returns(new List <CredCard2Record> { new CredCard2Record { Description = $"\"HOLLYHILL {ReconConsts.iTunes_description}\"" } }); var cred_card2_file = new GenericFile <CredCard2Record>(new CSVFile <CredCard2Record>(mock_cred_card2_file_io.Object)); var data_loading_info = new DataLoadingInformation <CredCard2Record, CredCard2InOutRecord> { Sheet_name = MainSheetNames.Cred_card2, Loader = new CredCard2AndCredCard2InOutLoader() }; var reconciliator = new Reconciliator <CredCard2Record, CredCard2InOutRecord>(data_loading_info, cred_card2_file, cred_card2_in_out_file); var matcher = new CredCard2AndCredCard2InOutMatcher(this); // Act matcher.SetiTunesStrings(); matcher.Filter_matching_transactions_from_cred_card2_in_out(reconciliator); // Assert Assert.AreEqual(3, reconciliator.Owned_file.Records.Count); Assert.AreEqual(ReconConsts.iTunes_description + "1", reconciliator.Owned_file.Records[0].Description); Assert.AreEqual(ReconConsts.iTunes_description + "2", reconciliator.Owned_file.Records[1].Description); Assert.AreEqual(ReconConsts.iTunes_description + "3", reconciliator.Owned_file.Records[2].Description); }
private void Merge_budget_data <TThirdPartyType, TOwnedType>( ISpreadsheet spreadsheet, ICSVFile <TOwnedType> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { _input_output.Output_line("Merging budget data with pending data..."); spreadsheet.Add_budgeted_monthly_data_to_pending_file(budgeting_months, pending_file, data_loading_info.Monthly_budget_data); if (null != data_loading_info.Annual_budget_data) { spreadsheet.Add_budgeted_annual_data_to_pending_file(budgeting_months, pending_file, data_loading_info.Annual_budget_data); } }
public void M_WillCallGenerateAdHocDataWithPendingFile_ForPassedInLoader() { // Arrange var mock_input_output = new Mock <IInputOutput>(); var reconciliate = new FileLoader(mock_input_output.Object, new Clock()); var mock_spreadsheet = new Mock <ISpreadsheet>(); var mock_pending_file_io = new Mock <IFileIO <BankRecord> >(); var mock_pending_file = new Mock <ICSVFile <BankRecord> >(); var mock_actual_bank_file_io = new Mock <IFileIO <ActualBankRecord> >(); var mock_bank_out_file_io = new Mock <IFileIO <BankRecord> >(); var budgeting_months = new BudgetingMonths { Start_year = 2020, Next_unplanned_month = 6, Last_month_for_budget_planning = 6 }; mock_actual_bank_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)) .Returns(new List <ActualBankRecord>()); mock_bank_out_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)) .Returns(new List <BankRecord>()); var mock_loader = new Mock <ILoader <ActualBankRecord, BankRecord> >(); mock_loader.Setup(x => x.Create_new_third_party_file(It.IsAny <IFileIO <ActualBankRecord> >())).Returns(new ActualBankInFile(new CSVFile <ActualBankRecord>(mock_actual_bank_file_io.Object))); mock_loader.Setup(x => x.Create_new_owned_file(It.IsAny <IFileIO <BankRecord> >())).Returns(new GenericFile <BankRecord>(new CSVFile <BankRecord>(mock_bank_out_file_io.Object))); var loading_info = new DataLoadingInformation <ActualBankRecord, BankRecord> { Loader = mock_loader.Object, File_paths = new FilePaths() }; var mock_matcher = new Mock <IMatcher>(); // Act var reconciliation_interface = reconciliate.Load <ActualBankRecord, BankRecord>( mock_spreadsheet.Object, mock_pending_file_io.Object, mock_pending_file.Object, mock_actual_bank_file_io.Object, mock_bank_out_file_io.Object, budgeting_months, loading_info, mock_matcher.Object); // Assert mock_loader.Verify(x => x.Generate_ad_hoc_data( mock_input_output.Object, mock_spreadsheet.Object, mock_pending_file.Object, budgeting_months, loading_info), Times.Exactly(1)); }
private void Merge_unreconciled_data <TThirdPartyType, TOwnedType>( ISpreadsheet spreadsheet, ICSVFile <TOwnedType> pending_file, DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { _input_output.Output_line("Merging unreconciled rows from spreadsheet with pending and budget data..."); spreadsheet.Add_unreconciled_rows_to_csv_file <TOwnedType>(data_loading_info.Sheet_name, pending_file); _input_output.Output_line("Copying merged data (from pending, unreconciled, and budgeting) into main 'owned' csv file..."); pending_file.Update_source_lines_for_output(data_loading_info.Loading_separator); pending_file.Write_to_file_as_source_lines(data_loading_info.File_paths.Owned_file_name); _input_output.Output_line("..."); }
Create_reconciliation_interface <TThirdPartyType, TOwnedType>( DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info, Reconciliator <TThirdPartyType, TOwnedType> reconciliator, IMatcher matcher) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { _input_output.Output_line("Creating reconciliation interface..."); var reconciliation_interface = new ReconciliationInterface <TThirdPartyType, TOwnedType>( new InputOutput(), reconciliator, data_loading_info.Third_party_descriptor, data_loading_info.Owned_file_descriptor, matcher); return(reconciliation_interface); }
public void Merge_bespoke_data_with_pending_file( IInputOutput input_output, ISpreadsheet spreadsheet, ICSVFile <BankRecord> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <ActualBankRecord, BankRecord> data_loading_info) { input_output.Output_line(ReconConsts.Loading_expenses); _expected_income_csv_file.Load(false); spreadsheet.Add_unreconciled_rows_to_csv_file <ExpectedIncomeRecord>(MainSheetNames.Expected_in, _expected_income_file.File); _expected_income_csv_file.Populate_source_records_from_records(); _expected_income_file.Filter_for_employer_expenses_and_bank_transactions_only(); _expected_income_file.Copy_to_pending_file(pending_file); _expected_income_csv_file.Populate_records_from_original_file_load(); }
Load_files_and_merge_data <TThirdPartyType, TOwnedType>( DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info, ISpreadsheetRepoFactory spreadsheet_factory, IMatcher matcher) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { ReconciliationInterface <TThirdPartyType, TOwnedType> reconciliation_interface = null; try { // NB This is the only function the spreadsheet is used in, until the very end (Reconciliator.Finish, called from // ReconciliationInterface), when another spreadsheet instance gets created by FileIO so it can call // WriteBackToMainSpreadsheet. Between now and then, everything is done using csv files. var spreadsheet_repo = spreadsheet_factory.Create_spreadsheet_repo(); var spreadsheet = new Spreadsheet(spreadsheet_repo); BudgetingMonths budgeting_months = Recursively_ask_for_budgeting_months(spreadsheet); _input_output.Output_line("Loading data..."); var pending_file_io = new FileIO <TOwnedType>(spreadsheet_factory); var third_party_file_io = new FileIO <TThirdPartyType>(spreadsheet_factory); var owned_file_io = new FileIO <TOwnedType>(spreadsheet_factory); var pending_file = new CSVFile <TOwnedType>(pending_file_io); reconciliation_interface = Load <TThirdPartyType, TOwnedType>( spreadsheet, pending_file_io, pending_file, third_party_file_io, owned_file_io, budgeting_months, data_loading_info, matcher); } finally { spreadsheet_factory.Dispose_of_spreadsheet_repo(); } _input_output.Output_line(""); _input_output.Output_line(""); return(reconciliation_interface); }
Load_third_party_and_owned_files_into_reconciliator <TThirdPartyType, TOwnedType>( DataLoadingInformation <TThirdPartyType, TOwnedType> data_loading_info, IFileIO <TThirdPartyType> third_party_file_io, IFileIO <TOwnedType> owned_file_io) where TThirdPartyType : ICSVRecord, new() where TOwnedType : ICSVRecord, new() { _input_output.Output_line("Loading data back in from 'owned' and 'third party' files..."); third_party_file_io.Set_file_paths(data_loading_info.File_paths.Main_path, data_loading_info.File_paths.Third_party_file_name); owned_file_io.Set_file_paths(data_loading_info.File_paths.Main_path, data_loading_info.File_paths.Owned_file_name); var third_party_file = data_loading_info.Loader.Create_new_third_party_file(third_party_file_io); var owned_file = data_loading_info.Loader.Create_new_owned_file(owned_file_io); var reconciliator = new Reconciliator <TThirdPartyType, TOwnedType>( data_loading_info, third_party_file, owned_file); return(reconciliator); }
public void Generate_ad_hoc_data( IInputOutput input_output, ISpreadsheet spreadsheet, ICSVFile <BankRecord> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <ActualBankRecord, BankRecord> data_loading_info) { if (budgeting_months.Do_expected_out_budgeting) { Update_owed_CHB(input_output, spreadsheet, budgeting_months); Update_weekly_item(input_output, spreadsheet, budgeting_months, "weekly spends", Codes.Code004, Codes.Code074); Update_weekly_item(input_output, spreadsheet, budgeting_months, "grocery shopping", Codes.Code005, Codes.Code075); Update_monthly_item(input_output, spreadsheet, budgeting_months, "yoga", Codes.Code078, Codes.Code078); Update_monthly_item(input_output, spreadsheet, budgeting_months, "fuel", Codes.Code006, Codes.Code006); Update_monthly_item(input_output, spreadsheet, budgeting_months, "vet", Codes.Code007, Codes.Code007); Update_monthly_item(input_output, spreadsheet, budgeting_months, "domain hosting", Codes.Code011, Codes.Code011); } }
public void Merge_bespoke_data_with_pending_file( IInputOutput input_output, ISpreadsheet spreadsheet, ICSVFile <BankRecord> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <ActualBankRecord, BankRecord> data_loading_info) { Add_most_recent_credit_card_direct_debits( input_output, spreadsheet, pending_file, ReconConsts.Cred_card1_name, ReconConsts.Cred_card1_dd_description); Add_most_recent_credit_card_direct_debits( input_output, spreadsheet, pending_file, ReconConsts.Cred_card2_name, ReconConsts.Cred_card2_dd_description); }
public void M_WillFilterActualBankFileForExpenseTransactionsOnly() { // Arrange var mock_bank_and_bank_in_loader = new Mock <IBankAndBankInLoader>(); var mock_actual_bank_file_io = new Mock <IFileIO <ActualBankRecord> >(); mock_actual_bank_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)) .Returns(new List <ActualBankRecord> { new ActualBankRecord { Description = $"\"'{ReconConsts.Employer_expense_description}\"" }, new ActualBankRecord { Description = "something else" } }); var actual_bank_file = new ActualBankInFile(new CSVFile <ActualBankRecord>(mock_actual_bank_file_io.Object)); var mock_bank_in_file_io = new Mock <IFileIO <BankRecord> >(); mock_bank_in_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)) .Returns(new List <BankRecord> { new BankRecord { Type = Codes.Expenses, Description = Codes.Expenses + "1" } }); var bank_in_file = new GenericFile <BankRecord>(new CSVFile <BankRecord>(mock_bank_in_file_io.Object)); var data_loading_info = new DataLoadingInformation <ActualBankRecord, BankRecord> { Sheet_name = MainSheetNames.Bank_in }; var reconciliator = new Reconciliator <ActualBankRecord, BankRecord>(data_loading_info, actual_bank_file, bank_in_file); var matcher = new BankAndBankInMatcher(this, new FakeSpreadsheetRepoFactory(), mock_bank_and_bank_in_loader.Object); // Act matcher.Filter_for_all_expense_transactions_from_actual_bank_in(reconciliator); // Assert Assert.AreEqual(1, reconciliator.Third_party_file.Records.Count); Assert.AreEqual(ReconConsts.Employer_expense_description, reconciliator.Third_party_file.Records[0].Description.Remove_punctuation()); }
public void Merge_bespoke_data_with_pending_file( IInputOutput input_output, ISpreadsheet spreadsheet, ICSVFile <BankRecord> pending_file, BudgetingMonths budgeting_months, DataLoadingInformation <ActualBankRecord, BankRecord> data_loading_info) { Add_most_recent_credit_card_direct_debits( input_output, spreadsheet, pending_file, ReconConsts.Cred_card1_name, ReconConsts.Cred_card1_dd_description); Add_most_recent_credit_card_direct_debits( input_output, spreadsheet, pending_file, ReconConsts.Cred_card2_name, ReconConsts.Cred_card2_dd_description); // Note that we can't update bank balance here because we don't have access to third party file, // so we do it below in Do_actions_which_require_third_party_data_access. }
public void Will_not_lose_previously_matched_records_when_files_are_refreshed() { // Arrange var some_other_actual_bank_description = "Some other ActualBank description"; var some_other_bank_description = "Some other bank description"; var actual_bank_data = new List <ActualBankRecord> { new ActualBankRecord { Description = ReconConsts.Employer_expense_description }, new ActualBankRecord { Description = some_other_actual_bank_description } }; var mock_actual_bank_file_io = new Mock <IFileIO <ActualBankRecord> >(); mock_actual_bank_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)).Returns(actual_bank_data); var actual_bank_file = new GenericFile <ActualBankRecord>(new CSVFile <ActualBankRecord>(mock_actual_bank_file_io.Object)); var bank_data = new List <BankRecord> { new BankRecord { Description = "BankRecord01", Type = Codes.Expenses }, new BankRecord { Description = "BankRecord02", Type = Codes.Expenses }, new BankRecord { Description = "BankRecord03", Type = Codes.Expenses }, new BankRecord { Description = some_other_bank_description, Type = "Not an expense" } }; var mock_bank_file_io = new Mock <IFileIO <BankRecord> >(); mock_bank_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)).Returns(bank_data); var bank_file = new GenericFile <BankRecord>(new CSVFile <BankRecord>(mock_bank_file_io.Object)); var data_loading_info = new DataLoadingInformation <ActualBankRecord, BankRecord> { Sheet_name = MainSheetNames.Bank_in }; var reconciliator = new Reconciliator <ActualBankRecord, BankRecord>(data_loading_info, actual_bank_file, bank_file); var expected_potential_matches = new List <PotentialMatch> { new PotentialMatch { Actual_records = new List <ICSVRecord> { bank_data[0], bank_data[1] }, Console_lines = new List <ConsoleLine> { new ConsoleLine { Description_string = "Console Description" } } } }; var mock_bank_and_bank_in_loader = new Mock <IBankAndBankInLoader>(); var matcher = new BankAndBankInMatcher(this, new FakeSpreadsheetRepoFactory(), mock_bank_and_bank_in_loader.Object); matcher.Filter_for_all_expense_transactions_from_actual_bank_in(reconciliator); matcher.Filter_for_all_wages_rows_and_expense_transactions_from_expected_in(reconciliator); reconciliator.Set_match_finder((record, file) => expected_potential_matches); reconciliator.Set_record_matcher(matcher.Match_specified_records); reconciliator.Find_reconciliation_matches_for_next_third_party_record(); reconciliator.Match_current_record(0); Assert.AreEqual(1, reconciliator.Third_party_file.Records.Count); Assert.AreEqual(2, reconciliator.Owned_file.Records.Count); Assert.IsFalse(reconciliator.Owned_file.Records[0].Matched); Assert.IsTrue(reconciliator.Owned_file.Records[1].Matched); Assert.IsTrue(reconciliator.Owned_file.Records[1].Description.Contains(ReconConsts.SeveralExpenses)); // Act reconciliator.Refresh_files(); // Assert Assert.AreEqual(2, reconciliator.Third_party_file.Records.Count); Assert.AreEqual(some_other_actual_bank_description, reconciliator.Third_party_file.Records[1].Description); Assert.AreEqual(3, reconciliator.Owned_file.Records.Count); Assert.IsFalse(reconciliator.Owned_file.Records[0].Matched); Assert.AreEqual(some_other_bank_description, reconciliator.Owned_file.Records[1].Description); Assert.AreEqual(actual_bank_data[0], reconciliator.Owned_file.Records[2].Match); Assert.IsTrue(reconciliator.Owned_file.Records[2].Matched); Assert.IsTrue(reconciliator.Owned_file.Records[2].Description.Contains(ReconConsts.SeveralExpenses)); }
public void Will_not_lose_previously_matched_records_when_files_are_refreshed() { // Arrange var some_other_third_party_description = "Some other third party Cred Card 2 description"; var some_other_owned_description = "Some other owned Cred Card 2 description"; var third_party_data = new List <CredCard2Record> { new CredCard2Record { Description = ReconConsts.Amazon_description }, new CredCard2Record { Description = some_other_third_party_description } }; var mock_cred_card2_file_io = new Mock <IFileIO <CredCard2Record> >(); mock_cred_card2_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)).Returns(third_party_data); var cred_card2_file = new GenericFile <CredCard2Record>(new CSVFile <CredCard2Record>(mock_cred_card2_file_io.Object)); var owned_data = new List <CredCard2InOutRecord> { new CredCard2InOutRecord { Description = $"{ReconConsts.Amazon_description} CredCard2InOutRecord01" }, new CredCard2InOutRecord { Description = $"{ReconConsts.Amazon_description} CredCard2InOutRecord02" }, new CredCard2InOutRecord { Description = $"{ReconConsts.Amazon_description} CredCard2InOutRecord03" }, new CredCard2InOutRecord { Description = some_other_owned_description } }; var mock_cred_card2_in_out_file_io = new Mock <IFileIO <CredCard2InOutRecord> >(); mock_cred_card2_in_out_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null)).Returns(owned_data); var cred_card2_in_out_file = new GenericFile <CredCard2InOutRecord>(new CSVFile <CredCard2InOutRecord>(mock_cred_card2_in_out_file_io.Object)); var data_loading_info = new DataLoadingInformation <CredCard2Record, CredCard2InOutRecord> { Sheet_name = MainSheetNames.Cred_card2, Loader = new CredCard2AndCredCard2InOutLoader() }; var reconciliator = new Reconciliator <CredCard2Record, CredCard2InOutRecord>(data_loading_info, cred_card2_file, cred_card2_in_out_file); var expected_potential_matches = new List <PotentialMatch> { new PotentialMatch { Actual_records = new List <ICSVRecord> { owned_data[0], owned_data[1] }, Console_lines = new List <ConsoleLine> { new ConsoleLine { Description_string = "Console Description" } } } }; var matcher = new CredCard2AndCredCard2InOutMatcher(this); matcher.Filter_matching_transactions_from_cred_card2(reconciliator); matcher.Filter_matching_transactions_from_cred_card2_in_out(reconciliator); reconciliator.Set_match_finder((record, file) => expected_potential_matches); reconciliator.Set_record_matcher(matcher.Match_specified_records); reconciliator.Find_reconciliation_matches_for_next_third_party_record(); reconciliator.Match_current_record(0); Assert.AreEqual(1, reconciliator.Third_party_file.Records.Count); Assert.AreEqual(2, reconciliator.Owned_file.Records.Count); Assert.IsFalse(reconciliator.Owned_file.Records[0].Matched); Assert.IsTrue(reconciliator.Owned_file.Records[1].Matched); Assert.IsTrue(reconciliator.Owned_file.Records[1].Description.Contains(ReconConsts.SeveralAmazonTransactions)); // Act matcher.SetAmazonStrings(); reconciliator.Refresh_files(); // Assert Assert.AreEqual(2, reconciliator.Third_party_file.Records.Count); Assert.AreEqual(some_other_third_party_description, reconciliator.Third_party_file.Records[1].Description); Assert.AreEqual(3, reconciliator.Owned_file.Records.Count); Assert.IsFalse(reconciliator.Owned_file.Records[0].Matched); Assert.AreEqual(some_other_owned_description, reconciliator.Owned_file.Records[1].Description); Assert.AreEqual(third_party_data[0], reconciliator.Owned_file.Records[2].Match); Assert.IsTrue(reconciliator.Owned_file.Records[2].Matched); Assert.IsTrue(reconciliator.Owned_file.Records[2].Description.Contains(ReconConsts.SeveralAmazonTransactions)); }