/// <summary>
        /// Get the list of inspection reports
        /// </summary>
        /// <param name="parameters">Filter data to execute the search</param>
        /// <returns>DynamicDataGrid</returns>
        public static DynamicDataGrid SearchInspectionReportList(ParameterSearchInspectionReport parameters)
        {
            DynamicDataGrid dynamicDataGrid = new DynamicDataGrid();
            DynamicDataRow dataRow = null;
            PaginatedList<FormValue> resultQuery = null;
            string fieldName = string.Empty;
            string fieldValue = string.Empty;
            int fieldType = 0;
            List<PropertyInfo> filterProperties = null;
            List<string> gridFields = new List<string>();
            Dictionary<string, DynamicDataRowValue> temRowValues = null;
            List<FormValue> inspectionReportItemQuery = null;
            List<ApprovalItem> approvalItems = null;
            List<Guid?> inspectionReportItemIds = null;
            //obtain the definition of the form
            Form inspectionReportForm = DynamicFormEngine.GetFormDefinition(parameters.BusinessApplicationId, FormType.InspectionReport, parameters.InspectionReportName, parameters.IsClient);
            //obtain the id of the selected inspection report
            Guid inspectionReportId = GetInspectionReportByName(parameters.InspectionReportName, parameters.ServiceOrderId).InspectionReportId;

            using (VestalisEntities context = new VestalisEntities())
            {
                //get the query
                resultQuery = GetInspectionReportQuery(context, inspectionReportId, parameters, ref inspectionReportItemIds);
                //set data of pagination
                dynamicDataGrid.Page = parameters.SelectedPage;
                dynamicDataGrid.NumberOfPages = resultQuery.NumberOfPages;
                dynamicDataGrid.TotalNumberOfItemsWithoutPagination = resultQuery.TotalCount;
                dynamicDataGrid.PageSize = parameters.PageSize;

                //Get approval items for the inspection report and the roles of the logged user

                approvalItems = GetApprovalItemsGivenIds(context, inspectionReportItemIds, parameters.RolesForUser);
                //set flags for show buttons
                dynamicDataGrid.CanPublishAll = approvalItems.Any(data => data.CanPublish.GetValueOrDefault() && data.ApprovalStatus == (int)ApprovalStatus.Ready);
                dynamicDataGrid.CanValidateAll = approvalItems.Any(data => !data.CanPublish.GetValueOrDefault() && data.ApprovalStatus == (int)ApprovalStatus.Ready);

                inspectionReportItemQuery = resultQuery.Collection;

                var groupInspectionReports = (from formValue in inspectionReportItemQuery
                                              group formValue by new { formValue.InspectionReportItemId }
                                                  into rows
                                                  select new
                                                  {
                                                      serviceOrderId = rows.Key,
                                                      rows
                                                  });

                if (inspectionReportForm != null && (inspectionReportItemQuery != null && inspectionReportItemQuery.Count > 0))
                {
                    //get the fields that can be showed in the grid
                    foreach (var section in inspectionReportForm.Sections)
                    {
                        if (parameters.IsClient)
                        {
                            gridFields.AddRange(
                                section.FormElements.Where(element => element.IsDataGridVisible && element.IsVisibleClient).Select(
                                    element => element.Identifier));
                        }
                        else
                        {
                            gridFields.AddRange(
                                section.FormElements.Where(element => element.IsDataGridVisible).Select(
                                    element => element.Identifier));
                        }
                    }

                    var formValueProperties = new List<string>();
                    formValueProperties.Add("FieldType");
                    formValueProperties.Add("FieldName");

                    //Get the fields definition for the business application
                    Fields fieldBusinessApplication = CacheHandler.Get(String.Format("Field{0}", parameters.BusinessApplicationId),
                                                    () => DynamicFormEngine.GetFields(parameters.BusinessApplicationId));

                    foreach (var group in groupInspectionReports)
                    {
                        dataRow = new DynamicDataRow();
                        temRowValues = new Dictionary<string, DynamicDataRowValue>();
                        gridFields.ForEach(field =>
                        {
                            Field currentField = fieldBusinessApplication.Items.FirstOrDefault(x => x.FieldName == field);
                            if (currentField is FieldsPictureField)
                            {
                                if (!parameters.IsExport)
                                {
                                    temRowValues.Add(field, new DynamicDataRowValue() { FieldType = (int)FieldType.PictureField });
                                    temRowValues[field].Pictures = PictureDocumentBusiness.SearchPictureGridInspectionReport(parameters.ServiceOrderId, group.serviceOrderId.InspectionReportItemId.Value);
                                }
                                else
                                {
                                    var captionPic = parameters.Captions.FirstOrDefault(caption => caption.FieldName == currentField.FieldName);
                                    parameters.Captions.Remove(captionPic);
                                }
                            }
                            else if (currentField is FieldsStatusField)
                            {
                                temRowValues.Add(field, new DynamicDataRowValue() { FieldType = (int)FieldType.StatusField });
                            }
                            else
                            {
                                temRowValues.Add(field, new DynamicDataRowValue() { FieldType = 2 });
                            }

                        });
                        foreach (var data in group.rows)
                        {
                            filterProperties = data.GetType().GetProperties().Where(property => formValueProperties.Contains(property.Name)).ToList();

                            //Get the field name
                            if (filterProperties.FirstOrDefault(item => item.Name == "FieldName") != null)
                            {
                                fieldName = data.GetPropertyValue<object>("FieldName").ToString();
                            }

                            //Get the field type and field value
                            if (filterProperties.FirstOrDefault(item => item.Name == "FieldType") != null)
                            {
                                string tempValue = data.GetPropertyValue<object>("FieldType").ToString();
                                if (!string.IsNullOrEmpty(tempValue))
                                {
                                    fieldType = int.Parse(tempValue);
                                    //Get the value as a string according the type
                                    fieldValue = GetFieldValue(data, fieldType, fieldValue);
                                }
                            }

                            //if all values are filled,the system continues for create the result
                            if ((!string.IsNullOrEmpty(fieldName) && gridFields.Any(field => field == fieldName))
                                && !string.IsNullOrEmpty(fieldValue) && fieldType > 0)
                            {
                                temRowValues[fieldName].FieldValue = fieldValue;
                                temRowValues[fieldName].FieldType = fieldType;
                            }

                            fieldName = string.Empty;
                            fieldValue = string.Empty;
                            fieldType = 0;
                        }

                        dataRow.FieldValues.Clear();
                        temRowValues.Values.ToList().ForEach(value =>
                        {
                            dataRow.FieldValues.Add(new DynamicDataRowValue { FieldType = value.FieldType, FieldValue = value.FieldValue, Pictures = value.Pictures });
                        });

                        //get the identifier of row
                        Guid inspectionReportItemId = group.serviceOrderId.InspectionReportItemId.Value;
                        dataRow.RowIdentifier = inspectionReportItemId;

                        SetApprovalItems(dataRow, approvalItems, inspectionReportItemId);

                        //add the row to the dinamic grid
                        dynamicDataGrid.DataRows.Add(dataRow);
                    }
                }
            }

            SetStatusInspectionReport(dynamicDataGrid);
            dynamicDataGrid.Captions = parameters.Captions;
            return dynamicDataGrid;
        }
        /// <summary>
        /// Get the list of service orders
        /// </summary>
        /// <param name="parameters">Parameters</param>
        /// <returns>DynamicDataGrid</returns>
        public static DynamicDataGrid SearchOrderList(ParameterSearchServicerOrder parameters)
        {
            DynamicDataGrid dynamicDataGrid = new DynamicDataGrid();
            DynamicDataRow dataRow = null;
            string fieldName = string.Empty;
            string fieldValue = string.Empty;
            int fieldType = 0;
            List<PropertyInfo> filterProperties = null;
            List<string> gridFields = new List<string>();
            bool isOk = false;
            Dictionary<string, DynamicDataRowValue> temRowValues = null;
            List<FormValue> serviceOrderQuery = null;
            PaginatedList<FormValue> resultQuery = null;
            List<ApprovalItem> approvalItems = null;
            //obtain the definition of the form
            Form serviceOrder = CacheHandler.Get(String.Format("Form{0}", parameters.BusinessApplicationId),
                                                 () =>
                                                 DynamicFormEngine.GetFormDefinition(parameters.BusinessApplicationId,
                                                                                       FormType.ServiceOrder, false));
            using (VestalisEntities context = new VestalisEntities())
            {

                //Get the values from data base
                resultQuery = GetServiceOrderQuery(context, parameters);

                serviceOrderQuery = resultQuery.Collection;

                dynamicDataGrid.Page = parameters.Page;
                dynamicDataGrid.NumberOfPages = resultQuery.NumberOfPages;
                dynamicDataGrid.TotalNumberOfItemsWithoutPagination = resultQuery.TotalCount;
                dynamicDataGrid.PageSize = parameters.PageSize;

                //agroup the result by service order
                var groupServices = (from item in serviceOrderQuery
                                     group item by new { item.ServiceOrderId }
                                         into rows
                                         select new
                                         {
                                             serviceOrderId = rows.Key,
                                             rows
                                         });

                //verify if the result have data in the query
                if (serviceOrder != null && (serviceOrderQuery != null && serviceOrderQuery.Count > 0))
                {
                    //get the fields that can be showed in the grid
                    foreach (var section in serviceOrder.Sections)
                    {
                        if (parameters.IsClient)
                        {
                            gridFields.AddRange(
                                section.FormElements.Where(element => element.IsDataGridVisible && element.IsVisibleClient).Select(
                                    element => element.Identifier));
                        }
                        else
                        {
                            gridFields.AddRange(
                                section.FormElements.Where(element => element.IsDataGridVisible).Select(
                                    element => element.Identifier));
                        }
                    }

                    var formValueProperties = new List<string>();
                    formValueProperties.Add("FieldType");
                    formValueProperties.Add("FieldName");

                    //verify the result of the query
                    foreach (var group in groupServices)
                    {
                        dataRow = new DynamicDataRow();
                        temRowValues = new Dictionary<string, DynamicDataRowValue>();
                        gridFields.ForEach(field =>
                        {
                            temRowValues.Add(field, new DynamicDataRowValue() { FieldType = 2});
                        });
                        foreach (var data in group.rows)
                        {
                            filterProperties =
                                data.GetType().GetProperties().Where(property => formValueProperties.Contains(property.Name)).ToList();
                            foreach (var property in filterProperties)
                            {
                                //obtain the values of the necesary properties for create the result
                                if (property.Name == "FieldName")
                                {
                                    fieldName = data.GetPropertyValue<object>(property.Name).ToString();
                                }
                                else if (property.Name == "FieldType")
                                {
                                    string tempValue = data.GetPropertyValue<object>(property.Name).ToString();
                                    if (!string.IsNullOrEmpty(tempValue))
                                    {
                                        fieldType = int.Parse(tempValue);
                                        fieldValue = GetFieldValue(data, fieldType, fieldValue);
                                    }
                                }

                                //if all values are filled,the system continues for create the result
                                if ((!string.IsNullOrEmpty(fieldName) && gridFields.Any(field => field == fieldName))
                                    && !string.IsNullOrEmpty(fieldValue) && fieldType > 0)
                                {
                                    //if in the result the system founds a catalogue id,the system retrieves the value of catalogue
                                    fieldValue = GetFinalFieldValue(temRowValues, fieldName, fieldType, fieldValue);
                                    isOk = true;
                                }
                                if (isOk)
                                {
                                    isOk = false;
                                    dataRow.FieldValues.Clear();
                                    temRowValues.Values.ToList().ForEach(value =>
                                    {
                                        dataRow.FieldValues.Add(new DynamicDataRowValue { FieldType = value.FieldType, FieldValue = value.FieldValue });
                                    });
                                    break;
                                }
                            }
                            fieldName = string.Empty;
                            fieldValue = string.Empty;
                            fieldType = 0;
                        }
                        //get the identifier of row
                        dataRow.RowIdentifier = group.serviceOrderId.ServiceOrderId;
                        approvalItems = GetApprovalItemsOfServiceOrder(dataRow.RowIdentifier.Value, parameters.RolesForUser, context);

                        dataRow.CanPublish = approvalItems.Any(data => data.CanPublish.GetValueOrDefault());
                        dataRow.CanValidate = approvalItems.Any(data => !data.CanPublish.GetValueOrDefault());

                        if (parameters.IsClient)
                        {
                            //Get the first report that has data published to the client
                            dataRow.FirstInspectionReportClient = (
                                                                      from inspectionReport in context.InspectionReports
                                                                      where
                                                                          inspectionReport.ServiceOrderId ==
                                                                          dataRow.RowIdentifier.Value
                                                                          && inspectionReport.IsDeleted == false &&
                                                                          inspectionReport.IsClientVisible == true &&
                                                                          inspectionReport.InspectionReportItems.Count(
                                                                              item =>
                                                                              item.IsDeleted == false &&
                                                                              item.PublicationDate.HasValue) > 0
                                                                      orderby inspectionReport.FormOrder
                                                                      select
                                                                          inspectionReport.FormName).FirstOrDefault();
                            //Get the number of pictures related to the service order
                            int countPictures =
                                context.Pictures.Count(
                                    item =>
                                    item.IsDeleted == false && item.ServiceOrderId == dataRow.RowIdentifier.Value);

                            //Get the number of documents related to the service order
                            int countDocuments =
                                context.Documents.Count(
                                    item =>
                                    item.IsDeleted == false && item.ServiceOrderId == dataRow.RowIdentifier.Value);

                            dataRow.HasPicturesClient = countPictures > 0
                                                            ? true
                                                            : false;

                            dataRow.HasDocumentsClient = countDocuments > 0
                                                             ? true
                                                             : false;
                        }

                        //add the row to the dinamic grid
                        dynamicDataGrid.DataRows.Add(dataRow);
                    }
                }
            }
            return dynamicDataGrid;
        }
        /// <summary>
        /// Set the approval status in the inspection report item
        /// </summary>
        /// <param name="dataRow">Current datarow</param>
        /// <param name="approvalItems">List of approval items</param>
        /// <param name="inspectionReportItemId">Id of inspection report</param>
        private static void SetApprovalItems(DynamicDataRow dataRow, List<ApprovalItem> approvalItems, Guid inspectionReportItemId)
        {
            if (approvalItems != null)
            {
                ApprovalItem approvalItem = null;
                //get the approval item
                if (approvalItems.Count > 1)
                {
                    approvalItem = approvalItems.OrderByDescending(data => data.ApprovalLevel).Where(data => data.ApprovalStatus == (int)ApprovalStatus.Ready && data.InspectionReportItemId == inspectionReportItemId).FirstOrDefault();
                    if (approvalItem == null)
                    {
                        approvalItem = approvalItems.OrderByDescending(data => data.ApprovalLevel).Where(data => data.ApprovalStatus == (int)ApprovalStatus.Completed && data.InspectionReportItemId == inspectionReportItemId).FirstOrDefault();
                    }
                }
                else
                {
                    approvalItem = approvalItems.FirstOrDefault(data => data.InspectionReportItemId == inspectionReportItemId);
                }

                //if exist the approval item, the system will continue with the process
                if (approvalItem != null)
                {
                    //set publish option
                    if (approvalItem.CanPublish.GetValueOrDefault())
                    {
                        dataRow.CanPublish = true;
                        dataRow.CanValidate = false;
                    }
                    else
                    {
                        //set validate option
                        dataRow.CanPublish = false;
                        dataRow.CanValidate = true;
                    }
                    //set read only
                    if (approvalItem.InspectionReportItem.PublicationDate != null)
                    {
                        dataRow.IsReadOnly = true;
                    }
                    else
                    {
                        dataRow.IsReadOnly = approvalItem.IsReadOnly.GetValueOrDefault();
                    }
                    dataRow.CurrentCompletedLevel = approvalItem.InspectionReportItem.CurrentCompletedLevel.GetValueOrDefault();
                    dataRow.ApprovalStatus = approvalItem.ApprovalStatus.GetValueOrDefault();
                    dataRow.IsPublished = approvalItem.InspectionReportItem.PublicationDate != null;
                }
            }
        }