5

When updating the stock balance in a catalog I have found this pipeline to help me do that.

UpdateItemAvailabilityPipeline

In order to use that I need to know the name of the product catalog, the productId (and if applicable, the variantId) and what amount to change the current stock balance with.

Unfortunatly what I have to work with is only one of those three, the productId. Instead of the product catalog name I have a name for the inventory catalog and instead of the number to change the stock balance with I have a number to set the stock balance to.

I could of cause fetch the current stock balance from the database and calculate the difference to what it needs to be but if I don't have to do that extra database call, all the better. And I still would need a way to get the product catalog name from the inventory catalog name.

In order to avoid that I wonder:

Is there a pipeline that I could use that let me set a fix number directly in the inventory catalog without going through the product catalog?

2
  • Why you have these constraints? No product catalog name available and balance delta? Commented Apr 16, 2018 at 8:53
  • The system that feed my code with information does not know the name of the product catalog, just the inventory catalog name and it sends the acctual quantity it have, not a delta since it does not know how many items the store think it have. Commented Apr 16, 2018 at 9:01

1 Answer 1

5

There's no simple "Set product X to inventory Y" command or pipeline, but here's how we've done it. I've included stubs for handling variants, but not the code that actually loads the variant.

I preferred a pipeline, but I'll just delimit the blocks with comments to keep things simple. The pipeline was invoked once for each inventory update from a Command using a transaction.

It also assumes that the InventorySet has already been found and added to the context (we only do this once, so it's not part of this pipeline).

Yes, it's a fair bit of code unfortunately, but it does all the things that the BizFX UI does when you associate a product to an inventory set.

public class UpdateInventoryArgument
{
    public string ProductId { get; set; }
    public int Quantity { get; set; }
}

//////////////////////////////////
// ResolveSellableItemBlock

// Inject
IFindEntityPipeline findEntityPipeline;

var sellableItemId = $"{CommerceEntity.IdPrefix<SellableItem>()}{arg.ProductId}";
var sellableItem = await findEntityPipeline.Run(new FindEntityArgument(typeof(SellableItem), sellableItemId, false), context) as SellableItem;

if (sellableItem == null)
{
    context.Abort(await context.CommerceContext.AddMessage(context.GetPolicy<KnownResultCodes>().Warning, "EntityNotFound",
        new[] { sellableItemId }, $"SellableItem '{sellableItemId}' was not found."), context);
    return null;
}

context.CommerceContext.AddUniqueObjectByType(sellableItem);

ItemVariationComponent itemVariation = null;

// Launch this pipeline with Options, not a Context, so that future blocks
// don't accidentally get the previous interation's variant
if (itemVariation != null)
{
    context.CommerceContext.AddUniqueObjectByType(itemVariation);
}

//////////////////////////////////
// ResolveInventoryInformationBlock

// Inject
IGetInventoryInformationPipeline getInventoryInformationPipeline;

var sellableItem = context.CommerceContext.GetObject<SellableItem>();
var itemVariation = context.CommerceContext.GetObject<ItemVariationComponent>();

var inventoryInformation = await getInventoryInformationPipeline.Run(new SellableItemInventorySetArgument(sellableItem.Id, arg.InventorySetId)
{
    VariationId = itemVariation != null ? itemVariation.Id : null
}, context);

if (inventoryInformation == null)
{
    string inventoryInformationId = $"{arg.InventorySetId.SimplifyEntityName()}-{sellableItem.ProductId}";
    if (itemVariation != null)
    {
        inventoryInformationId += $"-{itemVariation.Id}";
    }

    inventoryInformation = new InventoryInformation
    {
        Id = $"{CommerceEntity.IdPrefix<InventoryInformation>()}{inventoryInformationId}",
        FriendlyId = inventoryInformationId,
        InventorySet = new EntityReference(arg.InventorySetId, ""),
        SellableItem = new EntityReference(sellableItem.Id, ""),
        VariationId = itemVariation != null ? itemVariation.Id : null
    };

    inventoryInformation.GetComponent<TransientListMembershipsComponent>().Memberships.Add(CommerceEntity.ListName<InventoryInformation>());
}

context.CommerceContext.AddUniqueObjectByType(inventoryInformation);

////////////////////////
// UpdateInventoryInformationBlock

var inventoryInformation = context.CommerceContext.GetObject<InventoryInformation>();

entoryInformation = context.CommerceContext.GetObject<InventoryInformation>();

if (inventoryInformation == null)
{
    return Task.FromResult((UpdateInventoryArgument)null);
}

inventoryInformation.Quantity = arg.Quantity;

return Task.FromResult(arg);

//////////////////////
// PersistInventoryInformationPipeline

// Inject
ICreateRelationshipPipeline createRelationshipPipeline;
IPersistEntityPipeline persistEntityPipeline;

var inventoryInformation = context.CommerceContext.GetObject<InventoryInformation>();
var sellableItem = context.CommerceContext.GetObject<SellableItem>();
var itemVariation = context.CommerceContext.GetObject<ItemVariationComponent>();

if (inventoryInformation == null)
{
    context.Abort(await context.CommerceContext.AddMessage(context.GetPolicy<KnownResultCodes>().Error, "EntityNotFound",
        new object[0], $"InventoryInformation was not found in context"), context);
    return null;
}

if (sellableItem == null)
{
    context.Abort(await context.CommerceContext.AddMessage(context.GetPolicy<KnownResultCodes>().Error, "EntityNotFound",
        new object[0], $"SellableItem was not found in context"), context);
    return null;
}

var isNew = inventoryInformation.IsPersisted == false;

await persistEntityPipeline.Run(new PersistEntityArgument(inventoryInformation), context);

if (isNew)
{
    await createRelationshipPipeline.Run(new RelationshipArgument(arg.InventorySetId, inventoryInformation.Id, "InventorySetToInventoryInformation"), context);

    (itemVariation != null ? itemVariation.GetComponent<InventoryComponent>() : sellableItem.GetComponent<InventoryComponent>())
        .InventoryAssociations.Add(new InventoryAssociation
        {
            InventoryInformation = new EntityReference(inventoryInformation.Id, ""),
            InventorySet = new EntityReference(arg.InventorySetId, "")
        });

    await persistEntityPipeline.Run(new PersistEntityArgument(sellableItem), context);
}

return arg;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.