Create Invoice - Extended

  1# This is an example where we create a customized invoice with logos and attachments,
  2# and a payment gateway, then send it by email to your address.
  3
  4from datetime import date
  5from freshbooks import Client as FreshBooksClient
  6from freshbooks import FreshBooksError
  7
  8FB_CLIENT_ID = "<your client id>"
  9ACCESS_TOKEN = "<your access token>"
 10ACCOUNT_ID = "<your account id>"
 11DESTINATION_EMAIL = "<your email>"  # Don't use the same email as the account owner.
 12
 13freshBooksClient = FreshBooksClient(client_id=FB_CLIENT_ID, access_token=ACCESS_TOKEN)
 14
 15# Create the client
 16print("Creating client...")
 17try:
 18    client_data = {
 19        "email": DESTINATION_EMAIL,
 20        "organization": "Python SDK Test Client"
 21    }
 22    client = freshBooksClient.clients.create(ACCOUNT_ID, client_data)
 23except FreshBooksError as e:
 24    print(e)
 25    print(e.status_code)
 26    exit(1)
 27
 28print(f"Created client {client.id}")
 29
 30# Upload a logo and attachment with examples of file_path and file_stream.
 31try:
 32    print("Uploading invoice logo")
 33    # We upload a file by providing the path to the file.
 34    logo = freshBooksClient.images.upload(ACCOUNT_ID, file_path="./assets/sample_logo.png")
 35
 36    print("Uploading invoice attachment")
 37    # We upload a file by opening it and providing the file stream.
 38    attachment = freshBooksClient.attachments.upload(
 39        ACCOUNT_ID, file_stream=open("./assets/sample_attachment.pdf", "rb")
 40    )
 41except FreshBooksError as e:
 42    print(e)
 43    print(e.status_code)
 44    exit(1)
 45
 46# Create the invoice with taxed line items, a custom colour and logo, and an attachment.
 47
 48# Taxed line items
 49line1 = {
 50    "name": "A Taxed Item",
 51    "description": "These things are taxed",
 52    "qty": 2,
 53    "taxAmount1": "13",
 54    "taxName1": "HST",
 55    "unit_cost": {
 56        "amount": "27.00",
 57        "code": "CAD"
 58    }
 59}
 60line2 = {
 61    "name": "Another Taxed ItemRegular Glasses",
 62    "description": "With a different tax",
 63    "qty": 4,
 64    "taxAmount1": "5",
 65    "taxName1": "GST",
 66    "unit_cost": {
 67        "amount": "6.95",
 68        "code": "CAD"
 69    }
 70}
 71
 72presentation = {
 73    "theme_primary_color": "#1fab13",
 74    "theme_layout": "simple",
 75    "theme_font_name": "modern",
 76    "image_logo_src": f"/uploads/images/{logo.jwt}"  # The logo upload response contains a jwt token
 77}
 78
 79invoice_data = {
 80    "customerid": client.id,
 81    "create_date": date.today().isoformat(),
 82    "due_offset_days": 5,
 83    "lines": [line1, line2],
 84    "attachments": [
 85        {
 86            "jwt": attachment.jwt,
 87            "media_type": attachment.media_type
 88        }
 89    ],
 90    "presentation": presentation
 91}
 92print("Creating invoice...")
 93try:
 94    invoice = freshBooksClient.invoices.create(ACCOUNT_ID, invoice_data)
 95except FreshBooksError as e:
 96    print(e)
 97    print(e.status_code)
 98    exit(1)
 99
100print(f"Created invoice {invoice.invoice_number} (Id: {invoice.id})")
101print(f"Invoice total is {invoice.amount.amount} {invoice.amount.code}")
102
103# Once the invoice is created, a payment option can be added to it.
104print("Adding fbpay payment option...")
105payment_option_data = {
106    "gateway_name": "fbpay",
107    "entity_id": invoice.id,
108    "entity_type": "invoice",
109    "has_credit_card": True
110}
111try:
112    freshBooksClient.invoice_payment_options.create(ACCOUNT_ID, invoice.id, payment_option_data)
113except FreshBooksError as e:
114    print(e)
115    print(e.status_code)
116    exit(1)
117
118# Invoices are created in draft status, so we need to send it.
119print("Sending the invoice by email...")
120invoice_data = {
121    "action_email": True,
122    "email_recipients": [destination_email],
123    "email_include_pdf": False,
124    "invoice_customized_email": {
125        "subject": "Test Styled Invoice",
126        "body": "This was an example",
127    }
128}
129try:
130    invoice = freshBooksClient.invoices.update(ACCOUNT_ID, invoice.id, invoice_data)
131except FreshBooksError as e:
132    print(e)
133    print(e.status_code)
134    exit(1)