27 #include <glib/gi18n.h> 34 #include "assistant-loan.h" 36 #include "SchedXaction.hpp" 38 #include "SX-ttinfo.hpp" 39 #include "gnc-amount-edit.h" 40 #include "gnc-account-sel.h" 42 #include "gnc-exp-parser.h" 43 #include "gnc-component-manager.h" 44 #include "dialog-utils.h" 47 #include "gnc-gui-query.h" 49 #include "gnc-frequency.h" 55 #include <gnc-locale-utils.hpp> 56 #include <boost/locale.hpp> 64 namespace bl = boost::locale;
66 #define DIALOG_LOAN_ASSISTANT_CM_CLASS "assistant-loan-setup" 68 static QofLogModule log_module = GNC_MOD_ASSISTANT;
87 struct LoanAssistantData_;
93 typedef struct RepayOptData_
101 gboolean throughEscrowP;
102 gboolean specSrcAcctP;
115 typedef struct RepayOptDataDefault_
118 const char *defaultTxnMemo;
119 gboolean escrowDefault;
120 gboolean specSrcAcctDefault;
126 { N_(
"Taxes"), N_(
"Tax Payment"), TRUE, FALSE },
127 { N_(
"Insurance"), N_(
"Insurance Payment"), TRUE, FALSE },
129 { N_(
"PMI"), N_(
"PMI Payment"), TRUE, FALSE },
130 { N_(
"Other Expense"), N_(
"Miscellaneous Payment"), FALSE, FALSE },
137 typedef struct RepayOptUI_
141 struct LoanAssistantData_ *ldd;
142 GtkCheckButton *optCb;
143 GtkCheckButton *escrowCb;
151 GNC_VARIABLE_3_1 = GNC_VARIABLE,
169 GNC_IRATE_APR_WEEKLY,
170 GNC_IRATE_APR_MONTHLY,
171 GNC_IRATE_APR_QUARTERLY,
172 GNC_IRATE_APR_ANNUALLY
180 typedef struct rev_repayment_row
183 gnc_numeric *numCells;
189 typedef struct LoanData_
192 gnc_numeric principal;
196 GList *loan_schedule;
209 GList *repayment_schedule;
217 int revRepayOptToColMap[ (
sizeof(REPAY_DEFAULTS)
226 typedef struct LoanAssistantData_
229 GtkWidget *assistant;
243 GNCAccountSel *prmAccountGAS;
244 GNCAmountEdit *prmOrigPrincGAE;
245 GtkSpinButton *prmIrateSpin;
246 GtkComboBox *prmType;
247 GtkFrame *prmVarFrame;
250 GtkSpinButton *prmLengthSpin;
251 GtkComboBox *prmLengthType;
252 GtkSpinButton *prmRemainSpin;
253 GtkComboBox *prmIrateType;
257 GtkCheckButton *optEscrowCb;
258 GtkBox *optEscrowHBox;
259 GNCAccountSel *optEscrowGAS;
262 GtkEntry *repTxnName;
264 GtkEntry *repAmtEntry;
265 GNCAccountSel *repAssetsFromGAS;
266 GNCAccountSel *repPrincToGAS;
267 GNCAccountSel *repIntToGAS;
268 GtkFrame *repFreqFrame;
272 GtkEntry *payTxnName;
273 GtkEntry *payAmtEntry;
274 GNCAccountSel *payAcctFromGAS;
275 GNCAccountSel *payAcctEscToGAS;
276 GNCAccountSel *payAcctEscFromGAS;
277 GNCAccountSel *payAcctToGAS;
279 GtkCheckButton *payUseEscrow;
280 GtkCheckButton *paySpecSrcAcct;
281 GtkLabel *payAcctFromLabel;
282 GtkLabel *payEscToLabel;
283 GtkLabel *payEscFromLabel;
284 GtkRadioButton *payTxnFreqPartRb;
285 GtkRadioButton *payTxnFreqUniqRb;
290 GtkComboBox *revRangeOpt;
291 GtkFrame *revDateFrame;
295 GtkScrolledWindow *revScrollWin;
296 GtkTreeView *revView;
302 typedef struct toCreateSX_
320 static void loan_assistant_window_destroy_cb( GtkWidget *
object, gpointer user_data );
321 static void loan_assistant_close_handler( gpointer user_data );
324 static void loan_info_prep( GtkAssistant *assistant, gpointer user_data );
325 static void loan_info_prm_type_cb( GtkWidget *w, gpointer user_data );
326 static void loan_info_calc_update_cb( GtkWidget *widget, gpointer user_data );
327 void loan_info_page_valid_cb( GtkWidget *widget, gpointer user_data );
328 static gboolean loan_info_page_complete( GtkAssistant *assistant, gpointer user_data );
329 static void loan_info_page_save( GtkAssistant *assistant, gpointer user_data );
331 static void loan_opt_prep( GtkAssistant *assistant, gpointer user_data );
332 static void loan_opt_toggled_cb( GtkToggleButton *tb, gpointer user_data );
333 static void loan_opt_consistency_cb( GtkToggleButton *tb, gpointer user_data );
334 static void loan_opt_escrow_toggle_cb( GtkToggleButton *tb, gpointer user_data );
335 static void loan_opt_escrow_toggled_cb( GtkToggleButton *tb, gpointer user_data );
336 void loan_opt_page_valid_cb (GtkWidget *widget, gpointer user_data );
337 static gboolean loan_opt_page_complete( GtkAssistant *assistant, gpointer user_data );
339 static void loan_rep_prep ( GtkAssistant *assistant, gpointer user_data );
340 void loan_rep_page_valid_cb (GtkWidget *widget, gpointer user_data );
341 static gboolean loan_rep_page_complete( GtkAssistant *assistant, gpointer user_data );
342 static void loan_rep_page_save( GtkAssistant *assistant, gpointer user_data );
344 static void loan_pay_prep ( GtkAssistant *assistant, gpointer user_data );
346 static void loan_pay_use_esc_toggle_cb( GtkToggleButton *tb, gpointer user_data );
347 static void loan_pay_spec_src_setup(
LoanAssistantData *ldd, gboolean newState );
348 static void loan_pay_spec_src_toggle_cb( GtkToggleButton *tb, gpointer user_data );
349 static void loan_pay_freq_toggle_cb( GtkToggleButton *tb, gpointer user_data );
350 static void loan_pay_page_valid_cb (GtkWidget *widget, gpointer user_data );
351 static gboolean loan_pay_complete( GtkAssistant *assistant, gpointer user_data );
352 static gboolean loan_pay_all_opt_valid ( GtkAssistant *assistant, gpointer user_data );
353 static void loan_pay_back_button_cb( GtkButton *button, gpointer user_data );
354 static void loan_pay_next_button_cb( GtkButton *button, gpointer user_data );
356 static void loan_rev_prep ( GtkAssistant *assistant, gpointer user_data );
358 static void loan_rev_range_opt_changed_cb( GtkComboBox *combo, gpointer user_data );
359 static void loan_rev_range_changed_cb(
GNCDateEdit *gde, gpointer user_data );
360 static void loan_rev_get_loan_range(
LoanAssistantData *ldd, GDate *start, GDate *end );
361 static void loan_rev_get_dates(
LoanAssistantData *ldd, GDate *start, GDate *end );
362 static void loan_rev_update_view(
LoanAssistantData *ldd, GDate *start, GDate *end );
363 static void loan_rev_sched_list_free( gpointer data, gpointer user_data );
364 static void loan_rev_hash_to_list( gpointer key, gpointer val, gpointer user_data );
365 static void loan_rev_hash_free_date_keys( gpointer key, gpointer val, gpointer user_data );
370 static float loan_apr_to_simple_formula (
float rate,
float compounding_periods);
374 static void loan_tcSX_free( gpointer data, gpointer user_data );
377 void loan_assistant_prepare( GtkAssistant *assistant, GtkWidget *page, gpointer user_data );
378 void loan_assistant_finish( GtkAssistant *gtkassistant, gpointer user_data );
379 void loan_assistant_cancel( GtkAssistant *gtkassistant, gpointer user_data );
380 void loan_assistant_close( GtkAssistant *gtkassistant, gpointer user_data );
388 loan_assistant_close_handler( gpointer user_data )
391 gtk_widget_destroy( ldd->window );
397 loan_assistant_window_destroy_cb( GtkWidget *
object, gpointer user_data )
403 gnc_unregister_gui_component_by_data (DIALOG_LOAN_ASSISTANT_CM_CLASS, ldd);
411 g_date_free( ldd->ld.startDate );
412 g_date_free( ldd->ld.varStartDate );
413 recurrenceListFree(&ldd->ld.loan_schedule);
415 if ( ldd->ld.repMemo )
416 g_free( ldd->ld.repMemo );
418 for ( i = 0; i < ldd->ld.repayOptCount; i++ )
424 g_free( rod->txnMemo );
426 if ( rod->startDate )
427 g_date_free( rod->startDate );
429 if (rod->schedule != NULL)
430 recurrenceListFree(&rod->schedule);
432 g_free( ldd->ld.repayOpts[i] );
433 g_free( ldd->repayOptsUI[i] );
435 g_free( ldd->ld.repayOpts );
436 g_free( ldd->repayOptsUI );
438 if ( ldd->ld.repAmount )
439 g_free( ldd->ld.repAmount );
441 g_date_free( ldd->ld.repStartDate );
446 if ( ldd->ld.revSchedule )
448 g_list_foreach( ldd->ld.revSchedule,
449 loan_rev_sched_list_free,
451 g_list_free( ldd->ld.revSchedule );
452 ldd->ld.revSchedule = NULL;
466 loan_assistant_data_init( ldd );
468 builder = gtk_builder_new();
470 gnc_builder_add_from_file (builder ,
"assistant-loan.glade",
"len_liststore");
471 gnc_builder_add_from_file (builder ,
"assistant-loan.glade",
"range_liststore");
472 gnc_builder_add_from_file (builder ,
"assistant-loan.glade",
"type_liststore");
473 gnc_builder_add_from_file (builder ,
"assistant-loan.glade",
"rate_liststore");
475 gnc_builder_add_from_file (builder ,
"assistant-loan.glade",
"loan_mortgage_assistant");
476 window = GTK_WIDGET(gtk_builder_get_object (builder,
"loan_mortgage_assistant"));
477 ldd->window = window;
480 gtk_widget_set_name (GTK_WIDGET(window),
"gnc-id-assistant-loan");
483 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
484 GTK_WIDGET(gtk_builder_get_object(builder,
"loan_intro_page")),
486 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
487 GTK_WIDGET(gtk_builder_get_object(builder,
"loan_options_page")),
489 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
490 GTK_WIDGET(gtk_builder_get_object(builder,
"loan_review_page")),
495 ldd->prmTable = GTK_GRID(gtk_builder_get_object(builder,
"param_table"));
496 ldd->prmVarFrame = GTK_FRAME(gtk_builder_get_object(builder,
"type_freq_frame"));
497 ldd->prmIrateSpin = GTK_SPIN_BUTTON (gtk_builder_get_object(builder,
"irate_spin"));
498 ldd->prmType = GTK_COMBO_BOX (gtk_builder_get_object(builder,
"type_combobox"));
499 gtk_combo_box_set_active( GTK_COMBO_BOX( ldd->prmType), FALSE );
500 ldd->prmLengthSpin = GTK_SPIN_BUTTON (gtk_builder_get_object(builder,
"len_spin"));
501 ldd->prmLengthType = GTK_COMBO_BOX (gtk_builder_get_object(builder,
"len_opt"));
502 gtk_combo_box_set_active( GTK_COMBO_BOX( ldd->prmLengthType), FALSE );
503 ldd->prmRemainSpin = GTK_SPIN_BUTTON (gtk_builder_get_object(builder,
"rem_spin"));
504 ldd->prmIrateType = GTK_COMBO_BOX (gtk_builder_get_object(builder,
"irate_type_combobox"));
505 gtk_combo_box_set_active( GTK_COMBO_BOX( ldd->prmIrateType), FALSE );
510 ldd->repTable = GTK_GRID(gtk_builder_get_object(builder,
"repay_table"));
511 ldd->repTxnName = GTK_ENTRY(gtk_builder_get_object(builder,
"txn_title"));
512 ldd->repAmtEntry = GTK_ENTRY(gtk_builder_get_object(builder,
"amount_ent"));
513 ldd->repFreqFrame = GTK_FRAME(gtk_builder_get_object(builder,
"freq_frame"));
517 ldd->optVBox = GTK_BOX(gtk_builder_get_object(builder,
"loan_options_page"));
518 ldd->optEscrowCb = GTK_CHECK_BUTTON(gtk_builder_get_object(builder,
"opt_escrow_cb"));
519 ldd->optEscrowHBox = GTK_BOX(gtk_builder_get_object(builder,
"opt_escrow_hbox"));
523 ldd->payTable = GTK_GRID(gtk_builder_get_object(builder,
"pay_table"));
524 ldd->payTxnName = GTK_ENTRY(gtk_builder_get_object(builder,
"pay_txn_title"));
525 ldd->payAmtEntry = GTK_ENTRY(gtk_builder_get_object(builder,
"pay_amt_ent"));
526 ldd->payUseEscrow = GTK_CHECK_BUTTON(gtk_builder_get_object(builder,
"pay_use_escrow"));
527 ldd->paySpecSrcAcct = GTK_CHECK_BUTTON(gtk_builder_get_object(builder,
"pay_specify_source"));
528 ldd->payAcctFromLabel = GTK_LABEL(gtk_builder_get_object(builder,
"pay_from_account_label"));
529 ldd->payEscToLabel = GTK_LABEL(gtk_builder_get_object(builder,
"pay_escrow_to_label"));
530 ldd->payEscFromLabel = GTK_LABEL(gtk_builder_get_object(builder,
"pay_escrow_from_label"));
531 ldd->payTxnFreqPartRb = GTK_RADIO_BUTTON(gtk_builder_get_object(builder,
"pay_txn_part_rb"));
532 ldd->payTxnFreqUniqRb = GTK_RADIO_BUTTON(gtk_builder_get_object(builder,
"pay_uniq_freq_rb"));
533 ldd->payFreqHBox = GTK_BOX(gtk_builder_get_object(builder,
"pay_freq_hbox"));
537 ldd->revTable = GTK_GRID(gtk_builder_get_object(builder,
"rev_date_range_table"));
538 ldd->revRangeOpt = GTK_COMBO_BOX(gtk_builder_get_object(builder,
"rev_range_opt"));
539 ldd->revDateFrame = GTK_FRAME(gtk_builder_get_object(builder,
"rev_date_frame"));
540 ldd->revScrollWin = GTK_SCROLLED_WINDOW(gtk_builder_get_object(builder,
"rev_scrollwin"));
550 GList *liabilityAcct;
553 GList *paymentFromAccts;
555 GList *paymentToAccts;
564 liabilityAcct = NULL;
565 paymentFromAccts = NULL;
566 paymentToAccts = NULL;
568 liabilityAcct = g_list_append( liabilityAcct,
570 for ( i = 0; i < fromLen; i++ )
573 = g_list_append( paymentFromAccts,
574 GINT_TO_POINTER( paymentFroms[i] ) );
576 = g_list_append( paymentToAccts,
577 GINT_TO_POINTER( paymentFroms[i] ) );
580 for ( i = 0; i < toLen; i++ )
582 paymentToAccts = g_list_append( paymentToAccts,
583 GINT_TO_POINTER( paymentTos[i] ) );
590 struct gas_in_tables_data
594 gboolean newAcctAbility;
595 int left, top, width, height;
596 GList *allowableAccounts;
600 { &ldd->prmAccountGAS, ldd->prmTable, TRUE, 1, 0, 1, 1, liabilityAcct },
601 { &ldd->repAssetsFromGAS, ldd->repTable, TRUE, 1, 2, 1, 1, paymentFromAccts },
602 { &ldd->repPrincToGAS, ldd->repTable, TRUE, 1, 3, 1, 1, paymentToAccts },
603 { &ldd->repIntToGAS, ldd->repTable, TRUE, 3, 3, 1, 1, paymentToAccts },
604 { &ldd->payAcctFromGAS, ldd->payTable, TRUE, 1, 4, 1, 1, paymentFromAccts },
605 { &ldd->payAcctEscToGAS, ldd->payTable, FALSE, 3, 4, 1, 1, paymentToAccts },
606 { &ldd->payAcctEscFromGAS, ldd->payTable, FALSE, 1, 5, 1, 1, paymentFromAccts },
607 { &ldd->payAcctToGAS, ldd->payTable, TRUE, 3, 5, 1, 1, paymentToAccts },
611 ldd->prmOrigPrincGAE = GNC_AMOUNT_EDIT(gnc_amount_edit_new());
612 gtk_grid_attach (GTK_GRID(ldd->prmTable), GTK_WIDGET(ldd->prmOrigPrincGAE), 1, 1, 1, 1);
614 gtk_widget_set_halign (GTK_WIDGET(ldd->prmOrigPrincGAE), GTK_ALIGN_FILL);
615 gtk_widget_set_hexpand (GTK_WIDGET(ldd->prmOrigPrincGAE), FALSE);
616 g_object_set (GTK_WIDGET(ldd->prmOrigPrincGAE),
"margin", 2,
nullptr);
618 g_signal_connect (G_OBJECT(ldd->prmOrigPrincGAE),
"changed",
619 G_CALLBACK(loan_info_page_valid_cb), ldd);
621 for ( i = 0; gas_data[i].loc != NULL; i++ )
623 GNCAccountSel *gas = GNC_ACCOUNT_SEL(gnc_account_sel_new());
625 gnc_account_sel_set_new_account_ability(
626 gas, gas_data[i].newAcctAbility );
627 if ( gas_data[i].allowableAccounts != NULL )
629 gnc_account_sel_set_acct_filters(
630 gas, gas_data[i].allowableAccounts, NULL );
633 gtk_grid_attach (GTK_GRID(gas_data[i].
table),
640 gtk_widget_set_halign (GTK_WIDGET(gas), GTK_ALIGN_FILL);
641 gnc_account_sel_set_new_account_modal (GNC_ACCOUNT_SEL(gas),
true);
642 g_object_set (GTK_WIDGET(gas),
"margin", 2,
nullptr);
643 *(gas_data[i].loc) = gas;
648 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payAcctEscToGAS), FALSE );
649 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payAcctEscFromGAS), FALSE );
654 struct gde_in_tables_data
658 int left, top, width, height;
662 { &ldd->prmStartDateGDE, ldd->prmTable, 1, 4, 1, 1 },
663 { &ldd->revStartDate, ldd->revTable, 1, 0, 1, 1 },
664 { &ldd->revEndDate, ldd->revTable, 1, 1, 1, 1 },
668 for ( i = 0; gde_data[i].loc != NULL; i++ )
675 gtk_grid_attach (GTK_GRID(gde_data[i].
table),
676 GTK_WIDGET( *gde_data[i].loc ),
682 gtk_widget_set_halign (GTK_WIDGET( *gde_data[i].loc ), GTK_ALIGN_START);
683 gtk_widget_set_hexpand (GTK_WIDGET( *gde_data[i].loc ), FALSE);
684 g_object_set (GTK_WIDGET( *gde_data[i].loc ),
"margin", 0,
nullptr);
689 gtk_widget_set_sensitive( GTK_WIDGET(ldd->prmVarFrame), FALSE );
691 g_signal_connect( ldd->prmType,
"changed",
692 G_CALLBACK( loan_info_prm_type_cb ),
700 a = GTK_ADJUSTMENT(gtk_adjustment_new( 8.0, 0.001,
703 gtk_spin_button_set_adjustment( ldd->prmIrateSpin, a );
704 gtk_spin_button_set_value( ldd->prmIrateSpin, 8.00 );
705 gtk_spin_button_set_snap_to_ticks( ldd->prmIrateSpin, TRUE );
707 a = GTK_ADJUSTMENT(gtk_adjustment_new( 360, 1,
710 gtk_spin_button_set_adjustment( ldd->prmLengthSpin, a );
711 g_signal_connect( ldd->prmLengthSpin,
"changed",
712 G_CALLBACK( loan_info_calc_update_cb ),
714 g_signal_connect( ldd->prmStartDateGDE,
"date-changed",
715 G_CALLBACK( loan_info_calc_update_cb ),
717 g_signal_connect( ldd->prmLengthSpin,
"value-changed",
718 G_CALLBACK( loan_info_calc_update_cb ),
720 g_signal_connect( ldd->prmLengthType,
"changed",
721 G_CALLBACK( loan_info_calc_update_cb ),
724 a = GTK_ADJUSTMENT(gtk_adjustment_new( 360, 1,
727 gtk_spin_button_set_adjustment( ldd->prmRemainSpin, a );
730 g_signal_connect( ldd->optEscrowCb,
"toggled",
731 G_CALLBACK(loan_opt_escrow_toggle_cb), ldd );
732 gtk_widget_set_sensitive( GTK_WIDGET(ldd->optEscrowHBox), FALSE );
733 ldd->optEscrowGAS = GNC_ACCOUNT_SEL(gnc_account_sel_new());
734 g_object_set (ldd->optEscrowGAS,
"entry-width", 50, NULL);
735 gnc_account_sel_set_new_account_modal (GNC_ACCOUNT_SEL(ldd->optEscrowGAS),
true);
736 gnc_account_sel_set_new_account_ability( ldd->optEscrowGAS, TRUE );
737 gtk_container_add( GTK_CONTAINER(ldd->optEscrowHBox),
738 GTK_WIDGET(ldd->optEscrowGAS) );
753 str = g_string_sized_new( 32 );
755 for ( i = 0; i < ldd->ld.repayOptCount; i++ )
757 rouid = ldd->repayOptsUI[i];
758 vb = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
759 gtk_box_set_homogeneous (GTK_BOX (vb), FALSE);
760 gtk_widget_set_margin_start (GTK_WIDGET(vb), 12);
766 g_string_printf( str, _(
"… pay \"%s\"?"),
767 rouid->optData->name );
770 gtk_check_button_new_with_label(
772 gtk_box_pack_start( GTK_BOX(vb),
773 GTK_WIDGET(rouid->optCb),
777 gtk_check_button_new_with_label(
778 _(
"via Escrow account?") ));
779 gtk_widget_set_sensitive(
780 GTK_WIDGET(rouid->escrowCb),
783 gtk_box_pack_start( GTK_BOX(vb), GTK_WIDGET(rouid->escrowCb), FALSE, FALSE, 2 );
784 gtk_widget_set_margin_start (GTK_WIDGET(rouid->escrowCb), 12);
786 g_signal_connect( rouid->optCb,
"toggled",
787 G_CALLBACK(loan_opt_toggled_cb),
789 g_signal_connect( rouid->optCb,
"toggled",
790 G_CALLBACK(loan_opt_consistency_cb),
792 g_signal_connect( rouid->escrowCb,
"toggled",
793 G_CALLBACK(loan_opt_escrow_toggled_cb),
796 gtk_box_pack_start( GTK_BOX(ldd->optVBox), GTK_WIDGET(vb), FALSE, FALSE, 2 );
797 gtk_widget_show_all( GTK_WIDGET(ldd->optVBox) );
799 g_string_free( str, TRUE );
802 g_signal_connect( ldd->payUseEscrow,
"toggled",
803 G_CALLBACK(loan_pay_use_esc_toggle_cb), ldd );
804 g_signal_connect( ldd->paySpecSrcAcct,
"toggled",
805 G_CALLBACK(loan_pay_spec_src_toggle_cb), ldd );
806 g_signal_connect( ldd->payTxnFreqUniqRb,
"toggled",
807 G_CALLBACK(loan_pay_freq_toggle_cb), ldd );
811 hbox = GTK_BOX(gtk_builder_get_object(builder,
"type_freq_hbox"));
812 ldd->prmVarGncFreq = GNC_FREQUENCY(gnc_frequency_new( NULL, NULL ));
813 gtk_box_pack_start( GTK_BOX(hbox) , GTK_WIDGET(ldd->prmVarGncFreq), TRUE, FALSE, 0 );
814 g_signal_connect (ldd->prmVarGncFreq,
"changed",
815 G_CALLBACK (loan_info_page_valid_cb), ldd);
819 hbox = GTK_BOX(gtk_builder_get_object(builder,
"freq_frame_hbox"));
820 ldd->repGncFreq = GNC_FREQUENCY(gnc_frequency_new( NULL, NULL ));
821 gtk_box_pack_start( GTK_BOX(hbox) , GTK_WIDGET(ldd->repGncFreq), TRUE, FALSE, 0 );
822 g_signal_connect (ldd->repGncFreq,
"changed",
823 G_CALLBACK (loan_rep_page_valid_cb), ldd);
826 ldd->payGncFreq = GNC_FREQUENCY(gnc_frequency_new( NULL, NULL ));
827 gtk_container_add( GTK_CONTAINER(ldd->payFreqHBox), GTK_WIDGET(ldd->payGncFreq) );
829 g_signal_connect (ldd->payGncFreq,
"changed",
830 G_CALLBACK (loan_pay_page_valid_cb), ldd);
832 butt = GTK_WIDGET(gtk_builder_get_object(builder,
"pay_back_button"));
833 g_signal_connect (butt,
"clicked",
834 G_CALLBACK (loan_pay_back_button_cb), ldd);
836 butt = GTK_WIDGET(gtk_builder_get_object(builder,
"pay_next_button"));
837 g_signal_connect (butt,
"clicked",
838 G_CALLBACK (loan_pay_next_button_cb), ldd);
844 g_signal_connect (ldd->prmAccountGAS,
"account_sel_changed",
845 G_CALLBACK (loan_info_page_valid_cb), ldd);
846 g_signal_connect( ldd->prmIrateType,
"changed",
847 G_CALLBACK( loan_info_page_valid_cb ), ldd );
851 g_signal_connect (ldd->optEscrowGAS,
"account_sel_changed",
852 G_CALLBACK (loan_opt_page_valid_cb), ldd);
856 g_signal_connect (ldd->repAssetsFromGAS,
"account_sel_changed",
857 G_CALLBACK (loan_rep_page_valid_cb), ldd);
858 g_signal_connect (ldd->repIntToGAS,
"account_sel_changed",
859 G_CALLBACK (loan_rep_page_valid_cb), ldd);
860 g_signal_connect (ldd->repPrincToGAS,
"account_sel_changed",
861 G_CALLBACK (loan_rep_page_valid_cb), ldd);
865 g_signal_connect (ldd->payAcctFromGAS,
"account_sel_changed",
866 G_CALLBACK (loan_pay_page_valid_cb), ldd);
867 g_signal_connect (ldd->payAcctToGAS,
"account_sel_changed",
868 G_CALLBACK (loan_pay_page_valid_cb), ldd);
869 g_signal_connect (ldd->payAcctEscFromGAS,
"account_sel_changed",
870 G_CALLBACK (loan_pay_page_valid_cb), ldd);
871 g_signal_connect (ldd->payAcctEscToGAS,
"account_sel_changed",
872 G_CALLBACK (loan_pay_page_valid_cb), ldd);
876 gtk_combo_box_set_active( ldd->revRangeOpt, 0 );
877 g_signal_connect( ldd->revRangeOpt,
"changed",
878 G_CALLBACK( loan_rev_range_opt_changed_cb ),
880 g_signal_connect( ldd->revStartDate,
"date-changed",
881 G_CALLBACK( loan_rev_range_changed_cb ),
883 g_signal_connect( ldd->revEndDate,
"date-changed",
884 G_CALLBACK( loan_rev_range_changed_cb ),
888 g_signal_connect( ldd->window,
"destroy",
889 G_CALLBACK(loan_assistant_window_destroy_cb),
892 gtk_builder_connect_signals(builder, ldd);
893 g_object_unref(G_OBJECT(builder));
895 gtk_widget_show_all( ldd->window );
908 for ( optCount = 0; REPAY_DEFAULTS[optCount].name != NULL; optCount++ )
911 ldd->currentIdx = -1;
913 ldd->ld.principal = gnc_numeric_zero();
914 ldd->ld.startDate = g_date_new();
915 ldd->ld.varStartDate = g_date_new();
917 ldd->ld.loan_schedule = NULL;
918 ldd->ld.repayment_schedule = NULL;
921 recurrenceSet(r, 1, PERIOD_MONTH, ldd->ld.startDate, WEEKEND_ADJ_NONE);
922 ldd->ld.repayment_schedule = g_list_append(ldd->ld.repayment_schedule, r);
925 ldd->ld.repMemo = g_strdup( _(
"Loan") );
926 ldd->ld.repAmount = NULL;
927 ldd->ld.repStartDate = g_date_new();
928 ldd->ld.repayOptCount = optCount;
932 for ( i = 0; i < optCount; i++ )
934 g_assert( REPAY_DEFAULTS[i].name != NULL );
937 ldd->repayOptsUI[i]->ldd = ldd;
939 optData = ldd->ld.repayOpts[i]
940 = ldd->repayOptsUI[i]->optData
943 optData->enabled = FALSE;
944 optData->optValid = FALSE;
945 optData->FreqUniq = FALSE;
946 optData->name = g_strdup( _(REPAY_DEFAULTS[i].name) );
947 optData->txnMemo = g_strdup( _(REPAY_DEFAULTS[i].
949 optData->amount = 0.0;
950 optData->throughEscrowP = REPAY_DEFAULTS[i].escrowDefault;
951 optData->specSrcAcctP = REPAY_DEFAULTS[i].specSrcAcctDefault;
952 optData->schedule = NULL;
953 optData->startDate = NULL;
961 loan_info_prep( GtkAssistant *assistant, gpointer user_data )
965 gnc_amount_edit_set_amount( ldd->prmOrigPrincGAE, ldd->ld.principal );
966 gtk_spin_button_set_value( ldd->prmIrateSpin, ldd->ld.interestRate );
967 gtk_combo_box_set_active( ldd->prmIrateType, ldd->ld.rateType );
968 gtk_combo_box_set_active( ldd->prmType, ldd->ld.type );
969 if ( ldd->ld.type != GNC_FIXED )
971 g_signal_handlers_block_by_func( GNC_FREQUENCY( ldd->prmVarGncFreq),
972 (gpointer) loan_info_page_valid_cb, ldd );
973 gnc_frequency_setup_recurrence(ldd->prmVarGncFreq, ldd->ld.loan_schedule, ldd->ld.varStartDate);
974 g_signal_handlers_unblock_by_func( GNC_FREQUENCY( ldd->prmVarGncFreq),
975 (gpointer) loan_info_page_valid_cb, ldd );
982 tmpTm = g_new0(
struct tm, 1 );
984 g_date_to_struct_tm (ldd->ld.startDate, tmpTm);
985 gnc_date_edit_set_time (ldd->prmStartDateGDE,
992 gtk_spin_button_set_value( ldd->prmLengthSpin, ldd->ld.numPer );
993 gtk_combo_box_set_active( ldd->prmLengthType, ldd->ld.perSize );
994 gtk_spin_button_set_value( ldd->prmRemainSpin, ldd->ld.numMonRemain );
1001 loan_info_prm_type_cb( GtkWidget *w, gpointer user_data )
1006 index = gtk_combo_box_get_active( ldd->prmType );
1007 gtk_widget_set_sensitive( GTK_WIDGET(ldd->prmVarFrame),
1008 index != GNC_FIXED );
1014 loan_info_calc_update_cb( GtkWidget *w, gpointer user_data )
1018 int i, totalVal, total, remain;
1020 g_date_clear( &start, 1 );
1021 g_date_clear( &now, 1 );
1024 for ( i = 0; g_date_compare( &start, &now ) < 0; i++ )
1026 g_date_add_months( &start, 1 );
1031 gchar *valueStr = gtk_editable_get_chars( GTK_EDITABLE(ldd->prmLengthSpin),
1033 totalVal = strtol( valueStr, NULL, 10 );
1037 * ( gtk_combo_box_get_active( ldd->prmLengthType )
1040 gtk_spin_button_set_value( ldd->prmRemainSpin, remain );
1041 gtk_widget_show( GTK_WIDGET(ldd->prmRemainSpin) );
1046 loan_info_page_valid_cb (GtkWidget *widget, gpointer user_data )
1049 GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
1050 gint num = gtk_assistant_get_current_page (assistant);
1051 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
1053 gtk_assistant_set_page_complete (assistant, page,
1054 loan_info_page_complete (assistant, ldd));
1060 loan_info_page_complete( GtkAssistant *assistant, gpointer user_data )
1064 gnc_commodity *currency;
1068 ldd->ld.primaryAcct = gnc_account_sel_get_account( ldd->prmAccountGAS );
1070 if ( ldd->ld.primaryAcct == NULL )
1075 print_info = gnc_commodity_print_info (currency, FALSE);
1076 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT(ldd->prmOrigPrincGAE), print_info);
1077 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT(ldd->prmOrigPrincGAE),
1080 result = gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT(ldd->prmOrigPrincGAE),
1081 &value, FALSE,
nullptr);
1091 loan_info_page_save( GtkAssistant *assistant, gpointer user_data )
1095 ldd->ld.primaryAcct = gnc_account_sel_get_account( ldd->prmAccountGAS );
1097 if ( ! ldd->ld.repPriAcct )
1099 ldd->ld.repPriAcct = ldd->ld.primaryAcct;
1101 ldd->ld.principal = gnc_amount_edit_get_amount( ldd->prmOrigPrincGAE );
1102 ldd->ld.interestRate = gtk_spin_button_get_value( ldd->prmIrateSpin );
1103 ldd->ld.rateType =
static_cast<IRateType
>( gtk_combo_box_get_active (ldd->prmIrateType ));
1104 ldd->ld.type =
static_cast<LoanType
>( gtk_combo_box_get_active( ldd->prmType ));
1106 if ( ldd->ld.type != GNC_FIXED )
1108 recurrenceListFree(&ldd->ld.loan_schedule);
1109 gnc_frequency_save_to_recurrence(ldd->prmVarGncFreq,
1110 &ldd->ld.loan_schedule,
1111 ldd->ld.varStartDate);
1119 tmpTT = gnc_date_edit_get_date( ldd->prmStartDateGDE );
1123 g_date_set_dmy( ldd->ld.startDate,
1125 static_cast<GDateMonth>(tmpTm->tm_mon + 1),
1126 (1900 + tmpTm->tm_year) );
1134 (gtk_combo_box_get_active( ldd->prmLengthType )
1135 == GNC_MONTHS) ? GNC_MONTHS : GNC_YEARS;
1137 gtk_spin_button_get_value_as_int( ldd->prmLengthSpin );
1138 ldd->ld.numMonRemain =
1139 gtk_spin_button_get_value_as_int( ldd->prmRemainSpin );
1147 loan_opt_prep( GtkAssistant *assistant, gpointer user_data )
1154 loan_info_page_save(assistant, ldd);
1156 if ( ldd->ld.escrowAcct )
1158 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ldd->optEscrowCb), TRUE );
1159 gnc_account_sel_set_account( ldd->optEscrowGAS, ldd->ld.escrowAcct, FALSE );
1161 for ( i = 0; i < ldd->ld.repayOptCount; i++ )
1163 rouid = ldd->repayOptsUI[i];
1164 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(rouid->optCb),
1165 rouid->optData->enabled );
1166 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(rouid->escrowCb),
1167 rouid->optData->throughEscrowP
1168 && rouid->optData->enabled
1169 && ldd->ld.escrowAcct );
1170 gtk_widget_set_sensitive( GTK_WIDGET(rouid->escrowCb),
1171 rouid->optData->enabled
1172 && ldd->ld.escrowAcct );
1179 loan_opt_toggled_cb( GtkToggleButton *tb, gpointer user_data )
1184 rouid->optData->enabled = gtk_toggle_button_get_active(tb);
1190 loan_opt_consistency_cb( GtkToggleButton *tb, gpointer user_data )
1192 GtkToggleButton *escrowCb;
1196 escrowCb = GTK_TOGGLE_BUTTON(rouid->escrowCb);
1198 gtk_toggle_button_set_active( escrowCb,
1199 gtk_toggle_button_get_active(
1201 rouid->ldd->optEscrowCb) )
1202 && rouid->optData->throughEscrowP
1203 && gtk_toggle_button_get_active(tb) );
1206 gtk_widget_set_sensitive( GTK_WIDGET(escrowCb),
1207 gtk_toggle_button_get_active(tb)
1208 && gtk_toggle_button_get_active(
1209 GTK_TOGGLE_BUTTON(rouid->ldd->optEscrowCb)) );
1215 loan_opt_escrow_toggle_cb( GtkToggleButton *tb, gpointer user_data )
1221 GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
1222 gint num = gtk_assistant_get_current_page (assistant);
1223 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
1225 newState = gtk_toggle_button_get_active(tb);
1226 gtk_widget_set_sensitive( GTK_WIDGET(ldd->optEscrowHBox), newState );
1230 if (GNC_ACCOUNT_SEL( ldd->ld.escrowAcct) == NULL)
1231 gtk_assistant_set_page_complete (assistant, page, FALSE);
1235 ldd->ld.escrowAcct = NULL;
1236 gnc_account_sel_set_account( GNC_ACCOUNT_SEL( ldd->optEscrowGAS), NULL , FALSE );
1237 gtk_assistant_set_page_complete (assistant, page, TRUE);
1242 for ( i = 0; i < ldd->ld.repayOptCount; i++ )
1244 rouid = ldd->repayOptsUI[i];
1250 g_signal_handlers_block_by_func( rouid->escrowCb,
1251 (gpointer) loan_opt_escrow_toggled_cb,
1253 gtk_toggle_button_set_active(
1254 GTK_TOGGLE_BUTTON(rouid->escrowCb),
1256 && gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(rouid->optCb) )
1257 && rouid->optData->throughEscrowP ) );
1258 gtk_widget_set_sensitive(
1259 GTK_WIDGET(rouid->escrowCb),
1261 && gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(rouid->optCb) ) );
1262 g_signal_handlers_unblock_by_func( rouid->escrowCb,
1263 (gpointer) loan_opt_escrow_toggled_cb,
1267 rouid->optData->from = ldd->ld.escrowAcct;
1271 rouid->optData->from = NULL;
1279 loan_opt_escrow_toggled_cb( GtkToggleButton *tb, gpointer user_data )
1284 rouid->optData->throughEscrowP = gtk_toggle_button_get_active( tb );
1289 loan_opt_page_valid_cb (GtkWidget *widget, gpointer user_data )
1293 GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
1294 gint num = gtk_assistant_get_current_page (assistant);
1295 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
1297 gtk_assistant_set_page_complete (assistant, page,
1298 loan_opt_page_complete (assistant, ldd));
1304 loan_opt_page_complete( GtkAssistant *assistant, gpointer user_data )
1308 if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(ldd->optEscrowCb) ) )
1310 ldd->ld.escrowAcct =
1311 gnc_account_sel_get_account( ldd->optEscrowGAS );
1313 if ( ldd->ld.escrowAcct == NULL )
1318 ldd->ld.escrowAcct = NULL;
1327 loan_rep_prep( GtkAssistant *assistant, gpointer user_data )
1332 if ( ldd->ld.repAmount )
1334 g_free( ldd->ld.repAmount );
1337 str = g_string_sized_new( 64 );
1338 loan_get_pmt_formula( ldd, str);
1339 ldd->ld.repAmount = g_string_free (str,
false);
1341 if ( ldd->ld.repMemo )
1342 gtk_entry_set_text( ldd->repTxnName, ldd->ld.repMemo );
1344 if ( ldd->ld.repAmount )
1345 gtk_entry_set_text( ldd->repAmtEntry, ldd->ld.repAmount );
1347 gnc_account_sel_set_account( ldd->repAssetsFromGAS, ldd->ld.repFromAcct, FALSE );
1348 gnc_account_sel_set_account( ldd->repPrincToGAS, ldd->ld.repPriAcct, FALSE );
1349 gnc_account_sel_set_account( ldd->repIntToGAS, ldd->ld.repIntAcct, FALSE );
1351 g_signal_handlers_block_by_func( ldd->repGncFreq,
1352 (gpointer) loan_rep_page_valid_cb, ldd );
1353 gnc_frequency_setup_recurrence(ldd->repGncFreq, ldd->ld.repayment_schedule, ldd->ld.repStartDate);
1354 g_signal_handlers_unblock_by_func( ldd->repGncFreq,
1355 (gpointer) loan_rep_page_valid_cb, ldd );
1361 (i < ldd->ld.repayOptCount)
1362 && !ldd->ld.repayOpts[i]->enabled;
1365 if ( i < ldd->ld.repayOptCount )
1366 ldd->currentIdx = i;
1368 ldd->currentIdx = -1;
1374 loan_rep_page_valid_cb (GtkWidget *widget, gpointer user_data )
1377 GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
1378 gint num = gtk_assistant_get_current_page (assistant);
1379 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
1381 gtk_assistant_set_page_complete (assistant, page,
1382 loan_rep_page_complete (assistant, ldd));
1388 loan_rep_page_complete( GtkAssistant *assistant, gpointer user_data )
1392 ldd->ld.repFromAcct =
1393 gnc_account_sel_get_account( ldd->repAssetsFromGAS );
1395 if ( ldd->ld.repFromAcct == NULL )
1398 ldd->ld.repPriAcct =
1399 gnc_account_sel_get_account( ldd->repPrincToGAS );
1401 if ( ldd->ld.repPriAcct == NULL )
1404 ldd->ld.repIntAcct =
1405 gnc_account_sel_get_account( ldd->repIntToGAS );
1407 if ( ldd->ld.repIntAcct == NULL )
1416 loan_rep_page_save( GtkAssistant *assistant, gpointer user_data )
1420 if ( ldd->ld.repMemo )
1421 g_free( ldd->ld.repMemo );
1423 gtk_editable_get_chars( GTK_EDITABLE(ldd->repTxnName), 0, -1 );
1425 if ( ldd->ld.repAmount )
1426 g_free( ldd->ld.repAmount );
1428 gtk_editable_get_chars( GTK_EDITABLE(ldd->repAmtEntry), 0, -1 );
1430 ldd->ld.repFromAcct =
1431 gnc_account_sel_get_account( ldd->repAssetsFromGAS );
1433 ldd->ld.repPriAcct =
1434 gnc_account_sel_get_account( ldd->repPrincToGAS );
1436 ldd->ld.repIntAcct =
1437 gnc_account_sel_get_account( ldd->repIntToGAS );
1439 recurrenceListFree(&ldd->ld.repayment_schedule);
1440 gnc_frequency_save_to_recurrence(ldd->repGncFreq,
1441 &ldd->ld.repayment_schedule,
1442 ldd->ld.repStartDate);
1449 loan_pay_prep( GtkAssistant *assistant, gpointer user_data )
1456 gint num = gtk_assistant_get_current_page (assistant);
1457 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
1460 loan_rep_page_save(assistant, ldd);
1463 if (ldd->currentIdx == -1 )
1465 gtk_assistant_set_current_page (assistant, num + 1);
1469 g_assert( ldd->currentIdx >= 0 );
1470 g_assert( ldd->currentIdx <= ldd->ld.repayOptCount );
1472 rod = ldd->ld.repayOpts[ldd->currentIdx];
1473 str = g_string_sized_new( 32 );
1475 g_string_printf( str, _(
"Loan Repayment Option: \"%s\""), rod->name );
1476 gtk_assistant_set_page_title (assistant, page, str->str );
1479 gtk_entry_set_text( ldd->payTxnName, rod->txnMemo );
1480 g_string_printf( str,
"%0.2f", rod->amount );
1481 gtk_entry_set_text( ldd->payAmtEntry, str->str );
1483 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payUseEscrow),
1484 (ldd->ld.escrowAcct != NULL) );
1487 g_signal_handlers_block_by_func( ldd->payUseEscrow,
1488 (gpointer) loan_pay_use_esc_toggle_cb,
1491 loan_pay_use_esc_setup( ldd,
1492 (ldd->ld.escrowAcct != NULL)
1493 && rod->throughEscrowP );
1494 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ldd->payUseEscrow),
1495 (rod->throughEscrowP
1496 && ldd->ld.escrowAcct != NULL) );
1498 g_signal_handlers_unblock_by_func( ldd->payUseEscrow,
1499 (gpointer) loan_pay_use_esc_toggle_cb,
1504 g_signal_handlers_block_by_func( ldd->paySpecSrcAcct,
1505 (gpointer) loan_pay_spec_src_toggle_cb,
1507 loan_pay_spec_src_setup( ldd, rod->specSrcAcctP );
1508 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ldd->paySpecSrcAcct),
1509 rod->specSrcAcctP );
1511 g_signal_handlers_unblock_by_func( ldd->paySpecSrcAcct,
1512 (gpointer) loan_pay_spec_src_toggle_cb,
1516 g_signal_handlers_block_by_func(ldd->payAcctToGAS,
1517 (gpointer) loan_pay_page_valid_cb, ldd );
1518 gnc_account_sel_set_account( ldd->payAcctToGAS, rod->to, FALSE );
1519 g_signal_handlers_unblock_by_func(ldd->payAcctToGAS,
1520 (gpointer) loan_pay_page_valid_cb, ldd );
1523 g_signal_handlers_block_by_func(ldd->payTxnFreqUniqRb,
1524 (gpointer) loan_pay_freq_toggle_cb, ldd );
1525 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ldd->payTxnFreqPartRb), !rod->FreqUniq );
1526 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ldd->payTxnFreqUniqRb), rod->FreqUniq );
1527 g_signal_handlers_unblock_by_func(ldd->payTxnFreqUniqRb,
1528 (gpointer) loan_pay_freq_toggle_cb, ldd );
1530 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payFreqHBox), rod->FreqUniq );
1532 if ( rod->FreqUniq )
1534 g_signal_handlers_disconnect_by_func( ldd->payGncFreq,
1535 (gpointer) loan_pay_page_valid_cb, ldd );
1536 gtk_container_remove( GTK_CONTAINER(ldd->payFreqHBox), GTK_WIDGET(ldd->payGncFreq) );
1537 ldd->payGncFreq = NULL;
1538 ldd->payGncFreq = GNC_FREQUENCY(gnc_frequency_new_from_recurrence( rod->schedule, rod->startDate ));
1539 gtk_container_add( GTK_CONTAINER(ldd->payFreqHBox), GTK_WIDGET(ldd->payGncFreq) );
1540 g_signal_connect (ldd->payGncFreq,
"changed",
1541 G_CALLBACK (loan_pay_page_valid_cb), ldd);
1543 g_string_free( str, TRUE );
1544 loan_pay_page_valid_cb(GTK_WIDGET(ldd->window), ldd);
1550 loan_pay_page_valid_cb (GtkWidget *widget, gpointer user_data )
1553 GtkAssistant *assistant = GTK_ASSISTANT(ldd->window);
1554 gint num = gtk_assistant_get_current_page (assistant);
1555 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
1557 gtk_assistant_set_page_complete (assistant, page,
1558 ( loan_pay_complete (assistant, ldd) &&
1559 loan_pay_all_opt_valid (assistant, ldd )));
1567 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payEscToLabel), newState );
1568 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payEscFromLabel), newState );
1571 g_signal_handlers_block_by_func( ldd->payAcctEscToGAS,
1572 (gpointer) loan_pay_page_valid_cb, ldd );
1573 g_signal_handlers_block_by_func( ldd->payAcctEscFromGAS,
1574 (gpointer) loan_pay_page_valid_cb, ldd );
1575 gnc_account_sel_set_account( ldd->payAcctEscToGAS, ldd->ld.escrowAcct, FALSE );
1576 gnc_account_sel_set_account( ldd->payAcctEscFromGAS, ldd->ld.escrowAcct, FALSE );
1577 g_signal_handlers_unblock_by_func( ldd->payAcctEscToGAS,
1578 (gpointer) loan_pay_page_valid_cb, ldd );
1579 g_signal_handlers_unblock_by_func( ldd->payAcctEscFromGAS,
1580 (gpointer) loan_pay_page_valid_cb, ldd );
1587 loan_pay_use_esc_toggle_cb( GtkToggleButton *tb, gpointer user_data )
1592 newState = gtk_toggle_button_get_active( tb );
1593 loan_pay_use_esc_setup( ldd, newState );
1601 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payAcctFromLabel), newState );
1602 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payAcctFromGAS), newState );
1605 g_signal_handlers_block_by_func( ldd->payAcctFromGAS,
1606 (gpointer) loan_pay_page_valid_cb, ldd );
1607 gnc_account_sel_set_account( ldd->payAcctFromGAS, ldd->ld.repayOpts[ldd->currentIdx]->from, FALSE );
1608 g_signal_handlers_unblock_by_func( ldd->payAcctFromGAS,
1609 (gpointer) loan_pay_page_valid_cb, ldd );
1613 g_signal_handlers_block_by_func( ldd->payAcctFromGAS,
1614 (gpointer) loan_pay_page_valid_cb, ldd );
1615 gnc_account_sel_set_account( ldd->payAcctFromGAS, NULL, FALSE );
1616 ldd->ld.repayOpts[ldd->currentIdx]->from = NULL;
1617 g_signal_handlers_unblock_by_func( ldd->payAcctFromGAS,
1618 (gpointer) loan_pay_page_valid_cb, ldd );
1625 loan_pay_spec_src_toggle_cb( GtkToggleButton *tb, gpointer user_data )
1630 newState = gtk_toggle_button_get_active( tb );
1631 loan_pay_spec_src_setup( ldd, newState );
1637 loan_pay_freq_toggle_cb( GtkToggleButton *tb, gpointer user_data )
1642 g_assert( ldd->currentIdx >= 0 );
1643 g_assert( ldd->currentIdx <= ldd->ld.repayOptCount );
1645 rod = ldd->ld.repayOpts[ldd->currentIdx];
1647 rod->FreqUniq = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(ldd->payTxnFreqUniqRb) );
1648 gtk_widget_set_sensitive( GTK_WIDGET(ldd->payFreqHBox), rod->FreqUniq );
1650 if ( rod->FreqUniq )
1652 if ( rod->schedule == NULL )
1656 recurrenceSet(r, 1, PERIOD_MONTH, ldd->ld.startDate, WEEKEND_ADJ_NONE);
1657 rod->schedule = g_list_append(rod->schedule, r);
1659 if ( rod->startDate == NULL )
1661 rod->startDate = g_date_new();
1662 *rod->startDate = *ldd->ld.startDate;
1664 g_signal_handlers_block_by_func( ldd->payGncFreq,
1665 (gpointer) loan_pay_page_valid_cb, ldd );
1666 gnc_frequency_setup_recurrence(ldd->payGncFreq, rod->schedule, rod->startDate);
1667 g_signal_handlers_unblock_by_func( ldd->payGncFreq,
1668 (gpointer) loan_pay_page_valid_cb, ldd );
1674 recurrenceListFree(&rod->schedule);
1676 if ( rod->startDate )
1678 g_date_free( rod->startDate );
1679 rod->startDate = NULL;
1687 loan_pay_next_button_cb( GtkButton *button, gpointer user_data )
1693 if ( loan_pay_complete ( GTK_ASSISTANT(ldd->window), user_data ) != FALSE )
1696 for ( i = ldd->currentIdx + 1;
1697 (i < ldd->ld.repayOptCount)
1698 && !ldd->ld.repayOpts[i]->enabled; i++ )
1700 if ( i < ldd->ld.repayOptCount )
1702 ldd->currentIdx = i;
1703 loan_pay_prep( GTK_ASSISTANT(ldd->window), user_data );
1711 loan_pay_back_button_cb( GtkButton *button, gpointer user_data )
1717 if ( loan_pay_complete ( GTK_ASSISTANT(ldd->window), user_data ) != FALSE)
1720 for ( i = ldd->currentIdx - 1;
1721 (i > -1) && !ldd->ld.repayOpts[i]->enabled;
1726 ldd->currentIdx = i;
1727 loan_pay_prep( GTK_ASSISTANT(ldd->window), user_data );
1735 loan_pay_all_opt_valid ( GtkAssistant *assistant, gpointer user_data )
1743 for ( i = 0; (i < ldd->ld.repayOptCount); i++ )
1745 if (ldd->ld.repayOpts[i]->enabled)
1747 if (ldd->ld.repayOpts[i]->optValid)
1759 loan_pay_complete( GtkAssistant *assistant, gpointer user_data )
1765 g_assert( ldd->currentIdx >= 0 );
1766 g_assert( ldd->currentIdx <= ldd->ld.repayOptCount );
1767 rod = ldd->ld.repayOpts[ ldd->currentIdx ];
1769 tmpStr = gtk_editable_get_chars( GTK_EDITABLE(ldd->payTxnName),
1771 if ( rod->txnMemo != NULL )
1773 g_free( rod->txnMemo );
1775 rod->txnMemo = tmpStr;
1778 tmpStr = gtk_editable_get_chars( GTK_EDITABLE(ldd->payAmtEntry),
1780 rod->amount = (float)strtod( tmpStr, NULL );
1784 gtk_toggle_button_get_active(
1785 GTK_TOGGLE_BUTTON(ldd->paySpecSrcAcct) );
1788 if ( rod->specSrcAcctP )
1790 rod->from = gnc_account_sel_get_account( ldd->payAcctFromGAS );
1791 if ( rod->from == NULL )
1796 rod->to = gnc_account_sel_get_account( ldd->payAcctToGAS );
1797 if ( rod->to == NULL )
1801 rod->optValid = TRUE;
1804 if ( rod->FreqUniq )
1806 if ( rod->startDate == NULL )
1808 rod->startDate = g_date_new();
1810 recurrenceListFree(&rod->schedule);
1811 gnc_frequency_save_to_recurrence(ldd->payGncFreq, &rod->schedule, rod->startDate);
1813 if (! rod->schedule )
1825 loan_rev_prep( GtkAssistant *assistant, gpointer user_data )
1828 static const int BASE_COLS = 3;
1830 GtkListStore *store;
1831 GtkCellRenderer *renderer;
1832 GtkTreeViewColumn *column;
1838 if (ldd->currentIdx != -1)
1839 loan_pay_complete(assistant, ldd);
1842 if ( ldd->revView != NULL )
1844 gtk_widget_destroy( GTK_WIDGET(ldd->revView) );
1845 ldd->revView = NULL;
1848 ldd->ld.revNumPmts = BASE_COLS;
1850 for ( i = 0; i < ldd->ld.repayOptCount; i++ )
1852 ldd->ld.revRepayOptToColMap[i] = -1;
1853 if ( ! ldd->ld.repayOpts[i]->enabled )
1859 ldd->ld.revRepayOptToColMap[i] = ldd->ld.revNumPmts;
1860 ldd->ld.revNumPmts += 1;
1863 types = g_new( GType, ldd->ld.revNumPmts + 1 );
1864 for ( i = 0; i < ldd->ld.revNumPmts + 1; i++ )
1865 types[i] = G_TYPE_STRING;
1866 store = gtk_list_store_newv(ldd->ld.revNumPmts + 1, types);
1869 ldd->revView = GTK_TREE_VIEW(
1870 gtk_tree_view_new_with_model( GTK_TREE_MODEL(store) ));
1871 g_object_unref(store);
1874 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(ldd->revView), gnc_tree_view_get_grid_lines_pref ());
1876 renderer = gtk_cell_renderer_text_new();
1877 column = gtk_tree_view_column_new_with_attributes(_(
"Date"), renderer,
1878 "text", LOAN_COL_DATE,
1880 gtk_tree_view_append_column(ldd->revView, column);
1882 renderer = gtk_cell_renderer_text_new();
1883 column = gtk_tree_view_column_new_with_attributes(_(
"Payment"), renderer,
1884 "text", LOAN_COL_PAYMENT,
1886 gtk_tree_view_append_column(ldd->revView, column);
1888 renderer = gtk_cell_renderer_text_new();
1889 column = gtk_tree_view_column_new_with_attributes(_(
"Principal"), renderer,
1890 "text", LOAN_COL_PRINCIPAL,
1892 gtk_tree_view_append_column(ldd->revView, column);
1894 renderer = gtk_cell_renderer_text_new();
1895 column = gtk_tree_view_column_new_with_attributes(_(
"Interest"), renderer,
1896 "text", LOAN_COL_INTEREST,
1898 gtk_tree_view_append_column(ldd->revView, column);
1902 for ( i = 0; i < ldd->ld.repayOptCount; i++ )
1904 if ( ldd->ld.revRepayOptToColMap[i] == -1 )
1908 renderer = gtk_cell_renderer_text_new();
1909 column = gtk_tree_view_column_new_with_attributes
1910 (ldd->ld.repayOpts[i]->name, renderer,
1911 "text", LOAN_COL_INTEREST + col,
1913 gtk_tree_view_append_column(ldd->revView, column);
1918 gtk_container_add( GTK_CONTAINER(ldd->revScrollWin),
1919 GTK_WIDGET(ldd->revView) );
1920 gtk_widget_show( GTK_WIDGET(ldd->revView) );
1922 loan_rev_recalc_schedule( ldd );
1926 g_date_clear( &start, 1 );
1927 g_date_clear( &end, 1 );
1928 loan_rev_get_dates( ldd, &start, &end );
1929 loan_rev_update_view( ldd, &start, &end );
1936 loan_rev_range_opt_changed_cb( GtkComboBox *combo, gpointer user_data )
1941 opt = gtk_combo_box_get_active( ldd->revRangeOpt );
1942 gtk_widget_set_sensitive( GTK_WIDGET(ldd->revDateFrame),
1946 g_date_clear( &start, 1 );
1947 g_date_clear( &end, 1 );
1948 loan_rev_get_dates( ldd, &start, &end );
1949 loan_rev_update_view( ldd, &start, &end );
1956 loan_rev_range_changed_cb(
GNCDateEdit *gde, gpointer user_data )
1961 g_date_clear( &start, 1 );
1962 g_date_clear( &end, 1 );
1963 loan_rev_get_dates( ldd, &start, &end );
1964 loan_rev_update_view( ldd, &start, &end );
1974 struct tm *endDateMath;
1976 *start = *ldd->ld.startDate;
1978 endDateMath = g_new0(
struct tm, 1 );
1979 g_date_to_struct_tm (ldd->ld.startDate, endDateMath);
1980 monthsTotal = ( ldd->ld.numPer
1981 * ( ldd->ld.perSize == GNC_MONTHS ? 1 : 12 ) );
1982 endDateMath->tm_mon += monthsTotal;
1984 g_date_subtract_days( end, 1 );
1985 g_free (endDateMath);
1993 int range = gtk_combo_box_get_active( ldd->revRangeOpt );
1998 g_date_set_dmy( start, 1, G_DATE_JANUARY, g_date_get_year( start ) );
1999 g_date_set_dmy( end, 31, G_DATE_DECEMBER, g_date_get_year( start ) );
2004 g_date_add_years( end, 1 );
2007 loan_rev_get_loan_range( ldd, start, end );
2011 gnc_date_edit_get_date( ldd->revStartDate ) );
2013 gnc_date_edit_get_date( ldd->revEndDate ) );
2016 PERR(
"Unknown review date range option %d", range );
2025 loan_rev_sched_list_free( gpointer data, gpointer user_data )
2028 g_free( rrr->numCells );
2035 loan_rev_hash_to_list( gpointer key, gpointer val, gpointer user_data )
2037 GList **l = (GList**)user_data;
2041 DEBUG(
"%.8x, %.8x",
2042 GPOINTER_TO_UINT(key),
2043 GPOINTER_TO_UINT(val));
2047 rrr->date = *(GDate*)key;
2048 rrr->numCells = (gnc_numeric*)val;
2049 *l = g_list_append( *l, (gpointer)rrr );
2055 loan_rev_hash_free_date_keys( gpointer key, gpointer val, gpointer user_data )
2057 g_free( (GDate*)key );
2066 gnc_numeric *rowNumData;
2067 GHashTable *repayment_schedule;
2069 g_date_clear( &start, 1 );
2070 g_date_clear( &end, 1 );
2071 loan_rev_get_loan_range( ldd, &start, &end );
2081 GDate curDate, nextDate;
2082 GString *pmtFormula, *ppmtFormula, *ipmtFormula;
2086 pmtFormula = g_string_sized_new( 64 );
2087 loan_get_pmt_formula( ldd, pmtFormula );
2088 ppmtFormula = g_string_sized_new( 64 );
2089 loan_get_ppmt_formula( ldd, ppmtFormula );
2090 ipmtFormula = g_string_sized_new( 64 );
2091 loan_get_ipmt_formula( ldd, ipmtFormula );
2093 ivar = g_hash_table_new( g_str_hash, g_str_equal );
2094 g_date_clear( &curDate, 1 );
2096 g_date_subtract_days( &curDate, 1 );
2097 g_date_clear(&nextDate, 1);
2098 recurrenceListNextInstance(ldd->ld.repayment_schedule, &curDate, &nextDate);
2100 g_date_valid( &nextDate )
2101 && g_date_compare( &nextDate, &end ) <= 0 ;
2104 recurrenceListNextInstance(ldd->ld.repayment_schedule,
2105 &curDate, &nextDate))
2111 (gnc_numeric*)g_hash_table_lookup( repayment_schedule,
2113 if ( rowNumData == NULL)
2116 GDate *dateKeyCopy = g_date_new();
2118 *dateKeyCopy = nextDate;
2119 rowNumData = g_new0( gnc_numeric, ldd->ld.revNumPmts );
2120 g_assert( rowNumData != NULL );
2121 for ( j = 0; j < ldd->ld.revNumPmts; j++ )
2125 g_hash_table_insert( repayment_schedule,
2126 (gpointer)dateKeyCopy,
2127 (gpointer)rowNumData );
2132 ival = gnc_numeric_create( i, 1 );
2133 g_hash_table_insert( ivar, (gpointer)
"i", &ival );
2135 if ( ! gnc_exp_parser_parse_separate_vars(
2136 pmtFormula->str, &val, &eloc, ivar ) )
2138 PERR(
"pmt Parsing error at %s", eloc );
2142 rowNumData[0] = val;
2144 if ( ! gnc_exp_parser_parse_separate_vars(
2145 ppmtFormula->str, &val, &eloc, ivar ) )
2147 PERR(
"ppmt Parsing error at %s", eloc );
2151 rowNumData[1] = val;
2153 if ( ! gnc_exp_parser_parse_separate_vars(
2154 ipmtFormula->str, &val, &eloc, ivar ) )
2156 PERR(
"ipmt Parsing error at %s", eloc );
2160 rowNumData[2] = val;
2163 g_string_free( ipmtFormula, TRUE );
2164 g_string_free( ppmtFormula, TRUE );
2165 g_string_free( pmtFormula, TRUE );
2167 g_hash_table_destroy( ivar );
2173 GDate curDate, nextDate;
2176 for ( i = 0; i < ldd->ld.repayOptCount; i++ )
2178 if ( ! ldd->ld.repayOpts[i]->enabled )
2182 = ( ldd->ld.repayOpts[i]->schedule != NULL
2183 ? ldd->ld.repayOpts[i]->schedule
2184 : ldd->ld.repayment_schedule );
2186 g_date_clear( &curDate, 1 );
2188 g_date_subtract_days( &curDate, 1 );
2189 g_date_clear(&nextDate, 1);
2190 recurrenceListNextInstance(schedule, &curDate, &nextDate );
2191 for ( ; g_date_valid( &nextDate )
2192 && g_date_compare( &nextDate, &end ) <= 0;
2194 recurrenceListNextInstance(
2195 schedule, &curDate, &nextDate ) )
2201 rowNumData = (gnc_numeric*)g_hash_table_lookup( repayment_schedule,
2203 if ( rowNumData == NULL )
2206 GDate *dateKeyCopy = g_date_new();
2208 *dateKeyCopy = nextDate;
2209 rowNumData = g_new0( gnc_numeric, ldd->ld.revNumPmts );
2210 g_assert( rowNumData != NULL );
2211 for ( j = 0; j < ldd->ld.revNumPmts; j++ )
2215 g_hash_table_insert( repayment_schedule,
2216 (gpointer)dateKeyCopy,
2217 (gpointer)rowNumData );
2224 rowNumData[ ldd->ld.revRepayOptToColMap[i] ]
2232 if ( ldd->ld.revSchedule != NULL )
2234 g_list_foreach( ldd->ld.revSchedule,
2235 loan_rev_sched_list_free,
2237 g_list_free( ldd->ld.revSchedule );
2238 ldd->ld.revSchedule = NULL;
2240 g_hash_table_foreach( repayment_schedule, loan_rev_hash_to_list,
2241 &ldd->ld.revSchedule );
2242 g_hash_table_foreach( repayment_schedule, loan_rev_hash_free_date_keys,
2244 g_hash_table_destroy( repayment_schedule );
2245 ldd->ld.revSchedule =
2246 g_list_sort( ldd->ld.revSchedule, (GCompareFunc)g_date_compare );
2255 static const gchar *NO_AMT_CELL_TEXT =
" ";
2258 GtkListStore *store;
2261 pai = gnc_default_price_print_info(NULL);
2262 pai.min_decimal_places = 2;
2264 store = GTK_LIST_STORE(gtk_tree_view_get_model( ldd->revView ));
2266 gtk_list_store_clear( store );
2268 for ( l = ldd->ld.revSchedule; l != NULL; l = l->next )
2274 if ( g_date_compare( &rrr->date, start ) < 0 )
2276 if ( g_date_compare( &rrr->date, end ) > 0 )
2279 gtk_list_store_append(store, &iter);
2282 gtk_list_store_set( store, &iter, LOAN_COL_DATE, tmpBuf, -1 );
2284 for ( i = 0; i < ldd->ld.revNumPmts; i++ )
2291 gtk_list_store_set( store, &iter,
2292 i + 1, NO_AMT_CELL_TEXT,
2298 g_assert( numPrinted < 50 );
2300 gtk_list_store_set( store, &iter,
2312 gfloat loan_apr_to_simple_formula (gfloat rate, gfloat compounding_periods)
2317 simple_rate = compounding_periods * ((pow((1 + rate), (1 / compounding_periods))) - 1);
2318 return (simple_rate);
2321 using boost::locale::conv::utf_to_utf;
2334 int do_frac_digits()
const {
return prec; }
2339 std::string to_str_with_prec (
const gdouble val)
2343 LCID lcid = GetThreadLocale();
2346 numfmt.NumDigits = prec;
2347 GetLocaleInfoW(lcid, LOCALE_RETURN_NUMBER|LOCALE_ILZERO, (LPWSTR)&numval,
2348 sizeof(numval)/
sizeof(
wchar_t));
2349 numfmt.LeadingZero = numval;
2350 wchar_t grouping[10];
2351 GetLocaleInfoW(lcid, LOCALE_SGROUPING, grouping,
2352 sizeof(grouping)/
sizeof(
wchar_t));
2353 auto semi = wcschr(grouping,
';');
2355 numfmt.Grouping = _wtoi(grouping);
2357 GetLocaleInfoW(lcid, LOCALE_SDECIMAL, decsep,
2358 sizeof(decsep)/
sizeof(
wchar_t) );
2359 numfmt.lpDecimalSep = decsep;
2361 GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousep,
2362 sizeof(thousep)/
sizeof(
wchar_t));
2363 numfmt.lpThousandSep = thousep;
2364 GetLocaleInfoW(lcid, LOCALE_RETURN_NUMBER|LOCALE_INEGNUMBER,
2365 (LPWSTR)&numval,
sizeof(numval)/
sizeof(
wchar_t));
2366 numfmt.NegativeOrder = numval;
2368 std::wstringstream valstr;
2370 int size = GetNumberFormatW(lcid, 0, valstr.str().c_str(),
2371 &numfmt,
nullptr, 0);
2372 wchar_t* buf =
static_cast<wchar_t*
>(malloc(
sizeof(
wchar_t) * size));
2373 GetNumberFormatW(lcid, 0, valstr.str().c_str(), &numfmt, buf, size);
2374 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,
wchar_t> conv;
2375 std::string result = conv.to_bytes(buf);
2380 std::wstringstream valstr;
2382 valstr << std::put_money(val * pow(10, prec));
2383 return utf_to_utf<char>(valstr.str());
2389 loan_get_formula_internal(
LoanAssistantData *ldd, GString *gstr,
const gchar *tpl )
2391 g_assert( ldd != NULL );
2392 g_assert( gstr != NULL );
2394 gdouble pass_thru_rate = ldd->ld.interestRate / 100.0;
2395 gdouble periods = (ldd->ld.numPer * (ldd->ld.perSize == GNC_MONTHS ? 1 : 12)) * 1.;
2398 gdouble period_rate;
2399 auto rate_case = ldd->ld.rateType;
2402 case GNC_IRATE_SIMPLE:
2403 period_rate = pass_thru_rate;
2405 case GNC_IRATE_APR_DAILY:
2406 period_rate = loan_apr_to_simple_formula (pass_thru_rate, 365);
2408 case GNC_IRATE_APR_WEEKLY:
2409 period_rate = loan_apr_to_simple_formula (pass_thru_rate, 52);
2411 case GNC_IRATE_APR_MONTHLY:
2412 period_rate = loan_apr_to_simple_formula (pass_thru_rate, 12);
2414 case GNC_IRATE_APR_QUARTERLY:
2415 period_rate = loan_apr_to_simple_formula (pass_thru_rate, 4);
2417 case GNC_IRATE_APR_ANNUALLY:
2418 period_rate = loan_apr_to_simple_formula (pass_thru_rate, 1);
2421 period_rate = ldd->ld.interestRate / 100;
2424 auto period_rate_str = to_str_with_prec<5> (period_rate);
2425 auto period_base_str = to_str_with_prec<2> (12.0);
2426 auto periods_str = to_str_with_prec<2> (periods);
2427 auto principal_str = to_str_with_prec<2> (principal);
2437 auto formula = (bl::format (tpl) % period_rate_str %
2438 period_base_str % periods_str % principal_str).str();
2439 g_string_append (gstr, formula.c_str());
2446 loan_get_formula_internal (ldd, gstr,
"pmt( {1} / {2} : {3} : {4} : 0 : 0 )");
2454 loan_get_formula_internal (ldd, gstr,
"ppmt( {1} / {2} : i : {3} : {4} : 0 : 0 )");
2462 loan_get_formula_internal (ldd, gstr,
"ipmt( {1} / {2} : i : {3} : {4} : 0 : 0 )");
2468 ld_calc_sx_instance_num(GDate *start_date, GList *schedule)
2471 GDate next_date, today;
2473 g_date_clear(&next_date, 1);
2474 g_date_clear(&today, 1);
2477 if (g_date_compare(start_date, &today) > 0)
2480 instance_count = -1;
2484 recurrenceListNextInstance(schedule, start_date, &next_date);
2486 while (g_date_compare(&next_date, &today) < 0);
2488 return instance_count;
2494 loan_tcSX_free( gpointer data, gpointer user_data )
2497 g_free( tcSX->
name );
2512 SchedXactions *sxes;
2518 xaccSchedXactionSetStartDate( sx, &tcSX->
start );
2519 xaccSchedXactionSetLastOccurDate( sx, &tcSX->last );
2524 ttxn_vec.push_back (tcSX->
mainTxn);
2528 g_assert (!ttxn_vec.empty());
2530 xaccSchedXactionSetTemplateTrans (sx, ttxn_vec, gnc_get_current_book());
2532 sxes = gnc_book_get_schedxactions(gnc_get_current_book());
2533 gnc_sxes_add_sx(sxes, sx);
2537 static TTSplitInfoPtr
2538 find_account_from_template_splits (
const TTInfoPtr& txn,
const Account* account)
2540 auto& splits{txn->get_template_splits ()};
2541 auto has_acct = [account](
auto ttinfo){
return ttinfo->get_account() == account; };
2542 auto it = std::find_if (splits.begin(), splits.end(), has_acct);
2543 return it == splits.end() ? nullptr : *it;
2623 TTSplitInfoPtr fromSplit;
2624 TTSplitInfoPtr ttsi;
2627 #define AMTBUF_LEN 64 2628 gchar amtBuf[AMTBUF_LEN];
2637 if ( rod->throughEscrowP && ldd->ld.escrowAcct )
2644 auto ttsi = find_account_from_template_splits (paymentSX->
mainTxn, ldd->ld.escrowAcct);
2646 gstr = g_string_new (ttsi->get_debit_formula());
2647 g_string_append_printf( gstr,
" + %s", amtBuf );
2648 ttsi->set_debit_formula (gstr->str);
2649 g_string_free( gstr, TRUE );
2654 if ( rod->from != NULL )
2661 auto ttsi = find_account_from_template_splits (tcSX->
escrowTxn, ldd->ld.escrowAcct);
2665 ttsi = std::make_shared<TTSplitInfo>();
2666 ttsi->set_memo (rod->txnMemo);
2667 ttsi->set_account (ldd->ld.escrowAcct);
2668 tcSX->
escrowTxn->append_template_split (ttsi);
2670 if ( (str = (gchar*)ttsi->get_credit_formula ())
2673 gstr = g_string_sized_new( 16 );
2680 gstr = g_string_new( str );
2681 g_string_append_printf( gstr,
" + " );
2683 g_string_append_printf( gstr,
"%s", amtBuf );
2684 ttsi->set_credit_formula (gstr->str);
2685 g_string_free( gstr, TRUE );
2692 fromSplit = find_account_from_template_splits (paymentSX->
mainTxn, ldd->ld.repFromAcct);
2693 g_assert (fromSplit);
2696 ttsi = std::make_shared<TTSplitInfo>();
2697 ttsi->set_memo (rod->txnMemo);
2698 ttsi->set_account (ldd->ld.escrowAcct);
2699 ttsi->set_credit_formula (amtBuf);
2700 tcSX->
escrowTxn->append_template_split (ttsi);
2708 if ( rod->from != NULL )
2714 fromSplit = find_account_from_template_splits (tcSX->
mainTxn, ldd->ld.repFromAcct);
2718 if ( fromSplit != NULL )
2721 gstr = g_string_new (fromSplit->get_credit_formula ());
2722 g_string_append_printf( gstr,
" + %s", amtBuf );
2723 fromSplit->set_credit_formula (gstr->str);
2724 g_string_free( gstr, TRUE );
2732 ttsi = std::make_shared<TTSplitInfo>();
2733 ttsi->set_memo (rod->txnMemo);
2734 ttsi->set_account (rod->from ? rod->from : ldd->ld.repFromAcct);
2735 ttsi->set_credit_formula (amtBuf);
2737 if ( rod->throughEscrowP )
2741 tti->append_template_split (ttsi);
2748 ttsi = std::make_shared<TTSplitInfo>();
2749 ttsi->set_memo (rod->txnMemo);
2750 ttsi->set_account (rod->to);
2751 ttsi->set_debit_formula (amtBuf);
2752 toTxn->append_template_split (ttsi);
2779 GList *repaySXes = NULL;
2784 TTSplitInfoPtr ttsi;
2788 paymentSX->
name = g_strdup(ldd->ld.repMemo);
2789 paymentSX->
start = *ldd->ld.startDate;
2790 paymentSX->last = *ldd->ld.repStartDate;
2791 g_date_subtract_months( &paymentSX->last, 1 );
2793 paymentSX->end = *ldd->ld.repStartDate;
2794 g_date_add_months( &paymentSX->end, ldd->ld.numMonRemain - 1);
2797 paymentSX->
schedule = ldd->ld.repayment_schedule;
2801 (ldd->ld.numPer * ( ldd->ld.perSize == GNC_YEARS ? 12 : 1 ))
2802 - ldd->ld.numMonRemain + 1;
2804 paymentSX->
mainTxn = std::make_shared<TTInfo>();
2808 GString *payMainTxnDesc = g_string_sized_new( 32 );
2809 g_string_printf( payMainTxnDesc,
2812 ( ldd->ld.escrowAcct == NULL
2814 : _(
"Escrow Payment") )
2817 paymentSX->
mainTxn->set_description(payMainTxnDesc->str);
2818 g_string_free( payMainTxnDesc, TRUE );
2840 srcAcct = ldd->ld.repFromAcct;
2841 if ( ldd->ld.escrowAcct != NULL )
2843 Account *realSrcAcct = srcAcct;
2844 srcAcct = ldd->ld.escrowAcct;
2845 gstr = g_string_sized_new( 32 );
2846 loan_get_pmt_formula( ldd, gstr );
2849 ttsi = std::make_shared<TTSplitInfo>();
2850 ttsi->set_memo (ldd->ld.repMemo);
2851 ttsi->set_account (realSrcAcct);
2852 ttsi->set_credit_formula (gstr->str);
2853 ttxn->append_template_split (ttsi);
2858 ttsi = std::make_shared<TTSplitInfo>();
2859 ttsi->set_memo (ldd->ld.repMemo);
2860 ttsi->set_account (ldd->ld.escrowAcct);
2861 ttsi->set_debit_formula (gstr->str);
2862 ttxn->append_template_split (ttsi);
2865 g_string_free( gstr, TRUE );
2867 paymentSX->
escrowTxn = std::make_shared<TTInfo>();
2871 GString *escrowTxnDesc;
2872 escrowTxnDesc = g_string_new( ldd->ld.repMemo );
2873 g_string_append_printf( escrowTxnDesc,
" - %s", _(
"Payment") );
2874 paymentSX->
escrowTxn->set_description (escrowTxnDesc->str);
2875 g_string_free( escrowTxnDesc, TRUE );
2881 ttsi = std::make_shared<TTSplitInfo>();
2883 gstr = g_string_new( ldd->ld.repMemo );
2884 g_string_append_printf( gstr,
" - %s",
2886 ttsi->set_memo (gstr->str);
2887 g_string_free( gstr, TRUE );
2890 ttsi->set_account (srcAcct);
2891 gstr = g_string_sized_new( 32 );
2892 loan_get_pmt_formula( ldd, gstr );
2893 ttsi->set_credit_formula (gstr->str);
2894 ttxn->append_template_split (ttsi);
2895 g_string_free( gstr, TRUE );
2901 ttsi = std::make_shared<TTSplitInfo>();
2903 gstr = g_string_new( ldd->ld.repMemo );
2904 g_string_append_printf( gstr,
" - %s",
2906 ttsi->set_memo (gstr->str);
2907 g_string_free( gstr, TRUE );
2910 ttsi->set_account (ldd->ld.repPriAcct);
2911 gstr = g_string_sized_new( 32 );
2912 loan_get_ppmt_formula( ldd, gstr );
2913 ttsi->set_debit_formula (gstr->str);
2914 ttxn->append_template_split (ttsi);
2915 g_string_free( gstr, TRUE );
2921 ttsi = std::make_shared<TTSplitInfo>();
2923 gstr = g_string_new( ldd->ld.repMemo );
2924 g_string_append_printf( gstr,
" - %s",
2926 ttsi->set_memo (gstr->str);
2927 g_string_free( gstr, TRUE );
2930 ttsi->set_account (ldd->ld.repIntAcct);
2931 gstr = g_string_sized_new( 32 );
2932 loan_get_ipmt_formula( ldd, gstr );
2933 ttsi->set_debit_formula (gstr->str);
2934 ttxn->append_template_split (ttsi);
2935 g_string_free( gstr, TRUE );
2940 for ( i = 0; i < ldd->ld.repayOptCount; i++ )
2943 if ( ! rod->enabled )
2947 if ( rod->schedule != NULL )
2950 gstr = g_string_new( ldd->ld.repMemo );
2951 g_string_append_printf( gstr,
" - %s",
2953 tcSX->
name = g_strdup(gstr->str);
2954 tcSX->
start = *ldd->ld.startDate;
2955 tcSX->last = *ldd->ld.repStartDate;
2957 tcSX->end = tcSX->last;
2958 g_date_add_months( &tcSX->end, ldd->ld.numMonRemain );
2964 ld_calc_sx_instance_num(&tcSX->
start, rod->schedule);
2965 rod->schedule = NULL;
2966 tcSX->
mainTxn = std::make_shared<TTInfo>();
2968 tcSX->
mainTxn->set_description (gstr->str);
2969 tcSX->
escrowTxn = std::make_shared<TTInfo>();
2971 tcSX->
escrowTxn->set_description(gstr->str);
2973 g_string_free( gstr, TRUE );
2976 repaySXes = g_list_prepend (repaySXes, tcSX);
2981 ld_setup_repayment_sx( ldd, rod, paymentSX, tcSX );
2984 repaySXes = g_list_reverse (repaySXes);
2989 loan_create_sx_from_tcSX( ldd, paymentSX );
2991 for ( l = repaySXes; l; l = l->next )
2993 loan_create_sx_from_tcSX( ldd, (
toCreateSX*)l->data );
2997 loan_tcSX_free( paymentSX, NULL );
2998 g_list_foreach( repaySXes, loan_tcSX_free, NULL );
2999 g_list_free( repaySXes );
3005 loan_assistant_finish ( GtkAssistant *gtkassistant, gpointer user_data )
3008 loan_create_sxes( ldd );
3014 loan_assistant_cancel( GtkAssistant *gtkassistant, gpointer user_data )
3017 gnc_close_gui_component_by_data( DIALOG_LOAN_ASSISTANT_CM_CLASS, ldd );
3022 loan_assistant_close( GtkAssistant *gtkassistant, gpointer user_data )
3025 gnc_close_gui_component_by_data( DIALOG_LOAN_ASSISTANT_CM_CLASS, ldd );
3030 loan_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
3033 gint currentpage = gtk_assistant_get_current_page(assistant);
3035 switch (currentpage)
3039 loan_info_prep (assistant, user_data);
3043 loan_opt_prep (assistant, user_data);
3047 loan_rep_prep (assistant, user_data);
3051 loan_pay_prep (assistant, user_data);
3055 loan_rev_prep (assistant, user_data);
3067 gnc_ui_sx_loan_assistant_create (
void)
3074 gnc_loan_assistant_create (ldd);
3076 component_id = gnc_register_gui_component (DIALOG_LOAN_ASSISTANT_CM_CLASS,
3077 NULL, loan_assistant_close_handler,
3080 gnc_gui_component_watch_entity_type (component_id,
3082 QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);
3084 gtk_widget_show_all (ldd->window);
3086 gnc_window_adjust_for_screen (GTK_WINDOW(ldd->window));
A transient struct used to collate the GDate and the gnc_numeric row-data for the repayment review sc...
void gnc_sx_set_schedule(SchedXaction *sx, GList *schedule)
void gnc_sx_set_instance_count(SchedXaction *sx, gint instance_num)
Sets the instance count to something other than the default.
TTInfoPtr mainTxn
The main/source transaction being created.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
Date and Time handling routines.
gnc_numeric double_to_gnc_numeric(double n, gint64 denom, gint how)
Convert a floating-point number to a gnc_numeric.
gint gnc_gdate_equal(gconstpointer gda, gconstpointer gdb)
Compares two GDate*'s for equality; useful for using GDate*'s as GHashTable keys. ...
utility functions for the GnuCash UI
Expense accounts are used to denote expenses.
gchar * name
The name of the SX.
guint gnc_gdate_hash(gconstpointer gd)
Provides a "hash" of a GDate* value; useful for using GDate*'s as GHashTable keys.
size_t qof_print_gdate(char *buf, size_t bufflen, const GDate *gd)
Convenience; calls through to qof_print_date_dmy_buff().
#define DEBUG(format, args...)
Print a debugging message.
The data relating to a single "repayment option" – a potential [sub-]transaction in the repayment...
#define PERR(format, args...)
Log a serious error.
The cash account type is used to denote a shoe-box or pillowcase stuffed with * cash.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
void gnc_tm_free(struct tm *time)
free a struct tm* created with gnc_localtime() or gnc_gmtime()
gdouble gnc_numeric_to_double(gnc_numeric n)
Convert numeric to floating-point value.
The UI-side storage of the loan assistant data.
The default repayment options data.
Account handling public routines.
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Change the denominator of a gnc_numeric value to the specified denominator under standard arguments '...
gint instNum
The current 'instance-num' count.
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code)
Create a gnc_numeric object that signals the error condition noted by error_code, rather than a numbe...
Anchor Scheduled Transaction info in a book.
A transient structure to contain SX details during the creation process.
GDate start
The start, last-occurred and end dates.
The bank account type denotes a savings or checking account held at a bank.
The UI-side storage of the repayment options.
Argument is not a valid number.
time64 gnc_mktime(struct tm *time)
calculate seconds from the epoch given a time struct
GList * schedule
The SX schedule.
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
struct tm * gnc_localtime(const time64 *secs)
fill out a time struct from a 64-bit time value.
asset (and liability) accounts indicate generic, generalized accounts that are none of the above...
All type declarations for the whole Gnucash engine.
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
void xaccSchedXactionSetName(SchedXaction *sx, const gchar *newName)
A copy of the name is made.
liability (and asset) accounts indicate generic, generalized accounts that are none of the above...
void gnc_gdate_set_time64(GDate *gd, time64 time)
Set a GDate to a time64.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
TTInfoPtr escrowTxn
The optional escrow transaction being created.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
time64 gnc_time(time64 *tbuf)
get the current time
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
Check for error signal in value.
SchedXaction * xaccSchedXactionMalloc(QofBook *book)
Creates and initializes a scheduled transaction.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Scheduled Transactions public handling routines.
void xaccSchedXactionSetEndDate(SchedXaction *sx, const GDate *newEnd)
Set to an invalid GDate to turn off 'end-date' definition.
#define GNC_HOW_DENOM_SIGFIGS(n)
Build a 'how' value that will generate a denominator that will keep at least n significant figures in...
Data about a loan repayment.
The Credit card account is used to denote credit (e.g.