Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add schedule end date/count field #1899

Merged
merged 19 commits into from
Dec 14, 2023

Conversation

jfdoming
Copy link
Contributor

@jfdoming jfdoming commented Nov 11, 2023

Resurrecting #407! This PR adds an end date/max occurrences field to the schedule creator. Closes #1568 and #241.

Screenshots

Current popup:

image

New popup:

image

Copy link

netlify bot commented Nov 11, 2023

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit 816254a
🔍 Latest deploy log https://app.netlify.com/sites/actualbudget/deploys/6578a1e055efc000086755fe
😎 Deploy Preview https://deploy-preview-1899.demo.actualbudget.org/
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

github-actions bot commented Nov 11, 2023

Bundle Stats — desktop-client

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
16 3.08 MB → 3.08 MB (+1.29 kB) +0.04%
Changeset
File Δ Size
src/components/select/RecurringSchedulePicker.js 📈 +2.72 kB (+13.70%) 19.86 kB → 22.58 kB
../loot-core/src/shared/schedules.ts 📈 +734 B (+8.83%) 8.12 kB → 8.83 kB
src/components/schedules/DiscoverSchedules.tsx 📈 +146 B (+1.73%) 8.26 kB → 8.41 kB
src/components/common/Select.tsx 📈 +38 B (+0.67%) 5.54 kB → 5.57 kB
src/components/schedules/EditSchedule.js 📈 +133 B (+0.34%) 38.25 kB → 38.38 kB
src/components/rules/Value.tsx 📈 +12 B (+0.18%) 6.41 kB → 6.43 kB
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/main.js 1.26 MB → 1.26 MB (+1.29 kB) +0.10%

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
static/js/665.chunk.js 824.28 kB 0%
static/media/Inter-italic.var.woff2 239.29 kB 0%
static/media/Inter-roman.var.woff2 221.86 kB 0%
static/js/444.chunk.js 156.11 kB 0%
static/js/231.chunk.js 117.38 kB 0%
static/js/wide-components.chunk.js 114.96 kB 0%
static/js/reports.chunk.js 76.41 kB 0%
static/js/narrow-components.chunk.js 51.17 kB 0%
static/js/226.chunk.js 28.92 kB 0%
static/js/473.chunk.js 13 kB 0%
static/js/resize-observer-polyfill.chunk.js 8.88 kB 0%
static/css/main.css 7.41 kB 0%
asset-manifest.json 2.07 kB 0%
index.html 1.66 kB 0%
static/media/browser-server.js 911 B 0%

Copy link
Contributor

github-actions bot commented Nov 11, 2023

Bundle Stats — loot-core

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
2 2.23 MB → 2.23 MB (+662 B) +0.03%
Changeset
File Δ Size
packages/loot-core/src/shared/schedules.ts 📈 +734 B (+8.83%) 8.12 kB → 8.83 kB
packages/loot-core/src/server/budget/goals/goalsSchedule.ts 📈 +533 B (+8.45%) 6.16 kB → 6.68 kB
packages/loot-core/src/server/schedules/app.ts 📈 +334 B (+1.96%) 16.62 kB → 16.94 kB
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
kcab.worker.js 1.23 MB → 1.23 MB (+662 B) +0.05%

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
xfo.xfo.kcab.worker.js 1014.46 kB 0%

@jfdoming jfdoming force-pushed the jfdoming/schedule-end-date branch from 1625ea4 to 8e7a947 Compare November 11, 2023 20:30
Copy link
Contributor

@Shazib Shazib left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@@ -0,0 +1,6 @@
---
category: Bugfix
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd tag this as a feature personally!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops totally my bad! I was in bugfixing mode in my mind 😆

@@ -25,6 +25,9 @@ export interface ScheduleEntity {
}[];
skipWeekend: boolean;
start: string;
endMode: 'never' | 'after_n_occurrences' | 'on_date';
endOccurrences: number;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be be possible to only store endDate regardless of endMode?

So when the user selects '5 occurrences' we work out the date of the 5th occurrence and store that? Just thinking about saving a column but maybe its not worth the effort.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes showing the future UI a lot easier. For example, if you add a schedule and then go edit the rule later, having a dedicated endOccurrences field means we can just use that for hydrating the UI. If we don't have that field, we have to have logic like "generate dates until we pass the end date" which could get pretty inefficient if someone inputs a large # of occurrences. Let me know if this makes sense!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too fussed either way, Just a suggestion! But I wouldn't necessarily have thought it would hurt perf too badly even for v large dates, particularly as you only see one at a time.

Copy link
Contributor Author

@jfdoming jfdoming Nov 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, thanks for the suggestion! I think I should have been more clear: I'm talking about the rules page which displays the same selector:
image
If we don't store endOccurrences, I think we'd have to recalculate it on this page by manually iterating until we hit endDate, no?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeh you're correct; you'd probably have to iterate through the schedule executions till you reach 'end date'. Even then I dont think it would be too slow.

but given what you've got now works I wouldn't worry too much about it!

id="repeat_end_dropdown"
bare
options={[
['never', 'forever'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use 'indefinitely' here instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea!

@youngcw
Copy link
Member

youngcw commented Nov 13, 2023

@shall0pass This will need testing against templates when one or both of us get a chance.

@youngcw
Copy link
Member

youngcw commented Nov 15, 2023

This will need testing

I tried this really quick and it caused the template script to get into some sort of infinite loop. Thats likely not a reason to hold this PR back, but will need fixed soon.

@jfdoming
Copy link
Contributor Author

This will need testing

I tried this really quick and it caused the template script to get into some sort of infinite loop. Thats likely not a reason to hold this PR back, but will need fixed soon.

@youngcw is this related to #1917 at all or is that something else?

@youngcw
Copy link
Member

youngcw commented Nov 17, 2023

#1917 is for something else. The schedule template processor needs updated to handle the schedules ending

@jfdoming
Copy link
Contributor Author

jfdoming commented Nov 17, 2023

#1917 is for something else. The schedule template processor needs updated to handle the schedules ending

Got it. I'll try to replicate this later today

@jfdoming
Copy link
Contributor Author

#1917 is for something else. The schedule template processor needs updated to handle the schedules ending

I think this is fixed now! Semi-related to the previous issue, just needed to add a further fallback to the logic

@youngcw
Copy link
Member

youngcw commented Nov 21, 2023

I think this is fixed now! Semi-related to the previous issue, just needed to add a further fallback to the logic

Cool it looks to be working for me. Ill try some more to see if I can break it, but so far so good!

@jfdoming jfdoming force-pushed the jfdoming/schedule-end-date branch from 3f51914 to cca80a0 Compare November 24, 2023 08:36
@jfdoming
Copy link
Contributor Author

(sorry, rebased on master due to merge conflicts)

@jfdoming jfdoming force-pushed the jfdoming/schedule-end-date branch from cca80a0 to cd1451b Compare December 2, 2023 05:38
@@ -90,6 +89,10 @@ export async function goalsSchedule(
dateConditions,
monthUtils._parse(next_date),
);
if (!diffDays) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works correctly. If you have a schedule that has two occurrences in the same month, the function could exit prematurely. I think diffDays needs to be reevaluated before doing this check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works correctly. If you have a schedule that has two occurrences in the same month, the function could exit prematurely. I think diffDays needs to be reevaluated before doing this check.

Oh, nice catch! This should definitely have been reevaluated. I decided to slightly update how the logic works to be more straightforward/correct in general, let me know your thoughts! Also fixed another bug I found incidentally, that one can move to a separate PR if you like.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My test budget is crashing with the current build. Here it is if you want to try and debug it. I believe it was working before these most recent changes, so its likely somewhere in there.
template_test_export.zip

Copy link
Contributor Author

@jfdoming jfdoming Dec 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yikes, sorry about that. I'll look into this later today and add what I find to my own manual tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, sorry for the pain here. I was able to run your test budget with no issues in the latest commit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've attached a test budget.
2023-12-05-My-Finances-564f13f.zip

In this test file if you use the "Savings" category that has a schedule called "breakWeekend", the months of December and March aren't right. Those days both fall on a Saturday those months and only budget for one of the two schedules.
I haven't tried it, but I think this only occurs on the 'before' style schedules. What if instead of passing the weekendSolveMode variable of the actual schedule, we force it to 'after' so diffDays won't automatically be evaluated as 0 and will then look for a second schedule for the month? Thanks for all the cleanup you've done!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, nice catch! This was just one place I missed in my refactor, I believe this should be fixed in that budget now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you've got it!

@trafico-bot trafico-bot bot added ⚠️ Changes requested Pull Request needs changes before it can be reviewed again 🔍 Ready for Review and removed 🔍 Ready for Review ⚠️ Changes requested Pull Request needs changes before it can be reviewed again labels Dec 2, 2023
@youngcw
Copy link
Member

youngcw commented Dec 5, 2023

Looks to be working with the template test file! I tried both number of occurrences and end date and it seems to work right. @shall0pass You understand the schedule template a lot better than I do so Ill defer reviewing the code to you.

@youngcw youngcw removed request for Shazib and youngcw December 5, 2023 16:25
@youngcw
Copy link
Member

youngcw commented Dec 6, 2023

Fixes #506 as well

@jfdoming
Copy link
Contributor Author

jfdoming commented Dec 9, 2023

(just rebased on master again due to merge conflicts, and fixed one let -> const)

@jfdoming jfdoming requested a review from Shazib December 10, 2023 03:50
Copy link
Contributor

@joel-jeremy joel-jeremy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@jfdoming
Copy link
Contributor Author

Looks good!

Awesome, thanks! Are we good to merge, then? (I don't have merge permissions, not sure how this normally works)

@shall0pass shall0pass merged commit c09a85f into actualbudget:master Dec 14, 2023
19 checks passed
@trafico-bot trafico-bot bot added ✨ Merged Pull Request has been merged successfully and removed ✅ Approved ✨ Merged Pull Request has been merged successfully labels Dec 14, 2023
@Kidglove57
Copy link

I have two instances of Actual, one updated today in “edge” and the other using the “latest” tag. In addition I had four scheduled payments auto posting this morning. They are set up for “after the weekend” but that was not relevant today as it was a Friday. This is what I observed:

  1. These schedules posted automatically and correctly in “latest”.
  2. However, in my experimental file using “edge” none of the scheduled payments auto posted. Instead they simply showed as “due”.

It may be a coincidence but the merge of the above PR seems to be the difference between the behaviour on my two files. I wonder therefore if there may still be a bug here to be hunted down?

@carkom
Copy link
Contributor

carkom commented Dec 15, 2023

@jfdoming

Yes, I see the same as @Kidglove57 . Any schedules that were created before this PR are given a "null" for "endMode" which means it doesn't run. Is there a catch for this case in the code? I haven't read through it, so it may already exist, but something like if "isRecurring === true" and "endMode == null" then assume it's indefinite. Sorry again if you've already got this in there but it may not be working properly.

@jfdoming
Copy link
Contributor Author

@jfdoming

Yes, I see the same as @Kidglove57 . Any schedules that were created before this PR are given a "null" for "endMode" which means it doesn't run. Is there a catch for this case in the code? I haven't read through it, so it may already exist, but something like if "isRecurring === true" and "endMode == null" then assume it's indefinite. Sorry again if you've already got this in there but it may not be working properly.

Yikes, sorry about that. I thought I handled those cases but clearly not. I'll look into it now

@jfdoming
Copy link
Contributor Author

Hmm, @Kidglove57 I'm struggling to reproduce this issue. Do you have a redacted sample budget you can share where this occurs? I tried making a schedule with the endMode initially undefined, but that seemed to work fine

@Kidglove57
Copy link

Kidglove57 commented Dec 16, 2023

I’ve got two more scheduled transactions due to post tomorrow (Sunday). They are useful for this trial as, unlike the previous failed posts, these are without “after the weekend” enabled. I’ll see what happens and if they auto post and report back here.

The problem with test budgets is that the only way to reproduce this is when real future scheduled transactions are due to post. I will add in a brand new test schedule as a further trial.

@jfdoming
Copy link
Contributor Author

I’ve got two more scheduled transactions due to post tomorrow (Sunday). They are useful for this trial as, unlike the previous failed posts, these are without “after the weekend” enabled. I’ll see what happens and if they auto post and report back here.

The problem with test budgets is that the only way to reproduce this is when real future scheduled transactions are due to post. I will add in a brand new test schedule as a further trial.

I was currently testing things by altering my system time. So I think I would be able to fast forward things that way. But maybe I'm misunderstanding! At any rate, awaiting your test results 🙏

@Kidglove57
Copy link

Thank you - I will. Bearing in mind @carkom comment, and as an extra check, may I ask if the schedules you were testing were created prior to this release?

@Kidglove57
Copy link

Good morning. I am glad to bring good news. Both my two pre existing scheduled transactions and my test transaction posted successfully this morning (Sunday) using the latest Edge. I have no way of assessing why all four scheduled payments due on Friday failed (unless it was the fact that they were marked “after the weekend”). I’ll set up another test transaction today with the “after the weekend” marker and see what happens on Monday. Fingers crossed!

@Kidglove57
Copy link

All posted successfully this morning! I’ll keep an eye on this and thank you for your patience. Hopefully my experience on Friday was a one off!

@jfdoming
Copy link
Contributor Author

All posted successfully this morning! I’ll keep an eye on this and thank you for your patience. Hopefully my experience on Friday was a one off!

Glad to hear it worked! It is definitely strange that it didn't work on Friday though... Maybe something with "after the weekend" on a Friday. I'll keep following this thread just in case!

@jfdoming jfdoming deleted the jfdoming/schedule-end-date branch December 23, 2023 05:37
FlorianLang06 pushed a commit to FlorianLang06/actual that referenced this pull request Mar 7, 2024
* Add "end" field with date/count options

* Use "end" field to generate schedule

* Show "end" field in recurring description

* Disable weekend before/after picker when not enabled

* Add release notes

* Fix failing typechecks

* Add some description tests

* PR feedback

* 'Features', not 'Feature'

* Fix goal templates infinite loop

* Empty commit to bump ci

* Fix bug where schedule templates in the past would apply incorrectly

For example, if you had a schedule which started in November 2023 for
1.00, and you applied the schedule in October 2023, then you would end
up with a value of 0.50 applied in October.

* Fix handling of schedules with an end date

This commit also includes a refactor of the skip-weekend logic: rather
than referring only to dates with skipped weekends (which requires
checking whether the "next date" request worked correctly), we track a
"base date" which is the previous value of the schedule according to the
rrule, excluding any weekend-skipping. This lets us use `addDays(baseDate, 1)`
to get the next occurrence, regardless of the weekend behaviour.

Doing things this way ensures that the loop will always make progress.

* Only compute skipped weekend if weekend skips were requested

* Fix typo in iterate-schedule-occurrences code

We should be using `nextBaseDate` to derive the next base date, not
`nextDate`; this is because we want the base date to be guaranteed to
make progress in each loop iteration, so we can finish in at most 30
iterations without duplicate base dates.

* Use const

* Revert const -> let for one mutable variable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature] Add end date to repeated Schedules [Feature] Set finish condition to repeating transactions
7 participants