Public/Add-LedgerTimeEntry.ps1
|
<# .SYNOPSIS Reports time (tidrapportering) on a project or customer. .DESCRIPTION Adds a time entry to the journal's time/yyyy-MM.txt file for the month of the date. The customer follows the project. The hourly rate is resolved when the entry is registered and stored on it: -Rate, otherwise the project's rate, otherwise the customer's rate. Later rate changes therefore do not change time already reported. Time on an internal project (without a customer) is never billable. Billable time is invoiced with New-LedgerTimeInvoice. .PARAMETER JournalPath The path to an existing journal directory. If omitted, uses the current journal set via Set-LedgerCurrentJournal. .PARAMETER Hours The number of hours, as a decimal (7.5 or '7,5') or a duration ('7:30'). Must be greater than 0 and at most 24. .PARAMETER ProjectNumber The project number. Either -ProjectNumber or -CustomerNumber is required. .PARAMETER CustomerNumber The customer, for time that is not reported on a project. .PARAMETER Date The date the work was done. Defaults to today. .PARAMETER ResourceId The resource (person) who did the work. Defaults to the default resource (see Add-LedgerTimeResource). .PARAMETER Text Optional description of the work. .PARAMETER NonBillable Registers the time as not billable (e.g. warranty work or internal meetings on a customer project). .PARAMETER Rate Overrides the hourly rate for this entry. .PARAMETER PassThru Returns the created entry. .EXAMPLE Add-LedgerTimeEntry 7.5 -ProjectNumber 1001 Reports 7.5 hours today on project 1001 for the default resource. .EXAMPLE Add-LedgerTimeEntry '3:45' -ProjectNumber 1001 -Date 2024-03-12 -ResourceId BK -Text 'Workshop kravställning' Add-LedgerTimeEntry 1 -ProjectNumber 1001 -Date 2024-03-12 -NonBillable -Text 'Felrättning under garanti' Reports a subcontractor's workshop and an hour of non-billable warranty work. #> function Add-LedgerTimeEntry { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter()] [string]$JournalPath, [Parameter(Mandatory, Position = 0)] [string]$Hours, [Parameter()] [string]$ProjectNumber, [Parameter()] [string]$CustomerNumber, [Parameter()] [datetime]$Date = (Get-Date).Date, [Parameter()] [string]$ResourceId, [Parameter()] [string]$Text, [Parameter()] [switch]$NonBillable, [Parameter()] [ValidateRange(0, 1000000)] [decimal]$Rate, [Parameter()] [switch]$PassThru ) $JournalPath = Resolve-LedgerJournalPath -JournalPath $JournalPath -SchemaCheck Write $h = ConvertFrom-LedgerHours -Text $Hours Test-LedgerHours -Hours $h $context = Get-LedgerTimeContext -JournalPath $JournalPath $rateArg = if ($PSBoundParameters.ContainsKey('Rate')) { $Rate } else { $null } $target = Resolve-LedgerTimeEntryTarget -Context $context -ResourceId $ResourceId -ProjectNumber $ProjectNumber ` -CustomerNumber $CustomerNumber -Billable (-not $NonBillable) -Rate $rateArg $entries = @(Read-LedgerTimeEntries -JournalPath $JournalPath) $nextId = if ($entries) { ($entries | Measure-Object -Property EntryId -Maximum).Maximum + 1 } else { 1 } $entry = [PSCustomObject]@{ EntryId = [int]$nextId Date = $Date.Date ResourceId = $target.ResourceId ProjectNumber = $target.ProjectNumber CustomerNumber = $target.CustomerNumber Hours = $h Billable = $target.Billable Rate = $target.Rate Text = ConvertTo-LedgerTimeField $Text InvoiceNumber = $null } $what = if ($target.ProjectNumber) { "project $($target.ProjectNumber)" } else { "customer $($target.CustomerNumber)" } if ($PSCmdlet.ShouldProcess("$($Date.ToString('yyyy-MM-dd')) $($target.ResourceId)", "Report $h h on $what")) { Save-LedgerTimeEntries -JournalPath $JournalPath -Entries ($entries + $entry) -Months $Date.ToString('yyyy-MM') if ($PassThru) { ConvertTo-LedgerTimeEntryOutput -Entry $entry -Context $context -InvoiceStatus @{} } } } |