﻿-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date, ,>
-- Description:	<Description, ,>
-- =============================================
CREATE FUNCTION [dbo].[date_add]
(
	@date date
	,@addition varchar(10)
	,@shift_to_first bit = 1
)
RETURNS date
AS
BEGIN
	DECLARE @Ret date = @date;
	SET @addition = LOWER(ISNULL(@addition,''));
	DECLARE @negative bit = 0;
	IF LEFT(@addition,1) = '-' 
		BEGIN
			SET @negative = 1;
			SET @addition = REPLACE(@addition, '-', '');
		END

	IF @addition like '[1-9]%[dwmqy]'
		BEGIN
			DECLARE @num int = TRY_CONVERT(int, LEFT(@addition, patindex('%[^0-9]%', @addition) - 1)) * IIF(@negative = 1, -1, 1), @unit varchar(2) = LOWER(RIGHT(@addition, LEN(@addition) - patindex('%[^0-9]%', @addition) + 1)) ;
			if @num is not null
			BEGIN
				
				SET @ret = CASE WHEN ISNULL(@shift_to_first,1) = 1 THEN 
									CASE 
										WHEN @unit = 'y' THEN DATEADD(YEAR, @num - 1, dbo.date_nextFirst(@date, 'y'))
										WHEN @unit = 'q' THEN DATEADD(QUARTER, @num - 1, dbo.date_nextFirst(@date, 'q'))
										WHEN @unit = 'm' THEN DATEADD(Month, @num - 1, dbo.date_nextFirst(@date, 'm'))
										WHEN @unit = 'w' THEN DATEADD(WEEK, @num - 1, dbo.date_nextFirst(@date, 'w'))
										WHEN @unit = 'd' THEN DATEADD(DAY, @num - 1, dbo.date_nextFirst(@date, 'd'))
										WHEN @unit in ('bd','wd') THEN [dbo].[AddBusinessDays](@date, @num)
										ELSE @date
									END
								ELSE 
									CASE 
										WHEN @unit = 'y' THEN DATEADD(YEAR, @num, @date)
										WHEN @unit = 'q' THEN DATEADD(QUARTER, @num, @date)
										WHEN @unit = 'm' THEN DATEADD(Month, @num, @date)
										WHEN @unit = 'w' THEN DATEADD(WEEK, @num, @date)
										WHEN @unit = 'd' THEN DATEADD(DAY, @num, @date)
										WHEN @unit in ('bd','wd') THEN [dbo].[AddBusinessDays](@date, @num)
										ELSE @date
									END
							END;
								
			END

		END

	RETURN @ret;

END