Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

Send timer reminder emails #16

Merged
merged 18 commits into from Apr 24, 2015
Merged

Send timer reminder emails #16

merged 18 commits into from Apr 24, 2015

Conversation

laserlemon
Copy link
Contributor

If a user hasn't started a timer by a configured time in the morning, he or she receives an email reminder to either start a timer or to update the Zenefits PTO calendar. If the user already has PTO scheduled in the Zenefits calendar, a reminder is never sent.

TODO

  • Determine appropriate morning check-in time (10am Eastern)
  • Send reminders at the specified time in the user's time zone
  • Set up rake hourglass:send_timer_reminders on Heroku scheduler
  • Skip timer reminders for holidays and scheduled PTO
  • Set ZENEFITS_PTO_CALENDAR_URL in production
  • Set up rake hourglass:sync_pto on Heroku scheduler

@laserlemon laserlemon added the WIP label Apr 21, 2015
@laserlemon
Copy link
Contributor Author

My thought is that 10am Eastern is a fair time to expect a timer to have started, considering the expectation of attendance at the 9:30am standup.

Also, because the standup is always at 9:30am Eastern time, we might be able to punt for now on sending these reminders in the user's time zone.

This allows us to check timers at multiple times throughout the day
without spamming people. This is especially useful so that we can time
the email deliveries based on factors like the user's time zone or the
application time zone's current UTC offset.

def call
User.all.each do |user|
next if user.timer_reminder_sent_on.try(:today?)
Copy link
Member

Choose a reason for hiding this comment

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

You can do al this in SQL, because if you pass a TimeWithZone into a query, Rails will figure out the TZ stuff for you.

Copy link
Member

Choose a reason for hiding this comment

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

User.where.not(timer_reminder_sent_on: Date.today) i think.

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'll drop that in and see if it's 💚.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

💣 The problem is that we want to continue past line 11 if the user's never had a timer reminder set, as well.

Copy link
Member

Choose a reason for hiding this comment

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

Or to the rescue!

User.where("timer_reminder_sent_on < ? OR timer_reminder_sent_on IS NULL", Date.current)

Copy link
Member

Choose a reason for hiding this comment

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

I think that performs an inner join so would only match users that have days recorded in hourglass.
The pto check is a more complicated query

Copy link
Member

Choose a reason for hiding this comment

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

Ok @laserlemon you're going to hate this and @trestrantham is going to love it ;)

User.where("timer_reminder_sent_on < ? OR timer_reminder_sent_on IS NULL", context.date).
  joins(
    User.arel_table.join(Day.arel_table, Arel::Nodes::OuterJoin).on(
      Day.arel_table[:user_id].eq(User.arel_table[:id]).and(
        Day.arel_table[:date].eq(context.date).and(Day.arel_table[:pto].eq(false))
      )
    ).join_sources
  )

Tests pass with this locally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ha! Remember what I said about clarity? :trollface:

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'm going to go the route of assuming that the user already has a day recorded because of how often new hours are fetched for the day and because of how this particular interactor is scheduled for later in the morning. That also gives us the benefit of not having to call out to Harvest so we can keep this all in the model.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated in 9b74755.

@laserlemon laserlemon removed the WIP label Apr 21, 2015
@laserlemon
Copy link
Contributor Author

👀 🙏

@danielmorrison
Copy link
Member

Have you thought about putting the "sent" flag on the Day class? It would require you to create more Day records but might be clearer.

@laserlemon
Copy link
Contributor Author

@danielmorrison What do you mean by the "sent" flag?

@danielmorrison
Copy link
Member

Tracking when you sent the reminder

Daniel Morrison
[i] Collective Idea
http://collectiveidea.com
http://get.harmonyapp.com
44 East 8th Street, Suite 410
Holland, MI 49423
616-990-0155
daniel@collectiveidea.com

On Apr 22, 2015, at 11:38 AM, Steve Richert notifications@github.com wrote:

@danielmorrison What do you mean by the "sent" flag?


Reply to this email directly or view it on GitHub.

@laserlemon
Copy link
Contributor Author

Oh, that's an interesting thought. I'll take a look when I have some time.

@laserlemon
Copy link
Contributor Author

Yeah, storing that on the day is way better. Great idea. Implementing now.

timer_reminder_sent: false
)
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@danielmorrison I think this makes a lot more sense for querying for timer reminders.

@laserlemon
Copy link
Contributor Author

:shipit:

This ensures that nobody gets a timer reminder email before he or she is
expected to be working.
This information will be used in analytics and in determining whether to
send timer reminders to users.
This will be used to parse the PTO calendar provided by Zenefits.
This will run periodically to keep Hourglass in step with Zenefits, and
should run before timer reminders are sent out so that nobody is sent a
timer reminder on his or her day off.
The last thing we want to do is bug somebody on vacation!
This should be able to be run from the console for any day you like.
Rather than making an external call to Harvest, we can rely on the data
we have being up to date enough to determine whether a user has started
a timer yet today.

This also removes the ability for this particular interactor to be
callable with a custom date because it doesn't make as much sense in
this context as it does for an interactor like FetchDailyHours.

The change also fixes a bug where a user's timer_reminder_sent_on column
was updated even if no reminder was necessary.
…rather than users. This makes it much easier to keep track of several
days that have already had reminders sent, rather than just the last
one.
This now makes more sense as timer reminders are controlled by
individual days themselves rather than by user records.
@laserlemon
Copy link
Contributor Author

This is now deployed for "real world" testing.

danielmorrison added a commit that referenced this pull request Apr 24, 2015
@danielmorrison danielmorrison merged commit 2e44fe2 into master Apr 24, 2015
@danielmorrison danielmorrison deleted the timer-reminder branch April 24, 2015 15:20
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants