Example #1
0
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/>&nbsp<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/>&nbsp<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/>&nbsp<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/>&nbsp<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/>&nbsp;<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/>&nbsp;<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()