Skip to content

Commit

Permalink
Merge pull request #57 from form3tech-oss/add-email-address-to-report
Browse files Browse the repository at this point in the history
Add email address to the report
  • Loading branch information
lchrzaszcz-form3 authored Oct 4, 2023
2 parents 7357569 + 4c05fec commit faead79
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 27 deletions.
30 changes: 28 additions & 2 deletions cmd/generate_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ func calculateSummaryData(data []*report.ScheduleData, pricesInfo *configuration
userSummary, ok := usersSummary[schedUser.Name]
if !ok {
userSummary = &report.ScheduleUser{
Name: schedUser.Name,
Name: schedUser.Name,
EmailAddress: schedUser.EmailAddress,
}
usersSummary[schedUser.Name] = userSummary
}
Expand Down Expand Up @@ -359,8 +360,14 @@ func (pd *pagerDutyClient) generateScheduleData(scheduleInfo *api.ScheduleInfo,
return nil, fmt.Errorf("aborted due to calendar '%s' not found for user '%s'", calendarName, userID)
}

userEmailAddress, err := pd.getUserEmail(userRotaInfo.ID)
if err != nil {
return nil, fmt.Errorf("aborted due to failed to get user's email address: %w", err)
}

scheduleUserData := &report.ScheduleUser{
Name: userRotaInfo.Name,
Name: userRotaInfo.Name,
EmailAddress: userEmailAddress,
}

for _, period := range userRotaInfo.Periods {
Expand Down Expand Up @@ -445,6 +452,25 @@ func (pd *pagerDutyClient) getUserTimezone(userID string) (string, error) {
return timezone, nil
}

func (pd *pagerDutyClient) getUserEmail(userID string) (string, error) {
var email string

if len(pd.cachedUsers) == 0 {
err := pd.loadUsersInMemoryCache()
if err != nil {
return "", fmt.Errorf("failed to get user with id %s email: %w", userID, err)
}
}

for _, user := range pd.cachedUsers {
if user.ID == userID {
email = user.Email
}
}

return email, nil
}

func updateDataForDate(calendar *configuration.BHCalendar, data *report.ScheduleUser, currentMonth time.Month, date time.Time) {
if date.Hour() < Config.RotationInfo.DailyRotationStartsAt {
newDate := date.Add(time.Hour * time.Duration(-(date.Hour() + 1))) // move to yesterday night to determine which kind of day it was
Expand Down
82 changes: 81 additions & 1 deletion cmd/generate_report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package cmd

import (
"errors"
"github.com/form3tech-oss/go-pagerduty-oncall-report/api"
"testing"
"time"

"github.com/form3tech-oss/go-pagerduty-oncall-report/api"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -148,6 +149,85 @@ func Test_pagerDutyClient_getUserTimezone(t *testing.T) {
}
}

func Test_pagerDutyClient_getUserEmailAddress(t *testing.T) {
tests := []struct {
name string
cachedUsers []*api.User
defaultUserTimezone string
mockSetup func(mock *clientMock)
want string
wantErr bool
}{
{
name: "Successfully find the user email address",
cachedUsers: []*api.User{
{
ID: "USER_ID",
Email: "[email protected]",
},
},
want: "[email protected]",
wantErr: false,
},
{
name: "User with empty email address will receive empty string",
cachedUsers: []*api.User{
{
ID: "USER_ID",
},
},
want: "",
wantErr: false,
},
{
name: "User not cached will receive empty email address",
cachedUsers: []*api.User{
{
ID: "NOT_THE_USER_ID",
},
},
want: "",
wantErr: false,
},
{
name: "If user not cached it will load users in cache and successfully return email address",
mockSetup: func(mock *clientMock) {
mock.On("ListUsers").Once().Return([]*api.User{
{ID: "USER_ID", Email: "[email protected]"},
}, nil)
},
want: "[email protected]",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockedClient := &clientMock{}
if tt.mockSetup != nil {
tt.mockSetup(mockedClient)
}

pd := pagerDutyClient{
client: mockedClient,
cachedUsers: tt.cachedUsers,
defaultUserTimezone: tt.defaultUserTimezone,
}

got, err := pd.getUserEmail("USER_ID")
mockedClient.AssertExpectations(t)

if tt.wantErr == true {
require.Error(t, err)
return
}

require.NoError(t, err)

assert.Equal(t, tt.want, got)
})
}
}

func Test_pagerDutyClient_convertToUserLocalTimezone(t *testing.T) {
tests := []struct {
name string
Expand Down
16 changes: 8 additions & 8 deletions report/console_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ type consoleReport struct {

const (
blankLine = ""
separator = " --------------------------------------------------------------------------------------------------------------------------------"
rowFormat = "| %-25s || %7v | %7v | %12v | %13v | %13v | %18v | %9v |"
separator = " ------------------------------------------------------------------------------------------------------------------------------------------"
rowFormat = "| %-35s || %7v | %7v | %12v | %13v | %13v | %18v | %9v |"
)

func NewConsoleReport(currency string) Writer {
Expand All @@ -36,7 +36,7 @@ func (r *consoleReport) GenerateReport(data *PrintableData) (string, error) {
fmt.Println(fmt.Sprintf("| Time Range: %s to %s", scheduleData.StartDate.Format(time.RFC822), scheduleData.EndDate.Format(time.RFC822)))
fmt.Println(separator)
fmt.Println(fmt.Sprintf(rowFormat, "USER", "WEEKDAY", "WEEKEND", "BANK HOLIDAY", "TOTAL WEEKDAY", "TOTAL WEEKEND", "TOTAL BANK HOLIDAY", "TOTAL"))
fmt.Println(fmt.Sprintf(rowFormat, "", "HOURS", "HOURS", "HOURS", "AMOUNT", "AMOUNT", "AMOUNT", "AMOUNT"))
fmt.Println(fmt.Sprintf(rowFormat, "EMAIL", "HOURS", "HOURS", "HOURS", "AMOUNT", "AMOUNT", "AMOUNT", "AMOUNT"))
fmt.Println(fmt.Sprintf(rowFormat, "", "DAYS", "DAYS", "DAYS", "", "", "", ""))
fmt.Println(separator)

Expand All @@ -53,21 +53,21 @@ func (r *consoleReport) GenerateReport(data *PrintableData) (string, error) {
fmt.Sprintf("%s%v", r.currency, userData.TotalAmountWeekendHours),
fmt.Sprintf("%s%v", r.currency, userData.TotalAmountBankHolidaysHours),
fmt.Sprintf("%s%v", r.currency, userData.TotalAmount)))
fmt.Println(fmt.Sprintf(rowFormat, "_________________________",
fmt.Println(fmt.Sprintf(rowFormat, userData.EmailAddress,
fmt.Sprintf("%.1f d", userData.NumWorkDays),
fmt.Sprintf("%.1f d", userData.NumWeekendDays),
fmt.Sprintf("%.1f d", userData.NumBankHolidaysDays),
"_____________", "_____________", "__________________", "_________"))
fmt.Println(separator)
}
fmt.Println(separator)
}

fmt.Println("")
fmt.Println(separator)
fmt.Println("| Users summary")
fmt.Println(separator)
fmt.Println(fmt.Sprintf(rowFormat, "USER", "WEEKDAY", "WEEKEND", "BANK HOLIDAY", "TOTAL WEEKDAY", "TOTAL WEEKEND", "TOTAL BANK HOLIDAY", "TOTAL"))
fmt.Println(fmt.Sprintf(rowFormat, "", "HOURS", "HOURS", "HOURS", "AMOUNT", "AMOUNT", "AMOUNT", "AMOUNT"))
fmt.Println(fmt.Sprintf(rowFormat, "EMAIL", "HOURS", "HOURS", "HOURS", "AMOUNT", "AMOUNT", "AMOUNT", "AMOUNT"))
fmt.Println(fmt.Sprintf(rowFormat, "", "DAYS", "DAYS", "DAYS", "", "", "", ""))
fmt.Println(separator)

Expand All @@ -84,13 +84,13 @@ func (r *consoleReport) GenerateReport(data *PrintableData) (string, error) {
fmt.Sprintf("%s%v", r.currency, userData.TotalAmountWeekendHours),
fmt.Sprintf("%s%v", r.currency, userData.TotalAmountBankHolidaysHours),
fmt.Sprintf("%s%v", r.currency, userData.TotalAmount)))
fmt.Println(fmt.Sprintf(rowFormat, "_________________________",
fmt.Println(fmt.Sprintf(rowFormat, userData.EmailAddress,
fmt.Sprintf("%.1f d", userData.NumWorkDays),
fmt.Sprintf("%.1f d", userData.NumWeekendDays),
fmt.Sprintf("%.1f d", userData.NumBankHolidaysDays),
"_____________", "_____________", "__________________", "_________"))
fmt.Println(separator)
}
fmt.Println(separator)

return "", nil
}
4 changes: 2 additions & 2 deletions report/csv_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (r *csvReport) GenerateReport(data *PrintableData) (string, error) {
fmt.Println(fmt.Sprintf("| Generating report(s) from '%s' to '%s'", data.Start.Format("Mon Jan _2 15:04:05 2006"), data.End.Add(time.Second*-1).Format("Mon Jan _2 15:04:05 2006")))
fmt.Println(separator)

header := []string{"User",
header := []string{"User", "Email",
"Weekday Hours", "Weekday Days", "Weekend Hours", "Weekend Days", "Bank Holiday Hours", "Bank Holiday Days",
"Total Weekday Amount (" + r.currency + ")", "Total Weekend Amount (" + r.currency + ")",
"Total Bank Holiday Amount (" + r.currency + ")", "Total Amount (" + r.currency + ")"}
Expand Down Expand Up @@ -120,7 +120,7 @@ func (r *csvReport) writeSingleRotation(scheduleData *ScheduleData, data *Printa
}

func writeUser(userData *ScheduleUser, w *csv.Writer) error {
dat := []string{userData.Name,
dat := []string{userData.Name, userData.EmailAddress,
fmt.Sprintf("%v", userData.NumWorkHours),
fmt.Sprintf("%.1f", userData.NumWorkDays),
fmt.Sprintf("%v", userData.NumWeekendHours),
Expand Down
32 changes: 18 additions & 14 deletions report/pdf_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

const (
matrixRowFormat = "%-23s %8v %8v %11v %10v %10v %13v %9v"
matrixRowFormat = "%-40s %8v %8v %10v %8v %8v %12v %10v"
)

type pdfReport struct {
Expand Down Expand Up @@ -57,7 +57,11 @@ func (r *pdfReport) GenerateReport(data *PrintableData) (string, error) {

pdf.SetFont("Arial", "B", 13)
pdf.CellFormat(0, 5,
fmt.Sprintf(" Schedule: '%s' (%s)", scheduleData.Name, scheduleData.ID),
fmt.Sprintf(" Schedule name: '%s'", scheduleData.Name),
"L", 0, "L", false, 0, "")
pdf.Ln(8)
pdf.CellFormat(0, 5,
fmt.Sprintf(" Schedule ID: %s", scheduleData.ID),
"L", 0, "L", false, 0, "")
pdf.Ln(8)

Expand All @@ -66,21 +70,21 @@ func (r *pdfReport) GenerateReport(data *PrintableData) (string, error) {
"L", 0, "L", false, 0, "")
pdf.Ln(8)

pdf.SetFont("Courier", "B", 9)
pdf.SetFont("Courier", "B", 8)
pdf.CellFormat(0, 5,
fmt.Sprintf(matrixRowFormat, "USER", "WEEKDAY", "WEEKEND", "B. HOLIDAY", "WEEKDAY", "WEEKEND", "B. HOLIDAY", "TOTAL"),
"", 0, "L", false, 0, "")
pdf.Ln(3)
pdf.CellFormat(0, 5,
fmt.Sprintf(matrixRowFormat, "", "HOURS", "HOURS", "HOURS", "AMOUNT", "AMOUNT", "AMOUNT", "AMOUNT"),
fmt.Sprintf(matrixRowFormat, "EMAIL", "HOURS", "HOURS", "HOURS", "AMOUNT", "AMOUNT", "AMOUNT", "AMOUNT"),
"", 0, "L", false, 0, "")
pdf.Ln(3)
pdf.CellFormat(0, 5,
fmt.Sprintf(matrixRowFormat, "", "DAYS", "DAYS", "DAYS", "", "", "", ""),
"B", 0, "L", false, 0, "")
pdf.Ln(5)

pdf.SetFont("Courier", "", 9)
pdf.SetFont("Courier", "", 8)

sort.Slice(scheduleData.RotaUsers, func(i, j int) bool {
return strings.Compare(scheduleData.RotaUsers[i].Name, scheduleData.RotaUsers[j].Name) < 1
Expand All @@ -99,12 +103,12 @@ func (r *pdfReport) GenerateReport(data *PrintableData) (string, error) {
"", 0, "L", false, 0, "")
pdf.Ln(3)
pdf.CellFormat(0, 5,
fmt.Sprintf(matrixRowFormat, "_______________________",
fmt.Sprintf(matrixRowFormat, tr(userData.EmailAddress),
fmt.Sprintf("%.1f d", userData.NumWorkDays),
fmt.Sprintf("%.1f d", userData.NumWeekendDays),
fmt.Sprintf("%.1f d", userData.NumBankHolidaysDays),
"__________", "__________", "_____________", "_________"),
"", 0, "L", false, 0, "")
"", "", "", ""),
"B", 0, "L", false, 0, "")
pdf.Ln(5)
}

Expand All @@ -118,13 +122,13 @@ func (r *pdfReport) GenerateReport(data *PrintableData) (string, error) {
"L", 0, "L", false, 0, "")
pdf.Ln(8)

pdf.SetFont("Courier", "B", 9)
pdf.SetFont("Courier", "B", 8)
pdf.CellFormat(0, 5,
fmt.Sprintf(matrixRowFormat, "USER", "WEEKDAY", "WEEKEND", "B. HOLIDAY", "WEEKDAY", "WEEKEND", "B. HOLIDAY", "TOTAL"),
"", 0, "L", false, 0, "")
pdf.Ln(3)
pdf.CellFormat(0, 5,
fmt.Sprintf(matrixRowFormat, "", "HOURS", "HOURS", "HOURS", "AMOUNT", "AMOUNT", "AMOUNT", "AMOUNT"),
fmt.Sprintf(matrixRowFormat, "EMAIL", "HOURS", "HOURS", "HOURS", "AMOUNT", "AMOUNT", "AMOUNT", "AMOUNT"),
"", 0, "L", false, 0, "")
pdf.Ln(3)
pdf.CellFormat(0, 5,
Expand All @@ -136,7 +140,7 @@ func (r *pdfReport) GenerateReport(data *PrintableData) (string, error) {
return strings.Compare(data.UsersSchedulesSummary[i].Name, data.UsersSchedulesSummary[j].Name) < 1
})

pdf.SetFont("Courier", "", 9)
pdf.SetFont("Courier", "", 8)
for _, userData := range data.UsersSchedulesSummary {
pdf.CellFormat(0, 5,
fmt.Sprintf(matrixRowFormat, tr(userData.Name),
Expand All @@ -150,12 +154,12 @@ func (r *pdfReport) GenerateReport(data *PrintableData) (string, error) {
"", 0, "L", false, 0, "")
pdf.Ln(3)
pdf.CellFormat(0, 5,
fmt.Sprintf(matrixRowFormat, "_______________________",
fmt.Sprintf(matrixRowFormat, tr(userData.EmailAddress),
fmt.Sprintf("%.1f d", userData.NumWorkDays),
fmt.Sprintf("%.1f d", userData.NumWeekendDays),
fmt.Sprintf("%.1f d", userData.NumBankHolidaysDays),
"__________", "__________", "_____________", "_________"),
"", 0, "L", false, 0, "")
"", "", "", ""),
"B", 0, "L", false, 0, "")
pdf.Ln(5)
}

Expand Down
1 change: 1 addition & 0 deletions report/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type ScheduleData struct {

type ScheduleUser struct {
Name string
EmailAddress string
NumWorkHours float32
NumWorkDays float32
TotalAmountWorkHours float32
Expand Down

0 comments on commit faead79

Please sign in to comment.