CREATE FUNCTION [dbo].[Kardeks](@Startdate SMALLDATETIME, @Enddate SMALLDATETIME,@WarehouseCode VARCHAR(3), @SellerCode VARCHAR(5) =NULL , @LessInventoiry INT)
RETURNS @Kardeks  TABLE
(
   GoodsCode VARCHAR(20),
   CountRow Int 
)


BEGIN 
	Declare @OldRemain Money 
	DECLARE @BeforeRemain MONEY
	DECLARE @CalcRemain MONEY
	DECLARE @AutoId BIGINT 
	DECLARE @Date SMALLDATETIME
	DECLARE @Row INT 
	DECLARE @DifferDate INT  = DATEDIFF(DAY,@StartDate, @EndDate)
	DECLARE @GoodsCode VARCHAR(20)
	DECLARE @CacheData AS TABLE
			(
				Line INT,
				Autoid BIGINT ,
				FactorType CHAR(10) ,
				Qty MONEY ,
				Remain MONEY , 
				FactorDate SMALLDATETIME,
				Radif INT 
			)

	DECLARE @TmpValue AS TABLE
			(
				GoodsCode VARCHAR(20),
				CountRow Int 
			)

	DECLARE @TmpFactor AS TABLE
			(
			Line INT,
			Autoid BIGINT ,
			FactorType CHAR(10) ,
			Qty MONEY ,
			Remain MONEY , 
			FactorDate SMALLDATETIME
			)

			DECLARE @CacheDate AS TABLE
			(
			  FactorDate SMALLDATETIME
			)

	INSERT INTO @CacheDate(FactorDate)
	SELECT date FROM dbo.Tbl_Dates WHERE date BETWEEN @Startdate AND @Enddate

	DECLARE CursorWarehouse CURSOR FOR
	SELECT K_Code GoodsCode
	From Havaleh WITH (NOLOCK)
	Inner Join HeadH WITH (NOLOCK) ON HeadH.Id_Havaleh = Havaleh.Id_Havaleh
	Where Reciver = @WarehouseCode
	AND CONVERT(VARCHAR(10), Tarikh_faktor,111) <= @EndDate 
	AND Sender = ISNULL(@SellerCode, Sender)
	GROUP BY K_Code

	OPEN CursorWarehouse
	FETCH NEXT FROM CursorWarehouse INTO @GoodsCode 
	WHILE @@FETCH_STATUS = 0 
	BEGIN
		DELETE FROM @TmpFactor
		DELETE FROM @CacheData

		SELECT @OldRemain =ISNULL(SUM(NumberOfEntries),0) - ISNULL(SUM(NumberOfOutputs),0) 
		FROM (
			  SELECT K_Code GoodsCode, Tarikh_faktor,
			  CASE 
				WHEN HeadH.Kind_Flag in (2,3,6,8,0,1) THEN Reciver
			  ELSE Sender
			  END WarehouseCode,
			  Case 
				When HeadH.Kind_Flag in (2,3,6,8,0,1) And Havaleh.Reciver = @WarehouseCode Then Sum(K_Qty1)
			  End As NumberOfEntries,
			  Case
				When HeadH.Kind_Flag in (5,7,9,4,1) And Havaleh.Sender = @WarehouseCode Then Sum(K_Qty1)
			  End As NumberOfOutputs
			  From Havaleh WITH (NOLOCK)
			  Inner Join HeadH WITH (NOLOCK) ON (HeadH.Id_Havaleh = Havaleh.Id_Havaleh)
       		  WHERE K_Code = @GoodsCode
			  And (Sender = @WarehouseCode Or Reciver = @WarehouseCode)
       		  AND CONVERT(VARCHAR(10), Tarikh_faktor,111) < @StartDate 
			  Group By HeadH.Kind_Flag, K_Code, Havaleh.Sender, Havaleh.Reciver, Tarikh_faktor
			 ) AS T

		SET @BeforeRemain = @OldRemain
		SET @CalcRemain = 0 
		SET @OldRemain = ISNULL(@OldRemain,0)

		INSERT @CacheData(FactorType, Qty, Autoid, FactorDate, Radif)
		SELECT Kind_Flag, k_qty1, Autoid, FactorDate, table2.radif FROM( 
		select 
		CASE 
 		  WHEN table1.Kind_Flag IN(5,7,9,4) THEN -table1.K_Qty1
		  WHEN table1.Kind_Flag = 1 AND Sender = @WarehouseCode THEN -table1.K_Qty1
		ELSE table1.K_Qty1
		END as k_qty1 ,k_code,table1.FactorDate,AutoId,table1.Kind_Flag,
		case 
		when Kind_Flag=2 then 1 
		when Kind_Flag=3 then 2 
		when Kind_Flag=6 then 3 
		when Kind_Flag=8 then 4 
		when Kind_Flag=0 then 5 
		when Kind_Flag=1 then 6 
		when Kind_Flag=4 then 7 
		when Kind_Flag=5 then 8 
		when Kind_Flag=7 then 9 
		when Kind_Flag=9 then 10 
		end as radif 
		FROM ( 
		SELECT Sum(Havaleh.K_Qty1) K_Qty1,headH.Kind_Flag,Sender, Reciver, 
		Havaleh.K_Code, Headh.Tarikh_Faktor as FactorDate, Havaleh.AutoId 
		FROM headH WITH (NOLOCK) 
		INNER JOIN Havaleh WITH (NOLOCK) ON headH.Id_Havaleh =Havaleh.Id_Havaleh 
		INNER JOIN KalaId WITH (NOLOCK) ON dbo.Havaleh.K_Code = KalaId.K_Code 
		WHERE Havaleh.K_Code= @GoodsCode 
		And (Havaleh.Sender = @WarehouseCode OR Havaleh.Reciver = @WarehouseCode ) 
		AND CONVERT(VARCHAR(10),Tarikh_faktor,111) BETWEEN @Startdate AND @Enddate
		GROUP by Havaleh.K_Code,headH.Kind_Flag,Headh.Tarikh_Faktor,Havaleh.AutoId,Sender,Reciver
		) table1 
		)table2 
	  ORDER by FactorDate,radif, AutoId 
  
	  DECLARE CursorCache CURSOR FOR 
	  SELECT AutoId , Qty FROM @CacheData 
	  OPEN CursorCache 
	  FETCH NEXT FROM CursorCache INTO @AutoId , @CalcRemain 
	  WHILE @@FETCH_STATUS = 0 
	  BEGIN 
		 UPDATE @CacheData Set Remain = @OldRemain + @CalcRemain
		 WHERE AutoId = @AutoId 
		 SET @OldRemain = @OldRemain + @CalcRemain 
		 FETCH NEXT FROM CursorCache INTO @AutoId , @CalcRemain 
	  END 
	  CLOSE CursorCache 
	  DEALLOCATE CursorCache 
  
	  INSERT INTO @TmpFactor(Line, Autoid, FactorType, Qty, Remain, FactorDate) 
	  SELECT ROW_NUMBER() OVER(ORDER BY Autoid) line, Autoid, FactorType,  Qty , Remain, [@CacheDate].FactorDate FactorDate FROM @CacheDate
	  LEFT OUTER JOIN @CacheData ON [@CacheData].FactorDate = [@CacheDate].FactorDate
	  ORDER by FactorDate,radif, AutoId 

	  DECLARE CursorFactor CURSOR FOR
	  SELECT ROW_NUMBER() OVER(ORDER BY Autoid) Row, Autoid, Remain  FROM @TmpFactor
	  ORDER BY FactorDate, Autoid
	  OPEN CursorFactor
	  FETCH NEXT FROM CursorFactor INTO @Row, @Autoid, @CalcRemain
	  WHILE @@FETCH_STATUS = 0
	  BEGIN
		IF @Autoid IS NULL 
		  UPDATE @TmpFactor SET Remain = @BeforeRemain WHERE Line = @Row
		ELSE
		  SET @BeforeRemain = @CalcRemain
		FETCH NEXT FROM CursorFactor INTO @Row, @Autoid, @CalcRemain
	  END
	  CLOSE CursorFactor
	  DEALLOCATE CursorFactor
      
	  INSERT INTO @TmpValue(GoodsCode, CountRow)
	  SELECT @GoodsCode, ABS(@DifferDate - COUNT(0)) FROM @TmpFactor
      WHERE Remain <=@LessInventoiry  AND ISNULL(FactorType,0) NOT IN(1,8) 
	  AND Qty IS Null   

	  FETCH NEXT FROM CursorWarehouse INTO @GoodsCode 
  END
  CLOSE CursorWarehouse
  DEALLOCATE CursorWarehouse
  INSERT INTO @Kardeks(GoodsCode, CountRow)
  SELECT GoodsCode, CountRow FROM @TmpValue
  RETURN
END
