https://bugs.kde.org/show_bug.cgi?id=524736

            Bug ID: 524736
           Summary: Overdue final scheduled transaction disappears after
                    declining an unrelated QIF match
    Classification: Applications
           Product: kmymoney
      Version First 5.2.2
       Reported In:
          Platform: Mageia RPMs
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: ux-ui
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

DESCRIPTION
A finite scheduled transaction has reached its final payment date, but the
final occurrence has not been paid and must remain active and
overdue. During a QIF import, KMyMoney proposes a transaction with a similar
amount as a match. The user declines the match.
Afterwards, the schedule disappears from the Scheduled Transactions view as if
it had been completed. 
Declining the match does not itself call modifySchedule(). The refresh only
exposes an incorrect isFinished() result which already
exists in the stored schedule state. 

Consider a monthly schedule with these dates: 
previous occurrence due: 2026-07-23
final occurrence due: 2026-08-23
schedule end date: 2026-08-23

Enter the 2026-07-23 occurrence late, using 2026-08-24 as its actual posting
date. The normal schedule-entry code then produces: 
lastPayment = 2026-08-24
nextDueDate = 2026-08-23
endDate = 2026-08-23

This is valid: lastPayment is the actual posting date of the previous
occurrence, while nextDueDate == endDate is the still
unpaid final occurrence. 
The current implementation returns true from isFinished() because lastPayment
>= endDate. It ignores the authoritative pending
nextDueDate. When finished schedules are hidden, the schedule disappears from
the Scheduled Transactions view on refresh. 
The QIF matcher still finds it when the imported transaction date is inside the
match window. Choosing No leaves the schedule
unchanged, but the view then presents the already incorrect finished state. 
Manual reproduction 
Enable Do not show finished schedules.
Create an estimated monthly withdrawal schedule for 100.00 with payee Pending
final occurrence.
Set its next occurrence to 2026-07-23 and its final transaction date to
2026-08-23.
Enter the 2026-07-23 occurrence, but change its posting date to 2026-08-24.
Import the attached reproducer.qif into the same account. Its transaction is
dated 2026-08-23 and has amount -105.00, which
is inside the 10% variation of an estimated schedule.
In the “Schedule found” question, choose No. 
Depending on when the Scheduled Transactions view refreshes, it may disappear
immediately after step 4 or when the import dialog
closes. In either case, the deterministic error is that the unpaid 2026-08-23
occurrence is classified as finished instead of overdue. 
Automated regression reproduction 
Apply 0001-add-regression-tests.patch to current upstream master and run: 
cmake --build <build-dir> --target test-mymoneyschedule test-matchfinder
test-mymoneyxmlreader
<build-dir>/bin/test-mymoneyschedule testPendingFinalOccurrenceAfterLatePayment
<build-dir>/bin/test-matchfinder
testScheduleMatch_pendingFinalOccurrenceAfterLatePayment
<build-dir>/bin/test-mymoneyxmlreader
testReadPendingFinalOccurrenceAfterLatePayment

All three tests fail before the fix: 
MyMoneyScheduleTest:
'!schedule.isFinished()' returned FALSE

MatchFinderTest:
'!m_schedule.isFinished()' returned FALSE

MyMoneyXmlReaderTest:
actual nextDueDate: Invalid QDate
expected: endDate (2022-08-18)

The matcher test uses a 5% amount difference and explicitly checks that, after
the negative-answer path performs no schedule update,
the final occurrence is still active and overdue. 
Secondary persistence problem 
The XML reader treats every nextDueDate <= lastPayment as legacy corruption,
clears nextDueDate, and recalculates it from
lastPayment. For the valid late-payment state above, recalculation starts after
endDate, so the pending final occurrence becomes
an invalid date and is lost after reopening a .kmy file. 
Code involved 
The incorrect completion decision is made in
kmymoney/mymoney/mymoneyschedule.cpp, in
MyMoneySchedule::isFinished(). The problematic case is the comparison of
lastPayment with endDate: lastPayment records
the actual posting date of the previous occurrence and can legitimately be
later than the still-pending final nextDueDate. 
The related reload problem is in kmymoney/plugins/xml/mymoneyxmlreader.cpp,
where a nextDueDate <= lastPayment
value is repaired unconditionally. That relation is valid when a previous
occurrence was posted late and a final occurrence on or before
endDate is still unpaid. 

The schedule remains active and overdue after declining the QIF proposal.
Saving and reopening an XML .kmy file preserves the pending final due date.
The schedule becomes finished after its next due date is advanced past the end
date. 
Candidate patch for maintainer review 
0002-keep-pending-final-occurrence-active.patch demonstrates one possible
resolution: use the pending nextDueDate when
deciding whether a finite schedule is complete, and do not apply the XML legacy
repair to a valid occurrence on or before endDate. It
is supplied for review; the maintainer can choose the final implementation and
its scope. 
After applying both patches: 
test-mymoneyschedule passed
test-matchfinder passed
test-mymoneyxmlreader passed
3/3 tests passed

Tested against upstream master 6581e644f using Qt 6.10.0/KF 6 on Mageia 10.
The symptom was not observed with Mageia 9
KMyMoney 5.1.3. 



EXPECTED RESULT
A valid nextDueDate on or before endDate means an occurrence is still pending,
even when the previous occurrence was
posted after endDate.

SOFTWARE/OS VERSIONS
  Operating System: Mageia 10
  KDE Plasma Version: Not applicable (LXQt session)
  KDE Frameworks Version: 6.22.0
  Qt Version: 6.10.0


ADDITIONAL INFORMATION
No exact duplicate was found in KDE Bugzilla

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to