public async Task <ActionResult> PrintSesiUjianIndikatorIpu(string id)
        {
            var context = new SphDataContext();
            var sesi    = await context.LoadOneAsync <SesiUjian>(x => x.Id == id);

            var user = await context.LoadOneAsync <Pengguna>(x => x.MyKad == sesi.MyKad);

            var ujianTask      = context.LoadOneAsync <Ujian>(x => x.Id == sesi.NamaUjian);
            var permohonanTask = context.LoadOneAsync <Permohonan>(x => x.PermohonanNo == sesi.NamaProgram);
            await Task.WhenAll(ujianTask, permohonanTask);


            if (null == sesi)
            {
                return(HttpNotFound("Cannot find SesiUjian " + id));
            }
            if (null == user)
            {
                return(HttpNotFound("Cannot find user with MyKad " + sesi.MyKad));
            }

            var vm = new IpuTraitViewModel(sesi)
            {
                Permohonan = await permohonanTask,
                Ujian      = await ujianTask,
                Pengguna   = user
            };

            /* */
            var apTask = context.LoadOneAsync <SkorIPU>(x => vm.A.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "A");
            var bpTask = context.LoadOneAsync <SkorIPU>(x => vm.B.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "B");
            var cpTask = context.LoadOneAsync <SkorIPU>(x => vm.C.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "C");
            var dpTask = context.LoadOneAsync <SkorIPU>(x => vm.D.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "D");
            var epTask = context.LoadOneAsync <SkorIPU>(x => vm.E.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "E");
            var fpTask = context.LoadOneAsync <SkorIPU>(x => vm.F.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "F");
            var gpTask = context.LoadOneAsync <SkorIPU>(x => vm.G.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "G");
            var hpTask = context.LoadOneAsync <SkorIPU>(x => vm.H.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "H");
            var ipTask = context.LoadOneAsync <SkorIPU>(x => vm.I.IsBetween(x.NilaiMin, x.NilaiMax, true, true) && x.Jantina == user.Jantina && x.Tret == "I");
            await Task.WhenAll(apTask, bpTask, cpTask, epTask, fpTask, gpTask, hpTask, ipTask);

            var ap = await apTask;
            var bp = await bpTask;
            var cp = await cpTask;
            var dp = await dpTask;
            var ep = await epTask;
            var fp = await fpTask;
            var gp = await gpTask;
            var hp = await hpTask;
            var ip = await ipTask;

            vm.SkorA = ap.Percentile;
            vm.SkorB = bp.Percentile;
            vm.SkorC = cp.Percentile;
            vm.SkorD = dp.Percentile;
            vm.SkorE = ep.Percentile;
            vm.SkorF = fp.Percentile;
            vm.SkorG = gp.Percentile;
            vm.SkorH = hp.Percentile;
            vm.SkorI = ip.Percentile;
            vm.SkorJ = vm.J;

            var viewName = "Indikator-Ipu-" + user.Jantina;

            return(View(viewName, vm));
        }
        public async Task <ActionResult> Program(ProgramReportModel model)
        {
            if (model.Ujian == "IPU")
            {
                var html2 = await IpuTraitViewModel.GenerateLaporanTable(model);

                return(Content(html2, "text/html", Encoding.UTF8));
            }
            if (model.Ujian.Contains("UKBP"))
            {
                var html2 = await UkbpTraitViewModel.GenerateLaporanTable(model);

                return(Content(html2, "text/html", Encoding.UTF8));
            }

            var context = new SphDataContext();
            var no      = $"{model.Program}/{model.Bil}/{model.Siri}/{model.Tahun}";
            var ujian   = await context.LoadOneAsync <Ujian>(x => x.UjianNo == model.Ujian || x.NamaUjian == model.Ujian);

            var query = context.CreateQueryable <SesiUjian>()
                        .Where(s => s.NamaProgram == model.Program)
                        .Where(s => s.NamaUjian == model.Ujian)
                        .Where(s => s.Status == "Diambil");
            var sesiLo = await context.LoadAsync(query, 1, 200, true);

            var sesi = sesiLo.ItemCollection;

            while (sesiLo.HasNextPage)
            {
                sesiLo = await context.LoadAsync(query, sesiLo.CurrentPage + 1, 200, true);

                sesi.AddRange(sesiLo.ItemCollection);
            }

            var soalanQuery = context.CreateQueryable <Soalan>()
                              .Where(s => s.NamaUjian == ujian.UjianNo || s.NamaUjian == ujian.NamaUjian);
            var soalanLo = await context.LoadAsync(soalanQuery, 1, 200, true);

            var soalans = soalanLo.ItemCollection;

            while (soalanLo.HasNextPage)
            {
                soalanLo = await context.LoadAsync(soalanQuery, soalanLo.CurrentPage + 1, 200, true);

                soalans.AddRange(soalanLo.ItemCollection);
            }

            var traits = soalans.Select(s => s.Trait).Distinct().OrderBy(s => s).ToArray();

            var ppkp = model.Ujian == "PPKP";

            var html = new StringBuilder();

            html.AppendLine("<table class=\"table table-striped table-bordered\">");
            html.AppendLine("   <thead>");
            html.AppendLine("       <tr>");
            html.AppendLine("           <th>Nama</th>");
            html.AppendLine("           <th>Tarikh</th>");
            if (ppkp)
            {
                var namaTraits = new [] { "A", "B", "C", "D", "E" };
                foreach (var t in namaTraits)
                {
                    html.AppendLine("           <th>" + t + "</th>");
                }
            }

            foreach (var t in traits)
            {
                html.AppendLine("           <th>" + t + "</th>");
            }



            html.AppendLine("           <th>Cetakan Individu</th>");
            html.AppendLine("       </tr>");
            html.AppendLine("   </thead>");
            html.AppendLine("   <tbody>");
            foreach (var s in sesi)
            {
                html.AppendLine("   <tr>");
                html.AppendLine("   <td>" + s.NamaPengguna + "</td>");
                html.AppendFormat("   <td>{0:dd/MM/yyyy}</td>", s.TarikhUjian);

                if (ppkp)
                {
                    var namaTraits = new [] { "A", "B", "C", "D", "E" };
                    foreach (var t in namaTraits)
                    {
                        var t1    = t;
                        var score = s.JawapanCollection.Where(a => a.Trait.StartsWith(t1)).Sum(a => a.Nilai);
                        html.AppendLine("           <td>" + score + "</td>");
                    }
                }

                foreach (var t in traits)
                {
                    var t1    = t;
                    var score = s.JawapanCollection.Where(a => a.Trait == t1).Sum(a => a.Nilai);
                    html.AppendLine("           <td>" + score + "</td>");
                }


                var ip        = s.NamaUjian.Contains("IP") && !s.NamaUjian.Contains("IPU");
                var ibk       = s.NamaUjian.Contains("IBK");
                var iso       = s.NamaUjian.Contains("ISO");
                var hlp       = s.NamaUjian.Contains("HLP");
                var ukbp      = s.NamaUjian.Contains("UKBP");
                var indikator = ibk || ip || hlp || iso ? "" :
                                $@"<a class=""indikator-report btn btn-info"" target=""_blank"" href=""cetak-laporan/indikator/{
                        s.NamaUjian}/{s.Id}""> <i class=""fa fa-print""></i> Indikator</a>";
                if (ppkp)
                {
                    indikator = $@"<a class=""laporan-profile-report btn btn-info"" target=""_blank"" 
                    href=""cetak-laporan/ppkp/profile/{s.Id}""> <i class=""fa fa-print""></i> Profil</a>

<a class=""laporan-umum-report btn btn-info"" target=""_blank"" 
                    href=""cetak-laporan/ppkp/umum/{s.Id}""> <i class=""fa fa-print""></i> Umum</a>

<a class=""laporan-khusus-report btn btn-info"" target=""_blank"" 
                    href=""cetak-laporan/ppkp/khusus/{s.Id}""> <i class=""fa fa-print""></i> Khusus</a>"
                    ;

                    html.AppendLine($@"
                    <td>
                         {indikator}
                    </td>");
                }
                else if (ukbp)
                {
                    indikator = $@"<a class=""btn btn-info"" target=""_blank"" 
                                href=""cetak-laporan/indikator/ukbp/{s.Id}""> <i class=""fa fa-print""></i>Indikator</a>";

                    html.AppendLine($@"
                    <td>
                         {indikator}
                    </td>");
                }
                else
                {
                    html.AppendFormat(@"
                    <td>
                        <a class=""trait-report btn btn-info"" target=""_blank"" href=""cetak-laporan/trait/{2}/{0}""> <i class=""fa fa-print""></i> Tret</a>
                        {1}
                    </td>", s.Id, indikator, s.NamaUjian);
                }


                html.AppendLine("   </tr>");
            }


            // sum
            html.AppendLine("   <tr>");
            html.AppendLine("   <td>Jumlah Markah</td>");
            html.AppendLine("   <td></td>");
            if (ppkp)
            {
                var namaTraits = new [] { "A", "B", "C", "D", "E" };
                foreach (var t in namaTraits)
                {
                    var t1    = t;
                    var score = sesi.SelectMany(x => x.JawapanCollection).Where(a => a.Trait.StartsWith(t1)).Sum(a => a.Nilai);
                    html.AppendLine("           <td>" + score + "</td>");
                }
            }
            foreach (var t in traits)
            {
                var t1    = t;
                var score = sesi.SelectMany(x => x.JawapanCollection).Where(a => a.Trait == t1).Sum(a => a.Nilai);
                html.AppendLine("           <td>" + score + "</td>");
            }
            html.AppendLine("   <td></td>");
            html.AppendLine("   </tr>");

            // average
            html.AppendLine("   <tr>");
            html.AppendLine("   <td>Purata Markah</td>");
            html.AppendLine("   <td></td>");


            if (ppkp)
            {
                var namaTraits = new [] { "A", "B", "C", "D", "E" };
                foreach (var t in namaTraits)
                {
                    var t1 = t;
                    if (sesi.Count > 0)
                    {
                        var avg = sesi.SelectMany(x => x.JawapanCollection).Where(a => a.Trait.StartsWith(t1)).Sum(a => a.Nilai) / sesi.Count;
                        html.AppendLine("           <td>" + avg + "</td>");
                    }
                    else
                    {
                        html.AppendLine("           <td> NA</td>");
                    }
                }
            }

            foreach (var t in traits)
            {
                var t1 = t;
                if (sesi.Count > 0)
                {
                    var avg = sesi.SelectMany(x => x.JawapanCollection).Where(a => a.Trait == t1).Sum(a => a.Nilai) / sesi.Count;
                    html.AppendLine("           <td>" + avg + "</td>");
                }
                else
                {
                    html.AppendLine("           <td> NA</td>");
                }
            }
            html.AppendLine("   <td></td>");
            html.AppendLine("   </tr>");

            html.AppendLine("</tbody>");
            html.AppendLine("</table>");

            return(Content(html.ToString(), "text/html", Encoding.UTF8));
        }
        public async Task <ActionResult> PrintSesiUjianTraitIpu(string id)
        {
            var context = new SphDataContext();
            var sesi    = await context.LoadOneAsync <SesiUjian>(x => x.Id == id);

            var user = await context.LoadOneAsync <Pengguna>(x => x.MyKad == sesi.MyKad);

            var ujianTask      = context.LoadOneAsync <Ujian>(x => x.Id == sesi.NamaUjian);
            var permohonanTask = context.LoadOneAsync <Permohonan>(x => x.PermohonanNo == sesi.NamaProgram);
            await Task.WhenAll(ujianTask, permohonanTask);


            if (null == sesi)
            {
                return(HttpNotFound("Cannot find SesiUjian " + id));
            }
            if (null == user)
            {
                return(HttpNotFound("Cannot find user with MyKad " + sesi.MyKad));
            }

            var vm = new IpuTraitViewModel(sesi)
            {
                Permohonan = await permohonanTask,
                Ujian      = await ujianTask,
                Pengguna   = user
            };

            /* */
            var apTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.A);
            var bpTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.B);
            var cpTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.C);
            var dpTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.D);
            var epTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.E);
            var fpTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.F);
            var gpTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.G);
            var hpTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.H);
            var ipTask = context.LoadOneAsync <IpuPercentileNorms>(x => x.RawScore == vm.I);
            await Task.WhenAll(apTask, bpTask, cpTask, epTask, fpTask, gpTask, hpTask, ipTask);

            var ap = await apTask;
            var bp = await bpTask;
            var cp = await cpTask;
            var dp = await dpTask;
            var ep = await epTask;
            var fp = await fpTask;
            var gp = await gpTask;
            var hp = await hpTask;
            var ip = await ipTask;

            var a = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "A" && x.NilaiMin <= ap.A && ap.A <= x.NilaiMax);
            var b = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "B" && x.NilaiMin <= bp.B && bp.B <= x.NilaiMax);
            var c = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "C" && x.NilaiMin <= cp.C && cp.C <= x.NilaiMax);
            var d = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "D" && x.NilaiMin <= dp.D && dp.D <= x.NilaiMax);
            var e = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "E" && x.NilaiMin <= ep.E && ep.E <= x.NilaiMax);
            var f = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "F" && x.NilaiMin <= fp.F && fp.F <= x.NilaiMax);
            var g = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "G" && x.NilaiMin <= gp.G && gp.G <= x.NilaiMax);
            var h = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "H" && x.NilaiMin <= hp.H && hp.H <= x.NilaiMax);
            var i = context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "I" && x.NilaiMin <= ip.I && ip.I <= x.NilaiMax);

            vm.RecommendationA = await a;
            vm.RecommendationB = await b;
            vm.RecommendationC = await c;
            vm.RecommendationD = await d;
            vm.RecommendationE = await e;
            vm.RecommendationF = await f;
            vm.RecommendationG = await g;
            vm.RecommendationH = await h;
            vm.RecommendationI = await i;
            vm.RecommendationJ = await context.LoadOneAsync <IpuRecommendation>(x => x.Tret == "J" && x.NilaiMin <= vm.J && vm.J <= x.NilaiMax);


            return(View("Trait-Ipu", vm));
        }