PsTimeTracking.psm1

#Region './Classes/1.class1.ps1' 0
class Class1
{
    [string]$Name = 'Class1'

    Class1()
    {
        #default Constructor
    }

    [String] ToString()
    {
        # Typo "calss" is intentional
        return ( 'This calss is {0}' -f $this.Name)
    }
}
#EndRegion './Classes/1.class1.ps1' 16
#Region './Classes/2.class2.ps1' 0
class Class2
{
    [string]$Name = 'Class2'

    Class2()
    {
        #default constructor
    }

    [String] ToString()
    {
        return ( 'This calss is {0}' -f $this.Name)
    }
}
#EndRegion './Classes/2.class2.ps1' 15
#Region './Classes/3.class11.ps1' 0
class Class11 : Class1
{
    [string]$Name = 'Class11'

    Class11 ()
    {
    }

    [String] ToString()
    {
        return ( 'This calss is {0}:{1}' -f $this.Name,'class1')
    }
}
#EndRegion './Classes/3.class11.ps1' 14
#Region './Classes/4.class12.ps1' 0
class Class12 : Class1
{
    [string]$Name = 'Class12'

    Class12 ()
    {
    }

    [String] ToString()
    {
        return ( 'This calss is {0}:{1}' -f $this.Name,'class1')
    }
}
#EndRegion './Classes/4.class12.ps1' 14
#Region './Public/Add-PstTime.ps1' 0
<#
.SYNOPSIS
Adds a chunk of time to the day so far.

.DESCRIPTION
Adds a chunk of time to the day so far.

.PARAMETER Client
The client to add time to.

.PARAMETER Project
The project to add time to.

.PARAMETER Minutes
The number of minutes to add.

.PARAMETER StartTime
If provided this will be added to the day summary.

.EXAMPLE
PS> Add-PstTime -Client ClientA -Project BigProject -Minutes 60

Adds 60 mins to the day so far for ClientA - BigProject.

#>


function Add-PstTime {
    param (

        $Client,

        $Project,

        $Minutes,

        $StartTime
    )
    Clear-Host

    Write-host ('Adding {0} minutes for {1} - {2}' -f $Minutes, $Client, $Project)

    [Array]$TodaysWork = Restore-Pstday

    $Addtime = $Client | Select-Object  @{l='Client';e={$Client}},@{l='Project';e={$Project}},@{l='StartTime';e={$StartTime}}, @{l='Elapsed';e={New-TimeSpan -Minutes $Minutes}}
    $Addtime | Format-Table -AutoSize | Out-String | Write-Host  -ForegroundColor White
    $TodaysWork += $AddTime

    # backup the day so far just in case
    Backup-PstDay -TodaysWork $TodaysWork

    # Output day summary
    Get-PstDaySummary

}
#EndRegion './Public/Add-PstTime.ps1' 55
#Region './Public/Backup-PstDay.ps1' 0
<#
.SYNOPSIS
Backups the day so far to a json file in the local appdata folder.

.DESCRIPTION
backups the day so far to a json file in the local appdata folder.

This is used to restore the day so far if the script is closed.

.PARAMETER TodaysWork
The day so far to backup.

.EXAMPLE
PS> Backup-PstDay -TodaysWork $TodaysWork

Backups the day so far to a json file in the local appdata folder.

#>

function Backup-PstDay {
    param (
        [parameter(ValueFromPipeline=$true, Mandatory)]
        $TodaysWork
    )
    $folder = Join-Path $env:localappdata 'PstTimeTracker'

    if (!(Test-Path $folder)) {
        New-Item $folder -ItemType Directory | Out-Null
    }

    if($TodaysWork) {

        $fileName = Join-Path $folder ('todayswork-{0}.json' -f (Get-Date -Format 'yyyy-MM-dd'))
        $TodaysWork | Select-Object Client, Project, StartTime, @{l='ElapsedTotalSeconds';e={$_.Elapsed.TotalSeconds}} | ConvertTo-Json | Out-File $fileName
    }

    # remove json files older than 10 days
    Get-ChildItem $folder *.json | where-object lastWriteTime -lt (get-date).AddDays(-10) | Remove-Item
}
#EndRegion './Public/Backup-PstDay.ps1' 39
#Region './Public/Get-PstDaySummary.ps1' 0
<#
.SYNOPSIS
Gets the day summary.

.DESCRIPTION
Gets the day summary.

If a date is provided it will restore the day so far from the json file in the local appdata folder and display the summary.

.PARAMETER date
If provided this will restore the specified day from the json file in the local appdata folder and display the summary.

.EXAMPLE
PS> Get-PstDaySummary

This will display the day summary for the day so far.

.EXAMPLE
PS> Get-PstDaySummary -date 2023-01-01

This will restore the json from the local appdata folder for 2023-01-01 and display the summary.

#>

function Get-PstDaySummary {
    param (
        $date
    )

    if($date) {
        $RestoredWork = Restore-PstDay -date $date

        [Array]$results = $RestoredWork | Group-Object Client, Project | Select-Object Name, @{l='Total';e={New-TimeSpan -Seconds (($_.Group.Elapsed.TotalSeconds | Measure-Object -sum ).sum)}}
        $results += [PSCustomObject]@{
            Name = '===Total'
            Total = New-TimeSpan -Seconds ($RestoredWork | Select-Object @{l='TotalSecs';e={$_.elapsed.TotalSeconds}} | Measure-object -Property TotalSecs -Sum).Sum
        }
        $results | Out-String | Write-Host  -ForegroundColor White

    } else {
        $TodaysWork = Restore-PstDay

        if($TodaysWork) {

            Write-Host '--------------------------' -ForegroundColor DarkGreen -BackgroundColor White
            Write-Host 'So far today: ' -ForegroundColor DarkGreen -BackgroundColor White
            Write-Host '--------------------------' -ForegroundColor DarkGreen -BackgroundColor White

            [Array]$results = $TodaysWork | Group-Object Client, Project | Select-Object Name, @{l='Total';e={New-TimeSpan -Seconds (($_.Group.Elapsed.TotalSeconds | Measure-Object -sum ).sum)}}
            $results += [PSCustomObject]@{
                Name = '===Total'
                Total = New-TimeSpan -Seconds ($TodaysWork | Select-Object @{l='TotalSecs';e={$_.elapsed.TotalSeconds}} | Measure-object -Property TotalSecs -Sum).Sum
            }
            $results | Out-String | Write-Host  -ForegroundColor White
        } else {
            Write-Host 'Nothing recorded yet...' -ForegroundColor DarkRed -BackgroundColor White
        }
    }

}
#EndRegion './Public/Get-PstDaySummary.ps1' 60
#Region './Public/Restore-PstDay.ps1' 0
<#
.SYNOPSIS
Restores the day so far from the json file in the local appdata folder.

.DESCRIPTION
Restores the day so far from the json file in the local appdata folder.

This is used to restore the day so far if the script is closed.

.PARAMETER date
If provided this will restore the specified day from the json file in the local appdata folder.

.EXAMPLE
PS> Restore-PstDay

This will restore the day so far from the json file in the local appdata folder.

.EXAMPLE
PS> Restore-PstDay -date 2023-01-01

This will restore the json from the local appdata folder for 2023-01-01.

#>

function Restore-PstDay {
    param (
        $date = (Get-Date).Date
    )

    $folder = Join-Path $env:localappdata 'PstTimeTracker'

    $fileName = Join-Path $folder ('todayswork-{0}.json' -f (Get-Date($date) -Format 'yyyy-MM-dd'))

    if (Test-Path $fileName) {

        Get-Content $fileName | ConvertFrom-Json | Select-Object Client, Project, StartTime, @{l='Elapsed';e={New-TimeSpan -Seconds $_.ElapsedTotalSeconds}}
    }
}
#EndRegion './Public/Restore-PstDay.ps1' 38
#Region './Public/Start-PstDay.ps1' 0
<#
.SYNOPSIS
Starts the day.

.DESCRIPTION
Starts the day.

Restore the day so far from the json file in the local appdata folder if it exists.

.EXAMPLE
PS> Start-PstDay

This will start the day and restore the day so far from the json file in the local appdata folder if it exists.

#>

function Start-PstDay {

    [Array]$TodaysWork = Restore-PstDay

}
#EndRegion './Public/Start-PstDay.ps1' 21
#Region './Public/Start-PstTimer.ps1' 0
<#
.SYNOPSIS
Starts a timer for a client and project.

.DESCRIPTION
Starts a timer for a client and project.

.PARAMETER Client
Client to track time against.

.PARAMETER Project
Project to track time against.

.EXAMPLE
PS> Start-PstTimer -Client ClientA -Project BigProject

This will start a timer for ClientA - BigProject.

#>

function Start-PstTimer {
    param (
        $Client,

        $Project
    )
    Clear-Host

    $startTime = (Get-Date)

    $timer = New-Object System.Diagnostics.Stopwatch
    $timer.Start()

    [Array]$TodaysWork = Restore-PstDay

    if($TodaysWork) {
        # Output day summary
        Get-PstDaySummary
    }

    $null = Read-host ('Working on {0} - {1}, since {2} - Press any key to stop?' -f $Client, $Project, $startTime)

    $timer.Stop()

    Write-Host '--------------------------' -ForegroundColor DarkMagenta -BackgroundColor White
    Write-Host 'Just worked on: ' -ForegroundColor DarkMagenta -BackgroundColor White
    Write-Host '--------------------------' -ForegroundColor DarkMagenta -BackgroundColor White

    $Addtime = $timer | Select-Object  @{l='Client';e={$Client}},@{l='Project';e={$Project}},@{l='StartTime';e={$startTime}},  Elapsed
    $Addtime | Format-Table -AutoSize | Out-String | Write-Host  -ForegroundColor White
    $TodaysWork += $AddTime

    # backup the day so far just in case
    Backup-PstDay -TodaysWork $TodaysWork

    # Output day summary
    Get-PstDaySummary

}
#EndRegion './Public/Start-PstTimer.ps1' 59