CTX Tags - Best Practice and Common Mistakes
9 min read
CTX tags are the most powerful group of tags that make the building language for SAP CPQ (Configure Price Quote) formulas. As the formulas can be used all around the application, in very different contexts, applicability of this topic is quite wide.
The CTX tags themselves are useful as an implementer is able to extract values from any context by selecting the context at first and then continue by drilling down through the list of hierarchically ordered objects and properties. But many of these items have their specifics worthy of paying attention to, otherwise you will end up with implementation errors for which you will need long hours of debugging to understand.
The article talks about the specifics and depicts some examples of wrong use. It will equip you with advice on how to use the tags properly.
Table of Contents
Main Context is Not Always Available
CTX is short for Context, which is the most appropriate name for the tags group as one
always starts building formulas by selecting the main context at first (Quote, Product, Visitor, Pricebook,
MyContainer, ...). SAP CPQ will let you build any formulas and use it as a condition or action anywhere inside
of the app. But the context might not be available in runtime, depending on how you use the formula. This
dependency is not just static, the actual user journey and the current objects on stack also determine some
Let us say that you have some formula to be evaluated in Configurator context, built by using a Quote-context tag: <*CTX( Quote. ___)*> .
Depending on how you arrived to the configuration and what is the state of the application parameters for your tenant, the quote object might or might not exist. This happens in the case when user journey starts from catalogue and parameters are set so no quote is created at first, in the background. If, for example, the new quote link takes you to quote directly and only then you enter Configurator by executing Add Item action, you will have Quote object available for sure, even though it is to be used in Configurator context.
If a context does not exist, do not expect SAP CPQ to push an error message or log some information about it - the tags language is conceived in a way to return empty string for a value which is not available, so formulas get robust and they work without crashes - as most often, that is the desirable way. So, if you have queried for a property of an object that is currently not available, SAP CPQ will use the empty value, which is quite hard to notice from end-user side if you do not have this in mind in advance.
Properties Also Depend on Context
It is not just the main context to which behavior runtime parameters influence significantly - this applies for multiple properties on lower levels too. Let us use the example of a widely used CurrentItem property inside of Quote context. For example, a formula that gets the value of a product attribute for the quote item could be:
<*CTX( Quote.CurrentItem.Attribute(Additional Disk Space).Value )*>
What implementers usually overlook is that this tag is built to be used
only inside of an item-loop context. It means the formula above can be used, e.g., as the calculation
formula for a quote item custom field. The engine would repeat the custom field calculation for every item
and CurrentItem would always be used to refer to the current item in the loop. That is correct and expected
But often, people use CurrentItem with wrong reasoning. For example: they aim to build some formula that runs in Configurator (product) context, but they want to use a certain field value coming from the corresponding product item in quote. This might be in the case when certain product calculation should run after user edits item.
They usually reach for CurrentItem in this case, by drilling down through options in the CTX builder, and
that is a wrong choice.
<*CTX( Quote.CurrentItem.____)*> will always point to the first item in quote if the context is not loop, as SAP CPQ always tries to resolve a formula and makes its calculation successful.
The issue here is not a formula crash, but that data coming from a wrong item is used, without implementer or end user being aware of it.
Quote.CurrentItem is just an example, this remark should be taken as a general one.
CTX Offers Better Formatting
It might be that you prefer regular tags as you are not aware of all CTX capabilities or that you just use CTX tags wrongly. Regular formula tags always return a single-formatted result as those, most often do not posses additional configuration options. CTX tags, by rule, offer you to format your output data, next to just fetching the value. This is quite important, as due to the current user preferences and selections in quote, things might become very complex.
For example, for any date field, with CTX, you can choose which exact format you want to get as the
output, because the format that the system uses to store dates is often different from end-user date format.
The same applies for time zones that every user can set for itself. So, you could use the following example
tags to extract some date info:
<*CTX( Quote.DateCreated.Format(yyyy.MM.dd HH:mm:ss.ff) )*>
<*CTX( Quote.DateCreated.InUserTimezone.InUSDateFormat )*>
With numbers, this is becoming even more important. For example, if you are building a formula for a quote-level rule, it is significant if the price field that your are using returns the value expressed for the market and currency selected in quote, in run time, or if they use values expressed in the default market and currency. Numbers can also be formatted very differently and use different separators for decimals and thousands, so if you do numbers analysis it is important which format some tag returns.
This is why for all pricing fields, in the very end you are able to use one of the four formats below (here on the example of the quote total):
<*CTX( Quote.Total.TotalAmount.DefaultDecimal )*>
<*CTX( Quote.Total.TotalAmount.DefaultDisplay )*>
<*CTX( Quote.Total.TotalAmount.MarketDecimal )*>
<*CTX( Quote.Total.TotalAmount.MarketDisplay )*>
Default means that the price is expressed in the default market and currency, while Market implies that the current user-selected market in quote, will be used for price formatting. Decimal means that en-US number format is used together with the default number of display decimals while Display implies that the user number format is used.
All together, CTX tags offer many options to format your data and get the right output. Conversely, pay attention that by disregarding output format that a tag retrieves by default, you might end up with business logic errors that could be hard to notice and, usually, get exposed only after orders are placed for live quotes. So, you are expected to build correct formatting into your formulas from the start.
Use of CTX in Documents Generation
Those who work with SAP CPQ document templates are familiar with our document-generation tags language - a different language in comparison to SAP CPQ formula tags where CTX is located. Those people also know that the language is not easy to use as the tags, for example, use abbreviated names to fit into document format. Since there are many of them and every object property has its own separate tag, those are not easy to manage. This is why we created tools that allow users to select data points and SAP CPQ would generate a document template itself, together with the tags content. The user needs to add static text and styling later and use it to create a new template from setup.
But you are not limited to the methods above and to eventual search through documentation pages. You can use
CTX tags inside of document templates quite easily.
This will also work optimally, but this of course based on the type of CTX tag that you are using. It will not be optimal if you query database.
For example, instead of memorizing (or going to help pages) that
is the tag that retrieves the email of the quote owner you can go with CTX tags that you are quite used to work with:
<<Q_TAG(<*CTX( Quote.Owner.Email )*>)>>
Q_TAG is the hook to fetch a CTX tag value, from a template, in quote context.
The original tag is, by rule, shorter in length than the CTX counterpart, but CTX can do much more and you, will more likely by now, have much more experience with the latter.
You are not limited to quote context only - you can execute CTX in the item context too. For this you should use the C_TAG hook. So, instead of
you could use
<<C_TAG(<*CTX( Quote.CurrentItem.RolledUpCartItem )*> )>>
as the second option is probably how you are used to fetch rolled up number for a cart item.
CTX tags are the broadest and the most useful group of SAP CPQ tags that build SAP CPQ formulas.
But there are many specifics and points of attention that one needs to be aware of regarding CTX. This article tries to focus on those which are the most typical.
The article will also not give any basic tutorial on CTX tags. That you can find in the official help page on CTX, where the list of all tags is also located.
CTX is not the only type of tags - there are others about which you can read here.
Do not forget to browse through other articles in the series and learn about other crucial business topics that often get implemented wrong during project implementation.