def generate(doc_id): """given the document id generate a pdf string output """ s = couchdb.Server(settings.COUCH_DSN) db = s['client_docs'] doc = db.get(doc_id) if doc == None: raise Exception('Failed to generate pdf.', 'Document %s not found.' % doc_id) client_id = doc['client_id'] engine = create_engine(settings.MYSQL_DSN) conn = engine.connect() output_stream = StringIO() doc_pdf = SimpleDocTemplate(output_stream) #get fname, lname sql = text("""SELECT fname, lname, company_name, company_address from leads WHERE id = :client_id """) client_details = conn.execute(sql, client_id=client_id).fetchone() doc_pdf.client_id = client_id doc_pdf.client_details = client_details doc_pdf.order_id = doc['order_id'] #check clients running balance r = db.view('client/running_balance', key=client_id) if len(r.rows) == 0: doc_pdf.running_balance = Decimal(0) else: doc_pdf.running_balance = Decimal('%0.2f' % r.rows[0].value) sql = text("""SELECT sign from currency_lookup WHERE code = :currency """) doc_pdf.currency_sign = conn.execute( sql, currency=doc['currency']).fetchone()['sign'] doc_pdf.currency = doc['currency'] doc_pdf.total_amount = locale.format('%0.2f', Decimal(doc['total_amount']), True) if doc.has_key('invoice_date'): x = doc['invoice_date'] else: x = doc['added_on'] doc_pdf.invoice_date = date(x[0], x[1], x[2]).strftime('%B %d, %Y') if doc.has_key('pay_before_date'): x = doc['pay_before_date'] doc_pdf.pay_before_date = date(x[0], x[1], x[2]).strftime('%B %d, %Y') #get client settings for the removal of Available Balance now = get_ph_time(as_array=True) view = db.view('client/settings', startkey=[client_id, now], endkey=[client_id, [2011, 1, 1, 0, 0, 0, 0]], descending=True, limit=1, include_docs=True) doc_client_settings = view.rows[0].doc show_available_balance = True if doc_client_settings.has_key('days_before_suspension'): if doc_client_settings['days_before_suspension'] == -30: show_available_balance = False doc_pdf.show_available_balance = show_available_balance #spacer Story = [Spacer(1, 3 * inch)] #collect items items = doc['items'] items_has_date = False styles = getSampleStyleSheet() style_table = styles['Normal'] style_table.fontSize = 8 p_num_hours = Paragraph('<b>Number of Hours / Quantity</b>', style_table) p_hourly_rate = Paragraph( '<b>Hourly Rate / Unit Price %s</b>' % (doc_pdf.currency_sign), style_table) pdf_items = [ [ "Item", "Date", "Name and Designation of Staff", p_num_hours, p_hourly_rate, "Amount %s" % (doc_pdf.currency_sign) ], ] for item in items: item_date = '' if item.has_key('start_date'): items_has_date = True x = item['start_date'] y = date(x[0], x[1], x[2]) item_date += y.strftime('%b %d, %Y') if item.has_key('end_date'): items_has_date = True x = item['end_date'] y = date(x[0], x[1], x[2]) item_date += y.strftime(' - %b %d, %Y') description = Paragraph(item['description'], style_table) pdf_item = [ item['item_id'], Paragraph(item_date, style_table), description, locale.format('%0.2f', Decimal(item['qty']), True), locale.format('%0.2f', Decimal(item['unit_price']), True), locale.format('%0.2f', Decimal(item['amount']), True) ] pdf_items.append(pdf_item) summary = [] #append sub_total p_sub_total = Paragraph('<para alignment="right"><b>Sub Total</b></para>', style_table) summary.append([ p_sub_total, '', '', '', '', locale.format('%0.2f', Decimal(doc['sub_total']), True) ]) #append gst p_gst = Paragraph('<para alignment="right"><b>GST</b></para>', style_table) summary.append([ p_gst, '', '', '', '', locale.format('%0.2f', Decimal(doc['gst_amount']), True) ]) #append total_amount p_total_amount = Paragraph( '<para alignment="right"><b>Total Amount</b></para>', style_table) summary.append([ p_total_amount, '', '', '', '', '%s %s%s' % (doc_pdf.currency, doc_pdf.currency_sign, locale.format('%0.2f', Decimal(doc['total_amount']), True)) ]) grid_style = [ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('FONTSIZE', (0, 0), (-1, -1), 8), ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), ('ALIGN', (0, 0), (-1, 0), 'CENTER'), ('ALIGN', (0, 1), (0, -1), 'RIGHT'), ('ALIGN', (3, 1), (3, -1), 'RIGHT'), ('ALIGN', (4, 1), (4, -1), 'RIGHT'), ('ALIGN', (5, 1), (5, -1), 'RIGHT'), ] width_date = 1 * inch width_description = None if items_has_date == False: width_date = 0.4 * inch width_description = 3.5 * inch t = Table(pdf_items, colWidths=[ 0.4 * inch, width_date, width_description, 0.6 * inch, 0.6 * inch, 1 * inch ], style=grid_style, repeatRows=1) Story.append(t) grid_style_summary = [ ('FONTSIZE', (0, 0), (-1, -1), 8), ('ALIGN', (5, 0), (5, -1), 'RIGHT'), ('SPAN', (0, -1), (4, -1)), ('SPAN', (0, -2), (4, -2)), ('SPAN', (0, -3), (4, -3)), ('FONTNAME', (-1, -1), (-1, -1), 'Helvetica-Bold'), #bold total_amount figure ('BACKGROUND', (-1, -1), (-1, -1), colors.yellow), #change background color or total_amount figure ('GRID', (-1, -3), (-1, -1), 0.5, colors.grey), ] t_summary = Table(summary, colWidths=[ 0.4 * inch, width_date, width_description, 0.6 * inch, 0.6 * inch, 1 * inch ], style=grid_style_summary) Story.append(t_summary) p = Paragraph("""HOW TO PAY:""", styleH2) Story.append(p) Story.append(Spacer(1, 0.1 * inch)) styles = getSampleStyleSheet() style = styles["Normal"] style.borderWidth = 1 style.borderRadius = 0.08 * inch style.borderPadding = 0.1 * inch style.fontName = 'Helvetica' style.borderColor = (0.22, 0.34, 0.53) style.backColor = (0.92, 0.96, 0.86) style.spaceAfter = 0.25 * inch #payment_link = 'https://remotestaff.com.au/portal/ClientTopUp/TopUp.html?order_id=%s' % doc['order_id'] payment_link = 'https://remotestaff.com.au/portal/v2/payments/top-up/%s' % doc[ 'order_id'] p = Paragraph( """ <b>PAY ONLINE OR PHONE USING YOUR CREDIT CARD</b><br/> <br/> We accept Visa, Master Card and AMEX. Follow this link <a color="blue" href="%s">%s</a> to pay for this invoice or call +61(02) 8014 9196 press 4 to pay over the phone. """ % (payment_link, payment_link), style) Story.append(p) debit_form_link = 'https://remotestaff.com.au/portal/pdf_report/credit_card_debit_form/THKGENDirectDebitForm.pdf' credit_card_form_link = 'https://remotestaff.com.au/portal/pdf_report/credit_card_debit_form/?id=%s' % client_id p = Paragraph( """ <b>AUTO DEBIT</b><br/> <br/> Have your account paid on the invoice due date automaticaly via direct debit or credit card to save time. Fill this form <a color="blue" href="%s">%s</a> (Australian Clients Only) or Credit Card form <a color="blue" href="%s">%s</a> and return to <a color="blue" href="mailto:[email protected]">[email protected]</a> """ % (debit_form_link, debit_form_link, credit_card_form_link, credit_card_form_link), style) Story.append(p) p = Paragraph( """ <b>ELECTRONIC BANK TRANSFER TO</b><br/> <br/> <b>Australia : </b><br/> Account Name: Think Innovations Pty. Ltd.<br/> BSB: 082 973<br/> Account Number: 49 058 9267<br/> Bank Branch: Darling Street, Balmain NSW 2041<br/> Swift Code: NATAAU3302S<br/> <br/> <b>United Kingdom : </b><br/> Account Name: Think Innovations Pty. Ltd.<br/> UK Bank Address: HSBC. 25 Nothing Hill Gate. London. W11 3JJ<br/> Sort code: 40-05-09<br/> Acc: 61-50-63-23<br/> Swift Code: MIDLGB22<br/> IBAN Number: GB54MIDL40050961506323<br/> <br/> <b>United States : </b><br/> Account Name: Think Innovations Pty. Ltd.<br/> Bank Branch: HSBC Bank USA NA 452 Fifth Avenue, New York, NY 10018<br/> Account number: 048-984-515<br/> Routing Number: 021001088<br/> Swift code: MRMDUS33<br/> """, style) Story.append(p) p = Paragraph( """ <b>Note:</b><br/> <br/> For Invoices in Australian Dollar a Merchant facility fees apply for the following credit card holders: <br/> """, styleN) Story.append(p) styleN.bulletIndent = 0.2 * inch p = Paragraph("""<br/><bullet>AMEX : 2%</bullet>""", styleN) Story.append(p) p = Paragraph("""<br/><bullet>Visa / MasterCard : 1%</bullet>""", styleN) Story.append(p) p = Paragraph( """<br/>For Invoices in Pounds and USD, 2% Merchant facility fees apply for all credit card payments.""", styleN) Story.append(p) p = Paragraph( """<br/>Paypal fees ranging from 1.1% - 2.4% of your invoice amount applies and will be reflected as a debit on your Available Balance Sheet.""", styleN) Story.append(p) p = Paragraph( """<br/>Note that we prefer payments made via bank transfer or direct debit.""", styleN) Story.append(p) Story.append(Spacer(1, 1 * inch)) styles_ref_doc = getSampleStyleSheet() style_ref_doc = styles_ref_doc['Normal'] style_ref_doc.fontName = 'Courier' style_ref_doc.fontSize = 9 p = Paragraph( """ -----------------------------------------<br/> Ref doc: %s -----------------------------------------<br/> """ % doc_id, style_ref_doc) Story.append(p) doc_pdf.title = 'INVOICE %s' % doc['order_id'] doc_pdf.subject = 'doc_id %s' % doc['_id'] doc_pdf.author = 'remotestaff' doc_pdf.creator = 'celery task generate_pdf_invoice.generate' doc_pdf.build(Story, onFirstPage=myFirstPage, onLaterPages=myLaterPages) output_stream.seek(0) return output_stream.read()