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);
        }
        public void M_CanShowFirstExpenseTransactionWithListOfMatches()
        {
            // Arrange
            var mock_bank_and_bank_in_loader = new Mock <IBankAndBankInLoader>();
            var mock_actual_bank_file_io     = new Mock <IFileIO <ActualBankRecord> >();
            var mock_bank_file_io            = new Mock <IFileIO <BankRecord> >();

            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"
                }
            });
            mock_bank_file_io.Setup(x => x.Load(It.IsAny <List <string> >(), null))
            .Returns(new List <BankRecord> {
                new BankRecord {
                    Type = Codes.Expenses, Description = Codes.Expenses
                },
                new BankRecord {
                    Type = Codes.Expenses, Description = Codes.Expenses
                },
                new BankRecord {
                    Type = Codes.Expenses, Description = Codes.Expenses
                },
                new BankRecord {
                    Type = "Chq", Description = "something else"
                }
            });
            var reconciliator = new Reconciliator <ActualBankRecord, BankRecord>("Bank In", mock_actual_bank_file_io.Object, mock_bank_file_io.Object);
            var matcher       = new BankAndBankInMatcher(this, new FakeSpreadsheetRepoFactory(), mock_bank_and_bank_in_loader.Object);

            // Act
            matcher.Debug_preliminary_stuff(reconciliator);

            // Assert
            var expense_description_lines = _output_all_lines_recorded_console_lines.Where(
                x => x.Description_string == ReconConsts.Employer_expense_description);

            Assert.AreEqual(1, expense_description_lines.Count(), "transaction with expense description.");
            var expense_code_lines = _output_all_lines_recorded_console_lines.Where(
                x => x.Description_string == Codes.Expenses);

            Assert.AreEqual(3, expense_code_lines.Count(), "row with expense code.");

            // Clean up
            reconciliator.Refresh_files();
        }
        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);
        }
Beispiel #4
0
        public void Match_BankIn_records(
            RecordForMatching <ActualBankRecord> record_for_matching,
            int match_index,
            ICSVFile <BankRecord> owned_file)
        {
            var match = (BankRecord)record_for_matching.Matches[match_index].Actual_records[0];

            if (match.Type == Codes.ExpectedInBankTransaction)
            {
                _bank_and_bank_in_loader.Update_expected_income_record_when_matched(
                    record_for_matching.SourceRecord,
                    match);
            }

            Reconciliator <ActualBankRecord, BankRecord> .Match_specified_records(record_for_matching, match_index, owned_file);
        }
        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);
        }
        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 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 MovementController(Human human)
 {
     Human          = human;
     _reconciliator = new Reconciliator(human);
 }
        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));
        }