GnuCash  5.6-150-g038405b370+
gncinvoice_jinja.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
32 
33 try:
34  import locale
35  import os
36  import sys
37  import getopt
38  import gnucash
39  import str_methods
40  import jinja2
41  from gncinvoicefkt import *
42  from gnucash import SessionOpenMode
43 except ImportError as import_error:
44  print("Problem importing modules.")
45  print(import_error)
46  sys.exit(2)
47 
48 
49 class Usage(Exception):
50  def __init__(self, msg):
51  self.msg = msg
52 
53 
54 def main(argv=None):
55  if argv is None:
56  argv = sys.argv
57  try:
58  # default values
59  prog_name = argv[0]
60  ignore_lock = True
61  filename_template = None
62  filename_output = None
63  no_output = False
64  list_invoices = False
65  invoice_number = None
66  invoice_id = None
67  filename_from_invoice = False
68  output_path = None
69  with_ipshell = False
70 
71  try:
72  opts, args = getopt.getopt(argv[1:], "fhliI:t:o:OP:", ["help"])
73  except getopt.error as msg:
74  raise Usage(msg)
75 
76  for opt in opts:
77  if opt[0] in ["-f"]:
78  print("ignoring lock")
79  ignore_lock = True
80  if opt[0] in ["-h", "--help"]:
81  raise Usage("Help:")
82  if opt[0] in ["-I"]:
83  invoice_id = opt[1]
84  print("using invoice ID '" + str(invoice_id) + "'.")
85  if opt[0] in ["-i"]:
86  print("Using ipshell")
87  with_ipshell = True
88  if opt[0] in ["-o"]:
89  filename_output = opt[1]
90  print("using output file", filename_output)
91  if opt[0] in ["-O"]:
92  if filename_output:
93  print("given output filename will be overwritten,")
94  print("creating output filename from Invoice data.")
95  filename_from_invoice = True
96  if opt[0] in ["-t"]:
97  filename_template = opt[1]
98  print("using template file", filename_template)
99  if opt[0] in ["-l"]:
100  list_invoices = True
101  print("listing invoices")
102  if opt[0] in ["-P"]:
103  output_path = opt[1]
104  print("output path is", output_path + ".")
105 
106  # Check for correct input
107  if len(args) > 1:
108  print("opts:", opts, "args:", args)
109  raise Usage("Only one input possible !")
110  if len(args) == 0:
111  raise Usage("No input given !")
112  input_url = args[0]
113 
114  # Check for correct template
115  if not filename_template:
116  no_output = True
117  if not list_invoices:
118  raise Usage("No template given !")
119 
120  # Check for output file
121  if not (filename_output or filename_from_invoice):
122  if filename_template:
123  filename_output = filename_template + ".out"
124  print("no output filename given, will be:", filename_output)
125 
126  except Usage as err:
127  if err.msg == "Help:":
128  retcode = 0
129  else:
130  print("Error:", err.msg, file=sys.stderr)
131  print("for help use --help", file=sys.stderr)
132  retcode = 2
133 
134  print()
135  print("Usage:")
136  print()
137  print("Invoke with", prog_name, "gnucash_url.")
138  print("where input is")
139  print(" filename")
140  print("or file://filename")
141  print("or mysql://user:password@host/databasename")
142  print()
143  print("-f force open = ignore lock (read only)")
144  print("-l list all invoices")
145  print("-h or --help for this help")
146  print("-I ID use invoice ID")
147  print("-t filename use filename as template file")
148  print("-o filename use filename as output file")
149  print("-O create output filename by date, owner and invoice number")
150  print("-P path path for output file. Overwrites path in -o option")
151 
152  return retcode
153 
154  # Try to open the given input
155  try:
156  print(
157  "Opening", input_url, " (ignore-lock = read-only)." if ignore_lock else "."
158  )
159  session = gnucash.Session(
160  input_url,
161  SessionOpenMode.SESSION_READ_ONLY
162  if ignore_lock
163  else SessionOpenMode.SESSION_NORMAL_OPEN,
164  )
165  except Exception as exception:
166  print("Problem opening input.")
167  print(exception)
168  return 2
169 
170  book = session.book
171  root_account = book.get_root_account()
172  comm_table = book.get_table()
173  EUR = comm_table.lookup("CURRENCY", "EUR")
174 
175  invoice_list = get_all_invoices(book)
176 
177  if list_invoices:
178  for number, invoice in enumerate(invoice_list):
179  print(str(number) + ")")
180  print(invoice)
181 
182  if not (no_output):
183 
184  if invoice_id:
185  invoice = book.InvoiceLookupByID(invoice_id)
186  if not invoice:
187  print("ID not found.")
188  return 2
189 
190  if invoice_number:
191  invoice = invoice_list[invoice_number]
192 
193  print("Using the following invoice:")
194  print(invoice)
195 
196  path_template = os.path.dirname(filename_template)
197  filename_template_basename = os.path.basename(filename_template)
198 
199  loader = jinja2.FileSystemLoader(path_template)
200  env = jinja2.Environment(loader=loader)
201  template = env.get_template(filename_template_basename)
202 
203  # company = gnucash_business.Company(book.instance)
204 
205  output = template.render(invoice=invoice, locale=locale) # , company=company)
206 
207  if filename_from_invoice:
208  filename_date = invoice.GetDatePosted().strftime(
209  "%Y-%m-%d"
210  ) # something like 2014-11-01
211  filename_owner_name = str(invoice.GetOwner().GetName())
212  filename_invoice_id = str(invoice.GetID())
213  filename_output = (
214  filename_date
215  + "_"
216  + filename_owner_name
217  + "_"
218  + filename_invoice_id
219  + ".tex"
220  )
221 
222  if output_path:
223  filename_output = os.path.join(
224  output_path, os.path.basename(filename_output)
225  )
226 
227  print("Writing output", filename_output, ".")
228  with open(filename_output, "w") as f:
229  f.write(output)
230 
231  if with_ipshell:
232  import IPython
233 
234  IPython.embed()
235 
236 
237 if __name__ == "__main__":
238  sys.exit(main())