Create Sitecore Commerce items with a script – Part 3 (Category)

In the previous articles of this serie, I have shown you how to create some utility scripts and how to create a new catalog in your XC database.

We’ll create now some categories under our new catalog. Let’s open Business Tools, create two categories and see what request and payload are sent from our client to the XC authoring server.

For the first category, the Payload JSON (removed from unnecessary values) is

{
  "Name": "Details",
  "DisplayName": "Details",
  "EntityId": "Entity-Catalog-JSSCatalog",
  "EntityVersion": 1,
  "Action": "AddCategory",
  "ItemId": "",
  "DisplayRank": 500,
  "UiHint": "Flat",
  "Properties": [
    {
      "Name": "Version",
      "DisplayName": "Version",
      "Value": "1",
      "IsHidden": true,
      "OriginalType": "System.Int32",
      "IsReadOnly": true,
      "UiType": "",
      "IsRequired": true,
      "Policies": []
    },
    {
      "Name": "Name",
      "DisplayName": "Name",
      "Value": "JSSCat1",
      "IsHidden": false,
      "OriginalType": "System.String",
      "IsReadOnly": false,
      "UiType": "",
      "IsRequired": true,
      "Policies": []
    },
    {
      "Name": "DisplayName",
      "DisplayName": "Display Name",
      "Value": "JSSCat1",
      "IsHidden": false,
      "OriginalType": "System.String",
      "IsReadOnly": false,
      "UiType": "",
      "IsRequired": true,
      "Policies": []
    },
    {
      "Name": "Description",
      "DisplayName": "Description",
      "Value": "JSSCat1",
      "IsHidden": false,
      "OriginalType": "System.String",
      "IsReadOnly": false,
      "UiType": "",
      "IsRequired": false,
      "Policies": []
    }
  ]
}

For the second category, the JSON is

{
  "Name": "Details",
  "DisplayName": "Details",
  "EntityId": "Entity-Catalog-JSSCatalog",
  "EntityVersion": 1,
  "Action": "AddCategory",
  "ItemId": "",
  "DisplayRank": 500,
  "UiHint": "Flat",
  "Properties": [
    {
      "Name": "Version",
      "DisplayName": "Version",
      "Value": "2",
      "IsHidden": true,
      "OriginalType": "System.Int32",
      "IsReadOnly": true,
      "UiType": "",
      "IsRequired": true,
      "Policies": []
    },
    {
      "Name": "Name",
      "DisplayName": "Name",
      "Value": "JSSCat2",
      "IsHidden": false,
      "OriginalType": "System.String",
      "IsReadOnly": false,
      "UiType": "",
      "IsRequired": true,
      "Policies": []
    },
    {
      "Name": "DisplayName",
      "DisplayName": "Display Name",
      "Value": "JSSCat2",
      "IsHidden": false,
      "OriginalType": "System.String",
      "IsReadOnly": false,
      "UiType": "",
      "IsRequired": true,
      "Policies": []
    },
    {
      "Name": "Description",
      "DisplayName": "Description",
      "Value": "JSSCat2",
      "IsHidden": false,
      "OriginalType": "System.String",
      "IsReadOnly": false,
      "UiType": "",
      "IsRequired": false,
      "Policies": []
    }
  ]
}

The field “EntityId” shows which Catalog will be the parent for those categories. And the property Version corresponds to the actual version of the item’s parent (the Catalog in our case). Each time we create an child item to an item, the version number of the parent will increase. This is why the parameter Value has the value 1 for the first category, and the value 2 for the second category.

To understand that we are creating a hierarchy of items and the creation of items is based on the parent’s version is essential. In the last article, we created a function called GetCatalogVersion. We will need to call this function each time we create a catalog, in order to get the Version of the Catalog.

As we did for the Catalog, we also need to know if the category we create is already in the XC database or not. Similarly, we will create a new function GetCategoryVersion to get this Category version (or 0 if the category is not in the database). As with the Catalog, we will use the Postman API request Catalogs and make a script of it:

The GetCategoryVersion function

Function GetCategoryVersion {
    [CmdletBinding()]
    PARAM
    (
        [string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Token,
        [string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Category,
        [string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$IdentityServiceUri
    )

    $contentType = 'application/json'
    $headers = BuildHeaders($token)
    $uri = "$IdentityServiceUri/api/Categories"
	#$uri = "$IdentityServiceUri/api/GetList(id='Categories',type='Sitecore.Commerce.Plugin.Catalog.Category, Sitecore.Commerce.Plugin.Catalog',skip=0,take=1000)?`$expand=Items"
    
	$Res = Invoke-RestMethod -Uri $uri -ContentType $contentType -Method Get -Headers $headers
	
    $catVersion = ($Res.value | Where-Object { $_.FriendlyId -eq $Category} | Select-Object Version)
	
    if ($null -eq $catVersion -or $catVersion.Count -eq 0) {
        return 0
    }

    return $catVersion[0].Version

}

The AddCategory function

Function AddCategory {
    [CmdletBinding()]
    PARAM
    (
    [string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Token,
    [string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$IdentityServiceUri,
    [string] $Category,
    [string] $Version,
    [string] $Name,
    [string] $DisplayName,
    [string] $Description
    )

    $body = @{entityView=@{Name="Details";DisplayName="Details";EntityId=$Category;Action="AddCategory";ItemId="";Properties=@( `
    [pscustomobject]@{Name="Version";DisplayName="Version";Value=$Version;IsHidden=$True;OriginalType="System.Int32";IsReadOnly=$True;IsRequired=$True},`
    [pscustomobject]@{Name="Name";DisplayName="Name";Value=$Name;IsHidden=$False;OriginalType="System.String";IsReadOnly=$False;IsRequired=$True},`
    [pscustomobject]@{Name="DisplayName";DisplayName="Display Name";Value=$DisplayName;IsHidden=$False;OriginalType="System.String";IsReadOnly=$False;IsRequired=$True},`
    [pscustomobject]@{Name="Description";DisplayName="Description";Value=$Description;IsHidden=$False;OriginalType="System.String";IsReadOnly=$False;IsRequired=$False}`
    );DisplayRank=500;UiHint="Flat";Icon="dashboard"}} | ConvertTo-Json -Depth 100

	$contentType = 'application/json'
    $headers = BuildHeaders($token)
    $uri = "$IdentityServiceUri/api/DoAction()"
    $Res = Invoke-RestMethod -Uri $uri -ContentType $contentType -Method Post -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes($body))
	
	$errorKey = $Res.Messages[0].CommerceTermKey
	if ($errorKey -eq "CategoryNameAlreadyInUse") {
		return "Exists"
	}

    return $Res.ResponseCode

}

Binding it all together, we can how create the CreateCategoryFromCatalog function

Function CreateCategoryFromCatalog {
    [CmdletBinding()]
    PARAM
    (
    [string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Token,
    [string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$IdentityServiceUri,
    [pscustomobject] $Data
    )

    $catalog = $Data.Catalog
    $category = $Data.Name
    $categoryDescription = $Data.Description
    $category_friendlyId = "$catalog-$category"
    $catalogEntity = "Entity-Catalog-$catalog"
    
    $version = GetCatalogVersion -Token $token -Catalog $catalog -IdentityServiceUri $IdentityServiceUri
    $versionCategory = GetCategoryVersion -Token $token -Category $category_friendlyId -IdentityServiceUri $IdentityServiceUri

    if ($versionCategory -eq 0) {
        $result = AddCategory -Token $token -Category $catalogEntity -Version $version -Name $category -DisplayName $category  -Description $categoryDescription -IdentityServiceUri $IdentityServiceUri
        if ($result -ne "Ok") {
			if ($result -eq "Exists")  {
				Write-Host("category $category already exists")
			} else {
				Write-Host("Error adding category $category : $result")
				Exit 1
			}
        }
        $versionCategory = GetCategoryVersion -Token $token -Category $category_friendlyId -IdentityServiceUri $IdentityServiceUri
        Write-Host("Created category $category")
    }else {
		Write-Host("Already existing category $category")
	}
}

And now creating catalogs is a matter of a one-liner of code

CreateCategoryFromCatalog -Token $token -Data @{Catalog="JSSCatalog"; Name="JSSCat1"; Description="JSSCat1"} -IdentityServiceUri "https://$authoringAlias"
CreateCategoryFromCatalog -Token $token -Data @{Catalog="JSSCatalog"; Name="JSSCat2"; Description="JSSCat2"} -IdentityServiceUri "https://$authoringAlias"

In the next article I’ll show you to create Sellable items with variants and a template

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: