static AddressQF* build_shared_quickfill (QofBook *book, const char * key) { AddressQF *result; QofQuery *query = new_query_for_addresss(book); GList *entries = qof_query_run(query); /* g_warning("Found %d GncAddress items", g_list_length (entries)); */ result = g_new0(AddressQF, 1); result->qf_addr2 = gnc_quickfill_new(); result->qf_addr3 = gnc_quickfill_new(); result->qf_addr4 = gnc_quickfill_new(); result->qf_sort = QUICKFILL_ALPHA; result->book = book; g_list_foreach (entries, address_cb, result); qof_query_destroy(query); result->listener = qof_event_register_handler (listen_for_gncaddress_events, result); qof_book_set_data_fin (book, key, result, shared_quickfill_destroy); return result; }
/** Finds the GncEntry with the matching description string as given * in "desc", but searches this in the whole book. */ static GncEntry* find_entry_in_book_by_desc(GncEntryLedger *reg, const char* desc) { GncEntry *result = NULL; gboolean use_invoice; QofQuery *query; GList *entries = NULL; switch (reg->type) { case GNCENTRY_INVOICE_ENTRY: case GNCENTRY_INVOICE_VIEWER: case GNCENTRY_CUST_CREDIT_NOTE_ENTRY: case GNCENTRY_CUST_CREDIT_NOTE_VIEWER: use_invoice = TRUE; break; default: use_invoice = FALSE; }; query = new_query_for_entry_desc(reg, desc, use_invoice); entries = qof_query_run(query); /* Do we have a non-empty result? */ if (entries) { /* That's the result. */ result = (GncEntry*) entries->data; /*g_warning("Found %d GncEntry items", g_list_length (entries));*/ } qof_query_destroy(query); return result; }
static int get_num_xactions_before_date(QofBook *book, time64 close_date) { QofQuery *q; GSList *param; QofQueryPredData *pred; GList *res, *n; int cnt = 0; q = qof_query_create_for(GNC_ID_TRANS); qof_query_set_max_results(q, -1); qof_query_set_book (q, book); /* Look for transactions earlier than the closing date */ param = g_slist_prepend (NULL, TRANS_DATE_POSTED); pred = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, close_date); qof_query_add_term (q, param, pred, QOF_QUERY_FIRST_TERM); /* Run the query, find how many transactions there are */ res = qof_query_run (q); cnt = 0; for (n = res; n; n = n->next) cnt ++; qof_query_destroy (q); return cnt; }
/* Return the list of entries (NOTE: Should use a query here!) */ static GList * gnc_entry_ledger_get_entries (GncEntryLedger *ledger) { if (ledger->query) return qof_query_run (ledger->query); // g_warning ("No query to run?"); return NULL; }
static void refresh_handler (GHashTable *changes, gpointer user_data) { GNCLedgerDisplay2 *ld = user_data; const EventInfo *info; gboolean has_leader; GList *splits; ENTER("changes=%p, user_data=%p", changes, user_data); if (ld->loading) { LEAVE("already loading"); return; } has_leader = (ld->ld_type == LD2_SINGLE || ld->ld_type == LD2_SUBACCOUNT); if (has_leader) { Account *leader = gnc_ledger_display2_leader (ld); if (!leader) { gnc_close_gui_component (ld->component_id); LEAVE("no leader"); return; } } if (changes && has_leader) { info = gnc_gui_get_entity_events (changes, &ld->leader); if (info && (info->event_mask & QOF_EVENT_DESTROY)) { gnc_close_gui_component (ld->component_id); LEAVE("destroy"); return; } } /* Its not clear if we should re-run the query, or if we should * just use qof_query_last_run(). Its possible that the dates * changed, requiring a full new query. Similar considerations * needed for multi-user mode. */ splits = qof_query_run (ld->query); //FIXME Not Needed ? gnc_ledger_display2_set_watches (ld, splits); // gnc_ledger_display2_set_watches (ld, splits); //preference changes come this way gnc_ledger_display2_refresh_internal (ld, splits); LEAVE(" "); }
LotList * xaccQueryGetLots (QofQuery * q, query_txn_match_t runtype) { GList * splits = qof_query_run(q); GList * current = NULL; GList * retval = NULL; GHashTable * lot_hash = g_hash_table_new(g_direct_hash, g_direct_equal); GNCLot * lot = NULL; gpointer val = NULL; int count = 0; /* iterate over matching splits, incrementing a match-count in * the hash table */ for (current = splits; current; current = current->next) { lot = xaccSplitGetLot((Split *)(current->data)); /* don't waste time looking up unless we need the count * information */ if (runtype == QUERY_TXN_MATCH_ALL) { val = g_hash_table_lookup(lot_hash, lot); count = GPOINTER_TO_INT(val); } g_hash_table_insert(lot_hash, lot, GINT_TO_POINTER(count + 1)); } /* now pick out the transactions that match */ if (runtype == QUERY_TXN_MATCH_ALL) { g_hash_table_foreach(lot_hash, query_match_all_lot_filter_func, &retval); } else { g_hash_table_foreach(lot_hash, query_match_any_lot_filter_func, &retval); } g_hash_table_destroy(lot_hash); return retval; }
void gnc_ledger_display_refresh (GNCLedgerDisplay *ld) { ENTER("ld=%p", ld); if (!ld) { LEAVE("no display"); return; } if (ld->loading) { LEAVE("already loading"); return; } gnc_ledger_display_refresh_internal (ld, qof_query_run (ld->query)); LEAVE(" "); }
void gnc_ledger_display2_refresh (GNCLedgerDisplay2 *ld) { ENTER("ld=%p", ld); if (!ld) { LEAVE("no display"); return; } if (ld->loading) { LEAVE("already loading"); return; } // Update the query before refresh gnc_tree_model_split_reg_update_query (ld->model, ld->query); gnc_ledger_display2_refresh_internal (ld, qof_query_run (ld->query)); LEAVE(" "); }
/******************************************************************* * get_earliest_in_book * * Find the earliest date occuring in the book. Do this by making * a query and sorting by date. Since the truncated sort returns * only the *last* search results, sort in decreasing order. *******************************************************************/ static time64 get_earliest_in_book (QofBook *book) { QofQuery *q; GSList *p1, *p2; GList *res; time64 earliest; q = qof_query_create_for (GNC_ID_SPLIT); qof_query_set_max_results (q, 1); qof_query_set_book (q, book); /* Sort by transaction date */ p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED); p1 = g_slist_prepend (p1, SPLIT_TRANS); p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT); qof_query_set_sort_order (q, p1, p2, NULL); /* Reverse the sort order */ qof_query_set_sort_increasing (q, FALSE, FALSE, FALSE); /* Run the query, find the earliest transaction date */ res = qof_query_run (q); if (res) { earliest = xaccQueryGetEarliestDateFound (q); } else { /* If no results, we don't want to bomb totally */ earliest = gnc_time (0); } qof_query_destroy (q); return earliest; }
SplitList * xaccQueryGetSplitsUniqueTrans(QofQuery *q) { GList * splits = qof_query_run(q); GList * current; GList * result = NULL; GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal); for (current = splits; current; current = current->next) { Split *split = current->data; Transaction *trans = xaccSplitGetParent (split); if (!g_hash_table_lookup (trans_hash, trans)) { g_hash_table_insert (trans_hash, trans, trans); result = g_list_prepend (result, split); } } g_hash_table_destroy (trans_hash); return g_list_reverse (result); }
int main (int argc, char *argv[]) { int err, fake_argc = 1; char * fake_argv[] = {"hello", 0}; QofBook *book; Account *root; char *bufp; int rc, sz; /* intitialize the engine */ gnc_engine_init (fake_argc, fake_argv); /* contact the database, which is a flat file for this demo */ book = qof_book_new (); rc = gnc_book_begin (book, "file:/tmp/demo.gnucash", FALSE); if (!rc) goto bookerrexit; rc = gnc_book_load (book); if (!rc) goto bookerrexit; /* the root pointer points to our local cache of the data */ root = gnc_book_get_root_account (book); /* --------------------------------------------------- */ /* done with initialization, go into event loop */ while (FCGI_Accept() >= 0) { GList *split_list; Query *q = NULL; char *request_method; int read_len = 0; /* get the request method */ request_method = getenv ("REQUEST_METHOD"); /* Lets pretend that method=get means user has logged * in. Send the user the accounts and currencies, * but not the transactions/splits. */ if (!strcmp ("GET", request_method)) { gncxml_write_account_tree_to_buf(root, &bufp, &sz); /* print the HTTP header */ printf("Content-type: text/gnc-xml\r\n" "Content-Length: %d\r\n" "\r\n", sz); /* send the xml to the client */ printf ("%s", bufp); free (bufp); /* wait for the next request */ continue; } if (!strcmp ("POST", request_method)) { char * content_length = getenv("CONTENT_LENGTH"); read_len = atoi (content_length); /* read 'read_len' bytes from stdin ... */ bufp = (char *) malloc (read_len); fread (bufp, read_len, 1, stdin); /* conver the xml input into a gnucash query structure... */ q = gncxml_read_query (bufp, read_len); xaccQuerySetGroup (q, root); /* hack -- limit to 30 splits ... */ qof_query_set_max_results (q, 30); split_list = qof_query_run (q); qof_query_destroy (q); /* wait for the next request */ continue; } /* if we got to here, an error -- unknown method */ printf("Content-type: text/plain\r\n" "\r\n" "unknown request type \n"); } bookerrexit: err = gnc_book_get_error (book); /* 500 Server Error */ FCGI_SetExitStatus (500); printf("Content-type: text/plain\r\n\r\n" "error was %s\n", strerror (err)); FCGI_Finish(); /* close the book */ qof_book_destroy (book); /* shut down the engine */ gnc_engine_shutdown (); sleep (1); return 0; }
static void create_children (GNCGeneralSearch *gsl, const char *label, gboolean text_editable, QofIdTypeConst type, QofBook *book) { GtkListStore * list_store; QofQuery * q; GtkTreeIter iter; GList * list, * it; GtkEntryCompletion *completion; /* Add a text entry box */ gsl->entry = gtk_entry_new (); if (!text_editable) gtk_editable_set_editable (GTK_EDITABLE (gsl->entry), FALSE); gtk_box_pack_start (GTK_BOX (gsl), gsl->entry, TRUE, TRUE, 0); /* Setup a GtkEntryCompletion auxiliary widget for our Entry box * This requires an internal table ("model") with the possible * auto-completion text entries */ /* Query for the requested object type */ q = qof_query_create_for (type); qof_query_add_boolean_match(q, g_slist_prepend (NULL, QOF_PARAM_ACTIVE), TRUE, QOF_QUERY_AND); qof_query_set_book (q, book); list = qof_query_run(q); /* Setup the internal model */ list_store = gtk_list_store_new (GSL_N_COLUMNS, G_TYPE_STRING, G_TYPE_OBJECT); for (it = list; it != NULL ; it = it->next) { char * name; name = g_strdup(qof_object_printable(type, it->data)); /* Add a new row to the model */ if (name) { gtk_list_store_append (list_store, &iter); gtk_list_store_set (list_store, &iter, GSL_COLUMN_TEXT, name, GSL_COLUMN_QOFOBJECT, G_OBJECT(it->data), -1); g_free(name); } } qof_query_destroy(q); /* Add the GtkEntryCompletion widget */ completion = gtk_entry_completion_new(); gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(list_store)); gtk_entry_completion_set_text_column(completion, 0); gtk_entry_completion_set_inline_completion(completion, TRUE); gtk_entry_set_completion(GTK_ENTRY(gsl->entry), completion); g_signal_connect (G_OBJECT (completion), "match_selected", G_CALLBACK (gnc_gsl_match_selected_cb), gsl); g_signal_connect (G_OBJECT (gsl->entry), "focus-out-event", G_CALLBACK (gnc_gsl_focus_out_cb), gsl); g_object_unref(completion); gtk_widget_show (gsl->entry); /* Add the search button */ gsl->button = gtk_button_new_with_label (label); gtk_box_pack_start (GTK_BOX (gsl), gsl->button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (gsl->button), "clicked", G_CALLBACK (search_cb), gsl); gtk_widget_show (gsl->button); }
GtkWidget * gnc_reconcile_view_new (Account *account, GNCReconcileViewType type, time64 statement_date) { GNCReconcileView *view; GtkListStore *liststore; gboolean include_children, auto_check; GList *accounts = NULL; GList *splits; Query *query; g_return_val_if_fail (account, NULL); g_return_val_if_fail ((type == RECLIST_DEBIT) || (type == RECLIST_CREDIT), NULL); view = g_object_new (GNC_TYPE_RECONCILE_VIEW, NULL); /* Create the list store with 6 columns and add to treeview, column 0 will be a pointer to the entry */ liststore = gtk_list_store_new (6, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN ); gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (liststore)); g_object_unref (liststore); view->account = account; view->view_type = type; view->statement_date = statement_date; query = qof_query_create_for (GNC_ID_SPLIT); qof_query_set_book (query, gnc_get_current_book ()); include_children = xaccAccountGetReconcileChildrenStatus (account); if (include_children) accounts = gnc_account_get_descendants (account); /* match the account */ accounts = g_list_prepend (accounts, account); xaccQueryAddAccountMatch (query, accounts, QOF_GUID_MATCH_ANY, QOF_QUERY_AND); g_list_free (accounts); /* limit the matches to CREDITs and DEBITs only, depending on the type */ if (type == RECLIST_CREDIT) xaccQueryAddValueMatch(query, gnc_numeric_zero (), QOF_NUMERIC_MATCH_CREDIT, QOF_COMPARE_GTE, QOF_QUERY_AND); else xaccQueryAddValueMatch(query, gnc_numeric_zero (), QOF_NUMERIC_MATCH_DEBIT, QOF_COMPARE_GTE, QOF_QUERY_AND); /* limit the matches only to Cleared and Non-reconciled splits */ xaccQueryAddClearedMatch (query, CLEARED_NO | CLEARED_CLEARED, QOF_QUERY_AND); /* Initialize the QueryList */ gnc_reconcile_view_construct (view, query); /* find the list of splits to auto-reconcile */ auto_check = gnc_prefs_get_bool (GNC_PREFS_GROUP_RECONCILE, GNC_PREF_CHECK_CLEARED); if (auto_check) { time64 statement_date_day_end = gnc_time64_get_day_end(statement_date); for (splits = qof_query_run (query); splits; splits = splits->next) { Split *split = splits->data; char recn = xaccSplitGetReconcile (split); time64 trans_date = xaccTransGetDate (xaccSplitGetParent (split)); /* Just an extra verification that our query is correct ;) */ g_assert (recn == NREC || recn == CREC); if (recn == CREC && gnc_difftime (trans_date, statement_date_day_end) <= 0) g_hash_table_insert (view->reconciled, split, split); } } /* Free the query -- we don't need it anymore */ qof_query_destroy (query); return GTK_WIDGET (view); }
/******************************************************* * account_splits * * gather the splits / transactions for an account and * send them to a file *******************************************************/ static void account_splits (CsvExportInfo *info, Account *acc, FILE *fh ) { Query *q; GSList *p1, *p2; GList *splits; QofBook *book; q = qof_query_create_for (GNC_ID_SPLIT); book = gnc_get_current_book(); qof_query_set_book (q, book); /* Sort by transaction date */ p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED); p1 = g_slist_prepend (p1, SPLIT_TRANS); p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT); qof_query_set_sort_order (q, p1, p2, NULL); xaccQueryAddSingleAccountMatch (q, acc, QOF_QUERY_AND); xaccQueryAddDateMatchTT (q, TRUE, info->csvd.start_time, TRUE, info->csvd.end_time, QOF_QUERY_AND); /* Run the query */ for (splits = qof_query_run (q); splits; splits = splits->next) { Split *split; Transaction *trans; SplitList *s_list; GList *node; Split *t_split; int nSplits; int cnt; gchar *line; split = splits->data; trans = xaccSplitGetParent (split); nSplits = xaccTransCountSplits (trans); s_list = xaccTransGetSplitList (trans); // Look for trans already exported in trans_list if (g_list_find (info->trans_list, trans) != NULL) continue; // Simple Layout if (info->simple_layout) { line = make_simple_trans_line (acc, trans, split, info); /* Write to file */ if (!write_line_to_file (fh, line)) { info->failed = TRUE; break; } g_free (line); continue; } // Complex Transaction Line. line = make_complex_trans_line (acc, trans, split, info); /* Write to file */ if (!write_line_to_file (fh, line)) { info->failed = TRUE; break; } g_free (line); /* Loop through the list of splits for the Transaction */ node = s_list; cnt = 0; while ((cnt < nSplits) && (info->failed == FALSE)) { t_split = node->data; // Complex Split Line. line = make_complex_split_line (trans, t_split, info); if (!write_line_to_file (fh, line)) info->failed = TRUE; g_free (line); cnt++; node = node->next; } info->trans_list = g_list_prepend (info->trans_list, trans); // add trans to trans_list } qof_query_destroy (q); g_list_free (splits); }
static void gnc_query_list_fill(GNCQueryList *list) { GNCQueryListPriv *priv; gchar *strings[list->num_columns + 1]; GList *entries, *item; const GncGUID *guid; gint i; /* Clear all watches */ priv = GNC_QUERY_LIST_GET_PRIVATE(list); gnc_gui_component_clear_watches (priv->component_id); /* Reverse the list now because 'append()' takes too long */ entries = qof_query_run(list->query); for (item = entries; item; item = item->next) { GList *node; gint row; const QofParam *gup; QofParam *qp = NULL; for (i = 0, node = list->column_params; node; node = node->next) { GNCSearchParam *param = node->data; GSList *converters = gnc_search_param_get_converters (param); const char *type = gnc_search_param_get_param_type (param); gpointer res = item->data; /* if this is a boolean, ignore it now -- we'll use a checkmark later */ if (!safe_strcmp (type, QOF_TYPE_BOOLEAN)) { strings[i++] = g_strdup(""); continue; } /* Do all the object conversions */ for (; converters; converters = converters->next) { qp = converters->data; if (converters->next) { res = (qp->param_getfcn)(res, qp); } } /* Now convert this to a text value for the row */ if (!safe_strcmp(type, QOF_TYPE_DEBCRED) || !safe_strcmp(type, QOF_TYPE_NUMERIC)) { gnc_numeric (*nfcn)(gpointer, QofParam *) = (gnc_numeric(*)(gpointer, QofParam *))(qp->param_getfcn); gnc_numeric value = nfcn(res, qp); if (list->numeric_abs) value = gnc_numeric_abs (value); strings[i++] = g_strdup(xaccPrintAmount(value, gnc_default_print_info(FALSE))); } else strings[i++] = qof_query_core_to_string (type, res, qp); } row = gtk_clist_append (GTK_CLIST(list), (gchar **) strings); gtk_clist_set_row_data (GTK_CLIST(list), row, item->data); /* Free up our strings */ for (i = 0; i < list->num_columns; i++) { if (strings[i]) g_free (strings[i]); } /* Now update any checkmarks */ update_booleans (list, row); /* and set a watcher on this item */ gup = priv->get_guid; guid = (const GncGUID*)((gup->param_getfcn)(item->data, gup)); gnc_gui_component_watch_entity (priv->component_id, guid, QOF_EVENT_MODIFY | QOF_EVENT_DESTROY); list->num_entries++; } }
static GNCLedgerDisplay * gnc_ledger_display_internal (Account *lead_account, Query *q, GNCLedgerDisplayType ld_type, SplitRegisterType reg_type, SplitRegisterStyle style, gboolean use_double_line, gboolean is_template ) { GNCLedgerDisplay *ld; gint limit; const char *klass; GList *splits; switch (ld_type) { case LD_SINGLE: klass = REGISTER_SINGLE_CM_CLASS; if (reg_type >= NUM_SINGLE_REGISTER_TYPES) { PERR ("single-account register with wrong split register type"); return NULL; } if (!lead_account) { PERR ("single-account register with no account specified"); return NULL; } if (q) { PWARN ("single-account register with external query"); q = NULL; } ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account); if (ld) return ld; break; case LD_SUBACCOUNT: klass = REGISTER_SUBACCOUNT_CM_CLASS; if (!lead_account) { PERR ("sub-account register with no lead account"); return NULL; } if (q) { PWARN ("account register with external query"); q = NULL; } ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account); if (ld) return ld; break; case LD_GL: klass = REGISTER_GL_CM_CLASS; if (!q) { PWARN ("general journal with no query"); } break; default: PERR ("bad ledger type: %d", ld_type); return NULL; } ld = g_new (GNCLedgerDisplay, 1); ld->leader = *xaccAccountGetGUID (lead_account); ld->query = NULL; ld->ld_type = ld_type; ld->loading = FALSE; ld->destroy = NULL; ld->get_parent = NULL; ld->user_data = NULL; limit = gnc_prefs_get_float(GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_MAX_TRANS); /* set up the query filter */ if (q) ld->query = qof_query_copy (q); else gnc_ledger_display_make_query (ld, limit, reg_type); ld->component_id = gnc_register_gui_component (klass, refresh_handler, close_handler, ld); /******************************************************************\ * The main register window itself * \******************************************************************/ ld->use_double_line_default = use_double_line; ld->reg = gnc_split_register_new (reg_type, style, use_double_line, is_template); gnc_split_register_set_data (ld->reg, ld, gnc_ledger_display_parent); splits = qof_query_run (ld->query); gnc_ledger_display_set_watches (ld, splits); gnc_ledger_display_refresh_internal (ld, splits); return ld; }
qof_query_set_book(qr, ::gnc_account_get_book(selectedAccount)); // To look for dates, you need to create a "PredData" object Timespec calve_date; //calve_date = gdate_to_timespec(trans.getGDatePosted()); QofQueryPredData *pred_data = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, calve_date); // and additionally a "query parameter" object GSList *param_list = qof_query_build_param_list (TRANS_DATE_POSTED, NULL); // The "PredData" and the "query parameter" object are added to this query qof_query_add_term (qr, param_list, pred_data, QOF_QUERY_FIRST_TERM); // Query is run; result is returned GList *result = qof_query_run (qr); SplitQList querySplitList = Split::fromGList(result); Split qSplit; int numOfQuerSplits = querySplitList.count(); for(i=0; i < numOfQuerSplits; ++i) { qSplit = querySplitList.at(i); //qDebug()<<qSplit.getCorrAccountName(); qDebug()<<qSplit.getParent().getDatePosted().toString(); } // "result" is now a GList of "Transaction*" because at //qof_query_create_for, we've asked for transactions.
/******************************************************* * account_splits * * gather the splits / transactions for an account and * send them to a file *******************************************************/ static void account_splits (CsvExportInfo *info, Account *acc, FILE *fh ) { Query *q; GSList *p1, *p2; GList *splits; QofBook *book; gchar *end_sep; gchar *mid_sep; q = qof_query_create_for(GNC_ID_SPLIT); book = gnc_get_current_book(); qof_query_set_book (q, book); /* Set up separators */ if (info->use_quotes) { end_sep = "\""; mid_sep = g_strconcat ( "\"", info->separator_str, "\"", NULL); } else { end_sep = ""; mid_sep = g_strconcat ( info->separator_str, NULL); } /* Sort by transaction date */ p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED); p1 = g_slist_prepend (p1, SPLIT_TRANS); p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT); qof_query_set_sort_order (q, p1, p2, NULL); xaccQueryAddSingleAccountMatch (q, acc, QOF_QUERY_AND); xaccQueryAddDateMatchTT (q, TRUE, info->csvd.start_time, TRUE, info->csvd.end_time, QOF_QUERY_AND); /* Run the query */ for (splits = qof_query_run(q); splits; splits = splits->next) { Split *split; Transaction *trans; SplitList *s_list; GList *node; Split *t_split; int nSplits; int cnt; gchar *part1; gchar *part2; gchar *date; const gchar *currentSel; const gchar *split_amount; split = splits->data; trans = xaccSplitGetParent(split); nSplits = xaccTransCountSplits(trans); s_list = xaccTransGetSplitList(trans); /* Date */ date = qof_print_date ( xaccTransGetDate(trans)); part1 = g_strconcat ( end_sep, date, mid_sep, NULL); g_free(date); /* Name */ currentSel = xaccAccountGetName(acc); part2 = g_strconcat ( part1, currentSel, mid_sep, NULL); g_free(part1); /* Number */ currentSel = gnc_get_num_action(trans, NULL); part1 = g_strconcat ( part2, currentSel, mid_sep, NULL); g_free(part2); /* Description */ currentSel = xaccTransGetDescription(trans); part2 = g_strconcat ( part1, currentSel, mid_sep, NULL); g_free(part1); /* Notes */ currentSel = xaccTransGetNotes(trans); if (currentSel == NULL) part1 = g_strconcat ( part2, mid_sep, NULL); else part1 = g_strconcat ( part2, currentSel, mid_sep, NULL); g_free(part2); /* Memo */ currentSel = xaccSplitGetMemo(split); part2 = g_strconcat ( part1, currentSel, mid_sep, NULL); g_free(part1); /* Category */ currentSel = xaccSplitGetCorrAccountName(split); part1 = g_strconcat ( part2, currentSel, mid_sep, "T", mid_sep, NULL); g_free(part2); /* Action */ currentSel = gnc_get_num_action(NULL, split); part2 = g_strconcat ( part1, currentSel, mid_sep, NULL); g_free(part1); /* Reconcile */ switch (xaccSplitGetReconcile (split)) { case NREC: currentSel = "N"; break; case CREC: currentSel = "C"; break; case YREC: currentSel = "Y"; break; case FREC: currentSel = "F"; break; case VREC: currentSel = "V"; break; default: currentSel = "N"; } part1 = g_strconcat ( part2, currentSel, mid_sep, NULL); g_free(part2); /* To with Symbol */ split_amount = xaccPrintAmount(xaccSplitGetAmount(split), gnc_split_amount_print_info(split, TRUE)); part2 = g_strconcat ( part1, split_amount, mid_sep, NULL); g_free(part1); /* From with Symbol */ part1 = g_strconcat ( part2, "", mid_sep, NULL); g_free(part2); /* To Number Only */ split_amount = xaccPrintAmount(xaccSplitGetAmount(split), gnc_split_amount_print_info(split, FALSE)); part2 = g_strconcat ( part1, split_amount, mid_sep, NULL); g_free(part1); /* From Number Only */ part1 = g_strconcat ( part2, "", mid_sep, "", mid_sep, "", end_sep, "\n", NULL); g_free(part2); /* Write to file */ if (!write_line_to_file(fh, part1)) { info->failed = TRUE; break; } g_free(part1); /* Loop through the list of splits for the Transcation */ node = s_list; cnt = 0; while ( (cnt < nSplits) && (info->failed == FALSE)) { t_split = node->data; /* Start of line */ part1 = g_strconcat ( end_sep, mid_sep, mid_sep, mid_sep, mid_sep, mid_sep, NULL); /* Memo */ currentSel = xaccSplitGetMemo(t_split); part2 = g_strconcat ( part1, currentSel, mid_sep, NULL); g_free(part1); /* Account */ currentSel = xaccAccountGetName( xaccSplitGetAccount(t_split)); part1 = g_strconcat ( part2, currentSel, mid_sep, "S", mid_sep, NULL); g_free(part2); /* Action */ currentSel = gnc_get_num_action(NULL, t_split); part2 = g_strconcat ( part1, currentSel, mid_sep, NULL); g_free(part1); /* Reconcile */ switch (xaccSplitGetReconcile (split)) { case NREC: currentSel = "N"; break; case CREC: currentSel = "C"; break; case YREC: currentSel = "Y"; break; case FREC: currentSel = "F"; break; case VREC: currentSel = "V"; break; default: currentSel = "N"; } part1 = g_strconcat ( part2, currentSel, mid_sep, NULL); g_free(part2); /* From / To with Symbol */ split_amount = xaccPrintAmount(xaccSplitGetAmount(t_split), gnc_split_amount_print_info(t_split, TRUE)); if (xaccSplitGetAccount(t_split) == acc) part2 = g_strconcat ( part1, split_amount, mid_sep, mid_sep, NULL); else part2 = g_strconcat ( part1, mid_sep, split_amount, mid_sep, NULL); g_free(part1); /* From / To Numbers only */ split_amount = xaccPrintAmount(xaccSplitGetAmount(t_split), gnc_split_amount_print_info(t_split, FALSE)); if (xaccSplitGetAccount(t_split) == acc) part1 = g_strconcat ( part2, split_amount, mid_sep, mid_sep, NULL); else part1 = g_strconcat ( part2, mid_sep, split_amount, mid_sep, NULL); g_free(part2); /* From / To - Share Price / Conversion factor */ split_amount = xaccPrintAmount(xaccSplitGetSharePrice(t_split), gnc_split_amount_print_info(t_split, FALSE)); if (xaccSplitGetAccount(t_split) == acc) part2 = g_strconcat ( part1, split_amount, mid_sep, end_sep, "\n", NULL); else part2 = g_strconcat ( part1, mid_sep, split_amount, end_sep, "\n", NULL); g_free(part1); if (!write_line_to_file(fh, part2)) info->failed = TRUE; g_free(part2); cnt++; node = node->next; } } g_free(mid_sep); qof_query_destroy (q); g_list_free( splits ); }
int main (int argc, char *argv[]) { int err, fake_argc = 1; char * fake_argv[] = {"hello", 0}; QofBook *book; Account *root; char *request_bufp, *reply_bufp; int rc, sz; /* intitialize the engine */ gnc_engine_init (fake_argc, fake_argv); /* contact the database, which is a flat file for this demo */ /* this should really be an SQL server */ book = qof_book_new (); rc = gnc_book_begin (book, "file:/tmp/demo.gnucash", FALSE); if (!rc) goto bookerrexit; rc = gnc_book_load (book); if (!rc) goto bookerrexit; /* the root pointer points to our local cache of the data */ root = gnc_book_get_root_account (book); /* --------------------------------------------------- */ /* done with initialization, go into event loop */ while (FCGI_Accept() >= 0) { GList *split_list; Query *q = NULL; const char *request_method; const char *user_agent; const char *auth_string; const char *content_length; gchar guidstr[GUID_ENCODING_LENGTH+1]; int read_len = 0; int send_accts = 0; /* get the user agent; reject if wrong agent */ user_agent = getenv ("HTTP_USER_AGENT"); if (strncmp ("gnucash", user_agent, 7)) { reject_user_agent (user_agent); continue; } /* get the request method */ request_method = getenv ("REQUEST_METHOD"); if (strcmp ("POST", request_method)) { /* method=post is the only spported method*/ reject_method(request_method); continue; } /* ----------------------------------------------- */ /* look for an authentication cookie */ auth_string = find_cookie ("gnc-server"); /* found the cookie, lets make sure that it is valid */ if (auth_string) { gboolean valid_session; valid_session = have_session (auth_string); if (!valid_session) { /* XXX invalid sessions are a sign of hacking; * this event should be noted in a security log * and the server admin contacted. */ reject_session (auth_string); continue; } } /* go ahead and read the message body. * we'll need this soon enough */ content_length = getenv("CONTENT_LENGTH"); read_len = atoi (content_length); /* read 'read_len' bytes from stdin ... */ request_bufp = (char *) g_malloc (read_len); fread (request_bufp, read_len, 1, stdin); /* if no previously authenticated session, * authenticate now */ if (!auth_string) { char *name = NULL, *passwd = NULL; parse_for_login (request_bufp, &name, &passwd); auth_string = auth_user (name, passwd, guidstr); if (!auth_string) { reject_auth(); g_free (request_bufp); continue; } send_accts = 1; } /* ----------------------------------------------- */ /* send only the accounts to the user */ if (send_accts) { /* print the HTTP header */ printf("Content-type: text/gnc-xml\r\n" "Set-Cookie: %s\r\n" "Content-Length: %d\r\n" "\r\n", auth_string, sz); /* since this is the first time the user is logging * in, send them the full set of accounts. * (Do not send them any transactions yet). */ gncxml_write_account_tree_to_buf(root, &reply_bufp, &sz); /* send the xml to the client */ printf ("%s", reply_bufp); g_free (request_bufp); /* wait for the next request */ continue; } /* ----------------------------------------------- */ /* If we got to here, then the ser should be sending * us a query xml. * we should somehow error check that what we got * is really a valid query */ /* conver the xml input into a gnucash query structure... */ q = gncxml_read_query (request_bufp, read_len); xaccQuerySetGroup (q, root); /* hack -- limit to 30 splits ... */ qof_query_set_max_results (q, 30); split_list = qof_query_run (q); /* poke those splits into an ccount group structure */ /* XXX not implemented */ /* send the account group structure back to the user */ /* XXX not implemented */ qof_query_destroy (q); g_free (request_bufp); } bookerrexit: err = gnc_book_get_error (book); /* 500 Server Error */ FCGI_SetExitStatus (500); printf("Content-type: text/plain\r\n\r\n" "error was %s\n", strerror (err)); FCGI_Finish(); /* close the book */ qof_book_destroy (book); /* shut down the engine */ gnc_engine_shutdown (); sleep (1); /* must return a non-zero error code, otherwise fastcgi * attempts to respawn this daemon. */ return 500; }