30 #include <glib/gi18n.h>
34 #include "gnc-tree-util-split-reg.h"
35 #include "gnc-tree-model-split-reg.h"
36 #include "gnc-tree-view-split-reg.h"
39 #include "dialog-utils.h"
40 #include "dialog-transfer.h"
41 #include "engine-helpers.h"
45 #define SPLIT_TRANS_STR _("-- Split Transaction --")
46 #define STOCK_SPLIT_STR _("-- Stock Split --")
62 split = gnc_tree_view_split_reg_get_current_split (view);
64 depth = gnc_tree_view_reg_get_selected_row_depth (view);
94 gboolean have_rate = FALSE;
95 QofBook *book = gnc_get_current_book ();
101 rate_split = gnc_price_get_value (prc);
112 rate_split =
gnc_numeric_div (gnc_numeric_create (100, 100), gnc_price_get_value (prc),
122 rate_split = gnc_numeric_create (100, 100);
134 ENTER(
"gtu_sr_needs_exchange_rate - trans %p and split %p", trans, split);
140 LEAVE(
"gtu_sr_needs_exchange_rate split_com to txn_curr return TRUE");
144 reg_com = gnc_tree_view_split_reg_get_reg_commodity (view);
147 LEAVE(
"gtu_sr_needs_exchange_rate split_com and reg_com return TRUE");
150 LEAVE(
"No Exchange rate needed");
162 gboolean rate_split_ok, rate_reg_ok;
166 gnc_commodity *reg_comm = gnc_tree_view_split_reg_get_reg_commodity (view);
169 gboolean have_rate = TRUE;
174 model = gnc_tree_view_split_reg_get_model_from_view (view);
176 reg_acc = gnc_tree_model_split_reg_get_anchor (model);
179 rate_split_ok = xaccTransGetRateForCommodity (trans, xfer_comm, split, &rate_split);
183 rate_reg_ok = xaccTransGetRateForCommodity (trans, reg_comm, split, &rate_reg);
187 expanded = gnc_tree_view_split_reg_trans_expanded (view, trans);
196 if (rate_reg_ok && rate_split_ok && !force)
204 rate_split = gtu_sr_get_rate_from_db (reg_comm, xfer_comm);
207 xfer = gnc_xfer_dialog (NULL, NULL);
209 gnc_xfer_dialog_is_exchange_dialog (xfer, &rate_split);
216 gnc_xfer_dialog_set_num (xfer, gnc_get_num_action (trans, split));
220 if (gnc_xfer_dialog_run_exchange_dialog (xfer, &rate_split, value, reg_acc, trans, xfer_comm, expanded))
223 rate_split = gnc_numeric_create (1, 1);
241 gtu_sr_get_value_denom (
Split *split)
261 gtu_sr_get_amount_denom (
Split *split)
288 model = gnc_tree_view_split_reg_get_model_from_view (view);
294 case ASSET_REGISTER2:
295 case CREDIT_REGISTER2:
296 case LIABILITY_REGISTER2:
297 case INCOME_REGISTER2:
298 case EXPENSE_REGISTER2:
299 case EQUITY_REGISTER2:
300 case TRADING_REGISTER2:
301 case GENERAL_LEDGER2:
306 case STOCK_REGISTER2:
307 case CURRENCY_REGISTER2:
308 case PORTFOLIO_LEDGER2:
309 case RECEIVABLE_REGISTER2:
310 case PAYABLE_REGISTER2:
319 gnc_tree_util_split_reg_is_multi (
Split *split)
321 gboolean multi = FALSE;
350 gnc_tree_util_split_reg_get_transfer_entry (
Split *split, gboolean *is_multi)
352 static char *name = NULL;
353 gboolean multi = FALSE;
376 name = g_strdup (SPLIT_TRANS_STR);
381 name = g_strdup (STOCK_SPLIT_STR);
385 name = g_strdup (
"");
397 gnc_tree_util_split_reg_template_get_transfer_entry (
Split *split)
399 static char *name = NULL;
420 gnc_tree_util_split_reg_template_get_fdebt_entry (
Split *split)
422 gchar *formula = NULL;
424 g_return_val_if_fail (split != NULL, NULL);
426 "sx-debit-formula", &formula,
433 gnc_tree_util_split_reg_template_get_fcred_entry (
Split *split)
435 gchar *formula = NULL;
437 g_return_val_if_fail (split != NULL, NULL);
439 "sx-credit-formula", &formula,
447 gnc_tree_util_split_reg_get_date_help (GDate *date)
452 if (g_date_valid (date))
455 memset (&tm, 0,
sizeof (tm));
456 g_date_to_struct_tm (date, &tm);
457 qof_strftime (
string,
sizeof (
string), _(
"%A %d %B %Y"), &tm);
458 return g_strdup (
string);
461 return g_strdup (
" ");
466 gnc_tree_util_split_reg_parse_date (GDate *parsed,
const char *datestr)
468 int day, month, year;
472 if (!datestr)
return;
479 day = tm_today.tm_mday;
480 month = tm_today.tm_mon + 1;
481 year = tm_today.tm_year + 1900;
486 if (use_autoreadonly)
488 GDate *d = g_date_new_dmy (day, month, year);
490 if (g_date_compare (d, readonly_threshold) < 0)
492 g_warning(
"Entered date %s is before the \"auto-read-only threshold\"; resetting to the threshold.", datestr);
494 GtkWidget *dialog = gtk_message_dialog_new (NULL,
498 "%s", _(
"Cannot store a transaction at this date"));
499 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
500 "%s", _(
"The entered date of the new transaction is older than the \"Read-Only Threshold\" set for this book. "
501 "This setting can be changed in File -> Properties -> Accounts."));
502 gtk_dialog_run (GTK_DIALOG (dialog));
503 gtk_widget_destroy (dialog);
507 day = g_date_get_day (readonly_threshold);
508 month = g_date_get_month (readonly_threshold);
509 year = g_date_get_year (readonly_threshold);
512 g_date_free (readonly_threshold);
514 g_date_set_dmy (parsed, day, month, year);
521 GtkCellRenderer *cr0 = NULL;
526 renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (col));
527 cr0 = g_list_nth_data (renderers, 0);
528 g_list_free (renderers);
530 viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cr0),
"view_column"));
532 if (viewcol == COL_RECN)
534 const char recn_flags[] = {
NREC,
CREC, 0};
546 this_flag = strstr (flags, text);
548 if (this_flag != NULL && *this_flag !=
'\0')
552 index = this_flag - flags;
554 if (flags[index + 1] !=
'\0')
559 rec = recn_flags[index];
564 gnc_tree_view_split_reg_set_dirty_trans (view, trans);
572 if (viewcol == COL_TYPE)
586 this_flag = strstr (flags, text);
588 if (this_flag != NULL && *this_flag !=
'\0')
592 index = this_flag - flags;
594 if (flags[index + 1] !=
'\0')
599 type = type_flags[index];
604 gnc_tree_view_split_reg_set_dirty_trans (view, trans);
627 if (!gnc_tree_util_split_reg_has_rate (view))
646 return gnc_tree_util_split_reg_needs_conv_rate (view, txn, acc);
657 if (gnc_tree_util_split_reg_get_debcred_entry (view, trans, split, is_blank, &ret_num, &ret_print_info))
660 return gnc_numeric_zero();
674 model = gnc_tree_view_split_reg_get_model_from_view (view);
692 MonetaryList *imbal_list;
702 if (imbal_list->next)
709 imbal_mon = imbal_list->data;
730 acc = gnc_tree_model_split_reg_get_anchor (model);
732 if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc))
735 xaccTransGetAccountConvRate (trans, acc),
746 *ret_num = imbalance;
747 *ret_print_info = gnc_account_print_info (acc, FALSE);
758 account = gnc_tree_model_split_reg_get_anchor (model);
765 gboolean use_symbol, is_current = FALSE;
766 Split *current_split = gnc_tree_view_split_reg_get_current_split (view);
767 RowDepth depth = gnc_tree_view_reg_get_selected_row_depth (view);
769 if ((split == current_split) && (depth == SPLIT3))
772 if (model->
type == STOCK_REGISTER2 ||
773 model->
type == CURRENCY_REGISTER2 ||
774 model->
type == PORTFOLIO_LEDGER2)
779 if (gtu_sr_use_security (view))
782 amount_commodity = currency;
787 amount_commodity = split_commodity;
795 print_info = gnc_commodity_print_info (amount_commodity, use_symbol);
806 print_info = gnc_commodity_print_info (split_commodity, use_symbol);
817 case STOCK_REGISTER2:
818 case CURRENCY_REGISTER2:
819 case PORTFOLIO_LEDGER2:
821 print_info = gnc_commodity_print_info (currency, FALSE);
827 amount = xaccSplitConvertAmount (split, account);
830 print_info = gnc_account_print_info (account, FALSE);
839 *ret_print_info = print_info;
860 model = gnc_tree_view_split_reg_get_model_from_view (view);
862 anchor = gnc_tree_model_split_reg_get_anchor (model);
868 LEAVE(
"input is zero");
872 window = gnc_tree_view_split_reg_get_parent (view);
874 if (gtu_sr_needs_exchange_rate (view, trans, split))
876 if (gtu_sr_handle_exchange_rate (view, input, trans, split, force))
882 gnc_error_dialog (window,
"%s",
883 _(
"Exchange Rate Canceled, using existing rate or default 1 to 1 rate if this is a new transaction."));
885 LEAVE(
"used exchange rate");
889 gnc_tree_util_split_reg_save_amount_values (view, trans, split, input);
905 model = gnc_tree_view_split_reg_get_model_from_view (view);
909 acc = gnc_tree_model_split_reg_get_anchor (model);
916 if (!xaccTransGetRateForCommodity (trans, reg_com, NULL, &convrate))
917 convrate = gnc_numeric_create (100, 100);
921 if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc))
929 amtconv = xaccTransGetAccountConvRate (trans, acc);
938 if (model->
type == STOCK_REGISTER2 ||
939 model->
type == CURRENCY_REGISTER2 ||
940 model->
type == PORTFOLIO_LEDGER2)
956 if (gnc_tree_util_split_reg_needs_amount (view, split))
985 if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc))
1004 if (gnc_tree_util_split_reg_needs_amount (view, split))
1030 gboolean price_changed = FALSE;
1031 gboolean value_changed = FALSE;
1032 gboolean amount_changed = FALSE;
1034 gboolean recalc_amount = FALSE;
1035 gboolean recalc_price = FALSE;
1036 gboolean recalc_value = FALSE;
1037 gboolean expanded = FALSE;
1043 model = gnc_tree_view_split_reg_get_model_from_view (view);
1046 if (!gnc_tree_model_split_reg_get_sub_account (model))
1047 account = gnc_tree_model_split_reg_get_anchor (model);
1049 expanded = gnc_tree_view_split_reg_trans_expanded (view, trans);
1078 if (viewcol == COL_AMTVAL && !expanded)
1080 value_changed = TRUE;
1089 else if (viewcol == COL_AMTVAL && expanded)
1091 amount_changed = TRUE;
1101 if (viewcol == COL_PRICE)
1103 price_changed = TRUE;
1106 amount = gnc_numeric_create (1,1);
1115 if ((viewcol == COL_CREDIT || viewcol == COL_DEBIT) && !expanded)
1117 amount_changed = TRUE;
1126 else if ((viewcol == COL_CREDIT || viewcol == COL_DEBIT) && expanded)
1128 value_changed = TRUE;
1138 DEBUG(
"value_changed %d, price_changed %d, amount_changed %d", value_changed, price_changed, amount_changed);
1144 GList *radio_list = NULL;
1145 const char *title = _(
"Recalculate Transaction");
1146 const char *message = _(
"The values entered for this transaction "
1147 "are inconsistent. Which value would you "
1148 "like to have recalculated?");
1151 radio_list = g_list_append (radio_list,
1152 g_strdup_printf (
"%s (%s)",
1153 _(
"_Shares"), _(
"Changed")));
1155 radio_list = g_list_append (radio_list, g_strdup (_(
"_Shares")));
1158 radio_list = g_list_append (radio_list,
1159 g_strdup_printf (
"%s (%s)",
1160 _(
"_Price"), _(
"Changed")));
1162 radio_list = g_list_append (radio_list, g_strdup (_(
"_Price")));
1165 radio_list = g_list_append (radio_list,
1166 g_strdup_printf (
"%s (%s)",
1167 _(
"_Value"), _(
"Changed")));
1169 radio_list = g_list_append (radio_list, g_strdup (_(
"_Value")));
1185 choice = gnc_choose_radio_option_dialog
1186 (gnc_tree_view_split_reg_get_parent (view),
1193 for (node = radio_list; node; node = node->next)
1194 g_free (node->data);
1196 g_list_free (radio_list);
1201 recalc_amount = TRUE;
1204 recalc_price = TRUE;
1207 recalc_value = TRUE;
1215 DEBUG(
"recalc_value %d, recalc_price %d, recalc_amount %d", recalc_value, recalc_price, recalc_amount);
1219 denom = gtu_sr_get_amount_denom (split);
1268 denom = gtu_sr_get_value_denom (split);
1295 if (!gnc_tree_util_split_reg_is_multi (split) && expanded)
1338 denom = gtu_sr_get_value_denom (split);
1342 split_rate = gnc_numeric_create (100,100);
1359 ENTER(
"trans %p and split %p is_blank %d", trans, split, is_blank);
1361 num = gnc_tree_util_split_reg_get_value_for (view, trans, split, is_blank);
void xaccSplitSetValue(Split *s, gnc_numeric amt)
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
char xaccTransGetTxnType(const Transaction *trans)
int gnc_commodity_get_fraction(const gnc_commodity *cm)
time64 timespecToTime64(Timespec ts)
void qof_instance_get(const QofInstance *inst, const gchar *first_param,...)
Wrapper for g_object_get.
Split * xaccTransGetSplit(const Transaction *trans, int i)
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
gboolean xaccAccountIsPriced(const Account *acc)
gboolean xaccTransIsOpen(const Transaction *trans)
int xaccAccountGetCommoditySCU(const Account *acc)
gnc_numeric gnc_numeric_neg(gnc_numeric a)
void gnc_price_unref(GNCPrice *p)
#define DEBUG(format, args...)
char xaccSplitGetReconcile(const Split *split)
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
gboolean gnc_numeric_zero_p(gnc_numeric a)
void xaccSplitSetReconcile(Split *split, char recn)
Transaction * xaccSplitGetParent(const Split *split)
gchar * gnc_numeric_to_string(gnc_numeric n)
#define ENTER(format, args...)
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
gnc_commodity * gnc_default_currency(void)
gchar * gnc_get_account_name_for_register(const Account *account)
void xaccTransSetTxnType(Transaction *trans, char type)
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
void xaccSplitSetAmount(Split *s, gnc_numeric amt)
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
gnc_numeric xaccTransGetImbalanceValue(const Transaction *trans)
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
void gnc_monetary_list_free(MonetaryList *list)
const char * xaccTransGetDescription(const Transaction *trans)
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
gsize qof_strftime(gchar *buf, gsize max, const gchar *format, const struct tm *tm)
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
void xaccTransBeginEdit(Transaction *trans)
void gnc_tm_get_today_start(struct tm *tm)
gnc_numeric xaccSplitGetValue(const Split *split)
Account * xaccSplitGetAccount(const Split *s)
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
MonetaryList * xaccTransGetImbalance(const Transaction *trans)
Timespec xaccTransRetDatePostedTS(const Transaction *trans)
gboolean qof_scan_date(const char *buff, int *day, int *month, int *year)
Split * xaccSplitGetOtherSplit(const Split *split)
#define LEAVE(format, args...)
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
const char * xaccSplitGetMemo(const Split *split)
GNCPrice * gnc_pricedb_lookup_latest(GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
gboolean qof_book_uses_autoreadonly(const QofBook *book)
const char * xaccSplitGetType(const Split *s)
API for Transactions and Splits (journal entries)
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
const gchar * QofLogModule
gnc_numeric xaccSplitGetAmount(const Split *split)
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)