// Description static gchar* add_description (gchar *so_far, Transaction *trans, CsvExportInfo *info) { const gchar *desc; gchar *conv; gchar *result; desc = xaccTransGetDescription (trans) ? xaccTransGetDescription (trans) : "" ; conv = csv_txn_test_field_string (info, desc); result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (conv); g_free (so_far); return result; }
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; }
gboolean xaccScrubMergeSubSplits (Split *split, gboolean strict) { gboolean rc = FALSE; Transaction *txn; SplitList *node; GNCLot *lot; if (strict && (FALSE == is_subsplit (split))) return FALSE; txn = split->parent; // Don't mess with splits from an invoice transaction // Those are the responsibility of the business code if (gncInvoiceGetInvoiceFromTxn (txn)) return FALSE; lot = xaccSplitGetLot (split); ENTER ("(Lot=%s)", gnc_lot_get_title(lot)); restart: for (node = txn->splits; node; node = node->next) { Split *s = node->data; if (xaccSplitGetLot (s) != lot) continue; if (s == split) continue; if (qof_instance_get_destroying(s)) continue; // Don't mess with splits from an invoice transaction // Those are the responsibility of the business code if (gncInvoiceGetInvoiceFromTxn (s->parent)) return FALSE; if (strict) { /* OK, this split is in the same lot (and thus same account) * as the indicated split. Make sure it is really a subsplit * of the split we started with. It's possible to have two * splits in the same lot and transaction that are not subsplits * of each other, the test-period test suite does this, for * example. Only worry about adjacent sub-splits. By * repeatedly merging adjacent subsplits, we'll get the non- * adjacent ones too. */ if (!xaccSplitIsPeerSplit (split, s)) continue; } merge_splits (split, s); rc = TRUE; goto restart; } if (rc && gnc_numeric_zero_p (split->amount)) { time64 pdate = xaccTransGetDate (txn); gchar *pdatestr = gnc_ctime (&pdate); PWARN ("Result of merge has zero amt!"); PWARN ("Transaction details - posted date %s - description %s", pdatestr, xaccTransGetDescription(txn)); g_free (pdatestr); } LEAVE (" splits merged=%d", rc); return rc; }
gboolean gnc_ui_payment_is_customer_payment(const Transaction *txn) { SplitList *slist; gboolean result = TRUE; Split *assetaccount_split; gnc_numeric amount; if (!txn) return result; // We require the txn to have one split in an A/R or A/P account. slist = xaccTransGetSplitList(txn); if (!slist) return result; if (countAssetAccounts(slist) == 0) { g_message("No asset splits in txn \"%s\"; cannot use this for assigning a payment.", xaccTransGetDescription(txn)); return result; } assetaccount_split = getFirstAssetAccountSplit(slist); amount = xaccSplitGetValue(assetaccount_split); result = gnc_numeric_positive_p(amount); // positive amounts == customer //g_message("Amount=%s", gnc_numeric_to_string(amount)); return result; }
static void add_quickfill_completions(TableLayout *layout, Transaction *trans, Split *split, gboolean has_last_num) { Split *s; int i = 0; gnc_quickfill_cell_add_completion( (QuickFillCell *) gnc_table_layout_get_cell(layout, DESC_CELL), xaccTransGetDescription(trans)); gnc_quickfill_cell_add_completion( (QuickFillCell *) gnc_table_layout_get_cell(layout, NOTES_CELL), xaccTransGetNotes(trans)); if (!has_last_num) gnc_num_cell_set_last_num( (NumCell *) gnc_table_layout_get_cell(layout, NUM_CELL), gnc_get_num_action(trans, split)); while ((s = xaccTransGetSplit(trans, i)) != NULL) { gnc_quickfill_cell_add_completion( (QuickFillCell *) gnc_table_layout_get_cell(layout, MEMO_CELL), xaccSplitGetMemo(s)); i++; } }
xmlNodePtr gnc_transaction_dom_tree_create(Transaction *trn) { xmlNodePtr ret; gchar *str = NULL; ret = xmlNewNode(NULL, BAD_CAST "gnc:transaction"); xmlSetProp(ret, BAD_CAST "version", BAD_CAST transaction_version_string); xmlAddChild(ret, guid_to_dom_tree("trn:id", xaccTransGetGUID(trn))); xmlAddChild(ret, commodity_ref_to_dom_tree("trn:currency", xaccTransGetCurrency(trn))); str = g_strdup (xaccTransGetNum(trn)); if (str && (g_strcmp0(str, "") != 0)) { xmlNewTextChild(ret, NULL, BAD_CAST "trn:num", checked_char_cast (str)); } g_free (str); add_timespec(ret, "trn:date-posted", xaccTransRetDatePostedTS(trn), TRUE); add_timespec(ret, "trn:date-entered", xaccTransRetDateEnteredTS(trn), TRUE); str = g_strdup (xaccTransGetDescription(trn)); if (str) { xmlNewTextChild(ret, NULL, BAD_CAST "trn:description", checked_char_cast (str)); } g_free (str); { xmlNodePtr kvpnode = kvp_frame_to_dom_tree("trn:slots", xaccTransGetSlots(trn)); if (kvpnode) { xmlAddChild(ret, kvpnode); } } add_trans_splits(ret, trn); return ret; }
xmlNodePtr gnc_transaction_dom_tree_create (Transaction* trn) { xmlNodePtr ret; gchar* str = NULL; ret = xmlNewNode (NULL, BAD_CAST "gnc:transaction"); xmlSetProp (ret, BAD_CAST "version", BAD_CAST transaction_version_string); xmlAddChild (ret, guid_to_dom_tree ("trn:id", xaccTransGetGUID (trn))); xmlAddChild (ret, commodity_ref_to_dom_tree ("trn:currency", xaccTransGetCurrency (trn))); str = g_strdup (xaccTransGetNum (trn)); if (str && (g_strcmp0 (str, "") != 0)) { xmlNewTextChild (ret, NULL, BAD_CAST "trn:num", checked_char_cast (str)); } g_free (str); add_timespec (ret, "trn:date-posted", xaccTransRetDatePostedTS (trn), TRUE); add_timespec (ret, "trn:date-entered", xaccTransRetDateEnteredTS (trn), TRUE); str = g_strdup (xaccTransGetDescription (trn)); if (str) { xmlNewTextChild (ret, NULL, BAD_CAST "trn:description", checked_char_cast (str)); } g_free (str); /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ xmlAddChild (ret, qof_instance_slots_to_dom_tree ("trn:slots", QOF_INSTANCE (trn))); add_trans_splits (ret, trn); return ret; }
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 void downloaded_transaction_changed_cb (GtkTreeSelection *selection, GNCImportMatchPicker *matcher) { GNCImportMatchInfo * match_info; GtkTreeModel *dl_model; GtkListStore *match_store; GtkTreeIter iter; GList * list_element; gchar *text; const gchar *ro_text; /*DEBUG("row: %d%s%d",row,", column: ",column);*/ /* Get the transaction info from the "downloaded" model. */ if (!gtk_tree_selection_get_selected(selection, &dl_model, &iter)) { matcher->selected_trans_info = NULL; return; } gtk_tree_model_get(dl_model, &iter, DOWNLOADED_COL_INFO_PTR, &matcher->selected_trans_info, -1); /* Now rewrite the "match" model based on that trans. */ match_store = GTK_LIST_STORE(gtk_tree_view_get_model(matcher->match_view)); gtk_list_store_clear(match_store); list_element = g_list_first (gnc_import_TransInfo_get_match_list (matcher->selected_trans_info)); while (list_element != NULL) { match_info = list_element->data; gtk_list_store_append(match_store, &iter); /* Print fields. */ /* Probability */ text = g_strdup_printf("%d", gnc_import_MatchInfo_get_probability (match_info)); gtk_list_store_set(match_store, &iter, MATCHER_COL_CONFIDENCE, text, -1); g_free(text); /* Date */ text = qof_print_date ( xaccTransGetDate ( xaccSplitGetParent ( gnc_import_MatchInfo_get_split(match_info) ) )); gtk_list_store_set(match_store, &iter, MATCHER_COL_DATE, text, -1); g_free(text); /* Amount */ ro_text = xaccPrintAmount( xaccSplitGetAmount ( gnc_import_MatchInfo_get_split(match_info) ), gnc_split_amount_print_info(gnc_import_MatchInfo_get_split(match_info), TRUE) ); gtk_list_store_set(match_store, &iter, MATCHER_COL_AMOUNT, ro_text, -1); /*Description*/ ro_text = xaccTransGetDescription ( xaccSplitGetParent( gnc_import_MatchInfo_get_split(match_info)) ); gtk_list_store_set(match_store, &iter, MATCHER_COL_DESCRIPTION, ro_text, -1); /*Split memo*/ ro_text = xaccSplitGetMemo(gnc_import_MatchInfo_get_split(match_info) ); gtk_list_store_set(match_store, &iter, MATCHER_COL_MEMO, ro_text, -1); gtk_list_store_set(match_store, &iter, MATCHER_COL_INFO_PTR, match_info, -1); if (gnc_import_MatchInfo_get_probability(match_info) != 0) { if (SHOW_NUMERIC_SCORE == TRUE) { gtk_list_store_set(match_store, &iter, MATCHER_COL_CONFIDENCE_PIXBUF, gen_probability_pixbuf(gnc_import_MatchInfo_get_probability(match_info), matcher->user_settings, GTK_WIDGET(matcher->match_view)), -1); } else { gtk_list_store_set(match_store, &iter, MATCHER_COL_CONFIDENCE_PIXBUF, gen_probability_pixbuf(gnc_import_MatchInfo_get_probability(match_info), matcher->user_settings, GTK_WIDGET(matcher->match_view)), -1); } } if (match_info == gnc_import_TransInfo_get_selected_match (matcher->selected_trans_info)) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(matcher->match_view); gtk_tree_selection_select_iter(selection, &iter); } list_element = g_list_next(list_element); } }
static gboolean save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits ) { const GncGUID* guid; gint op; gboolean is_infant; QofInstance* inst; gboolean is_ok = TRUE; gchar* err = NULL; g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( pTx != NULL, FALSE ); inst = QOF_INSTANCE(pTx); is_infant = qof_instance_get_infant( inst ); if ( qof_instance_get_destroying( inst ) ) { op = OP_DB_DELETE; } else if ( be->is_pristine_db || is_infant ) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } if ( op != OP_DB_DELETE ) { gnc_commodity *commodity = xaccTransGetCurrency( pTx ); // Ensure the commodity is in the db is_ok = gnc_sql_save_commodity( be, commodity ); if ( ! is_ok ) { err = "Commodity save failed: Probably an invalid or missing currency"; qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT); } } if ( is_ok ) { is_ok = gnc_sql_do_db_operation( be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx, tx_col_table ); if ( ! is_ok ) { err = "Transaction header save failed. Check trace log for SQL errors"; } } if ( is_ok ) { // Commit slots and splits guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if ( ! is_ok ) { err = "Slots save failed. Check trace log for SQL errors"; } if ( is_ok && do_save_splits ) { is_ok = save_splits( be, guid, xaccTransGetSplitList( pTx ) ); if ( ! is_ok ) { err = "Split save failed. Check trace log for SQL errors"; } } } else { is_ok = gnc_sql_slots_delete( be, guid ); if ( ! is_ok ) { err = "Slots delete failed. Check trace log for SQL errors"; } if ( is_ok ) { is_ok = delete_splits( be, pTx ); if ( ! is_ok ) { err = "Split delete failed. Check trace log for SQL errors"; } } } } if (! is_ok ) { G_GNUC_UNUSED gchar *message1 = "Transaction %s dated %s in account %s not saved due to %s.%s"; G_GNUC_UNUSED gchar *message2 = "\nDatabase may be corrupted, check your data carefully."; Split* split = xaccTransGetSplit( pTx, 0); Account *acc = xaccSplitGetAccount( split ); /* FIXME: This needs to be implemented qof_error_format_secondary_text( GTK_MESSAGE_DIALOG( msg ), message1, xaccTransGetDescription( pTx ), qof_print_date( xaccTransGetDate( pTx ) ), xaccAccountGetName( acc ), err, message2 ); */ PERR( "Transaction %s dated %s in account %s not saved due to %s.\n", xaccTransGetDescription( pTx ), qof_print_date( xaccTransGetDate( pTx ) ), xaccAccountGetName( acc ), err ); } return is_ok; }
/* Either sets the value and amount for split and returns TRUE, or does nothing and returns FALSE. */ static gboolean gtu_sr_handle_exchange_rate (GncTreeViewSplitReg *view, gnc_numeric amount, Transaction *trans, Split *split, gboolean force) { GncTreeModelSplitReg *model; XferDialog *xfer; gboolean rate_split_ok, rate_reg_ok; gnc_numeric rate_split, rate_reg, value; Account *reg_acc; gnc_commodity *xfer_comm = xaccAccountGetCommodity (xaccSplitGetAccount (split)); gnc_commodity *reg_comm = gnc_tree_view_split_reg_get_reg_commodity (view); gnc_commodity *trans_curr = xaccTransGetCurrency (trans); gboolean expanded; gboolean have_rate = TRUE; ENTER("handle_exchange_rate amount %s, trans %p and split %p force %d", gnc_numeric_to_string (amount), trans, split, force); model = gnc_tree_view_split_reg_get_model_from_view (view); reg_acc = gnc_tree_model_split_reg_get_anchor (model); /* Rate from trans-curr to split-comm */ rate_split_ok = xaccTransGetRateForCommodity (trans, xfer_comm, split, &rate_split); DEBUG("rate_split_ok %d and xfer_comm %s", rate_split_ok, gnc_commodity_get_fullname (xfer_comm)); /* Rate from trans-curr to reg-comm */ rate_reg_ok = xaccTransGetRateForCommodity (trans, reg_comm, split, &rate_reg); DEBUG("rate_reg_ok %d and reg_comm %s", rate_reg_ok, gnc_commodity_get_fullname (reg_comm)); /* Are we expanded */ expanded = gnc_tree_view_split_reg_trans_expanded (view, trans); if (gnc_commodity_equal (trans_curr, xfer_comm) && rate_split_ok) { xaccSplitSetAmount (split, amount); xaccSplitSetValue (split, amount); return TRUE; } if (rate_reg_ok && rate_split_ok && !force) { value = gnc_numeric_div (amount, rate_reg, gnc_commodity_get_fraction (trans_curr), GNC_HOW_DENOM_REDUCE); amount = gnc_numeric_mul (value, rate_split, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND); } else { if (!rate_split_ok) rate_split = gtu_sr_get_rate_from_db (reg_comm, xfer_comm); /* create the exchange-rate dialog */ xfer = gnc_xfer_dialog (NULL, NULL); gnc_xfer_dialog_is_exchange_dialog (xfer, &rate_split); /* fill in the dialog entries */ gnc_xfer_dialog_set_description (xfer, xaccTransGetDescription (trans)); gnc_xfer_dialog_set_memo (xfer, xaccSplitGetMemo (split)); /* Get per book option */ gnc_xfer_dialog_set_num (xfer, gnc_get_num_action (trans, split)); gnc_xfer_dialog_set_date (xfer, timespecToTime64 (xaccTransRetDatePostedTS (trans))); value = amount; if (gnc_xfer_dialog_run_exchange_dialog (xfer, &rate_split, value, reg_acc, trans, xfer_comm, expanded)) { if (!rate_split_ok) rate_split = gnc_numeric_create (1, 1); have_rate = FALSE; } else have_rate = TRUE; amount = gnc_numeric_mul (value, rate_split, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND); } xaccSplitSetAmount (split, amount); xaccSplitSetValue (split, value); LEAVE("handle_exchange_rate set split %p amt=%s; and val=%s", split, gnc_numeric_to_string (amount), gnc_numeric_to_string (value)); return have_rate; }
static const char* node_and_transaction_equal (xmlNodePtr node, Transaction* trn) { xmlNodePtr mark; while (g_strcmp0 ((char*)node->name, "text") == 0) node = node->next; if (!check_dom_tree_version (node, "2.0.0")) { return "version wrong. Not 2.0.0 or not there"; } if (!node->name || g_strcmp0 ((char*)node->name, "gnc:transaction")) { return "Name of toplevel node is bad"; } for (mark = node->xmlChildrenNode; mark; mark = mark->next) { if (g_strcmp0 ((char*)mark->name, "text") == 0) { } else if (g_strcmp0 ((char*)mark->name, "trn:id") == 0) { if (!equals_node_val_vs_guid (mark, xaccTransGetGUID (trn))) { return "ids differ"; } } /* This test will fail for many splits where the transaction has * splits in different commodities -- eg, buying or selling a * stock. jralls 2010-11-02 */ else if (g_strcmp0 ((char*)mark->name, "trn:currency") == 0) { #if 0 if (!equals_node_val_vs_commodity ( mark, xaccTransGetCurrency (trn), xaccTransGetBook (trn))) { return g_strdup ("currencies differ"); } #endif } else if (g_strcmp0 ((char*)mark->name, "trn:num") == 0) { if (!equals_node_val_vs_string (mark, xaccTransGetNum (trn))) { return "nums differ"; } } else if (g_strcmp0 ((char*)mark->name, "trn:date-posted") == 0) { if (!equals_node_val_vs_date (mark, xaccTransRetDatePostedTS (trn))) { return "posted dates differ"; } } else if (g_strcmp0 ((char*)mark->name, "trn:date-entered") == 0) { if (!equals_node_val_vs_date (mark, xaccTransRetDateEnteredTS (trn))) { return "entered dates differ"; } } else if (g_strcmp0 ((char*)mark->name, "trn:description") == 0) { if (!equals_node_val_vs_string (mark, xaccTransGetDescription (trn))) { return "descriptions differ"; } } else if (g_strcmp0 ((char*)mark->name, "trn:slots") == 0) { if (!equals_node_val_vs_kvp_frame (mark, qof_instance_get_slots (QOF_INSTANCE (trn)))) { return "slots differ"; } } else if (g_strcmp0 ((char*)mark->name, "trn:splits") == 0) { const char* msg = equals_node_val_vs_splits (mark, trn); if (msg != NULL) { return msg; } } else { return "unknown node"; } } return NULL; }
/******************************************************* * 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 ); }
void xaccLotScrubDoubleBalance (GNCLot *lot) { gnc_commodity *currency = NULL; SplitList *snode; GList *node; gnc_numeric zero = gnc_numeric_zero(); gnc_numeric value = zero; if (!lot) return; ENTER ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title")); for (snode = gnc_lot_get_split_list(lot); snode; snode = snode->next) { Split *s = snode->data; xaccSplitComputeCapGains (s, NULL); } /* We double-check only closed lots */ if (FALSE == gnc_lot_is_closed (lot)) return; for (snode = gnc_lot_get_split_list(lot); snode; snode = snode->next) { Split *s = snode->data; Transaction *trans = s->parent; /* Check to make sure all splits in the lot have a common currency */ if (NULL == currency) { currency = trans->common_currency; } if (FALSE == gnc_commodity_equiv (currency, trans->common_currency)) { /* This lot has mixed currencies. Can't double-balance. * Silently punt */ PWARN ("Lot with multiple currencies:\n" "\ttrans=%s curr=%s", xaccTransGetDescription(trans), gnc_commodity_get_fullname(trans->common_currency)); break; } /* Now, total up the values */ value = gnc_numeric_add (value, xaccSplitGetValue (s), GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT); PINFO ("Split=%p value=%s Accum Lot value=%s", s, gnc_num_dbg_to_string (s->value), gnc_num_dbg_to_string (value)); } if (FALSE == gnc_numeric_equal (value, zero)) { /* Unhandled error condition. Not sure what to do here, * Since the ComputeCapGains should have gotten it right. * I suppose there might be small rounding errors, a penny or two, * the ideal thing would to figure out why there's a rounding * error, and fix that. */ PERR ("Closed lot fails to double-balance !! lot value=%s", gnc_num_dbg_to_string (value)); for (node = gnc_lot_get_split_list(lot); node; node = node->next) { Split *s = node->data; PERR ("s=%p amt=%s val=%s", s, gnc_num_dbg_to_string(s->amount), gnc_num_dbg_to_string(s->value)); } } LEAVE ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title")); }
void xaccScrubSubSplitPrice (Split *split, int maxmult, int maxamtscu) { gnc_numeric src_amt, src_val; SplitList *node; if (FALSE == is_subsplit (split)) return; ENTER (" "); /* Get 'price' of the indicated split */ src_amt = xaccSplitGetAmount (split); src_val = xaccSplitGetValue (split); /* Loop over splits, adjust each so that it has the same * ratio (i.e. price). Change the value to get things * right; do not change the amount */ for (node = split->parent->splits; node; node = node->next) { Split *s = node->data; Transaction *txn = s->parent; gnc_numeric dst_amt, dst_val, target_val; gnc_numeric frac, delta; int scu; /* Skip the reference split */ if (s == split) continue; scu = gnc_commodity_get_fraction (txn->common_currency); dst_amt = xaccSplitGetAmount (s); dst_val = xaccSplitGetValue (s); frac = gnc_numeric_div (dst_amt, src_amt, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE); target_val = gnc_numeric_mul (frac, src_val, scu, GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP); if (gnc_numeric_check (target_val)) { PERR ("Numeric overflow of value\n" "\tAcct=%s txn=%s\n" "\tdst_amt=%s src_val=%s src_amt=%s\n", xaccAccountGetName (s->acc), xaccTransGetDescription(txn), gnc_num_dbg_to_string(dst_amt), gnc_num_dbg_to_string(src_val), gnc_num_dbg_to_string(src_amt)); continue; } /* If the required price changes are 'small', do nothing. * That is a case that the user will have to deal with * manually. This routine is really intended only for * a gross level of synchronization. */ delta = gnc_numeric_sub_fixed (target_val, dst_val); delta = gnc_numeric_abs (delta); if (maxmult * delta.num < delta.denom) continue; /* If the amount is small, pass on that too */ if ((-maxamtscu < dst_amt.num) && (dst_amt.num < maxamtscu)) continue; /* Make the actual adjustment */ xaccTransBeginEdit (txn); xaccSplitSetValue (s, target_val); xaccTransCommitEdit (txn); } LEAVE (" "); }
static gboolean gncScrubLotDanglingPayments (GNCLot *lot) { SplitList * split_list, *filtered_list = NULL, *match_list = NULL, *node; Split *ll_split = gnc_lot_get_earliest_split (lot); Transaction *ll_trans = xaccSplitGetParent (ll_split); gnc_numeric ll_val = xaccSplitGetValue (ll_split); time64 ll_date = xaccTransGetDate (ll_trans); const char *ll_desc = xaccTransGetDescription (ll_trans); // look for free splits (i.e. not in any lot) which, // compared to the lot link split // - have the same date // - have the same description // - have an opposite sign amount // - free split's abs value is less than or equal to ll split's abs value split_list = xaccAccountGetSplitList(gnc_lot_get_account (lot)); for (node = split_list; node; node = node->next) { Split *free_split = node->data; Transaction *free_trans; gnc_numeric free_val; if (NULL != xaccSplitGetLot(free_split)) continue; free_trans = xaccSplitGetParent (free_split); if (ll_date != xaccTransGetDate (free_trans)) continue; if (0 != g_strcmp0 (ll_desc, xaccTransGetDescription (free_trans))) continue; free_val = xaccSplitGetValue (free_split); if (gnc_numeric_positive_p (ll_val) == gnc_numeric_positive_p (free_val)) continue; if (gnc_numeric_compare (gnc_numeric_abs (free_val), gnc_numeric_abs (ll_val)) > 0) continue; filtered_list = g_list_append(filtered_list, free_split); } match_list = gncSLFindOffsSplits (filtered_list, ll_val); g_list_free (filtered_list); for (node = match_list; node; node = node->next) { Split *match_split = node->data; gnc_lot_add_split (lot, match_split); } if (match_list) { g_list_free (match_list); return TRUE; } else return FALSE; }
static guint sxftd_add_template_trans(SXFromTransInfo *sxfti) { Transaction *tr = sxfti->trans; GList *tt_list = NULL; GList *splits, *template_splits = NULL; TTInfo *tti = gnc_ttinfo_malloc(); TTSplitInfo *ttsi; Split *sp; gnc_numeric runningBalance; gnc_numeric split_value; const char *tmpStr; runningBalance = gnc_numeric_zero(); gnc_ttinfo_set_description(tti, xaccTransGetDescription(tr)); gnc_ttinfo_set_num(tti, gnc_get_num_action(tr, NULL)); gnc_ttinfo_set_currency(tti, xaccTransGetCurrency(tr)); for (splits = xaccTransGetSplitList(tr); splits; splits = splits->next) { sp = splits->data; ttsi = gnc_ttsplitinfo_malloc(); gnc_ttsplitinfo_set_action(ttsi, gnc_get_num_action(NULL, sp)); split_value = xaccSplitGetValue(sp); gnc_ttsplitinfo_set_memo(ttsi, xaccSplitGetMemo(sp)); runningBalance = gnc_numeric_add( runningBalance, split_value, 100, (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) ); if (gnc_numeric_positive_p(split_value)) { tmpStr = xaccPrintAmount( split_value, gnc_default_print_info(FALSE) ); gnc_ttsplitinfo_set_debit_formula( ttsi, tmpStr ); } else { /* Negate the numeric so it prints w/o the sign at the front. */ tmpStr = xaccPrintAmount( gnc_numeric_neg( split_value ), gnc_default_print_info(FALSE) ); gnc_ttsplitinfo_set_credit_formula( ttsi, tmpStr ); } /* Copy over per-split account info */ gnc_ttsplitinfo_set_account( ttsi, xaccSplitGetAccount( sp ) ); template_splits = g_list_append(template_splits, ttsi); } if ( ! gnc_numeric_zero_p( runningBalance ) && !gnc_verify_dialog( (GtkWidget *)sxfti->dialog, FALSE, "%s", _("The Scheduled Transaction Editor " "cannot automatically balance " "this transaction. " "Should it still be " "entered?") ) ) { return SXFTD_ERRNO_UNBALANCED_XACTION; } gnc_ttinfo_set_template_splits(tti, template_splits); tt_list = g_list_append(tt_list, tti); gnc_suspend_gui_refresh (); xaccSchedXactionSetTemplateTrans(sxfti->sx, tt_list, gnc_get_current_book ()); gnc_resume_gui_refresh (); return 0; }
static gint sxftd_init( SXFromTransInfo *sxfti ) { GtkWidget *w; const char *transName; gint pos; GList *schedule = NULL; time_t start_tt; struct tm *tmpTm; GDate date, nextDate; if ( ! sxfti->sx ) { return -1; } if ( ! sxfti->trans ) { return -2; } if ( xaccTransIsOpen( sxfti->trans ) ) { return SXFTD_ERRNO_OPEN_XACTION; } sxfti_attach_callbacks(sxfti); /* Setup the example calendar and related data structures. */ { int num_marks = SXFTD_EXCAL_NUM_MONTHS * 31; w = GTK_WIDGET(glade_xml_get_widget( sxfti->gxml, SXFTD_EX_CAL_FRAME )); sxfti->dense_cal_model = gnc_dense_cal_store_new(num_marks); sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(sxfti->dense_cal_model))); g_object_ref_sink(sxfti->example_cal); g_assert(sxfti->example_cal); gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS ); gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL ); gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) ); } /* Setup the start and end dates as GNCDateEdits */ { GtkWidget *paramTable = glade_xml_get_widget( sxfti->gxml, SXFTD_PARAM_TABLE ); sxfti->startDateGDE = GNC_DATE_EDIT( gnc_date_edit_new( time( NULL ), FALSE, FALSE ) ); gtk_table_attach( GTK_TABLE(paramTable), GTK_WIDGET( sxfti->startDateGDE ), 1, 2, 2, 3, (GTK_EXPAND | GTK_FILL), GTK_FILL, 0, 0 ); g_signal_connect( sxfti->startDateGDE, "date-changed", G_CALLBACK( sxftd_update_excal_adapt ), sxfti ); } { GtkWidget *endDateBox = glade_xml_get_widget( sxfti->gxml, SXFTD_END_DATE_BOX ); sxfti->endDateGDE = GNC_DATE_EDIT( gnc_date_edit_new( time( NULL ), FALSE, FALSE ) ); gtk_box_pack_start( GTK_BOX( endDateBox ), GTK_WIDGET( sxfti->endDateGDE ), FALSE, TRUE, 0 ); g_signal_connect( sxfti->endDateGDE, "date-changed", G_CALLBACK( sxftd_update_excal_adapt ), sxfti ); } /* Get the name from the transaction, try that as the initial SX name. */ transName = xaccTransGetDescription( sxfti->trans ); xaccSchedXactionSetName( sxfti->sx, transName ); /* Setup the initial start date for user display/confirmation */ /* compute good initial date. */ start_tt = xaccTransGetDate( sxfti->trans ); g_date_set_time_t( &date, start_tt ); w = glade_xml_get_widget(sxfti->gxml, SXFTD_FREQ_COMBO_BOX); gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0); g_signal_connect( w, "changed", G_CALLBACK(sxftd_freq_combo_changed), sxfti ); sxftd_update_schedule( sxfti, &date, &schedule); recurrenceListNextInstance(schedule, &date, &nextDate); recurrenceListFree(&schedule); tmpTm = g_new0( struct tm, 1 ); g_date_to_struct_tm( &nextDate, tmpTm ); start_tt = mktime( tmpTm ); g_free( tmpTm ); gnc_date_edit_set_time( sxfti->startDateGDE, start_tt ); w = glade_xml_get_widget( sxfti->gxml, SXFTD_NAME_ENTRY ); pos = 0; gtk_editable_insert_text( GTK_EDITABLE(w), transName, (strlen(transName) * sizeof(char)), &pos ); g_signal_connect( GTK_OBJECT(w), "destroy", G_CALLBACK(sxftd_destroy), sxfti ); sxftd_update_example_cal( sxfti ); return 0; }
static void refresh_model_row (GNCImportMainMatcher *gui, GtkTreeModel *model, GtkTreeIter *iter, GNCImportTransInfo *info) { GtkListStore *store; GtkTreeSelection *selection; gchar *tmp, *imbalance, *text, *color; const gchar *ro_text; Split *split; g_assert (gui); g_assert (model); g_assert (info); /*DEBUG("Begin");*/ store = GTK_LIST_STORE(model); gtk_list_store_set(store, iter, DOWNLOADED_COL_DATA, info, -1); /*Account:*/ split = gnc_import_TransInfo_get_fsplit (info); g_assert(split); // Must not be NULL ro_text = xaccAccountGetName(xaccSplitGetAccount(split)); gtk_list_store_set(store, iter, DOWNLOADED_COL_ACCOUNT, ro_text, -1); /*Date*/ text = qof_print_date ( xaccTransGetDate( gnc_import_TransInfo_get_trans(info) ) ); gtk_list_store_set(store, iter, DOWNLOADED_COL_DATE, text, -1); g_free(text); /*Amount*/ ro_text = xaccPrintAmount (xaccSplitGetAmount (split), gnc_split_amount_print_info(split, TRUE) ); gtk_list_store_set(store, iter, DOWNLOADED_COL_AMOUNT, ro_text, -1); /*Description*/ ro_text = xaccTransGetDescription(gnc_import_TransInfo_get_trans(info) ); gtk_list_store_set(store, iter, DOWNLOADED_COL_DESCRIPTION, ro_text, -1); /*Memo*/ ro_text = xaccSplitGetMemo(split); gtk_list_store_set(store, iter, DOWNLOADED_COL_MEMO, ro_text, -1); /*Actions*/ /* Action informations */ ro_text = text = color = NULL; switch (gnc_import_TransInfo_get_action(info)) { case GNCImport_ADD: if (gnc_import_TransInfo_is_balanced(info) == TRUE) { ro_text = _("New, already balanced"); color = COLOR_GREEN; } else { /* Assume that importers won't create transactions in two or more currencies so we can use xaccTransGetImbalanceValue */ imbalance = g_strdup (xaccPrintAmount (gnc_numeric_neg(xaccTransGetImbalanceValue (gnc_import_TransInfo_get_trans(info) )), gnc_commodity_print_info (xaccTransGetCurrency(gnc_import_TransInfo_get_trans (info)), TRUE) )); if (gnc_import_TransInfo_get_destacc (info) != NULL) { color = COLOR_GREEN; tmp = gnc_account_get_full_name (gnc_import_TransInfo_get_destacc (info)); if (gnc_import_TransInfo_get_destacc_selected_manually(info) == TRUE) { text = /* Translators: %1$s is the amount to be transferred. %2$s is the destination account. */ g_strdup_printf(_("New, transfer %s to (manual) \"%s\""), imbalance, tmp); } else { text = /* Translators: %1$s is the amount to be transferred. %2$s is the destination account. */ g_strdup_printf(_("New, transfer %s to (auto) \"%s\""), imbalance, tmp); } g_free (tmp); } else { color = COLOR_YELLOW; text = /* Translators: %s is the amount to be transferred. */ g_strdup_printf(_("New, UNBALANCED (need acct to transfer %s)!"), imbalance); } g_free (imbalance); } break; case GNCImport_CLEAR: if (gnc_import_TransInfo_get_selected_match(info)) { color = COLOR_GREEN; if (gnc_import_TransInfo_get_match_selected_manually(info) == TRUE) { ro_text = _("Reconcile (manual) match"); } else { ro_text = _("Reconcile (auto) match"); } } else { color = COLOR_RED; ro_text = _("Match missing!"); } break; case GNCImport_UPDATE: if (gnc_import_TransInfo_get_selected_match(info)) { color = COLOR_GREEN; if (gnc_import_TransInfo_get_match_selected_manually(info) == TRUE) { ro_text = _("Update and reconcile (manual) match"); } else { ro_text = _("Update and reconcile (auto) match"); } } else { color = COLOR_RED; ro_text = _("Match missing!"); } break; case GNCImport_SKIP: color = COLOR_RED; ro_text = _("Do not import (no action selected)"); break; default: color = "white"; ro_text = "WRITEME, this is an unknown action"; break; } gtk_list_store_set(store, iter, DOWNLOADED_COL_COLOR, color, DOWNLOADED_COL_ACTION_INFO, ro_text ? ro_text : text, -1); if (text) g_free(text); /* Set the pixmaps */ gtk_list_store_set(store, iter, DOWNLOADED_COL_ACTION_ADD, gnc_import_TransInfo_get_action(info) == GNCImport_ADD, -1); if (gnc_import_TransInfo_get_action(info) == GNCImport_SKIP) { /*Show the best match's confidence pixmap in the info column*/ gtk_list_store_set(store, iter, DOWNLOADED_COL_ACTION_PIXBUF, gen_probability_pixbuf( gnc_import_MatchInfo_get_probability ( gnc_import_TransInfo_get_selected_match (info)), gui->user_settings, GTK_WIDGET(gui->view)), -1); } gtk_list_store_set(store, iter, DOWNLOADED_COL_ACTION_CLEAR, gnc_import_TransInfo_get_action(info) == GNCImport_CLEAR, -1); if (gnc_import_TransInfo_get_action(info) == GNCImport_CLEAR) { /*Show the best match's confidence pixmap in the info column*/ gtk_list_store_set(store, iter, DOWNLOADED_COL_ACTION_PIXBUF, gen_probability_pixbuf( gnc_import_MatchInfo_get_probability ( gnc_import_TransInfo_get_selected_match (info)), gui->user_settings, GTK_WIDGET(gui->view)), -1); } gtk_list_store_set(store, iter, DOWNLOADED_COL_ACTION_UPDATE, gnc_import_TransInfo_get_action(info) == GNCImport_UPDATE, -1); if (gnc_import_TransInfo_get_action(info) == GNCImport_UPDATE) { /*Show the best match's confidence pixmap in the info column*/ gtk_list_store_set(store, iter, DOWNLOADED_COL_ACTION_PIXBUF, gen_probability_pixbuf( gnc_import_MatchInfo_get_probability ( gnc_import_TransInfo_get_selected_match (info)), gui->user_settings, GTK_WIDGET(gui->view)), -1); } selection = gtk_tree_view_get_selection(gui->view); gtk_tree_selection_unselect_all(selection); }
static gboolean create_each_transaction_helper(Transaction *template_txn, void *user_data) { Transaction *new_txn; GList *txn_splits, *template_splits; Split *copying_split; gnc_commodity *first_cmdty = NULL; gboolean err_flag = FALSE; SxTxnCreationData *creation_data; creation_data = (SxTxnCreationData*)user_data; /* FIXME: In general, this should [correctly] deal with errors such as not finding the approrpiate Accounts and not being able to parse the formula|credit/debit strings. */ new_txn = xaccTransClone(template_txn); xaccTransBeginEdit(new_txn); g_debug("creating template txn desc [%s] for sx [%s]", xaccTransGetDescription(new_txn), xaccSchedXactionGetName(creation_data->instance->parent->sx)); /* clear any copied KVP data */ qof_instance_set_slots(QOF_INSTANCE(new_txn), kvp_frame_new()); /* Bug#500427: copy the notes, if any */ if (xaccTransGetNotes(template_txn) != NULL) { xaccTransSetNotes(new_txn, g_strdup(xaccTransGetNotes(template_txn))); } xaccTransSetDate(new_txn, g_date_get_day(&creation_data->instance->date), g_date_get_month(&creation_data->instance->date), g_date_get_year(&creation_data->instance->date)); /* the accounts and amounts are in the kvp_frames of the splits. */ template_splits = xaccTransGetSplitList(template_txn); txn_splits = xaccTransGetSplitList(new_txn); if ((template_splits == NULL) || (txn_splits == NULL)) { g_critical("transaction w/o splits for sx [%s]", xaccSchedXactionGetName(creation_data->instance->parent->sx)); xaccTransDestroy(new_txn); xaccTransCommitEdit(new_txn); return FALSE; } for (; txn_splits && template_splits; txn_splits = txn_splits->next, template_splits = template_splits->next) { Split *template_split; Account *split_acct; gnc_commodity *split_cmdty = NULL; /* FIXME: Ick. This assumes that the split lists will be ordered identically. :( They are, but we'd rather not have to count on it. --jsled */ template_split = (Split*)template_splits->data; copying_split = (Split*)txn_splits->data; if (!_get_template_split_account(creation_data->instance, template_split, &split_acct, creation_data->creation_errors)) { err_flag = TRUE; break; } /* clear out any copied Split frame data. */ qof_instance_set_slots(QOF_INSTANCE(copying_split), kvp_frame_new()); split_cmdty = xaccAccountGetCommodity(split_acct); if (first_cmdty == NULL) { first_cmdty = split_cmdty; xaccTransSetCurrency(new_txn, first_cmdty); } xaccSplitSetAccount(copying_split, split_acct); { gnc_numeric credit_num, debit_num, final; gint gncn_error; credit_num = gnc_numeric_zero(); debit_num = gnc_numeric_zero(); _get_credit_formula_value(creation_data->instance, template_split, &credit_num, creation_data->creation_errors); _get_debit_formula_value(creation_data->instance, template_split, &debit_num, creation_data->creation_errors); final = gnc_numeric_sub_fixed( debit_num, credit_num ); gncn_error = gnc_numeric_check(final); if (gncn_error != GNC_ERROR_OK) { GString *err = g_string_new(""); g_string_printf(err, "error %d in SX [%s] final gnc_numeric value, using 0 instead", gncn_error, xaccSchedXactionGetName(creation_data->instance->parent->sx)); g_critical("%s", err->str); if (creation_data->creation_errors != NULL) *creation_data->creation_errors = g_list_append(*creation_data->creation_errors, err); else g_string_free(err, TRUE); final = gnc_numeric_zero(); }
static gint sxftd_init( SXFromTransInfo *sxfti ) { GtkWidget *w; const char *transName; gint pos; GList *schedule = NULL; time64 start_tt; struct tm *tmpTm; GDate date, nextDate; if ( ! sxfti->sx ) { return -1; } if ( ! sxfti->trans ) { return -2; } if ( xaccTransIsOpen( sxfti->trans ) ) { return SXFTD_ERRNO_OPEN_XACTION; } /* Setup Widgets */ { sxfti->ne_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "never_end_button")); sxfti->ed_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "end_on_date_button")); sxfti->oc_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "n_occurrences_button")); sxfti->n_occurences = GTK_ENTRY(gtk_builder_get_object(sxfti->builder, "n_occurrences_entry")); } /* Get the name from the transaction, try that as the initial SX name. */ transName = xaccTransGetDescription( sxfti->trans ); xaccSchedXactionSetName( sxfti->sx, transName ); sxfti->name = GTK_ENTRY(gtk_builder_get_object(sxfti->builder, "name_entry" )); pos = 0; gtk_editable_insert_text( GTK_EDITABLE(sxfti->name), transName, (strlen(transName) * sizeof(char)), &pos ); sxfti_attach_callbacks(sxfti); /* Setup the example calendar and related data structures. */ { int num_marks = SXFTD_EXCAL_NUM_MONTHS * 31; w = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "ex_cal_frame" )); sxfti->dense_cal_model = gnc_dense_cal_store_new(num_marks); sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(sxfti->dense_cal_model))); g_object_ref_sink(sxfti->example_cal); g_assert(sxfti->example_cal); gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS ); gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL ); gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) ); } /* Setup the start and end dates as GNCDateEdits */ { GtkWidget *paramTable = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "param_table" )); sxfti->startDateGDE = GNC_DATE_EDIT( gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE)); gtk_table_attach( GTK_TABLE(paramTable), GTK_WIDGET( sxfti->startDateGDE ), 1, 2, 2, 3, (GTK_EXPAND | GTK_FILL), GTK_FILL, 0, 0 ); g_signal_connect( sxfti->startDateGDE, "date-changed", G_CALLBACK( sxftd_update_excal_adapt ), sxfti ); } { GtkWidget *endDateBox = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "end_date_hbox" )); sxfti->endDateGDE = GNC_DATE_EDIT( gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE)); gtk_box_pack_start( GTK_BOX( endDateBox ), GTK_WIDGET( sxfti->endDateGDE ), TRUE, TRUE, 0 ); g_signal_connect( sxfti->endDateGDE, "date-changed", G_CALLBACK( sxftd_update_excal_adapt ), sxfti ); } /* Setup the initial start date for user display/confirmation */ /* compute good initial date. */ start_tt = xaccTransGetDate( sxfti->trans ); gnc_gdate_set_time64( &date, start_tt ); sxfti->freq_combo = GTK_COMBO_BOX(gtk_builder_get_object(sxfti->builder, "freq_combo_box")); gtk_combo_box_set_active(GTK_COMBO_BOX(sxfti->freq_combo), 0); g_signal_connect( sxfti->freq_combo, "changed", G_CALLBACK(sxftd_freq_combo_changed), sxfti ); sxftd_update_schedule( sxfti, &date, &schedule); recurrenceListNextInstance(schedule, &date, &nextDate); recurrenceListFree(&schedule); start_tt = gnc_time64_get_day_start_gdate (&nextDate); gnc_date_edit_set_time( sxfti->startDateGDE, start_tt ); g_signal_connect( G_OBJECT(sxfti->name), "destroy", G_CALLBACK(sxftd_destroy), sxfti ); sxftd_update_example_cal( sxfti ); return 0; }
static void downloaded_transaction_append(GNCImportMatchPicker * matcher, GNCImportTransInfo * transaction_info) { GtkListStore *store; GtkTreeIter iter; GtkTreeSelection *selection; Transaction *trans; Split *split; gchar *text; const gchar *ro_text; gboolean found = FALSE; GNCImportTransInfo *local_info; g_assert(matcher); g_assert(transaction_info); /*DEBUG("Begin");*/ /* Has the transaction already been added? */ store = GTK_LIST_STORE(gtk_tree_view_get_model(matcher->downloaded_view)); if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { do { gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, DOWNLOADED_COL_INFO_PTR, &local_info, -1); if (local_info == transaction_info) { found = TRUE; break; } } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); } if (!found) gtk_list_store_append(store, &iter); split = gnc_import_TransInfo_get_fsplit(transaction_info); trans = gnc_import_TransInfo_get_trans(transaction_info); /*Account*/ ro_text = xaccAccountGetName(xaccSplitGetAccount(split)); gtk_list_store_set(store, &iter, DOWNLOADED_COL_ACCOUNT, ro_text, -1); /*Date*/ text = qof_print_date(xaccTransGetDate(trans)); gtk_list_store_set(store, &iter, DOWNLOADED_COL_DATE, text, -1); g_free(text); /*Amount*/ ro_text = xaccPrintAmount(xaccSplitGetAmount(split), gnc_split_amount_print_info(split, TRUE)); gtk_list_store_set(store, &iter, DOWNLOADED_COL_AMOUNT, ro_text, -1); /*Description*/ ro_text = xaccTransGetDescription(trans); gtk_list_store_set(store, &iter, DOWNLOADED_COL_DESCRIPTION, ro_text, -1); /*Memo*/ ro_text = xaccSplitGetMemo(split); gtk_list_store_set(store, &iter, DOWNLOADED_COL_MEMO, ro_text, -1); /*Imbalance*/ /* Assume that the importer won't create a transaction that involves two or more currencies and no non-currency commodity. In that case can use the simpler value imbalance check. */ ro_text = xaccPrintAmount(xaccTransGetImbalanceValue(trans), gnc_default_print_info(TRUE)); gtk_list_store_set(store, &iter, DOWNLOADED_COL_BALANCED, ro_text, -1); gtk_list_store_set(store, &iter, DOWNLOADED_COL_INFO_PTR, transaction_info, -1); selection = gtk_tree_view_get_selection(matcher->downloaded_view); gtk_tree_selection_select_iter(selection, &iter); }