test item
This commit is contained in:
parent
14ffeda5b4
commit
8dd09e1e97
3 changed files with 140 additions and 39 deletions
|
@ -113,7 +113,7 @@ class Item(object):
|
||||||
:param units: Amount
|
:param units: Amount
|
||||||
:type units: int or str or unicode
|
:type units: int or str or unicode
|
||||||
:param unit_price: Unit price
|
:param unit_price: Unit price
|
||||||
:type unit_price: Decimal or str or unicode
|
:type unit_price: Decimal or str or unicode or int or float
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -123,7 +123,7 @@ class Item(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def amount(self):
|
def amount(self):
|
||||||
return int(self.units) * Decimal(self.unit_price)
|
return int(self.units) * Decimal(str(self.unit_price))
|
||||||
|
|
||||||
|
|
||||||
class Transaction(object):
|
class Transaction(object):
|
||||||
|
|
|
@ -8,6 +8,7 @@ from reportlab.lib.pagesizes import letter
|
||||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||||
from reportlab.lib.units import inch
|
from reportlab.lib.units import inch
|
||||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, Spacer
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, Spacer
|
||||||
|
from reportlab.platypus.doctemplate import _doNothing
|
||||||
|
|
||||||
from pyinvoice.components import SimpleTable, TableWithHeader, PaidStamp
|
from pyinvoice.components import SimpleTable, TableWithHeader, PaidStamp
|
||||||
from pyinvoice.models import PDFInfo, Item, Transaction, InvoiceInfo, ServiceProviderInfo, ClientInfo
|
from pyinvoice.models import PDFInfo, Item, Transaction, InvoiceInfo, ServiceProviderInfo, ClientInfo
|
||||||
|
@ -170,8 +171,7 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
self._build_service_provider_info()
|
self._build_service_provider_info()
|
||||||
self._build_client_info()
|
self._build_client_info()
|
||||||
|
|
||||||
def _build_items(self):
|
def _item_raw_data_and_subtotal(self):
|
||||||
# Items
|
|
||||||
item_data = []
|
item_data = []
|
||||||
item_subtotal = 0
|
item_subtotal = 0
|
||||||
|
|
||||||
|
@ -190,7 +190,16 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
)
|
)
|
||||||
item_subtotal += item.amount
|
item_subtotal += item.amount
|
||||||
|
|
||||||
if item_data:
|
return item_data, item_subtotal
|
||||||
|
|
||||||
|
def _item_data_and_style(self):
|
||||||
|
# Items
|
||||||
|
item_data, item_subtotal = self._item_raw_data_and_subtotal()
|
||||||
|
style = []
|
||||||
|
|
||||||
|
if not item_data:
|
||||||
|
return item_data, style
|
||||||
|
|
||||||
self._story.append(
|
self._story.append(
|
||||||
Paragraph('Detail', self._defined_styles.get('Heading1'))
|
Paragraph('Detail', self._defined_styles.get('Heading1'))
|
||||||
)
|
)
|
||||||
|
@ -202,7 +211,6 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
sum_start_y_index = len(item_data)
|
sum_start_y_index = len(item_data)
|
||||||
sum_end_x_index = -1 - 1
|
sum_end_x_index = -1 - 1
|
||||||
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)
|
||||||
style = []
|
|
||||||
|
|
||||||
# ##### Subtotal #####
|
# ##### Subtotal #####
|
||||||
item_data.append(
|
item_data.append(
|
||||||
|
@ -225,12 +233,17 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
tax_total = None
|
tax_total = None
|
||||||
|
|
||||||
# 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))
|
item_data.append(('Total', '', '', '', 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)))
|
||||||
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
|
||||||
|
|
||||||
|
def _build_items(self):
|
||||||
|
item_data, style = self._item_data_and_style()
|
||||||
|
if item_data:
|
||||||
self._story.append(TableWithHeader(item_data, horizontal_align='LEFT', style=style))
|
self._story.append(TableWithHeader(item_data, horizontal_align='LEFT', style=style))
|
||||||
|
|
||||||
def _build_transactions(self):
|
def _build_transactions(self):
|
||||||
|
@ -274,4 +287,4 @@ class SimpleInvoice(SimpleDocTemplate):
|
||||||
self._build_transactions()
|
self._build_transactions()
|
||||||
self._build_bottom_tip()
|
self._build_bottom_tip()
|
||||||
|
|
||||||
self.build(self._story, onFirstPage=PaidStamp(7 * inch, 5.8 * inch) if self.is_paid else None)
|
self.build(self._story, onFirstPage=PaidStamp(7 * inch, 5.8 * inch) if self.is_paid else _doNothing)
|
|
@ -1,3 +1,4 @@
|
||||||
|
from decimal import Decimal
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
|
@ -8,10 +9,10 @@ from pyinvoice.templates import SimpleInvoice
|
||||||
|
|
||||||
class TestSimpleInvoice(unittest.TestCase):
|
class TestSimpleInvoice(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.file_base_dir = os.path.dirname(os.path.realpath(__file__))
|
self.file_base_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'fixtures/dist')
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
invoice_path = os.path.join(self.file_base_dir, 'fixtures/dist/simple.pdf')
|
invoice_path = os.path.join(self.file_base_dir, 'simple.pdf')
|
||||||
|
|
||||||
if os.path.exists(invoice_path):
|
if os.path.exists(invoice_path):
|
||||||
os.remove(invoice_path)
|
os.remove(invoice_path)
|
||||||
|
@ -54,3 +55,90 @@ class TestSimpleInvoice(unittest.TestCase):
|
||||||
doc.finish()
|
doc.finish()
|
||||||
|
|
||||||
self.assertTrue(os.path.exists(invoice_path))
|
self.assertTrue(os.path.exists(invoice_path))
|
||||||
|
|
||||||
|
def test_only_items(self):
|
||||||
|
invoice_path = os.path.join(self.file_base_dir, 'only_items.pdf')
|
||||||
|
if os.path.exists(invoice_path):
|
||||||
|
os.remove(invoice_path)
|
||||||
|
|
||||||
|
invoice = SimpleInvoice(invoice_path)
|
||||||
|
|
||||||
|
# Before add items
|
||||||
|
item_data, item_subtotal = invoice._item_raw_data_and_subtotal()
|
||||||
|
self.assertEqual(len(item_data), 0)
|
||||||
|
self.assertEqual(item_subtotal, Decimal('0'))
|
||||||
|
item_data, style = invoice._item_data_and_style()
|
||||||
|
self.assertEqual(len(item_data), 0)
|
||||||
|
self.assertEqual(style, [])
|
||||||
|
|
||||||
|
# Add items
|
||||||
|
invoice.add_item(Item('Item1', 'Item desc', 1, 1.1))
|
||||||
|
invoice.add_item(Item('Item2', 'Item desc', 2, u'2.2'))
|
||||||
|
invoice.add_item(Item(u'Item3', 'Item desc', 3, '3.3'))
|
||||||
|
|
||||||
|
# After add items
|
||||||
|
items = invoice.items
|
||||||
|
self.assertEqual(len(items), 3)
|
||||||
|
self.assertEqual(items[0].name, 'Item1')
|
||||||
|
self.assertEqual(items[0].amount, Decimal('1.1'))
|
||||||
|
self.assertEqual(items[1].amount, Decimal('4.4'))
|
||||||
|
self.assertEqual(items[2].name, u'Item3')
|
||||||
|
self.assertEqual(items[2].amount, Decimal('9.9'))
|
||||||
|
|
||||||
|
item_data, item_subtotal = invoice._item_raw_data_and_subtotal()
|
||||||
|
self.assertEqual(item_subtotal, Decimal('15.4'))
|
||||||
|
self.assertEqual(len(item_data), 3)
|
||||||
|
|
||||||
|
item_data, style = invoice._item_data_and_style()
|
||||||
|
self.assertEqual(len(item_data), 6) # header, subtotal, total
|
||||||
|
self.assertEqual(item_data[-2][-1], Decimal('15.4')) # subtotal
|
||||||
|
self.assertEqual(item_data[-1][-1], Decimal('15.4')) # total
|
||||||
|
|
||||||
|
invoice.finish()
|
||||||
|
|
||||||
|
self.assertTrue(os.path.exists(invoice_path))
|
||||||
|
|
||||||
|
def test_only_items_with_tax_rate(self):
|
||||||
|
invoice_path = os.path.join(self.file_base_dir, 'only_items.pdf')
|
||||||
|
if os.path.exists(invoice_path):
|
||||||
|
os.remove(invoice_path)
|
||||||
|
|
||||||
|
invoice = SimpleInvoice(invoice_path)
|
||||||
|
|
||||||
|
# Before add items
|
||||||
|
item_data, item_subtotal = invoice._item_raw_data_and_subtotal()
|
||||||
|
self.assertEqual(len(item_data), 0)
|
||||||
|
self.assertEqual(item_subtotal, Decimal('0'))
|
||||||
|
item_data, style = invoice._item_data_and_style()
|
||||||
|
self.assertEqual(len(item_data), 0)
|
||||||
|
self.assertEqual(style, [])
|
||||||
|
|
||||||
|
# Add items
|
||||||
|
invoice.add_item(Item('Item1', 'Item desc', 1, 1.1))
|
||||||
|
invoice.add_item(Item('Item2', 'Item desc', 2, u'2.2'))
|
||||||
|
invoice.add_item(Item(u'Item3', 'Item desc', 3, '3.3'))
|
||||||
|
# set tax rate
|
||||||
|
invoice.set_item_tax_rate(19)
|
||||||
|
|
||||||
|
# After add items
|
||||||
|
items = invoice.items
|
||||||
|
self.assertEqual(len(items), 3)
|
||||||
|
self.assertEqual(items[0].name, 'Item1')
|
||||||
|
self.assertEqual(items[0].amount, Decimal('1.1'))
|
||||||
|
self.assertEqual(items[1].amount, Decimal('4.4'))
|
||||||
|
self.assertEqual(items[2].name, u'Item3')
|
||||||
|
self.assertEqual(items[2].amount, Decimal('9.9'))
|
||||||
|
|
||||||
|
item_data, item_subtotal = invoice._item_raw_data_and_subtotal()
|
||||||
|
self.assertEqual(item_subtotal, Decimal('15.4'))
|
||||||
|
self.assertEqual(len(item_data), 3)
|
||||||
|
|
||||||
|
item_data, style = invoice._item_data_and_style()
|
||||||
|
self.assertEqual(len(item_data), 7) # header, subtotal, tax, total
|
||||||
|
self.assertEqual(item_data[-3][-1], Decimal('15.4')) # subtotal
|
||||||
|
self.assertEqual(item_data[-2][-1], Decimal('2.926')) # tax
|
||||||
|
self.assertEqual(item_data[-1][-1], Decimal('18.326')) # total
|
||||||
|
|
||||||
|
invoice.finish()
|
||||||
|
|
||||||
|
self.assertTrue(os.path.exists(invoice_path))
|
Loading…
Reference in a new issue