DELIMITER $$

DROP PROCEDURE IF EXISTS `pl_NaliczProgFrekw`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `pl_NaliczProgFrekw`(
	IN _MODE VARCHAR(250),
	IN _GUID VARCHAR(38),
	IN _Param_A VARCHAR(255),	
	IN _Param_B VARCHAR(255),	
	IN _Param_C VARCHAR(255),	
	IN _Param_D VARCHAR(255)	
)
SPROC: BEGIN

	DECLARE _SQLText TEXT DEFAULT '';
	
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------	
	'spr.ciaglosc.zwoln'
		Sprawdzanie ciągłości zwolnienia chorobowego (nr zadania:  41096)
		"Jeżeli w czasie rejestracji zwolnienia okaże się, że w okresie tego zwolnienia 
		 mija 150,170,182 dzień CIĄGŁEGO zwolnienia -> dać komunikat -> TA SAMA CHOROBA."
		UWAGA wynik naliczenia umieszczamy w @frekw.tool.suma
		Parametry
			_GUID		GUID pracownika
			_Param_A	Data poczatkowa rejestrowanej absencji
			_Param_B	Data koncowa rejestrowanej absencji
		CALL pl_NaliczProgFrekw('spr.ciaglosc.zwoln', @_Prac, '2016-04-22', '2016-08-29', '', '');		
------------------------------------------------------------------------------------------------------------------------------------------------------------------*/	
	IF _MODE = 'spr.ciaglosc.zwoln' THEN  
	    SET  @frekw.tool.Zmiana = 0;
	
		-- dlugosc (w dniach) aktualnie rejestrowanej absencji
		SELECT ( TO_DAYS(_Param_B) - TO_DAYS(_Param_A) ) INTO @frekw.tool.AbsIleDni;  
	
		/* spr., czy suma (dotychczas zarejestrowane nieob. +  aktualna nieobecnosc )  przekracza progi (150,170,182)
		  (analizujemy dotad zarejestrowane absencje z okresu: od dnia poprzedzajacego aktualnie rejestrowaną  do dnia (Prog - dlugosc akt. absencji) wstecz,
		  dzieki czemu analizujemy tylko te przypadki, gdzie przekroczenie progu ma miejsce w aktualnie rejestrowanej absencji
		*/
		SET _SQLText =  
		'SELECT SUM(1) AS sDni, SUM(IF(absencja=''C'', 1, 0)) AS sDniC
		 FROM frekw_po
         WHERE PracGUID = ''##PracGUID##'' 
			AND rok_msc_dzien BETWEEN DATE_SUB(''##AktDataOd##'', INTERVAL (##Prog## - @frekw.tool.AbsIleDni + 1) DAY)  AND DATE_SUB(''##AktDataOd##'', INTERVAL 1 DAY)
		 INTO @frekw.tool.sDni, @frekw.tool.sDniC
		';
		SET @frekw.tool.Prog = 150;
		SET @frekw.tool.SQLText = REPLACE(_SQLText, '##PracGUID##', _GUID);
		SET @frekw.tool.SQLText = REPLACE(@frekw.tool.SQLText, '##AktDataOd##', _Param_A);
		SET @frekw.tool.SQLText = REPLACE(@frekw.tool.SQLText, '##Prog##', _varSTR(@frekw.tool.Prog));		
		CALL _ExecuteCmd(@frekw.tool.SQLText, @Error);
		
		--  sformulowanie "mija 150,170,182 dzień CIĄGŁEGO zwolnienia" -> przyjęto, że musi być przekroczenie progu (warunek ">" a nie ">=")
		SET @frekw.tool.s150 = (@frekw.tool.sDni = @frekw.tool.sDniC) AND (@frekw.tool.sDniC + @frekw.tool.AbsIleDni  > @frekw.tool.Prog);
		IF NOT @frekw.tool.s150 THEN  -- brak ciaglosci lub brak przekroczenia progu
			SELECT 0 AS przekroczenie, 0 AS prog; 
			LEAVE SPROC;
		ELSE  -- byla ciaglosc i przekroczono prog 150 dni, teraz sprawdzamy, czy przekroczono prog 170 dni	;		
			SET @frekw.tool.Prog = 170;
			SET @frekw.tool.SQLText = REPLACE(_SQLText, '##PracGUID##', _GUID);
			SET @frekw.tool.SQLText = REPLACE(@frekw.tool.SQLText, '##AktDataOd##', _Param_A);
			SET @frekw.tool.SQLText = REPLACE(@frekw.tool.SQLText, '##Prog##', _varSTR(@frekw.tool.Prog));		
			CALL _ExecuteCmd(@frekw.tool.SQLText, @Error);
			
			SET @frekw.tool.s170 = (@frekw.tool.sDni = @frekw.tool.sDniC) AND (@frekw.tool.sDniC + @frekw.tool.AbsIleDni  > @frekw.tool.Prog);
			
			IF NOT @frekw.tool.s170 THEN
				-- przekroczony prog 150 dni, nieprzekroczony prog 170 dni				
				SELECT 1 AS przekroczenie, 150 AS prog; 
				LEAVE SPROC;				
			ELSE 	-- byla ciaglosc i przekroczono prog 170 dni, teraz sprawdzamy, czy przekroczono prog 182 dni	;	
				SET @frekw.tool.Prog = 182;
				SET @frekw.tool.SQLText = REPLACE(_SQLText, '##PracGUID##', _GUID);
				SET @frekw.tool.SQLText = REPLACE(@frekw.tool.SQLText, '##AktDataOd##', _Param_A);
				SET @frekw.tool.SQLText = REPLACE(@frekw.tool.SQLText, '##Prog##', _varSTR(@frekw.tool.Prog));		
				CALL _ExecuteCmd(@frekw.tool.SQLText, @Error);
				
				SET @frekw.tool.s182 = (@frekw.tool.sDni = @frekw.tool.sDniC) AND (@frekw.tool.sDniC + @frekw.tool.AbsIleDni  > @frekw.tool.Prog);
				/* jesli przekroczono   prog 170 dni a nie przekroczono progu 182 dni, to właczamy znacznik zmiany
				   jesli przekroczono   prog 170 dni oraz przekroczono prog 182 dni, to j.w.
				   (ewentualnie trzebaby badac, czy długosc dotych. zarejestrowanych abencji jest w przedziale (170, 181) - jesli tak, oraz jesli
				    przekroczono prog 182 dni to wł.znacznik)
				*/
                SELECT 1 AS przekroczenie, IF(@frekw.tool.s182, 182, 170) AS prog; 			
			END IF;	
		END IF;
	
				
	END IF;	--	IF _MODE = 'spr.ciaglosc.zwoln' 	
	
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------	
	'calc.na.dzien'
		Nalicza/sprawdza dla pracownika _GUID w frekw na dzien _Param_A 
		Parametry
			_GUID		GUID pracownika
			_Param_A	Dzien
			_Param_D	'rok' - przełom roku; 'hp' - zmiana w historii pracy (w trakcie roku)
		CALL pl_NaliczProgFrekw('calc.na.dzien', @_Prac, '2011-05-17', '', '', '');		
------------------------------------------------------------------------------------------------------------------------------------------------------------------*/	
	IF _MODE = 'calc.na.dzien' THEN
		SET _GUID = IFNULL(_GUID, '');
	--	Czy istnieje wagon ?
		CALL pl_NaliczProgFrekw('tool.check.dzien', _GUID, _Param_A, '', '', '');		
		IF NOT @tool.check.Exist THEN
			LEAVE SPROC;
		END IF;
		
	--	W @frekw.tool.suma mamy sumę na dzień	
		CALL pl_NaliczProgFrekw('tool.get.sum', _GUID, _Param_A, '', '', '');		
		
		IF _Param_D = 'rok' THEN
		--	Zmiana roku
			LEAVE SPROC;
			
		END IF;
		
		IF _Param_D = 'hp' THEN
		--	Zmiana w historii pracy (w trakcie roku)
			LEAVE SPROC;
			
		END IF;
		
		
	END IF;	--	IF _MODE = 'calc.na.dzien'
	
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------	
	'calc.miesiac.rok'
		Nalicza/sprawdza dla pracownika _GUID w frekw wszystkie dni dla roku _Param_A miesiaca _Param_B
		Parametry
			_GUID		GUID pracownika
			_Param_A	rok
			_Param_B	miesiac
		CALL pl_NaliczProgFrekw('calc.miesiac.rok', @_Prac, '2011', '5', '', '');		
------------------------------------------------------------------------------------------------------------------------------------------------------------------*/	
	IF _MODE = 'calc.miesiac.rok' THEN
	--	Czy istnieje wagon ?
		CALL pl_NaliczProgFrekw('tool.check.rok.miesiac', _GUID, _Param_A, _Param_B, '', '');		
		IF NOT @tool.check.Exist THEN
			LEAVE SPROC;
		END IF;
		
	--	`t_historia_pracy_to_calc` union napisany przez Maksa
		DROP TEMPORARY TABLE IF EXISTS `t_historia_pracy_to_calc`;
		CREATE TEMPORARY TABLE `t_historia_pracy_to_calc`

			SELECT 
				h1.OdDnia, Etat_L, Etat_M, TypNiepelnospr 
			FROM `historia_pracy` h1 
			WHERE 
				h1.GUIDPr = _GUID AND 
				YEAR(h1.OdDnia) = _Param_A AND 
				MONTH(h1.OdDnia) = _Param_B AND 
				(h1.zmiany LIKE "%%etat%%") 
				
			UNION  
			
			SELECT 
				h2.OdDnia, h2.Etat_L, h2.Etat_M, h2.TypNiepelnospr 
			FROM `historia_pracy` h2 
			JOIN `historia_pracy` poprz on h2.GUIDPr = poprz.GUIDPr and poprz.OdDnia = 
				(select max(tmp.oddnia) from `historia_pracy` tmp where tmp.GUIDPr = poprz.GUIDPr and tmp.oddnia < h2.oddnia) 
			WHERE 
				h2.GUIDPr = _GUID AND 
				YEAR(h2.OdDnia) = _Param_A AND 
				MONTH(h2.OdDnia) = _Param_B AND 
				(h2.zmiany like '%%TypNiepelnospr%%' ) AND 
				((h2.TypNiepelnospr in (0,1) and poprz.TypNiepelnospr in (3,2)) OR  (poprz.TypNiepelnospr in (0,1) and h2.TypNiepelnospr in (3,2))) 
		;
		
	--	Kursor do petli	
		
		BEGIN
			DECLARE _LocalDate DATE;
			DECLARE _done BOOL DEFAULT FALSE;
			DECLARE _c_proc CURSOR FOR
				SELECT 
					OdDnia
				FROM `t_historia_pracy_to_calc`
				;
			DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE;
			OPEN _c_proc;
				loop1: LOOP
				--	pobierz date dla kazdego rekordu
					FETCH _c_proc INTO
						_LocalDate;
					IF _done THEN
						LEAVE loop1;
					ELSE
				--	Naliczenie atomiczne na dzien	
						CALL pl_NaliczProgFrekw('calc.na.dzien', _GUID, _LocalDate, '', '', '');		
						
					END IF;
				END LOOP;
			CLOSE _c_proc;
		END;			
		DROP TEMPORARY TABLE IF EXISTS `t_historia_pracy_to_calc`;
	END IF;	--	IF _MODE = 'calc.miesiac.rok'
	
	


/*------------------------------------------------------------------------------------------------------------------------------------------------------------------	
	'tool.check.dzien'
		Sprawdza czy jest wagon pracownika _GUID na dzien _Param_A
		Parametry
			_GUID		GUID pracownika
			_Param_A	dzien
		CALL pl_NaliczProgFrekw('tool.check.dzien', @_Prac, '2011-05-16', '', '', '');		
		
	LUB
	
	'tool.check.rok.miesiac'
		Sprawdza czy jest wagon pracownika _GUID na rok _Param_A i miesiac _Param_B
		Parametry
			_Param_A	rok
			_Param_B	miesiac
		CALL pl_NaliczProgFrekw('tool.check.rok.miesiac', @_Prac, '2011', '5', '', '');		
	
	UWAGA
		w zmiennej @tool.check.Exist jest wynik 0 nie ma wagonu <> 0 jest
------------------------------------------------------------------------------------------------------------------------------------------------------------------*/	
	IF _MODE LIKE 'tool.check.%' THEN
		IF _MODE = 'tool.check.dzien' THEN
			SET @tool.check.Date = _Param_A;
			SET @tool.check.Year = YEAR(_Param_A);
			SET @tool.check.Month = MONTH(_Param_A);
		END IF;	--	IF _MODE = 'tool.check.dzien'
		IF _MODE = 'tool.check.rok.miesiac' THEN
			SET @tool.check.Year = _Param_A;
			SET @tool.check.Month = _Param_B;
			SET @tool.check.Date = DATE(CONCAT(@tool.check.Year, '-', @tool.check.Month, '-', '01'));
		END IF;	--	IF _MODE = 'tool.check.rok.miesiac'

		SET @tool.check.Exist = 0;
		SELECT 
			COUNT(*) AS ile 
		INTO
			@tool.check.Exist
		FROM frekw f 
		JOIN frekw_po p on p.FrekwGUID = f.GUID 
		WHERE
			f.PracGUID = _GUID AND 
			f.deleted = 0 AND 
			f.rok = @tool.check.Year AND
			f.miesiac = @tool.check.Month AND
			p.rok_msc_dzien = @tool.check.Date
		;
		SET @tool.check.Exist = IFNULL(@tool.check.Exist, 0);
		
			
	END IF;	--	IF _MODE LIKE 'tool.check.%' 

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------	
	'tool.get.sum'
		Nalicza sumę wolnego czas (w godz.?) do dnia _Param_A dla pracownika _GUID
		UWAGA wynik naliczenia umieszczamy w @frekw.tool.suma
		Parametry
			_GUID		GUID pracownika
			_Param_A	dzien
		CALL pl_NaliczProgFrekw('tool.get.sum', @_Prac, '2011-05-16', '', '', '');		
------------------------------------------------------------------------------------------------------------------------------------------------------------------*/	
	IF _MODE = 'tool.get.sum' THEN
	
		SELECT 
			DataZatrudnieniaWzakl
		INTO
			@frekw.tool.DataZatr
		FROM `Pracownicy` p
		WHERE
			p.GUID = _GUID
		;
		
		SELECT 
		/*
			p.pula_url,				-- pula
			p.godz_absencji,		-- godziny absencji danego dnia
			p.korekta_plus,			-- C+
			p.korekta_minus,		-- C-
			p.avg_min_per_day		-- grzesiowy wspolczynnik
		*/
			SUM(p.pula_url + p.korekta_plus - p.korekta_minus - p.godz_absencji) 
		INTO
			@frekw.tool.suma
		FROM `frekw_po` p, `frekw` n
		WHERE
			n.PracGUID = _GUID AND 
			p.frekwguid = n.guid AND 
			p.rok_msc_dzien <= _Param_A AND
			p.rok_msc_dzien >= @frekw.tool.DataZatr AND
			n.rok = year(p.rok_msc_dzien) and n.miesiac = month(p.rok_msc_dzien)
		;	
		SET @frekw.tool.suma = IFNULL(@frekw.tool.suma, 0);
	END IF;	--	IF _MODE = 'tool.get.sum' 

END$$

DELIMITER ;

/*
====================================================================================================================================================================================
	NOTATNIK
====================================================================================================================================================================================

select 
  p.pula_url,           # pula
  p.godz_absencji,      # godziny absencji danego dnia
  p.korekta_plus,       # C+
  p.korekta_minus,      # C-
  p.avg_min_per_day     # grzesiowy wspolczynnik
from frekw_po p, frekw n
where p.frekwguid = n.guid and n.PracGUID = %s and n.rok = year(p.rok_msc_dzien) and n.miesiac = month(p.rok_msc_dzien)
  and p.rok_msc_dzien = %s


function NaliczProgFrekwAtom(aPracGUID: String; aData: TDateTime): Boolean;
const
  cCheckSQL = 'SELECT COUNT(*) AS ile FROM frekw f '+
    'join frekw_po p on p.FrekwGUID = f.GUID '+
    'where f.PracGUID = %s and f.deleted = 0 and f.rok = %d and f.miesiac = %d '+
    '  and p.rok_msc_dzien = %s ';
var
  aSQL: String;
  aI : Integer;
begin
  test, czy istnieje wagon
  aI := 0;
  aSQL := Format(cCheckSQL, [aPracGUID, DateTimeToSQL(aData)]);
  ConnectSupport.GetQueryInteger(aSQL, 'ile', nil, aI);
  Result := (aI = 1);
  if not Result then Exit;
  //call ?

end;

function NaliczProgiFrekw(aPracGUID: String; aRok, aMiesiac: Integer): Boolean;
const
  cCheckSQL = 'SELECT COUNT(*) AS ile FROM frekw '+
    'where PracGUID = ''%s'' and deleted = 0 and rok = %d and miesiac = %d ';
  cGetTriggersSQL =
    'SELECT OdDnia, Etat_L, Etat_M, TypNiepelnospr '+
    ' FROM historia_pracy h1 '+
    ' WHERE GUIDPr = ''%s'' AND OdDnia BETWEEN %s AND %s '+
    ' AND (h1.zmiany LIKE "%%etat%%") '+
    'UNION  '+
    'SELECT h2.OdDnia, h2.Etat_L, h2.Etat_M, h2.TypNiepelnospr '+
    ' FROM historia_pracy h2 '+
    ' join historia_pracy poprz on h2.GUIDPr = poprz.GUIDPr and poprz.OdDnia = '+
    '  (select max(tmp.oddnia) from historia_pracy tmp where tmp.GUIDPr = poprz.GUIDPr and tmp.oddnia < h2.oddnia) '+
    ' WHERE h2.GUIDPr = ''%s'' AND h2.OdDnia BETWEEN %s AND %s AND h2.zmiany like ''%%TypNiepelnospr%%'' '+
    ' AND ((h2.TypNiepelnospr in (0,1) and poprz.TypNiepelnospr in (3,2)) OR  (poprz.TypNiepelnospr in (0,1) and h2.TypNiepelnospr in (3,2)) ) '+
    ' ';
var
  aSQL: String;
  aI: Integer;
  aTrigDS: TDataSet;
  aStart, aKoniec: String;
begin
  aI := 0;
  aSQL := Format(cCheckSQL, [aPracGUID, aRok, aMiesiac]);
  ConnectSupport.GetQueryInteger(aSQL, 'ile', nil, aI);
  Result := (aI = 1);
  if not Result then Exit;
  aStart := DateTimeToSQL(EncodeDate(aRok, aMiesiac, 1));
  aKoniec := DateTimeToSQL(EncodeDate(aRok, aMiesiac, DaysInAMonth(aRok, aMiesiac)));
  aSQL := Format(cGetTriggersSQL, [aPracGUID, aStart, aKoniec,
                                   aPracGUID, aStart, aKoniec]);
  aTrigDS := ConnectSupport.GetQuery(aSQL);
  if Assigned(aTrigDS) then
  try
    if DataSetIsNotEmpty(aTrigDS) then
    begin
      aTrigDS.First;
      while not aTrigDS.Eof do
      begin
        NaliczProgFrekwAtom(aPracGUID, aTrigDS.FieldByName('OdDnia').AsDateTime);
      end;
    end;
  finally
    FreeAndNil(aTrigDS);
  end;
  
end;

*/

      

	  