summary history files

commit:fa76ffccfc60eded84869c92e5df9522782534b0
date:Mon Feb 16 20:41:20 2026 +1100
parents:1677d1db09db45ac7cfe15b10170cf903dc033da, 01ad3f1da1ac995b6222789cdc3eded8834f25b0
Merge pull request #5 from rene00/transaction-multiple-accounts

Transaction multiple accounts
diff --git a/internal/cli/account.go b/internal/cli/account.go
line changes: +4/-4
index 5315ae4..106bd40
--- a/internal/cli/account.go
+++ b/internal/cli/account.go
@@ -58,7 +58,7 @@ using its GUID or full account name path.`,
 			account, err := s.Accounts.Get(cmd.Context(), guidOrAccountName)
 			if err != nil {
 				if errors.Is(err, sql.ErrNoRows) {
-					account, err = s.Accounts.Get(cmd.Context(), guidOrAccountName, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
+					account, err = s.Accounts.Get(cmd.Context(), guidOrAccountName, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
 					if err != nil {
 						return accountError(err)
 					}
@@ -72,7 +72,7 @@ using its GUID or full account name path.`,
 				parentAccount, err = s.Accounts.Get(cmd.Context(), guidOrAccountName)
 				if err != nil {
 					if errors.Is(err, sql.ErrNoRows) {
-						account, err = s.Accounts.Get(cmd.Context(), guidOrAccountName, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
+						account, err = s.Accounts.Get(cmd.Context(), guidOrAccountName, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
 						if err != nil {
 							return accountError(err)
 						}
@@ -89,7 +89,7 @@ using its GUID or full account name path.`,
 				account.Name = flags.name
 				newFullName := account.FullName[:strings.LastIndex(account.FullName, ":")+1] + account.Name
 				exists := true
-				_, err := s.Accounts.Get(cmd.Context(), newFullName, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
+				_, err := s.Accounts.Get(cmd.Context(), newFullName, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
 				if err != nil {
 					if errors.Is(err, sql.ErrNoRows) {
 						exists = false
@@ -152,7 +152,7 @@ func getAccountCmd(cli *cli) *cobra.Command {
 			account, err := s.Accounts.Get(cmd.Context(), guidOrAccountName)
 			if err != nil {
 				if errors.Is(err, sql.ErrNoRows) {
-					account, err = s.Accounts.Get(cmd.Context(), guidOrAccountName, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
+					account, err = s.Accounts.Get(cmd.Context(), guidOrAccountName, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
 					if err != nil {
 						return accountError(err)
 					}

diff --git a/internal/cli/cli.go b/internal/cli/cli.go
line changes: +8/-6
index 52a6550..2097cd3
--- a/internal/cli/cli.go
+++ b/internal/cli/cli.go
@@ -12,18 +12,20 @@ import (
 )
 
 var (
-	ErrTransactionMissing   = errors.New("transaction guid missing")
-	ErrTransactionNotFound  = errors.New("transaction not found")
-	ErrAccountDoesNotExist  = errors.New("account does not exist")
-	ErrAccountMissingParent = errors.New("account missing parent")
-	ErrAccountMissing       = errors.New("account name or guid missing")
-	ErrAccountAlreadyExists = errors.New("account already exists")
+	ErrTransactionMissing            = errors.New("transaction guid missing")
+	ErrTransactionNotFound           = errors.New("transaction not found")
+	ErrAccountDoesNotExist           = errors.New("account does not exist")
+	ErrAccountMissingParent          = errors.New("account missing parent")
+	ErrAccountMissing                = errors.New("account name or guid missing")
+	ErrAccountAlreadyExists          = errors.New("account already exists")
+	ErrAccountSpecifiedMultiplyTimes = errors.New("account specified multiple times")
 )
 
 var (
 	FlagsUsageOutput           = "Output format (json, table)"
 	FlagsUsageIncludeTotals    = "Include account totals when rendering table"
 	FlagsUsageAccountShortName = "Output accounts short name"
+	FlagsUsageAccountDepth     = "Maximum account depth to include (0=unlimited, 1=this account only, 2+=include descendants)"
 )
 
 func accountError(err error) error {

diff --git a/internal/cli/transaction.go b/internal/cli/transaction.go
line changes: +105/-30
index a9e1314..ec69f5e
--- a/internal/cli/transaction.go
+++ b/internal/cli/transaction.go
@@ -47,7 +47,7 @@ func bulkUpdateTransactionCmd(cli *cli) *cobra.Command {
 				sourceAccount, err = txStore.Accounts.Get(cmd.Context(), flags.sourceAccount)
 				if err != nil {
 					if errors.Is(err, sql.ErrNoRows) {
-						sourceAccount, err = txStore.Accounts.Get(cmd.Context(), flags.sourceAccount, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
+						sourceAccount, err = txStore.Accounts.Get(cmd.Context(), flags.sourceAccount, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
 						if err != nil {
 							return accountError(err)
 						}
@@ -62,7 +62,7 @@ func bulkUpdateTransactionCmd(cli *cli) *cobra.Command {
 				destinationAccount, err = txStore.Accounts.Get(cmd.Context(), flags.destinationAccount)
 				if err != nil {
 					if errors.Is(err, sql.ErrNoRows) {
-						destinationAccount, err = txStore.Accounts.Get(cmd.Context(), flags.destinationAccount, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
+						destinationAccount, err = txStore.Accounts.Get(cmd.Context(), flags.destinationAccount, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
 						if err != nil {
 							return accountError(err)
 						}
@@ -150,7 +150,7 @@ func updateTransactionCmd(cli *cli) *cobra.Command {
 				sourceAccount, err = txStore.Accounts.Get(cmd.Context(), flags.sourceAccount)
 				if err != nil {
 					if errors.Is(err, sql.ErrNoRows) {
-						sourceAccount, err = txStore.Accounts.Get(cmd.Context(), flags.sourceAccount, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
+						sourceAccount, err = txStore.Accounts.Get(cmd.Context(), flags.sourceAccount, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
 						if err != nil {
 							return ErrAccountDoesNotExist
 						}
@@ -165,7 +165,7 @@ func updateTransactionCmd(cli *cli) *cobra.Command {
 				destinationAccount, err = txStore.Accounts.Get(cmd.Context(), flags.destinationAccount)
 				if err != nil {
 					if errors.Is(err, sql.ErrNoRows) {
-						destinationAccount, err = txStore.Accounts.Get(cmd.Context(), flags.destinationAccount, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
+						destinationAccount, err = txStore.Accounts.Get(cmd.Context(), flags.destinationAccount, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
 						if err != nil {
 							return ErrAccountDoesNotExist
 						}
@@ -205,7 +205,8 @@ func updateTransactionCmd(cli *cli) *cobra.Command {
 
 func listTransactionCmd(cli *cli) *cobra.Command {
 	var flags struct {
-		account         string
+		accounts        []string
+		accountDepth    int
 		limit           int
 		startPostDate   string
 		endPostDate     string
@@ -214,26 +215,72 @@ func listTransactionCmd(cli *cli) *cobra.Command {
 		orderByPostDate bool
 		orderDescending bool
 		includeTotals   bool
+		shortName       bool
 	}
 	var cmd = &cobra.Command{
-		Use: "list",
+		Use:   "list [flags]",
+		Short: "List transactions",
+		Example: `* List transactions:
+
+  gt transaction list
+
+* List all transactions by setting limit to 0:
+
+  gt transactions list --limit=0
+
+* List transactions and output in json:
+
+  gt transaction list --output json
+
+* List transactions for account guid:
+
+  gt transaction list --account 9b1d2bc513da4076b236aee6114b21a7
+
+* List transactions for account name:
+
+  gt transaction list --account expenses:dining:pizza
+
+* List transactions for multiple accounts:
+
+  gt transaction list --account expenses:dining --account expenses:takeaway
+
+* List transactions for account tree and exclude totals:
+
+  gt transaction list --account expenses:petrol --include-totals=false
+
+* List transactions with a date range:
+
+  gt transaction list --start-post-date 2025-01-01 --end-post-date 2025-03-31
+
+* List transactions within a date range and with a description that contains %Pizza:
+ 
+  gt transaction list --start-post-date 2024-01-01 --end-post-date 2024-12-31 --description-like "%Pizza"
+`,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			var err error
 			s := store.NewStore(cli.db)
 			transactionQuery := store.NewTransactionQuery()
 
-			var account *store.Account
-			if flags.account != "" {
-				account, err = s.Accounts.Get(cmd.Context(), flags.account)
-				if err != nil {
-					if errors.Is(err, sql.ErrNoRows) {
-						account, err = s.Accounts.Get(cmd.Context(), flags.account, []store.AccountsOptFunc{store.WithAccountTree(true)}...)
-						if err != nil {
+			var accounts []*store.Account
+			if len(flags.accounts) != 0 {
+				seen := make(map[string]struct{}, len(flags.accounts))
+				for _, i := range flags.accounts {
+					account, err := s.Accounts.Get(cmd.Context(), i)
+					if err != nil {
+						if errors.Is(err, sql.ErrNoRows) {
+							account, err = s.Accounts.Get(cmd.Context(), i, []store.AccountsOptFunc{store.WithAccountFullName(true)}...)
+							if err != nil {
+								return ErrAccountDoesNotExist
+							}
+						} else {
 							return ErrAccountDoesNotExist
 						}
-					} else {
-						return ErrAccountDoesNotExist
 					}
+					if _, exists := seen[account.GUID]; exists {
+						return ErrAccountSpecifiedMultiplyTimes
+					}
+					seen[account.GUID] = struct{}{}
+					accounts = append(accounts, account)
 				}
 			}
 
@@ -264,12 +311,31 @@ func listTransactionCmd(cli *cli) *cobra.Command {
 			}
 
 			var transactions []*store.Transaction
-			if account != nil {
+			if len(accounts) != 0 {
 				// NOTE(rene): If account is not nil, user is wanting to list
 				// transactions by account. To do this, we must find all splits with
 				// account_guid == account then return all transactions for found
 				// splits.
-				splits, err := s.Splits.All(cmd.Context(), store.NewSplitQuery().Where("account_guid=?", account.GUID))
+				var allAccounts []*store.Account
+
+				for _, account := range accounts {
+					allAccounts = append(allAccounts, account)
+					allAccounts = append(allAccounts, account.GetDescendants()...)
+				}
+
+				accountGUIDs := make([]string, len(allAccounts))
+				for i, account := range allAccounts {
+					accountGUIDs[i] = account.GUID
+				}
+
+				placeholders := make([]string, len(accountGUIDs))
+				args := make([]any, len(accountGUIDs))
+				for i, guid := range accountGUIDs {
+					placeholders[i] = "?"
+					args[i] = guid
+				}
+
+				splits, err := s.Splits.All(cmd.Context(), store.NewSplitQuery().Where(fmt.Sprintf("account_guid IN (%s)", strings.Join(placeholders, ",")), args...))
 				if err != nil {
 					return err
 				}
@@ -283,16 +349,20 @@ func listTransactionCmd(cli *cli) *cobra.Command {
 					}
 				}
 
-				placeholders := make([]string, len(txGUIDs))
-				args := make([]any, len(txGUIDs))
-				for i, guid := range txGUIDs {
-					placeholders[i] = "?"
-					args[i] = guid
-				}
+				if len(txGUIDs) == 0 {
+					transactions = []*store.Transaction{}
+				} else {
+					placeholders = make([]string, len(txGUIDs))
+					args = make([]any, len(txGUIDs))
+					for i, guid := range txGUIDs {
+						placeholders[i] = "?"
+						args[i] = guid
+					}
 
-				transactions, err = s.Transactions.All(cmd.Context(), transactionQuery.Copy().Where(fmt.Sprintf("guid IN (%s)", strings.Join(placeholders, ",")), args...))
-				if err != nil {
-					return err
+					transactions, err = s.Transactions.All(cmd.Context(), transactionQuery.Copy().Where(fmt.Sprintf("guid IN (%s)", strings.Join(placeholders, ",")), args...))
+					if err != nil {
+						return err
+					}
 				}
 			} else {
 				transactions, err = s.Transactions.All(cmd.Context(), transactionQuery)
@@ -306,13 +376,12 @@ func listTransactionCmd(cli *cli) *cobra.Command {
 				return err
 			}
 
-			renderOpts := []render.RendererOptsFunc{render.WithIncludeTotals(flags.includeTotals)}
+			renderOpts := []render.RendererOptsFunc{render.WithIncludeTotals(flags.includeTotals), render.WithAccountShortName(flags.shortName)}
 			return r.Render(cmd.OutOrStdout(), transactions, renderOpts...)
 		},
 	}
 
 	cmd.Flags().IntVar(&flags.limit, "limit", 50, "Limit")
-	cmd.Flags().StringVar(&flags.account, "account", "", "Account GUID")
 	cmd.Flags().StringVar(&flags.startPostDate, "start-post-date", "", "Start Post Date")
 	cmd.Flags().StringVar(&flags.endPostDate, "end-post-date", "", "Start Post Date")
 	cmd.Flags().BoolVar(&flags.orderByPostDate, "order-by-post-date", true, "Order by Post Date")
@@ -320,12 +389,16 @@ func listTransactionCmd(cli *cli) *cobra.Command {
 	cmd.Flags().StringVar(&flags.descriptionLike, "description-like", "", "Description like")
 	cmd.Flags().StringVar(&flags.output, "output", "table", FlagsUsageOutput)
 	cmd.Flags().BoolVar(&flags.includeTotals, "include-totals", true, FlagsUsageIncludeTotals)
+	cmd.Flags().BoolVar(&flags.shortName, "short-name", false, FlagsUsageAccountShortName)
+	cmd.Flags().StringArrayVar(&flags.accounts, "account", []string{}, "Filter by account GUID or account full name (can specify multiple times)")
 	return cmd
 }
 
 func getTransactionCmd(cli *cli) *cobra.Command {
 	var flags struct {
-		output string
+		output        string
+		shortName     bool
+		includeTotals bool
 	}
 	var cmd = &cobra.Command{
 		Use: "get",
@@ -346,9 +419,11 @@ func getTransactionCmd(cli *cli) *cobra.Command {
 				return err
 			}
 
-			return r.Render(cmd.OutOrStdout(), transaction)
+			renderOpts := []render.RendererOptsFunc{render.WithIncludeTotals(false), render.WithAccountShortName(flags.shortName)}
+			return r.Render(cmd.OutOrStdout(), transaction, renderOpts...)
 		},
 	}
 	cmd.Flags().StringVar(&flags.output, "output", "table", "Output format")
+	cmd.Flags().BoolVar(&flags.shortName, "short-name", false, FlagsUsageAccountShortName)
 	return cmd
 }

diff --git a/internal/render/render.go b/internal/render/render.go
line changes: +7/-2
index fcb3e28..fff3584
--- a/internal/render/render.go
+++ b/internal/render/render.go
@@ -124,10 +124,15 @@ func renderTransactions(table *tablewriter.Table, opts RendererOpts, transaction
 
 		for _, split := range transaction.Splits {
 			debit, credit := formatAmount(split.ValueNum, split.ValueDenom)
+			accountName := split.Account.FullName
+			if opts.accountShortName {
+				accountName = split.Account.Name
+			}
+
 			table.Append([]string{
 				"",
 				"",
-				split.Account.Name,
+				accountName,
 				debit,
 				credit,
 			})
@@ -135,7 +140,7 @@ func renderTransactions(table *tablewriter.Table, opts RendererOpts, transaction
 			accountGUID := split.AccountGUID
 			if _, exists := accountTotals[accountGUID]; !exists {
 				accountTotals[accountGUID] = &AccountTotal{
-					Name:       split.Account.Name,
+					Name:       accountName,
 					TotalNum:   0,
 					TotalDenom: split.ValueDenom,
 				}

diff --git a/internal/store/accounts.go b/internal/store/accounts.go
line changes: +150/-6
index 8ab4ae0..18d5fda
--- a/internal/store/accounts.go
+++ b/internal/store/accounts.go
@@ -21,6 +21,23 @@ type Account struct {
 	Description   *string
 	Hidden        *int64
 	Placeholder   *int64
+
+	Parent   *Account
+	Children []*Account
+	Level    int
+}
+
+func (a *Account) GetDescendants() []*Account {
+	var descendants []*Account
+	var traverse func(*Account)
+	traverse = func(account *Account) {
+		for _, child := range account.Children {
+			descendants = append(descendants, child)
+			traverse(child)
+		}
+	}
+	traverse(a)
+	return descendants
 }
 
 type AccountQuery struct {
@@ -127,25 +144,131 @@ type AccountsStore struct {
 	Opts AccountsOpts
 }
 
+// AccountsOpts configures account query and retrieval behavior.
 type AccountsOpts struct {
-	withAccountTree bool
+	// withAccountFullName indicates that the lookup string should be interpreted as
+	// a colon-separated full account name (e.g., "expenses:dining:pizza") rather than
+	// a GUID. When true, Get() traverses the account tree from the root to locate
+	// the account by its hierarchy path.
+	withAccountFullName bool
 }
 
 func defaultAccountsOpts() *AccountsOpts {
 	return &AccountsOpts{
-		withAccountTree: false,
+		withAccountFullName: false,
 	}
 }
 
 type AccountsOptFunc func(*AccountsOpts)
 
-func WithAccountTree(b bool) AccountsOptFunc {
+func WithAccountFullName(b bool) AccountsOptFunc {
 	return func(o *AccountsOpts) {
-		o.withAccountTree = b
+		o.withAccountFullName = b
 	}
 }
 
-// getFullAccountName takes a store.Account and attempts to return its full account name (e.g. expenses:dining:pizza)
+func getAccountSubtree(ctx context.Context, db DBTX, guid string) ([]*Account, error) {
+	query := `
+WITH RECURSIVE account_tree AS (
+	SELECT
+		accounts.guid,
+		accounts.name,
+		accounts.account_type,
+		accounts.commodity_guid,
+		accounts.commodity_scu,
+		accounts.non_std_scu,
+		accounts.parent_guid,
+		accounts.code,
+		accounts.description,
+		accounts.hidden,
+		accounts.placeholder
+	FROM accounts
+	WHERE accounts.guid = ?
+	UNION ALL
+	SELECT
+		a.guid,
+		a.name,
+		a.account_type,
+		a.commodity_guid,
+		a.commodity_scu,
+		a.non_std_scu,
+		a.parent_guid,
+		a.code,
+		a.description,
+		a.hidden,
+		a.placeholder
+	FROM accounts a
+	INNER JOIN account_tree at ON a.parent_guid = at.guid
+)
+SELECT
+	guid,
+	name,
+	account_type,
+	commodity_guid,
+	commodity_scu,
+	non_std_scu,
+	parent_guid,
+	code,
+	description,
+	hidden,
+	placeholder
+FROM account_tree
+`
+	rows, err := db.QueryContext(ctx, query, guid)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+
+	var accounts []*Account
+	for rows.Next() {
+		account, err := scanAccount(rows)
+		if err != nil {
+			return nil, err
+		}
+		fullName, err := getFullAccountName(ctx, db, account)
+		if err != nil {
+			return nil, err
+		}
+		account.FullName = fullName
+		accounts = append(accounts, account)
+	}
+
+	return accounts, nil
+}
+
+func buildTreeFromAccounts(accounts []*Account, root *Account) {
+	accountMap := make(map[string]*Account)
+	for _, account := range accounts {
+		account.Children = make([]*Account, 0)
+		accountMap[account.GUID] = account
+	}
+
+	for _, account := range accounts {
+		if account.ParentGUID != nil {
+			if parent, exists := accountMap[*account.ParentGUID]; exists {
+				parent.Children = append(parent.Children, account)
+				account.Parent = parent
+				account.Level = parent.Level + 1
+			}
+		}
+	}
+
+	if rootFromAccountMap := accountMap[root.GUID]; rootFromAccountMap != nil {
+		root.Children = rootFromAccountMap.Children
+		root.Parent = rootFromAccountMap.Parent
+		root.Level = rootFromAccountMap.Level
+
+		for _, child := range root.Children {
+			if child.Parent != root {
+				child.Parent = root
+			}
+		}
+	}
+}
+
+// getFullAccountName takes a store.Account and attempts to return its full
+// account name (e.g. expenses:dining:pizza)
 func getFullAccountName(ctx context.Context, db DBTX, account *Account) (string, error) {
 	s := []string{account.Name}
 	for account.ParentGUID != nil {
@@ -193,6 +316,20 @@ func getAccountFromAccountTree(ctx context.Context, db DBTX, s string) (*Account
 	return parentAccounts[len(parentAccounts)-1], nil
 }
 
+func getSubtreeWithTree(ctx context.Context, db DBTX, root *Account) error {
+	accounts, err := getAccountSubtree(ctx, db, root.GUID)
+	if err != nil {
+		return err
+	}
+
+	if len(accounts) == 0 {
+		return sql.ErrNoRows
+	}
+
+	buildTreeFromAccounts(accounts, root)
+	return nil
+}
+
 func (s AccountsStore) Get(ctx context.Context, guidOrName string, opts ...AccountsOptFunc) (*Account, error) {
 	var account *Account
 	o := defaultAccountsOpts()
@@ -200,7 +337,7 @@ func (s AccountsStore) Get(ctx context.Context, guidOrName string, opts ...Accou
 		fn(o)
 	}
 
-	if o.withAccountTree {
+	if o.withAccountFullName {
 		account, err := getAccountFromAccountTree(ctx, s.db, guidOrName)
 		if err != nil {
 			return nil, err
@@ -210,6 +347,9 @@ func (s AccountsStore) Get(ctx context.Context, guidOrName string, opts ...Accou
 			return nil, err
 		}
 		account.FullName = fullName
+		if err := getSubtreeWithTree(ctx, s.db, account); err != nil {
+			return nil, err
+		}
 		return account, nil
 	}
 
@@ -231,6 +371,10 @@ func (s AccountsStore) Get(ctx context.Context, guidOrName string, opts ...Accou
 	}
 	account.FullName = fullName
 
+	if err := getSubtreeWithTree(ctx, s.db, account); err != nil {
+		return nil, err
+	}
+
 	return account, nil
 }
 

diff --git a/internal/store/transactions.go b/internal/store/transactions.go
line changes: +44/-1
index b1cdf4d..a585ef8
--- a/internal/store/transactions.go
+++ b/internal/store/transactions.go
@@ -185,6 +185,17 @@ func (t TransactionsStore) Get(ctx context.Context, guid string) (*Transaction, 
 		return nil, sql.ErrNoRows
 	}
 
+	for _, transaction := range transactions {
+		for _, split := range transaction.Splits {
+			account := split.Account
+			accountFullName, err := getFullAccountName(ctx, t.db, account)
+			if err != nil {
+				return nil, err
+			}
+			account.FullName = accountFullName
+		}
+	}
+
 	return transactions[0], nil
 }
 
@@ -263,7 +274,23 @@ func (t TransactionsStore) All(ctx context.Context, q *TransactionQuery) ([]*Tra
 	}
 	defer rows.Close()
 
-	return scanTransactions(rows)
+	transactions, err = scanTransactions(rows)
+	if err != nil {
+		return nil, err
+	}
+
+	for _, transaction := range transactions {
+		for _, split := range transaction.Splits {
+			account := split.Account
+			accountFullName, err := getFullAccountName(ctx, t.db, account)
+			if err != nil {
+				return nil, err
+			}
+			account.FullName = accountFullName
+		}
+	}
+
+	return transactions, nil
 }
 
 func scanTransactions(rows *sql.Rows) ([]*Transaction, error) {
@@ -394,6 +421,22 @@ func scanTransactions(rows *sql.Rows) ([]*Transaction, error) {
 					NonSTDSCU:    accountNonStdSCU.Int64,
 				}
 
+				if accountCommodityGUID.Valid {
+					account.CommodityGUID = &accountCommodityGUID.String
+				}
+
+				if accountParentGUID.Valid {
+					account.ParentGUID = &accountParentGUID.String
+				}
+
+				if accountCode.Valid {
+					account.Code = &accountCode.String
+				}
+
+				if accountDescription.Valid {
+					account.Description = &accountDescription.String
+				}
+
 				if accountHidden.Valid {
 					account.Hidden = &accountHidden.Int64
 				}