This is intended as a case study description of the thought and steps to creating a live product which hopefully can help others do the same in less time or conceive and implement more clever applications of this extraordinarily powerful tool.

We needed a product for design and layout services which acted like a menu from which estimators could select specific design “products” which had pre-set times – concept layouts for customer approval, production layouts for fabrication or production art for the printers, routers, etc. Since an estimate might have one or a multiple of such products, we wanted to be able to pick from a selection list which permit the inclusion of one or many of its contents.

SmartParts seemed to be the best method.

Basic Discussion of Approach

Since Smart Parts is built from Parts, we needed to create a list of parts which encompassed the “products” we envisaged. After considerable research we identified often repeated requests and catalogued the actual time required to complete them – E,g, a concept drawing showing a monument entry sign. We created parts named for the type of product – E.g. Concept Art:Monument Sign or Concept Art: Monument Sign Illustrated or Production Art:Inserts.

The SmartPart Search Variable presents a top-level and sub-level category well; so to present the lists in manageable chunks, we settled on two categories for the parts - the overall category which would return all the needed parts which we called “Design” and then sub-categories based on the kind of Design being requested. For the sub-categories we were also guided by the fact that the parts in them would have different hour rates and markups.

The final pricing form is shown below with 3 “products” or parts selected. The comments and pictures following attempt to illustrate how we achieved this.

Plan out the Part Names and the categories before starting the creation of Parts and the implementation will be smoother but don't let that slwo you down as you can change these later.

  1. Step 1

Created a top level Part Category called Design which would be the Hierarchy wildcard.

  1. Step 2

Created sub-categories under the Design Category to contain the actual parts

  1. Created user constants for the hour rates and markups for the parts
  2. Created variables for the hour rates and markups for the parts which house the user constant. This is an added step which then permits us to put the variables in popups and pricing forms to modify the values for a specific order.
  3. Created the parts to be found in the SmartParts Seach variable. Since the input quantity could be quantity of hours, sign types, signs, inserts, etc., we needed to be able to show the needed units on the pricing form in the Search Variable.

To do that and display the type of unit to be specified, we hijacked the SKU object which is a text field and entered the unit type being ordered there, as this variable is available in the SmartParts Search variable setup.

For the same reason we needed to set up those parts where the quantity entered is different from the hours required with different display and inventory units.

  1. Created the pricing form following the directions posted on this WIKI for the creation of the SmartParts variables: (

**The Search Variable**

**The Filter Variable**

**The Summary Variable**

  1. Added cosmetic adjustments to fit the presentation to our application and users. For example, we used a Pricing Form RZ Panel and text object to cover the top banner of the SmartParts variables with a description of what that variable is showing. We also added a place for adding comments or text explanations. See the blue bar on top of the SmarParts variables above.
  2. Realizing that the Estimator needed considerable latitude to adjust the price resulting from this product and form, we created a popup to permit discounting,, using a slider to add to or reduce the resulting price. To make this as useful as possible, we added some objects and code to show in real-time the margin impact of any discounts applied.

  1. Created the Product which we named “Design Services SP”.

Since the pricing is based entirely on the variables and units of the Parts, we set the Pricing formula to Parts Based.

Brought in all the variables we had created for the product.

Set the Slider Discount formula in the Product Pricing Discount Formula builder so that the discount appears on the screen pricing form.

  1. Created layout sheets for presenting the resulting selections in an estimate or invoice and work order. For the work order, we wanted the designers to be able to see both the quantity of the units ordered and the hours assumed for them.

For SmartParts the layout code must be based on Part Properties rather than modifiers and variables. Additionally, since the parts are built by the SmartParts variable as an array, they must be accessed by index number. This meant that the the portion of the layout code relating to the selected parts needed to be encased in a "For" statement.

To determine the actual names of the properties we needed to go to this WIKI and Tech Support as they do not always conform to their object names in the database. CFL employs two methods of passing Part information through properties. One is a direct statement- E.g.

Parts[index].SKU;  --or 

The other is a function


Almost all of the part information is available in CFL from one of these property statements; however when the Display unit is different from the Inventory Unit, we had to derive the quantity ordered from the formula (note that since these numbers are being retrieved for a layout, they are converted to a string value):

IF GetPartProperty(Parts[counter].PartCode,"DisplayToUnitRatio") 0 THEN
              ELSE 0

With modifications the code below should be usable for most any SmartParts product. The “ ” is the code for a hard space.

Declare Counter:=0;
Declare Index := Parts.SonCount-1 ;
Declare PartsList:="";
For Counter := 0 to Index  DO
PartsList:=  HTMLFONT(PartsList+  " "+Parts[Counter].Part.PartCategoryName+" : " +Parts[Counter],"Arial",3)+"   "+ HTMLRETURN
" "+" "+" "+" "+" "+ Parts[counter].Part.SKU+//units and quantity ordered
              IF GetPartProperty(Parts[counter].PartCode,"DisplayToUnitRatio") 0 THEN
              ELSE 0
                  +" "+" "+" "+" "+" "
+"     Estimated time = "
+  TOSTRING(Parts[counter].estimatedquantity) +" Hr(s) "
+" "+" "+" "+" "+" "+" "+ "@Hr Rate Of $"
                 +TOSTRING(Parts[counter].EstimatedCost / IF Parts[counter].EstimatedQuantity 0 then Parts[counter].EstimatedQuantity Else 1 ENDIF)+".   "
+"     Total Cost = $"
              + TOSTRING(Parts[counter].EstimatedCost."###,##.##")
                  +" "+" "+" " + " Markup = "
                1-(Parts[counter].EstimatedCost / IF
                 Parts[counter].SuggestedPrice=0  THEN 1 ELSE Parts[counter].SuggestedPrice."##.##"   ENDIF) )
)+ "%"
+ "   Total Price = $" +  TOSTRING(Parts[counter].SuggestedPrice."###,##.##")
IF Comments "" THEN


Contributor: Steve Gillispie with much help from Steve Hendrix and Kyle King

Date: _10/7/2017

Version: Control 6.1

You could leave a comment if you were logged in.