Oracle CPQ Best Practices
Oracle CPQ Best Practices
PURPOSE
The purpose of good coding style is to write code that is readable. Readable code is more easily
understood and is therefore easier to debug, extend and modify. The following are a set of
guidelines that should only be violated with good reason (e.g. convention dictates a different
format).
DETAILS
Neat and logically organized code helps to ensure that there is not any wasted time on
unnecessary computations and is exactly like reading a good essay. It helps the reader's
understanding and aids them in unifying concepts and processes in their mind.
Major sections of the code should be clearly marked and contain a brief explanation of its
purpose, who wrote the code and the date the code was written or modified
o Provide visual contrast if possible.
o These are like chapters in a book, or specific tasks in an algorithm.
o Aids another programmer in identifying where they are in the script, as well as the
current section's purpose.
o Aids in ensuring the script is well structured and reminds the coder of what you did in
different areas of a very large BML script (such as Commerce Pricing).
o Aids everyone in quickly skimming or scanning the BML script without having to read
through multiple, individual lines of comments.
Secondary sections of the code should also be clearly marked and contain a brief explanation if
necessary
o Some major sections of the BML script can become very complex. Decompose the steps
and explain them to the reader as clearly as possible.
Group related lines of code together
o The proximity of related lines of code immediately communicates to a reader that those lines
share a relation of some sort.
o This helps a reader to identify which lines of code correspond to which pieces of
functionality, therefore aiding debugging, amendment and extension.
o Curly brackets should almost always close at the beginning and end of a line of code The only
exception for the curly bracket rules should be the inner array declaration of a hard-coded 2D
array.
No code of any kindshould exist on the same line as a closing curly bracket denoting the end of a
nested code block.
The name and format of a BML local variable should immediately communicate its purpose,
intended behavior, and usage. There should never be more than one statement on one line (i.e.
never more than one semicolon ending a statement)
o Local variables used as CONSTANTS should:
Have all letters CAPITALIZED
Use UNDERSCORES to separate words in the name of the constant Example: ITEM_DELIM =
"*@*@*";
o Local variables used as VARIABLES should:In all cases, the name of the variable
should describe itself.
For example: totalListPrice is probably the sum of all line item list prices
The first letter should be lower case
The first letter of each subsequent word in the name should be UPPER CASE
DO NOT use underscores to delimit separate words in the name Example: totalListPrice =
0.0
Variable names for Arrays should have the "List", "Arr", "Array" and/or "2D" suffix
Example:docNumList, upgradedPartsArray, partsData2DArray
Variable names for Dictionaries should have the "Dict" suffix, and have a comment at the end
of the declaration explaining the mapping between Key and Value
Example:
sequenceNumDict = dict(string) //Key: Document Number, Value:
Sequence Number
relatedLicenseToDocNumDict = dict(float) //Key: relatedLicense,
Value: Document Number
o The exception to this rule is when iterating over Records in a RecordSet. For example:
"for partRecord in partRecords {"
Variable names for RecordSets should have the "Records" suffix. For example: partRecords
Variable names for Booleans should have the "is" or "has" prefix (or whatever can be answered
with a "yes/no" answer). Possible exceptions include standard booleans such as "debug"
Example: isUpgrade, isMandatory, hasRelatedLicense
There should never be more than one statement on one line that is, never more than one
semicolon ending a statement).
Print statements should be extricated from convoluted code and separated into a debug-flag
controlled "if" block, if possible, and if it doesn't cause the code to become less readable.
Functions with a single argument should always enclose that argument in parentheses.
For example: not(hasLicensing) rather than "not has Licensing".
Extremely long single-line statements, such as String concatenations, should be split across
multiple lines in an easy-to-read manner.
COMMERCE BEST PRACTICES
PURPOSE
By following these Best Practices, you will ensure your Oracle CPQ Experience is as smooth and
friendly as possible.
DETAILS
Attributes
Rules
No nested loops.
Minimize number of loops.
Select variables carefully at the line level.
Keep in mind the difference between document number and sequence number.
Do not use advanced actions unless there is a demonstrated need. All validation and constraint
rules written with advanced action attributes will be returned as a nested dictionary.
If you need to loop through line items, please do store them into temporary variables, for
example, string dictionary or float dictionary. After you store them, use the temporary variables
than looping through line item documents collection.
Always do the line item looping on the advanced modify / default
Return format [docNo]~variableName~variableValue|
Other
Avoid using the line item attribute advanced function on modify action.
When building the result string, use a temporary result string in loops in order to minimize the
number of large string concatenations.
Advanced validations will no longer be available on commerce actions. All validations will be
written from the commerce rule editor page. However, if you are upgrading from an earlier
version of BigMachines, your current advanced validations will remain in place, until you
migrate to the new commerce validation rules.
Start with the standard QuickStart commerce process when possible.
Limited number of data columns available, so define carefully.
Always use new format instead of legacy.
Make sure to transition document out of start step.
Test performance early and often. AJAX enabled constraint and hiding rules might make the
transaction page slow depending on the number of attributes, rules, use of advanced function etc.
Pricing is not supported in the Start step. It is best practice to save the quote after returning from
Config. After saving, you can apply discounts or other pricing adjustments.
CONFIGURABLE ATTRIBUTES BEST PRACTICES
PURPOSE
The purpose of this document is to state the best practices for configuration attributes.
DETAILS
Configurable Attributes
Image Menu
PURPOSE
DETAILS
Always
Use new format instead of legacy where the choice is available (Recommended Items and
Approval Sequences for example).
Transition document out of start step, otherwise it will be removed.
Keep in mind the limited number of data columns available.
o Define carefully (search, native reporting, and timer variables must also be columns).
o Also be wary of data types, these can never be switched once created.
When Possible:
Never:
PURPOSE
DETAILS
Any added or changed functionality should be broken into logical modules for each pricing
requirement, not all placed in one large add-on function. For example, if you have a requirement
for customer specific pricing and a requirement for promotional pricing, these should each have
their own function in order to keep the code manageable and modularized.
Any pricing functionality that must be added on top of the QuickStart standard functionality
should be added as follows:
o Create a new BML Library for each module - this is where the BML should be written for the
new functionality.
o Call the BML Library from the pricing function, passing in the necessary parameters. The
BML Library call should be assigned to a variable, that way the return value of the BML
Library will be stored in that variable.
o An example of this is the QuickStart Max Discount functionality - the logic is in a BML
Library and this library gets called from the pricing function.
Any functionality that must be changed from the QuickStart standard functionality should either
be changed directly in the pricing function or placed in a BML Library and called from the
pricing function using the following guidelines:
o If very little code must be added to change the QuickStart pricing function, then the changes
can be made directly in the pricing function (existing lines should never be deleted, only
commented out, and comments detailing the change should be added).
o If the change is substantial and the functionality can be modularized, then a BML Library
should be created for the new functionality and called from within the pricing function. An
example of this is the QuickStart Volume Pricing functionality - the logic is in a BML
Library and this library gets called from within the pricing function.
Do not put validations in the pricing script. Do validations in the validations section or a separate
library
Eliminate unused code. Frequently, portions of the QuickStart template are commented out in
lieu of newly-implemented script. These unused blocks of code should be deleted.
Don’t declare variables unnecessarily. If a variable is used as a static value, do not declare a
variable for this purpose.
If multiple loops are used to iterate through line items, combine them if possible. In addition to
aiding the compile size, user-side performance will improve, as well.
Combine conditional blocks of text. If several blocks of text are separately controlled by the
same condition (as in “if” statements), combine them so that the compiler only must assess the
condition once.
CONFIGURATION ARRAY BEST PRACTICES
PURPOSE
The purpose is to portray the best practices for utilizing configuration array sets.
DETAILS
If you created the wrong way you DO NOT need to delete your attribute and recreate. Here are
the steps to fix an Array Set that is not showing the increment / decrement buttons:
o Do the following for each array in the array set:
Go to the Array Attribute on the admin side.
Go to the Set Properties tab.
Change the Array Set from the real one to the [DEFAULT] one.
Change the Array Control Attribute to the blank entry.
Click Apply. *important step*
Change the Array Set back to the real one.
Click Update.
o Once you have done that for all arrays, the little icons should come back.
If the +/- buttons are still not available, ensure that the control attribute is not associated to any
other attribute sets.
o Do the following to verify the array control attribute association:
Go to the array control attribute
Uncheck the Array Control Attribute check box
Click Apply to attempt to confirm the change
An error should be shown on the top stating:
"To uncheck the Array Control Check Box, you must first remove the
association between this config attribute and the following Array Sets:
Array Set A (arraySetA)
Array Set B (arraySetB)"
o Locate the unwanted array sets and remove the association of the control attribute.
If you recommend a value for a string array of “” (blank) or $BM_UNCHANGED_STR$ (leave
value unchanged), even if the value is blank, you will still get the recommendation message
(Don't select any value).
When you add a new element to an array using the +/- buttons, the value it takes is the value of
the previous last element (the now penultimate element). Defaults are not respected in arrays.
The recommendation text for an array attribute always shows the variable name of the attribute,
rather than the display name, as for non-array attributes.
Set Type Recommendations will work for an array attribute only if none of the values of those
attribute elements is changed by the user. Once changed, the system treats it as an overwrite of the
attribute and will not perform a Set recommendation on any elements that get added afterward.
Force Set Type Recommendations can only be used
CUSTOM HTML BEST PRACTICES
PURPOSE
The purpose is to write well-structured and standards-compliant custom HTML code, that is easy to
follow and to debug.
SOLUTION
HTML is a language that allows non-standard code to execute and render to varying levels of
accuracy. Successful rendering, however, does not mean that the code is semantically correct or
guarantee that it will validate as standards compliant. In addition, non-standard code may cause
rendering issues. When writing HTML, please make sure to nest and close all elements correctly, to
use IDs and classes appropriately, and to always validate the code.
The code that follows has multiple errors, including using the intro ID attribute value multiple times
when it should be a unique value, closing the <p> and <strong> elements in the wrong order within
the first paragraph, and not closing the <p> element at all in the second paragraph:
Bad Code
<p id="intro">New items on the menu today
include <strong>caramel apple cider and breakfast
crepes</p>.</strong>
<p id="intro">The caramel apple cider is delicious.
Good Code
<p class="intro">New items on the menu today
include <strong>caramel apple cider and breakfast
crepes</strong>.</p>
<p class="intro">The caramel apple cider is delicious.</p>
Make Use of Semantic Elements
The library of elements in HTML is fairly large, with well over 100 elements available for use.
Deciding which elements to use to describe different content may be difficult, but these elements are
the backbone of semantics.
Here the HTML doesn’t use the proper heading and paragraph elements; instead, it uses meaningless
elements to style and group content:
Bad Code
<span class="heading"><strong>Welcome Back</span></strong>
<br><br>
It has been a while. What have you been up to lately?
<br><br>
Good Code
<h1>Welcome Back</h1>
<p>It has been a while. What have you been up to lately?</p>
Here are a few quick rules that can help keeping the syntax clean and organized:
Use lowercase letters within element names, attributes, and values
Indent nested elements
Strictly use double quotes, not single or completely omitted quotes
Remove the forward slash at the end of self-closing elements Omit
the values on Boolean attributes
Observing these rules will help keep the code neat and legible. Looking at the two sets of HTML
here, the good code is easier to digest and understand:
Bad Code
<Aside>
<h3>Chicago</h3>
<H5 HIDDEN='HIDDEN'>City in Illinois</H5>
<img src=chicago.jpg alt="Chicago, the third most
populous city in the United States" />
<ul>
<li>234 square miles</li>
<li>2.715 million
residents</li> </ul>
</ASIDE>
Good Code
<aside>
<h3>Chicago</h3>
<h5 hidden>City in Illinois</h5>
<img src="chicago.jpg" alt="Chicago, the third
most populous city in the United States">
<ul>
<li>234 square miles</li>
<li>2.715 million residents</li>
</ul>
</aside>
Use Practical ID & Class Values
ID and class values need to be practical, relating to the content itself, not the style of the content.
Using a value of red to describe red text isn’t ideal, as it describes the presentation of the content.
Should the style of the text ever need to be changed to blue, not only does the CSS have to be
changed, but so does the HTML in every instance where the class red exists.
The HTML here assumes that the alert message will be red. However, should the style of the alert
change to orange the class name of red will no longer make sense and will likely cause confusion:
Bad Code
<p class="red">Error! Please try again.</p>
Good Code
<p class="alert">Error! Please try again.</p>
Images should always include the "alt" attribute. Screen readers and other accessibility software
rely on the "alt" attribute to provide context for images.
The "alt" attribute value should be very descriptive of what the image contains. If the image doesn’t
contain anything of relevance, the "alt" attribute should still be included; however, the value should be
left blank so that screen readers will ignore it rather than read the name of the image file.
Additionally, if an image doesn’t have a meaningful value—perhaps it is part of the user interface,
for example—it should be included as a CSS background image if at all possible, not as an <img>
element:
Bad Code
<img src="puppy.jpg">
Good Code
<img src="puppy.jpg" alt="A beautiful, two-year-old hound mix
puppy">
Never use inline styles within HTML. It creates pages that takes longer to load, and it is difficult
to maintain debug. Instead, use external style sheets with classes to target elements, and apply styles
as necessary.
Here, any desired changes to styles within the bad code must be made in the HTML. Consequently,
these styles cannot be reused, and the consistency of the styles will likely suffer:
Bad Code
<p style="color: #393; font-size: 24px;">Thank you!</p>
Good Code
<p class="alert-success">Thank you!</p>
Participant PrOFILES BEST PRACTICES
PURPOSE
DETAILS
Participant Profiles are created for each step in the workflow. For each profile, you can define:
Document Views: define whether actions and groups are shown or hidden, and whether
attributes are read-only, editable, or hidden
Transition Rules: define what workflow step will be next and set up email notifications
User Access Rights: control who will be assigned to this profile once a transaction reaches this
step (you can also control user access to a profile using the Advanced Forwarding Rules for the
Step)
Do not clone Steps. Due to a bug (#15383), corruption to the original and copied step can result.
There are two ways to assign users to Participant Profiles: User Access Rights and Advanced
Forwarding Rules. Note that Participant Profiles are assigned according to Groups and User Types.
You can't assign profiles to individual users by username.
You can use the Advanced Forward Rules to assign Participant Profiles to Groups, based on attributes
in the quote. Participant Profiles will only be assigned when the step changes.
For example, if approvers are assigned to quotes according to a user hierarchy, you can define a quote
attribute to store the name of the approver group (e.g., Manager-East, Manager-West). In the Forward
Rule, you can use that attribute to determine which groups to assign to the Approver profile for that
quote.
Troubleshooting
Tips:
Remember that the profiles are evaluated in the order in which they appear.
Check performer steps (is Start listed incorrectly?), forwarding rules, and rights based on user
type.
When a user forwards a transaction manually from the transaction manager, the recipient will
get the same access rights as the sender.
Document views determine what is visible to users in the participant profile. Choices for the
document views depend on the entity. For tabs, the options are Show or Hide. Note that if a
tab is hidden, all attributes and actions within the tab are hidden. For actions, the choices are
Active, Inactive, or Hide. For attributes, the choices are Read/Write, Read-Only, and
Hide. Note that you can also adjust these setting from the attribute or action, enabling you to
quickly adjust the behavior of the same entity across all steps.
Defining Transitions and Notifications
Tips:
Always put an always true rule at the bottom of a set to avoid errors in logs.
Transition rules can have the same step as a destination. Use this to send notifications without
changing steps (e.g. a reminder email).
XML notifications are sent to the partner server specified in Admin/Integration Settings. This
allows integration with ERP and other non-CRM systems at specified transitions.
Since notification emails must be defined for each transition, the same message may be defined in
many places. By using XML templates and variables in the subject line as much as possible, you
can reduce the number of places you will need to update to make changes to the messages.
COMMERCE PERFORMANCE BEST PRACTICES
PURPOSE
DETAILS
To Maximize Performance:
Remove Print Statement - Remove all your print statement before go-live.
Minimize number of loops, including nested and parallel loops.
DON'T USE any default function at the line attribute level.
Eradicate the use of Python.
It is recommended to avoid any conflicts when admins are working on the site, meaning
limit the amount of admins making changes to one site at one time.
Try to use dict("string") instead of dict("string[]"). The speed on processing and storing
dict("string") is faster than dict("string[]"). General idea is that the simple structure is faster.
Eliminate Revert to Defaults on line item attributes if you have any for those actions. They
run n times, plus they invoke the line item advanced default script every time.
Check the modify tab of the quote level action named “Update Pricing” (variable name
_update_line_items.) This action is triggered any time a change is made in the line item grid.
If any of the quote or line level attributes have “Revert to Default” selected go to those
attributes and make sure that a default is defined. Not having a default defined on the attribute
and trying to revert to default causes major performance problems.
Eliminate line item summation attributes. They run n times every update.
If you need to loop through line items, please do store them into temporary variables, for
example, string dictionary or float dictionary. After you store them, use the temporary
variables than looping through line item documents collection.
If you have advanced modifies on those actions, optimize the code:
o Eliminate nested for loops. o
Eliminate parallel for loops.
o Eliminate table calls done in for loops.
o When building the result string, use a temporary result string in loops in order to minimize the
number of large string concatenations.
Eliminate calls to Global Functions everywhere.
Eliminate or optimize quote level summation attributes.
Eliminate or optimize HTML/Read-Only attributes. Keep in mind that the HTML attribute
defaults run every time the page is opened. Thus if they have functions that build up a big
string (and especially if the functions loop through lines), it can cause problems.
Performance Issues caused by Read-only text or HTML Attributes would only be observed on
Steps where they are available on the layout (Document Views set to Read/Write or Read-
Only).
Eliminate any revert to defaults for quote level attributes on those actions.
Do not put large text area attributes on the page. These will be submitted back to the server
when an action is performed on the page, even if the action has "leave value unchanged" for
the attribute.
o Line item text area attributes are particularly worrisome. These attributes have to be initialized for
every line item created, and if there is any kind of default on them (whether on the attribute
itself or through the advanced line default), it could have a significant performance impact.
Delete any unused attributes.
Take advantage that the first main doc always has document number=1. Instead of
res=res+_quote_doc_number+"~varname~+value+"|"; use res=res+"|1~varname~"+value.
Use the "Run Once For All Line Items" option on advanced line item default if you have any
loops. Be sure to make sure the final results are correct. If you do not select run once, the
advanced default will run for each line item added. If you have many recommended items you
are adding at once, this can cause a significant performance penalty.
Rather than calling the same data table multiple times with slightly different queries, get table
data once, put it into an array, and process the data as you loop through the array. The size of
the data table and the number of queries will obviously influence the impact of this change.
If calling large tables, look to reduce number of records by redesigning tables. Use indexing
where applicable.
Minimize the number of RTE fields on line item attributes (no more than 5, as a general rule).
Minimize the number of line item attributes and the number of attributes displayed in the line
item grid (below 500 on the line and 25-30 columns on the grid)
Use pagination on the line item grid. Reducing the number of lines reduces the amount of
HTML rendered. In addition, it reduces the number of input fields on the form, so the BM
JavaScript that checks for changes will be faster. Aim for 20-25 line items per page.
Do not put model/configurator-specific pricing in the pricing script. Instead, use the relevant
configurator to calculate these.
CONFIG PERFORMANCE BEST PRACTICES
PURPOSE
DETAILS
To Maximize Performance:
PURPOSE
With the ability to migrate between sites, there is also the ability to cause coding issues by hard
coding the URL of a particular instance to be a part of the site structure. This article will discuss the
best practices in preventing site-specific URLs from causing issues post-migration.
SOLUTION
If site name is left off the beginning of a URL (making it a "relative" link), BigMachines
implicitly assigns the name of the site the code is running on. This makes the code
portable between sites.
For example:
o https://site.bigmachines.com/commerce/new_equipment/products/model_co
n figs.jsp?segment=Shoes&product_line=pumps&model=daisy
Note that the lower() function is required because the file manager is case sensitive.
o siteName = lower(_system_supplier_company_name);
filemanager_path = "/bmfsweb/"+siteName+"/image/";
Also, best practice is to pass this site name value into util functions which require site
name, instead of referencing the site name in the util itself:
executeQuery = util.executeSOAPQuery(soapQuery,"ERR",siteName);
Use $BASE_PATH$
$BASE_PATH$ always has the value of: /bmfsweb/{"siteName"}/image and can be used to
dynamically reference a file location in the file manager by placing $BASE_PATH$ before
the specific folder and file name.
For example:
o src='/bmfsweb/playground/image/HomePage/Shoes.jpg
" can be revised to a portable version:
src="$BASE_PATH$/HomePage/Shoes.jpg
BMQL filemanager_path
In version 11.1, BigMachines added the capability to pull data off of a transaction into
Configuration using BMQL. You can use this in combination with the Commerce method to
expose the site name in a Configuration. Assuming that the Quote Variable Name of the
Commerce Document is "quote_process" the code would look like this:
o path = "";
return path;
Directory Structure
Some files that you link to within the File Manager can have references within themselves. CSS
files, for instance, may have links to images. In the case of CSS, you can use relative links within
your file to find other files in the File Manager. As long as the folder structure stays consistent,
this will work across sites. For example, assume the following directory structure in
the file manager:
o stylesheets/
style.css
images/
photo.jpg
There are some paramaters available in the snippets that provide site-specific information:
$XSL_COMPANYNAME_PARAM returns the site name
$XSL_URL_PARAM returns the site URL, including the
protocol. (http://sitename.bigmachines.com/)
o <!-- Example XSL Snippet-->
<xsl:variable name="image_url">
<xsl:value-of select="concat($XSL_URL_PARAM,
'/bmfsweb/',$XSL_COMPANYNAME_PARAM,
'/image/my_folder/my_image.gif"/> </xsl:variable>
_BM_HOST_COMPANY
From within the Home Page Alt JS file, you will have access to the global variable
_BM_HOST_COMPANY, which refers to the current site name.
o // outer function to avoid creating global variables
(function() {
var image_url =
"/bmfsweb/"+_BM_HOST_COMPANY+"/image/my_folder/my_image.jpg";
}());
page_data
When modifying the Home Page XSL, Parts Search XSL, or other XSL display templates, the site
name is available under the "page_data" element. Here's how to select it in the Home Page.
Notice that we translate it to lower case for the file manager link:
o <xsl:variable name="sitename"
select="translate(/home_page/page_data/host_company,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/> <xsl:variable
name="image_url"
select="concat('/bmfsweb/',$sitename,'/image/my_folder/my_image.jpg')"/>
Symbolic Link
A symbolic link can be created per site to redirect relative link calls that use a path such as
"bmfsweb/PRODUCTIONSITENAME/" in a non-production site to the correct path of
"bmfsweb/TESTSITENAME/."
The Operations team must be contacted to create symbolic links.
Notes
It is best to use relative paths and dynamic variables instead of explicitly "hard coding" site
name as they allow for the code to be moved to and from different instances without having
to be changed.
TIMER BEST PRACTICES
PURPOSE
Timer Background:
Timers create tasks in the task thread to execute. When the time comes for the task to be
performed, the condition is checked again. Once the task is complete, it will not return on a
site unless one of the inputs changes. However, the threads are re-evaluated when a site is
refreshed. In order to prevent undesired timer actions, add a condition flag on the timer. The
timer action should change this flag.
o Note: Timers will only run if the date attribute tied to the timer is
modified by the action that transitions the transaction to the step
with the timer. As an alternative, an action modifying the date
attribute in the step with the timer that keeps the transaction in the
step with the timer will also cause the timer to run.
SOLUTION
Step 1:
Create a date attribute. NOTE: It can be set to system time, system timer plus some
interval (e.g. 30 days from now), or a given time (e.g. end of calendar year).
Step 2:
Include that date attribute into the data columns. NOTE: If you do not include the date
attribute into the data columns, it cannot be used as a timer trigger.
Step 3:
The timer should trigger an action that modifies your new date attribute. NOTE: It could
be set to the current time, or another interval, or a new given time.
o Example: If you want to use a timer to send a reminder about open quotes
every two weeks, the action should set the date attribute to system time
plus two weeks.
How to Debug Timer Issues:
Step 1:
This issue occurs: recurring timer continues being fired even when quote is out of the
“timer-ed” step.
Step 2:
Put the “lastEmailed_quote” attribute (or whatever is controlling your recurring timer) as a
writable attribute for admins.
o NOTE: If just a single quote is acting up, you can set the date
to sometime in the far future.
Step 3:
Ensure that the user (e.g. TimerUser) has access to the timer action in the step. Timers are
mapped to a user.
o NOTE: If more than one quote is acting up, double-check your timers. The
above fix will not work for a systemic problem.
CONFIGURATION LAYOUT BEST PRACTICES
PURPOSE
This document overviews the Configuration Layout Editor and its best practices.
DETAILS
The administrator should ensure that column widths add up to be 100 %.
In the new layout, widths specified for layout elements and attributes are respected. The
administrator must ensure that enough space is available within a column to display attributes
properly.
Upgrade advanced templates to use templates created using the standard drag and drop editor.
All attributes are migrated in their own row to maintain legacy behavior of preserving white
space on hiding attributes. It is recommended that the administrator move attributes to a
single cell if collapsed space behavior is desired. A single cell is considered the same column
and same row on the layout.
Most styling should be done using the regular stylesheet UI. The alternate stylesheet can be
used for additional CSS customization.
Update existing alternate Stylesheets to use the latest array icons.
Define CSS classes for tabs and groups to aid in advanced styling.
APPLICATION BOUNDARIES
PURPOSE
DETAILS
BML:
Use certain special characters in a script (e.g., 0x1c), or they can corrupt the entire commerce
process when the script is deployed
Configuration:
Magic Numbers
These may be handled (part custom fields) or unhandled and result in java exceptions (commerce groups).
Regarding the 100 character limit for Reporting Manager, when Reporting Manager performs the
search through quotes, it will only search within those 100 characters, even if the attribute the data
column takes its information from has more than 100 characters.
PRELIMINARIES
Question: How do I know if it’s a possible performance issue, or just a user issue?
Answer: If the user can reproduce the problem, it may be a performance issue.
Here are our best practices for investigating performance issues. Reproduction is key – when you
give us detailed information by following these steps, it’s much more likely we can reproduce the
issue and get root causes on performance issues.
1. Get details.
Contrast the possibilities for investigation and resolution between the statements “Site is
slow” and “When user X clicks Update Line Items on quote 2012-1325, it takes 10
seconds.”
2. Reproduce the issue. Use the information from step 1 to try to reproduce on your machine.
Get actual times yourself. Measure time at least thrice. If there is a large difference in times
(in general, more than a few seconds), there may be a network issue. Have the user run the
test again. If the user sees the same time, have the user run a trace route.
3. If the issue is site wide and you are able to reproduce, ask Oracle Ops to check the
environment. They will look at memory and CPU usage, and see if anything looks out of the
ordinary. Ops may need to restart the site. Make sure to coordinate the restart with business.
5. Focus efforts on the high-impact areas. You do not want to spend several hours on a BML
script when that script is only 5% of the problem. Below are a few examples:
b. Remove integration. Try the same action with a user who is not integrated with CRM
and run the test. If this takes care of the performance problem, investigate the
integrations being performed at that point.
c. Remove suspect scripts. If there is a script you think may be causing the performance
issue, replace the script with a return “”; and measure performance again.
d. Change settings. Several of the items in the Performance Checklist are simple
changes (e.g. Pagination, Run Once for All Line Items). Make the change and
measure performance.
6. Find the issue and make changes. Verify performance change as well as consistent
functionality.
BEST PRACTICES
Site Wide
Ask Oracle OPS for the specs of the server and find out if an upgrade is possible (mostly
moot after 2013 upgrades – Not applicable for VF)
Remove or comment out all of your print statements. Any calculations on a print function,
such as concatenations, will be run on the end user side, even though the print itself will not
have an effect.
Be judicious in your use of Auto Updates and AJAX.
Eradicate the use of Python.
DO NOT USE JAVASCRIPT
Minimize number of loops, including nested and parallel loops.
If using Apache and the str:split command consider replacing the command with an XSL
template to avoid a known Apache bug causing memory leaks and slow performance.
Configuration
CHECKLIST
configurator: XXXX
Eliminate Python
Eliminate JavaScript
1 o close at line:
. Outer loop open at line: XXXX XXXX
o close at line:
Inner loop open at line: XXXX XXXX
2 o close at line:
. Outer loop open at line: XXXX XXXX
o close at line:
Inner loop open at line: XXXX XXXX
attributes: XXXX
Minimize the number of line item attributes (<500) and the number of attributes displayed
in the line item grid (25-30)
o Number of line item attributes: XXXX
o Number of attributes displayed on the line item grid: XXXX
Eliminate calling the same data table multiple times with slightly different queries
When looping through line items building the result string, use temporary variables
☐ Check modify tab of Update Pricing action for Revert to Default attributes
☐ Use the “Run Once For All Line Items” option on advanced line item default if you have any
loops