gnucash maint: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Sun Jan 29 17:16:32 EST 2023


Updated	 via  https://github.com/Gnucash/gnucash/commit/5bbfb8ef (commit)
	 via  https://github.com/Gnucash/gnucash/commit/34ed91ea (commit)
	 via  https://github.com/Gnucash/gnucash/commit/894f8241 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2d3d0506 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8e6fb15d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/dd50c7af (commit)
	from  https://github.com/Gnucash/gnucash/commit/34be3c8b (commit)



commit 5bbfb8efd49f171b0674e04046cd8689155452f5
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sun Jan 29 23:11:49 2023 +0100

    Add proper indent to scheme changes from previous commit
    
    Committed seperately to make it easier to look at the actual changes.
    This commit only adds a 2 space indent to one function body.

diff --git a/gnucash/report/report-utilities.scm b/gnucash/report/report-utilities.scm
index eaf42e5ee..9974e2d6d 100644
--- a/gnucash/report/report-utilities.scm
+++ b/gnucash/report/report-utilities.scm
@@ -995,49 +995,49 @@ query instead.")
 ;;                 amount does not match the transaction amount
 ;; overpayment: a number indicating overpayment amount
 (define (gnc:payment-txn->payment-info txn)
-(let* ((apar-split (xaccTransGetFirstAPARAcctSplit txn #t))
-       (apar-acct (xaccSplitGetAccount apar-split)))
-  (let lp ((splits (xaccTransGetSplitList txn))
-           (invoices '())
-           (overpayment 0)
-           (opposing-splits '()))
-    (match splits
-      (() (vector invoices opposing-splits overpayment))
-      (((? not-APAR? split) . rest)
-       (gnc:msg "next " (gnc:strify split) " overpayment " (+ overpayment (xaccSplitConvertAmount split apar-acct)))
-       (lp rest invoices (+ overpayment (xaccSplitConvertAmount split apar-acct))
-           opposing-splits))
-      ((split . rest)
-       (let* ((lot (xaccSplitGetLot split))
-              (lot-all-splits (gnc-lot-get-split-list lot)))
-         (define split=? (cut equal? <> split))
-         (match (gncInvoiceGetInvoiceFromLot lot)
-           (() (let lp1 ((lot-splits lot-all-splits)
-                         (overpayment overpayment)
-                         (opposing-splits opposing-splits))
-                 (match lot-splits
-                   (() (lp rest invoices overpayment opposing-splits))
-                   (((? split=?) . tail) (lp1 tail overpayment opposing-splits))
-                   ((s . tail)
-                    (let* ((lot-bal (gnc-lot-get-balance lot))
-                           (lot-bal (if (sign-equal? lot-bal (xaccSplitConvertAmount s apar-acct))
-                                        0 lot-bal))
-                           (derived? (not (zero? lot-bal)))
-                           (partial-amount
-                            (fold
-                             (lambda (a b)
-                               (if (equal? s a) b (+ b (xaccSplitConvertAmount a apar-acct))))
-                             (- lot-bal) lot-all-splits)))
-                      (gnc:msg "next " (gnc:strify s) " overpayment " (+ overpayment partial-amount))
-                      (lp1 tail (+ overpayment partial-amount)
-                           (cons (list s partial-amount derived?)
-                                 opposing-splits)))))))
-           (inv
-            (gnc:msg "next " (gnc:strify split) " overpayment " (+ overpayment (xaccSplitConvertAmount split apar-acct)))
-            (lp rest
-                (cons (cons inv split) invoices)
-                (+ overpayment (xaccSplitConvertAmount split apar-acct))
-                opposing-splits)))))))))
+  (let* ((apar-split (xaccTransGetFirstAPARAcctSplit txn #t))
+        (apar-acct (xaccSplitGetAccount apar-split)))
+    (let lp ((splits (xaccTransGetSplitList txn))
+            (invoices '())
+            (overpayment 0)
+            (opposing-splits '()))
+      (match splits
+        (() (vector invoices opposing-splits overpayment))
+        (((? not-APAR? split) . rest)
+        (gnc:msg "next " (gnc:strify split) " overpayment " (+ overpayment (xaccSplitConvertAmount split apar-acct)))
+        (lp rest invoices (+ overpayment (xaccSplitConvertAmount split apar-acct))
+            opposing-splits))
+        ((split . rest)
+        (let* ((lot (xaccSplitGetLot split))
+                (lot-all-splits (gnc-lot-get-split-list lot)))
+          (define split=? (cut equal? <> split))
+          (match (gncInvoiceGetInvoiceFromLot lot)
+            (() (let lp1 ((lot-splits lot-all-splits)
+                          (overpayment overpayment)
+                          (opposing-splits opposing-splits))
+                  (match lot-splits
+                    (() (lp rest invoices overpayment opposing-splits))
+                    (((? split=?) . tail) (lp1 tail overpayment opposing-splits))
+                    ((s . tail)
+                      (let* ((lot-bal (gnc-lot-get-balance lot))
+                            (lot-bal (if (sign-equal? lot-bal (xaccSplitConvertAmount s apar-acct))
+                                          0 lot-bal))
+                            (derived? (not (zero? lot-bal)))
+                            (partial-amount
+                              (fold
+                              (lambda (a b)
+                                (if (equal? s a) b (+ b (xaccSplitConvertAmount a apar-acct))))
+                              (- lot-bal) lot-all-splits)))
+                        (gnc:msg "next " (gnc:strify s) " overpayment " (+ overpayment partial-amount))
+                        (lp1 tail (+ overpayment partial-amount)
+                            (cons (list s partial-amount derived?)
+                                  opposing-splits)))))))
+            (inv
+              (gnc:msg "next " (gnc:strify split) " overpayment " (+ overpayment (xaccSplitConvertAmount split apar-acct)))
+              (lp rest
+                  (cons (cons inv split) invoices)
+                  (+ overpayment (xaccSplitConvertAmount split apar-acct))
+                  opposing-splits)))))))))
 
 ;; create a stepped list, then add a date in the infinite future for
 ;; the "current" bucket

commit 34ed91eac969a3fb5cff8802a38293abeedc6ba6
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sun Jan 29 22:50:44 2023 +0100

    Bug 798734 - Aging Reports don't handle mixed currency payments and invoices without Trading Accounts
    
    Revisit the fix. It still made assumptions about the way
    payment transactions were created. It can now handle
    payment transaction either in the payment account
    currency or in the post account currency.

diff --git a/gnucash/report/report-utilities.scm b/gnucash/report/report-utilities.scm
index 79d3131f8..eaf42e5ee 100644
--- a/gnucash/report/report-utilities.scm
+++ b/gnucash/report/report-utilities.scm
@@ -987,7 +987,7 @@ query instead.")
 (define (not-APAR? s)
   (not (xaccAccountIsAPARType (xaccAccountGetType (xaccSplitGetAccount s)))))
 ;; analyse a payment transaction and return a 3-element vector:
-;; (vector invoices opposing-splits overpayment)
+;; (vector invoices overpayment opposing-splits)
 ;;
 ;; invoices: a list of (cons invoice inv-APAR-split)
 ;; opposing-splits: a list of (list pmt-APAR-split partial-amount derived?)
@@ -995,6 +995,8 @@ query instead.")
 ;;                 amount does not match the transaction amount
 ;; overpayment: a number indicating overpayment amount
 (define (gnc:payment-txn->payment-info txn)
+(let* ((apar-split (xaccTransGetFirstAPARAcctSplit txn #t))
+       (apar-acct (xaccSplitGetAccount apar-split)))
   (let lp ((splits (xaccTransGetSplitList txn))
            (invoices '())
            (overpayment 0)
@@ -1002,7 +1004,8 @@ query instead.")
     (match splits
       (() (vector invoices opposing-splits overpayment))
       (((? not-APAR? split) . rest)
-       (lp rest invoices (+ overpayment (xaccSplitGetValue split))
+       (gnc:msg "next " (gnc:strify split) " overpayment " (+ overpayment (xaccSplitConvertAmount split apar-acct)))
+       (lp rest invoices (+ overpayment (xaccSplitConvertAmount split apar-acct))
            opposing-splits))
       ((split . rest)
        (let* ((lot (xaccSplitGetLot split))
@@ -1017,22 +1020,24 @@ query instead.")
                    (((? split=?) . tail) (lp1 tail overpayment opposing-splits))
                    ((s . tail)
                     (let* ((lot-bal (gnc-lot-get-balance lot))
-                           (lot-bal (if (sign-equal? lot-bal (xaccSplitGetValue s))
+                           (lot-bal (if (sign-equal? lot-bal (xaccSplitConvertAmount s apar-acct))
                                         0 lot-bal))
                            (derived? (not (zero? lot-bal)))
                            (partial-amount
                             (fold
                              (lambda (a b)
-                               (if (equal? s a) b (+ b (xaccSplitGetValue a))))
+                               (if (equal? s a) b (+ b (xaccSplitConvertAmount a apar-acct))))
                              (- lot-bal) lot-all-splits)))
+                      (gnc:msg "next " (gnc:strify s) " overpayment " (+ overpayment partial-amount))
                       (lp1 tail (+ overpayment partial-amount)
                            (cons (list s partial-amount derived?)
                                  opposing-splits)))))))
            (inv
+            (gnc:msg "next " (gnc:strify split) " overpayment " (+ overpayment (xaccSplitConvertAmount split apar-acct)))
             (lp rest
                 (cons (cons inv split) invoices)
-                (+ overpayment (xaccSplitGetValue split))
-                opposing-splits))))))))
+                (+ overpayment (xaccSplitConvertAmount split apar-acct))
+                opposing-splits)))))))))
 
 ;; create a stepped list, then add a date in the infinite future for
 ;; the "current" bucket
@@ -1046,7 +1051,7 @@ query instead.")
 (define-public (gnc:owner-splits->aging-list splits num-buckets
                                              to-date date-type receivable?)
   (gnc:msg "processing " (qof-print-date to-date) " date-type " date-type
-           "receivable? " receivable?)
+           " receivable? " receivable?)
   (let ((bucket-dates (make-extended-interval-list to-date (- num-buckets 3)))
         (buckets (make-vector num-buckets 0)))
     (define (addbucket! idx amt)
@@ -1064,10 +1069,11 @@ query instead.")
                          (xaccSplitGetParent (car splits))))
                (lot (gncInvoiceGetPostedLot invoice))
                (lot-splits (gnc-lot-get-split-list lot))
+               (apar-acct (gncInvoiceGetPostedAcc invoice))
                (bal (fold
                      (lambda (a b)
                        (if (<= (xaccTransGetDate (xaccSplitGetParent a)) to-date)
-                           (+ (xaccSplitGetValue a) b)
+                           (+ (xaccSplitConvertAmount a apar-acct) b)
                            b))
                      0 lot-splits))
                (bal (if receivable? bal (- bal)))

commit 894f8241e127ce180eb74ee280a49c4a95ba88cf
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sun Jan 29 22:48:50 2023 +0100

    Revisit invoice payment in multi-currency context
    
    - Show proper amount in dialog when applying or editing an existing transaction as payment
    - Be more careful not to waste the existing payment split
    - If the user changed the payment amount while starting from an existing transaction
      unreconcile the changed payment split
    - Avoid needlessly changing transaction currency (only do so if the user chose
      a new transfer account and the old currency is neither the new transfer account's
      currency nor the post account's currency)

diff --git a/gnucash/gnome/dialog-payment.c b/gnucash/gnome/dialog-payment.c
index 75712bc58..fa9a403ac 100644
--- a/gnucash/gnome/dialog-payment.c
+++ b/gnucash/gnome/dialog-payment.c
@@ -1825,7 +1825,8 @@ PaymentWindow * gnc_ui_payment_new_with_txn (GtkWindow* parent, GncOwner *owner,
         GDate txn_date = xaccTransGetDatePostedGDate (txn);
         gnc_ui_payment_window_set_date(pw, &txn_date);
     }
-    gnc_ui_payment_window_set_amount(pw, xaccSplitGetValue(payment_split));
+
+    gnc_ui_payment_window_set_amount(pw, xaccSplitConvertAmount (payment_split, post_acct));
     if (payment_split)
         gnc_ui_payment_window_set_xferaccount(pw, xaccSplitGetAccount(payment_split));
     return pw;
diff --git a/libgnucash/engine/gncOwner.c b/libgnucash/engine/gncOwner.c
index c3c8b7315..5fcc0b24f 100644
--- a/libgnucash/engine/gncOwner.c
+++ b/libgnucash/engine/gncOwner.c
@@ -756,10 +756,12 @@ gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn,
     QofBook *book;
     Split *split;
     const char *name;
-    gnc_commodity *commodity;
+    gnc_commodity *post_comm, *xfer_comm;
     Split *xfer_split = NULL;
     Transaction *txn = NULL;
     GNCLot *payment_lot;
+    gnc_numeric xfer_amount = gnc_numeric_zero();
+    gnc_numeric txn_value = gnc_numeric_zero();
 
     /* Verify our arguments */
     if (!owner || !posted_acc || !xfer_acc) return NULL;
@@ -768,7 +770,9 @@ gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn,
     /* Compute the ancillary data */
     book = gnc_account_get_book (posted_acc);
     name = gncOwnerGetName (gncOwnerGetEndOwner ((GncOwner*)owner));
-    commodity = gncOwnerGetCurrency (owner);
+    post_comm = xaccAccountGetCommodity (posted_acc);
+    xfer_comm = xaccAccountGetCommodity (xfer_acc);
+
 //    reverse = use_reversed_payment_amounts(owner);
 
     if (preset_txn && *preset_txn)
@@ -776,110 +780,90 @@ gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn,
 
     if (txn)
     {
-        xaccTransSetDescription (txn, name ? name : "");
+        int i = 0;
 
         /* Pre-existing transaction was specified. We completely clear it,
-         * except for the split in the transfer account, unless the
-         * transaction can't be reused (wrong currency, wrong transfer account).
-         * In that case, the transaction is simply removed and an new
-         * one created. */
-
+         * except for a pre-existing transfer split. We're very conservative
+         * in preserving that one as it may have been reconciled already. */
         xfer_split = xaccTransFindSplitByAccount(txn, xfer_acc);
-
-        if (xaccTransGetCurrency(txn) != gncOwnerGetCurrency (owner))
-        {
-            PINFO("Uh oh, mismatching currency/commodity between selected transaction and owner. We fall back to manual creation of a new transaction.");
-            xfer_split = NULL;
-        }
-
-        if (!xfer_split)
-        {
-            PINFO("Huh? Asset account not found anymore. Fully deleting old txn and now creating a new one.");
-
-            xaccTransBeginEdit (txn);
-            xaccTransDestroy (txn);
-            xaccTransCommitEdit (txn);
-
-            txn = NULL;
-        }
-        else
+        xaccTransBeginEdit (txn);
+        while (i < xaccTransCountSplits(txn))
         {
-            int i = 0;
-            xaccTransBeginEdit (txn);
-            while (i < xaccTransCountSplits(txn))
-            {
-                Split *split = xaccTransGetSplit (txn, i);
-                if (split == xfer_split)
-                {
-                    gnc_set_num_action (NULL, split, num, _("Payment"));
-                    ++i;
-                }
-                else
-                {
-                    xaccSplitDestroy(split);
-                }
-            }
-            /* Note: don't commit transaction now - that would insert an imbalance split.*/
+            Split *split = xaccTransGetSplit (txn, i);
+            if (split == xfer_split)
+                ++i;
+            else
+                xaccSplitDestroy(split);
         }
+        /* Note: don't commit transaction now - that would insert an imbalance split.*/
     }
-
-    /* Create the transaction if we don't have one yet */
-    if (!txn)
+    else
     {
         txn = xaccMallocTransaction (book);
         xaccTransBeginEdit (txn);
     }
 
+    /* Complete transaction setup */
+    xaccTransSetDescription (txn, name ? name : "");
+    if (!gnc_commodity_equal(xaccTransGetCurrency (txn), post_comm) &&
+        !gnc_commodity_equal (xaccTransGetCurrency (txn), xfer_comm))
+        xaccTransSetCurrency (txn, xfer_comm);
+
+    /* With all commodities involved known, define split amounts and txn value.
+     * - post amount (amount passed in as parameter) is always in post_acct commodity,
+     * - xfer amount requires conversion if the xfer account has a different
+     *   commodity than the post account.
+     * - txn value requires conversion if the post account has a different
+     *   commodity than the transaction */
+    if (gnc_commodity_equal(post_comm, xfer_comm))
+        xfer_amount = amount;
+    else
+        xfer_amount = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
+                                       GNC_HOW_RND_ROUND_HALF_UP);
+
+    if (gnc_commodity_equal(post_comm, xaccTransGetCurrency (txn)))
+        txn_value = amount;
+    else
+        txn_value = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
+                                      GNC_HOW_RND_ROUND_HALF_UP);
+
     /* Insert a split for the transfer account if we don't have one yet */
     if (!xfer_split)
     {
-
-        /* Set up the transaction */
-        xaccTransSetDescription (txn, name ? name : "");
-        /* set per book option */
-        xaccTransSetCurrency (txn, commodity);
-
-
         /* The split for the transfer account */
-        split = xaccMallocSplit (book);
-        xaccSplitSetMemo (split, memo);
+        xfer_split = xaccMallocSplit (book);
+        xaccSplitSetMemo (xfer_split, memo);
         /* set per book option */
-        gnc_set_num_action (NULL, split, num, _("Payment"));
+        gnc_set_num_action (NULL, xfer_split, num, _("Payment"));
         xaccAccountBeginEdit (xfer_acc);
-        xaccAccountInsertSplit (xfer_acc, split);
+        xaccAccountInsertSplit (xfer_acc, xfer_split);
         xaccAccountCommitEdit (xfer_acc);
-        xaccTransAppendSplit (txn, split);
+        xaccTransAppendSplit (txn, xfer_split);
 
-        if (gnc_commodity_equal(xaccAccountGetCommodity(xfer_acc), commodity))
-        {
-            xaccSplitSetBaseValue (split, amount, commodity);
-        }
-        else
-        {
-            /* This will be a multi-currency transaction. The amount passed to this
-             * function is in the owner commodity (also used by the post account).
-             * For the xfer split we also need to value the payment in the xfer account's
-             * commodity.
-             * exch is from post account to xfer account so that can be used directly
-             * to calculate the equivalent amount in the xfer account's commodity. */
-            gnc_numeric xfer_amount = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
-                                                 GNC_HOW_RND_ROUND_HALF_UP);
-
-            xaccSplitSetAmount(split, xfer_amount); /* Payment in xfer account currency */
-            xaccSplitSetValue(split, amount); /* Payment in transaction currency */
-        }
+        xaccSplitSetAmount(xfer_split, xfer_amount); /* Payment in xfer account currency */
+        xaccSplitSetValue(xfer_split, txn_value); /* Payment in transaction currency */
+    }
+    /* For a pre-existing xfer split, let's check if the amount and value
+     * have changed. If so, update them and unreconcile. */
+    else if (!gnc_numeric_equal (xaccSplitGetAmount (xfer_split), xfer_amount) ||
+             !gnc_numeric_equal (xaccSplitGetValue (xfer_split), txn_value))
+    {
+        xaccSplitSetAmount (xfer_split, xfer_amount);
+        xaccSplitSetValue (xfer_split, txn_value);
+        xaccSplitSetReconcile (xfer_split, NREC);
     }
 
     /* Add a split in the post account */
     split = xaccMallocSplit (book);
     xaccSplitSetMemo (split, memo);
     /* set per book option */
-    gnc_set_num_action (NULL, split, num, _("Payment"));
+    xaccSplitSetAction (split, _("Payment"));
     xaccAccountBeginEdit (posted_acc);
     xaccAccountInsertSplit (posted_acc, split);
     xaccAccountCommitEdit (posted_acc);
     xaccTransAppendSplit (txn, split);
-    xaccSplitSetBaseValue (split, gnc_numeric_neg (amount), commodity);
+    xaccSplitSetAmount (split, gnc_numeric_neg (amount));
+    xaccSplitSetValue (split, gnc_numeric_neg (txn_value));
 
     /* Create a new lot for the payment */
     payment_lot = gnc_lot_new (book);
@@ -887,7 +871,7 @@ gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn,
     gnc_lot_add_split (payment_lot, split);
 
     /* Mark the transaction as a payment */
-    gnc_set_num_action (txn, NULL, num, _("Payment"));
+    xaccTransSetNum (txn, num);
     xaccTransSetTxnType (txn, TXN_TYPE_PAYMENT);
 
     /* Set date for transaction */

commit 2d3d05068d5a0d8f1349324616e37dc6fbc7f551
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sun Jan 29 11:37:54 2023 +0100

    Edit/assign payment - be more prudent not to lose data
    
    We can't handle the case where a transaction has splits in more than one
    APAR account. Instead of only warning that some of them will be lost
    refuse to continue and leave it to the user to fix the transaction first.

diff --git a/gnucash/gnome/dialog-payment.c b/gnucash/gnome/dialog-payment.c
index 4718942f4..75712bc58 100644
--- a/gnucash/gnome/dialog-payment.c
+++ b/gnucash/gnome/dialog-payment.c
@@ -1694,10 +1694,11 @@ static Split *select_payment_split (GtkWindow *parent, Transaction *txn)
 
 static GList *select_txn_lots (GtkWindow *parent, Transaction *txn, Account **post_acct, gboolean *abort)
 {
-    gboolean has_no_lot_apar_splits = FALSE;
-    SplitList *post_splits = NULL, *no_lot_post_splits = NULL;
+    SplitList *apar_splits = NULL; /* all spits in txn that are APAR type */
+    SplitList *apar_splits_no_lot = NULL; /* all splits in txn that are APAR type, but not tied to a lot */
     SplitList *iter;
     GList *txn_lots = NULL;
+    GList *unique_apar_accts = NULL;
 
     /* There's no use in continuing if I can't set the post_acct or abort variables */
     if (!post_acct || !abort)
@@ -1706,11 +1707,20 @@ static GList *select_txn_lots (GtkWindow *parent, Transaction *txn, Account **po
     *abort = FALSE;
     *post_acct = NULL;
 
-    post_splits = xaccTransGetAPARAcctSplitList (txn, FALSE);
-    for (iter = post_splits; iter; iter = iter->next)
+    /* Start by filtering out all APAR splits that have lots. Those are the ones we can
+       display as invoices and pre-payments in the payment window. */
+    apar_splits = xaccTransGetAPARAcctSplitList (txn, FALSE);
+    for (iter = apar_splits; iter; iter = iter->next)
     {
         GNCLot *postlot = NULL;
         Split *post_split = iter->data;
+        Account *apar_acct = xaccSplitGetAccount (post_split);
+
+        /* Store found apar_acct in our list of unique_apar_accts
+         * for later processing */
+        if (!g_list_find (unique_apar_accts, apar_acct))
+            unique_apar_accts = g_list_prepend (unique_apar_accts, apar_acct);
+
         postlot = xaccSplitGetLot (post_split);
         if (postlot)
         {
@@ -1718,59 +1728,55 @@ static GList *select_txn_lots (GtkWindow *parent, Transaction *txn, Account **po
             lot_info->lot = postlot;
             lot_info->amount = xaccSplitGetValue (post_split);
             txn_lots = g_list_prepend (txn_lots, lot_info);
-            *post_acct = xaccSplitGetAccount (post_split);
+            *post_acct = apar_acct;
         }
         else
-        {
-            /* Make sure not to override post_acct if it was set above from a lot split */
-            if (!*post_acct)
-                *post_acct = xaccSplitGetAccount (post_split);
-            no_lot_post_splits = g_list_prepend (no_lot_post_splits, post_split);
-            has_no_lot_apar_splits = TRUE;
-        }
+            apar_splits_no_lot = g_list_prepend (apar_splits_no_lot, post_split);
     }
+    g_list_free (apar_splits);
 
-    g_list_free (post_splits);
+    /* If no post_acct was selected from the postlots, fall back to the first apar split's
+     * account if there is one. */
+    if (!*post_acct && apar_splits_no_lot)
+        *post_acct = xaccSplitGetAccount (apar_splits_no_lot->data);
+    g_list_free (apar_splits_no_lot);
 
-    /* If the txn has both APAR splits linked to a business lot and
-     * splits that are not, issue a warning some will be discarded.
+    /* Abort if the txn has splits in more than one APAR account
+     * GnuCash can only handle one post account per payment transaction.
      */
-    if (has_no_lot_apar_splits && gnc_list_length_cmp (txn_lots, 0))
+    if (g_list_length (unique_apar_accts) > 1)
     {
         GtkWidget *dialog;
         char *split_str = g_strdup ("");
-        for (iter = no_lot_post_splits; iter; iter = iter->next)
+
+        for (iter = unique_apar_accts; iter; iter = iter->next)
         {
-            Split *post_split = iter->data;
-            char *tmp_str = gen_split_desc (txn, post_split);
-            char *tmp_str2 = g_strconcat(split_str, "• ", tmp_str, "\n", NULL);
-            g_free (tmp_str);
+            Account *acct = iter->data;
+            char *acct_name = gnc_account_get_full_name (acct);
+            char *tmp_str = g_strconcat(split_str, "• ", acct_name, "\n", NULL);
+            g_free (acct_name);
             g_free (split_str);
-            split_str = tmp_str2;
+            split_str = tmp_str;
         }
 
         dialog = gtk_message_dialog_new (parent,
                                          GTK_DIALOG_DESTROY_WITH_PARENT,
-                                         GTK_MESSAGE_WARNING,
-                                         GTK_BUTTONS_CANCEL,
-                                         _("The transaction has at least one split in a business account that is not part of a business transaction.\n"
-                                         "If you continue these splits will be ignored:\n\n%s\n"
-                                         "Do you wish to continue and ignore these splits?"),
+                                         GTK_MESSAGE_INFO,
+                                         GTK_BUTTONS_CLOSE,
+                                         _("This transaction has splits in multiple business accounts:\n\n%s\n"
+                                         "GnuCash can only handle transactions that post to a single account.\n\n"
+                                         "Please correct this manually by editing the transaction directly and then try again."),
                                          split_str);
-        gtk_dialog_add_buttons (GTK_DIALOG(dialog),
-                                _("Continue"), GTK_BUTTONS_OK, NULL);
-        gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_BUTTONS_CANCEL);
-        if (gtk_dialog_run (GTK_DIALOG(dialog)) != GTK_BUTTONS_OK)
-        {
-            *abort = TRUE;
-            g_list_free_full (txn_lots, g_free);
-            txn_lots = NULL;
-        }
+        gtk_dialog_run (GTK_DIALOG(dialog));
         gtk_widget_destroy (dialog);
+        PINFO("Multiple asset accounts in splits of txn \"%s\"; cannot use this for assigning a payment.",
+              xaccTransGetDescription(txn));
         g_free (split_str);
-    }
 
-    g_list_free (no_lot_post_splits);
+        *abort = TRUE;
+        g_list_free_full (txn_lots, g_free);
+        txn_lots = NULL;
+    }
 
     return txn_lots;
 }

commit 8e6fb15d44a497b11962772fb6ce3d064ca8a8b7
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sun Jan 29 11:32:58 2023 +0100

    Improve a few messages related to business payments

diff --git a/gnucash/gnome/dialog-payment.c b/gnucash/gnome/dialog-payment.c
index 54f382706..4718942f4 100644
--- a/gnucash/gnome/dialog-payment.c
+++ b/gnucash/gnome/dialog-payment.c
@@ -1573,18 +1573,29 @@ static char *gen_split_desc (Transaction *txn, Split *split)
     char *acct_name = gnc_account_get_full_name (xfer_acct);
     const char *action = gnc_get_action_num (txn, split);
     const char *memo = xaccSplitGetMemo (split);
+    char rec_state = xaccSplitGetReconcile (split);
     const char *print_amt = xaccPrintAmount(value, gnc_account_print_info (xfer_acct, TRUE));
     char *split_str = NULL;
+    char *rec_str = NULL;
+
+    if (rec_state == CREC)
+        rec_str = g_strdup_printf("[%s] ", _("Cleared"));
+    else if (rec_state == YREC)
+        rec_str = g_strdup_printf("[%s] ", _("Reconciled"));
+    else
+        rec_str = g_strdup("");
 
     if (action && *action && memo && *memo)
-        split_str = g_strdup_printf ("%s: %s (%s, %s)", acct_name, print_amt,
+        split_str = g_strdup_printf ("%s%s: %s (%s, %s)", rec_str, acct_name, print_amt,
                                         action, memo);
     else if((action && *action) || (memo && *memo))
-        split_str = g_strdup_printf ("%s: %s (%s)", acct_name, print_amt,
+        split_str = g_strdup_printf ("%s%s: %s (%s)", rec_str, acct_name, print_amt,
                                         action ? action : memo);
     else
-        split_str = g_strdup_printf ("%s: %s", acct_name, print_amt);
+        split_str = g_strdup_printf ("%s%s: %s", rec_str, acct_name, print_amt);
+
     g_free (acct_name);
+    g_free (rec_str);
 
     return split_str;
 }
@@ -1621,8 +1632,8 @@ static Split *select_payment_split (GtkWindow *parent, Transaction *txn)
         GList *node;
         GtkWidget *first_rb = NULL;
         int answer = GTK_BUTTONS_OK;
-        const char *message = _("While this transaction has multiple splits that can be considered\nas 'the payment split', gnucash only knows how to handle one.\n"
-                                "Please select one, the others will be ignored.\n\n");
+        const char *message = _("While this transaction has multiple splits that can be considered\nas 'the payment split', GnuCash only knows how to handle one.\n"
+                                "Please select one, the others will be discarded.\n\n");
         GtkDialog *dialog = GTK_DIALOG(
                             gtk_dialog_new_with_buttons (_("Warning"),
                                                          parent,

commit dd50c7af13ed3954492e997884fa962b76df6328
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sun Jan 29 11:31:24 2023 +0100

    Multi-currency - show split amount rather than transaction value
    
    This issue was found while evaluating bug 798734, but not
    the immediate topic of that bug.

diff --git a/gnucash/gnome/dialog-payment.c b/gnucash/gnome/dialog-payment.c
index 3447debb1..54f382706 100644
--- a/gnucash/gnome/dialog-payment.c
+++ b/gnucash/gnome/dialog-payment.c
@@ -1568,7 +1568,7 @@ gboolean gnc_ui_payment_is_customer_payment(const Transaction *txn)
 // ///////////////
 static char *gen_split_desc (Transaction *txn, Split *split)
 {
-    gnc_numeric value = xaccSplitGetValue(split);
+    gnc_numeric value = xaccSplitGetAmount(split);
     Account *xfer_acct = xaccSplitGetAccount(split);
     char *acct_name = gnc_account_get_full_name (xfer_acct);
     const char *action = gnc_get_action_num (txn, split);



Summary of changes:
 gnucash/gnome/dialog-payment.c      | 108 ++++++++++++++++------------
 gnucash/report/report-utilities.scm |  88 ++++++++++++-----------
 libgnucash/engine/gncOwner.c        | 140 ++++++++++++++++--------------------
 3 files changed, 172 insertions(+), 164 deletions(-)



More information about the gnucash-changes mailing list