def __init__(self, purchases=[]):
     self.categories = defaultdict(lambda: [0.0, set(), 0.0])
     self.purchases = purchases
     self.unsane_items = []
     self.unsane_categories = []
     self.category_dict = ItemCategoryDict()
     self.total = 0.0
示例#2
0
def test_purchase():
    expected_positions = []
    cat_dict = ItemCategoryDict()
    cat_dict.item_category_dict = {'Pfand': 'Pfand', 'Cola Zero': 'Cola'}
    Position = namedtuple('item',
                          ['name', 'category', 'price', 'count', 'weight'])
    expected_positions.append(Position('Cola Zero', 'Cola', 0.39, 1, '1.5l'))
    expected_positions.append(Position('Pfand', 'Pfand', 0.25, 1, ''))
    expected_positions.append(Position('Mandelhörnchen', '', 1.59, 1, ''))
    expected_positions.append(Position('Kaffeegetränk', '', 0.49, 1, '0.25l'))
    expected_positions.append(
        Position('Schokolade Edelbitter', '', 1.09, 1, ''))
    expected_positions.append(
        Position('Schokolade Erdbeere Joghurt Crisp', '', 1.19, 1, '200g'))
    with Purchase('2015-05-21',
                  'Aldi',
                  payment_method='cash',
                  category_dict=cat_dict) as purchase:
        purchase.add_item('Cola Zero', 0.39, 1, weight='1.5l')
        purchase.add_item('Pfand', 0.25, 1)
        purchase.add_item('Mandelhörnchen', 1.59, 1)
        purchase.add_item('Kaffeegetränk', 0.49, 1, weight='0.25l')
        purchase.add_item('Schokolade Edelbitter', 1.09, 1)
        purchase.add_item('Schokolade Erdbeere Joghurt Crisp',
                          1.19,
                          1,
                          weight='200g')
        assert expected_positions == purchase.positions
        assert purchase.total == 5
示例#3
0
def test_category_create(factory_file):
    category_dict = ItemCategoryDict()
    category_dict.item_category_dict = {}
    category_dict.extract_new_categories('receipts_test.csv')
    assert '' not in category_dict.item_category_dict
    assert 'Bio Company' not in category_dict.item_category_dict
    assert category_dict.item_category_dict['Blanc de Pomm'] == 'Zubrot'
示例#4
0
 def test_category(self):
     category_dict = ItemCategoryDict()
     category_dict.item_category_dict = {'Pfand': 'Pfand',
                                         'Pesto': 'Pesto',
                                         'Parmesan': 'Käse',
                                         'Heumilch': 'Milch',
                                         'Milch': 'Milch',
                                         }
     cat_milch = category_dict.get_category('Milch')
     assert cat_milch == 'Milch'
示例#5
0
 def test_category(self):
     category_dict = ItemCategoryDict()
     category_dict.item_category_dict = {
         'Pfand': 'Pfand',
         'Pesto': 'Pesto',
         'Parmesan': 'Käse',
         'Heumilch': 'Milch',
         'Milch': 'Milch',
     }
     cat_milch = category_dict.get_category('Milch')
     assert cat_milch == 'Milch'
 def __init__(self, purchases=[]):
     self.categories = defaultdict(lambda: [0.0, set(), 0.0])
     self.purchases = purchases
     self.unsane_items = []
     self.unsane_categories = []
     self.category_dict = ItemCategoryDict()
     self.total = 0.0
示例#7
0
def test_purchase_ledger_only():
    cat_dict = ItemCategoryDict()
    cat_dict.item_category_dict = {'Pfand': 'Aktiva:Pfand',
                                   'Cola': 'Ausgaben:Konsum:Cola'}
    with Purchase('2015-05-21',
                  'Übertrag',
                  payment_method='Giro',
                  category_dict=cat_dict,
                  flags='L') as purchase:
        purchase.add_item('Auszahlung', 100, 1, category='Aktiva:Portmonaie')
    actual_output = purchase.get_ledger()
    expected_output = "2015-05-21 Übertrag\n"
    expected_output += "  Aktiva:Giro  -100.0\n"
    expected_output += "  Aktiva:Portmonaie  100.0\n"
    expected_output += "\n"
    assert expected_output == actual_output
示例#8
0
def test_purchase_ledger():
    cat_dict = ItemCategoryDict()
    cat_dict.item_category_dict = {'Pfand': 'Aktiva:Pfand',
                                   'Cola': 'Ausgaben:Konsum:Cola'}
    with Purchase('2015-05-21',
                  'Testgeschäft',
                  payment_method='cash',
                  category_dict=cat_dict) as purchase:
        purchase.add_item('Cola', 0.39, 1, weight='1.5l')
        purchase.add_item('Pfand', 0.25, 1)
    actual_output = purchase.get_ledger()
    expected_output = "2015-05-21 Testgeschäft\n"
    expected_output += "  Aktiva:Portmonaie  -0.64\n"
    expected_output += "  Ausgaben:Konsum:Cola  0.39\n"
    expected_output += "  Aktiva:Pfand  0.25\n"
    expected_output += "\n"
    assert expected_output == actual_output
示例#9
0
def test_purchase_ledger_only():
    cat_dict = ItemCategoryDict()
    cat_dict.item_category_dict = {
        'Pfand': 'Aktiva:Pfand',
        'Cola': 'Ausgaben:Konsum:Cola'
    }
    with Purchase('2015-05-21',
                  'Übertrag',
                  payment_method='Giro',
                  category_dict=cat_dict,
                  flags='L') as purchase:
        purchase.add_item('Auszahlung', 100, 1, category='Aktiva:Portmonaie')
    actual_output = purchase.get_ledger()
    expected_output = "2015-05-21 Übertrag\n"
    expected_output += "  Aktiva:Giro  -100.0\n"
    expected_output += "  Aktiva:Portmonaie  100.0\n"
    expected_output += "\n"
    assert expected_output == actual_output
示例#10
0
def test_readfile(factory_file):
    empty_dict = ItemCategoryDict()
    empty_dict.item_category_dict = {}
    with Parser(category_dictionary=empty_dict) as p:
        purchases = p.read_file('receipts_test.csv')
    assert purchases[0].date == '2015-11-29'
    assert purchases[0].shop == 'Bio Company'
    assert purchases[0].payment_method == 'cash'
    assert purchases[0].positions[0].name == 'Blanc de Pomm'
    assert purchases[0].positions[0].price == 1.69
    assert purchases[0].positions[0].count == 1
    assert purchases[0].positions[0].category == 'Zubrot'
    assert purchases[0].positions[1].name == 'Seidentofu'
    assert purchases[0].positions[1].price == 5.18
    assert purchases[0].positions[1].count == 2
    assert purchases[0].positions[1].category == ''
    assert purchases[1].date == '2014-11-01'
    assert purchases[1].shop == 'Bio Company'
    assert purchases[1].payment_method == 'Giro'
示例#11
0
def test_purchase_ledger():
    cat_dict = ItemCategoryDict()
    cat_dict.item_category_dict = {
        'Pfand': 'Aktiva:Pfand',
        'Cola': 'Ausgaben:Konsum:Cola'
    }
    with Purchase('2015-05-21',
                  'Testgeschäft',
                  payment_method='cash',
                  category_dict=cat_dict) as purchase:
        purchase.add_item('Cola', 0.39, 1, weight='1.5l')
        purchase.add_item('Pfand', 0.25, 1)
    actual_output = purchase.get_ledger()
    expected_output = "2015-05-21 Testgeschäft\n"
    expected_output += "  Aktiva:Portmonaie  -0.64\n"
    expected_output += "  Ausgaben:Konsum:Cola  0.39\n"
    expected_output += "  Aktiva:Pfand  0.25\n"
    expected_output += "\n"
    assert expected_output == actual_output
示例#12
0
 def __init__(self, date, shop, **kwargs):
     self._date = None
     self.date = date
     self.shop = shop
     self.payment_method = kwargs.get('payment_method', 'cash')
     self._positions = []
     self.category_dict = kwargs.get('category_dict', ItemCategoryDict())
     self._total = 0.0
     self.flags = {}
     self.extract_flags(kwargs.get('flags', ''))
     self.unsane_items = []
示例#13
0
def test_purchase():
    expected_positions = []
    cat_dict = ItemCategoryDict()
    cat_dict.item_category_dict = {'Pfand': 'Pfand', 'Cola Zero': 'Cola'}
    Position = namedtuple('item', ['name',
                                   'category',
                                   'price',
                                   'count',
                                   'weight'])
    expected_positions.append(Position('Cola Zero', 'Cola', 0.39, 1, '1.5l'))
    expected_positions.append(Position('Pfand', 'Pfand', 0.25, 1, ''))
    expected_positions.append(Position('Mandelhörnchen', '', 1.59, 1, ''))
    expected_positions.append(Position('Kaffeegetränk', '', 0.49, 1, '0.25l'))
    expected_positions.append(Position('Schokolade Edelbitter',
                                       '',
                                       1.09,
                                       1,
                                       ''))
    expected_positions.append(Position('Schokolade Erdbeere Joghurt Crisp',
                                       '',
                                       1.19,
                                       1,
                                       '200g'))
    with Purchase('2015-05-21',
                  'Aldi',
                  payment_method='cash',
                  category_dict=cat_dict) as purchase:
        purchase.add_item('Cola Zero', 0.39, 1, weight='1.5l')
        purchase.add_item('Pfand', 0.25, 1)
        purchase.add_item('Mandelhörnchen', 1.59, 1)
        purchase.add_item('Kaffeegetränk', 0.49, 1, weight='0.25l')
        purchase.add_item('Schokolade Edelbitter', 1.09, 1)
        purchase.add_item('Schokolade Erdbeere Joghurt Crisp',
                         1.19,
                         1,
                         weight='200g')
        assert expected_positions == purchase.positions
        assert purchase.total == 5
示例#14
0
 def __init__(self, *args, **kwargs):
     self.dictionary = kwargs.get('category_dictionary', ItemCategoryDict())
     self.purchase_is_active = None
     self.active_purchase = None
     self.purchases = []
示例#15
0
parser.add_argument("-l",
                    "--ledger",
                    action="store_true",
                    help="show receipts in ledger format ")
parser.add_argument("-d",
                    "--date",
                    metavar=('date'),
                    default="1900-01-01",
                    help="show only output from this day on")

args = parser.parse_args()

parser_args = {}

if args.categories_file:
    cat_dict = ItemCategoryDict(path=args.categories_file)
    parser_args['category_dictionary'] = cat_dict

with ReceiptParser(**parser_args) as p:
    purchases = p.read_file(args.receipts_file)
rc = ReceiptCollection(purchases)
rc.collect_items()

if args.categories:
    for key in rc.categories:
        print key
elif args.show_null:
    print 'Items without category:'
    for item in rc.categories[''][1]:
        print item
elif args.show_category is not None:
示例#16
0
class ReceiptCollection(object):
    '''
    Collection of purchases with evaluation and output options.
    '''

    def __init__(self, purchases=[]):
        self.categories = defaultdict(lambda: [0.0, set(), 0.0])
        self.purchases = purchases
        self.unsane_items = []
        self.unsane_categories = []
        self.category_dict = ItemCategoryDict()
        self.total = 0.0

    def collect_items(self):
        '''
        sort all positions in our stored receipts/purchases into their
        respective categories
        '''
        for purchase in self.purchases:
            self.unsane_items.extend(purchase.unsane_items)
            for item in purchase.positions:
                self.categories[item.category][1].add(item.name)
                self.categories[item.category][0] += item.price

        self.check_sanity()
        self.calculate_total()

    def totalize_categories(self):
        self.initialize_super_categories()
        for category in self.categories.keys():
            catsum = 0
            length = len(category)
            for cat in self.categories.keys():
                if (cat[0:length] == category):
                    catsum += self.categories[cat][0]
            self.categories[category][2] = catsum

    def initialize_super_categories(self):
        missing_super_categories = []
        for category in self.categories.keys():
            if (category[:category.rfind(':')] not in self.categories.keys()):
                missing_super_categories.append(category[:category.rfind(':')])
        for missing in missing_super_categories:
            while True:
                if missing not in self.categories:
                    self.categories[missing][0] = 0
                if missing.rfind(':') == -1:
                    break
                missing = missing[:missing.rfind(':')]

    def check_category(self, category, item):
        '''
        make list of conflicting categories
        '''
        stored_category = self.category_dict.get_category(item)
        if category != stored_category:
            self.unsane_categories.append((item, category, stored_category))

    def check_sanity(self):
        '''
        make list of items belonging to more than one category
        '''
        all_items = set()
        for category in self.categories:
            if category is '':
                continue
            for item in self.categories[category][1]:
                if item in all_items:
                    self.unsane_items.append(item)
                self.check_category(category, item)
                all_items.add(item)

    def calculate_total(self):
        '''
        calculate the grand total across all categories
        '''
        self.total = 0.0
        for category in self.categories:
            self.total += self.categories[category][0]

    def get_ledger(self, date='1900-01-01'):
        '''
        create output in the format of the ledger application
        '''
        ledger_output = ""
        for receipt in sorted(self.purchases, key=lambda t: t.date):
            if receipt.date >= date:
                ledger_output += receipt.get_ledger()
        return ledger_output
示例#17
0
class ReceiptCollection(object):
    '''
    Collection of purchases with evaluation and output options.
    '''
    def __init__(self, purchases=[]):
        self.categories = defaultdict(lambda: [0.0, set(), 0.0])
        self.purchases = purchases
        self.unsane_items = []
        self.unsane_categories = []
        self.category_dict = ItemCategoryDict()
        self.total = 0.0

    def collect_items(self):
        '''
        sort all positions in our stored receipts/purchases into their
        respective categories
        '''
        for purchase in self.purchases:
            self.unsane_items.extend(purchase.unsane_items)
            for item in purchase.positions:
                self.categories[item.category][1].add(item.name)
                self.categories[item.category][0] += item.price

        self.check_sanity()
        self.calculate_total()

    def totalize_categories(self):
        self.initialize_super_categories()
        for category in self.categories.keys():
            catsum = 0
            length = len(category)
            for cat in self.categories.keys():
                if (cat[0:length] == category):
                    catsum += self.categories[cat][0]
            self.categories[category][2] = catsum

    def initialize_super_categories(self):
        missing_super_categories = []
        for category in self.categories.keys():
            if (category[:category.rfind(':')] not in self.categories.keys()):
                missing_super_categories.append(category[:category.rfind(':')])
        for missing in missing_super_categories:
            while True:
                if missing not in self.categories:
                    self.categories[missing][0] = 0
                if missing.rfind(':') == -1:
                    break
                missing = missing[:missing.rfind(':')]

    def check_category(self, category, item):
        '''
        make list of conflicting categories
        '''
        stored_category = self.category_dict.get_category(item)
        if category != stored_category:
            self.unsane_categories.append((item, category, stored_category))

    def check_sanity(self):
        '''
        make list of items belonging to more than one category
        '''
        all_items = set()
        for category in self.categories:
            if category is '':
                continue
            for item in self.categories[category][1]:
                if item in all_items:
                    self.unsane_items.append(item)
                self.check_category(category, item)
                all_items.add(item)

    def calculate_total(self):
        '''
        calculate the grand total across all categories
        '''
        self.total = 0.0
        for category in self.categories:
            self.total += self.categories[category][0]

    def get_ledger(self, date='1900-01-01'):
        '''
        create output in the format of the ledger application
        '''
        ledger_output = ""
        for receipt in sorted(self.purchases, key=lambda t: t.date):
            if receipt.date >= date:
                ledger_output += receipt.get_ledger()
        return ledger_output