Orders.psm1

<#
.SYNOPSIS
    This function places an order of Tech Data products for a Tech Data end customer.
.DESCRIPTION
    This function places an order of Tech Data products for a Tech Data end customer.
    It returns the order information if it has been placed successfully, null otherwise.
.PARAMETER apiHeaders
    The TechData API headers generated by Get-TechDataRestApiHeaders.
.PARAMETER environment
    The environment to which the call will be made, either production or test.
#>

function New-TechDataOrder {
    param (
        # The Tech Data API headers generated by Get-TechDataRestApiHeaders.
        [Parameter(Mandatory=$false, ValueFromPipeline=$true)]
        [ValidateNotNull()]
        $apiHeaders = $Global:TechDataApiHeaders,

        # The Reseller purchase order number for the order.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$resellerPONumber,

        # The Customer purchase order number for the order.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$customerPONumber,

        # The Tech Data end customer ID.
        [Parameter(Mandatory=$true)]
        $customerID,

        # A list of the Tech Data product SKUs, quantities, and additional data.
        [Parameter(Mandatory=$true)]
        [Object[]]$productList,

        # The payment method.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$paymentMethod,

        # The first name of the logged on reseller user.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$resellerUserFirstName,

        # The last name of the logged on reseller.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$resellerUserLastName,

        # The environment to which the call will be made, either production or test.
        [Parameter(Mandatory=$false)]
        [ValidateSet("production", "test")]
        [String]$environment = "test"
    )

    try {
        # Set the protocol to TLS 1.2
        [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12

        # Retrieve the URL
        $url = Get-TechDataApiEndpointUrl -NewOrder -Environment $environment

        # Set up the REST call body in JSON format
        $body = @{
            placeOrders = @(@{
                poNumber        = $resellerPONumber
                endCustomer     = [PSCustomObject]@{
                    id                  = $customerID
                    customerPoNumber    = $customerPONumber
                }
                lines           = $productList
                paymentMethod   = [PSCustomObject]@{
                    type                = $paymentMethod
                }
                metaData        = [PSCustomObject]@{
                    firstName           = $resellerUserFirstName
                    lastName            = $resellerUserLastName
                    isEndCustomer       = $true
                }
            })
        } | ConvertTo-Json -Depth 10

        # Try to call the API
        $response = Invoke-RestMethodWithRetry -Uri $url -Headers $apiHeaders -Body $body -Method "POST" -IntervalMilliseconds 500 -MaximumNumberOfCalls 20 -ReturnUnsuccessfulResponseObject
        if (!$response) {
            return $null
        }

        # Check if call was a success
        if ($response.Result -eq "Failed") {
            Write-Error "API call failed with key $($response.Key), error code $($response.ErrorCode) and error message '$($response.ErrorMessage)'."
            return $null
        }

        # Return the order information
        return $response.BodyText.PlaceOrdersDetails
    }
    catch {
        Write-Error "Exception occurred on line $($_.InvocationInfo.ScriptLineNumber): `r`n$($_.Exception.Message)"
        return $null
    }
}