namespace Kreta.DataAccessManual
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using Kreta.Core;
    using Kreta.Core.Enum;
    using Kreta.Core.Exceptions;
    using Kreta.DataAccess.Interfaces;
    using Kreta.DataAccessManual.Interfaces;
    using Kreta.DataAccessManual.Util;
    using Kreta.Enums;
    using Kreta.Framework;
    using Kreta.Framework.Entities;
    using Kreta.Framework.Util;
    using SDA.DataProvider;
    using SDA.Kreta.Entities;

    internal class TanuloCsoportDal : DataAccessBase, ITanuloCsoportDal
    {
        public TanuloCsoportDal(DalHandler handler) : base(handler)
        {
        }

        public TanuloCsoportDal(DalHandler handler, GridParameters gridParameters) : base(handler, gridParameters)
        {
        }

        public void Delete(int id, bool logikai = true)
        {
            var entity = Get(id);

            Delete(entity, logikai);
        }

        public void Delete(ITanuloCsoport dto, bool logikai = true)
        {
            var entity = dto as TanuloCsoport;

            entity.TanuloTanugyiAdatok?.JogviszonySzuneteltetes?.DeleteAll();
            entity.TanuloTanugyiAdatok?.Delete(logikai);

            var zaradekDal = DalHelper.ZaradekDal();
            entity.ZaradekList.ToList().ForEach(zaradek => zaradekDal.Delete(zaradek));

            DalHelper.HetesDal().DeleteHetesekInIdoszak(dto.TanevId, dto.OsztalyCsoportId, dto.TanuloId, dto.BelepesDatum, dto.KilepesDatum);

            entity.Delete(logikai);
            DalHelper.Commit();
        }

        public void FullUpdate(ITanuloCsoport dto)
        {
            var entity = dto as TanuloCsoport;
            if (dto.TanuloTanugyiAdatok != null)
            {
                var tanuloTanugyiAdatok = dto.TanuloTanugyiAdatok as TanuloTanugyiAdatok;
                tanuloTanugyiAdatok.FullUpdate();
            }

            DalHelper.HetesDal().DeleteHetesekNotInIdoszak(dto.TanevId, dto.OsztalyCsoportId, dto.TanuloId, dto.BelepesDatum, dto.KilepesDatum);

            entity.FullUpdate();

            DalHelper.Commit();
        }

        public void Update(ITanuloCsoport dto)
        {
            var entity = dto as TanuloCsoport;

            DalHelper.HetesDal().DeleteHetesekNotInIdoszak(dto.TanevId, dto.OsztalyCsoportId, dto.TanuloId, dto.BelepesDatum, dto.KilepesDatum);

            entity.Update();

            DalHelper.Commit();
        }

        public ITanuloCsoport Get()
        {
            return TanuloCsoport.GiveAnInstance();
        }

        public ITanuloCsoport Get(int id)
        {
            var entity = TanuloCsoport.GiveAnInstance();
            entity.LoadByID(id);
            return entity;
        }

        public void Insert(ITanuloCsoport dto)
        {
            var entity = dto as TanuloCsoport;
            entity.Insert();
            dto.ID = entity.ID;

            DalHelper.Commit();
        }

        public DataSet FilterTanuloIsInClass(int tanevId, List<int> tanuloId, OktNevelesiKategoriaEnum? kategoriaTipus)
        {
            var parameters = new List<CommandParameter>();
            var inParameters = new List<string>();
            if (kategoriaTipus != null)
            {
                parameters.Add(new CommandParameter("pKategoria", (int)kategoriaTipus));
            }
            else
            {
                parameters.Add(new CommandParameter("pKategoria", DBNull.Value));
            }
            foreach (var id in tanuloId)
            {
                var name = $"pTanuloId{tanuloId.IndexOf(id)}";
                parameters.Add(new CommandParameter(name, id));
                inParameters.Add("@" + name);
            }

            parameters.Add(new CommandParameter("ptanevId", tanevId));
            var commandText = @"
select tcs.C_TANULOID ID
,o.ID OsztalyID
,tcs.C_BELEPESDATUM BelepesDatum
,tcs.C_KILEPESDATUM KilepesDatum
from(
SELECT [C_OSZTALYCSOPORTID]
      ,[C_TANULOID]
      ,C_BELEPESDATUM
      ,C_KILEPESDATUM
FROM T_TANULOCSOPORT_OSSZES Where TOROLT ='F' And C_TANEVID = @ptanevId ) as tcs
inner join (select ID from T_OSZTALYCSOPORT_Osszes Where TOROLT ='F' And C_TANEVID = @ptanevId And (@pKategoria IS NULL OR C_FELADATKATEGORIAID = @pKategoria)) as ocs on ocs.ID = tcs.C_OSZTALYCSOPORTID
inner join (select ID from T_OSZTALY_Osszes Where TOROLT ='F' And C_AltanevId = @ptanevId ) as o on o.ID = tcs.C_OSZTALYCSOPORTID
WHERE tcs.C_TANULOID IN (" + string.Join(",", inParameters) + ")";

            return GetData(commandText, parameters);
        }

        public DataSet GetTanulokOsztalyCSoport(int tanevId, List<int> tanuloId, OktNevelesiKategoriaEnum? kategoriaTipus)
        {
            var parameters = new List<CommandParameter>();//TODO @devKornel: obj. initializerrel
            parameters.Add(new CommandParameter("ptanevId", tanevId));
            if (kategoriaTipus != null)
            {
                parameters.Add(new CommandParameter("pKategoria", (int)kategoriaTipus));
            }
            else
            {
                parameters.Add(new CommandParameter("pKategoria", DBNull.Value));
            }

            var inParameters = new List<string>();
            foreach (var id in tanuloId)
            {
                var name = string.Format("pTanuloId{0}", tanuloId.IndexOf(id));
                parameters.Add(new CommandParameter(name, id));
                inParameters.Add("@" + name);
            }

            var commandText = @"
            SELECT
                 [C_OSZTALYCSOPORTID]       OsztalyCsoportId
                ,[C_TANULOID]               TanuloId
                ,[T_TANULOCSOPORT_Osszes].[ID]
                ,C_KILEPESDATUM             KilepesDatum
                ,C_BELEPESDATUM             BelepesDatum
            FROM [T_TANULOCSOPORT_Osszes]
            INNER JOIN (select ID from T_OSZTALYCSOPORT_Osszes Where TOROLT ='F' And C_TANEVID = @ptanevId And (@pKategoria IS NULL OR C_FELADATKATEGORIAID = @pKategoria )) AS ocs ON ocs.ID = [T_TANULOCSOPORT_Osszes].C_OSZTALYCSOPORTID
            WHERE
                    [TOROLT] = 'F'
                AND C_TANEVID = @ptanevId
                AND C_TANULOID IN (" + string.Join(",", inParameters) + ")";
            return GetData(commandText, parameters);
        }

        public DataSet GetTanulokOsztalyai(IList<int> tanuloIdList)
        {
            var parameters = new List<CommandParameter>();
            var inParameters = new List<string>();

            for (int i = 0; i < tanuloIdList.Count; i++)
            {
                var name = string.Format("pTanuloId{0}", i);
                parameters.Add(new CommandParameter(name, tanuloIdList[i]));
                inParameters.Add("@" + name);
            }

            string commandText = $@"
            SELECT
                 TanuloCsoport.C_TANULOID
                ,OsztalyCsoport.C_NEV
                ,TanuloCsoport.C_BELEPESDATUM
                ,TanuloCsoport.C_KILEPESDATUM
            FROM T_TANULOCSOPORT TanuloCsoport
                INNER JOIN T_OSZTALY Osztaly ON Osztaly.ID = TanuloCsoport.C_OSZTALYCSOPORTID AND Osztaly.TOROLT = 'F'
                INNER JOIN T_OSZTALYCSOPORT OsztalyCsoport ON OsztalyCsoport.ID = Osztaly.ID AND OsztalyCsoport.TOROLT = 'F'
            WHERE
                TanuloCsoport.TOROLT = 'F'
                AND TanuloCsoport.C_TANULOID IN (" + (inParameters.Count == 0 ? "NULL" : string.Join(",", inParameters)) + ")"
            ;

            return GetData(commandText, parameters);
        }

        public DataSet GetTanuloOsztalyCsoport(int tanevId, IEnumerable<int> tanuloIds, OktNevelesiKategoriaEnum? kategoriaTipus)
        {
            if (!tanuloIds.NotNullAndAny())
            {
                throw new ArgumentNullException();
            }

            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanevId", tanevId),

            };
            if (kategoriaTipus.HasValue)
            {
                parameters.Add(new CommandParameter("pKategoria", (int)kategoriaTipus));
            }
            else
            {
                parameters.Add(new CommandParameter("pKategoria", DBNull.Value));
            }
            var commandText = $@"
SELECT 
     tcs.ID
    ,tcs.C_OSZTALYCSOPORTID AS OsztalyCsoportId
    ,tcs.C_TANULOID AS TanuloId
    ,tcs.C_BELEPESDATUM AS BelepesDatum
    ,tcs.C_KILEPESDATUM AS KilepesDatum
FROM T_TANULOCSOPORT_OSSZES tcs
INNER JOIN T_OSZTALYCSOPORT_OSSZES ocs ON ocs.ID = tcs.C_OSZTALYCSOPORTID AND ocs.TOROLT = 'F'
    AND (:pKategoria IS NULL OR ocs.C_FELADATKATEGORIAID = :pKategoria)
WHERE tcs.TOROLT = 'F' 
    AND tcs.C_TANEVID = :pTanevId 
    AND ISNULL(tcs.C_KILEPESDATUM, GETDATE()) >= GETDATE()
    AND tcs.C_TANULOID IN ({string.Join(",", tanuloIds)})";

            return GetData(commandText, parameters);
        }

        public DataSet GetTanulokOsztalyaiByTanuloIdp(int tanevId, IEnumerable<Guid> tanuloIdps)
        {
            if (!tanuloIdps.NotNullAndAny())
            {
                throw new ArgumentNullException();
            }

            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanevId", tanevId),
                new CommandParameter("pKategoria", (int)OktNevelesiKategoriaEnum.NevelesOktatas)
            };

            var commandText = $@"
SELECT 
     f.C_IDPEGYEDIAZONOSITO AS TanuloIdp
    ,ocs.ID AS OsztalyId
    ,ocs.C_NEV AS OsztalyNev
    ,ocs.C_EVFOLYAMTIPUSA AS EvfolyamId
    ,evfolyam.C_NAME AS EvfolyamNev
FROM T_TANULOCSOPORT_OSSZES tcs
INNER JOIN T_OSZTALYCSOPORT_OSSZES ocs ON ocs.ID = tcs.C_OSZTALYCSOPORTID AND ocs.TOROLT = 'F'
    AND ocs.C_FELADATKATEGORIAID = :pKategoria
INNER JOIN T_OSZTALY_OSSZES o ON ocs.ID = o.ID AND o.TOROLT = 'F'
INNER JOIN T_DICTIONARYITEMBASE evfolyam ON evfolyam.ID = ocs.C_EVFOLYAMTIPUSA AND Evfolyam.C_TANEVID = ocs.C_TANEVID AND evfolyam.TOROLT = 'F'
INNER JOIN T_FELHASZNALO f ON f.ID = tcs.C_TANULOID AND f.TOROLT = 'F'
WHERE tcs.TOROLT = 'F' 
    AND tcs.C_TANEVID = :pTanevId 
    AND ISNULL(tcs.C_KILEPESDATUM, DATEADD(day, 1, GETDATE())) > GETDATE()
    AND f.C_IDPEGYEDIAZONOSITO IN ({string.Join(",", tanuloIdps.Select(x => $"'{x}'"))})";

            return GetData(commandText, parameters);
        }

        public DataSet MindenOsztallyalRendelkezoTanulo(int tanevId, DateTime date)
        {
            var parameters = new List<CommandParameter>();//TODO @devKornel: obj. initializerrel
            parameters.Add(new CommandParameter("pDate", date));
            parameters.Add(new CommandParameter("ptanevId", tanevId));
            var commandText = @"
select tcs.C_TANULOID ID,
f.C_NYOMTATASINEV + ' (' + CONVERT(nvarchar(50), f.C_SZULETESIDATUM, 102) + '.) ' Nev,
f.C_SZULETESIDATUM as SzulDatum,
f.C_NEME as Neme
from(
SELECT [C_OSZTALYCSOPORTID]
      ,[C_TANULOID]
FROM [T_TANULOCSOPORT_Osszes] Where TOROLT ='F' And C_TANEVID = :ptanevId
and C_BELEPESDATUM <= :pDate
and (C_KILEPESDATUM is null or C_KILEPESDATUM > :pDate)
) as tcs
inner join (select ID from T_OSZTALYCSOPORT_Osszes Where TOROLT ='F' And C_TANEVID = :ptanevId ) as ocs on ocs.ID = tcs.C_OSZTALYCSOPORTID
inner join (select ID from T_OSZTALY_Osszes Where TOROLT ='F' And C_AlTANEVID = :ptanevId ) as o on o.ID = tcs.C_OSZTALYCSOPORTID
inner join (select ID, C_NYOMTATASINEV, C_SZULETESIDATUM, C_NEME FROM T_FELHASZNALO_Osszes Where TOROLT ='F') as f on f.ID = tcs.C_TANULOID
";
            return GetData(commandText, parameters, dictionaryItemColumns: "Neme");
        }

        public DataSet Osztalyok(int tanevId, OktNevelesiKategoriaEnum? kategoriaTipus = null)
        {
            var parameters = new List<CommandParameter>();//TODO @devKornel: obj. initializerrel
            parameters.Add(new CommandParameter("ptanevId", tanevId));
            if (kategoriaTipus.HasValue)
            {
                parameters.Add(new CommandParameter("pkategoriaTipus", (int)kategoriaTipus));
            }
            else
            {
                parameters.Add(new CommandParameter("pkategoriaTipus", DBNull.Value));
            }

            var commandText = @"
SELECT
    CASE WHEN ocs.C_NEV NOT LIKE '%[^0-9]%' THEN CAST(LEFT(ocs.C_NEV,9) AS INT) ELSE 2147483647 END NumberOrder,
    CASE WHEN LEFT(ocs.C_NEV, 1) BETWEEN '0' AND '9' AND ocs.C_NEV LIKE '%[^0-9]%' THEN CAST(LEFT(SUBSTRING(ocs.C_NEV, 1, PATINDEX('%[^0-9]%', ocs.C_NEV) - 1),9) AS INT) ELSE 2147483647 END NumberAndTextOrder,
    ocs.ID ID, ocs.C_NEV + ' (' + tanev.C_NEV + ')' Nev
FROM T_OSZTALYCSOPORT_OSSZES ocs
    INNER JOIN (SELECT ID FROM T_OSZTALY_OSSZES WHERE TOROLT ='F' ) o ON ocs.ID = o.ID
    LEFT JOIN  (SELECT ID, C_NEV FROM T_TANEV_Osszes WHERE TOROLT ='F') tanev ON tanev.ID = @ptanevId
WHERE ocs.TOROLT ='F' And ocs.C_TANEVID = @ptanevId and (@pkategoriaTipus is null Or ocs.C_FELADATKATEGORIAID = @pkategoriaTipus)
ORDER BY NumberOrder ASC, NumberAndTextOrder ASC, ocs.C_NEV ASC
            ";

            var ds = GetData(commandText, parameters);
            return ds;
        }

        public DataSet GetCsoportok(int tanevId, OktNevelesiKategoriaEnum? kategoriaTipus = null, bool dualisKepzesIsEnabled = false, bool csakDualis = false, int? szervezetId = null)
        {
            var parameters = new List<CommandParameter>();//TODO @devKornel: obj. initializerrel
            parameters.Add(new CommandParameter("ptanevId", tanevId));
            if (kategoriaTipus.HasValue && !szervezetId.IsEntityId())
            {
                parameters.Add(new CommandParameter("pkategoriaTipus", (int)kategoriaTipus));
            }
            else
            {
                parameters.Add(new CommandParameter("pkategoriaTipus", DBNull.Value));
            }

            var commandText = @"
                SELECT
    CASE WHEN OsztalyCsoport.C_NEV NOT LIKE '%[^0-9]%' THEN CAST(LEFT(OsztalyCsoport.C_NEV,9) AS INT) ELSE 2147483647 END NumberOrder,
    CASE WHEN LEFT(OsztalyCsoport.C_NEV, 1) BETWEEN '0' AND '9' AND OsztalyCsoport.C_NEV LIKE '%[^0-9]%' THEN CAST(LEFT(SUBSTRING(OsztalyCsoport.C_NEV, 1, PATINDEX('%[^0-9]%', OsztalyCsoport.C_NEV) - 1),9) AS INT) ELSE 2147483647 END NumberAndTextOrder,
    OsztalyCsoport.ID               ID,
    OsztalyCsoport.C_NEV            Nev,
    Csoport.C_OSZTALYBONTASID       OsztalyId,
    Csoport.C_Tipusa                CsoportTipusId,
    Osztaly.Nev                     OsztalyNev

FROM (
    SELECT
        ID,
        C_NEV,
        C_EVFOLYAMTIPUSA
    FROM
        T_OSZTALYCSOPORT_Osszes
    WHERE
        TOROLT ='F' AND
        C_TANEVID = @ptanevId
        and (@pkategoriaTipus is null Or T_OSZTALYCSOPORT_Osszes.C_FELADATKATEGORIAID = @pkategoriaTipus)
) OsztalyCsoport
    INNER JOIN  T_CSOPORT_Osszes Csoport
            ON OsztalyCsoport.ID = Csoport.ID AND Csoport.C_ISAUTOEGYENICSOPORT = 'F' " + @"
    " + (!dualisKepzesIsEnabled ? "" :
        (!csakDualis ? " LEFT " : " INNER ") + @"JOIN T_SZERVEZET_OSSZES Szervezet ON Szervezet.ID = Csoport.C_SZERVEZETID  AND Szervezet.TOROLT ='F' AND Szervezet.C_TANEVID = @ptanevId") + @"
    LEFT JOIN(
        SELECT
            T_OSZTALYCSOPORT_Osszes.ID       ID,
            T_OSZTALYCSOPORT_Osszes.C_NEV    Nev
        FROM
            T_OSZTALYCSOPORT_Osszes
    INNER JOIN  T_OSZTALY_Osszes
             ON T_OSZTALYCSOPORT_Osszes.ID = T_OSZTALY_Osszes.ID
        Where
        T_OSZTALYCSOPORT_Osszes.TOROLT ='F' AND
        T_OSZTALYCSOPORT_Osszes.C_TANEVID = @ptanevId
    ) Osztaly
        ON Csoport.C_OSZTALYBONTASID = Osztaly.ID
WHERE Csoport.TOROLT = 'F' " +
(dualisKepzesIsEnabled ? !csakDualis ? " AND Szervezet.ID IS NULL " : (szervezetId.HasValue ? " AND Szervezet.ID  = " + szervezetId.Value.ToString() : " ") : "") + @"
ORDER BY
    NumberOrder ASC, NumberAndTextOrder ASC, OsztalyCsoport.C_NEV ASC
            ";

            var ds = GetData(commandText, parameters);
            return ds;
        }

        public DataSet OsztalyTanuloi(int tanevId, List<int> osztalyIds, bool kovTanev = false, DateTime? datum = null, bool pIsJogviszonyKezeles = false)
        {
            if (osztalyIds.Count < 1)
            {
                throw new BlException(BlExceptionType.ListaNemTartalmazElemet);
            }

            var osztalyIdParameterList = new List<string>(osztalyIds.Count);
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanevId", tanevId),
                new CommandParameter("pDatum", datum ?? DateTime.Now)
            };

            for (int i = 0; i < osztalyIds.Count; i++)
            {
                var parameterName = $"pOsztalyId{i}";
                osztalyIdParameterList.Add($"@{parameterName}");
                parameters.Add(new CommandParameter(parameterName, osztalyIds[i]));
            }

            var commandText = $@"
                SELECT
                    f.ID,
                    f.Nev,
                    f.NevElotagNelkul,
                    f.SzulDatum,
                    f.Neme,
                    tcs.C_OSZTALYCSOPORTID OsztalyCsoportId,
                    tcs.KilepesDatum,
                    tcs.C_BELEPESDATUM BelepesDatum ,
                    CASE WHEN (tcs.KilepesDatum IS NULL OR tcs.KilepesDatum > :pDatum) THEN 'T' ELSE 'F' END Aktiv
                    ,(SELECT 
                          CHAR(13) + C_SZOVEG 
                      FROM T_ZARADEK_OSSZES
                      WHERE
                          TOROLT = 'F' AND
                          C_TANEVID = @pTanevId AND
                          C_ISKIVAGYATSOROLASIZARADEK = 'T' AND
                          C_TANULOCSOPORTID = tcs2.ID
                      FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)') AS KiVagyAtsorolasiZaradek "
                      + (!pIsJogviszonyKezeles ? "" : @"
                        ,NULL as JogviszonyId
                        ,jv.JogviszonyCount ") + $@"
                FROM
                    (SELECT ID FROM T_OSZTALY_OSSZES WHERE TOROLT = 'F' AND ID IN ({string.Join(",", osztalyIdParameterList)}) AND C_ALTANEVID = @pTanevId) o
                INNER JOIN (
                    SELECT
                        C_TANULOID,
                        C_OSZTALYCSOPORTID,
                        C_BELEPESDATUM,
                        CASE
                            WHEN MAX(CASE WHEN C_KILEPESDATUM IS NULL THEN 1 ELSE 0 END) = 0
                            THEN MAX(C_KILEPESDATUM)
                        END KilepesDatum
                    FROM
                        T_TANULOCSOPORT_OSSZES
                    WHERE
                        TOROLT = 'F' AND
                        C_TANEVID = @pTanevId
                    GROUP BY
                        C_TANULOID,
                        C_OSZTALYCSOPORTID,
                        C_BELEPESDATUM
                    ) tcs ON
                        o.ID = tcs.C_OSZTALYCSOPORTID
                INNER JOIN (
                    SELECT
                        ID,
                        IIF (aktosztaly.C_NEV IS NULL,
                            C_NYOMTATASINEV + ' (' + CONVERT(nvarchar(50), C_SZULETESIDATUM, 102) + '.) ',
                            C_NYOMTATASINEV + ' (' + CONVERT(nvarchar(50), C_SZULETESIDATUM, 102) + '., ' + aktosztaly.C_NEV + ') '
                        ) as Nev,
                        IIF(C_NEVSORREND = 'T',
                            C_UTONEV + ' ' + C_VEZETEKNEV,
                            C_VEZETEKNEV + ' ' + C_UTONEV) as 'NevElotagNelkul',
                        C_SZULETESIDATUM as SzulDatum,
                        C_NEME as Neme
                    FROM
                        T_FELHASZNALO_OSSZES
                    LEFT JOIN (
                        SELECT
                            T_TANULOCSOPORT_OSSZES.C_TANULOID,
                            T_OSZTALYCSOPORT_OSSZES.C_NEV,
                             T_TANULOCSOPORT_OSSZES.C_OSZTALYCSOPORTID
                        FROM
                            T_TANULOCSOPORT_OSSZES
                        INNER JOIN
                            T_OSZTALY_OSSZES ON
                                T_OSZTALY_OSSZES.ID = T_TANULOCSOPORT_OSSZES.C_OSZTALYCSOPORTID AND
                                T_OSZTALY_OSSZES.TOROLT = 'F'
                        INNER JOIN
                            T_OSZTALYCSOPORT_OSSZES ON
                                T_OSZTALYCSOPORT_OSSZES.ID = T_TANULOCSOPORT_OSSZES.C_OSZTALYCSOPORTID AND
                                T_OSZTALYCSOPORT_OSSZES.TOROLT = 'F'
                        WHERE
                            T_TANULOCSOPORT_OSSZES.TOROLT= 'F' AND
                            T_TANULOCSOPORT_OSSZES.C_TANEVID = @pTanevId "
                            + (!kovTanev ? " AND T_TANULOCSOPORT_OSSZES.C_BELEPESDATUM <= :pDatum AND (T_TANULOCSOPORT_OSSZES.C_KILEPESDATUM IS NULL OR T_TANULOCSOPORT_OSSZES.C_KILEPESDATUM > :pDatum)" : string.Empty) + $@"
                    ) aktosztaly ON
                        aktosztaly.C_TANULOID = T_FELHASZNALO_OSSZES.ID and aktosztaly.C_OSZTALYCSOPORTID IN ({string.Join(",", osztalyIdParameterList)})
                    WHERE
                        TOROLT = 'F'
                    ) f ON f.ID = tcs.C_TANULOID " + (!pIsJogviszonyKezeles ? "" : @"
                    OUTER APPLY (
                        SELECT jv.C_TANULOID as tanuloId, MAX(jv.ID) as JogviszonyId,COUNT(1) JogviszonyCount
                        FROM T_TBJOGVISZONY_OSSZES jv 
                            WHERE jv.C_TANULOID = f.ID
                                AND jv.TOROLT = 'F'
                                AND jv.C_ISAKTIV = 'T'
                                AND jv.C_JOGVMEGSZUNESEJOGCIMTIPUSID IS NULL
                                AND jv.C_TANEVID = @pTanevId
                            GROUP BY jv.C_TANULOID) jv "
                    ) + $@"
                LEFT JOIN (
                    SELECT
                        ID,
                        C_OSZTALYCSOPORTID,
                        C_TANULOID,
                        C_BELEPESDATUM
                    FROM
                        T_TANULOCSOPORT_OSSZES
                    WHERE
                        TOROLT = 'F' AND
                        C_TANEVID = @pTanevId AND
                        C_KILEPESDATUM IS NULL
                ) tcs2 ON
                    tcs2.C_TANULOID = tcs.C_TANULOID AND
                    tcs2.C_OSZTALYCSOPORTID = tcs.C_OSZTALYCSOPORTID";
            var ds = GetData(commandText, parameters, dictionaryItemColumns: "Neme", booleanColumns: "Aktiv");
            return ds;
        }

        /// INFO @MobilBe: Mobil használja
        public DataSet OsztalyTanuloi(int tanevId, List<int> osztalyIds, DateTime datum)
        {
            if (osztalyIds.Count < 1)
            {
                throw new BlException(BlExceptionType.ListaNemTartalmazElemet);
            }

            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanevId", tanevId),
                new CommandParameter("pDatum", datum)
            };

            var commandText = $@" SELECT DISTINCT
                                      f.ID Id
                                     ,f.C_NYOMTATASINEV Nev
                                     ,f.C_SZULETESIDATUM SzuletesiDatum
                                     ,f.C_ANYJANEVE AnyjaNeve
                                     ,tcs.C_OSZTALYCSOPORTID OsztalyCsoportId
                                  FROM T_TANULOCSOPORT_OSSZES tcs
                                      INNER JOIN T_FELHASZNALO_OSSZES f ON f.ID = tcs.C_TANULOID
                                  WHERE tcs.TOROLT = 'F' AND 
                                        tcs.C_TANEVID = :pTanevId AND
                                        tcs.C_BELEPESDATUM < :pDatum AND
                                        (tcs.C_KILEPESDATUM IS NULL OR tcs.C_KILEPESDATUM >= :pDatum) AND 
                                        tcs.C_OSZTALYCSOPORTID IN ({string.Join(",", osztalyIds)})";

            return GetData(commandText, parameters);
        }

        public DataSet CsoportTanuloi(int tanevId, int csoportId, DateTime pDatum, bool isKovTanev)
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pCsoportId", csoportId),
                new CommandParameter("pTanevId", tanevId),
                new CommandParameter("pKovTanev", isKovTanev.ToBit()),
                new CommandParameter("pDatum", pDatum)
            };

            var commandText = @"SELECT
                                   f.ID
                                  ,f.C_NYOMTATASINEV + ' (' + CONVERT(nvarchar(50), C_SZULETESIDATUM, 102) + '., ' + aktOsztaly.Osztalynev + ') ' as Nev
                                  ,f.C_SZULETESIDATUM AS SzulDatum
                                  ,f.C_NEME AS Neme
                                  ,IIF(C_NEVSORREND = 'T',
                                    f.C_UTONEV + ' ' + f.C_VEZETEKNEV,
                                    f.C_VEZETEKNEV + ' ' + f.C_UTONEV) as 'NevElotagNelkul'
                                  ,tcs.C_OSZTALYCSOPORTID OsztalyCsoportId
                                  ,tcs2.KilepesDatum
                                  ,tcs.C_BELEPESDATUM AS BelepesDatum
                                  ,CASE WHEN (tcs.C_KILEPESDATUM IS NULL OR tcs.C_KILEPESDATUM > :pDatum) THEN 'T' ELSE 'F' END Aktiv
                                FROM T_TANULOCSOPORT_OSSZES tcs
                                  INNER JOIN T_OSZTALYCSOPORT_OSSZES ocs on ocs.ID = C_OSZTALYCSOPORTID AND ocs.TOROLT = 'F'
                                  INNER JOIN ( SELECT
                                                 C_TANULOID
                                                ,C_OSZTALYCSOPORTID
                                                ,CASE WHEN MAX(CASE WHEN C_KILEPESDATUM IS NULL THEN 1 ELSE 0 END) = 0
                                                      THEN MAX(C_KILEPESDATUM)
                                                 END KilepesDatum
                                               FROM T_TANULOCSOPORT_OSSZES
                                               WHERE TOROLT='F'
                                                 AND C_TANEVID = :pTanevId
                                               GROUP BY C_TANULOID, C_OSZTALYCSOPORTID
                                             ) tcs2 on ocs.ID = tcs2.C_OSZTALYCSOPORTID and tcs2.C_TANULOID = tcs.C_TANULOID
                                  INNER JOIN T_FELHASZNALO_OSSZES f ON f.ID = tcs.C_TANULOID AND f.TOROLT = 'F'
                                  CROSS APPLY fnGetTanuloOsztalyString (f.ID, :pDatum, ocs.C_FELADATKATEGORIAID, 0, :pKovTanev, NULL) aktOsztaly
                                  INNER JOIN T_TANEV_OSSZES Tanev ON Tanev.ID = tcs.C_TANEVID AND Tanev.TOROLT = 'F'
                                WHERE tcs.TOROLT = 'F'
                                  AND tcs.C_TANEVID = :pTanevId
                                  AND tcs.C_OSZTALYCSOPORTID = :pCsoportId
                                  AND (tcs.C_BELEPESDATUM <= :pDatum)
                                  AND (tcs.C_KILEPESDATUM > :pDatum OR tcs.C_KILEPESDATUM IS NULL )";

            var ds = this.GetData(commandText, parameters, dictionaryItemColumns: "Neme", booleanColumns: "Aktiv");
            return ds;
        }

        public DataSet OsztalyNelkuliTanulok(int tanevId, OktNevelesiKategoriaEnum kategoriaTipus)
        {
            var parameters = new List<CommandParameter>();//TODO @devKornel: obj. initializerrel
            parameters.Add(new CommandParameter("pTanevId", tanevId));
            parameters.Add(new CommandParameter("pKategoria", (int)kategoriaTipus));
            var commandText = @"
SELECT
  t.ID as ID,
  f.C_NYOMTATASINEV + ' (' + CONVERT(nvarchar(50), f.C_SZULETESIDATUM, 102) + '.) ' as Nev
  ,IIF(C_NEVSORREND = 'T',
        f.C_UTONEV + ' ' + f.C_VEZETEKNEV,
        f.C_VEZETEKNEV + ' ' + f.C_UTONEV) as 'NevElotagNelkul'
  ,f.C_SZULETESIDATUM as SzulDatum
  ,f.C_NEME as Neme
FROM T_FELHASZNALO_OSSZES f
INNER JOIN T_TANULO_OSSZES t ON f.ID = t.ID
WHERE
  f.TOROLT='F'  AND f.C_TANEVID = @pTanevId
  AND t.TOROLT='F' AND t.C_ALTANEVID = @pTanevId
  AND (
    SELECT Count(1)
    FROM T_TANULOCSOPORT_OSSZES tcs
    JOIN T_OSZTALY_OSSZES o ON o.ID = tcs.C_OSZTALYCSOPORTID AND o.C_ALTANEVID = @pTanevId
    JOIN T_OSZTALYCSOPORT_OSSZES ocs ON ocs.ID = o.ID AND ocs.C_FELADATKATEGORIAID = @pKategoria
    WHERE tcs.C_TANULOID = f.ID AND tcs.TOROLT = 'F' AND tcs.c_tanevId = @pTanevId
    ) = 0
            ";

            var ds = this.GetData(commandText, parameters, dictionaryItemColumns: "Neme");
            return ds;
        }

        public DataSet GetDualisTanulok(int tanevId, DateTime pLekerdezesDatum, int? pSzervezetId = null)
        {
            using (SDACommand command = new SDACommand())
            {
                command.Connection = UserContext.Instance.SDAConnection;
                command.Transaction = UserContext.Instance.SDATransaction;
                command.CommandType = CommandType.StoredProcedure;

                command.CommandText = "uspGetDualisTanulok";

                command.Parameters.Add("pSzervezetId", pSzervezetId);
                command.Parameters.Add("pLekerdezesDatum", pLekerdezesDatum);
                command.Parameters.Add("pTanevId", tanevId);
                var dts = new DataSet();
                using (var adapter = new SDADataAdapter())
                {
                    adapter.SelectCommand = command;
                    adapter.Fill(dts);
                }

                SetDNAME(dts.Tables[0], "Neme");
                return dts;
            }
        }

        public DataSet OsszesTanulo(int tanevId, bool isKovTanev) /*Aktiv*/
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanevId", tanevId),
                new CommandParameter("pKovTanev", isKovTanev.ToBit())
            };

            var commandText = $@"
SELECT
  t.ID as ID,
  f.C_NYOMTATASINEV + ' (' + CONVERT(nvarchar(50), f.C_SZULETESIDATUM, 102) + '.' + IIF(TanuloOsztalyString.Osztalynev IS NOT NULL, ', ' + TanuloOsztalyString.Osztalynev, '') +') ' as Nev
  ,IIF(C_NEVSORREND = 'T',
    f.C_UTONEV + ' ' + f.C_VEZETEKNEV,
    f.C_VEZETEKNEV + ' ' + f.C_UTONEV) as 'NevElotagNelkul'
  ,f.C_SZULETESIDATUM as SzulDatum,
  f.C_NEME as Neme,
  TanuloOsztalyString.Osztalynev as TanuloOsztalyai
FROM T_FELHASZNALO_OSSZES f
INNER JOIN T_TANULO_OSSZES t ON f.ID = t.ID
CROSS APPLY fnGetTanuloOsztalyString(t.ID, default, {(int)OktNevelesiKategoriaEnum.AlapfokuMuveszetoktatas}, default, :pKovTanev, NULL) TanuloOsztalyString
WHERE
  f.TOROLT='F'  AND f.C_TANEVID = :pTanevId
  AND t.TOROLT='F' AND t.C_ALTANEVID = :pTanevId
            ";

            var ds = this.GetData(commandText, parameters, dictionaryItemColumns: "Neme");
            return ds;
        }

        public DataSet KiiratkoztatottTanulok(OktNevelesiKategoriaEnum feladatKategoria, int tanevId)
        {
            using (SDACommand command = new SDACommand())
            {
                command.Connection = UserContext.Instance.SDAConnection;
                command.Transaction = UserContext.Instance.SDATransaction;
                command.CommandType = CommandType.StoredProcedure;

                command.CommandText = "uspGetKiiratkoztatottTanulok";

                command.Parameters.Add("pFeladatKategoriaId", (int)feladatKategoria);
                command.Parameters.Add("pTanevId", tanevId);
                var dts = new DataSet();
                using (var adapter = new SDADataAdapter())
                {
                    adapter.SelectCommand = command;
                    adapter.Fill(dts);
                }

                SetDNAME(dts.Tables[0], "Neme");
                return dts;
            }
        }

        public DataSet KiiratkoztatottTanulok(int tanevId, OktNevelesiKategoriaEnum feladatKategoria)
        {
            List<CommandParameter> parameters = new List<CommandParameter>
            {
                new CommandParameter("pKisoroltTanevId", tanevId),
                new CommandParameter("OktNevKatTipus", (int)feladatKategoria)
            };

            var commandText = @"
                SELECT
                    fh.ID as ID
                    ,fh.C_NYOMTATASINEV as Nev
                    ,fh.C_SZULETESIDATUM as SzulDatum
                    ,fh.C_NEME as Neme
                    ,MAX(tcs.C_KILEPESDATUM) as KilepesDatum
                FROM T_FELHASZNALO_OSSZES fh
                    INNER JOIN T_TANULOCSOPORT_OSSZES tcs ON tcs.C_TANULOID = fh.ID
                    INNER JOIN T_OSZTALY_OSSZES o ON o.ID = tcs.C_OSZTALYCSOPORTID
                    INNER JOIN T_OSZTALYCSOPORT_OSSZES ocs ON o.ID = ocs.ID AND ocs.C_FELADATKATEGORIAID = @OktNevKatTipus
                WHERE tcs.C_KILEPESDATUM IS NOT NULL
                    AND fh.C_TANEVID = :pKisoroltTanevId
                    AND fh.TOROLT = 'F' AND tcs.TOROLT = 'F' AND o.TOROLT = 'F'
                    AND NOT EXISTS (select 1 from T_TANULOCSOPORT where T_TANULOCSOPORT.C_TANULOID = fh.ID AND C_KILEPESDATUM is null)
                GROUP BY fh.ID, fh.C_NYOMTATASINEV, fh.C_SZULETESIDATUM, fh.C_NEME
            ";

            var ds = this.GetData(commandText, parameters, dictionaryItemColumns: "Neme");
            return ds;
        }

        public DataSet KiiratkoztatottTanulok(int kisoroltTanevId, int besorolasTanevId)
        {
            List<CommandParameter> parameters = new List<CommandParameter>
            {
                new CommandParameter("pKisoroltTanevId", kisoroltTanevId),
                new CommandParameter("pBesorolasTanevId", besorolasTanevId),
                new CommandParameter("OktNevKatTipus", (int)OktNevelesiKategoriaEnum.NevelesOktatas)
            };
            var commandText = @"
                SELECT
                    fh.ID as ID
                    ,fh.C_NYOMTATASINEV as Nev
                    ,fh.C_SZULETESIDATUM as SzulDatum
                    ,fh.C_NEME as Neme
                    ,MAX(tcs.C_KILEPESDATUM) as KilepesDatum
                FROM T_FELHASZNALO_OSSZES fh
                    INNER JOIN T_TANULOCSOPORT_OSSZES tcs ON tcs.C_TANULOID = fh.ID
                    INNER JOIN T_OSZTALY_OSSZES o ON o.ID = tcs.C_OSZTALYCSOPORTID
                    INNER JOIN T_OSZTALYCSOPORT_OSSZES ocs ON o.ID = ocs.ID AND ocs.C_FELADATKATEGORIAID = @OktNevKatTipus
                WHERE tcs.C_KILEPESDATUM IS NOT NULL
                    AND fh.C_TANEVID = :pKisoroltTanevId
                    AND fh.TOROLT = 'F' AND tcs.TOROLT = 'F' AND o.TOROLT = 'F'
                    AND NOT EXISTS (
                                    SELECT 1 FROM T_FELHASZNALO_OSSZES fh2
                                        INNER JOIN T_TANULO_OSSZES t ON t.ID = fh2.ID
                                    WHERE fh2.C_OKTATASIAZONOSITO = fh.C_OKTATASIAZONOSITO
                                        AND fh2.C_TANEVID = :pBesorolasTanevId
                                        AND fh2.TOROLT = 'F'
                                    )
                GROUP BY fh.ID, fh.C_NYOMTATASINEV, fh.C_SZULETESIDATUM, fh.C_NEME
            ";

            var ds = this.GetData(commandText, parameters, dictionaryItemColumns: "Neme");
            return ds;
        }

        public DataSet GetTanuloOsztalyBontasosCsoportKapcsolatai(int tanevId, int tanuloId, int osztalyId)
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pOsztalyID", osztalyId),
                new CommandParameter("pTanuloID", tanuloId),
                new CommandParameter("ptanevId", tanevId)
            };
            string CommandText = @"
SELECT 
     tcs.ID
    ,cs.ID CsoportId
    ,cs.C_ISAUTOEGYENICSOPORT
    ,ISNULL(COUNT(tcs2.ID),0) as CsoportTanuloSzam
FROM T_CSOPORT_OSSZES cs
INNER JOIN (
    SELECT 
         ID
        ,C_OSZTALYCSOPORTID as OsztalyCsoportID
        ,C_TANULOID as TanuloID 
    FROM  T_TANULOCSOPORT_OSSZES 
    where C_TANEVID = :ptanevId and Torolt = 'F') tcs ON cs.ID = tcs.OsztalyCsoportID
INNER JOIN T_TANULOCSOPORT_OSSZES tcs2 ON tcs2.C_OSZTALYCSOPORTID = cs.ID AND tcs2.TOROLT = 'F'
WHERE tcs.TanuloID = :pTanuloID
    AND cs.C_OSZTALYBONTASID = :pOsztalyID
    And cs.Torolt = 'F'
    And cs.C_AlTANEVID  = :ptanevId
GROUP BY 
     tcs.ID
    ,cs.ID
    ,cs.C_ISAUTOEGYENICSOPORT
";
            var ds = this.GetData(CommandText, parameters);
            return ds;
        }

        public DataSet GetTanulokAdatai(List<int> tanuloIdList)
        {
            List<CommandParameter> parameters = new List<CommandParameter>();
            var inParameters = new List<string>();

            foreach (var id in tanuloIdList)
            {
                var name = string.Format("pTanuloId{0}", tanuloIdList.IndexOf(id));
                parameters.Add(new CommandParameter(name, id));
                inParameters.Add(":" + name);
            }

            var commandText = @"
              SELECT ID, C_NYOMTATASINEV Nev, C_SZULETESIDATUM SzulDatum
                FROM T_FELHASZNALO_Osszes
                WHERE T_FELHASZNALO_Osszes.TOROLT='F' AND T_FELHASZNALO_Osszes.ID IN (" + string.Join(",", inParameters) + ")";

            var ds = GetData(commandText, parameters);
            return ds;
        }

        public DataSet GetFelvettNebulok()
        {
            var paramList = new List<CommandParameter> { new CommandParameter("felvettStatusz", (int)FelvetelStatuszaTipusEnum.Felveve) };

            var commandText = $@"
SELECT  ID                  AS Id,
        C_TANULOCSALADINEVE AS Csaladnev,
        C_TANULOUTONEVE     AS Utonev,
        C_SZULETESIIDO      AS SzuletesiDatum

FROM    T_NEBULO

WHERE   TOROLT = 'F' AND C_FELVETELSTATUSZA = @felvettStatusz
";
            return GetData(commandText, paramList);
        }

        public DataSet GetFelvettEsMegNemLetezoKovTanevesNebulok(bool useNemFelvettStatusz)
        {
            var statusz = ((int)FelvetelStatuszaTipusEnum.Felveve).ToString();
            if (useNemFelvettStatusz)
            {
                statusz += "," + ((int)FelvetelStatuszaTipusEnum.NemFelveve).ToString();
            }

            var commandText = $@"
                SELECT
                    n.ID                  AS Id,
                    n.C_TANULOCSALADINEVE AS Csaladnev,
                    n.C_TANULOUTONEVE     AS Utonev,
                    n.C_SZULETESIIDO      AS SzuletesiDatum
                FROM T_NEBULO n
                WHERE n.TOROLT = 'F' 
                AND n.C_FELVETELSTATUSZA in ({statusz})
                AND NOT EXISTS( /*Kiszedi a köv tanéves userket*/
                    SELECT *
                    FROM T_TANULO_OSSZES ta
                    JOIN T_FELHASZNALO_OSSZES f ON f.ID = ta.ID AND f.TOROLT = 'F'
                    JOIN T_TANEV_OSSZES t on t.ID = ta.C_ALTANEVID
                    WHERE ta.TOROLT = 'F'
                    AND f.C_OKTATASIAZONOSITO = n.C_OKTATASIAZONOSITOSZAMA
                    AND t.TOROLT = 'F' 
                    AND t.C_AKTIV = 'F' 
                    AND t.C_SORSZAM = (SELECT C_SORSZAM + 2 FROM T_TANEV WHERE C_AKTIV = 'T' AND TOROLT = 'F')
                )
                AND NOT EXISTS( /*Kiszedi az akt tanéves sorokat is (óvodás)*/
                    SELECT *
                    FROM T_TANULO ta
                    JOIN T_FELHASZNALO f ON f.ID = ta.ID AND f.TOROLT = 'F'
                    WHERE ta.TOROLT = 'F'
                    AND f.C_OKTATASIAZONOSITO = n.C_OKTATASIAZONOSITOSZAMA
                )
            ";

            return GetData(commandText);
        }

        public void RemoveTanuloMulasztasByDate(int tanuloId, int fromOsztalyId, DateTime date)
        {
            string commandText = @"
                update mulasztas
                set
                  mulasztas.TOROLT = 'T'
                from T_TANULOMULASZTAS mulasztas
                    join T_TANITASIORA t on t.ID = mulasztas.C_TANITASIORAKID and t.TOROLT = 'F' and t.C_OSZTALYCSOPORTID = :pFromOsztalyId
                    join T_OSZTALY o on o.ID = t.C_OSZTALYCSOPORTID and o.TOROLT = 'F' and o.ID = :pFromOsztalyId
                where
                    mulasztas.C_ORATANULOIID = :pTanuloId and cast(mulasztas.LASTCHANGED as date) > :pDate
            ";

            using (SDACommand command = DAUtil.CreateCommand(commandText))
            {
                command.Parameters.Add("pTanuloId", SDADBType.Int).Value = tanuloId;
                command.Parameters.Add("pFromOsztalyId", SDADBType.Int).Value = fromOsztalyId;
                command.Parameters.Add("pDate", SDADBType.String).Value = date.ToString("yyyyMMdd");
                command.ExecuteNonQuery();
            }
        }

        public int Check4TValidacio(int validationType, string vezeteknev, string utonev, string anyjaNeve, string szuletesiHely,
            DateTime szuletesiDatum, int? userId, int tanevId, string elotag)
        {
            int result = -1;

            using (SDACommand command = new SDACommand())
            {
                command.Connection = UserContext.Instance.SDAConnection;
                command.Transaction = UserContext.Instance.SDATransaction;
                command.CommandType = CommandType.StoredProcedure;

                command.CommandText = "sp_Check4TValidation";

                command.Parameters.Add("pCheckValidationType", validationType);
                command.Parameters.Add("pElotag", string.IsNullOrWhiteSpace(elotag) ? "" : elotag);
                command.Parameters.Add("pVezeteknev", vezeteknev);
                command.Parameters.Add("pUtonev", utonev);
                command.Parameters.Add("pAnyjaNeve", anyjaNeve);
                command.Parameters.Add("pSzuletesiHely", szuletesiHely);
                command.Parameters.Add("pSzuletesiDatum", szuletesiDatum);
                command.Parameters.Add("pTanevId", tanevId);
                command.Parameters.Add("pUserId", userId);

                result = Convert.ToInt32(command.ExecuteScalar());
            }

            return result;
        }

        public int CheckOktatasiAzonosito(string oktatasiAzonosito, int tanevId)
        {
            using (SDA.DataProvider.SDACommand command = new SDA.DataProvider.SDACommand())
            {
                command.Connection = UserContext.Instance.SDAConnection;
                command.Transaction = UserContext.Instance.SDATransaction;

                command.Parameters.Add("pOktatasiAzonosito", oktatasiAzonosito);
                command.Parameters.Add("pTanevId", tanevId);

                command.CommandText = @"
                SELECT f.ID FROM T_FELHASZNALO_OSSZES f
                    INNER JOIN T_TANULO_OSSZES t ON t.ID = f.ID AND t.TOROLT = 'F'
                WHERE
                    f.C_OKTATASIAZONOSITO = :pOktatasiAzonosito AND f.C_TANEVID = :pTanevId AND f.TOROLT = 'F'
            ";

                var result = command.ExecuteScalar();
                if (result != null)
                    return int.Parse(result.ToString());
                return -1;
            }
        }

        public DataSet GetKovTanuloByAktTanulo(int tanevId, int aktTanuloId)
        {
            var parameters = new List<CommandParameter>();//TODO @devKornel: obj. initializerrel
            parameters.Add(new CommandParameter("pAktTanuloId", aktTanuloId));
            parameters.Add(new CommandParameter("pKovTanevId", tanevId));

            var commandText = @"
                SELECT
                    aktF.ID as AktTanuloId
                    ,kovF.ID as KovTanuloId
                    ,aktF.C_NYOMTATASINEV as KovTanuloNev
                    ,kovO.ID as KovTanuloOsztalyId
                    ,kovOcs.C_NEV as KovTanuloOsztalyNev
                FROM T_FELHASZNALO_OSSZES aktF
                    LEFT JOIN T_FELHASZNALO_OSSZES kovF ON kovf.C_TANEVID = :pKovTanevId AND kovF.TOROLT = 'F' AND (
                        (kovF.C_VEZETEKNEV = aktF.C_VEZETEKNEV AND kovF.C_UTONEV = aktF.C_UTONEV AND kovF.C_ANYJANEVE = aktF.C_ANYJANEVE AND kovF.C_SZULETESIDATUM = aktF.C_SZULETESIDATUM AND kovF.C_SZULETESIHELY = aktF.C_SZULETESIHELY)
                      OR
                        (kovF.C_OKTATASIAZONOSITO = aktF.C_OKTATASIAZONOSITO)
                    )
                    LEFT JOIN T_TANULOCSOPORT_OSSZES kovTcs ON kovTcs.C_TANULOID = kovF.ID AND kovTcs.C_TANEVID = :pKovTanevId AND kovTcs.TOROLT = 'F'
                    LEFT JOIN T_OSZTALYCSOPORT_OSSZES kovOcs ON kovOcs.ID = kovTcs.C_OSZTALYCSOPORTID AND kovOcs.C_TANEVID = :pKovTanevId AND kovOcs.TOROLT = 'F'
                    LEFT JOIN T_OSZTALY_OSSZES kovO ON kovO.ID = kovTcs.C_OSZTALYCSOPORTID AND kovO.C_ALTANEVID = :pKovTanevId AND kovO.TOROLT = 'F'
                WHERE
                    aktF.ID = :pAktTanuloId AND aktF.TOROLT = 'F'
            ";

            var ds = this.GetData(commandText, parameters);
            return ds;
        }

        public int GetJogviszonyLimit(int tanevId, OktNevelesiKategoriaEnum kategoriaTipus)
        {
            using (var command = new SDACommand())
            {
                command.Connection = UserContext.Instance.SDAConnection;
                command.Transaction = UserContext.Instance.SDATransaction;
                command.Parameters.Add("pTanevID", tanevId);
                command.Parameters.Add("pKategoriaTipus", (int)kategoriaTipus);

                command.CommandText = @"
                    select C_FELADATCSOPORTTANULOOSZTALYK from T_OKTNEVELESIKATEGORIA_OSSZES
                    where ID = @pKategoriaTipus and C_ALTANEVID = @pTanevID
                ";

                var result = command.ExecuteScalar();

                if (result != DBNull.Value && result != null)
                {
                    return Convert.ToInt32(result);
                }

                return 1;
            }
        }

        public DataSet GetTanuloOsztalyKapcsolatok(int tanevId, int tanuloId, DateTime datum, OktNevelesiKategoriaEnum kategoriaTipus)
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanuloId", tanuloId),
                new CommandParameter("pTanevId", tanevId),
                new CommandParameter("pDatum", datum),
                new CommandParameter("pKategoria", (int)kategoriaTipus)
            };

            var commandText = @"
select
ocs.ID Id
,ocs.C_NEV Nev
,tcs.ID TanuloCsoportId
,cs.ID CsoportId
,cs.C_OSZTALYBONTASID OsztalybontasId
,ISNULL(cs.C_ISAUTOEGYENICSOPORT,'F') IsAutoEgyeni
,cs.CREATED CsoportLetrehozasDatuma
from T_OSZTALYCSOPORT_OSSZES ocs
INNER JOIN T_TANULOCSOPORT_OSSZES tcs ON tcs.C_OSZTALYCSOPORTID = ocs.ID
  AND tcs.TOROLT ='F' and tcs.C_TANEVID = @pTanevId
  AND tcs.C_BELEPESDATUM <= @pDatum AND (tcs.C_KILEPESDATUM IS NULL OR tcs.C_KILEPESDATUM > @pDatum)
  AND ocs.C_FELADATKATEGORIAID = @pKategoria
  AND tcs.C_TANULOID = @pTanuloId
LEFT JOIN T_CSOPORT_OSSZES cs on cs.ID = ocs.ID
            ";

            var ds = this.GetData(commandText, parameters);
            return ds;
        }

        public DataSet GetOsztalyEgyeniCsoportok(int tanevId, int osztalyId)
        {
            var parameters = new List<CommandParameter>();
            parameters.Add(new CommandParameter("pTanevId", tanevId));
            parameters.Add(new CommandParameter("pOsztaly", osztalyId));

            var commandText = @"
select
    tcs.ID as ID
    ,tcs.C_TANULOID as TanuloId
    ,cs.ID as EgyeniCsoportId
from T_TANULOCSOPORT_OSSZES tcs
INNER JOIN T_CSOPORT_OSSZES cs ON tcs.C_OSZTALYCSOPORTID = cs.ID AND cs.C_ISAUTOEGYENICSOPORT = 'T' AND cs.TOROLT = 'F' AND cs.C_OSZTALYBONTASID = :pOsztaly
where
    tcs.TOROLT = 'F' AND tcs.C_TANEVID = :pTanevId
            ";

            var ds = this.GetData(commandText, parameters);
            return ds;
        }

        public DataSet GetOsztalyCsoportokByNev(int tanevId, string osztalyCsoportNev)
        {
            var parameters = new List<CommandParameter>();
            parameters.Add(new CommandParameter("pTanevId", tanevId));
            parameters.Add(new CommandParameter("pOsztalyCsoportNev", osztalyCsoportNev));

            var commandText = @"
select
     ocs.ID as ID
    ,ocs.C_NEV as EgyeniCsoportNev
from T_OSZTALYCSOPORT_OSSZES ocs
where
    ocs.TOROLT = 'F' AND ocs.C_TANEVID = :pTanevId AND ocs.C_NEV LIKE '%' + :pOsztalyCsoportNev + '%'
            ";

            var ds = this.GetData(commandText, parameters);
            return ds;
        }

        public DataSet GetTanuloByTanevAndOsztalyAndKiiratkoztatasDatum(int tanevId, int? tanuloId = null, int? osztalyId = null, DateTime? kiiratkoztatasDatum = null)
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanevId", tanevId)
            };

            StringBuilder commandText = new StringBuilder(@"
            select
            ID
            ,C_OSZTALYCSOPORTID
            ,C_TANULOID
            ,C_KILEPESDATUM
            from T_TANULOCSOPORT_OSSZES
            WHERE C_TANEVID = :pTanevId AND TOROLT = 'F'
            ");

            if (tanuloId.HasValue)
            {
                commandText.Append($" AND C_TANULOID = @{nameof(tanuloId)} ");
                parameters.Add(new CommandParameter(nameof(tanuloId), tanuloId));
            }

            if (osztalyId.HasValue)
            {
                commandText.Append($" AND C_OSZTALYCSOPORTID = @{nameof(osztalyId)} ");
                parameters.Add(new CommandParameter(nameof(osztalyId), osztalyId));
            }

            if (kiiratkoztatasDatum.HasValue)
            {
                commandText.Append($" AND C_KILEPESDATUM = @{nameof(kiiratkoztatasDatum)} ");
                parameters.Add(new CommandParameter(nameof(kiiratkoztatasDatum), kiiratkoztatasDatum));
            }

            var ds = this.GetData(commandText.ToString(), parameters);
            return ds;
        }

        public DataSet GetTanuloCsoportDataSet(int tanevId, int? oktNevelesiKategoriaId = null)
        {
            var commandParameterList = new List<CommandParameter>
            {
                new CommandParameter("pTanevId", tanevId),
                oktNevelesiKategoriaId.IsEntityId() ?
                    new CommandParameter("pOktNevelesiKategoriaId", oktNevelesiKategoriaId.Value) :
                    new CommandParameter("pOktNevelesiKategoriaId", DBNull.Value)
            };

            const string commandText = @"
                SELECT
                   tcs.ID AS Id
                  ,tcs.C_BELEPESDATUM AS BelepesDatum
                  ,tcs.C_KILEPESDATUM AS KilepesDatum
                  ,tcs.C_IMPORTALT AS Importalt

                  ,fh.ID AS FelhasznaloId
                  ,fh.C_NEVSORREND AS FelhasznaloNevsorrend
                  ,fh.C_ELOTAG AS FelhasznaloElotag
                  ,fh.C_VEZETEKNEV AS FelhasznaloVezeteknev
                  ,fh.C_UTONEV AS FelhasznaloKeresztnev
                  ,fh.C_SZULETESIHELY AS FelhasznaloSzuletesiHely
                  ,fh.C_SZULETESIDATUM AS FelhasznaloSzuletesiIdo
                  ,fh.C_ANYJANEVE AS FelhasznaloAnyjaNeve
                  ,fh.C_OKTATASIAZONOSITO AS FelhasznaloOktatasiAzonosito

                  ,ocs.ID AS OsztalyCsoportId
                  ,ocs.C_NEV AS OsztalyCsoportNev
                  ,ocs.C_FELADATKATEGORIAID AS OsztalyCsoportFeladatKategoriaId
                FROM T_TANULOCSOPORT_OSSZES tcs
                  INNER JOIN T_FELHASZNALO_OSSZES fh ON fh.ID = tcs.C_TANULOID AND fh.C_TANEVID = tcs.C_TANEVID AND fh.TOROLT = 'F'
                  INNER JOIN T_TANULO_OSSZES dk ON dk.ID = tcs.C_TANULOID AND dk.C_ALTANEVID = tcs.C_TANEVID AND dk.TOROLT = 'F'
                  INNER JOIN T_OSZTALYCSOPORT_OSSZES ocs ON ocs.ID = tcs.C_OSZTALYCSOPORTID AND ocs.C_TANEVID = tcs.C_TANEVID AND ocs.TOROLT = 'F'
                    AND (:pOktNevelesiKategoriaId IS NULL OR ocs.C_FELADATKATEGORIAID = :pOktNevelesiKategoriaId)
                WHERE tcs.C_TANEVID = :pTanevId
                  AND tcs.TOROLT = 'F'
            ";

            return GetData(commandText, commandParameterList);
        }

        public DataSet GetFeladatkategoriabaTartozoTanuloCsoportok(int tanevId, int tanuloId, int osztalyId)
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pOsztalyID", osztalyId),
                new CommandParameter("pTanuloID", tanuloId),
                new CommandParameter("ptanevId", tanevId),
            };
            string CommandText = @"
            SELECT tcs.ID
            ,tcs.C_TANULOID
                FROM
                T_CSOPORT_OSSZES cs
                    INNER JOIN T_TANULOCSOPORT_OSSZES tcs ON tcs.C_OSZTALYCSOPORTID = cs.ID
                    INNER JOIN T_OSZTALYCSOPORT_OSSZES ocs ON ocs.ID = cs.Id AND ocs.C_FELADATKATEGORIAID = (SELECT C_FELADATKATEGORIAID FROM T_OSZTALYCSOPORT_OSSZES WHERE ID = :pOsztalyID)
            WHERE
                tcs.C_TANULOID = :pTanuloID
                AND tcs.C_TANEVID = :ptanevId
                AND tcs.TOROLT = 'F'
                AND ocs.TOROLT = 'F' ";
            var ds = this.GetData(CommandText, parameters);
            return ds;
        }

        public bool IsTanuloJogviszonyKetDatumKozott(int tanevId, int tanuloId, DateTime kezdete, DateTime vege, int? feladatKategoriaId = (int)OktNevelesiKategoriaEnum.NevelesOktatas)
        {
            using (var command = new SDACommand())
            {
                command.Connection = UserContext.Instance.SDAConnection;
                command.Transaction = UserContext.Instance.SDATransaction;
                command.CommandType = CommandType.Text;
                command.CommandText = @"
                    SELECT tcso.ID
                    FROM T_TANULOCSOPORT tcso 
                        INNER JOIN T_OSZTALY o ON o.ID=tcso.C_OSZTALYCSOPORTID
                        INNER JOIN T_OSZTALYCSOPORT ocso ON ocso.ID = o.ID AND ocso.C_FELADATKATEGORIAID = :pFeladatKategoriaId
                    WHERE 
                        (
                            tcso.C_BELEPESDATUM < :pJogviszonyVizsgalatVege AND (tcso.C_KILEPESDATUM >= :pJogviszonyVizsgalatEleje OR tcso.C_KILEPESDATUM IS NULL)
                        )
                        AND tcso.C_TANULOID = :pTanuloId
                        AND tcso.C_TANEVID = :pTanevId                
                ";
                command.Parameters.Add("pTanevId", SDADBType.Int).Value = tanevId;
                command.Parameters.Add("pTanuloId", SDADBType.Int).Value = tanuloId;
                command.Parameters.Add("pJogviszonyVizsgalatEleje", SDADBType.DateTime).Value = kezdete;
                command.Parameters.Add("pJogviszonyVizsgalatVege", SDADBType.DateTime).Value = vege;
                feladatKategoriaId = feladatKategoriaId ?? (int)OktNevelesiKategoriaEnum.NevelesOktatas;
                command.Parameters.Add("pFeladatKategoriaId", SDADBType.Int).Value = feladatKategoriaId;

                return ((int?)command.ExecuteScalar()).HasValue;
            }
        }

        public DataSet GetJogviszonyLimitList(int tanevId)
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanevId", tanevId),
            };

            var commandText = @"
SELECT
     ID
    ,C_FELADATCSOPORTTANULOOSZTALYK 
FROM T_OKTNEVELESIKATEGORIA_OSSZES
WHERE TOROLT = 'F' AND C_ALTANEVID = @pTanevId";

            var ds = GetData(commandText, parameters);
            return ds;
        }

        public DataSet GetOsztalybaNemSoroltTanulok(DateTime kisorolasDatum, int tanevId, bool isLeptetes, bool pIsJogviszonyKezeles = false)
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pKisorolasDatum", kisorolasDatum),
                new CommandParameter("pFeladatKategoriaId", (int)OktNevelesiKategoriaEnum.NevelesOktatas),
                new CommandParameter("pTanevId", tanevId),
            };
            var commandText = @"
            SELECT
                 t.ID AS Id
                ,f.C_NYOMTATASINEV + ' (' + CONVERT(nvarchar(50), f.C_SZULETESIDATUM, 102) + '.) ' AS Nev
                ,f.C_SZULETESIDATUM AS SzulDatum
                ,f.C_NEME AS Neme "
                + (!pIsJogviszonyKezeles ? "" : @"
                ,NULL as JogviszonyId
                ,jv.JogviszonyCount ") + $@"
            FROM T_FELHASZNALO f
            INNER JOIN T_TANULO t ON f.ID = t.ID AND t.C_ALTANEVID = @pTanevId
            OUTER APPLY (
                SELECT tcs.ID
                FROM T_TANULOCSOPORT tcs
                INNER JOIN T_OSZTALYCSOPORT ocs ON ocs.ID = tcs.C_OSZTALYCSOPORTID AND ocs.C_FELADATKATEGORIAID = @pFeladatKategoriaId
                INNER JOIN T_OSZTALY o ON o.ID = ocs.ID
                WHERE tcs.C_TANULOID = t.ID
                    AND tcs.C_BELEPESDATUM < @pKisorolasDatum
                    AND (tcs.C_KILEPESDATUM IS NULL OR tcs.C_KILEPESDATUM >" + (!isLeptetes ? "=" : "") + @" @pKisorolasDatum)
            ) tcs" +
            (!pIsJogviszonyKezeles ? "" : @"
            OUTER APPLY (
                SELECT jv.C_TANULOID as tanuloId, MAX(jv.ID) as JogviszonyId,COUNT(1) JogviszonyCount
                FROM T_TBJOGVISZONY_OSSZES jv 
                    WHERE jv.C_TANULOID = f.ID
                        AND jv.TOROLT = 'F'
                        AND jv.C_ISAKTIV = 'T'
                        AND jv.C_JOGVMEGSZUNESEJOGCIMTIPUSID IS NULL
                        AND jv.C_TANEVID = @pTanevId
                    GROUP BY jv.C_TANULOID) jv "
            ) + $@"
            WHERE tcs.ID IS NULL ";

            var ds = GetData(commandText, parameters, dictionaryItemColumns: "Neme");
            return ds;
        }

        public int GetTanuloOsztalybaSorolasainakSzama(int tanuloId, int tanevId, OktNevelesiKategoriaEnum kategoriaTipus)
        {
            var parameters = new List<CommandParameter>
            {
                new CommandParameter("pTanuloId", tanuloId),
                new CommandParameter("pFeladatKategoriaId", (int)kategoriaTipus),
                new CommandParameter("pTanevId", tanevId),
            };

            var commandText = @"
            SELECT 1
            FROM T_TANULOCSOPORT_OSSZES tcs
              INNER JOIN T_OSZTALY_OSSZES o ON o.ID = tcs.C_OSZTALYCSOPORTID AND o.TOROLT = 'F' AND o.C_ALTANEVID = @pTanevId
              INNER JOIN T_OSZTALYCSOPORT_OSSZES ocs ON o.ID = ocs.ID AND ocs.TOROLT = 'F' AND ocs.C_TANEVID = @pTanevId
            WHERE
              tcs.C_TANULOID = @pTanuloId
              AND ocs.C_FELADATKATEGORIAID = @pFeladatKategoriaId
              AND tcs.TOROLT = 'F'
              AND tcs.C_TANEVID = @pTanevId";

            var ds = GetData(commandText, parameters);

            return ds.Tables[0].Rows.Count;
        }
    }
}