Create invoices from templates with jinja2

This commit is contained in:
Christoph Holtermann
2014-11-10 15:52:19 +01:00
parent d2ed373426
commit 15a69f1205
2 changed files with 231 additions and 0 deletions

View File

@@ -0,0 +1,163 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
##@file
# @ingroup python_bindings_examples
# @author Christoph Holtermann (c.holtermann (at) gmx.de)
# @date 2014-11
# @brief exports an invoice from gnucash using a template file
#
# Input is a template file that will be filled with information from
# gnucash Invoices. Jinja2 templating engine ist used. Templates can
# be Latex, Html or anything.
#
# This is a sequel to latex_invoices.py that exported to a lco file
# to be imported into a LaTeX letter.
# The approach used here is not as dependent on external files and
# more modular as it allows to use arbitrary templates
#
# Questions / Issues:
# * How to print a list of all invoices ? ( Or to post a search via python )
# * How much logic in the template, how much preprocessing in this file ?
try:
import sys
import getopt
import gnucash
import str_methods
import jinja2
from gncinvoicefkt import *
except ImportError as import_error:
print "Problem importing modules."
print import_error
sys.exit(2)
class Usage(Exception):
def __init__(self, msg):
self.msg = msg
def main(argv=None):
if argv is None:
argv = sys.argv
try:
# default values
prog_name = argv[0]
ignore_lock = True
filename_template = None
filename_output = None
no_output = False
list_invoices = True
invoice_number = None
invoice_id = None
try:
opts, args = getopt.getopt(argv[1:], "fhI:t:o:", ["help"])
except getopt.error, msg:
raise Usage(msg)
for opt in opts:
if opt[0] in ["-f"]:
print "ignoring lock"
ignore_lock = True
if opt[0] in ["-h","--help"]:
raise Usage("Help:")
if opt[0] in ["-I"]:
invoice_id = opt[1]
print "using invoice ID '" + str(invoice_id) + "'."
if opt[0] in ["-o"]:
filename_output = opt[1]
print "using output file", filename_output
if opt[0] in ["-t"]:
filename_template = opt[1]
print "using template file", filename_template
# Check for correct input
if len(args)>1:
print "opts:",opts,"args:",args
raise Usage("Only one input possible !")
if len(args)==0:
raise Usage("No input given !")
input_url = args[0]
# Check for correct template
if not filename_template:
raise Usage("No template given !")
# Check for output file
if not filename_output:
filename_output = filename_template + ".out"
except Usage, err:
if err.msg == "Help:":
retcode=0
else:
print >>sys.stderr, "Error:",err.msg
print >>sys.stderr, "for help use --help"
retcode=2
print
print "Usage:"
print
print "Invoke with",prog_name,"gnucash_url."
print "where input is"
print " filename"
print "or file://filename"
print "or mysql://user:password@host/databasename"
print
print "-f force open = ignore lock"
print "-h or --help for this help"
print "-I ID invoice with this ID"
print "-t filename use filename as template file"
print "-o filename use filename as output file"
return retcode
# Try to open the given input
try:
print "Opening", input_url, "."
session = gnucash.Session(input_url, ignore_lock=ignore_lock)
except Exception as exception:
print "Problem opening input."
print exception
return 2
book = session.book
root_account = book.get_root_account()
comm_table = book.get_table()
EUR = comm_table.lookup("CURRENCY", "EUR")
# invoice_list = get_all_invoices(book)
# if list_invoices:
# for number,invoice in enumerate(invoice_list):
# print str(number)+")"
# print invoice
if not (no_output):
if invoice_id:
invoice = book.InvoiceLookupByID(invoice_id)
if not invoice:
print "ID not found."
return 2
if invoice_number:
invoice = invoice_list[invoice_number]
print "Using the following invoice:"
print invoice
loader = jinja2.FileSystemLoader('.')
env = jinja2.Environment(loader=loader)
template = env.get_template(filename_template)
#import IPython
#IPython.embed()
output = template.render(invoice=invoice)
print "Writing output", filename_output, "."
with open(filename_output, 'w') as f:
f.write(output.encode('utf-8'))
if __name__ == "__main__":
sys.exit(main())

View File

@@ -0,0 +1,68 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
try:
import gnucash
from gnucash.gnucash_business import Customer, Employee, Vendor, Job, \
Address, Invoice, Entry, TaxTable, TaxTableEntry, GNC_AMT_TYPE_PERCENT, \
GNC_DISC_PRETAX
import str_methods
except ImportError as import_error:
print "Problem importing modules."
print import_error
sys.exit(2)
def get_all_lots(account):
"""Return all lots in account and descendants"""
ltotal=[]
descs = account.get_descendants()
for desc in descs:
if type(desc).__name__ == 'SwigPyObject':
desc = gnucash.Account(instance=desc)
ll=desc.GetLotList()
ltotal+=ll
return ltotal
def get_all_invoices_from_lots(account):
"""Return all invoices in account and descendants
This is based on lots. So invoices without lots will be missed."""
lot_list=get_all_lots(account)
invoice_list=[]
for lot in lot_list:
if type(lot).__name__ == 'SwigPyObject':
lot = gnucash.GncLot(instance=lot)
invoice=gnucash.gnucash_core_c.gncInvoiceGetInvoiceFromLot(lot.instance)
if invoice:
invoice_list.append(Invoice(instance=invoice))
return invoice_list
def get_all_invoices(book):
"""Returns all invoices in the book."""
invoice_list = []
invoice = True
invoice_id = 0
while invoice:
invoice_id += 1
invoice = book.InvoiceLookupByID('%06d' % invoice_id)
if invoice:
invoice_list.append(invoice)
return invoice_list
def get_all_customers(book):
"""Returns all customers in book."""
customer_list = []
customer = True
customer_id = 0
while customer:
customer_id += 1
customer = book.CustomerLookupByID('%06d' % customer_id)
if customer:
customer_list.append(customer)
return customer_list