GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
split-register-model-save.c
1 /********************************************************************\
2  * split-register-model-save.c -- split register model object *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA [email protected] *
20  * *
21 \********************************************************************/
22 
23 #include "config.h"
24 
25 #include <glib.h>
26 
27 #include "Scrub.h"
28 #include "SchedXaction.h"
29 #include "datecell.h"
30 #include "gnc-engine.h"
31 #include "engine-helpers.h"
32 #include "numcell.h"
33 #include "pricecell.h"
34 #include "recncell.h"
35 #include "split-register-model-save.h"
36 #include "split-register-p.h"
37 #include "app-utils/gnc-exp-parser.h"
38 
39 
41 {
42  Transaction *trans;
43  Split *split;
44 
45  gboolean handled_dc; /* We have already handled the debit/credit cells. */
46  gboolean do_scrub; /* Scrub other split at the end. */
47  gboolean reg_expanded; /* Register is in expanded (split) mode */
48 };
49 
50 /* This static indicates the debugging module that this .o belongs to. */
51 static QofLogModule log_module = GNC_MOD_LEDGER;
52 
53 
54 static void
55 gnc_split_register_save_date_cell (BasicCell * cell,
56  gpointer save_data,
57  gpointer user_data)
58 {
59  SRSaveData *sd = save_data;
60  const char *value;
61  GDate gdate;
62 
63  g_return_if_fail (gnc_basic_cell_has_name (cell, DATE_CELL));
64 
65  value = gnc_basic_cell_get_value (cell);
66 
67  /* commit any pending changes */
68  gnc_date_cell_commit ((DateCell *) cell);
69 
70  DEBUG ("DATE: %s", value ? value : "(null)");
71 
72  gnc_date_cell_get_date_gdate ((DateCell *) cell, &gdate);
73 
74  xaccTransSetDatePostedGDate (sd->trans, gdate);
75 }
76 
77 static void
78 gnc_split_register_save_type_cell (BasicCell * cell,
79  gpointer save_data,
80  gpointer user_data)
81 {
82  SRSaveData *sd = save_data;
83  char value;
84 
85  g_return_if_fail (gnc_basic_cell_has_name (cell, TYPE_CELL));
86 
87  value = gnc_recn_cell_get_flag ((RecnCell *)cell);
88 
89  xaccTransSetTxnType (sd->trans, value);
90 }
91 
92 static void
93 gnc_split_register_save_due_date_cell (BasicCell * cell,
94  gpointer save_data,
95  gpointer user_data)
96 {
97  SRSaveData *sd = save_data;
98  const char *value;
99  Timespec ts;
100 
101  g_return_if_fail (gnc_basic_cell_has_name (cell, DDUE_CELL));
102 
103  value = gnc_basic_cell_get_value (cell);
104 
105  /* commit any pending changes */
106  gnc_date_cell_commit ((DateCell *) cell);
107 
108  DEBUG ("DATE: %s", value ? value : "(null)");
109 
110  gnc_date_cell_get_date ((DateCell *) cell, &ts);
111 
112  xaccTransSetDateDueTS (sd->trans, &ts);
113 }
114 
115 static void
116 gnc_split_register_save_num_cell (BasicCell * cell,
117  gpointer save_data,
118  gpointer user_data)
119 {
120  SRSaveData *sd = save_data;
121  SplitRegister *reg = user_data;
122  const char *value;
123 
124  g_return_if_fail (gnc_basic_cell_has_name (cell, NUM_CELL));
125 
126  value = gnc_basic_cell_get_value (cell);
127 
128  DEBUG ("NUM: %s\n", value ? value : "(null)");
129 
130  /* set per book option */
131  gnc_set_num_action (sd->trans, sd->split, value, NULL);
132 
133  if (gnc_num_cell_set_last_num ((NumCell *) cell, value))
134  {
135  SRInfo *info = gnc_split_register_get_info (reg);
136  Split *blank_split = xaccSplitLookup (&info->blank_split_guid,
137  gnc_get_current_book ());
138  Transaction *blank_trans = xaccSplitGetParent (blank_split);
139 
140  if (sd->trans == blank_trans)
141  gnc_split_register_set_last_num (reg, gnc_basic_cell_get_value (cell));
142  }
143 }
144 
145 static void
146 gnc_split_register_save_tnum_cell (BasicCell * cell,
147  gpointer save_data,
148  gpointer user_data)
149 {
150  SRSaveData *sd = save_data;
151  SplitRegister *reg = user_data;
152  const char *value;
153 
154  g_return_if_fail (gnc_basic_cell_has_name (cell, TNUM_CELL));
155 
156  value = gnc_basic_cell_get_value (cell);
157 
158  DEBUG ("TNUM: %s\n", value ? value : "(null)");
159 
160  /* set tran-num using utility function */
161  gnc_set_num_action (sd->trans, NULL, value, NULL);
162 }
163 
164 static void
165 gnc_split_register_save_desc_cell (BasicCell * cell,
166  gpointer save_data,
167  gpointer user_data)
168 {
169  SRSaveData *sd = save_data;
170  const char *value;
171 
172  g_return_if_fail (gnc_basic_cell_has_name (cell, DESC_CELL));
173 
174  value = gnc_basic_cell_get_value (cell);
175 
176  DEBUG ("DESC: %s", value ? value : "(null)");
177 
178  xaccTransSetDescription (sd->trans, value);
179 }
180 
181 static void
182 gnc_split_register_save_notes_cell (BasicCell * cell,
183  gpointer save_data,
184  gpointer user_data)
185 {
186  SRSaveData *sd = save_data;
187  const char *value;
188 
189  g_return_if_fail (gnc_basic_cell_has_name (cell, NOTES_CELL));
190 
191  value = gnc_basic_cell_get_value (cell);
192 
193  DEBUG ("NOTES: %s", value ? value : "(null)");
194 
195  xaccTransSetNotes (sd->trans, value);
196 }
197 
198 static void
199 gnc_split_register_save_recn_cell (BasicCell * bcell,
200  gpointer save_data,
201  gpointer user_data)
202 {
203  SRSaveData *sd = save_data;
204  RecnCell *cell = (RecnCell *) bcell;
205 
206  g_return_if_fail (gnc_basic_cell_has_name (bcell, RECN_CELL));
207 
208  DEBUG ("RECN: %c", gnc_recn_cell_get_flag (cell));
209 
210  xaccSplitSetReconcile (sd->split, gnc_recn_cell_get_flag (cell));
211 }
212 
213 static void
214 gnc_split_register_save_actn_cell (BasicCell * cell,
215  gpointer save_data,
216  gpointer user_data)
217 {
218  SRSaveData *sd = save_data;
219  const char *value;
220 
221  g_return_if_fail (gnc_basic_cell_has_name (cell, ACTN_CELL));
222 
223  value = gnc_basic_cell_get_value (cell);
224 
225  DEBUG ("ACTN: %s", value ? value : "(null)");
226 
227  /* Set split-action with gnc_set_num_action which is the same as
228  * xaccSplitSetAction with these arguments */
229  gnc_set_num_action (NULL, sd->split, NULL, value);
230 }
231 
232 static void
233 gnc_split_register_save_memo_cell (BasicCell * cell,
234  gpointer save_data,
235  gpointer user_data)
236 {
237  SRSaveData *sd = save_data;
238  const char *value;
239 
240  g_return_if_fail (gnc_basic_cell_has_name (cell, MEMO_CELL));
241 
242  value = gnc_basic_cell_get_value (cell);
243 
244  DEBUG ("MEMO: %s", value ? value : "(null)");
245 
246  xaccSplitSetMemo (sd->split, value);
247 }
248 
249 /* OK, the handling of transfers gets complicated because it depends
250  * on what was displayed to the user. For a multi-line display, we
251  * just reparent the indicated split. For a two-line display, we want
252  * to reparent the "other" split, but only if there is one. XFRM is
253  * the straight split, MXFRM is the mirrored split. */
254 static void
255 gnc_split_register_save_xfrm_cell (BasicCell * cell,
256  gpointer save_data,
257  gpointer user_data)
258 {
259  SRSaveData *sd = save_data;
260  SplitRegister *reg = user_data;
261  Account *old_acc;
262  Account *new_acc;
263 
264  g_return_if_fail (gnc_basic_cell_has_name (cell, XFRM_CELL));
265 
266  old_acc = xaccSplitGetAccount (sd->split);
267 
268  new_acc = gnc_split_register_get_account (reg, XFRM_CELL);
269 
270  if ((new_acc != NULL) && (old_acc != new_acc))
271  xaccAccountInsertSplit (new_acc, sd->split);
272 }
273 
274 static void
275 gnc_split_register_save_mxfrm_cell (BasicCell * cell,
276  gpointer save_data,
277  gpointer user_data)
278 {
279  SRSaveData *sd = save_data;
280  SplitRegister *reg = user_data;
281  Split * other_split;
282 
283  g_return_if_fail (gnc_basic_cell_has_name (cell, MXFRM_CELL));
284 
285  other_split = xaccSplitGetOtherSplit (sd->split);
286 
287  /* other_split may be null for two very different reasons:
288  * (1) the parent transaction has three or more splits in it,
289  * and so the "other" split is ambiguous, and thus null.
290  * (2) the parent transaction has only this one split as a child.
291  * and "other" is null because there is no other.
292  *
293  * In the case (2), we want to create the other split, so that
294  * the user's request to transfer actually works out. */
295 
296  if (!other_split)
297  {
298  other_split = xaccTransGetSplit (sd->trans, 1);
299 
300  if (!other_split)
301  {
302  other_split = xaccMallocSplit (gnc_get_current_book ());
303  xaccTransAppendSplit (sd->trans, other_split);
304  }
305  }
306 
307  if (other_split)
308  {
309  Account *old_acc;
310  Account *new_acc;
311 
312  /* Do some reparenting. Insertion into new account
313  * will automatically delete from the old account. */
314  old_acc = xaccSplitGetAccount (other_split);
315  new_acc = gnc_split_register_get_account (reg, MXFRM_CELL);
316 
317  if ((new_acc != NULL) && (old_acc != new_acc))
318  xaccAccountInsertSplit (new_acc, other_split);
319  }
320 }
321 
322 static void
323 gnc_split_register_save_shares_cell (BasicCell * bcell,
324  gpointer save_data,
325  gpointer user_data)
326 {
327  SRSaveData *sd = save_data;
328  PriceCell *cell = (PriceCell *) bcell;
329  gnc_numeric amount;
330 
331  g_return_if_fail (gnc_basic_cell_has_name (bcell, SHRS_CELL));
332 
333  amount = gnc_price_cell_get_value (cell);
334 
335  DEBUG ("SHRS");
336 
337  xaccSplitSetAmount (sd->split, amount);
338 
339  sd->do_scrub = TRUE;
340 }
341 
342 static void
343 gnc_split_register_save_price_cell (BasicCell * bcell,
344  gpointer save_data,
345  gpointer user_data)
346 {
347  SRSaveData *sd = save_data;
348  PriceCell *cell = (PriceCell *) bcell;
349  gnc_numeric price;
350 
351  g_return_if_fail (gnc_basic_cell_has_name (bcell, PRIC_CELL));
352 
353  price = gnc_price_cell_get_value (cell);
354 
355  DEBUG ("PRIC");
356 
357  /* If we handled the Debcred cell then don't set the share price! */
358  if (!sd->handled_dc)
359  xaccSplitSetSharePrice (sd->split, price);
360 
361  sd->do_scrub = TRUE;
362 }
363 
365 gnc_split_register_debcred_cell_value (SplitRegister *reg)
366 {
367  PriceCell *cell;
368  gnc_numeric new_amount;
369  gnc_numeric credit;
370  gnc_numeric debit;
371 
372  cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
373  CRED_CELL);
374  credit = gnc_price_cell_get_value (cell);
375 
376  cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
377  DEBT_CELL);
378  debit = gnc_price_cell_get_value (cell);
379 
380  new_amount = gnc_numeric_sub_fixed (debit, credit);
381 
382  return new_amount;
383 }
384 
385 static gnc_numeric
386 gnc_split_register_get_rate_cell (SplitRegister *reg, const char *cell_name)
387 {
388  PriceCell *rate_cell;
389 
390  rate_cell = (PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
391  cell_name);
392  if (rate_cell)
393  return gnc_price_cell_get_value (rate_cell);
394 
395  /* Uhh, just return '1' */
396  return gnc_numeric_create (100, 100);
397 }
398 
399 gboolean
400 gnc_split_register_split_needs_amount (SplitRegister *reg, Split *split)
401 {
402  Transaction *txn = xaccSplitGetParent (split);
403  Account *acc = xaccSplitGetAccount (split);
404 
405  return gnc_split_register_needs_conv_rate (reg, txn, acc);
406 }
407 
408 static void
409 gnc_split_register_save_amount_values (SRSaveData *sd, SplitRegister *reg)
410 {
411  Account *acc;
412  gnc_numeric new_amount, convrate, amtconv, value;
413  gnc_commodity *curr, *reg_com, *xfer_com;
414  Account *xfer_acc;
415 
416  new_amount = gnc_split_register_debcred_cell_value (reg);
417  acc = gnc_split_register_get_default_account (reg);
418 
419  xfer_acc = xaccSplitGetAccount (sd->split);
420  xfer_com = xaccAccountGetCommodity (xfer_acc);
421  reg_com = xaccAccountGetCommodity (acc);
422  curr = xaccTransGetCurrency (sd->trans);
423 
424  /* First, compute the conversion rate to convert the value to the
425  * amount.
426  */
427  amtconv = convrate = gnc_split_register_get_rate_cell (reg, RATE_CELL);
428  if (acc && gnc_split_register_needs_conv_rate (reg, sd->trans, acc))
429  {
430 
431  /* If we are in an expanded register and the xfer_acc->comm !=
432  * reg_acc->comm then we need to compute the convrate here.
433  * Otherwise, we _can_ use the rate_cell!
434  */
435  if (sd->reg_expanded && ! gnc_commodity_equal (reg_com, xfer_com))
436  amtconv = xaccTransGetAccountConvRate(sd->trans, acc);
437  }
438 
439  if (xaccTransUseTradingAccounts (sd->trans))
440  {
441  /* Using currency accounts, the amount is probably really the
442  amount and not the value. */
443  gboolean is_amount;
444  if (reg->type == STOCK_REGISTER ||
445  reg->type == CURRENCY_REGISTER ||
446  reg->type == PORTFOLIO_LEDGER)
447  {
448  if (xaccAccountIsPriced(xfer_acc) ||
450  is_amount = FALSE;
451  else
452  is_amount = TRUE;
453  }
454  else
455  {
456  is_amount = TRUE;
457  }
458 
459  if (is_amount)
460  {
461  xaccSplitSetAmount(sd->split, new_amount);
462  if (gnc_split_register_split_needs_amount (reg, sd->split))
463  {
464  value = gnc_numeric_div(new_amount, amtconv,
467  xaccSplitSetValue(sd->split, value);
468  }
469  else
470  xaccSplitSetValue(sd->split, new_amount);
471  }
472  else
473  {
474  xaccSplitSetValue(sd->split, new_amount);
475  }
476 
477  return;
478  }
479 
480  /* How to interpret new_amount depends on our view of this
481  * transaction. If we're sitting in an account with the same
482  * commodity as the transaction, then we can set the Value and then
483  * compute the amount. Otherwise we are setting the "converted
484  * value". This means we need to convert new_amount to the actual
485  * 'value' by dividing by the convrate in order to set the value.
486  */
487 
488  /* Now compute/set the split value. Amount is in the register
489  * currency but we need to convert to the txn currency.
490  */
491  if (acc && gnc_split_register_needs_conv_rate (reg, sd->trans, acc))
492  {
493 
494  /* convert the amount to the Value ... */
495  value = gnc_numeric_div (new_amount, amtconv,
498  xaccSplitSetValue (sd->split, value);
499  }
500  else
501  xaccSplitSetValue (sd->split, new_amount);
502 
503  /* Now re-compute the Amount from the Value. We may need to convert
504  * from the Value back to the amount here using the convrate from
505  * earlier.
506  */
507  value = xaccSplitGetValue (sd->split);
508 
509  if (gnc_split_register_split_needs_amount (reg, sd->split))
510  {
511  acc = xaccSplitGetAccount (sd->split);
512  new_amount = gnc_numeric_mul (value, convrate,
515  xaccSplitSetAmount (sd->split, new_amount);
516  }
517 }
518 
519 static void
520 gnc_split_register_save_debcred_cell (BasicCell * bcell,
521  gpointer save_data,
522  gpointer user_data)
523 {
524  SRSaveData *sd = save_data;
525  SplitRegister *reg = user_data;
526 
527  g_return_if_fail (gnc_basic_cell_has_name (bcell, DEBT_CELL) ||
528  gnc_basic_cell_has_name (bcell, CRED_CELL));
529 
530  if (sd->handled_dc)
531  return;
532 
533  gnc_split_register_save_amount_values (sd, reg);
534 
535  sd->handled_dc = TRUE;
536  sd->do_scrub = TRUE;
537 }
538 
539 static void
540 gnc_split_register_save_rate_cell (BasicCell * bcell,
541  gpointer save_data,
542  gpointer user_data)
543 {
544  SRSaveData *sd = save_data;
545 
546  /* if the exchrate cell changed, then make sure to force a scrub */
547  sd->do_scrub = TRUE;
548 }
549 
550 static void
551 gnc_split_register_save_cells (gpointer save_data,
552  gpointer user_data)
553 {
554  SRSaveData *sd = save_data;
555  SplitRegister *reg = user_data;
556  Split *other_split;
557  gnc_commodity *txn_cur;
558  gnc_numeric rate = gnc_numeric_zero();
559 
560  g_return_if_fail (sd != NULL);
561 
562  if (!sd->do_scrub)
563  return;
564 
565  other_split = xaccSplitGetOtherSplit (sd->split);
566  txn_cur = xaccTransGetCurrency (sd->trans);
567 
568  xaccSplitScrub (sd->split);
569 
570  rate = gnc_split_register_get_rate_cell (reg, RATE_CELL);
571 
572  if (other_split && !sd->reg_expanded)
573  {
574  gnc_numeric amount, value = xaccSplitGetValue (sd->split);
575  Account *acc;
576  gboolean split_needs_amount;
577 
578  split_needs_amount = gnc_split_register_split_needs_amount(reg, sd->split);
579 
580  /* We are changing the rate on the current split, but it was not
581  * handled in the debcred handler, so we need to do it here.
582  */
583  if (!sd->handled_dc && split_needs_amount && !gnc_numeric_zero_p (rate))
584  {
585  gnc_numeric amount = xaccSplitGetAmount (sd->split);
586  value = gnc_numeric_div(
587  amount, rate, gnc_commodity_get_fraction(txn_cur), GNC_HOW_RND_ROUND_HALF_UP);
588  xaccSplitSetValue (sd->split, value);
589 
590  /* XXX: do we need to set the amount on the other split? */
591  }
592 
593  /* Now reverse the value for the other split */
594  value = gnc_numeric_neg (value);
595 
596  if (gnc_split_register_split_needs_amount (reg, other_split))
597  {
598  acc = xaccSplitGetAccount (other_split);
599 
600  /* If we don't have an exchange rate then figure it out. Or, if
601  * BOTH splits require an amount, then most likely we're in the
602  * strange case of having a transaction currency different than
603  * _both_ accounts -- so grab the other exchange rate.
604  */
605  if (gnc_numeric_zero_p (rate) || split_needs_amount)
606  rate = xaccTransGetAccountConvRate(xaccSplitGetParent (other_split),
607  acc);
608 
609  amount = gnc_numeric_mul (value, rate, xaccAccountGetCommoditySCU (acc),
611  xaccSplitSetAmount (other_split, amount);
612 
613  }
614 
615  xaccSplitSetValue (other_split, value);
616 
617  xaccSplitScrub (other_split);
618  }
619  else if (gnc_split_register_split_needs_amount (reg, sd->split) &&
620  ! gnc_numeric_zero_p (rate))
621  {
622  /* this is either a multi-split or expanded transaction, so only
623  * deal with this split... In particular we need to reset the
624  * Value if the conv-rate changed.
625  *
626  * If we handled the debcred then no need to do anything there --
627  * the debcred handler did all the computation. If NOT, then the
628  * convrate changed -- reset the value from the amount.
629  */
630  if (!sd->handled_dc)
631  {
632  gnc_split_register_save_amount_values (sd, reg);
633 #if 0
634  gnc_numeric value, amount;
635 
636  amount = xaccSplitGetAmount (sd->split);
637  value = gnc_numeric_div (amount, rate, gnc_commodity_get_fraction (txn_cur),
639  xaccSplitSetValue (sd->split, value);
640 #endif
641  }
642  }
643 }
644 
645 static void
646 gnc_template_register_save_unexpected_cell (BasicCell * cell,
647  gpointer save_data,
648  gpointer user_data)
649 {
650  PERR ("unexpected changed fields in a template register");
651 }
652 
653 static void
654 gnc_template_register_save_xfrm_cell (BasicCell * cell,
655  gpointer save_data,
656  gpointer user_data)
657 {
658  SRSaveData *sd = save_data;
659  SplitRegister *reg = user_data;
660  SRInfo *info = gnc_split_register_get_info (reg);
661  Account *template_acc;
662  const GncGUID *acctGUID;
663  KvpFrame *kvpf;
664  Account *acct;
665 
666  g_return_if_fail (gnc_basic_cell_has_name (cell, XFRM_CELL));
667 
668  /* save the account GncGUID into the kvp_data. */
669  acct = gnc_split_register_get_account (reg, XFRM_CELL);
670  if (!acct)
671  {
672  PERR ("unknown account");
673  return;
674  }
675 
676  acctGUID = xaccAccountGetGUID (acct);
677  qof_instance_set (QOF_INSTANCE (sd->split),
678  "sx-account", acctGUID,
679  NULL);
680  template_acc = xaccAccountLookup (&info->template_account,
681  gnc_get_current_book ());
682 
683  /* set the actual account to the fake account for these templates */
684  xaccAccountInsertSplit (template_acc, sd->split);
685 }
686 
687 static void
688 gnc_template_register_save_mxfrm_cell (BasicCell * cell,
689  gpointer save_data,
690  gpointer user_data)
691 {
692 }
693 
694 static void
695 gnc_template_register_save_debcred_cell (BasicCell * cell,
696  gpointer save_data,
697  gpointer user_data)
698 {
699  SRSaveData *sd = save_data;
700  SplitRegister *reg = user_data;
701  const char *credit_formula, *debit_formula;
702  char *error_loc;
703  gnc_numeric credit_amount, debit_amount;
704  gboolean parse_result;
705 
706  g_return_if_fail (gnc_basic_cell_has_name (cell, FDEBT_CELL) ||
707  gnc_basic_cell_has_name (cell, FCRED_CELL));
708 
709  if (sd->handled_dc)
710  return;
711 
712  /* amountStr = gnc_numeric_to_string (new_amount); */
713 
714  credit_formula = gnc_table_layout_get_cell_value (reg->table->layout,
715  FCRED_CELL);
716  /* If the value can be parsed into a numeric result (without any
717  * further variable definitions), store that numeric value
718  * additionally in the kvp. Otherwise store a zero numeric
719  * there.*/
720  parse_result = gnc_exp_parser_parse_separate_vars(credit_formula,
721  &credit_amount,
722  &error_loc, NULL);
723  if (!parse_result)
724  credit_amount = gnc_numeric_zero();
725 
726  debit_formula = gnc_table_layout_get_cell_value (reg->table->layout,
727  FDEBT_CELL);
728 
729  /* If the value can be parsed into a numeric result, store that
730  * numeric value additionally. See above comment.*/
731  parse_result = gnc_exp_parser_parse_separate_vars(debit_formula,
732  &debit_amount,
733  &error_loc, NULL);
734  if (!parse_result)
735  debit_amount = gnc_numeric_zero();
736 
737  qof_instance_set (QOF_INSTANCE (sd->split),
738  "sx-credit-formula", credit_formula,
739  "sx-credit-numeric", &credit_amount,
740  "sx-debit-formula", debit_formula,
741  "sx-debit-numeric", &debit_amount,
742  NULL);
743  /* set the amount to an innocuous value */
744  /* Note that this marks the split dirty */
745  xaccSplitSetValue (sd->split, gnc_numeric_create (0, 1));
746 
747  sd->handled_dc = TRUE;
748 }
749 
750 static void
751 gnc_template_register_save_shares_cell (BasicCell * cell,
752  gpointer save_data,
753  gpointer user_data)
754 {
755  SRSaveData *sd = save_data;
756  char *sharesStr = "(x + y)/42";
757 
758  g_return_if_fail (gnc_basic_cell_has_name (cell, SHRS_CELL));
759  /* FIXME: shares cells are numeric by definition. */
760  qof_instance_set (QOF_INSTANCE (sd->split),
761  "sx-shares", sharesStr,
762  NULL);
763 
764  /* set the shares to an innocuous value */
765  /* Note that this marks the split dirty */
767  gnc_numeric_create (0, 1),
768  gnc_numeric_create (0, 1));
769 }
770 
771 void
772 gnc_split_register_model_add_save_handlers (TableModel *model)
773 {
774  g_return_if_fail (model != NULL);
775 
776  gnc_table_model_set_save_handler (model,
777  gnc_split_register_save_date_cell,
778  DATE_CELL);
779 
780  gnc_table_model_set_save_handler (model,
781  gnc_split_register_save_due_date_cell,
782  DDUE_CELL);
783 
784  gnc_table_model_set_save_handler (model,
785  gnc_split_register_save_type_cell,
786  TYPE_CELL);
787 
788  gnc_table_model_set_save_handler (model,
789  gnc_split_register_save_num_cell,
790  NUM_CELL);
791 
792  gnc_table_model_set_save_handler (model,
793  gnc_split_register_save_tnum_cell,
794  TNUM_CELL);
795 
796  gnc_table_model_set_save_handler (model,
797  gnc_split_register_save_desc_cell,
798  DESC_CELL);
799 
800  gnc_table_model_set_save_handler (model,
801  gnc_split_register_save_notes_cell,
802  NOTES_CELL);
803 
804  gnc_table_model_set_save_handler (model,
805  gnc_split_register_save_recn_cell,
806  RECN_CELL);
807 
808  gnc_table_model_set_save_handler (model,
809  gnc_split_register_save_actn_cell,
810  ACTN_CELL);
811 
812  gnc_table_model_set_save_handler (model,
813  gnc_split_register_save_memo_cell,
814  MEMO_CELL);
815 
816  gnc_table_model_set_save_handler (model,
817  gnc_split_register_save_xfrm_cell,
818  XFRM_CELL);
819 
820  gnc_table_model_set_save_handler (model,
821  gnc_split_register_save_mxfrm_cell,
822  MXFRM_CELL);
823 
824  gnc_table_model_set_save_handler (model,
825  gnc_split_register_save_shares_cell,
826  SHRS_CELL);
827 
828  gnc_table_model_set_save_handler (model,
829  gnc_split_register_save_price_cell,
830  PRIC_CELL);
831 
832  gnc_table_model_set_save_handler (model,
833  gnc_split_register_save_debcred_cell,
834  DEBT_CELL);
835 
836  gnc_table_model_set_save_handler (model,
837  gnc_split_register_save_debcred_cell,
838  CRED_CELL);
839 
840  gnc_table_model_set_save_handler (model,
841  gnc_split_register_save_rate_cell,
842  RATE_CELL);
843 
844  gnc_table_model_set_post_save_handler (model, gnc_split_register_save_cells);
845 }
846 
847 void
848 gnc_template_register_model_add_save_handlers (TableModel *model)
849 {
850  g_return_if_fail (model != NULL);
851 
852  gnc_split_register_model_add_save_handlers (model);
853 
854  gnc_table_model_set_save_handler (model,
855  gnc_template_register_save_unexpected_cell,
856  DATE_CELL);
857 
858  gnc_table_model_set_save_handler (model,
859  gnc_template_register_save_unexpected_cell,
860  DDUE_CELL);
861 
862  gnc_table_model_set_save_handler (model,
863  gnc_template_register_save_xfrm_cell,
864  XFRM_CELL);
865 
866  gnc_table_model_set_save_handler (model,
867  gnc_template_register_save_mxfrm_cell,
868  MXFRM_CELL);
869 
870  gnc_table_model_set_save_handler (model,
871  gnc_template_register_save_debcred_cell,
872  FDEBT_CELL);
873 
874  gnc_table_model_set_save_handler (model,
875  gnc_template_register_save_debcred_cell,
876  FCRED_CELL);
877 
878  gnc_table_model_set_save_handler (model,
879  gnc_template_register_save_shares_cell,
880  SHRS_CELL);
881 }
882 
883 SRSaveData *
884 gnc_split_register_save_data_new (Transaction *trans, Split *split,
885  gboolean expanded)
886 {
887  SRSaveData *sd;
888 
889  g_return_val_if_fail (trans != NULL, NULL);
890  g_return_val_if_fail (split != NULL, NULL);
891 
892  sd = g_new0 (SRSaveData, 1);
893 
894  sd->trans = trans;
895  sd->split = split;
896  sd->handled_dc = FALSE;
897  sd->do_scrub = FALSE;
898  sd->reg_expanded = expanded;
899 
900  return sd;
901 }
902 
903 void
904 gnc_split_register_save_data_destroy (SRSaveData *sd)
905 {
906  g_free (sd);
907 }
void xaccSplitSetValue(Split *s, gnc_numeric amt)
Definition: Split.c:1294
#define xaccTransAppendSplit(t, s)
Definition: Transaction.h:357
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Split * xaccTransGetSplit(const Transaction *trans, int i)
Definition: Transaction.c:2144
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Definition: Transaction.c:1015
gboolean xaccAccountIsPriced(const Account *acc)
Definition: Account.c:4249
The type, style and table for the register.
int xaccAccountGetCommoditySCU(const Account *acc)
Definition: Account.c:2458
gnc_numeric gnc_numeric_neg(gnc_numeric a)
void xaccTransSetNotes(Transaction *trans, const char *notes)
Definition: Transaction.c:2115
#define DEBUG(format, args...)
Definition: qoflog.h:255
void qof_instance_set(QofInstance *inst, const gchar *first_param,...)
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)
void xaccTransSetDescription(Transaction *trans, const char *desc)
Definition: Transaction.c:2085
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
gboolean gnc_numeric_zero_p(gnc_numeric a)
void xaccSplitSetReconcile(Split *split, char recn)
Definition: Split.c:1826
Transaction * xaccSplitGetParent(const Split *split)
Definition: Split.c:1903
#define PERR(format, args...)
Definition: qoflog.h:237
void xaccTransSetDatePostedGDate(Transaction *trans, GDate date)
Definition: Transaction.c:1928
Definition: guid.h:65
#define xaccAccountGetGUID(X)
Definition: Account.h:239
void xaccTransSetTxnType(Transaction *trans, char type)
Definition: Transaction.c:2016
convert single-entry accounts to clean double-entry
Split * xaccSplitLookup(const GncGUID *guid, QofBook *book)
Definition: Split.c:1104
void xaccSplitSetAmount(Split *s, gnc_numeric amt)
Definition: Split.c:1258
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
void xaccSplitSetMemo(Split *split, const char *memo)
Definition: Split.c:1774
void xaccSplitSetSharePriceAndAmount(Split *s, gnc_numeric price, gnc_numeric amt)
Definition: Split.c:1196
void xaccSplitScrub(Split *split)
Definition: Scrub.c:176
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
All type declarations for the whole Gnucash engine.
Split * xaccMallocSplit(QofBook *book)
Definition: Split.c:582
Definition: SplitP.h:71
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Definition: Account.c:3148
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Definition: Transaction.c:1348
#define xaccAccountInsertSplit(acc, s)
Definition: Account.h:972
void xaccTransSetDateDueTS(Transaction *trans, const Timespec *ts)
Definition: Transaction.c:2006
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
Split * xaccSplitGetOtherSplit(const Split *split)
Definition: Split.c:2086
void xaccSplitSetSharePrice(Split *s, gnc_numeric price)
Definition: Split.c:1224
Scheduled Transactions public handling routines.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
const gchar * QofLogModule
Definition: qofid.h:89
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
Definition: Account.c:1827