GnuCash  4.11-243-g1cac132214+
latex_invoices.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
52 
53 try:
54  import sys
55  import getopt
56  import gnucash
57  import str_methods
58  from gncinvoicefkt import *
59  from IPython import version_info as IPython_version_info
60 
61  if IPython_version_info[0] >= 1:
62  from IPython.terminal.ipapp import TerminalIPythonApp
63  else:
64  from IPython.frontend.terminal.ipapp import TerminalIPythonApp
65  from gnucash.gnucash_business import (
66  Customer,
67  Employee,
68  Vendor,
69  Job,
70  Address,
71  Invoice,
72  Entry,
73  TaxTable,
74  TaxTableEntry,
75  GNC_AMT_TYPE_PERCENT,
76  GNC_DISC_PRETAX,
77  )
78  from gnucash import SessionOpenMode
79  import locale
80 except ImportError as import_error:
81  print("Problem importing modules.")
82  print(import_error)
83  sys.exit(2)
84 
85 
86 class Usage(Exception):
87  def __init__(self, msg):
88  self.msg = msg
89 
90 
91 def invoice_to_lco(invoice):
92  """returns a string which forms a lco-file for use with LaTeX"""
93 
94  lco_out = u"\ProvidesFile{data.lco}[]\n"
95 
96  def write_variable(ukey, uvalue, replace_linebreak=True):
97 
98  outstr = u""
99  if uvalue.endswith("\n"):
100  uvalue = uvalue[0 : len(uvalue) - 1]
101 
102  if not ukey in [u"fromaddress", u"toaddress", u"date"]:
103  outstr += u"\\newkomavar{"
104  outstr += ukey
105  outstr += u"}\n"
106 
107  outstr += u"\\setkomavar{"
108  outstr += ukey
109  outstr += u"}{"
110  if replace_linebreak:
111  outstr += uvalue.replace(u"\n", u"\\\\") + "}"
112  return outstr
113 
114  # Write owners address
115  add_str = u""
116  owner = invoice.GetOwner()
117  if owner.GetName() != "":
118  add_str += owner.GetName() + "\n"
119 
120  addr = owner.GetAddr()
121  if addr.GetName() != "":
122  add_str += addr.GetName() + "\n"
123  if addr.GetAddr1() != "":
124  add_str += addr.GetAddr1() + "\n"
125  if addr.GetAddr2() != "":
126  add_str += addr.GetAddr2() + "\n"
127  if addr.GetAddr3() != "":
128  add_str += addr.GetAddr3() + "\n"
129  if addr.GetAddr4() != "":
130  add_str += addr.GetAddr4() + "\n"
131 
132  lco_out += write_variable("toaddress2", add_str)
133 
134  # Invoice number
135  inr_str = invoice.GetID()
136  lco_out += write_variable("rechnungsnummer", inr_str)
137 
138  # date
139  date = invoice.GetDatePosted()
140  udate = date.strftime("%d.%m.%Y")
141  lco_out += write_variable("date", udate) + "\n"
142 
143  # date due
144  date_due = invoice.GetDateDue()
145  udate_due = date_due.strftime("%d.%m.%Y")
146  lco_out += write_variable("date_due", udate_due) + "\n"
147 
148  # Write the entries
149  ent_str = u""
150  locale.setlocale(locale.LC_ALL, "")
151  for n, ent in enumerate(invoice.GetEntries()):
152 
153  line_str = u""
154 
155  if type(ent) != Entry:
156  ent = Entry(instance=ent) # Add to method_returns_list
157 
158  descr = ent.GetDescription()
159  price = ent.GetInvPrice().to_double()
160  n = ent.GetQuantity()
161 
162  uprice = locale.currency(price).rstrip(" EUR")
163  un = str(
164  int(float(n.num()) / n.denom())
165  ) # choose best way to format numbers according to locale
166 
167  line_str = u"\Artikel{"
168  line_str += un
169  line_str += u"}{"
170  line_str += descr
171  line_str += u"}{"
172  line_str += uprice
173  line_str += u"}"
174 
175  # print(line_str)
176  ent_str += line_str
177 
178  lco_out += write_variable("entries", ent_str)
179 
180  return lco_out
181 
182 
183 def main(argv=None):
184  if argv is None:
185  argv = sys.argv
186  try:
187  prog_name = argv[0]
188  with_ipshell = False
189  ignore_lock = False
190  no_latex_output = True
191  list_invoices = False
192  output_file_name = "data.lco"
193  invoice_number = None
194 
195  try:
196  opts, args = getopt.getopt(argv[1:], "fhiln:po:", ["help"])
197  except getopt.error as msg:
198  raise Usage(msg)
199 
200  for opt in opts:
201  if opt[0] in ["-f"]:
202  print("ignoring lock")
203  ignore_lock = True
204  if opt[0] in ["-h", "--help"]:
205  raise Usage("Help:")
206  if opt[0] in ["-i"]:
207  print("Using ipshell")
208  with_ipshell = True
209  if opt[0] in ["-l"]:
210  print("listing all invoices")
211  list_invoices = True
212  if opt[0] in ["-n"]:
213  invoice_number = int(opt[1])
214  print("using invoice number", invoice_number)
215  no_latex_output = False
216  if opt[0] in ["-o"]:
217  output_file_name = opt[1]
218  print("using output file", output_file_name)
219  if len(args) > 1:
220  print("opts:", opts, "args:", args)
221  raise Usage("Only one input can be accepted !")
222  if len(args) == 0:
223  raise Usage("No input given !")
224  input_url = args[0]
225  except Usage as err:
226  if err.msg == "Help:":
227  retcode = 0
228  else:
229  print("Error:", err.msg, file=sys.stderr)
230  print("for help use --help", file=sys.stderr)
231  retcode = 2
232 
233  print("Generate a LaTeX invoice or print out all invoices.")
234  print()
235  print("Usage:")
236  print()
237  print("Invoke with", prog_name, "input.")
238  print("where input is")
239  print(" filename")
240  print("or file://filename")
241  print("or mysql://user:password@host/databasename")
242  print()
243  print("-f force open = ignore lock")
244  print("-h or --help for this help")
245  print("-i for ipython shell")
246  print("-l list all invoices")
247  print("-n number use invoice number (no. from previous run with -l)")
248  print("-o name use name as outputfile. default: data.lco")
249 
250  return retcode
251 
252  # Try to open the given input
253  try:
254  session = gnucash.Session(
255  input_url,
256  SessionOpenMode.SESSION_READ_ONLY
257  if ignore_lock
258  else SessionOpenMode.SESSION_NORMAL_OPEN,
259  )
260  except Exception as exception:
261  print("Problem opening input.")
262  print(exception)
263  return 2
264 
265  book = session.book
266  root_account = book.get_root_account()
267  comm_table = book.get_table()
268  EUR = comm_table.lookup("CURRENCY", "EUR")
269 
270  invoice_list = get_all_invoices(book)
271 
272  if list_invoices:
273  for number, invoice in enumerate(invoice_list):
274  print(str(number) + ")")
275  print(invoice)
276 
277  if not (no_latex_output):
278 
279  if invoice_number == None:
280  print("Using the first invoice:")
281  invoice_number = 0
282 
283  invoice = invoice_list[invoice_number]
284  print("Using the following invoice:")
285  print(invoice)
286 
287  lco_str = invoice_to_lco(invoice)
288 
289  # Opening output file
290  f = open(output_file_name, "w")
291  f.write(lco_str)
292  f.close()
293 
294  if with_ipshell:
295  app = TerminalIPythonApp.instance()
296  app.initialize(argv=[]) # argv=[] instructs IPython to ignore sys.argv
297  app.start()
298 
299  # session.save()
300  session.end()
301 
302 
303 if __name__ == "__main__":
304  sys.exit(main())