Tutorial: ASP.NET MVC 5 Timesheet

This tutorial shows how to create a monthly timesheet application in ASP.NET MVC. It shows one day per row, in/out times for each event, daily totals. Optional non-business hours hiding. C# and VB sample source code available for download.
Jan 21, 2015
asp.net mvc 5 timesheet

Features

  • Timesheet view (1 day per row)
  • Switching full day/business hours views
  • Employee filter using a drop-down list
  • Drag and drop event creating
  • Drag and drop event moving and resizing
  • Event editing using a modal dialog
  • Event text for recording details (like project name or job description)
  • Column with daily total (hours spent)
  • ASP.NET MVC 5
  • SQL Server sample database (LocalDB)
  • Visual Studio 2013 solution
  • C# source code
  • VB source code

Source code of the tutorial is available for download.

Example - Adding a Column with Daily Totals

asp.net mvc 5 timesheet total duration

C#

@Html.DayPilotScheduler("dps", new DayPilotSchedulerConfig
{
    BackendUrl = Url.Action("Backend", "Scheduler"),
    // ...
    HeaderColumns = new RowHeaderColumnCollection
    {
        new RowHeaderColumn("Day", 100),
        new RowHeaderColumn("Total", 100)
    }
})

VB

@Html.DayPilotScheduler("dps", New DayPilotSchedulerConfig With
{
    .BackendUrl = Url.Action("Backend", "Scheduler"),
    ' ...
    .HeaderColumns = New RowHeaderColumnCollection From
    {
        New RowHeaderColumn("Day", 100),
        New RowHeaderColumn("Total", 100)
    }
})

The total hours are calculated in the MVC controller:

C#

class Dps : DayPilotScheduler
{
    TimesheetDataContext dc = new TimesheetDataContext();
    
    // ...

    protected override void OnBeforeResHeaderRender(BeforeResHeaderRenderArgs e)
    {
        if (e.Columns.Count > 0)
        {
            var start = e.Date;
            var end = start.AddDays(1);
            var employee = SelectedEmployee();

            TimeSpan total = TimeSpan.Zero;
            (from tr in dc.TimesheetRecords where tr.EmployeeId == employee && !((tr.TimesheetOut <= start) || (tr.TimesheetIn >= end)) select tr).ToList().ForEach(tr => total = total.Add(tr.TimesheetOut - tr.TimesheetIn));

            e.Columns[0].Html = total.ToString("hh\\:mm");
        }

    }
    
}

VB

Private Class Dps
  Inherits DayPilotScheduler

  Private dc As New TimesheetDataContext()
  
  ' ...

  Protected Overrides Sub OnBeforeResHeaderRender(ByVal e As BeforeResHeaderRenderArgs)
    If e.Columns.Count > 0 Then
      Dim start = e.Date
      Dim [end] = start.AddDays(1)
      Dim employee = SelectedEmployee()

                Dim total As TimeSpan = TimeSpan.Zero
                Dim records = (From tr In dc.TimesheetRecords _
                    Where tr.EmployeeId = employee AndAlso Not ((tr.TimesheetOut <= start) OrElse (tr.TimesheetIn >= [end])) _
                    Select tr)
                records.ToList().ForEach(Sub(tr) total = total.Add(tr.TimesheetOut - tr.TimesheetIn))

      e.Columns(0).Html = total.ToString("hh\:mm")
    End If

  End Sub

End Class