auto calculate total

This commit is contained in:
zhangshine 2015-06-09 22:20:04 +08:00
parent b13a80160d
commit 4444e709f8
3 changed files with 66 additions and 35 deletions

View file

@ -1,4 +1,5 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from decimal import Decimal
class PDFInfo(object): class PDFInfo(object):
@ -55,22 +56,22 @@ class Item(object):
""" """
Product/Item information Product/Item information
""" """
def __init__(self, item_id, name, description, units, unit_price, subtotal, vat_tax=None): def __init__(self, name, description, units, unit_price):
""" """
Item modal init Item modal init
:param item_id: Order id or Item id
:param name: Item name :param name: Item name
:param units: Amount :param units: Amount
:param unit_price: Unit price :param unit_price: Unit price
:return: :return:
""" """
self.item_id = item_id
self.name = name self.name = name
self.description = description self.description = description
self.units = units self.units = units
self.unit_price = unit_price self.unit_price = unit_price
self.vat_tax = vat_tax
self.subtotal = subtotal @property
def amount(self):
return int(self.units) * Decimal(self.unit_price)
class Transaction(object): class Transaction(object):

View file

@ -1,5 +1,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from datetime import datetime, date from datetime import datetime, date
from decimal import Decimal
from reportlab.lib import colors from reportlab.lib import colors
from reportlab.lib.enums import TA_CENTER, TA_RIGHT from reportlab.lib.enums import TA_CENTER, TA_RIGHT
from reportlab.lib.pagesizes import letter from reportlab.lib.pagesizes import letter
@ -42,8 +43,7 @@ class SimpleInvoice(SimpleDocTemplate):
self.client_info = None self.client_info = None
self.is_paid = False self.is_paid = False
self._items = [] self._items = []
self.item_tax_total = None self._item_tax_rate = None
self.item_total = None
self._transactions = [] self._transactions = []
self._story = [] self._story = []
@ -55,6 +55,9 @@ class SimpleInvoice(SimpleDocTemplate):
if isinstance(item, Item): if isinstance(item, Item):
self._items.append(item) self._items.append(item)
def set_item_tax_rate(self, rate):
self._item_tax_rate = rate
@property @property
def transactions(self): def transactions(self):
return self._transactions[:] return self._transactions[:]
@ -162,37 +165,65 @@ class SimpleInvoice(SimpleDocTemplate):
def __build_items(self): def __build_items(self):
# Items # Items
item_data = [ item_data = []
( item_subtotal = 0
item.item_id,
item.name, for item in self._items:
Paragraph(item.description, self._defined_styles.get('TableParagraph')), if not isinstance(item, Item):
item.units, continue
item.unit_price,
item.vat_tax if item.vat_tax is not None else '-', item_data.append(
item.subtotal (
) for item in self._items if isinstance(item, Item) item.name,
] Paragraph(item.description, self._defined_styles.get('TableParagraph')),
item.units,
item.unit_price,
item.amount
)
)
item_subtotal += item.amount
if item_data: if item_data:
self._story.append( self._story.append(
Paragraph('Detail', self._defined_styles.get('Heading1')) Paragraph('Detail', self._defined_styles.get('Heading1'))
) )
item_data.insert(0, ('#', 'Name', 'Description', 'Units', 'Unit Price', 'Vat/Tax', 'Subtotal'))
if self.item_tax_total or self.item_total: item_data_title = ('Name', 'Description', 'Units', 'Unit Price', 'Amount')
item_data.insert(0, item_data_title) # Insert title
# Summary field
sum_start_y_index = len(item_data)
sum_end_x_index = -1 - 1
sum_start_x_index = len(item_data_title) - abs(sum_end_x_index)
style = []
# ##### Subtotal #####
item_data.append(
('Subtotal', '', '', '', item_subtotal)
)
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'))
# Tax total
if self._item_tax_rate is not None:
tax_total = item_subtotal * (Decimal(str(self._item_tax_rate)) / Decimal('100'))
item_data.append( item_data.append(
( ('Vat/Tax ({0}%)'.format(self._item_tax_rate), '', '', '', tax_total)
'Total', '', '', '', '',
self.item_tax_total if self.item_tax_total else '-',
self.item_total if self.item_total else '-'
)
) )
style = [ sum_start_y_index += 1
('SPAN', (0, len(item_data) - 1), (4, len(item_data) - 1)), style.append(('SPAN', (0, sum_start_y_index), (sum_start_x_index, sum_start_y_index)))
('ALIGN', (0, len(item_data) - 1), (-3, -1), 'RIGHT'), style.append(('ALIGN', (0, sum_start_y_index), (sum_end_x_index, -1), 'RIGHT'))
]
else: else:
style = None tax_total = None
# Total
total = item_subtotal + tax_total if tax_total else Decimal('0')
item_data.append(('Total', '', '', '', total))
sum_start_y_index += 1
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'))
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):

View file

@ -32,11 +32,10 @@ doc.client_info = ClientInfo(
post_code='222222' post_code='222222'
) )
doc.add_item(Item('0000', 'Item', 'Item', 1, '1.1', '1.32', '0.22')) doc.add_item(Item('Item', 'Item desc', 1, '1.1'))
doc.add_item(Item('1111', 'Item', 'Item', 2, '2.2', '4.4')) doc.add_item(Item('Item', 'Item desc', 2, '2.2'))
doc.add_item(Item('2222', 'Item', 'Item', 3, '3.3', '9.9')) doc.add_item(Item('Item', 'Item desc', 3, '3.3'))
doc.item_tax_total = Decimal('.22') doc.set_item_tax_rate(20) # 20%
doc.item_total = Decimal('16.2')
doc.add_transaction(Transaction('Paypal', 111, datetime.now(), 1)) doc.add_transaction(Transaction('Paypal', 111, datetime.now(), 1))
doc.add_transaction(Transaction('Strip', 222, datetime.now(), 2)) doc.add_transaction(Transaction('Strip', 222, datetime.now(), 2))