O2C Demo Data Generator - Complete Script
This page contains the complete refactored PowerShell 7+ script for generating Order-to-Cash demo data. This version consolidates message generation, BPM logic, and helper functions for improved maintainability.
Key improvements:
- Cross-platform compatible (PowerShell 7+ with ternary operators)
- Consolidated message payload generation
- Streamlined BPM relationship logic
- Helper functions for code reuse
- Better performance and readability
Script Requirements
- PowerShell Version: 7.0 or later
- Cross-Platform: Works on Windows, Linux, and macOS
- Dependencies: None (uses built-in cmdlets)
Complete Script
# Generate-O2C-Demo-Data.ps1 (REFACTORED - PowerShell 7+ Required)
#
# PowerShell script to generate 100 Order-to-Cash (O2C) demo orders and log them to Nodinite Log API
# Refactored version with consolidated message generation, BPM logic, and helper functions
# REQUIRES: PowerShell 7.0+ for ternary operators and null-coalescing (cross-platform compatible)
#
# Usage:
# pwsh .\Generate-O2C-Demo-Data.ps1 -LogApiUrl "https://your-nodinite-instance/api/v2/LogEvents" `
# -ApiKey "your-api-key" `
# -OutputFile "/tmp/O2C-Orders.json"
param(
[Parameter(Mandatory = $false)]
[string]$LogApiUrl = "https://localhost:5001/api/v2/LogEvents",
[Parameter(Mandatory = $false)]
[string]$ApiKey = "YOUR_API_KEY_HERE",
[Parameter(Mandatory = $false)]
[string]$OutputFile = "C:\Temp\O2C-Demo-Data.json",
[Parameter(Mandatory = $false)]
[int]$OrderCount = 100,
[Parameter(Mandatory = $false)]
[switch]$ExportToFile,
[Parameter(Mandatory = $false)]
[switch]$DryRun
)
$LOG_AGENT_VALUE_ID = 5
$ENDPOINT_TYPE_ID = 60
$PROGRESSION_PROBABILITY = 0.90
$today = (Get-Date).Date
$baseDate = [DateTime]::SpecifyKind((Get-Date -Year $today.Year -Month $today.Month -Day $today.Day -Hour 6 -Minute 0 -Second 0 -Millisecond 0), [DateTimeKind]::Utc)
$executionDate = (Get-Date).ToString("yyyyMMdd")
$customerPrefix = "PIC"
# Compact step definitions - only unique properties per step
$stepTemplates = @{
0 = @{ System = "Portal"; Domain = "Sales"; DomainIndex = 0; MessageType = "O2C.Order.Received/1.0"; ProcessName = "O2C-Order-Reception"; ProcessingMachineName = "portal-server-01" }
1 = @{ System = "ERP"; Domain = "Planning"; DomainIndex = 1; MessageType = "O2C.Order.Entry/1.0"; ProcessName = "O2C-Order-Entry"; ProcessingMachineName = "erp-server-01" }
2 = @{ System = "Portal"; Domain = "Sales"; DomainIndex = 0; MessageType = "O2C.Order.Confirmation/1.0"; ProcessName = "O2C-Confirmation"; ProcessingMachineName = "portal-server-01" }
3 = @{ System = "ERP"; Domain = "Planning"; DomainIndex = 1; MessageType = "O2C.Order.Scheduled/1.0"; ProcessName = "O2C-Planning"; ProcessingMachineName = "erp-server-01" }
4 = @{ System = "WMS"; Domain = "Logistics"; DomainIndex = 2; MessageType = "O2C.Order.Ready/1.0"; ProcessName = "O2C-Packing"; ProcessingMachineName = "wms-server-01" }
5 = @{ System = "WMS"; Domain = "Logistics"; DomainIndex = 2; MessageType = "O2C.Order.Delivered/1.0"; ProcessName = "O2C-Delivery"; ProcessingMachineName = "wms-server-01" }
6 = @{ System = "ERP-Finance"; Domain = "Finance"; DomainIndex = 3; MessageType = "O2C.Order.Invoice/1.0"; ProcessName = "O2C-Invoicing"; ProcessingMachineName = "erp-server-01" }
}
$eventDefs = @(
@{ StepNumber = 0; Direction = 0; Format = "JSON"; Service = "INT1337-RCV-Order-Incoming"; Endpoint = "Portal-OrderReceived-Drop"; Uri = "C:\Integration\Portal\Orders\In"; Module = "Portal.OrderService.Receiver"; IsBiz = $true }
@{ StepNumber = 0; Direction = 1; Format = "JSON"; Service = "INT1337-SND-Order-Incoming"; Endpoint = "Portal-Order-Send"; Uri = "C:\Integration\Portal\Orders\Out"; Module = "Portal.OrderService.Forwarder"; IsBiz = $false }
@{ StepNumber = 1; Direction = 0; Format = "XML"; Service = "INT1337-RCV-Order-Entry"; Endpoint = "ERP-OrderEntry-Receive"; Uri = "C:\Integration\ERP\Orders\In"; Module = "ERP.Order.EntryService.Receiver"; IsBiz = $false }
@{ StepNumber = 1; Direction = 1; Format = "XML"; Service = "INT1337-ENT-Order-Entry"; Endpoint = "ERP-OrderEntry-Send"; Uri = "C:\Integration\ERP\Orders\Out"; Module = "ERP.Order.EntryService"; IsBiz = $true }
@{ StepNumber = 2; Direction = 0; Format = "CSV"; Service = "INT1337-RCV-Confirm-Incoming"; Endpoint = "Portal-Confirmation-Receive"; Uri = "C:\Integration\Portal\Confirmations\In"; Module = "Portal.ConfirmationService.Receiver"; IsBiz = $false }
@{ StepNumber = 2; Direction = 1; Format = "CSV"; Service = "INT1337-SND-Confirm-Outgoing"; Endpoint = "Portal-Confirmation-Send"; Uri = "C:\Integration\Portal\Confirmations\Out"; Module = "Portal.ConfirmationService.Sender"; IsBiz = $true }
@{ StepNumber = 3; Direction = 0; Format = "JSON"; Service = "INT1337-RCV-Planned-Incoming"; Endpoint = "ERP-Planning-Receive"; Uri = "C:\Integration\ERP\Planning\In"; Module = "ERP.PlanningService.Receiver"; IsBiz = $false }
@{ StepNumber = 3; Direction = 1; Format = "JSON"; Service = "INT1337-PLN-Order-Scheduled"; Endpoint = "ERP-Planning-Send"; Uri = "C:\Integration\ERP\Planning\Out"; Module = "ERP.PlanningService.Scheduler"; IsBiz = $true }
@{ StepNumber = 4; Direction = 0; Format = "XML"; Service = "INT1337-RCV-Packing-Incoming"; Endpoint = "WMS-Packing-Receive"; Uri = "C:\Integration\WMS\Packing\In"; Module = "WMS.PackingService.Receiver"; IsBiz = $false }
@{ StepNumber = 4; Direction = 1; Format = "XML"; Service = "INT1337-PKG-Order-Packed"; Endpoint = "WMS-Packing-Send"; Uri = "C:\Integration\WMS\Packing\Out"; Module = "WMS.PackingService.Completer"; IsBiz = $true }
@{ StepNumber = 5; Direction = 0; Format = "PSV"; Service = "INT1337-RCV-Order-Delivered-Incoming"; Endpoint = "WMS-Delivery-Receive"; Uri = "C:\Integration\WMS\Delivery\In"; Module = "WMS.DeliveryService.Receiver"; IsBiz = $false }
@{ StepNumber = 5; Direction = 1; Format = "PSV"; Service = "INT1337-RCV-Order-Delivered"; Endpoint = "WMS-Delivery-Send"; Uri = "C:\Integration\WMS\Delivery\Out"; Module = "WMS.DeliveryService.Sender"; IsBiz = $true }
@{ StepNumber = 6; Direction = 0; Format = "JSON"; Service = "INT1337-RCV-Invoice-Incoming"; Endpoint = "ERP-Finance-Invoice-Receive"; Uri = "C:\Integration\ERP\Finance\Invoices\In"; Module = "ERP.FinanceService.Receiver"; IsBiz = $false }
@{ StepNumber = 6; Direction = 1; Format = "JSON"; Service = "INT1337-INV-Order-Invoiced"; Endpoint = "ERP-Finance-Invoice-Send"; Uri = "C:\Integration\ERP\Finance\Invoices\Out"; Module = "ERP.FinanceService.Invoicer"; IsBiz = $true }
)
$milestones = @{
0 = @{ Rcv = "Order Received from Customer"; Snd = "Order Forwarded to ERP" }
1 = @{ Rcv = "Order Entry Received"; Snd = "Order Entry in ERP Finished" }
2 = @{ Rcv = "Confirmation Received"; Snd = "Order Confirmation Delivered to Customer" }
3 = @{ Rcv = "Planning Request Received"; Snd = "Production Scheduled in ERP" }
4 = @{ Rcv = "Packing Request Received"; Snd = "Order Completed for Transport" }
5 = @{ Rcv = "Order Delivered Received"; Snd = "Order Delivered" }
6 = @{ Rcv = "Invoice Request Received"; Snd = "Order Invoiced" }
}
$downstreamFlows = @{
0 = @(1); 1 = @(2, 3); 2 = @(3); 3 = @(4); 4 = @(5); 5 = @(6); 6 = @()
}
function ConvertTo-Base64 {
param([string]$Text)
return [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Text))
}
function Get-FileExtension {
param([string]$Format)
return $Format -eq "JSON" ? ".json" : $Format -eq "XML" ? ".xml" : $Format -eq "CSV" ? ".csv" : $Format -eq "PSV" ? ".psv" : ".dat"
}
function Get-ShortMilestone {
param([string]$Milestone)
$m = $Milestone -replace " from Customer| to Customer| in ERP Finished| in ERP", ""
$words = $m -split ' '
if ($words.Count -ge 3) {
$m = $m -eq "Order Confirmation Delivered" ? "Confirmation Sent" : $m -eq "Order Completed for Transport" ? "Ready for Transport" : $words.Count -gt 3 ? "$($words[0]) $($words[-2]) $($words[-1])" : $m
}
return $m
}
function New-MessagePayload {
param([int]$StepNum, [string]$OrderId, [string]$CorrelationId)
$ordNum = $OrderId.Substring(4)
$payloads = @{
0 = @{
batchId = "batch-2025-10-14-001"
generatedAt = $baseDate.ToString("O")
orderId = $OrderId
customer = @{ customerId = "CUST-001"; name = "Acme Corporation"; email = "orders@acme.example.com" }
orderDate = $baseDate.ToString("O")
orderRows = @(@{ rowId = 1; sku = "SKU-DEMO-001"; description = "Demo Widget"; quantity = 1; unitPrice = 99.95; lineTotal = 99.95 })
orderTotal = 99.95
currency = "USD"
} | ConvertTo-Json -Depth 10
1 = @"
<?xml version="1.0" encoding="utf-8"?>
<OrderEntry xmlns="http://schemas.acme.example/O2C/1.0">
<OrderHeader><OrderId>$OrderId</OrderId><OrderDate>2025-10-14T09:15:00Z</OrderDate><EntryDate>2025-10-14T09:18:30Z</EntryDate><OrderStatus>ENTERED</OrderStatus></OrderHeader>
<Customer><CustomerId>CUST-001</CustomerId><CustomerName>Acme Corporation</CustomerName><CustomerEmail>orders@acme.example.com</CustomerEmail></Customer>
<OrderLines><OrderLine><LineId>1</LineId><SKU>SKU-DEMO-001</SKU><Description>Demo Widget</Description><Quantity>1</Quantity><UnitPrice>99.95</UnitPrice><LineTotal>99.95</LineTotal><InventoryReserved>true</InventoryReserved></OrderLine></OrderLines>
<OrderTotal>99.95</OrderTotal><Currency>USD</Currency><ERPReferenceNumber>ERP-2025-$ordNum</ERPReferenceNumber>
</OrderEntry>
"@
2 = @"
OrderConfirmationHeader
ConfirmationId,ConfirmationDate,CorrelationId,OrderId,OrderDate,CustomerID,CustomerName,CustomerEmail,ConfirmationStatus
CONF-2025-$ordNum,2025-10-14T09:22:15Z,$CorrelationId,ORD-$ordNum,2025-10-14T09:15:00Z,CUST-001,Acme Corporation,orders@acme.example.com,CONFIRMED
OrderConfirmationDetails
LineNumber,SKU,Description,QuantityOrdered,UnitPrice,LineTotal
1,SKU-DEMO-001,Demo Widget,1,99.95,99.95
OrderConfirmationFooter
OrderTotal,Currency,EstimatedShipDate,TrackingEnabled
99.95,USD,2025-10-21,true
"@
3 = @{
scheduleId = "SCH-2025-$ordNum"; orderId = $OrderId; customerId = "CUST-001"; customerName = "Acme Corporation"
orderDate = "2025-10-14T09:15:00Z"; scheduleDate = "2025-10-14T09:37:45Z"
productionLines = @(@{ lineId = "LINE-01"; lineName = "Assembly Line A"; scheduledStart = "2025-10-16T06:00:00Z"; scheduledEnd = "2025-10-16T14:30:00Z"; expectedDuration = 510; shift = "DAY"; capacity = 50 })
materials = @(@{ materialId = "MAT-SKU-DEMO-001"; sku = "SKU-DEMO-001"; description = "Demo Widget"; quantityRequired = 1; quantityAllocated = 1; availableAtScheduleTime = $true })
orderQuantity = 1; orderAmount = 99.95; currency = "USD"; priorityLevel = "NORMAL"; schedulingStatus = "CONFIRMED"; estimatedCompletionDate = "2025-10-16T14:30:00Z"
} | ConvertTo-Json -Depth 10
4 = @"
<?xml version="1.0" encoding="utf-8"?>
<OrderPacking xmlns="http://schemas.acme.example/O2C/1.0">
<PackingHeader><PackingId>PKG-2025-$ordNum</PackingId><OrderId>$OrderId</OrderId><PackingDate>2025-10-16T16:45:30Z</PackingDate><PackingStatus>COMPLETED</PackingStatus><Warehouse>WH-01</Warehouse><Zone>ZONE-A</Zone></PackingHeader>
<Customer><CustomerId>CUST-001</CustomerId><CustomerName>Acme Corporation</CustomerName><ShippingAddress>100 Commerce Drive, Suite 100, Springfield, IL 62701</ShippingAddress></Customer>
<PackedItems><PackedItem><LineId>1</LineId><SKU>SKU-DEMO-001</SKU><Description>Demo Widget</Description><OrderedQuantity>1</OrderedQuantity><PackedQuantity>1</PackedQuantity><SerialNumber>SN-DW-2025$ordNum</SerialNumber><Condition>NEW</Condition></PackedItem></PackedItems>
<ShipmentInfo><TrackingNumber>TRK-20251016-$ordNum</TrackingNumber><Carrier>Standard Courier</Carrier><ShippingMethod>GROUND</ShippingMethod><EstimatedDeliveryDate>2025-10-21</EstimatedDeliveryDate><ShipmentWeight>5.0</ShipmentWeight><WeightUnit>LBS</WeightUnit></ShipmentInfo>
<OrderTotal>99.95</OrderTotal><Currency>USD</Currency>
</OrderPacking>
"@
5 = @"
DeliveryConfirmationHeader
DeliveryId|DeliveryDate|CorrelationId|OrderId|CustomerID|CustomerName|ShippingAddress|DeliveryStatus
DLVY-2025-$ordNum|2025-10-20T14:32:15Z|$CorrelationId|$OrderId|CUST-001|Acme Corporation|100 Commerce Drive, Suite 100, Springfield, IL 62701|DELIVERED
DeliveryDetails
LineNumber|SKU|Description|QuantityOrdered|QuantityDelivered|Condition
1|SKU-DEMO-001|Demo Widget|1|1|GOOD
DeliveryProof
TrackingNumber|Carrier|DeliverySignature|DeliveryTime|RecipientName|ProofOfDeliveryLocation|PhotoUrl
TRK-20251016-$ordNum|Standard Courier|ACM-AUTO-SIGN|2025-10-20T14:32:15Z|Auto-confirmed|Front Porch|https://pod.courier.example/2025/10/dlvy-$ordNum.jpg
DeliveryFooter
OrderTotal|Currency|ReturnWindow|ReturnInstructions
99.95|USD|30|Visit returns.acme.com
"@
6 = @{
invoiceId = "INV-2025-$ordNum"; orderId = $OrderId; customerId = "CUST-001"; customerName = "Acme Corporation"; customerEmail = "orders@acme.example.com"
invoiceDate = "2025-10-21T09:15:00Z"; dueDate = "2025-11-20"; paymentTerms = "NET30"; invoiceStatus = "ISSUED"
invoiceItems = @(@{ lineNumber = 1; description = "Demo Widget"; sku = "SKU-DEMO-001"; quantity = 1; unitPrice = 99.95; lineTotal = 99.95; taxCode = "STANDARD"; taxRate = 0.0; taxAmount = 0.0 })
subtotal = 99.95; taxTotal = 0.0; shippingCharge = 0.0; invoiceTotal = 99.95; currency = "USD"; paymentMethod = "INVOICE"
purchaseOrder = "PO-2025-$ordNum"; trackingNumber = "TRK-20251016-$ordNum"; gl_account = "4100-Sales-Revenue"; revenue_recognition_date = "2025-10-20"
} | ConvertTo-Json -Depth 10
}
return ConvertTo-Base64 $payloads[$StepNum]
}
function New-NodiniteLogEvent {
param([hashtable]$EventDef, [string]$OrderId, [string]$CorrelationId, [DateTime]$LogDateTime, [int]$SequenceNo, [int]$ProcessingTimeMs, [int]$LogStatus, [string]$Body, [hashtable]$PrevSendService, [hashtable]$SameStepRecvService)
$stepNum = $EventDef.StepNumber
$stepTemplate = $stepTemplates[$stepNum]
$isDir0 = $EventDef.Direction -eq 0
$milestone = $milestones[$stepNum][$isDir0 ? "Rcv" : "Snd"]
# Build Repository Binding
$repBinding = @{
Name = "Standard Transport Contract"
Service = @{
Name = $EventDef.Service
Direction = $isDir0 ? "Receive" : "Send"
System = @{ Name = $stepTemplate.System }
Integration = @{ Name = "INT1337 - Order-to-Cash" }
}
}
if ($isDir0 -and $null -ne $PrevSendService) {
$repBinding.Service.ExternalServiceRelations = @(@{
Name = $PrevSendService.Service
Direction = $PrevSendService.Direction -eq 0 ? "Receive" : "Send"
System = @{ Name = $PrevSendService.System }
})
}
if (-not $isDir0 -and $null -ne $SameStepRecvService) {
$repBinding.Service.InternalServiceRelations = @(@{
Name = $SameStepRecvService.Service
Direction = $SameStepRecvService.Direction -eq 0 ? "Receive" : "Send"
System = @{ Name = $SameStepRecvService.System }
})
}
if ($EventDef.IsBiz) {
$bpmRels = @()
foreach ($downStep in $downstreamFlows[$stepNum]) {
$dnEvent = $eventDefs | Where-Object { $_.StepNumber -eq $downStep -and $_.IsBiz }
if ($dnEvent) {
$dnTemplate = $stepTemplates[$downStep]
$dnMilestone = $milestones[$downStep]["Snd"]
$shortMile = Get-ShortMilestone $dnMilestone
$label = $downStep -eq 3 ? "Order Planned" : $shortMile
$bpmRels += @{
Name = $dnEvent.Service
ArtifactRenaming = $shortMile
Direction = $dnEvent.Direction -eq 0 ? "Receive" : "Send"
Domain = @{ Name = $dnTemplate.Domain; Index = $dnTemplate.DomainIndex }
System = @{ Name = $dnTemplate.System }
Step = $downStep
Label = $label
ConnectorStyle = 0
SourceAttachmentPoint = 3
TargetAttachmentPoint = 1
}
}
}
$shortMile = Get-ShortMilestone $milestone
$repBinding.Service.BPMs = @(@{
Name = "INT1337 - Order-to-Cash Flow"
ArtifactRenaming = $shortMile
Domain = @{ Name = $stepTemplate.Domain; Index = $stepTemplate.DomainIndex }
Step = $stepNum
ServiceRelations = $bpmRels
})
}
$bindingJson = ($repBinding | ConvertTo-Json -Depth 10) -replace '\r?\n\s*', ''
$context = New-Object PSObject
$context | Add-Member -MemberType NoteProperty -Name "FileName" -Value "$OrderId-$($milestone.ToLower() -replace ' ', '-')$(Get-FileExtension $EventDef.Format)"
$context | Add-Member -MemberType NoteProperty -Name "OrderNumber" -Value $OrderId
$context | Add-Member -MemberType NoteProperty -Name "CustomerId" -Value "CUST-001"
$context | Add-Member -MemberType NoteProperty -Name "CustomerName" -Value "Acme Corporation"
$context | Add-Member -MemberType NoteProperty -Name "OrderAmount" -Value "99.95"
$context | Add-Member -MemberType NoteProperty -Name "ExtendedProperties/1.0#RepositoryBinding" -Value $bindingJson
return @{
LogAgentValueId = $LOG_AGENT_VALUE_ID
EndPointName = $EventDef.Endpoint
EndPointUri = $EventDef.Uri
EndPointDirection = $EventDef.Direction
EndPointTypeId = $ENDPOINT_TYPE_ID
OriginalMessageTypeName = $EventDef.IsBiz ? $stepTemplate.MessageType : "O2C.Forwarding/1.0"
LogDateTime = $LogDateTime.ToString("O")
EventDirection = $isDir0 ? 17 : 18
ProcessingUser = "$($stepTemplate.System)\OrderService"
SequenceNo = $SequenceNo
EventNumber = $SequenceNo
LogText = $milestone
ApplicationInterchangeId = $CorrelationId
LocalInterchangeId = $null
LogStatus = $LogStatus
ProcessName = $stepTemplate.ProcessName
ProcessingMachineName = $stepTemplate.ProcessingMachineName
ProcessingModuleName = $EventDef.Module
ProcessingModuleType = "WindowsService"
ServiceInstanceActivityId = $null
ProcessingTime = $ProcessingTimeMs
Body = $Body
Context = $context
}
}
Write-Host "Order-to-Cash (O2C) Demo Data Generator [REFACTORED]" -ForegroundColor Cyan
Write-Host "====================================================" -ForegroundColor Cyan
Write-Host "Generating $OrderCount orders with probabilistic step completion..." -ForegroundColor Yellow
Write-Host ""
$allLogEvents = @()
$globalDateTime = $baseDate
$globalSequenceNo = 0
for ($orderNum = 1; $orderNum -le $OrderCount; $orderNum++) {
$orderId = "ORD-" + (10000 + $orderNum).ToString()
$currentTime = Get-Date -Format "HHmm"
$correlationId = "$customerPrefix-$executionDate-$currentTime-" + $orderNum.ToString("D4")
# Determine which steps this order will complete (first order always completes all 7 steps)
$completedSteps = $orderNum -eq 1 ? 7 : {
$steps = 1
for ($s = 1; $s -le 6; $s++) {
if ((Get-Random -Minimum 0 -Maximum 100) / 100 -le $PROGRESSION_PROBABILITY) { $steps = $s + 1 }
else { break }
}
[int]$steps
}.Invoke()[0]
$previousSendService = $null
$currentDateTime = $globalDateTime
for ($stepNum = 0; $stepNum -lt $completedSteps; $stepNum++) {
$rcvEvent = $eventDefs | Where-Object { $_.StepNumber -eq $stepNum -and $_.Direction -eq 0 }
$sndEvent = $eventDefs | Where-Object { $_.StepNumber -eq $stepNum -and $_.Direction -eq 1 }
$body = New-MessagePayload $stepNum $orderId $correlationId
$isLastStep = $stepNum -eq ($completedSteps - 1)
$isIncomplete = $completedSteps -lt 7
$currentDateTime = $currentDateTime.AddSeconds((Get-Random -Minimum 30 -Maximum 300))
$globalSequenceNo++
$allLogEvents += New-NodiniteLogEvent $rcvEvent $orderId $correlationId $currentDateTime $globalSequenceNo (Get-Random -Minimum 5 -Maximum 50) 0 $body $previousSendService $null
$currentDateTime = $currentDateTime.AddSeconds((Get-Random -Minimum 1 -Maximum 5))
$sendStatus = $isLastStep -and $isIncomplete ? -1337 : 0
$globalSequenceNo++
$rcvEventInfo = @{ Service = $rcvEvent.Service; Direction = $rcvEvent.Direction; System = $stepTemplates[$stepNum].System }
$allLogEvents += New-NodiniteLogEvent $sndEvent $orderId $correlationId $currentDateTime $globalSequenceNo (Get-Random -Minimum 40 -Maximum 300) $sendStatus $body $null $rcvEventInfo
$previousSendService = @{ Service = $sndEvent.Service; Direction = $sndEvent.Direction; System = $stepTemplates[$stepNum].System }
}
$globalDateTime = $currentDateTime.AddSeconds((Get-Random -Minimum 120 -Maximum 600))
if ($orderNum % 10 -eq 0) {
Write-Host "Generated $orderNum/$OrderCount orders..." -ForegroundColor Green
}
}
Write-Host ""
Write-Host "Generated $(($allLogEvents | Measure-Object).Count) total log events" -ForegroundColor Cyan
if ($DryRun) {
Write-Host ""
Write-Host "DRY RUN MODE - First 2 orders only:" -ForegroundColor Yellow
$allLogEvents | Select-Object -First 14 | ConvertTo-Json -Depth 20 | Write-Host
}
elseif ($ExportToFile) {
Write-Host ""
Write-Host "Exporting to file: $OutputFile" -ForegroundColor Cyan
$allLogEvents | ConvertTo-Json -Depth 20 | Out-File -FilePath $OutputFile -Encoding UTF8
Write-Host "Export completed successfully" -ForegroundColor Green
}
else {
Write-Host ""
Write-Host "Would call Log API at: $LogApiUrl" -ForegroundColor Cyan
Write-Host "With $($allLogEvents.Count) events" -ForegroundColor Cyan
}
Write-Host ""
Write-Host "Summary:" -ForegroundColor Cyan
Write-Host " Orders: $OrderCount" -ForegroundColor White
Write-Host " Log Events: $($allLogEvents.Count)" -ForegroundColor White
Write-Host " Average Events per Order: $([Math]::Round($allLogEvents.Count / $OrderCount, 2))" -ForegroundColor White
Write-Host ""
Usage Examples
See the O2C Demo Data Generator Usage Guide for complete usage examples, parameters, and use cases.
Quick Start:
# Preview first order only
.\Generate-O2C-Demo-Data-REFACTORED.ps1 -DryRun
# Export 100 orders to file
.\Generate-O2C-Demo-Data-REFACTORED.ps1 -ExportToFile -OutputFile "C:\Temp\O2C-Demo.json"
Script Features
Consolidated Functions:
ConvertTo-Base64- Base64 encoding for message bodiesGet-FileExtension- Format-specific file extensionsGet-ShortMilestone- Shortened milestone names for BPM visualizationNew-MessagePayload- Centralized message payload generation (all 7 steps)New-NodiniteLogEvent- Complete log event construction with BPM metadata
Improved Organization:
- Step templates defined in single hashtable
- Event definitions array with all metadata
- Milestone definitions consolidated
- Downstream flow relationships mapped
Cross-Platform Support:
- PowerShell 7+ ternary operators (
condition ? true : false) - Cross-platform path handling
- UTC datetime management
- Consistent encoding (UTF8)
Next Steps
O2C Demo Usage Guide - Complete usage examples and parameters
Run the script with -DryRun to preview generated data
Download and save as Generate-O2C-Demo-Data-REFACTORED.ps1
Related Topics
O2C Demo Overview - Complete Order-to-Cash scenario documentation
Usage Guide and Examples - Detailed usage instructions
Log API Reference - Integration with Nodinite Log API
Order Received Stylesheet - Message visualization examples