GnuCash  4.8a-176-g88ecf8dd1
gnucash_core.py
Go to the documentation of this file.
1 # gnucash_core.py -- High level python wrapper classes for the core parts
2 # of GnuCash
3 #
4 # Copyright (C) 2008 ParIT Worker Co-operative <paritinfo@parit.ca>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License as
7 # published by the Free Software Foundation; either version 2 of
8 # the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, contact:
17 # Free Software Foundation Voice: +1-617-542-5942
18 # 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
19 # Boston, MA 02110-1301, USA gnu@gnu.org
20 #
21 # @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
22 # @author Jeff Green, ParIT Worker Co-operative <jeff@parit.ca>
23 
24 # The following is for doxygen
25 
30 
31 from enum import IntEnum
32 from urllib.parse import urlparse
33 
34 from gnucash import gnucash_core_c
35 from gnucash import _sw_core_utils
36 
37 from gnucash.function_class import \
38  ClassFromFunctions, extract_attributes_with_prefix, \
39  default_arguments_decorator, method_function_returns_instance, \
40  methods_return_instance, process_list_convert_to_instance, \
41  method_function_returns_instance_list, methods_return_instance_lists
42 
43 from gnucash.gnucash_core_c import gncInvoiceLookup, gncInvoiceGetInvoiceFromTxn, \
44  gncInvoiceGetInvoiceFromLot, gncEntryLookup, gncInvoiceLookup, \
45  gncCustomerLookup, gncVendorLookup, gncJobLookup, gncEmployeeLookup, \
46  gncTaxTableLookup, gncTaxTableLookupByName, gnc_search_invoice_on_id, \
47  gnc_search_customer_on_id, gnc_search_bill_on_id , \
48  gnc_search_vendor_on_id, gncInvoiceNextID, gncCustomerNextID, \
49  gncVendorNextID, gncTaxTableGetTables, gnc_numeric_zero, \
50  gnc_numeric_create, double_to_gnc_numeric, string_to_gnc_numeric, \
51  gnc_numeric_to_string
52 
53 from gnucash.deprecation import (
54  deprecated_args_session,
55  deprecated_args_session_init,
56  deprecated_args_session_begin,
57  deprecated
58 )
59 
60 try:
61  import gettext
62 
63  _localedir = _sw_core_utils.gnc_path_get_localedir()
64  gettext.install(_sw_core_utils.GETTEXT_PACKAGE, _localedir)
65 except:
66  print()
67  print("Problem importing gettext!")
68  import traceback
69  import sys
70  exc_type, exc_value, exc_traceback = sys.exc_info()
71  traceback.print_exception(exc_type, exc_value, exc_traceback)
72  print()
73 
74  def _(s):
75  """Null translator function, gettext not available"""
76  return s
77 
78  import builtins
79  builtins.__dict__['_'] = _
80 
81 class GnuCashCoreClass(ClassFromFunctions):
82  _module = gnucash_core_c
83 
84  def do_lookup_create_oo_instance(self, lookup_function, cls, *args):
85  thing = lookup_function(self.get_instance(), *args)
86  if thing != None:
87  thing = cls(instance=thing)
88  return thing
89 
90 
91 class GnuCashBackendException(Exception):
92  def __init__(self, msg, errors):
93  Exception.__init__(self, msg)
94  self.errors = errors
95 
96 
97 class SessionOpenMode(IntEnum):
98  """Mode for opening sessions.
99 
100  This replaces three booleans that were passed in order: ignore_lock, create,
101  and force. It's structured so that one can use it as a bit field with the
102  values in the same order, i.e. ignore_lock = 1 << 2, create_new = 1 << 1, and
103  force_new = 1.
104 
105  enumeration members
106  -------------------
107 
108  SESSION_NORMAL_OPEN = 0 (All False)
109  Open will fail if the URI doesn't exist or is locked.
110 
111  SESSION_NEW_STORE = 2 (False, True, False (create))
112  Create a new store at the URI. It will fail if the store already exists and is found to contain data that would be overwritten.
113 
114  SESSION_NEW_OVERWRITE = 3 (False, True, True (create | force))
115  Create a new store at the URI even if a store already exists there.
116 
117  SESSION_READ_ONLY = 4, (True, False, False (ignore_lock))
118  Open the session read-only, ignoring any existing lock and not creating one if the URI isn't locked.
119 
120  SESSION_BREAK_LOCK = 5 (True, False, True (ignore_lock | force))
121  Open the session, taking over any existing lock.
122 
123  source: lignucash/engine/qofsession.h
124  """
125 
126  SESSION_NORMAL_OPEN = gnucash_core_c.SESSION_NORMAL_OPEN
127  """All False
128  Open will fail if the URI doesn't exist or is locked."""
129 
130  SESSION_NEW_STORE = gnucash_core_c.SESSION_NEW_STORE
131  """False, True, False (create)
132  Create a new store at the URI. It will fail if the store already exists and is found to contain data that would be overwritten."""
133 
134  SESSION_NEW_OVERWRITE = gnucash_core_c.SESSION_NEW_OVERWRITE
135  """False, True, True (create | force)
136  Create a new store at the URI even if a store already exists there."""
137 
138  SESSION_READ_ONLY = gnucash_core_c.SESSION_READ_ONLY
139  """True, False, False (ignore_lock)
140  Open the session read-only, ignoring any existing lock and not creating one if the URI isn't locked."""
141 
142  SESSION_BREAK_LOCK = gnucash_core_c.SESSION_BREAK_LOCK
143  """True, False, True (ignore_lock | force)
144  Open the session, taking over any existing lock."""
145 
146 
148  """A GnuCash book editing session
149 
150  To commit changes to the session you may need to call save,
151  (this is always the case with the file backend).
152 
153  When you're down with a session you may need to call end()
154 
155  Every Session has a Book in the book attribute, which you'll definitely
156  be interested in, as every GnuCash entity (Transaction, Split, Vendor,
157  Invoice..) is associated with a particular book where it is stored.
158  """
159 
160  @deprecated_args_session_init
161  def __init__(self, book_uri=None, mode=None, instance=None, book=None):
162  """!
163  A convenient constructor that allows you to specify a book URI,
164  begin the session, and load the book.
165 
166  This can give you the power of calling
167  qof_session_new, qof_session_begin, and qof_session_load all in one!
168 
169  qof_session_load is only called if url scheme is "xml" and
170  mode is SESSION_NEW_STORE or SESSION_NEW_OVERWRITE
171 
172  @param book_uri must be a string in the form of a URI/URL. The access
173  method specified depends on the loaded backends. Paths may be relative
174  or absolute. If the path is relative, that is if the argument is
175  "file://somefile.xml", then the current working directory is
176  assumed. Customized backends can choose to search other
177  application-specific directories or URI schemes as well.
178  It be None to skip the calls to qof_session_begin and
179  qof_session_load.
180 
181  @param instance argument can be passed if new Session is used as a
182  wrapper for an existing session instance
183 
184  @param mode The SessionOpenMode.
185  @note SessionOpenMode replaces deprecated ignore_lock, is_new and force_new.
186 
187  @par SessionOpenMode
188  `SESSION_NORMAL_OPEN`: Find an existing file or database at the provided uri and
189  open it if it is unlocked. If it is locked post a QOF_BACKEND_LOCKED error.
190  @par
191  `SESSION_NEW_STORE`: Check for an existing file or database at the provided
192  uri and if none is found, create it. If the file or database exists post a
193  QOF_BACKED_STORE_EXISTS and return.
194  @par
195  `SESSION_NEW_OVERWRITE`: Create a new file or database at the provided uri,
196  deleting any existing file or database.
197  @par
198  `SESSION_READ_ONLY`: Find an existing file or database and open it without
199  disturbing the lock if it exists or setting one if not. This will also set a
200  flag on the book that will prevent many elements from being edited and will
201  prevent the backend from saving any edits.
202  @par
203  `SESSION_BREAK_LOCK`: Find an existing file or database, lock it, and open
204  it. If there is already a lock replace it with a new one for this session.
205 
206  @par Errors
207  qof_session_begin() signals failure by queuing errors. After it completes use
208  qof_session_get_error() and test that the value is `ERROR_BACKEND_NONE` to
209  determine that the session began successfully.
210 
211  @exception as begin() and load() are wrapped with raise_backend_errors_after_call()
212  this function can raise a GnuCashBackendException. If it does,
213  you don't need to cleanup and call end() and destroy(), that is handled
214  for you, and the exception is raised.
215  """
216  if instance is not None:
217  GnuCashCoreClass.__init__(self, instance=instance)
218  else:
219  if book is None:
220  book = Book()
221  GnuCashCoreClass.__init__(self, book)
222 
223  if book_uri is not None:
224  try:
225  if mode is None:
226  mode = SessionOpenMode.SESSION_NORMAL_OPEN
227  self.begin(book_uri, mode)
228  # Take care of backend inconsistency
229  # New xml file can't be loaded, new sql store
230  # has to be loaded before it can be altered
231  # Any existing store obviously has to be loaded
232  # More background: https://bugs.gnucash.org/show_bug.cgi?id=726891
233  is_new = mode in (SessionOpenMode.SESSION_NEW_STORE, SessionOpenMode.SESSION_NEW_OVERWRITE)
234  scheme = urlparse(book_uri).scheme
235  if not (is_new and scheme == 'xml'):
236  self.load()
237  except GnuCashBackendException as backend_exception:
238  self.end()
239  self.destroy()
240  raise
241 
242  def __enter__(self):
243  return self
244 
245  def __exit__(self, exc_type, exc_value, traceback):
246  # Roll back changes on exception by not calling save. Only works for XMl backend.
247  if not exc_type:
248  self.save()
249  self.end()
250 
251  def raise_backend_errors(self, called_function="qof_session function"):
252  """Raises a GnuCashBackendException if there are outstanding
253  QOF_BACKEND errors.
254 
255  set called_function to name the function that was last called
256  """
257  errors = self.pop_all_errors()
258  if errors != ():
260  "call to %s resulted in the "
261  "following errors, %s" % (called_function, backend_error_dict[errors[0]]),
262  errors )
263 
264  def generate_errors(self):
265  """A generator that yields any outstanding QofBackend errors
266  """
267  while self.get_error() is not ERR_BACKEND_NO_ERR:
268  error = self.pop_error()
269  yield error
270 
271  def pop_all_errors(self):
272  """Returns any accumulated qof backend errors as a tuple
273  """
274  return tuple( self.generate_errors() )
275 
276  # STATIC METHODS
277  @staticmethod
278  def raise_backend_errors_after_call(function, *args, **kwargs):
279  """A function decorator that results in a call to
280  raise_backend_errors after execution.
281  """
282  def new_function(self, *args, **kwargs):
283  return_value = function(self, *args, **kwargs)
284  self.raise_backend_errors(function.__name__)
285  return return_value
286  return new_function
287 
289  """A Book encapsulates all of the GnuCash data, it is the place where
290  all GnuCash entities (Transaction, Split, Vendor, Invoice...), are
291  stored. You'll notice that all of the constructors for those entities
292  need a book to be associated with.
293 
294  The most common way to get a book is through the book property in the
295  Session class, that is, create a session that connects to some storage,
296  such as through 'my_session = Session('file:my_books.xac')', and access
297  the book via the book property, 'my_session.book'
298 
299  If you would like to create a Book without any backing storage, call the
300  Book constructor without any parameters, 'Book()'. You can later merge
301  such a book into a book with actual store by using merge_init.
302 
303  Methods of interest
304  get_root_account -- Returns the root level Account
305  get_table -- Returns a commodity lookup table, of type GncCommodityTable
306  """
307  def InvoiceLookup(self, guid):
308  from gnucash.gnucash_business import Invoice
309  return self.do_lookup_create_oo_instance(
310  gncInvoiceLookup, Invoice, guid.get_instance() )
311 
312  def EntryLookup(self, guid):
313  from gnucash.gnucash_business import Entry
314  return self.do_lookup_create_oo_instance(
315  gncEntryLookup, Entry, guid.get_instance() )
316 
317  def CustomerLookup(self, guid):
318  from gnucash.gnucash_business import Customer
319  return self.do_lookup_create_oo_instance(
320  gncCustomerLookup, Customer, guid.get_instance())
321 
322  def JobLookup(self, guid):
323  from gnucash.gnucash_business import Job
324  return self.do_lookup_create_oo_instance(
325  gncJobLookup, Job, guid.get_instance() )
326 
327  def VendorLookup(self, guid):
328  from gnucash.gnucash_business import Vendor
329  return self.do_lookup_create_oo_instance(
330  gncVendorLookup, Vendor, guid.get_instance() )
331 
332  def EmployeeLookup(self, guid):
333  from gnucash.gnucash_business import Employee
334  return self.do_lookup_create_oo_instance(
335  gncEmployeeLookup, Employee, guid.get_instance() )
336 
337  def TaxTableLookup(self, guid):
338  from gnucash.gnucash_business import TaxTable
339  return self.do_lookup_create_oo_instance(
340  gncTaxTableLookup, TaxTable, guid.get_instance() )
341 
342  def TaxTableLookupByName(self, name):
343  from gnucash.gnucash_business import TaxTable
344  return self.do_lookup_create_oo_instance(
345  gncTaxTableLookupByName, TaxTable, name)
346 
347  def TaxTableGetTables(self):
348  from gnucash.gnucash_business import TaxTable
349  return [ TaxTable(instance=item) for item in gncTaxTableGetTables(self.instance) ]
350 
351  def BillLookupByID(self, id):
352  from gnucash.gnucash_business import Bill
353  return self.do_lookup_create_oo_instance(
354  gnc_search_bill_on_id, Bill, id)
355 
356  def InvoiceLookupByID(self, id):
357  from gnucash.gnucash_business import Invoice
358  return self.do_lookup_create_oo_instance(
359  gnc_search_invoice_on_id, Invoice, id)
360 
361  def CustomerLookupByID(self, id):
362  from gnucash.gnucash_business import Customer
363  return self.do_lookup_create_oo_instance(
364  gnc_search_customer_on_id, Customer, id)
365 
366  def VendorLookupByID(self, id):
367  from gnucash.gnucash_business import Vendor
368  return self.do_lookup_create_oo_instance(
369  gnc_search_vendor_on_id, Vendor, id)
370 
371  def InvoiceNextID(self, customer):
372  ''' Return the next invoice ID.
373  '''
374  from gnucash.gnucash_core_c import gncInvoiceNextID
375  return gncInvoiceNextID(self.get_instance(),customer.GetEndOwner().get_instance()[1])
376 
377  def BillNextID(self, vendor):
378  ''' Return the next Bill ID. '''
379  from gnucash.gnucash_core_c import gncInvoiceNextID
380  return gncInvoiceNextID(self.get_instance(),vendor.GetEndOwner().get_instance()[1])
381 
382  def CustomerNextID(self):
383  ''' Return the next Customer ID. '''
384  from gnucash.gnucash_core_c import gncCustomerNextID
385  return gncCustomerNextID(self.get_instance())
386 
387  def VendorNextID(self):
388  ''' Return the next Vendor ID. '''
389  from gnucash.gnucash_core_c import gncVendorNextID
390  return gncVendorNextID(self.get_instance())
391 
393  """Object used by GnuCash to store all numbers. Always consists of a
394  numerator and denominator.
395 
396  The constants GNC_DENOM_AUTO,
397  GNC_HOW_RND_FLOOR, GNC_HOW_RND_CEIL, GNC_HOW_RND_TRUNC,
398  GNC_HOW_RND_PROMOTE, GNC_HOW_RND_ROUND_HALF_DOWN,
399  GNC_HOW_RND_ROUND_HALF_UP, GNC_HOW_RND_ROUND, GNC_HOW_RND_NEVER,
400  GNC_HOW_DENOM_EXACT, GNC_HOW_DENOM_REDUCE, GNC_HOW_DENOM_LCD,
401  and GNC_HOW_DENOM_FIXED are available for arithmetic
402  functions like GncNumeric.add
403 
404  Look at gnc-numeric.h to see how to use these
405  """
406 
407  def __init__(self, *args, **kargs):
408  """Constructor that supports the following formats:
409  * No arguments defaulting to zero: eg. GncNumeric() == 0/1
410  * A integer: e.g. GncNumeric(1) == 1/1
411  * Numerator and denominator intager pair: eg. GncNumeric(1, 2) == 1/2
412  * A floating point number: e.g. GncNumeric(0.5) == 1/2
413  * A floating point number with defined conversion: e.g.
414  GncNumeric(0.5, GNC_DENOM_AUTO,
415  GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER) == 1/2
416  * A string: e.g. GncNumeric("1/2") == 1/2
417  """
418  if 'instance' not in kargs:
419  kargs['instance'] = GncNumeric.__args_to_instance(args)
420  GnuCashCoreClass.__init__(self, [], **kargs)
421 
422  @staticmethod
423  def __args_to_instance(args):
424  if len(args) == 0:
425  return gnc_numeric_zero()
426  elif len(args) == 1:
427  arg = args[0]
428  if isinstance(arg, int):
429  return gnc_numeric_create(arg ,1)
430  elif isinstance(arg, float):
431  return double_to_gnc_numeric(arg, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER)
432  elif isinstance(arg, str):
433  instance = gnc_numeric_zero()
434  if not string_to_gnc_numeric(arg, instance):
435  raise TypeError('Failed to convert to GncNumeric: ' + str(args))
436  return instance
437  else:
438  raise TypeError('Only single int/float/str allowed: ' + str(args))
439  elif len(args) == 2:
440  if isinstance(args[0], int) and isinstance(args[1], int):
441  return gnc_numeric_create(*args)
442  else:
443  raise TypeError('Only two ints allowed: ' + str(args))
444  elif len(args) == 3:
445  if isinstance(args[0], float) \
446  and isinstance(args[1], int) \
447  and type(args[2]) == type(GNC_HOW_DENOM_FIXED):
448  return double_to_gnc_numeric(*args)
449  else:
450  raise TypeError('Only (float, int, GNC_HOW_RND_*) allowed: ' + str(args))
451  else:
452  raise TypeError('Required single int/float/str or two ints: ' + str(args))
453 
454  def to_fraction(self):
455  from fractions import Fraction
456  return Fraction(self.num(), self.denom())
457 
458  def __str__(self):
459  """Returns a human readable numeric value string as UTF8."""
460  return gnc_numeric_to_string(self.instance)
461 
463  '''
464  Each priceEach price in the database represents an "instantaneous"
465  quote for a given commodity with respect to another commodity.
466  For example, a given price might represent the value of LNUX in USD on 2001-02-03.
467 
468  Fields:
469  * commodity: the item being priced.
470  * currency: the denomination of the value of the item being priced.
471  * value: the value of the item being priced.
472  * time: the time the price was valid.
473  * source: a string describing the source of the quote. These strings will be something like this:
474  "Finance::Quote", "user:misc", "user:foo", etc. If the quote came from a user, as a matter of policy,
475  you *must* prefix the string you give with "user:". For now, the only other reserved values are
476  "Finance::Quote" and "old-file-import". Any string used must be added to the source_list array in
477  dialog-price-edit-db.c so that it can be properly translated. (There are unfortunately many strings
478  in users' databases, so this string must be translated on output instead of always being used in untranslated form).
479  * type: the type of quote - types possible right now are bid, ask, last, nav, and
480  unknown.Each price in the database represents an "instantaneous" quote for a given
481  commodity with respect to another commodity.
482  For example, a given price might represent the value of LNUX in USD on 2001-02-03.
483 
484  See also https://code.gnucash.org/docs/head/group__Price.html
485  '''
486  _new_instance = 'gnc_price_create'
487 GncPrice.add_methods_with_prefix('gnc_price_')
488 
489 
491  '''
492  a simple price database for gnucash.
493  The PriceDB is intended to be a database of price quotes, or more specifically,
494  a database of GNCPrices. For the time being, it is still a fairly simple
495  database supporting only fairly simple queries. It is expected that new
496  queries will be added as needed, and that there is some advantage to delaying
497  complex queries for now in the hope that we get a real DB implementation
498  before they're really needed.
499 
500  Every QofBook contains a GNCPriceDB, accessible via gnc_pricedb_get_db.
501 
502  Definition in file gnc-pricedb.h.
503  See also https://code.gnucash.org/docs/head/gnc-pricedb_8h.html
504  '''
505 
506 @deprecated("Use gnc_pricedb_latest_before_t64")
507 def gnc_pricedb_lookup_latest_before_t64(self, commodity, currency, date):
508  return self.lookup_nearest_before_t64(commodity, currency, date)
509 
510 GncPriceDB.add_method('gnc_pricedb_lookup_latest_before_t64', 'lookup_latest_before_t64')
511 
512 GncPriceDB.lookup_latest_before_t64 = method_function_returns_instance(GncPriceDB.lookup_latest_before_t64, GncPrice)
513 
514 GncPriceDB.add_methods_with_prefix('gnc_pricedb_')
515 PriceDB_dict = {
516  'lookup_latest' : GncPrice,
517  'lookup_nearest_in_time64' : GncPrice,
518  'lookup_nearest_before_t64' : GncPrice,
519  'convert_balance_latest_price' : GncNumeric,
520  'convert_balance_nearest_price_t64' : GncNumeric,
521  }
522 methods_return_instance(GncPriceDB,PriceDB_dict)
523 GncPriceDB.get_prices = method_function_returns_instance_list(
524  GncPriceDB.get_prices, GncPrice )
525 
527 
529  """A CommodityTable provides a way to store and lookup commodities.
530  Commodities are primarily currencies, but other tradable things such as
531  stocks, mutual funds, and material substances are possible.
532 
533  Users of this library should not create their own CommodityTable, instead
534  the get_table method from the Book class should be used.
535 
536  This table is automatically populated with the GnuCash default commodity's
537  which includes most of the world's currencies.
538  """
539 
540  def _get_namespaces_py(self):
541  return [ns.get_name() for ns in self.get_namespaces_list()]
542 
544  pass
545 
546 class GncLot(GnuCashCoreClass):
547  def GetInvoiceFromLot(self):
548  from gnucash.gnucash_business import Invoice
549  return self.do_lookup_create_oo_instance(
550  gncInvoiceGetInvoiceFromLot, Invoice )
551 
553  """A GnuCash Transaction
554 
555  Consists of at least one (generally two) splits to represent a transaction
556  between two accounts.
557 
558 
559  Has a GetImbalance() method that returns a list of all the imbalanced
560  currencies. Each list item is a two element tuple, the first element is
561  the imbalanced commodity, the second element is the value.
562 
563  Warning, the commodity.get_instance() value can be None when there
564  is no currency set for the transaction.
565  """
566  _new_instance = 'xaccMallocTransaction'
567  def GetNthSplit(self, n):
568  return self.GetSplitList().pop(n)
569 
570  def GetInvoiceFromTxn(self):
571  from gnucash.gnucash_business import Transaction
572  return self.do_lookup_create_oo_instance(
573  gncInvoiceGetInvoiceFromTxn, Transaction )
574 
575  def __eq__(self, other):
576  return self.Equal(other, True, False, False, False)
577 
578 def decorate_monetary_list_returning_function(orig_function):
579  def new_function(self, *args):
580  """decorate function that returns list of gnc_monetary to return tuples of GncCommodity and GncNumeric
581 
582  Args:
583  *args: Variable length argument list. Will get passed to orig_function
584 
585  Returns:
586  array of tuples: (GncCommodity, GncNumeric)
587 
588  ToDo:
589  Maybe this function should better reside in module function_class (?)"""
590  # warning, item.commodity has been shown to be None
591  # when the transaction doesn't have a currency
592  return [(GncCommodity(instance=item.commodity),
593  GncNumeric(instance=item.value))
594  for item in orig_function(self, *args) ]
595  return new_function
596 
598  """A GnuCash Split
599 
600  The most basic representation of a movement of currency from one account to
601  another.
602  """
603  _new_instance = 'xaccMallocSplit'
604 
605  def __eq__(self, other):
606  return self.Equal(other, True, False, False)
607 
609  """A GnuCash Account.
610 
611  A fundamental entity in accounting, an Account provides representation
612  for a financial object, such as a ACCT_TYPE_BANK account, an
613  ACCT_TYPE_ASSET (like a building),
614  a ACCT_TYPE_LIABILITY (such as a bank loan), a summary of some type of
615  ACCT_TYPE_EXPENSE, or a summary of some source of ACCT_TYPE_INCOME .
616 
617  The words in upper case are the constants that GnuCash and this library uses
618  to describe account type. Here is the full list:
619  ACCT_TYPE_ASSET, ACCT_TYPE_BANK, ACCT_TYPE_CASH, ACCT_TYPE_CHECKING, \
620  ACCT_TYPE_CREDIT, ACCT_TYPE_EQUITY, ACCT_TYPE_EXPENSE, ACCT_TYPE_INCOME, \
621  ACCT_TYPE_LIABILITY, ACCT_TYPE_MUTUAL, ACCT_TYPE_PAYABLE, \
622  ACCT_TYPE_RECEIVABLE, ACCT_TYPE_STOCK, ACCT_TYPE_ROOT, ACCT_TYPE_TRADING
623 
624  These are not strings, they are attributes you can import from this
625  module
626  """
627  _new_instance = 'xaccMallocAccount'
628 
630  _new_instance = 'guid_new_return'
631 
632 # Session
633 Session.add_constructor_and_methods_with_prefix('qof_session_', 'new')
634 
635 def one_arg_default_none(function):
636  return default_arguments_decorator(function, None, None)
637 Session.decorate_functions(one_arg_default_none, "load", "save")
638 
639 Session.decorate_functions( Session.raise_backend_errors_after_call,
640  "begin", "load", "save", "end")
641 Session.decorate_method(default_arguments_decorator, "begin", None, mode=SessionOpenMode.SESSION_NORMAL_OPEN)
642 Session.decorate_functions(deprecated_args_session_begin, "begin")
643 
644 Session.get_book = method_function_returns_instance(
645  Session.get_book, Book )
646 
647 Session.book = property( Session.get_book )
648 
649 # import all of the session backend error codes into this module
650 this_module_dict = globals()
651 for error_name, error_value, error_name_after_prefix in \
652  extract_attributes_with_prefix(gnucash_core_c, 'ERR_'):
653  this_module_dict[ error_name ] = error_value
654 
655 #backend error codes used for reverse lookup
656 backend_error_dict = {}
657 for error_name, error_value, error_name_after_prefix in \
658  extract_attributes_with_prefix(gnucash_core_c, 'ERR_'):
659  backend_error_dict[ error_value ] = error_name
660 
661 # GncNumeric denominator computation schemes
662 # Used for the denom argument in arithmetic functions like GncNumeric.add
663 from gnucash.gnucash_core_c import GNC_DENOM_AUTO
664 
665 # GncNumeric rounding instructions
666 # used for the how argument in arithmetic functions like GncNumeric.add
667 from gnucash.gnucash_core_c import \
668  GNC_HOW_RND_FLOOR, GNC_HOW_RND_CEIL, GNC_HOW_RND_TRUNC, \
669  GNC_HOW_RND_PROMOTE, GNC_HOW_RND_ROUND_HALF_DOWN, \
670  GNC_HOW_RND_ROUND_HALF_UP, GNC_HOW_RND_ROUND, GNC_HOW_RND_NEVER
671 
672 # GncNumeric denominator types
673 # used for the how argument in arithmetic functions like GncNumeric.add
674 from gnucash.gnucash_core_c import \
675  GNC_HOW_DENOM_EXACT, GNC_HOW_DENOM_REDUCE, GNC_HOW_DENOM_LCD, \
676  GNC_HOW_DENOM_FIXED
677 
678 # import account types
679 from gnucash.gnucash_core_c import \
680  ACCT_TYPE_ASSET, ACCT_TYPE_BANK, ACCT_TYPE_CASH, ACCT_TYPE_CHECKING, \
681  ACCT_TYPE_CREDIT, ACCT_TYPE_EQUITY, ACCT_TYPE_EXPENSE, ACCT_TYPE_INCOME, \
682  ACCT_TYPE_LIABILITY, ACCT_TYPE_MUTUAL, ACCT_TYPE_PAYABLE, \
683  ACCT_TYPE_RECEIVABLE, ACCT_TYPE_STOCK, ACCT_TYPE_ROOT, ACCT_TYPE_TRADING
684 
685 #Book
686 Book.add_constructor_and_methods_with_prefix('qof_book_', 'new')
687 Book.add_method('gnc_book_get_root_account', 'get_root_account')
688 Book.add_method('gnc_book_set_root_account', 'set_root_account')
689 Book.add_method('gnc_commodity_table_get_table', 'get_table')
690 Book.add_method('gnc_pricedb_get_db', 'get_price_db')
691 Book.add_method('qof_book_increment_and_format_counter', 'increment_and_format_counter')
692 
693 #Functions that return Account
694 Book.get_root_account = method_function_returns_instance(
695  Book.get_root_account, Account )
696 #Functions that return GncCommodityTable
697 Book.get_table = method_function_returns_instance(
698  Book.get_table, GncCommodityTable )
699 #Functions that return GNCPriceDB
700 Book.get_price_db = method_function_returns_instance(
701  Book.get_price_db, GncPriceDB)
702 
703 # GncNumeric
704 GncNumeric.add_constructor_and_methods_with_prefix('gnc_numeric_', 'create')
705 
706 gncnumeric_dict = {
707  'same' : GncNumeric,
708  'add' : GncNumeric,
709  'sub' : GncNumeric,
710  'mul' : GncNumeric,
711  'div' : GncNumeric,
712  'neg' : GncNumeric,
713  'abs' : GncNumeric,
714  'add_fixed' : GncNumeric,
715  'sub_fixed' : GncNumeric,
716  'convert' : GncNumeric,
717  'reduce' : GncNumeric
718  }
719 methods_return_instance(GncNumeric, gncnumeric_dict)
720 
721 # GncCommodity
722 GncCommodity.add_constructor_and_methods_with_prefix('gnc_commodity_', 'new')
723 #Functions that return GncCommodity
724 GncCommodity.clone = method_function_returns_instance(
725  GncCommodity.clone, GncCommodity )
726 
727 # GncCommodityTable
728 GncCommodityTable.add_methods_with_prefix('gnc_commodity_table_')
729 commoditytable_dict = {
730  'lookup' : GncCommodity,
731  'lookup_unique' : GncCommodity,
732  'find_full' : GncCommodity,
733  'insert' : GncCommodity,
734  'add_namespace': GncCommodityNamespace,
735  'find_namespace': GncCommodityNamespace,
736  }
737 methods_return_instance(GncCommodityTable, commoditytable_dict)
738 
739 methods_return_instance_lists(
740  GncCommodityTable, { 'get_namespaces_list': GncCommodityNamespace,
741  'get_commodities': GncCommodity,
742  'get_quotable_commodities': GncCommodity,
743 
744  } )
745 setattr(GncCommodityTable, 'get_namespaces', getattr(GncCommodityTable, '_get_namespaces_py'))
746 
747 # GncCommodityNamespace
748 GncCommodityNamespace.add_methods_with_prefix('gnc_commodity_namespace_')
749 GncCommodityNamespace.get_commodity_list = \
750  method_function_returns_instance_list(
751  GncCommodityNamespace.get_commodity_list, GncCommodity )
752 
753 # GncLot
754 GncLot.add_constructor_and_methods_with_prefix('gnc_lot_', 'new')
755 
756 gnclot_dict = {
757  'get_account' : Account,
758  'get_book' : Book,
759  'get_earliest_split' : Split,
760  'get_latest_split' : Split,
761  'get_balance' : GncNumeric,
762  'lookup' : GncLot,
763  'make_default' : GncLot
764  }
765 methods_return_instance(GncLot, gnclot_dict)
766 
767 # Transaction
768 Transaction.add_methods_with_prefix('xaccTrans')
769 Transaction.add_method('gncTransGetGUID', 'GetGUID')
770 
771 Transaction.add_method('xaccTransGetDescription', 'GetDescription')
772 Transaction.add_method('xaccTransDestroy', 'Destroy')
773 
774 trans_dict = {
775  'GetSplit': Split,
776  'FindSplitByAccount': Split,
777  'Clone': Transaction,
778  'Reverse': Transaction,
779  'GetReversedBy': Transaction,
780  'GetImbalanceValue': GncNumeric,
781  'GetAccountValue': GncNumeric,
782  'GetAccountAmount': GncNumeric,
783  'GetAccountConvRate': GncNumeric,
784  'GetAccountBalance': GncNumeric,
785  'GetCurrency': GncCommodity,
786  'GetGUID': GUID
787  }
788 
789 methods_return_instance(Transaction, trans_dict)
790 methods_return_instance_lists(
791  Transaction, { 'GetSplitList': Split,
792  })
793 Transaction.decorate_functions(
794  decorate_monetary_list_returning_function, 'GetImbalance')
795 
796 # Split
797 Split.add_methods_with_prefix('xaccSplit')
798 Split.add_method('gncSplitGetGUID', 'GetGUID')
799 Split.add_method('xaccSplitDestroy', 'Destroy')
800 
801 split_dict = {
802  'GetBook': Book,
803  'GetAccount': Account,
804  'GetParent': Transaction,
805  'Lookup': Split,
806  'GetOtherSplit': Split,
807  'GetAmount': GncNumeric,
808  'GetValue': GncNumeric,
809  'GetSharePrice': GncNumeric,
810  'ConvertAmount': GncNumeric,
811  'GetBaseValue': GncNumeric,
812  'GetBalance': GncNumeric,
813  'GetClearedBalance': GncNumeric,
814  'GetReconciledBalance': GncNumeric,
815  'VoidFormerAmount': GncNumeric,
816  'VoidFormerValue': GncNumeric,
817  'GetGUID': GUID
818  }
819 methods_return_instance(Split, split_dict)
820 
821 Split.account = property( Split.GetAccount, Split.SetAccount )
822 Split.parent = property( Split.GetParent, Split.SetParent )
823 
824 # Account
825 Account.add_methods_with_prefix('xaccAccount')
826 Account.add_methods_with_prefix('gnc_account_')
827 Account.add_method('gncAccountGetGUID', 'GetGUID')
828 Account.add_method('xaccAccountGetPlaceholder', 'GetPlaceholder')
829 
830 account_dict = {
831  'get_book' : Book,
832  'Lookup' : Account,
833  'get_parent' : Account,
834  'get_root' : Account,
835  'nth_child' : Account,
836  'lookup_by_code' : Account,
837  'lookup_by_name' : Account,
838  'lookup_by_full_name' : Account,
839  'FindTransByDesc' : Transaction,
840  'FindSplitByDesc' : Split,
841  'GetBalance' : GncNumeric,
842  'GetClearedBalance' : GncNumeric,
843  'GetReconciledBalance' : GncNumeric,
844  'GetPresentBalance' : GncNumeric,
845  'GetProjectedMinimumBalance' : GncNumeric,
846  'GetBalanceAsOfDate' : GncNumeric,
847  'ConvertBalanceToCurrency' : GncNumeric,
848  'ConvertBalanceToCurrencyAsOfDate' : GncNumeric,
849  'GetBalanceInCurrency' : GncNumeric,
850  'GetClearedBalanceInCurrency' : GncNumeric,
851  'GetReconciledBalanceInCurrency' : GncNumeric,
852  'GetPresentBalanceInCurrency' : GncNumeric,
853  'GetProjectedMinimumBalanceInCurrency' : GncNumeric,
854  'GetBalanceAsOfDateInCurrency' : GncNumeric,
855  'GetBalanceChangeForPeriod' : GncNumeric,
856  'GetCommodity' : GncCommodity,
857  'GetGUID': GUID
858  }
859 methods_return_instance(Account, account_dict)
860 methods_return_instance_lists(
861  Account, { 'GetSplitList': Split,
862  'get_children': Account,
863  'get_children_sorted': Account,
864  'get_descendants': Account,
865  'get_descendants_sorted': Account
866  })
867 Account.name = property( Account.GetName, Account.SetName )
868 
869 #GUID
870 GUID.add_methods_with_prefix('guid_')
871 GUID.add_method('xaccAccountLookup', 'AccountLookup')
872 GUID.add_method('xaccTransLookup', 'TransLookup')
873 GUID.add_method('xaccSplitLookup', 'SplitLookup')
874 
875 
876 GUID.add_method('guid_to_string', 'to_string')
877 #GUID.add_method('string_to_guid', 'string_to_guid')
878 
879 guid_dict = {
880  'copy' : GUID,
881  'TransLookup': Transaction,
882  'AccountLookup': Account,
883  'SplitLookup': Split
884  }
885 methods_return_instance(GUID, guid_dict)
886 
887 #GUIDString
889  pass
890 
891 GUIDString.add_constructor_and_methods_with_prefix('string_', 'to_guid')
892 
893 #Query
894 from gnucash.gnucash_core_c import \
895  QOF_QUERY_AND, \
896  QOF_QUERY_OR, \
897  QOF_QUERY_NAND, \
898  QOF_QUERY_NOR, \
899  QOF_QUERY_XOR
900 
901 from gnucash.gnucash_core_c import \
902  QOF_STRING_MATCH_NORMAL, \
903  QOF_STRING_MATCH_CASEINSENSITIVE
904 
905 from gnucash.gnucash_core_c import \
906  QOF_COMPARE_LT, \
907  QOF_COMPARE_LTE, \
908  QOF_COMPARE_EQUAL, \
909  QOF_COMPARE_GT, \
910  QOF_COMPARE_GTE, \
911  QOF_COMPARE_NEQ
912 
913 from gnucash.gnucash_core_c import \
914  INVOICE_TYPE
915 
916 from gnucash.gnucash_core_c import \
917  INVOICE_IS_PAID
918 
920 
921  def search_for(self, obj_type):
922  """Set search_for to obj_type
923 
924  calls qof_query_search_for. Buffers search string for queries lifetime.
925  @see https://bugs.gnucash.org/show_bug.cgi?id=796137"""
926  self.__search_for_buf = obj_type
927  self._search_for(self.__search_for_buf)
928 
929 Query.add_constructor_and_methods_with_prefix('qof_query_', 'create', exclude=["qof_query_search_for"])
930 
931 Query.add_method('qof_query_set_book', 'set_book')
932 Query.add_method('qof_query_search_for', '_search_for')
933 Query.add_method('qof_query_run', 'run')
934 Query.add_method('qof_query_add_term', 'add_term')
935 Query.add_method('qof_query_add_boolean_match', 'add_boolean_match')
936 Query.add_method('qof_query_add_guid_list_match', 'add_guid_list_match')
937 Query.add_method('qof_query_add_guid_match', 'add_guid_match')
938 Query.add_method('qof_query_destroy', 'destroy')
939 
941  pass
942 
943 QueryStringPredicate.add_constructor_and_methods_with_prefix(
944  'qof_query_','string_predicate')
945 
947  pass
948 
949 QueryBooleanPredicate.add_constructor_and_methods_with_prefix(
950  'qof_query_', 'boolean_predicate')
951 
953  pass
954 
955 QueryInt32Predicate.add_constructor_and_methods_with_prefix(
956  'qof_query_', 'int32_predicate')
957 
959  pass
960 
961 QueryDatePredicate.add_constructor_and_methods_with_prefix(
962  'qof_query_', 'date_predicate', exclude=["qof_query_date_predicate_get_date"])
963 QueryDatePredicate.add_method('qof_query_date_predicate_get_date', 'get_date')
964 
966  pass
967 
968 QueryGuidPredicate.add_constructor_and_methods_with_prefix(
969  'qof_query_', 'guid_predicate')
gnc_numeric double_to_gnc_numeric(double in, gint64 denom, gint how)
Convert a floating-point number to a gnc_numeric.
def search_for(self, obj_type)
def raise_backend_errors_after_call(function, args, kwargs)
gchar * gnc_numeric_to_string(gnc_numeric n)
Convert to string.
gboolean string_to_gnc_numeric(const gchar *str, gnc_numeric *n)
Read a gnc_numeric from str, skipping any leading whitespace.
def BillNextID(self, vendor)
def raise_backend_errors(self, called_function="qof_session function")
def do_lookup_create_oo_instance(self, lookup_function, cls, args)
Definition: gnucash_core.py:84
def InvoiceNextID(self, customer)
def __init__(self, args, kargs)
def __init__(self, book_uri=None, mode=None, instance=None, book=None)
A convenient constructor that allows you to specify a book URI, begin the session, and load the book.