How can I schedule bi-weekly jobs? - date

My app requires users to schedule recurring events that can recur daily, weekly, monthly, or bi-weekly.
By bi-weekly, I mean every fortnight (14 days) starting from an arbitrary date value provided at the time of creation.
My jobs table has two columns to support this: job_frequency_id and job_frequency_value. I'm able to schedule all types except for bi-weekly.
The first col is an FK to the job_frequencies table; it contains daily, weekly, monthy, bi-weekly values. The job_frequency_value contains the value corresponding to the frequency.
For example: If a job has a job_frquency_id == 3 and job_frequency_value == 10, it will run every 10th day of the month.
How do I add bi-weekly support without tampering with my db structure? I will use the job_frequency_value col to store the start date of the 14 day period, but I'm unsure of the calculation going forward.

Say your starting date is stored as a variable named 'createdDate'.
nextFortnight = DateAdd("ww", job_frequency_value*2, createdDate);

can you wrap your scheduled task in a and set it to run every week?
Something like
<cfif DateDiff('ww',CreateDate(2011,01,01),Today'sDate) MOD 2 EQ 1>
That way if the weeks are odd your scheduled task runs completely and if it's an odd week then it runs the scheduled task, but ignore all your code.

Related

Schedule Builds not adhering to CRON in Foundry

Schedule has been set to update this table between 14th to 25th of every month Mon-Fri. Although, the build got triggered recently on 12th of August which shouldn't happen according to the specified CRON.
The culprit seems to be a limitation of the cron expression, outside of Foundry - specifically this part:
The day of a command's execution can be specified by two fields — day of month, and day of week. If both fields are restricted (i.e., aren't *), the command will be run when either field matches the current time. For example, ``30 4 1,15 * 5'' would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday.
So the cron schedule 30 8 14-25 * 1-5 will run between the 14th and 25th of the month and every Monday through Friday. (See for example crontab.guru (https://crontab.guru/#30_8_14-25_*_1-5).)
The generated description for it is not accurate, unfortunately we don't have much control over it as we use a library to turn the cron expressions into human readable expressions.
Related:
https://unix.stackexchange.com/questions/602328/are-the-day-of-month-and-day-of-week-crontab-fields-mutually-exclusive
https://unix.stackexchange.com/questions/602216/when-will-an-interval-cron-execute-the-first-time-ex-3-days/602222#602222
https://blog.healthchecks.io/2022/09/schedule-cron-job-the-funky-way/

How to calculate YTD hours on a Crystal Report?

My company has a payroll program that prints payroll checks and pay stubs using Crystal Reports. The report selects payroll data from a table that has these columns: Hours, PeriodAmount, and YTDAmount. The hours are based on payroll period ending date. The report selects records based on a single pay period end date. So, hours would be selected for a single pay period only. However, we would like to print YTD hours on the pay stub. In other words, hours accumulated from beginning of year to current pay period. Since YTD hours is not a column in the table, would we need to include a sub report to accumulate hours? I don't think running totals would work since we are selecting a single period only. Any thoughts? Thanks.
Yes, a subreport is one option.
Another option is to select all pay periods in the current year and compute the total for the current period using a conditional total. For example, create af ormula that returns the hours if the record belongs to the current period and zero otherwise. Then, SUM that formula per employee. That SUM would give you the hours in the current period.

Weekly hour allocation problem in Rails and Postgresql

If I have a list of tasks with a certain date ranges, and the task is broken into weekly hour chunks of work (ie. 30 hours from 2018-12-31 to 2019-01-06 ... etc starting from Monday).
The kind of operations I would like to do are
Display all the weekly hours of all the tasks for a list of users
Sum the weekly hours for a user for all his tasks for the week
When the duration of the task is modified, create/destroy the weekly hour chunks.
Would it be more efficient to store these weekly records as
start date/end date/hours,
year/week number/hours
Storing start/end date probably give more flexibility to the table as it could potentially store non-weekly align hours.
Storing week number means given a date range, creating the weekly chunks is as simple as finding the week number of the start date and the week number of the end date, and populating the weeks in between (without converting to date ranges). Also easier validation for updating the hours for a week, as long as the week number is 1-53.
Wondering if anyone has tried out either option and can give any pointers on their preferred option.
I would probably go for a daterange column.
That gives you the flexibility to have differently sized chunks and allows you to define an exclusion constraint to prevent overlapping ranges.
Finding the row for a given week is still quite simple using the "contains" operator #>, e.g. where the_column #> to_date('2019-24', 'iyyy-iw') finds the row(s) that contain week number 24 in 2019.
The expression to_date('2019-24', 'iyyy-iw') returns the first day (Monday) of the specified week.
Finding all rows that are between two weeks can also be done, however construction the corresponding date range looks a bit ugly. You can either construction an inclusive range with the first and last day: daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-24', 'iyyy-iw') + 6, '[]')
Or you can create a range with an exclusive upper range with the next week's first day: daterange(to_date('2019-24', 'iyyy-iw'), to_date('2019-25', 'iyyy-iw'), '[)')
While ranges can be indexed quite efficiently and , the required GIST indexes are a bit more expensive to maintain than a B-Tree index on two integer columns.
Another downside of using ranges (if you don't really need the flexibility) is that they take up more space than two integer columns (14 byte instead of 8, or even 4 with two smallint). So if the size of the table is of any concern, then your current solution with the year/week columns is more efficient.
"Storing week number means given a date range, creating the weekly chunks is as simple as finding the week number of the start date and the week number of the end date"
If your input is a start and end date to begin with (rather than a "week number"), then I would definitely go for a daterange column. If that start and end date cover more than one week, then you store only one row, rather than multiple rows.

Configure sp_add_schedule to run on the first day of every X months/weeks

I need to configure my jobs scheduling dynamically.
The jobs will always run on the first day of the week once every X weeks. Same for months.
Looking at the documentation,
I see that for weeks option I would need to use freq_type=8 (weekly) with freq_interval=1 (Sunday). But which parameter should be used to mark that the repetition should be once every X weeks?
You should set freq_recurrence_factor = X

How to set workflow condition that runs 2AM everyday?

I am to create email alert which works together with workflow rule.
My goal is to set the workflow that runs 2am everyday &&
my custom object field 'startDate' is tomorrow.
Basically every 2am workflow checks my custom object and see if startDate is tomorrow.
I'm at workflow page looking at Date predefined variable,
I see:
DATE
DATEVALUE
DAY
MONTH
NOW
TODAY
YEAR
For the startDate, I can set condition startDate = today() + 1
For second condition which is 2am everyday I can't think of a way. I don't see HOUR variable etc..
Has anyone done this before?
UPDATE
This might work I have to test though..
Change NOW() datetime output to String (done by TEXT)
Start from index 12 and grab 2 chars to the right (done by MID)
This means I obtained hour part of current time and if the value equals to '02' which means
2am at night.
MID(TEXT(NOW()), 12, 2) = '02'
Wait a sec.. but WHEN does salesforce check this workflow???
If they check workflow once a day, what time it would be? If check is done past 2am, this workflow would never get looked at??? I'm a bit confused.
Work flow only triggers on some event (object update, create, etc.). So having it run at 2am without a some sort of trigger is impossible.
The trick is to use schedulable apex to insert an object (or update a field) every day at 2am and set your workflow to trigger on that insert/update. Then your workflow would fire off on that object at whatever time your scheduled apex ran.