Display All Days for Monthly Time Tracking
We include time allocation when we invoice clients at the end of a given month. Time is tracked in a custom object within our Salesforce org so we simply run a report and export it to be sent to clients when billing. This is usually in the form of a spreadsheet and includes the date, hours, short description and employee.
If the client wanted to see the time allocation for every day of the month even if the employee didn't work every day then we'd have to export the report from Salesforce and manipulate the resulting file in order to meet the need. This is due to the fact that Salesforce can only report on data that is entered into the database.
To work around this limitation you could create a Visualforce page that determines all of the dates for a given month and only include allocation details if a time tracking record exists for the date. You could go even further and have the Visualforce page render as an Excel file thereby increasing efficiency even further.
For the purposes of this post we will simply show you how to create a Visualforce page that displays all of the days for a given month.
First we need an Apex Class controller for the page:
/*
Created by: Greg Hacic
Last Update: 2 February 2017 by Greg Hacic
Questions?: greg@interactiveties.com
Notes:
- controller for monthlyTime.page
*/
public class monthlyTime {
public Integer monthSelection = Date.Today().Month(); //month > declared here so it can be overwritten in afuture enhancement
public Integer yearSelection = Date.Today().Year(); //year > declared here so it can be overwritten in afuture enhancement
public List<timeEntry> timeEntries = new List<timeEntry>(); //custom wrapper object for Date and Time_Card__c details
public Decimal totalHours = 0.0; //total hours
//constructor
public monthlyTime() {
grabTimecards(); //build the list of wrapper objects to display
}
//grab all of the Time_Card__c records for the employee, project and month
private void grabTimecards() {
List<Date> daysForMonth = buildDaysInMonth(); //create the list of all days for the month
timeEntries.clear(); //empty the timeEntries list
totalHours = 0; //reset the total to zero
//placeholder for loop to grab your custom time card records and increment the overall hours
//construct the list of time entry objects
for (Date d : daysForMonth) { //for all of the dates in our list
timeEntries.add(new timeEntry(d, 'placeholder')); //create a new timeEntry object for the date
}
}
//grabs all of the days in the month for the selected month & year
private List<Date> buildDaysInMonth() {
List<Date> returnList = new List<Date>(); //return list of Dates
Integer daysInMonth = Date.daysInMonth(yearSelection, monthSelection); //number of days in month
for (Integer day = 1; day <= daysInMonth; day++) { //for first to last day in month
returnList.add(Date.newInstance(yearSelection, monthSelection, day)); //add the date to our list
}
return returnList; //return the list
}
//returns the list of wrapper objects
public List<timeEntry> getTimeEntries() {
return timeEntries; //return the list
}
//returns the total of all hours
public Decimal getTotalHours() {
return totalHours; //return total hours
}
//wrapper for Time Card records with Date
public class timeEntry {
public Date day {get; set;} //Date
public String allocationDetails {get; set;} //placeholder for your custom time entry record details
//constructor
public timeEntry(Date d, String t) {
this.day = d;
this.allocationDetails = t;
}
}
}
Next is the Visualforce page:
<apex:page controller="monthlyTime">
<!--
Created by: Greg Hacic
Last Update: 2 February 2017 by Greg Hacic
Questions?: greg@interactiveties.com
-->
<apex:pageMessages></apex:pageMessages>
<table>
<tr>
<th>Date</th>
<th>Hours</th>
<th>Description</th>
<th>Purpose</th>
<th>Employee</th>
</tr>
<apex:repeat id="timecarddetails" value="{!timeEntries}" var="t">
<tr>
<td><c:localeFormattedDate dateProvided="{!t.day}"></c:localeFormattedDate></td>
<td colspan="4">{!t.allocationDetails}</td>
</tr>
</apex:repeat>
<tr>
<th colspan="2">Total Hours</th>
<th>{!totalHours}</th>
<th colspan="2"></th>
</tr>
</table>
</apex:page>