gnucash maint: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Fri Mar 25 13:14:16 EDT 2016


Updated	 via  https://github.com/Gnucash/gnucash/commit/f5a7aeca (commit)
	 via  https://github.com/Gnucash/gnucash/commit/6fd35694 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/656a3a9b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d5d58dac (commit)
	 via  https://github.com/Gnucash/gnucash/commit/531335a8 (commit)
	from  https://github.com/Gnucash/gnucash/commit/163c4dd4 (commit)



commit f5a7aeca791300d4e5942a28573ef0bd5d197dcd
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Fri Mar 25 18:09:27 2016 +0100

    Bug 719904 - Decide payment type only based on the account type involved
    
    This commit improves payment type deduction by first checking
    whether an AR or AP account is found in the transaction.
    If not, fall back to previous heuristic of positive action
    means customer payment, negative action means vendor
    action. The logic can still go wrong (no means to declare
    an employee payment, and credit notes are interpreted as
    opposite sign payments). Needs a follow up to fix that.

diff --git a/src/business/business-gnome/dialog-payment.c b/src/business/business-gnome/dialog-payment.c
index 11b0c3e..96d20e4 100644
--- a/src/business/business-gnome/dialog-payment.c
+++ b/src/business/business-gnome/dialog-payment.c
@@ -1170,19 +1170,34 @@ gnc_ui_payment_new (GncOwner *owner, QofBook *book)
 gboolean gnc_ui_payment_is_customer_payment(const Transaction *txn)
 {
     gboolean result = TRUE;
-    Split *assetaccount_split;
+    Split *assetaccount_split, *aparaccount_split;
     gnc_numeric amount;
 
     if (!txn)
         return result;
 
-    // We require the txn to have one split in an A/R or A/P account.
-
     if (!xaccTransGetSplitList(txn))
         return result;
+
+    /* First test if one split is in an A/R or A/P account.
+     * That will give us the best Customer vs Vendor/Employee distinction */
+    aparaccount_split = xaccTransGetFirstAPARAcctSplit(txn);
+    if (aparaccount_split)
+    {
+        if (xaccAccountGetType (xaccSplitGetAccount (aparaccount_split)) == ACCT_TYPE_RECEIVABLE)
+            return TRUE;  // Type is Customer
+        else if (xaccAccountGetType (xaccSplitGetAccount (aparaccount_split)) == ACCT_TYPE_PAYABLE)
+            return FALSE; // Type is Vendor/Employee, there's not enough information to refine more
+    }
+
+    /* For the lack of an A/R or A/P account we'll assume positive changes to an
+     * Asset/Liability or Equity account are Customer payments the others will be
+     * considered Vendor payments */
     assetaccount_split = xaccTransGetFirstPaymentAcctSplit(txn);
     if (!assetaccount_split)
     {
+        /* Transaction isn't valid for a payment, just return the default
+         * Calling code will have to handle this situation properly */
         g_message("No asset splits in txn \"%s\"; cannot use this for assigning a payment.",
                   xaccTransGetDescription(txn));
         return result;
diff --git a/src/business/business-gnome/gnc-plugin-business.c b/src/business/business-gnome/gnc-plugin-business.c
index 2c493f8..b82a747 100644
--- a/src/business/business-gnome/gnc-plugin-business.c
+++ b/src/business/business-gnome/gnc-plugin-business.c
@@ -822,7 +822,9 @@ static void gnc_plugin_business_cmd_assign_payment (GtkAction *action,
     SplitRegister *reg;
     Split *split;
     Transaction *trans;
-    gboolean is_customer;
+    gboolean have_owner;
+    GncOwner owner;
+    GncOwner *owner_p;
 
     g_return_if_fail (mw != NULL);
     g_return_if_fail (GNC_IS_PLUGIN_BUSINESS (mw->data));
@@ -846,16 +848,20 @@ static void gnc_plugin_business_cmd_assign_payment (GtkAction *action,
 
     trans = xaccSplitGetParent(split);
     g_return_if_fail(trans);
-    is_customer = gnc_ui_payment_is_customer_payment(trans);
 
     plugin_business = GNC_PLUGIN_BUSINESS (mw->data);
     plugin_business_priv = GNC_PLUGIN_BUSINESS_GET_PRIVATE (plugin_business);
 
+    have_owner = gncOwnerGetOwnerFromTxn (trans, &owner);
+    if (have_owner)
+        owner_p = &owner;
+    else if (gnc_ui_payment_is_customer_payment(trans))
+        owner_p = plugin_business_priv->last_customer;
+    else
+        owner_p = plugin_business_priv->last_vendor;
+
     gnc_business_assign_payment (gnc_plugin_page_get_window(plugin_page),
-                                 trans,
-                                 is_customer
-                                 ? plugin_business_priv->last_customer
-                                 : plugin_business_priv->last_vendor);
+                                 trans, owner_p);
 }
 
 static const gchar *register_txn_actions[] =

commit 6fd35694e2b320acf6142f686d7b9bf74ae9fd22
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Fri Mar 25 17:39:20 2016 +0100

    Factor out a convenience function to retrieve a (business) owner starting from a transaction

diff --git a/src/engine/gncOwner.c b/src/engine/gncOwner.c
index 0c0af8b..c55dd5c 100644
--- a/src/engine/gncOwner.c
+++ b/src/engine/gncOwner.c
@@ -637,6 +637,31 @@ gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner)
     return (owner->owner.undefined != NULL);
 }
 
+gboolean gncOwnerGetOwnerFromTxn (Transaction *txn, GncOwner *owner)
+{
+    Split *apar_split = NULL;
+
+    if (!txn || !owner) return FALSE;
+
+    if (xaccTransGetTxnType (txn) == TXN_TYPE_NONE)
+        return FALSE;
+
+    apar_split = xaccTransGetFirstAPARAcctSplit (txn);
+    if (apar_split)
+    {
+        GNCLot *lot = xaccSplitGetLot (apar_split);
+        GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
+        if (invoice)
+            gncOwnerCopy (gncInvoiceGetOwner (invoice), owner);
+        else if (!gncOwnerGetOwnerFromLot (lot, owner))
+                return FALSE;
+
+        return TRUE; // Got owner from either invoice or lot
+    }
+
+    return FALSE;
+}
+
 gboolean gncOwnerIsValid (const GncOwner *owner)
 {
     if (!owner) return FALSE;
diff --git a/src/engine/gncOwner.h b/src/engine/gncOwner.h
index b805ac6..204bf34 100644
--- a/src/engine/gncOwner.h
+++ b/src/engine/gncOwner.h
@@ -195,6 +195,15 @@ gint gncOwnerLotsSortFunc (GNCLot *lotA, GNCLot *lotB);
  */
 gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner);
 
+/** Convenience function to get the owner from a transaction.
+ * Transactions don't really have an owner. What this function will
+ * do it figure out whether the transaction is part of a business
+ * transaction (either a posted invoice/bill/voucher/credit note or
+ * a payment transaction) and use the business object behind it
+ * to extract owner information.
+ */
+gboolean gncOwnerGetOwnerFromTxn (Transaction *txn, GncOwner *owner);
+
 gboolean gncOwnerGetOwnerFromTypeGuid (QofBook *book, GncOwner *owner, QofIdType type, GncGUID *guid);
 
 /** Get the kvp-frame from the underlying owner object */
diff --git a/src/gnome/dialog-print-check.c b/src/gnome/dialog-print-check.c
index 78fdf22..1ec4c3e 100644
--- a/src/gnome/dialog-print-check.c
+++ b/src/gnome/dialog-print-check.c
@@ -1706,28 +1706,20 @@ gnc_ui_print_check_dialog_create(GtkWidget *parent,
      * it would create build problems */
     if (g_list_length(pcd->splits) == 1)
     {
+        GncOwner txn_owner;
+
         trans = xaccSplitGetParent((Split *)(pcd->splits->data));
-        if (xaccTransGetTxnType (trans) == TXN_TYPE_PAYMENT)
+        if (gncOwnerGetOwnerFromTxn (trans, &txn_owner))
         {
-            Split *apar_split = xaccTransGetFirstAPARAcctSplit (trans);
-            if (apar_split)
-            {
-                GNCLot *lot = xaccSplitGetLot (apar_split);
-                GncOwner owner;
-                if (!gncOwnerGetOwnerFromLot (lot, &owner))
-                {
-                    GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
-                    if (invoice)
-                        gncOwnerCopy (gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice)), &owner);
-                }
-
-                /* Got a business owner, get the address */
-                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_name), gncOwnerGetName(&owner));
-                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_1), gncAddressGetAddr1 (gncOwnerGetAddr(&owner)));
-                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_2), gncAddressGetAddr2 (gncOwnerGetAddr(&owner)));
-                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_3), gncAddressGetAddr3 (gncOwnerGetAddr(&owner)));
-                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_4), gncAddressGetAddr4 (gncOwnerGetAddr(&owner)));
-            }
+            GncOwner owner;
+            gncOwnerCopy (gncOwnerGetEndOwner (&txn_owner), &owner);
+
+            /* Got a business owner, get the address */
+            gtk_entry_set_text(GTK_ENTRY(pcd->check_address_name), gncOwnerGetName(&owner));
+            gtk_entry_set_text(GTK_ENTRY(pcd->check_address_1), gncAddressGetAddr1 (gncOwnerGetAddr(&owner)));
+            gtk_entry_set_text(GTK_ENTRY(pcd->check_address_2), gncAddressGetAddr2 (gncOwnerGetAddr(&owner)));
+            gtk_entry_set_text(GTK_ENTRY(pcd->check_address_3), gncAddressGetAddr3 (gncOwnerGetAddr(&owner)));
+            gtk_entry_set_text(GTK_ENTRY(pcd->check_address_4), gncAddressGetAddr4 (gncOwnerGetAddr(&owner)));
         }
     }
 

commit 656a3a9b5703452f05e5d697cd9268def382563b
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Fri Mar 25 16:16:00 2016 +0100

    Provide option to print checks directly from the payment window

diff --git a/src/business/business-gnome/dialog-payment.c b/src/business/business-gnome/dialog-payment.c
index f2cfc8a..11b0c3e 100644
--- a/src/business/business-gnome/dialog-payment.c
+++ b/src/business/business-gnome/dialog-payment.c
@@ -51,6 +51,7 @@
 #include "business-gnome-utils.h"
 
 #include "dialog-transfer.h"
+#include "dialog-print-check.h"
 #include "gnome-search/gnc-general-search.h"
 
 #define DIALOG_PAYMENT_CUSTOMER_CM_CLASS "customer-payment-dialog"
@@ -72,6 +73,7 @@ struct _payment_window
     GtkWidget   * acct_tree;
     GtkWidget   * docs_list_tree_view;
     GtkWidget   * commodity_label;
+    GtkWidget   * print_check;
 
     gint          component_id;
     QofBook     * book;
@@ -84,6 +86,7 @@ struct _payment_window
     GList       * acct_commodities;
 
     Transaction * pre_existing_txn;
+    gboolean      print_check_state;
 };
 
 void gnc_ui_payment_window_set_num (PaymentWindow *pw, const char* num)
@@ -236,6 +239,16 @@ gnc_payment_window_check_payment (PaymentWindow *pw)
 update_cleanup:
     gtk_widget_set_sensitive (pw->acct_tree, enable_xfer_acct);
 
+    /* Disable "Print Check" widget if amount is zero but save current
+       state to restore when the widget is re-enabled */
+    if (gtk_widget_is_sensitive (pw->print_check))
+        pw->print_check_state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(pw->print_check));
+    if (!enable_xfer_acct)
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(pw->print_check), FALSE);
+    gtk_widget_set_sensitive (pw->print_check, enable_xfer_acct);
+    if (gtk_widget_is_sensitive (pw->print_check))
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(pw->print_check), pw->print_check_state);
+
     /* Check if there are issues preventing a successful payment */
     gtk_widget_set_tooltip_text (pw->payment_warning, conflict_msg);
     if (conflict_msg)
@@ -736,15 +749,24 @@ gnc_payment_ok_cb (GtkWidget *widget, gpointer data)
         else
             auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_BILL, GNC_PREF_AUTO_PAY);
 
-        gncOwnerApplyPayment (&pw->owner, pw->pre_existing_txn, selected_lots,
-                              pw->post_acct, pw->xfer_acct, pw->amount_tot,
-                              exch, date, memo, num, auto_pay);
+        gncOwnerApplyPayment (&pw->owner, &(pw->pre_existing_txn), selected_lots,
+                              pw->post_acct, pw->xfer_acct, pw->amount_tot, exch,
+                              date, memo, num, auto_pay);
     }
     gnc_resume_gui_refresh ();
 
     /* Save the transfer account, xfer_acct */
     gnc_payment_dialog_remember_account(pw, pw->xfer_acct);
 
+    if (gtk_widget_is_sensitive (pw->print_check) &&
+        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(pw->print_check)))
+    {
+        Split *split = xaccTransFindSplitByAccount (pw->pre_existing_txn, pw->xfer_acct);
+        GList *splits = NULL;
+        splits = g_list_append(splits, split);
+        gnc_ui_print_check_dialog_create(NULL, splits);
+    }
+
     gnc_ui_payment_window_destroy (pw);
 }
 
@@ -975,6 +997,7 @@ new_payment_window (GncOwner *owner, QofBook *book, GncInvoice *invoice)
     box = GTK_WIDGET (gtk_builder_get_object (builder, "date_box"));
     pw->date_edit = gnc_date_edit_new (time(NULL), FALSE, FALSE);
     gtk_box_pack_start (GTK_BOX (box), pw->date_edit, TRUE, TRUE, 0);
+    pw->print_check = GTK_WIDGET (gtk_builder_get_object (builder, "print_check"));
 
     pw->docs_list_tree_view = GTK_WIDGET (gtk_builder_get_object (builder, "docs_list_tree_view"));
     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(pw->docs_list_tree_view));
diff --git a/src/business/business-gnome/gtkbuilder/dialog-payment.glade b/src/business/business-gnome/gtkbuilder/dialog-payment.glade
index 4c61b36..83ae08c 100644
--- a/src/business/business-gnome/gtkbuilder/dialog-payment.glade
+++ b/src/business/business-gnome/gtkbuilder/dialog-payment.glade
@@ -262,7 +262,7 @@
                           <object class="GtkTable" id="table2">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="n_rows">8</property>
+                            <property name="n_rows">9</property>
                             <property name="n_columns">2</property>
                             <property name="column_spacing">3</property>
                             <property name="row_spacing">3</property>
@@ -549,6 +549,24 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic
                                 <property name="bottom_attach">3</property>
                               </packing>
                             </child>
+                            <child>
+                              <placeholder/>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="print_check">
+                                <property name="label" translatable="yes">Print Check</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">8</property>
+                                <property name="bottom_attach">9</property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
diff --git a/src/engine/gncInvoice.c b/src/engine/gncInvoice.c
index 50f3373..9b6c33f 100644
--- a/src/engine/gncInvoice.c
+++ b/src/engine/gncInvoice.c
@@ -1854,7 +1854,7 @@ gncInvoiceApplyPayment (const GncInvoice *invoice, Transaction *txn,
     g_return_if_fail (owner->owner.undefined);
 
     /* Create a lot for this payment */
-    payment_lot = gncOwnerCreatePaymentLot (owner, txn, invoice->posted_acc, xfer_acc,
+    payment_lot = gncOwnerCreatePaymentLot (owner, &txn, invoice->posted_acc, xfer_acc,
                                             amount, exch, date, memo, num);
 
     /* Select the invoice as only payment candidate */
diff --git a/src/engine/gncOwner.c b/src/engine/gncOwner.c
index b0e7eca..0c0af8b 100644
--- a/src/engine/gncOwner.c
+++ b/src/engine/gncOwner.c
@@ -705,7 +705,7 @@ gncOwnerLotsSortFunc (GNCLot *lotA, GNCLot *lotB)
 }
 
 GNCLot *
-gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn,
+gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction **preset_txn,
                           Account *posted_acc, Account *xfer_acc,
                           gnc_numeric amount, gnc_numeric exch, Timespec date,
                           const char *memo, const char *num)
@@ -715,6 +715,7 @@ gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn,
     const char *name;
     gnc_commodity *commodity;
     Split *xfer_split = NULL;
+    Transaction *txn = NULL;
     GNCLot *payment_lot;
 
     /* Verify our arguments */
@@ -727,6 +728,9 @@ gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn,
     commodity = gncOwnerGetCurrency (owner);
 //    reverse = use_reversed_payment_amounts(owner);
 
+    if (preset_txn && *preset_txn)
+        txn = *preset_txn;
+
     if (txn)
     {
         /* Pre-existing transaction was specified. We completely clear it,
@@ -845,6 +849,8 @@ gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn,
 
     /* Commit this new transaction */
     xaccTransCommitEdit (txn);
+    if (preset_txn)
+        *preset_txn = txn;
 
     return payment_lot;
 }
@@ -1357,7 +1363,7 @@ void gncOwnerAutoApplyPaymentsWithLots (const GncOwner *owner, GList *lots)
  * then all open lots for the owner are considered.
  */
 void
-gncOwnerApplyPayment (const GncOwner *owner, Transaction *txn, GList *lots,
+gncOwnerApplyPayment (const GncOwner *owner, Transaction **preset_txn, GList *lots,
                       Account *posted_acc, Account *xfer_acc,
                       gnc_numeric amount, gnc_numeric exch, Timespec date,
                       const char *memo, const char *num, gboolean auto_pay)
@@ -1372,7 +1378,7 @@ gncOwnerApplyPayment (const GncOwner *owner, Transaction *txn, GList *lots,
 
     /* If there's a real amount to transfer create a lot for this payment */
     if (!gnc_numeric_zero_p (amount))
-        payment_lot = gncOwnerCreatePaymentLot (owner, txn, posted_acc, xfer_acc,
+        payment_lot = gncOwnerCreatePaymentLot (owner, preset_txn, posted_acc, xfer_acc,
                                                 amount, exch, date, memo, num);
 
     if (lots)
diff --git a/src/engine/gncOwner.h b/src/engine/gncOwner.h
index 416a89a..b805ac6 100644
--- a/src/engine/gncOwner.h
+++ b/src/engine/gncOwner.h
@@ -208,7 +208,7 @@ KvpFrame* gncOwnerGetSlots(GncOwner* owner);
  * split in the transfer account).
  */
 GNCLot *
-gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn,
+gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction **preset_txn,
                           Account *posted_acc, Account *xfer_acc,
                           gnc_numeric amount, gnc_numeric exch, Timespec date,
                           const char *memo, const char *num);
@@ -261,7 +261,7 @@ void gncOwnerAutoApplyPaymentsWithLots (const GncOwner *owner, GList *lots);
  * details on what happens exactly.
  */
 void
-gncOwnerApplyPayment (const GncOwner *owner, Transaction *txn, GList *lots,
+gncOwnerApplyPayment (const GncOwner *owner, Transaction **preset_txn, GList *lots,
                       Account *posted_acc, Account *xfer_acc,
                       gnc_numeric amount, gnc_numeric exch, Timespec date,
                       const char *memo, const char *num, gboolean auto_pay);

commit d5d58dacbaeb080002e24e10cb2a9392f947f719
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Fri Mar 25 14:43:15 2016 +0100

    Check printing: extract address from invoice/bill for payment transactions
    
    If the transaction is marked as a (business feature) payment,
    extract the address of the bill/invoice associated with the
    payment, or the owner if there's no bill/invoice yet.

diff --git a/src/gnome/dialog-print-check.c b/src/gnome/dialog-print-check.c
index d47ce80..78fdf22 100644
--- a/src/gnome/dialog-print-check.c
+++ b/src/gnome/dialog-print-check.c
@@ -1705,18 +1705,36 @@ gnc_ui_print_check_dialog_create(GtkWidget *parent,
     /* Can't access business objects e.g. Customer,Vendor,Employee because
      * it would create build problems */
     if (g_list_length(pcd->splits) == 1)
-        trans = xaccSplitGetParent((Split *)(pcd->splits->data));
-    else
-        trans = NULL;
-    if ( trans )
     {
-        gtk_entry_set_text(GTK_ENTRY(pcd->check_address_name), xaccTransGetDescription(trans));
-    }
-    else
-    {
-        /* nothing to do - defaults to blank */
+        trans = xaccSplitGetParent((Split *)(pcd->splits->data));
+        if (xaccTransGetTxnType (trans) == TXN_TYPE_PAYMENT)
+        {
+            Split *apar_split = xaccTransGetFirstAPARAcctSplit (trans);
+            if (apar_split)
+            {
+                GNCLot *lot = xaccSplitGetLot (apar_split);
+                GncOwner owner;
+                if (!gncOwnerGetOwnerFromLot (lot, &owner))
+                {
+                    GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
+                    if (invoice)
+                        gncOwnerCopy (gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice)), &owner);
+                }
+
+                /* Got a business owner, get the address */
+                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_name), gncOwnerGetName(&owner));
+                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_1), gncAddressGetAddr1 (gncOwnerGetAddr(&owner)));
+                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_2), gncAddressGetAddr2 (gncOwnerGetAddr(&owner)));
+                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_3), gncAddressGetAddr3 (gncOwnerGetAddr(&owner)));
+                gtk_entry_set_text(GTK_ENTRY(pcd->check_address_4), gncAddressGetAddr4 (gncOwnerGetAddr(&owner)));
+            }
+        }
     }
 
+    /* Use transaction description as address name if no better address has been found */
+    if ( trans && (0 == gtk_entry_get_text_length (GTK_ENTRY(pcd->check_address_name))) )
+        gtk_entry_set_text(GTK_ENTRY(pcd->check_address_name), xaccTransGetDescription(trans));
+
     gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder, "lower_left")));
 
     gnc_ui_print_restore_dialog(pcd);

commit 531335a8f97ef2bd5e408cde6af7e399c75845ac
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Fri Mar 25 12:10:10 2016 +0100

    Move some utility functions from gui code to engine
    
    And reduce some of the clutter in these functions and their callers.

diff --git a/src/business/business-gnome/dialog-payment.c b/src/business/business-gnome/dialog-payment.c
index 127dad4..f2cfc8a 100644
--- a/src/business/business-gnome/dialog-payment.c
+++ b/src/business/business-gnome/dialog-payment.c
@@ -821,15 +821,6 @@ gnc_payment_leave_amount_cb (GtkWidget *widget, GdkEventFocus *event,
     gnc_payment_window_check_payment (pw);
 }
 
-static gboolean AccountTypeOkForPayments (GNCAccountType type)
-{
-    if (xaccAccountIsAssetLiabType(type) ||
-        xaccAccountIsEquityType(type))
-        return TRUE;
-    else
-        return FALSE;
-}
-
 /* Select the list of accounts to show in the tree */
 static void
 gnc_payment_set_account_types (GncTreeViewAccount *tree)
@@ -840,7 +831,7 @@ gnc_payment_set_account_types (GncTreeViewAccount *tree)
     gnc_tree_view_account_get_view_info (tree, &avi);
 
     for (i = 0; i < NUM_ACCOUNT_TYPES; i++)
-        avi.include_type[i] = AccountTypeOkForPayments (i);
+        avi.include_type[i] = gncBusinessIsPaymentAcctType (i);
 
     gnc_tree_view_account_set_view_info (tree, &avi);
 }
@@ -1151,67 +1142,11 @@ gnc_ui_payment_new (GncOwner *owner, QofBook *book)
     return gnc_ui_payment_new_with_invoice (owner, book, NULL);
 }
 
-// ////////////////////////////////////////////////////////////
-static void increment_if_asset_account (gpointer data,
-                                        gpointer user_data)
-{
-    int *r = user_data;
-    const Split *split = data;
-    const Account *account = xaccSplitGetAccount(split);
-    if (AccountTypeOkForPayments(xaccAccountGetType (account)))
-        ++(*r);
-}
-static int countAssetAccounts(SplitList* slist)
-{
-    int result = 0;
-    g_list_foreach(slist, &increment_if_asset_account, &result);
-    return result;
-}
-
-static gint predicate_is_asset_account(gconstpointer a,
-                                       gconstpointer user_data)
-{
-    const Split *split = a;
-    const Account *account = xaccSplitGetAccount(split);
-    if (AccountTypeOkForPayments(xaccAccountGetType(account)))
-        return 0;
-    else
-        return -1;
-}
-static gint predicate_is_apar_account(gconstpointer a,
-                                      gconstpointer user_data)
-{
-    const Split *split = a;
-    const Account *account = xaccSplitGetAccount(split);
-    if (xaccAccountIsAPARType(xaccAccountGetType(account)))
-        return 0;
-    else
-        return -1;
-}
-static Split *getFirstAssetAccountSplit(SplitList* slist)
-{
-    GList *r = g_list_find_custom(slist, NULL, &predicate_is_asset_account);
-    if (r)
-        return r->data;
-    else
-        return NULL;
-}
-static Split *getFirstAPARAccountSplit(SplitList* slist)
-{
-    GList *r = g_list_find_custom(slist, NULL, &predicate_is_apar_account);
-    if (r)
-        return r->data;
-    else
-        return NULL;
-}
-
 // ///////////////
 
 gboolean gnc_ui_payment_is_customer_payment(const Transaction *txn)
 {
-    SplitList *slist;
     gboolean result = TRUE;
-
     Split *assetaccount_split;
     gnc_numeric amount;
 
@@ -1220,17 +1155,17 @@ gboolean gnc_ui_payment_is_customer_payment(const Transaction *txn)
 
     // We require the txn to have one split in an A/R or A/P account.
 
-    slist = xaccTransGetSplitList(txn);
-    if (!slist)
+    if (!xaccTransGetSplitList(txn))
         return result;
-    if (countAssetAccounts(slist) == 0)
+    assetaccount_split = xaccTransGetFirstPaymentAcctSplit(txn);
+    if (!assetaccount_split)
     {
         g_message("No asset splits in txn \"%s\"; cannot use this for assigning a payment.",
                   xaccTransGetDescription(txn));
         return result;
     }
 
-    assetaccount_split = getFirstAssetAccountSplit(slist);
+    assetaccount_split = xaccTransGetFirstPaymentAcctSplit(txn);
     amount = xaccSplitGetValue(assetaccount_split);
     result = gnc_numeric_positive_p(amount); // positive amounts == customer
     //g_message("Amount=%s", gnc_numeric_to_string(amount));
@@ -1241,8 +1176,6 @@ gboolean gnc_ui_payment_is_customer_payment(const Transaction *txn)
 
 PaymentWindow * gnc_ui_payment_new_with_txn (GncOwner *owner, Transaction *txn)
 {
-    SplitList *slist;
-
     Split *assetaccount_split;
     Split *postaccount_split;
     gnc_numeric amount;
@@ -1253,23 +1186,22 @@ PaymentWindow * gnc_ui_payment_new_with_txn (GncOwner *owner, Transaction *txn)
 
     // We require the txn to have one split in an Asset account.
 
-    slist = xaccTransGetSplitList(txn);
-    if (!slist)
+    if (!xaccTransGetSplitList(txn))
         return NULL;
-    if (countAssetAccounts(slist) == 0)
+    assetaccount_split = xaccTransGetFirstPaymentAcctSplit(txn);
+    if (!assetaccount_split)
     {
         g_message("No asset splits in txn \"%s\"; cannot use this for assigning a payment.",
                   xaccTransGetDescription(txn));
         return NULL;
     }
 
-    assetaccount_split = getFirstAssetAccountSplit(slist);
-    postaccount_split = getFirstAPARAccountSplit(slist); // watch out: Might be NULL
+    postaccount_split = xaccTransGetFirstAPARAcctSplit(txn); // watch out: Might be NULL
     amount = xaccSplitGetValue(assetaccount_split);
 
     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_assert(assetaccount_split); // we can rely on this because of the check above
     g_debug("Amount=%s", gnc_numeric_to_string(amount));
 
     // Fill in the values from the given txn
diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c
index 2425de5..0e2a4fc 100644
--- a/src/engine/Transaction.c
+++ b/src/engine/Transaction.c
@@ -60,6 +60,7 @@ struct timeval
 #include <gnc-gdate-utils.h>
 #include "SchedXaction.h"
 #include "qofbackend-p.h"
+#include "gncBusiness.h"
 
 /* Notes about xaccTransBeginEdit(), xaccTransCommitEdit(), and
  *  xaccTransRollback():
@@ -2141,6 +2142,28 @@ xaccTransGetSplitList (const Transaction *trans)
     return trans ? trans->splits : NULL;
 }
 
+Split *xaccTransGetFirstPaymentAcctSplit(const Transaction *trans)
+{
+    FOR_EACH_SPLIT (trans,
+                    const Account *account = xaccSplitGetAccount(s);
+                    if (gncBusinessIsPaymentAcctType(xaccAccountGetType(account)))
+                        return s;
+                   );
+
+    return NULL;
+}
+
+Split *xaccTransGetFirstAPARAcctSplit(const Transaction *trans)
+{
+    FOR_EACH_SPLIT (trans,
+                    const Account *account = xaccSplitGetAccount(s);
+                    if (xaccAccountIsAPARType(xaccAccountGetType(account)))
+                        return s;
+                   );
+
+    return NULL;
+}
+
 int
 xaccTransCountSplits (const Transaction *trans)
 {
diff --git a/src/engine/Transaction.h b/src/engine/Transaction.h
index 2d3ae9d..474c46f 100644
--- a/src/engine/Transaction.h
+++ b/src/engine/Transaction.h
@@ -370,6 +370,21 @@ int xaccTransGetSplitIndex(const Transaction *trans, const Split *split);
 SplitList *   xaccTransGetSplitList (const Transaction *trans);
 gboolean      xaccTransStillHasSplit(const Transaction *trans, const Split *s);
 
+/** The xaccTransGetFirstPaymentAcctSplit() method returns a pointer to the first
+    split in this transaction that belongs to an account which is considered a
+    valid account for business payments.
+    @param trans The transaction
+
+    If there is no such split in the transaction NULL will be returned. */
+Split *       xaccTransGetFirstPaymentAcctSplit (const Transaction *trans);
+
+/** The xaccTransGetFirstPaymentAcctSplit() method returns a pointer to the first
+    split in this transaction that belongs to an AR or AP account.
+    @param trans The transaction
+
+    If there is no such split in the transaction NULL will be returned. */
+Split *       xaccTransGetFirstAPARAcctSplit (const Transaction *trans);
+
 /** Set the transaction to be ReadOnly by setting a non-NULL value as "reason".
  *
  * FIXME: If "reason" is NULL, this function does nothing, instead of removing the
diff --git a/src/engine/gncBusiness.c b/src/engine/gncBusiness.c
index 4653b79..eb8d62d 100644
--- a/src/engine/gncBusiness.c
+++ b/src/engine/gncBusiness.c
@@ -88,3 +88,12 @@ GList * gncBusinessGetOwnerList (QofBook *book, const char *type_name,
 
     return data.result;
 }
+
+gboolean gncBusinessIsPaymentAcctType (GNCAccountType type)
+{
+    if (xaccAccountIsAssetLiabType(type) ||
+        xaccAccountIsEquityType(type))
+        return TRUE;
+    else
+        return FALSE;
+}
diff --git a/src/engine/gncBusiness.h b/src/engine/gncBusiness.h
index b9a960f..1d4c1fa 100644
--- a/src/engine/gncBusiness.h
+++ b/src/engine/gncBusiness.h
@@ -36,6 +36,7 @@
 
 #include <glib.h>
 #include "qof.h"
+#include "Account.h"
 
 /* @deprecated backwards-compat definitions */
 #define GNC_BILLTERM_MODULE_NAME GNC_ID_BILLTERM
@@ -80,5 +81,10 @@ typedef GList OwnerList;
 OwnerList * gncBusinessGetOwnerList (QofBook *book, QofIdTypeConst type_name,
                                      gboolean all_including_inactive);
 
+/** Returns whether the given account type is a valid type to use in
+ * business payments. Currently payments are allowed to/from assets,
+ * liabilities and equity accounts. */
+gboolean gncBusinessIsPaymentAcctType (GNCAccountType type);
+
 
 #endif /* GNC_BUSINESS_H_ */



Summary of changes:
 src/business/business-gnome/dialog-payment.c       | 138 ++++++++-------------
 src/business/business-gnome/gnc-plugin-business.c  |  18 ++-
 .../business-gnome/gtkbuilder/dialog-payment.glade |  20 ++-
 src/engine/Transaction.c                           |  23 ++++
 src/engine/Transaction.h                           |  15 +++
 src/engine/gncBusiness.c                           |   9 ++
 src/engine/gncBusiness.h                           |   6 +
 src/engine/gncInvoice.c                            |   2 +-
 src/engine/gncOwner.c                              |  37 +++++-
 src/engine/gncOwner.h                              |  13 +-
 src/gnome/dialog-print-check.c                     |  28 +++--
 11 files changed, 203 insertions(+), 106 deletions(-)



More information about the gnucash-changes mailing list