Skip to content

Fix transactions posting a day early when booked around midnight.#2744

Open
OtterBoops wants to merge 7 commits into
we-promise:mainfrom
OtterBoops:fix/2668-transactions-posting-day-early
Open

Fix transactions posting a day early when booked around midnight.#2744
OtterBoops wants to merge 7 commits into
we-promise:mainfrom
OtterBoops:fix/2668-transactions-posting-day-early

Conversation

@OtterBoops

@OtterBoops OtterBoops commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

This PR fixes #2668 and implements some tests surrounding the edge case.

Summary by CodeRabbit

  • Bug Fixes
    • Improved transaction date parsing across multiple providers to respect the account family timezone when converting timestamps to Date, including Unix timestamps, ISO-like datetime strings, and Time/DateTime inputs.
    • Handles datetime-like strings vs date-only strings more reliably to avoid off-by-one-day issues near midnight.
  • Tests
    • Added/extended unit coverage to verify timezone-aware date conversion for Akahu, Enable Banking, Lunchflow, and other affected processors.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Timestamp-based transaction dates now use each account family’s timezone across multiple provider processors and shared date helpers. Date-only strings retain direct date parsing, and regression tests cover timezone-adjusted calendar dates.

Changes

Transaction date timezone handling

Layer / File(s) Summary
Family-aware date helper parsing
app/models/indexa_capital_account/data_helpers.rb, lib/generators/provider/family/templates/data_helpers.rb.tt
Date helpers accept family context, timezone-adjust timestamp-like values, and preserve direct parsing for date-only strings.
Timezone-aware processor date parsing
app/models/*_entry/processor.rb
Provider processors apply family timezone conversion to numeric, time-like, and timestamp-string inputs before producing dates.
Timezone conversion regression coverage
test/models/*_entry/processor_test.rb
Tests verify expected local calendar dates for timestamp inputs across positive and negative timezone offsets.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes unrelated timezone/date parsing changes for many other providers and the generator beyond the Lunch Flow bug in #2668. Split the broader parser normalization and generator updates into a separate follow-up PR, or limit this change to Lunch Flow and required shared helpers.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main fix: transactions no longer post a day early around midnight.
Linked Issues check ✅ Passed The Lunch Flow timezone-aware date fix and regression test address the bug where payments before 1am BST showed on the previous day.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/models/akahu_entry/processor_test.rb (1)

101-107: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Correct the UTC time in inline comments.

The Unix timestamp 1752537000 evaluates exactly to 23:50:00 UTC rather than 23:30:00 UTC (which would be 1752535800). While this 20-minute difference does not affect the correctness of the tests—since both times still fall on the target Date.new(2025, 7, 15) in the specified timezones—updating the comments prevents potential confusion for future readers reviewing the math.

  • test/models/akahu_entry/processor_test.rb#L101-L107: update 23:30:00 to 23:50:00 and the local time to 11:50:00 NZST.
  • test/models/enable_banking_entry/processor_test.rb#L435-L441: update 23:30:00 to 23:50:00 and the local time to 01:50:00 CEST.
  • test/models/lunchflow_entry/processor_test.rb#L383-L391: update 23:30:00 to 23:50:00 and the local time to 00:50:00 BST.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/models/akahu_entry/processor_test.rb` around lines 101 - 107, Correct
the inline timestamp comments without changing test data: in
test/models/akahu_entry/processor_test.rb lines 101-107, use 23:50:00 UTC and
11:50:00 NZST; in test/models/enable_banking_entry/processor_test.rb lines
435-441, use 23:50:00 UTC and 01:50:00 CEST; in
test/models/lunchflow_entry/processor_test.rb lines 383-391, use 23:50:00 UTC
and 00:50:00 BST.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/models/akahu_entry/processor_test.rb`:
- Around line 101-107: Correct the inline timestamp comments without changing
test data: in test/models/akahu_entry/processor_test.rb lines 101-107, use
23:50:00 UTC and 11:50:00 NZST; in
test/models/enable_banking_entry/processor_test.rb lines 435-441, use 23:50:00
UTC and 01:50:00 CEST; in test/models/lunchflow_entry/processor_test.rb lines
383-391, use 23:50:00 UTC and 00:50:00 BST.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e9b23c24-15fd-4577-a698-0880c41911a1

📥 Commits

Reviewing files that changed from the base of the PR and between b613d10 and 0fcc43c.

📒 Files selected for processing (6)
  • app/models/akahu_entry/processor.rb
  • app/models/enable_banking_entry/processor.rb
  • app/models/lunchflow_entry/processor.rb
  • test/models/akahu_entry/processor_test.rb
  • test/models/enable_banking_entry/processor_test.rb
  • test/models/lunchflow_entry/processor_test.rb

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0fcc43c97c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread test/models/akahu_entry/processor_test.rb Outdated

@jjmata jjmata left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed the timezone conversion fix. The core approach (.in_time_zone(account&.family&.timezone).to_date) is sound, but a few things worth a look:

  • Same bug likely still present elsewhere: app/models/brex_entry/processor.rb, mercury_entry/processor.rb, sophtron_entry/processor.rb, up_entry/processor.rb, wise_entry/processor.rb, and coinstats_entry/processor.rb all have the identical unconverted Time.at(...).to_date / Time.parse(...).to_date pattern in their date methods that this PR fixes for Akahu/Enable Banking/Lunchflow. Same midnight/"day early" bug is reproducible in any of these. Might be worth a tracking issue even if out of scope here.
  • Inconsistent within the PR's own scope: akahu_entry/processor.rb's String branch now detects time-bearing ISO strings (include?("T") || include?(":")) and runs them through in_time_zone, but the String branches in enable_banking_entry/processor.rb and lunchflow_entry/processor.rb still do a bare Date.parse(value). If either provider ever returns a datetime string (vs. a pure date) for booking_date/date, that path reproduces the exact bug being fixed here.
  • Nil-timezone fallback is silent: families.timezone has no DB default, so account&.family&.timezone can be nil for many accounts. Time#in_time_zone(nil) is a documented ActiveSupport no-op — it just returns the original (system/UTC) time, silently reverting to the old buggy behavior. Probably fine as a fallback, but worth confirming that's intentional, or logging it via DebugLogEntry.capture per repo convention so it's visible when a family lacks a timezone.
  • Test coverage is one-sided: all three new tests use positive-UTC-offset zones (Pacific/Auckland, Europe/Berlin, Europe/London). None cover a negative-offset zone (e.g. America/New_York) or a DST-transition date, so the fix isn't verified in that direction even though the in_time_zone approach should logically handle it correctly.

No blocking issues — the fix itself looks correct for the three files it touches.


Generated by Claude Code

@sure-admin

Copy link
Copy Markdown
Collaborator

This fix looks right for Akahu, Enable Banking, and Lunchflow, but I think the same pattern should also move into the Provider family generator.

The main place is lib/generators/provider/family/templates/data_helpers.rb.tt, which still parses timestamp strings with Time.zone.parse(...).to_date and Time / DateTime values with plain to_date. Since transactions_processor.rb.tt routes imported transaction dates through that helper, newly generated providers can still hit the same around-midnight date shift unless the parsing is anchored to the linked account family's timezone.

I also found at least one already-implemented provider with the same issue still present: app/models/indexa_capital_account/data_helpers.rb keeps the same Time.zone.parse(...).to_date logic, so it should probably be updated alongside the generator so they don't drift apart.

Separately, a few existing entry processors still appear vulnerable when the upstream payload is a real timestamp rather than a date-only string, especially app/models/mercury_entry/processor.rb and app/models/coinstats_entry/processor.rb. I wouldn't block this PR on broad cleanup, but it feels worth either following up here or opening a small follow-up issue/PR for the rest of the timestamp-bearing providers.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/models/indexa_capital_account/data_helpers.rb`:
- Around line 66-76: Reorder the date case branches so the combined Time,
DateTime, and ActiveSupport::TimeWithZone branch is evaluated before the Date
branch, allowing DateTime values to receive timezone conversion. Apply this
change in app/models/indexa_capital_account/data_helpers.rb (lines 66-76),
lib/generators/provider/family/templates/data_helpers.rb.tt (lines 47-57), and
app/models/wise_entry/processor.rb (lines 152-161); no other behavior needs
changing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b8504b02-3d20-44bb-b1da-952ed880eaa2

📥 Commits

Reviewing files that changed from the base of the PR and between 7d27369 and 196175b.

📒 Files selected for processing (11)
  • app/models/brex_entry/processor.rb
  • app/models/coinstats_entry/processor.rb
  • app/models/enable_banking_entry/processor.rb
  • app/models/indexa_capital_account/data_helpers.rb
  • app/models/lunchflow_entry/processor.rb
  • app/models/mercury_entry/processor.rb
  • app/models/sophtron_entry/processor.rb
  • app/models/up_entry/processor.rb
  • app/models/wise_entry/processor.rb
  • lib/generators/provider/family/templates/data_helpers.rb.tt
  • test/models/lunchflow_entry/processor_test.rb
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/models/lunchflow_entry/processor.rb
  • app/models/enable_banking_entry/processor.rb

Comment thread app/models/indexa_capital_account/data_helpers.rb
@OtterBoops

OtterBoops commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Some pipeline tests fail with:
ArgumentError: you can't define an already defined column 'product' on 'enable_banking_accounts'.

The only thing I can think of is editing migrations to use unless column_exists?, but this feels like scope creep.
e.g.

# db/migrate/20260627101954_add_balance_reversal_to_enable_banking_accounts.rb
add_column :enable_banking_accounts, :treat_balance_as_available_credit, :boolean, default: false, null: false unless column_exists?(:enable_banking_accounts, :treat_balance_as_available_credit)

Want me to try and apply a fix? Doesn't feel like a decision for me to make. @jjmata

Copy link
Copy Markdown
Collaborator

Following up on your question above: this looks like a real duplicate-migration issue rather than scope creep, so a defensive unless column_exists? guard (or squashing the conflicting migrations) seems reasonable rather than out of scope — but that's a maintainer call. Also flagging @sure-admin's unaddressed note: the same timezone fix should probably extend to the provider generator template (data_helpers.rb.tt) and IndexaCapitalAccount, or new/that provider will silently reintroduce this bug.


Generated by Claude Code

@OtterBoops

OtterBoops commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

Also flagging @sure-admin's unaddressed note: the same timezone fix should probably extend to the provider generator template (data_helpers.rb.tt) and IndexaCapitalAccount, or new/that provider will silently reintroduce this bug.

Yeah I'll address it, I was just making sure that further changes I make won't be out of scope.
As soon as I have the greenlight from a maintainer, I'll patch the rest up.

@jjmata

jjmata commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Yeah I'll address it, I was just making sure that further changes I make won't be out of scope.
As soon as I have the greenlight from a maintainer, I'll patch the rest up.

Totally cool to add those to the scope here, @OtterBoops ... thanks for checking!

@OtterBoops

Copy link
Copy Markdown
Contributor Author

Totally cool to add those to the scope here, @OtterBoops ... thanks for checking!

Everything should be covered. Lemme know if there are any other remarks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

Bug: Transactions posting a day early

4 participants