https://bugs.gnucash.org/attachment.cgi?id=373545 on bug 797595 will illustrate this issue. For the 26/08/2010 bill (€1,13) there are two payments. A €80 and a €20 payment. The two payments are actually one single payment transaction. It was created by first making a €100 payment to Asset1 and then altering that transaction afterwards to be €80 in Asset1 and €20 in asset2. This was done as that better reflected the real payment scenario: I had a couple of bills at once to pay, and part was paid in cash while part was wired via bank transfer. The gnucash UI doesn't have a way to enter that directly but the internal logic supports it perfectly. The issue is this is not obvious at all from the report. There's no way to discern this split payment from two individual payments that happened to be on the same date. I was thinking of ways to improve this and perhaps we can do so by representing this slightly differently: As it's the same payment, we could merge the cells vertically (remove the horizontal divider line) and only display the date, reference and type once. Description and amount are the only elements unique to each payment split. Note that this same payment is shown LHS as a single €100 amount. Perhaps we can do the same split there to make it easier to match the payment's representation LHS with RHS occurences ?
I think I can work better with illustrations as follows: 26/08/2010 Bill posting Expenses:Bills 1.13 EUR A/Payable -1.13 EUR (L1) 22/10/2011 Payment A/Payable +100.00 EUR (L1) Asset1 -80.00 EUR Asset2 -20.00 EUR I guess the L1 splits are linked in the same lot? Which asset is cash? Isn't the lot unfulfilled via above txns? I wouldn't like to merge RHS cells vertically; it would complicate the code much more. LHS currently shows 1 row per APAR transaction; RHS shows 1 row per split. For reasons described before to mta, I *don't* think it's wise to change LHS to 1 row per split.
> For reasons described before to mta, I *don't* think it's wise to > change LHS to 1 row per split. ... because LHS in my view should show individual payment activity... if I paid 10 bills with 1 payment, I do *not* want to see 10 LHS rows with 10 RHS rows. I designed this report so that 1 LHS payment -> 10 RHS bills. Although we could change it to 1 row/split for both LHS and RHS, personally I'd be unhappy with the output.
(In reply to Christopher Lam from comment #1) > I think I can work better with illustrations as follows: > > 26/08/2010 Bill posting > Expenses:Bills 1.13 EUR > A/Payable -1.13 EUR (L1) > > 22/10/2011 Payment > A/Payable +100.00 EUR (L1) > Asset1 -80.00 EUR > Asset2 -20.00 EUR > > I guess the L1 splits are linked in the same lot? Which asset is cash? Isn't > the lot unfulfilled via above txns? Actually I think the lot would be cleared as follows 26/08/2010 Bill posting Expenses:Bills 1.13 EUR A/Payable -1.13 EUR (L1) 22/10/2011 Payment A/Payable +1.13 EUR (L1) A/Payable +98.87 EUR Asset1 -80.00 EUR Asset2 -20.00 EUR
(In reply to Christopher Lam from comment #2) > > For reasons described before to mta, I *don't* think it's wise to > > change LHS to 1 row per split. > > ... because LHS in my view should show individual payment activity... if I > paid 10 bills with 1 payment, I do *not* want to see 10 LHS rows with 10 RHS > rows. I designed this report so that 1 LHS payment -> 10 RHS bills. Although > we could change it to 1 row/split for both LHS and RHS, personally I'd be > unhappy with the output. I agree LHS. I mostly added that because I thought you wanted LHS and RHS to show as much as possible the same data. But considering LHS on a transaction basis is much better. However my suggestion would not have created 10 LHS rows if you paid 10 bills in one transaction. It would still be one row: namely the non APAR split value. It would have become 2 rows if I manually manipulated the payment transaction to have two non-APAR splits: one for a cash payment and one for a bank transfer. Instead of splitting LHS in multiple rows you could also do what you do with the descriptions and concatenate the non-APAR split amounts rather than summing them. I'll attach screenshots and a test book to illustrate.
Created attachment 373550 [details] Testbook with a manipulated payment This testbook is meant to illustrate the case of a payment transaction that has multiple non-APAR splits. Currently this can only be achieved by manually post-processing a payment as the payment window has no way to generate this kind of payments. However the underlying engine logic does support it and this trick has been explained more than once to users on the mailing lists in the past. So this is a transaction we can encounter in real books.
Created attachment 373551 [details] New-owner report as it's currently generated for the sample book. This screenshot shows the report as it will be rendered for the sample book. Note LHS there's nothing suggesting the payment was 20 cash and 80 bank. The Description field on the other hand does suggest there was more than one split (as it is a multi-line concatenation of these split's memos).
Created attachment 373552 [details] The report with a tweak to the LHS representation of the payment transaction This version of the report still only has one row per transaction LHS. However as with the descriptions, the non-APAR payment amounts are now concatenated rather than totalled. The advantage of this representation is that the amounts reflected match what I paid and that it's easier to map this LHS representation to the RHS split representation of the same payment. Additionally this way LHS links can be made to map to the exact splits in the APAR account, rather than to an arbitrary one.
Lastly I take your point that RHS is split based, so I agree not to change that.
And while hitting the submit button, I realized it may be very tricky to deal with bug 797595 for the transaction illustrated in this bug (797596) if each non APAR split is represented separately. So I *think* RHS you want to represent a row for each *APAR* split, not for each non-APAR split. Going back to the earlier example: 26/08/2010 Bill posting Expenses:Bills 1.13 EUR A/Payable -1.13 EUR (L1) 22/10/2011 Payment A/Payable +1.13 EUR (L1) A/Payable +98.87 EUR Asset1 -80.00 EUR Asset2 -20.00 EUR The 20 and 80 are not representative in any way on how the payment is linked to the bill. The 1,13 and 98,87 are. So combinating this bug and bug 797595 I think the representation of the above should really be: LHS 29/08/10 Bill 1,13 22/10/11 Payment 1,13 of (80 + 20) 22/10/11 Payment (80 + 20) 29/08/10 Bill 1,13 of 1,13 Overpayment 98,87 Again, how exactly to represent (a) the sum of the two separate non-APAR splits and (b) the assigned part vs the total of the transaction RHS can be experimented with. Separate columns, or with newlines or in paranthesis,...
Created attachment 373555 [details] Updated testbook with several other transaction samples This updated book can be used for more than this particular enhancement request. I'm dropping it here for now to be able to reference it more easily. If it turns out some of the extra samples need a more detailed enhancement request of their own, I'll create those later on.
Created attachment 373558 [details] trial patch. slightly better payments decoding. still doesn't recognise Adfisc Bill 00007 correctly. not sure why. but it's a step (forward, backward or sideways, not sure) -- * INV finds CN * CN finds INV * Pre-payments are highlighted together with the payment. * UNPAID invoice highlighted together with invoice and invoice's partial payment.
my branch maint-797596 still has latest&greatest. The only remaining issue is the Adfisc report, still weird.
Created attachment 373562 [details] Same book, one additionally complicated payment The most recent version of this book adds another test scenario. The related transactions are dated 23/01/2020 through 25/01/2020. It's heavily manipulated artificial transaction just for illustration of how a lot link works. 23/01 has a posted bill, total amount €100 24/01 started off as a €120 payment that pays the €100 25/01 starts off as a €150 refund, offsetting the 24/01 (with a €130 overpayment) At this point the 24/01 payment will be split into 120 Checking 100 AP (offsetting the bill) 20 AP (used in the refund) This is now manipulated to become 20 Checking 100 AP (offsetting the bill) 80 AP (used in the refund) So the Checking part is greatly reduced and the split used to compensate the refund is adjusted to make the transaction balance. Note this is something gnucash wouldn't do. It would make reduce the AP offsetting the bill. So we're on theoretical territory now. This manipulation causes the lot connecting the 24/01 payment and the 25/01 refund to be totally off balance. It now has two Credit AP splits. So let's continue to manipulate, this time the 25/01 transaction. From 150 AP 150 Checking Let's turn this one around: 150 AP 150 Checking Looking at the lot will now show a net 70 overpayment. Which should be right. The total bill was 100, 20 was paid on 24/01, 80 was paid on 25/01 as can be seen in the checking account. This is what the book now holds as sample. Now this actually comes pretty close to the layout of a lot link transaction. If you manipulate the middle transaction just slightly more to become This is now manipulated to become 100 AP (offsetting the bill) 100 AP (used in the other payment) This has become a lot link transaction in that the transaction only has splits in the AP register and links two lots. The first lot contains a bill, the second doesn't.
Created attachment 373563 [details] Current representation of quasi lot link transaction The treatment for the transaction I have now added and a lot link transaction are very similar and the report almost does it right for the payment. I'll get into to the additional issue I see in a minute. First let's continue on the lot link vs payment link. Let's have a closer look at how the 24/01 payment is presented: * LHS it presents a €20 payment. This can be considered the sum of all APAR split amounts. * RHS we will present all the information as found in the lots it's linked with. In this particular case this involves two lots: 1. The bill lot, which is represented correctly 2. The lot connecting to the 150 payment. (There's also a prepayment, which I think is wrong, more on that later) Now imagine for the 24/01 payment the 20 part is removed and instead the 80 AP is increased to 100. That would give the payment the same anatomy as our odd lot link from my book: one leg in an invoice lot, one leg in a non-invoice lot * The lhs rule: sum of all APAR split amounts would now return 0. We don't display 0 balance elements LHS because that doesn't affect our total balance. * RHS whenever LHS leads to a lot in which there's also a LLT split, we treat similarly to what we do with ordinary payment transactions: a. if it's an invoice lot, show the invoice details b. if it's not an invoice lot, show a line for each other APAR split. That's what you currently do as far as I can see in the report result.
I should also point out there are a few sign reversal issues RHS. For example refunds have negative amounts but positive totals. That's confusing. In addition until refunds came up the sum of the partial amounts rhs always matched the bill or payment total for the associated LHS transaction. With the refunds this is not always true any more, which is also due to a sign reversal issue. For example the 13/01 refund has a 160 total, but if you sum the two partial amounts and the prepayment RHS, you'll get at 180. The amounts can be corrected by taking the lot's open balance sign into account. If the "pre-payment" in this case would have been presented as -10, the sum would be correct. However I feel the terms Pre-payment and Payment don't apply very well in all situations ?
Created attachment 373564 [details] ^ Thanks will review above. My main concern is how to convert LHS invoice to RHS payment-list. The algorithm in this revision is as follows, and is in the same order as the cond starting from #L573: (1) start from invoice->lot, process the gnc-lot-get-split-list in order: (2) if lot-split list from (1) whose parent is the invoice->posted-txn, then skip it else process as a payment (i.e. reduces the lot) split. (3) each lot-reducing split is analysed, finds its peer splits. when we run out of peer split, process the next lot-reducing split and go to (2). (4) if peer-split has same sign as lot-split, we don't want it. (5) analyse peer split, attempt to find a document's posting split. in modern books, this is a link txn. process it and loop to (3) with the next peer split. (6) if this lot-reducing split is a LINK transaction and (5) didn't find a document posting split, we process as a special case. loop to (3) with next peer split. (7) if this lot-reducing split's peer is still APAR then there's no further useful data to be obtained. loop to (3) with next peer split. (8) this lot-reducing split is not APAR. collate all non-APAR splits and render into a single RHS row, then loop to (3) with next peer split. =-=-=-=-=-=-=- Example: (1) Invoice $100, posted, creates posting txn, and a lot of $100 (2) This initial $100 lot opening split is skipped (3) A lot-reducing split of $20 is met, and analysed. (4) This $20 may be part of a complex transaction as follows, whereby $40 feeds another lot, and $60 is the bank transfer. We skip the $40 split, and will process the $60 split next. TXN-TYPE-PAYMENT (a) AR: -20 (belongs to this invoice's lot) AR: -40 (belongs to another invoice's lot) Bank1:+30 (I get paid) Bank2:+30 (I get paid into another bank) or TXN-TYPE-LINK (b) AR: -20 (belongs to this invoice's lot) AR: -40 (belongs to another invoice's lot) AR: +60 (belongs to another document's lot) (5) We have encountered a transaction type (b) as above. We start from the $60 split, and lot-split->posting-split manages to find the document (invoice/bill/CN)'s posting split. From this posting split, we derive the documents' details, and add to the resulting table. (6) [compatibility] This is TXN-TYPE-LINK but we couldn't find posting-split. Display the LINK transaction details instead. (7) skip as described. (8) We have encountered a transaction type (a). Start from a $30 split, collate all non-APAR splits ($30+$30) and present into a single RHS row. =-=-=-=-=-=-=-=-=- Conclusion: this works, but could probably be much simpler.
So in the lp1 loop I really see 3 types of splits that are of interest: 1. APAR split with sign opposite of lot-split that links to another document (which due to the opposite sign must be an offsetting document) 2. APAR split with sign opposite of lot-split that does not link to another document (old style APAR and possibly future payment if I do eliminate the lot links altogether) 3. All non-APAR splits. Each APAR line from case 1 or 2 will go into a separate row. The splits from case 3 are merged into a single row. And if I understand your code correctly the first non-APAR split you encounter will trigger a loop that will process all non-APAR splits in one go so that will happen only once per lot. You may be able to simplify your logic (and probably speed up the report) if you rearrange tests 4, 5, 6 and 7. That is in pseudo language: if (lot-txn-split == APAR split) { if (signOf(lot-txn-split) == signOf(lot-split) restart loop with next lot-txn-split if (lot-split->posting-split returns valid post split) handle as offsetting document else handle as old lot link split } else handle as payment split I believe this may be faster because it will only call gncInvoiceGetInvoiceFromLot on APAR splits of the proper sign. The code now will run it on all splits that are of proper sign. And as you established the function is slow. Other than that I don't think you can simplify much. I *think* the declaration of lot-txn in line 659 is superfluous. lot-txn is set just outside of lp1 and is invariant as long as lp1 is executed.
Created attachment 373568 [details] Updated as per latest Thanks. Did some changes as described, i.e. small rearrangement of make-invoice->payment-table conditionals. I'll review #c13 and #c14 in due course. My overriding concern is there are three separate payment-analysis algorithms in use. (1) LHS invoice -> RHS payments one is mostly debugged, except sign-reversals (2) LHS payment -> RHS payee-info is not debugged completely yet. (3) owner-splits->aging-list to generate the bracketed amounts. It would be nice to create a canonical "payment-data -> payment-info" process which can be used for all 3 uses as above. The lot-viewer.scm can assist debug all.
(In reply to Geert Janssens from comment #13) Meanwhile, lot-viewer.scm makes your manipulation look easy :) Date Desc Type Bill 000006 None Non-APAR Document 000006 b3505293 23/01/20 Vendor Inv -€100.00 : €100.00 24/01/20 Vendor Pmt €100.00 -€80.00 -€20.00 25/01/20 Vendor Pmt : €150.00 -€150.00 Balance €0.00 €70.00 How then should new-owner-report it? 23/01/20 Bill 100.00 -> 24/01/20 Payment 20.00 of 20.00 -> 24/01/20 Link 80.00 of 80.00 24/01/20 Payment ????? -> 23/01/20 Bill ????? of ?????? 25/01/20 Refund 150.00 -> 25/01/20 Refund 150.00 of 150.00
23/01/20 Bill 100.00 -> 24/01/20 Payment 100.00 of 20.00 + 80.00 24/01/20 Payment 20.00 -> 23/01/20 Bill 100.00 of 100.00 -> 25/01/20 Payment -80.00 of 150.00 25/01/20 Payment 150.00 -> 24/01/20 Payment 80.00 of 20.00 + 80.00 -> Pre-Payment 70.00 As this is a complex matter I may be missing some details. However if we make a minor tweak to the LHS invoice->RHS payment details logic, LHS payment->RHS payment info can be considered a superset of that. The tweak I'd make is to group the 2 and 3 splits as discussed in comment 17. This does mean changes to the logic as you have it currently. But with that change I believe the code can be reused for LHS payment->RHS payment info. There's only one major difference between payment transactions and invoice transactions. For an invoice there can be only one APAR split leading to one lot (which is the one you start your analysis with for LHS invoice->RHS details). For payment transactions there can be multiple APAR splits leading to multiple lots. So if you loop over the code you currently use for LHSinvoice->RHS details with each lot you get from the payment transaction, that should give you the necessary payment info. Determination of prepayments or unpaid parts looks to be slightly more involved than I thought so far. Instead of simply assuming the lot open balance, we should calculate the difference between the LSH amount and the sum of all RHS amounts. LHS amount > RHS amount LHS amount < RHS amount(*) LHS Invoice Diff = "Unpaid" Diff = "Prepayment" LHS Payment Diff = "Prepayment" Diff = "Unpaid" (*) I'm not sure this can happen. This can only be calculated after all LHS APAR splits->via-lots->RHS rows are processed. If I'm not missing anything, this should allow you to reduce the number of analysis algorithms to two. One for the big table and one for the bracketed amounts. The bracketed amounts one should be a simplification of the big table one. It's only concerned with open lots and the balances of these open lots whereas the big table will analyse each transaction in the APAR account.
(In reply to Geert Janssens from comment #20) > 23/01/20 Bill 100.00 -> 24/01/20 Payment 100.00 of 20.00 + 80.00 > 24/01/20 Payment 20.00 -> 23/01/20 Bill 100.00 of 100.00 > -> 25/01/20 Payment -80.00 of 150.00 > 25/01/20 Payment 150.00 -> 24/01/20 Payment 80.00 of 20.00 + 80.00 > -> Pre-Payment 70.00 Would you mind adding an explanation of the provenance of each and every number? The LHS numbers are easy -- they are the APAR sums. To make it easier to cross-reference I reprint the lot-viewer output A B C Date Desc Type Bill 000006 None Non-APAR Document 000006 b3505293 1 23/01/20 Vendor Inv -€100.00 : €100.00 2 24/01/20 Vendor Pmt €100.00 -€80.00 -€20.00 3 25/01/20 Vendor Pmt : €150.00 -€150.00 Balance €0.00 €70.00 LHS Payments -> RHS Payment-info are coming from where exactly? Please use spreadsheet notation.
Even better a simple algorithm to derive the numbers. e.g. I can't figure out how to ensure payment 24/01/20 wouldn't have overpayment whereas payment 25/01/20 would have.
(In reply to Christopher Lam from comment #22) > Even better a simple algorithm to derive the numbers. e.g. I can't figure > out how to ensure payment 24/01/20 wouldn't have overpayment whereas payment > 25/01/20 would have. That one in particular comes from the formula Overpayment amount = sum(lhs transaction APAR amounts) - sum(RHS row amounts). I'll try to make a spreadsheet for the complete overview.
Created attachment 373572 [details] current representation at 1e0983d0d Current representation, updated. Multicolumn report, with Vendor Report and lot-viewer.scm to illustrate better.
(In reply to Geert Janssens from comment #17) > > if (lot-txn-split == APAR split) > { > if (signOf(lot-txn-split) == signOf(lot-split) > restart loop with next lot-txn-split > if (lot-split->posting-split returns valid post split) > handle as offsetting document > else > handle as old lot link split > } > else > handle as payment split For now 1e0983d0d is as follows: if (lot-txn-split != APAR split) handle as payment split elif (signOf(lot-txn-split) == signOf(lot-split) restart loop with next lot-txn-split elif (lot-split->posting-split returns valid post split) handle as offsetting document else handle as old lot link split (i.e. handle as payment split) I *think* the following is the simplest invoice->payment possible: the first conditional can be removed; in practice it'll *hide* non-APAR payment splits of equal sign as lot-split. Food for thought. if (signOf(lot-txn-split) == signOf(lot-split) restart loop with next lot-txn-split elif (lot-split->posting-split returns valid post split) handle as offsetting document else handle as payment, or old lot link split
@gjanssens if you are still interested in helping fix this, I'm looking at Bug797796sample.gnucash. I wonder if comment 20 is correct: 23/01/20 Bill 100.00 -> 24/01/20 Payment 100.00 of 20.00 + 80.00 24/01/20 Payment 20.00 -> 23/01/20 Bill 100.00 of 100.00 -> 25/01/20 Payment -80.00 of 150.00 25/01/20 Payment 150.00 -> 24/01/20 Payment 80.00 of 20.00 + 80.00 -> Pre-Payment 70.00 Your RHS analysis for 24/01/20 suggests that the -80.00 payment must marry up with the 150.00 payment, which is not true -- the -80.00 APAR split and the 150.00 APAR split do not have the same lot. I have a patch which simplifies the LHS-payment analysis and simplifies it a lot. Usually simplifications are good news. modified gnucash/report/reports/standard/new-owner-report.scm @@ -643,23 +643,16 @@ (match splits (() (make-payment-info (AP-negate overpayment) invoices opposing-splits)) ((split . rest) - (let ((lot (xaccSplitGetLot split))) - (define (equal-to-split? s) (equal? s split)) - (match (gncInvoiceGetInvoiceFromLot lot) - (() (let lp1 ((lot-splits (gnc-lot-get-split-list lot)) - (opposing-splits opposing-splits)) - (match lot-splits - (() (lp rest - (- overpayment (gnc-lot-get-balance lot)) - invoices - opposing-splits)) - (((? equal-to-split?) . tail) (lp1 tail opposing-splits)) - ((head . tail) (lp1 tail (cons head opposing-splits)))))) - (inv - (lp rest - overpayment - (cons (cons inv split) invoices) - opposing-splits)))))))) + (define invoice (gncInvoiceGetInvoiceFromLot (xaccSplitGetLot split))) + (if (null? invoice) + (lp rest + (- overpayment (xaccSplitGetAmount split)) + invoices + opposing-splits) + (lp rest + overpayment + (cons (cons invoice split) invoices) + opposing-splits)))))) (define (make-payment->invoices-list txn) (list
Oops - these APAR splits were linked via a lot, but no invoice. Let's ignore comment 26.
(In reply to Christopher Lam from comment #21) > (In reply to Geert Janssens from comment #20) > > 23/01/20 Bill 100.00 -> 24/01/20 Payment 100.00 of 20.00 + 80.00 > > 24/01/20 Payment 20.00 -> 23/01/20 Bill 100.00 of 100.00 > > -> 25/01/20 Payment -80.00 of 150.00 > > 25/01/20 Payment 150.00 -> 24/01/20 Payment 80.00 of 20.00 + 80.00 > > -> Pre-Payment 70.00 > > Would you mind adding an explanation of the provenance of each and every > number? > The LHS numbers are easy -- they are the APAR sums. > > To make it easier to cross-reference I reprint the lot-viewer output > > A B C > Date Desc Type Bill 000006 None Non-APAR > Document 000006 > b3505293 > > 1 23/01/20 Vendor Inv -€100.00 : €100.00 > 2 24/01/20 Vendor Pmt €100.00 -€80.00 -€20.00 > 3 25/01/20 Vendor Pmt : €150.00 -€150.00 > Balance €0.00 €70.00 > > LHS Payments -> RHS Payment-info are coming from where exactly? Please use > spreadsheet notation. It's been a long time since I have looked at this. Chris, to help me get up to speed again, can you do the inverse for me and tell me where you currently get the numbers in your result ? I'm having trouble wading through your advanced guile code :(
Created attachment 374102 [details] Testbook, updated 2021-06-30, with simple, partially paid bill
Comment on attachment 373572 [details] current representation at 1e0983d0d Looking at this screenshot you could argue this enhancement request has been implemented: the first highlighted line on the RHS nicely shows two lines for the total amount, which properly represents the way the nonAPAR splits of that payment transaction are divided. There are a few other issues still though some of which are partially related to this.
Created attachment 374103 [details] Illustration of current issues This screenshot is taken from the most recent test book with gnucash maint as of today (a few days after release of gnucash 4.6). 1. Credit note amounts RHS have the wrong sign. Like payments their sign should be the inverse of bill amounts. A small issue, not immediately related to this RFE. If preferred I'll report it separately 2. and 3. We're looking at a refund that gets payed again with two later payments. No bills or credit notes involved. This is a bit of an odd case which I added to test the symmetry of our code. A payment that gets refunded is the more common case, but apart of signs it both cases should behave similarly. Note in particular the refund was € 160, which gets paid for by a payment of € 120 and one of € 50. That's an overpayment of € 10. Technically the RHS representation maps perfectly with the splits in the involved transactions. However the result is fairly counter-intuitive: intuitively you would expect a € 160 refund to be paid with € 120 and € 40 and no mention of an overpayment here. One would expect the overpayment as part of the RHS in 3. But not both in 2. and 3. This is a hard case. What's reported is the internal representation. There's no direct relation between the € 40 and an opposing split in the lot we're processing. I have thought a lot about this and the best rule I can come up with to calculate partial amount is sum(APAR splits in lot, except for binding split) minus (lot balance IF lot balance has opposite sign of binding split) I haven't verified it for each and every use case yet, but it's a start. 4. Is a variation on the same theme. 5. LHS we have a Payment and a Bill column. This is however not very representative - we also have refunds (printed in the bill column) and credit notes (printed in the payment column). I wonder if the report wouldn't be better if we just used one column with signed values or go with debit and credit as column headers. If type info is needed, there's already another column for it.
Created attachment 374104 [details] Highlight issue illustration - part 1
Created attachment 374105 [details] Highlight issue illustration - part 2 Another hint something is awkward with points 2. and 3. in the previous comment can be seen in the two screenshots of the highlighted transactions: In the first screenshot I have highlighted the refund LHS. RHS this highlights 3 lines: a pre-payment of € 10, a payment of € 120 and a payment of € 40. Regardless of how you look at this, the selected RHS total doesn't match the selected LHS total. That makes the report very confusing (and I dare argue buggy even). In the second screenshot I have highlighted the second payment, which is € 50 total of which € 40 is used to pay the refund and € 10 is an overpayment. Again the totals LHS and RHS don't match. All of this would be fixed if RHS the partial amount of €-50 would be €-40 and the first pre-payment wouldn't be present. This matches intuitive expectations. And the formula suggested in the previous comment could get us there (presuming it wouldn't break other cases). The only downside would be that there would be no split directly matching the €-40 amount. There's only the €-50 amount split. So perhaps if we go this route, we may have to annotate this amount (*) and add a footnote this amount is inferred, rather than directly taken from a split.
Created attachment 374108 [details] WIP [1] done I think 1. for LHS invoices, don't negate RHS CN amounts 2-4. the payment details are analysed via `define payments-list` in #L733 onwards. Is it the intention that the 13/01/20 LHS refund of 160 will have ONE RHS link, or THREE? 5. I think Debit/Credit would work well.
for 5. make (formal? #t) in make-heading-list
Created attachment 374111 [details] for 2-4 try this
Point 1 and 5 are fixed. As for 2-4, we have our first step - the RHS line shows the proper partial amount. However a few issues remain a. with your change adding the asterisks, suddenly almost all partial amounts loose their links and have an annotation. I think the annotation is only needed if the calculated partial amount is not equal to the relevant split amount (which is also equivalent to when the lot balance wasn't zero). As far as I'm concerned the links to the splits can remain in all cases. In the case where the split amount and the calculated amount differ the link can still be helpful to find which split was used as a basis to infer the actual partial amount. b. The RHS expansions where you recalculate the partial amount should also have the pre-payments adjusted. In the example on the transaction of 13/01/2020, there should not be a prepayment amount anymore. The LHS is fully covered by the two partial amounts RHS. There is a mismatch between calculated amount and total split amount. That's already represented in the two columns (partial vs total) and that mismatch appears in the next transaction, the payment transaction on 15/01/2020. Displaying it for both the refund transaction and the payment transaction is confusing and unhelpful. I think what should happen here is that the prepayment amount should be calucated as the difference between the LHS amount and the sum of RHS partial amounts. I'm not sure how it is currently calculated.
Created attachment 374116 [details] Testbook, updated with customer invoices and payments we went through a few iterations of coding and testing while conversing on irc. As a result the report is now in good shape for vendors. This version of the book adds some basic transactions for customers. The last one (a simple invoice paid in two parts of which the second payment is an overpayment) is not yet represented properly. The pre-payment line is not listed in the report though its visible in the lot viewer report.
Created attachment 374117 [details] Screenshot illustrating missing prepayment on customer report
I think all issues resolved.
I have tested your most recent work on your github branch https://github.com/christopherlam/gnucash/bug797596 I agree all issues mentioned in this bug report are resolved. Additional issues were found and discussed on irc. I believe all relevant ones have been fixed as well. Irc mentioned a few untested (and contrived) corner cases. I propose to just wait and see if we ever encounter them. This bug at least can be closed after merging the final work into maint.
For reference, other contrived corner cases described in https://code.gnucash.org/logs/2021/07/08.html#T10:58:32 Merged and pushed to maint.