Modules/businessdev.ALbuild.Apps/Public/Get-BcTranslationUnit.ps1

function Get-BcTranslationUnit {
    <#
    .SYNOPSIS
        Lists the translation units of an AL XLIFF file as structured objects (the read surface behind
        `albuild translation list`).
 
    .DESCRIPTION
        Projects each trans-unit to { id, source, developerNote, context (Xliff-Generator note),
        currentTarget, state, tmOrigin } using the shared Get-BcXliffUnit reader. This is the stable input
        a consumer uses to translate the remaining open strings. -OnlyMissing returns just the units that
        still need a translation (empty target or a needs-translation/-adaptation state); -State filters by
        an explicit target state.
 
    .PARAMETER Path
        The XLIFF file to read.
 
    .PARAMETER OnlyMissing
        Return only units that still need a translation.
 
    .PARAMETER State
        Return only units whose target state equals this value.
 
    .OUTPUTS
        PSCustomObject per unit: { id, source, developerNote, context, currentTarget, state, tmOrigin }.
    #>

    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Path,
        [switch] $OnlyMissing,
        [string] $State
    )

    if (-not (Test-Path -LiteralPath $Path)) { throw "XLIFF file not found: '$Path'." }
    [xml] $doc = Get-Content -LiteralPath $Path -Raw -Encoding UTF8

    foreach ($u in (Get-BcXliffUnit -Document $doc)) {
        $isMissing = [string]::IsNullOrWhiteSpace($u.Target) -or ($u.TargetState -in @('needs-translation', 'needs-adaptation'))
        if ($OnlyMissing -and -not $isMissing) { continue }

        $effectiveState = if ($u.TargetState) { $u.TargetState }
        elseif ([string]::IsNullOrWhiteSpace($u.Target)) { 'needs-translation' }
        else { 'translated' }
        if ($State -and ($effectiveState -ne $State)) { continue }

        $tmOrigin = $null
        foreach ($n in @($u.UnitNode.SelectNodes(".//*[local-name()='note']"))) {
            if ($n.Attributes) {
                foreach ($a in $n.Attributes) {
                    if ($a.Name -ieq 'from-tool' -and $a.Value -eq 'albuild-tm') { $tmOrigin = $n.InnerText }
                }
            }
        }

        [PSCustomObject]@{
            id            = $u.Id
            source        = $u.Source
            developerNote = $u.DevNote
            context       = $u.GenNote
            currentTarget = $u.Target
            state         = $effectiveState
            tmOrigin      = $tmOrigin
        }
    }
}