Force.

com Workbook: Spring '11

Force.com Workbook

Last updated: February 20, 2011
© Copyright 2000-2011 salesforce.com, inc. All rights reserved. Salesforce.com is a registered trademark of salesforce.com, inc., as are other

names and marks. Other marks appearing herein may be trademarks of their respective owners.

Table of Contents

Table of Contents
About the Force.com Workbook...........................................................................................................................................................3 Tutorial #1: Creating a Warehouse Application....................................................................................................................................5 Step 1: Create a Merchandise Custom Object..........................................................................................................................5 Step 2: Add Description, Price, and Total Inventory Fields......................................................................................................7 Step 3: Create a Tab................................................................................................................................................................10 Step 4: Create a Warehouse App.............................................................................................................................................11 Step 5: Create a Merchandise Record.....................................................................................................................................12 Summary.................................................................................................................................................................................13 Tutorial #2: Adding Relationships......................................................................................................................................................14 Step 1: Create an Invoice Statement Custom Object..............................................................................................................14 Step 2: Create a Line Item Object...........................................................................................................................................17 Step 3: Relate the Objects.......................................................................................................................................................18 Step 4: Add Invoice Statements to the App............................................................................................................................19 Step 5: Create an Invoice Record............................................................................................................................................19 Summary.................................................................................................................................................................................21 Tutorial #3: Creating Reports and Dashboards...................................................................................................................................22 Step 1: Enable Reporting on Objects......................................................................................................................................22 Step 2: Create a Tabular Report..............................................................................................................................................23 Step 3: Create a Summary Report...........................................................................................................................................25 Step 4: Create a Matrix Report...............................................................................................................................................26 Step 5: Create a Dashboard.....................................................................................................................................................28 Summary.................................................................................................................................................................................30 Tutorial #4: Using Formulas and Validation Rules..............................................................................................................................31 Step 1: Calculate a Value for Each Line Item..........................................................................................................................31 Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field............................................................32 Step 3: Check Inventory With a Validation Rule....................................................................................................................33 Step 4: Test the Validation Rule..............................................................................................................................................35 Step 5: Improve the Validation Rule........................................................................................................................................36 Summary.................................................................................................................................................................................37 Tutorial #5: Using Workflow and Approvals.......................................................................................................................................38 Step 1: Populate the Line Item Price Using a Workflow Rule................................................................................................38 Step 2: Update Total Inventory When an Order is Placed......................................................................................................41 Step 3: Test the Workflow Rules.............................................................................................................................................42 Step 4: Create an Email Template...........................................................................................................................................43 Step 5: Create an Approval Process.........................................................................................................................................44 Step 6: Create a Custom Profile..............................................................................................................................................46 Step 7: Create a User...............................................................................................................................................................47 Step 8: Test the Approval Process............................................................................................................................................48 Summary.................................................................................................................................................................................50 Tutorial #6: Adding Business Logic with Apex..................................................................................................................................51 Step 1: Create an Apex Trigger Definition..............................................................................................................................52

i

.........................................................................................................................................................................................61 Summary.............................................................................................................................................................90 Step 6: Import Your Enterprise WSDL.............85 Step 1: Configure Your Salesforce Personal Information..........64 Step 1: Enable Visualforce Development Mode........................................................................................................89 Step 4: Install and Launch Force..............................................................................................................................................................60 Step 5: View Code Coverage and Improve Tests..........................................................78 Step 2: Add Methods to the Controller.........................................................................................................................................Table of Contents Step 2: Define a List Variable.................65 Step 3: Add a Stylesheet Static Resource........................................................................................................................................................................................................................53 Step 3: Iterate Through the List and Modify Price...........................63 Tutorial #8: Building a Custom User Interface Using Visualforce.....................................................................................................................81 Step 4: Bonus Step—Updating the Page with AJAX...................com Flex Project..................................................................................................................54 Step 4: Test the Trigger.........................................................................................................................................................................................................................................................................................................................75 Step 4: Configure and Test the Site.....................................56 Tutorial #7: Adding Tests to Your Application................................................................................................104 Delivering Your Application.................................................................................................................................................................................................................................................................77 Tutorial #10: Creating a Store Front.............................................................................................................................................................................com Flex................................................................................................................72 Step 1: Create a Product Catalog Page........................................................................................................................................................................................................................100 Summary.........................................................................................................................................................................................................................................................................................68 Step 5: Display the Inventory Count Sheet as a Visualforce Page......................................................................64 Step 2: Create a Visualforce Page..........105 ii ....................................................................................................................................92 Step 7: Set the Force.........com IDE...........................................................................................................................................................................................com Flex................................................................................................................................................................................................................................55 Summary.................................78 Step 1: Create a Controller....................................................................................87 Step 3: Generate Your Enterprise WSDL.................................................................................................................................................................72 Step 2: Register a Force...............82 Summary............................................................59 Step 4: Execute the Test....................74 Step 3: Create a Force................................................................................................................................................................................................................................94 Step 9: Testing the Inventory Tracker application.........................................................com Domain Name...........................................................57 Step 1: Create an Apex Test Class....................................................................................................................................................................................................58 Step 3: Write Code to Execute the Trigger........................................................................104 Creating a Project in the Force.................................................................................................................90 Step 5: Create a Force..com Flex Application Component Attributes............................75 Summary..............................................................................................................................................................79 Step 3: Create the Store Front.....................................................................................................................................................................................................................................................................................................................................................................................................69 Summary......................93 Step 8: Create the Inventory Tracker Window Component............................................................................................................................................................................................................................................................................................................................................................................................86 Step 2: Create an Offline Briefcase Configuration.............66 Step 4: Add a Controller to the Page.........................................................................................71 Tutorial #9: Creating a Public Web Page Using Sites..............................104 Creating and Logging into a Sandbox............................................................................................................com Site...............................................................................................................................84 Tutorial #11: Creating a Desktop App with Force..............57 Step 2: Add Test Methods to the Class...................................................................................................103 Appendix.............................................................

If you'd like to develop offline and integrate with the app. It may sound like a lot. You can't use Free Edition to complete Tutorial #11: Creating a Desktop App with Force. Apple® Safari version 5.com/join. see “Supported Browsers” in the Salesforce online help. You'll continue by adding business logic: validation rules to ensure that there is enough stock. Developer Edition uses a Start Here tab. You'll start developing the application from the bottom up. 7.com platform to build virtually any kind of application. If you have not created a sandbox yet.x. you can migrate the changes from your sandbox to production.6. The pictures in the workbook may be slightly different from what you see on your screen. Force.force.com Flex. navigate to developer. As a developer preview.jsp. we've added a final tutorial to use Force. but it's all quite easy—as you'll soon see.0. However. most applications share certain characteristics such as: • • • • A database to model the information in the application Business logic and workflow to carry out particular tasks under certain conditions A user interface to expose data and functionality to those logged in to your application A public website to show data and functionality on the Web The tutorials are centered around building a very simple warehouse management system. that is. so it's easiest if you complete all of the tutorials within your sandbox organization. workflow to update inventory when something is sold. While you can use the Force. and then the start of a simple store front. see Delivering Your Application on page 105.0.com development environment supports the following browsers: Mozilla Firefox version 3. Once the database and business logic are complete. navigate to salesforce.0. Each of the tutorials builds on the previous tutorial to advance the application's development and simultaneously showcase a particular feature of the platform.com Flex is only available in Developer Edition. these differences are trivial. and trigger logic to update the prices in open invoices.com Workbook About the Force. To sign up for a Free Edition organization.com Workbook shows you how to create an application in a series of tutorials. you can also use Free Edition with the following considerations.0.com Workbook The Force. which has all of the required features and functionality.x. Note: The Force.com/form/signup/freeforce-platform. 3 . you'll first build a database model for keeping track of merchandise. In most cases. For example.com Flex. When you complete the application. approvals to send email notifications for large invoice values.About the Force. while Free Edition has a Getting Started tab. and 8. a public website to display a product catalog. Microsoft® Internet Explorer versions 6. For more information. Choosing a Development Environment This workbook is designed to be used with a Developer Edition organization. see Creating and Logging into a Sandbox on page 104. • • • • Some of the tutorials require that you use a sandbox. you'll create a user interface to display a product inventory to staff. To sign up for a free Developer Edition organization. For more information.

However...com and to access a rich set of resources. If you like to do things quickly.force.About the Force. there's a lot of useful information here and some additional steps to flesh out your app.force.com/workbook.com IDE Delivering Your Application Advanced 30 minutes Intermediate Intermediate Intermediate 30–45 minutes 20-30 minutes 30 minutes Advanced 20-30 minutes Beginner Intermediate Advanced 20-30 minutes 30-45 minutes 20-30 minutes Beginner Beginner 20-30 minutes 20-30 minutes Difficulty Estimated Time to Complete Tell Me More..com Flex Appendix Creating and Logging into a Sandbox Creating a Project in the Force. move on to the next step.com. Tutorial Create the App Tutorial #1: Creating a Warehouse Application Tutorial #2: Adding Relationships Add Logic Tutorial #4: Using Formulas and Validation Rules Tutorial #5: Using Workflow and Approvals Tutorial #6: Adding Business Logic with Apex Write Tests Tutorial #7: Adding Tests to Your Application Extend the User Interface Tutorial #8: Building a Custom User Interface Using Visualforce Tutorial #9: Creating a Public Web Page Using Sites Tutorial #10: Creating a Store Front Offline Integration Tutorial #11: Creating a Desktop App with Force. At the end of each step there is an optional Tell Me More section. visit Developer Force at developer. 4 . if you're a smell-the-roses type.com Workbook How is the Workbook Organized? The tutorials in this workbook build on one another and are designed to be done in order. You can find the latest version of this Workbook and additional tutorials that extend the app at developer. • • To learn more about Force.

Enter your username (in the form of an email address) and password. and screens that allow you to list. See Also: Step 1: Create a Merchandise Custom Object Step 2: Add Description. So you'll begin by creating a data object that keeps track of all the elements of a particular merchandise item. but you can also create custom objects to track anything you want.Tutorial #1: Creating a Warehouse Application Tutorial #1: Creating a Warehouse Application Level: Beginner. Price.salesforce. and so on. such as its name. and price of all your merchandise. description. price. and then click Create ➤ Objects in the sidebar menu to display the Custom Objects page. When you complete this tutorial.com platform. An object comes with standard fields. 5 . these data objects are called custom objects. and Total Inventory Fields Step 3: Create a Tab Step 4: Create a Warehouse App Step 5: Create a Merchandise Record Summary Step 1: Create a Merchandise Custom Object The Force. Duration: 20-30 minutes At the heart of this application is what you want to sell: merchandise. description. But you can also add your own fields to track or list just about anything you can think of. 3. and a custom object that tracks the name.com. Launch your browser and go to https://login. a tab. 2. On the Force. you can think of a custom object as representing a table. view and edit information about the object.com platform includes predefined standard objects. The first step is to create a custom object that will hold information about merchandise. 1. as well as screens that allow you to view and edit all of this information. you will have a working application with its own menu. Click Your Name ➤ Setup in the upper right corner. If you are familiar with databases.

• • • For the Label. enter Merchandise. 6 . 5. For the Plural Label. 6. enter Merchandise. Click New Custom Object to display the New Custom Object wizard. Leave all other values as they are. Click Save to finish creating your new object. Fill in the custom object definition.Tutorial #1: Creating a Warehouse Application 4.

If you guessed that custom fields have names that end in __c. the Merchandise object has a standard field for Owner. Create the Description field. which differentiates them from standard objects and makes them easier to identify. and inventory. All custom objects end in __c.Tutorial #1: Creating a Warehouse Application Tell Me More. 1. Take a look at the following image to familiarize yourself with the Merchandise custom object. 1.. 7 . such as a description. After you save the new custom object.. which means it will automatically track who created each record. Price. Custom fields—You haven't defined any custom fields yet. how much it costs. you're right. Merchandise detail page—This page shows you everything you need to know about your Merchandise custom object. For example.. these are called standard fields. Price. price. you didn't specify an API name. 2. and how many are in stock. and Total Inventory Fields Step 2: Add Description. 3. and Total Inventory Fields A merchandise object should have fields that are used for tracking various information. You can add custom fields to list or track just about anything you can think of. 4. See Also: Tutorial #1: Creating a Warehouse Application Step 2: Add Description. validation rules. Follow the steps below to create custom fields for the description. relationships. and other neat features to this custom object. This name is how you reference the object programmatically. but one is generated for you. Standard fields—Some fields are generated automatically. API name—When you created the Merchandise object. Soon you'll be adding fields. the detail page for the custom object opens. you'll do that in the next step.

Scroll down to the Custom Fields & Relationships related list. One of your business rules says that you can't create new merchandise without providing a description. • • • • • For the Field Label. and click Next again. Optionally. Click Save & New to save the Description field and return to the first step of the wizard. c. and click Next. Create the Price field. 2. For Data Type.Tutorial #1: Creating a Warehouse Application a. enter Description and press the Tab key. b. a. The Field Name field should already be populated with the field name: Description. select Currency. but for the sake of brevity we leave these out in the remainder of the workbook. Fill in the custom field details. e. d. For Data Type. Fill in the custom field details: 8 . Click New to launch the New Custom Field wizard. Select the Required checkbox. b. It's a good idea to fill these in. Making Description a required field fulfills that business rule. Do not fill in the Default Value field. select Text Area and click Next. f. Click Next. accept the defaults. fill in the Description and Help Text fields.

a. In the next step. and click Next. The Field Name is used internally in code. and click Next. e. You may have noticed that when you enter a Field Label. and so it should be easy to read and may contain spaces. Create the Total Inventory field. At this point we have a nice representation of our warehouse items: they each have a name. select Number and click Next. accept the defaults. Click Save to create the Inventory field and to return to the Merchandise Custom Object page. We've also recorded the total number of items (Total Inventory) that we have for each piece of merchandise. For example. you can make another Stock Price field now if you want to. enter Price. the system automatically populates the Field Name as well. d. just follow the same steps above and use the Stock Price name. However. b.. In the next step. enter Total Inventory. For Data Type. For the Length enter 16 and for Decimal Places enter 2. Note: This app has only one Price field. In the next step. and must not contain spaces or illegal characters. a field labeled “Customer ph# :” would be named Customer_ph in the code (the system replaces spaces with underscores and removes the # and : characters). c. c. See Also: Tutorial #1: Creating a Warehouse Application Step 1: Create a Merchandise Custom Object Step 3: Create a Tab 9 . and click Next. and we'll use that for both the stock price and retail price. Check the Required checkbox. click Save & New to save the Price field and to return to the first step of the wizard. and a price.. So why do you need both? A Field Label is what the user sees. d. 3. e. Fill in the custom field details: • • For the Field Label. Tell Me More. and click Next. a description. accept the defaults. Select the Required checkbox. Accept the defaults for the remaining fields.Tutorial #1: Creating a Warehouse Application • • • For the Field Label. Leave the defaults for the remaining fields..

As soon as you create the tab.Tutorial #1: Creating a Warehouse Application Step 3: Create a Tab Tabs provide an easy way to find and organize objects and records. click New to launch the New Custom Tab wizard. they will be able to create. When users click this tab. Tell Me More. 6. view.. When you create a tab. 1. 4. Accept the remaining defaults. 3. you can choose your own color and custom image by clicking Create your own style.. In the Custom Objects Tabs related list. In this step you will create a tab for the Merchandise custom object. select Merchandise. Price. click Create ➤ Tabs. 5. Click Next and then Save to finish creating the tab. and edit records. For the Tab Style. you're not stuck with a standard set of icons and colors. and Total Inventory Fields Step 4: Create a Warehouse App 10 . and click Next. From the Object drop-down list. you can see it at the top of the screen. Within the Setup area. click the lookup icon and select the Box icon. 2. See Also: Tutorial #1: Creating a Warehouse Application Step 2: Add Description.

. if you refer to the Start Here tab a lot. 7. As soon as you create the application. Later. Click Next. Navigate to Your Name ➤ Setup ➤ Create ➤ Apps.com app menu in the upper right corner of the page. 3. Leave the Default Landing Tab set to the Home tab. it appears in the Force. Click New to launch the New Custom App wizard. you can modify custom applications to group all of your most frequently used tabs together in one place. and click Next. you can add that to 11 . The tabs in an application don't have to be related to each other. Select the Visible checkbox to make the application available to all user profiles. enter Warehouse. In the Available Tabs list.Tutorial #1: Creating a Warehouse Application Step 4: Create a Warehouse App An application is a set of tabs. For example. Accept the defaults on the next page.. For the App Name. • • For the App Label.. locate the Merchandise tab and click Add to add it to the list of selected tabs. 8. In this step you create a Warehouse application and add a tab to it. 5. Tell Me More. using the default logo for the app. 4. enter Warehouse. 6. Click Save to create the Warehouse application. In fact. you'll add more tabs to the app. and click Next. 2. 1. 9. Fill in the custom app details.

In the Total Inventory field enter 2000.99. Select the Warehouse application from the Force. • • • • In the Merchandise Name field enter Wee Jet. You can switch between applications you have created. as shown in the following image. Now check to see how your new application works. When you define an object on Force.. but it would be more realistic if you had more merchandise. For Description field enter A small plane. read. bought. See Also: Tutorial #1: Creating a Warehouse Application Step 3: Create a Tab Step 5: Create a Merchandise Record Step 5: Create a Merchandise Record At this point you've created a functioning application. 2. Tell Me More.com. Go ahead and create some more. or installed by simply selecting any one of them from the menu.. Your warehouse will work just fine with only one product..com app menu. 4. the platform automatically generates a user interface that lets you create. In the Price field enter 9. See Also: Tutorial #1: Creating a Warehouse Application Step 4: Create a Warehouse App Summary 12 . Click the Merchandise tab and then click New to create a new product. and delete records.Tutorial #1: Creating a Warehouse Application the Warehouse app. 3. Tip: use Save and New to create new records rapidly. Fill in all the fields. Click Save. 1. update.

Although the application is far from complete. it's easy to use the online interface and wizards to create a custom object. and a tab. As you can see. The next step is to use an invoice to track how your merchandise moves in and out of your warehouse. it already has a lot of built-in functionality. such as the ability to view and create merchandise. and then pull it all together into an application that lets you create and track information about your merchandise. fields.Tutorial #1: Creating a Warehouse Application Summary Congratulations! You have just built a Warehouse application that keeps track of products you have in stock. See Also: Tutorial #1: Creating a Warehouse Application Step 5: Create a Merchandise Record 13 .

and a description. enter Invoice Statements. enter Invoice Statement. you create two new objects. Click Your Name ➤ Setup ➤ Create ➤ Objects. Each line item is an indication of how many units of a particular merchandise item was sold. • • • • In the Label field . Duration: 20-30 minutes In this tutorial. This relationship lets you compose multiple line items and associate them with a single invoice statement. Select Starts with vowel sound. In the Record Name field . 2. Prerequisites Warehouse App You first need to create the basic Warehouse application as described in Tutorial #1: Creating a Warehouse Application on page 5. If you're familiar with relational databases.Tutorial #2: Adding Relationships Tutorial #2: Adding Relationships Level: Beginner. In the Plural Label field. 1. 14 . In this step. so you'll also add a relationship between the merchandise and line item objects. and all you need to do here is establish how the objects are related. enter Invoice Number. a status. the difference being that Force. Click New Custom Object and fill in the custom object definition.com takes care of the underlying implementation for you. you can think of relationship as foreign keys. an invoice statement and a line item. See Also: Step 1: Create an Invoice Statement Custom Object Step 2: Create a Line Item Object Step 3: Relate the Objects Step 4: Add Invoice Statements to the App Step 5: Create an Invoice Record Summary Step 1: Create an Invoice Statement Custom Object An invoice statement is required to move inventory into or out of the warehouse. and associate them to each other in a master-detail relationship. you create an invoice statement with a unique number.

Tutorial #2: Adding Relationships • • • In the Data Type field . Add a Status field. Leave all other values as they are and click Save. • • In the Field Label field . enter Status. a. select Picklist and click Next. enter INV-{0000}. b. 15 . In the Display Format field. each entry on its own line. Fill in the custom field details. Enter the following picklist values in the box provided. Scroll down to the Custom Fields & Relationships related list and click New. For Data Type. enter 1. c. In the Starting Number field. 4. Open Closed Negotiating Pending • Select the checkbox for Use first value as default value. select Auto Number. 3.

5. select Read Only and then click Next. The platform will now automatically assign a number to each new unique record that is created. c. Note how we set the invoice name data type to Auto-Number. Click Save to the detail page for the Invoice Statement object.Tutorial #2: Adding Relationships d. enter Description. accept the defaults. d. When displayed. In the Data Type field. b. the format will look as follows: INV-0002. Click Save & New. In the Field Label and Field Name fields. See Also: Tutorial #2: Adding Relationships Step 2: Create a Line Item Object 16 . select Text Area and click Next. a. as shown here. e. Click Next. Your Invoice Statement object should now have two custom fields. and also supplied a Display Format. Now create an optional Description field.. and click Next again.. f. beginning with the starting number you specify. Click Next. Tell Me More. For Field Level Security..

You are first going to create the Line Item object. • • • • In the Label field . click Next. Leave all other values as they are and click Save. Change the Record Name to Line Item Number. Fill in the custom field details. Scroll down to the Custom Fields & Relationships related list and click New. Leave the Data Type field set to Text. 2. d. 1. Click Next. and then later relate it to the Invoice Statement and Merchandise objects. We'll call it Unit Price so that we don't get confused with the Merchandise object Price field. b. • • In the Field Label field. enter Unit Price. e. c. enter Line Item. and then click Save & New. 3. a.Tutorial #2: Adding Relationships Step 2: Create a Line Item Object Each invoice is going to be made up of a number of invoice line items. Add a read-only Unit Price field. Select Read-Only for all profiles. In the Length field. select Currency and click Next. which represent the number of Merchandise items being sold at a particular price. enter Line Items. 17 . 4. enter 16. In the Plural Label field . The field is read-only because the value will be retrieved from the Merchandise object in a later tutorial. and for Decimal Places enter 2. In the Data Type field. Click Your Name ➤ Setup ➤ Create ➤ Objects. Click New Custom Object and fill in the custom object definition.

8. Unlike the previous fields. enter Units Sold and click Next. c. these get their values from other objects. 4. Inventory Statement. 3. Click Save to return to the detail page of the Line Item custom object. Tell Me More. a. Accept the defaults on the following screens by clicking Next. select Master-Detail Relationship and click Next. and the Invoice_Number field. 2. 1. and currency. In the Related To field. d. Deselect the checkbox next to Merchandise Layout so that Line Items don't appear on the Merchandise related list.Tutorial #2: Adding Relationships Note: If Read-Only is not available. select Master-Detail Relationship and click Next. you want to relate them to each other. Accept the defaults on the next three screens by clicking Next. which is automatically assigned by the Auto-number data type. you probably selected Required by mistake.. 6. and then click Save to return to the Inventory Item detail screen. In the Data Type field. 5. All of those fields have something in common: the values are provided by the user. The Line Item is related to both an Invoice Statement (a statement is composed of a number of line items) and Merchandise (a line item takes its price from the merchandise). which defaults to Open. Click Save & New. select your Merchandise custom object and click Next. See Also: Tutorial #2: Adding Relationships Step 1: Create an Invoice Statement Custom Object Step 3: Relate the Objects Step 3: Relate the Objects Now that you have all the objects representing the data model. select Number and click Next. On each of those objects you created custom fields to represent text. Click Next. 18 . In the next step you will create two more fields. In the Field Label field. You also created two custom fields that have system-generated values: the Status picklist.. and Line Item. 9. numbers. scroll down to the Custom Fields & Relationships related list and click New. In the Data Type field. In the Data Type field. At this point you've created three custom objects: Merchandise. accepting the defaults. 5. Click Previous and deselect Required. You follow similar steps to add a Units Sold field. 7.. b. In the Related To field. select your Invoice Statement custom object and click Next. On the detail page of the Line Item object.

See Also: Tutorial #2: Adding Relationships Step 2: Create a Line Item Object Step 4: Add Invoice Statements to the App Step 4: Add Invoice Statements to the App Just as you did before. Your Invoice Statements tab is now part of your app. click New to launch the New Custom Tab wizard. delete. you'll want to create a tab for the Invoice Statement object and add it to your Warehouse app. This will expose the user interface that Force. In the Custom Object Tabs related list. click the lookup button and select the Form icon. 3. Accept the remaining defaults. allowing you to aggregate information about the child records. 19 . deselect all the checkboxes except Warehouse. click Create ➤ Tabs. This will add the Invoice Statements tab to your Warehouse app. 7. Click the Invoice Statements tab.. For the Tab Style. On the Add to Custom Apps page. so that you can view. and that the Invoice Line Items are related to Merchandise. and update records.. From the Object drop-down list. See Also: Tutorial #2: Adding Relationships Step 3: Relate the Objects Step 5: Create an Invoice Record Step 5: Create an Invoice Record As you saw in the previous tutorial. 6. the user interface provides a way of navigating between related records as well. 1. Click Save to finish creating the tab. 2.com automatically generates for this object. You'll use that feature in a later tutorial. Within the Setup area. the platform automatically generates a user interface for the objects you create. 2. 5. 1. edit.. Click New. Because you also related the objects. and click Next and then Next again.Tutorial #2: Adding Relationships Tell Me More. Master-detail relationships also support roll-up summary fields. select Invoice Statement. You have just created two master-detail relationships ensuring that your Invoice Statement records are related to Invoice Line Item records. for the Merchandise custom object. 4.

In the Description field. like Invoice Statements? The short answer is that it's easier to work with text when 20 . 1. when what you enter is a number. and how the user interface displays an empty Line Items related list below it. Tell Me More. enter First Invoice and then click Save.. 3.. The Invoice Statement is linked to the Line Item via a master-detail field—that's how you created this relationship and why there's a related list on the Invoice Statement detail page. Click Save. • • • • In the Line Item Number field enter 1. Fill in the fields. In the Unit Price field enter 10.Tutorial #2: Adding Relationships 3. For the Merchandise field. why not make it an auto-number field. If line items are numbered. In the Units Sold field. 2. The detail page of your invoice statement should look like this. click the lookup button and select a product. enter 4. Notice how the invoice was automatically assigned a number. You might be wondering why Line Item Number is a text field. Click New Line Item.. Next you'll add a line item to the invoice.

but it makes a later tutorial. Tutorial #9: Creating a Public Web Page Using Sites. you created relationships between the objects in your data model.Tutorial #2: Adding Relationships we work with records. Now that you have built the basic application. The relationships work like foreign keys in relational databases. The master-detail relationship allows you to aggregate information. The relationships also provide additional benefits: you can navigate to the related records in a user interface and a query language. letting you concentrate on what matters (the relationships) instead of the underlying implementation. You can make Line Item an auto number field if you want to. See Also: Tutorial #2: Adding Relationships Step 4: Add Invoice Statements to the App Summary Summary In this tutorial. You'll learn about that later as well. See Also: Tutorial #2: Adding Relationships Step 5: Create an Invoice Record 21 . and this tutorial is supposed to be easy. and in the next tutorial you'll see how to sum the price of each invoice line item into the invoice statement. yet they operate at a more abstract level. a bit more difficult. you can add business logic with formulas and validation rules in Tutorial #4: Using Formulas and Validation Rules on page 31.

. In the Optional Features section.com object can be configured to allow reporting. 3. It's easy to group and summarize your data. 1. and the reports in folders that you can access. Click Your Name ➤ Setup ➤ Create ➤ Objects. you will display your data in reports using three different formats. then click the Add arrow. Prerequisites Warehouse App First create the basic Warehouse application in Tutorial #1 on page 5. 4. Click Your Name ➤ Setup ➤ Create ➤ Apps. • • The Allow Reports flag makes the data in the object available to the reporting engine. and another invoice. 4. lists your data in a simple table. Data The reports you create in this tutorial will look better if you have more data. 2.com provides a drag-and-drop report builder that lets you quickly organize and present your data. 6. In the Custom Object Definition Detail section. Repeat for Dashboards. Click Save. Tell Me More. In this tutorial. and that the Reports and Dashboards tabs are available to your application.. You will also create a dashboard using one of your reports. select Reports. 1. The next two let you group your data and add a chart. ensure that the Allow Reports option is enabled on your objects. The first format. but you want to report on that data as well. 22 . You can then share these reports to help business users make more informed decisions. then add relationships as described in Tutorial #2: Adding Relationships on page 14. Step 1: Enable Reporting on Objects Every Force. Select Merchandise from the Custom Objects list. 5. Select Warehouse from the Apps list. The Reports tab provides access to a set of pre-defined reports. and add formulas and charts. Repeat this procedure for your Invoice and Line Item objects. 2. so that you can easily access them later. Before you write your first report. click Edit. 5. Click Save. Duration: 20-30 minutes You’ve built an application that captures and manipulates warehouse data.Tutorial #3: Creating Reports and Dashboards Tutorial #3: Creating Reports and Dashboards Level: Beginner. tabular. all of the reports that you create. 3. Force.. In the Available Tabs panel. Click Edit. Now add the Reports and Dashboards tabs to your application. select Enable Reports. Go ahead and create one or two more merchandise items.

Click the Reports tab. select Merchandise. Report types set the rules for which records to show in reports. but can be used to show column summaries. like sum. 6. much like a spreadsheet. Click Apply. 7. and minimum. enter Merchandise Reports. 5. with its dynamic preview built from a limited number of records. In the Report Folder Label field. The Merchandise Name field is in the report by default. They also determine which fields you can use. average. Click Create New Custom Report. The default report format is tabular.Tutorial #3: Creating Reports and Dashboards Step 2: Create a Tabular Report In this step you will create a tabular report. 3. and then click Create. Tabular reports present data in simple rows and columns. placing them beside the Merchandise Name column: • • • Description Price Total Inventory You now have a basic report. They don't contain groupings. 1. 3. Click Create New Folder. select Other Reports. Drag each of the following fields from Fields pane to the Preview pane. In the Select Category panel. but let’s add a few bells and whistles like sums and averages. 2. Click the button next to Price header and select Summarize this Field. Click Save. The report builder appears. based on object relationships. In the Select Report Type panel. 23 . 4. Figure 1: Report Builder 8. 2. 1. and then press the TAB key so the Folder Unique Name field auto-populates. maximum. Select the Max and Min checkboxes.

5. click on the name of any merchandise record listed in the report to view its detail page.com. select All Merchandise from the View drop-down list to assign the set of records that the report will use. 11. Tell Me More. You can return to your reports at any time by selecting the Reports tab. In the Report Name field. You will now see your All Merchandise with Price and Inventory report displayed. Click Apply. The procedures you followed in creating this report will be similar to those you follow in the later steps. In the Report Description field. The folder a report is placed in determines its visibility and security. For example. 10.. You can click through to the data records that are being reported on. determined which fields to display. • • • 24 . you can add Public Groups. The Grand Totals area of the report indicates the record count as well as the summaries you chose.. • You can order the report data by clicking the column headers to toggle between ascending and descending order. The other reports in this tutorial follow a similar set procedure. and set data filters for the report . and clicking Go. a characteristic found in all reports on Force. enter What is all our Merchandise with Price and Total Inventory? 12. Click the button next to Total Inventory and select Summarize this Field. 13. While you are not able to specify a specific user to access a report folder. You selected the objects that you want to report on. optionally added summary data. 7. Modify these settings by clicking Edit on the Report Folder on the Reports tab. Select the Sum checkbox. enter All Merchandise with Price and Inventory. Review the data and click Save. Click Run Report. In the Filters pane.Tutorial #3: Creating Reports and Dashboards 4. Roles.. selecting the Merchandise Reports folder. with the addition of grouping and charts. selected the report format. Select Merchandise Reports from the Report Folder drop-down list. Click Save and Run Report. 9. 6. You can make additional changes to this report by clicking the Customize button. 8. or Roles and Subordinates to control visibility.

8. 3. Click the Reports tab. select Sum of Units Sold. The Chart Editor dialog box appears. In the Y-Axis drop-down list. as well as average price and total units sold. Select the Merchandise Name field (either from Fields or Preview panel) and drag it to the grouping drop zone. and in the Value drop-down list. From the Line Item node in the Fields pane. 5. Click Create New Custom Report. Select the vertical bar chart. select Average of Unit Price. Click the Format drop-down list and choose Summary. 8. 4. Select Average and click Apply. Click Create. Select Plot additional values. Click the button next to Unit Price and select Summarize this Field. Figure 2: Invoice Report with Bells and Whistles Now let's add a fancy combination chart to the report: 1. In the Display drop-down list. Click Save. 7. 4. 7. Select Other Reports. 25 . drag across the Unit Price and Units Sold fields to the Preview pane. 9. then Invoice Statements with Line Items and Merchandise. select Line. The default format is tabular. 2. Click the button next to Units Sold and select Summarize this Field. select Merchandise: Merchandise Name. 1. Select Use second axis. 5. In this step you'll create a summary report and group by the merchandise name. 11. 6. The report now includes all the invoices and their associated line items grouped by merchandise item. 6. You can group report data by up to three levels. 3. This groups report data by unique merchandise item. and add a chart. 2. 10. 9. Select Sum and click Apply. Click OK. Click Add Chart to set up a chart to represent your data.Tutorial #3: Creating Reports and Dashboards Step 3: Create a Summary Report Summary reports allow for more advanced customization than tabular reports. In the X-Axis drop-down list.

Click OK. In the Report Description field. The combination chart shows the data. Click Save and Run Report. In the Report Folder drop-down list. Double-click the following fields to add them to the report. if you prefer. 13. Step 4: Create a Matrix Report In this step you will create a matrix report that groups and summarizes both columns and rows. 6. 5. 11. enter What merchandise has been selling and what’s the average unit price? 12. You can check rows of interest on your report and click Drill Down to filter the report to only those rows. • • • Invoice Statement: Invoice Value Units Sold Merchandise: Merchandise Name 26 . This report will show summary data of merchandise items per day and across different invoice statement status values. Click Create New Custom Report. 1. 7. then Merchandise with Line Items and Invoice Statements. enter Merchandise Sold by Invoice No & Price. 4. 2. Click the Reports tab.. In the Report Name field. 3. Clear the slate by selecting Remove all Columns. plotting each merchandise item against units sold (across all invoices) as well as superimposing a second graph mapping the average unit price for the item. select Merchandise Reports.. Click Create. Tell Me More.Tutorial #3: Creating Reports and Dashboards 10. Select Other Reports. select Matrix from the Format drop-down list. In the Preview panel. You can also drag them.. 8.

Values are tallied both horizontally and vertically. ensure that All Merchandise is selected from the View drop-down list. 7. Create a secondary row grouping by dragging the Merchandise: Merchandise Name field to the second drop zone. 8. Click Add Chart.Tutorial #3: Creating Reports and Dashboards 9. Select Plot additional values. 3. select Invoice Statement: Status. Click on the Formatting tab to further customize the chart. 27 . Select the Stacked graph type. The Chart Editor dialog box appears. Create a row grouping by dragging the Invoice Statement: Create Date field to the row drop zone. select Sum of Units Sold. In the Filters pane. You’ll get an astounding amount of information generated in the report. Click Customize. Figure 3: Matrix Table Now let's add a combination chart to this report: 1. 13. Select the Sum checkbox. 5. select Record Count 10. To add summaries. 12. 6. In the Y-Axis drop-down list. select Bottom. In the X-Axis drop-down list. and within the report depending on the column grouping (Invoice Status) and row groupings (Created Date and Merchandise Name). 2. Click Run Report. In the Group-By drop-down list. 11. 14. Create a column grouping for the status of invoice statements by dragging the Invoice Statement: Status field to the column drop zone. For Legend Position. 10. For Value. 12. select Invoice Statement: Created Date. 4. enter Units Sold per Day by Invoice Status. For Chart Title. 9. Select Use second axis. 11. click the button next to the Units Sold and Invoice Statement: Invoice Value fields and select Summarize this Field. Select the Vertical Bar Chart. 13.

gauges. Choose either a predefined duration or enter your own custom dates and click Run Report to update the page. 17. select Merchandise Reports. For Report Description. The chart and report currently display all records. and automatically takes into account the status of each invoice. by Invoice Status? 19. you’ll see multiple summary rows For example. 20. Click Save. • • The Sum of Units Sold has a scale on the left side of the chart that correlates to the horizontal bars of your chart. You can quickly change how your chart is displayed by clicking Edit. metrics. Click Save and Run Report. 18.Tutorial #3: Creating Reports and Dashboards 14. Record Count has its own scale on the right side of the chart that correlates to the blue line on your chart. Tell Me More. making your report easier to see. Because you defined multiple grouping levels in the report. For Report Folder. dashboards are organized into folders. tables. enter How many units are we selling each day. regardless of when they were created. 28 .. If you want to narrow the time frame that is represented. Click the Dashboards tab. 15. then press the TAB key.. for Invoice Statement Status. and even Visualforce components. you can define it in the upper right corner of the page. 1. For Report Name. grouping the invoices over daily periods. • • • Step 5: Create a Dashboard You can show all the reports you've built in the same place by including them in a dashboard. Select Show Axis Label.. Similar to reports. Your data can be represented by charts. enter Daily Units Sold by Invoice Status. Click OK 16. You can deselect Show ➤ Details to only show summary information. The resulting graph summarizes the units sold. which provides a graphical summary of the data in your application.

then Save and Run Dashboard. and press the TAB key. specific user.. Click Save. 7. All users with access to the dashboard see the same data. click the button next to the View dashboard as field. Select Use chart as defined in source report. Your dashboard now has one component in the left column. Click OK. Click New Dashboard. 17. 9. Click Dashboard Properties. From the Data Sources tab. enter Merchandise and Invoice Summary. 29 . Click OK. click the wrench icon ( ) in the upper right corner. 8. 16. select Merchandise Dashboards. drag the vertical bar chart over to the first column. 15. In the Save To drop-down list. For Title. enter Merchandise Dashboards.. Tell Me More. 13. 5. 6. then click the + sign next to Merchandise Reports.. 3. 12. On the Vertical Bar Chart. 4. You can add up to 20 components to create a more complex dashboard.Tutorial #3: Creating Reports and Dashboards 2. From the Components tab. 11. and drag Weekly Units Sold by Invoice Status on top of the vertical chart in the first column. Click Go to Dashboard List to view your dashboards. Click Save. it runs using the security settings of that single. regardless of their own personal security settings. • When you set a running user for a dashboard. Click Create New Folder. To set the running user. Add a header to the component by clicking Edit Header and entering Items Sold per Day. For Dashboard Folder Label. 10. 14. click Reports.

and can be delivered through email. then Edit again. You also created a dashboard. a summary report that grouped and graphed your data. click Refresh. Creating meaningful reports is a skill well worth learning! 30 . and select the Dashboard Snapshot checkbox. Summary In this tutorial you created three reports: a quick tabular report that listed your records with simple column summaries. then Save. groupings and charts. To refresh the data in the dashboard. and a matrix report that provided a multi-dimensional analysis of your data. experiment with them by modifying the filters. Each time you view a dashboard. Add the dashboard to your Home tab by clicking Setup ➤ Customize ➤ Home ➤ Home Page Layouts. Click Edit. A dashboard won't automatically refresh unless it is set to do so. it indicates in the upper right corner when it was last refreshed. Select your Home tab to see it in action. Click Next. which you can place on your home tab for quick reference. Now that you’ve built the basic reports.Tutorial #3: Creating Reports and Dashboards • • • Dashboards can be updated either manually or on a schedule.

2. Prerequisites Warehouse App You first need to create the basic Warehouse application and add relationships. and click Next. ensuring that you can't create a line item for more merchandise than you have in stock. and return a result. 31 . and click New. Choose Formula as the field type. validate your data. you will enhance the Warehouse app by adding a formula field to automatically calculate the total value for each line item. You will also use this new line item value and a property of the master-detail relationships to automatically total an invoice value. with formula fields and validation rules. 1. perform calculations. The functions you use in formula fields and field validation rules are a lot like the functions you would use in a spreadsheet program. However. Duration: 20-30 minutes The Force. Finally. In this tutorial. Both formula fields and field validation rules use built-in functions that allow you to automatically manipulate your data.Tutorial #4: Using Formulas and Validation Rules Tutorial #4: Using Formulas and Validation Rules Level: Beginner. and calculate other values based on your data.com platform lets you create formulas and field validation rules to help maintain and enhance the quality of the data entered in your app. you will add a formula to perform an inventory check. 3. you reference fields in your app's records. you will add a new calculated field called Value to the line item. where you can reference values in other cells of the spreadsheet. Navigate to the Line Item custom object page by clicking Your Name ➤ Setup ➤ Create ➤ Objects ➤ Line Item. This field will multiply the number of items with the price and act as a total for each line item. Scroll down to the Custom Fields & Relationships related list. as described in Tutorial #2: Adding Relationships on page 14. See Also: Step 1: Calculate a Value for Each Line Item Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field Step 3: Check Inventory With a Validation Rule Step 4: Test the Validation Rule Step 5: Improve the Validation Rule Summary Step 1: Calculate a Value for Each Line Item In the first step of this tutorial.

See Also: Tutorial #4: Using Formulas and Validation Rules Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field Now that you have the total for each line item. Tell Me More. In the Formula Return Type field. 5. Roll-up summary is a special type of field that lets you aggregate information about related detail (child) objects. and click Next. Because the line items have a master-detail relationship with the invoice statement. enter Value. In the Insert Merge Field drop-down list. 2.. 1. Scroll down to the Custom Fields & Relationships related list. In this case. 10.Tutorial #4: Using Formulas and Validation Rules 4. Click the Insert Operator drop-down list and choose Multiply. you want to sum the value of each line item. 32 . Click Next. and click New. choose Currency. In the Insert Merge Field drop-down list. it makes sense to add them all to get the invoice total. Navigate back to the Invoice Statement custom object page by clicking Your Name ➤ Setup ➤ Create ➤ Objects ➤ Invoice Statement. You should now see Unit_Price__c in the text box. which allows you to do much more with these formulas. In the Field Label and Field Name fields. 9. The formula you entered was quite straight forward: a simple multiplication of two field values on the same record. and then click Save.. we can use a roll-up summary field to calculate this value. You should now see Unit_Price__c * Units_Sold__c in the text box. 6. 3. 7. 8. click Next again. Click Next. There's also an Advanced Formula tab. The Formula field type is great for automatically deriving field values from other values. select Unit_Price. you can see there's a new field called Value. When you return to the detail page for the custom object. select Units Sold. Choose Roll-Up Summary as the data type. as you have done here..

The validation rules can be used to determine what range of input is valid. wait a few seconds and then refresh.. choose Sum. and to display a message to the user if a field value is not valid. In the Field to Aggregate list choose Value. you'll see your new roll-up summary field in action. Verify that your screen looks like the following and then click Next. You can test this new functionality by adding a new line item. Scroll down to the Validation Rules related list. If the field shows an hour glass.Tutorial #4: Using Formulas and Validation Rules 4. If you navigate back to an invoice statement record. 1. In the Field Label field. For Roll Up Type field. displaying the total value of all the invoice line items. Click Next again and then click Save. 6.. In the Summarized Object list choose Line Items. 2. 9.. 5. and click New. See Also: Tutorial #4: Using Formulas and Validation Rules Step 1: Calculate a Value for Each Line Item Step 3: Check Inventory With a Validation Rule Step 3: Check Inventory With a Validation Rule The fields that you define in objects can have validation rules. 8. 7. Tell Me More. written in the same formula language that you used to create the formula field. The error condition formulas should evaluate to true when you want to display a message to the user. Navigate back to the Line Item custom object page by clicking Your Name ➤ Setup ➤ Create ➤ Objects ➤ Line Item. 33 . enter Invoice Value and click Next.

Click Insert.. For the Error Location. Merchandise__r.Tutorial #4: Using Formulas and Validation Rules 3. then choose Units Sold from the drop-down list. b. 6. enter Order in stock. Click Check Syntax to make sure there are no errors. but as you saw here. a. c. h.Total_Inventory__c < Units_Sold__c 5.Total_Inventory__c < f. Click Insert and verify the code looks like the following. 7. Click Save. If you do find errors. In the Rule Name field. click Insert Field to open the Insert Field popup window. Type the less-than symbol < so that the formula looks like this: Merchandise__r. 34 . Select Merchandise > in the second column. Select Line Item > in the first column. enter You have ordered more items than we have in stock. Select Total Inventory in the third column. Let's analyze the formula you created. 8. g. In the Error Message field. you can easily traverse the available objects and find the components you need for the formula. e. select Field. You can enter a formula directly into the Error Condition Formula area. i. Select Units Sold in the second column. d. fix them before proceeding.. 4. In the Error Condition Formula area. Tell Me More.. Select Line Item > in the first column. Click Insert Field again.

Merchandise__r. 5. the formula checks that the total inventory on the related merchandise record is less than the number of units being sold. the platform automatically provides a relationship field that lets you navigate from a Line Item record to a Merchandise record.Total_Inventory__c—This tells the system to retrieve the value of Total Inventory field on the related Merchandise record. 3. Click Cancel. Click on the Invoice Statements tab and select an existing invoice.Tutorial #4: Using Formulas and Validation Rules • Mechandise__r—Because the Merchandise object is related to the Line Item object. You should see an error indicating that there are not enough items in stock. See Also: Tutorial #4: Using Formulas and Validation Rules Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field Step 4: Test the Validation Rule Step 4: Test the Validation Rule Now test the validation rule you created in Step 3. you need to provide a formula that is true if an error should be displayed. 2. 4. 1. Click Save. Scroll down to Line Items and click Edit next to one of the line items. As indicated on the Error Condition Formula page. • • • Total_Inventory__c—This is the field you created to track the total amount of stock on a Merchandise record. See Also: Tutorial #4: Using Formulas and Validation Rules Step 3: Check Inventory With a Validation Rule Step 5: Improve the Validation Rule 35 . Units_Sold__c—This refers to the Units Sold field on the current (Line Item) record. Modify the Units Sold value to a number larger than the amount in stock. and this is just what you want: it will only be true when the total inventory is less than the units sold. Putting it all together. that's what the Mechandise__r is doing. Click Cancel.

Click Check Syntax to make sure there are no errors. This function returns true if you're creating a new record. you return FALSE to indicate that there's no validation failure. If the prior value was smaller. FALSE. 5.. IF ( Units_Sold__c < PRIORVALUE(Units_Sold__c). you'll need to use the PRIORVALUE() function to tell you the prior value of the field before it was modified. If the prior value was greater. false otherwise. If it's not a new record.Total_Inventory__c < (Units_Sold__c . so you perform another conditional check. this time to determine if the number of units has gone up or down. not creating a new record.PRIORVALUE(Units_Sold__c)) ) ) 4. you shouldn't need to check inventory.Tutorial #4: Using Formulas and Validation Rules Step 5: Improve the Validation Rule The logic in the validation formula is a little bit flawed! Imagine that you edit a record and decrease the number of units sold. by comparing it to its prior value using the PRIORVALUE function. you need to check that you have • • not sold more than you have in stock. ensuring that at run time one of the two branches will be taken depending on the condition. You can improve the validation rule to include these scenarios by using the ISNEW() function in your formula.. Tell Me More. Navigate back to the Line Item custom object page by clicking Your Name ➤ Setup ➤ Create ➤ Objects ➤ Line Item. ISNEW is the condition. Merchandise__r. • • • • IF is a conditional. Replace the existing formula with the following. See Also: Tutorial #4: Using Formulas and Validation Rules Step 4: Test the Validation Rule Summary 36 . For new records. 3. If ISNEW is false. 2. then you've updated the record and decreased its units. Let's look at this formula in a little more detail. In this case. you know that you're performing an update to an existing record. Scroll down to the Validation Rules related list. so you have to check whether there's enough inventory to hold the difference between the new number of units and the old. Or if you increased the number of units sold.. Since you have enough stock. Merchandise__r. then you've increased the number of units. If ISNEW is true. IF( ISNEW(). Click Save. you should only need to verify that the number of additional items is in stock. then you simply check inventory as you did previously. 1.Total_Inventory__c < Units_Sold__c . which determines whether you are creating a new record. and next to Order in stock click Edit.

An invoice could be made up of multiple line items. For the first formula you created a subtotal for each line item by multiplying the price of a product by the number of units that were ordered. You also learned how to define a validation rule to make sure you have enough items in stock. and existing records with updates.Tutorial #4: Using Formulas and Validation Rules Summary In this tutorial you created formula fields and validation rules that enhance and validate your app's data. so you created a roll-up summary field to automatically add up the line item subtotals. See Also: Tutorial #4: Using Formulas and Validation Rules Step 5: Improve the Validation Rule 37 . The first version of the rule was simple. but you enhanced it to work with both new records. These kinds of modifications can be applied to any field in your app when you want to make sure the data entered meets certain criteria.

though you probably didn't notice that in the user interface because your default user is an administrative user. In your Force. tasks. 38 . Not only do they save time. you've created the Line Item and the Merchandise objects with Price fields. Approval processes can automate all of your organization's approvals—from simple to complex. You've also marked the Line Item Price field as read-only. In this tutorial. and outbound messages) based on time triggers. criteria. Workflow rules can trigger actions (such as email alerts. Prerequisites Formulas and Validation You first need to create the roll-up summary field and validation rules as described in Tutorial #4: Using Formulas and Validation Rules on page 31. Duration: 30-45 minutes Your company can operate more efficiently with standardized internal procedures and automated business processes. and the second updates the inventory whenever you update a product line item.com app.Tutorial #5: Using Workflow and Approvals Tutorial #5: Using Workflow and Approvals Level: Intermediate. who has access to all data. field updates. you can use workflow rules and approval processes to automate your procedures and processes. Now you'll create a workflow rule to populate the unit price on the line with the unit price on the merchandise at the time the line item is created. You will also create an approval process that requires explicit approval from the manager if an invoice is over $2000. you create and test two workflow rules. You can create this complex logic quite easily with a declarative workflow rule. they also enforce consistency and compliance within your company's business practices. The first carries the current price of a merchandise item into the newly created line item record. See Also: Step 1: Populate the Line Item Price Using a Workflow Rule Step 2: Update Total Inventory When an Order is Placed Step 3: Test the Workflow Rules Step 4: Create an Email Template Step 5: Create an Approval Process Step 6: Create a Custom Profile Step 7: Create a User Step 8: Test the Approval Process Summary Step 1: Populate the Line Item Price Using a Workflow Rule At this point. and formulas.

12. Click Insert. Select Use a formula to set the new value. In Step 3 of the Workflow Rule wizard. 8. 5. enter Line Item Created. 3. click Continue. Click Show Formula Editor. click Add Workflow Action and choose New Field Update. 39 . 15. For Evaluation Criteria. select Only when a record is created. 10. 9. The New Field Update wizard opens. enter true. Make sure your page looks like the following and then click Save & Next. Click Insert Field. Select Line Item > in the first column. select formula evaluates to true. select Line Item as the object and click Next. and Price in the third column. 13. enter Insert Merchandise Price. In the Rule Criteria field. select Line Item in the first box and Unit Price in the second. 2. 14. In the Rule Name field. In Step 1 of the Workflow Rule wizard. If you see the Understanding Workflow page. click New Rule. On the All Workflow Rules page. 4. Click Your Name ➤ Setup ➤ Create ➤ Workflow & Approvals ➤ Workflow Rules. In the Name field. Merchandise > in the second column. 16. in the Immediate Workflow Actions section. In the text box. 11. In the Field to Update drop-down list. 6. 7.Tutorial #5: Using Workflow and Approvals 1.

you will see that line item's unit price will automatically be set to the price of the related merchandise record. Remember that because you are an administrator. and then view it. You'll make that happen later. and that's always true. Click Save to close the New Field Update wizard and return to Step 3 of the Workflow wizard. See Also: Tutorial #5: Using Workflow and Approvals Step 2: Update Total Inventory When an Order is Placed 40 . The reason this workflow rule runs only when a record is created (and never afterward) is that we don't want to increase the invoice price of an item after the item has been added to the invoice.. You might be wondering why we've created a rule whose formula always evaluates to true. 18. the customer would appreciate being updated with the new price. its criteria are not evaluated when records are created or saved. If you now create a new line item. Important: Forgetting to activate a new workflow rule is a common mistake. it just wasn't necessary this time.. However.. click Done. 19. On the Specify Workflow Actions page. You can also use a formula to evaluate an expression. you see an input field for price. save it. if the item's price goes down. On the Workflow Rule page. If your rule is not active. It would confuse a customer to suddenly find out the item's price is higher than what was advertised. The reason is that we want the field update to happen every time a record is created. click Activate. But your users won't see that field because it was set to read-only. Tell Me More.Tutorial #5: Using Workflow and Approvals 17.

This can be accomplished with another workflow rule. you need to decrease the total inventory by the number of units sold. 1. select Merchandise. you want any updates to the line items to be reflected in the Total Inventory field you created on the Merchandise object. In the Field drop-down list. As you create new invoices (which will default to "Open" status). In the second. 14. you need to adjust the total inventory by the difference between the numbers of old and new units sold. select Invoice Statement: Status. 13.Tutorial #5: Using Workflow and Approvals Step 2: Update Total Inventory When an Order is Placed Ideally. In the Name field. But if you're updating a line item. In the first Field to Update drop-down list. In the Rule Criteria field. select Line Item as the object and click Next. 12. 15. 4. Click Show Formula Editor. click Continue. select criteria are met. 41 . Under Value click the lookup icon and choose Open. In Step 1 of the Workflow Rule wizard. in the Immediate Workflow Actions section. The New Field Update wizard opens. 7. For Evaluation Criteria select Every time a record is created or edited. Enter the following code. you want the total inventory of the Merchandise records to be automatically maintained. Then for Operator. IF ( ISNEW(). otherwise proceed to the next step. 8. 2. Click Insert Selected. enter Line Item Updated. The only trick to it is changing the total inventory value. select Total Inventory. select equals. click New Rule. If you're creating a new line item. 5. If you see the Understanding Workflow screen. 10. On the All Workflow Rules page. 3. 11. 6. enter Update Stock Inventory. In the Rule Name field. Select Use a formula to set the new value. In Step 3 of the Workflow Rule wizard. Click Your Name ➤ Setup ➤ Create ➤ Workflow & Approvals ➤ Workflow Rules. 9. Make sure your screen looks like the following and then click Save & Next. click Add Workflow Action and choose New Field Update.

click Activate. Click the Invoice Statements tab.Tutorial #5: Using Workflow and Approvals Merchandise__r. Click Check Syntax and make corrections if necessary. Leave the Unit Price field blank. See Also: Tutorial #5: Using Workflow and Approvals Step 1: Populate the Line Item Price Using a Workflow Rule Step 3: Test the Workflow Rules Step 3: Test the Workflow Rules You can check to make sure your workflows are functioning as expected by creating a new line item. 19. On the Specify Workflow Actions page. click Done. 17. 1. Select New Line Item and enter the following values.PRIORVALUE(Units_Sold__c)) ) 16.(Units_Sold__c . Click the invoice record you created earlier. 42 . Merchandise__r. Set Units Sold to 1000. 18.Total_Inventory__c . 3.Total_Inventory__c . • • • In the Line Item Number field enter 2. On the Workflow Rule page. Click Save to close the New Field Update wizard and return to Step 3 of the Workflow wizard.Units_Sold__c . Then verify that its unit price is automatically set and that the total inventory on the stock has decreased. 2.

Note that the unit price has been set to the same value as on the Wee Jet record.Invoice_Value__c} on {!Invoice_Statement__c. 4. just assume we're talking about whatever currency you're using. Notice that the Total Inventory is down to 1000 from 2000 (or whatever you entered). Note: If your default currency is not set to US dollars. 43 .OwnerFullName} submitted for approval an Invoice Statement that totalled {!Invoice_Statement__c. click the lookup icon and select the Wee Jet merchandise record. See Also: Tutorial #5: Using Workflow and Approvals Step 2: Update Total Inventory When an Order is Placed Step 4: Create an Email Template Step 4: Create an Email Template One of the business rules that you want to enforce in your workflow is that all invoices totaling over $2000 must be approved by a manager. You create the approval process in the next steps. 7. and then click Save.LastModifiedDate} 8. In this step you create the email template that will be used by the workflow rule to generate and send the email. 5. Click Save. In the Email Template Name field. 5. In the Subject field. In the Email Body field. Now open the Wee Jet merchandise record by clicking on the Wee Jet link. To implement this rule you need to create two additional elements: an email to be sent to the manager when an invoice exceeds $2000. enter the following code and text.Tutorial #5: Using Workflow and Approvals • Next to the Merchandise field. 3. Click Your Name ➤ Setup ➤ Communication Templates ➤ Email Templates. 6. Click New Template. 4. enter A large invoice has been submitted. and an approval process for the manager to follow. select Text and click Next. 1. Click line item 2. enter Large Invoice Template. In Step 1 of the Email Template wizard. 6. Select Available For Use. {!Invoice_Statement__c. 2. Verify that your screen looks like the following.

for example {!Invoice_Statement__c. 3. this value will be dynamically substituted with the actual invoice value that generated the approval process. 4. In the Field drop-down list. choose Invoice Value. b.. Click Your Name ➤ Setup ➤ Create ➤ Workflow & Approvals ➤ Approval Processes.Tutorial #5: Using Workflow and Approvals Tell Me More. Next to the Approval Assignment Email Template field. In the Manage Approval Processes For drop-down list. Click Create New Approval Process and choose Use Jump Start Wizard from the drop-down list. At the time the email is generated.Invoice_Value__c}. choose greater than. enter Large Invoice Value.. 2. 44 . c. 6. Creating and using an approval process is just as easy as creating a workflow rule. choose Invoice Statement. Enter the following values in the Specify Entry Criteria area. 1. In the Name field. 5. click the lookup icon and select the Large Invoice Template you just created. a. See Also: Tutorial #5: Using Workflow and Approvals Step 3: Test the Workflow Rules Step 5: Create an Approval Process Step 5: Create an Approval Process In this step you create an approval process that requires explicit approval from the manager if an invoice is over 2000. In the Value field enter 2000. In the Operator drop-down list. The email body text that you just entered supports merge fields..

Click Approval Processes to return to the approval list. Choose A specific value and select Open. but before it can run. Click Save. Related List Initial Submission Actions Final Approval Actions Final Rejection Actions Name Field to Update Picklist Options Choose A specific value and select Pending. Click Activate to activate the approval process. 14. Click View Approval Process Detail Page. You've finished creating the approval process. the user's manager is assigned as the approver. Click Save. Set Initial Approval Status Status Set Final Approval Status Set Final Rejection Status Status Status 12. 9. 13. 11. Create new field update actions by clicking Add New and selecting Field Update for each related list in the following table. You'll see a warning that you must activate the approval process. you have to define what happens to records when they're first submitted. Click OK. Choose A specific value and select Closed. You'll create a user named Bob Smith in the next step. when they're approved. 8. Configure each field update action as shown. 45 . 10.Tutorial #5: Using Workflow and Approvals 7. This ensures that if a particular user starts the approval process. and when they're rejected. Select Automatically assign an approver using a standard or custom hierarchy field and choose Manager for the hierarchy field.

but not standard profiles. click Edit. In the Profile Name field. if the record is rejected. Edit. and under Custom Object Permissions.. You'll create the new user in the next step. while the Final Rejection action unlocks it. Then in your new custom profile. 5.Free User. You can change these permissions in custom profiles. See Also: Tutorial #5: Using Workflow and Approvals Step 4: Create an Email Template Step 6: Create a Custom Profile Step 6: Create a Custom Profile A profile is a collection of permissions and other settings associated with a user or a group of users.” “Edit. 1. 3. Select Clone next to Standard User. it shouldn't be changed in the meantime. In this step. This makes sense: if someone submits a record for approval. it should be unlocked so changes can be made. enter Basic User. and Merchandise objects. Click Save. select the Read. and Delete boxes for the Invoice Statements. Create.. 2. 6. Likewise.” “Create. If you're using Free Edition. Line Items. 4. 46 . Default actions are associated with a few of the approval steps. This security setting ensures that access to custom objects and their data is only explicitly granted to users. select Clone next to Force.. On the detail page for your new profile. Verify that your screen looks like the following.” and “Delete”) are disabled for most profiles. the permissions to access that object (“Read. Click Your Name ➤ Setup ➤ Manage Users ➤ Profiles. The Initial Submission actions and Final Approval actions both lock the record. Scroll to the bottom of the profile edit page. 7. you'll enable object permissions so your users can access the objects. and then click Save. If you create a custom object. Your organization has a number of standard profiles already defined.com . you'll create a custom profile that you can assign to users who need to access the custom objects in the Warehouse app.Tutorial #5: Using Workflow and Approvals Tell Me More.

1. see “Editing Profiles Using Profile Lists” in the Salesforce online help. the invoice is routed to his or her manager. See Also: Tutorial #5: Using Workflow and Approvals Step 5: Create an Approval Process Step 7: Create a User Step 7: Create a User When you create a Force. select Salesforce. enter Smith. For more information. select Force. On the All Users page. but you'll need to create a unique username for Bob..Tutorial #5: Using Workflow and Approvals Tell Me More. enter Bob. select Basic User. Enter the following information: • • • • • In the First Name field. • • • In the Manager field. You use this configuration to make sure that if the new user creates an invoice that meets certain conditions. select the user you created when you signed up for your organization. In the Last Name field. In the Email field. Note: Write down Bob's username (his imaginary email address). or make them completely invisible. In the Profile field. you create a new user and link that user to your current user's account via the Manager field. In the User License field. 2. so that a user sees only his or her records or those of his or her manager. In this step. For example. You've just seen how easy it is to create and edit a custom profile. because you'll be logging in as him shortly. click New User. The Username field defaults to your email address.com Free Edition..com — Free. it's automatically enabled to allow multiple users to log in.com application. enter bsmith. so that you will receive the approval requests routed to Bob Smith.. Click Your Name ➤ Setup ➤ Manage Users ➤ Users. In the Alias field. enter your own email address. Now you can customize the application by configuring it to function differently depending on the profile of the user logging in. If you are using the Force. You can also strictly enforce data sharing. 3. you can use enhanced profile list views to create a custom list view of your profiles and then edit the profiles from the list. you can grant read-only access to fields to a certain group of users. in the form of an imaginary email address. If you need to edit many profiles. 47 .

1. so it must be the default. Click Your Name ➤ Setup ➤ Customize ➤ Home ➤ Home Page Layouts. In Free Edition.Tutorial #5: Using Workflow and Approvals 4. See Also: Tutorial #5: Using Workflow and Approvals Step 6: Create a Custom Profile Step 8: Test the Approval Process Step 8: Test the Approval Process We can now put the approval process together and see it in action. he or she can approve (or reject) the invoice. he will be able to click the new Submit for Approval button on the invoice statement. In a real-world scenario. You should now receive an email confirming the creation of the new user. 3. 48 . Next to Warehouse. you have to modify the Basic User profile to use the Warehouse app. If Bob Smith creates an invoice. your business process might require you to email the invoice owner and ask for confirmation. There's one more setup step to complete the approval process. And if not. Click Save. Click Your Name ➤ Setup ➤ Manage Users ➤ Profiles. skip this step. click Edit. 2. and the total value of the invoice is greater than $2000. so don't log in as Bob Smith yet or you'll have to immediately log back in as the administrator. The app will send an email to his manager (using the email template you created earlier) and lock the record. (If you're using Developer Edition.) 1. Before testing the approval process. When the manager logs in. you want it to remain in the original Open status. before Bob can login and use the Warehouse app. Next to the Basic User profile. preventing Bob from making any more changes. and so on. select Default. If the manager approves the invoice. make sure that your Home page can display items that require approval. you want its status updated to Closed. Free Edition users only get access to one app.

.. (You may have to scroll down to see it. From your Approval Process detail page. If this is your first time logging in as Bob. 4. click Approval Process and select the process you created. Select the Items to Approve option. 49 . 6. (If you're using Free Edition. Click Save. When you log in to the application as administrator. An email is sent to Bob Smith's designated manager who. you may have to change your password. The approval process diagram appears in a separate browser window. Click Submit for Approval. 4. In the familiar Your Name ➤ Setup area. To create a new record and test the approval process. Log in as Bob Smith. 1. if it is not already selected. Select the Warehouse app. While developing the application. 3. 8. for purposes of this tutorial. click Edit next to VolunteerForce Home Page. Log out of the application. Add a New Line Item and enough units sold of the Wee Jet item that you created earlier to make the invoice value greater than $2000. 7. 1. Since you're the manager. and then click Save.) 3.) The record is locked until the manager approves the invoice. Click New and create an invoice statement. Go ahead and Approve it.Tutorial #5: Using Workflow and Approvals 2. 2. is you the administrator. 2. you see the pending approval request on the Home tab. 5. you need to log out of your administrator account and log back in as a standard user. An Approval field allows the manager to approve or reject the invoice and continue the workflow. you can check your email to verify this result. Click Edit next to your home page layout. you can see a nice diagram of the approval process and the actions that will fire at each step.. Click Next. Click the Invoice Statements tab. the user you created earlier. you've been logged in as an administrator. Click View Diagram. Tell Me More.

Tutorial #5: Using Workflow and Approvals

See Also:
Tutorial #5: Using Workflow and Approvals Step 7: Create a User Summary

Summary
Workflow rules and approval processes help you automate your business processes and enforce your standards. The workflow rule automatically updates price and inventory across different objects. The approval process runs whenever a condition is met, and then sends an email alert to the designated recipient. Important: If you're using Free Edition, the remaining tutorials require that you develop in a sandbox. If you're not developing in a sandbox now, follow the instructions in Creating and Logging into a Sandbox on page 104. Your sandbox copy won't duplicate your existing records for you, so after you log in, you need to recreate the Wee Jet record described in Step 5: Create a Merchandise Record on page 12, and the invoice statement described in Step 5: Create an Invoice Record on page 19.

See Also:
Tutorial #5: Using Workflow and Approvals Step 8: Test the Approval Process

50

Tutorial #6: Adding Business Logic with Apex

Tutorial #6: Adding Business Logic with Apex
Level: Advanced; Duration: 20-30 minutes

Apex is a strongly-typed, object-oriented, Java™-like programming language that runs on Force.com. Apex is used to add programmatic business logic to applications. For example you can use it to write triggers, Web services, and program controllers in your app's user interface layer. You've already added business logic using the declarative workflow environment. In this tutorial you'll create additional logic using Apex, which is ideal for juggling multiple records and complex logic. The business case you'll be working on requires that when a price for a piece of merchandise goes down, you will pass the savings along to your customers. To do this, you'll create an Apex trigger that updates all open invoices whenever the merchandise price decreases. A trigger is a set of code that fires at a particular time in the lifecycle of a record. In this case, you will create a trigger that fires after a merchandise record is updated. There are two ways to develop applications on Force.com: you can either use the online environment, as you've been doing up to this point, or use the Force.com IDE. If you don't have the IDE installed, it will take a moment to set up. However, if you are already familiar with the IDE, you know that it has syntax highlighting, code insight, and many other features that make development—especially team development—highly productive. Note: If you're using Free Edition, all development must be done in your sandbox. If you have not created a sandbox yet, see Creating and Logging into a Sandbox on page 104.

Prerequisites
Basic Knowledge For this tutorial, it helps to have basic knowledge of an object-oriented programming language like Java or C#, but it is not required. This tutorial can also be completed in the Force.com IDE, so familiarity with Eclipse is useful but not necessary. Software Requirements You can use the Force.com IDE for this tutorial if you want to. In that case you'll need Eclipse 3.3 or 3.4 and the Force.com IDE plugin: wiki.developerforce.com/index.php/Force.com_IDE. If you need help creating a project, see Creating a Project in the Force.com IDE on page 104.

51

Tutorial #6: Adding Business Logic with Apex

“Developer Mode,” “Modify All Data,” and “Author Apex” permissions Since this tutorial involves working with Apex, make sure that you have the proper permissions to create Apex classes.

See Also:
Step 1: Create an Apex Trigger Definition Step 2: Define a List Variable Step 3: Iterate Through the List and Modify Price Step 4: Test the Trigger Summary

Step 1: Create an Apex Trigger Definition
The first thing you need to do is create the trigger definition, which contains the trigger name, the affected object, and an action that fires the trigger. You can create triggers in the Web interface or in the Force.com IDE. Instructions are provided for both tools. To create a trigger in the Web interface: 1. 2. 3. 4. Click Your Name ➤ Setup ➤ Create ➤ Objects in the sidebar menu. Click your Merchandise custom object. On the Merchandise detail page, scroll down to Triggers and click New. Replace <name> and <events> so that the code matches the following:
trigger HandleProductPriceChange on Merchandise__c (after update) { }

5. If you're using the Web interface, click Quick Save, which will save your work and let you continue editing. Saving your work at this point also verifies that you've entered the code correctly, because if you've made syntax errors, the system won't let you save. To create the trigger in the Force.com IDE: 1. In the Package Explorer, right-click your project and click New ➤ Apex Trigger. 2. In the dialog box, enter HandleProductPriceChange for the name. 3. In the Object drop-down list, choose Merchandise__c. Note: If this object doesn't appear in the list of object, click Refresh Objects. (Ignore the warning that pops up about how you must select an operation.) 4. Select after update.

52

Between the square brackets. so there are often line breaks where they aren't strictly needed. so you'll select only those that are in the set of records that triggered this code to run and have their status set to Negotiating. for example. so if you like to use lowercase.. updates and deletes—either before or after one of these events. on Merchandise__c—The object the trigger acts on— in this case. we won't comment everything here. but it's now ready to accept any logic that you want to execute when a Merchandise record is updated.. You'll code the trigger body next.Tutorial #6: Adding Business Logic with Apex 5. Apex ignores white spaces. The trigger you defined fires after a record is updated. See Also: Tutorial #6: Adding Business Logic with Apex Step 2: Define a List Variable Step 2: Define a List Variable The first thing you need to do is define a list variable that will hold a list of line items. you can enter select instead of SELECT. your Merchandise__c custom object.Status__c = 'Negotiating' AND j.Merchandise__r. but its good practice to comment your code. Apex isn't case sensitive. You don't need all the line items. that's OK. 53 .Merchandise__r. Note: For the sake of brevity.Price__c FROM Line_Item__c j WHERE j. 2. Also. j. Note: We try to make our code samples fit on the page.. let's break up the trigger definition and examine each part.Unit_Price__c. Tell Me More. (after update)—The action that fires the trigger. Your trigger doesn't do anything yet. Between the curly braces of your trigger definition. Click Finish and the file opens in the Editor. • • • • HandleProductPriceChange—The name of the trigger.id IN :Trigger. Before we get to the trigger logic. 1. List<Line_Item__c> openLineItems = [SELECT j. such as inserts. so if the format of your code doesn't look exactly the same. Apex triggers are fired in response to data actions.new FOR UPDATE]. // update invoice line items associated with open invoices List<Line_Item__c> openLineItems = [ ]. enter the following comment and then declare a list variable. enter a query that pulls information from your Line Item custom object.Invoice_Statement__r. { }—The code that goes between the curly brackets is called the body and determines what the trigger does.

Between the for loop's curly braces. } } 4... Declare a for loop. enter code that updates the price. See Also: Tutorial #6: Adding Business Logic with Apex Step 1: Create an Apex Trigger Definition Step 3: Iterate Through the List and Modify Price Step 3: Iterate Through the List and Modify Price In the previous step. enter a conditional if statement. for (Line_Item__c li: openLineItems) { if ( li. Let's take a look at that query in detail. It pulls only the unique IDs of the records that are new. The “j” in Line_Item__c j is an alias: it is a convenient shorthand that allows you to refer to Line_Item__c as “j”. AND—This is the second condition of your statement. for (Line_Item__c li: openLineItems) { } 2. Now you can iterate through the list using a for loop and modify an item's original price if its new price is lower. for (Line_Item__c li: openLineItems) { if ( li. The code uses a special variable. add the following. What's contained in that list is determined by the query inside the square brackets. In this case you want to return only those records where the status is Negotiating. which is written in the Salesforce Object Query Language (SOQL). The lock remains until the trigger is complete.. FOR UPDATE—This tells the platform to lock the records.Unit_Price__c ){ li.Unit_Price__c = li.Price__c < li.Unit_Price__c ){ } } 3.Merchandise__r. The openLineItems list holds a list of records from your Line_Item__c custom object.Price__c < li. Now you want to update the line items. • • • • • SELECT—Determines which fields are retrieved on the object.new. WHERE—This is the start of the condition statement.Merchandise__r. 54 . Between the curly brackets.Price__c.Tutorial #6: Adding Business Logic with Apex Tell Me More. 1. The for loop is complete. Trigger. FROM—Determines which object or objects you want to access.Merchandise__r. preventing other program or users from making updates to them. which is automatically initialized with the identifiers of the records being updated. you created a list of line items and stored it in a variable called openLineItems. Before the trigger's final curly brace. update openLineItems.

update the unit price on the current line item (assigned to variable li) with the new merchandise price. if (li. select the Is Active checkbox.Invoice_Statement__r.Merchandise__r.. j. update openLineItems.Unit_Price__c = li.Price__c < li. } } update openLineItems.Price__c FROM Line_Item__c j WHERE j.Unit_Price__c ) { }—Check to see if the price on the merchandise record is lower than the current price. That's simple enough. li.Unit_Price__c ){ li. updates the records in the database. See Also: Tutorial #6: Adding Business Logic with Apex Step 2: Define a List Variable Step 4: Test the Trigger Step 4: Test the Trigger Now let's test the trigger in the app. } Tell Me More. you'll need to activate it. As you iterate. First you need to create a new invoice statement and order at least one product.—Finally.Tutorial #6: Adding Business Logic with Apex 5. which becomes available after saving the trigger. • • If you're using the Web interface.Price__c.. 6. If you're using the IDE.Merchandise__r. click the Metadata tab and change the status value to Active. The only requirement is that you change the status field of the invoice statement to Negotiating.Merchandise__r.Merchandise__r.new FOR UPDATE]. You only want to take an action if this is true.Unit_Price__c.Merchandise__r.. To try out the trigger.Status__c = 'Negotiating' AND j. Then you'll 55 .id IN :Trigger. the current line item is assigned to the variable li. or modify an existing one. trigger HandleProductPriceChange on Merchandise__c (after update) { List<Line_Item__c> openLineItems = [SELECT j. for (Line_Item__c li: openLineItems) { if ( li. Verify that your code looks like the following and then Save.Unit_Price__c = li. During development you typically leave a trigger inactive.Merchandise__r. but what about that for loop? • • • for (Line_Item__c li: openLineItems) { }—Iterates over the list of open line item. The final statement.Price__c < li.Price__c.

you may have updated the merchandise record's description. 7.. You can have more than one trigger associated with an object that can be triggered under different events and conditions.new set (the list of Merchandise records that have been updated). See Also: Tutorial #6: Adding Business Logic with Apex Step 4: Test the Trigger 56 . 2. you built on the application by adding business logic that updates all open invoices when the unit price of a merchandise item goes down. creating a new set of these records that pass the price criterion. If you want an extreme reduction. and note its Unit Price. 4. change it to . 8.01. you defined a trigger that executes whenever a merchandise record is saved with a lower unit price. and neither of these cases requires the trigger to fire. 1. Navigate back to the Invoice and the Line Item. Click the Invoice Statements tab. Change its Status to Negotiating and click Save. Edit the record. Click the Merchandise tab.. An important part of creating Apex triggers is making sure you have automated tests that verify that your trigger works as it should. You'll learn about testing in Tutorial #7: Adding Tests to Your Application on page 57. To do this. that doesn't mean your trigger should update the record. 6.. Ideally this trigger should iterate over the Trigger. and only then retrieve the related line item records. For example. Triggers are very useful in scenarios such as these—when you need to update multiple records on a particular condition. and verify that your line item and invoice values are updated. Now click on a Line Item. You may have noticed that this trigger is a little wasteful: it initializes and operates on a list of all line item records that belong to invoice statements under negotiation. just because a merchandise record was updated. 5. Note how the values of the line item and the invoice have automatically changed. 3. Click the name of an existing invoice statement.Tutorial #6: Adding Business Logic with Apex lower the unit price of a merchandise item used in one of the line items of that invoice. Tell Me More. or increased its price. However. and select the Wee Jet record (or any other item used in the line items). Take note of the Total Value of the invoice. See Also: Tutorial #6: Adding Business Logic with Apex Step 3: Iterate Through the List and Modify Price Summary Summary In this tutorial. lowering the unit price.

To facilitate testing. which exercises the Apex trigger you just created. Good tests ensure that your code not only behaves as it should. there is a set limit on the number of queries that can be performed in a trigger. In this step you create the class to contain the unit tests.com_IDE.4 and the Force.com IDE for this tutorial if you want to. but also that it doesn't exceed these limits. to ensure that no backward compatibility problems are introduced.developerforce. the platform requires that you test any Apex you write before that code can be deployed to a production environment. To that end.3 or 3. To create a new Apex class in the Web interface: 57 . Testing ensures that your code behaves as it should and doesn't consume resources unnecessarily.php/Force.com IDE plugin: wiki. see Creating a Project in the Force. Tests are also run before a new release of the platform is made available. If you need help creating a project. See Also: Step 1: Create an Apex Test Class Step 2: Add Test Methods to the Class Step 3: Write Code to Execute the Trigger Step 4: Execute the Test Step 5: View Code Coverage and Improve Tests Summary Step 1: Create an Apex Test Class All unit tests are contained in Apex classes. Duration: 20-30 minutes Testing is one of the most important steps in developing any application.com IDE on page 104. In that case you'll need Eclipse 3.Tutorial #7: Adding Tests to Your Application Tutorial #7: Adding Tests to Your Application Level: Advanced. Software Requirements You can use the Force. For example. but it also benefits the platform. In this tutorial you'll write and execute a unit test. Apex supports unit tests. which programmatically validate the code behavior and expected results. All Apex code has a set of limits that determine how many resources may be consumed. Not only does testing benefit you (you will have more confidence in the applications you write). Prerequisites Apex Tutorial You first need to create an Apex trigger as described in Tutorial #6: Adding Business Logic with Apex on page 51.com/index.

Tell Me More. @isTest private class TestHandleProductPriceChange { } 4. The trigger that you created. 2. In the IDE. 3. which you want to test. So the first thing you need to do is create test records in the database. which creates an invoice statement and inserts it into the database. You want the method to create an Invoice Statement as well as Merchandise and Line Item records. Start by creating the test method that will contain your three test procedures. Between the curly braces. only works when records are updated. 4. enter the following code. enter the following code. choose Test Class. The @isTest annotation tells Force. and add these to the database. Then click New ➤ Apex Class. You will now create test methods within this class that perform the actual tests. 58 . To create a new Apex class in the Force. 3. Click Finish to create the class.. replace the generated comment and code. Click New. static testMethod void testPriceChange() } { Note: If you're using the IDE..com IDE: 1. Click Your Name ➤ Setup ➤ Develop ➤ Apex Classes. add the following code. In the editor pane. Between the curly braces. insert invoice.com that all code within the Apex class is code that tests the rest of your code. Click Quick Save to save your work and continue editing. Invoice_Statement__c invoice = new Invoice_Statement__c(Status__c = 'Negotiating'). See Also: Tutorial #7: Adding Tests to Your Application Step 2: Add Test Methods to the Class Step 2: Add Test Methods to the Class Now you can add a method to the class that will do the actual testing. right-click your project folder. 1. enter TestHandleProductPriceChange for the name. On the Create Apex Class page. 2. In the Template field.Tutorial #7: Adding Tests to Your Application 1. 2..

By marking where your actual test begins and ends. update products.startTest(). After insert lineItems. directly below insert products. Note: This code modifies the price of one of the Merchandise records.id. You'll do that in the next step. Merchandise__c = products[0]. Directly below insert invoice. Total_Inventory__c = 10). Price__c = 10. Line_Item__c[] lineItems = new Line_Item__c[] { new Line_Item__c(Invoice_Statement__c = invoice. Total_Inventory__c = 10) }. add the following lines. 59 . Then. the system won't count your setup code towards the governor limits.id. insert products. The system will not consider the setup code and database operations that precede it to be part of the test. Merchandise__c[] products = new Merchandise__c[]{ new Merchandise__c(Name = 'item 1'.Tutorial #7: Adding Tests to Your Application 3. which is the condition you need for the trigger to fire. It then calls startTest(). ensuring that your test is a more accurate reflection of how it would behave in a production environment. Unit_Price__c = 11. 1. Testing also ensures that your code doesn't exceed certain governor limits—which limits the resources your Apex code may use. Note how the invoice statement that you created has a status set to Negotiating. Test. Price__c = 11. You now need to write the code that will fulfill the other conditions for the trigger to fire: you need to lower the price of a piece of merchandise. You have now set up the data. as that only happens when you update the price of a Merchandise record. which is part of the testing framework that marks the point in your test code when your test actually begins.id.stopTest(). enter the code to add line items. Units_Sold__c = 3). new Merchandise__c(Name = 'item 2'. Unit_Price__c = 10. new Line_Item__c(Invoice_Statement__c = invoice.id. Merchandise__c = products[1]. insert lineItems.. add the code to create new merchandise records. See Also: Tutorial #7: Adding Tests to Your Application Step 1: Create an Apex Test Class Step 3: Write Code to Execute the Trigger Step 3: Write Code to Execute the Trigger The code in your test method doesn't really do much yet: it won't cause your trigger to execute. products[0]. Units_Sold__c = 6) }. raising its price. Description__c = 'test product 2'. 4. Description__c = 'test product 1'.price__c = 20. Test.

because the price was raised in the setup code. lineItems = [SELECT id.stopTest(). You are now going to execute the tests. Test. lineItems = [SELECT id.unit_price__c == 10). insert invoice.com has a testing framework that lets you execute tests.assert(lineItems[0].unit_price__c == 10). Merchandise__c = products[1].assert(lineItems[0]. Units_Sold__c = 6) }. new Line_Item__c(Invoice_Statement__c = invoice. Add the following code after Test.startTest(). insert lineItems.id. Test. system. The remainder of this tutorial uses the Web interface. Description__c = 'test product 2'.id.com ➤ Run Tests. Total_Inventory__c = 10) }.com IDE by right-clicking the class name in the Package Explorer and choosing Force. unit_price__c FROM Line_Item__c WHERE id IN :lineItems]. you need to check whether the price in the line items has changed. update products.Tutorial #7: Adding Tests to Your Application 2. but you can also execute tests in the Force. Ideally.id. Unit_Price__c = 10. unit_price__c FROM Line_Item__c WHERE id IN :lineItems]. insert products. Unit_Price__c = 11. system. Note: These steps show how to execute steps in the Web interface. Price__c = 11. Total_Inventory__c = 10). Line_Item__c[] lineItems = new Line_Item__c[] { new Line_Item__c(Invoice_Statement__c = invoice. Merchandise__c = products[0].stopTest().price__c = 20. 3. new Merchandise__c(Name = 'item 2'. Price__c = 10. and look at the resulting code coverage. Verify that your code looks like the following and then Save.id. and also check code coverage. Description__c = 'test product 1'. Now that you have updated the products. Units_Sold__c = 3). products[0]. but you should be able to follow along easily in the IDE. it shouldn't have. 60 . } } See Also: Tutorial #7: Adding Tests to Your Application Step 2: Add Test Methods to the Class Step 4: Execute the Test Step 4: Execute the Test Force. Merchandise__c[] products = new Merchandise__c[]{ new Merchandise__c(Name = 'item 1'. @isTest private class TestHandleProductPriceChange { static testMethod void testPriceChange() { Invoice_Statement__c invoice = new Invoice_Statement__c (Status__c = 'Negotiating').

Tutorial #7: Adding Tests to Your Application 1. By looking through the Debug Log. for example. Click Run Test and you'll see output similar to the following. and you have your code in the test class. that result would be flagged here. • It indicates whether your tests were successful or not. It indicates code coverage: how many lines of code you executed in some other class or trigger. and more. The term code coverage refers to how much of your production code is covered by testing code. In the next step. which we'll call test code. That's enough code coverage to deploy. You have your trigger. Navigate to your test class by clicking Your Name ➤ Setup ➤ Develop ➤ Apex Classes. If the boolean condition in the system. Adding lots of asserts is a great way for you to test the expected behavior of your code. and then click your test class. does it execute all. but we strive for perfection. It provides detail about the execution of the test. you can see that your Order_in_Stock validation rule has fired. In other words: when someone runs your testing code. which we'll call production code. And you can see which records you created. the production code? If it 61 .assert statement that you added to the test had failed. you'll view the code coverage to see where you need to add more test cases to bring it up to 100%. • • Note also how the result page shows that you provided 80% coverage of the HandleProductPriceChange trigger. 2. how many queries you executed. TestHandleProductsPriceChange. See Also: Tutorial #7: Adding Tests to Your Application Step 3: Write Code to Execute the Trigger Step 5: View Code Coverage and Improve Tests Step 5: View Code Coverage and Improve Tests You have written two sets of code. or only some portion of. This result tells you a number of important things.

we only raise it. Note: If you have been using the Force.price__c = 5. Starting with products[0]. click 80. 4. You can make these concepts a little more concrete by looking at a graphical code coverage chart. System. replace the code up to the next curly brace with the following. Click Save. 3.stopTest(). line 13 wasn't executed because we don't lower the price of a merchandise item. Close the Code Coverage window and then click Your Name ➤ Setup ➤ Develop ➤ Apex Classes and select your test class TestHandleProductPriceChange.unit_price__c == 10).Tutorial #7: Adding Tests to Your Application only executes a portion of the code. 7. Synchronizing is easy (right-click your class and choose Force. 5.unit_price__c == 5). products[0]. // unchanged System. but it's even easier to avoid! 1. and you'll see that you have 100% code coverage.com IDE for this tutorial. // lower price Test. The red highlight marks lines that have not been executed. Now click Run Test again.assert(lineItems[0].assert(lineItems[1].price__c = 20. 2. // raise price products[1]. That red line is good indicator that your test isn't complete. Developing in both the IDE and the Web interface at the same time requires that you synchronize with the server every time you switch back and forth. The blue highlight marks lines of code that have been covered (executed) as a result of our test method. The Code Coverage page opens. In this case. In the Code Coverage section. update products. So let's modify your test method to improve your code coverage. Click Edit. // changed!! 6. keep using it.startTest(). unit_price__c FROM Line_Item__c WHERE id IN :lineItems]. Test. 62 .com ➤ Synchronize with Server). that could mean your production code contain bugs in the untested code. lineItems = [SELECT id.

and the test case you have just written misses one. ideally you should also check all possible scenarios. Right now it only checks invoice statements that have a status of Negotiating.Tutorial #7: Adding Tests to Your Application See Also: Tutorial #7: Adding Tests to Your Application Step 4: Execute the Test Summary Summary In this tutorial you created tests for the Apex trigger and saw how the integrated testing tools can help you attain 100% code coverage. then raising or lowering the price shouldn't have any effect. See Also: Tutorial #7: Adding Tests to Your Application Step 5: View Code Coverage and Improve Tests 63 . Creating unit tests as you develop is necessary for deployment and it's also the key to successful long-term development. if an invoice statement does not have a status of Negotiating. For example. It should also check other status values. But it's important to note that code coverage isn't the only goal for testing.

Tutorial #8: Building a Custom User Interface Using Visualforce

Tutorial #8: Building a Custom User Interface Using Visualforce
Level: Intermediate; Duration: 30–45 minutes

Visualforce is a component-based user interface framework for the Force.com platform. In previous tutorials you built and extended your application by using a user interface that is automatically generated. Visualforce gives you a lot more control over the user interface by providing a view framework that includes a tag-based markup language similar to HTML, a library of reusable components that can be extended, and an Apex-based controller model. Visualforce supports the Model-View-Controller (MVC) style of user interface design, and is highly flexible. In this tutorial, you will use Visualforce to create a new interface for the Warehouse application that displays an inventory count sheet that lets you list all Merchandise inventory, as well as update the counts on each. The purpose of the count sheet is to update the computer system with a physical count of the merchandise, in case they are different.

Prerequisites
Basic Knowledge For this tutorial, it helps to have basic knowledge of markup languages like HTML and XML, but it is not required.

See Also:
Step 1: Enable Visualforce Development Mode Step 2: Create a Visualforce Page Step 3: Add a Stylesheet Static Resource Step 4: Add a Controller to the Page Step 5: Display the Inventory Count Sheet as a Visualforce Page Summary

Step 1: Enable Visualforce Development Mode
Development Mode embeds a Visualforce page editor in your browser. It allows you to see code and preview the page at the same time. Development Mode also adds an Apex editor for editing controllers and extensions. 1. Click Your Name ➤ Setup ➤ My Personal Information ➤ Personal Information. 2. Click Edit. 3. Select the Development Mode checkbox and click Save.

64

Tutorial #8: Building a Custom User Interface Using Visualforce

See Also:
Tutorial #8: Building a Custom User Interface Using Visualforce Step 2: Create a Visualforce Page

Step 2: Create a Visualforce Page
In this step you create a Visualforce page that will serve as an inventory count sheet. 1. In your browser, add the text /apex/CountSheet to the URL for your Salesforce instance. For example, if your Salesforce instance is https://na1.salesforce.com, the new URL would be https://na1.salesforce.com/apex/CountSheet. You will get an error message: Page CountSheet does not exist.

2. Click the Create Page CountSheet link to create the new page. 3. Click the Page Editor link in the bottom left corner of the page. The Page Editor tab displays the code and a preview of the new page (which has some default text). It should look like this.

65

Tutorial #8: Building a Custom User Interface Using Visualforce

4. You don't really want the heading of the page to say “Congratulations”, so change the contents of the <h1> tag to Inventory Count Sheet, and go ahead and remove the comments. The code for the page should now look like this.
<apex:page> <h1>Inventory Count Sheet</h1> </apex:page>

5. Click the Save icon at the top of the Page Editor. The page reloads to reflect your changes.

Tell Me More....
Notice that the code for the page looks a lot like standard HTML. That's because a Visualforce page combines HTML tags, such as <h1>, with Visualforce-specific tags, which start with <apex:>

See Also:
Tutorial #8: Building a Custom User Interface Using Visualforce Step 1: Enable Visualforce Development Mode Step 3: Add a Stylesheet Static Resource

Step 3: Add a Stylesheet Static Resource
You want your Warehouse application to look slick, so you're going to use a custom stylesheet (CSS file) to specify the color, font, and arrangement of text on your page. Most Web pages and Web designers use CSS, a standard Web technology, for this purpose, so we've created one for you. In order for your pages to reference a stylesheet, you have to upload it as a static resource. A static resource is a file or collection of files that is stored on Force.com. Once your stylesheet is added as a static resource, it can be referenced by any of your Visualforce pages. To add a style sheet as a static resource: 1. 2. 3. 4. 5. In your browser, go to developer.force.com/workbook/styles. Download the file and save it to your desktop. Back in the app, click Your Name ➤ Setup ➤ Develop ➤ Static Resources and click New. In the Name field, enter styles. Click Browse and find the styles.zip file you downloaded. In the Cache Control picklist choose Public.

66

Now you need to modify your Visualforce page to reference the stylesheet. <apex:page standardStylesheets="false" showHeader="false" sidebar="false"> 3. Now specify the location of the stylesheet as shown. Just as you did when you created the page. Now you need to tell the page where to find the stylesheet. Click Save.Tutorial #8: Building a Custom User Interface Using Visualforce 6.css')}" /> 6.styles. Start typing stylesheet and when you see apex:stylesheet. The editor has code insight.styles. 'styles. <apex:stylesheet value="{!URLFOR($Resource. 2. Note: If your Visualforce pages are exposed on a public website.com uses a global content delivery network of cache servers to hold copies of your static files. Click the Save icon at the top of the Page Editor. which gives you a drop-down list of the elements that are available in this context. 5. then Force.css')}" /> <h1>Inventory Count Sheet</h1> </apex:page> 7. Modify the attributes of the <apex:page> tag and enter the following code to remove the standard stylesheet. 67 . 1. add the text /apex/CountSheet to the URL for your Salesforce instance. so add a new line below the first <apex:page> tag and type <apex: 4. the header. select it. 'styles. and the sidebar. Verify that your code looks like the following: <apex:page standardStylesheets="false" showHeader="false" sidebar="false"> <apex:stylesheet value="{!URLFOR($Resource.

However. and a file within that resource. Click the Save icon at the top of the Page Editor. • • $Resources is a global variable which Visualforce has access to. <apex:page standardStylesheets="false" showHeader="false" sidebar="false" standardController="Merchandise__c"> 3. You can extend the standard controllers to add new functionality. See Also: Tutorial #8: Building a Custom User Interface Using Visualforce Step 2: Create a Visualforce Page Step 4: Add a Controller to the Page Step 4: Add a Controller to the Page Visualforce's Model-View-Controller design pattern makes it easy to separate the view and its styling from the underlying database and logic. because you've indicated that the page should use a controller... Next. add the standard list controller definition. and the standard header and sidebar are no longer present. the view (the Visualforce page) interacts with a controller. Tell Me More. click Page Editor to edit the page. With $Resource. For example. If the Page Editor isn't open on your Visualforce page. You won't notice any change on the page. In this tutorial you'll use the default controller. The editor ignores whitespace. it's because you've already encountered it to dynamically evaluate values when the Visualforce page is rendered. the controller may contain the logic that should be executed when a button is clicked. All Force. so in many cases you don't need to write the code for the controller yourself. <apex:page standardStylesheets="false" showHeader="false" sidebar="false" standardController="Merchandise__c" recordSetVar="products"> 4. you refer to the resource called "styles" which you created earlier. which exposes some functionality to the page.Tutorial #8: Building a Custom User Interface Using Visualforce Note how the page now looks very different.com objects have default standard controllers that can be used to interact with the data associated with the object. A controller also typically interacts with the model (the database)—exposing data that the view might want to display.. so you can enter the text on a new line. or create custom controllers from scratch. In our case. Let's take a look at that stylesheet code in a little more detail. Modify your code to enable the Merchandise__c standard controller by editing the first <apex:page> tag. and defined the variable products. 68 . The URLFOR() function locates the static resource. 2. In MVC. the variable will be available to you in the body of the page and it will represent a list of Merchandise records. the controller is usually an Apex class. 1. the title is in a different font and location. and calculates the URL that should be generated in your final page. If the syntax looks familiar.styles.

69 . The var attribute assigns each item of that list.The value attribute indicates which list of items the dataTable component should iterate over. and you will see your table appear. Its value. for one single iteration. and determine where it gets its data by looking up the appropriate field in the pitem variable. Start by typing <apex:d and press Enter to select dataTable from the drop-down list. <apex:dataTable value="{!products}" var="pitem" rowClasses="odd. 4. will ensure that a new variable. It will display a table of all the merchandise records. and highlight <apex:form> when it appears in the drop-down list. <apex:dataTable value="{!products}" var="pitem" rowClasses="odd. 2. which provides additional controller support for listing a number of records with pagination. The headerValue attribute has simply provided a header title for the column. together with an input field on each so that you can update the inventory count. Add the following code between the opening and closing dataTable tags. The rowClasses attribute assigns CSS styling names to alternate rows.name} indicates that we want to display the name field of the current row. start typing <apex:f on a new line. On one or more lines within the tag. to the pitem variable. enter the following. The recordSetVar attribute enables a standard list controller. The form will allow you to make updates to the page.. Click Save. 3..Tutorial #8: Building a Custom User Interface Using Visualforce Tell Me More. Now you need to add some attributes to the dataTable tag. and below it you'll see a list of rows: one for each merchandise record. will contain the set of records to be displayed on the Visualforce page. which you've set to products. In the line below the </h1> tag. Press Enter and notice that the system generates the opening and closing tags for you.name}"/> </apex:column> </apex:dataTable> 6.even"> <apex:column headerValue="Product"> <apex:outputText value="{!pitem.even"> 5. 1. Now you are going to define each column. The expression {!pitem. Place your cursor between the tags and create a data table. products. See Also: Tutorial #8: Building a Custom User Interface Using Visualforce Step 3: Add a Stylesheet Static Resource Step 5: Display the Inventory Count Sheet as a Visualforce Page Step 5: Display the Inventory Count Sheet as a Visualforce Page You now have all the functionality in place to flesh out the Visualforce page..

and the recordSetVar to products. add two more columns. That statement var="pitem" assigns a variable called pitem that holds the current row. you're updating the physical count of the product and performing a quick save. not an outputField. As a result. which updates the values on the records. displays the current inventory. and invokes a method called quicksave on the standard controller.. It's this list that the dataTable component uses. but it will also allow you to change it.Total_Inventory__c}"/> </apex:column> <apex:column headerValue="Physical Count"> <apex:inputField value="{!pitem. The standard controller you used for this page was set to Merchandise__c.. • • • 70 . • The dataTable component produces a table with rows.Total_Inventory__c}"/> </apex:column> Note: The second column is an inputField.. and each row is found by iterating over a list. Click Save and you have an inventory count sheet! It lists all the merchandise records. The commandButton component displays the button. The inputField will display a value. To do this. Now. which updates the product with the new count. As a final embellishment. and provides an input field for the physical count. <apex:column headerValue="Inventory"> <apex:outputField value="{!pitem. <br/> <apex:commandButton action="{!quicksave}" value="Update Counts" /> Tell Me More. after the closing tag for the first column. 8.Tutorial #8: Building a Custom User Interface Using Visualforce 7. the controller automatically populated the products list variable with merchandise records retrieved from the database. You need a way to reference the current row as you iterate over the list. Here.com objects. The rowClasses and styleClass attributes simply use some of the styles from the CSS style sheet that you loaded in the static resource. You can safely remove this–it will just make things look less pretty! Every standard controller has various methods that exist for all Force. 9. enter the following code directly above the </apex:form> line. add a button that will modify the physical count on any row and refresh the values on the page.

See Also: Tutorial #8: Building a Custom User Interface Using Visualforce Step 5: Display the Inventory Count Sheet as a Visualforce Page 71 . You'll find out about that in the Tutorial #9: Creating a Public Web Page Using Sites tutorial. Now that you have created some Visualforce components. <apex:commandLink action="{!next}" value="Next" rendered="{!hasNext}" /> See Also: Tutorial #8: Building a Custom User Interface Using Visualforce Step 4: Add a Controller to the Page Summary Summary Congratulations! You have created a new interface for your Warehouse application by creating a Visualforce page that uses a standard controller. It also provides a way of saving records. you can expose this functionality on a public website. The page also makes use of a lot of functionality provided by the standard controller behind the scenes. For example. the functionality is there. the controller automatically queries the database and finds all merchandise records and assigns them to the products variable. through its quicksave method. Your page is highly configurable. add the following code below the commandButton for page-flipping action. you can easily modify which data is displayed in each row by modifying the column components. For example. If you have enough records to page through them.Tutorial #8: Building a Custom User Interface Using Visualforce • Although pagination isn't shown in this example.

2. If you're still in the Visualforce editor. Click Clone. You can also enable users to register for. Duration: 20-30 minutes The application you just created requires that you log in use it. Select the CountSheet page you created earlier. you will create a Visualforce page. or log into. Prerequisites Visualforce Tutorial You first need to create the Visualforce page.com servers. Click Your Name ➤ Setup ➤ Develop ➤ Pages. 1. you clone the inventory count page you created earlier.com supports your application in a multi-user environment. data validation on collected information is performed automatically. enable Sites for your organization. The new Product Catalog page will show description and price instead of inventory and count. Sites enables you to create public websites and applications that are directly integrated with your organization—without requiring users to log in with a username and password. In this tutorial. and expose the Visualforce page you created as a public product catalog on the Web. an associated portal seamlessly from your public site. as described in Tutorial #8: Building a Custom User Interface Using Visualforce on page 64. See Also: Step 1: Create a Product Catalog Page Step 2: Register a Force. While Force.com Site Step 4: Configure and Test the Site Summary Step 1: Create a Product Catalog Page In this step.Tutorial #9: Creating a Public Web Page Using Sites Tutorial #9: Creating a Public Web Page Using Sites Level: Intermediate.com domain name. You can publicly expose any information stored in your organization through a branded URL of your choice. register your Force. 72 . sometimes you need to eliminate the login—for example on a public website. 3.com Domain Name Step 3: Create a Force. you click Back in your browser until you see the Setup area. Because sites are hosted on Force. You can also make the site's pages match the look and feel of your company's brand. there are no data integration issues. And because sites are built on native pages.

There are a few important things to note here. By simply changing a couple of values in a table.Description__c}"/> </apex:column> <apex:column headerValue="Price"> <apex:outputField value="{!pitem. 6.com platform can be cloned. 10.even"> <apex:column headerValue="Product"> <apex:outputText value="{!pitem. Verify that your code looks like the following and then click Save. Now you'll make a similar change on the next column to display the price. and as you just saw.name}"/> </apex:column> <apex:column headerValue="Description"> <apex:outputField value="{!pitem. • • Lots of components on the Force. The standard controllers for the Visualforce page make all your data readily accessible. it's easy to clone a Visualforce page. 5. Change Inventory to Description and change Total_Inventory__c to Description__c.styles. The code should look like the following. In the Page Editor. Change Physical Count to Price... change the contents of the <h1> tag to Merchandise Catalog.Price__c}"/> </apex:column> 9.Total_Inventory__c}"/> </apex:column> 7. On the Page Editor tab. but changing the table heading and the data within. find the following lines. Then change inputfield to outputfield. You're keeping the same table. <apex:column headerValue="Description"> <apex:outputField value="{!pitem. remove the opening and closing <apex:form> and <apex:commandButton> tags..Description__c}"/> </apex:column> 8.Tutorial #9: Creating a Public Web Page Using Sites 4. Finally. <apex:page standardStylesheets="false" showHeader="false" sidebar="false" standardController="Merchandise__c" recordSetVar="products" > <apex:stylesheet value="{!URLFOR($Resource. you can display data from different fields. as shown. <apex:column headerValue="Price"> <apex:outputField value="{!pitem.Price__c}"/> </apex:column> </apex:dataTable> </apex:page> Tell Me More. 73 . because you don't want to accept input on this page. 'styles. <apex:column headerValue="Inventory"> <apex:outputField value="{!pitem. change the Label and Name fields to Catalog. Then change Total_Inventory__c to Price __c. In the editor.css')}"/> <h1>Merchandise Catalog</h1> <apex:dataTable value="{!products}" var="pitem" rowClasses="odd.

force. and not contain two consecutive underscores. you are prompted to change it. register your company's Force.com domain. Salesforce. not include spaces. 3. but you can also extend the controller to create custom functionality.com. See Also: Tutorial #9: Creating a Public Web Page Using Sites Step 2: Register a Force. Free Edition domain names are assigned automatically and can't be updated. such as mycompany. 2. See Also: Tutorial #9: Creating a Public Web Page Using Sites Step 1: Create a Product Catalog Page Step 3: Create a Force.Tutorial #9: Creating a Public Web Page Using Sites • Did you notice how easy it was to change an input field to an output field? The Visualforce standard controller is powerful indeed.com domain.com domain name after you have registered it. which hosts your site.com.com domain by doing the following. if you choose “mycompany” as your domain prefix. It may take up to 48 hours for your registration to take effect. 5. not end with an underscore. Click Your Name ➤ Setup ➤ Develop ➤ Sites. your domain name would be http://www.com Domain. Click Register My Force. and even create your own controller from scratch.com Domain Name Your unique Force.mycompany. Congratulations! You are now ready to create your first Force.com Site 74 . and must be unique in your organization. After you accept the Terms of Use and register your Force.com site. the changes related to site creation are tracked in your organization's Setup Audit Trail and the Site History related list. Enter a unique name for your Force. is constructed from the unique domain prefix that you register. 4. If it is not unique.com recommends using your company's name or a variation. plus force. Create a custom Web address if you want to use a custom domain name. Caution: You cannot modify your Force. 1.com domain. For example. Click Check Availability to confirm that the domain name you entered is unique. It must begin with a letter. To get started. Read and accept the Sites Terms of Use by selecting the checkbox.com Domain Name Step 2: Register a Force. This name can contain only underscores and alphanumeric characters.

Select the Active checkbox. and then visit your new site. Go to the Sites list by clicking Your Name ➤ Setup ➤ Develop ➤ Sites.com Domain Name Step 4: Configure and Test the Site Step 4: Configure and Test the Site Now that you've created your site. See Also: Tutorial #9: Creating a Public Web Page Using Sites Step 2: Register a Force. unless you explicitly enable it. 4. and established a default page. b. fill in the site details: a. In this step you will toggle this security setting for the Merchandise object. Click Save.com Site Now that you have registered your domain. 3. In the Active Site Home Page field enter Catalog. One of the controls ensures that data isn't displayed. The platform has a number of conservative controls in place for data security. 1. you can make the Merchandise Catalog Visualforce page you created the home page for your new site. The Site Edit page appears. you're almost ready to try it out. In the Site Label and Site Name fields enter Catalog. c. On the Site Edit page. even on public pages. 75 . Click New. 2. 1. Go to the Sites page by clicking Your Name ➤ Setup ➤ Develop ➤ Sites.Tutorial #9: Creating a Public Web Page Using Sites Step 3: Create a Force.

4.com keeps track of the number of page views a Developer Edition site and imposes a daily bandwidth limit on the site. Now go back to your website and refresh your browser and you should see your page. For example. • 76 . Force. you'll see a large Authorization Required page. Note: If you still have an authorization required message. Click Save. Click the Site Label link.. and made it the home page for that site. 3. This is because the anonymous website viewer hasn't yet been granted permission to view the data that the page is displaying.. Scroll down to the Custom Object Permissions section and select the Read permission for the Merchandise object. click Edit. Click the Site URL link for the Product Catalog site.na1.Tutorial #9: Creating a Public Web Page Using Sites 2.force. 5. you probably didn't set your Active Site Home Page to Catalog in the previous step. Go back to the setup page. You can go ahead and create additional Visualforce pages and assign them to the site as well. Let's fix this. you will be able to access it with a URL something like http://workbook-developer-edition. This action opens either a new tab or a new window (depending on your browser). it should be called Catalog. 6. 7. if you add a page Meme to the site. instead of seeing your Merchandise Catalog page.. • You've assigned a single Visualforce page to the site. Tell Me More. However. Click Public Access Settings and then in the Profile Detail section.com/Meme (depending on your domain name of course).

you cloned a Visualforce page and then enabled your Developer Edition organization for Sites functionality. and tested the site to see that it works. To create the site. the next logical step is to provide a way for people to order merchandise. registered the page as your home page. <apex:page cache="true" expires="600"> See Also: Tutorial #9: Creating a Public Web Page Using Sites Step 3: Create a Force. Then you registered a unique Force.com domain name. Now that you have a site with a product catalog.com Site Summary Summary Congratulations. tweaked the security.Tutorial #9: Creating a Public Web Page Using Sites • Sites sites lets you make use of a global content delivery network for fast access and caching of your site pages on production environments. you have created a public website! Anyone in the world can access the site you just created and look at your home page. You simply need to modify the page component to include a cache instruction. all without having to log in. See Also: Tutorial #9: Creating a Public Web Page Using Sites Step 4: Configure and Test the Site 77 . You'll do that next in the tutorial Tutorial #10: Creating a Store Front on page 78.

com IDE on page 104. Duration: 30 minutes Apex is an object-oriented programming language. discover more Apex syntax.com IDE for this tutorial if you want to. see Creating a Project in the Force. which executes when products have been selected.” “Modify All Data. make sure that you have the proper permissions to create Apex classes. and learn how to pass values between a Visualforce page and its controller.Tutorial #10: Creating a Store Front Tutorial #10: Creating a Store Front Level: Intermediate. create Web services. Prerequisites Warehouse App You first need to create the basic Warehouse application and add relationships. “Developer Mode. which will use a controller you write in Apex. 78 . If you need help creating a project. and contain code that will be executed in response to page actions. See Also: Step 1: Create a Controller Step 2: Add Methods to the Controller Step 3: Create the Store Front Step 4: Bonus Step—Updating the Page with AJAX Summary Step 1: Create a Controller Instead of using the default controller. send email.4 and the Force. and shop(). you're now going to write the controller code yourself. and much more.” and “Author Apex” permissions Since this tutorial involves working with Apex.php/Force. you'll create an Apex class. as described in Tutorial #2: Adding Relationships on page 14. In that case you'll need Eclipse 3. Using Apex. In this tutorial you are going to create a simple Visualforce store front page. Controllers typically retrieve the data to be displayed in a Visualforce page. Your rudimentary store front will have two methods: getProducts().com IDE plugin: wiki.3 or 3. such as a command button being clicked. Along the way. which returns the products your store front will display.com/index. make calls to the database.developerforce.com_IDE. Software Requirements You can use the Force. as you did in the previous tutorial. you can create classes and methods.

so that the end user can select how many of each item they wish to purchase. public DisplayMerchandise[] getProducts() { if (products == null) { 79 . specify StoreFront for the name. so you'll add those in the next step. set. together with a count. You now have a rudimentary class for your controller. } public Decimal count { get. set. 3. and a new inner class called DisplayMerchandise to hold the data. public PageReference shop() { return null. } } 3. 2. Click Finish.Tutorial #10: Creating a Store Front To create the class in the Web interface: 1. } 2. You also want the shop to display merchandise items. DisplayMerchandise[] products. but you'll need it as a placeholder for the action that occurs when someone clicks the Shop button. Add the following code as the definition of the class and then click Quick Save.merchandise = item. define a field to hold a list of DisplayMerchandise. Within the current class (on the next line). right-click your project folder and select New ➤ Apex Class. Click Your Name ➤ Setup ➤ Develop ➤ Apex Classes. See Also: Tutorial #10: Creating a Store Front Step 2: Add Methods to the Controller Step 2: Add Methods to the Controller In the last step you created a custom controller. In the IDE. Now you'll add methods to it. public class DisplayMerchandise { public Merchandise__c merchandise { get. which is going to initialize the products. It's not going to do anything yet.com IDE: 1. } public DisplayMerchandise(Merchandise__c item) { this. 2. define the method getProducts(). On the next line. Add the following code to the class (just after the public class StoreFront { line). You'll start by adding the shop() method. 1. Click New. It has no methods or fields. On the Create Apex Class page. 3. public class StoreFront { } To create the class in the Force.

set. } } public DisplayMerchandise[] getProducts() { if (products == null) { products = new DisplayMerchandise[]{}. It uses standard Apex classes and methods to access the database.merchandise = item. description__c. } public Decimal count { get.. adding them to a list of DisplayMerchandise products. It then iterates over the records returned by the query. } } return products. description__c. The DisplayMerchandise class “wraps” the Merchandise type that you already have in the database. name. } } You have now finished defining a simple controller. } } return products. price__c FROM Merchandise__c WHERE Total_Inventory__c > 0]) { products. } 4.add(new DisplayMerchandise(item)). Verify that your code looks like the following and then click Save. public class StoreFront { public PageReference shop() { return null. which is then returned. adding a new decimal field. Tell Me More. } public DisplayMerchandise(Merchandise__c item) { this.add(new DisplayMerchandise(item)). name. also called a SOQL query) returning all Merchandise records that have a positive total inventory. The getProducts() method executes a query (the text within square brackets. set. public class DisplayMerchandise { public Merchandise__c merchandise { get.Tutorial #10: Creating a Store Front products = new DisplayMerchandise[]{}. The constructor lets you create a new DisplayMerchandise instance by passing in an existing Merchandise record. } DisplayMerchandise[] products. The instance variable products is defined as a list of DisplayMerchandise instances. price__c FROM Merchandise__c WHERE Total_Inventory__c > 0]) { products. for (Merchandise__c item : [SELECT id... See Also: Tutorial #10: Creating a Store Front Step 1: Create a Controller Step 3: Create the Store Front 80 . for (Merchandise__c item : [SELECT id.

4. Enter this code on the next line. 2. You are now ready to insert the contents of the form between the opening and closing form tags. <apex:page standardStylesheets="false" showHeader="false" sidebar="false" controller="StoreFront" > <apex:stylesheet value="{!URLFOR($Resource. add /apex/StoreFront to the end of your instance.price__c}"/> </apex:column> <apex:column headerValue="#Items"> <apex:inputText value="{!pitem. Click the Page Editor tab at the bottom. between the open and close form tags.count}"/> </apex:column> </apex:dataTable> <br /> <apex:commandButton action="{!shop}" value="Buy" /> 6. Replace the text in the editor with the following.even"> <apex:column headerValue="Product"> <apex:outputText value="{!pitem. 'styles.styles. You'll see the familiar error message.css')}"/> <h1>Store Front</h1> <apex:form> </apex:form> </apex:page> Note: The controller="StoreFront" attribute ensures that the Visualforce page you are creating will use the StoreFront Apex class as its controller.name}"/> </apex:column> <apex:column headerValue="Price"> <apex:outputText value="{!pitem. so let's create that now. <apex:dataTable value="{!products}" var="pitem" rowClasses="odd. For example: https://na1.merchandise.Tutorial #10: Creating a Store Front Step 3: Create the Store Front Your store front uses another Visualforce page for the store front. In the address bar of your browser. and a button to call the shop method. Your Store Front page should look like this. You will create a table that iterates over the products.salesforcecom/apex/StoreFront. 1. Click the Create Page StoreFront link. 81 .merchandise. 5. Click Save. 3.

adding the items to a shopping basket.. • • See Also: Tutorial #10: Creating a Store Front Step 2: Add Methods to the Controller Step 4: Bonus Step—Updating the Page with AJAX Step 4: Bonus Step—Updating the Page with AJAX This step is optional. indicating that the table should iterate over a list called products. {!shop}. where it can be processed.salesforce. Click the Page Editor tab. In a real-world scenario you could imagine emailing the order. It shows you how Visualforce transparently passes data back to your controller. • The value attribute of the dataTable is set to "products". and so on. Each of these will form a new row. 1. for example https://na1. 2. the shop() method that you wrote in the controller has access to the merchandise counts that were entered by the end-user on the Visualforce page. This step shows you how to access that data in the controller.com/apex/StoreFront. 82 . Let's take a look. There's a lot of new stuff here. you will simply display that data in the page again (using a nifty AJAX page update). Because this is an action.Tutorial #10: Creating a Store Front Tell Me More. Because you are using a custom controller. The Visualforce page has an action.. Navigate to your Visualforce page by using its URL. Visualforce automatically looks for a method called getProducts() in your Apex controller. invoking a Web service. and is assigned to the pitem variable in the Visualforce page as the dataTable iterates. a method with the exact same name is used in the Apex controller. For example.. In this step. The getProducts() method in your controller returns an array of DisplayMerchandise objects.

. 4. Click the Controller tab next to the Page Editor tab. public PageReference shop() { message = 'You bought: '. <apex:outputPanel id="msg">{!message}</apex:outputPanel> You just created an output panel identified as msg. Locate the shop() method (lines 4 through 6) and replace it with the following code. change the commandButton tag to include a reRender attribute. Click Create Apex property StoreFront. 5. Tell Me More. It updates the panel identified as "msg" after it calls the shop() method on the controller. Click Save. You'll notice that a text field appears beneath the merchandise list. 4. 2. 3. The Page Editor will figure out that you don't have any method or property called “message” and offer to create it for you. indicating how many products you purchased.count > 0) { message += p. which hasn't been created yet.message. <apex:commandButton action="{!shop}" reRender="msg" value="Buy" /> You have now modified the Visualforce page to use an in-place AJAX update. which displays an item from the controller called "message".count + ') } } return null. Visualforce will automatically ensure that the data you change in the user interface is reflected by the data in the products variable.merchandise..name + ' (' + p. Note: Notice how this code simply utilizes the products variable. } '. for (DisplayMerchandise p: products) { if (p. Add a number to one of the merchandise items. 1.. Modify your page by adding the following code after the </apex:form> line.Tutorial #10: Creating a Store Front 3. and click Buy. 83 . Now test the shopping cart. Click the Save icon. Now modify the shop() method to update the message property displayed in the panel with a list of items that were selected. 6. This simple addition exposes a lot of powerful functionality. Now.

Another thing you might want to do next is to deliver your app. such as arrays. This functionality is extremely powerful. create a username and password. you modified the Visualforce page to use the data passed back to the controller to display a message using an AJAX update. For more information. was accomplished with a simple reRender attribute.com/workbook for the portal tutorial and other new additions to the workbook. See Also: Tutorial #10: Creating a Store Front Step 4: Bonus Step—Updating the Page with AJAX 84 . The next thing you might do is create an authenticated portal. In this tutorial you created an Apex class and used a few of the features of the language. Visit developer. In order to do that. the panel updates without updating the entire screen. without refreshing the entire page. see Delivering Your Application on page 105. by either packaging for distribution or deploying it to a production organization. and purchase merchandise. and querying the database. However. we have included detailed steps on how to create a portal that works with the app you just built. iteration. which typically requires complex JavaScript manipulation. The AJAX effect that does this. If you did the bonus step.Tutorial #10: Creating a Store Front • • As you saw in this step. which is outside the scope of this workbook. you'd need to create a portal. with many of the features typically found in similar languages such as Java. so that people can log into your site. See Also: Tutorial #10: Creating a Store Front Step 3: Create the Store Front Summary Summary Apex is a powerful object-oriented language. and lets you quickly build forms and other complex input pages. When you click the Buy button. Visualforce automatically mirrored the data changes on the form back to the products variable.force.

com Flex Tutorial #11: Creating a Desktop App with Force. and delete Salesforce data via asynchronous requests to the Force. Inventory Tracker will include: • • • • • A login screen that prompts users for their credentials and establishes connectivity with Force.com includes classes that facilitate the development of Flex-based applications for Salesforce. including the detection of Internet connectivity Adobe’s Data Management Services (DMS). prices. Adobe Flash Builder for Force.com Flex to build a basic desktop app called Inventory Tracker. which creates and manages local databases for desktop applications that operate online and offline Data synchronization between Salesforce and desktop applications Generated ActionScript classes that mirror your Salesforce enterprise WSDL and provide access to Salesforce objects MXML components to simplify the implementation of user interfaces that render Salesforce data. The framework provides: • • • • • • Seamless handling of connected and disconnected states for desktop apps. enabling managers to track inventory on tablet PCs while on foot in a warehouse with inconsistent Wi-Fi. These applications create. and popup notifications called toasts An engine and user interface for resolving data conflicts and errors in desktop applications The Force.com Flex is a framework for creating Flex-based desktop and Web applications that leverage Salesforce logic. data.com Flex Level: Advanced. update. and indicates the number of unresolved data conflicts and errors 85 . Force.com—an enhanced version of Adobe's Eclipse-based integrated development environment (IDE) for developing Flex applications.com when online A list of merchandise. This tutorial demonstrates how to use Force.com Flex framework installs as a standalone instance of Adobe® Flash® Builder for Force.com Flex status bars. Duration: 30 minutes Force. including descriptions.Tutorial #11: Creating a Desktop App with Force. The app will provide offline access to merchandise data. and security. and inventory counts for each item Editable details for each item a user selects A conflict resolution interface that lets users easily resolve data conflicts that occur when values in the app violate validation rules or conflict with changes made by other users A status bar that notifies users whether the app is connected to the Internet.com API.

com Flex desktop app up and running.com Flex components and classes The tutorial provides all the code you need to get your first Force.com Flex Project Step 6: Import Your Enterprise WSDL Step 7: Set the Force.com. To develop or use a Force. you must have the Offline User option selected in your Salesforce personal information.com Flex desktop application. See Also: Step 1: Configure Your Salesforce Personal Information Step 2: Create an Offline Briefcase Configuration Step 3: Generate Your Enterprise WSDL Step 4: Install and Launch Force.Tutorial #11: Creating a Desktop App with Force. click Your Name ➤ Setup ➤ Manage Users ➤ Users. 1.com Flex Application Component Attributes Step 8: Create the Inventory Tracker Window Component Step 9: Testing the Inventory Tracker application Summary Step 1: Configure Your Salesforce Personal Information Force.com Flex desktop applications leverage the Connect Offline technology in Force. we'll use standard Adobe MXML components and ActionScript classes alongside Force.com Flex To create the app.com Flex Step 5: Create a Force. In Salesforce. 86 .

Enter a name for your offline briefcase configuration. 5. 1. 4. Select the Active checkbox. 87 . 3. Select the Offline User checkbox. such as Inventory Tracker App Data.com Flex 2. Click New Offline Briefcase Configuration. so create an offline briefcase configuration that includes the Merchandise object.com data specified in the offline briefcase configuration assigned to you in Salesforce. The Inventory Tracker application needs to access merchandise data. click Your Name ➤ Setup ➤ Desktop Administration ➤ Offline Briefcase Configuration. 4. See Also: Tutorial #11: Creating a Desktop App with Force. In Salesforce.com Flex Step 2: Create an Offline Briefcase Configuration Step 2: Create an Offline Briefcase Configuration Your Force.com Flex desktop application accesses only Force. Click Edit next to your name. Click Save.Tutorial #11: Creating a Desktop App with Force. 3. Select your name in the Available Members list and click Add to move it to the Assigned Members list. 2.

com Flex 6. Click Edit in the Data Sets related list. Select Merchandise Name in the Order By picklist. The Offline Briefcase Configuration detail page appears. Select Merchandise and click OK. Click Save. 10. 88 ..Tutorial #11: Creating a Desktop App with Force. Click Add.. 9. 8. 7..

Click Done. which describes your Force. This is typically all that's needed when integrating with another system as it fully describes all the objects and the Web service.com Flex desktop applications and Force. activities. Tell Me More. Force. For example. Enterprise WSDL refers to the Web Services Definition Language. 89 .com Flex Step 1: Configure Your Salesforce Personal Information Step 3: Generate Your Enterprise WSDL Step 3: Generate Your Enterprise WSDL Web services are a common form of integration.com objects.Tutorial #11: Creating a Desktop App with Force. opportunities. leads.com Connect Offline... contacts. See Also: Tutorial #11: Creating a Desktop App with Force.. Offline briefcase configurations are sets of parameters that determine the records available in Force. edit. create. Use Connect Offline to view. automatically. and Force.com Flex 11.com also.com data using the same browser-based interface as the online system but without an Internet connection. while another configuration includes accounts and related opportunities for account executives. one configuration might include leads and opportunities for sales representatives. and custom object records (including relationship groups). You can also add and update products and schedules on opportunities.com provides a robust set of functionality to support both incoming and outgoing Web services calls. Connect Offline is a client application that lets you access a subset of Force. and delete accounts. generates a Web service end point that allows access to the data in your application. You can create multiple briefcase configurations and associate each with different users and profiles to simultaneously suit the needs of various types of offline users.

. Use this type of project to create Force. 2. 1. In your browser.com Flex Project Installing Force. We will import our enterprise WSDL into our development project later to create an ActionScript class for the Merchandise object. Name the file enterprise. Extract the contents of the zip file.com Flex Step 3: Generate Your Enterprise WSDL Step 5: Create a Force.com Flex Project Step 5: Create a Force.com Flex Step 2: Create an Offline Briefcase Configuration Step 4: Install and Launch Force.com Flex desktop applications: • • • • • Data storage and synchronization Online and offline detection Data conflict and error resolution Status bars Toaster alerts 90 . See Also: Tutorial #11: Creating a Desktop App with Force. Force.com objects in your ActionScript code. save a local copy of your current enterprise WSDL. and automatically generate ActionScript classes for every object your enterprise WSDL contains. Adobe's integrated development environment (IDE) based on the Eclipse platform.com Flex development projects. Click Generate Enterprise WSDL.com/flashbuilder.com Flex Step 4: Install and Launch Force. For now.com Flex zip file from developer.. double-click the Adobe Flash Builder shortcut on your desktop. 4.force.wsdl and click Save.com Flex You can import your enterprise WSDL into your Force.Tutorial #11: Creating a Desktop App with Force..com Flex project type in Adobe Flash Builder. 3.com Flex creates a Force.com Flex Download the Force. When the installation is complete. Force. click Your Name ➤ Setup ➤ Develop ➤ API. click File ➤ Save Page As. Use the classes to access Force. and install it as follows: 1. It does not affect other installations of Eclipse that you might have on your machine. Double-click the installer. 3.com Flex applications. 2.com Flex projects are Flex projects with additional ActionScript classes that add the following functionality to Force. In Salesforce.com Flex installs as a standalone version of Adobe Flash Builder. See Also: Tutorial #11: Creating a Desktop App with Force.

Figure 4: Connect to Data/Service Link 5. Force. then click Next. Select the Force. Select the Data/Services tab and click the Connect to Data/Service link. 2. To open a Force.com Flex creates a Fiber model of your enterprise WSDL. select File ➤ New ➤ Project.com Flex project: 1. then click Next. and click Finish. The New Project wizard opens.com Flex Force. 3.com Flex desktop applications projects also have ActionScript classes and MXML components that let you add user interface components with the Salesforce look and feel to your both desktop and Web applications. Select your enterprise WSDL.com Flex Project in the Flash Builder folder and click Next.Tutorial #11: Creating a Desktop App with Force. In Flash Builder. Figure 5: Fiber Model of Your Enterprise WSDL 91 . 4. select Desktop (runs in Adobe AIR). Enter Inventory Tracker as the project name. 6. Select Salesforce.

com Flex Step 6: Import Your Enterprise WSDL Step 6: Import Your Enterprise WSDL As with other Flex projects. See Also: Tutorial #11: Creating a Desktop App with Force.com Flex Step 4: Install and Launch Force. 92 . Select the Data/Services tab and click the Connect to Data/Service link. then click Next. Force. Select your enterprise WSDL. Force.com Flex You are ready to begin coding your application. When you import your WSDL. Force. Select Salesforce.com Flex projects let you import your Salesforce enterprise WSDL as a data service. Figure 6: Connect to Data/Service Link 2.com Flex creates a Fiber model of your enterprise WSDL.com Flex: • • • Generates ActionScript classes for every standard and custom object in your Salesforce WSDL Renders a model of your WSDL that you can visually introspect Provides code hinting and compiler warnings in Adobe Flash Builder based on your WSDL To import your WSDL: 1.Tutorial #11: Creating a Desktop App with Force. 3. then click Next.

com Flex desktop application is contained within an F3DesktopApplication component. Force.salesforce. and handles the initial synchronization of data between Force. 4.com Flex application.com Flex desktop application to Force. set the requiredTypes attribute to Merchandise__c. Open the Main. In the F3DesktopApplication component.com Flex Application Component Attributes Every Force.adobe. 3.com/flex/mx" xmlns:flexforforce="http://flexforforce.com Flex application template you can modify for your Inventory Tracker application.salesforce. Your final code should look like this.INFO}" filters="{['com. In the WindowedApplication component.com.com objects your Force. set the title attribute to Inventory Tracker. This sets the name that appears in the title bar of the application.mxml file located in src ➤ (default package) if it is not already open.*']}"/> <flexforforce:F3DesktopApplication id="app" statusChanged="statusChangedHandler(event)" loginComplete="loginCompleteHandler(event)" loginFailed="loginFailedHandler(event)" sessionExpired="sessionExpiredHandler(event)" 93 .adobe.com Flex Application Component Attributes Step 7: Set the Force. Modify the attributes of the flexforforce:F3DesktopApplication element in this template as follows: 1.adobe.com/flex/spark" xmlns:mx="library://ns.com and the Force. 2.com Flex projects have a default MXML file that contains a Force.The application component connects the Force. <?xml version="1.com Flex Step 5: Create a Force.com/mxml/2009" xmlns:s="library://ns.com Flex Figure 7: Fiber Model of Your Enterprise WSDL See Also: Tutorial #11: Creating a Desktop App with Force.Tutorial #11: Creating a Desktop App with Force. This attribute specifies the Force.com Flex application references.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.com" title="Inventory Tracker" showStatusBar="false"> <fx:Declarations> <s:TraceTarget includeCategory="true" includeLevel="true" includeTime="true" level="{LogEventLevel.com Flex Project Step 7: Set the Force.

The logic for the main functionality of the Inventory Tracker application consists of ActionScript and MXML that utilize two Adobe component sets.com Flex status bar instead. FieldContainer components group data and simplify the process of manipulating several fields in a single operation. You don't need to modify the login UI.com Flex component that renders a status bar at the bottom of the application. The main UI of the Inventory Tracker consists of two parts. The showStatusBar attribute determines whether the application renders the standard Flash Builder status bar and is set to false to allow the application to show the Force.com Flex project. See Also: Tutorial #11: Creating a Desktop App with Force. The main UI for your application. • • • Modify the default code to implement the Inventory Tracker application logic as follows.com Flex components simplify the process of accessing Force. as well as Force. You'll reference the FieldContainer ID later in the code. Remove the Label component. You can click on the record details to edit them.com Flex Step 6: Import Your Enterprise WSDL Step 8: Create the Inventory Tracker Window Component Step 8: Create the Inventory Tracker Window Component The Inventory Tracker has two users interfaces: a login dialog and a main window containing the primary functionality. An XML Script component in which you can enter ActionScript. <flexforforce:FieldContainer id="_editFieldContainer" width="100%"> </flexforforce:FieldContainer> 94 . which is in a Spark Group component.com Flex requiredTypes="Merchandise__c"/> </fx:Declarations> 5. This component contains default ActionScript that initializes the data when the Force. enter _editFieldContainer. and the showStatusBar attribute.com Flex components. The component contains a layout component used to arrange your UI elements.com logic and data in your code. The FieldContainer you're creating here will also render the details of the selected record at the top of the screen.Tutorial #11: Creating a Desktop App with Force. When you select a record in that list. Set the FieldContainer component width to 100% and for the ID.com Flex FieldContainer component. the details of the record appears in the top part. Spark and Halo. Save the file. the text displayed in the title bar. The default MXML code includes: • A Spark WindowedApplication component that specifies the namespaces. <s:Label text="Put your components here"/> 2. Inside the VGroup component.com Flex application opens. a VGroup component that creates a vertical grouping of the UI elements. 1. and a Force. A Spark states component used to determine which of the UIs is presented. A Save button below the record details lets you commit those changes to Force. You'll enter the application logic in the default WindowedApplication component generated when you create a Force. add a Force.com. Force. The lower part contains a list of merchandise records.

com. but you need to add the ActionScript that retrieves Salesforce data and saves the data in the Force. The fields you create with the FieldAndLabel component automatically function in Force. Begin the ActionScript by importing the classes you need for the ActionScript in the <![CDATA[ section inside the <fx:Script> element. <flexforforce:LabelAndField <flexforforce:LabelAndField <flexforforce:LabelAndField <flexforforce:LabelAndField field="Merchandise__c. Leave this component as is.com Flex 3.LogEventLevel. The code will look like this: import import import import import import import import import import import com.LoginResultEvent.com Flex applications the same way they do on the Salesforce user interface. and automatically provide inline editing.Description__c" /> field="Merchandise__c.IManaged.Tutorial #11: Creating a Desktop App with Force.salesforce.events.com API name.com Flex application. hover details.events. Now add a standard Spark button.events. add one Force. Within the FieldContainer component. 95 . which you'll write later.flexforforce. and Info icon help text.salesforce. <mx:DataGrid id="_dataGrid" width="100%" height="100%" dataProvider="{_gridDataProvider}" itemClick="onDataGridItemClick()"> <mx:columns> <mx:DataGridColumn dataField="Name" /> <mx:DataGridColumn dataField="Description__c" headerText="Description" /> <mx:DataGridColumn dataField="Price__c" headerText="Price" /> <mx:DataGridColumn dataField="Total_Inventory__c" headerText="Total Inventory" /> </mx:columns> </mx:DataGrid> The dataProvider attribute references a variable that you'll create later. error notification. and configure it to execute a function called onEditSaveClick.data. com. and the itemClick attribute references a function that you'll create later. and reference each field by its internal Force. com. The fields also respect field dependencies. com. The Inventory Tracker application user interface is now in place.salesforce.LoginFaultEvent. which is part of the default code. mx.notifications. You'll use a standard ActionScript DataGrid component to render the list.CursorManager. The final component in the VGroup element is the Force. 7. Below the Save button in the Inventory Tracker user interface.salesforce.Name" /> field="Merchandise__c.managers. mx.F3Message. For example.StatusChangedEvent. date fields display a calendar when clicked.collections.Alert.ArrayCollection.events.Total_Inventory__c" /> 4.Price__c" /> field="Merchandise__c. mx. A LabelAndField component renders a Salesforce field value with its label.salesforce.controls.salesforce. you will display a list of merchandise records. <s:Button label="Save" click="onEditSaveClick()"/> 5. mx. com.SessionExpiredEvent. mx.DynamicEntity.logging. Enter the code as shown below.com Flex LabelAndField component for each field of the Merchandise object you want to display. 6. label it Save.com Flex StatusBar component.

Responder( function(rows:ArrayCollection):void {_gridDataProvider = rows. The code will use this variable to display the data in the list. 9.com Flex component that provides standard contextual error and information messages. null ) ). // when the login is complete the main state should be shown currentState = "main".flexforforce.rpc.com Flex import mx. The complete function looks like this: protected function loginCompleteHandler( event : LoginResultEvent ) : void { CursorManager. Merchandise__c—The ActionScript service class representing the Merchandise object. ArrayCollection—An ActionScript wrapper that exposes an array as a collection that can be accessed and manipulated.Tutorial #11: Creating a Desktop App with Force.Responder(commitToDB.removeBusyCursor(). This will be used to store the records to be displayed in the UI. [Bindable] private var _gridDataProvider:ArrayCollection = null. Responder—An ActionScript component that ensures that NULL responder functions do not cause problems internally. The classes are as follows.com Flex component that binds dynamically to any item the user selects. It is used to display the selected item in the top part of the UI. new mx.com Flex.rpc. F3Message—A Force.rpc. } You referenced this function when you assigned the loginComplete attribute in the F3DesktopApplication element at the beginning of this step in the tutorial. • • • • • • DynamicEntity—A Force. Create a variable to hold the merchandise data.updateObject( new mx. This class is automatically generated by Force. import services. null) ).wrapper.}. app. Create a function named onEditSaveClick that copies the changes a user makes to the data back into memory from the user interface. 8. } 96 . The loginCompleteHandler() function in the default code sets the current state to main so that the main UI is displayed.Responder. Modify this function to query the database so the merchandise data is displayed in the lower part. such as data conflicts.query( "select * from Merchandise__c".Merchandise__c. 10. private function onEditSaveClick():void { _editFieldContainer. IManaged—An ActionScript interface that provides the contract for a managed object.fieldCollection.

com. mx. 11.events.controls.com/flex/spark" xmlns:mx="library://ns.LogEventLevel. com. Refer to the FieldContainer by the ID you set for it earlier (_editFieldContainer).IManaged. Save the file. the function calls the commitToDB function. which commits the data in memory to the database. mx. Create a function that renders the FieldContainer data in the Force. com.SessionExpiredEvent.render(de). This function also performs a simple validation of the data the user enters. mx.adobe. } 12. Your final code should look like this.events.LoginResultEvent. <?xml version="1. mx.flexforforce.Tutorial #11: Creating a Desktop App with Force.StatusChangedEvent. If the data is valid.logging.ArrayCollection. _editFieldContainer.notifications.salesforce. } 13. 97 .DynamicEntity. private function commitToDB(managedObject:IManaged):void { app.salesforce. com.CursorManager.salesforce.adobe.events. private function onDataGridItemClick():void { var de:DynamicEntity = _dataGrid.LoginFaultEvent. and clears the data from the FieldContainer.managers.fieldCollection.com/flex/mx" xmlns:flexforforce="http://flexforforce.com" title="Inventory Tracker" showStatusBar="false"> <fx:Declarations> <s:TraceTarget includeCategory="true" includeLevel="true" includeTime="true" level="{LogEventLevel.*']}"/> <flexforforce:F3DesktopApplication id="app" statusChanged="statusChangedHandler(event)" loginComplete="loginCompleteHandler(event)" loginFailed="loginFailedHandler(event)" sessionExpired="sessionExpiredHandler(event)" requiredTypes="Merchandise__c"/> </fx:Declarations> <fx:Script> <![CDATA[ import import import import import import import import import import import com.F3Message.events.com Flex application.salesforce.INFO}" filters="{['com.salesforce.salesforce.Alert.com/mxml/2009" xmlns:s="library://ns. Create the commitToDB function.wrapper.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.salesforce.selectedItem as DynamicEntity.com Flex This action is triggered when the user clicks the Save button.collections. com.adobe.salesforce.data.save( managedObject ). mx.

text.rpc. var alertString : String.rpc.Responder.setBusyCursor(). } protected function sessionExpiredHandler( event : SessionExpiredEvent ) : void { // Alert will be shown if default is not prevented. } protected function loginClickHandler( event : MouseEvent ) : void { _username = username. app.selectedItem as DynamicEntity. } protected function loginCompleteHandler( event : LoginResultEvent ) : void { CursorManager.show( alertString. null ) ). new mx.preventDefault().save( managedObject ).rpc.preventDefault().message.loginByCredentials( _username. } protected function statusChangedHandler( event : StatusChangedEvent ) : void { status = event. private var _username : String. private function onEditSaveClick():void { _editFieldContainer. event.text.description. "Session Expired" ). // when the login is complete the main state should be shown currentState = "main".". import services. _editFieldContainer.fieldCollection. CursorManager. alertString = "Your session expired and was automatically re-newed. } protected function loginFailedHandler( event : LoginFaultEvent ) : void { CursorManager. null) ).render(de).fieldCollection. } private function commitToDB(managedObject:IManaged):void { app. private var _password : String. _password = password.wrapper. CursorManager. // By default an alert shows that login failed.Responder( function(rows:ArrayCollection):void {_gridDataProvider = rows. " + "Please repeat your last operation.setBusyCursor(). Alert. app.removeBusyCursor().com Flex import mx.updateObject( new mx.Merchandise__c.flexforforce.query( "select * from Merchandise__c". To implement an own logic // you can prevent default by uncommenting the following line: //event. } private function onDataGridItemClick():void { var de:DynamicEntity = _dataGrid.wrapper. [Bindable] private var _gridDataProvider:ArrayCollection = null.Tutorial #11: Creating a Desktop App with Force. currentState = "login".}. 98 .removeBusyCursor(). _password ).Responder(commitToDB.

Tutorial #11: Creating a Desktop App with Force.Description__c" /> <flexforforce:LabelAndField field="Merchandise__c.loginPending}" label="{status}"/> </mx:Form> </s:VGroup> <s:Group includeIn="main" enabled="{!app.Total_Inventory__c" /> </flexforforce:FieldContainer> <s:Button label="Save" click="onEditSaveClick()" /> <mx:DataGrid id="_dataGrid" width="100%" height="100%" 99 .Name" /> <flexforforce:LabelAndField field="Merchandise__c.loginByCredentials( _username.loginPending}" width="100%" height="100%"> <s:layout> <s:BasicLayout/> </s:layout> <s:VGroup paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10"> <flexforforce:FieldContainer id="_editFieldContainer" width="100%"> <flexforforce:LabelAndField field="Merchandise__c.com Flex // when the login session expired the user could be re-logged in automatically pp. _password ).Price__c" /> <flexforforce:LabelAndField field="Merchandise__c.com Login" fontWeight="bold"/> <mx:Form> <mx:FormItem label="Username"> <s:TextInput id="username" text=""/> </mx:FormItem> <mx:FormItem label="Password" direction="horizontal"> <s:TextInput id="password" text="" displayAsPassword="true"/> <s:Button label="Login" enabled="{!app. } ]]> </fx:Script> <s:states> <s:State name="login"/> <s:State name="main"/> </s:states> <s:VGroup includeIn="login" horizontalCenter="0" verticalCenter="0"> <s:Label text="Salesforce.loginPending}" click="loginClickHandler(event)"/> </mx:FormItem> <mx:ProgressBar indeterminate="true" visible="{app.

.. 1. In Flash Builder.com Flex Application Component Attributes Step 9: Testing the Inventory Tracker application Step 9: Testing the Inventory Tracker application The Inventory Tracker application is now ready to be tested.com Flex Step 7: Set the Force.Tutorial #11: Creating a Desktop App with Force. ➤ Desktop Application. Verify that your machine has an active Internet connection. The Inventory Tracker application login screen appears.com Flex dataProvider="{_gridDataProvider}" itemClick="onDataGridItemClick()"> <mx:columns> <mx:DataGridColumn dataField="Name" /> <mx:DataGridColumn dataField="Description__c" headerText="Description" /> <mx:DataGridColumn dataField="Price__c" headerText="Price" /> <mx:DataGridColumn dataField="Total_Inventory__c" headerText="Total Inventory" /> </mx:columns> </mx:DataGrid> </s:VGroup> <flexforforce:StatusBar left="0" bottom="0"/> </s:Group> </s:WindowedApplication> See Also: Tutorial #11: Creating a Desktop App with Force. 2. 100 . right-click on the Inventory Tracker project and select Run as.

The Inventory Tracker user interface appears. In the login screen. 101 .Tutorial #11: Creating a Desktop App with Force. enter the username and password you use to log into your Force. and click Login.com Flex application.com Flex 3.

Tutorial #11: Creating a Desktop App with Force. Select a record in the list and change its data.com application and verify that your change appears. To test the data conflict resolution capability: a. then click Save. Change a field in your Force. 7. b. Log into your Force. Select the icon in the status bar and select Sync Now. 102 . Change the same field in the Inventory Tracker application to a different value and click Save. the status bar icon changes to indicate a conflict exists. When you select Sync Now in the Inventory Tracker application. c. 5.com application and click Save.com Flex 4. 6. Click Resolve in the status bar to launch the conflict resolution interface.

com Flex app that gives users the ability to view and edit Force. It demonstrates the fundamentals of Force. As you can probably imagine. you can use Force.com Flex Step 8: Create the Inventory Tracker Window Component Summary Summary In this tutorial. See Also: Tutorial #11: Creating a Desktop App with Force.com Flex Step 9: Testing the Inventory Tracker application 103 .com Flex without much coding. Select the value you want to keep. See Also: Tutorial #11: Creating a Desktop App with Force.com apps.com Flex The conflict resolution interface lets you see the values in both Salesforce and the Inventory Tracker application.com Flex to create far more powerful Force.com data both with and without an Internet connection. you created a simple Force. then click Continue To Summary.Tutorial #11: Creating a Desktop App with Force.com Flex apps to enhance the ways in which users interact with your Force.

Your browser opens a login page. 104 . You may have also noticed that the URL in your browser is different. Click Start Copy. 3. c. 2. Enter a project name. Specify your organization credentials. To create one: 1. 2. Select File ➤ New ➤ Force. you may have noticed that the User Name field is different than your regular user name. Next to your sandbox. Force.. If you are using a sandbox for development. Click Your Name ➤ Setup ➤ Data Management ➤ Sandbox. When you logged in.com IDE: 1. Log into your Free Edition organization... Enter your password. Click Next. so it helps to identify each project with a descriptive name. enter your password and click Login. e. such as Dev. 4. select Sandbox from the drop-down list. a. Enter a Name. That's because each sandbox has its own instance that's different from the one used by your regular organization.Creating and Logging into a Sandbox APPENDIX Creating and Logging into a Sandbox If you're using Free Edition. When the sandbox is available.com Project. click Login. Creating a Project in the Force. If you're not the type to watch water boil. you should do all your development in a sandbox. refresh your browser and look at the Status field. Enter the username you use to log in as an administrator. 3. click Your Name ➤ Setup ➤ Data Management ➤ Sandbox. Creating a copy of the production organization takes a moment. Click New Sandbox. log in: 1. step away and we'll email you when the copy completes. d. 5. Call this one Workbook. You can have multiple project names on the same organization. If you navigated to a different page during the sandbox copy. b. To track the progress. The username is in the form of an email address. Tell Me More.com IDE To create a project in the Force.com automatically appends your sandbox name to your user name so that you can log into multiple sandboxes. in the Environment field. 2.

have no way of controlling what happens to the components that were in it. use the Force.com online help. You can use them to distribute an application to multiple organizations. use the Force. then you'll want to package it.com_IDE. you can also easily distribute upgrades to customers who installed older versions of the application. For more information. If you're developing this application for just one organization. With managed packages. Once an unmanaged package is installed in another organization. On the Project Content page click Finish to retrieve Apex and Visualforce and components. Delivering Your Application Now that your application is complete.developerforce.com/index. For more information. code. you. it means your current IP is not recognized from a trusted network range. with control over the intellectual property and licensing.com platform provides two types of packages: unmanaged and managed: • Unmanaged packages are used to distribute copies of the bundled components. the publisher. Managed packages are used to distribute copies of the bundled components in a way that leaves you. The Force. 105 . About Deploying If you want to deploy your code to a production organization that you have login credentials for. About Packaging Packages are like suitcases that can contain your components. see wiki. including all of the source code. If you're developing this application to be installed in multiple organizations. the publisher. see wiki.com/index. These are typically free packages without the option to upgrade. • For more information on packaging. there are a couple options available: • • If you're comfortable with a command-line interface. Managed packages are the preferred way to release applications on Force. From the Salesforce user interface. 3.com IDE. or applications. see “Overview of Packages” in the Force.com Migration Tool for deployment.php/Force. click Your Name ➤ Setup ➤ My Personal Information ➤ Reset My Security Token and follow the instructions there. If you prefer a graphical interface.Delivering Your Application Note: If you get a LOGIN_MUST_USE_SECURITY_TOKEN error.developerforce.com AppExchange.php/Migration_Tool_Guide. then you'll deploy it. you'll want to know about the various ways you can deliver it. You must reset your security token.

Sign up to vote on this title
UsefulNot useful