Skip to content

Commit 82f23b1

Browse files
committed
Tax treatment under the Czech legislation.
1 parent 7b1e44a commit 82f23b1

File tree

7 files changed

+151
-18
lines changed

7 files changed

+151
-18
lines changed

InvoiceGenerator/api.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ def __setattr__(self, key, value):
1212

1313
class Address(UnicodeProperty):
1414
_attrs = ('summary', 'address', 'city', 'zip', 'phone', 'email',
15-
'bank_name', 'bank_account', 'note')
15+
'bank_name', 'bank_account', 'note', 'vat_id', 'ir')
1616

1717
def __init__(self, summary, address='', city='', zip='', phone='', email='',
18-
bank_name='', bank_account='', note=''):
18+
bank_name='', bank_account='', note='', vat_id='', ir=''):
1919
self.summary = summary
2020
self.address = address
2121
self.city = city
@@ -25,14 +25,23 @@ def __init__(self, summary, address='', city='', zip='', phone='', email='',
2525
self.bank_name = bank_name
2626
self.bank_account = bank_account
2727
self.note = note
28+
self.vat_id = vat_id
29+
self.ir = ir
2830

2931

3032
def get_address_lines(self):
31-
return [
33+
address_line = [
3234
self.summary,
3335
self.address,
34-
u'%s %s' % (self.zip, self.city),
36+
u'%s %s' % (self.zip, self.city)
3537
]
38+
if self.vat_id:
39+
address_line.append(u'Vat in: %s' % self.vat_id)
40+
41+
if self.ir:
42+
address_line.append(u'IR: %s' % self.ir)
43+
44+
return address_line
3645

3746
def get_contact_lines(self):
3847
return [
@@ -71,6 +80,9 @@ def total(self):
7180
def total_tax(self):
7281
return self.price * self.count * (1.0 + self.tax / 100.0)
7382

83+
def count_tax(self):
84+
return self.total_tax - self.total
85+
7486
@property
7587
def description(self):
7688
return self._description
@@ -153,3 +165,25 @@ def use_tax(self):
153165
use_tax = True
154166
continue
155167
return use_tax
168+
169+
def _get_grouped_items_by_tax(self):
170+
table = {}
171+
for item in self.items:
172+
if not table.has_key(item.tax):
173+
table[item.tax] = {'total': item.total, 'total_tax': item.total_tax, 'tax': item.count_tax()}
174+
else:
175+
table[item.tax]['total'] += item.total
176+
table[item.tax]['total_tax'] += item.total_tax
177+
table[item.tax]['tax'] += item.count_tax()
178+
179+
return table
180+
181+
def generate_breakdown_vat(self):
182+
return self._get_grouped_items_by_tax()
183+
184+
def generate_breakdown_vat_table(self):
185+
rows = []
186+
for vat,items in self.generate_breakdown_vat().iteritems():
187+
rows.append((vat, items['total'], items['total_tax'], items['tax']))
188+
189+
return rows

InvoiceGenerator/pdf.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from reportlab.lib.units import mm
77
from reportlab.pdfbase.ttfonts import TTFont
88
from reportlab.pdfbase import pdfmetrics
9-
9+
from reportlab.platypus.tables import Table, TableStyle
1010

1111
from conf import _, FONT_PATH, FONT_BOLD_PATH
1212
from api import Invoice
@@ -114,8 +114,10 @@ def drawProvider(self,TOP,LEFT):
114114

115115
self.pdf.drawText(text)
116116
if self.invoice.provider.note:
117-
self.pdf.drawString((LEFT + 2) * mm, (TOP - 26) * mm,
118-
self.invoice.provider.note)
117+
self.pdf.setFont('DejaVu', 6)
118+
text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 23) * mm)
119+
text.textLines(self.invoice.provider.note)
120+
self.pdf.drawText(text)
119121

120122
def drawPayment(self,TOP,LEFT):
121123
self.pdf.setFont('DejaVu-Bold', 9)
@@ -199,9 +201,40 @@ def drawItems(self,TOP,LEFT):
199201
path.lineTo((LEFT + 176) * mm, (TOP - i) * mm)
200202
self.pdf.drawPath(path, True, True)
201203

202-
self.pdf.setFont('DejaVu-Bold', 11)
203-
self.pdf.drawString((LEFT + 100) * mm, (TOP - i - 7) * mm, _(u'Total')+': %.2f %s' % (self.invoice.price, self.invoice.currency))
204-
if items_are_with_tax:
204+
if not items_are_with_tax:
205+
self.pdf.setFont('DejaVu-Bold', 11)
206+
self.pdf.drawString((LEFT + 100) * mm, (TOP - i - 7) * mm, _(u'Total')+': %.2f %s' % (self.invoice.price, self.invoice.currency))
207+
else:
208+
self.pdf.setFont('DejaVu-Bold', 6)
209+
self.pdf.drawString((LEFT + 1) * mm, (TOP - i - 2) * mm, _(u'Breakdown VAT'))
210+
vat_list, tax_list, total_list, total_tax_list = [_(u'VAT rate')], [_(u'Tax')], [_(u'Without VAT')], [_(u'With VAT')]
211+
for vat, items in self.invoice.generate_breakdown_vat().iteritems():
212+
vat_list.append('%.2f%%' % vat)
213+
tax_list.append('%.2f %s' % (items['tax'], self.invoice.currency))
214+
total_list.append('%.2f %s' % (items['total'], self.invoice.currency))
215+
total_tax_list.append('%.2f %s' % (items['total_tax'], self.invoice.currency))
216+
217+
218+
self.pdf.setFont('DejaVu', 6)
219+
text = self.pdf.beginText((LEFT + 1) * mm, (TOP - i - 5) * mm)
220+
text.textLines('\n'.join(vat_list))
221+
self.pdf.drawText(text)
222+
223+
text = self.pdf.beginText((LEFT + 11) * mm, (TOP - i - 5) * mm)
224+
text.textLines('\n'.join(tax_list))
225+
self.pdf.drawText(text)
226+
227+
text = self.pdf.beginText((LEFT + 27) * mm, (TOP - i - 5) * mm)
228+
text.textLines('\n'.join(total_list))
229+
self.pdf.drawText(text)
230+
231+
text = self.pdf.beginText((LEFT + 45) * mm, (TOP - i - 5) * mm)
232+
text.textLines('\n'.join(total_tax_list))
233+
self.pdf.drawText(text)
234+
235+
236+
237+
self.pdf.setFont('DejaVu-Bold', 11)
205238
self.pdf.drawString((LEFT + 100) * mm, (TOP - i - 14) * mm, _(u'Total with tax')+': %.2f %s' % (self.invoice.price_tax, self.invoice.currency))
206239

207240
if items_are_with_tax:

locale/cs/LC_MESSAGES/messages.mo

163 Bytes
Binary file not shown.

locale/cs/LC_MESSAGES/messages.po

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgstr ""
88
"Project-Id-Version: 0.2.0\n"
99
"Report-Msgid-Bugs-To: \n"
1010
"POT-Creation-Date: 2012-04-07 17:30+0200\n"
11-
"PO-Revision-Date: 2012-04-17 22:51+0100\n"
11+
"PO-Revision-Date: 2012-04-20 23:30+0100\n"
1212
"Last-Translator: rbas <rbas@rbas.cz>\n"
1313
"Language-Team: LANGUAGE <LL@li.org>\n"
1414
"Language: \n"
@@ -106,3 +106,15 @@ msgstr "Datum zdanitelného plnění"
106106
msgid "Paytype"
107107
msgstr "Typ platby"
108108

109+
msgid "Breakdown VAT"
110+
msgstr "Rozpis DPH"
111+
112+
msgid "VAT rate"
113+
msgstr "Sazba"
114+
115+
msgid "Without VAT"
116+
msgstr "Bez DPH"
117+
118+
msgid "With VAT"
119+
msgstr "S DPH"
120+

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def read(fname):
88

99
setup(
1010
name = "InvoiceGenerator",
11-
version = "0.2.2",
11+
version = "0.2.3",
1212
author = "Adam Strauch",
1313
author_email = "cx@initd.cz",
1414
description = ("Library to generate PDF invoice."),

tests/test_api.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class AddressTest(unittest.TestCase):
1010

1111
attrs = ('summary', 'address', 'city', 'zip', 'phone', 'email',
12-
'bank_name', 'bank_account', 'note')
12+
'bank_name', 'bank_account', 'note', 'vat_id', 'ir')
1313

1414
addresss_object = Address
1515

@@ -95,6 +95,14 @@ def test_count_total(self):
9595
item = Item(count, price)
9696
self.assertEquals(count * price, item.total)
9797

98+
def test_count_tax(self):
99+
100+
item = Item(2, 50, tax=50)
101+
self.assertEqual(50, item.count_tax())
102+
103+
item = Item(2, 50)
104+
self.assertEqual(0, item.count_tax())
105+
98106
def test_count_total_with_tax(self):
99107
count = 24
100108
price = 42
@@ -164,4 +172,30 @@ def test_use_tax(self):
164172
invoice.add_item(Item(1, 500, tax=99.9))
165173
invoice.add_item(Item(500, 5))
166174

167-
self.assertTrue(invoice.use_tax)
175+
self.assertTrue(invoice.use_tax)
176+
177+
def test_generate_breakdown_vat(self):
178+
invoice = Invoice(Client('Foo'), Provider('Bar'), Creator('Blah'))
179+
invoice.add_item(Item(1, 500, tax=50))
180+
invoice.add_item(Item(3, 500, tax=50))
181+
invoice.add_item(Item(500, 5, tax=0))
182+
invoice.add_item(Item(5, 500, tax=0))
183+
184+
expected = {
185+
0.0: {'total': 5000.0, 'total_tax': 5000.0, 'tax': 0.0},
186+
50.0: {'total': 2000.0, 'total_tax': 3000.0, 'tax': 1000}}
187+
188+
self.assertEquals(expected, invoice.generate_breakdown_vat())
189+
190+
191+
def test_generate_breakdown_vat_table(self):
192+
invoice = Invoice(Client('Foo'), Provider('Bar'), Creator('Blah'))
193+
invoice.add_item(Item(1, 500, tax=50))
194+
invoice.add_item(Item(3, 500, tax=50))
195+
invoice.add_item(Item(500, 5, tax=0))
196+
invoice.add_item(Item(5, 500, tax=0))
197+
198+
expected = [(0.00, 5000.0, 5000.0, 0),(50.0, 2000.0, 3000.0, 1000.0)]
199+
200+
self.assertEquals(expected, invoice.generate_breakdown_vat_table())
201+

tests/test_pdf.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,34 @@ def test_required_args(self):
1616
SimpleInvoice(invoice)
1717

1818
def test_generate(self):
19-
20-
invoice = Invoice(Client('Kkkk'), Provider('Pupik'), Creator('blah'))
21-
invoice.add_item(Item(32, 600))
19+
provider = Provider('Pupik')
20+
provider.address = 'Kubelikova blah blah blah'
21+
provider.zip = '12655465'
22+
provider.city = 'Frantisek'
23+
provider.vat_id = 'CZ8590875682'
24+
provider.ir = '785684523'
25+
provider.email = 'mail@email.com'
26+
provider.bank_account = '56484984968/68'
27+
provider.bank_name = 'RB'
28+
provider.note = u'zapsaná v obchodním rejstříku vedeném městským soudem v Praze,\noddíl C, vložka 176551'
29+
30+
client = Client('Kkkk')
31+
client.address = 'Kubelikova blah blah blah'
32+
client.zip = '12655465'
33+
client.city = 'Frantisek'
34+
client.vat_id = 'CZ8590875682'
35+
client.ir = '785684523'
36+
client.email = 'mail@email.com'
37+
38+
invoice = Invoice(client, provider, Creator('blah'))
39+
invoice.add_item(Item(32, 600, tax=50))
40+
invoice.add_item(Item(32, 600, tax=0))
2241
invoice.specific_symbol = 666
2342
invoice.taxable_date = '1.1.1979'
2443
invoice.variable_symbol = '000000001'
44+
invoice.currency = u'Kč'
2545

26-
tmp_file = NamedTemporaryFile()
46+
tmp_file = NamedTemporaryFile(delete=False, prefix='xx_')
2747

2848
pdf = SimpleInvoice(invoice)
2949
pdf.gen(tmp_file.name)

0 commit comments

Comments
 (0)