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; }
static void gnc_ledger_display_set_watches (GNCLedgerDisplay *ld, GList *splits) { GList *node; gnc_gui_component_clear_watches (ld->component_id); gnc_gui_component_watch_entity_type (ld->component_id, GNC_ID_ACCOUNT, QOF_EVENT_MODIFY | QOF_EVENT_DESTROY | GNC_EVENT_ITEM_CHANGED); for (node = splits; node; node = node->next) { Split *split = node->data; Transaction *trans = xaccSplitGetParent (split); gnc_gui_component_watch_entity (ld->component_id, xaccTransGetGUID (trans), QOF_EVENT_MODIFY); } }
void xaccTransScrubCurrency (Transaction *trans) { SplitList *node; gnc_commodity *currency; if (!trans) return; /* If there are any orphaned splits in a transaction, then the * this routine will fail. Therefore, we want to make sure that * there are no orphans (splits without parent account). */ xaccTransScrubOrphans (trans); currency = xaccTransGetCurrency (trans); if (currency && gnc_commodity_is_currency(currency)) return; currency = xaccTransFindCommonCurrency (trans, qof_instance_get_book(trans)); if (currency) { xaccTransBeginEdit (trans); xaccTransSetCurrency (trans, currency); xaccTransCommitEdit (trans); } else { if (NULL == trans->splits) { PWARN ("Transaction \"%s\" has no splits in it!", trans->description); } else { SplitList *node; char guid_str[GUID_ENCODING_LENGTH + 1]; guid_to_string_buff(xaccTransGetGUID(trans), guid_str); PWARN ("no common transaction currency found for trans=\"%s\" (%s);", trans->description, guid_str); for (node = trans->splits; node; node = node->next) { Split *split = node->data; if (NULL == split->acc) { PWARN (" split=\"%s\" is not in any account!", split->memo); } else { gnc_commodity *currency = xaccAccountGetCommodity(split->acc); PWARN ("setting to split=\"%s\" account=\"%s\" commodity=\"%s\"", split->memo, xaccAccountGetName(split->acc), gnc_commodity_get_mnemonic(currency)); xaccTransBeginEdit (trans); xaccTransSetCurrency (trans, currency); xaccTransCommitEdit (trans); return; } } } return; } for (node = trans->splits; node; node = node->next) { Split *sp = node->data; if (!gnc_numeric_equal(xaccSplitGetAmount (sp), xaccSplitGetValue (sp))) { gnc_commodity *acc_currency; acc_currency = sp->acc ? xaccAccountGetCommodity(sp->acc) : NULL; if (acc_currency == currency) { /* This Split needs fixing: The transaction-currency equals * the account-currency/commodity, but the amount/values are * inequal i.e. they still correspond to the security * (amount) and the currency (value). In the new model, the * value is the amount in the account-commodity -- so it * needs to be set to equal the amount (since the * account-currency doesn't exist anymore). * * Note: Nevertheless we lose some information here. Namely, * the information that the 'amount' in 'account-old-security' * was worth 'value' in 'account-old-currency'. Maybe it would * be better to store that information in the price database? * But then, for old currency transactions there is still the * 'other' transaction, which is going to keep that * information. So I don't bother with that here. -- cstim, * 2002/11/20. */ PWARN ("Adjusted split with mismatched values, desc=\"%s\" memo=\"%s\"" " old amount %s %s, new amount %s", trans->description, sp->memo, gnc_num_dbg_to_string (xaccSplitGetAmount(sp)), gnc_commodity_get_mnemonic (currency), gnc_num_dbg_to_string (xaccSplitGetValue(sp))); xaccTransBeginEdit (trans); xaccSplitSetAmount (sp, xaccSplitGetValue(sp)); xaccTransCommitEdit (trans); } /*else { PINFO ("Ok: Split '%s' Amount %s %s, value %s %s", xaccSplitGetMemo (sp), gnc_num_dbg_to_string (amount), gnc_commodity_get_mnemonic (currency), gnc_num_dbg_to_string (value), gnc_commodity_get_mnemonic (acc_currency)); }*/ } } }
static 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; }
static xmlNodePtr invoice_dom_tree_create (GncInvoice* invoice) { xmlNodePtr ret; Timespec ts; Transaction* txn; GNCLot* lot; Account* acc; GncBillTerm* term; GncOwner* billto; gnc_numeric amt; ret = xmlNewNode (NULL, BAD_CAST gnc_invoice_string); xmlSetProp (ret, BAD_CAST "version", BAD_CAST invoice_version_string); xmlAddChild (ret, guid_to_dom_tree (invoice_guid_string, qof_instance_get_guid (QOF_INSTANCE (invoice)))); xmlAddChild (ret, text_to_dom_tree (invoice_id_string, gncInvoiceGetID (invoice))); xmlAddChild (ret, gnc_owner_to_dom_tree (invoice_owner_string, gncInvoiceGetOwner (invoice))); ts = gncInvoiceGetDateOpened (invoice); xmlAddChild (ret, timespec_to_dom_tree (invoice_opened_string, &ts)); maybe_add_timespec (ret, invoice_posted_string, gncInvoiceGetDatePosted (invoice)); term = gncInvoiceGetTerms (invoice); if (term) xmlAddChild (ret, guid_to_dom_tree (invoice_terms_string, qof_instance_get_guid (QOF_INSTANCE (term)))); maybe_add_string (ret, invoice_billing_id_string, gncInvoiceGetBillingID (invoice)); maybe_add_string (ret, invoice_notes_string, gncInvoiceGetNotes (invoice)); xmlAddChild (ret, int_to_dom_tree (invoice_active_string, gncInvoiceGetActive (invoice))); txn = gncInvoiceGetPostedTxn (invoice); if (txn) xmlAddChild (ret, guid_to_dom_tree (invoice_posttxn_string, xaccTransGetGUID (txn))); lot = gncInvoiceGetPostedLot (invoice); if (lot) xmlAddChild (ret, guid_to_dom_tree (invoice_postlot_string, gnc_lot_get_guid (lot))); acc = gncInvoiceGetPostedAcc (invoice); if (acc) xmlAddChild (ret, guid_to_dom_tree (invoice_postacc_string, qof_instance_get_guid (QOF_INSTANCE (acc)))); xmlAddChild (ret, commodity_ref_to_dom_tree (invoice_currency_string, gncInvoiceGetCurrency (invoice))); billto = gncInvoiceGetBillTo (invoice); if (billto && billto->owner.undefined != NULL) xmlAddChild (ret, gnc_owner_to_dom_tree (invoice_billto_string, billto)); amt = gncInvoiceGetToChargeAmount (invoice); if (! gnc_numeric_zero_p (amt)) xmlAddChild (ret, gnc_numeric_to_dom_tree (invoice_tochargeamt_string, &amt)); /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ xmlAddChild (ret, qof_instance_slots_to_dom_tree (invoice_slots_string, QOF_INSTANCE (invoice))); return ret; }
void xaccTransWriteLog (Transaction *trans, char flag) { GList *node; char trans_guid_str[GUID_ENCODING_LENGTH + 1]; char split_guid_str[GUID_ENCODING_LENGTH + 1]; const char *trans_notes; char dnow[100], dent[100], dpost[100], drecn[100]; Timespec ts; if (!gen_logs) return; if (!trans_log) return; timespecFromTime_t(&ts, time(NULL)); gnc_timespec_to_iso8601_buff (ts, dnow); timespecFromTime_t(&ts, trans->date_entered.tv_sec); gnc_timespec_to_iso8601_buff (ts, dent); timespecFromTime_t(&ts, trans->date_posted.tv_sec); gnc_timespec_to_iso8601_buff (ts, dpost); guid_to_string_buff (xaccTransGetGUID(trans), trans_guid_str); trans_notes = xaccTransGetNotes(trans); fprintf (trans_log, "===== START\n"); for (node = trans->splits; node; node = node->next) { Split *split = node->data; const char * accname = ""; char acc_guid_str[GUID_ENCODING_LENGTH + 1]; gnc_numeric amt, val; if (xaccSplitGetAccount(split)) { accname = xaccAccountGetName (xaccSplitGetAccount(split)); guid_to_string_buff(xaccAccountGetGUID(xaccSplitGetAccount(split)), acc_guid_str); } else { acc_guid_str[0] = '\0'; } timespecFromTime_t(&ts, split->date_reconciled.tv_sec); gnc_timespec_to_iso8601_buff (ts, drecn); guid_to_string_buff (xaccSplitGetGUID(split), split_guid_str); amt = xaccSplitGetAmount (split); val = xaccSplitGetValue (split); /* use tab-separated fields */ fprintf (trans_log, "%c\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t" "%s\t%s\t%s\t%s\t%c\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%s\n", flag, trans_guid_str, split_guid_str, /* trans+split make up unique id */ /* Note that the next three strings always exist, * so we don't need to test them. */ dnow, dent, dpost, acc_guid_str, accname ? accname : "", trans->num ? trans->num : "", trans->description ? trans->description : "", trans_notes ? trans_notes : "", split->memo ? split->memo : "", split->action ? split->action : "", split->reconciled, gnc_numeric_num(amt), gnc_numeric_denom(amt), gnc_numeric_num(val), gnc_numeric_denom(val), /* The next string always exists. No need to test it. */ drecn); } fprintf (trans_log, "===== END\n"); /* get data out to the disk */ fflush (trans_log); }