public async Task <IActionResult> Index()
        {
            var companies = await _companyBusinessManager.GetCompanies();

            ViewBag.Companies = companies.Select(x => new SelectListItem()
            {
                Text = x.Name, Value = x.Id.ToString()
            });

            var filters = await _businessManager.GetInvoiceConstructorSearchCriterias();

            ViewBag.SearchCriterias = filters.Select(x => new SelectListItem()
            {
                Text = x.Name ?? $"Search criteria {x.Id}", Value = x.Id.ToString()
            });

            var model = new InvoiceConstructorFilterViewModel()
            {
                Date = DateTime.Now.LastDayOfMonth()
            };

            return(View(model));
        }
        public async Task <IActionResult> GenerateConstructor(InvoiceConstructorFilterViewModel model)
        {
            try {
                if (!ModelState.IsValid)
                {
                    throw new Exception("Form is not valid!");
                }
                var company = await _companyBusinessManager.GetCompany(model.CompanyId);

                var summary = await _companyBusinessManager.GetSummaryRanges(model.CompanyId);

                var constructorSearches = await _businessManager.GetInvoiceConstructorSearchCriterias(model.SearchCriterias.ToArray());

                var constructors = await _businessManager.GetConstructorInvoices(model.CompanyId, model.Date ?? DateTime.Now);

                foreach (var constructorSearch in constructorSearches)
                {
                    foreach (var summaryRange in summary)
                    {
                        var constructor = constructors.Where(x => x.SearchCriteriaId == constructorSearch.Id && x.SummaryRangeId == summaryRange.Id).FirstOrDefault();
                        if (constructor == null)
                        {
                            var entity = await _businessManager.CreateConstructorInvoice(new InvoiceConstructorDto()
                            {
                                CompanyId        = model.CompanyId,
                                Date             = model.Date.Value,
                                SearchCriteriaId = constructorSearch.Id,
                                SummaryRangeId   = summaryRange.Id
                            });

                            constructors.Add(entity);
                        }
                        else
                        {
                            //update
                        }
                    }
                }

                var customerCounts = new Dictionary <long, int>();
                foreach (var searchCriteria in constructorSearches)
                {
                    var constructor = new InvoiceConstructorDto()
                    {
                        CompanyId        = model.CompanyId,
                        Date             = model.Date ?? DateTime.Now,
                        SearchCriteriaId = searchCriteria.Id,
                    };

                    var customers = await _businessManager.GetCustomers(constructor);

                    if (!customerCounts.ContainsKey(searchCriteria.Id))
                    {
                        customerCounts.Add(searchCriteria.Id, customers.Count);
                    }
                }

                var viewDataDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
                {
                    { "SummaryRanges", _mapper.Map <List <CompanySummaryRangeViewModel> >(summary) },
                    { "SearchCriterias", _mapper.Map <List <InvoiceConstructorSearchViewModel> >(constructorSearches) },
                    { "CompanyName", company.Name },
                    { "Constructors", _mapper.Map <List <InvoiceConstructorViewModel> >(constructors) },
                    { "CustomerCounts", customerCounts }
                };

                string html = _viewRenderService.RenderToStringAsync("_ConstructorPartial", model, viewDataDictionary).Result;
                return(Ok(html));
            } catch (Exception er) {
                return(BadRequest(er.Message ?? er.StackTrace));
            }
        }