Private/JournalMetadata.ps1
|
# Helpers for arbitrary company metadata stored as "Key: Value" lines in a # journal's journal.txt. Well-known fields (Name, OrgNumber) have dedicated # parameters and are handled explicitly; everything else is free-form metadata. # Fields that have first-class parameters / handling and must not be set through # the generic -Metadata channel. $script:LedgerReservedJournalKeys = @('Name', 'OrgNumber', 'SchemaVersion', 'CompanyType') # Allowed values for the CompanyType journal field (Swedish company forms): # AB = aktiebolag, EF = enskild firma, HB = handelsbolag, KB = kommanditbolag. $script:LedgerCompanyTypes = @('AB', 'EF', 'HB', 'KB') # Default equity account the net result is booked to at year-end, per company # form. Forms without an entry require an explicit -EquityAccount at closing. $script:LedgerDefaultEquityAccounts = @{ AB = '2099' EF = '2019' } function Test-LedgerCompanyType { <# .SYNOPSIS Validates a journal company type against the allowed set, throwing if invalid. .DESCRIPTION CompanyType is a first-class journal field that drives year-end defaults (for example which equity account the net result is booked to). Only the fixed set of supported Swedish company forms is accepted. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$CompanyType ) if ($script:LedgerCompanyTypes -notcontains $CompanyType) { throw "Invalid company type '$CompanyType'. Allowed values: $($script:LedgerCompanyTypes -join ', ')." } } function Resolve-LedgerEquityAccount { <# .SYNOPSIS Returns the default equity account a year-end result is booked to, based on the journal's CompanyType. .DESCRIPTION Reads the journal's CompanyType and maps it to the equity account the net result is transferred to (see $script:LedgerDefaultEquityAccounts). Throws a helpful error when the company form has no default (HB, KB) or the journal has no CompanyType, prompting the caller to pass an explicit equity account. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$JournalPath ) $journal = Get-LedgerJournal -Path $JournalPath $companyType = $journal.CompanyType if ($companyType -and $script:LedgerDefaultEquityAccounts.ContainsKey($companyType)) { return $script:LedgerDefaultEquityAccounts[$companyType] } if ($companyType) { throw "Cannot determine a default equity account for company type '$companyType'. Specify -EquityAccount." } throw "Cannot determine the equity account: the journal has no CompanyType. Set one with Set-LedgerJournal -CompanyType, or specify -EquityAccount." } function Resolve-LedgerResultCarryAccount { <# .SYNOPSIS Returns the equity account a not-yet-booked year-end result is carried into when copying opening balances, based on the journal's CompanyType. .DESCRIPTION Like Resolve-LedgerEquityAccount but never throws: when the CompanyType maps to a default equity account (AB -> 2099, EF -> 2019) that account is used; otherwise (HB, KB or a journal without a CompanyType) it falls back to 2099 (Årets resultat, aktiebolag) to preserve backward-compatible behaviour. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$JournalPath ) $journal = Get-LedgerJournal -Path $JournalPath $companyType = $journal.CompanyType if ($companyType -and $script:LedgerDefaultEquityAccounts.ContainsKey($companyType)) { return $script:LedgerDefaultEquityAccounts[$companyType] } return '2099' } function Test-LedgerMetadataKey { <# .SYNOPSIS Validates a journal metadata key, throwing if it is reserved or malformed. .DESCRIPTION Metadata is persisted as "Key: Value" lines, so keys must be simple identifiers (start with a letter; letters, digits and underscores only) to keep the plain-text format unambiguous. Reserved keys are rejected with a hint to use the dedicated parameter instead. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$Key ) if ($Key -notmatch '^[A-Za-z][A-Za-z0-9_]*$') { throw "Invalid metadata key '$Key'. Keys must start with a letter and contain only letters, digits and underscores." } if ($script:LedgerReservedJournalKeys -contains $Key) { throw "'$Key' is a reserved journal field. Use the -$Key parameter instead of -Metadata." } } function Format-LedgerMetadataValue { <# .SYNOPSIS Normalises a metadata value so it occupies a single journal.txt line. #> [CmdletBinding()] param ( [Parameter()] [AllowNull()] [AllowEmptyString()] [string]$Value ) # Collapse tabs and line breaks so each field stays on a single line. return (ConvertTo-LedgerTextField $Value) } |