Search

Index

Revindex Storefront

Shipwire export order (Powershell)

Last updated on 2015-04-17 13 mins. to read

The following script will export orders to Shipwire for fulfilling.

# ShipwireFulfillment.ps1
#
# This script will export all pending orders that needs to be fulfilled
# by Shipwire.
# It will mark the SalesOrderDetail object as shipped and the entire
# SalesOrder as completed when every order detail has been fulfilled.
######################################################################




# Configuration
######################################################################


$APIKey = '00000000-0000-0000-0000-000000000000'
$APIUrl = 'http://domain.com/DesktopModules/Revindex.Dnn.RevindexStorefront/Api/Rest/V1/ServiceHandler.ashx?portalid=0'
$APIUsername = 'host'


# Number of days to look back at orders
$BackOrderDays = -7


$LogFileName = ('Log.' + [DateTime]::Now.ToString('yyyyMMdd') + '.txt')


$NetworkTimeout = 30000


# The email(s) to notify on success/error. Separated multiple emails by semicolon.
$NotificationRecipient = 'support@localhost.com'


$NotificationSender = 'support@localhost.com'


# The platform or software which is referring this order.
$ShipwireReferer = ''


$ShipwirePassword = 'nokuwi'


# Enter the word 'Test' if you wish to run a test but not send orders for fulfillment. Leave blank in production.
$ShipwireTest = 'Test'


$ShipwireUsername = 'testuser'


$SMTPPassword = 'xxxxxx'
$SMTPServer = 'mail.localhost.com'
$SMTPUser = 'mailer'


# The folder to store files, logs, etc. defaults to the current execution path
$WorkingFolder = ((Split-Path $MyInvocation.MyCommand.Path) + '\')




# Functions
######################################################################




# Function to help post HTTP request to web service
Function PostWebRequest([String] $url, [String] $data, [int] $timeout)
{    
    $buffer = [System.Text.Encoding]::UTF8.GetBytes($data)
    [System.Net.HttpWebRequest] $webRequest = [System.Net.WebRequest]::Create($url)
    $webRequest.Timeout = $timeout
    $webRequest.Method = "POST"
    $webRequest.ContentType = "application/x-www-form-urlencoded"
    $webRequest.ContentLength = $buffer.Length;


    $requestStream = $webRequest.GetRequestStream()
    $requestStream.Write($buffer, 0, $buffer.Length)
    $requestStream.Flush()
    $requestStream.Close()


    [System.Net.HttpWebResponse] $webResponse = $webRequest.GetResponse()
    $streamReader = New-Object System.IO.StreamReader($webResponse.GetResponseStream())
    $result = $streamReader.ReadToEnd()
    return $result
}




# Function to send email
Function SendEmail([String]$smtpServer, [String] $smtpUser, [String] $smtpPassword, [String] $sender, [String] $recipient, [String] $subject, [String] $body, [String] $attachment)
{
    $msg = New-Object System.Net.Mail.MailMessage
    $msg.From = $sender
    $msg.ReplyTo = $sender
    
    foreach ($r in $recipient.Split(';'))
    {
        if ($r)
        {
            $msg.To.Add($r)
        }
    }
    $msg.subject = $subject
    $msg.body = $body
    
    if ($attachment -and [System.IO.File]::Exists($attachment))
    {
        $att = New-Object System.Net.Mail.Attachment($attachment)
        $msg.Attachments.Add($att)
    }


    $smtp = New-Object System.Net.Mail.SmtpClient($smtpServer)
    $smtp.Credentials = New-Object System.Net.NetworkCredential($smtpUser, $smtpPassword);
    $smtp.Send($msg)
}




# Start program
######################################################################




Try
{    
$xShipRequest = [Xml] "<?xml version='1.0' encoding='utf-8'?>
<OrderList>
<Username>$ShipwireUsername</Username>
  <Password>$ShipwirePassword</Password>
  <Server>$ShipwireTest</Server>
  <Referer>$ShipwireReferer</Referer>
</OrderList>"


    # Get sales orders needing to be fulfilled
    $StartDate = [DateTime]::Now.AddDays($BackOrderDays).ToString("s")
    $StopDate = [DateTime]::Now.ToString("s")


    $xRequest = [Xml] "<?xml version='1.0' encoding='utf-8'?>
                        <request>
                          <version>1.0</version>
                          <credential>
                            <username>$APIUsername</username>
                            <apiKey>$APIKey</apiKey>
                          </credential>
                          <service>GetSalesOrdersByDateRange</service>
                          <parameters>
                            <startDate>$StartDate</startDate>
                            <stopDate>$StopDate</stopDate>
                          </parameters>
                        </request>"




    [Xml]$xResponse = PostWebRequest $APIUrl $xRequest.InnerXml $NetworkTimeout
    if ($xResponse.response.code -ne '2000')
    {
        Throw New-Object System.InvalidOperationException("Error executing GetSalesOrdersByDateRange. Response: " + $xResponse.response.code + ' ' + $xResponse.response.message)
    }
    [System.Xml.XmlElement]$salesOrders = $xResponse.SelectSingleNode('/response/return/salesOrders')


    foreach ($salesOrder in $salesOrders.SelectNodes('salesOrder'))
    {
        # Look for pending order status
        if ($salesOrder.status -eq '1')
        {
# Create Shipwire fulfillment request
$xShipRequestOrder = $xShipRequest.CreateElement('Order')
$xShipRequestOrder.SetAttribute('id', $salesOrder.salesOrderID)
$xShipRequest.OrderList.AppendChild($xShipRequestOrder)

$xShipRequestWarehouse = $xShipRequest.CreateElement('Warehouse')
$xShipRequestWarehouse.InnerText = '00'
$xShipRequestOrder.AppendChild($xShipRequestWarehouse)

$xShipRequestOrderAddressInfo = $xShipRequest.CreateElement('AddressInfo')
$xShipRequestOrderAddressInfo.SetAttribute('type', 'ship')
$xShipRequestOrder.AppendChild($xShipRequestOrderAddressInfo)

$xShipRequestOrderAddressInfoName = $xShipRequest.CreateElement('Name')
$xShipRequestOrderAddressInfoNameFull = $xShipRequest.CreateElement('Full')
$xShipRequestOrderAddressInfoNameFull.InnerText = $salesOrder.shippingFirstName + ' ' + $salesOrder.shippingLastName
$xShipRequestOrderAddressInfoName.AppendChild($xShipRequestOrderAddressInfoNameFull)
$xShipRequestOrder.AddressInfo.AppendChild($xShipRequestOrderAddressInfoName)

$xShipRequestOrderAddressInfoAddress1 = $xShipRequest.CreateElement('Address1')
$xShipRequestOrderAddressInfoAddress1.InnerText = $salesOrder.shippingStreet.Replace("`r", '').Split("`n")[0]
$xShipRequestOrderAddressInfo.AppendChild($xShipRequestOrderAddressInfoAddress1)

$xShipRequestOrderAddressInfoAddress2 = $xShipRequest.CreateElement('Address2')
$xShipRequestOrderAddressInfoAddress2.InnerText = $salesOrder.shippingStreet.Replace("`r", '').Split("`n")[1]
$xShipRequestOrderAddressInfo.AppendChild($xShipRequestOrderAddressInfoAddress2)

$xShipRequestOrderAddressInfoCity = $xShipRequest.CreateElement('City')
$xShipRequestOrderAddressInfoCity.InnerText = $salesOrder.shippingCity
$xShipRequestOrderAddressInfo.AppendChild($xShipRequestOrderAddressInfoCity)

$xShipRequestOrderAddressInfoState = $xShipRequest.CreateElement('State')
if ($salesOrder.shippingCountryCode -eq 'US' -or $salesOrder.shippingCountryCode -eq 'CA')
{
$xShipRequestOrderAddressInfoState.InnerText = $salesOrder.shippingSubdivisionCode
}
else
{
$xShipRequestOrderAddressInfoState.InnerText = $salesOrder.shippingSubdivisionName
}
$xShipRequestOrderAddressInfo.AppendChild($xShipRequestOrderAddressInfoState)

$xShipRequestOrderAddressInfoCountry = $xShipRequest.CreateElement('Country')
$xShipRequestOrderAddressInfoCountry.InnerText = $salesOrder.shippingCountryCode
$xShipRequestOrderAddressInfo.AppendChild($xShipRequestOrderAddressInfoCountry)

$xShipRequestOrderAddressInfoZip = $xShipRequest.CreateElement('Zip')
$xShipRequestOrderAddressInfoZip.InnerText = $salesOrder.shippingPostalCode
$xShipRequestOrderAddressInfo.AppendChild($xShipRequestOrderAddressInfoZip)

$xShipRequestOrderAddressInfoPhone = $xShipRequest.CreateElement('Phone')
$xShipRequestOrderAddressInfoPhone.InnerText = $salesOrder.shippingPhone
$xShipRequestOrderAddressInfo.AppendChild($xShipRequestOrderAddressInfoPhone)

$xShipRequestOrderAddressInfoEmail = $xShipRequest.CreateElement('Email')
$xShipRequestOrderAddressInfoEmail.InnerText = $salesOrder.shippingEmail
$xShipRequestOrderAddressInfo.AppendChild($xShipRequestOrderAddressInfoEmail)

# Query shipping method
            $xRequest = [Xml] ("<?xml version='1.0' encoding='utf-8'?>
                                <request>
                                  <version>1.0</version>
                                  <credential>
                                    <username>$APIUsername</username>
                                    <apiKey>$APIKey</apiKey>
                                  </credential>
                                  <service>GetActiveShippingMethod</service>
                                  <parameters>
                                    <shippingMethodID>" + $salesOrder.shippingMethodID + "</shippingMethodID>
                                  </parameters>
                                </request>")




            [Xml]$xResponse = PostWebRequest $APIUrl $xRequest.InnerXml $NetworkTimeout
            if ($xResponse.response.code -ne '2000')
            {
                Throw New-Object System.InvalidOperationException("Error executing GetActiveShippingMethod. Response: " + $xResponse.response.code + ' ' + $xResponse.response.message)
            }
            $shippingMethod = $xResponse.response.return.shippingMethod

if (!$shippingMethod.universalServiceName.StartsWith("SHIPWIRE:"))
{
continue
}

$xShipRequestOrderCarrier = $xShipRequest.CreateElement('Carrier')
$xShipRequestOrderCarrier.InnerText = $shippingMethod.universalServiceName.Replace("SHIPWIRE:", "")
$xShipRequestOrder.AppendChild($xShipRequestOrderCarrier)

            # Query sales order details
            $xRequest = [Xml] ("<?xml version='1.0' encoding='utf-8'?>
                                <request>
                                  <version>1.0</version>
                                  <credential>
                                    <username>$APIUsername</username>
                                    <apiKey>$APIKey</apiKey>
                                  </credential>
                                  <service>GetSalesOrderDetails</service>
                                  <parameters>
                                    <salesOrderID>" + $salesOrder.salesOrderID + "</salesOrderID>
                                    <stopDate>$StopDate</stopDate>
                                  </parameters>
                                </request>")




            [Xml]$xResponse = PostWebRequest $APIUrl $xRequest.InnerXml $NetworkTimeout
            if ($xResponse.response.code -ne '2000')
            {
                Throw New-Object System.InvalidOperationException("Error executing GetSalesOrderDetails. Response: " + $xResponse.response.code + ' ' + $xResponse.response.message)
            }
            [System.Xml.XmlElement]$salesOrderDetails = $xResponse.SelectSingleNode('/response/return/salesOrderDetails')
            
$itemNum = 0
            foreach ($salesOrderDetail in $salesOrderDetails.SelectNodes('salesOrderDetail'))
            {
                # Make sure we haven't already fulfilled this sales order detail otherwise we can skip it
                if ($salesOrderDetail.shippingStatus -ne '2')
                {
                    continue
                }
                
                # Query product info for matching distributor
                $xRequest = [Xml] ("<?xml version='1.0' encoding='utf-8'?>
                                    <request>
                                      <version>1.0</version>
                                      <credential>
                                        <username>$APIUsername</username>
                                        <apiKey>$APIKey</apiKey>
                                      </credential>
                                      <service>GetActiveProductVariant</service>
                                      <parameters>
                                        <productVariantID>" + $salesOrderDetail.productVariantID + "</productVariantID>
                                      </parameters>
                                    </request>")




                [Xml]$xResponse = PostWebRequest $APIUrl $xRequest.InnerXml $NetworkTimeout
                if ($xResponse.response.code -ne '2000')
                {
                    Throw New-Object System.InvalidOperationException("Error executing GetActiveProductVariant. Response: " + $xResponse.response.code + ' ' + $xResponse.response.message)
                }
                $productVariant = $xResponse.response.return.productVariant
                                    
# Append Shipwire item to fulfillment request
$xShipRequestOrderItem = $xShipRequest.CreateElement('Item')
$xShipRequestOrderItem.SetAttribute('num', $itemNum)
$xShipRequestOrder.AppendChild($xShipRequestOrderItem)

$xShipRequestOrderItemCode = $xShipRequest.CreateElement('Code')
$xShipRequestOrderItemCode.InnerText = $salesOrderDetail.sku
$xShipRequestOrderItem.AppendChild($xShipRequestOrderItemCode)

$xShipRequestOrderItemQuantity = $xShipRequest.CreateElement('Quantity')
$xShipRequestOrderItemQuantity.InnerText = $salesOrderDetail.quantity
$xShipRequestOrderItem.AppendChild($xShipRequestOrderItemQuantity)

$itemNum = $itemNum + 1

                # Mark SalesOrderDetail as shipped
                $salesOrderDetail.shippingStatus = '3'
                
                # Update order detail shipping status to shipped (3).
                $xRequest = [Xml] ("<?xml version='1.0' encoding='utf-8'?>
                            <request>
                              <version>1.0</version>
                              <credential>
                                <username>$APIUsername</username>
                                <apiKey>$APIKey</apiKey>
                              </credential>
                              <service>UpdateSalesOrderDetail</service>
                              <parameters>
                                <salesOrderDetailID>" + $salesOrderDetail.salesOrderDetailID + "</salesOrderDetailID>
                                <shippingStatus>3</shippingStatus>
                              </parameters>
                            </request>")
                            
                [Xml]$xResponse = PostWebRequest $APIUrl $xRequest.InnerXml $NetworkTimeout
                if ($xResponse.response.code -ne '2000')
                {
                    Throw New-Object System.InvalidOperationException("Error executing UpdateSalesOrderDetail. Response: " + $xResponse.response.code + ' ' + $xResponse.response.message)
                }
            }

            # Update order status to Completed and Shipped if all sales order details have been accounted for.
            $orderIsComplete = $true
            foreach ($salesOrderDetail in $salesOrderDetails.SelectNodes('salesOrderDetail'))
            {
                if ($salesOrderDetail.shippingStatus -eq '2' -or $salesOrderDetail.shippingStatus -eq '4')
                {
                    $orderIsComplete = $false
                    break
                }
            }
            
            if ($orderIsComplete)
            {
                # Update order status to shipped (3) and order completed (4).
                $xRequest = [Xml] ("<?xml version='1.0' encoding='utf-8'?>
                                <request>
                                  <version>1.0</version>
                                  <credential>
                                    <username>$APIUsername</username>
                                    <apiKey>$APIKey</apiKey>
                                  </credential>
                                  <service>UpdateSalesOrder</service>
                                  <parameters>
                                    <salesOrderID>" + $salesOrder.salesOrderID + "</salesOrderID>
                                    <salesPaymentStatus>" + $salesOrder.salesPaymentStatus + "</salesPaymentStatus>
                                    <shippingStatus>3</shippingStatus>
                                    <status>4</status>
                                  </parameters>
                                </request>")
                                
                [Xml]$xResponse = PostWebRequest $APIUrl $xRequest.InnerXml $NetworkTimeout
                if ($xResponse.response.code -ne '2000')
                {
                    Throw New-Object System.InvalidOperationException("Error executing UpdateSalesOrder. Response: " + $xResponse.response.code + ' ' + $xResponse.response.message)
                }
            }
        }
    }


# Submit to Shipwire fulfillment
$shipwireAPIUrl = 'https://api.shipwire.com/exec/FulfillmentServices.php'
if ($ShipwireTest -ne '')
{
$shipwireAPIUrl = 'https://api.beta.shipwire.com/exec/FulfillmentServices.php'
}
[Xml]$xResponse = PostWebRequest $shipwireAPIUrl $xShipRequest.InnerXml $NetworkTimeout
[System.Xml.XmlElement]$xSubmitOrderResponse = $xResponse.SelectSingleNode('/SubmitOrderResponse')
    if ($xSubmitOrderResponse.Status -eq '0')
    {
        # Log completion
    ([DateTime]::Now.ToString("s") + "`tSuccess`t" + $xShipRequest.InnerXml) >> ($WorkingFolder + $LogFileName)

# Notify progress
    SendEmail $SMTPServer $SMTPUser $SMTPPassword $NotificationSender $NotificationRecipient 'Fulfillment completed successfully' 'Fulfillment completed successfully' ($WorkingFolder + $LogFileName)
    }
    else
{
    # Log completion
    ([DateTime]::Now.ToString("s") + "`t" + $xSubmitOrderResponse.ErrorMessage.InnerText + "`t" + $xShipRequest.InnerXml) >> ($WorkingFolder + $LogFileName)

# Notify progress
    SendEmail $SMTPServer $SMTPUser $SMTPPassword $NotificationSender $NotificationRecipient 'Fulfillment failed' 'Fulfillment failed' ($WorkingFolder + $LogFileName)
    }
}
Catch
{
    # Log errors
    ([DateTime]::Now.ToString("s") + "`t" + $_.Exception.Message + "`t") >> ($WorkingFolder + $LogFileName)
    
    # Notify error
    SendEmail $SMTPServer $SMTPUser $SMTPPassword $NotificationSender $NotificationRecipient 'Fulfillment failed' 'Fulfillment failed' ($WorkingFolder + $LogFileName)
}

Comments


Powered by Revindex Wiki