Oh my gosh, so many things going wrong here.
Converting all of these date/datetime values to strings. Don't do it. Date and datetime values are dates and datetime values - converting them to strings causes all kinds of bad things like lack of validation, inability to use indexes for seeks or range scans, dropping of all kinds of in-built date function support, etc.
I think this query is much tidier by avoiding all of the conversions to strings, and also gives you a much better shot at index usage, should an index ever exist on StartDate
(today or in the future).
AND
(
(
pur.StudyYearID <= @StudyYear
AND pur.StartDate >= @d AND
AND pur.StartDate < DATEADD(YEAR, 1, @next_year)
)
OR
(
pur.StudyYearID > @StudyYear
AND pur.StartDate >= DATEADD(YEAR, YEAR(GETDATE())
+ SUBSTRING(pur.StudyYearID, 2, 1) - LEFT(@WorkGroup, 1) - 1900, 0)
AND pur.StartDate < DATEADD(YEAR, 1 + YEAR(GETDATE())
+ SUBSTRING(pur.StudyYearID, 2, 1) - LEFT(@WorkGroup, 1) - 1900, 0)
)
)