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

Convert MembershipLog.modified_date from date to timestamp so we record time as well #31799

Merged
merged 1 commit into from
Jan 18, 2025

Conversation

mattwire
Copy link
Contributor

Overview

Currently only the date is recorded in civicrm_membership_log. This is problematic if there are multiple changes on the same day because it is not clear which ones happened first. You can guess if you sort by table ID as well but it makes it much harder to correlate changes with other log entries.

Before

Only date recorded in MembershipLog.modified_date

After

Both date and time recorded in MembershipLog.modified_date

Technical Details

Converts database field to timestamp and checks that we are passing in full date/time as params when updating.

Comments

Copy link

civibot bot commented Jan 16, 2025

🤖 Thank you for contributing to CiviCRM! ❤️ We will need to test and review this PR. 👷

Introduction for new contributors...
  • If this is your first PR, an admin will greenlight automated testing with the command ok to test or add to whitelist.
  • A series of tests will automatically run. You can see the results at the bottom of this page (if there are any problems, it will include a link to see what went wrong).
  • A demo site will be built where anyone can try out a version of CiviCRM that includes your changes.
  • If this process needs to be repeated, an admin will issue the command test this please to rerun tests and build a new demo site.
  • Before this PR can be merged, it needs to be reviewed. Please keep in mind that reviewers are volunteers, and their response time can vary from a few hours to a few weeks depending on their availability and their knowledge of this particular part of CiviCRM.
  • A great way to speed up this process is to "trade reviews" with someone - find an open PR that you feel able to review, and leave a comment like "I'm reviewing this now, could you please review mine?" (include a link to yours). You don't have to wait for a response to get started (and you don't have to stop at one!) the more you review, the faster this process goes for everyone 😄
  • To ensure that you are credited properly in the final release notes, please add yourself to contributor-key.yml
  • For more information about contributing, see CONTRIBUTING.md.
Quick links for reviewers...

➡️ Online demo of this PR 🔗

@civibot civibot bot added the master label Jan 16, 2025
@mattwire mattwire force-pushed the membershiplogtimestamp branch 2 times, most recently from e75b04a to f162ee7 Compare January 16, 2025 11:53
@Sjord
Copy link
Contributor

Sjord commented Jan 16, 2025

  1. Would a default value of CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP make sense for this field?
  2. Isn't the correct date format string for a timestamp Y-m-d H:i:s instead of YmdHis?

@mattwire
Copy link
Contributor Author

  • Would a default value of CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP make sense for this field?

It's a log table, each entry is added as a history and not modified afterwards so it doesn't make sense in this case. The modified_date refers to the date the membership was modified.

  • Isn't the correct date format string for a timestamp Y-m-d H:i:s instead of YmdHis?

I don't think it matters as the DAO layer understands both.

@demeritcowboy
Copy link
Contributor

the membership test fails look related

@mattwire mattwire force-pushed the membershiplogtimestamp branch 2 times, most recently from ab49191 to d6c0e3a Compare January 16, 2025 18:52
@@ -379,12 +379,12 @@ public function testSubmitRecurCompleteInstant(): void {
$log = $this->callAPISuccessGetSingle('MembershipLog', ['membership_id' => $membership['id'], 'options' => ['limit' => 1, 'sort' => 'id DESC']]);
$this->assertEquals(CRM_Utils_Time::date($nextYear . '-01-01'), $log['start_date']);
$this->assertEquals(CRM_Utils_Time::date($nextYear . '-01-31'), $log['end_date']);
$this->assertEquals(CRM_Utils_Time::date('Y-m-d'), $log['modified_date']);
$this->assertEquals(date('Y-m-d'), CRM_Utils_Time::date('Y-m-d', strtotime($log['modified_date'])));
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason not to just change equals part to compare against the time too? We're using frozen time (the use of CRM_Utils_Time) in these tests so second rollovers won't be an intermittent issue. By removing CRM_Utils_Time and just using date() it's thawing out the time.

Suggested change
$this->assertEquals(date('Y-m-d'), CRM_Utils_Time::date('Y-m-d', strtotime($log['modified_date'])));
$this->assertEquals(CRM_Utils_Time::date('Y-m-d H:i:s'), $log['modified_date']);

I haven't run that but given that the PR is about ADDING a time component, it seems like we would want to test that time is getting used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough. Why do you say it's using frozen time? I can see the class but there are various options and I don't see where the input is set to frozen?

Copy link
Contributor

@demeritcowboy demeritcowboy Jan 16, 2025

Choose a reason for hiding this comment

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

Ah you're right it just sets a fixed "starting" time that the universe is relative to (in setUp). So if we do start getting second rollovers there is another method available to compare two numbers with a fudge factor: assertApproxEquals()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I've updated to use assertApproxEquals with a tolerance of 20 seconds

@mattwire mattwire force-pushed the membershiplogtimestamp branch 2 times, most recently from 8b99c2c to 33ff5e3 Compare January 16, 2025 19:49
@mattwire mattwire force-pushed the membershiplogtimestamp branch from 33ff5e3 to 5098c21 Compare January 17, 2025 10:23
@mattwire mattwire force-pushed the membershiplogtimestamp branch from 5098c21 to 2f207c1 Compare January 17, 2025 14:06
@civicrm civicrm deleted a comment from seamuslee001 Jan 17, 2025
@@ -379,7 +379,7 @@ public function testSubmitRecurCompleteInstant(): void {
$log = $this->callAPISuccessGetSingle('MembershipLog', ['membership_id' => $membership['id'], 'options' => ['limit' => 1, 'sort' => 'id DESC']]);
$this->assertEquals(CRM_Utils_Time::date($nextYear . '-01-01'), $log['start_date']);
$this->assertEquals(CRM_Utils_Time::date($nextYear . '-01-31'), $log['end_date']);
$this->assertEquals(CRM_Utils_Time::date('Y-m-d'), $log['modified_date']);
$this->assertApproxEquals(strtotime(CRM_Utils_Time::date('Y-m-d H:i:s')), strtotime($log['modified_date']), 20);
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 this can be simplified to just CRM_Utils_Time::time() but I'll put it up as a followup.

@demeritcowboy demeritcowboy merged commit e443b36 into civicrm:master Jan 18, 2025
1 check passed
@mattwire mattwire deleted the membershiplogtimestamp branch January 24, 2025 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants