namespace Hims.Infrastructure.Services
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Dapper;
    using Domain.Entities.ChargeModules;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Hims.Domain.Entities;
    using Shared.UserModels.ChargeModule;

    public class ChargeModuleServices : IChargeModuleService
    {
        private readonly IUnitOfWork unitOfWork;

        public ChargeModuleServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        #region Charge Templates

        public async Task<IEnumerable<ChargeModuleTemplateModel>> FetchChargeTemplatesAsync(ChargeTemplateFilterModel model)
        {
            var where = @"WHERE 1 = 1 AND cmt.""Active"" IS TRUE";
            if (!string.IsNullOrEmpty(model.TemplateName))
            {
                where += $@" AND LOWER(cmt.""TemplateName"") ILIKE '%{model.TemplateName.ToLower()}%'";
            }

            if (model.LocationId > 0)
            {
                where += $@" AND cmt.""LocationId"" = {model.LocationId}";
            }

            if (model.Status != null)
            {
                where += $@" AND cmt.""IsInUse"" = {(bool)model.Status}";
            }

            var query = $@"SELECT COUNT(*) OVER () AS ""TotalItems"", cmt.""ChargeModuleTemplateId"", cmt.""StartDate"", cmt.""EndDate"", cmt.""Active"", cmt.""TemplateName"",
		                cmt.""IsInUse"", cmt.""LocationId"", l.""Name"" AS ""LocationName"", a.""FullName"" AS ""CreatedByName"", m.""FullName"" AS ""ModifiedByName"",
                        cmt.""CreatedBy"", cmt.""CreatedDate"", cmt.""ModifiedBy"", cmt.""ModifiedDate""
		                FROM ""ChargeModuleTemplate"" cmt
		                JOIN ""Location"" l ON l.""LocationId""= cmt.""LocationId"" AND l.""Active"" IS TRUE
		                JOIN ""Account"" a ON a.""AccountId"" = cmt.""CreatedBy"" AND a.""Active"" IS TRUE
		                LEFT JOIN ""Account"" m ON m.""AccountId"" = cmt.""ModifiedBy"" AND m.""Active"" IS TRUE
		                {where}
		                ORDER BY cmt.""IsInUse"" DESC, cmt.""CreatedDate"" DESC";

            if (model.IsPaginationEnabled)
            {
                model.PageIndex -= 1;
                query += " LIMIT " + model.PageSize + " OFFSET " + (model.PageIndex * model.PageSize);
            }

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

        public async Task<int> ModifyChargeTemplateAsync(ChargeModuleTemplateModel model)
        {
            var checkIfQuery = $@"SELECT COUNT(*) FROM ""ChargeModuleTemplate"" WHERE LOWER(""TemplateName"") = LOWER('{model.TemplateName.Trim()}') AND ""LocationId"" = {model.LocationId}";
            if (model.ChargeModuleTemplateId == 0)
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                    return -1;

                var template = new ChargeModuleTemplate
                {
                    Active = true,
                    CreatedBy = model.CreatedBy,
                    CreatedDate = DateTime.UtcNow.AddMinutes(330),
                    StartDate = model.StartDate,
                    EndDate = model.EndDate,
                    LocationId = model.LocationId,
                    TemplateName = model.TemplateName.Trim()
                };

                return await this.unitOfWork.ChargeModuleTemplates.InsertAsync(template);
            }
            else
            {
                checkIfQuery += $@" AND ""ChargeModuleTemplateId"" <> {model.ChargeModuleTemplateId} ";
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                    return -1;

                var findOldOne = await this.unitOfWork.ChargeModuleTemplates.FindAsync(p => p.ChargeModuleTemplateId == model.ChargeModuleTemplateId);
                if (findOldOne == null)
                    return -2;

                findOldOne.StartDate = model.StartDate;
                findOldOne.EndDate = model.EndDate;
                findOldOne.TemplateName = model.TemplateName;
                findOldOne.ModifiedDate = DateTime.UtcNow.AddMinutes(330);
                findOldOne.ModifiedBy = model.CreatedBy;

                return await this.unitOfWork.ChargeModuleTemplates.UpdateAsync(findOldOne);
            }
        }

        public async Task<bool> SetInUseChargeTemplateAsync(ChargeModuleTemplateModel model)
        {
            var query = $@"UPDATE ""ChargeModuleTemplate"" SET ""IsInUse"" = FALSE WHERE ""LocationId"" = {model.LocationId};
                           UPDATE ""ChargeModuleTemplate"" SET ""IsInUse"" = TRUE WHERE ""ChargeModuleTemplateId"" = {model.ChargeModuleTemplateId}";
            return await this.unitOfWork.Current.ExecuteAsync(query) > 0;
        }

        #endregion

        public async Task<int> ModifyChargeAsync(ChargeModuleInsertionModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();

            foreach (var charge in model.Charges)
            {
                if (charge.ChargeModuleDetailsId != null && charge.ChargeModuleDetailsId != 0)
                {
                    var getOldCharge = await this.unitOfWork.ChargeModuleDetails.FindAsync(c => c.ChargeModuleDetailsId == charge.ChargeModuleDetailsId);
                    if (getOldCharge == null)
                    {
                        transaction.Rollback();
                        return -3;
                    }

                    getOldCharge.Amount = Math.Round(charge.Amount, 2);
                    getOldCharge.ModifiedBy = model.CreatedBy;
                    getOldCharge.ModifiedDate = DateTime.UtcNow.AddMinutes(330);

                    var updateCharge = await this.unitOfWork.ChargeModuleDetails.UpdateAsync(getOldCharge, transaction);
                    if (updateCharge == 0)
                    {
                        transaction.Rollback();
                        return -4;
                    }
                }
                else
                {
                    var checkChargeExists = await this.unitOfWork.ChargeModuleCategorys.FindAsync(c => c.ChargeCategoryId == charge.ChargeCategoryId && c.ModulesMasterId == model.ModulesMasterId && c.ChargeModuleTemplateId == model.ChargeModuleTemplateId);
                    if (checkChargeExists == null)
                    {
                        checkChargeExists = new ChargeModuleCategory
                        {
                            Active = true,
                            ChargeCategoryId = charge.ChargeCategoryId,
                            ChargeModuleTemplateId = model.ChargeModuleTemplateId,
                            ModulesMasterId = model.ModulesMasterId,
                            CreatedBy = model.CreatedBy,
                            CreatedDate = DateTime.UtcNow.AddMinutes(330)
                        };

                        checkChargeExists.ChargeModuleCategoryId = await this.unitOfWork.ChargeModuleCategorys.InsertAsync(checkChargeExists, transaction);
                        if (checkChargeExists.ChargeModuleCategoryId == 0)
                        {
                            transaction.Rollback();
                            return -1;
                        }
                    }

                    var chargeModuleDetail = new ChargeModuleDetails
                    {
                        Amount = Math.Round(charge.Amount, 2),
                        ChargeModuleCategoryId = checkChargeExists.ChargeModuleCategoryId,
                        CreatedBy = model.CreatedBy,
                        CreatedDate = DateTime.UtcNow.AddMinutes(330),
                        LocationId = model.LocationId,
                        ReferenceId = charge.ReferenceId
                    };

                    chargeModuleDetail.ChargeModuleDetailsId = await this.unitOfWork.ChargeModuleDetails.InsertAsync(chargeModuleDetail, transaction);
                    if (chargeModuleDetail.ChargeModuleDetailsId == 0)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                }
            }

            transaction.Commit();
            return 1;
        }

        public async Task<IEnumerable<ChargeModuleDetailsModel>> FetchGivenChargesAsync(ChargeModuleDetailsModel model)
        {
            var where = "where 1=1";
            if (model.LocationId > 0)
            {
                where += $@" and cmt.""LocationId"" = {model.LocationId}";
            }
            if (model.ChargeModuleCategoryId != null)
            {
                where += $@" and cmd.""ChargeModuleCategoryId"" = {model.ChargeModuleCategoryId}";
            }

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

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

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

            if (!string.IsNullOrEmpty(model.ReferenceIds))
            {
                where += $@" and cmd.""ReferenceId"" in ({model.ReferenceIds})";
            }

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

            var query = $@"SELECT cmd.""ChargeModuleDetailsId"", cmd.""ReferenceId"", cmd.""ChargeModuleCategoryId"", cmd.""Amount"", cmt.""LocationId"", cmd.""CreatedBy"", cmd.""CreatedDate"", cmd.""ModifiedBy"", cmd.""ModifiedDate"",
		                            cc.""ChargeCategoryName"" , cc.""Default"" ,cmc.""ChargeCategoryId"" , cmc.""ModulesMasterId"" , cmc.""ChargeModuleTemplateId"",
		                            mm.""ModuleName"" ,c.""FullName"" as ""CreatedByName"", m.""FullName"" as ""ModifiedByName""
	                            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 ""Account"" c ON c.""AccountId"" = cmd.""CreatedBy""
	                            left join ""Account"" m on m.""AccountId"" = cmd.""ModifiedBy""
	                            {where}
	                            order by cmd.""ChargeModuleDetailsId"" asc";
            return await this.unitOfWork.Current.QueryAsync<ChargeModuleDetailsModel>(query);
        }

        public async Task<int> DeleteChargeAsync(int chargeModuleDetailsId)
        {
            var query = $@"DELETE FROM ""ChargeModuleDetails"" WHERE ""ChargeModuleDetailsId""= {chargeModuleDetailsId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

        public async Task<ChargeModuleDetailsModel> GetRequiredDetailForChargeFetchAsync(string moduleName, int locationId)
        {
            var returnModel = new ChargeModuleDetailsModel();
            var activeTemplate = await this.unitOfWork.ChargeModuleTemplates.FindAsync(t => t.LocationId == locationId && t.IsInUse);
            if (activeTemplate == null)
            {
                return null;
            }

            returnModel.ChargeModuleTemplateId = activeTemplate.ChargeModuleTemplateId;

            var moduleId = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(
                $@"select mm.""ModulesMasterId""  from ""ModulesMaster"" mm where lower(mm.""ModuleName"") = '{moduleName}'");
            if (moduleId == 0)
            {
                return null;
            }

            returnModel.ModulesMasterId = moduleId;

            return returnModel;
        }

        public async Task<IEnumerable<DoctorSpecializationChargeModuleDetailsModel>> FetchDoctorSpecializationGivenChargesAsync(DoctorSpecializationChargeModuleDetailsModel model)
        {
            var where = "where 1=1";
            if (model.DoctorSpecializationChargeModuleCategoryId != null)
            {
                where += $@" and cmd.""DoctorSpecializationChargeModuleCategoryId"" = {model.DoctorSpecializationChargeModuleCategoryId}";
            }

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

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

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

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

            if (!string.IsNullOrEmpty(model.ReferenceIds))
            {
                where += $@" and cmd.""ReferenceId"" in ({model.ReferenceIds})";
            }
            if (model.ReferenceId != null)
            {
                where += $@" and cmd.""ReferenceId"" = {model.ReferenceId}";
            }

            var query = $@"SELECT cmd.""DoctorSpecializationChargeModuleDetailsId"",cmd.""ReferenceId"", cmd.""DoctorSpecializationChargeModuleCategoryId"", cmd.""Amount"", cmd.""LocationId"", cmd.""CreatedBy"", cmd.""CreatedDate"", cmd.""ModifiedBy"", cmd.""ModifiedDate"",
		                            cc.""ChargeName"" ,cmc.""ChargeTypesId"" , cmc.""ModulesMasterId"" , cmc.""ChargeModuleTemplateId"",
		                            mm.""ModuleName"" ,c.""FullName"" as ""CreatedByName"", m.""FullName"" as ""ModifiedByName""
	                            FROM ""DoctorSpecializationChargeModuleDetails"" cmd
	                            join ""DoctorSpecializationChargeModuleCategory"" cmc on cmc.""DoctorSpecializationChargeModuleCategoryId"" = cmd.""DoctorSpecializationChargeModuleCategoryId""
	                            join ""ChargeTypes"" cc on cc.""ChargeTypesId"" = cmc.""ChargeTypesId"" and cc.""Active"" = true
	                            join ""ModulesMaster"" mm on mm.""ModulesMasterId"" = cmc.""ModulesMasterId""
	                            join ""Account"" c ON c.""AccountId"" = cmd.""CreatedBy""
	                            left join ""Account"" m on m.""AccountId"" = cmd.""ModifiedBy""
	                            {where}
	                            order by cmd.""DoctorSpecializationChargeModuleDetailsId"" asc";
            return await this.unitOfWork.Current.QueryAsync<DoctorSpecializationChargeModuleDetailsModel>(query);
        }

        public async Task<int> ModifyDoctorSpecializationChargeAsync(DoctorSpecializationChargeModuleInsertionModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();
            var visitsandFollowups = await this.unitOfWork.DoctorSpecializationMaps.FindAsync(c => c.DoctorSpecializationMapId == model.ReferenceId);
            if (visitsandFollowups == null)
            {
                return -7;
            }
            visitsandFollowups.FollowUpDays = model.FollowUpDays;
            visitsandFollowups.FollowUpDaysLimit = model.FollowUpDaysLimit;
            var res = await this.unitOfWork.DoctorSpecializationMaps.UpdateAsync(visitsandFollowups, transaction);
            if (res == 0)
            {
                transaction.Rollback();
                return -8;
            }
            foreach (var charge in model.Charges)
            {
                if (charge.DoctorSpecializationChargeModuleDetailsId != null && charge.DoctorSpecializationChargeModuleDetailsId != 0)
                {
                    var getOldCharge = await this.unitOfWork.DoctorSpecializationChargeModuleDetails.FindAsync(c => c.DoctorSpecializationChargeModuleDetailsId == charge.DoctorSpecializationChargeModuleDetailsId);
                    if (getOldCharge == null)
                    {
                        transaction.Rollback();
                        return -3;
                    }

                    getOldCharge.Amount = Math.Round(charge.Amount, 2);
                    getOldCharge.ModifiedBy = model.CreatedBy;
                    getOldCharge.ModifiedDate = DateTime.UtcNow.AddMinutes(330);

                    var updateCharge = await this.unitOfWork.DoctorSpecializationChargeModuleDetails.UpdateAsync(getOldCharge, transaction);
                    if (updateCharge == 0)
                    {
                        transaction.Rollback();
                        return -4;
                    }
                }
                else
                {
                    var checkChargeExists = await this.unitOfWork.DoctorSpecializationChargeModuleCategorys.FindAsync(c => c.ChargeTypesId == charge.ChargeTypesId && c.ModulesMasterId == model.ModulesMasterId && c.ChargeModuleTemplateId == model.ChargeModuleTemplateId);
                    if (checkChargeExists == null)
                    {
                        checkChargeExists = new DoctorSpecializationChargeModuleCategory
                        {
                            Active = true,
                            ChargeTypesId = charge.ChargeTypesId,
                            ChargeModuleTemplateId = model.ChargeModuleTemplateId,
                            ModulesMasterId = model.ModulesMasterId,
                            CreatedBy = model.CreatedBy,
                            CreatedDate = DateTime.UtcNow.AddMinutes(330)
                        };

                        checkChargeExists.DoctorSpecializationChargeModuleCategoryId = await this.unitOfWork.DoctorSpecializationChargeModuleCategorys.InsertAsync(checkChargeExists, transaction);
                        if (checkChargeExists.DoctorSpecializationChargeModuleCategoryId == 0)
                        {
                            transaction.Rollback();
                            return -1;
                        }
                    }

                    var chargeModuleDetail = new DoctorSpecializationChargeModuleDetails
                    {
                        Amount = Math.Round(charge.Amount, 2),
                        DoctorSpecializationChargeModuleCategoryId = checkChargeExists.DoctorSpecializationChargeModuleCategoryId,
                        CreatedBy = model.CreatedBy,
                        CreatedDate = DateTime.UtcNow.AddMinutes(330),
                        LocationId = model.LocationId,
                        ReferenceId = model.ReferenceId
                    };

                    chargeModuleDetail.DoctorSpecializationChargeModuleDetailsId = await this.unitOfWork.DoctorSpecializationChargeModuleDetails.InsertAsync(chargeModuleDetail, transaction);
                    if (chargeModuleDetail.DoctorSpecializationChargeModuleDetailsId == 0)
                    {
                        transaction.Rollback();
                        return -2;
                    }
                }
            }

            transaction.Commit();
            return 1;
        }

        public async Task<int> DeleteDoctorSpecializationChargeAsync(int doctorSpecializationChargeModuleDetailsId)
        {
            var query = $@"DELETE FROM ""DoctorSpecializationChargeModuleDetails"" WHERE ""DoctorSpecializationChargeModuleDetailsId""= {doctorSpecializationChargeModuleDetailsId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

        public async Task<DoctorSpecializationMap> FetchOrCreateRefrenceId(DoctorSpecializationChargeModuleDetailsModel model)
        {
            var transaction = this.unitOfWork.BeginTransaction();
            var checkIfExists = await this.unitOfWork.DoctorSpecializationMaps.FindAsync(h => h.SpecializationId == model.SpecializationId && h.ConsultationTypeId == model.ConsultationTypeId && h.ProviderId == model.ProviderId && h.LocationId == model.LocationId);
            if (checkIfExists == null)
            {
                checkIfExists = new DoctorSpecializationMap
                {
                    SpecializationId = (int)model.SpecializationId,
                    ConsultationTypeId = (int)model.ConsultationTypeId,
                    ProviderId = model.ProviderId,
                    LocationId = (int)model.LocationId,
                    FollowUpDaysLimit = 0,
                    FollowUpDays = 0

                };
                checkIfExists.DoctorSpecializationMapId = await this.unitOfWork.DoctorSpecializationMaps.InsertAsync(checkIfExists, transaction);
                if (checkIfExists.DoctorSpecializationMapId == 0)
                {
                    transaction.Rollback();
                    return null;
                }
                transaction.Commit();
                return checkIfExists;
            }
            else
            {
                return checkIfExists;
            }
        }

        #region Update Location Charges

        public Task<IEnumerable<LocationChargePriceModel>> FetchLocationChargePricesAsync(int locationId, int chargeModuleTemplateId, int modulesMasterId, int chargeReferenceId)
        {
            var where = $@"WHERE cmd.""LocationId"" = {locationId} AND cmd.""ReferenceId"" = {chargeReferenceId} AND cmc.""ModulesMasterId"" = {modulesMasterId} AND cmc.""ChargeModuleTemplateId"" = {chargeModuleTemplateId}";
            var query = $@"SELECT cmd.""ChargeModuleCategoryId"", cmc.""ChargeCategoryId"", cc.""ChargeCategoryName"", cmd.""LocationId"", cmc.""ModulesMasterId"",
                            cmc.""ChargeModuleTemplateId"", cmd.""ChargeModuleDetailsId"", cmd.""ReferenceId"", cmd.""Amount"", ac.""FullName"" AS ""LastModifiedByName"",
                            COALESCE(cmd.""ModifiedBy"", cmd.""CreatedBy"") AS ""LastModifiedBy"", COALESCE(cmd.""ModifiedDate"", cmd.""CreatedDate"") AS ""LastModifiedDate""
                            FROM ""ChargeModuleDetails"" cmd
                            LEFT JOIN ""ChargeModuleCategory"" cmc ON cmc.""ChargeModuleCategoryId"" = cmd.""ChargeModuleCategoryId"" AND cmc.""Active"" IS TRUE
                            LEFT JOIN ""ChargeCategory"" cc ON cc.""ChargeCategoryId"" = cmc.""ChargeCategoryId"" AND cc.""Active"" IS TRUE
                            LEFT JOIN ""Account"" ac ON ac.""AccountId"" = COALESCE(cmd.""ModifiedBy"", cmd.""CreatedBy"") AND ac.""Active"" IS TRUE
                            {where}";
            return this.unitOfWork.Current.QueryAsync<LocationChargePriceModel>(query);
        }

        public async Task<bool> UpdateLocationChargePricesAsync(List<ChargeModuleDetailsModel> model)
        {
            var transaction = this.unitOfWork.BeginTransaction();

            var failureCount = 0;
            foreach (var item in model)
            {
                ChargeModuleDetails chargeModuleDetails;
                if (item.ChargeModuleDetailsId > 0)
                {
                    chargeModuleDetails = await this.unitOfWork.ChargeModuleDetails.FindAsync(m => m.ChargeModuleDetailsId == item.ChargeModuleDetailsId, transaction);
                    chargeModuleDetails.LocationId = (int)item.LocationId;
                    chargeModuleDetails.ChargeModuleCategoryId = (int)item.ChargeModuleCategoryId;
                    chargeModuleDetails.ReferenceId = (int)item.ReferenceId;
                    chargeModuleDetails.Amount = item.Amount;
                    chargeModuleDetails.ModifiedBy = item.CreatedBy;
                    chargeModuleDetails.ModifiedDate = DateTime.UtcNow.AddMinutes(330);
                    var updated = await this.unitOfWork.ChargeModuleDetails.UpdateAsync(chargeModuleDetails, transaction);
                    if (updated == 0)
                        failureCount++;
                }
                else
                {
                    if (item.ChargeModuleCategoryId == null || item.ChargeModuleCategoryId == 0)
                    {
                        var chargeModuleCategory = new ChargeModuleCategory
                        {
                            Active = true,
                            CreatedBy = (int)item.CreatedBy,
                            CreatedDate = DateTime.UtcNow.AddMinutes(330),
                            ChargeCategoryId = (int)item.ChargeCategoryId,
                            ChargeModuleTemplateId = item.ChargeModuleTemplateId,
                            ModulesMasterId = item.ModulesMasterId
                        };
                        item.ChargeModuleCategoryId = await this.unitOfWork.ChargeModuleCategorys.InsertAsync(chargeModuleCategory, transaction);
                        if (item.ChargeModuleCategoryId == 0)
                            failureCount++;
                    }

                    if (item.ChargeCategoryId > 0)
                    {
                        chargeModuleDetails = new ChargeModuleDetails
                        {
                            LocationId = (int)item.LocationId,
                            ChargeModuleCategoryId = (int)item.ChargeModuleCategoryId,
                            ReferenceId = (int)item.ReferenceId,
                            Amount = item.Amount,
                            CreatedBy = (int)item.CreatedBy,
                            CreatedDate = DateTime.UtcNow.AddMinutes(330)
                        };
                        var added = await this.unitOfWork.ChargeModuleDetails.InsertAsync(chargeModuleDetails, transaction);
                        if (added == 0)
                            failureCount++;
                    }
                }
            }

            if (failureCount > 0)
            {
                transaction.Rollback();
                return false;
            }

            transaction.Commit();
            return true;
        }

        #endregion
    }
}