def draw_totals(self, totals_x, line_height, subtotal_y): tax_y = subtotal_y - line_height credit_y = tax_y - line_height total_y = credit_y - (line_height * 2) totals_money_x = totals_x + inches(1) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(inches(5.7), subtotal_y - inches(1.2), inches(2.05), inches(0.5), fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawString(totals_x, subtotal_y, "Subtotal:") self.canvas.drawString(totals_x, tax_y, "Tax (%0.2f%%):" % self.tax_rate) self.canvas.drawString(totals_x, credit_y, "Credit:") self.canvas.drawString(totals_x, total_y, "Total:") self.canvas.drawString(totals_money_x, subtotal_y, get_money_str(self.subtotal)) self.canvas.drawString(totals_money_x, tax_y, get_money_str(self.applied_tax)) self.canvas.drawString(totals_money_x, credit_y, get_money_str(self.applied_credit)) self.canvas.drawString(totals_money_x, total_y, get_money_str(self.total)) self.canvas.setFontSize(SMALL_FONT_SIZE) self.canvas.drawString(inches(5.85), subtotal_y - inches(1.4), "Thank you for using CommCare HQ.") self.canvas.setFontSize(DEFAULT_FONT_SIZE)
def draw_footer(self): self.canvas.rect(inches(0.75), inches(1.3), inches(4), inches(0.5)) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(inches(5), inches(1.05), inches(3), inches(0.5), fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawString(inches(5.6), inches(2.45), "Subtotal:") self.canvas.drawString(inches(5.6), inches(2.15), "Tax (%s%%):" % get_money_str(self.tax_rate)) self.canvas.drawString(inches(5.6), inches(1.85), "Credit:") self.canvas.drawString(inches(5.2), inches(1.25), "Total:") self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.45), get_money_str(self.subtotal)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.15), get_money_str(self.applied_tax)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.85), get_money_str(self.applied_credit)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.25), get_money_str(self.total)) self.canvas.drawString(inches(5), inches(0.8), "Thank you for using CommCare HQ.") footer_text = ("Payable by check or wire transfer. " "Wire transfer is preferred: " "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number)s " "Swift Code: %(swift_code)s") % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number': self.routing_number, 'swift_code': self.swift_code, } payment_info = Paragraph(footer_text, ParagraphStyle('')) payment_info.wrapOn(self.canvas, inches(4), inches(0.9)) payment_info.drawOn(self.canvas, inches(0.75), inches(0.6))
def draw_table(self, items): origin_x = inches(0.5) origin_y = inches(6.72) self.canvas.translate(origin_x, origin_y) height = inches(0.725 * len(items)) description_x = inches(2.4) quantity_x = inches(3.15) rate_x = inches(3.9) subtotal_x = inches(5.1) credits_x = inches(6.0) total_x = inches(7.25) header_height = inches(0.3) self.canvas.rect(0, 0, total_x, -height) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(0, 0, total_x, header_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.line(description_x, header_height, description_x, -height) self.canvas.line(quantity_x, header_height, quantity_x, -height) self.canvas.line(rate_x, header_height, rate_x, -height) self.canvas.line(subtotal_x, header_height, subtotal_x, -height) self.canvas.line(credits_x, header_height, credits_x, -height) self.canvas.setFontSize(SMALL_FONT_SIZE) self.canvas.drawCentredString(midpoint(0, description_x), inches(0.1), "PRODUCT") self.canvas.drawCentredString(midpoint(description_x, quantity_x), inches(0.1), "QUANTITY") self.canvas.drawCentredString(midpoint(quantity_x, rate_x), inches(0.1), "UNIT COST") self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), inches(0.1), "SUBTOTAL") self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), inches(0.1), "CREDITS") self.canvas.drawCentredString(midpoint(credits_x, total_x), inches(0.1), "TOTAL") self.canvas.setFontSize(DEFAULT_FONT_SIZE) coord_y = 0 for item_index in range(len(items)): if coord_y < -height: raise InvoiceError("Cannot fit line items on invoice") item = items[item_index] description = Paragraph(item.description, ParagraphStyle('', fontSize=DEFAULT_FONT_SIZE, )) description.wrapOn(self.canvas, description_x - inches(0.2), -header_height) coord_y -= description.height + inches(0.05) description.drawOn(self.canvas, inches(0.1), coord_y) self.canvas.drawCentredString( midpoint(description_x, quantity_x), coord_y, str(item.quantity) ) self.canvas.drawCentredString( midpoint(quantity_x, rate_x), coord_y, get_money_str(item.unit_cost) ) self.canvas.drawCentredString( midpoint(rate_x, subtotal_x), coord_y, get_money_str(item.subtotal) ) self.canvas.drawCentredString( midpoint(subtotal_x, credits_x), coord_y, get_money_str(item.credits) ) self.canvas.drawCentredString( midpoint(credits_x, total_x), coord_y, get_money_str(item.total) ) coord_y -= inches(0.1) self.canvas.line(0, coord_y, total_x, coord_y) self.canvas.translate(-origin_x, -origin_y)
def draw_table(self): origin_x = inches(0.5) origin_y = inches(6.2) self.canvas.translate(origin_x, origin_y) height = inches(3.5) description_x = inches(2.4) quantity_x = inches(3.15) rate_x = inches(3.9) subtotal_x = inches(5.1) credits_x = inches(6.3) total_x = inches(7.5) header_height = inches(0.3) self.canvas.rect(0, 0, total_x, -height) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(0, 0, total_x, header_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.line(description_x, header_height, description_x, -height) self.canvas.line(quantity_x, header_height, quantity_x, -height) self.canvas.line(rate_x, header_height, rate_x, -height) self.canvas.line(subtotal_x, header_height, subtotal_x, -height) self.canvas.line(credits_x, header_height, credits_x, -height) self.canvas.drawCentredString(midpoint(0, description_x), inches(0.1), "Product") self.canvas.drawCentredString(midpoint(description_x, quantity_x), inches(0.1), "Quantity") self.canvas.drawCentredString(midpoint(quantity_x, rate_x), inches(0.1), "Unit Cost") self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), inches(0.1), "Subtotal") self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), inches(0.1), "Credits Applied") self.canvas.drawCentredString(midpoint(credits_x, total_x), inches(0.1), "Total") coord_y = 0 for item_index in range(len(self.items)): if coord_y < -height: raise InvoiceError("Cannot fit line items on invoice") item = self.items[item_index] description = Paragraph(item.description, ParagraphStyle('', fontSize=12, )) description.wrapOn(self.canvas, description_x - inches(0.2), -header_height) coord_y -= description.height + inches(0.05) description.drawOn(self.canvas, inches(0.1), coord_y) self.canvas.drawCentredString( midpoint(description_x, quantity_x), coord_y, str(item.quantity) ) self.canvas.drawCentredString( midpoint(quantity_x, rate_x), coord_y, get_money_str(item.unit_cost) ) self.canvas.drawCentredString( midpoint(rate_x, subtotal_x), coord_y, get_money_str(item.subtotal) ) self.canvas.drawCentredString( midpoint(subtotal_x, credits_x), coord_y, get_money_str(item.credits) ) self.canvas.drawCentredString( midpoint(credits_x, total_x), coord_y, get_money_str(item.total) ) coord_y -= inches(0.1) self.canvas.line(0, coord_y, total_x, coord_y) self.canvas.translate(-origin_x, -origin_y)
def get_column_formatted_str(subtotal, deduction): return mark_safe('%s<br />(%s)') % ( get_money_str(subtotal), get_money_str(deduction) )
def get_exportable_column(amount): return format_datatables_data( text=get_money_str(amount), sort_key=amount, )
def draw_footer(self): self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(inches(5), inches(1.05), inches(3), inches(0.5), fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawString(inches(5.6), inches(2.45), "Subtotal:") self.canvas.drawString(inches(5.6), inches(2.15), "Tax (%s%%):" % get_money_str(self.tax_rate)) self.canvas.drawString(inches(5.6), inches(1.85), "Credit:") self.canvas.drawString(inches(5.2), inches(1.25), "Total:") self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.45), get_money_str(self.subtotal)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.15), get_money_str(self.applied_tax)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.85), get_money_str(self.applied_credit)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.25), get_money_str(self.total)) self.canvas.drawString(inches(5), inches(0.8), "Thank you for using CommCare HQ.") payment_description = """Payable by credit card, check, wire or ACH transfer.<br /> For all payments, include "Invoice #" (displayed in top right corner).<br /> <strong>Credit card payments</strong> are preferred and can be made online.<br /> """ ach_payment_text = ( "<strong>ACH payment</strong> (preferred over wire payment for transfer in the US):<br />" "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number_ach)s<br />") % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number_ach': self.routing_number_ach, } wire_payment_text = ("<strong>Wire payment</strong>:<br />" "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number_wire)s " "Swift Code: %(swift_code)s<br/>") % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number_wire': self.routing_number_wire, 'swift_code': self.swift_code, } payment_info = Paragraph( '\n'.join([ payment_description, ach_payment_text, wire_payment_text, ]), ParagraphStyle('')) payment_info.wrapOn(self.canvas, inches(4.25), inches(0.9)) payment_info.drawOn(self.canvas, inches(0.5), inches(0.6))
def draw_table(self): origin_x = inches(0.5) origin_y = inches(6.2) self.canvas.translate(origin_x, origin_y) height = inches(3.5) description_x = inches(2.4) quantity_x = inches(3.15) rate_x = inches(3.9) subtotal_x = inches(5.1) credits_x = inches(6.3) total_x = inches(7.5) header_height = inches(0.3) self.canvas.rect(0, 0, total_x, -height) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(0, 0, total_x, header_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.line(description_x, header_height, description_x, -height) self.canvas.line(quantity_x, header_height, quantity_x, -height) self.canvas.line(rate_x, header_height, rate_x, -height) self.canvas.line(subtotal_x, header_height, subtotal_x, -height) self.canvas.line(credits_x, header_height, credits_x, -height) self.canvas.drawCentredString(midpoint(0, description_x), inches(0.1), "Product") self.canvas.drawCentredString(midpoint(description_x, quantity_x), inches(0.1), "Quantity") self.canvas.drawCentredString(midpoint(quantity_x, rate_x), inches(0.1), "Unit Cost") self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), inches(0.1), "Subtotal") self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), inches(0.1), "Credits Applied") self.canvas.drawCentredString(midpoint(credits_x, total_x), inches(0.1), "Total") coord_y = 0 for item_index in range(len(self.items)): if coord_y < -height: raise InvoiceError("Cannot fit line items on invoice") item = self.items[item_index] description = Paragraph(item.description, ParagraphStyle( '', fontSize=12, )) description.wrapOn(self.canvas, description_x - inches(0.2), -header_height) coord_y -= description.height + inches(0.05) description.drawOn(self.canvas, inches(0.1), coord_y) self.canvas.drawCentredString(midpoint(description_x, quantity_x), coord_y, str(item.quantity)) self.canvas.drawCentredString(midpoint(quantity_x, rate_x), coord_y, get_money_str(item.unit_cost)) self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), coord_y, get_money_str(item.subtotal)) self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), coord_y, get_money_str(item.credits)) self.canvas.drawCentredString(midpoint(credits_x, total_x), coord_y, get_money_str(item.total)) coord_y -= inches(0.1) self.canvas.line(0, coord_y, total_x, coord_y) self.canvas.translate(-origin_x, -origin_y)
def draw_footer(self): from corehq.apps.domain.views import DomainBillingStatementsView self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(inches(5), inches(1.65), inches(3), inches(0.5), fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawString(inches(5.6), inches(3.05), "Subtotal:") self.canvas.drawString(inches(5.6), inches(2.75), "Tax (%0.2f%%):" % self.tax_rate) self.canvas.drawString(inches(5.6), inches(2.45), "Credit:") self.canvas.drawString(inches(5.2), inches(1.85), "Total:") self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(3.05), get_money_str(self.subtotal)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.75), get_money_str(self.applied_tax)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.45), get_money_str(self.applied_credit)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.85), get_money_str(self.total)) self.canvas.drawString(inches(5), inches(1.4), "Thank you for using CommCare HQ.") payment_description = ( "Payment Options:<br />" "<strong>Credit card payments</strong> are preferred and can be made online here: " "<link href='%(payment_page)s' color='blue'>%(payment_page)s</link><br />" "<br />" "<strong>ACH or Wire:</strong> If you make payment via ACH or Wire, please make sure to email " "<font color='blue'>%(invoicing_contact_email)s</font> " "so that we can match your payment to the correct invoice. Please include: " "Invoice #, Project Space, and payment date in the email. <br />" ) % { 'invoicing_contact_email': settings.INVOICING_CONTACT_EMAIL, 'payment_page': absolute_reverse(DomainBillingStatementsView.urlname, args=[self.project_name]), } payment_info = Paragraph(payment_description, ParagraphStyle('')) payment_info.wrapOn(self.canvas, inches(4.25), inches(0.9)) payment_info.drawOn(self.canvas, inches(0.5), inches(1.8)) ach_payment_text = ( "<strong>ACH payment</strong> (preferred over wire payment for transfer in the US):<br />" "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number_ach)s<br />" ) % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number_ach': self.routing_number_ach, } wire_payment_text = ( "<strong>Wire payment</strong>:<br />" "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number_wire)s " "Swift Code: %(swift_code)s<br/>" ) % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number_wire': self.routing_number_wire, 'swift_code': self.swift_code, } payment_info2 = Paragraph('\n'.join([ ach_payment_text, wire_payment_text, ]), ParagraphStyle('')) payment_info2.wrapOn(self.canvas, inches(4.25), inches(0.9)) payment_info2.drawOn(self.canvas, inches(0.7), inches(0.4))
def draw_footer(self): self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(inches(5), inches(1.05), inches(3), inches(0.5), fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawString(inches(5.6), inches(2.45), "Subtotal:") self.canvas.drawString(inches(5.6), inches(2.15), "Tax (%s%%):" % get_money_str(self.tax_rate)) self.canvas.drawString(inches(5.6), inches(1.85), "Credit:") self.canvas.drawString(inches(5.2), inches(1.25), "Total:") self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.45), get_money_str(self.subtotal)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.15), get_money_str(self.applied_tax)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.85), get_money_str(self.applied_credit)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.25), get_money_str(self.total)) self.canvas.drawString(inches(5), inches(0.8), "Thank you for using CommCare HQ.") payment_description = """Payable by credit card, check, wire or ACH transfer.<br /> For all payments, include "Invoice #" (displayed in top right corner).<br /> <strong>Credit card payments</strong> are preferred and can be made online.<br /> """ ach_payment_text = ( "<strong>ACH payment</strong> (preferred over wire payment for transfer in the US):<br />" "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number_ach)s<br />" ) % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number_ach': self.routing_number_ach, } wire_payment_text = ( "<strong>Wire payment</strong>:<br />" "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number_wire)s " "Swift Code: %(swift_code)s<br/>" ) % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number_wire': self.routing_number_wire, 'swift_code': self.swift_code, } payment_info = Paragraph('\n'.join([ payment_description, ach_payment_text, wire_payment_text, ]), ParagraphStyle('')) payment_info.wrapOn(self.canvas, inches(4.25), inches(0.9)) payment_info.drawOn(self.canvas, inches(0.5), inches(0.6))
def draw_footer(self): from corehq.apps.domain.views import DomainBillingStatementsView totals_x = inches(5.85) line_height = inches(0.25) subtotal_y = inches(3.5) tax_y = subtotal_y - line_height credit_y = tax_y - line_height total_y = credit_y - (line_height * 2) totals_money_x = totals_x + inches(1) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect( inches(5.7), inches(2.3), inches(2.05), inches(0.5), fill=1 ) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawString(totals_x, subtotal_y, "Subtotal:") self.canvas.drawString(totals_x, tax_y, "Tax (%0.2f%%):" % self.tax_rate) self.canvas.drawString(totals_x, credit_y, "Credit:") self.canvas.drawString(totals_x, total_y, "Total:") self.canvas.drawString( totals_money_x, subtotal_y, get_money_str(self.subtotal) ) self.canvas.drawString( totals_money_x, tax_y, get_money_str(self.applied_tax) ) self.canvas.drawString( totals_money_x, credit_y, get_money_str(self.applied_credit) ) self.canvas.drawString( totals_money_x, total_y, get_money_str(self.total) ) self.canvas.setFontSize(SMALL_FONT_SIZE) self.canvas.drawString(inches(5.85), inches(2.1), "Thank you for using CommCare HQ.") self.canvas.setFontSize(DEFAULT_FONT_SIZE) width = inches(5.00) left_x = inches(0.5) options = "PAYMENT OPTIONS:" self.canvas.setFontSize(SMALL_FONT_SIZE) options_text = Paragraph(options, ParagraphStyle('')) options_text.wrapOn(self.canvas, width, inches(.12)) options_text.drawOn(self.canvas, left_x, inches(3.5)) self.canvas.setFontSize(DEFAULT_FONT_SIZE) flywire = """<strong>International payments:</strong> Make payments in your local currency via bank transfer or credit card by following this link: <link href='{flywire_link}' color='blue'>{flywire_link}</link><br />""".format( flywire_link="https://wl.flywire.com/?destination=DMG" ) flywire_text = Paragraph(flywire, ParagraphStyle('')) flywire_text.wrapOn(self.canvas, width, inches(.4)) flywire_text.drawOn(self.canvas, left_x, inches(2.95)) credit_card = """<strong>Credit card payments (USD)</strong> can be made online here:<br /> <link href='{payment_page}' color='blue'>{payment_page}</link><br />""".format( payment_page=absolute_reverse( DomainBillingStatementsView.urlname, args=[self.project_name]) ) credit_card_text = Paragraph(credit_card, ParagraphStyle('')) credit_card_text.wrapOn(self.canvas, width, inches(.5)) credit_card_text.drawOn(self.canvas, left_x, inches(2.4)) ach_or_wire = """<strong>ACH or Wire:</strong> If you make payment via ACH or Wire, please make sure to email <font color='blue'>{invoicing_contact_email}</font> so that we can match your payment to the correct invoice. Please include: Invoice No., Project Space, and payment date in the email. <br />""".format( invoicing_contact_email=settings.INVOICING_CONTACT_EMAIL, ) ach_or_wire_text = Paragraph(ach_or_wire, ParagraphStyle('')) ach_or_wire_text.wrapOn(self.canvas, width, inches(.5)) ach_or_wire_text.drawOn(self.canvas, left_x, inches(1.7)) ach_payment_text = """<strong>ACH payment</strong> (preferred over wire payment for transfer in the US):<br /> Bank: {bank_name} Bank Address: {bank_address} Account Number: {account_number} Routing Number or ABA: {routing_number_ach}<br />""".format( bank_name=self.bank_name, bank_address=self.bank_address, account_number=self.account_number, routing_number_ach=self.routing_number_ach ) wire_payment_text = """<strong>Wire payment</strong>:<br /> Bank: {bank_name} Bank Address: {bank_address} Account Number: {account_number} Routing Number or ABA: {routing_number_wire} Swift Code: {swift_code}<br/>""".format( bank_name=self.bank_name, bank_address=self.bank_address, account_number=self.account_number, routing_number_wire=self.routing_number_wire, swift_code=self.swift_code ) payment_info2 = Paragraph('\n'.join([ ach_payment_text, wire_payment_text, ]), ParagraphStyle('')) payment_info2.wrapOn(self.canvas, width - inches(0.1), inches(0.9)) payment_info2.drawOn(self.canvas, inches(0.6), inches(0.5))
def draw_table(self): origin_x = inches(0.5) origin_y = inches(6.2) self.canvas.translate(origin_x, origin_y) height = inches(3.5) description_x = inches(3) quantity_x = inches(3.75) rate_x = inches(4.5) subtotal_x = inches(5.5) credits_x = inches(6.5) total_x = inches(7.5) header_height = inches(0.3) self.canvas.rect(0, 0, total_x, -height) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(0, 0, total_x, header_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.line(description_x, header_height, description_x, -height) self.canvas.line(quantity_x, header_height, quantity_x, -height) self.canvas.line(rate_x, header_height, rate_x, -height) self.canvas.line(subtotal_x, header_height, subtotal_x, -height) self.canvas.line(credits_x, header_height, credits_x, -height) self.canvas.drawCentredString(midpoint(0, description_x), inches(0.1), "Description") self.canvas.drawCentredString(midpoint(description_x, quantity_x), inches(0.1), "Quantity") self.canvas.drawCentredString(midpoint(quantity_x, rate_x), inches(0.1), "Rate") self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), inches(0.1), "Subtotal") self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), inches(0.1), "Credits") self.canvas.drawCentredString(midpoint(credits_x, total_x), inches(0.1), "Total") coord_y = 0 for item_index in range(len(self.items)): if item_index > 13: raise InvoiceError("Too many line items to fit to invoice") item = self.items[item_index] description = Paragraph(item.description, ParagraphStyle('', fontSize=12, )) description.wrapOn(self.canvas, description_x - inches(0.2), -header_height) coord_y -= description.height + inches(0.05) description.drawOn(self.canvas, inches(0.1), coord_y) self.canvas.drawCentredString( midpoint(description_x, quantity_x), coord_y, str(item.quantity) ) self.canvas.drawCentredString( midpoint(quantity_x, rate_x), coord_y, get_money_str(item.rate) ) self.canvas.drawCentredString( midpoint(rate_x, subtotal_x), coord_y, get_money_str(item.subtotal) ) self.canvas.drawCentredString( midpoint(subtotal_x, credits_x), coord_y, get_money_str(item.credits) ) self.canvas.drawCentredString( midpoint(credits_x, total_x), coord_y, get_money_str(item.total) ) coord_y -= inches(0.1) self.canvas.line(0, coord_y, total_x, coord_y) self.canvas.translate(-origin_x, -origin_y)