gnucash stable: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Fri Jun 5 18:12:21 EDT 2026


Updated	 via  https://github.com/Gnucash/gnucash/commit/f3c053fb (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2d0a3850 (commit)
	from  https://github.com/Gnucash/gnucash/commit/7178a868 (commit)



commit f3c053fbee8c290d0fd111b125a4a52b03de862e
Merge: 7178a86859 2d0a3850ae
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Jun 5 15:04:32 2026 -0700

    Merge Peter Kim's 'bug-799767-rest-api-post-accounts' into stable.


commit 2d0a3850aebaf5738caed7648e5584ce8939cc78
Author: peter <peter at table74.com>
Date:   Mon May 25 14:40:50 2026 -0500

    Bug 799767 - POST /accounts route in rest-api example is broken
    
    addAccount was rewritten to accept (name, currency, account_type_id,
    parent_account_guid, description, code), validate each field, look up
    the parent by GUID, and return gnucash_simple.accountToDict(account).
    The route handler was updated to pull the form fields and call it with the
    new signature.
    
    README was updated to reflect these changes.

diff --git a/bindings/python/example_scripts/rest-api/README b/bindings/python/example_scripts/rest-api/README
index 393035f96d..21127f8ee3 100644
--- a/bindings/python/example_scripts/rest-api/README
+++ b/bindings/python/example_scripts/rest-api/README
@@ -19,6 +19,19 @@ GET request to /accounts/<guid> - returns an individual account
 GET request to /accounts/<guid>/splits - returns splits for an individual
 account
 
+POST request to /accounts - creates a new account
+
+POST variables:
+name - required - the name of the account
+currency - required - a gnucash currency code e.g. GBP
+account_type_id - required - the numeric account type id (e.g. 0 for BANK,
+2 for ASSET, 8 for INCOME, 9 for EXPENSE - see ACCT_TYPE_* in
+libgnucash/engine/Account.h)
+parent_account_guid - required - the GUID of the parent account (the root
+account's GUID can be obtained from /accounts)
+description - optional - a description for the account
+code - optional - an account code
+
 POST request to /transactions - creates a new transaction (currently with only
 two splits)
 
diff --git a/bindings/python/example_scripts/rest-api/gnucash_rest.py b/bindings/python/example_scripts/rest-api/gnucash_rest.py
index f28c0e8315..274a2fa3c6 100644
--- a/bindings/python/example_scripts/rest-api/gnucash_rest.py
+++ b/bindings/python/example_scripts/rest-api/gnucash_rest.py
@@ -87,8 +87,16 @@ def api_accounts():
 
     elif request.method == 'POST':
 
+        name = str(request.form.get('name', ''))
+        currency = str(request.form.get('currency', ''))
+        account_type_id = request.form.get('account_type_id', '')
+        parent_account_guid = str(request.form.get('parent_account_guid', ''))
+        description = str(request.form.get('description', ''))
+        code = str(request.form.get('code', ''))
+
         try:
-            account = addAccount(session.books)
+            account = addAccount(session.book, name, currency,
+                account_type_id, parent_account_guid, description, code)
         except Error as error:
             return Response(json.dumps({'errors': [{'type' : error.type,
                 'message': error.message, 'data': error.data}]}), status=400,
@@ -1664,28 +1672,67 @@ def addBill(book, id, vendor_id, currency_mnumonic, date_opened, notes):
 
     return gnucash_simple.billToDict(bill)
 
-def addAccount(book, name, currency_mnumonic, account_guid):
+def addAccount(book, name, currency_mnumonic, account_type_id,
+    parent_account_guid, description, code):
 
-    from gnucash.gnucash_core_c import \
-    ACCT_TYPE_ASSET, ACCT_TYPE_RECEIVABLE, ACCT_TYPE_INCOME, \
-    GNC_OWNER_CUSTOMER, ACCT_TYPE_LIABILITY
+    from gnucash.gnucash_core_c import ACCT_TYPE_ROOT, ACCT_TYPE_TRADING
 
-    root_account = book.get_root_account()
+    if name == '':
+        raise Error('NoAccountName',
+            'A name must be entered for this account',
+            {'field': 'name'})
+
+    try:
+        account_type_id = int(account_type_id)
+    except (TypeError, ValueError):
+        raise Error('InvalidAccountTypeID',
+            'A valid account type id must be supplied for this account',
+            {'field': 'account_type_id'})
+
+    # account types above TRADING (CHECKING, SAVINGS, MONEYMRKT, CREDITLINE)
+    # are aliases that the engine refuses to set - see Account.h
+    if (account_type_id < 0 or account_type_id > ACCT_TYPE_TRADING
+            or account_type_id == ACCT_TYPE_ROOT):
+        raise Error('InvalidAccountTypeID',
+            'A valid account type id must be supplied for this account',
+            {'field': 'account_type_id'})
 
     commod_table = book.get_table()
     currency = commod_table.lookup('CURRENCY', currency_mnumonic)
 
     if currency is None:
-        raise Error('InvalidCustomerCurrency',
-            'A valid currency must be supplied for this customer',
+        raise Error('InvalidAccountCurrency',
+            'A valid currency must be supplied for this account',
             {'field': 'currency'})
 
+    if parent_account_guid == '':
+        raise Error('NoParentAccount',
+            'A parent account guid must be supplied for this account',
+            {'field': 'parent_account_guid'})
+
+    guid = gnucash.gnucash_core.GUID()
+    gnucash.gnucash_core.GUIDString(parent_account_guid, guid)
+    parent_account = guid.AccountLookup(book)
+
+    if parent_account is None:
+        raise Error('InvalidParentAccount',
+            'A parent account with this guid does not exist',
+            {'field': 'parent_account_guid'})
+
     account = Account(book)
-    root_account.append_child(root_account)
+    parent_account.append_child(account)
     account.SetName(name)
-    account.SetType(ACCT_TYPE_ASSET)
+    account.SetType(account_type_id)
     account.SetCommodity(currency)
 
+    if description != '':
+        account.SetDescription(description)
+
+    if code != '':
+        account.SetCode(code)
+
+    return gnucash_simple.accountToDict(account)
+
 def addTransaction(book, num, description, date_posted, currency_mnumonic, splits):
 
     transaction = Transaction(book)



Summary of changes:
 bindings/python/example_scripts/rest-api/README    | 13 +++++
 .../example_scripts/rest-api/gnucash_rest.py       | 67 ++++++++++++++++++----
 2 files changed, 70 insertions(+), 10 deletions(-)



More information about the gnucash-changes mailing list