32 #include "engine-helpers.h" 38 #include "gnc-exp-parser.h" 48 gboolean reg_expanded;
52 static QofLogModule log_module = GNC_MOD_LEDGER;
56 gnc_split_register_save_date_cell (BasicCell * cell,
60 SRSaveData *sd = save_data;
64 g_return_if_fail (gnc_basic_cell_has_name (cell, DATE_CELL));
66 value = gnc_basic_cell_get_value (cell);
68 DEBUG (
"DATE: %s", value ? value :
"(null)");
79 gnc_split_register_save_type_cell (BasicCell * cell,
83 SRSaveData *sd = save_data;
86 g_return_if_fail (gnc_basic_cell_has_name (cell, TYPE_CELL));
88 value = gnc_recn_cell_get_flag ((
RecnCell *)cell);
94 gnc_split_register_save_due_date_cell (BasicCell * cell,
98 SRSaveData *sd = save_data;
101 g_return_if_fail (gnc_basic_cell_has_name (cell, DDUE_CELL));
102 value = gnc_basic_cell_get_value (cell);
105 DEBUG (
"DATE: %s", value ? value :
"(null)");
111 gnc_split_register_save_num_cell (BasicCell * cell,
115 SRSaveData *sd = save_data;
116 SplitRegister *reg = user_data;
119 g_return_if_fail (gnc_basic_cell_has_name (cell, NUM_CELL));
121 value = gnc_basic_cell_get_value (cell);
123 DEBUG (
"NUM: %s\n", value ? value :
"(null)");
126 gnc_set_num_action (sd->trans, sd->split, value, NULL);
128 if (gnc_num_cell_set_last_num ((
NumCell *) cell, value))
130 SRInfo *info = gnc_split_register_get_info (reg);
132 gnc_get_current_book ());
135 if (sd->trans == blank_trans)
136 gnc_split_register_set_last_num (reg, gnc_basic_cell_get_value (cell));
141 gnc_split_register_save_tnum_cell (BasicCell * cell,
145 SRSaveData *sd = save_data;
148 g_return_if_fail (gnc_basic_cell_has_name (cell, TNUM_CELL));
150 value = gnc_basic_cell_get_value (cell);
152 DEBUG (
"TNUM: %s\n", value ? value :
"(null)");
155 gnc_set_num_action (sd->trans, NULL, value, NULL);
159 gnc_split_register_save_desc_cell (BasicCell * cell,
163 SRSaveData *sd = save_data;
166 g_return_if_fail (gnc_basic_cell_has_name (cell, DESC_CELL));
168 value = gnc_basic_cell_get_value (cell);
170 DEBUG (
"DESC: %s", value ? value :
"(null)");
176 gnc_split_register_save_notes_cell (BasicCell * cell,
180 SRSaveData *sd = save_data;
183 g_return_if_fail (gnc_basic_cell_has_name (cell, NOTES_CELL));
185 value = gnc_basic_cell_get_value (cell);
187 DEBUG (
"NOTES: %s", value ? value :
"(null)");
193 gnc_split_register_save_recn_cell (BasicCell * bcell,
197 SRSaveData *sd = save_data;
200 g_return_if_fail (gnc_basic_cell_has_name (bcell, RECN_CELL));
202 DEBUG (
"RECN: %c", gnc_recn_cell_get_flag (cell));
208 gnc_split_register_save_actn_cell (BasicCell * cell,
212 SRSaveData *sd = save_data;
215 g_return_if_fail (gnc_basic_cell_has_name (cell, ACTN_CELL));
217 value = gnc_basic_cell_get_value (cell);
219 DEBUG (
"ACTN: %s", value ? value :
"(null)");
223 gnc_set_num_action (NULL, sd->split, NULL, value);
227 gnc_split_register_save_memo_cell (BasicCell * cell,
231 SRSaveData *sd = save_data;
234 g_return_if_fail (gnc_basic_cell_has_name (cell, MEMO_CELL));
236 value = gnc_basic_cell_get_value (cell);
238 DEBUG (
"MEMO: %s", value ? value :
"(null)");
249 gnc_split_register_save_xfrm_cell (BasicCell * cell,
253 SRSaveData *sd = save_data;
254 SplitRegister *reg = user_data;
258 g_return_if_fail (gnc_basic_cell_has_name (cell, XFRM_CELL));
262 new_acc = gnc_split_register_get_account (reg, XFRM_CELL);
264 if ((new_acc != NULL) && (old_acc != new_acc))
269 gnc_split_register_save_mxfrm_cell (BasicCell * cell,
273 SRSaveData *sd = save_data;
274 SplitRegister *reg = user_data;
277 g_return_if_fail (gnc_basic_cell_has_name (cell, MXFRM_CELL));
309 new_acc = gnc_split_register_get_account (reg, MXFRM_CELL);
311 if ((new_acc != NULL) && (old_acc != new_acc))
317 gnc_split_register_save_shares_cell (BasicCell * bcell,
321 SRSaveData *sd = save_data;
325 g_return_if_fail (gnc_basic_cell_has_name (bcell, SHRS_CELL));
337 gnc_split_register_save_price_cell (BasicCell * bcell,
341 SRSaveData *sd = save_data;
345 g_return_if_fail (gnc_basic_cell_has_name (bcell, PRIC_CELL));
359 gnc_split_register_debcred_cell_value (SplitRegister *reg)
362 gnc_numeric new_amount;
366 cell = (
PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
370 cell = (
PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
374 new_amount = gnc_numeric_sub_fixed (debit, credit);
380 gnc_split_register_get_rate_cell (SplitRegister *reg,
const char *cell_name)
384 rate_cell = (
PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
390 return gnc_numeric_create (100, 100);
394 gnc_split_register_split_needs_amount (SplitRegister *reg, Split *split)
399 return gnc_split_register_needs_conv_rate (reg, txn, acc);
403 gnc_split_register_save_amount_values (SRSaveData *sd, SplitRegister *reg)
406 gnc_numeric new_amount, convrate, amtconv, value;
407 gnc_commodity *curr, *reg_com, *xfer_com;
410 new_amount = gnc_split_register_debcred_cell_value (reg);
411 acc = gnc_split_register_get_default_account (reg);
421 amtconv = convrate = gnc_split_register_get_rate_cell (reg, RATE_CELL);
422 if (acc && gnc_split_register_needs_conv_rate (reg, sd->trans, acc))
430 amtconv = xaccTransGetAccountConvRate(sd->trans, acc);
438 if (reg->type == STOCK_REGISTER ||
439 reg->type == CURRENCY_REGISTER ||
440 reg->type == PORTFOLIO_LEDGER)
456 if (gnc_split_register_split_needs_amount (reg, sd->split))
485 if (acc && gnc_split_register_needs_conv_rate (reg, sd->trans, acc))
503 if (gnc_split_register_split_needs_amount (reg, sd->split))
514 gnc_split_register_save_debcred_cell (BasicCell * bcell,
518 SRSaveData *sd = save_data;
519 SplitRegister *reg = user_data;
521 g_return_if_fail (gnc_basic_cell_has_name (bcell, DEBT_CELL) ||
522 gnc_basic_cell_has_name (bcell, CRED_CELL));
527 gnc_split_register_save_amount_values (sd, reg);
529 sd->handled_dc = TRUE;
534 gnc_split_register_save_rate_cell (BasicCell * bcell,
538 SRSaveData *sd = save_data;
545 gnc_split_register_save_cells (gpointer save_data,
548 SRSaveData *sd = save_data;
549 SplitRegister *reg = user_data;
551 gnc_commodity *txn_cur;
554 g_return_if_fail (sd != NULL);
564 rate = gnc_split_register_get_rate_cell (reg, RATE_CELL);
566 if (other_split && !sd->reg_expanded)
570 gboolean split_needs_amount;
572 split_needs_amount = gnc_split_register_split_needs_amount(reg, sd->split);
590 if (gnc_split_register_split_needs_amount (reg, other_split))
613 else if (gnc_split_register_split_needs_amount (reg, sd->split) &&
626 gnc_split_register_save_amount_values (sd, reg);
628 gnc_numeric value, amount;
640 gnc_template_register_save_unexpected_cell (BasicCell * cell,
644 PERR (
"unexpected changed fields in a template register");
648 gnc_template_register_save_xfrm_cell (BasicCell * cell,
652 SRSaveData *sd = save_data;
653 SplitRegister *reg = user_data;
654 SRInfo *info = gnc_split_register_get_info (reg);
659 g_return_if_fail (gnc_basic_cell_has_name (cell, XFRM_CELL));
662 acct = gnc_split_register_get_account (reg, XFRM_CELL);
665 PERR (
"unknown account");
671 "sx-account", acctGUID,
674 gnc_get_current_book ());
681 gnc_template_register_save_mxfrm_cell (BasicCell * cell,
688 save_cell (SplitRegister *reg, Split* split,
const char *cell_name)
690 const gboolean is_credit = g_strcmp0 (cell_name, FCRED_CELL) == 0;
691 const char *formula = is_credit ?
692 "sx-credit-formula" :
"sx-debit-formula";
693 const char *
numeric = is_credit ?
694 "sx-credit-numeric" :
"sx-debit-numeric";
695 const char *value = gnc_table_layout_get_cell_value (reg->table->layout,
697 gnc_numeric new_amount = gnc_numeric_zero ();
698 GHashTable *parser_vars = g_hash_table_new (g_str_hash, g_str_equal);
705 const gboolean parse_result =
706 gnc_exp_parser_parse_separate_vars (value, &new_amount,
707 &error_loc, parser_vars);
708 if (!parse_result || g_hash_table_size (parser_vars) != 0)
709 new_amount = gnc_numeric_zero ();
710 g_hash_table_unref (parser_vars);
718 gnc_template_register_save_debcred_cell (BasicCell * cell,
722 SRSaveData *sd = save_data;
723 SplitRegister *reg = user_data;
725 g_return_if_fail (gnc_basic_cell_has_name (cell, FDEBT_CELL) ||
726 gnc_basic_cell_has_name (cell, FCRED_CELL));
731 save_cell (reg, sd->split, FCRED_CELL);
732 save_cell (reg, sd->split, FDEBT_CELL);
738 sd->handled_dc = TRUE;
742 gnc_template_register_save_shares_cell (BasicCell * cell,
746 SRSaveData *sd = save_data;
747 char *sharesStr =
"(x + y)/42";
749 g_return_if_fail (gnc_basic_cell_has_name (cell, SHRS_CELL));
752 "sx-shares", sharesStr,
758 gnc_numeric_create (0, 1),
759 gnc_numeric_create (0, 1));
763 gnc_split_register_model_add_save_handlers (
TableModel *model)
765 g_return_if_fail (model != NULL);
767 gnc_table_model_set_save_handler (model,
768 gnc_split_register_save_date_cell,
771 gnc_table_model_set_save_handler (model,
772 gnc_split_register_save_due_date_cell,
775 gnc_table_model_set_save_handler (model,
776 gnc_split_register_save_type_cell,
779 gnc_table_model_set_save_handler (model,
780 gnc_split_register_save_num_cell,
783 gnc_table_model_set_save_handler (model,
784 gnc_split_register_save_tnum_cell,
787 gnc_table_model_set_save_handler (model,
788 gnc_split_register_save_desc_cell,
791 gnc_table_model_set_save_handler (model,
792 gnc_split_register_save_notes_cell,
795 gnc_table_model_set_save_handler (model,
796 gnc_split_register_save_recn_cell,
799 gnc_table_model_set_save_handler (model,
800 gnc_split_register_save_actn_cell,
803 gnc_table_model_set_save_handler (model,
804 gnc_split_register_save_memo_cell,
807 gnc_table_model_set_save_handler (model,
808 gnc_split_register_save_xfrm_cell,
811 gnc_table_model_set_save_handler (model,
812 gnc_split_register_save_mxfrm_cell,
815 gnc_table_model_set_save_handler (model,
816 gnc_split_register_save_shares_cell,
819 gnc_table_model_set_save_handler (model,
820 gnc_split_register_save_price_cell,
823 gnc_table_model_set_save_handler (model,
824 gnc_split_register_save_debcred_cell,
827 gnc_table_model_set_save_handler (model,
828 gnc_split_register_save_debcred_cell,
831 gnc_table_model_set_save_handler (model,
832 gnc_split_register_save_rate_cell,
835 gnc_table_model_set_post_save_handler (model, gnc_split_register_save_cells);
839 gnc_template_register_model_add_save_handlers (
TableModel *model)
841 g_return_if_fail (model != NULL);
843 gnc_split_register_model_add_save_handlers (model);
845 gnc_table_model_set_save_handler (model,
846 gnc_template_register_save_unexpected_cell,
849 gnc_table_model_set_save_handler (model,
850 gnc_template_register_save_unexpected_cell,
853 gnc_table_model_set_save_handler (model,
854 gnc_template_register_save_xfrm_cell,
857 gnc_table_model_set_save_handler (model,
858 gnc_template_register_save_mxfrm_cell,
861 gnc_table_model_set_save_handler (model,
862 gnc_template_register_save_debcred_cell,
865 gnc_table_model_set_save_handler (model,
866 gnc_template_register_save_debcred_cell,
869 gnc_table_model_set_save_handler (model,
870 gnc_template_register_save_shares_cell,
875 gnc_split_register_save_data_new (Transaction *trans, Split *split,
880 g_return_val_if_fail (trans != NULL, NULL);
881 g_return_val_if_fail (split != NULL, NULL);
883 sd = g_new0 (SRSaveData, 1);
887 sd->handled_dc = FALSE;
888 sd->do_scrub = FALSE;
889 sd->reg_expanded = expanded;
895 gnc_split_register_save_data_destroy (SRSaveData *sd)
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
The RecnCell object implements a cell handler that will cycle through a series of single-character va...
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction's split list.
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Determine whether this transaction should use commodity trading accounts.
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false. ...
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
void xaccTransSetNotes(Transaction *trans, const char *notes)
Sets the transaction Notes.
#define DEBUG(format, args...)
Print a debugging message.
void qof_instance_set(QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_set Group setting multiple parameters in a single begin/commit/rollback.
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
Save handlers for the SplitRegister Model and Template SplitRegister model.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
void xaccSplitSetReconcile(Split *split, char recn)
Set the reconcile flag.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
#define PERR(format, args...)
Log a serious error.
#define xaccAccountGetGUID(X)
void xaccTransSetTxnType(Transaction *trans, char type)
Set the Transaction Type: note the type will be saved into the Transaction kvp property as a backward...
convert single-entry accounts to clean double-entry
Split * xaccSplitLookup(const GncGUID *guid, QofBook *book)
The xaccSplitLookup() subroutine will return the split associated with the given id, or NULL if there is no such split.
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
The PriceCell object implements a cell handler that stores a single double-precision value...
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
void xaccSplitSetSharePriceAndAmount(Split *s, gnc_numeric price, gnc_numeric amt)
The xaccSplitSetSharePriceAndAmount() method will simultaneously update the share price and the numbe...
void gnc_date_cell_get_date(DateCell *cell, time64 *time, gboolean warn)
Set a time64 to the value in the DateCell.
void gnc_date_cell_commit(DateCell *cell)
Commits any pending changes to the value of the cell.
void xaccSplitScrub(Split *split)
The xaccSplitScrub method ensures that if this split has the same commodity and currency, then it will have the same amount and value.
private declarations for SplitRegister
void xaccTransSetDateDue(Transaction *trans, time64 time)
Dates and txn-type for A/R and A/P "invoice" postings.
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
All type declarations for the whole Gnucash engine.
Split * xaccMallocSplit(QofBook *book)
Constructor.
The NumCell object implements a number handling cell.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
Split * xaccSplitGetOtherSplit(const Split *split)
The xaccSplitGetOtherSplit() is a convenience routine that returns the other of a pair of splits...
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
void xaccSplitSetSharePrice(Split *s, gnc_numeric price)
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
The DateCell object implements a date handling cell.
Scheduled Transactions public handling routines.
The type used to store guids in C.
gnc_numeric gnc_price_cell_get_value(PriceCell *cell)
return the value of a price cell
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id...