locked
Razor Pages : How to call a calculated subtotal from another page? RRS feed

  • Question

  • User-1166899701 posted

    Hi all. I hope you are doing well.

    I would really appreciate your help with my problem.

    I have a page in which I am calculating a Total value from other values calculated from entered values.

    Payrolls Index.chtml page:

    @page
    @model Pro.Pages.Payrolls.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
      
    
    <p>
        <a asp-page="Create">Add New Payroll</a> for an existing employee.
    </p>
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].EmployeeID)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].FullName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Salary)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Deduction)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].OvertimeHours)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Bonus)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Total)
                </th>
    
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Payroll)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.ID)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.FullName)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.Salary)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Deduction)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.OvertimeHours)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Bonus)
                    </td>
                    @{
                        decimal CalcOvertime(decimal salary, int hours)
                        {
                            return ((salary / ((31 - 4) * 8)) * hours);
                        }
                    }
    
                    @{
                        decimal CalculateTotal(decimal salary, decimal deduction, decimal overtime, decimal bonus)
                        {
                            return (salary - deduction + overtime + bonus);
                        }
                    }
    
                    @{
                        item.Total = CalculateTotal(item.Employee.Salary, item.Deduction, CalcOvertime((item.Employee.Salary), (item.OvertimeHours)), item.Bonus); 
                    }
    
                    <td>
                        @Html.DisplayFor(modelItem => item.Total)
                    </td>
    
    
    
                    <td>
                       <a asp-page="./Edit" asp-route-id="@item.EmployeeID">Edit</a>
                            | 
                        <a asp-page="./Details" asp-route-id="@item.EmployeeID">Details</a>
                        | 
                            <a asp-page="./Delete" asp-route-id="@item.EmployeeID">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    
        <tfoot>
            <tr>
                <td colspan="6"><b>Total</b></td>
                <td><b>@Model.Payroll.Sum(i => i.Total).ToString("0,0.00") </b></td>
            </tr>
        </tfoot>
    </table>

    Payrolls Index.cshtml.cs page:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using Microsoft.EntityFrameworkCore;
    using Pro.Authorization;
    using Pro.Data;
    using Pro.Models;
    using Pro.Pages.Employees;
    
    namespace Pro.Pages.Payrolls
    {
        public class IndexModel : DI_BasePageModel
        {
    
            public IndexModel(
            ApplicationDbContext context,
            IAuthorizationService authorizationService,
            UserManager<IdentityUser> userManager)
            : base(context, authorizationService, userManager)
            {
            }
    
    
            public IList<Payroll> Payroll { get; set; }
    
            public async Task OnGetAsync()
            {
                var payrolls = from c in Context.Payroll.Include(j => j.Employee)
                  .AsNoTracking()
                                    select c;
    
                Payroll = await payrolls.ToListAsync();
    
    
            }
        }
    }
    

    How can I retrieve the "Total" value (highlighted above), which is a subtotal of all of the totals that will be calculated of all payrolls, and use it to perform calculations on a new page?

    Sorry if this is a dumb question. I've been searching about it for days.

    I am using ASP.NET Core 2.2.

    Sunday, November 3, 2019 11:35 AM

Answers

  • User475983607 posted

    The common design methodology is moving shared logic to a class or library that both Razor pages access.  Otherwise, you'll have duplicate code in two pages.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, November 3, 2019 12:36 PM
  • User711641945 posted

    Hi suhaixo,

    I suggest that you could put the calculating a Total value to the handler and set session for Total value.Then No matter where you want to use the Total value,you could get it.

    1.Payrolls Index.chtml:

    @page
    @model IndexModel
    <p>
        <a asp-page="Create">Add New Payroll</a> for an existing employee.
    </p>
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].EmployeeID)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].FullName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Salary)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Deduction)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].OvertimeHours)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Bonus)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Total)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Payroll)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.ID)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.FullName)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.Salary)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Deduction)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.OvertimeHours)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Bonus)
                    </td>               
                    <td>
                        @Html.DisplayFor(modelItem => item.Total)
                    </td>
                    <td>
                        <a asp-page="./Edit" asp-route-id="@item.EmployeeID">Edit</a>
                        |
                        <a asp-page="./Details" asp-route-id="@item.EmployeeID">Details</a>
                        |
                        <a asp-page="./Delete" asp-route-id="@item.EmployeeID">Delete</a>
                    </td>
                </tr>
                        }
        </tbody>
        <tfoot>
            <tr>
                <td colspan="6"><b>Total</b></td>
                <td><b>@Model.Payroll.Sum(i => i.Total).ToString("0,0.00")</b></td>
            </tr>
        </tfoot>
    </table>

    2.Payrolls Index.cshtml.cs:

    using Microsoft.AspNetCore.Http;

    public async Task OnGetAsync() { var payrolls = from c in Context.Payroll.Include(j => j.Employee).AsNoTracking() select c Payroll = await payrolls.ToListAsync(); foreach (var item in Payroll) { item.Total = CalculateTotal(item.Employee.Salary, item.Deduction, CalcOvertime((item.Employee.Salary), (item.OvertimeHours)), item.Bonus); } var data = Payroll.Sum(i => i.Total).ToString("0,0.00"); HttpContext.Session.SetString("total", data);//set session here } decimal CalcOvertime(decimal salary, int hours) { return ((salary / ((31 - 4) * 8)) * hours); } decimal CalculateTotal(decimal salary, decimal deduction, decimal overtime, decimal bonus) { return (salary - deduction + overtime + bonus); }

    3.Details.cshtml(the razor page you want to get the Total value):

    @page
    @model DetailsModel
    
    <h1>Details</h1>
    @Model.Total 

    4.Details.cshtml.cs:

    using Microsoft.AspNetCore.Http;

    public string Total { get; set; } public async Task<IActionResult> OnGetAsync() { //your logic... Total=HttpContext.Session.GetString("total");//get session here return Page(); }

    5.Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        //...
        services.AddSession();
    }
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //...
        app.UseSession();
    }

    Reference:

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-3.0#set-and-get-session-values

    Best Regards,

    Rena

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 4, 2019 5:33 AM

All replies

  • User475983607 posted

    The common design methodology is moving shared logic to a class or library that both Razor pages access.  Otherwise, you'll have duplicate code in two pages.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, November 3, 2019 12:36 PM
  • User711641945 posted

    Hi suhaixo,

    I suggest that you could put the calculating a Total value to the handler and set session for Total value.Then No matter where you want to use the Total value,you could get it.

    1.Payrolls Index.chtml:

    @page
    @model IndexModel
    <p>
        <a asp-page="Create">Add New Payroll</a> for an existing employee.
    </p>
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].EmployeeID)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].FullName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Salary)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Deduction)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].OvertimeHours)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Bonus)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Payroll[0].Total)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Payroll)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.ID)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.FullName)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Employee.Salary)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Deduction)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.OvertimeHours)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Bonus)
                    </td>               
                    <td>
                        @Html.DisplayFor(modelItem => item.Total)
                    </td>
                    <td>
                        <a asp-page="./Edit" asp-route-id="@item.EmployeeID">Edit</a>
                        |
                        <a asp-page="./Details" asp-route-id="@item.EmployeeID">Details</a>
                        |
                        <a asp-page="./Delete" asp-route-id="@item.EmployeeID">Delete</a>
                    </td>
                </tr>
                        }
        </tbody>
        <tfoot>
            <tr>
                <td colspan="6"><b>Total</b></td>
                <td><b>@Model.Payroll.Sum(i => i.Total).ToString("0,0.00")</b></td>
            </tr>
        </tfoot>
    </table>

    2.Payrolls Index.cshtml.cs:

    using Microsoft.AspNetCore.Http;

    public async Task OnGetAsync() { var payrolls = from c in Context.Payroll.Include(j => j.Employee).AsNoTracking() select c Payroll = await payrolls.ToListAsync(); foreach (var item in Payroll) { item.Total = CalculateTotal(item.Employee.Salary, item.Deduction, CalcOvertime((item.Employee.Salary), (item.OvertimeHours)), item.Bonus); } var data = Payroll.Sum(i => i.Total).ToString("0,0.00"); HttpContext.Session.SetString("total", data);//set session here } decimal CalcOvertime(decimal salary, int hours) { return ((salary / ((31 - 4) * 8)) * hours); } decimal CalculateTotal(decimal salary, decimal deduction, decimal overtime, decimal bonus) { return (salary - deduction + overtime + bonus); }

    3.Details.cshtml(the razor page you want to get the Total value):

    @page
    @model DetailsModel
    
    <h1>Details</h1>
    @Model.Total 

    4.Details.cshtml.cs:

    using Microsoft.AspNetCore.Http;

    public string Total { get; set; } public async Task<IActionResult> OnGetAsync() { //your logic... Total=HttpContext.Session.GetString("total");//get session here return Page(); }

    5.Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        //...
        services.AddSession();
    }
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //...
        app.UseSession();
    }

    Reference:

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-3.0#set-and-get-session-values

    Best Regards,

    Rena

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 4, 2019 5:33 AM
  • User-1166899701 posted

    I will give both a shot! Thank you guys so much, I truly appreciate it!!

    Monday, November 4, 2019 7:38 AM