From f1729225f3d6888790ede78d2d54b774aac77318 Mon Sep 17 00:00:00 2001 From: zhangshine Date: Sun, 31 May 2015 00:30:00 +0800 Subject: [PATCH] Item tables --- pyinvoice/components.py | 21 ++++++++++++++------- pyinvoice/models.py | 5 +++++ pyinvoice/templates.py | 24 ++++++++++++++++++++++-- test.py | 9 ++++++++- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/pyinvoice/components.py b/pyinvoice/components.py index 987c7d4..8e59dd0 100644 --- a/pyinvoice/components.py +++ b/pyinvoice/components.py @@ -1,5 +1,3 @@ -from reportlab.graphics.charts.textlabels import Label -from reportlab.graphics.shapes import Drawing from reportlab.lib.units import inch from reportlab.platypus import Paragraph, Table, TableStyle from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet @@ -19,15 +17,24 @@ class CodeSnippet(Paragraph): class SimpleTable(Table): - style = TableStyle([ - ('INNERGRID', (0, 0), (-1, -1), .25, colors.black), - ('BOX', (0, 0), (-1, -1), .25, colors.black), - ]) - def __init__(self, data, horizontal_align=None): Table.__init__(self, data, hAlign=horizontal_align) +class TableWithHeader(Table): + def __init__(self, data, horizontal_align=None): + Table.__init__(self, data, hAlign=horizontal_align) + + style = TableStyle([ + ('INNERGRID', (0, 0), (-1, -1), .25, colors.black), + ('BOX', (0, 0), (-1, -1), .25, colors.black), + ('BACKGROUND', (0, 0), (-1, -len(data)), colors.lightgrey), + ('ALIGN', (0, 0), (-1, -1), 'CENTER'), + ('VALIGN', (0, 0), (-1, -1), 'MIDDLE') + ]) + self.setStyle(style) + + class PaidStamp(object): def __init__(self, x, y): self.x = x diff --git a/pyinvoice/models.py b/pyinvoice/models.py index fe40747..5c9de76 100644 --- a/pyinvoice/models.py +++ b/pyinvoice/models.py @@ -60,12 +60,17 @@ class Item(object): :param unit_price: Unit price :return: """ + # TODO: add vat/tax, subtotal self.item_id = item_id self.name = name self.description = description self.units = units self.unit_price = unit_price + @property + def subtotal(self): + return int(self.units) * self.unit_price + class Transaction(object): """ diff --git a/pyinvoice/templates.py b/pyinvoice/templates.py index 5d9de36..045fbc9 100644 --- a/pyinvoice/templates.py +++ b/pyinvoice/templates.py @@ -1,9 +1,11 @@ from __future__ import unicode_literals from datetime import datetime, date +from reportlab.lib.enums import TA_CENTER from reportlab.lib.pagesizes import letter +from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import inch -from reportlab.platypus import SimpleDocTemplate -from pyinvoice.components import SimpleTable +from reportlab.platypus import SimpleDocTemplate, Paragraph +from pyinvoice.components import SimpleTable, TableWithHeader from pyinvoice.models import PDFInfo, Item, Transaction, InvoiceInfo, ServiceProviderInfo, ClientInfo @@ -87,4 +89,22 @@ class SimpleInvoice(SimpleDocTemplate): ('country', 'Country'), ('post_code', 'Post code'), ('email', 'Email'), ('client_id', 'Client id')] story.append(SimpleTable(self.__attribute_to_table_data(self.client_info, props), horizontal_align='LEFT')) + item_table_paragraph_style = ParagraphStyle( + 'ItemTableParagraph', + parent=getSampleStyleSheet()['Normal'], + alignment=TA_CENTER + ) + + item_data = [( + item.item_id, + item.name, + Paragraph(item.description, item_table_paragraph_style), + item.units, + item.unit_price, + item.subtotal + ) for item in self._items if isinstance(item, Item)] + if item_data: + item_data.insert(0, ('Item id', 'Name', 'Description', 'Units', 'Unit Price', 'Subtotal')) + story.append(TableWithHeader(item_data, horizontal_align='LEFT')) + self.build(story) \ No newline at end of file diff --git a/test.py b/test.py index 69d3304..e07a60a 100644 --- a/test.py +++ b/test.py @@ -1,9 +1,12 @@ from datetime import datetime -from pyinvoice.models import InvoiceInfo, ServiceProviderInfo, ClientInfo +from decimal import Decimal +from pyinvoice.models import InvoiceInfo, ServiceProviderInfo, ClientInfo, Item from pyinvoice.templates import SimpleInvoice doc = SimpleInvoice('test.pdf') + doc.invoice_info = InvoiceInfo('1024', datetime.now(), datetime.now()) + doc.service_provider_info = ServiceProviderInfo( name='PyInvoice', street='My Street', @@ -24,5 +27,9 @@ doc.client_info = ClientInfo( post_code='Client Post code' ) +doc.add_item(Item('0000', 'Item 0000', 'Item Description 1 Long--------------------------------Item Description 1 Long', 1, Decimal('1.1'))) +doc.add_item(Item('1111', 'Item 1111', 'Item Description 2', 2, Decimal('2.2'))) +doc.add_item(Item('2222', 'Item 2222', 'Item Description 3', 3, Decimal('3.3'))) + # doc.build(story, onFirstPage=PaidStamp(7*inch, 5.8*inch)) doc.finish() \ No newline at end of file