Link an asset to a product

This action script example links an asset to a specified product when the filename of that asset changes to {product number}_{name}. The action executes in the pre-commit phase (in-process).

Note

Pre-commit means that the script executes before the triggering event. In that case, the script executes before the entity is modified.

Before you begin
  • Ensure the schema includes entities and relations for M.Asset and M.Product.

  • Verify that the asset filenames match the requirements for linking, such as formatting or naming conventions.

Script

RequestResponse
using System.Linq;
using System.Threading.Tasks;

var asset = Context.Target as IEntity;
if(asset == null) return;

var filename = asset.GetPropertyValue<string>("FileName");
if(string.IsNullOrEmpty(filename)) return;

var splitFilename = filename.Split('_');
if(splitFilename.Count()  2) return;

var productNumber = splitFilename[0];
var productId = await GetProductId(productNumber);

if(productId.HasValue){
  var productRelation = asset.GetRelation("PCMProductToAsset");
  productRelation.SetIds(new long[]{ productId.Value });
  MClient.Logger.Info($"Asset {asset.Id} is linked to product {productId.Value}.");
}
else{
  MClient.Logger.Warn($"No product found with product number {productNumber}!");
}

async Task<long?> GetProductId(string productNumber)
{
  var query = Query.CreateQuery(entities => 
    from e in entities
    where e.Property("ProductNumber") == productNumber
    && e.DefinitionName =="M.PCM.Product"
    select e);
  var productId = await MClient.Querying.SingleIdAsync(query);
  MClient.Logger.Info(productId.ToString());

  return productId;
}

Script explanation

The included libraries are:

RequestResponse
using System.Linq;
using System.Threading.Tasks;

Since the action executes during pre-commit, we retrieve the Target object from the Context and cast it to IEntity. The Target is the asset involved in the creation or modification event. If the asset does not exist, the script exits:

RequestResponse
var asset = Context.Target as IEntity;
if(asset == null) return;

The GetPropertyValue method retrieves the FileName from the asset. If the filename is null or empty, the script exits:

RequestResponse
var filename = asset.GetPropertyValue<string>("FileName");
if(string.IsNullOrEmpty(filename)) return;

If the filename is in the specified format, it is split into two parts: {productNumber} and {name}. If not, the script exits.

RequestResponse
var splittedFilename = filename.Split('_');
if(splittedFilename.Count()  2) return;

The GetProductId(productnumber) method lazy-loads the productNumber. The productNumber is the number specified on the filename:

RequestResponse
var productNumber = splittedFilename[0];
var productId = await GetProductId(productNumber);

If the productId has a value, the SetIds method links the asset to the PCMProductToAsset relation:

RequestResponse
if(productId.HasValue){
  var productRelation = asset.GetRelation("PCMProductToAsset");
  productRelation.SetIds(new long[]{ productId.Value });
  MClient.Logger.Info($"Asset {asset.Id} is linked to product {productId.Value}.");
}
else{
  MClient.Logger.Warn($"No product found for product number {productNumber}!");
}

The GetProductId method uses the productNumber parameter to return the productId:

RequestResponse
async Task<long?> GetProductId(string productNumber)
{
  var query = Query.CreateQuery(entities => 
    from e in entities
    where e.Property("ProductNumber") == productNumber
    && e.DefinitionName =="M.PCM.Product"
    select e);
  var productId = await MClient.Querying.SingleIdAsync(query);
  MClient.Logger.Info(productId.ToString());

  return productId;
}

Setup

To set up your asset, script, action, and trigger:

  1. Create an asset (or edit an existing one) with a filename formatted as: {productnumber}_{name}.

  2. Create a script of the Action type; publish it, and enable it.

  3. Create an action of the Action script type, and link it to your script.

  4. Create a trigger:

    • In the General tab, set the Objective to Entity creation and Entity modification.

    • In the General tab, set the Execution type to In process.

    • In the Conditions tab, add a condition for the Asset(M.Asset) entity definition.

    • In this condition, add a new condition for the Filename(FileName) entity definition, and set it to Has changed.

    • In the Actions tab, add the related action under Pre-commit actions.

    • Save, and activate the trigger.

Do you have some feedback for us?

If you have suggestions for improving this article,