Ejemplo n.º 1
0
 def start_new_purchase(self, line):
     '''
     Create and initialize new purchase object.
     '''
     date = validate_date(line[0])
     self.purchase_is_active = True
     payment_method = line[3]
     if payment_method is '':
         payment_method = 'cash'
     self.active_purchase = Purchase(date=date,
                                     shop=line[2],
                                     category_dict=self.dictionary,
                                     payment_method=payment_method,
                                     flags=line[1])
Ejemplo n.º 2
0
 def createPurchaseObjects(self, metapurchases):
     purchases = []
     for meta in metapurchases:
         purchase = Purchase(meta[1],
                             meta[2],
                             payment_method=meta[4],
                             flags=meta[3])
         positions = self.getPositions(meta[0])
         for position in positions:
             purchase.add_item(name=position[1],
                               count=position[0],
                               category=position[2],
                               price=position[3])
         purchases.append(purchase)
     return purchases
Ejemplo n.º 3
0
 def createPurchaseObjects(self, metapurchases):
     purchases = []
     for meta in metapurchases:
         purchase = Purchase(meta[1],
                             meta[2],
                             payment_method=meta[4],
                             flags=meta[3])
         positions = self.getPositions(meta[0])
         for position in positions:
             purchase.add_item(name=position[1],
                               count=position[0],
                               category=position[2],
                               price=position[3])
         purchases.append(purchase)
     return purchases
Ejemplo n.º 4
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
Ejemplo n.º 5
0
def test_create_ledger():
    receipt_collection = ReceiptCollection()
    Position = namedtuple('item',
                          ['name', 'category', 'price', 'count', 'weight'])
    testPurchaseOne = Purchase('2015-11-29', "TestShopOne")
    testPurchaseOne.positions.append(
        Position('foo', 'category:subcategory1', 1.23, '', ''))
    receipt_collection.purchases.append(testPurchaseOne)
    testPurchaseTwo = Purchase('2015-11-28',
                               "TestShopTwo",
                               payment_method="Giro")
    testPurchaseTwo.positions.append(
        Position('bar', 'category:subcategory2', 4.56, '', ''))
    testPurchaseTwo.positions.append(
        Position('foo', 'category:subcategory1', 2.46, '2', ''))
    receipt_collection.purchases.append(testPurchaseTwo)
    testPurchaseThree = Purchase('2015-11-30',
                                 "TestShopThree",
                                 payment_method="Giro")
    testPurchaseThree.positions.append(
        Position('bar', 'category:subcategory2', 4.56, '', ''))
    testPurchaseThree.positions.append(
        Position('foo', 'category:subcategory1', 2.46, '2', ''))
    receipt_collection.purchases.append(testPurchaseThree)

    actual_output = receipt_collection.get_ledger()
    expected_output = "2015-11-28 TestShopTwo\n"
    expected_output += "  Aktiva:Giro  -7.02\n"
    expected_output += "  category:subcategory2  4.56\n"
    expected_output += "  category:subcategory1  2.46\n"
    expected_output += "\n"
    expected_output += "2015-11-29 TestShopOne\n"
    expected_output += "  Aktiva:Portmonaie  -1.23\n"
    expected_output += "  category:subcategory1  1.23\n"
    expected_output += "\n"
    expected_output += "2015-11-30 TestShopThree\n"
    expected_output += "  Aktiva:Giro  -7.02\n"
    expected_output += "  category:subcategory2  4.56\n"
    expected_output += "  category:subcategory1  2.46\n"
    expected_output += "\n"
    assert expected_output == actual_output
Ejemplo n.º 6
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
Ejemplo n.º 7
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
Ejemplo n.º 8
0
class Parser(object):
    '''
    Parse csv file with receipts.
    '''

    def __init__(self, *args, **kwargs):
        self.dictionary = kwargs.get('category_dictionary', ItemCategoryDict())
        self.purchase_is_active = None
        self.active_purchase = None
        self.purchases = []

    def __enter__(self):
        return self

    def __exit__(self, thetype, value, traceback):
        pass

    def read_file(self, file_path):
        '''
        Read a csv file and parse its contents into array of purchases
        '''
        with open(file_path, 'r') as receipt_file:
            csv_reader = csv.reader(receipt_file)
            first_line = True
            for line in csv_reader:
                if first_line:
                    first_line = False
                    continue
                if self.active_purchase is None:
                    self.handle_out_of_purchase_line(line)
                else:
                    self.handle_in_purchase_line(line)
        self.clean_up()
        return self.purchases

    @staticmethod
    def check_line_empty_enough(line):
        '''
        Check that the date-, name- and price-field are empty to signal an
        empty line
        '''
        return line[0] is '' and line[2] is '' and line[3] is ''

    @staticmethod
    def check_purchase_header(line):
        '''
        Check that the date field and the shopname field are not empty.
        '''
        return line[0] is not '' and line[2] is not ''

    def start_new_purchase(self, line):
        '''
        Create and initialize new purchase object.
        '''
        date = validate_date(line[0])
        self.purchase_is_active = True
        payment_method = line[3]
        if payment_method is '':
            payment_method = 'cash'
        self.active_purchase = Purchase(date=date,
                                        shop=line[2],
                                        category_dict=self.dictionary,
                                        payment_method=payment_method,
                                        flags=line[1])

    def handle_out_of_purchase_line(self, line):
        '''
        The line must by either empty or the begin of a new purchase.
        '''
        if self.check_line_empty_enough(line):
            return

        if self.check_purchase_header(line):
            self.start_new_purchase(line)
        else:
            raise RuntimeError('file badly formatted: ' + str(line))

    def handle_in_purchase_line(self, line):
        '''
        The line should either be empty, ending the purchase or it should be
        a valid position.
        '''
        if self.check_line_empty_enough(line):
            self.purchases.append(self.active_purchase)
            self.active_purchase = None
            return
        if line[0] is not '' or line[2] is '':
            raise RuntimeError('file badly formatted: ' + str(line))
        # if line[3] is '':
        #     warning('price missing ' + line[2])
        #     @TODO: decide if we should handle a missing price in the parser
        else:
            try:
                quantity = int(line[1])
            except ValueError:
                if line[1] != '':
                    warning('quantity must be empty or number: ' + quantity)
                    raise
                quantity = 1
            self.active_purchase.add_item(name=line[2],
                                          price=line[3],
                                          count=quantity,
                                          category=line[4])

    def clean_up(self):
        if self.active_purchase is not None:
            self.purchases.append(self.active_purchase)
            self.active_purchase = None
def purchase_list_fixture(request):
    purchase_list = []
    test_purchase1 = Purchase('2015-11-29', 'Bio Company')
    test_purchase1.add_item(name='Blanc de Pomm',
                            price=1.69,
                            count=1,
                            category='Zubrot')
    test_purchase1.add_item('Seidentofu', 5.18, 2)
    purchase_list.append(test_purchase1)

    test_purchase2 = Purchase('2014-11-01', 'Bio Company')
    test_purchase2.add_item('Risotto', 4.38, 2, category='Kochzutaten')
    test_purchase2.add_item('Sesam', 3.69, 1)
    test_purchase2.add_item('Cashewbruch', 10.99, 1)
    test_purchase2.add_item('Bananen', 1.22, 1, category='Obst')
    test_purchase2.add_item('Roggenmehl', 3.98, 2, category='Mehl')
    test_purchase2.add_item('Walnusskerne', 3.49, 1)
    test_purchase2.add_item('Datteln', 5.29, 1)
    test_purchase2.add_item('Safranfäden', 6.29, 1, category='Gewürze')
    test_purchase2.add_item('Vanillepulver', 2.49, 1, category='Gewürze')
    test_purchase2.add_item('Kakaopulver', 2.19, 1)
    test_purchase2.add_item('Basilikum, frisch', 1.99, 1, category='Gewürze')
    test_purchase2.add_item('Item without Price', '', 1, category='Mehl')
    test_purchase2.add_item('Roggenmehl', 3.98, 2, category='Obst')
    purchase_list.append(test_purchase2)

    test_purchase3 = Purchase('2015-11-17',
                              'Übertrag',
                              payment_method='Giro',
                              flags='L')
    test_purchase3.add_item('Abhebung', 100, 1, category='Aktiva:Portmonaie')
    purchase_list.append(test_purchase3)

    return purchase_list
def purchase_list_fixture(request):
    purchase_list = []
    test_purchase1 = Purchase('2015-11-29', 'Bio Company')
    test_purchase1.add_item(name='Blanc de Pomm',
                            price=1.69,
                            count=1,
                            category='Zubrot')
    test_purchase1.add_item('Seidentofu', 5.18, 2)
    purchase_list.append(test_purchase1)

    test_purchase2 = Purchase('2014-11-01', 'Bio Company')
    test_purchase2.add_item('Risotto', 4.38, 2, category='Kochzutaten')
    test_purchase2.add_item('Sesam', 3.69, 1)
    test_purchase2.add_item('Cashewbruch', 10.99, 1)
    test_purchase2.add_item('Bananen', 1.22, 1, category='Obst')
    test_purchase2.add_item('Roggenmehl', 3.98, 2, category='Mehl')
    test_purchase2.add_item('Walnusskerne', 3.49, 1)
    test_purchase2.add_item('Datteln', 5.29, 1)
    test_purchase2.add_item('Safranfäden', 6.29, 1, category='Gewürze')
    test_purchase2.add_item('Vanillepulver', 2.49, 1, category='Gewürze')
    test_purchase2.add_item('Kakaopulver', 2.19, 1)
    test_purchase2.add_item('Basilikum, frisch', 1.99, 1, category='Gewürze')
    test_purchase2.add_item('Item without Price', '', 1, category='Mehl')
    test_purchase2.add_item('Roggenmehl', 3.98, 2, category='Obst')
    purchase_list.append(test_purchase2)

    test_purchase3 = Purchase('2015-11-17',
                              'Übertrag',
                              payment_method='Giro',
                              flags='L')
    test_purchase3.add_item('Abhebung', 100, 1, category='Aktiva:Portmonaie')
    purchase_list.append(test_purchase3)

    return purchase_list
Ejemplo n.º 11
0
def test_parse_multiple_purchases(factory_file):
    expected_purchases = []
    expected_purchase1 = Purchase('2015-11-29', 'Bio Company')
    expected_purchase1.add_item(name='Blanc de Pomm',
                                price=1.69,
                                count=1,
                                category='Zubrot')
    expected_purchase1.add_item('Seidentofu', 5.18, 2)
    expected_purchases.append(expected_purchase1)

    expected_purchase2 = Purchase('2014-11-01', 'Bio Company',
                                  payment_method='Giro')
    expected_purchase2.add_item('Risotto', 4.38, 2, category='Kochzutaten')
    expected_purchase2.add_item('Sesam', 3.69, 1)
    expected_purchase2.add_item('Cashewbruch', 10.99, 1)
    expected_purchase2.add_item('Bananen', 1.22, 1, category='Obst')
    expected_purchase2.add_item('Roggenmehl', 3.98, 2, category='Mehl')
    expected_purchase2.add_item('Walnusskerne', 3.49, 1)
    expected_purchase2.add_item('Datteln', 5.29, 1)
    expected_purchase2.add_item('Safranfäden', 6.29, 1, category='Gewürze')
    expected_purchase2.add_item('Vanillepulver', 2.49, 1, category='Gewürze')
    expected_purchase2.add_item('Kakaopulver', 2.19, 1)
    expected_purchase2.add_item('Basilikum, frisch', 1.99, 1, category='Gewürze')
    expected_purchase2.add_item('Item without Price', '', 1, category='Mehl')
    expected_purchase2.add_item('Roggenmehl', 3.98, 2, category='Obst')
    expected_purchases.append(expected_purchase2)

    expected_purchase3 = Purchase('2015-11-17',
                                  'Übertrag',
                                  payment_method='Giro',
                                  flags='L')
    expected_purchase3.add_item('Abhebung', 100, 1, category='Aktiva:Portmonaie')
    expected_purchases.append(expected_purchase3)

    with Parser() as p:
        actual_purchases = p.read_file('receipts_test.csv')

    assert actual_purchases == expected_purchases