Here's a little SP I wrote that I thought might be useful. Feel free to improve on it.
To use it, run the create script below on the database,and then set the 'Send a reminder when their status reports are ___ overdue' in Personal Settings under 'My Resources' Status Reports' in the 'Manage My Resources' Alerts and Reminders ' section.
Now I know that this is not what that reminder is intended for but I don't use that feature anyway and its a convenient flag to use.
What it does (perhaps a little clumsily) is to detect any subscription to that reminder option and then send an email to the subscriber in HTML format identifying missing or otherwise incomplete timesheets - if applicable.
What it does not do: It does not use the frequency and periods overdue settings.
I simply scheduled the SP to run on a Monday Afternoon using the database scheduler, weekly and it sends a reminder to any manager who cares enough to subscribe.
USE [ProjectServer_Published_production]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[SDP_SEND_TIMESHEET_REMINDERS]
AS
BEGIN
--DECLARE @MANAGER_UID AS UNIQUEIDENTIFIER
DECLARE @MANAGER_NAME AS VARCHAR(512)
DECLARE @MANAGER_EMAIL AS VARCHAR(512)
DECLARE @MANAGER_UID AS UNIQUEIDENTIFIER
DECLARE @RES_NAME AS VARCHAR(512)
DECLARE @RES_EMAIL AS VARCHAR(512)
DECLARE @RES_UID AS UNIQUEIDENTIFIER
DECLARE @TIMESHEET_START_DATE AS DATETIME
DECLARE @TIMESHEET_START_DATE_TEXT AS VARCHAR(30)
DECLARE @TIMESHEET_TOTAL AS DECIMAL(26,5)
DECLARE @TIMESHEET_TOTAL_TEXT AS VARCHAR(5)
DECLARE @TIMESHEET_STATUS AS SMALLINT
DECLARE @TIMESHEET_STATUS_TEXT AS VARCHAR(30)
DECLARE @EMAIL_MESSAGE AS VARCHAR(MAX)
DECLARE TIMESHEET_MANAGERS_CURSOR CURSOR STATIC FOR
SELECT
DISTINCT RES_UID FROM dbo.MSP_REMINDER_SUBSCRIPTION
WHERE
REMINDER_UID IN('bb4edde0-a868-4753-a0f2-d8dfef2ffed1','1c654c08-ea4f-4aa8-8fcd-610f5d51b3f0')
OPEN TIMESHEET_MANAGERS_CURSOR
FETCH NEXT FROM TIMESHEET_MANAGERS_CURSOR INTO @MANAGER_UID
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @MANAGER_NAME = (SELECT RES_NAME FROM MSP_RESOURCES WHERE RES_UID = @MANAGER_UID)
SET @EMAIL_MESSAGE = '<table border="1"><tr><th>Resource</th><th>Period</th><th>Status</th><th>Total</th></tr>'
DECLARE MISSING_TIMESHEETS_CURSOR CURSOR STATIC FOR
SELECT DISTINCT
Managers.RES_NAME AS MGR_NAME,
Managers.WRES_EMAIL AS MGR_EMAIL,
Managers.RES_UID AS MGR_UID,
Resources.RES_NAME AS TS_USER_NAME,
Resources.WRES_EMAIL AS TS_USER_EMAIL,
Resources.RES_UID AS TS_USER_UID,
Timesheets.WPRD_START_DATE,
Timesheets.TS_GRAND_TOTAL_ACT_VALUE,
Timesheets.TS_STATUS_ENUM
FROM
(SELECT
RESOURCE_TIME_PERIODS.RES_UID,
RESOURCE_TIME_PERIODS.WPRD_START_DATE,
RESOURCE_TIME_PERIODS.WPRD_UID,
dbo.MSP_RESOURCES.RES_NAME,
ISNULL(dbo.MSP_TIMESHEETS.TS_GRAND_TOTAL_ACT_VALUE / 1000 / 60, 0) AS TS_GRAND_TOTAL_ACT_VALUE,
ISNULL(dbo.MSP_TIMESHEETS.TS_STATUS_ENUM, 10) AS TS_STATUS_ENUM
FROM
(
SELECT
MSP_WEB_TIME_PERIODS_1.WPRD_UID,
MSP_RESOURCES_1.RES_UID,
MSP_WEB_TIME_PERIODS_1.WPRD_START_DATE
FROM
dbo.MSP_RESOURCES AS MSP_RESOURCES_1 INNER JOIN
dbo.MSP_WEB_TIME_PERIODS AS MSP_WEB_TIME_PERIODS_1 ON
MSP_RESOURCES_1.RES_HIRE_DATE <= MSP_WEB_TIME_PERIODS_1.WPRD_START_DATE
WHERE
(MSP_RESOURCES_1.RES_TYPE = 2)
) AS RESOURCE_TIME_PERIODS INNER JOIN
dbo.MSP_RESOURCES ON
RESOURCE_TIME_PERIODS.RES_UID = dbo.MSP_RESOURCES.RES_UID LEFT OUTER JOIN
dbo.MSP_TIMESHEETS ON
RESOURCE_TIME_PERIODS.RES_UID = dbo.MSP_TIMESHEETS.RES_UID AND
RESOURCE_TIME_PERIODS.WPRD_UID = dbo.MSP_TIMESHEETS.WPRD_UID
WHERE
(dbo.MSP_TIMESHEETS.TS_UID IS NOT NULL) AND
(RESOURCE_TIME_PERIODS.WPRD_START_DATE < GETDATE() AND
(dbo.MSP_TIMESHEETS.TS_STATUS_ENUM < 3)) OR
((dbo.MSP_TIMESHEETS.TS_UID IS NULL) AND
(RESOURCE_TIME_PERIODS.WPRD_START_DATE < GETDATE()))
) AS Timesheets INNER JOIN
dbo.MSP_RESOURCES AS Resources ON Timesheets.RES_UID = Resources.RES_UID INNER JOIN
dbo.MSP_RESOURCES AS Managers INNER JOIN
dbo.MSP_REMINDER_SUBSCRIPTION AS Subscriptions ON
Managers.RES_UID = Subscriptions.RES_UID ON
Resources.RES_TIMESHEET_MGR_UID = Subscriptions.RES_UID
WHERE
Subscriptions.REMINDER_UID IN('bb4edde0-a868-4753-a0f2-d8dfef2ffed1', '1c654c08-ea4f-4aa8-8fcd-610f5d51b3f0') AND
Resources.RES_TYPE = 2 AND
Managers.RES_UID = @MANAGER_UID
OPEN MISSING_TIMESHEETS_CURSOR
FETCH NEXT FROM MISSING_TIMESHEETS_CURSOR INTO
@MANAGER_NAME,
@MANAGER_EMAIL,
@MANAGER_UID,
@RES_NAME,
@RES_EMAIL,
@RES_UID,
@TIMESHEET_START_DATE,
@TIMESHEET_TOTAL,
@TIMESHEET_STATUS
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @TIMESHEET_START_DATE_TEXT = CONVERT(VARCHAR(30),@TIMESHEET_START_DATE,103)
SET @TIMESHEET_TOTAL_TEXT = CONVERT(VARCHAR(26),@TIMESHEET_TOTAL)
SET @TIMESHEET_STATUS_TEXT =
CASE @TIMESHEET_STATUS
WHEN 0 THEN 'In progress'
WHEN 1 THEN 'Submitted'
WHEN 2 THEN 'Acceptable'
WHEN 3 THEN 'Approved'
WHEN 4 THEN 'Rejected'
WHEN 5 THEN 'Pending submission (PM needs to approve)'
ELSE 'Missing'
END
SET @EMAIL_MESSAGE = @EMAIL_MESSAGE + '<tr><td>'+@RES_NAME+'</td><td>'+@TIMESHEET_START_DATE_TEXT+'</td><td>'+@TIMESHEET_STATUS_TEXT+'</td><td>'+@TIMESHEET_TOTAL_TEXT+'</td></tr>'
FETCH NEXT FROM MISSING_TIMESHEETS_CURSOR INTO
@MANAGER_NAME,
@MANAGER_EMAIL,
@MANAGER_UID,
@RES_NAME,
@RES_EMAIL,
@RES_UID,
@TIMESHEET_START_DATE,
@TIMESHEET_TOTAL,
@TIMESHEET_STATUS
END
SET @EMAIL_MESSAGE = @EMAIL_MESSAGE+ '</tr></table>'
exec [msdb].[dbo].[sp_send_dbmail] @profile_name = 'Timesheets', @recipients = @MANAGER_EMAIL, @subject = 'Timesheet reminder service', @body = @EMAIL_MESSAGE , @body_format = 'HTML'
CLOSE MISSING_TIMESHEETS_CURSOR
DEALLOCATE MISSING_TIMESHEETS_CURSOR
FETCH NEXT FROM TIMESHEET_MANAGERS_CURSOR INTO @MANAGER_UID
END
CLOSE TIMESHEET_MANAGERS_CURSOR
DEALLOCATE TIMESHEET_MANAGERS_CURSOR
END
GO