/// <summary>
 /// form felépítéséhez szolgáló queryk futtatása
 /// </summary>
 /// <param name="ID_Form">form id-ja</param>
 /// <returns>CustomForm egy példányát adja vissza</returns>      
 public CustomForm GetFormById(int ID_Form)
 {
     CustomForm myForm = new CustomForm();
     myForm.FormHeader = GetFormHeaderByFormId(ID_Form);
     myForm.Rowdefinition = GetFormRowDefinitionByFormId(ID_Form);
     myForm.Fieldoptions = GetFormFieldOptionsByFormId(ID_Form);
     return myForm;
 }
        /// <summary>
        /// szerkesztés megkezdésekor kezdő értékek letárolása tbl_frmFormTransaction táblában
        /// </summary>
        /// <param name="ID_Created_By">user id</param>
        /// <param name="myForm">CustomForm példány</param>
        /// <param name="blAddnew">új rekord felvétele/módosítás</param>
        /// <returns>CustomForm</returns>
        private CustomForm OpenFormTransactionRows(int ID_Created_By, ref CustomForm myForm, bool blAddnew)
        {
            if (myForm.Status == FormStatus.AccesDenied)
                {
                    return myForm;
                }

                ServiceConfig srvcont = new ServiceConfig(_serviceconfigparameters);
                try
                {
                    var form_data = GetFormDataByFormIdKeyValue(myForm.FormHeader.FormID, myForm.FormHeader.KeyValue, blAddnew);

                    if (form_data == null || form_data.Count == 0)
                    {
                        myForm.Status = FormStatus.InvalidParameters;
                        myForm.StatusMessage = "Selected item does not exist in the current table!";
                        return myForm;
                    }

                    myForm.Data = form_data;
                    var stat_open_id = srvcont.DataContext.tbl_frmTransactionStatus.FirstOrDefault(f => f.TransactionStatus == Constants.TRANSACTION_STATUS.OPEN).ID;
                    foreach (var row in form_data)
                    {
                        var transaction_item = new Entities.tbl_frmFormTransaction();
                        transaction_item.ID_frmFormTransactionHeader = myForm.FormHeader.EditGuid;
                        transaction_item.ID_frmFormField = (int)row.fieldid;
                        transaction_item.ID_frmTransactionStatus = stat_open_id;
                        transaction_item.Value = row.id;
                        transaction_item.TS_CREATE = DateTime.Now;
                        transaction_item.CREATED_BY = ID_Created_By;
                        transaction_item.VALID_FROM = DateTime.Now;
                        transaction_item.VALID_TO = myForm.FormHeader.EditGuidExpire;
                        srvcont.DataContext.tbl_frmFormTransaction.AddObject(transaction_item);
                    }

                    srvcont.DataContext.SaveChanges();
                    myForm.Status = FormStatus.ProcedureReady;
                    myForm.FormHeader.IsReadOnly = false;

                }
                catch (Exception ex)
                {
                    HelperClasses.ExceptionHandler.LogException(ex, srvcont, "OpenFormTransactionRows");
                    myForm.Status = FormStatus.ProcedureFailed;
                    myForm.FormHeader.IsReadOnly = true;
                    myForm.StatusMessage = "Form rows openening failed!";
                }

                return myForm;
        }
        /// <summary>
        /// 1) edit guid létrehozása, kiválasztott rekord tárolása tbl_frmFormTransactionHeader táblában
        /// </summary>
        /// <param name="ID_Created_By">user id, aki a szerkesztést indítja</param>
        /// <param name="myForm">CustomForm egy példánya</param>
        /// <param name="blAddnew">új rekord felvétele/módosítás</param>
        /// <returns>CustomForm</returns>
        private CustomForm OpenEditGuid(int ID_Created_By, ref CustomForm myForm, bool blAddnew)
        {
            ServiceConfig srvcont = new ServiceConfig(_serviceconfigparameters);
                var header_item = new Entities.tbl_frmFormTransactionHeader();

                if (myForm.Status == FormStatus.AccesDenied)
                {
                    return myForm;
                }

                try
                {
                    header_item.ID = Guid.NewGuid().ToString();
                    header_item.ID_frmForm = myForm.FormHeader.FormID;
                    header_item.NewItem = blAddnew;
                    header_item.ID_genTableField = myForm.FormHeader.ID_TableField;
                    header_item.KeyValue = myForm.FormHeader.KeyValue;
                    header_item.ID_frmTransactionStatus = srvcont.DataContext.tbl_frmTransactionStatus.FirstOrDefault(f => f.TransactionStatus == Constants.TRANSACTION_STATUS.OPEN).ID;
                    header_item.OBSOLATE = false;
                    header_item.CREATED_BY = ID_Created_By;
                    header_item.TS_CREATE = DateTime.Now;
                    header_item.VALID_FROM = DateTime.Now;
                    header_item.VALID_TO = myForm.FormHeader.EditGuidExpire;

                    srvcont.DataContext.tbl_frmFormTransactionHeader.AddObject(header_item);
                    srvcont.DataContext.SaveChanges();

                    myForm.FormHeader.EditGuid = header_item.ID;
                    myForm.Status = FormStatus.ProcedureInProgress;
                }
                catch (Exception ex)
                {
                    HelperClasses.ExceptionHandler.LogException(ex, srvcont, "OpenEditGuid");
                    myForm.Status = FormStatus.ProcedureFailed;
                    myForm.StatusMessage = "Form header openening failed!";
                    myForm.FormHeader.IsReadOnly = true;
                    myForm.FormHeader.EditGuid = "";

                }

                return myForm;
        }
        /// <summary>
        /// mentéskor tbl_frmFormTransaction táblában kezdő értékek invalidálása
        /// </summary>
        /// <param name="ID_Created_By">user id</param>
        /// <param name="myForm">CustomForm példány</param>
        private void InvalidateFormTransactionRows(int ID_Created_By, ref CustomForm myForm)
        {
            if (myForm.Status == FormStatus.AccesDenied)
                {
                    return;
                }

                ServiceConfig srvcont = new ServiceConfig(_serviceconfigparameters);
                string guid = myForm.FormHeader.EditGuid;
                var stat_cancel_id = srvcont.DataContext.tbl_frmTransactionStatus.FirstOrDefault(f => f.TransactionStatus == Constants.TRANSACTION_STATUS.CANCELED).ID;
                try
                {
                    myForm.Status = FormStatus.ProcedureInProgress;
                    foreach (var item in myForm.Data)
                    {
                        var trRow = srvcont.DataContext.tbl_frmFormTransaction.FirstOrDefault(f => f.ID_frmFormTransactionHeader == guid && f.ID_frmFormField == item.fieldid && f.OBSOLATE == false && f.CREATED_BY == ID_Created_By);
                        if (trRow != null)
                        {
                            trRow.OBSOLATE = true;
                            trRow.ID_frmTransactionStatus = stat_cancel_id;
                        }
                    }
                    srvcont.DataContext.SaveChanges();
                    myForm.Status = FormStatus.ProcedureReady;
                }
                catch (Exception ex)
                {

                    HelperClasses.ExceptionHandler.LogException(ex, srvcont, "InvalidateFormTransactionRow");
                    myForm.Status = FormStatus.ProcedureFailed;
                    myForm.FormHeader.IsReadOnly = true;
                    myForm.StatusMessage = "Invalidating FormTransactionRow failed!";
                }
        }
        /// <summary>
        /// mentéskor tbl_frmFormTransaction táblába új értékek beszúrása
        /// </summary>
        /// <param name="ID_Created_By">user id</param>
        /// <param name="myForm">CustomForm példány</param>
        private void InsertFormTransactionRows(int ID_Created_By, ref CustomForm myForm)
        {
            if (myForm.Status == FormStatus.AccesDenied)
                {
                    return;
                }

                ServiceConfig srvcont = new ServiceConfig(_serviceconfigparameters);

                string guid = myForm.FormHeader.EditGuid;
                int table_fieldid = myForm.FormHeader.ID_TableField;
                var stat_open_id = srvcont.DataContext.tbl_frmTransactionStatus.FirstOrDefault(f => f.TransactionStatus == Constants.TRANSACTION_STATUS.OPEN).ID;
                var expire = srvcont.DataContext.tbl_frmFormTransactionHeader.FirstOrDefault(f => f.ID == guid && f.ID_genTableField == table_fieldid && f.CREATED_BY == ID_Created_By).VALID_TO;

                try
                {
                    myForm.Status = FormStatus.ProcedureInProgress;
                    foreach (var item in myForm.Data)
                    {
                        Entities.tbl_frmFormTransaction nRow = new Entities.tbl_frmFormTransaction();
                        nRow.ID_frmFormTransactionHeader = myForm.FormHeader.EditGuid;
                        nRow.ID_frmTransactionStatus = stat_open_id;
                        nRow.ID_frmFormField = (int)item.fieldid;
                        nRow.Value = item.id;
                        nRow.TS_CREATE = DateTime.Now;
                        nRow.CREATED_BY = ID_Created_By;
                        nRow.VALID_FROM = DateTime.Now;
                        nRow.VALID_TO = expire;
                        srvcont.DataContext.tbl_frmFormTransaction.AddObject(nRow);
                    }

                    srvcont.DataContext.SaveChanges();
                    myForm.Status = FormStatus.ProcedureReady;

                }
                catch (Exception ex)
                {

                    HelperClasses.ExceptionHandler.LogException(ex, srvcont, "InsertFormTransactionRow");
                    myForm.Status = FormStatus.ProcedureFailed;
                    myForm.FormHeader.IsReadOnly = true;
                    myForm.StatusMessage = "Inserting FormTransactionRow failed!";
                }
        }
        /// <summary>
        /// Cancel státusz állítása tbl_frmFormTransaction táblában
        /// </summary>
        /// <param name="ID_Created_By">user id</param>
        /// <param name="myForm">CustomForm példány</param>
        private void CancelFormTransactionRows(int ID_Created_By, ref CustomForm myForm)
        {
            if (myForm.Status == FormStatus.AccesDenied)
                {
                    return;
                }

                ServiceConfig srvcont = new ServiceConfig(_serviceconfigparameters);

                string guid = myForm.FormHeader.EditGuid;
                int table_fieldid = myForm.FormHeader.ID_TableField;
                var stat_cancel_id = srvcont.DataContext.tbl_frmTransactionStatus.FirstOrDefault(f => f.TransactionStatus == Constants.TRANSACTION_STATUS.CANCELED).ID;

                try
                {

                    var trRows = from row in srvcont.DataContext.tbl_frmFormTransaction.Where(w => w.ID_frmFormTransactionHeader == guid && w.CREATED_BY == ID_Created_By)
                                 select row;

                    foreach (var trRow in trRows)
                    {
                        trRow.MODIFIED_BY = ID_Created_By;
                        trRow.OBSOLATE = true;
                        trRow.ID_frmTransactionStatus = stat_cancel_id;
                    }

                    srvcont.DataContext.SaveChanges();
                    myForm.Status = FormStatus.ProcedureReady;

                }
                catch (Exception ex)
                {

                    HelperClasses.ExceptionHandler.LogException(ex, srvcont, "CancelFormTransactionRows");
                    myForm.Status = FormStatus.ProcedureFailed;
                    myForm.FormHeader.IsReadOnly = true;
                    myForm.StatusMessage = "Cancelling FormTransactionRows failed!";
                }
        }
        /// <summary>
        /// form mentése
        /// 0) ID_TrHeader, ID_Tablefield alapján annak ellenőrzése, hogy az adott editguid létezik-e
        /// 1) ID_TrHeader, ID_FormField alapján tbl_frmFormTransaction tábla sorainak érvénytelenítése
        /// 2) ID_TrHeader guid, ID_FormField, frm_keyValue alapján új sorok felvétele tbl_frmFormTransaction táblába
        /// 3) értékekek validálása
        /// 4) update sp futtatása
        /// 5) mentés ellenőrzése
        /// </summary>
        /// <param name="ID_Created_By">user id</param>
        /// <param name="json_arr">formheader</param>
        /// <returns>CustomForm</returns>
        public CustomForm SetFormData_Save(int ID_Created_By, string json_arr_header, string json_arr_data)
        {
            ServiceConfig srvcont = new ServiceConfig(_serviceconfigparameters);
                HelperClasses.Serializer srl = new HelperClasses.Serializer();

                CustomForm myForm = new CustomForm();
                myForm.FormHeader = srl.NTSoftJsonDeserialize<CustomFormHeader>(json_arr_header);
                myForm.Data = srl.NTSoftJsonDeserialize<List<FormData>>(json_arr_data);

                if (string.IsNullOrEmpty(myForm.FormHeader.EditGuid) || myForm.FormHeader.ID_TableField == 0 || ID_Created_By == 0)
                {
                    myForm.Status = FormStatus.InvalidParameters;
                    myForm.StatusMessage = "Error in Formheader!";
                    myForm.FormHeader.IsReadOnly = true;
                    return myForm;
                }

                //0)
                if (!EditGuidExist(myForm.FormHeader.EditGuid, myForm.FormHeader.ID_TableField, ID_Created_By))
                {
                    myForm.Status = FormStatus.AccesDenied;
                    myForm.StatusMessage = "Your edit session is expired or does not exist!";
                    myForm.FormHeader.IsReadOnly = true;
                    return myForm;
                }

                //1)
                InvalidateFormTransactionRows(ID_Created_By, ref myForm);

                if (myForm.Status == FormStatus.ProcedureReady)
                {
                    //2)
                    InsertFormTransactionRows(ID_Created_By, ref myForm);
                }

                //3 validálás

                foreach (var item in myForm.Data)
                {
                    if (!ValueIsValid((int)item.fieldid, item.id))
                    {
                        myForm.Status = FormStatus.InvalidParameters;
                        myForm.StatusMessage = "Form validation failed!";
                        return myForm;
                    }
                }

                if (myForm.Status == FormStatus.ProcedureReady)
                {
                    var stat_save_id = srvcont.DataContext.tbl_frmTransactionStatus.FirstOrDefault(f => f.TransactionStatus == Constants.TRANSACTION_STATUS.SAVED).ID;
                    //4)
                    srvcont.DataContext.sp_frmSetData(myForm.FormHeader.EditGuid, stat_save_id);
                    //5)
                    if (IsDataSaved(myForm.FormHeader.EditGuid, myForm.FormHeader.ID_TableField, ID_Created_By))
                    {
                        myForm.Status = FormStatus.ProcedureReady;
                    }
                    else
                    {
                        myForm.Status = FormStatus.ProcedureFailed;
                        myForm.StatusMessage = "Error in form save routine!";
                        myForm.FormHeader.IsReadOnly = true;
                        return myForm;
                    }
                }
                //save sp meghívása
                return myForm;
        }
        /// <summary>
        /// rekord Cancel státusz állítása tbl_frmFormTransactionHeader, tbl_frmFormTransaction táblákban
        /// </summary>
        /// <param name="ID_Created_By"></param>
        /// <param name="json_arr"></param>
        /// <returns>CustomForm</returns>
        public CustomForm SetFormData_Cancel(int ID_Created_By, string json_arr)
        {
            ServiceConfig srvcont = new ServiceConfig(_serviceconfigparameters);
                HelperClasses.Serializer srl = new HelperClasses.Serializer();

                CustomForm myForm = new CustomForm();
                myForm.FormHeader = srl.NTSoftJsonDeserialize<CustomFormHeader>(json_arr);

                if (string.IsNullOrEmpty(myForm.FormHeader.EditGuid) || myForm.FormHeader.ID_TableField == 0 || ID_Created_By == 0)
                {
                    myForm.Status = FormStatus.InvalidParameters;
                    myForm.StatusMessage = "Error in Formheader!";
                    myForm.FormHeader.IsReadOnly = true;
                    return myForm;
                }

                CancelFormTransactionHeader(ID_Created_By, ref myForm);

                if (myForm.Status == FormStatus.ProcedureInProgress)
                {
                    //2)
                    CancelFormTransactionRows(ID_Created_By, ref myForm);
                }

                return myForm;
        }
        /// <summary>
        /// form szerkesztésének megkezdésekor: 
        /// 0) ID_TableField, KeyValue alapján annak ellenőrzése, hogy az adott rekord szerkeszthető-e
        /// 1) edit guid létrehozása, kiválasztott rekord tárolása tbl_frmFormTransactionHeader táblában -> EditGuidOpen()
        /// 2) formon szereplő kezdő értékek letárolása tbl_frmFormTransaction táblába
        /// </summary>
        /// <param name="ID_Form">annak a formnak az id-ja, amin a szerkesztés történik</param>
        /// <param name="ID_Created_By">user id, aki a szerkesztést indítja</param>
        /// <param name="frm_keyValue">formhoz tartozó tábla kulcs mezőjének értéke (szerkesztett rekord azonosítója)</param>
        /// <returns>CustomForm</returns>
        public CustomForm SetFormData_BeginEdit(int ID_Form, int ID_Created_By, string frm_keyValue, bool blAddNew)
        {
            ServiceConfig srvcont = new ServiceConfig(_serviceconfigparameters);
                CustomForm myForm = new CustomForm();

                if (ID_Form == 0 || ID_Created_By == 0 || string.IsNullOrEmpty(frm_keyValue))
                {
                    myForm.Status = FormStatus.InvalidParameters;
                    myForm.StatusMessage = "Form or item is not selected!";
                    return myForm;
                }

                //ha új elem felvétele, akkor keyValue + guid
                myForm.FormHeader.KeyValue = blAddNew ? frm_keyValue + Guid.NewGuid().ToString() : frm_keyValue;
                //ha új elem felvétele, akkor long expire
                myForm.FormHeader.EditGuidExpire = blAddNew ? DateTime.Now.AddMinutes(ExpireMinutesLong) : DateTime.Now.AddMinutes(ExpireMinutes);
                myForm.FormHeader.FormID = ID_Form;
                myForm.FormHeader.ID_TableField = (int)srvcont.DataContext.tbl_frmForm.FirstOrDefault(f => f.ID == ID_Form).ID_genTableField;

                //0)
                int? lockedByUser = KeyValueLockedByUser(myForm.FormHeader.ID_TableField, myForm.FormHeader.KeyValue);
                if(lockedByUser != null)
                {
                    string winName = srvcont.DataContext.tbl_hrStaff.FirstOrDefault(f => f.ID == lockedByUser).Windows_user_name;
                    myForm.Status = FormStatus.AccesDenied;
                    myForm.StatusMessage = "Selected item is currently being modified by user: "******" ! Please try later!";
                    myForm.FormHeader.IsReadOnly = true;
                    return myForm;
                }

                //1)
                OpenEditGuid(ID_Created_By, ref myForm, blAddNew);
                if (myForm.Status == FormStatus.ProcedureInProgress)
                {
                    //2)
                    OpenFormTransactionRows(ID_Created_By, ref myForm, blAddNew);
                }

                return myForm;
        }