Work with the Pricing Entity Views and Actions API

Abstract

How to use the Sitecore XC Pricing Entity Views and Actions API to exchange pricing-related information.

External systems can exchange pricing-related information using the Entity Views and Actions API, an authoring API that is based on the Commerce Views service.

You must include Commerce Engine operations and commands within a container call (using C#) as shown in this example.

To execute any operation in the Sitecore Experience Commerce (XC) system, the calling system must first obtain a valid bearer authorization token from the Sitecore Identity Server.

Note

The Views and Actions API is an authoring API designed to service a business user interface and is not optimized for integration scenario.

You should consider the following when using the Views and Actions API for your commerce integration:

  • The Views and Actions API can only process one Commerce entity at the time and does not support batch processing.

  • The Views and Actions API carries more overhead than the Commerce web service API. A call to the Views and Action API is typically a 3-step process that requires getting the action's view, modifying the view's properties with updated values, and then executing the action.

The XC Pricing View Actions API provides actions to add, get, edit and manage associated catalogs for price books.

You can use a price book using the Views and Actions API. Consider the following in mind when adding a price book:

  • Price book names are unique.

  • Once you create a price book, you cannot change its name.

  • You cannot delete price books.

To add price book:

  1. Get the entity view for the action:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView(string.Empty, "Details", "AddPriceBook", string.Empty);
    EntityView view = Proxy.GetValue(query);
  2. Modify the view's properties. At a minimum, you must provide a value for the Name property. All other view properties are optional. In the following example, the query includes a value for all properties:

    var nameProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Name"));
    nameProperty.Value = "MyPriceBook";
    var displayNameProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("DisplayName"));
    displayNameProperty.Value = "Book Display Name";
    var descriptionProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Description"));
    descriptionProperty.Value = "Book Description";
    var currencySetProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("CurrencySetId"));
    currencySetProperty.Value = "{0F65742E-317F-44B0-A4DE-EBF06209E8EE}";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

    The response returns the price book friendly ID in the PriceBookAdded model, for example:

    PriceBookAdded priceBookAddedModel = command.Models.OfType<PriceBookAdded>().FirstOrDefault();
    string bookFriendlyId = priceBookAddedModel?.PriceBookFriendlyId;

You can get different price book views using the Pricing Entity Views and Actions API. Price books use composite entity views. When you query a price book's Master view, the response also returns the child views (for example, Details, PriceBookCatalogs, and PriceCards child views. You can query child views individually. Child views can also be the parent of other child views.

  • To retrieve a price book's master view:

    DataServiceActionQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", "Master", string.Empty, string.Empty);
    EntityView view = Proxy.GetValue(query);
  • To retrieve a price book's child view, for examples, a details view, associated catalogs view or a price cards view:

    // getting the book's details view
    query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", "Details", string.Empty, string.Empty);
    view = Proxy.GetValue(query);
    
    // getting the book's associated catalogs view
    query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", "PriceBookCatalogs", string.Empty, string.Empty);
    view = Proxy.GetValue(query);
    
    // getting the book's cards view
    query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", "PriceCards", string.Empty, string.Empty);
    view = Proxy.GetValue(query);

Edit a price book using (C#)

You can make change to a price book's display name, description and currency set properties using the Pricing Entity Views and Actions API. If you do not provide a new value for one of those properties, then current value remains unchanged.

To change a price book's properties:

  1. Get the entity view for the action, for example:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", "Details", "EditPriceBook", string.Empty)
    EntityView view = Proxy.GetValue(query);
  2. Modify the view's properties as needed, for example,

    var displayNameProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("DisplayName"));
    displayNameProperty.Value = "Edited Book Display Name";
    var descriptionProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Description"));
    descriptionProperty.Value = "Edited Book Description";
    var currencySetProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("CurrencySetId"));
    currencySetProperty.Value = "{0F65742E-317F-44B0-A4DE-EBF06209E8EE}";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

Associate a catalog to a price book (C#)

You can use the Pricing Views and Actions API to associate a catalog to a price book in order to apply the price cards to catalog items. You can associate the same price book to multiple catalogs, but you can only associate a catalog to one price book.

To associate a catalog to a price book:

  1. Get the entity view for the action, for example:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", "PriceBookCatalogs", "AssociateCatalog", string.Empty);
    EntityView view = Proxy.GetValue(query);
  2. Modify the view's properties, for example:

    var catalogProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("CatalogName"));
    catalogProperty.Value = "MyCatalog";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

Disassociate a catalog from a price book (C#)

You can disassociate a catalog from a price book when you no longer want its price cards to apply to sellable items defined within the catalog.

To disassociate the price book:

  1. Get the entity view for the action:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", string.Empty, "DisassociateCatalog", string.Empty);
    EntityView view = Proxy.GetValue(query);
  2. Modify the view's properties, for example: view.ItemId = "MyCatalog";

  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

You can use the Pricing Views and Actions API to perform add, get, edit, duplicate and delete actions for price cards.

You can create a price card within a specified price book. The name of a price card must be unique within the price book. You cannot change the name of a price card after you create it.

To create a price card:

  1. Get the entity view for the action, for example:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", "Details", "AddPriceCard", string.Empty);
    EntityView view = Proxy.GetValue(query);
  2. Modify the view's properties. At a minimum, you must provide a value for the "Name" properties. Optionally, you can specify values for the other properties, for example:

    var nameProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Name"));
    nameProperty.Value = "MyPriceCard";
    var displayNameProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("DisplayName"));
    displayNameProperty.Value = "Card Display Name";
    var descriptionProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Description"));
    descriptionProperty.Value = "Card Description";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

    The response returns the price card friendly ID using the PriceCardAdded model, for example:

    PriceCardAdded priceCardAddedModel = command.Models.OfType<PriceCardAdded>().FirstOrDefault();
    string cardFriendlyId = priceCardAddedModel?.PriceCardFriendlyId;

You can retrieve different price card views using the Pricing Views and Actions API. Price card views are implemented as composite entity views. When you query a price card'sMaster view, the response returns its child views (for example the price card's Details and PriceSnapshots, child views.

You can also query child views individually. Child views can defined their own child views.

  • To retrieve a price card's master view:

    DataServiceActionQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "Master", string.Empty, string.Empty);
    EntityView view = Proxy.GetValue(query);
  • To retrieve a price card's child views individually, for example the "Details" view, and the "PriceSnapShots" view, respectively:

    // getting the card's details view
    query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "Details", string.Empty, string.Empty);
    view = Proxy.GetValue(query);
    
    // getting the card's snapshots view
    query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "PriceCardSnapshots", string.Empty, string.Empty);
    view = Proxy.GetValue(query);
    

You can modify the DisplayName and the Description properties of an existing price card using the Pricing Views and Actions API. You cannot change the value of the name property (the price card's internal name). If you do not provide new values for a property, its current value remains unchanged.

To edit a price card:

  1. Get the entity view for the action:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceBook-{bookFriendlyId}", "Details", "EditPriceBook", string.Empty)
    EntityView view = Proxy.GetValue(query);
  2. Set the view's properties, for example:

    var displayNameProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("DisplayName"));
    displayNameProperty.Value = "Edited Book Display Name";
    var descriptionProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Description"));
    descriptionProperty.Value = "Edited Book Description";
    var currencySetProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("CurrencySetId"));
    currencySetProperty.Value = "{0F65742E-317F-44B0-A4DE-EBF06209E8EE}";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

You can use the Views and Actions API to duplicate an existing price card to create a new price card within the same price book. The price snapshots in the duplicated price card are set to draft status.

To duplicate a price card:

  1. Get the entity view for the action:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "Details", "DuplicatePriceCard", string.Empty);
    EntityView view = Proxy.GetValue(query);
  2. Modify the views properties by providing a name for the new price card, for example:

    Note

    The name of the price card must be unique within a price book.

    var nameProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("DuplicateCardName"));
    nameProperty.Value = "MyDuplicatePriceCard";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

You can use the Views and Actions API to delete a price card from a price book.

Note

You cannot delete a price card that contains approved price snapshots.

To delete a price card:

  1. Get the entity view for the action, for example:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", string.Empty, "DeletePriceCard", string.Empty);
    EntityView view = Proxy.GetValue(query);
  2. Modify the view's properties to specify the friendly ID of the price card to delete:

    view.ItemId = $"Entity-PriceCard-{cardFriendlyId}";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

A snapshot defines a price that can apply to a price card at a specified date and time. The Pricing Views and Actions API provides add, edit, remove, add tag, remove tag actions for snapshots.

Add a snapshot (C#)

You can add a snapshot to an existing price card using the the Pricing Views and Actions API.

To add a snapshot to a price card:

  1. Get the entity view for the action, for example:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "Details", "EditPriceCard", string.Empty);
    EntityView view = Proxy.GetValue(query);
  2. Modify the view's properties as required, for example:

    var displayNameProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("DisplayName"));
    displayNameProperty.Value = "Edited Card Display Name";
    var descriptionProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Description"));
    descriptionProperty.Value = "Edited Card Description";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

You can modify the properties of a price card's snapshot when it is in a draft status.

To edit a snapshot:

  1. Get the entity view for the action:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "PriceSnapshotDetails", "EditPriceSnapshot", snapshotId);
    EntityView view = Proxy.GetValue(query);
  2. Modify the properties view as required:

    var dateProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("BeginDate"));
    dateProperty.Value = DateTimeOffset.UtcNow.AddDays(5).ToString(CultureInfo.InvariantCulture);
    var tagsProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("IncludedTags"));
    tagsProperty.Value = "['Tag1', 'Tag2']";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

Remove a price snapshot (C#)

You can remove a price snapshot from a price card programmatically using the Pricing actions and view API.

To remove a snapshot from:

  1. Get the entity view for the action:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", string.Empty, "DeletePriceCard", snapshotId);
    EntityView view = Proxy.GetValue(query);
  2. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

You can use the Pricing Views and Actions API to apply tiered pricing, a way to apply a discount based on the quantity of a sellable item purchased. For example, using tiered pricing, you can set the price of a sellable to $5.00, but reduce the price to $4.00 if the customer buys a quantity of five or more of the same sellable item.

The Pricing Views and Actions API provides methods to add, edit, and remove price tiers from a price snapshot. You can only perform these operations on price snapshots with a draft status.

Add a price tier to a snapshot (C#)

You can add multiple price tiers to a snapshot at the same time. When you add a price tier, you must first select the currency, and then specify the tier's quantities and prices.

The following example shows how to add two tiers with USD currency, using quantities of 1 and 2, and prices of 20 and 10. Only one tier child view is returned, if you wish to add more than one tier you can add more child views.

  1. Get the view for the action, specifying the currency, for example, to USD:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "PriceRow", "SelectCurrency", snapshotId);
    EntityView view = Proxy.GetValue(query);
    var currencyProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Currency"));
    var availableCurrenciesPolicy = currencyProperty.Policies.OfType<AvailableSelectionsPolicy>().FirstOrDefault();
    currencyProperty.Value = availableCurrenciesPolicy?.List.FirstOrDefault().Name;
    // == "USD"
    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

    Note

    The response only returns one price tier child view.

  2. Set the views properties, for example, to specify the quantities and prices:

    Note

    As shown in the following example, you can add multiple price tiers by adding additional "PriceCell" entities and setting the required properties values.

    view = command.Models.OfType<EntityView>().FirstOrDefault(v => v.Name.Equals(view.Name));
    EntityView firstPriceCellView = view.ChildViews.OfType<EntityView>().FirstOrDefault(cv => cv.Name.Equals("PriceCell"));
    firstPriceCellView.Properties.FirstOrDefault(p => p.Name.Equals("Quantity")).Value = "1";
    firstPriceCellView.Properties.FirstOrDefault(p => p.Name.Equals("Price")).Value = "20";
    // only one PriceCell child view is returned, if you wish to add more than one tier you can add more PriceCell child views
    EntityView secondPriceCellView = new EntityView { Name = "PriceCell", EntityId = $"Entity-PriceCard-{cardFriendlyId}", ItemId = snapshotId };
    secondPriceCellView.Properties.Add(new ViewProperty { Name = "Quantity", Value = "2" });
    secondPriceCellView.Properties.Add(new ViewProperty { Name = "Price", Value = "10" });
    view.ChildViews.Add(cellView);
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

Edit a price tier

You can change the price tier amount in a snapshot. You can edit the price of multiple price tiers within a snapshot at the same time. You cannot change the price tier currency.

To change a price tier amount:

  1. Get the entity view for the action:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "PriceRow", "EditCurrency", $"{snapshotId}|USD");
    EntityView view = Proxy.GetValue(query);

    Note

    If a snapshot contains multiple price tiers, the response returns each tier as a child view.

  2. Modify the value of the PriceCellView properties to specify the desired amount, for example:

    EntityView firstPriceCellView = view.ChildViews.OfType<EntityView>().FirstOrDefault(cv => cv.Name.Equals("PriceCell"));
    firstPriceCellView.Properties.FirstOrDefault(p => p.Name.Equals("Price")).Value = "50";
    EntityView secondPriceCellView = view.ChildViews.OfType<EntityView>().LastOrDefault(cv => cv.Name.Equals("PriceCell"));
    secondPriceCellView.Properties.FirstOrDefault(p => p.Name.Equals("Price")).Value = "100";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

Remove a price tier

You can remove a price tier from a snapshot or remove multiple price tiers (of the same currency) in a single query.

To remove a price tier:

  1. Get the entity view for the action, for example, for a price tier using the USD currency:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "PriceRow",  string.Empty, $"{snapshotId}|USD");
    EntityView view = Proxy.GetValue(query);
  2. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

Price snapshots are subject to an approval process. A price snapshot must be in the approved status in order to apply. During the snapshot approval process, the price snapshot transition as follows:

  • From Draft to ReadyForApproval status

  • From ReadyForApproval to Draft

  • From ReadyForApproval to Approved

Note

You cannot change the status of an approved snapshot.

Change a snapshot status from draft to ReadyforApproval (C#)

You request approval of a draft snapshot by changing its status to ReadyForApproval.

To request approval of a snapshot:

  1. Get the entity view for the action, for example:

    {cardFriendlyId}", "SetSnapshotApprovalStatus", "RequestSnapshotApproval", snapshotId);
    EntityView view = Proxy.GetValue(query);
    
  2. Set the view's property:

    var commentProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Comment"));
    commentProperty.Value = "Requesting approval";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

Change a snapshot status from ReadyforApproval to draft (C#)

You change the status of a snapshot from ReadyforApproval to draft to reject a snapshot submitted for approval. The draft snapshot can then be modified.

To reject a snapshot:

  1. Get the entity view for the action:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "SetSnapshotApprovalStatus", "RejectSnapshot", snapshotId);
    EntityView view = Proxy.GetValue(query);
  2. Set the view's properties, for example:

    var commentProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Comment"));
    commentProperty.Value = "Rejecting approval"
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));

Change a snapshot status from ReadyforApproval to Approved (C#)

You approve a price snapshot by changing its status from ReadyforApproval to Approved. An approved snapshot cannot be modified.

To approve a price snapshot:

  1. Get the entity view for the action, for example:

    DataServiceQuerySingle<EntityView> query = container.GetEntityView($"Entity-PriceCard-{cardFriendlyId}", "SetSnapshotApprovalStatus", "ApproveSnapshot", snapshotId);
    EntityView view = Proxy.GetValue(query);
  2. Set the view's properties, for example:

    var commentProperty = view.Properties.FirstOrDefault(p => p.Name.Equals("Comment"));
    commentProperty.Value = "Approving";
  3. Execute the action:

    CommerceCommand command = Proxy.DoCommand(container.DoAction(view));