Beispiel #1
0
void
xaccAccountAssignLots (Account *acc)
{
    SplitList *splits, *node;

    if (!acc) return;

    ENTER ("acc=%s", xaccAccountGetName(acc));
    xaccAccountBeginEdit (acc);

restart_loop:
    splits = xaccAccountGetSplitList(acc);
    for (node = splits; node; node = node->next)
    {
        Split * split = node->data;

        /* If already in lot, then no-op */
        if (split->lot) continue;

        /* Skip voided transactions */
        if (gnc_numeric_zero_p (split->amount) &&
                xaccTransGetVoidStatus(split->parent)) continue;

        if (xaccSplitAssign (split)) goto restart_loop;
    }
    xaccAccountCommitEdit (acc);
    LEAVE ("acc=%s", xaccAccountGetName(acc));
}
Beispiel #2
0
void
xaccLotFill (GNCLot *lot)
{
    Account *acc;
    Split *split;
    GNCPolicy *pcy;

    if (!lot) return;
    acc = gnc_lot_get_account(lot);
    pcy = gnc_account_get_policy(acc);

    ENTER ("(lot=%s, acc=%s)", gnc_lot_get_title(lot), xaccAccountGetName(acc));

    /* If balance already zero, we have nothing to do. */
    if (gnc_lot_is_closed (lot)) return;

    split = pcy->PolicyGetSplit (pcy, lot);
    if (!split) return;   /* Handle the common case */

    /* Reject voided transactions */
    if (gnc_numeric_zero_p(split->amount) &&
            xaccTransGetVoidStatus(split->parent)) return;

    xaccAccountBeginEdit (acc);

    /* Loop until we've filled up the lot, (i.e. till the
     * balance goes to zero) or there are no splits left.  */
    while (1)
    {
        Split *subsplit;

        subsplit = xaccSplitAssignToLot (split, lot);
        if (subsplit == split)
        {
            PERR ("Accounting Policy gave us a split that "
                  "doesn't fit into this lot\n"
                  "lot baln=%s, isclosed=%d, aplit amt=%s",
                  gnc_num_dbg_to_string (gnc_lot_get_balance(lot)),
                  gnc_lot_is_closed (lot),
                  gnc_num_dbg_to_string (split->amount));
            break;
        }

        if (gnc_lot_is_closed (lot)) break;

        split = pcy->PolicyGetSplit (pcy, lot);
        if (!split) break;
    }
    xaccAccountCommitEdit (acc);
    LEAVE ("(lot=%s, acc=%s)", gnc_lot_get_title(lot), xaccAccountGetName(acc));
}
static gchar*
make_simple_trans_line (Account *acc, Transaction *trans, Split *split, CsvExportInfo *info)
{
    gboolean t_void = xaccTransGetVoidStatus (trans);

    gchar *result = begin_trans_string (trans, info);
    result = add_account_name (result, acc, NULL, TRUE, info);
    result = add_number (result, trans, info);
    result = add_description (result, trans, info);
    result = add_category (result, split, TRUE, info);
    result = add_reconcile (result, split, info);
    result = add_amount (result, split, t_void, TRUE, TRANS_SIMPLE, info);
    result = add_amount (result, split, t_void, FALSE, TRANS_SIMPLE, info);
    result = add_rate (result, split, t_void, info);
    return result;
}
static gchar*
make_complex_split_line (Transaction *trans, Split *split, CsvExportInfo *info)
{
    gboolean t_void = xaccTransGetVoidStatus (trans);

    gchar *result = begin_split_string (trans, split, t_void, info);
    result = add_memo (result, split, info);
    result = add_account_name (result, NULL, split, TRUE, info);
    result = add_account_name (result, NULL, split, FALSE, info);
    result = add_line_type (result, SPLIT_LINE, info);
    result = add_action (result,split, SPLIT_LINE, info);
    result = add_reconcile (result, split, info);
    result = add_amount (result, split, t_void, TRUE, SPLIT_LINE, info);
    result = add_comm_mnemonic (result, trans, split, info);
    result = add_comm_namespace (result, trans, split, info);
    result = add_amount (result, split, t_void, FALSE, SPLIT_LINE, info);
    result = add_price (result, split, t_void, info);
    return result;
}
Beispiel #5
0
void
gncScrubBusinessSplit (Split *split)
{
    const gchar *memo = _("Please delete this transaction. Explanation at http://wiki.gnucash.org/wiki/Business_Features_Issues#Double_Posting");
    Transaction *txn;

    if (!split) return;
    ENTER ("(split=%p)", split);

    txn = xaccSplitGetParent (split);
    if (txn)
    {
        gchar txntype = xaccTransGetTxnType (txn);
        const gchar *read_only = xaccTransGetReadOnly (txn);
        gboolean is_void = xaccTransGetVoidStatus (txn);
        GNCLot *lot = xaccSplitGetLot (split);

        /* Look for transactions as a result of double posting an invoice or bill
         * Refer to https://bugzilla.gnome.org/show_bug.cgi?id=754209
         * to learn how this could have happened in the past.
         * Characteristics of such transaction are:
         * - read only
         * - not voided (to ensure read only is set by the business functions)
         * - transaction type is none (should be type invoice for proper post transactions)
         * - assigned to a lot
         */
        if ((txntype == TXN_TYPE_NONE) && read_only && !is_void && lot)
        {
            gchar *txn_date = qof_print_date (xaccTransGetDateEntered (txn));
            xaccTransClearReadOnly (txn);
            xaccSplitSetMemo (split, memo);
            gnc_lot_remove_split (lot, split);
            PWARN("Cleared double post status of transaction \"%s\", dated %s. "
                  "Please delete transaction and verify balance.",
                  xaccTransGetDescription (txn),
                  txn_date);
            g_free (txn_date);
        }

    }

    LEAVE ("(split=%p)", split);
}
static gchar*
make_complex_trans_line (Account *acc, Transaction *trans, Split *split, CsvExportInfo *info)
{
    gboolean t_void = xaccTransGetVoidStatus (trans);

    gchar *result = begin_trans_string (trans, info);
    result = add_type (result, trans, info);
    result = add_second_date (result, trans, info);
    result = add_account_name (result, acc, NULL, FALSE, info);
    result = add_number (result, trans, info);
    result = add_description (result, trans, info);
    result = add_notes (result, trans, info);
    result = add_memo (result, split, info);
    result = add_category (result, split, TRUE, info);
    result = add_category (result, split, FALSE, info);
    result = add_line_type (result, TRANS_COMPLEX, info);
    result = add_action (result,split, TRANS_COMPLEX, info);
    result = add_reconcile (result, split, info);
    result = add_amount (result, split, t_void, TRUE, TRANS_COMPLEX, info);
    result = add_comm_mnemonic (result, trans, NULL, info);
    result = add_comm_namespace (result, trans, NULL, info);
    result = add_trans_eol (result, info);
    return result;
}