PyInvoice/pyinvoice/templates.py

168 lines
6 KiB
Python
Raw Normal View History

from __future__ import unicode_literals
from datetime import datetime, date
2015-06-06 09:44:18 +00:00
from reportlab.lib.enums import TA_CENTER, TA_RIGHT
2015-05-27 17:09:44 +00:00
from reportlab.lib.pagesizes import letter
2015-05-30 16:30:00 +00:00
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
2015-05-27 17:09:44 +00:00
from reportlab.lib.units import inch
2015-05-30 16:30:00 +00:00
from reportlab.platypus import SimpleDocTemplate, Paragraph
2015-06-06 09:51:52 +00:00
2015-06-06 09:00:31 +00:00
from pyinvoice.components import SimpleTable, TableWithHeader, PaidStamp
from pyinvoice.models import PDFInfo, Item, Transaction, InvoiceInfo, ServiceProviderInfo, ClientInfo
2015-05-27 17:09:44 +00:00
class SimpleInvoice(SimpleDocTemplate):
default_pdf_info = PDFInfo(title='Invoice', author='CiCiApp.com', subject='Invoice')
def __init__(self, invoice_path, pdf_info=None):
if not pdf_info:
pdf_info = self.default_pdf_info
2015-05-27 17:09:44 +00:00
SimpleDocTemplate.__init__(
self,
invoice_path,
pagesize=letter,
2015-05-28 10:17:55 +00:00
rightMargin=inch,
leftMargin=inch,
topMargin=inch,
bottomMargin=inch,
**pdf_info.__dict__
)
2015-06-06 09:44:18 +00:00
self._defined_styles = getSampleStyleSheet()
self._defined_styles.add(
ParagraphStyle('RightHeading1', parent=self._defined_styles.get('Heading1'), alignment=TA_RIGHT)
)
self._defined_styles.add(
ParagraphStyle('ItemTableParagraph', parent=self._defined_styles.get('Normal'), alignment=TA_CENTER)
)
self.invoice_info = None
self.service_provider_info = None
self.client_info = None
2015-06-06 09:00:31 +00:00
self.is_paid = False
self._items = []
self._transactions = []
2015-06-06 09:31:18 +00:00
self._story = []
@property
def items(self):
return self._items[:]
def add_item(self, item):
if isinstance(item, Item):
self._items.append(item)
@property
def transactions(self):
return self._transactions[:]
def add_transaction(self, t):
if isinstance(t, Transaction):
self._transactions.append(t)
@staticmethod
2015-06-06 09:17:57 +00:00
def __format_value(value):
if isinstance(value, datetime):
value = value.strftime('%Y-%m-%d %H:%M')
elif isinstance(value, date):
value = value.strftime('%Y-%m-%d')
return value
def __attribute_to_table_data(self, instance, attribute_verbose_name_list):
data = []
2015-06-06 09:17:57 +00:00
for property_name, verbose_name in attribute_verbose_name_list:
attr = getattr(instance, property_name)
if attr:
attr = self.__format_value(attr)
data.append(['{0}:'.format(verbose_name), attr])
return data
2015-06-06 09:31:18 +00:00
def __build_invoice_info(self):
if isinstance(self.invoice_info, InvoiceInfo):
2015-06-06 09:44:18 +00:00
self._story.append(
2015-06-08 15:15:36 +00:00
Paragraph('Invoice', self._defined_styles.get('RightHeading1'))
2015-06-06 09:44:18 +00:00
)
props = [('invoice_id', 'Invoice id'), ('invoice_datetime', 'Invoice date'),
('due_datetime', 'Invoice due date')]
2015-06-06 09:31:18 +00:00
self._story.append(
2015-06-08 15:15:36 +00:00
SimpleTable(self.__attribute_to_table_data(self.invoice_info, props), horizontal_align='RIGHT')
)
2015-06-06 09:31:18 +00:00
def __build_service_provider_info(self):
if isinstance(self.service_provider_info, ServiceProviderInfo):
2015-06-06 09:44:18 +00:00
self._story.append(
Paragraph('Merchant', self._defined_styles.get('RightHeading1'))
)
props = [('name', 'Name'), ('street', 'Street'), ('city', 'City'), ('state', 'State'),
('country', 'Country'), ('post_code', 'Post code')]
2015-06-06 09:31:18 +00:00
self._story.append(
SimpleTable(self.__attribute_to_table_data(self.service_provider_info, props), horizontal_align='RIGHT')
)
2015-06-06 09:31:18 +00:00
def __build_client_info(self):
2015-06-06 09:17:57 +00:00
# ClientInfo
if isinstance(self.client_info, ClientInfo):
2015-06-06 09:44:18 +00:00
self._story.append(
Paragraph('Client', self._defined_styles.get('Heading1'))
)
props = [('name', 'Name'), ('street', 'Street'), ('city', 'City'), ('state', 'State'),
('country', 'Country'), ('post_code', 'Post code'), ('email', 'Email'), ('client_id', 'Client id')]
2015-06-06 09:31:18 +00:00
self._story.append(
SimpleTable(self.__attribute_to_table_data(self.client_info, props), horizontal_align='LEFT')
)
2015-06-06 09:31:18 +00:00
def __build_items(self):
2015-06-06 09:17:57 +00:00
# Items
2015-06-06 09:31:18 +00:00
item_data = [
(
item.item_id,
item.name,
2015-06-06 09:44:18 +00:00
Paragraph(item.description, self._defined_styles.get('ItemTableParagraph')),
2015-06-06 09:31:18 +00:00
item.units,
item.unit_price,
item.subtotal
) for item in self._items if isinstance(item, Item)
]
2015-05-30 16:30:00 +00:00
if item_data:
2015-06-06 09:44:18 +00:00
self._story.append(
Paragraph('Detail', self._defined_styles.get('Heading1'))
)
2015-05-30 16:30:00 +00:00
item_data.insert(0, ('Item id', 'Name', 'Description', 'Units', 'Unit Price', 'Subtotal'))
2015-06-06 09:31:18 +00:00
self._story.append(TableWithHeader(item_data, horizontal_align='LEFT'))
2015-05-30 16:30:00 +00:00
2015-06-06 09:31:18 +00:00
def __build_transactions(self):
2015-06-06 09:17:57 +00:00
# Transaction
2015-06-06 09:31:18 +00:00
transaction_table_data = [
(
t.transaction_id,
t.gateway,
self.__format_value(t.transaction_datetime),
t.amount
) for t in self._transactions if isinstance(t, Transaction)
]
2015-06-06 09:17:57 +00:00
if transaction_table_data:
2015-06-06 09:44:18 +00:00
self._story.append(
Paragraph('Transaction', self._defined_styles.get('Heading1'))
)
2015-06-06 09:17:57 +00:00
transaction_table_data.insert(0, ('Transaction id', 'Gateway', 'Transaction date', 'Amount'))
2015-06-06 09:31:18 +00:00
self._story.append(TableWithHeader(transaction_table_data, horizontal_align='LEFT'))
def finish(self):
self._story = []
self.__build_invoice_info()
self.__build_service_provider_info()
self.__build_client_info()
self.__build_items()
self.__build_transactions()
2015-06-06 09:17:57 +00:00
2015-06-06 09:31:18 +00:00
self.build(self._story, onFirstPage=PaidStamp(7 * inch, 5.8 * inch) if self.is_paid else None)