We have a json file which contains an array with products with sell price and for some (the products we have to buy) a part number and buy price. For example:
{
"Prices":[
{
"Product":"AD User",
"Price":3.52
},
{
"Product":"Skype for Business Plus SAL",
"Price":4.68,
"Part number":"6SH-00002",
"Buy price":3.90
},
{
"Product":"Citrix CAL",
"Price":6.40,
"Part number":"ROYSPLACXABASE",
"Buy price":5.33
}
]
}
I use the following code to retrieve the contents of the json and for each object with a part number i put an object to an array of PSCustomObjects and add an int OrderCount and a function to increment this OrderCount:
$PurchaseOrder = @()
[object[]]$Prices = Get-Content 'C:\Pricelist.json' | Out-String | ConvertFrom-Json
foreach($_price in ($Prices.prices | Where-Object {$_."Part Number"})){
$PurchaseOrderItem = $_price.psobject.copy()
$PurchaseOrderItem | Add-Member -Name "OrderCount" -MemberType NoteProperty -Value 0
$PurchaseOrderItem | Add-Member -MemberType ScriptMethod -Name IncrementOrderCount {
param([int]$amount)
$this.OrderCount = $this.OrderCount + $amount
}
$PurchaseOrder += $PurchaseOrderItem
}
If figured out the following function to update the $PurchaseOrder:
function Update-PurchaseOrder{
[Cmdletbinding()]
param(
[ref]$PurchaseOrder,
[string]$ProductName,
[int]$Count
)
$PurchaseOrder.Value.where({$_.Product -eq $ProductName}).IncrementOrderCount($Count)
}
Instead I get the following error when I run this function
Update-PurchaseOrder -PurchaseOrder ([ref]$PurchaseOrder) -ProductName "Citrix CAL" -Count 5
Method invocation failed because [System.Collections.ObjectModel.Collection`1[[System.Management.Automation.PSObject, System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]] does not contain a
method named 'IncrementOrderCount'.
At line:9 char:5
+ $PurchaseOrder.Value.where({$_.Name -eq $ProductName}).IncrementO ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
If i run this code with a $Prices
object which is created manually, for example:
$Prices = @([pscustomobject]@{Product="Product1";Price=1},[pscustomobject]@{Product="Product2";Price=2})
It does run without any problem. I've tried to cast several objects to different types, but I'm out of options.
I've added an additional piece of code to check if the Product exists in my PurchaseOrder, now it runs without problem.
Write-Verbose "Updating PurchaseOrder for product $Title "
if($PurchaseOrder.Value.where({$_.Product -eq $Title})){
try{
$PurchaseOrder.Value.where({$_.Product -eq $Title}).IncrementOrderCount($Count)
} catch {
Write-Warning "Error while incrementing OrderCount for product $($Title): $($_.Exception.Message)"
}
} else {
Write-Verbose "Product $Title not found in PurchaseOrder."
}
Use ForEach-Object
to iterate over the collection and then call the method on each object.
Also the property with the Product name is Product
rather than Name.
function Update-PurchaseOrder{
[Cmdletbinding()]
param(
[ref]$PurchaseOrder,
[string]$ProductName,
[int]$Count
)
$PurchaseOrder.Value.where({$_.Product -eq $ProductName}) | ForEach-Object {$_.IncrementOrderCount($Count)}
}
Also I believe $PurchaseOrder
would already be passed by reference so you could skip the extra hassle and just pass $PurchaseOrder
rather than ([ref]$PurchaseOrder)
. And then not need the extra step of unpacking the value in the function.