Invouce amounts rounded to 2 decimals (#1)
* round total, subtotal and tax to 2 digits * version update * version update * version update * version update * version update * changes: 1) decimal.quantize function used instead of round 2) added function to limit number of digits 3) extended constructor of class * typo * changed getdecimals function * changed getdecimals function * updated test_templates * updated test_templates
This commit is contained in:
parent
d6f75e46bb
commit
4c7dc7e5ec
3 changed files with 20 additions and 7 deletions
|
@ -15,8 +15,9 @@ from pyinvoice.models import PDFInfo, Item, Transaction, InvoiceInfo, ServicePro
|
||||||
|
|
||||||
class SimpleInvoice(SimpleDocTemplate):
|
class SimpleInvoice(SimpleDocTemplate):
|
||||||
default_pdf_info = PDFInfo(title='Invoice', author='CiCiApp.com', subject='Invoice')
|
default_pdf_info = PDFInfo(title='Invoice', author='CiCiApp.com', subject='Invoice')
|
||||||
|
precision = None
|
||||||
|
|
||||||
def __init__(self, invoice_path, pdf_info=None):
|
def __init__(self, invoice_path, pdf_info=None, precision='0.01'):
|
||||||
if not pdf_info:
|
if not pdf_info:
|
||||||
pdf_info = self.default_pdf_info
|
pdf_info = self.default_pdf_info
|
||||||
|
|
||||||
|
@ -31,6 +32,8 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
**pdf_info.__dict__
|
**pdf_info.__dict__
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.precision = precision
|
||||||
|
|
||||||
self._defined_styles = getSampleStyleSheet()
|
self._defined_styles = getSampleStyleSheet()
|
||||||
self._defined_styles.add(
|
self._defined_styles.add(
|
||||||
ParagraphStyle('RightHeading1', parent=self._defined_styles.get('Heading1'), alignment=TA_RIGHT)
|
ParagraphStyle('RightHeading1', parent=self._defined_styles.get('Heading1'), alignment=TA_RIGHT)
|
||||||
|
@ -216,8 +219,9 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
sum_start_x_index = len(item_data_title) - abs(sum_end_x_index)
|
sum_start_x_index = len(item_data_title) - abs(sum_end_x_index)
|
||||||
|
|
||||||
# ##### Subtotal #####
|
# ##### Subtotal #####
|
||||||
|
rounditem_subtotal = self.getroundeddecimal(item_subtotal, self.precision)
|
||||||
item_data.append(
|
item_data.append(
|
||||||
('Subtotal', '', '', '', item_subtotal)
|
('Subtotal', '', '', '', rounditem_subtotal)
|
||||||
)
|
)
|
||||||
|
|
||||||
style.append(('SPAN', (0, sum_start_y_index), (sum_start_x_index, sum_start_y_index)))
|
style.append(('SPAN', (0, sum_start_y_index), (sum_start_x_index, sum_start_y_index)))
|
||||||
|
@ -226,8 +230,9 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
# Tax total
|
# Tax total
|
||||||
if self._item_tax_rate is not None:
|
if self._item_tax_rate is not None:
|
||||||
tax_total = item_subtotal * (Decimal(str(self._item_tax_rate)) / Decimal('100'))
|
tax_total = item_subtotal * (Decimal(str(self._item_tax_rate)) / Decimal('100'))
|
||||||
|
roundtax_total = self.getroundeddecimal(tax_total, self.precision)
|
||||||
item_data.append(
|
item_data.append(
|
||||||
('Vat/Tax ({0}%)'.format(self._item_tax_rate), '', '', '', tax_total)
|
('Vat/Tax ({0}%)'.format(self._item_tax_rate), '', '', '', roundtax_total)
|
||||||
)
|
)
|
||||||
sum_start_y_index += 1
|
sum_start_y_index += 1
|
||||||
style.append(('SPAN', (0, sum_start_y_index), (sum_start_x_index, sum_start_y_index)))
|
style.append(('SPAN', (0, sum_start_y_index), (sum_start_x_index, sum_start_y_index)))
|
||||||
|
@ -237,13 +242,20 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
|
|
||||||
# Total
|
# Total
|
||||||
total = item_subtotal + (tax_total if tax_total else Decimal('0'))
|
total = item_subtotal + (tax_total if tax_total else Decimal('0'))
|
||||||
item_data.append(('Total', '', '', '', total))
|
roundtotal = self.getroundeddecimal(total, self.precision)
|
||||||
|
item_data.append(('Total', '', '', '', roundtotal))
|
||||||
sum_start_y_index += 1
|
sum_start_y_index += 1
|
||||||
style.append(('SPAN', (0, sum_start_y_index), (sum_start_x_index, sum_start_y_index)))
|
style.append(('SPAN', (0, sum_start_y_index), (sum_start_x_index, sum_start_y_index)))
|
||||||
style.append(('ALIGN', (0, sum_start_y_index), (sum_end_x_index, -1), 'RIGHT'))
|
style.append(('ALIGN', (0, sum_start_y_index), (sum_end_x_index, -1), 'RIGHT'))
|
||||||
|
|
||||||
return item_data, style
|
return item_data, style
|
||||||
|
|
||||||
|
def getroundeddecimal(self, nrtoround, precision):
|
||||||
|
d = Decimal(nrtoround)
|
||||||
|
aftercomma = Decimal(precision) # or anything that has the exponent depth you want
|
||||||
|
rvalue = Decimal(d.quantize(aftercomma, rounding='ROUND_HALF_UP'))
|
||||||
|
return rvalue
|
||||||
|
|
||||||
def _build_items(self):
|
def _build_items(self):
|
||||||
item_data, style = self._item_data_and_style()
|
item_data, style = self._item_data_and_style()
|
||||||
if item_data:
|
if item_data:
|
||||||
|
|
3
setup.py
3
setup.py
|
@ -13,9 +13,10 @@ with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
|
||||||
# allow setup.py to be run from any path
|
# allow setup.py to be run from any path
|
||||||
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
|
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
|
||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='PyInvoice',
|
name='PyInvoice',
|
||||||
version='0.1.0',
|
version='0.1.7',
|
||||||
packages=['pyinvoice', 'tests'],
|
packages=['pyinvoice', 'tests'],
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
license='MIT License',
|
license='MIT License',
|
||||||
|
|
|
@ -144,8 +144,8 @@ class TestSimpleInvoice(unittest.TestCase):
|
||||||
item_data, style = invoice._item_data_and_style()
|
item_data, style = invoice._item_data_and_style()
|
||||||
self.assertEqual(len(item_data), 7) # header, subtotal, tax, total
|
self.assertEqual(len(item_data), 7) # header, subtotal, tax, total
|
||||||
self.assertEqual(item_data[-3][-1], Decimal('15.4')) # subtotal
|
self.assertEqual(item_data[-3][-1], Decimal('15.4')) # subtotal
|
||||||
self.assertEqual(item_data[-2][-1], Decimal('2.926')) # tax
|
self.assertEqual(item_data[-2][-1], Decimal('2.93')) # tax
|
||||||
self.assertEqual(item_data[-1][-1], Decimal('18.326')) # total
|
self.assertEqual(item_data[-1][-1], Decimal('18.33')) # total
|
||||||
|
|
||||||
invoice.finish()
|
invoice.finish()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue