namespace Hims.Infrastructure.Services
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using System.Linq;

    using Dapper;
    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Domain.Configurations;

    using Hims.Shared.DataFilters;
    using Hims.Shared.UserModels.ServiceOrder;
    using Hims.Domain.Entities.Labs;

    using Shared.EntityModels;
    using Shared.UserModels.Laboratory;
    using Shared.UserModels.Labs;
    using Shared.UserModels.Labs.Report;
    using Hims.Domain.Entities.Enums;
    using Hims.Shared.Library.Enums;
    using Hims.Shared.UserModels;


    /// <inheritdoc />
    public class LabsServices : ILabsService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;
        /// <summary>
        /// The amazon s3 configuration.
        /// </summary>
        private readonly IAmazonS3Configuration amazonS3Configuration;

        /// <summary>
        /// The appointment transaction services.
        /// </summary>
        private readonly IAppointmentTransactionService appointmentTransactionsServices;

        /// <summary>
        /// The payment map helper service
        /// </summary>
        private readonly IPaymentMapHelperService paymentMapHelperService;

        /// <summary>
        /// The running environment
        /// </summary>
        private readonly IRunningEnvironment runningEnvironment;

        /// <inheritdoc cref="ILabsService" />
        public LabsServices(IUnitOfWork unitOfWork, IAmazonS3Configuration amazonS3Configuration, IAppointmentTransactionService appointmentTransactionsServices, IPaymentMapHelperService paymentMapHelperService, IRunningEnvironment runningEnvironment)
        {
            this.unitOfWork = unitOfWork;
            this.amazonS3Configuration = amazonS3Configuration;
            this.appointmentTransactionsServices = appointmentTransactionsServices;
            this.paymentMapHelperService = paymentMapHelperService;
            this.runningEnvironment = runningEnvironment;
        }

        /// <inheritdoc/>
        public async Task<int> CreateUnitAsync(LookupValueModel model)
        {
            if (model.LookupId == 0)
            {
                var lookup = await this.unitOfWork.Lookups.FindAsync(m => m.Name == "LaboratoryUnit");
                if (lookup == null)
                {
                    var lookupModel = new Lookup { Name = "LaboratoryUnit", Description = "Laboratory Units types." };
                    model.LookupId = await this.unitOfWork.Lookups.InsertAsync(lookupModel);
                }
                else
                {
                    model.LookupId = lookup.LookupId;
                }
            }

            var valueModel = new LookupValue
            {
                LookupId = model.LookupId,
                Name = model.Name,
                CreatedBy = model.LoginAccountId,
                CreatedDate = DateTime.Now
            };
            if (await this.CheckLookupValueName(model.Name, model.LookupId))
            {
                return -1;
            }

            return await this.unitOfWork.LookupValues.InsertAsync(valueModel);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabParameterMethod>> FetchAllParameterMethod()
        {
            var query = $@"select * from ""LabParameterMethod"" ";
            return await this.unitOfWork.Current.QueryAsync<LabParameterMethod>(query);
        }

        /// <inheritdoc/>
        public async Task<int> ModifyLabParameteresAsync(LabParameterModel model)
        {
            var labParameterHeader = new LabParameterHeader
            {
                Active = true,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                DisplayName = model.DisplayName,
                ParameterName = model.ParameterName,
                ReferenceOutput = model.ReferenceOutput,
                LabParameterHeaderId = model.LabParameterHeaderId,
                Text = model.Text,
                MachineId = model.MachineId,
                MachineParameterName = model.MachineParameterName,
                ParameterId = await this.GetParameterCodeAsync()
            };

            if (!string.IsNullOrEmpty(model.MethodName))
            {
                var checkQueryMethod = $@"Select * from ""LabParameterMethod"" where lower(""MethodName"") = '{model.MethodName.Trim().ToLower()}'";
                var checkMethod = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<LabParameterMethod>(checkQueryMethod);
                if (checkMethod != null)
                {
                    labParameterHeader.LabParameterMethodId = checkMethod.LabParameterMethodId;
                }
                else
                {
                    var labMethod = new LabParameterMethod
                    {
                        MethodName = model.MethodName.Trim()
                    };

                    labParameterHeader.LabParameterMethodId = await this.unitOfWork.LabParameterMethods.InsertAsync(labMethod);
                }
            }

            var checkIfQuery = $@"Select count(*) from ""LabParameterHeader"" where lower(""ParameterName"") = '{model.ParameterName.ToLower()}' ";
            var transaction = this.unitOfWork.BeginTransaction();
            if (labParameterHeader.LabParameterHeaderId == 0)
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                labParameterHeader.LabParameterHeaderId = await this.unitOfWork.LabParameterHeaders.InsertAsync(labParameterHeader, transaction);
                if (labParameterHeader.LabParameterHeaderId == 0)
                {
                    transaction.Rollback();
                    return -2;
                }
            }
            else
            {
                checkIfQuery += $@" and ""LabParameterHeaderId"" <> {labParameterHeader.LabParameterHeaderId} ";
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                var getOldHeader = await this.unitOfWork.LabParameterHeaders.FindAsync(h => h.LabParameterHeaderId == labParameterHeader.LabParameterHeaderId);
                getOldHeader.ParameterName = labParameterHeader.ParameterName;
                getOldHeader.DisplayName = labParameterHeader.DisplayName;
                getOldHeader.ReferenceOutput = labParameterHeader.ReferenceOutput;
                getOldHeader.ModifiedBy = labParameterHeader.CreatedBy;
                getOldHeader.ModifiedDate = DateTime.Now;
                getOldHeader.LabParameterMethodId = labParameterHeader.LabParameterMethodId;
                getOldHeader.Text = labParameterHeader.Text;
                getOldHeader.MachineId = labParameterHeader.MachineId;
                getOldHeader.MachineParameterName = labParameterHeader.MachineParameterName;

                var updateResponse = await this.unitOfWork.LabParameterHeaders.UpdateAsync(getOldHeader, transaction);
                if (updateResponse == 0)
                {
                    transaction.Rollback();
                    return -2;
                }
            }

            foreach (var detail in model.ParameterGroup)
            {
                var parameterDetail = new LabParameterDetail
                {
                    LabParameterHeaderId = labParameterHeader.LabParameterHeaderId,
                    FromAge = detail.FromAge,
                    ToAge = detail.ToAge,
                    FromAgeType = detail.FromAgeType,
                    ToAgeType = detail.ToAgeType,
                    Gender = detail.Gender,
                    LabParameterDetailId = detail.LabParameterDetailId,
                    MaxCriticalValue = detail.MaxCriticalValue,
                    MaxValue = detail.MaxValue,
                    MinCriticalValue = detail.MinCriticalValue,
                    MinValue = detail.MinValue,
                    UnitId = detail.UnitId,
                    RangeText = detail.RangeText
                };
                if (parameterDetail.LabParameterDetailId == 0)
                {
                    parameterDetail.LabParameterDetailId = await this.unitOfWork.LabParameterDetails.InsertAsync(parameterDetail, transaction);
                    if (parameterDetail.LabParameterDetailId == 0)
                    {
                        transaction.Rollback();
                        return -3;
                    }
                }
                else
                {
                    var getdetails = await this.unitOfWork.LabParameterDetails.FindAsync(d => d.LabParameterDetailId == parameterDetail.LabParameterDetailId);
                    if (getdetails == null)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                    getdetails.FromAge = parameterDetail.FromAge;
                    getdetails.ToAge = parameterDetail.ToAge;
                    getdetails.FromAgeType = parameterDetail.FromAgeType;
                    getdetails.ToAgeType = parameterDetail.FromAgeType;
                    getdetails.Gender = parameterDetail.Gender;
                    getdetails.LabParameterDetailId = parameterDetail.LabParameterDetailId;
                    getdetails.MaxCriticalValue = parameterDetail.MaxCriticalValue;
                    getdetails.MaxValue = parameterDetail.MaxValue;
                    getdetails.MinCriticalValue = parameterDetail.MinCriticalValue;
                    getdetails.MinValue = parameterDetail.MinValue;
                    getdetails.UnitId = parameterDetail.UnitId;
                    getdetails.RangeText = parameterDetail.RangeText;

                    var updateResponse = await this.unitOfWork.LabParameterDetails.UpdateAsync(getdetails, transaction);
                    if (updateResponse == 0)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                }
            }

            transaction.Commit();
            return labParameterHeader.LabParameterHeaderId;
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabParameterModel>> FetchLabParameterHeaderAsync(LabParameterModel model)
        {
            var where = "where 1=1";
            if (model.Active != null)
            {
                where += (bool)model.Active ? $@" and lph.""Active"" is true " : $@" and lph.""Active"" is false ";
            }
            if (!string.IsNullOrEmpty(model.ParameterName))
            {
                where += $@" and lower(lph.""ParameterName"") ilike '%{model.ParameterName.ToLower()}%' ";
            }
            if (!string.IsNullOrEmpty(model.DisplayName))
            {
                where += $@" and lower(lph.""DisplayName"") ilike '%{model.DisplayName.ToLower()}%' ";
            }

            if (!string.IsNullOrEmpty(model.Term))
            {
                where += $@" and (lower(lph.""ParameterName"") ilike '%{model.Term.ToLower()}%' or lower(lph.""DisplayName"") ilike '%{model.Term.ToLower()}%')";
            }

            if (model.LabParameterHeaderId > 0)
            {
                where += $@" and lph.""LabParameterHeaderId"" = {model.LabParameterHeaderId}";
            }

            var query = $@"select count(lph.*) over() as ""TotalItems"",lph.""ParameterId"",lph.""LabParameterHeaderId"",lph.""ParameterName"",lph.""DisplayName"",lph.""ReferenceOutput"",lph.""Active"", lph.""CreatedBy"",
			                lph.""CreatedDate"", lph.""ModifiedBy"",lph.""ModifiedDate"",c.""FullName"" as ""CreatedByName"", m.""FullName"" as ""ModifiedByName"",
                            lph.""LabParameterMethodId"", lpm.""MethodName"",lph.""Text"",lph.""MachineId"",lph.""MachineParameterName""
  			                 from ""LabParameterHeader"" lph 
  			                 join ""Account"" c on c.""AccountId"" = lph.""CreatedBy""
  			                 left join ""Account"" m on m.""AccountId"" = lph.""ModifiedBy""
                             left join ""LabParameterMethod"" lpm on lpm.""LabParameterMethodId"" = lph.""LabParameterMethodId""  
                                {where}  			                
                                order by lph.""CreatedDate"" desc";

            if (model.PageSize != null && model.PageIndex != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }
            return await this.unitOfWork.Current.QueryAsync<LabParameterModel>(query);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabParameterDetailModel>> FetchLabParameterDetailAsync(int labParameterHeaderId)
        {
            var query = $@"select lpd.""LabParameterDetailId"",lpd.""LabParameterHeaderId"",lpd.""Gender"",lpd.""FromAge"",lpd.""FromAgeType"",lpd.""ToAge"",
		                            lpd.""ToAgeType"",lpd.""MinValue"",lpd.""MaxValue"",lpd.""MinCriticalValue"",lpd.""MaxCriticalValue"",lpd.""UnitId"",lpd.""RangeText"",
		                            lv.""Name"" as ""UnitName""
			                            from ""LabParameterDetail"" lpd
			                            left join ""LookupValue"" lv on lv.""LookupValueId"" = lpd.""UnitId""
			                            where lpd.""LabParameterHeaderId"" = {labParameterHeaderId}";
            return await this.unitOfWork.Current.QueryAsync<LabParameterDetailModel>(query);
        }

        /// <inheritdoc/>
        public async Task<int> ModifyLabComponentsAsync(LabComponentModel model)
        {
            var labComponentHeader = new LabComponentHeader
            {
                Active = true,
                ComponentName = model.ComponentName.Trim(),
                ComponentId = await this.GetComponentIdAsync(),
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                LabComponentHeaderId = model.LabComponentHeaderId
            };

            var checkIfQuery = $@"Select count(*) from ""LabComponentHeader"" where lower(""ComponentName"") = '{model.ComponentName.ToLower()}' ";

            var transaction = this.unitOfWork.BeginTransaction();

            if (labComponentHeader.LabComponentHeaderId == 0)
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                labComponentHeader.LabComponentHeaderId = await this.unitOfWork.LabComponentHeaders.InsertAsync(labComponentHeader, transaction);
                if (labComponentHeader.LabComponentHeaderId == 0)
                {
                    transaction.Rollback();
                    return -1;
                }
            }
            else
            {
                checkIfQuery += $@" and ""LabComponentHeaderId"" <>{labComponentHeader.LabComponentHeaderId} ";
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                var findOldHeader = await this.unitOfWork.LabComponentHeaders.FindAsync(h => h.LabComponentHeaderId == labComponentHeader.LabComponentHeaderId);
                if (findOldHeader == null)
                {
                    transaction.Rollback();
                    return -1;
                }
                findOldHeader.ComponentName = model.ComponentName;
                findOldHeader.ModifiedBy = model.CreatedBy;
                findOldHeader.ModifiedDate = DateTime.Now;

                var updateResponse = await this.unitOfWork.LabComponentHeaders.UpdateAsync(findOldHeader, transaction);
                if (updateResponse == 0)
                {
                    transaction.Rollback();
                    return -1;
                }
            }

            foreach (var detail in model.Parameters)
            {
                var detailModel = new LabComponentDetail
                {
                    LabComponentDetailId = detail.LabComponentDetailId,
                    LabComponentHeaderId = labComponentHeader.LabComponentHeaderId,
                    LabParameterHeaderId = detail.LabParameterHeaderId,
                    Priority = detail.Priority
                };

                if (detailModel.LabComponentDetailId == 0)
                {
                    detailModel.LabComponentDetailId = await this.unitOfWork.LabComponentDetails.InsertAsync(detailModel, transaction);
                    if (detailModel.LabComponentDetailId == 0)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                }
                else
                {
                    var getPreviousDetail = await this.unitOfWork.LabComponentDetails.FindAsync(d => d.LabComponentDetailId == detailModel.LabComponentDetailId);
                    if (getPreviousDetail == null)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                    getPreviousDetail.Priority = detailModel.Priority;
                    var updateDetailResponse = await this.unitOfWork.LabComponentDetails.UpdateAsync(getPreviousDetail, transaction);
                    if (updateDetailResponse == 0)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                }
            }

            transaction.Commit();
            return labComponentHeader.LabComponentHeaderId;
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabComponentModel>> FetchLabComponentHeaderAsync(LabComponentModel model)
        {
            var where = "where 1=1";

            if (model.Active != null)
            {
                where += (bool)model.Active ? $@" and lch.""Active"" is true " : $@" and lch.""Active"" is false ";
            }

            if (!string.IsNullOrEmpty(model.ComponentName))
            {
                where += $@" and lower(lch.""ComponentName"") ilike '%{model.ComponentName.ToLower()}%'";
            }

            if (!string.IsNullOrEmpty(model.ComponentId))
            {
                where += $@" and lower(lch.""ComponentId"") ilike '%{model.ComponentId.ToLower()}%'";
            }

            if (!string.IsNullOrEmpty(model.Term))
            {
                where += $@" and (lower(lch.""ComponentName"") ilike '%{model.Term.ToLower()}%' or lower(lch.""ComponentId"") like '%{model.Term.ToLower()}%')";
            }

            if (model.LabComponentHeaderId > 0)
            {
                where += $@"  and lch.""LabComponentHeaderId"" = {model.LabComponentHeaderId}";
            }

            var query = $@"SELECT count(*) over() as ""TotalItems"", lch.""LabComponentHeaderId"", lch.""ComponentName"", lch.""ComponentId"", lch.""Active"", lch.""CreatedBy"", lch.""CreatedDate"", lch.""ModifiedBy"", lch.""ModifiedDate"",
			                    c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"",concat(lch.""ComponentName"", lch.""ComponentId"") as ""Joined"",
                                (select count(*) from ""LabComponentDetail"" where ""LabComponentHeaderId"" = lch.""LabComponentHeaderId"") as ""ParameterCount""
			                    FROM ""LabComponentHeader"" lch
			                    join ""Account"" c on c.""AccountId"" = lch.""CreatedBy"" 
			                    left join ""Account"" m on m.""AccountId"" =lch.""ModifiedBy""  
			                    {where}
			                    order by lch.""CreatedDate"" desc";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }

            return await this.unitOfWork.Current.QueryAsync<LabComponentModel>(query);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabComponentDetailModel>> FetchLabComponentDetailAsync(int labComponentHeaderId)
        {
            var query = $@"SELECT lcd.""LabComponentDetailId"", lcd.""LabComponentHeaderId"", lcd.""LabParameterHeaderId"", lcd.""Priority"",
		                        lph.""ParameterName"" ,lph.""DisplayName"" 
		                        FROM ""LabComponentDetail"" lcd
		                        join ""LabParameterHeader"" lph ON lph.""LabParameterHeaderId"" =lcd.""LabParameterHeaderId"" 
		                        where lcd.""LabComponentHeaderId"" = {labComponentHeaderId}
		                        order by lcd.""Priority"" asc";
            return await this.unitOfWork.Current.QueryAsync<LabComponentDetailModel>(query);
        }

        /// <inheritdoc/>
        public async Task<int> ModifyTemplateAsync(LabTemplateModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();

            var templateHeader = new LabTemplateHeader
            {
                Active = true,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                LabTemplateHeaderId = model.LabTemplateHeaderId,
                TemplateId = await this.GetTemplateIdAsync(),
                TemplateName = model.TemplateName.Trim(),
                IsInterpretation = model.IsInterpretation != null && (bool)model.IsInterpretation,
                IsMethod = model.IsMethod != null && (bool)model.IsMethod,
                MethodText = model.MethodText,
                InterpretationText = model.InterpretationText
            };

            var checkIfQuery = $@"Select count(*) from ""LabTemplateHeader"" where lower(""TemplateName"") = '{model.TemplateName.ToLower()}' ";
            if (templateHeader.LabTemplateHeaderId == 0)
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                templateHeader.LabTemplateHeaderId = await this.unitOfWork.LabTemplateHeaders.InsertAsync(templateHeader, transaction);
                if (templateHeader.LabTemplateHeaderId == 0)
                {
                    transaction.Rollback();
                    return -1;
                }
            }
            else
            {
                checkIfQuery += $@" and ""LabTemplateHeaderId"" <> {templateHeader.LabTemplateHeaderId}";
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                var getOldTemplate = await this.unitOfWork.LabTemplateHeaders.FindAsync(t => t.LabTemplateHeaderId == templateHeader.LabTemplateHeaderId);
                getOldTemplate.TemplateName = templateHeader.TemplateName;
                getOldTemplate.ModifiedBy = templateHeader.CreatedBy;
                getOldTemplate.ModifiedDate = DateTime.Now;
                getOldTemplate.IsMethod = templateHeader.IsMethod;
                getOldTemplate.IsInterpretation = templateHeader.IsInterpretation;
                getOldTemplate.MethodText = templateHeader.MethodText;
                getOldTemplate.InterpretationText = templateHeader.InterpretationText;

                var templateUpdateResponse = await this.unitOfWork.LabTemplateHeaders.UpdateAsync(getOldTemplate, transaction);
                if (templateUpdateResponse == 0)
                {
                    transaction.Rollback();
                    return -1;
                }
            }

            foreach (var detail in model.Components)
            {
                var templateDetail = new LabTemplateDetail
                {
                    LabComponentHeaderId = detail.LabComponentHeaderId != null && detail.LabComponentHeaderId != 0 ? detail.LabComponentHeaderId : (int?)null,
                    LabTemplateHeaderId = templateHeader.LabTemplateHeaderId,
                    LabTemplateDetailId = detail.LabTemplateDetailId,
                    Priority = detail.Priority,
                    LabParameterHeaderId = detail.LabParameterHeaderId != null && detail.LabParameterHeaderId != 0 ? detail.LabParameterHeaderId : (int?)null
                };

                if (templateDetail.LabTemplateDetailId == 0)
                {
                    templateDetail.LabTemplateDetailId = await this.unitOfWork.LabTemplateDetails.InsertAsync(templateDetail, transaction);
                    if (templateDetail.LabTemplateDetailId == 0)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                }
                else
                {
                    var templateUpdateResponse = await this.unitOfWork.LabTemplateDetails.UpdateAsync(templateDetail, transaction);
                    if (templateUpdateResponse == 0)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                }
            }

            transaction.Commit();
            return templateHeader.LabTemplateHeaderId;
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabTemplateModel>> FetchLabTemplateHeaderAsync(LabTemplateModel model)
        {
            var where = "where 1=1";

            if (model.Active != null)
            {
                where += (bool)model.Active ? $@" and lth.""Active"" is true " : $@" and lth.""Active"" is false ";
            }

            if (!string.IsNullOrEmpty(model.TemplateName))
            {
                where += $@" and lower(lth.""TemplateName"") ilike '%{model.TemplateName.ToLower()}%'";
            }

            if (!string.IsNullOrEmpty(model.TemplateId))
            {
                where += $@" and lower(lth.""TemplateId"") ilike '%{model.TemplateId}%'";
            }

            if (!string.IsNullOrEmpty(model.Term))
            {
                where += $@" and (lower(lth.""TemplateName"") ilike '%{model.Term.ToLower()}%' or lower(lth.""TemplateId"") like '%{model.Term.ToLower()}%')";
            }

            if (model.LabTemplateHeaderId > 0)
            {
                where += $@" and lth.""LabTemplateHeaderId"" = {model.LabTemplateHeaderId}";
            }

            var query = $@"SELECT count(lth.*) over() as ""TotalItems"", lth.""LabTemplateHeaderId"", lth.""TemplateName"", lth.""TemplateId"", lth.""Active"", lth.""CreatedBy"", lth.""CreatedDate"", 
		                            lth.""ModifiedBy"", lth.""ModifiedDate"", c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"",
                                    (select count(*) from ""LabTemplateDetail"" where ""LabTemplateHeaderId"" = lth.""LabTemplateHeaderId"") as ""ComponentCount"",
                                    lth.""IsMethod"",lth.""MethodText"",lth.""IsInterpretation"",lth.""InterpretationText"",
                                    concat(lth.""TemplateName"", lth.""TemplateId"") as ""Joined""
	                               FROM ""LabTemplateHeader"" lth
	                               join ""Account"" c on c.""AccountId"" = lth.""CreatedBy""
	                               left join ""Account"" m on m.""AccountId"" = lth.""ModifiedBy""
	                                {where}
	                               order by ""CreatedDate"" desc";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }

            return await this.unitOfWork.Current.QueryAsync<LabTemplateModel>(query);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabTemplateDetailModel>> FetchLabTemplateDetailAsync(int labTemplateHeaderId)
        {
            var query = $@"SELECT ltd.""LabTemplateDetailId"", ltd.""LabTemplateHeaderId"", ltd.""LabComponentHeaderId"", ltd.""Priority"",
		                        ltd.""LabParameterHeaderId"",lch.""ComponentName"",lch.""ComponentId"",lph.""ParameterName"" ,lph.""DisplayName"" 
		                        FROM ""LabTemplateDetail"" ltd
		                        left join ""LabComponentHeader"" lch on lch.""LabComponentHeaderId"" = ltd.""LabComponentHeaderId""		                        
		                        left join ""LabParameterHeader"" lph ON lph.""LabParameterHeaderId"" =ltd.""LabParameterHeaderId"" 		                       
		                        where ltd.""LabTemplateHeaderId"" = {labTemplateHeaderId}
                                order by ltd.""Priority"" asc";
            return await this.unitOfWork.Current.QueryAsync<LabTemplateDetailModel>(query);
        }

        public async Task<IEnumerable<LabSampleTypeModel>> FetchAllSampleTypeAsync()
        {
            var query = $@"Select * from ""LabSampleType""";
            return await this.unitOfWork.Current.QueryAsync<LabSampleTypeModel>(query);
        }

        /// <inheritdoc/>
        public async Task<int> ModifyLabMaster(LabMainDetailModel model)
        {
            var labTestModuleMaster = await this.unitOfWork.ModulesMasters.FindAsync(m => m.ModuleName == "Lab");
            if (labTestModuleMaster == null)
            {
                return -2;
            }
            var labMainDetail = new LabMainDetail
            {
                Active = true,
                IsExternalLab = model.IsExternalLab,
                IsInternalLab = model.IsInternalLab,
                LabDepartmentId = model.LabDepartmentId,
                TestCode = await this.GetMainLabIdAsync(),
                TestName = model.TestName,
                LabMainDetailId = model.LabMainDetailId,
                CreatedBy = (int)model.CreatedBy,
                CreatedDate = DateTime.Now,
                ModulesMasterId = labTestModuleMaster.ModulesMasterId,
                SampleUsage = model.SampleUsage,
                NablRequired = (bool)model.NablRequired,
                ConsentFormRequired = (bool)model.ConsentFormRequired,
                AssignDoctorRequired = (bool)model.AssignDoctorRequired,
                LabVacutainerId = (int)model.LabVacutainerId,
                NoOfSamplesCollect = (int)model.NoOfSamplesCollect,
                NoOfSamplesCollectText = model.NoOfSamplesCollectText,
                TestPrecaution = model.TestPrecaution
            };

            if (!string.IsNullOrEmpty(model.TypeName))
            {
                var checkType = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<LabSampleType>($@"select * from ""LabSampleType"" where lower(""TypeName"") = '{model.TypeName.ToLower()}'");
                if (checkType != null)
                {
                    labMainDetail.LabSampleTypeId = checkType.LabSampleTypeId;
                }
                else
                {
                    var labSample = new LabSampleType
                    {
                        TypeName = model.TypeName
                    };

                    labMainDetail.LabSampleTypeId = await this.unitOfWork.LabSampleTypes.InsertAsync(labSample);
                    if (labMainDetail.LabSampleTypeId == 0)
                    {
                        return -1;
                    }
                }
            }

            var transaction = this.unitOfWork.BeginTransaction();

            var checkIfQuery = $@" Select count(*) from ""LabMainDetail"" where lower(""TestName"") = '{labMainDetail.TestName.ToLower()}' ";

            if (labMainDetail.LabMainDetailId == 0)
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    transaction.Rollback();
                    return -2;
                }
                labMainDetail.LabMainDetailId = await this.unitOfWork.LabMainDetails.InsertAsync(labMainDetail, transaction);
                if (labMainDetail.LabMainDetailId == 0)
                {
                    transaction.Rollback();
                    return -5;
                }
            }
            else
            {
                checkIfQuery += $@" and ""LabMainDetailId"" <> {labMainDetail.LabMainDetailId} ";
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    transaction.Rollback();
                    return -2;
                }
                var getOldOne = await this.unitOfWork.LabMainDetails.FindAsync(l => l.LabMainDetailId == labMainDetail.LabMainDetailId);
                getOldOne.IsExternalLab = labMainDetail.IsExternalLab;
                getOldOne.IsInternalLab = labMainDetail.IsInternalLab;
                getOldOne.LabDepartmentId = labMainDetail.LabDepartmentId;
                getOldOne.TestName = labMainDetail.TestName;
                getOldOne.ModifiedBy = labMainDetail.CreatedBy;
                getOldOne.ModifiedDate = DateTime.Now;
                getOldOne.SampleUsage = labMainDetail.SampleUsage;
                getOldOne.NablRequired = labMainDetail.NablRequired;
                getOldOne.ConsentFormRequired = labMainDetail.ConsentFormRequired;
                getOldOne.AssignDoctorRequired = labMainDetail.AssignDoctorRequired;
                getOldOne.LabVacutainerId = labMainDetail.LabVacutainerId;
                getOldOne.NoOfSamplesCollect = labMainDetail.NoOfSamplesCollect;
                getOldOne.NoOfSamplesCollectText = labMainDetail.NoOfSamplesCollectText;
                getOldOne.TestPrecaution = labMainDetail.TestPrecaution;
                var updateMainLabResponse = await this.unitOfWork.LabMainDetails.UpdateAsync(getOldOne, transaction);
                if (updateMainLabResponse == 0)
                {
                    transaction.Rollback();
                    return -5;
                }
            }

            foreach (var template in model.Templates)
            {
                var templateModel = new LabMainDetailTemplate
                {
                    LabMainDetailId = labMainDetail.LabMainDetailId,
                    LabMainDetailTemplateId = template.LabMainDetailTemplateId,
                    LabTemplateHeaderId = template.LabTemplateHeaderId,
                    Priority = template.Priority
                };

                if (templateModel.LabMainDetailTemplateId == 0)
                {
                    templateModel.LabMainDetailTemplateId = await this.unitOfWork.LabMainDetailTemplates.InsertAsync(templateModel, transaction);
                    if (templateModel.LabMainDetailTemplateId == 0)
                    {
                        transaction.Rollback();
                        return -4;
                    }
                }
                else
                {
                    var getOldTemplate = await this.unitOfWork.LabMainDetailTemplates.FindAsync(t => t.LabMainDetailTemplateId == templateModel.LabMainDetailTemplateId);
                    if (getOldTemplate == null)
                    {
                        transaction.Rollback();
                        return -4;
                    }
                    getOldTemplate.Priority = templateModel.Priority;

                    var updateTemplateResponse = await this.unitOfWork.LabMainDetailTemplates.UpdateAsync(getOldTemplate, transaction);
                    if (updateTemplateResponse == 0)
                    {
                        transaction.Rollback();
                        return -4;
                    }
                }
            }
            transaction.Commit();
            return labMainDetail.LabMainDetailId;
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabMainDetailModel>> FetchAllLabMainDetailAsync(LabMainDetailModel model)
        {
            var where = " where 1=1";
            var extraColumn = string.Empty;

            if (model.Active != null)
            {
                where += (bool)model.Active ? $@" and lmd.""Active"" is true " : $@" and lmd.""Active"" is false ";
            }

            // if (model.LocationId != null)
            // {
            //       var templateId = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select cmt.""ChargeModuleTemplateId"" from ""ChargeModuleTemplate"" cmt where cmt.""LocationId"" = {model.LocationId} and cmt.""IsInUse"" is true");
            //       var moduleId = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select mm.""ModulesMasterId""  from ""ModulesMaster"" mm where lower(mm.""ModuleName"") = 'lab'");
            //       var chargeIds = await this.unitOfWork.Current.QueryAsync<int>($@"select cmc.""ChargeModuleCategoryId"" from ""ChargeModuleCategory"" cmc where cmc.""ModulesMasterId"" = {moduleId} and cmc.""ChargeModuleTemplateId"" = {templateId}");
            //       extraColumn = $@",(select count(cmd.""ReferenceId"")  from ""ChargeModuleDetails"" cmd where cmd.""ChargeModuleCategoryId"" in ({string.Join(",",chargeIds.Select(x=>x))})
            //and cmd.""ReferenceId"" = lmd.""LabMainDetailId"") as ""ChargeExistForCurrentLocation""";
            // }

            if (!string.IsNullOrEmpty(model.Term))
            {
                where += $@" and (lower(lmd.""TestName"") ilike '%{model.Term.ToLower()}%' or lower(lmd.""TestCode"") ilike '%{model.Term.ToLower()}%')";
            }

            if (model.IsFromBill && model.LocationId != null)
            {
                where += $@"  and lmd.""LabMainDetailId"" in (
	                            select distinct cmd.""ReferenceId""  from ""ChargeModuleDetails"" cmd where cmd.""ChargeModuleCategoryId"" in (select cmc.""ChargeModuleCategoryId"" from ""ChargeModuleCategory"" cmc where cmc.""ModulesMasterId"" = (select mm.""ModulesMasterId""  from ""ModulesMaster"" mm where lower(mm.""ModuleName"") = 'lab') 
									and cmc.""ChargeModuleTemplateId"" = (select cmt.""ChargeModuleTemplateId"" from ""ChargeModuleTemplate"" cmt where cmt.""LocationId"" = {model.LocationId} and cmt.""IsInUse"" is true))
									
	                            )";
            }

            if (model.DepartmentType != null)
            {
                where += $@"and (lower( ld.""DepartmentName"") = '{model.DepartmentType.ToLower()}')";
            }
            if (model.SampleType != null)
            {
                where += $@"and (lower( lst.""TypeName"") ='{model.SampleType.ToLower()}')";
            }
            if (model.SampleUsage != null)
            {
                where += $@"and (lower(lmd.""SampleUsage"") ='{model.SampleUsage.ToLower()}')";
            }
            if (model.TypeOfLab != null)
            {
                if (model.TypeOfLab == "Internal")
                {
                    where += $@"and  lmd.""IsInternalLab"" ='true' ";
                }
                else if (model.TypeOfLab == "External")
                {
                    where += $@"and  lmd.""IsExternalLab"" ='true' ";
                }
            }

            var query = $@"SELECT count(lmd.*) over() as ""TotalItems"", lmd.""LabMainDetailId"", lmd.""TestName"", lmd.""LabDepartmentId"", lmd.""TestCode"", lmd.""LabSampleTypeId"", lmd.""Active"", lmd.""IsInternalLab"", lmd.""IsExternalLab"",
		                            lmd.""CreatedBy"", lmd.""CreatedDate"", lmd.""ModifiedBy"", lmd.""ModifiedDate"", ld.""DepartmentName"" ,c.""FullName"" as ""CreatedByName"",
		                            lst.""TypeName"" ,m.""FullName"" as ""ModifiedByName"",lmd.""SampleUsage"",lmd.""NablRequired"",lmd.""ConsentFormRequired"",lmd.""AssignDoctorRequired"",lmd.""LabVacutainerId"",lv.""LabVacutainerName"",lmd.""NoOfSamplesCollect"",lmd.""NoOfSamplesCollectText"",lmd.""TestPrecaution"",
                                    concat(lmd.""TestName"", lmd.""TestCode"") as ""Joined""{extraColumn}
	                            FROM ""LabMainDetail"" lmd
	                            join ""LabDepartment"" ld ON ld.""LabDepartmentId"" = lmd.""LabDepartmentId"" 
	                            join ""Account"" c on c.""AccountId"" = lmd.""CreatedBy""
                                left join ""LabVacutainer"" lv ON lv.""LabVacutainerId"" = lmd.""LabVacutainerId""
	                            left join ""LabSampleType"" lst ON lst.""LabSampleTypeId"" = lmd.""LabSampleTypeId""  
	                            left join ""Account"" m ON m.""AccountId"" = lmd.""ModifiedBy"" 
	                                {where}
	                            order by lmd.""CreatedDate"" desc ";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageSize * model.PageIndex}";
            }

            return await this.unitOfWork.Current.QueryAsync<LabMainDetailModel>(query);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabMainDetailTemplateModel>> FetchLabTaggedTemplates(LabMainDetailTemplateModel model)
        {
            var where = "where 1=1";
            if (model.LabMainDetailId > 0)
            {
                where += $@" and lmdt.""LabMainDetailId"" = {model.LabMainDetailId}";
            }

            var query = $@"SELECT lmdt.""LabMainDetailTemplateId"", lmdt.""LabMainDetailId"", lmdt.""LabTemplateHeaderId"", lmdt.""Priority"",
		                            lth.""TemplateName"" ,lth.""TemplateId"" 
		                            FROM ""LabMainDetailTemplate"" lmdt
		                            join ""LabTemplateHeader"" lth ON lth.""LabTemplateHeaderId"" =lmdt.""LabTemplateHeaderId"" 
		                            {where}
		                            order by lmdt.""Priority"" asc";
            return await this.unitOfWork.Current.QueryAsync<LabMainDetailTemplateModel>(query);
        }

        /// <summary>
        /// Gets the parameter code asynchronous.
        /// </summary>
        /// <returns></returns>
        private async Task<string> GetParameterCodeAsync()
        {
            var fixedText = "SCMP"; // SCMP0959
            var query = $@"select ""ParameterId"" from ""LabParameterHeader"" order by ""ParameterId"" desc limit 1";
            var getPrevious = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>(query);
            return this.CommonFunction(getPrevious, fixedText);
        }

        /// <summary>
        /// Gets the main lab identifier asynchronous.
        /// </summary>
        /// <returns></returns>
        private async Task<string> GetMainLabIdAsync()
        {
            var fixedText = "T"; // T0000001            
            var query = $@"select ""TestCode"" from ""LabMainDetail"" order by ""TestCode"" desc limit 1";
            var getPrevious = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>(query);
            return this.CommonFunctionSixDigitMask(getPrevious, fixedText);
        }

        /// <summary>
        /// Gets the component identifier asynchronous.
        /// </summary>
        /// <returns></returns>
        private async Task<string> GetComponentIdAsync()
        {
            var fixedText = "COMP";
            var query = $@"select ""ComponentId"" from ""LabComponentHeader"" order by ""ComponentId"" desc limit 1 ";
            var getPrevious = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>(query);
            return this.CommonFunction(getPrevious, fixedText);
        }

        /// <summary>
        /// Gets the template identifier asynchronous.
        /// </summary>
        /// <returns></returns>
        private async Task<string> GetTemplateIdAsync()
        {
            var fixedText = "M"; // M0000039
            var query = $@"select ""TemplateId"" from ""LabTemplateHeader"" order by ""TemplateId"" desc limit 1 ";
            var getPrevious = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>(query);
            return this.CommonFunctionSixDigitMask(getPrevious, fixedText);
        }

        /// <summary>
        /// Commons the function six digit mask.
        /// </summary>
        /// <param name="getPrevious">The get previous.</param>
        /// <param name="fixedText">The fixed text.</param>
        /// <returns></returns>
        private string CommonFunctionSixDigitMask(string getPrevious, string fixedText)
        {
            if (getPrevious == null)
            {
                fixedText += $@"0000001";
                return fixedText;
            }
            else
            {
                var previousNum = getPrevious.Replace(fixedText, "");
                var getNumber = Convert.ToInt64(previousNum);
                getNumber += 1;
                string finalMaskedNumber;

                if (getNumber >= 1000000)
                {
                    finalMaskedNumber = $@"{getNumber}";
                }
                else if (getNumber >= 100000)
                {
                    finalMaskedNumber = $@"0{getNumber}";
                }
                else if (getNumber >= 10000)
                {
                    finalMaskedNumber = $@"00{getNumber}";
                }
                else if (getNumber >= 1000)
                {
                    finalMaskedNumber = $@"000{getNumber}";
                }
                else if (getNumber >= 100)
                {
                    finalMaskedNumber = $@"0000{getNumber}";
                }
                else if (getNumber >= 10)
                {
                    finalMaskedNumber = $@"00000{getNumber}";
                }
                else
                {
                    finalMaskedNumber = $@"000000{getNumber}";
                }
                return $@"{fixedText}{finalMaskedNumber}";
            }
        }

        /// <summary>
        /// Commons the function.
        /// </summary>
        /// <param name="getPrevious">The get previous.</param>
        /// <param name="fixedText">The fixed text.</param>
        /// <returns></returns>
        private string CommonFunction(string getPrevious, string fixedText)
        {
            if (getPrevious == null)
            {
                fixedText += $@"0001";
                return fixedText;
            }
            else
            {
                var previousNum = getPrevious.Replace(fixedText, "");
                var getNumber = Convert.ToInt64(previousNum);
                getNumber += 1;
                string finalMaskedNumber;
                if (getNumber >= 1000)
                {
                    finalMaskedNumber = $@"{getNumber}";
                }
                else if (getNumber >= 100)
                {
                    finalMaskedNumber = $@"0{getNumber}";
                }
                else if (getNumber >= 10)
                {
                    finalMaskedNumber = $@"00{getNumber}";
                }
                else
                {
                    finalMaskedNumber = $@"000{getNumber}";
                }
                return $@"{fixedText}{finalMaskedNumber}";
            }
        }

        /// <summary>
        /// The check lookup value name.
        /// </summary>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <param name="lookupId">
        /// The lookup id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        private async Task<bool> CheckLookupValueName(string name, int lookupId)
        {
            var lookup = await this.unitOfWork.LookupValues.FindAllAsync(m => m.LookupId == lookupId);
            var match = lookup?.ToList().Find(
                m => string.Equals(m.Name, name, StringComparison.CurrentCultureIgnoreCase));
            return match != null;
        }

        ///// <inheritdoc/>
        //public async Task<int> ModifyParameterStatusAsync(LabParameterHeader model,bool status)
        //{
        //    var query = $@"UPDATE ""LabParameterHeader"" SET ""Active"" = {status}, ""ModifiedBy""  = {model.ModifiedBy} , ""ModifiedDate"" = {DateTime.Now} WHERE ""LabParameterHeaderId"" = {model.LabParameterHeaderId}";
        //    var num = await unitOfWork.Current.ExecuteAsync(query);
        //    return num;
        //}

        ///<inheritdoc/>
        public async Task<int> ModifyParameterStatusAsync(LabParameterModel model)
        {
            int num;
            try
            {

                var foundId = await this.unitOfWork.LabParameterHeaders.FindAsync(m => m.LabParameterHeaderId == model.LabParameterHeaderId);
                foundId.Active = (bool)model.Active;
                foundId.ModifiedBy = model.ModifiedBy;
                foundId.ModifiedDate = DateTime.Now;

                num = await this.unitOfWork.LabParameterHeaders.UpdateAsync(foundId);
                return num;
            }
            catch (Exception e)
            {
                e.Message.ToString();
            }

            return -1;
        }

        ///<inheritdoc/>
        public async Task<int> ModifyComponentStatusAsync(LabComponentModel model)
        {
            int num;
            try
            {
                var foundId = await this.unitOfWork.LabComponentHeaders.FindAsync(m => m.LabComponentHeaderId == model.LabComponentHeaderId);
                foundId.Active = (bool)model.Active;
                foundId.ModifiedBy = model.ModifiedBy;
                foundId.ModifiedDate = DateTime.Now;

                //model.ModifiedDate = DateTime.Now;
                //var query = $@"UPDATE ""LabParameterHeader"" SET ""Active"" = {model.Active}, ""ModifiedBy""  = {model.ModifiedBy} , ""ModifiedDate"" = {model.ModifiedDate} WHERE ""LabParameterHeaderId"" = {model.LabParameterHeaderId}";
                //num = await unitOfWork.Current.ExecuteAsync(query);
                num = await this.unitOfWork.LabComponentHeaders.UpdateAsync(foundId);
                return num;
            }
            catch (Exception e)
            {
                e.Message.ToString();
            }

            return -1;
        }

        public async Task<int> ModifyTemplateStatusAsync(LabTemplateModel model)
        {
            int num;
            try
            {
                var foundId = await this.unitOfWork.LabTemplateHeaders.FindAsync(m => m.LabTemplateHeaderId == model.LabTemplateHeaderId);
                foundId.Active = (bool)model.Active;
                foundId.ModifiedBy = model.ModifiedBy;
                foundId.ModifiedDate = DateTime.Now;

                //model.ModifiedDate = DateTime.Now;
                //var query = $@"UPDATE ""LabParameterHeader"" SET ""Active"" = {model.Active}, ""ModifiedBy""  = {model.ModifiedBy} , ""ModifiedDate"" = {model.ModifiedDate} WHERE ""LabParameterHeaderId"" = {model.LabParameterHeaderId}";
                //num = await unitOfWork.Current.ExecuteAsync(query);
                num = await this.unitOfWork.LabTemplateHeaders.UpdateAsync(foundId);
                return num;
            }
            catch (Exception e)
            {
                e.Message.ToString();
            }

            return -1;
        }

        public async Task<int> ModifyLabMainDetailStatusAsync(LabMainDetailModel model)
        {
            int num;
            try
            {
                var foundId = await this.unitOfWork.LabMainDetails.FindAsync(m => m.LabMainDetailId == model.LabMainDetailId);
                foundId.Active = (bool)model.Active;
                foundId.ModifiedBy = model.ModifiedBy;
                foundId.ModifiedDate = DateTime.Now;

                //model.ModifiedDate = DateTime.Now;
                //var query = $@"UPDATE ""LabParameterHeader"" SET ""Active"" = {model.Active}, ""ModifiedBy""  = {model.ModifiedBy} , ""ModifiedDate"" = {model.ModifiedDate} WHERE ""LabParameterHeaderId"" = {model.LabParameterHeaderId}";
                //num = await unitOfWork.Current.ExecuteAsync(query);
                num = await this.unitOfWork.LabMainDetails.UpdateAsync(foundId);
                return num;
            }
            catch (Exception e)
            {
                e.Message.ToString();
            }

            return -1;
        }

        public async Task<IEnumerable<LabBookingModel>> FetchLabBookings(LabBookingModel model)
        {
            var where = "where 1=1"; //

            if (model.NewLabBookingHeaderId > 0)
            {
                where += $@" and nlbh.""NewLabBookingHeaderId"" = {model.NewLabBookingHeaderId}";
            }

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and nlbh.""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and nlbh.""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }

            if (!string.IsNullOrEmpty(model.DepartmentName))
            {
                where += $@" and (lower(ld.""DepartmentName"") ilike '%{model.DepartmentName.ToLower()}%')";
            }

            if (!string.IsNullOrEmpty(model.TestName))
            {
                where += $@" and (lower(lmd.""TestName"") ilike '%{model.TestName.ToLower()}%' or lower(lmd.""TestCode"") ilike '%{model.TestName.ToLower()}%')";
            }

            if (model.PatientId > 0)
            {
                where += $@" and nlbh.""PatientId"" = '{model.PatientId}'";
            }

            if (!string.IsNullOrEmpty(model.BookingType))
            {
                if (model.BookingType == "ip")
                {
                    where += $@" and nlbh.""AdmissionId"" is not null ";
                }
                else
                {
                    where += $@" and nlbh.""AdmissionId"" is null ";
                }
            }

            var query = $@"SELECT count(*) over () as ""TotalItems"", * from (select distinct nlbh.""NewLabBookingHeaderId"", nlbh.""RequisitionNumber"",nlbh.""Type"", nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",
                                 nlbh.""LocationId"", nlbh.""PayTypeId"",
                                 nlbh.""CreatedBy"", nlbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate"", c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"", COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName"") ,CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"",
                                 COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
                                 (CASE WHEN p.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('{this.amazonS3Configuration.BucketURL}', p.""Guid"", '/', p.""ThumbnailUrl"") ELSE '' END) AS ""PatientThumbnailUrl"",
                                    e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",p.""UMRNo"",p.""Gender"",p.""Age""
                                    ,p.""DateOfBirth"",nlbh.""OverallTotalAmount"",nlbh.""OverallDiscount"",nlbh.""OverallNetAmount"", nlbh.""PaymentNumber"",PD.""DepartmentName"", CASE WHEN nlbh.""AdmissionId"" is not null THEN 'IP' else 'OP' END ""BookingType""
                                    from ""NewLabBookingHeader"" nlbh
                                    join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId"" 
                                    join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
                                    join ""LabDepartment"" ld on ld.""LabDepartmentId"" = lmd.""LabDepartmentId""
                                    join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy"" 
                                    left join ""PayType"" pt ON pt.""PayTypeId"" = nlbh.""PayTypeId""
                                    join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
                                    left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy"" 
                                    left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
                                    left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
                                    left join ""Department"" PD on PD.""DepartmentId""=prv.""DepartmentId""
                                    left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" {where}
	                               order by nlbh.""CreatedDate"" desc) A";
            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }
            return await this.unitOfWork.Current.QueryAsync<LabBookingModel>(query);
        }

        public async Task<int> LabBookingsCancelling(LabBookingModel model)
        {

            var transaction = this.unitOfWork.BeginTransaction();

            var cancelHeader = new NewLabCancelBookingHeader
            {
                NewLabBookingHeaderId = (int)model.NewLabBookingHeaderId,
                TotalReturnAmount = model.OverallNetAmount,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
            };
            if (model.index != null)
            {
                int lab = (int)model.index;
                cancelHeader.TotalReturnAmount = model.Labs[lab].NetAmount;
            }
            else
            {
                cancelHeader.TotalReturnAmount = 0;
                var selectedLabs = model.Labs.FindAll(l => l.LabBookingStatusId == 1);
                for (int i = 0; i < selectedLabs.Count; i++)
                {
                    cancelHeader.TotalReturnAmount = cancelHeader.TotalReturnAmount + selectedLabs[i].NetAmount;
                }

            }
            cancelHeader.NewLabCancelBookingHeaderId = await this.unitOfWork.NewLabCancelBookingHeaders.InsertAsync(cancelHeader, transaction);
            if (cancelHeader.NewLabCancelBookingHeaderId == 0)
            {
                transaction.Rollback();
                return -1;
            }
            int details;
            if (model.index == null)
            {
                var selectedLabs = model.Labs.FindAll(l => l.LabBookingStatusId == 1);
                var labCancelDetail = selectedLabs.Select(l => new NewLabCancelBookingDetail
                {
                    NewLabCancelBookingHeaderId = cancelHeader.NewLabCancelBookingHeaderId,
                    NewLabBookingDetailId = l.NewLabBookingDetailId,
                    ReturnAmount = l.NetAmount,
                });
                details = await this.unitOfWork.NewLabCancelBookingDetails.BulkInsertAsync(labCancelDetail, transaction);
                if (details == 0)
                {
                    transaction.Rollback();
                    return -3;
                }
            }
            else
            {
                int lab = (int)model.index;
                var abc = model.Labs[lab];
                var labCancelDetail = new NewLabCancelBookingDetail()
                {
                    NewLabCancelBookingHeaderId = cancelHeader.NewLabCancelBookingHeaderId,
                    NewLabBookingDetailId = abc.NewLabBookingDetailId,
                    ReturnAmount = abc.NetAmount,
                };
                try
                {
                    labCancelDetail.NewLabCancelBookingDetailId = await this.unitOfWork.NewLabCancelBookingDetails.InsertAsync(labCancelDetail, transaction);
                }
                catch (Exception e)
                {
                    e.Message.ToString();
                }
                if (labCancelDetail.NewLabCancelBookingDetailId == 0)
                {
                    transaction.Rollback();
                    return -3;
                }
            }

            int count = 0;
            int a;

            if (model.index == null)
            {
                var agetStatusCancelled = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Cancelled");
                var selectedLabs = model.Labs.FindAll(l => l.LabBookingStatusId == 1);
                for (int i = 0; i < selectedLabs.Count; i++)
                {
                    var afoundId = await this.unitOfWork.NewLabBookingDetails.FindAsync(m => m.NewLabBookingDetailId == selectedLabs[i].NewLabBookingDetailId);

                    afoundId.LabBookingStatusId = agetStatusCancelled.LabBookingStatusId;
                    count = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(afoundId, transaction);
                    var afindId = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Booked");
                    a = await this.unitOfWork.NewLabBookingDetails.CountAsync(m => m.NewLabBookingHeaderId == model.NewLabBookingHeaderId && m.LabBookingStatusId != agetStatusCancelled.LabBookingStatusId);
                    if (a == 0)
                    {
                        var id = await this.unitOfWork.NewLabBookingHeaders.FindAsync(m => m.NewLabBookingHeaderId == model.NewLabBookingHeaderId);
                        id.Active = false;
                        await this.unitOfWork.NewLabBookingHeaders.UpdateAsync(id, transaction);

                    }
                }
                if (model.Labs.Count == selectedLabs.Count)
                {
                    var timeline = new LabBookingTimeLine
                    {
                        Comment = $@"All Labs has been Cancelled",
                        CommentedBy = model.CreatedBy,
                        CreatedDate = DateTime.Now,
                        LabBookingStatusId = agetStatusCancelled.LabBookingStatusId,
                        NewLabBookingHeaderId = model.Labs[0].NewLabBookingHeaderId
                    };

                    timeline.LabBookingTimeLineId = await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
                    if (timeline.LabBookingTimeLineId == 0)
                    {
                        transaction.Rollback();
                        return -4;
                    }
                }
                else
                {
                    foreach (var lab in selectedLabs)
                    {
                        var timeline = new LabBookingTimeLine
                        {
                            Comment = $@"{lab.TestName.ToUpper()} has been Cancelled",
                            CommentedBy = model.CreatedBy,
                            CreatedDate = DateTime.Now,
                            LabBookingStatusId = agetStatusCancelled.LabBookingStatusId,
                            NewLabBookingHeaderId = lab.NewLabBookingHeaderId,
                            NewLabBookingDetailId = lab.NewLabBookingDetailId
                        };

                        timeline.LabBookingTimeLineId = await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
                        if (timeline.LabBookingTimeLineId == 0)
                        {
                            transaction.Rollback();
                            return -4;
                        }
                    }
                }



            }
            else
            {
                int j = (int)model.index;
                var afoundId = await this.unitOfWork.NewLabBookingDetails.FindAsync(m => m.NewLabBookingDetailId == model.Labs[j].NewLabBookingDetailId);
                var statusCancelled = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Cancelled");
                afoundId.LabBookingStatusId = statusCancelled.LabBookingStatusId;
                count = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(afoundId, transaction);
                var afindId = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Booked");
                a = await this.unitOfWork.NewLabBookingDetails.CountAsync(m => m.NewLabBookingHeaderId == model.NewLabBookingHeaderId && m.LabBookingStatusId == afindId.LabBookingStatusId);
                if (a == 0)
                {
                    var id = await this.unitOfWork.NewLabBookingHeaders.FindAsync(m => m.NewLabBookingHeaderId == model.NewLabBookingHeaderId);
                    id.Active = false;
                    await this.unitOfWork.NewLabBookingHeaders.UpdateAsync(id, transaction);
                }
                var timeline = new LabBookingTimeLine
                {
                    Comment = $@"{model.Labs[j].TestName.ToUpper()} Labs has been Cancelled",
                    CommentedBy = model.CreatedBy,
                    CreatedDate = DateTime.Now,
                    LabBookingStatusId = statusCancelled.LabBookingStatusId,
                    NewLabBookingHeaderId = afoundId.NewLabBookingHeaderId,
                    NewLabBookingDetailId = afoundId.NewLabBookingDetailId
                };

                timeline.LabBookingTimeLineId = await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
                if (timeline.LabBookingTimeLineId == 0)
                {
                    transaction.Rollback();
                    return -4;
                }

            }
            if (cancelHeader.NewLabCancelBookingHeaderId > 0)
            {

                if (model.PaymentInitiationLogId != null && model.PaymentInitiationLogId != 0)
                {
                    PaymentMapHelperModel paymentHelper = new PaymentMapHelperModel { PaymentInitiationLogId = ((int)model.PaymentInitiationLogId), BillId = cancelHeader.NewLabCancelBookingHeaderId };
                    paymentHelper.PaymentMapHelperId = await this.paymentMapHelperService.AddAsync(paymentHelper);
                    if (paymentHelper.PaymentMapHelperId == 0)
                    {
                        transaction.Rollback();
                        return -6;
                    }
                }

                var BillHeader = await this.unitOfWork.NewLabBookingHeaders.FindAsync(m => m.NewLabBookingHeaderId == model.NewLabBookingHeaderId);
                //transaction for the sale return
                //to get master bill
                var getbillrecord = await this.unitOfWork.MasterBill.FindAsync(x => x.PatientId == BillHeader.PatientId && x.ReceiptAreaTypeId == (int)ReceiptAreaType.Labs && x.ModuleId == BillHeader.NewLabBookingHeaderId); //need to check more

                var commonTransaction = new AppointmentTransaction //
                {
                    AppointmentId = cancelHeader.NewLabCancelBookingHeaderId,
                    Transaction = model.Transaction ?? "",
                    TransactionDate = DateTime.Now,
                    TransactionId = model.TransactionId ?? await this.appointmentTransactionsServices.GetATransactionId(),
                    VoucherNumber = await this.appointmentTransactionsServices.GetVoucherNumber(),
                    BankReference = "",
                    BankCode = "",
                    Active = true,
                    PaymentId = 0,
                    PaymentModeId = 1,
                    //SettledAmount = (decimal)cancelHeader.TotalReturnAmount,
                    SettledAmount = (decimal)model.RefundAmount,
                    CreatedBy = (int)model.CreatedBy,
                    CreatedDate = DateTime.Now,
                    LocationId = (int)model.LocationId,
                    ReceiptTypeId = (int)ReceiptType.Refund,
                    ReceiptAreaTypeId = (int)ReceiptAreaType.LabsCancel,
                    SalucroStatusCode = model.SalucroStatusCode,
                    SalucroTransactionId = model.SalucroTransactionId,
                    PatientId = BillHeader.PatientId
                    //PayStatus-its cancel
                };
                commonTransaction.AppointmentTransactionId = await this.unitOfWork.AppointmentTransactions.InsertAsync(commonTransaction, transaction);
                if (commonTransaction.AppointmentTransactionId == 0)
                {
                    transaction.Rollback();
                    return -8;
                }
                var receipt = new Receipt
                {
                    Active = true,
                    //Cost = (double)cancelHeader.TotalReturnAmount,
                    Cost = (double)model.RefundAmount,
                    CreatedBy = (int)model.CreatedBy,
                    CreatedDate = DateTime.Now,
                    IsAdvance = false,
                    IsRefunded = false,
                    PayTypeId = (int)BillHeader.PayTypeId,
                    PaymentDetails = BillHeader.PaymentNumber,
                    ReceiptTypeId = ReceiptType.Refund,//
                    ReceiptAreaTypeId = ReceiptAreaType.LabsCancel,
                    RespectiveId = cancelHeader.NewLabCancelBookingHeaderId,
                    TransactionId = commonTransaction.AppointmentTransactionId,
                    MasterBillId = getbillrecord != null ? getbillrecord.MasterBillId : 0
                };

                receipt.ReceiptId = await this.unitOfWork.Receipt.InsertAsync(receipt);
                if (receipt.ReceiptId == 0)
                {
                    transaction.Rollback();
                    return -9;
                }

                var paidReceipts = await this.unitOfWork.Receipt.FindAllAsync(x => x.MasterBillId == receipt.MasterBillId && x.ReceiptAreaTypeId == ReceiptAreaType.Labs);
                var paidSum = 0.0;
                foreach (var item in paidReceipts)
                {
                    paidSum += item.Cost;
                }

                var refundReceipts = await this.unitOfWork.Receipt.FindAllAsync(x => x.MasterBillId == receipt.MasterBillId && x.ReceiptAreaTypeId == ReceiptAreaType.LabsCancel);
                var refundSum = 0.0;
                foreach (var item in refundReceipts)
                {
                    refundSum += item.Cost;
                }

                //update bill refund
                if (getbillrecord != null)
                {
                    //getbillrecord.Refund += (double)cancelHeader.TotalReturnAmount;
                    getbillrecord.Refund += (double)model.RefundAmount;
                    getbillrecord.RemovedAmount += cancelHeader.TotalReturnAmount;
                    if (paidSum == refundSum)
                    {
                        getbillrecord.Active = false;
                    }
                    await this.unitOfWork.MasterBill.UpdateAsync(getbillrecord);
                }
            }
            transaction.Commit();
            return cancelHeader.NewLabCancelBookingHeaderId;
        }

        public async Task<IEnumerable<LabBookingModel>> FetchCancelledLabBillAsync(LabBookingModel model)
        {
            var where = "where 1=1";

            if (model.NewLabCancelBookingHeaderId > 0)
            {
                where += $@" and nlcbh.""NewLabCancelBookingHeaderId"" = {model.NewLabCancelBookingHeaderId}";
            }

            if (model.NewLabBookingHeaderId > 0)
            {
                where += $@" and nlbh.""NewLabBookingHeaderId"" = {model.NewLabBookingHeaderId}";
            }

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and nlbh.""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and nlbh.""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }

            if (model.IsShowSampleCollected != null)
            {
                if ((bool)model.IsShowSampleCollected)
                {
                    where += $@" and (lbs.""Status"" = 'Booked' or lbs.""Status"" = 'SampleCollected')";
                }
                else
                {
                    where += $@" and lbs.""Status"" = 'Booked'";
                }
            }

            var mainQuery = $@"SELECT distinct nlbh.""NewLabBookingHeaderId"", count(nlbh.*) over () as ""TotalItems"", nlbh.""RequisitionNumber"", nlbh.""Type"", nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"", nlcbh.""TotalReturnAmount"",
                                       nlbh.""LocationId"", nlbh.""OverallTotalAmount"", nlbh.""OverallDiscount"", nlbh.""OverallNetAmount"", nlbh.""OverallDiscountPercentage"", nlbh.""PayTypeId"", 
                                    nlbh.""PaymentNumber"", nlcbh.""CreatedBy"", nlcbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate"", nlbh.""Active""  ,
                                    c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"",COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName"") ,CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"",
                                    COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
                                    (CASE WHEN p.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('{this.amazonS3Configuration.BucketURL}', p.""Guid"", '/', p.""ThumbnailUrl"") ELSE '' END) AS ""PatientThumbnailUrl"",
                                    e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",p.""UMRNo"",p.""Gender"",p.""Age""
                                   FROM ""NewLabCancelBookingHeader"" nlcbh
                                   join ""NewLabBookingHeader"" nlbh on nlbh.""NewLabBookingHeaderId"" = nlcbh.""NewLabBookingHeaderId""
                                   join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy"" 
                                   join ""PayType"" pt ON pt.""PayTypeId"" = nlbh.""PayTypeId""  
                                   join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId"" 
                                   join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId"" 
                                   join ""LabBookingStatus"" lbs on lbs.""LabBookingStatusId"" = nlbd.""LabBookingStatusId"" 
	                               left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy"" 
	                               left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId"" 
	                               left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId"" 
	                               left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" 
                                    {where} order by nlcbh.""CreatedDate"" desc";
            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                mainQuery += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }

            var headerResponse = await this.unitOfWork.Current.QueryAsync<LabBookingModel>(mainQuery);
            foreach (var header in headerResponse)
            {
                header.Labs = new List<NewLabBookingDetailModel>();

                var detailQuery = $@"SELECT nlbd.""NewLabBookingDetailId"", nlbd.""NewLabBookingHeaderId"", nlbd.""LabMainDetailId"", nlbd.""ChargeCategoryId"", nlbd.""LabBookingStatusId"", nlbd.""DiscountPercentage"", 
		                                    nlbd.""DiscountAmount"", nlbd.""TotalAmount"", nlbd.""NetAmount"", lbs.""Status"",nlcbd.""ReturnAmount"",
		                                    lmd.""TestName"",lmd.""TestCode"" , ld.""DepartmentName"" ,cc.""ChargeCategoryName""  
		                                    FROM ""NewLabCancelBookingDetail"" nlcbd
                                            join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingDetailId"" = nlcbd.""NewLabBookingDetailId""
		                                    join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId"" 
		                                    join ""LabMainDetail"" lmd ON lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
		                                    join ""LabDepartment"" ld on ld.""LabDepartmentId"" = lmd.""LabDepartmentId"" 
		                                    join ""ChargeCategory"" cc on cc.""ChargeCategoryId"" = nlbd.""ChargeCategoryId""  
		                                    where nlcbd.""NewLabCancelBookingHeaderId"" = {model.NewLabCancelBookingHeaderId}";
                header.Labs = (await this.unitOfWork.Current.QueryAsync<NewLabBookingDetailModel>(detailQuery)).ToList();
            }

            return headerResponse;
        }

        public async Task<IEnumerable<LabBookingModel>> FetchSelectedLabDataAsync(LabBookingModel model)
        {
            var where = "where 1=1";
            if (model.NewLabBookingHeaderId > 0)
            {
                where += $@" and nlbh.""NewLabBookingHeaderId"" = {model.NewLabBookingHeaderId} ";
            }
            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and nlbh.""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }
            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and nlbh.""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }
            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }
            if (model.IsShowSampleCollected != null)
            {
                if ((bool)model.IsShowSampleCollected)
                {
                    where += $@" and (lbs.""Status"" = 'Booked' or lbs.""Status"" = 'SampleCollected')";
                }
                else
                {
                    where += $@" and lbs.""Status"" = 'Booked'";
                }
            }
            var mainQuery = $@"with returnAmount as (select ""NewLabBookingHeaderId"",sum(COALESCE(""TotalReturnAmount"",0)) As ""OverallReturnNetAmount"" from ""NewLabCancelBookingHeader""
                                    where ""NewLabBookingHeaderId"" = {model.NewLabBookingHeaderId} group by ""NewLabBookingHeaderId"" )
                                    SELECT * FROM (SELECT distinct nlbh.""NewLabBookingHeaderId"", count(nlbh.*) over () as ""TotalItems"", nlbh.""RequisitionNumber"", nlbh.""Type"", nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",
                                       nlbh.""LocationId"", nlbh.""OverallTotalAmount"", nlbh.""OverallDiscount"", (nlbh.""OverallNetAmount"" - COALESCE(ra.""OverallReturnNetAmount"",0)) as ""OverallNetAmount"", nlbh.""OverallDiscountPercentage"", nlbh.""PayTypeId"",
                                    nlbh.""PaymentNumber"", nlbh.""CreatedBy"", nlbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate"", nlbh.""Active""  ,nlbh.""IsSalucroBill"",
                                    c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"",COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName"") ,CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"",
                                    COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
                                    (CASE WHEN p.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('{this.amazonS3Configuration.BucketURL}', p.""Guid"", '/', p.""ThumbnailUrl"") ELSE '' END) AS ""PatientThumbnailUrl"",
                                    e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",p.""UMRNo"",p.""Gender"",p.""Age"",
                                    --(select sum(RR.""Cost"") from ""Receipt"" RR  where  RR.""RespectiveId""=nlbh.""NewLabBookingHeaderId"" and RR.""ReceiptAreaTypeId""=8) ""PaidAmount""
                                    Coalesce(MB.""RemovedAmount"",0) ""RemovedAmount"",                
                                    (select SUM(COALESCE(RC.""Cost"",0)) from ""Receipt"" RC where RC.""RespectiveId""=nlbh.""NewLabBookingHeaderId"" and RC.""ReceiptAreaTypeId""=8 and RC.""ReceiptTypeId""=1)
                                    -case when nlcbh.""NewLabCancelBookingHeaderId"" is not null then (select SUM(COALESCE(RR.""Cost"",0)) from ""Receipt"" RR where RR.""RespectiveId""=nlcbh.""NewLabCancelBookingHeaderId"" and RR.""ReceiptAreaTypeId""=9 and RR.""ReceiptTypeId""=2) else 0 end ""PaidAmount""
                                   FROM ""NewLabBookingHeader"" nlbh                                   
                                   join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy""                                      
                                   join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
                                   join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId""
                                   join ""LabBookingStatus"" lbs on lbs.""LabBookingStatusId"" = nlbd.""LabBookingStatusId""
                                   left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy""
                                   left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
                                   left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
                                   left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId""
                                   left join returnAmount ra on ra.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId""
                                   --left join ""Receipt"" R on R.""RespectiveId""=nlbh.""NewLabBookingHeaderId"" and R.""ReceiptAreaTypeId""=8
                                   left join ""PayType"" pt ON pt.""PayTypeId"" = nlbh.""PayTypeId""
                                   left Join ""MasterBill"" MB on MB.""ModuleId""=nlbh.""NewLabBookingHeaderId"" and MB.""ReceiptAreaTypeId""=8
                                   left Join ""NewLabCancelBookingHeader"" nlcbh on nlcbh.""NewLabBookingHeaderId""=nlbh.""NewLabBookingHeaderId""
                                    {where}
                                     GROUP BY nlbh.""NewLabBookingHeaderId"",ra.""OverallReturnNetAmount"",c.""FullName"",m.""FullName"",p.""FullName"",p.""Mobile"", prv.""FullName""
                                   ,p.""ThumbnailUrl"", p.""Guid"",e.""FullName"",l.""Name"",p.""UMRNo"",p.""Gender"",p.""Age"",pt.""PayTypeName"",p.""Salutation"", MB.""RemovedAmount"",nlcbh.""NewLabCancelBookingHeaderId""
                                    order by nlbh.""CreatedDate"" desc) data limit 1";
            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                mainQuery += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }
            var headerResponse = await this.unitOfWork.Current.QueryAsync<LabBookingModel>(mainQuery);
            headerResponse.Select(l => new LabBookingModel
            {
                OverallTotalAmount = (double)(l.OverallTotalAmount + l.TotalReturnAmount),
            });
            foreach (var header in headerResponse)
            {
                header.Labs = new List<NewLabBookingDetailModel>();
                var detailQuery = $@"SELECT nlbd.""NewLabBookingDetailId"", nlbd.""NewLabBookingHeaderId"", nlbd.""LabMainDetailId"", nlbd.""ChargeCategoryId"", nlbd.""LabBookingStatusId"", nlbd.""DiscountPercentage"",
                                            nlbd.""DiscountAmount"", nlbd.""TotalAmount"", nlbd.""NetAmount"", lbs.""Status"",lbs.""RowColor"",nlbd.""Emergency"",
                                            lmd.""TestName"",lmd.""TestCode"" , ld.""DepartmentName"" ,cc.""ChargeCategoryName""  
                                            FROM ""NewLabBookingDetail"" nlbd
                                            join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId""
                                            join ""LabMainDetail"" lmd ON lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
                                            join ""LabDepartment"" ld on ld.""LabDepartmentId"" = lmd.""LabDepartmentId""
                                            join ""ChargeCategory"" cc on cc.""ChargeCategoryId"" = nlbd.""ChargeCategoryId""  
                                            where nlbd.""NewLabBookingHeaderId"" = {header.NewLabBookingHeaderId}";
                header.Labs = (await this.unitOfWork.Current.QueryAsync<NewLabBookingDetailModel>(detailQuery)).ToList();
            }
            return headerResponse;
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabBookingStatus>> FetchAllLabStatus()
        {
            var query = $@"select * from ""LabBookingStatus"" ";
            return await this.unitOfWork.Current.QueryAsync<LabBookingStatus>(query);
        }

        /// <inheritdoc/>
        public async Task<int> UpdateStatusColorAsync(LabBookingAllStatusModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"Select count(*) from ""LabBookingStatus"" where  ""LabBookingStatusId"" = {model.LabBookingStatusId}");
            if (checkIf > 1)
            {
                return -1;
            }

            var record = await this.unitOfWork.LabBookingStatus.FindAsync(p => p.LabBookingStatusId == model.LabBookingStatusId);
            if (record == null)
            {
                return 0;
            }

            record.RowColor = model.RowColor;

            return await this.unitOfWork.LabBookingStatus.UpdateAsync(record);
        }

        public async Task<IEnumerable<ChargeCategory>> FetchAllLabChargeCategories()
        {
            var query = $@"select * from ""ChargeCategory"" WHERE ""Active"" != false  order by ""Default"" desc ";
            return await this.unitOfWork.Current.QueryAsync<ChargeCategory>(query);
        }

        public async Task<IEnumerable<NewLabImportModel>> FetchAllAvailableImportLabAsync(int locationId)
        {
            var mainQuery = $@"select distinct(lmdc.""LabMainDetailId""), lmd.""TestName"",lmd.""TestCode""
                                 from ""LabMainDetailCharge"" lmdc
                                 join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = lmdc.""LabMainDetailId""
                                 where lmdc.""LocationId"" <> {locationId}                               
                                 EXCEPT 
                                 SELECT lmdc.""LabMainDetailId"" , lmd.""TestName"",lmd.""TestCode""
                                 FROM ""LabMainDetailCharge"" lmdc
                                 join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = lmdc.""LabMainDetailId""
                                 WHERE lmdc.""LocationId""= {locationId}  ";
            var headerResponse = await this.unitOfWork.Current.QueryAsync<NewLabImportModel>(mainQuery);
            foreach (var header in headerResponse)
            {
                header.LabCharges = new List<NewLabImportLabCharges>();

                var detailQuery = $@"select lmdc.""LabMainDetailChargeId"",lmdc.""LabMainDetailId"",lmdc.""ChargeCategoryId"", cc.""ChargeCategoryName"", lmdc.""Rate""
                                        from ""LabMainDetailCharge"" lmdc
                                        join ""ChargeCategory"" cc on cc.""ChargeCategoryId"" = lmdc.""ChargeCategoryId""
                                        where lmdc.""LocationId"" != {locationId} and lmdc.""LabMainDetailId"" = {header.LabMainDetailId}";

                header.LabCharges = (await this.unitOfWork.Current.QueryAsync<NewLabImportLabCharges>(detailQuery)).ToList();

            }

            return headerResponse;
        }

        public async Task<int> ImportLabAsync(NewLabImportModel model)
        {
            return 0;
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabTransferModel>> FetchResultAddedLabsAsync(LabTransferModel model)
        {
            var where = "where 1=1 ";

            if (model.CreatedLabLocationId != null)
            {
                where += $@" and nlbh.""LocationId"" = {model.CreatedLabLocationId} ";
            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }

            if (!string.IsNullOrEmpty(model.TransferNumber))
            {
                where += $@" and lower(lth.""TransferNumber"") = '{model.TransferNumber.Trim().ToLower()}'";
            }

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and lrv.""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and lrv.""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }

            if (model.TransferedLocationId > 0)
            {
                where += $@" and lth.""TransferedLocationId"" = {model.TransferedLocationId} ";
            }

            if (!string.IsNullOrEmpty(model.ReceivedFromDate))
            {
                where += $@" and lth.""ReceivedDate""::date >= '{Convert.ToDateTime(model.ReceivedFromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ReceivedToDate))
            {
                where += $@" and lth.""ReceivedDate""::date <= '{Convert.ToDateTime(model.ReceivedToDate):yyyy-MM-dd}'::date";
            }

            if (model.NewLabBookingDetailId != null)
            {
                where += $@" and nlbd.""NewLabBookingDetailId"" = {model.NewLabBookingDetailId}";
            }
            if (model.ProviderId != null && model.RoleId == 3)
            {
                where += $@" and lrv.""ApprovedBy"" = {model.ProviderId} and lrv.""Approved"" = false";
            }
            var query = $@"SELECT count(lts.*) over() as ""TotalItems"",a.""EncounterType"",nlbh.""AppointmentId"",lth.""TransferNumber"",lth.""TransferedBy"",lth.""TransferedDate"", lth.""ReceivedBy"" ,lth.""ReceivedDate"",lth.""TransferedLocationId"",
			                            tb.""FullName"" as ""TransferByName"",rb.""FullName"" as ""RecievedByName"", lmd.""TestName"" ,lmd.""TestCode"", lbs.""Status"" ,
			                            COALESCE (nlbh.""PatientName"" ,p.""FullName"" ) as ""PatientName"",nlbh.""RequisitionNumber"" ,
			                            COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
			                            e.""FullName"" as ""EmployeeName"",l.""Name"" as ""FromLocation"",p.""UMRNo"",p.""Gender"",p.""Age"",
			                            lsc.""SampleCollectedBy"" ,lsc.""CollectionDate"" ,lsc.""IsBarcodeGenerated"" ,lbs.""RowColor"",
			                            lsc.""BarcodeGeneratedBy"" , lsc.""BarcodeDate"" , sc.""FullName""  as ""SampleCollectedByName"",nlbd.""LabMainDetailId"",
                                        bc.""FullName"" as ""BarcodeGeneratedByName"", lt.""Name"" as ""TransferedToLocation"",nlbh.""CreatedDate"" as ""BookedDate"",
                                        nlbd.""NewLabBookingDetailId"",nlbh.""NewLabBookingHeaderId"",p.""DateOfBirth"",lrv.""Approved"",drv.""FullName"" as ""AssignedDoctor"",cd.""FullName"" as ""CreatedByName"",lrv.""CreatedDate"",nlbh.""PatientId"",nlbd.""HoldComments""
                                      FROM ""LabReportVerification"" lrv
                                      join ""LabTransferDetail"" lts ON lts.""NewLabBookingDetailId"" = lrv.""NewLabBookingDetailId"" 
		                              join ""LabTransferHeader"" lth ON lth.""LabTransferHeaderId"" = lts.""LabTransferHeaderId"" 
		                              join ""Location"" lt on lt.""LocationId"" = lth.""TransferedLocationId"" 
		                              join ""Account"" tb on tb.""AccountId"" = lth.""TransferedBy"" 		  
		                              left join ""Account"" rb on rb.""AccountId"" = lth.""ReceivedBy"" 
		                              join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingDetailId"" = lts.""NewLabBookingDetailId"" 
		                              join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
		                              join ""NewLabBookingHeader"" nlbh on nlbh.""NewLabBookingHeaderId"" = nlbd.""NewLabBookingHeaderId""
                                      left join ""Appointment"" a on a.""AppointmentId"" = nlbh.""AppointmentId""
		                              join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId"" 
		                              join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId"" 
		                              left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId"" 
	                                  left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId"" 
	                                  left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" 
	                                  left join ""LabSampleCollection"" lsc on lsc.""NewLabBookingDetailId"" = nlbd.""NewLabBookingDetailId"" 
	                                  left join ""Account"" sc on sc.""AccountId"" = lsc.""SampleCollectedBy"" 
	                                  left join ""Account"" bc on bc.""AccountId"" = lsc.""BarcodeGeneratedBy""
                                      left join ""Provider"" drv on drv.""ProviderId"" = lrv.""ApprovedBy""
                                      left join ""Account"" cd on cd.""AccountId"" = lrv.""CreatedBy"" 
                                        {where}  

                                        order by lth.""TransferedDate"" desc";
            //and nlbd.""LabBookingStatusId"" = 6
            //and (nlbd.""LabBookingStatusId"" = 8 or nlbd.""LabBookingStatusId"" =9)
            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageSize * model.PageIndex}";
            }

            return await this.unitOfWork.Current.QueryAsync<LabTransferModel>(query);
        }

        /// <summary>
        /// Assigns the lab report asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<int> AssignLabReportAsync(LabReportVerificationModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();
            var response = 0;
            var selectedLabs = model.ApprovedBy.ToList();
            var data1 = new LabReportVerification();
            for (int i = 0; i < selectedLabs.Count; i++)
            {
                data1.NewLabBookingDetailId = (int)model.NewLabBookingDetailId;
                data1.ApprovedBy = selectedLabs[i];
                data1.CreatedBy = (int)model.CreatedBy;
                data1.CreatedDate = DateTime.Now;
                try
                {
                    response = await this.unitOfWork.LabReportVerifications.InsertAsync(data1, transaction);
                    if (response != 0)
                    {
                        var getLabBookingDetail = await this.unitOfWork.NewLabBookingDetails.FindAsync(d => d.NewLabBookingDetailId == model.NewLabBookingDetailId);
                        var findDoctorAssignedStatus = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "DoctorAssigned");
                        getLabBookingDetail.LabBookingStatusId = findDoctorAssignedStatus.LabBookingStatusId;
                        var result = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(getLabBookingDetail, transaction);
                        var getLabDetail = await this.unitOfWork.LabMainDetails.FindAsync(l => l.LabMainDetailId == getLabBookingDetail.LabMainDetailId);
                        var getDoctorDetail = await this.unitOfWork.Providers.FindAsync(p => p.ProviderId == data1.ApprovedBy);
                        //var findReceivedStatus = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "DoctorAssigned");
                        var timeline = new LabBookingTimeLine
                        {
                            CommentedBy = (int)model.CreatedBy,
                            Comment = $@"{getLabDetail.TestName} is Asssigned to Dr. {getDoctorDetail.FullName}",
                            //Comment = $@"Parameters {(count > 0 ? "updated" : "added")} for lab {getLabDetail.TestName}",
                            CreatedDate = DateTime.Now,
                            LabBookingStatusId = findDoctorAssignedStatus.LabBookingStatusId,
                            NewLabBookingHeaderId = getLabBookingDetail.NewLabBookingHeaderId,
                            NewLabBookingDetailId = getLabBookingDetail.NewLabBookingDetailId
                        };
                        await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline);
                        //getLabBookingDetail.LabBookingStatusId = findReceivedStatus.LabBookingStatusId;
                        //await this.unitOfWork.NewLabBookingDetails.UpdateAsync(getLabBookingDetail);
                    }

                }
                catch (Exception e)
                {
                    e.Message.ToString();
                }

            }
            if (response == 0)
            {
                transaction.Rollback();
                return -3;
            }

            transaction.Commit();
            return 1;
        }

        public async Task<int> DoctorVerificationLabReportAsync(LabDoctorVerificationModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();
            var response = 0;
            var returnresponse = 0;
            var lookup = await this.unitOfWork.LabReportVerifications.FindAsync(m => m.NewLabBookingDetailId == model.NewLabBookingDetailId && m.ApprovedBy == model.DoctorId);
            if (lookup == null)
            {
                var report = new LabReportVerification
                {
                    CreatedBy = model.AccountId,
                    CreatedDate = DateTime.Now,
                    NewLabBookingDetailId = model.NewLabBookingDetailId,
                    ApprovedBy = model.DoctorId,
                    ApprovedDate = DateTime.Now,
                    Approved = true
                };

                response = await this.unitOfWork.LabReportVerifications.InsertAsync(report, transaction);
                if (response == 0)
                {
                    transaction.Rollback();
                    return -3;
                }
            }
            else
            {
                lookup.ApprovedDate = DateTime.Now;
                lookup.Approved = true;
                response = await this.unitOfWork.LabReportVerifications.UpdateAsync(lookup, transaction);
            }
            if (response == 0)
            {
                transaction.Rollback();
                return -3;
            }
            else
            {
                var getLabBookingDetail = await this.unitOfWork.NewLabBookingDetails.FindAsync(d => d.NewLabBookingDetailId == model.NewLabBookingDetailId);
                var getLabDetail = await this.unitOfWork.LabMainDetails.FindAsync(l => l.LabMainDetailId == getLabBookingDetail.LabMainDetailId);
                var getDoctorDetail = await this.unitOfWork.Providers.FindAsync(p => p.ProviderId == model.DoctorId);
                var findReceivedStatus = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Verified");
                var timeline = new LabBookingTimeLine
                {
                    CommentedBy = (int)model.AccountId,
                    Comment = $@" Dr. {getDoctorDetail.FullName} Verified {getLabDetail.TestName}",
                    CreatedDate = DateTime.Now,
                    LabBookingStatusId = findReceivedStatus.LabBookingStatusId,
                    NewLabBookingHeaderId = getLabBookingDetail.NewLabBookingHeaderId,
                    NewLabBookingDetailId = getLabBookingDetail.NewLabBookingDetailId
                };
                await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
            }
            var fetch = await this.unitOfWork.LabReportVerifications.FindAllAsync(m => m.NewLabBookingDetailId == model.NewLabBookingDetailId);
            var statusVerified = new LabBookingStatus();
            var statusDoctorAssigned = new LabBookingStatus();
            var data1 = new NewLabBookingDetail();
            if (fetch.ToList().Count < 2)
            {
                statusVerified = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Verified");
                data1 = await this.unitOfWork.NewLabBookingDetails.FindAsync(m => m.NewLabBookingDetailId == model.NewLabBookingDetailId);
                data1.LabBookingStatusId = statusVerified.LabBookingStatusId;
                response = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(data1, transaction);
                returnresponse = 1;
            }
            else
            {
                var notVerified = fetch.Where(x => x.Approved == false);
                //var notVerified=fetch.Select(x => x.Approved == false);
                if (notVerified.ToList().Count == 0)
                {
                    statusVerified = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Verified");
                    data1 = await this.unitOfWork.NewLabBookingDetails.FindAsync(m => m.NewLabBookingDetailId == model.NewLabBookingDetailId);
                    data1.LabBookingStatusId = statusVerified.LabBookingStatusId;
                    response = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(data1, transaction);
                    returnresponse = 1;
                }
                else
                {
                    statusDoctorAssigned = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "DoctorVerified");
                    data1 = await this.unitOfWork.NewLabBookingDetails.FindAsync(m => m.NewLabBookingDetailId == model.NewLabBookingDetailId);
                    data1.LabBookingStatusId = statusDoctorAssigned.LabBookingStatusId;
                    response = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(data1, transaction);
                    returnresponse = 2;
                }
            }

            transaction.Commit();
            return returnresponse;
        }

        public async Task<IEnumerable<LabReportProviderSignatureModel>> FetchDoctorLabReportSignatureAsync(int newLabBookingDetailId)
        {

            var query = $@"select prv.""ProviderId"", prv.""FullName"" as ""ProviderName"", (CASE WHEN prv.""Signature"" IS NOT NULL THEN CONCAT('{this.runningEnvironment.CurrentEnvironment}', '/', prv.""Guid"", '/', prv.""Signature"") ELSE NULL END) AS ""Signature"", dt.""DepartmentName"", lrv.""ApprovedDate""
                        from ""LabReportVerification"" lrv
                        left join ""Provider"" prv on prv.""ProviderId"" = lrv.""ApprovedBy""
                        left join ""Department"" dt on dt.""DepartmentId"" = prv.""DepartmentId""
                        where lrv.""NewLabBookingDetailId"" = {newLabBookingDetailId} and lrv.""Approved"" = true ";

            return await this.unitOfWork.Current.QueryAsync<LabReportProviderSignatureModel>(query);
        }

        public async Task<IEnumerable<ProviderIds>> FetchDoctorsAssignedForLabReportAsync(int newLabBookingDetailId)
        {

            var query = $@"select lrv.""ApprovedBy"", lrv.""Approved"",prv.""FullName"" as ""ProviderName"",lrv.""LabReportVerificationId"" from ""LabReportVerification"" lrv
                                               left join ""Provider"" prv ON prv.""ProviderId"" = lrv.""ApprovedBy""
                                               where ""NewLabBookingDetailId"" = {newLabBookingDetailId}";

            return await this.unitOfWork.Current.QueryAsync<ProviderIds>(query);
        }

        public async Task<IEnumerable<Machine>> FetchAllMachines()
        {
            var query = $@"select * from ""Machine"" where ""Active"" = true";
            return await this.unitOfWork.Current.QueryAsync<Machine>(query);
        }

        public async Task<int> DeletingDoctortoReports(LabReportVerificationModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();
            var response = 0;
            var query = $@"DELETE FROM ""LabReportVerification"" where ""LabReportVerificationId"" = {model.LabReportVerificationId}";
            response = await this.unitOfWork.Current.ExecuteAsync(query, transaction);
            if (response == 0)
            {
                return -1;
            }
            var findDoctorRemovedStatus = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "RemovedDoctor");
            var getLabBookingDetail = await this.unitOfWork.NewLabBookingDetails.FindAsync(d => d.NewLabBookingDetailId == model.NewLabBookingDetailId);
            var timeline = new LabBookingTimeLine
            {
                CommentedBy = (int)model.CreatedBy,
                Comment = $@"Provider Removed for lab {model.TestName}",
                CreatedDate = DateTime.Now,
                LabBookingStatusId = findDoctorRemovedStatus.LabBookingStatusId,
                NewLabBookingHeaderId = getLabBookingDetail.NewLabBookingHeaderId,
                NewLabBookingDetailId = getLabBookingDetail.NewLabBookingDetailId
            };
            await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
            var lookup = await this.unitOfWork.LabReportVerifications.FindAllAsync(m => m.NewLabBookingDetailId == model.NewLabBookingDetailId);
            var statusVerified = new LabBookingStatus();
            if (lookup.ToList().Count < 1)
            {
                getLabBookingDetail.LabBookingStatusId = findDoctorRemovedStatus.LabBookingStatusId;
                response = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(getLabBookingDetail, transaction);
            }
            else
            {
                var notVerified = lookup.Where(x => x.Approved == false);
                if (notVerified.ToList().Count == 0)
                {
                    statusVerified = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Verified");
                    //data1 = await this.unitOfWork.NewLabBookingDetails.FindAsync(m => m.NewLabBookingDetailId == model.NewLabBookingDetailId);
                    getLabBookingDetail.LabBookingStatusId = statusVerified.LabBookingStatusId;
                    response = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(getLabBookingDetail, transaction);
                }
            }
            transaction.Commit();
            return response;
            //return await this.unitOfWork.Current.QueryAsync<ProviderIds>(query);
        }

        public async Task<IEnumerable<LabReportPatientModel>> FetchPatientLabsAsync(LabReportPatientModel model)
        {
            var where = "where 1=1"; //
            if (model.FromDate != null)
            {
                where += $@" and nlbh.""CreatedDate""::date >= '{model.FromDate?.ToString("yyyy-MM-dd")}' ";
            }

            if (model.ToDate != null)
            {
                where += $@" and nlbh.""CreatedDate""::date  <= '{model.ToDate?.ToString("yyyy-MM-dd")}' ";
            }
            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }
            if (model.PayTypeId != null)
            {
                where += $@" and nlbh.""PayTypeId""= {model.PayTypeId}";
            }
            if (model.PatientId > 0)
            {
                where += $@" and nlbh.""PatientId"" = '{model.PatientId}'";
            }
            if (model.LocationId > 0)
            {
                where += $@" and  nlbh.""LocationId"" ={model.LocationId} ";
            }
            var query = $@"select nlbd.""NewLabBookingDetailId"",nlbd.""NewLabBookingHeaderId"", nlbd.""LabMainDetailId"",nlbd.""ChargeCategoryId""
                            ,nlbd.""DiscountPercentage"",nlbd.""DiscountAmount"", nlbd.""TotalAmount"", nlbd.""NetAmount"",nlbh.""RequisitionNumber"",nlbh.""PatientId""
                            ,lmd.""TestName"",lmd.""TestCode"" , ld.""DepartmentName"" ,cc.""ChargeCategoryName"",prv.""FullName"" as ""DoctorName"",nlbh.""CreatedDate""
                            ,c.""FullName"" as ""CreatedByName"",pt.""PayTypeName"", COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"",p.""UMRNo""
                            from ""NewLabBookingHeader"" nlbh
                            join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId"" 
                            join ""LabMainDetail"" lmd ON lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
                            join ""LabDepartment"" ld on ld.""LabDepartmentId"" = lmd.""LabDepartmentId""
                            join ""ChargeCategory"" cc on cc.""ChargeCategoryId"" = nlbd.""ChargeCategoryId""
                            join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
                            join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy"" 
                            join ""PayType"" pt ON pt.""PayTypeId"" = nlbh.""PayTypeId""
                            left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
                            {where} and nlbd.""LabBookingStatusId"" != 2 order by nlbh.""CreatedDate"" desc ";
            return await this.unitOfWork.Current.QueryAsync<LabReportPatientModel>(query);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabSampleHandlerModel>> FetchSamplecollectiontrackreports(LabSampleHandlerModel model)
        {

            var where = $@" where 1=1 ";
            if (model.LocationId != null)
            {
                where += $@" and lsc.""LocationId""= {model.LocationId}";
            }

            if (model.FromDate != null)
            {
                where += $@" and lsc.""CollectionDate"" >= '{model.FromDate}'";
            }
            if (model.ToDate != null)
            {
                where += $@" and lsc.""CollectionDate"" <= '{model.ToDate}'";
            }

            var query = $@" select distinct lsc.""LabSampleCollectionId"" ,lsc.""SampleCollectedBy"" ,lsc.""CollectionDate"" , 
                         nlbh.""RequisitionNumber"",nlbh.""CreatedDate"",
                         COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName"") ,CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"",
                        COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"",  COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",


                        p.""UMRNo"",lbs.""Status"",
                       lmd.""TestName"",lmd.""TestCode"",lsc.""SampleCollectedBy"" ,lsc.""CollectionDate"" , 
                        sc.""FullName""  as ""SampleCollectedByName"",lst.""TypeName"",  LD.""DepartmentName""

                        from ""LabSampleCollection"" lsc
                        join ""NewLabBookingDetail"" nlbd on nlbd.""NewLabBookingDetailId"" = lsc.""NewLabBookingDetailId"" 
                        join ""NewLabBookingHeader"" nlbh on nlbh.""NewLabBookingHeaderId"" = nlbd.""NewLabBookingHeaderId"" 
                       
                        join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId"" 
join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId"" 
                       join ""Location"" l ON l.""LocationId"" = lsc.""LocationId"" 
                        join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId"" 
                        join ""LabMainDetail"" lmd ON lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
						left join ""LabDepartment"" LD on LD.""LabDepartmentId""=lmd.""LabDepartmentId""

                        left join ""LabSampleType"" lst on lst.""LabSampleTypeId"" = lmd.""LabSampleTypeId""
                        left join ""Account"" sc on sc.""AccountId"" = lsc.""SampleCollectedBy""
                        {where} order by nlbh.""CreatedDate"" desc  ";
            return await this.unitOfWork.Current.QueryAsync<LabSampleHandlerModel>(query);
        }

        public async Task<IEnumerable<LabBookingModel>> FetchLabReports(LabBookingModel model)
        {
            var where = $@"where 1=1 and A.""LocationId""='{model.LocationId}'"; //
            if (model.CreatedBy > 0)
            {
                where += $@" and A.""CreatedBy""={model.CreatedBy} ";
            }

            if (model.NewLabBookingHeaderId > 0)
            {
                where += $@" and A.""NewLabBookingHeaderId"" = {model.NewLabBookingHeaderId}";
            }

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and A.""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and A.""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and A.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }

            if (model.PatientId > 0)
            {
                where += $@" and A.""PatientId"" = '{model.PatientId}'";
            }

            if (!string.IsNullOrEmpty(model.UMRNo))
            {
                where += $@" and A.""UMRNo"" = 'UMR{model.UMRNo}'";
            }

            if (model.PayTypeId != null)
            {
                where += $@" and A.""PayTypeId"" = {model.PayTypeId}";
            }

            if (model.DoctorId != null)
            {
                where += $@" and nlbh.""DoctorId"" = {model.DoctorId}";
            }

            //   var query1 = $@"with main as (SELECT distinct nlbh.""RequisitionNumber"",nlbh.""PaymentType"" ""TypeOfPayment"",nlbh.""NewLabBookingHeaderId"", nlbh.""Type"", nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",
            //                        nlbh.""LocationId"", nlbh.""PayTypeId"",
            //                        nlbh.""CreatedBy"", nlbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate"", c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"", COALESCE (nlbh.""PatientName"" ,p.""FullName"" ) as ""PatientName"",
            //                        COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
            //                        (CASE WHEN p.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('https://hims-devv.s3.amazonaws.com/', p.""Guid"", '/', p.""ThumbnailUrl"") ELSE '' END) AS ""PatientThumbnailUrl"",
            //                           e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",p.""UMRNo"",p.""Gender"",p.""Age""
            //                           ,p.""DateOfBirth"",nlbh.""OverallTotalAmount"",nlbh.""OverallDiscount"",nlbh.""OverallNetAmount"", nlbh.""PaymentNumber"",PD.""DepartmentName""
            //                           --,LS.""Status"", LS.""LabBookingStatusId"",LN.""TestName""
            //                           ,LD.""TotalAmount"",case when LD.""DiscountAmount"" is not null then LD.""DiscountAmount"" else 0 end as ""DiscountAmount""
            //                           ,R.""Cost"" as ""NetAmount""
            //                           ,sum(R.""Cost"") over() as ""GrandTotal""
            //                          ,sum(R.""Cost"") over() as ""OverallNetAmount""
            //                          --,sum(LD.""TotalAmount"") over() as ""GrandTotal""
            //                          --,sum(LD.""NetAmount"") over() as ""OverallNetAmount""
            //                          --,sum(case when LD.""DiscountAmount"" is not null then LD.""DiscountAmount"" else 0 end) over() as ""OverallDiscount"" 
            //                           from ""NewLabBookingHeader"" nlbh
            //                           join ""NewLabBookingDetail"" LD on nlbh.""NewLabBookingHeaderId""=LD.""NewLabBookingHeaderId""  and nlbh.""Active""<> false
            //                           --join ""LabMainDetail"" LN on LN.""LabMainDetailId"" = LD.""LabMainDetailId""
            //                           --join ""LabBookingStatus"" LS on LS.""LabBookingStatusId"" = LD.""LabBookingStatusId""
            //                           join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy""                                     
            //                           join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
            //                           left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy"" 
            //                           left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
            //                           left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
            //                           left join ""Department"" PD on PD.""DepartmentId""=prv.""DepartmentId""
            //                           left Join ""Receipt"" R on R.""RespectiveId""=nlbh.""NewLabBookingHeaderId"" and R.""ReceiptAreaTypeId""=8
            //                           left join ""PayType"" pt ON pt.""PayTypeId"" = R.""PayTypeId""
            //                           left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" {where}
            //                           order by nlbh.""CreatedDate"" desc)
            //                           Select count(*) over () as ""TotalItems"",* from main";


            //   var query = $@"with main as (SELECT distinct nlbh.""RequisitionNumber"",nlbh.""PaymentType"" ""TypeOfPayment"",nlbh.""NewLabBookingHeaderId"", nlbh.""Type"", nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",
            //                        nlbh.""LocationId"", nlbh.""PayTypeId"",
            //                        nlbh.""CreatedBy"", nlbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate"", c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"", COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName"") ,CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"",
            //                        COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
            //                           e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",p.""UMRNo"",p.""Gender"",p.""Age""
            //                           ,p.""DateOfBirth"",nlbh.""OverallTotalAmount""-COALESCE (nlcb.""TotalReturnAmount"",0) ""OverallTotalAmount"",nlbh.""OverallDiscount"",nlbh.""OverallNetAmount""-COALESCE(nlcb.""TotalReturnAmount"",0) ""OverallNetAmount"", nlbh.""PaymentNumber"",PD.""DepartmentName""
            //                           ,string_agg(DISTINCT LN.""TestName"", '/') AS ""TestName"",R.""Cost""-coalesce(RC.""Cost"",0) as ""NetAmount""
            //                           ,sum(R.""Cost""-coalesce(RC.""Cost"",0)) over() as ""GrandTotal""
            //                          ,sum(R.""Cost""-coalesce(RC.""Cost"",0)) over() as ""OverallNetAmount""
            //                           from ""NewLabBookingHeader"" nlbh
            //                           join ""NewLabBookingDetail"" LD on nlbh.""NewLabBookingHeaderId""=LD.""NewLabBookingHeaderId""  and nlbh.""Active""<> false
            //                           join ""LabMainDetail"" LN on LN.""LabMainDetailId"" = LD.""LabMainDetailId""
            //	                         left join ""NewLabCancelBookingHeader"" nlcb on nlcb.""NewLabBookingHeaderId""=nlbh.""NewLabBookingHeaderId""
            //                           join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy""                                     
            //                           join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
            //                           left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy"" 
            //                           left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
            //                           left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
            //                           left join ""Department"" PD on PD.""DepartmentId""=prv.""DepartmentId""
            //                           left Join ""Receipt"" R on R.""RespectiveId""=nlbh.""NewLabBookingHeaderId"" and R.""ReceiptAreaTypeId""=8
            //                           left Join ""Receipt"" RC on RC.""RespectiveId""=nlcb.""NewLabCancelBookingHeaderId"" and RC.""ReceiptAreaTypeId""=9
            //		                     join ""PayType"" pt ON pt.""PayTypeId"" = R.""PayTypeId""
            //                           left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" 
            //		                    {where} 
            //                          group by nlbh.""RequisitionNumber"",nlbh.""PaymentType"",nlbh.""NewLabBookingHeaderId"", nlbh.""Type"", nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",c.""FullName"",m.""FullName"",p.""FullName"",p.""Mobile""
            //                          ,prv.""FullName"",p.""ThumbnailUrl"", p.""Guid"", e.""FullName"",pt.""PayTypeName"",l.""Name"",p.""UMRNo"",p.""Gender"",p.""Age""
            //                          ,p.""DateOfBirth"",nlbh.""OverallTotalAmount"",nlbh.""OverallDiscount"",nlbh.""OverallNetAmount"", nlbh.""PaymentNumber"",PD.""DepartmentName""
            //                          ,R.""Cost"",nlcb.""TotalReturnAmount"",RC.""Cost"",p.""Salutation""
            //                          order by nlbh.""CreatedDate"" desc)
            //                          Select count(*) over () as ""TotalItems"",* from main";


            var query = $@"SELECT  A.""NewLabBookingHeaderId"",A.""RequisitionNumber"",A.""TypeOfPayment"", A.""Type"",
                        A.""PatientId"", A.""DoctorId"", A.""EmployeeId"",A.""LocationId"", A.""PayTypeId"",A.""CreatedBy"", A.""PaymentDetails"",
                        A.""CreatedDate"", A.""ModifiedBy"", A.""ModifiedDate"", A.""DoctorName""
                        ,A.""UMRNo"",A.""Gender"",A.""Age"" ,A.""DateOfBirth"",A.""PatientName"", A.""Mobile""
                        ,A.""CreatedByName"",A.""ModifiedByName"",A.""DepartmentName""
                        ,A.""EmployeeName"",A.""PayTypeName"" ,A.""LocationName"",A.""Cost"" ""NetAmount"" from
                        (SELECT  nlbh.""NewLabBookingHeaderId"",nlbh.""RequisitionNumber"",nlbh.""PaymentType"" ""TypeOfPayment"", nlbh.""Type"",
                        nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",nlbh.""LocationId"", R.""PayTypeId"",nlbh.""CreatedBy"", R.""PaymentDetails"",
                        nlbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName""
                        ,p.""UMRNo"",p.""Gender"",p.""Age"" ,p.""DateOfBirth"", COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName""),CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"", COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile""
                        ,c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"",PD.""DepartmentName""
                        ,e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",R.""Cost"" 
                        from ""NewLabBookingHeader"" nlbh
                        left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
                        join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy"" 
                        left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy"" 
                        left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
                        left join ""Department"" PD on PD.""DepartmentId""=prv.""DepartmentId""                                    
                        join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
                        left Join ""Receipt"" R on R.""RespectiveId""=nlbh.""NewLabBookingHeaderId"" and R.""ReceiptAreaTypeId""=8
                        join ""PayType"" pt ON pt.""PayTypeId"" = R.""PayTypeId""
                        left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" 

                        union all

                        SELECT  nlbh.""NewLabBookingHeaderId"",nlbh.""RequisitionNumber"",nlbh.""PaymentType"" ""TypeOfPayment"", nlbh.""Type"",
                        nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",nlbh.""LocationId"", RC.""PayTypeId"",nlbh.""CreatedBy"", RC.""PaymentDetails"",
                        nlbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate""
                        , COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName""
                        ,p.""UMRNo"",p.""Gender"",p.""Age"" ,p.""DateOfBirth"", COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName""),CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"", COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile""
                        ,c.""FullName"" as ""CreatedByName"" ,m.""FullName"" as ""ModifiedByName"" ,PD.""DepartmentName""
                        ,e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",-RC.""Cost""
                        from ""NewLabCancelBookingHeader"" nlbc
                        left join ""NewLabBookingHeader"" nlbh on nlbh.""NewLabBookingHeaderId""=nlbc.""NewLabBookingHeaderId""
                        left Join ""Receipt"" RC on RC.""RespectiveId""=nlbc.""NewLabCancelBookingHeaderId"" and RC.""ReceiptAreaTypeId""=9
                        left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
                        join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy"" 
                        left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy"" 
                        left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
                        left join ""Department"" PD on PD.""DepartmentId""=prv.""DepartmentId""
                        left join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
                        left join ""PayType"" pt ON pt.""PayTypeId"" = RC.""PayTypeId""
                        left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" ) A  {where} ";
            //if (model.PageIndex != null && model.PageSize != null)
            //{
            //    model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
            //    query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            //}
            return await this.unitOfWork.Current.QueryAsync<LabBookingModel>(query);
        }

        public async Task<IEnumerable<LabParameterResultsModel>> FetchAllLabParameterObservedValuesAsync(LabTransferModel model)
        {
            if (model.NewLabBookingDetailId < 1)
            {
                return null;
            }
            var query = $@"with totalActiveParameters as (select count(*) as ""Count"", ""NewLabBookingDetailId"" from ""LabParameterObservedValue"" 
                           where ""NewLabBookingDetailId"" = {model.NewLabBookingDetailId} and ""Active"" = true group by ""NewLabBookingDetailId"")
                           select lpov.""LabParameterObservedValueId"",lpov.""CreatedDate"",lpov.""ObservedValue"",a.""FullName"" as ""CreatedByName"",tap.""Count"",lph.""ParameterName"",lpov.""Active"" from ""LabParameterObservedValue"" lpov
                           join totalActiveParameters tap on tap.""NewLabBookingDetailId"" = lpov.""NewLabBookingDetailId""
                           join ""LabParameterHeader"" lph on lph.""LabParameterHeaderId"" = lpov.""LabParameterHeaderId""
                           join ""Account"" a on a.""AccountId"" = lpov.""CreatedBy""
                           where lpov.""NewLabBookingDetailId"" = {model.NewLabBookingDetailId}  group by lpov.""LabParameterObservedValueId"",lpov.""LabParameterObservedValueId"",tap.""Count"",lph.""ParameterName"",a.""FullName"" order by 1 ";
            return await this.unitOfWork.Current.QueryAsync<LabParameterResultsModel>(query);


        }


        public async Task<IEnumerable<LabBookingModel>> FetchSelectedLabDataForWebReports(LabBookingModel model)
        {
            var where = "where 1=1";

            if (model.NewLabBookingHeaderId > 0)
            {
                where += $@" and nlbh.""NewLabBookingHeaderId"" = {model.NewLabBookingHeaderId} ";
            }

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and nlbh.""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and nlbh.""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }

            if (model.IsShowSampleCollected != null)
            {
                if ((bool)model.IsShowSampleCollected)
                {
                    where += $@" and (lbs.""Status"" = 'Booked' or lbs.""Status"" = 'SampleCollected')";
                }
                else
                {
                    where += $@" and lbs.""Status"" = 'Booked'";
                }
            }

            var mainQuery = $@" SELECT distinct nlbh.""NewLabBookingHeaderId"", count(nlbh.*) over () as ""TotalItems"", nlbh.""RequisitionNumber"", nlbh.""Type"", nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",
                                       nlbh.""LocationId"", nlbh.""OverallTotalAmount"", nlbh.""OverallDiscount"",  nlbh.""OverallDiscountPercentage"", nlbh.""PayTypeId"", 
                                    nlbh.""PaymentNumber"", nlbh.""CreatedBy"", nlbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate"", nlbh.""Active""  ,
                                    c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"",COALESCE (nlbh.""PatientName"" ,p.""FullName"" ) as ""PatientName"",
                                    COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
                                    (CASE WHEN p.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('https://hims-qa.s3.amazonaws.com/', p.""Guid"", '/', p.""ThumbnailUrl"") ELSE '' END) AS ""PatientThumbnailUrl"",
                                    e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",p.""UMRNo"",p.""Gender"",p.""Age""
                                   FROM ""NewLabBookingHeader"" nlbh
                                   join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy"" 
                                   join ""PayType"" pt ON pt.""PayTypeId"" = nlbh.""PayTypeId""  
                                   join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId"" 
                                   join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId"" 
                                   join ""LabBookingStatus"" lbs on lbs.""LabBookingStatusId"" = nlbd.""LabBookingStatusId"" 
	                               left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy"" 
	                               left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId"" 
	                               left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId"" 
	                               left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" 
                                    {where} order by nlbh.""CreatedDate"" desc";
            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                mainQuery += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }

            var headerResponse = await this.unitOfWork.Current.QueryAsync<LabBookingModel>(mainQuery);
            headerResponse.Select(l => new LabBookingModel
            {
                OverallTotalAmount = (double)(l.OverallTotalAmount + l.TotalReturnAmount),
            });
            foreach (var header in headerResponse)
            {
                header.Labs = new List<NewLabBookingDetailModel>();

                var detailQuery = $@"SELECT nlbd.""NewLabBookingDetailId"", nlbd.""NewLabBookingHeaderId"", nlbd.""LabMainDetailId"", nlbd.""ChargeCategoryId"", nlbd.""LabBookingStatusId"", nlbd.""DiscountPercentage"", 
		                                    nlbd.""DiscountAmount"", nlbd.""TotalAmount"", nlbd.""NetAmount"", lbs.""Status"",lbs.""RowColor"",
		                                    lmd.""TestName"",lmd.""TestCode"" , ld.""DepartmentName"" ,cc.""ChargeCategoryName"",lsc.""SampleCollectedBy"", a.""FullName"" as ""CollectedByName"",lsc.""CollectionDate""
		                                    FROM ""NewLabBookingDetail"" nlbd
		                                    join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId""
		                                    join ""LabMainDetail"" lmd ON lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
		                                    join ""LabDepartment"" ld on ld.""LabDepartmentId"" = lmd.""LabDepartmentId"" 
		                                    join ""ChargeCategory"" cc on cc.""ChargeCategoryId"" = nlbd.""ChargeCategoryId""
                                            left join ""LabSampleCollection"" lsc on lsc.""NewLabBookingDetailId"" = nlbd.""NewLabBookingDetailId""
                                            left join ""Account"" a on a.""AccountId"" = lsc.""SampleCollectedBy""
		                                    where nlbd.""NewLabBookingHeaderId"" = {header.NewLabBookingHeaderId} order by nlbd.""NewLabBookingDetailId""";
                header.Labs = (await this.unitOfWork.Current.QueryAsync<NewLabBookingDetailModel>(detailQuery)).ToList();
            }

            return headerResponse;
        }

        /// <inheritdoc/>
        public async Task<int> ChangeSampleProcessStatusAsync(LabTransferModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();

            var lookup = await this.unitOfWork.NewLabBookingDetails.FindAsync(m => m.NewLabBookingDetailId == model.NewLabBookingDetailId);
            if (lookup == null)
            {
                transaction.Rollback();
                return -1;
            }
            var findLab = await this.unitOfWork.LabMainDetails.FindAsync(f => f.LabMainDetailId == lookup.LabMainDetailId);
            if (findLab == null)
            {
                transaction.Rollback();
                return -1;
            }
            var status = (await this.unitOfWork.LabBookingStatus.FindAllAsync()).ToList();
            if (status.Count == 0)
            {
                transaction.Rollback();
                return -1;
            }

            var findSub = await this.unitOfWork.LabSampleCollectionDetails.FindAsync(f => f.LabSampleCollectionDetailId == model.LabSampleCollectionDetailId);
            if (findSub == null)
            {
                transaction.Rollback();
                return -1;
            }

            if (model.Status == "SampleRejected")
            {
                findSub.LabBookingStatusId = (status.Find(s => s.Status == "SampleRejected")).LabBookingStatusId;
                findSub.Comment = model.Comment;
                var updateOldRes = await this.unitOfWork.LabSampleCollectionDetails.UpdateAsync(findSub, transaction);
                if (updateOldRes == 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                var newRec = new LabSampleCollectionDetail
                {
                    LabBookingStatusId = (status.Find(s => s.Status == "Booked")).LabBookingStatusId,
                    LabSampleCollectionId = findSub.LabSampleCollectionId,
                    SampleName = findSub.SampleName
                };

                var insertSub = await this.unitOfWork.LabSampleCollectionDetails.InsertAsync(newRec, transaction);
                if (insertSub == 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                var timeline = new LabBookingTimeLine
                {
                    CommentedBy = (int)model.TransferedBy,
                    Comment = $@"Sample Rejected for lab {model.TestName} because {model.Comment}",
                    CreatedDate = DateTime.Now,
                    LabBookingStatusId = (status.Find(s => s.Status == "SampleRejected")).LabBookingStatusId,
                    NewLabBookingHeaderId = lookup.NewLabBookingHeaderId,
                    NewLabBookingDetailId = lookup.NewLabBookingDetailId
                };
                var res = await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
                if (res == 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                lookup.LabBookingStatusId = (status.Find(s => s.Status == "PartiallyCollected")).LabBookingStatusId;
                var resp = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(lookup, transaction);
                if (resp == 0)
                {
                    transaction.Rollback();
                    return -1;
                }
                transaction.Commit();
                return resp;
            }
            else
            {
                findSub.LabBookingStatusId = (status.Find(s => s.Status == "SampleVerified")).LabBookingStatusId;
                var updateSub = await this.unitOfWork.LabSampleCollectionDetails.UpdateAsync(findSub, transaction);
                if (updateSub == 0)
                {
                    transaction.Rollback();
                    return -1;
                }
                var timeline = new LabBookingTimeLine
                {
                    CommentedBy = (int)model.TransferedBy,
                    Comment = $@"Sample Accepted for lab {model.TestName}",
                    CreatedDate = DateTime.Now,
                    LabBookingStatusId = (status.Find(s => s.Status == "SampleVerified")).LabBookingStatusId,
                    NewLabBookingHeaderId = lookup.NewLabBookingHeaderId,
                    NewLabBookingDetailId = lookup.NewLabBookingDetailId
                };
                var res = await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
                if (res == 0)
                {
                    transaction.Rollback();
                    return -1;
                }
            }

            transaction.Commit();

            var query = $@"select count(*) from ""LabSampleCollectionDetail""  where   ""LabSampleCollectionId"" = {findSub.LabSampleCollectionId} and ""LabBookingStatusId"" != {(status.Find(s => s.Status == "SampleVerified")).LabBookingStatusId}";
            var count = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(query);
            if (count == 0)
            {
                var updateQuery = $@"update ""NewLabBookingDetail"" set  ""LabBookingStatusId"" = {(status.Find(s => s.Status == "SampleVerified")).LabBookingStatusId} where  ""NewLabBookingDetailId"" = (select ""NewLabBookingDetailId"" from ""LabSampleCollection"" where ""LabSampleCollectionId"" = {findSub.LabSampleCollectionId} )";
                await this.unitOfWork.Current.ExecuteAsync(updateQuery);
            }
            return findSub.LabSampleCollectionDetailId;
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<LabTransferModel>> FetchTransferedLabsAsync(LabTransferModel model)
        {
            var where = "where 1=1";

            if (model.CreatedLabLocationId != null)
            {
                where += $@" and nlbh.""LocationId"" = {model.CreatedLabLocationId} ";
            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }

            if (!string.IsNullOrEmpty(model.TransferNumber))
            {
                where += $@" and lower(lth.""TransferNumber"") = '{model.TransferNumber.Trim().ToLower()}'";
            }

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and lth.""TransferedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and lth.""TransferedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }

            if (model.TransferedLocationId > 0)
            {
                where += $@" and lth.""TransferedLocationId"" = {model.TransferedLocationId} ";
            }

            if (!string.IsNullOrEmpty(model.ReceivedFromDate))
            {
                where += $@" and lth.""ReceivedDate""::date >= '{Convert.ToDateTime(model.ReceivedFromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ReceivedToDate))
            {
                where += $@" and lth.""ReceivedDate""::date <= '{Convert.ToDateTime(model.ReceivedToDate):yyyy-MM-dd}'::date";
            }

            if (model.NewLabBookingDetailId != null)
            {
                where += $@" and nlbd.""NewLabBookingDetailId"" = {model.NewLabBookingDetailId}";
            }
            where += $@" and lbs.""Status"" = 'ParameterAdded' ";
            if (model.PatientId > 0)
            {
                where += $@" and nlbh.""PatientId"" = {model.PatientId} and lbs.""Status"" = 'Verified' ";
            }

            var query = $@"SELECT count(lts.*) over() as ""TotalItems"",lth.""TransferNumber"",lth.""TransferedBy"",lth.""TransferedDate"", lth.""ReceivedBy"" ,lth.""ReceivedDate"",lth.""TransferedLocationId"",
			                            tb.""FullName"" as ""TransferByName"",rb.""FullName"" as ""RecievedByName"", lmd.""TestName"" ,lmd.""TestCode"", lbs.""Status"" ,
			                            COALESCE (nlbh.""PatientName"" ,p.""FullName"" ) as ""PatientName"",nlbh.""RequisitionNumber"" ,
			                            COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
			                            e.""FullName"" as ""EmployeeName"",l.""Name"" as ""FromLocation"",p.""UMRNo"",p.""Gender"",p.""Age"",
			                            lsc.""SampleCollectedBy"" ,lsc.""CollectionDate"" ,lsc.""IsBarcodeGenerated"" ,lbs.""RowColor"",
			                            lsc.""BarcodeGeneratedBy"" , lsc.""BarcodeDate"" , sc.""FullName""  as ""SampleCollectedByName"",
			                            bc.""FullName"" as ""BarcodeGeneratedByName"", lt.""Name"" as ""TransferedToLocation"",nlbh.""CreatedDate"" as ""BookedDate"",nlbh.""PatientId"",
                                        nlbd.""NewLabBookingDetailId"",nlbh.""NewLabBookingHeaderId"",p.""DateOfBirth"",nlbd.""Comment""
                                      FROM ""LabTransferDetail"" lts
		                              join ""LabTransferHeader"" lth ON lth.""LabTransferHeaderId"" = lts.""LabTransferHeaderId"" 
		                              join ""Location"" lt on lt.""LocationId"" = lth.""TransferedLocationId"" 
		                              join ""Account"" tb on tb.""AccountId"" = lth.""TransferedBy"" 		  
		                              left join ""Account"" rb on rb.""AccountId"" = lth.""ReceivedBy"" 
		                              join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingDetailId"" = lts.""NewLabBookingDetailId"" 
		                              join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
		                              join ""NewLabBookingHeader"" nlbh on nlbh.""NewLabBookingHeaderId"" = nlbd.""NewLabBookingHeaderId""
		                              join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId"" 
		                              join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId"" 
		                              left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId"" 
	                                  left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId"" 
	                                  left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" 
	                                  left join ""LabSampleCollection"" lsc on lsc.""NewLabBookingDetailId"" = nlbd.""NewLabBookingDetailId"" 
	                                  left join ""Account"" sc on sc.""AccountId"" = lsc.""SampleCollectedBy"" 
	                                  left join ""Account"" bc on bc.""AccountId"" = lsc.""BarcodeGeneratedBy""
                                        {where} 
			                            order by lth.""TransferedDate"" desc";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageSize * model.PageIndex}";
            }

            return await this.unitOfWork.Current.QueryAsync<LabTransferModel>(query);
        }

        /// <inheritdoc/>
        public async Task<int> NewDoctorAssigning(NewDoctorAssigningModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();
            var response = 0;
            var selectedLabs = model.Providers.ToList();
            var data12 = new LabReportVerification();
            foreach (var lab in model.Labs.ToList())
            {
                foreach (var ProviderId in model.Providers)
                {
                    data12.NewLabBookingDetailId = (int)lab.NewLabBookingDetailId;
                    data12.CreatedBy = model.CreatedBy;
                    data12.CreatedDate = DateTime.Now;
                    data12.ApprovedBy = ProviderId;
                    var response1 = await this.unitOfWork.LabReportVerifications.InsertAsync(data12, transaction);
                    if (response1 != 0)
                    {
                        var getLabBookingDetail = await this.unitOfWork.NewLabBookingDetails.FindAsync(d => d.NewLabBookingDetailId == lab.NewLabBookingDetailId);
                        var findDoctorAssignedStatus = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "DoctorAssigned");
                        getLabBookingDetail.LabBookingStatusId = findDoctorAssignedStatus.LabBookingStatusId;
                        var result = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(getLabBookingDetail, transaction);
                        var getLabDetail = await this.unitOfWork.LabMainDetails.FindAsync(l => l.LabMainDetailId == getLabBookingDetail.LabMainDetailId);
                        var getDoctorDetail = await this.unitOfWork.Providers.FindAsync(p => p.ProviderId == data12.ApprovedBy);
                        var timeline = new LabBookingTimeLine
                        {
                            CommentedBy = (int)model.CreatedBy,
                            Comment = $@"{getLabDetail.TestName} is Asssigned to Dr. {getDoctorDetail.FullName}",
                            CreatedDate = DateTime.Now,
                            LabBookingStatusId = findDoctorAssignedStatus.LabBookingStatusId,
                            NewLabBookingHeaderId = getLabBookingDetail.NewLabBookingHeaderId,
                            NewLabBookingDetailId = getLabBookingDetail.NewLabBookingDetailId
                        };
                        await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
                        response += response1;
                    }
                    else
                    {
                        transaction.Rollback();
                        return -3;
                    }
                }
            }
            if (response > 0)
            {
                transaction.Commit();
                return 1;
            }
            else
            {
                transaction.Rollback();
                return -2;
            }

        }

        public async Task<IEnumerable<LabBookingModel>> FetchLabStatusReports(LabBookingModel model)
        {
            var where = "where 1=1";
            var where2 = "where 1=1";
            var order = $@"order by nlbh.""CreatedDate"" desc";

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where2 += $@" and ""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where2 += $@" and ""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }
            if (model.NewLabBookingHeaderId > 0)
            {
                where += $@" and nlbh.""NewLabBookingHeaderId"" = {model.NewLabBookingHeaderId}";
            }

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and nlbh.""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and nlbh.""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }

            if (model.PatientId > 0)
            {
                where += $@" and nlbh.""PatientId"" = '{model.PatientId}'";
            }

            if (!string.IsNullOrEmpty(model.UMRNo))
            {
                where += $@" and p.""UMRNo"" = 'UMR{model.UMRNo}'";
            }

            if (model.PayTypeId != null)
            {
                where += $@" and nlbh.""PayTypeId"" = {model.PayTypeId}";
            }

            if (model.DoctorId != null)
            {
                where += $@" and nlbh.""DoctorId"" = {model.DoctorId}";
            }
            if (model.LabDepartmentId != null)
            {
                where += $@" and LN.""LabDepartmentId"" = {model.LabDepartmentId}";
            }
            if (model.LocationId != null)
            {
                where += $@"  and nlbh.""LocationId""='{model.LocationId}'";
            }
            if (model.LabBookingStatusId != null)
            {
                where += $@" and  LBD.""LabBookingStatusId"" = {model.LabBookingStatusId}";
            }
            if (!string.IsNullOrEmpty(model.TestName))
            {
                where += $@" and (lower(LN.""TestName"") ilike '%{model.TestName.ToLower()}%' or lower(LN.""TestCode"") ilike '%{model.TestName.ToLower()}%')";
            }

            var query = $@"
                        with statusDate as (
                        select distinct ""NewLabBookingHeaderId"",""LabBookingStatusId"",max(""CreatedDate"") as ""StatusDate""
                        from ""LabBookingTimeLine"" {where2}
                        group by  ""NewLabBookingHeaderId"",""LabBookingStatusId""
                        )


SELECT count(nlbh.*) over () as ""TotalItems"",
                        nlbh.""NewLabBookingHeaderId"", nlbh.""RequisitionNumber"",
             nlbh.""CreatedBy"", nlbh.""CreatedDate"", c.""FullName"" as ""CreatedByName"",l.""Name""  ""LocationName"",
            COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName"") ,CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"",COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"",p.""UMRNo"",p.""Gender"",p.""Age"",p.""DateOfBirth"",
            COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",PD.""DepartmentName""                                
            ,LS.""Status"", LS.""LabBookingStatusId"",LN.""TestName"", T.""StatusDate""	,LD.""DepartmentName"" as ""LabDepartmentName""								
                                    from ""NewLabBookingHeader"" nlbh
                                    join ""NewLabBookingDetail"" LBD on nlbh.""NewLabBookingHeaderId""=LBD.""NewLabBookingHeaderId""  and nlbh.""Active""<> false
                                    join ""LabMainDetail"" LN on LN.""LabMainDetailId"" = LBD.""LabMainDetailId""
                                    join ""LabDepartment"" LD  on LD.""LabDepartmentId""=LN.""LabDepartmentId""
                                    join ""LabBookingStatus"" LS on LS.""LabBookingStatusId"" = LBD.""LabBookingStatusId""
                                    join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy"" 
                                    join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
                                    left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
                                    left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
                                    left join ""Department"" PD on PD.""DepartmentId""=prv.""DepartmentId""
                                    left join statusDate T on T.""NewLabBookingHeaderId""=nlbh.""NewLabBookingHeaderId"" and T.""LabBookingStatusId""=LBD.""LabBookingStatusId""
                            {where}
	                           {order}  ";
            //if (model.PageIndex != null && model.PageSize != null)
            //{
            //    model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
            //    query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            //}
            return await this.unitOfWork.Current.QueryAsync<LabBookingModel>(query);
        }

        public async Task<IEnumerable<PatientPastLabReportsModel>> FetchPatientPastLabReportsAsync(PatientPastLabReportsModel model)
        {

            var query = $@"select count(nlbh.*) over() as ""TotalItems"",nlbh.""NewLabBookingHeaderId"",nlbh.""PatientId"",nlbd.""NewLabBookingDetailId"",nlbd.""LabMainDetailId"",
                           lmd.""TestName"",lmd.""TestCode"" ,lmd.""IsExternalLab"", lmd.""IsInternalLab"",nlbh.""CreatedDate"",lbs.""Status""
                           from ""NewLabBookingHeader"" nlbh  
                           join  ""NewLabBookingDetail"" nlbd on nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId""
                           join ""LabMainDetail"" lmd ON lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
                           join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId""
                           where nlbh.""PatientId"" = {model.PatientId} and nlbd.""LabMainDetailId"" = {model.LabMainDetailId} and lbs.""Status"" = 'Verified' and nlbd.""LabMainDetailId"" != {model.NewLabBookingDetailId} order by nlbh.""CreatedDate"" desc ";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageSize * model.PageIndex}";
            }

            return await this.unitOfWork.Current.QueryAsync<PatientPastLabReportsModel>(query);
        }

        public async Task<IEnumerable<LabTransferModel>> FetchTransferedLabs(int transferId)
        {

            var where = "where 1=1";

            if (transferId > 0)
            {
                where += $@" and lts.""LabTransferHeaderId"" = {transferId} ";
            }


            var query = $@"SELECT count(lts.*) over() as ""TotalItems"",lth.""TransferNumber"",lth.""TransferedBy"",lth.""TransferedDate"", lth.""ReceivedBy"" ,lth.""ReceivedDate"",lth.""TransferedLocationId"",
			                            tb.""FullName"" as ""TransferByName"",rb.""FullName"" as ""RecievedByName"", lmd.""TestName"" ,lmd.""TestCode"", lbs.""Status"" ,
			                            COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName"") ,CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"",nlbh.""RequisitionNumber"" ,
			                            COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
			                            e.""FullName"" as ""EmployeeName"",l.""Name"" as ""FromLocation"",p.""UMRNo"",p.""Gender"",p.""Age"",
			                            lsc.""SampleCollectedBy"" ,lsc.""CollectionDate"" ,lsc.""IsBarcodeGenerated"" ,lbs.""RowColor"",lth.""TransferredTemperatureComments"",
			                            lsc.""BarcodeGeneratedBy"" , lsc.""BarcodeDate"" , sc.""FullName""  as ""SampleCollectedByName"",lth.""ReceivedTemperatureComments"",
			                            bc.""FullName"" as ""BarcodeGeneratedByName"", lt.""Name"" as ""TransferedToLocation"",nlbh.""CreatedDate"" as ""BookedDate"",nlbh.""PatientId"",
                                        nlbd.""NewLabBookingDetailId"",nlbh.""NewLabBookingHeaderId"",p.""DateOfBirth"",lth.""TransferredTemperature"",lth.""ReceivedTemperature""
                                      FROM ""LabTransferDetail"" lts
		                              join ""LabTransferHeader"" lth ON lth.""LabTransferHeaderId"" = lts.""LabTransferHeaderId"" 
		                              join ""Location"" lt on lt.""LocationId"" = lth.""TransferedLocationId"" 
		                              join ""Account"" tb on tb.""AccountId"" = lth.""TransferedBy"" 		  
		                              left join ""Account"" rb on rb.""AccountId"" = lth.""ReceivedBy"" 
		                              join ""NewLabBookingDetail"" nlbd ON nlbd.""NewLabBookingDetailId"" = lts.""NewLabBookingDetailId"" 
		                              join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
		                              join ""NewLabBookingHeader"" nlbh on nlbh.""NewLabBookingHeaderId"" = nlbd.""NewLabBookingHeaderId""
		                              join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId"" 
		                              join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId"" 
		                              left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId"" 
	                                  left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId"" 
	                                  left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId"" 
	                                  left join ""LabSampleCollection"" lsc on lsc.""NewLabBookingDetailId"" = nlbd.""NewLabBookingDetailId"" 
	                                  left join ""Account"" sc on sc.""AccountId"" = lsc.""SampleCollectedBy"" 
	                                  left join ""Account"" bc on bc.""AccountId"" = lsc.""BarcodeGeneratedBy""
                                        {where} 
			                            order by lth.""TransferedDate"" desc";


            return await this.unitOfWork.Current.QueryAsync<LabTransferModel>(query);
        }

        public async Task<int> ChangeHoldStatusOfTest(LabHoldStatusModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();
            var response = 0;
            var response1 = 0;
            var getLabBookingDetail = await this.unitOfWork.NewLabBookingDetails.FindAsync(d => d.NewLabBookingDetailId == model.NewLabBookingDetailId);
            var getLabDetail = await this.unitOfWork.LabMainDetails.FindAsync(d => d.LabMainDetailId == getLabBookingDetail.LabMainDetailId);
            var getLabStatus = await this.unitOfWork.LabBookingStatus.FindAsync(d => d.Status == model.Status);
            if (model.Status == "Hold")
            {
                getLabBookingDetail.HoldBy = model.AccountId;
                getLabBookingDetail.HoldComments = model.HoldComments;
                getLabBookingDetail.LabBookingStatusId = getLabStatus.LabBookingStatusId;
                response = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(getLabBookingDetail, transaction);
                var timeline = new LabBookingTimeLine
                {
                    CommentedBy = (int)model.AccountId,
                    Comment = $@"Status Changed for {getLabDetail.TestName} Due to {model.HoldComments}",
                    CreatedDate = DateTime.Now,
                    LabBookingStatusId = getLabStatus.LabBookingStatusId,
                    NewLabBookingHeaderId = getLabBookingDetail.NewLabBookingHeaderId,
                    NewLabBookingDetailId = getLabBookingDetail.NewLabBookingDetailId
                };
                response1 = await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
                if (response == 0 || response1 == 0)
                {
                    transaction.Rollback();
                    return -3;
                }
            }
            else if (model.Status == "UnHold")
            {
                getLabBookingDetail.UnHoldBy = model.AccountId;
                getLabBookingDetail.UnHoldComments = model.UnHoldComments;
                getLabBookingDetail.LabBookingStatusId = getLabStatus.LabBookingStatusId;
                response = await this.unitOfWork.NewLabBookingDetails.UpdateAsync(getLabBookingDetail, transaction);
                var timeline = new LabBookingTimeLine
                {
                    CommentedBy = (int)model.AccountId,
                    Comment = $@"Status Changed for {getLabDetail.TestName} Due to {model.UnHoldComments}",
                    CreatedDate = DateTime.Now,
                    LabBookingStatusId = getLabStatus.LabBookingStatusId,
                    NewLabBookingHeaderId = getLabBookingDetail.NewLabBookingHeaderId,
                    NewLabBookingDetailId = getLabBookingDetail.NewLabBookingDetailId
                };
                response1 = await this.unitOfWork.LabBookingTimeLines.InsertAsync(timeline, transaction);
                if (response == 0 || response1 == 0)
                {
                    transaction.Rollback();
                    return -3;
                }
            }
            else
            {
                return -3;
            }
            if (response > 0)
            {
                transaction.Commit();
                return response;
            }
            else
            {
                return -1;
            }


        }

        public async Task<IEnumerable<LabTATReportModel>> FetchLabTatReports(LabBookingModel model)
        {
            var where = $@"where 1=1";
            var where2 = $@"where 1=1 and ""NewLabBookingDetailId"" is not null ";

            if (model.LocationId > 0)
            {
                where += $@" and nlbh.""LocationId""='{model.LocationId}'";
            }

            //if (!string.IsNullOrEmpty(model.FromDate))
            //{

            //    where2 += $@" and ""CreatedDate""::timestamp without time zone >= '{model.FromDate}'::timestamp without time zone";
            //}

            //if (!string.IsNullOrEmpty(model.ToDate))
            //{

            //    where2 += $@" and ""CreatedDate""::timestamp without time zone <= '{model.ToDate}'::timestamp without time zone";
            //}

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and nlbh.""CreatedDate""::date >= '{model.FromDate}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and nlbh.""CreatedDate""::date <= '{model.ToDate}'::date ";
            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" = '{model.RequisitionNumber}'";
            }

            if (model.PatientId > 0)
            {
                where += $@" and nlbh.""PatientId"" = '{model.PatientId}'";
            }

            if (model.LabBookingStatusId != null)
            {
                where += $@" and  LD.""LabBookingStatusId"" = {model.LabBookingStatusId}";
            }

            var query = $@"

            with statusDate as (
                select distinct ""NewLabBookingDetailId"",""LabBookingStatusId"",max(""CreatedDate"") as ""StatusDate"",
                        ""NewLabBookingHeaderId""
                from ""LabBookingTimeLine""
               {where2}
                 group by  ""NewLabBookingDetailId"",""LabBookingStatusId"", ""NewLabBookingHeaderId""
            )

    SELECT distinct(LD.""NewLabBookingDetailId"") ,count(nlbh.*) over() as ""TotalItems"",LD.""NewLabBookingDetailId"",
            nlbh.""NewLabBookingHeaderId"", nlbh.""RequisitionNumber"", nlbh.""PatientId"",  
            nlbh.""LocationId"",LDS.""Status"" as ""CurrentStatus"",LN.""TestName"",--nlbh.""CreatedBy"", nlbh.""CreatedDate"",c.""FullName"" as ""CreatedByName"",
            COALESCE(nlbh.""PatientName"", p.""FullName"") as ""PatientName"",COALESCE(p.""Mobile"", nlbh.""Mobile"") as ""Mobile"", COALESCE(nlbh.""DoctorName"", prv.""FullName"") as ""DoctorName"",p.""UMRNo"",p.""Gender"",p.""Age"",p.""DateOfBirth"",
            l.""Name"" as ""LocationName"",PD.""DepartmentName""
            , nlbh.""CreatedDate"" as ""BookedAt"",
            max(case when T.""LabBookingStatusId"" = 2 then T.""StatusDate"" end) as ""CancelAt"",
             SC.""CollectionDate"" as ""CollectedAt"",
           -- max(case when T.""LabBookingStatusId"" = 3 then T.""StatusDate"" end) as ""CollectedAt"",
            max(case when T.""LabBookingStatusId"" = 4  then T.""StatusDate"" end) as ""TransferedAt"",
            max(case when T.""LabBookingStatusId"" = 5 then T.""StatusDate"" end) as ""ReceivedAt"",
            max(case when T.""LabBookingStatusId"" = 12 then T.""StatusDate"" end) as ""SampleAccecptedAt"",--Accecpt/reject
            max(case when T.""LabBookingStatusId"" = 13 then T.""StatusDate"" end) as ""SampleRejectedAt"",--Accecpt/reject
            max(case when T.""LabBookingStatusId"" = 6 then T.""StatusDate"" end) as ""ParameterAddedAt"",
            max(case when T.""LabBookingStatusId"" = 18 then T.""StatusDate"" end) as ""TechnicianVerifiedAt"",
            max(case when T.""LabBookingStatusId"" = 8 then T.""StatusDate"" end) as ""DoctorAssignedAt"",
            max(case when T.""LabBookingStatusId"" = 7 then T.""StatusDate"" end) as ""VerifiedAt""

         from ""NewLabBookingHeader"" nlbh
         join ""NewLabBookingDetail"" LD on nlbh.""NewLabBookingHeaderId""=LD.""NewLabBookingHeaderId"" 
         join ""LabMainDetail"" LN on LN.""LabMainDetailId"" = LD.""LabMainDetailId""
         
         join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy""         
         join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
          left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
          left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
          left join ""Department"" PD on PD.""DepartmentId""=prv.""DepartmentId""
          
            left join statusDate T on T.""NewLabBookingDetailId""=LD.""NewLabBookingDetailId"" --and T.""LabBookingStatusId""=LD.""LabBookingStatusId""
             left join ""LabSampleCollection"" SC on SC.""NewLabBookingDetailId""=LD.""NewLabBookingDetailId""         
            left join ""LabBookingStatus"" LS on LS.""LabBookingStatusId"" = T.""LabBookingStatusId""
            join ""LabBookingStatus"" LDS on LDS.""LabBookingStatusId"" = LD.""LabBookingStatusId""	
            {where}
                group by  LD.""NewLabBookingDetailId"",
                nlbh.""NewLabBookingHeaderId"", nlbh.""RequisitionNumber"", nlbh.""PatientId"",  
                nlbh.""LocationId"",LDS.""Status"",LN.""TestName""
                ,nlbh.""PatientName"", p.""FullName"",p.""Mobile"", nlbh.""Mobile"", nlbh.""DoctorName"", prv.""FullName"",p.""UMRNo"",
                p.""Gender"",p.""Age"",p.""DateOfBirth"",
                ""LocationName"",PD.""DepartmentName"",SC.""CollectionDate""
            order by nlbh.""NewLabBookingHeaderId"" desc";

            return await this.unitOfWork.Current.QueryAsync<LabTATReportModel>(query);
        }

        /// <summary>
        /// Fetches the appointment mobile labs asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<IEnumerable<ApointmentLabsMobileModel>> FetchAppointmentMobileLabsAsync(ApointmentLabsMobileModel model)
        {
            var query = $@"select nlbd.""NewLabBookingDetailId"",nlbd.""NewLabBookingHeaderId"",lmd.""TestName"",lmd.""TestCode"",
                           lbs.""Status"",nlbh.""AppointmentId"",nlbh.""CreatedDate"",nlbh.""PatientId"" ,pat.""FullName"" as ""PatientName"" 
                           from ""NewLabBookingHeader"" nlbh
                           join ""NewLabBookingDetail"" nlbd on nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId""
                           join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
                           join ""LabBookingStatus"" lbs on lbs.""LabBookingStatusId"" = nlbd.""LabBookingStatusId""
                           join ""Patient"" pat on pat.""PatientId"" = nlbh.""PatientId""
                           where nlbh.""AppointmentId"" = {model.AppointmentId}";


            return await this.unitOfWork.Current.QueryAsync<ApointmentLabsMobileModel>(query);
        }

        /// <summary>
        /// Fetches the external lab agency asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<IEnumerable<ExternalLabAgencyModel>> FetchExternalLabAgencyAsync(ExternalLabAgencyModel model)
        {
            var where = "where 1=1";
            if (model.AgencyName != null && !model.AgencyName.Equals(""))
            {
                where += $@" AND ELA.""AgencyName"" ILike '%{model.AgencyName}%' ";
            }
            if (model.Active != null)
            {
                where += $@"AND ELA.""Active"" = {model.Active}";
            }
            var query = $@"SELECT count(ELA.""ExternalLabAgencyId"") over() ""TotalItems"", ELA.""ExternalLabAgencyId"", ELA.""AgencyName"", ELA.""Active"", ELA.""CreatedBy"", ELA.""AgencyCode"", ELA.""URL"", ELA.""Address"",
		                    ELA.""CreatedDate"", ELA.""ModifiedBy"", ELA.""ModifiedDate"",
		                    CR.""FullName"" as ""CreatedByName"",MR.""FullName"" as ""ModifiedByName""
	                    FROM ""ExternalLabAgency"" ELA
	                    join ""Account"" CR on CR.""AccountId"" = ELA.""CreatedBy""
	                    left join ""Account"" MR on MR.""AccountId"" = ELA.""ModifiedBy""
                        {where}
	                    order by ELA.""ExternalLabAgencyId"" desc";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageSize * model.PageIndex}";
            }


            return await this.unitOfWork.Current.QueryAsync<ExternalLabAgencyModel>(query);
        }

        /// <summary>
        /// Fetches the external lab agency details asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<ExternalLabAgencyModel> FetchExternalLabAgencyDetailsAsync(ExternalLabAgencyModel model)
        {
            var where = "where 1=1";
            if (model.ExternalLabAgencyId > 0)
            {
                where += $@"AND ELA.""ExternalLabAgencyId"" = {model.ExternalLabAgencyId}";
            }
            var query = $@"SELECT count(ELA.""ExternalLabAgencyId"") over() ""TotalItems"", ELA.""ExternalLabAgencyId"", ELA.""AgencyName"", ELA.""Active"", ELA.""CreatedBy"", ELA.""AgencyCode"", ELA.""URL"", ELA.""Address"",
		                    ELA.""CreatedDate"", ELA.""ModifiedBy"", ELA.""ModifiedDate"",
		                    CR.""FullName"" as ""CreatedByName"",MR.""FullName"" as ""ModifiedByName""
	                    FROM ""ExternalLabAgency"" ELA
	                    join ""Account"" CR on CR.""AccountId"" = ELA.""CreatedBy""
	                    left join ""Account"" MR on MR.""AccountId"" = ELA.""ModifiedBy""
                        {where}
	                    order by ELA.""ExternalLabAgencyId"" desc";

            var headerResponse = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ExternalLabAgencyModel>(query);
            var subquery = $@"SELECT count(ELA.""ExternalLabAgencyId"") over() ""TotalItems"",ELAD.""ExternalLabAgencyDetailId"", ELAD.""ExternalLabAgencyId"", ELAD.""LabMainDetailId"", ELAD.""Active"", ELAD.""CreatedBy"", ELAD.""LocationId"", ELAD.""Amount"",
		                    ELAD.""CreatedDate"", ELAD.""ModifiedBy"", ELAD.""ModifiedDate"",LMD.""TestName"",
		                    CR.""FullName"" as ""CreatedByName"",MR.""FullName"" as ""ModifiedByName""
	                    FROM ""ExternalLabAgencyDetail"" ELAD
                        join ""LabMainDetail"" LMD on LMD.""LabMainDetailId"" = ELAD.""LabMainDetailId""
                        join ""ExternalLabAgency"" ELA on ELA.""ExternalLabAgencyId"" = ELAD.""ExternalLabAgencyId""
	                    join ""Account"" CR on CR.""AccountId"" = ELA.""CreatedBy""
	                    left join ""Account"" MR on MR.""AccountId"" = ELA.""ModifiedBy""
                        where 1=1 and ELAD.""ExternalLabAgencyId"" = {model.ExternalLabAgencyId} AND ELAD.""LocationId"" = {model.LocationId}
	                    order by ELAD.""ExternalLabAgencyDetailId"" ";
            headerResponse.Labs = (await this.unitOfWork.Current.QueryAsync<ExternalLabAgencyDetailModel>(subquery)).ToList();

            return headerResponse;
        }

        /// <summary>
        /// Activates the or deactivate machine.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<int> ActivateOrDeactivateExternalLabAgency(ExternalLabAgencyModel model)
        {
            var query = $@"UPDATE ""ExternalLabAgency""
	                           SET ""ModifiedBy""={model.CreatedBy}, ""ModifiedDate""=now(), ""Active""= {model.Active}
	                           WHERE ""ExternalLabAgencyId""= {model.ExternalLabAgencyId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

        /// <summary>
        /// Activates the or deactivate external lab agency detail.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<int> ActivateOrDeactivateExternalLabAgencyDetail(ExternalLabAgencyDetailModel model)
        {
            var query = $@"UPDATE ""ExternalLabAgencyDetail""
	                           SET ""ModifiedBy""={model.CreatedBy}, ""ModifiedDate""=now(), ""Active""= {model.Active}
	                           WHERE ""ExternalLabAgencyDetailId""= {model.ExternalLabAgencyDetailId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

        /// <inheritdoc/>
        public async Task<int> ModifyExternalLabAgency(ExternalLabAgencyModel model)
        {

            var checkIfQuery = $@"SELECT count(""ExternalLabAgencyId"")	FROM ""ExternalLabAgency"" where lower(""AgencyName"") = '{model.AgencyName.ToLower()}'";

            if (model.ExternalLabAgencyId == 0)
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    return -1;
                }

                var Agency = new ExternalLabAgency
                {
                    //ExternalLabAgencyId = model.ExternalLabAgencyId,
                    Active = true,
                    CreatedBy = model.CreatedBy,
                    CreatedDate = DateTime.Now,
                    AgencyName = model.AgencyName,
                    AgencyCode = model.AgencyCode,
                    Address = model.Address,
                    URL = model.URL
                };

                return await this.unitOfWork.ExternalLabAgency.InsertAsync(Agency);
            }
            else
            {
                checkIfQuery += $@" and ""ExternalLabAgencyId"" <> {model.ExternalLabAgencyId} ";
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    return -2;
                }

                var oldRecord = await this.unitOfWork.ExternalLabAgency.FindAsync(d => d.ExternalLabAgencyId == model.ExternalLabAgencyId);
                if (oldRecord == null)
                {
                    return -3;
                }

                oldRecord.AgencyName = model.AgencyName;
                oldRecord.AgencyCode = model.AgencyCode;
                oldRecord.Address = model.Address;
                oldRecord.URL = model.URL;
                oldRecord.ModifiedBy = model.CreatedBy;
                oldRecord.ModifiedDate = DateTime.Now;

                return await this.unitOfWork.ExternalLabAgency.UpdateAsync(oldRecord);
            }

        }

        /// <summary>
        /// Modifies the external lab agency detail.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<int> ModifyExternalLabAgencyDetail(List<ExternalLabAgencyDetailModel> model)
        {

            var NewRecords = new List<ExternalLabAgencyDetail>();
            var ExistingRecords = new List<ExternalLabAgencyDetail>();
            foreach (var AgencyDetail in model)
            {
                if (AgencyDetail.ExternalLabAgencyDetailId == 0)
                {
                    var ExternalLabAgencyDetail = new ExternalLabAgencyDetail
                    {
                        Active = true,
                        ExternalLabAgencyId = AgencyDetail.ExternalLabAgencyId,
                        LocationId = AgencyDetail.LocationId,
                        LabMainDetailId = AgencyDetail.LabMainDetailId,
                        Amount = AgencyDetail.Amount,
                        CreatedBy = AgencyDetail.CreatedBy,
                        CreatedDate = DateTime.Now
                    };
                    NewRecords.Add(ExternalLabAgencyDetail);
                }
                else
                {
                    var ExternalLabAgencyDetail = new ExternalLabAgencyDetail
                    {
                        ExternalLabAgencyDetailId = AgencyDetail.ExternalLabAgencyDetailId,
                        Active = true,
                        ExternalLabAgencyId = AgencyDetail.ExternalLabAgencyId,
                        LocationId = AgencyDetail.LocationId,
                        LabMainDetailId = AgencyDetail.LabMainDetailId,
                        Amount = AgencyDetail.Amount,
                        ModifiedBy = AgencyDetail.CreatedBy,
                        ModifiedDate = DateTime.Now
                    };
                    ExistingRecords.Add(ExternalLabAgencyDetail);
                }
            }
            int NewRecordsInsertCount = 0;
            bool ExistingRecordsUpdated;
            var transaction = this.unitOfWork.BeginTransaction();
            if (NewRecords.Count > 0)
            {
                NewRecordsInsertCount = await this.unitOfWork.ExternalLabAgencyDetails.BulkInsertAsync(NewRecords, transaction);
                if (NewRecordsInsertCount == 0)
                {
                    transaction.Rollback();
                    return -4;
                }
            }

            if (ExistingRecords.Count > 0)
            {
                ExistingRecordsUpdated = await this.unitOfWork.ExternalLabAgencyDetails.BulkUpdateAsync(ExistingRecords, transaction);
                if (!ExistingRecordsUpdated)
                {
                    transaction.Rollback();
                    return -5;
                }
            }

            transaction.Commit();
            return model.Count();
        }
        public async Task<IEnumerable<LabChargeCategoryChargeModel>> FetchLabWithChargeCategoryChargeAsync(LabChargeCategoryChargeModel model)
        {
            var where = "where 1=1";
            if (model.ModulesMasterId > 0)
            {
                where += $@" and cmc.""ModulesMasterId"" = {model.ModulesMasterId}";
            }
            if (model.ChargeModuleTemplateId > 0)
            {
                where += $@" and cmc.""ChargeModuleTemplateId"" = {model.ChargeModuleTemplateId}";
            }
            if (model.ChargeCategoryId > 0)
            {
                where += $@" and cmc.""ChargeCategoryId"" = {model.ChargeCategoryId}";
            }
            if (!string.IsNullOrEmpty(model.Term))
            {
                where += $@" and (lower(lmd.""TestName"") ilike '%{model.Term.ToLower()}%' or lower(lmd.""TestCode"") ilike '%{model.Term.ToLower()}%')";
            }
            var query = $@"SELECT cmd.""ChargeModuleDetailsId"", cmd.""ReferenceId"", cmd.""ChargeModuleCategoryId"", cmd.""Amount"", cmt.""LocationId"",
		                            cc.""ChargeCategoryName"" , cc.""Default"" ,cmc.""ChargeCategoryId"" , cmc.""ModulesMasterId"" , cmc.""ChargeModuleTemplateId"",
		                            mm.""ModuleName"" ,lmd.""LabMainDetailId"",lmd.""TestName"",lmd.""TestCode""
                                FROM ""ChargeModuleDetails"" cmd
	                            join ""ChargeModuleCategory"" cmc on cmc.""ChargeModuleCategoryId"" = cmd.""ChargeModuleCategoryId""
	                            join ""ChargeCategory"" cc on cc.""ChargeCategoryId"" = cmc.""ChargeCategoryId"" and cc.""Active"" =true
                                join ""ChargeModuleTemplate"" cmt on cmt.""ChargeModuleTemplateId"" = cmc.""ChargeModuleTemplateId"" and cmt.""IsInUse"" is true
                                join ""ModulesMaster"" mm on mm.""ModulesMasterId"" = cmc.""ModulesMasterId""
                                join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = cmd.""ReferenceId""
	                            {where}
	                            order by cmd.""ChargeModuleDetailsId"" asc";
            return await this.unitOfWork.Current.QueryAsync<LabChargeCategoryChargeModel>(query);
        }

        /// <summary>
        /// Fetches the sample collected asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<IEnumerable<NewLabSampleHandlerModel>> FetchSampleCollectedAsync(NewLabSampleHandlerModel model)
        {
            var where = "where 1=1";

            if (model.NewLabBookingHeaderId > 0)
            {
                where += $@" and nlbh.""NewLabBookingHeaderId"" = {model.NewLabBookingHeaderId} and lbs.""Status"" != 'Cancelled'";
            }

            if (model.LocationId != null && model.LocationId > 0)
            {
                where += $@"  and subL.""LocationId""='{model.LocationId}'";
            }

            if (!string.IsNullOrEmpty(model.FromDate))
            {
                where += $@" and nlbh.""CreatedDate""::date >= '{Convert.ToDateTime(model.FromDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" and nlbh.""CreatedDate""::date <= '{Convert.ToDateTime(model.ToDate):yyyy-MM-dd}'::date";
            }

            if (!string.IsNullOrEmpty(model.BookingType))
            {
                if (model.BookingType == "ip")
                {
                    where += $@" and nlbh.""AdmissionId"" is not null ";
                }
                else
                {
                    where += $@" and nlbh.""AdmissionId"" is null ";
                }

            }

            if (!string.IsNullOrEmpty(model.RequisitionNumber))
            {
                where += $@" and nlbh.""RequisitionNumber"" ilike '%{model.RequisitionNumber}%'";
            }

            if (!string.IsNullOrEmpty(model.DepartmentName))
            {
                where += $@" and (lower(ld.""DepartmentName"") ilike '%{model.DepartmentName.ToLower()}%')";
            }

            if (!string.IsNullOrEmpty(model.TestName))
            {
                where += $@" and (lower(lmd.""TestName"") ilike '%{model.TestName.ToLower()}%' or lower(lmd.""TestCode"") ilike '%{model.TestName.ToLower()}%')";
            }

            if (model.PatientId != null && model.PatientId > 0)
            {
                where += $@" and  nlbd.""PatientId"" = {model.PatientId}";
            }

            if (model.IsInternalLab)
            {
                where += $@" and lmd.""IsInternalLab"" is true";
            }

            var query = $@"SELECT count(nlbh.*) over () as ""TotalItems"",nlbh.""NewLabBookingHeaderId"", nlbh.""RequisitionNumber"", nlbh.""Type"", nlbh.""PatientId"", nlbh.""DoctorId"", nlbh.""EmployeeId"",
                                       nlbh.""LocationId"", nlbh.""OverallTotalAmount"", nlbh.""OverallDiscount"", nlbh.""OverallNetAmount"", nlbh.""OverallDiscountPercentage"", nlbh.""PayTypeId"",
                                    nlbh.""PaymentNumber"", nlbh.""CreatedBy"", nlbh.""CreatedDate"", nlbh.""ModifiedBy"", nlbh.""ModifiedDate"", nlbh.""Active""  ,
                                    c.""FullName"" as ""CreatedByName"",m.""FullName"" as ""ModifiedByName"",COALESCE (CONCAT(p.""Salutation"",' ',p.""FullName"") ,CONCAT(p.""Salutation"",' ',nlbh.""PatientName"") ) as ""PatientName"",
                                    COALESCE (p.""Mobile"" ,nlbh.""Mobile"" ) as ""Mobile"", COALESCE (nlbh.""DoctorName"" , prv.""FullName"" ) as ""DoctorName"",
                                    (CASE WHEN p.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('{this.runningEnvironment.CurrentEnvironment}/', p.""Guid"", '/', p.""ThumbnailUrl"") ELSE '' END) AS ""PatientThumbnailUrl"",
                                    e.""FullName"" as ""EmployeeName"",pt.""PayTypeName"" ,l.""Name"" as ""LocationName"",p.""UMRNo"",p.""Gender"",p.""Age"",CASE WHEN nlbh.""AdmissionId"" is not null THEN 'IP' else 'OP' END ""BookingType"",
                                    nlbd.""NewLabBookingDetailId"", nlbd.""LabMainDetailId"", nlbd.""ChargeCategoryId"", nlbd.""LabBookingStatusId"", nlbd.""DiscountPercentage"",
		                            nlbd.""DiscountAmount"", nlbd.""TotalAmount"", nlbd.""NetAmount"", lbs.""Status"",
		                            lmd.""TestName"",lmd.""TestCode"", lmd.""IsExternalLab"", lmd.""IsInternalLab"" , ld.""DepartmentName"" ,cc.""ChargeCategoryName"" ,lst.""TypeName"",
		                            lsc.""LabSampleCollectionId"" ,lsc.""SampleCollectedBy"" ,lsc.""CollectionDate"" ,lsc.""IsBarcodeGenerated"" ,lbs.""RowColor"",
		                            lsc.""BarcodeGeneratedBy"" , lsc.""BarcodeDate"" , sc.""FullName""  as ""SampleCollectedByName"",lmd.""SampleUsage"",lmd.""ConsentFormRequired"",nlbd.""Emergency"",
		                            bc.""FullName"" as ""BarcodeGeneratedByName"",lscd.""Comment"",lv.""LabVacutainerName"", CASE WHEN nlbh.""AdmissionId"" is not null THEN 'IP' else 'OP' END ""BookingType""
                                    ,lscd.""LabSampleCollectionDetailId"", lscd.""SubSampleCollectedBy"", lscd.""SubCollectionDate"",
                                    lscd.""SubIsBarcodeGenerated"", lscd.""SubBarcodeGeneratedBy"", lscd.""SubBarcodeDate"", lscd.""LocationId"", lscd.""SampleName"",
                                    subC.""FullName"" as ""SubSampleCollectedByName"", subB.""FullName"" as ""SubBarcodeGeneratedByName"", subL.""Name"" as ""SubSampleCollectionLocation"",
                                    LMD.""NoOfSamplesCollect"" ,LMD.""NoOfSamplesCollectText"" , lbsd.""Status"" as ""SubStatus"",ltd.""LabTransferDetailId""
                                    FROM ""NewLabBookingHeader"" nlbh
                                   join ""NewLabBookingDetail"" nlbd on nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId""
                                   join ""Account"" c on c.""AccountId"" = nlbh.""CreatedBy""
                                   left join ""PayType"" pt ON pt.""PayTypeId"" = nlbh.""PayTypeId""
                                   join ""Location"" l ON l.""LocationId"" = nlbh.""LocationId""
                                   join ""LabBookingStatus"" lbs ON lbs.""LabBookingStatusId"" = nlbd .""LabBookingStatusId""
		                           join ""LabMainDetail"" lmd ON lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
		                           join ""LabDepartment"" ld on ld.""LabDepartmentId"" = lmd.""LabDepartmentId""
		                           join ""ChargeCategory"" cc on cc.""ChargeCategoryId"" = nlbd.""ChargeCategoryId""
		                           left join ""LabSampleType"" lst on lst.""LabSampleTypeId"" = lmd.""LabSampleTypeId""
                                   left join ""LabVacutainer"" lv on lv.""LabVacutainerId"" = lmd.""LabVacutainerId""
	                               left join ""Account"" m on m.""AccountId"" = nlbh.""ModifiedBy""
	                               left join ""Patient"" p ON p.""PatientId"" =nlbh.""PatientId""
	                               left join ""Provider"" prv on prv.""ProviderId"" = nlbh.""DoctorId""
	                               left join ""Account"" e on e.""AccountId"" = nlbh.""EmployeeId""
                                   join ""LabSampleCollection"" lsc on lsc.""NewLabBookingDetailId"" = nlbd.""NewLabBookingDetailId""
                                   join ""Account"" sc on sc.""AccountId"" = lsc.""SampleCollectedBy""
                                   join ""Account"" bc on bc.""AccountId"" = lsc.""BarcodeGeneratedBy""
                                   join ""LabSampleCollectionDetail"" lscd on lscd.""LabSampleCollectionId"" = lsc.""LabSampleCollectionId""
                                   join ""LabBookingStatus"" lbsd ON lbsd.""LabBookingStatusId"" = lscd.""LabBookingStatusId""
                                   join ""Account"" subC on subC.""AccountId"" = lscd.""SubSampleCollectedBy""
                                   join ""Account"" subB ON subB.""AccountId"" = lscd.""SubBarcodeGeneratedBy""
                                   join ""Location"" subL on subL.""LocationId"" = lscd.""LocationId""
                                   left join ""LabTransferDetail"" ltd on ltd.""LabSampleCollectionDetailId"" = lscd.""LabSampleCollectionDetailId""
                                   {where}
	                               order by nlbh.""CreatedDate"" desc";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }

            return await this.unitOfWork.Current.QueryAsync<NewLabSampleHandlerModel>(query);
        }

        public async Task<int> UnCollectSamplesAsync(List<LabSampleHandlerModel> model, int locationId)
        {
            if (model.Count == 0)
            {
                return -1;
            }
            var transaction = this.unitOfWork.BeginTransaction();
            var getStatusPending = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "Pending");
            if (getStatusPending == null)
            {
                return -2;
            }
            string abc = string.Join(",", model.Select(l => l.LabSampleCollectionDetailId));
            var query = $@"select * from ""LabSampleCollectionDetail"" where ""LabSampleCollectionDetailId"" in ({abc}) ";
            var SelectedSamples = await this.unitOfWork.Current.QueryAsync<LabSampleCollectionDetail>(query);
            var SelectedSamplesList = SelectedSamples.ToList();
            for (int i = 0; i < SelectedSamplesList.Count; i++)
            {
                SelectedSamplesList[i].SubSampleCollectedBy = null;
                SelectedSamplesList[i].SubCollectionDate = null;
                SelectedSamplesList[i].SubIsBarcodeGenerated = false;
                SelectedSamplesList[i].SubBarcodeGeneratedBy = null;
                SelectedSamplesList[i].SubBarcodeDate = null;
                SelectedSamplesList[i].LocationId = null;
                SelectedSamplesList[i].LabBookingStatusId = getStatusPending.LabBookingStatusId;
                SelectedSamplesList[i].UncollectComment = model[0].UncollectComment;
            }
            var result = await this.unitOfWork.LabSampleCollectionDetails.BulkUpdateAsync(SelectedSamples, transaction);
            if (!result)
            {
                transaction.Rollback();
                return -3;
            }
            var UncollectedSampleStatus = await this.unitOfWork.LabBookingStatus.FindAsync(x => x.Status == "SampleUncollected");
            var TimeLines = new List<LabBookingTimeLine>();
            var LabLogs = new List<LabLog>();
            foreach (var test in model)
            {
                var timeline = new LabBookingTimeLine
                {
                    Comment = $@"Sample Uncollected Succesfully for Test - {test.TestName} .",
                    CommentedBy = test.CreatedBy,
                    CreatedDate = DateTime.Now,
                    LabBookingStatusId = UncollectedSampleStatus.LabBookingStatusId,
                    NewLabBookingHeaderId = test.NewLabBookingHeaderId
                };
                TimeLines.Add(timeline);
                var labLog = new LabLog
                {
                    AccountId = test.CreatedBy,
                    LabLogTypeId = (int)LabLogTypes.Lab_Sample_Uncollection,
                    LogFrom = (short)test.RoleId,
                    LogDate = DateTime.UtcNow,
                    LocationId = locationId,
                    LogDescription = $@"'{test.CreatedByName}' has uncollected sample of '{test.TestName}' for '{test.RequisitionNumber}' '"
                };
                LabLogs.Add(labLog);
            }
            var TimelineInsertCount = await this.unitOfWork.LabBookingTimeLines.BulkInsertAsync(TimeLines, transaction);
            if (TimelineInsertCount == 0)
            {
                transaction.Rollback();
                return -4;
            }
            var LabLogInsertCount = await this.unitOfWork.LabLogs.BulkInsertAsync(LabLogs, transaction);
            if (LabLogInsertCount == 0)
            {
                transaction.Rollback();
                return -5;
            }
            transaction.Commit();
            return 1;
        }

        /// <summary>
        /// Gets all sample uncollect reasons.
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<string>> GetAllSampleUncollectReasons()
        {

            var query = $@"SELECT  L.""Name"" 
	                            FROM ""LookupValue"" L
                             
                               where  ""LookupId"" = (Select ""LookupId"" from ""Lookup"" where ""Name"" = 'LabSampleUncollect')";

            return await this.unitOfWork.Current.QueryAsync<string>(query);
        }

        /// <summary>
        /// Gets all sample reject reasons.
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<string>> GetAllSampleRejectReasons()
        {

            var query = $@"SELECT  L.""Name"" 
	                            FROM ""LookupValue"" L
                             
                               where  ""LookupId"" = (Select ""LookupId"" from ""Lookup"" where ""Name"" = 'LabSampleReject')";

            return await this.unitOfWork.Current.QueryAsync<string>(query);
        }

        /// <summary>
        /// Checks the lab is tagged or not asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        public async Task<bool> CheckLabIsTaggedOrNotAsync(ExternalLabAgencyDetailModel model)
        {

            var Exists = (await this.unitOfWork.ExternalLabAgencyDetails.FindAllAsync(i => i.LocationId == model.LocationId && i.LabMainDetailId == model.LabMainDetailId && i.Active == true)).ToList();
            if (Exists.Count > 0)
            {
                return true;
            }
            return false;

        }

        public async Task<IEnumerable<LISParamsFetchUserModel>> FetchTestParamsForLISAsync(int NewLabBookingDetailId)
        {

            var query = $@"select nlbd.""NewLabBookingDetailId"",lmdt.""LabTemplateHeaderId"",lch.""LabComponentHeaderId"",lph.""LabParameterHeaderId"",
                                lph.""ParameterName"", lph.""DisplayName"",lph.""MachineId"",lph.""MachineParameterName""
                                from ""NewLabBookingDetail"" nlbd
                                join ""LabMainDetail"" lmd on  lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
                                join ""LabMainDetailTemplate"" lmdt on lmdt.""LabMainDetailId"" = lmd.""LabMainDetailId"" --order by lmdt.""Priority""
                                join ""LabTemplateHeader"" lth on lth.""LabTemplateHeaderId"" = lmdt.""LabTemplateHeaderId""

                                join ""LabTemplateDetail"" ltd on ltd.""LabTemplateHeaderId"" = lth.""LabTemplateHeaderId"" --order by ""Priority""
                                join ""LabComponentHeader"" lch on lch.""LabComponentHeaderId"" = ltd.""LabComponentHeaderId"" --order by ""Priority""
                                join ""LabComponentDetail"" lcd on lcd.""LabComponentHeaderId"" = lch.""LabComponentHeaderId"" --order by ""Priority""
                                join ""LabParameterHeader"" lph on lph.""LabParameterHeaderId"" = lcd.""LabParameterHeaderId""
                                where ""NewLabBookingDetailId"" = {NewLabBookingDetailId}
                                union  all
                                select nlbd.""NewLabBookingDetailId"",lmdt.""LabTemplateHeaderId"",null as ""LabComponentHeaderId"",lph.""LabParameterHeaderId"",
                                lph.""ParameterName"", lph.""DisplayName"",lph.""MachineId"",lph.""MachineParameterName""
                                from ""NewLabBookingDetail"" nlbd
                                join ""LabMainDetail"" lmd on  lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
                                join ""LabMainDetailTemplate"" lmdt on lmdt.""LabMainDetailId"" = lmd.""LabMainDetailId"" --order by ""Priority""
                                join ""LabTemplateHeader"" lth on lth.""LabTemplateHeaderId"" = lmdt.""LabTemplateHeaderId""
                                join ""LabTemplateDetail"" ltd on ltd.""LabTemplateHeaderId"" = lth.""LabTemplateHeaderId"" --order by ""Priority""
                                join ""LabParameterHeader"" lph on lph.""LabParameterHeaderId"" = ltd.""LabParameterHeaderId""
                                where ""NewLabBookingDetailId"" = {NewLabBookingDetailId}; ";
            return await this.unitOfWork.Current.QueryAsync<LISParamsFetchUserModel>(query);
        }


        public async Task<int> InsertTestParamsOfLISAsync(List<LISParamsFetchUserModel> model)
        {
            var LISAccount = await this.unitOfWork.Accounts.FindAsync(x => x.UserName == "LIS");
            if (LISAccount == null)
            {
                return -1;
            }
            var transaction = this.unitOfWork.BeginTransaction();
            foreach (var lab in model)
            {
                var parameter = new LabParameterObservedValue
                {
                    CreatedBy = LISAccount.CreatedBy,
                    CreatedDate = DateTime.Now,
                    Active = true,
                    LabComponentHeaderId = lab.LabComponentHeaderId,
                    LabParameterHeaderId = lab.LabParameterHeaderId,
                    LabTemplateHeaderId = lab.LabTemplateHeaderId,
                    NewLabBookingDetailId = lab.NewLabBookingDetailId,
                    ObservedValue = lab.LabParameterObservedValue
                };
                var res = await this.unitOfWork.LabParameterObservedValues.InsertAsync(parameter, transaction);
                if (res == 0)
                {
                    transaction.Rollback();
                    return -2;
                }

            }
            transaction.Commit();
            return 1;
        }

    }

}
