2018-09-02 09:25:04 -05:00
|
|
|
#!/usr/bin/env python3
|
2014-11-10 08:52:19 -06:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
##@file
|
2014-12-07 10:18:57 -06:00
|
|
|
# @brief exports an invoice from gnucash using a template file, see \ref py_invoice_export
|
2014-11-10 08:52:19 -06:00
|
|
|
# @ingroup python_bindings_examples
|
|
|
|
# @author Christoph Holtermann (c.holtermann (at) gmx.de)
|
|
|
|
# @date 2014-11
|
|
|
|
#
|
2014-12-07 10:18:57 -06:00
|
|
|
# @details
|
2014-11-10 08:52:19 -06:00
|
|
|
# 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.
|
|
|
|
#
|
2014-11-12 06:28:25 -06:00
|
|
|
# Example templates for german invoices:
|
|
|
|
# - Invoice.tex.tmpl
|
|
|
|
# - Invoice_2.tex.tmpl
|
|
|
|
#
|
2014-11-10 08:52:19 -06:00
|
|
|
# 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
|
|
|
|
#
|
2014-12-07 10:18:57 -06:00
|
|
|
# Doxygen docs:
|
2018-11-03 04:08:56 -05:00
|
|
|
# - https://code.gnucash.org/docs/MAINT or MASTER
|
2014-12-07 10:18:57 -06:00
|
|
|
# - see page \ref py_invoice_export
|
2014-11-12 07:54:56 -06:00
|
|
|
#
|
2014-11-10 08:52:19 -06:00
|
|
|
# Questions / Issues:
|
2014-11-12 06:28:25 -06:00
|
|
|
# - How much logic in the template, how much preprocessing in this file ?
|
|
|
|
# - Internationalization - currencies, formatting of numbers
|
|
|
|
# - Providing data of gnucash owner
|
2014-11-10 08:52:19 -06:00
|
|
|
|
|
|
|
try:
|
2014-11-11 14:35:15 -06:00
|
|
|
import locale
|
2014-11-10 08:52:19 -06:00
|
|
|
import sys
|
|
|
|
import getopt
|
|
|
|
import gnucash
|
|
|
|
import str_methods
|
|
|
|
import jinja2
|
|
|
|
from gncinvoicefkt import *
|
|
|
|
except ImportError as import_error:
|
2018-03-22 17:08:22 -05:00
|
|
|
print("Problem importing modules.")
|
|
|
|
print(import_error)
|
2014-11-10 08:52:19 -06:00
|
|
|
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
|
2014-11-11 09:59:45 -06:00
|
|
|
list_invoices = False
|
2014-11-10 08:52:19 -06:00
|
|
|
invoice_number = None
|
|
|
|
invoice_id = None
|
|
|
|
|
|
|
|
try:
|
2014-11-11 09:59:45 -06:00
|
|
|
opts, args = getopt.getopt(argv[1:], "fhlI:t:o:", ["help"])
|
2018-09-02 09:25:04 -05:00
|
|
|
except getopt.error as msg:
|
2014-11-10 08:52:19 -06:00
|
|
|
raise Usage(msg)
|
|
|
|
|
|
|
|
for opt in opts:
|
|
|
|
if opt[0] in ["-f"]:
|
2018-03-22 17:08:22 -05:00
|
|
|
print("ignoring lock")
|
2014-11-10 08:52:19 -06:00
|
|
|
ignore_lock = True
|
|
|
|
if opt[0] in ["-h","--help"]:
|
|
|
|
raise Usage("Help:")
|
|
|
|
if opt[0] in ["-I"]:
|
|
|
|
invoice_id = opt[1]
|
2018-03-22 17:08:22 -05:00
|
|
|
print("using invoice ID '" + str(invoice_id) + "'.")
|
2014-11-10 08:52:19 -06:00
|
|
|
if opt[0] in ["-o"]:
|
|
|
|
filename_output = opt[1]
|
2018-03-22 17:08:22 -05:00
|
|
|
print("using output file", filename_output)
|
2014-11-10 08:52:19 -06:00
|
|
|
if opt[0] in ["-t"]:
|
|
|
|
filename_template = opt[1]
|
2018-03-22 17:08:22 -05:00
|
|
|
print("using template file", filename_template)
|
2014-11-11 09:59:45 -06:00
|
|
|
if opt[0] in ["-l"]:
|
|
|
|
list_invoices = True
|
2018-03-22 17:08:22 -05:00
|
|
|
print("listing invoices")
|
2014-11-10 08:52:19 -06:00
|
|
|
|
|
|
|
# Check for correct input
|
|
|
|
if len(args)>1:
|
2018-03-22 17:08:22 -05:00
|
|
|
print("opts:",opts,"args:",args)
|
2014-11-10 08:52:19 -06:00
|
|
|
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:
|
2014-11-11 09:59:45 -06:00
|
|
|
no_output = True
|
|
|
|
if not list_invoices:
|
|
|
|
raise Usage("No template given !")
|
2014-11-10 08:52:19 -06:00
|
|
|
|
|
|
|
# Check for output file
|
|
|
|
if not filename_output:
|
2014-11-11 09:59:45 -06:00
|
|
|
if filename_template:
|
|
|
|
filename_output = filename_template + ".out"
|
2018-03-22 17:08:22 -05:00
|
|
|
print("no output filename given, will be:", filename_output)
|
2014-11-10 08:52:19 -06:00
|
|
|
|
2018-09-02 09:25:04 -05:00
|
|
|
except Usage as err:
|
2014-11-10 08:52:19 -06:00
|
|
|
if err.msg == "Help:":
|
|
|
|
retcode=0
|
|
|
|
else:
|
2018-09-02 09:25:04 -05:00
|
|
|
print("Error:", err.msg, file=sys.stderr)
|
|
|
|
print("for help use --help", file=sys.stderr)
|
2014-11-10 08:52:19 -06:00
|
|
|
retcode=2
|
|
|
|
|
2018-03-22 17:08:22 -05:00
|
|
|
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("-l list all invoices")
|
|
|
|
print("-h or --help for this help")
|
|
|
|
print("-I ID use invoice ID")
|
|
|
|
print("-t filename use filename as template file")
|
|
|
|
print("-o filename use filename as output file")
|
2014-11-10 08:52:19 -06:00
|
|
|
|
|
|
|
return retcode
|
|
|
|
|
|
|
|
# Try to open the given input
|
|
|
|
try:
|
2018-03-22 17:08:22 -05:00
|
|
|
print("Opening", input_url, ".")
|
2014-11-10 08:52:19 -06:00
|
|
|
session = gnucash.Session(input_url, ignore_lock=ignore_lock)
|
|
|
|
except Exception as exception:
|
2018-03-22 17:08:22 -05:00
|
|
|
print("Problem opening input.")
|
|
|
|
print(exception)
|
2014-11-10 08:52:19 -06:00
|
|
|
return 2
|
|
|
|
|
|
|
|
book = session.book
|
|
|
|
root_account = book.get_root_account()
|
|
|
|
comm_table = book.get_table()
|
|
|
|
EUR = comm_table.lookup("CURRENCY", "EUR")
|
|
|
|
|
2014-11-11 09:59:45 -06:00
|
|
|
invoice_list = get_all_invoices(book)
|
2014-11-10 08:52:19 -06:00
|
|
|
|
2014-11-11 09:59:45 -06:00
|
|
|
if list_invoices:
|
|
|
|
for number,invoice in enumerate(invoice_list):
|
2018-03-22 17:08:22 -05:00
|
|
|
print(str(number)+")")
|
|
|
|
print(invoice)
|
2014-11-10 08:52:19 -06:00
|
|
|
|
|
|
|
if not (no_output):
|
|
|
|
|
|
|
|
if invoice_id:
|
|
|
|
invoice = book.InvoiceLookupByID(invoice_id)
|
|
|
|
if not invoice:
|
2018-03-22 17:08:22 -05:00
|
|
|
print("ID not found.")
|
2014-11-10 08:52:19 -06:00
|
|
|
return 2
|
|
|
|
|
|
|
|
if invoice_number:
|
|
|
|
invoice = invoice_list[invoice_number]
|
|
|
|
|
2018-03-22 17:08:22 -05:00
|
|
|
print("Using the following invoice:")
|
|
|
|
print(invoice)
|
2014-11-10 08:52:19 -06:00
|
|
|
|
|
|
|
loader = jinja2.FileSystemLoader('.')
|
|
|
|
env = jinja2.Environment(loader=loader)
|
|
|
|
template = env.get_template(filename_template)
|
|
|
|
|
|
|
|
#import IPython
|
|
|
|
#IPython.embed()
|
2014-11-11 14:35:15 -06:00
|
|
|
output = template.render(invoice=invoice, locale=locale)
|
2014-11-10 08:52:19 -06:00
|
|
|
|
2018-03-22 17:08:22 -05:00
|
|
|
print("Writing output", filename_output, ".")
|
2014-11-10 08:52:19 -06:00
|
|
|
with open(filename_output, 'w') as f:
|
|
|
|
f.write(output.encode('utf-8'))
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
sys.exit(main())
|