Public/New-MPCSystemAvtale.ps1

<#
.Synopsis
   Function for creating new MPC system contracts for Office Center Hønefoss AS.
.DESCRIPTION
   The cmdlet will take Autotask InstalledProduct entities (Configuration Items in GUI) with specific UDF values as input, validate that all required parameters exist, and create new MPC system contract (recurring service) with required contract services, adjustments and counter retainer contracts. Finally it will associate the InstalledProduct with the contract, add contract retainers and setup recurring tickets for counter readings.
.EXAMPLE
   $InstalledProduct | New-MPCSystemAvtale
 
   Will create the correct contracts, retainers and associate the InstalledProduct (Configuration Item) in $InstalledProduct, if all required fields on the InstalledProduct are filled in.
.INPUTS
   [Autotask.InstalledProduct]
.OUTPUTS
   None.
.NOTES
    These exact property values are required for contract creation:
    - $InstalledProduct.Type : 6
    - $InstalledProduct.UserDefinedFields : @{Ny kontrakt : Ja}
    - $InstalledProduct.UserDefinedFields : @{Kontraktstype : Systemavtale (klikkpris og fast månedspris)}
 
   The following $InstalledProduct properties are required for contract creation:
    - Location
    - SerialNumber
    - ServiceLevelAgreementID
    - UserDefinedFields:
        - Avtaleoppstart
        - Pris pr måned
        - Volum for farge
        - Klikkpris pr farge i øre
        - Volum for svart
        - Klikkpris pr svart i øre
 
.COMPONENT
   Autotask PSA.
#>

function New-MPCSystemAvtale
{
  [CmdletBinding(PositionalBinding=$true)]
  Param
  (
    # Autotask Installed Product entity (MPC)
    [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true,
    Position=0)]
    [ValidateScript({
          $p_udf = $_ | Get-AutotaskEntityUDFObject
          if($_.Location -and $_.SerialNumber -and $_.Type -eq 6 -and $p_udf.Avtaleoppstart -and $p_udf.Faktureringsintervall -and $p_udf.'Klikkpris farge (øre)' -and $p_udf.'Klikkpris sort/hvitt (øre)' -and $p_udf.'Volum for sort/hvitt' -and $p_udf.'Pris pr måned' -and $p_udf.'Volum for farge' -and $p_udf.'Avlesningsintervall')
          {
            $true
          }
    })]
    [Autotask.InstalledProduct]$printer,
        
    [Parameter(Mandatory=$false, 
        ValueFromPipeline=$false,
    Position=1)]
    [ValidateScript({
          Test-Path $_
    })]
    $logpath = 'C:\OCH-LOG'
  )
  # Oppretter loggvariabel og inputvariabel for å aktivere feilhåndtering
  $log = @()
  $ErrorHandling = @{
    ErrorVariable = '+err'
    ErrorAction = 'Stop'
  }
  $verbosemessage = "Henter innholdet i UDF til eget objekt"
  Write-Verbose $verbosemessage
  $t = $printer | Get-AutotaskEntityUDFObject
  $t.Avtaleoppstart = [datetime]$t.Avtaleoppstart
    
  $contractinfo = New-Object -TypeName PSObject -Property @{
    ReadingInterval = [int]$t.'Avlesningsintervall'
    InvoiceInterval = [int]$t.'Faktureringsintervall'
    DateOfAgreement = $t.Avtaleoppstart
    StartDate = Get-Date -Month 1 -Day 1 -Year $t.Avtaleoppstart.Year -Hour 0 -Minute 0 -Second 0 -Millisecond 0
    EndDate = Get-Date -Month 12 -Day 31 -Year $t.Avtaleoppstart.AddYears(3).Year -Hour 0 -Minute 0 -Second 0 -Millisecond 0
    PricePerMonth = [double]$t.'Pris pr måned'
    ColorRetainer = [double]$t.'Volum for farge'
    ColorClick = ($t.'Klikkpris farge (øre)')/100
    BwRetainer = $t.'Volum for sort/hvitt'
    BwClick = ($t.'Klikkpris sort/hvitt (øre)')/100
    AutotaskAccount = Get-AtwsAccount -id $printer.AccountID
    AutotaskAccountID = $($printer.AccountID)
    ColorAllocationCode = (Get-AtwsAllocationCode -ExternalNumber 'MPC_farge' -UseType 'Material Cost Code').id
    BWAllocationCode = (Get-AtwsAllocationCode -ExternalNumber 'MPC_sh' -UseType 'Material Cost Code').id
    SKU = (Get-AtwsProduct -id $printer.ProductID).SKU
    InvoicePeriod = ''
    ServiceID = 0
  }

  # Setter riktig faktureringsintervall
  if($t.Faktureringsintervall -eq 12){
    $contractinfo.InvoicePeriod = 'Yearly'
    $contractinfo.ServiceID = 317
  }
  elseif ($t.Faktureringsintervall -eq 6) {
    $contractinfo.InvoicePeriod = 'Semi-Annually'
    $contractinfo.ServiceID = 357
  }
  elseif ($t.Faktureringsintervall -eq 3) {
    $contractinfo.InvoicePeriod = 'Quarterly'
    $contractinfo.ServiceID = 380 
  }
  elseif ($t.Faktureringsintervall -eq 1) {
    $contractinfo.InvoicePeriod = 'Monthly'
    $contractinfo.ServiceID = 392
  }
  $verbosemessage = "Faktureringsintervall: $($contractinfo.InvoicePeriod) - ServiceID: $($contractinfo.ServiceID)"
  Write-Verbose $verbosemessage
   
  # Logg
  #$log += $contractinfo
  # Setter parametre for Recurring Service-kontrakt
  $rsc_parameters = @{
    AccountID = "$($contractinfo.AutotaskAccount.id)"
    BillingPreference = 'Manually'
    ContractCategory = 'Evatic'
    ContractName = 'MPC - Systemavtale - {0} - {1} - {2}' -f $contractinfo.AutotaskAccount.AccountName, $printer.SerialNumber, $printer.Location
    ContractPeriodType = "$($contractinfo.InvoicePeriod)"
    ContractType = 'Recurring Service'
    ContractNumber = "$($contractinfo.AutotaskAccount.AccountNumber)"
    EndDate = $contractinfo.EndDate
    EstimatedCost = 0
    EstimatedHours = 0
    EstimatedRevenue = 0
    ServiceLevelAgreementID = 'Responstid 8 timer'
    SetupFee = 0
    StartDate = $contractinfo.StartDate
    Status = 'Active'
    TimeReportingRequiresStartAndStopTimes = $True 
    UserDefinedFields = @{name = 'SerialNumber'; value = $printer.SerialNumber}
  }
  
  # Oppretter Recurring Service-kontrakt med tilhørende ContractServiceAdjustment
  $rsc = New-AtwsContract @rsc_parameters @ErrorHandling
  $verbosemessage ="Created contract: $($rsc.ContractName)"
  Write-Verbose $verbosemessage
  $log += $verbosemessage

  $csa_parameters = @{
    ContractID = $rsc.id
    ServiceId = $contractinfo.ServiceID
    EffectiveDate = $contractinfo.DateOfAgreement
    AdjustedUnitPrice = ($contractinfo.InvoiceInterval * $contractinfo.PricePerMonth)
    UnitChange = 1
  }
  
  $csa = New-AtwsContractServiceAdjustment @csa_parameters @ErrorHandling
  $verbosemessage = "Performed ContractServiceAdjustments: PriceChange $($csa_parameters.AdjustedUnitPrice), UnitChange $($csa_parameters.UnitChange)"
  Write-Verbose $verbosemessage
  $log += $verbosemessage
  
  # Assosierer Configuration Item med recurring servicekontrakt, setter SKU og printer location som søkbar info på Configuration Item og sørger for at kontrakten ikke skal lages enda en gang.
  $cs_parameters = @{
    ContractID = $rsc.id
    ServiceId = $contractinfo.ServiceID
  }

  $cs = Get-AtwsContractService @cs_parameters @ErrorHandling
  $verbosemessage = "Retrieved ContractService: UnitPrice $($cs.UnitPrice)"
  Write-Verbose $verbosemessage
  $log += $verbosemessage

  $printer_parameters = @{
    ContractID = $rsc.id
    ContractServiceID = $cs.id 
    ReferenceNumber = (Get-ATWSProduct -id $printer.ProductID).SKU
    ReferenceTitle = $printer.Location
  }
  $printer | Set-AtwsInstalledProduct @printer_parameters @ErrorHandling
  $verbosemessage ="Printer associated with contract: $($Printer.ContractID) and ContractService $($Printer.ContractServiceID)"
  Write-Verbose $verbosemessage -Verbose
  $log += $verbosemessage

  # Oppretter tellerverkskontrakter
  $rc_parameters = @{
    AccountID = $contractinfo.AutotaskAccount.id
    BillingPreference = 'Manually'  
    ContractCategory = 'Evatic'
    ContractType = 'Retainer'
    EndDate =  $contractinfo.EndDate
    EstimatedCost = 0
    EstimatedHours = 0
    EstimatedRevenue = 0
    ServiceLevelAgreementID = 'Responstid 8 timer'
    SetupFee = 0
    StartDate = $contractinfo.StartDate
    Status = 'Active'
    TimeReportingRequiresStartAndStopTimes = $True 
    UserDefinedFields = @{Name='SerialNumber';Value=$printer.SerialNumber}
  }
  $ColorContractName = @{
    ContractName = 'MPC - Tellerverk farge - {0} - {1} - {2}' -f $contractinfo.AutotaskAccount.AccountName, $printer.SerialNumber, $printer.Location
    SetupFeeAllocationCodeID = $contractinfo.ColorAllocationCode
  }
  $BWContractName = @{
    ContractName = 'MPC - Tellerverk sort/hvitt - {0} - {1} - {2}' -f $contractinfo.AutotaskAccount.AccountName, $printer.SerialNumber, $printer.Location
    SetupFeeAllocationCodeID = $contractinfo.BWAllocationCode
  }
  $colorrc = New-AtwsContract @rc_parameters @ColorContractName @ErrorHandling
  $verbosemessage ="Created contract: $($colorrc.ContractName)"
  Write-Verbose $verbosemessage
  $log += $verbosemessage

  $bwrc = New-AtwsContract @rc_parameters @BWContractName @ErrorHandling
  $verbosemessage ="Created contract: $($bwrc.ContractName)"
  Write-Verbose $verbosemessage
  $log += $verbosemessage

  # Oppretter ContractRetainers
  $cr_parameters = @{
    DatePurchased = $contractinfo.DateOfAgreement
    EndDate = $contractinfo.EndDate 
    StartDate =$contractinfo.DateOfAgreement
    Status = 'Active' 
  }
  $colorcr_parameters = @{
    Amount = $contractinfo.ColorClick * $contractinfo.ColorRetainer
    ContractID = $colorrc.id
  }
  $bwcr_parameters = @{
    Amount = $contractinfo.BwClick * $contractinfo.BwRetainer
    ContractID = $bwrc.id
  }
  $colorcr = New-AtwsContractRetainer @colorcr_parameters @cr_parameters @ErrorHandling
  $bwcr = New-AtwsContractRetainer @bwcr_parameters @cr_parameters @ErrorHandling
    
  $verbosemessage ="Created ContractRetainers: $($colorcr.id), $($colorcr.Amount) and $($bwcr.id), $($bwcr.Amount)"
  Write-Verbose $verbosemessage
  $log += $verbosemessage

  $oldtickets = Get-AtwsTicket -InstalledProductID $printer.id
  $oldtickets.Count
  #$oldtickets | Set-AtwsTicket -ContractID $rsc.id
  $verbosemessage ="Associated $($oldtickets.count) tickets with contract $($rsc.ContractName)."
  Write-Verbose $verbosemessage
  $log += $verbosemessage


  # Opprette recurring tickets for telleverksavlesninger
  $duedate = (Get-Date $contractinfo.DateOfAgreement.AddMonths($contractinfo.ReadingInterval) -Day 1)
  $k = 0
  while ($duedate -and $duedate -lt '2020-12-31 00:00:00'){
    $ticket_parameters = @{
      Title = "Tellerverksavlesning $($duedate.month)/$($duedate.Year) - $($printer.SerialNumber) - $($printer.Location)"
      AccountID = $contractinfo.AutotaskAccount.id 
      DueDateTime = $duedate
      InstalledProductID = $printer.id 
      TicketCategory = 'MPC'            
      QueueID = 'Recurring Tickets' 
      SubIssueType = 'Printer/MFC'
      TicketType = 'Service Request' 
      Status = 'New' 
      Priority = 'Medium'
      IssueType = 'Endring' 
      Source = 'PowerShell'
    }
                        
    $ticket = New-AtwsTicket @ticket_parameters @ErrorHandling 
    $duedate = $duedate.AddMonths($contractinfo.ReadingInterval)
    $k++
  }
  $verbosemessage = "Opprettet $($k) recurring tickets for tellerverksavlesninger."
  Write-Verbose $verbosemessage -Verbose
  $log += $verbosemessage
    

  if($err.count -eq 0){
    $printer | Set-AtwsInstalledProduct -UserDefinedFields @{name = 'Kontraktsstatus'; value = 'opprettet'}
    $printer | Set-AtwsInstalledProduct -UserDefinedFields @{name = 'Tellerverk sort/hvitt' ; value = 1 }
    $printer | Set-AtwsInstalledProduct -UserDefinedFields @{name = 'Tellerverk farge' ; value = 1 }
    $LastModifiedDate =  Get-Date -format "yyyy-MM-dd" 
    $printer | Set-AtwsInstalledProduct -UserDefinedFields @{name = 'ATWSAPI-LastModifiedDate'; value = $LastModifiedDate}
    $log | Out-File "$logpath\$(Get-Date -format "yyyy-MM-dd__HH.mm.ss")__$($printer.SerialNumber).log" 
  }
  else {
    $time = Get-Date -format "yyyy-MM-dd__HH.mm.ss"
    $log | Out-File "$logpath\$($time)__$($printer.SerialNumber) - with errors.log"
    $err | Out-File "$logpath\$($time)__$($printer.SerialNumber)__error.log"
    Clear-Variable $err 
  }
}