# Path: bankcsvtoqif/io.py
# class Messenger(object):
#     """ Handles console output.  """
# 
#     def __init__(self, on):
#         self.on = on
# 
#     def send_message(self, msg, preblanks=0):
#         if self.on:
#             for blank in range(0, preblanks):
#                 print()
#             print(msg)
# 
# Path: bankcsvtoqif/smartlabeler.py
# class Replacement(object):
#     """ A class to automatically handle replacements in transactions.
#         If 'pattern' is matched in the original description of a transaction,
#         the description is replaced by 'new_description' and the
#         target account 'account' is automatically added. The
#         'append_date'-flag works as follows:
#         append_date = 0: nothing is appended to 'new_description'
#         append_date = 1: appends year-month to 'new_description' like 2015-05
#         append_date = 2: appends year-next_month to 'new_description' like 2015-06
#     """
# 
#     def __init__(self, pattern=None, new_description=None, account=None, append_date=0):
#         self.pattern = pattern
#         self.new_description = new_description
#         self.account = account
#         self.append_date = append_date
# 
#     def load_from_json(self, data):
#         self.pattern = data[0]
#         self.new_description = data[1]
#         self.account = data[2]
#         self.append_date = data[3]
# 
#     def matches(self, search_str):
#         return self.pattern in search_str
# 
#     def should_append_date(self):
#         return self.append_date in [1, 2]
# 
#     def should_append_next_month_date(self):
#         return self.append_date == 2
# 
#     def get_description(self, date):
#         if not self.should_append_date():
#             return self.new_description
# 
#         if self.should_append_next_month_date():
#             date += monthdelta(1)
#         return self.new_description + ' ' + date.strftime('%Y-%m')
# 
# Path: bankcsvtoqif/transaction.py
# class Transaction(object):
#     """ Represents a transaction obtained from csv-file. """
# 
#     def __init__(self, date, description, debit, credit, target_account, source_account='Assets:Current Assets:Checking Account'):
#         self.date = date
#         self.description = description
#         self.debit = debit
#         self.credit = credit
#         self.target_account = target_account
#         self.source_account = source_account
# 
#     def __str__(self):
#         return '<Transaction %s, %s, %s, %s, %s>'% (
#             self.date,
#             self.description,
#             self.debit,
#             self.credit,
#             self.target_account
#         )
# 
#     @property
#     def amount(self):
#         return self.credit - self.debit
# 
#     def to_qif_line(self):
#         return [
#             '!Type:Cash',
#             'D' + self.date.strftime('%m/%d/%y'),
#             'S' + self.target_account,
#             'P' + self.description,
#             '$' + '%.2f' % self.amount,
#             '^'
#         ]
# 
# Path: bankcsvtoqif/smartlabeler.py
# class SmartLabeler(object):
#     """ Relabels descriptions of transactions using Replacements. """
# 
#     def __init__(self):
#         self.replacements = []
# 
#     def load_replacements_from_file(self, f, account_name):
#         all_replacements = json.load(f)
#         for repdata in all_replacements[account_name]:
#             r = Replacement()
#             r.load_from_json(repdata)
#             self.replacements.append(r)
# 
#     def has_replacement(self, transaction):
#         for replacement in self.replacements:
#             if replacement.matches(transaction.description):
#                 return replacement
# 
#     def replace(self, transaction, replacement):
#         if replacement.new_description:
#             transaction.description = replacement.get_description(transaction.date)
#         transaction.target_account = replacement.account
#         return transaction
# 
#     def run_replacements(self, transactions, messenger):
#         for index, transaction in enumerate(transactions):
#             replacement = self.has_replacement(transaction)
#             if replacement:
#                 transactions[index] = self.replace(transaction, replacement)
#                 messenger.send_message("replaced: " + transactions[index].__str__())


import unittest
import json
from datetime import datetime
from bankcsvtoqif.io import Messenger
    from StringIO import StringIO
    from io import StringIO
from bankcsvtoqif.smartlabeler import Replacement
from bankcsvtoqif.transaction import Transaction
from bankcsvtoqif.smartlabeler import SmartLabeler
        append_date = 1
        self.replacement0.load_from_json([pattern, new_description, account, append_date])
        self.assertEqual(self.replacement0.pattern, pattern)
        self.assertEqual(self.replacement0.new_description, new_description)
        self.assertEqual(self.replacement0.account, account)
        self.assertEqual(self.replacement0.append_date, append_date)

    def test_replacement_matches(self):
        self.assertEqual(self.replacement1.matches('Rent'), True)

    def test_replacement_should_append_date(self):
        self.assertEqual(self.replacement0.should_append_date(), False)
        self.assertEqual(self.replacement1.should_append_date(), True)
        self.assertEqual(self.replacement2.should_append_date(), True)

    def test_replacement_should_append_next_month_date(self):
        self.assertEqual(self.replacement0.should_append_next_month_date(), False)
        self.assertEqual(self.replacement1.should_append_next_month_date(), False)
        self.assertEqual(self.replacement2.should_append_next_month_date(), True)

    def test_replacement_get_description(self):
        date = datetime(2015, 5, 1)
        self.assertEqual(self.replacement0.get_description(date), 'Rent')
        self.assertEqual(self.replacement1.get_description(date), 'Rent 2015-05')
        self.assertEqual(self.replacement2.get_description(date), 'Rent 2015-06')


class TestSmartLabeler(unittest.TestCase):
    def setUp(self):
        self.transaction = Transaction(datetime(2015, 5, 1), 'RentXYZ234 3848267', 500, 0, 'Imbalance-EUR')

# Path: bankcsvtoqif/io.py
# class Messenger(object):
#     """ Handles console output.  """
# 
#     def __init__(self, on):
#         self.on = on
# 
#     def send_message(self, msg, preblanks=0):
#         if self.on:
#             for blank in range(0, preblanks):
#                 print()
#             print(msg)
# 
# Path: bankcsvtoqif/smartlabeler.py
# class Replacement(object):
#     """ A class to automatically handle replacements in transactions.
#         If 'pattern' is matched in the original description of a transaction,
#         the description is replaced by 'new_description' and the
#         target account 'account' is automatically added. The
#         'append_date'-flag works as follows:
#         append_date = 0: nothing is appended to 'new_description'
#         append_date = 1: appends year-month to 'new_description' like 2015-05
#         append_date = 2: appends year-next_month to 'new_description' like 2015-06
#     """
# 
#     def __init__(self, pattern=None, new_description=None, account=None, append_date=0):
#         self.pattern = pattern
#         self.new_description = new_description
#         self.account = account
#         self.append_date = append_date
# 
#     def load_from_json(self, data):
#         self.pattern = data[0]
#         self.new_description = data[1]
#         self.account = data[2]
#         self.append_date = data[3]
# 
#     def matches(self, search_str):
#         return self.pattern in search_str
# 
#     def should_append_date(self):
#         return self.append_date in [1, 2]
# 
#     def should_append_next_month_date(self):
#         return self.append_date == 2
# 
#     def get_description(self, date):
#         if not self.should_append_date():
#             return self.new_description
# 
#         if self.should_append_next_month_date():
#             date += monthdelta(1)
#         return self.new_description + ' ' + date.strftime('%Y-%m')
# 
# Path: bankcsvtoqif/transaction.py
# class Transaction(object):
#     """ Represents a transaction obtained from csv-file. """
# 
#     def __init__(self, date, description, debit, credit, target_account, source_account='Assets:Current Assets:Checking Account'):
#         self.date = date
#         self.description = description
#         self.debit = debit
#         self.credit = credit
#         self.target_account = target_account
#         self.source_account = source_account
# 
#     def __str__(self):
#         return '<Transaction %s, %s, %s, %s, %s>'% (
#             self.date,
#             self.description,
#             self.debit,
#             self.credit,
#             self.target_account
#         )
# 
#     @property
#     def amount(self):
#         return self.credit - self.debit
# 
#     def to_qif_line(self):
#         return [
#             '!Type:Cash',
#             'D' + self.date.strftime('%m/%d/%y'),
#             'S' + self.target_account,
#             'P' + self.description,
#             '$' + '%.2f' % self.amount,
#             '^'
#         ]
# 
# Path: bankcsvtoqif/smartlabeler.py
# class SmartLabeler(object):
#     """ Relabels descriptions of transactions using Replacements. """
# 
#     def __init__(self):
#         self.replacements = []
# 
#     def load_replacements_from_file(self, f, account_name):
#         all_replacements = json.load(f)
#         for repdata in all_replacements[account_name]:
#             r = Replacement()
#             r.load_from_json(repdata)
#             self.replacements.append(r)
# 
#     def has_replacement(self, transaction):
#         for replacement in self.replacements:
#             if replacement.matches(transaction.description):
#                 return replacement
# 
#     def replace(self, transaction, replacement):
#         if replacement.new_description:
#             transaction.description = replacement.get_description(transaction.date)
#         transaction.target_account = replacement.account
#         return transaction
# 
#     def run_replacements(self, transactions, messenger):
#         for index, transaction in enumerate(transactions):
#             replacement = self.has_replacement(transaction)
#             if replacement:
#                 transactions[index] = self.replace(transaction, replacement)
#                 messenger.send_message("replaced: " + transactions[index].__str__())


# Path: bankcsvtoqif/tests/test_smartlabeler.py
import unittest
import json
from datetime import datetime
from bankcsvtoqif.io import Messenger
    from StringIO import StringIO
    from io import StringIO
from bankcsvtoqif.smartlabeler import Replacement
from bankcsvtoqif.transaction import Transaction
from bankcsvtoqif.smartlabeler import SmartLabeler

        append_date = 1
        self.replacement0.load_from_json([pattern, new_description, account, append_date])
        self.assertEqual(self.replacement0.pattern, pattern)
        self.assertEqual(self.replacement0.new_description, new_description)
        self.assertEqual(self.replacement0.account, account)
        self.assertEqual(self.replacement0.append_date, append_date)

    def test_replacement_matches(self):
        self.assertEqual(self.replacement1.matches('Rent'), True)

    def test_replacement_should_append_date(self):
        self.assertEqual(self.replacement0.should_append_date(), False)
        self.assertEqual(self.replacement1.should_append_date(), True)
        self.assertEqual(self.replacement2.should_append_date(), True)

    def test_replacement_should_append_next_month_date(self):
        self.assertEqual(self.replacement0.should_append_next_month_date(), False)
        self.assertEqual(self.replacement1.should_append_next_month_date(), False)
        self.assertEqual(self.replacement2.should_append_next_month_date(), True)

    def test_replacement_get_description(self):
        date = datetime(2015, 5, 1)
        self.assertEqual(self.replacement0.get_description(date), 'Rent')
        self.assertEqual(self.replacement1.get_description(date), 'Rent 2015-05')
        self.assertEqual(self.replacement2.get_description(date), 'Rent 2015-06')


class TestSmartLabeler(unittest.TestCase):
    def setUp(self):
        self.transaction = Transaction(datetime(2015, 5, 1), 'RentXYZ234 3848267', 500, 0, 'Imbalance-EUR')

        self.replacement1 = Replacement('Rent', 'Rent', 'Expenses:Rent', 0)