static inline void addObj (GncTaxTable *table) { struct _book_info *bi; bi = qof_book_get_data (qof_instance_get_book(table), _GNC_MOD_NAME); bi->tables = g_list_insert_sorted (bi->tables, table, (GCompareFunc)gncTaxTableCompare); }
static inline void addObj (GncBillTerm *term) { struct _book_info *bi; bi = qof_book_get_data (qof_instance_get_book(term), _GNC_MOD_NAME); bi->terms = g_list_insert_sorted (bi->terms, term, (GCompareFunc)gncBillTermCompare); }
static inline void maybe_resort_list (GncBillTerm *term) { struct _book_info *bi; if (term->parent || term->invisible) return; bi = qof_book_get_data (qof_instance_get_book(term), _GNC_MOD_NAME); bi->terms = g_list_sort (bi->terms, (GCompareFunc)gncBillTermCompare); }
static inline void maybe_resort_list (GncTaxTable *table) { struct _book_info *bi; if (table->parent || table->invisible) return; bi = qof_book_get_data (qof_instance_get_book(table), _GNC_MOD_NAME); bi->tables = g_list_sort (bi->tables, (GCompareFunc)gncTaxTableCompare); }
void GncSqlBillTermBackend::load_all (GncSqlBackend* sql_be) { g_return_if_fail (sql_be != NULL); std::stringstream sql; sql << "SELECT * FROM " << TABLE_NAME; auto stmt = sql_be->create_statement_from_sql(sql.str()); auto result = sql_be->execute_select_statement(stmt); InstanceVec instances; BillTermParentGuidVec l_billterms_needing_parents; for (auto row : *result) { auto pBillTerm = load_single_billterm (sql_be, row, l_billterms_needing_parents); if (pBillTerm != nullptr) instances.push_back(QOF_INSTANCE(pBillTerm)); } if (!instances.empty()) gnc_sql_slots_load_for_instancevec (sql_be, instances); /* While there are items on the list of billterms needing parents, try to see if the parent has now been loaded. Theory says that if items are removed from the front and added to the back if the parent is still not available, then eventually, the list will shrink to size 0. */ if (!l_billterms_needing_parents.empty()) { bool progress_made = true; std::reverse(l_billterms_needing_parents.begin(), l_billterms_needing_parents.end()); auto end = l_billterms_needing_parents.end(); while (progress_made) { progress_made = false; end = std::remove_if(l_billterms_needing_parents.begin(), end, [&](BillTermParentGuidPtr s) { auto pBook = qof_instance_get_book (QOF_INSTANCE (s->billterm)); auto parent = gncBillTermLookup (pBook, &s->guid); if (parent != nullptr) { gncBillTermSetParent (s->billterm, parent); gncBillTermSetChild (parent, s->billterm); progress_made = true; delete s; return true; } return false; }); } } }
static void test_db (GNCPriceDB* db) { xmlNodePtr test_node; gchar* filename1; int fd; QofBook* book = qof_instance_get_book (QOF_INSTANCE (db)); test_node = gnc_pricedb_dom_tree_create (db); if (!test_node && db) { failure_args ("pricedb_xml", __FILE__, __LINE__, "gnc_pricedb_dom_tree_create returned NULL"); return; } if (!db) return; filename1 = g_strdup_printf ("test_file_XXXXXX"); fd = g_mkstemp (filename1); write_dom_node_to_file (test_node, fd); close (fd); { sixtp *parser; load_counter lc = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; sixtp_gdv2 data = {book, lc, NULL, NULL, FALSE}; parser = sixtp_new (); if (!sixtp_add_some_sub_parsers (parser, TRUE, "gnc:pricedb", gnc_pricedb_sixtp_parser_create (), NULL, NULL)) { failure_args ("sixtp_add_some_sub_parsers failed", __FILE__, __LINE__, "%d", iter); } else if (!gnc_xml_parse_file (parser, filename1, test_add_pricedb, (gpointer)&data, qof_session_get_book (session))) { failure_args ("gnc_xml_parse_file returned FALSE", __FILE__, __LINE__, "%d", iter); } } g_unlink (filename1); g_free (filename1); xmlFreeNode (test_node); }
void gncAddressCommitEdit (GncAddress *addr) { /* GnuCash 2.6.3 and earlier didn't handle address kvp's... */ if (!kvp_frame_is_empty (addr->inst.kvp_data)) gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (addr)), GNC_FEATURE_KVP_EXTRA_DATA); if (!qof_commit_edit (QOF_INSTANCE(addr))) return; qof_commit_edit_part2 (&addr->inst, gncAddressOnError, gncAddressOnDone, address_free); }
void gncEntryCommitEdit (GncEntry *entry) { /* GnuCash 2.6.3 and earlier didn't handle entry kvp's... */ if (!kvp_frame_is_empty (entry->inst.kvp_data)) gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (entry)), GNC_FEATURE_KVP_EXTRA_DATA); if (!qof_commit_edit (QOF_INSTANCE(entry))) return; qof_commit_edit_part2 (&entry->inst, gncEntryOnError, gncEntryOnDone, entry_free); }
void gncTaxTableCommitEdit (GncTaxTable *table) { /* GnuCash 2.6.3 and earlier didn't handle taxtable kvp's... */ if (!kvp_frame_is_empty (table->inst.kvp_data)) gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (table)), GNC_FEATURE_KVP_EXTRA_DATA); if (!qof_commit_edit (QOF_INSTANCE(table))) return; qof_commit_edit_part2 (&table->inst, gncTaxTableOnError, gncTaxTableOnDone, table_free); }
void gncTaxTableMakeInvisible (GncTaxTable *table) { struct _book_info *bi; if (!table) return; gncTaxTableBeginEdit (table); table->invisible = TRUE; bi = qof_book_get_data (qof_instance_get_book(table), _GNC_MOD_NAME); bi->tables = g_list_remove (bi->tables, table); gncTaxTableCommitEdit (table); }
/* * Given an owner, extract the open balance from the owner and then * convert it to the desired currency. */ gnc_numeric gncOwnerGetBalanceInCurrency (const GncOwner *owner, const gnc_commodity *report_currency) { gnc_numeric balance = gnc_numeric_zero (); GList *acct_list, *acct_node, *acct_types, *lot_list = NULL, *lot_node; QofBook *book; gnc_commodity *owner_currency; GNCPriceDB *pdb; g_return_val_if_fail (owner, gnc_numeric_zero ()); /* Get account list */ book = qof_instance_get_book (qofOwnerGetOwner (owner)); acct_list = gnc_account_get_descendants (gnc_book_get_root_account (book)); acct_types = gncOwnerGetAccountTypesList (owner); owner_currency = gncOwnerGetCurrency (owner); /* For each account */ for (acct_node = acct_list; acct_node; acct_node = acct_node->next) { Account *account = acct_node->data; /* Check if this account can have lots for the owner, otherwise skip to next */ if (g_list_index (acct_types, (gpointer)xaccAccountGetType (account)) == -1) continue; if (!gnc_commodity_equal (owner_currency, xaccAccountGetCommodity (account))) continue; /* Get a list of open lots for this owner and account */ lot_list = xaccAccountFindOpenLots (account, gncOwnerLotMatchOwnerFunc, (gpointer)owner, NULL); /* For each lot */ for (lot_node = lot_list; lot_node; lot_node = lot_node->next) { GNCLot *lot = lot_node->data; gnc_numeric lot_balance = gnc_lot_get_balance (lot); GncInvoice *invoice = gncInvoiceGetInvoiceFromLot(lot); if (invoice) balance = gnc_numeric_add (balance, lot_balance, gnc_commodity_get_fraction (owner_currency), GNC_HOW_RND_ROUND_HALF_UP); } } pdb = gnc_pricedb_get_db (book); if (report_currency) balance = gnc_pricedb_convert_balance_latest_price ( pdb, balance, owner_currency, report_currency); return balance; }
/* Returns a list of objects referring to this object */ GList* qof_instance_get_referring_object_list(const QofInstance* inst) { GetReferringObjectHelperData data; g_return_val_if_fail( inst != NULL, NULL ); /* scan all collections */ data.inst = inst; data.list = NULL; qof_book_foreach_collection(qof_instance_get_book(inst), get_referring_object_helper, &data); return data.list; }
void GncSqlTaxTableBackend::load_all (GncSqlBackend* sql_be) { g_return_if_fail (sql_be != NULL); /* First time, create the query */ std::stringstream sql; sql << "SELECT * FROM " << TT_TABLE_NAME; auto stmt = sql_be->create_statement_from_sql(sql.str()); auto result = sql_be->execute_select_statement(stmt); TaxTblParentGuidVec tt_needing_parents; for (auto row : *result) load_single_taxtable (sql_be, row, tt_needing_parents); /* While there are items on the list of taxtables needing parents, try to see if the parent has now been loaded. Theory says that if items are removed from the front and added to the back if the parent is still not available, then eventually, the list will shrink to size 0. */ if (!tt_needing_parents.empty()) { bool progress_made = true; std::reverse(tt_needing_parents.begin(), tt_needing_parents.end()); auto end = tt_needing_parents.end(); while (progress_made) { progress_made = false; end = std::remove_if(tt_needing_parents.begin(), end, [&](TaxTblParentGuidPtr s) { auto pBook = qof_instance_get_book (QOF_INSTANCE (s->tt)); auto parent = gncTaxTableLookup (pBook, &s->guid); if (parent != nullptr) { tt_set_parent (s->tt, &s->guid); progress_made = true; delete s; return true; } return false; }); } } }
PaymentWindow * gnc_ui_payment_new_with_txn (GncOwner *owner, Transaction *txn) { SplitList *slist; Split *assetaccount_split; Split *postaccount_split; gnc_numeric amount; PaymentWindow *pw; if (!txn) return NULL; // We require the txn to have one split in an Asset account. slist = xaccTransGetSplitList(txn); if (!slist) return NULL; if (countAssetAccounts(slist) == 0) { g_message("No asset splits in txn \"%s\"; cannot use this for assigning a payment.", xaccTransGetDescription(txn)); return NULL; } assetaccount_split = getFirstAssetAccountSplit(slist); postaccount_split = getFirstAPARAccountSplit(slist); // watch out: Might be NULL amount = xaccSplitGetValue(assetaccount_split); pw = gnc_ui_payment_new(owner, qof_instance_get_book(QOF_INSTANCE(txn))); g_assert(assetaccount_split); // we can rely on this because of the countAssetAccounts() check above g_debug("Amount=%s", gnc_numeric_to_string(amount)); // Fill in the values from the given txn pw->pre_existing_txn = txn; gnc_ui_payment_window_set_num(pw, gnc_get_num_action(txn, assetaccount_split)); gnc_ui_payment_window_set_memo(pw, xaccTransGetDescription(txn)); { GDate txn_date = xaccTransGetDatePostedGDate (txn); gnc_ui_payment_window_set_date(pw, &txn_date); } gnc_ui_payment_window_set_amount(pw, amount); gnc_ui_payment_window_set_xferaccount(pw, xaccSplitGetAccount(assetaccount_split)); if (postaccount_split) gnc_ui_payment_window_set_postaccount(pw, xaccSplitGetAccount(postaccount_split)); return pw; }
static Split * get_balance_split (Transaction *trans, Account *root, Account *account, gnc_commodity *commodity) { Split *balance_split; gchar *accname; if (!account || !gnc_commodity_equiv (commodity, xaccAccountGetCommodity(account))) { if (!root) { root = gnc_book_get_root_account (xaccTransGetBook (trans)); if (NULL == root) { /* This can't occur, things should be in books */ PERR ("Bad data corruption, no root account in book"); return NULL; } } accname = g_strconcat (_("Imbalance"), "-", gnc_commodity_get_mnemonic (commodity), NULL); account = xaccScrubUtilityGetOrMakeAccount (root, commodity, accname, ACCT_TYPE_BANK, FALSE); g_free (accname); if (!account) { PERR ("Can't get balancing account"); return NULL; } } balance_split = xaccTransFindSplitByAccount(trans, account); /* Put split into account before setting split value */ if (!balance_split) { balance_split = xaccMallocSplit (qof_instance_get_book(trans)); xaccTransBeginEdit (trans); xaccSplitSetParent(balance_split, trans); xaccSplitSetAccount(balance_split, account); xaccTransCommitEdit (trans); } return balance_split; }
static GncTaxTable *gncTaxTableCopy (const GncTaxTable *table) { GncTaxTable *t; GList *list; if (!table) return NULL; t = gncTaxTableCreate (qof_instance_get_book(table)); gncTaxTableSetName (t, table->name); for (list = table->entries; list; list = list->next) { GncTaxTableEntry *entry, *e; entry = list->data; e = gncTaxTableEntryCopy (entry); gncTaxTableAddEntry (t, e); } return t; }
static void xaccSchedXactionFree( SchedXaction *sx ) { GList *l; if ( sx == NULL ) return; qof_event_gen( &sx->inst, QOF_EVENT_DESTROY , NULL); if ( sx->name ) g_free( sx->name ); /* * we have to delete the transactions in the * template account ourselves */ delete_template_trans( sx ); /* * xaccAccountDestroy removes the account from * its group for us AFAICT. If shutting down, * the account is being deleted separately. */ if (!qof_book_shutting_down(qof_instance_get_book(sx))) { xaccAccountBeginEdit(sx->template_acct); xaccAccountDestroy(sx->template_acct); } for ( l = sx->deferredList; l; l = l->next ) { gnc_sx_destroy_temporal_state( l->data ); l->data = NULL; } if ( sx->deferredList ) { g_list_free( sx->deferredList ); sx->deferredList = NULL; } /* qof_instance_release (&sx->inst); */ g_object_unref( sx ); }
static void set_parent (gpointer pObject, gpointer pValue) { Account* pAccount; QofBook* pBook; GncGUID* guid = (GncGUID*)pValue; Account* pParent; g_return_if_fail (pObject != NULL); g_return_if_fail (GNC_IS_ACCOUNT (pObject)); pAccount = GNC_ACCOUNT (pObject); pBook = qof_instance_get_book (QOF_INSTANCE (pAccount)); if (guid != NULL) { pParent = xaccAccountLookup (guid, pBook); if (pParent != NULL) { gnc_account_append_child (pParent, pAccount); } } }
static GncBillTerm *gncBillTermCopy (const GncBillTerm *term) { GncBillTerm *t; if (!term) return NULL; t = gncBillTermCreate (qof_instance_get_book(term)); gncBillTermBeginEdit(t); gncBillTermSetName (t, term->name); gncBillTermSetDescription (t, term->desc); t->type = term->type; t->due_days = term->due_days; t->disc_days = term->disc_days; t->discount = term->discount; t->cutoff = term->cutoff; gncBillTermCommitEdit(t); return t; }
static void bt_set_parent (gpointer data, gpointer value) { GncBillTerm* billterm; GncBillTerm* parent; QofBook* pBook; GncGUID* guid = (GncGUID*)value; g_return_if_fail (data != NULL); g_return_if_fail (GNC_IS_BILLTERM (data)); billterm = GNC_BILLTERM (data); pBook = qof_instance_get_book (QOF_INSTANCE (billterm)); if (guid != NULL) { parent = gncBillTermLookup (pBook, guid); if (parent != NULL) { gncBillTermSetParent (billterm, parent); gncBillTermSetChild (parent, billterm); } } }
static void tt_set_parent( gpointer data, gpointer value ) { GncTaxTable* tt; GncTaxTable* parent; QofBook* pBook; GncGUID* guid = (GncGUID*)value; g_return_if_fail( data != NULL ); g_return_if_fail( GNC_IS_TAXTABLE(data) ); tt = GNC_TAXTABLE(data); pBook = qof_instance_get_book( QOF_INSTANCE(tt) ); if ( guid != NULL ) { parent = gncTaxTableLookup( pBook, guid ); if ( parent != NULL ) { gncTaxTableSetParent( tt, parent ); gncTaxTableSetChild( parent, tt ); } } }
void xaccTransScrubCurrency (Transaction *trans) { SplitList *node; gnc_commodity *currency; if (!trans) return; /* If there are any orphaned splits in a transaction, then the * this routine will fail. Therefore, we want to make sure that * there are no orphans (splits without parent account). */ xaccTransScrubOrphans (trans); currency = xaccTransGetCurrency (trans); if (currency && gnc_commodity_is_currency(currency)) return; currency = xaccTransFindCommonCurrency (trans, qof_instance_get_book(trans)); if (currency) { xaccTransBeginEdit (trans); xaccTransSetCurrency (trans, currency); xaccTransCommitEdit (trans); } else { if (NULL == trans->splits) { PWARN ("Transaction \"%s\" has no splits in it!", trans->description); } else { SplitList *node; char guid_str[GUID_ENCODING_LENGTH + 1]; guid_to_string_buff(xaccTransGetGUID(trans), guid_str); PWARN ("no common transaction currency found for trans=\"%s\" (%s);", trans->description, guid_str); for (node = trans->splits; node; node = node->next) { Split *split = node->data; if (NULL == split->acc) { PWARN (" split=\"%s\" is not in any account!", split->memo); } else { gnc_commodity *currency = xaccAccountGetCommodity(split->acc); PWARN ("setting to split=\"%s\" account=\"%s\" commodity=\"%s\"", split->memo, xaccAccountGetName(split->acc), gnc_commodity_get_mnemonic(currency)); xaccTransBeginEdit (trans); xaccTransSetCurrency (trans, currency); xaccTransCommitEdit (trans); return; } } } return; } for (node = trans->splits; node; node = node->next) { Split *sp = node->data; if (!gnc_numeric_equal(xaccSplitGetAmount (sp), xaccSplitGetValue (sp))) { gnc_commodity *acc_currency; acc_currency = sp->acc ? xaccAccountGetCommodity(sp->acc) : NULL; if (acc_currency == currency) { /* This Split needs fixing: The transaction-currency equals * the account-currency/commodity, but the amount/values are * inequal i.e. they still correspond to the security * (amount) and the currency (value). In the new model, the * value is the amount in the account-commodity -- so it * needs to be set to equal the amount (since the * account-currency doesn't exist anymore). * * Note: Nevertheless we lose some information here. Namely, * the information that the 'amount' in 'account-old-security' * was worth 'value' in 'account-old-currency'. Maybe it would * be better to store that information in the price database? * But then, for old currency transactions there is still the * 'other' transaction, which is going to keep that * information. So I don't bother with that here. -- cstim, * 2002/11/20. */ PWARN ("Adjusted split with mismatched values, desc=\"%s\" memo=\"%s\"" " old amount %s %s, new amount %s", trans->description, sp->memo, gnc_num_dbg_to_string (xaccSplitGetAmount(sp)), gnc_commodity_get_mnemonic (currency), gnc_num_dbg_to_string (xaccSplitGetValue(sp))); xaccTransBeginEdit (trans); xaccSplitSetAmount (sp, xaccSplitGetValue(sp)); xaccTransCommitEdit (trans); } /*else { PINFO ("Ok: Split '%s' Amount %s %s, value %s %s", xaccSplitGetMemo (sp), gnc_num_dbg_to_string (amount), gnc_commodity_get_mnemonic (currency), gnc_num_dbg_to_string (value), gnc_commodity_get_mnemonic (acc_currency)); }*/ } } }
static void test_employee (void) { QofBackend *be; QofBook *book; QofSession *session; GncEmployee *employee; session = qof_session_new(); qof_session_begin(session, QOF_STDOUT, FALSE, FALSE); book = qof_session_get_book(session); /* The book *must* have a backend to pass the test of the 'dirty' flag */ /* See the README file for details */ be = qof_book_get_backend (book); /* Test creation/destruction */ { do_test (gncEmployeeCreate (NULL) == NULL, "employee create NULL"); employee = gncEmployeeCreate (book); do_test (employee != NULL, "employee create"); do_test (qof_instance_get_book(QOF_INSTANCE(employee)) == book, "getbook"); gncEmployeeBeginEdit (employee); gncEmployeeDestroy (employee); success ("create/destroy"); } /* Test setting/getting routines; does the active flag get set right? */ { GncGUID guid; test_string_fcn (book, "Id", gncEmployeeSetID, gncEmployeeGetID); test_string_fcn (book, "Username", gncEmployeeSetUsername, gncEmployeeGetUsername); test_string_fcn (book, "Language", gncEmployeeSetLanguage, gncEmployeeGetLanguage); test_string_fcn (book, "Acl", gncEmployeeSetAcl, gncEmployeeGetAcl); test_numeric_fcn (book, "Workday", gncEmployeeSetWorkday, gncEmployeeGetWorkday); test_numeric_fcn (book, "Rate", gncEmployeeSetRate, gncEmployeeGetRate); test_bool_fcn (book, "Active", gncEmployeeSetActive, gncEmployeeGetActive); do_test (gncEmployeeGetAddr (employee) != NULL, "Addr"); guid_new (&guid); employee = gncEmployeeCreate (book); count++; gncEmployeeSetGUID (employee, &guid); do_test (guid_equal (&guid, qof_instance_get_guid(QOF_INSTANCE(employee))), "guid compare"); } #if 0 { GList *list; list = gncBusinessGetList (book, GNC_EMPLOYEE_MODULE_NAME, TRUE); do_test (list != NULL, "getList all"); do_test (g_list_length (list) == count, "correct length: all"); g_list_free (list); list = gncBusinessGetList (book, GNC_EMPLOYEE_MODULE_NAME, FALSE); do_test (list != NULL, "getList active"); do_test (g_list_length (list) == 1, "correct length: active"); g_list_free (list); } #endif { const char *str = get_random_string(); const char *res; GncAddress *addr; addr = gncEmployeeGetAddr (employee); gncAddressSetName (addr, str); res = qof_object_printable (GNC_ID_EMPLOYEE, employee); do_test (res != NULL, "Printable NULL?"); do_test (safe_strcmp (str, res) == 0, "Printable equals"); } }
static inline void remObj (GncBillTerm *term) { struct _book_info *bi; bi = qof_book_get_data (qof_instance_get_book(term), _GNC_MOD_NAME); bi->terms = g_list_remove (bi->terms, term); }
static inline void remObj (GncTaxTable *table) { struct _book_info *bi; bi = qof_book_get_data (qof_instance_get_book(table), _GNC_MOD_NAME); bi->tables = g_list_remove (bi->tables, table); }
static void test_employee (void) { QofBook *book; GncEmployee *employee; book = qof_book_new(); /* Test creation/destruction */ { do_test (gncEmployeeCreate (NULL) == NULL, "employee create NULL"); employee = gncEmployeeCreate (book); do_test (employee != NULL, "employee create"); do_test (qof_instance_get_book(QOF_INSTANCE(employee)) == book, "getbook"); gncEmployeeBeginEdit (employee); gncEmployeeDestroy (employee); success ("create/destroy"); } /* Test setting/getting routines; does the active flag get set right? */ { GncGUID guid; test_string_fcn (book, "Id", gncEmployeeSetID, gncEmployeeGetID); test_string_fcn (book, "Username", gncEmployeeSetUsername, gncEmployeeGetUsername); test_string_fcn (book, "Language", gncEmployeeSetLanguage, gncEmployeeGetLanguage); test_string_fcn (book, "Acl", gncEmployeeSetAcl, gncEmployeeGetAcl); test_numeric_fcn (book, "Workday", gncEmployeeSetWorkday, gncEmployeeGetWorkday); test_numeric_fcn (book, "Rate", gncEmployeeSetRate, gncEmployeeGetRate); test_bool_fcn (book, "Active", gncEmployeeSetActive, gncEmployeeGetActive); do_test (gncEmployeeGetAddr (employee) != NULL, "Addr"); guid_replace (&guid); employee = gncEmployeeCreate (book); count++; gncEmployeeSetGUID (employee, &guid); do_test (guid_equal (&guid, qof_instance_get_guid(QOF_INSTANCE(employee))), "guid compare"); } { GList *list; list = gncBusinessGetList (book, GNC_EMPLOYEE_MODULE_NAME, TRUE); do_test (list != NULL, "getList all"); do_test (g_list_length (list) == count, "correct length: all"); g_list_free (list); list = gncBusinessGetList (book, GNC_EMPLOYEE_MODULE_NAME, FALSE); do_test (list != NULL, "getList active"); do_test (g_list_length (list) == 1, "correct length: active"); g_list_free (list); } { const char *str = get_random_string(); const char *res; GncAddress *addr; addr = gncEmployeeGetAddr (employee); gncAddressSetName (addr, str); res = qof_object_printable (GNC_ID_EMPLOYEE, employee); do_test (res != NULL, "Printable NULL?"); do_test (g_strcmp0 (str, res) == 0, "Printable equals"); } qof_book_destroy (book); }
static void test_vendor (void) { QofBook *book; GncVendor *vendor; book = qof_book_new(); /* Test creation/destruction */ { do_test (gncVendorCreate (NULL) == NULL, "vendor create NULL"); vendor = gncVendorCreate (book); do_test (vendor != NULL, "vendor create"); do_test (qof_instance_get_book (QOF_INSTANCE(vendor)) == book, "getbook"); gncVendorBeginEdit (vendor); gncVendorDestroy (vendor); success ("create/destroy"); } /* Test setting/getting routines; does the active flag get set right? */ { GncGUID guid; test_string_fcn (book, "Id", gncVendorSetID, gncVendorGetID); test_string_fcn (book, "Name", gncVendorSetName, gncVendorGetName); test_string_fcn (book, "Notes", gncVendorSetNotes, gncVendorGetNotes); //test_string_fcn (book, "Terms", gncVendorSetTerms, gncVendorGetTerms); //test_bool_fcn (book, "TaxIncluded", gncVendorSetTaxIncluded, gncVendorGetTaxIncluded); test_bool_fcn (book, "Active", gncVendorSetActive, gncVendorGetActive); do_test (gncVendorGetAddr (vendor) != NULL, "Addr"); guid_new (&guid); vendor = gncVendorCreate (book); count++; gncVendorSetGUID (vendor, &guid); do_test (guid_equal (&guid, qof_instance_get_guid(QOF_INSTANCE(vendor))), "guid compare"); } { GList *list; list = gncBusinessGetList (book, GNC_ID_VENDOR, TRUE); do_test (list != NULL, "getList all"); do_test (g_list_length (list) == count, "correct length: all"); g_list_free (list); list = gncBusinessGetList (book, GNC_ID_VENDOR, FALSE); do_test (list != NULL, "getList active"); do_test (g_list_length (list) == 1, "correct length: active"); g_list_free (list); } { const char *str = get_random_string(); const char *res; gncVendorSetName (vendor, str); res = qof_object_printable (GNC_ID_VENDOR, vendor); do_test (res != NULL, "Printable NULL?"); do_test (g_strcmp0 (str, res) == 0, "Printable equals"); } qof_book_destroy (book); }
/* Get the trading split for a given commodity, creating it (and the necessary accounts) if it doesn't exist. */ static Split * get_trading_split (Transaction *trans, Account *root, gnc_commodity *commodity) { Split *balance_split; Account *trading_account; Account *ns_account; Account *account; gnc_commodity *default_currency = NULL; if (!root) { root = gnc_book_get_root_account (xaccTransGetBook (trans)); if (NULL == root) { /* This can't occur, things should be in books */ PERR ("Bad data corruption, no root account in book"); return NULL; } } /* Get the default currency. This is harder than it seems. It's not possible to call gnc_default_currency() since it's a UI function. One might think that the currency of the root account would do, but the root account has no currency. Instead look for the Income placeholder account and use its currency. */ default_currency = xaccAccountGetCommodity(gnc_account_lookup_by_name(root, _("Income"))); if (! default_currency) { default_currency = commodity; } trading_account = xaccScrubUtilityGetOrMakeAccount (root, default_currency, _("Trading"), ACCT_TYPE_TRADING, TRUE); if (!trading_account) { PERR ("Can't get trading account"); return NULL; } ns_account = xaccScrubUtilityGetOrMakeAccount (trading_account, default_currency, gnc_commodity_get_namespace(commodity), ACCT_TYPE_TRADING, TRUE); if (!ns_account) { PERR ("Can't get namespace account"); return NULL; } account = xaccScrubUtilityGetOrMakeAccount (ns_account, commodity, gnc_commodity_get_mnemonic(commodity), ACCT_TYPE_TRADING, FALSE); if (!account) { PERR ("Can't get commodity account"); return NULL; } balance_split = xaccTransFindSplitByAccount(trans, account); /* Put split into account before setting split value */ if (!balance_split) { balance_split = xaccMallocSplit (qof_instance_get_book(trans)); xaccTransBeginEdit (trans); xaccSplitSetParent(balance_split, trans); xaccSplitSetAccount(balance_split, account); xaccTransCommitEdit (trans); } return balance_split; }
/** This function is the handler for all event messages from the * engine. Its purpose is to update the owner tree model any time * an owner is added to the engine or deleted from the engine. * This change to the model is then propagated to any/all overlying * filters and views. This function listens to the ADD, REMOVE, and * DESTROY events. * * @internal * * @warning There is a "Catch 22" situation here. * gtk_tree_model_row_deleted() can't be called until after the item * has been deleted from the real model (which is the engine's * owner tree for us), but once the owner has been deleted from * the engine we have no way to determine the path to pass to * row_deleted(). This is a PITA, but the only other choice is to * have this model mirror the engine's owners instead of * referencing them directly. * * @param entity The guid of the affected item. * * @param type The type of the affected item. This function only * cares about items of type "owner". * * @param event type The type of the event. This function only cares * about items of type ADD, REMOVE, MODIFY, and DESTROY. * * @param user_data A pointer to the owner tree model. */ static void gnc_tree_model_owner_event_handler (QofInstance *entity, QofEventId event_type, GncTreeModelOwner *model, GncEventData *ed) { GncTreeModelOwnerPrivate *priv; GtkTreePath *path = NULL; GtkTreeIter iter; GncOwner owner; g_return_if_fail(model); /* Required */ if (!GNC_IS_OWNER(entity)) return; ENTER("entity %p of type %d, model %p, event_data %p", entity, event_type, model, ed); priv = GNC_TREE_MODEL_OWNER_GET_PRIVATE(model); qofOwnerSetEntity (&owner, entity); if (gncOwnerGetType(&owner) != priv->owner_type) { LEAVE("model type and owner type differ"); return; } if (qof_instance_get_book (entity) != priv->book) { LEAVE("not in this book"); return; } /* What to do, that to do. */ switch (event_type) { case QOF_EVENT_ADD: /* Tell the filters/views where the new owner was added. */ DEBUG("add owner %p (%s)", &owner, gncOwnerGetName(&owner)); /* First update our copy of the owner list. This isn't done automatically */ priv->owner_list = gncBusinessGetOwnerList (priv->book, gncOwnerTypeToQofIdType(priv->owner_type), TRUE); increment_stamp(model); if (!gnc_tree_model_owner_get_iter_from_owner (model, &owner, &iter)) { LEAVE("can't generate iter"); break; } path = gnc_tree_model_owner_get_path(GTK_TREE_MODEL(model), &iter); if (!path) { DEBUG("can't generate path"); break; } gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter); break; case QOF_EVENT_REMOVE: if (!ed) /* Required for a remove. */ break; DEBUG("remove owner %d (%s) from owner_list %p", ed->idx, gncOwnerGetName(&owner), priv->owner_list); path = gtk_tree_path_new(); if (!path) { DEBUG("can't generate path"); break; } increment_stamp(model); gtk_tree_path_append_index (path, ed->idx); gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), path); break; case QOF_EVENT_MODIFY: DEBUG("modify owner %p (%s)", &owner, gncOwnerGetName(&owner)); if (!gnc_tree_model_owner_get_iter_from_owner (model, &owner, &iter)) { LEAVE("can't generate iter"); return; } path = gnc_tree_model_owner_get_path(GTK_TREE_MODEL(model), &iter); if (!path) { DEBUG("can't generate path"); break; } gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter); break; default: LEAVE("unknown event type"); return; } if (path) gtk_tree_path_free(path); LEAVE(" "); return; }