private void CreateFile(ReportDto dto, string path, string fileName)
        {
            // Determine whether the directory exists. 
            if (!Directory.Exists(path))
            {
                // Try to create the directory.
                Directory.CreateDirectory(path);
                this.Info(() => "The directory was created successfully at " + Directory.GetCreationTime(path));
            }

            //Store to disk
            using (var fileStream = File.Create(path + @"\" + fileName))
            {
                var report = _reportingService.RenderAsync(dto.Template.ShortId, dto.Data).Result;
                report.Content.CopyTo(fileStream);

                this.Info(() => "Report : " + fileName + " created successfully");
            }
        }
        public override void Observe()
        {
            var bus = new TransactionBus(_bus);

            var userTransactions = new List<ContractUserTransactions>();
            var products = new List<ContractProductDetail>();
            products.Add(new ContractProductDetail { PackageName = "Test Package", TransactionCount = 12 });

            userTransactions.Add(new ContractUserTransactions
            {
                User = "******",
                Products = products
            });

            var statementList = new List<ContractStatement>();

            statementList.Add(new ContractStatement
             {
                 Customer = "Test Customer",
                 Client = "",
                 ContractName = "Test Contract",
                 UserTransactions = userTransactions
             });

            var data = new ReportDto
            {
                Template = new ReportTemplate { ShortId = "VkTYTvzp" },
                Data = new ReportData
                {
                    ContractStatements = statementList
                }
            };


            var report = new ReportMessage()
            {
                Id = Guid.NewGuid(),
                ReportBody = JsonConvert.SerializeObject(data),
                ReportType = "pdf"
            };

            bus.SendDynamic(report);
        }
        public override void Observe()
        {
            var bus = new TransactionBus(_bus);

            var packagesList = new List<ReportPackage>();
            packagesList.Add(new ReportPackage
            {
                ItemCode = "1000/200/002",
                ItemDescription = "PackageName",
                QuantityUnit = 1,
                Price = 16314.67,
                Vat = 2284
            });

            var data = new ReportDto
            {
                Template = new ReportTemplate { ShortId = "VJGAd9OM" },
                Data = new ReportData
                {
                    Customer = new ReportCustomer
                    {
                        Name = "Customer 1",
                        TaxRegistration = 4190195679,
                        Packages = packagesList
                    }
                }
            };


            var report = new ReportMessage()
            {
                Id = Guid.NewGuid(),
                ReportBody = JsonConvert.SerializeObject(data),
                ReportType = "pdf"
            };

            bus.SendDynamic(report);
        }
        public PreBillingModule(IRepository<PreBilling> preBillingDBRepository, 
                                IRepository<AccountMeta> accountMetaRepository, IRepository<UserMeta> userMetaRepository, ICacheProvider<PreBilling> preBillingCacheProvider,
                                IReportApiClient reportApiClient)
        {
            this.RequiresAnyClaim(new[] { RoleType.Admin.ToString(), RoleType.ProductManager.ToString(), RoleType.Support.ToString() });

            _preBillingDBRepository = preBillingDBRepository;
            _preBillingRepository = preBillingCacheProvider.CacheClient.GetAll();

            var endDateFilter = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 25);
            var startDateFilter = new DateTime(DateTime.UtcNow.Year, (DateTime.UtcNow.Month - 1), 26);

            Before += async (ctx, ct) =>
            {
                this.Info(() => "Before Hook - PreBilling");
                await CheckCache(ct);
                return null;
            };

            After += async (ctx, ct) => this.Info(() => "After Hook - PreBilling");

            Get["/PreBilling/"] = _ =>
            {
                var preBillStartDateFilter = Request.Query["startDate"];
                var preBillEndDateFilter = Request.Query["endDate"];

                if (!preBillStartDateFilter.HasValue && !preBillEndDateFilter.HasValue) return Negotiate.WithView("Index");

                if (preBillStartDateFilter.HasValue) startDateFilter = preBillStartDateFilter;
                if (preBillEndDateFilter.HasValue) endDateFilter = preBillEndDateFilter;

                endDateFilter = endDateFilter.AddHours(23).AddMinutes(59).AddSeconds(59);

                var customerClientList = new List<PreBillingDto>();

                foreach (var transaction in _preBillingRepository)
                {
                    var customerClientIndex = customerClientList.FindIndex(x => x.Id == transaction.CustomerId || x.Id == transaction.ClientId);
                    if (customerClientIndex > 0) continue;

                    var customerClient = new PreBillingDto();
                    

                    var customerTransactions = _preBillingRepository.Where(x => x.CustomerId == transaction.CustomerId
                                                                            && (x.Created >= startDateFilter && x.Created <= endDateFilter))
                                                                            .DistinctBy(x => x.UserTransaction.TransactionId);

                    var customerPackages = customerTransactions.Where(x => x.CustomerId == transaction.CustomerId)
                                                        .Select(x => x.Package.PackageId).Distinct().Count();

                    var customerUsers = customerTransactions.Where(x => x.CustomerId == transaction.CustomerId).DistinctBy(x => x.User.UserId).Count();


                    var clientTransactions = _preBillingRepository.Where(x => x.ClientId == transaction.ClientId
                                                                            && (x.Created >= startDateFilter && x.Created <= endDateFilter))
                                                                            .DistinctBy(x => x.UserTransaction.TransactionId);

                    var clientPackagesTotal = clientTransactions.Where(x => x.ClientId == transaction.ClientId)
                                                        .Select(x => x.Package.PackageId).Distinct().Count();

                    var clientUsers = customerTransactions.Where(x => x.ClientId == transaction.ClientId).DistinctBy(x => x.User.UserId).Count();

                    if (customerTransactions.Count() < 0 && clientTransactions.Count() < 0) continue;

                    // Customer
                    if (transaction.ClientId == new Guid())
                    {
                        customerClient = new PreBillingDto
                        {
                            Id = transaction.CustomerId,
                            CustomerName = transaction.CustomerName,
                            Transactions = customerTransactions.Count(),
                            Products = customerPackages,
                            AccountMeta = accountMetaRepository.FirstOrDefault(x => x.AccountNumber == transaction.AccountNumber),
                        };

                        customerClient.Users = customerUsers;
                    }

                    // Client
                    if (transaction.CustomerId == new Guid())
                    {
                        customerClient = new PreBillingDto
                        {
                            Id = transaction.ClientId,
                            CustomerName = transaction.ClientName,
                            Transactions = clientTransactions.Count(),
                            Products = clientPackagesTotal,
                            AccountMeta = accountMetaRepository.FirstOrDefault(x => x.AccountNumber == transaction.AccountNumber)
                        };

                        customerClient.Users = clientUsers;
                    }

                   if ((transaction.ClientId == new Guid()) && (transaction.CustomerId == new Guid())) continue;

                   if (customerClientIndex < 0 && customerClient.Transactions > 0) customerClientList.Add(customerClient);
                }

                return Negotiate
                    .WithView("Index")
                    .WithMediaRangeModel(MediaRange.FromString("application/json"), new { data = customerClientList });
            };


            Get["/PreBilling/CustomerClient/{searchId}/Users"] = param =>
            {
                var preBillStartDateFilter = Request.Query["startDate"];
                var preBillEndDateFilter = Request.Query["endDate"];

                if (preBillStartDateFilter.HasValue) startDateFilter = preBillStartDateFilter;
                if (preBillEndDateFilter.HasValue) endDateFilter = preBillEndDateFilter;

                endDateFilter = endDateFilter.AddHours(23).AddMinutes(59).AddSeconds(59);

                var searchId = new Guid(param.searchId);
                var customerUsersDetailList = new List<UserDto>();

                var preBillingRepo = _preBillingRepository.Where(x => (x.CustomerId == searchId || x.ClientId == searchId)
                                                                    && (x.Created >= startDateFilter && x.Created <= endDateFilter)).DistinctBy(x => x.UserTransaction.TransactionId);

                foreach (var transaction in preBillingRepo)
                {
                    var userTransactionsList = new List<TransactionDto>();

                    var userMeta = userMetaRepository.FirstOrDefault(x => x.Id == transaction.User.UserId) ?? new UserMeta
                    {
                        Id = transaction.User.UserId,
                        Username = transaction.User.Username
                    };

                    // Filter repo for user transaction;
                    var userTransactions = preBillingRepo.Where(x => x.User.UserId == transaction.User.UserId)
                                            .Select(x =>
                                            new TransactionDto
                                            {
                                                TransactionId = x.UserTransaction.TransactionId,
                                                RequestId = x.UserTransaction.RequestId,
                                                IsBillable = x.UserTransaction.IsBillable
                                            }).Distinct();

                    foreach (var userTransaction in userTransactions)
                    {
                        var userTransIndex = userTransactionsList.FindIndex(x => x.TransactionId == userTransaction.TransactionId);
                        if (userTransIndex < 0) userTransactionsList.Add(userTransaction);
                    }

                    var user = Mapper.Map<PreBilling, UserDto>(transaction);
                    Mapper.Map(userMeta, user);
                    user.Transactions = userTransactionsList;

                    var userIndex = customerUsersDetailList.FindIndex(x => x.UserId == user.UserId);
                    if (userIndex < 0) customerUsersDetailList.Add(user);
                }

                return Response.AsJson(new { data = customerUsersDetailList });
            };


            Get["/PreBilling/CustomerClient/{searchId}/Packages"] = param =>
            {
                var preBillStartDateFilter = Request.Query["startDate"];
                var preBillEndDateFilter = Request.Query["endDate"];

                if (preBillStartDateFilter.HasValue) startDateFilter = preBillStartDateFilter;
                if (preBillEndDateFilter.HasValue) endDateFilter = preBillEndDateFilter;

                endDateFilter = endDateFilter.AddHours(23).AddMinutes(59).AddSeconds(59);

                var searchId = new Guid(param.searchId);
                var customerPackagesDetailList = new List<PackageDto>();

                var preBillingRepo = _preBillingRepository.Where(x => (x.CustomerId == searchId || x.ClientId == searchId)
                                                                    && (x.Created >= startDateFilter && x.Created <= endDateFilter)).DistinctBy(x => x.UserTransaction.TransactionId);

                foreach (var transaction in preBillingRepo)
                {
                    var packageTransactions = preBillingRepo.Where(x => x.Package.PackageId == transaction.Package.PackageId).Distinct();

                    var package = Mapper.Map<Package, PackageDto>(transaction.Package);
                    package.PackageTransactions = packageTransactions.Count();
                    package.Created = transaction.Created;

                    var packageIndex = customerPackagesDetailList.FindIndex(x => x.PackageId == package.PackageId);

                    if (packageIndex < 0) customerPackagesDetailList.Add(package);

                    if (packageIndex >= 0)
                    {
                        if (customerPackagesDetailList[packageIndex].Created < package.Created)
                        {
                            customerPackagesDetailList[packageIndex] = package;
                        }
                    }
                }

                return Response.AsJson(new { data = customerPackagesDetailList });
            };

            Get["/PreBillingDump"] = _ =>
            {
                var preBillStartDateFilter = Request.Query["startDate"];
                var preBillEndDateFilter = Request.Query["endDate"];

                if (preBillStartDateFilter.HasValue) startDateFilter = preBillStartDateFilter;
                if (preBillEndDateFilter.HasValue) endDateFilter = preBillEndDateFilter;

                endDateFilter = endDateFilter.AddHours(23).AddMinutes(59).AddSeconds(59);

                var preBilling = _preBillingRepository.Where(x => x.Created >= startDateFilter && x.Created <= endDateFilter);

                var report = new ReportDto
                {
                    Template = new ReportTemplate { ShortId = "418Ky2Cj" },
                    Data = new ReportData
                    {
                        PreBillingData = Mapper.Map<IEnumerable<PreBilling>, IEnumerable<PreBillingRecord>>(preBilling)
                    }
                };

                var token = Context.Request.Headers.Authorization.Split(' ')[1];
                reportApiClient.Post(token, "/PreBillingReportDownload?startDate=" + startDateFilter + "&endDate="+ endDateFilter, null, report, null);


                var file = new FileStream(@"D:\LSA Reports\PreBilling " + startDateFilter.ToString("MMMM dd yyyy") + " - " + endDateFilter.ToString("MMMM dd yyyy") + ".xlsx", FileMode.Open);
                string fileName = "PreBilling_" + startDateFilter.ToString("MMMM-dd-yyyy") + "_" + endDateFilter.ToString("MMMM-dd-yyyy") + ".xlsx";

                var response = new StreamResponse(() => file, MimeTypes.GetMimeType(fileName));

                response.WithCookie("fileDownload", "true", DateTime.UtcNow.AddSeconds(10), "", "/");

                return response.AsAttachment(fileName);
            };

        }