IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SP_STOKMIADBAKIYESAYIM_INSERT]') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
DROP PROCEDURE SP_STOKMIADBAKIYESAYIM_INSERT
GO

create PROCEDURE SP_STOKMIADBAKIYESAYIM_INSERT
(
    @SUBEID INT,
    @DEPOID INT,
    @DONEMSON DATE,
    @BATCHSIZE INT = 100
)
AS
BEGIN
    SET NOCOUNT ON;

    BEGIN TRY

        
        BEGIN TRAN

        
        IF OBJECT_ID('tempdb..#DATA') IS NOT NULL DROP TABLE #DATA

        CREATE TABLE #DATA
        (
            ID INT IDENTITY(1,1) PRIMARY KEY,
            SUBEID INT,
            DEPOID INT,
            STOKID INT,
            SKTARIHI DATE,
            TARIH DATE,
            MIKTAR DECIMAL(18,4)
        )

        -------------------------------------------------
        -- AĞIR SORGU (1 KEZ)
        -------------------------------------------------
-------------------------------------------------
        -- AĞIR SORGU (OPTİMİZE EDİLMİŞ)
        -------------------------------------------------
        
        -- 1. ADIM: İhtiyaç duyulan max tarihleri önceden hesaplayıp değişkenlere atıyoruz.
        -- Bu işlem SQL Server'ı her satır için MAX(TARIH) aramaktan kurtarır.
        DECLARE @SON_SAYIM_TARIHI DATE;
        DECLARE @ONCEKI_SAYIM_TARIHI DATE;

        -- VWSTOKISL için son sayım tarihi
        SELECT @SON_SAYIM_TARIHI = ISNULL(MAX(TARIH), '19000101')
        FROM SAYIMDONEM
        WHERE KAPANDI = 1 
          AND SUBEID = @SUBEID 
          AND DEPOID = @DEPOID;

        -- Önceki sayım dönemi (UNION ALL altındaki sorgu için)
        SELECT @ONCEKI_SAYIM_TARIHI = MAX(TARIH)
        FROM SAYIMDONEM
        WHERE KAPANDI = 1 
          AND SUBEID = @SUBEID 
          AND DEPOID = @DEPOID 
          AND TARIH < @DONEMSON;

        -- 2. ADIM: CTE ile verileri toparlayıp tek seferde INSERT ediyoruz.
        ;WITH CTE_MIKTAR AS (
            -- BÖLÜM A: VWSTOKISL Hareketleri
            SELECT 
                SI.STOKID, 
                SI.SKTARIHI, 
                SUM(SI.GCADET) AS MIKTAR 
            FROM VWSTOKISL SI
            WHERE SI.SUBEID = @SUBEID
              AND SI.DEPOID = @DEPOID
              AND SI.MIADZORUNLU = 1
              AND SI.TARIH > @SON_SAYIM_TARIHI
              AND SI.TARIH <= @DONEMSON
            GROUP BY SI.STOKID, SI.SKTARIHI

            UNION ALL

            -- BÖLÜM B: Önceki Sayım Bakiyeleri
            SELECT 
                SKTSAYIM.STOKID, 
                SKTSAYIM.SKTARIHI, 
                SKTSAYIM.SAYIM AS MIKTAR
            FROM STOKMIADBAKIYESAYIM SKTSAYIM
            INNER JOIN SAYIM2 SAYIM 
                ON SAYIM.SUBEID = SKTSAYIM.SUBEID 
               AND SAYIM.DEPOID = SKTSAYIM.DEPOID 
               AND SAYIM.TARIH = SKTSAYIM.TARIH
               AND SAYIM.STOKID = SKTSAYIM.STOKID
            INNER JOIN STOK 
                ON SKTSAYIM.STOKID = STOK.STOKID
            INNER JOIN STOKGRUP 
                ON STOK.GRUP = STOKGRUP.KODU
            WHERE SKTSAYIM.SUBEID = @SUBEID
              AND SKTSAYIM.DEPOID = @DEPOID
              AND SAYIM.TARIH = @ONCEKI_SAYIM_TARIHI -- Tarihi değişkenden alıyoruz
              AND STOKGRUP.MIADZORUNLU = 1
              AND ISNULL(SKTSAYIM.SAYIM, 0) <> 0
        ),
        CTE_TOPLAM AS (
            -- Sube ve Depo zaten parametre olduğu için sadece Stok ve SKT bazında grupluyoruz
            SELECT 
                STOKID, 
                SKTARIHI, 
                SUM(MIKTAR) AS MIKTAR
            FROM CTE_MIKTAR
            GROUP BY STOKID, SKTARIHI
        )
        
        -- BÖLÜM C: Ana Insert İşlemi (NOT EXISTS kullanımı ile)
        INSERT INTO #DATA (SUBEID, DEPOID, STOKID, SKTARIHI, TARIH, MIKTAR)
        SELECT 
            @SUBEID, 
            @DEPOID, 
            CT.STOKID, 
            CT.SKTARIHI, 
            @DONEMSON, 
            CT.MIKTAR 
        FROM CTE_TOPLAM CT
        INNER JOIN SAYIM2 SYM 
            ON SYM.SUBEID = @SUBEID 
           AND SYM.DEPOID = @DEPOID 
           AND SYM.STOKID = CT.STOKID 
           AND SYM.TARIH = @DONEMSON
        WHERE NOT EXISTS (
            SELECT 1 
            FROM STOKMIADBAKIYESAYIM SKTSYM 
            WHERE SKTSYM.SUBEID = @SUBEID 
              AND SKTSYM.DEPOID = @DEPOID 
              AND SKTSYM.STOKID = CT.STOKID 
              AND SKTSYM.SKTARIHI = CT.SKTARIHI 
              AND SKTSYM.TARIH = @DONEMSON
        );

        -------------------------------------------------
        -- BATCH INSERT
        -------------------------------------------------
        DECLARE @MINID INT = 1
        DECLARE @MAXID INT

        SELECT @MAXID = MAX(ID) FROM #DATA

        WHILE @MINID <= @MAXID
        BEGIN
            INSERT INTO STOKMIADBAKIYESAYIM
                (SUBEID, DEPOID, STOKID, SKTARIHI, TARIH, MIKTAR)
            SELECT 
                SUBEID, DEPOID, STOKID, SKTARIHI, TARIH, MIKTAR
            FROM #DATA
            WHERE ID BETWEEN @MINID AND (@MINID + @BATCHSIZE - 1)

            SET @MINID = @MINID + @BATCHSIZE
        END

        
        COMMIT TRAN

    END TRY

    BEGIN CATCH

       
        IF @@TRANCOUNT > 0
            ROLLBACK TRAN

     
        DECLARE @HATA NVARCHAR(4000) = ERROR_MESSAGE()
        DECLARE @HATA_NO INT = ERROR_NUMBER()
        DECLARE @HATA_LINE INT = ERROR_LINE()

        RAISERROR (
            'SP_STOK_MIAD_SAYIM_PRO HATA! No:%d Line:%d Mesaj:%s',
            16, 1,
            @HATA_NO, @HATA_LINE, @HATA
        )

        RETURN

    END CATCH

END