diff --git a/src/business/business-gnome/dialog-payment.c b/src/business/business-gnome/dialog-payment.c index 2afeeb1853..16a29bbf38 100644 --- a/src/business/business-gnome/dialog-payment.c +++ b/src/business/business-gnome/dialog-payment.c @@ -60,7 +60,8 @@ struct _payment_window GtkWidget * memo_entry; GtkWidget * post_combo; GtkWidget * owner_choice; - GtkWidget * amount_edit; + GtkWidget * amount_debit_edit; + GtkWidget * amount_credit_edit; GtkWidget * date_edit; GtkWidget * acct_tree; GtkWidget * docs_list_tree_view; @@ -95,7 +96,23 @@ void gnc_ui_payment_window_set_date (PaymentWindow *pw, const GDate *date) void gnc_ui_payment_window_set_amount (PaymentWindow *pw, gnc_numeric amount) { g_assert(pw); - gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(pw->amount_edit), amount); + + /* Debits are negative, credits are positive */ + if (gnc_numeric_positive_p (amount)) + { + gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(pw->amount_credit_edit), + amount); + gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(pw->amount_debit_edit), + gnc_numeric_zero ()); + } + else + { + gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(pw->amount_debit_edit), + gnc_numeric_neg (amount)); + gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(pw->amount_credit_edit), + gnc_numeric_zero ()); + } + } void gnc_ui_payment_window_set_postaccount (PaymentWindow *pw, const Account* account) { @@ -126,6 +143,8 @@ void gnc_payment_cancel_cb (GtkWidget *widget, gpointer data); void gnc_payment_window_destroy_cb (GtkWidget *widget, gpointer data); void gnc_payment_acct_tree_row_activated_cb (GtkWidget *widget, GtkTreePath *path, GtkTreeViewColumn *column, PaymentWindow *pw); +void gnc_payment_leave_amount_cb (GtkWidget *widget, GdkEventFocus *event, + PaymentWindow *pw); static void @@ -203,9 +222,7 @@ gnc_payment_dialog_document_selection_changed (PaymentWindow *pw) /* Set the payment amount in the dialog */ val = gnc_payment_dialog_calculate_selected_total (pw); - /* XXX It may not always be correct to use the absolute value of amount here - * This is an assumption from before the credit notes implementation. */ - gnc_ui_payment_window_set_amount(pw, gnc_numeric_abs (val)); + gnc_ui_payment_window_set_amount(pw, val); } static void @@ -521,20 +538,22 @@ gnc_payment_ok_cb (GtkWidget *widget, gpointer data) PaymentWindow *pw = data; const char *text = NULL; Account *post, *acc; - gnc_numeric amount; + gnc_numeric amount_deb, amount_cred, amount_tot; if (!pw) return; - /* Verify the amount is non-zero */ - amount = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (pw->amount_edit)); + /* Verify the total amount is non-zero */ + amount_deb = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (pw->amount_debit_edit)); + amount_cred = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (pw->amount_credit_edit)); + amount_tot = gnc_numeric_sub (amount_cred, amount_deb, + gnc_commodity_get_fraction (xaccAccountGetCommodity (pw->post_acct)), + GNC_HOW_RND_ROUND_HALF_UP); - /* XXX Amounts could possibly be negative as well if you take credit notes into account - * This still has to be reviewed */ - if (gnc_numeric_check (amount) || !gnc_numeric_positive_p (amount)) + if (gnc_numeric_check (amount_tot) || gnc_numeric_zero_p (amount_tot)) { text = _("You must enter the amount of the payment. " - "The payment amount must be greater than zero."); + "The payment amount must not be zero."); gnc_error_dialog (pw->dialog, "%s", text); return; } @@ -597,7 +616,7 @@ gnc_payment_ok_cb (GtkWidget *widget, gpointer data) gnc_info_dialog(pw->dialog, "%s", text); gnc_xfer_dialog_select_to_account(xfer, post); - gnc_xfer_dialog_set_amount(xfer, amount); + gnc_xfer_dialog_set_amount(xfer, amount_tot); /* All we want is the exchange rate so prevent the user from thinking it makes sense to mess with other stuff */ @@ -611,7 +630,7 @@ gnc_payment_ok_cb (GtkWidget *widget, gpointer data) /* Perform the payment */ gncOwnerApplyPayment (&pw->owner, pw->pre_existing_txn, selected_lots, - post, acc, amount, exch, date, memo, num); + post, acc, amount_tot, exch, date, memo, num); } gnc_resume_gui_refresh (); @@ -671,6 +690,25 @@ gnc_payment_acct_tree_row_activated_cb (GtkWidget *widget, GtkTreePath *path, } } +void +gnc_payment_leave_amount_cb (GtkWidget *widget, GdkEventFocus *event, + PaymentWindow *pw) +{ + gnc_numeric amount_deb, amount_cred, amount_tot; + + if (! pw->amount_credit_edit || ! pw->amount_debit_edit) + return; + + /* If both credit and debit amount are entered, simplify it to either one */ + amount_deb = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (pw->amount_debit_edit)); + amount_cred = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (pw->amount_credit_edit)); + amount_tot = gnc_numeric_sub (amount_cred, amount_deb, + gnc_commodity_get_fraction (xaccAccountGetCommodity (pw->post_acct)), + GNC_HOW_RND_ROUND_HALF_UP); + + gnc_ui_payment_window_set_amount (pw, amount_tot); +} + /* Select the list of accounts to show in the tree */ static void gnc_payment_set_account_types (GncTreeViewAccount *tree) @@ -768,12 +806,25 @@ new_payment_window (GncOwner *owner, QofBook *book, GncInvoice *invoice) box = GTK_WIDGET (gtk_builder_get_object (builder, "owner_box")); pw->owner_choice = gnc_owner_select_create (label, box, book, owner); - box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_box")); - pw->amount_edit = gnc_amount_edit_new (); - gtk_box_pack_start (GTK_BOX (box), pw->amount_edit, TRUE, TRUE, 0); - gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (pw->amount_edit), + box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_debit_box")); + pw->amount_debit_edit = gnc_amount_edit_new (); + gtk_box_pack_start (GTK_BOX (box), pw->amount_debit_edit, TRUE, TRUE, 0); + gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (pw->amount_debit_edit), TRUE); - gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (pw->amount_edit), gnc_numeric_zero()); + gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (pw->amount_debit_edit), gnc_numeric_zero()); + g_signal_connect(G_OBJECT(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(pw->amount_debit_edit))), + "focus-out-event", + G_CALLBACK(gnc_payment_leave_amount_cb), pw); + + box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_credit_box")); + pw->amount_credit_edit = gnc_amount_edit_new (); + gtk_box_pack_start (GTK_BOX (box), pw->amount_credit_edit, TRUE, TRUE, 0); + gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (pw->amount_credit_edit), + TRUE); + gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (pw->amount_credit_edit), gnc_numeric_zero()); + g_signal_connect(G_OBJECT(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(pw->amount_credit_edit))), + "focus-out-event", + G_CALLBACK(gnc_payment_leave_amount_cb), pw); box = GTK_WIDGET (gtk_builder_get_object (builder, "date_box")); pw->date_edit = gnc_date_edit_new (time(NULL), FALSE, FALSE); @@ -1045,7 +1096,7 @@ PaymentWindow * gnc_ui_payment_new_with_txn (GncOwner *owner, Transaction *txn) pw = gnc_ui_payment_new(owner, qof_instance_get_book(QOF_INSTANCE(txn))); g_assert(assetaccount_split); // we can rely on this because of the countAssetAccounts() check above - //g_message("Amount=%s", gnc_numeric_to_string(amount)); + g_debug("Amount=%s", gnc_numeric_to_string(amount)); // Fill in the values from the given txn pw->pre_existing_txn = txn; @@ -1055,9 +1106,7 @@ PaymentWindow * gnc_ui_payment_new_with_txn (GncOwner *owner, Transaction *txn) GDate txn_date = xaccTransGetDatePostedGDate (txn); gnc_ui_payment_window_set_date(pw, &txn_date); } - /* XXX It may not always be correct to use the absolute value of amount here - * This is an assumption from before the credit notes implementation. */ - gnc_ui_payment_window_set_amount(pw, gnc_numeric_abs(amount)); + gnc_ui_payment_window_set_amount(pw, amount); gnc_ui_payment_window_set_xferaccount(pw, xaccSplitGetAccount(assetaccount_split)); if (postaccount_split) gnc_ui_payment_window_set_postaccount(pw, xaccSplitGetAccount(postaccount_split)); diff --git a/src/business/business-gnome/gtkbuilder/dialog-payment.glade b/src/business/business-gnome/gtkbuilder/dialog-payment.glade index 41469afb20..3efbf65aaa 100644 --- a/src/business/business-gnome/gtkbuilder/dialog-payment.glade +++ b/src/business/business-gnome/gtkbuilder/dialog-payment.glade @@ -18,14 +18,16 @@ True False + 3 3 2 + 3 + 3 True False 0 - none True @@ -38,6 +40,7 @@ True The company associated with this payment. The company associated with this payment. + 3 @@ -68,7 +71,6 @@ True False 0 - none True @@ -78,6 +80,7 @@ True False + 3 post_combo_model True 0 @@ -114,7 +117,6 @@ True False 0 - none True @@ -124,6 +126,7 @@ True True + 3 docs_list_hor_adj docs_list_vert_adj in @@ -148,6 +151,7 @@ fixed 50 Date + True True 0 @@ -164,6 +168,7 @@ fixed 50 Number + True 1 @@ -179,6 +184,7 @@ fixed 50 Type + True 2 @@ -194,6 +200,7 @@ fixed 50 Debit + True 3 @@ -209,6 +216,7 @@ fixed 50 Credit + True 4 @@ -246,22 +254,24 @@ True False 0 - none True False 12 - + True False + 3 - + True False - 3 - True + 8 + 2 + 3 + 3 True @@ -271,9 +281,21 @@ right - False - False - 0 + GTK_FILL + GTK_FILL + + + + + True + False + + + + + + 1 + 2 @@ -292,13 +314,67 @@ If you have selected an invoice, GnuCash will propose the amount still due for i In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. 1 - Amount + <b>Amount</b> + True right - False - False - 1 + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + False + True + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + 1 + Debit + right + + + 3 + 4 + GTK_FILL + GTK_FILL + + + + + True + False + True + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + 1 + Credit + right + + + 4 + 5 + GTK_FILL + GTK_FILL @@ -310,9 +386,10 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic right - False - False - 2 + 6 + 7 + GTK_FILL + GTK_FILL @@ -324,40 +401,40 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic right - False - False - 3 + 7 + 8 + GTK_FILL + GTK_FILL - - - False - True - 0 - - - - - True - False - 3 - True - + True False + True + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. - False - False - 0 + 1 + 2 + 3 + 4 - + True False True @@ -376,9 +453,10 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic - True - True - 1 + 1 + 2 + 4 + 5 @@ -389,9 +467,10 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic True - False - False - 2 + 1 + 2 + 6 + 7 @@ -402,16 +481,80 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic True - False - False - 3 + 1 + 2 + 7 + 8 + + + + + True + False + True + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + + + + + + 1 + 2 + + + 3 + + + + + True + False + True + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + The amount to pay for this invoice. + +If you have selected an invoice, GnuCash will propose the amount still due for it. You can change this amount to create a partial payment or an over-payment. + +In case of an over-payment or if no invoice was selected, GnuCash will automatically assign the remaining amount to the first unpaid invoice for this company. + + + + + + 5 + 6 + + + 3 + + + + + + + + + - True + False True - 1 + 0 @@ -440,7 +583,6 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic True False 0 - none True @@ -449,6 +591,7 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic 250 + 200 True True 3 @@ -493,7 +636,6 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic gtk-cancel - False True True True @@ -511,7 +653,6 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic gtk-ok - False True True True diff --git a/src/engine/gncOwner.c b/src/engine/gncOwner.c index 11566f9ac4..70cf00fbaa 100644 --- a/src/engine/gncOwner.c +++ b/src/engine/gncOwner.c @@ -700,17 +700,6 @@ gncOwnerLotsSortFunc (GNCLot *lotA, GNCLot *lotB) return timespec_cmp (&da, &db); } -static gboolean use_reversed_payment_amounts(const GncOwner *owner) -{ - g_assert(owner); - return (gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER); -} - - -/* - * Create a payment of "amount" for the owner and return - * the new lot associated with this payment. - */ GNCLot * gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn, Account *posted_acc, Account *xfer_acc, @@ -721,8 +710,6 @@ gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn, Split *split; const char *name; gnc_commodity *commodity; - gboolean reverse; - gnc_numeric payment_value = amount; Split *xfer_split = NULL; GNCLot *payment_lot; @@ -734,7 +721,7 @@ gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn, book = gnc_account_get_book (posted_acc); name = gncOwnerGetName (gncOwnerGetEndOwner ((GncOwner*)owner)); commodity = gncOwnerGetCurrency (owner); - reverse = use_reversed_payment_amounts(owner); +// reverse = use_reversed_payment_amounts(owner); if (txn) { @@ -811,15 +798,16 @@ gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn, if (gnc_commodity_equal(xaccAccountGetCommodity(xfer_acc), commodity)) { - xaccSplitSetBaseValue (split, reverse ? amount : - gnc_numeric_neg (amount), commodity); + xaccSplitSetBaseValue (split, amount, commodity); } else { /* Need to value the payment in terms of the owner commodity */ - xaccSplitSetAmount(split, reverse ? amount : gnc_numeric_neg (amount)); - payment_value = gnc_numeric_mul(amount, exch, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP); - xaccSplitSetValue(split, reverse ? payment_value : gnc_numeric_neg(payment_value)); + gnc_numeric payment_value = gnc_numeric_mul(amount, + exch, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP); + + xaccSplitSetAmount(split, amount); + xaccSplitSetValue(split, payment_value); } } @@ -831,7 +819,7 @@ gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn, xaccAccountInsertSplit (posted_acc, split); xaccAccountCommitEdit (posted_acc); xaccTransAppendSplit (txn, split); - xaccSplitSetBaseValue (split, reverse ? gnc_numeric_neg (amount) : amount, commodity); + xaccSplitSetBaseValue (split, gnc_numeric_neg (amount), commodity); /* Create a new lot for the payment */ payment_lot = gnc_lot_new (book);