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;
}
static void
gnc_ledger_display_make_query (GNCLedgerDisplay *ld,
                               gint limit,
                               SplitRegisterType type)
{
    Account *leader;
    GList *accounts;

    if (!ld)
        return;

    switch (ld->ld_type)
    {
    case LD_SINGLE:
    case LD_SUBACCOUNT:
        break;

    case LD_GL:
        return;

    default:
        PERR ("unknown ledger type: %d", ld->ld_type);
        return;
    }

    qof_query_destroy (ld->query);
    ld->query = qof_query_create_for(GNC_ID_SPLIT);

    /* This is a bit of a hack. The number of splits should be
     * configurable, or maybe we should go back a time range instead
     * of picking a number, or maybe we should be able to exclude
     * based on reconciled status. Anyway, this works for now. */
    if ((limit != 0) && (type != SEARCH_LEDGER))
        qof_query_set_max_results (ld->query, limit);

    qof_query_set_book (ld->query, gnc_get_current_book());

    leader = gnc_ledger_display_leader (ld);

    if (ld->ld_type == LD_SUBACCOUNT)
        accounts = gnc_account_get_descendants (leader);
    else
        accounts = NULL;

    accounts = g_list_prepend (accounts, leader);

    xaccQueryAddAccountMatch (ld->query, accounts,
                              QOF_GUID_MATCH_ANY, QOF_QUERY_AND);

    g_list_free (accounts);
}
/** Creates a new query that searches for an GncEntry item with
 * description string equal to the given "desc" argument. The query
 * will find the single GncEntry with the latest (=newest)
 * DATE_ENTERED. */
static QofQuery *new_query_for_entry_desc(GncEntryLedger *reg, const char* desc, gboolean use_invoice)
{
    QofQuery *query = NULL;
    QofQueryPredData *predData = NULL;
    GSList *param_list = NULL;
    GSList *primary_sort_params = NULL;
    const char* should_be_null = (use_invoice ? ENTRY_BILL : ENTRY_INVOICE);

    g_assert(reg);
    g_assert(desc);

    /* The query itself and its book */
    query = qof_query_create_for (GNC_ID_ENTRY);
    qof_query_set_book (query, reg->book);

    /* Predicate data: We want to compare one string, namely the given
     * argument */
    predData =
        qof_query_string_predicate (QOF_COMPARE_EQUAL, desc,
                                    QOF_STRING_MATCH_CASEINSENSITIVE, FALSE);

    /* Search Parameter: We want to query on the ENTRY_DESC column */
    param_list = qof_query_build_param_list (ENTRY_DESC, NULL);

    /* Register this in the query */
    qof_query_add_term (query, param_list, predData, QOF_QUERY_FIRST_TERM);

    /* For invoice entries, Entry->Bill must be NULL, and vice versa */
    qof_query_add_guid_match (query,
                              qof_query_build_param_list (should_be_null,
                                      QOF_PARAM_GUID, NULL),
                              NULL, QOF_QUERY_AND);

    /* Set the sort order: By DATE_ENTERED, increasing, and returning
     * only one single resulting item. */
    primary_sort_params = qof_query_build_param_list(ENTRY_DATE_ENTERED, NULL);
    qof_query_set_sort_order (query, primary_sort_params, NULL, NULL);
    qof_query_set_sort_increasing (query, TRUE, TRUE, TRUE);

    qof_query_set_max_results(query, 1);

    return query;
}
Exemple #4
0
/*******************************************************************
 * 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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}