Here's a simple example using Powershell to export pending orders to send for fulfillment via email.
# SalesOrderExport.ps1
#
# This script will export all pending orders with products belonging to
# a distributor and send the CSV file using email.
# It will keep track of all the order details fulfilled in a local file.
# It will mark the order as shipped and 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
# The distributor to match
$DistributorID = 1
$FulfillmentEmailBody = 'Order fulfillment text body'
# The email(s) to send fulfillment file. Separated multiple emails by semicolon.
$FulfillmentEmailRecipient = 'vendor@localhost.com'
$FulfillmentEmailSender = 'support@localhost.com'
$FulfillmentEmailSubject = 'Order fulfillment'
$FulfillmentFileName = ('Fulfillment.' + [DateTime]::Now.ToString('yyyyMMdd') + '.txt')
$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'
$OrderCompletionFileName = 'OrderCompletion.txt'
$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
{
# Load order completion data into array
$OrderCompletion = @()
if ([System.IO.File]::Exists($WorkingFolder + $OrderCompletionFileName))
{
$OrderCompletion = @(Import-Csv ($WorkingFolder + $OrderCompletionFileName))
}
# Get sales orders needing to be fulfilled
$StartDate = [DateTime]::Now.AddDays($BackOrderDays).ToString("s")
$StopDate = [DateTime]::Now.ToString("s")
$xRequest = [Xml] "
1.0
$APIUsername
$APIKey
GetSalesOrdersByDateRange
$StartDate
$StopDate
"
[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')
{
# Query sales order details
$xRequest = [Xml] ("
1.0
$APIUsername
$APIKey
GetSalesOrderDetails
" + $salesOrder.salesOrderID + "
$StopDate
")
[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')
foreach ($salesOrderDetail in $salesOrderDetails.SelectNodes('salesOrderDetail'))
{
# Make sure we haven't already fulfilled this sales order detail otherwise we can skip it
if (($OrderCompletion | Where-Object {$_.SalesOrderDetailID -eq $salesOrderDetail.salesOrderDetailID }))
{
continue
}
# Query product info for matching distributor
$xRequest = [Xml] ("
1.0
$APIUsername
$APIKey
GetActiveProductVariant
" + $salesOrderDetail.productVariantID + "
")
[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
if ($productVariant.distributorID -eq $DistributorID)
{
# Append data to CSV file
if (![System.IO.File]::Exists($WorkingFolder + $FulfillmentFileName))
{
# Write CSV headers
('Date,SalesOrderID,SalesOrderDetailID,SKU,DistributorSKU,Quantity') >> ($WorkingFolder + $FulfillmentFileName)
}
# Append data to CSV
($salesOrder.orderDate + ',' + $salesOrder.salesOrderID + ',' + $salesOrderDetail.salesOrderDetailID + ',' + $productVariant.sku + ',' + $productVariant.distributorSKU + ',' + $salesOrderDetail.quantity) >> ($WorkingFolder + $FulfillmentFileName)
# Keep track of completed sales order details. Add order detail to our tracking array
$OrderCompletion += New-Object -TypeName PSObject -Property @{ DistributorID = $DistributorID
Date = [DateTime]::Now.ToString("s")
SalesOrderID = $salesOrder.salesOrderID
SalesOrderDetailID = $salesOrderDetail.salesOrderDetailID }
}
}
# 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 (!($OrderCompletion | Where-Object {$_.SalesOrderDetailID -eq $salesOrderDetail.salesOrderDetailID }))
{
$orderIsComplete = $false
break
}
}
if ($orderIsComplete)
{
# Update order status to shipped (3) and order completed (4).
$xRequest = [Xml] ("
1.0
$APIUsername
$APIKey
UpdateSalesOrder
" + $salesOrder.salesOrderID + "
" + $salesOrder.salesPaymentStatus + "
3
4
")
[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)
}
# Remove records from order completion tracking belonging to this order
$OrderCompletion = @($OrderCompletion | Where-Object { $_.SalesOrderID -ne $salesOrder.salesOrderID })
}
}
}
# Send email to fulfill orders
if ([System.IO.File]::Exists($WorkingFolder + $FulfillmentFileName))
{
SendEmail $SMTPServer $SMTPUser $SMTPPassword $FulfillmentEmailSender $FulfillmentEmailRecipient $FulfillmentEmailSubject $FulfillmentEmailBody ($WorkingFolder + $FulfillmentFileName)
}
# Persist tracking to order completion file
$OrderCompletion | Export-Csv -NoTypeInformation ($WorkingFolder + $OrderCompletionFileName)
# Log completion
([DateTime]::Now.ToString("s") + "`t" + 'Fufillment completed successfully') >> ($WorkingFolder + $LogFileName)
# Notify progress
SendEmail $SMTPServer $SMTPUser $SMTPPassword $NotificationSender $NotificationRecipient 'Fulfillment completed successfully' 'Fulfillment completed successfully' ($WorkingFolder + $LogFileName)
}
Catch
{
# Log errors
([DateTime]::Now.ToString("s") + "`t" + $_.Exception.Message) >> ($WorkingFolder + $LogFileName)
# Notify error
SendEmail $SMTPServer $SMTPUser $SMTPPassword $NotificationSender $NotificationRecipient 'Fulfillment failed' 'Fulfillment failed' ($WorkingFolder + $LogFileName)
}