test item

This commit is contained in:
zhangshine 2015-06-10 22:55:53 +08:00
parent 14ffeda5b4
commit 8dd09e1e97
3 changed files with 140 additions and 39 deletions

View file

@ -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):

View file

@ -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)

View file

@ -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))