Introduction to Acumatica Framework

Size: px
Start display at page:

Download "Introduction to Acumatica Framework"

Transcription

1 Introduction to Acumatica Framework Training Guide T100 Introduction to Acumatica Framework 5.0

2 Contents 2 Contents Copyright...4 Introduction... 5 Getting Started...7 Application Programming Overview... 8 Querying the Data Entity Model Declaration RapidByte Application Overview Functional Requirements Application Pages Preparation of the Development Environment Summary: Application Overview and Preparations Part 1: Maintenance Pages Lesson 1: Creating the First Page Countries...32 Adding the CountryMaint Graph Adding Page RB Adding the Country Class Modifying the CountryMaint Graph Configuring the Grid on the Page...42 Adding the Page to the Site Map Conclusion: Creation of Pages Lesson 2: Creating the Customers Maintenance Page Adding the CustomerMaint Graph and Page RB Adding the Customer Class Configuring the CustomerMaint Graph and Page RB Adding Selectors to the Page Conclusion: Simple Form Edit Pages...56 Lesson 3: Adding Simple Business Logic to the Customers Page...57 Adding Logic on Update of the CountryCD Field Conclusion: Business Logic...60 Part 2: Data Entry Pages Lesson 4: Creating the Sales Order Data Entry Page Adding the SalesOrderEntry Graph and Page RB Adding the Product Class Adding the SalesOrder Class Adding the OrderLine Class Configuring the SalesOrderEntry Graph...70 Configuring Page RB Conclusion: Master-Detail Pages Lesson 5: Adding Simple Business Logic to the Sales Orders Page...76 Configuring a Combo Box Setting the Combo Box Value at Run Time Inserting Product Details into an Order Line...81 Conclusion: Usage of Combo Boxes and Autoinsertion of Values...83 Lesson 6: Calculating Totals Calculating the Extended Price of an Order Line Calculating the Lines Total and Tax Total of a Sales Order Calculating the Order Total...90

3 Contents 3 Conclusion: Calculations...91 Part 3: Inquiry Pages...92 Lesson 7: Creating the Sales Order Inquiry Page Adding the SalesOrderInq Graph...94 Adding Page RB Conclusion: Inquiry Pages Part 4: Processing Pages Lesson 8: Creating the Approve Sales Orders Page Implementing the Approval Operation Adding the SalesOrderProcess Graph Adding Page RB Conclusion: Processing Pages Lesson 9: Setting Up the UI for Approved Sales Orders Making Approved Sales Orders Read-only in the UI Conclusion: UI Setup Part 5: Reports Lesson 10: Creating the Sales Orders Printable Form Preparing Data for the Report Adding a Variable to the Report Configuring the Printable Page Layout Adding the Report URL to the Site Map Running the Report Form Conclusion: Reports Appendix: Application Design Database Schema Data Access Classes Application Pages Business Logic

4 Copyright 4 Copyright 2015 Acumatica, Inc. ALL RIGHTS RESERVED. No part of this document may be reproduced, copied, or transmitted without the express prior consent of Acumatica, Inc Lake Washington Blvd NE, Suite 100 Kirkland, WA Restricted Rights The product is provided with restricted rights. Use, duplication, or disclosure by the United States Government is subject to restrictions as set forth in the applicable License and Services Agreement and in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at DFARS or subparagraphs (c)(1) and (c)(2) of the Commercial Computer Software-Restricted Rights at 48 CFR , as applicable. Disclaimer Acumatica, Inc. makes no representations or warranties with respect to the contents or use of this document, and specifically disclaims any express or implied warranties of merchantability or fitness for any particular purpose. Further, Acumatica, Inc. reserves the right to revise this document and make changes in its content at any time, without obligation to notify any person or entity of such revisions or changes. Trademarks Acumatica is a registered trademark of Acumatica, Inc. All other product names and services herein are trademarks or service marks of their respective companies. Software Version Last updated: January 28, 2015

5 Introduction 5 Introduction The course consists of step-by-step lessons in which you develop a complete Acumatica Frameworkbased application. The course gives you an idea of how to develop your own applications by using Acumatica Framework. It demonstrates key components of the platform and their usage for typical tasks in application development. As you go through the course, you will create pages of all main types that are used in Acumatica Framework. After you complete all the lessons, you will be acquainted with basic techniques of programming with Acumatica Framework, such as working with data, implementing business logic and processing operations, and building reports. We recommend that you follow the lessons in the order in which they are provided in the course, because some lessons use the result of the previous ones. System Requirements For detailed system and browser requirements, see ConfiguringDevEnvironment.pdf attached to the training materials. To develop and debug your application, use Internet Information Services (IIS) hosted locally on your machine. You can debug an application running on IIS by attaching the Visual Studio debugger to the server process. For more information on how to debug Acumatica Framework applications, see Acumatica Framework > Debugging Applications in the documentation. Required Knowledge and Background To complete the course successfully, you should have the required knowledge: Proficiency with C# language, including but not limited to the following language features: Class structure OOP (inheritance, interfaces, polymorphism) Usage and creation of attributes Generics Delegates, anonymous methods and lambda expressions Knowledge of the main concepts of ASP.NET and Web Development: Application State Debugging ASP.NET Applications Using Visual Studio Attaching to IIS using Visual Studio Debugging Tools Client and Server-Side development Web Forms Structure Web Services Experience with SQL Server: Writing and debugging complex SQL queries (Where Clause, Aggregates, Subqueries) Understanding of database structure (Primary Keys, Data Types, Denormalization) Expericence with IIS: Configuration and deployment of ASP.NET websites Configuring and Securing IIS

6 Introduction 6 Review the following Microsoft Training Classes to see what training is covered or get up to speed with these technologies Programming in C# Querying Microsoft SQL Server 2012 Developing Microsoft SQL Server 2012 Databases Introduction to Web Development with Microsoft Visual Studio 2010 Acumatica Framework Documentation You can find the framework documentation: Online at the portal in the Documentation section. On the website of the Acumatica Framework-based application template that you will install locally as you go through this course. In the single AcumaticaFramework_DevelopmentGuide.pdf PDF documentation file, which is located in the folder where Acumatica Framework is installed. By default, the folder is C:\Program Files (x86)\acumatica Framework.

7 Getting Started 7 Getting Started In this part of the course, you will get an overview of application programming with Acumatica Framework and prepare to build the RapidByte application. After you see the requirements of the RapidByte application, you will set up the template to start programming the application. The Acumatica Framework application template includes the default database schema, which contains only system tables, the website, the Visual Studio solution, and an empty Class Library project for your application code. However, you will install the template for the T100 Introduction to Acumatica Framework course, which also adds application tables for RapidByte. Thus, after you complete the first part of the course, you will have the initial web application that is ready for development of a new business module.

8 Getting Started 8 Application Programming Overview Acumatica Framework provides the platform and tools for developing cloud business applications. This document explains Acumatica Framework runtime structure, introduces main components, and illustrates their relationships on simple examples. The chapter is a starting point for application developers who are going to develop and customize applications with the help of Acumatica Framework. This document is a mandatory reading before starting the Acumatica Framework Tutorial. Runtime Structure and Components An application written with Acumatica Framework has n-tier architecture with a clear separation of the presentation, business, and data access layers. The picture below illustrates the application component model from the point of view of the application programmer. Figure: Application architecture. Data Access Layer Acumatica Framework relies on object relationship mapping (ORM) technology to access the database from the business logic. Acumatica Framework implements own, proprietary ORM technology. This technology provides an application developer with a set of standard CRUD operations to execute on database tables and methods to execute complex SQL queries. An important feature of the Acumatica ORM technology is a high-performance serialization mechanism that stores modified but not persisted database records in the session state. Modified data are merged with the result of the query execution to emulate stateful data access behavior for the application developer and minimize the amount of data stored in the session.

9 Getting Started 9 Business Logic Layer Business Logic Layer is implemented as a set of business logic controllers (graphs). Each business logic controller consists of two parts: Entity Model that declares data access classes the entities are stored in, their relationships, and actions that can be executed over the entities Entity Business Logic that implements the business logic of the actions and events associated with modifying entity data Business logic controllers implement the interfaces for Presentation Layer to retrieve the entity data and execute the actions over the entity. Business Logic Layer relies on Data Access Layer to retrieve data from the database and execute CRUD operation. Presentation Layer Presentation Layer is responsible for providing: The user interface based on the ASPX technology and implemented as a set of declarative Web Forms The alternative interface for accessing the business logic in the form of auto-generated Web Service API Presentation Layer is completely declarative and contains no business logic. Related Links Querying the Data Entity Model Declaration Handling Entity Data Implementing Business Logic

10 Getting Started 10 Querying the Data This system implements a custom language for writing database queries called BQL (business query language). It is not LINQ and doesn't use it. BQL is written in C# and based on generic classes syntax, but still is very similar to SQL syntax. It has almost the same keywords placed in the order they are used in SQL. For example: PXSelect<Product, Where<Product.availQty, IsNotNull, And<Product.availQty, Greater<Product.bookedQty>>>> If the database provider is MS SQL Server, the framework will translate this expression into the following SQL query: SELECT * FROM Product WHERE Product.AvailQty IS NOT NULL AND Product.AvailQty > Product.BookedQty BQL gives several benefits to the application developer. It does not depend on database-provider specifics, is object-oriented and extendable. An important benefit is compile-time syntax validation, which helps to prevent SQL syntax errors. Since BQL is implemented on top of generic classes, you need types that would represent database tables. In the context of Acumatica Framework, they are called data access classes (DACs). For example, to execute the SQL query from the example above, you should define the Product data access class as: using System; using PX.Data; // Types used in BQL statements should derive from special interfaces: // table - IBqlTable, column - IBqlField. [System.SerializableAttribute()] public class Product : PX.Data.IBqlTable // The type used in BQL statements to reference the ProductID column public abstract class productid : PX.Data.IBqlField // The property holding ProductID value in a record [PXDBIdentity(IsKey = true)] public virtual int? ProductID get; set; // The type used in BQL statements to reference the AvailQty column public abstract class availqty : PX.Data.IBqlField // The property holding AvailQty value in a record [PXDBDecimal(2)] public virtual decimal? AvailQty get; set; // The type used in BQL statements to reference the BookedQty column public abstract class bookedqty : PX.Data.IBqlField // The property holding BookedQty value in a record [PXDBDecimal(2)] public virtual decimal? BookedQty get; set; Each table field is declared in a data access class twice: As a type to reference a field in the BQL command As a value to hold the table field data

11 Getting Started 11 If the DAC is bound to the database, it must have the same class name as the database table. Fields are bound to the database by means of data mapping attributes (such as PXDBIdentity and PXDBDecimal), using the same naming convention. A complete code sample that queries the database is given below: using System; using System.Collections; using PX.Data; public static void Main() // Select Product records PXResultSet<Product> res = PXSelect<Product, Where<Product.availQty, IsNotNull, And<Product.availQty, Greater<Product.bookedQty>>>>.Select(new PXGraph()); // You can iterate through the result set foreach(pxresult<product> rec in res) // A record from the result set can be cast to the DAC Product p = (Product)rec; Console.WriteLine("ID: 0, available: 0, booked: 0", p.productid, p.availqty, p.bookedqty); BQL library also supports such advanced features as: DACs that are not bound to the database Virtual fields that are not bound to the database Scalar sub-selects Projections Stored procedures execution Server-side calculated fields Non-blocking updates of statistical data records

12 Getting Started 12 Entity Model Declaration Business Entity or simply Entity in Acumatica Framework represents an individual instance of the objects (such as Product, Order) to which the information pertains. Entity can be simple, where the data are represented with a single database record in a single table, or complex. With the complex entity, data are typically held in multiple tables and associated through a complex hierarchy and relationship rules. Working with the business entities in Acumatica Framework is implemented through the business logic controller object also referred as graph (graph is a mathematical term for a set of objects where some pairs of objects are connected by links). A graph provides the interface for the presentation logic to operate with the business entity and relies on Data Access Layer components to store and retrieve the business entity from the database. Let s first take a look at the declaration of a simple business entity: //Declaration of the graph public class ProductMaint : PXGraph<ProductMaint> //Declaraion of the data view public PXSelect<Product> Products; //Declaration of the actions public PXCancel<Product> Cancel; public PXSave<Product> Save; In this example the graph implements the following interfaces: Products the data view that can be used for querying and modifying entity data Cancel the action that discard all the changes made to the entity and reloads it from the database Save the action that commits the changes made to the entity to the database and then reloads the committed data Handling Entity Data Data View and Entity Cache Data views implement the interfaces for querying entity data from the business logic controller and submitting modified data back to the entity. Data views are declared as public fields of PXSelect command type: public PXSelect<Product> Products; Based on this declaration, the system automatically instantiates the DAC entity cache. An entity cache object in the Acumatica Framework is the primary interface for working with individual entity records from the graph business logic. It has two components and two primary responsibilities: The Cached collection in-memory cache that contains modified entity records. The Cached collecton is instantiated based on the corresponding DAC declaration and managed by the cache. The controller the cache component that implements basic CRUD operations on the Cached collection and triggers a sequence of data manipulation events when modifying or accessing the data in the Cached collection. These events can be later subscribed from the graph to implement the business logic associated with entity data modification. The diagram below helps to understand the internal graph structure and responsibilities of the data view and the entity cache.

13 Getting Started 13 Figure: The graph structure a data view and an entity cache. Data Modification Scenarios Now lets consider basic entitiy data manipulation scenarious that can be executed from the graph business logic or from the user interface. Entity data manupulation through the user interface indirectly invokes the same methods as the direct call from the business logic. Querying Entity Data for the First Time Entity data can be requested through the Products.Select() method. During this operation, the systems will execute BQL command from the data view declaration. Data returned by the BQL command will be returned to the requestor. See the diagram below. Figure: Querying entity data for the first time. Updating an Existing Entity Record An existing business entity record can be updated through the Products.Update(record) method. This method places the modified record into the cache. If the data record is not found in the Cached collection, the cache controller will load the data record from the database, add it to the Cached collection, mark it as updated, and update it with the new values. The search of the data record in the Cached collection and loading of the data record from the database is based on the DAC key fields. The diagram below illustrates this scenario.

14 Getting Started 14 Figure: Updating the entity record for the first time. If the updated record exists in the Cached collection the cache controller will locate it and update it with the new values. The diagram below illustrates this scenario.

15 Getting Started 15 Figure: Updating the cached (previously modified) entity record. Inserting a New Entity Record A new record can be inserted into the business entity through the Products.Insert(record) method. The new inserted record will be added to the Cached collection and marked as inserted. The diagram below illustrates this scenario.

16 Getting Started 16 Figure: Inserting the new entity record. Deleting an Existing Entity Record An existing record can be deleted from the business entity using the Products.Delete(record) method. If the data record is not found in the Cached collection, the cache controller will load the data record from the database, add it to the Cached collection, and mark it as deleted. The search of the data record in the Cached collection and loading of the data record from the database is based on the DAC key fields. The diagram below illustrates this scenario.

17 Getting Started 17 Figure: Deleting the non-cached (unmodified) entity record. If the deleted record is found in the Cached collection, the cache controller will locate it and mark as deleted. The diagram below illustrates this scenario. Figure: Deleting of the cached (previously modified) entity record.

18 Getting Started 18 Querying an Updated Entity Data Entity data can be modified and then queried again. In this scenario, the data records stored in the caches memory will be merged with the result of the BQL command execution. Data records merge is based on DAC key fields. The final result of the Select() execution will incorporate all the earlier entity records modifications that has not been preserved to the database yet. The diagram below illustrates this scenario. Figure: Querying the modified entity data reading and merging with the cached data. Persisting Entity Changes to the Database When entity data are modified, the system has two different entity versions, the new one stored in the caches memory and the original one persisted in the database. At this point a programmer has two options: Save the new entity version to the database using the Persist() method of the graph Discard all in-memory changes and load the original entity version using the Clear() method of the graph From the Presentation Layer these methods are called by invocation of the Save and Cancel actions. These actions are predefined and mapped to the Persist() and Clear() methods. The diagram below illustrated saving of entity changes to to the database.

19 Getting Started 19 Figure: Saving the entity changes to the database. The diagram below illustrated discarding of all in-memory entity changes. Figure: Discarding the changes and loading the original entity data.

20 Getting Started 20 Preserving the Entity Version Between the Round Trips and Handling the Subsequent Selects from the Views It is important to understand that a graph is a stateless object. It is discarded after each data request. In order to preserve the modified entity version between the requests, the cache controller serializes the Cached collection into the session state and restores it later when the graph is instantiated on the subsequent request. In this scenario, it is very important that the cache contains only the modified entity records, not the complete entity record set. Implementing Business Logic Business logic is implemented by overloading certain methods invoked by the system in the process of manipulating data. For such procedures as inserting a data record or updating a data record, the PXCache controllers generate series of events causing invocation of the methods called event handlers. The application is able to interfere in the series of events on different stages. For this purpose, the application impements methods that are executed as event handlers. There are 18 events raised on all stages of data processing. Business logic can be divided into common logic relevant to different parts of the application and the logic specific to an application screen (web page). The common logic is implemented through event handler methods defined in attributes, while the screen-specific logic is implemented as methods in the associated graph. Common Business Logic The common business logic is implemented by defining event handlers in attributes. If such attribute is added to the declaration of a data access class, attribute logic is applied to the data records of this type for any graph used to access this table. There are a number of predefined attributes implemented in the framework. For example, in the following declaration of a data field for a column [PXDBDecimal(2)] public virtual string AvailQty get; set; PXDBDecimal is an attribute binding this field to a database column of the decimal type. The attributes of this form exist for most database data types. Another typical example of an attribute is PXUIField. It is used to configure the input control for the column in the user interface. This allows having the same visual representation of the column on all application screens (unless a screen redefines it). For example: [PXDBDecimal(2)] [PXUIField(DisplayName = "Available Qty", Enabled = false)] public virtual string AvailQty get; set; Application can also define its own attributes, in the following way: // Application-defined attribute implementing common business logic public class MyAttribute : PXEventSubscriberAttribute, IPXEventNameSubscriber // An event handler protected virtual void EventName(PXCache sender, PXRowEventNameEventArgs e)......

21 Getting Started 21 Such attributes are also added to the DAC declaration: [PXDBDecimal(2)] [PXUIField(DisplayName = "Available Qty", Enabled = false)] [MyAttribute] public virtual string AvailQty get; set; Screen-Specific Business Logic For a specific screen, the application can redefine the common logic or extend it. For this purpose, you should define event handlers in the graph associated with the screen. Each event hanlder method is tied to a particular table or a table field via the naming convention. For example, you can verify a value of a column: public class ProductRecalc : PXGraph<ProductRecalc>... // Event handler verifying that the value of the AvailQty column // in Product records is greater than 0. // It is triggered when, for instance, a Product record is updated. protected virtual void Product_AvailQty_FieldVerifying( PXCache sender, PXFieldVerifyingEventArgs e) Product p = (Product)e.Row; if (p!= null && p.availqty!= null) if (p.availqty < 0) throw new PXSetPropertyException<Product.availQty>( "Value must be greater than 0.");

22 Getting Started 22 RapidByte Application Overview In this section, you will get an overview of the RapidByte application that you will build as you complete the course. You will see the application requirements and the webpages that you will create in further lessons.

23 Getting Started 23 Functional Requirements The RapidByte application should provide the following functionality for working with sales orders: 1. A user should be able to enter sales orders and add products to them. A sales order is a document that contains the information about the products ordered by a particular customer. Each sales order has a unique number, a reference to the customer, and a reference to the company that provides the shipment of the order. The products added to a sales order (which can be only active products) are the order details. For each sales order, the application should also provide the following features: a. b. Calculation of the sales order totals: The tax total is the sum of the tax amounts of all order details (products added to the order). The lines total is the sum of the extended prices of all order details. The order total is the sum of the lines total, tax total, and freight amount specified in the order. Calculation of the extended price of an order detail: extended price = product quantity * unit price * (1 - discount / 100), where thediscount is specified as a percent in each order detail individually. The calculated values should be saved to the database. 2. The user should be able to get the list of all existing sales orders and the list of sales orders filtered by a particular customer. 3. The user should be able to approve sales orders. Once approved, a sales order becomes readonly and cannot be deleted from the database. 4. The user should be able to print sales orders. 5. The user should be able to edit customers. Each sales order should be associated with a customer. By using the listed requirements, we can plan the application pages that we will create in this course. For more information about the database structure and application classes, see Appendix: Application Design.

24 Getting Started 24 Application Pages In the RapidByte application, users must be able to enter sales orders, select them by the specified criteria, and approve them. We will create a separate page for each of these activities: a data entry page, an inquiry page, and a processing page for working with sales orders in the application. Based on the requirements, we also see that we need a page for sales order printing and a helper page for editing products. To start with a very simple Acumatica Framework page as an example, we will create the Countries page, which provides editing of the list of countries. In summary, we will create the following application pages: 1. Countries 2. Customers 3. Sales Orders 4. Sales Order Approval 5. Sales Order Inquiry 6. Sales Order Printing See below for the screenshots and brief descriptions of of the pages (including their Functional Requirements, where applicable): 1. Countries (no specific functional requirement) By using this page (shown below), users can edit the list of countries. The instructions for creating this application page demonstrate how to start building the application. In the application, the list of countries would help if you created a page for working with customers, because each customer has a country attribute. Figure: The Countries page 2. Customers (functional requirement #5) This helper page, as shown in the following screenshot, gives users the ability to add new customers and edit their parameters.

25 Getting Started 25 Figure: The Customers page 3. Sales Orders (functional requirement #1) The main page of the application, which should look like it does in the following screenshot, is this data entry page for sales orders. On this page, the user enters the sales order parameters and adds products to the sales order. The page should have the Approve button, which can be invoked to change the sales order status to Approved. Figure: The Sales Orders page 4. Approve Sales Orders (functional requirement #3) On this processing page (which is shown below), the user can select one sales order or multiple orders and run the approval operation for the selected orders or all listed orders. Figure: The Approve Sales Orders page 5. Sales Order Inquiry (functional requirement #2)

26 Getting Started 26 The page will display the list of sales orders, as shown below. The user can view all sales orders or only those of the selected customer. Figure: The Sales Order Inquiry page 6. Sales Orders printable form (functional requirement #4) The printable version of the sales order must include all sales order parameters and the list of order details, as the following screenshot illustrates.

27 Getting Started 27 Figure: The Sales Order printable document Users will be able to navigate to these pages from the application menu. To provide a complete navigation menu in the application, you will add these pages to the site map as you create them. Now that you understand what pages should be implemented in the application, go to the next lesson to set up the application template that will be used for creating of the application pages. Related Links Application Pages Appendix: Application Design

28 Getting Started 28 Preparation of the Development Environment You will now create the RapidByte application from the application template that is provided with Acumatica Framework. Do the following by instructions given in the ConfiguringDevEnvironment.pdf attached to the training materials: 1. Install Acumatica Framework. 2. Deploy a new application instance for a training course. On the Instance Configuration screen, specify the following values (see the screenshot below): Instance Name: RapidByte Visual Studio Solution Name: RB Select the training course: Introduction to Acumatica Framework Figure: Instance Configuration screen 3. Install the Visual Studio Templates. 4. Prepare the solution in Visual Studio by creating additional folders (see the screenshot below): Create the RapidByte folder in the Site\Pages folder (1) Create the RapidByte and RapidByte > DAC folders in the RB application project (2) The existing SM folder in the Site project contains system pages of the website; do not modify this folder or the files in it.

29 Getting Started 29 Figure: Solution structure for the RapidByte application To find the location of the solution, you can go to the Application Maintenance screen of the Acumatica Framework Configuration Wizard and see the SitePath column for the RapidByte instance. Now you are ready to start application development.

30 Getting Started 30 Summary: Application Overview and Preparations In this part of the course, you have learned that you will create the RapidByte demo application, which consists of six pages: 1. The Countries maintenance page 2. The Customers maintenance page 3. The Sales Orders data entry page 4. The Approve Sales Orders processing page 5. The Sales Order Inquiry inquiry page 6. The Sales Order Printable Form report form Based on the requirements identified in this lesson, you will design the application, which includes the database schema, the application classes, and the UI. In this course, we have designed the demo application for you; you can see the detailed description of the application components in Appendix: Application Design. To deploy a new instance of the Acumatica Framework-based application template and then maintain the deployed applications, you use the Acumatica Framework Configuration Wizard. The wizard also provides installation of specific Visual Studio templates that are used for creating ASP.NET pages in the site and classes in the application project. Now you have the template application ready for development of RapidByte pages. In the next lesson, you will create your first Acumatica Framework application page and test it on the website.

31 Part 1: Maintenance Pages 31 Part 1: Maintenance Pages In this part of the course, you will start with creating the first very simple pages of the application. You will create the maintenance pages that are helper pages used for the input of data on the main pages of the application, data entry and processing pages. The pages of these types will be created further in this course.

32 Part 1: Maintenance Pages 32 Lesson 1: Creating the First Page Countries In this lesson, you will create the first and simplest page in the application. The Countries maintenance page holds the list of countries that can be used for specifying the country attribute of customers. You will start with preparing the generator that produces DAC code from the specified database table. As you advance through this lesson, you will create the CountryMaint business logic controller (BLC, also referred to as graph), add the Countries webpage associated with this graph, and generate the Country data access class (DAC). As a result you will get a page that displays a list of countries in a grid (see the screenshot below). Finally, you will configure navigation to the created page on the website. Figure: The Countries page on the website We recommend that you use the Data Access Class Generator to generate the initial code of data access classes (DACs) in the application. The generator helps you to create the declaration of data access classes, which may have multiple fields and, thus, be time-consuming to code manually. The Data Access Class Generator saves you from typos and confusion. You can then easily maintain the DAC declaration manually once it has been generated. To use the Data Access Class Generator, you need a page with a business logic controller specified in its data source. This lesson provides detailed steps on how to prepare the generator. Once you complete the lesson, you will have the first page added to the RapidByte website. The page provides standard functionality for working with data records, including selection, insertion, edit, and deletion of data records through the grid. Lesson Objective In this lesson, you will create and test the first page of the RapidByte application, which displays a list of countries in the grid. You will see how to generate the initial declaration of a data access class by the table description in the database. You will also know how to configure the application page and create the business logic controller for it.

33 Part 1: Maintenance Pages 33 Adding the CountryMaint Graph To get access to the Data Access Class Generator tool in your application project, you need an application page linked to a business logic controller, so-called graph. In this step, you will start with creating the CountryMaint graph for the Countries page. Do the following: 1. In the RB application project, right-click the RapidByte folder and select Add > New Item. 2. In the window, select the PXGraph template. 3. Type the name of the created class, CountryMaint.cs, and click Add. The definition of the CountryMaint graph will be added to the project. The CountryMaint graph is empty for now, because at this moment it is just needed to link the application page that you will create on the next step to the application project. The Data Access Class Generator opens from the application page in design mode from any application page linked to a graph from the application project where the code should be generated. Later you will add the graph members that provide data and actions for the page. 4. Rebuild the project to be able to specify the graph for an application page. Now create an application page and set the CountryMaint graph in the datasource control on the page.

34 Part 1: Maintenance Pages 34 Adding Page RB In this step, you will add the first ASP.NET page to be able to open the Data Access Class Generator. To add the page, perform the following instructions: 1. In the Pages folder of Site, right-click RapidByte and select Add New Item. 2. In the window, select the ListView template. All application pages must be created from one of the special Acumatica Framework templates. The ListView template has the only grid container to represent a list of data records. 3. Type the name of the new page, RB aspx, and click Add. The new page will be added to the Site > Pages > RapidByte folder and opened in source mode. The page name complies with the Acumatica Framework convention where RB is a two-letter module identifier, 20 means maintenance type of the page, and 10 is the starting sequential number of the maintenance page in the module. For more information on naming conventions, see Acumatica Framework > Design Guidelines > Application Design Guidelines in the documentation. 4. Click the Design button to switch to design mode. Figure: Switch to design mode in Visual Studio By clicking the Source button, you can switch back to source mode.

35 Part 1: Maintenance Pages 35 Figure: View the page in design mode 5. When the visual elements appear, select the ds PXDataSource control. 6. In the Properties window, set TypeName:RB.RapidByte.CountryMaint. Every page should be associated with a graph. If you do not see RB.RapidByte.CountryMaint in the TypeName combo box, make sure that you have built the project before switching to design mode. If the graph is still not visible, right-click any page area and click Refresh to again render the page. 7. Save changes on the pages.

36 Part 1: Maintenance Pages 36 Adding the Country Class In this step, you will generate the first data access class in the project, Country. To add the class, you need to open the Data Access Class Generator, select the database table, select fields, and then generate the class declaration. Proceed as follows: 1. Open RB aspx in design mode. 2. After the visual elements appear, select the ds datasource control. 3. Click the smart tag at the top right corner of the datasource control, as shown below. Figure: Click the datasource control smart tag The Acumatica Framework code generator and layout editors for controls are opened from the smart tag menu of the control. Sometimes it is difficult to click the proper tag. In this case, you can try the following alternative way of opening the smart tag menu: Select the control in the Properties window (see 1 on the screenshot below). Right-click the control header in the design area to open the context menu related to the control (2). Select Show Smart Tag from the menu (3).

37 Part 1: Maintenance Pages 37 Figure: Open smart tag menu 4. In the PXDataSource Tasks dialog box, click Generate Class to open the Data Access Class Generator dialog box. Figure: Open the Data Access Class Generator 5. In the dialog box, select Country in the Name combo box (see 1 on the screenshot below). The list of columns available in the Country database table appears. You have created all database tables used in the RapidByte application when you deployed the training application template. 6. Make sure all columns are selected (2), and click Generate (3). The Country data access class (DAC) is added to the project in the RapidByte\DAC\Country.cs file.

38 Part 1: Maintenance Pages 38 Figure: Generate the Country data access class 7. Open Country.cs to view the generated code, which is shown below. namespace RB.RapidByte using System; using PX.Data; [System.SerializableAttribute()] public class Country : PX.Data.IBqlTable #region CountryCD public abstract class countrycd : PX.Data.IBqlField protected string _CountryCD; [PXDBString(2, IsKey = true, IsUnicode = true)] [PXDefault()] [PXUIField(DisplayName = "CountryCD")] public virtual string CountryCD get return this._countrycd; set this._countrycd = value; #endregion #region Description public abstract class description : PX.Data.IBqlField protected string _Description; [PXDBString(50, IsUnicode = true)]

39 Part 1: Maintenance Pages [PXUIField(DisplayName = "Description")] public virtual string Description get return this._description; set this._description = value; #endregion Correct DisplayName in the CountryCD property annotation to Country ID. The DisplayName parameter of PXUIField defines the label text that is displayed for the data field in the UI. CountryCD is the key field for the class, which is defined by the IsKey=true parameter of the PXDBString attribute as shown below. The PXDefault attribute here marks the field as mandatory. [PXDBString(2, IsKey = true, IsUnicode = true)] [PXDefault()] [PXUIField(DisplayName = "Country ID")] public virtual string CountryCD... In Acumatica ERP, CD is used for natural keys (such as CountryCD), which means keys that are human-readable and can have additional meaning. ID is used for surrogate keys (such as CountryID), which are pure identifiers. You typically display CD keys in the UI and hide ID keys. However, to avoid confusing users with differences between CD and ID keys, we recommend you to specify ID in the label of any key field. 9. Save changes and rebuild the project. Now the data access class that represents countries is ready. In the next step, you will modify the CountryMaint graph for working with Country data records on the application page. Declaration of Data Access Classes Every data access class (DAC) is declared as implementing the PX.Data.IBqlTable interface. Each data access class must have the System.SerializableAttribute attribute. The Country data access class contains two DAC fields: CountryCD and Description. The DAC field declaration consists of two members: A public abstract class that implements the PX.Data.IBqlField interface. This abstract class is used in BQL statements specified in views and attributes added to data field declarations. A public virtual property of a nullable data type that corresponds to the data type of this field. This property keeps the value of the data field. The attributes are added to the property and not to the abstract class of the data field declaration. The abstract class and property have the same name that differ by the case of the first letter. By convention, the abstract class name starts with a lowercase letter, while the property name starts with the same uppercase letter. In BQL statements, the data field is referred to by the abstract class name, while in generated SQL, the columns are referred by the property name. The attributes are specified for properties and not for abstract classes. Use of attributes is one of key techniques in Acumatica Framework-based applications. On DAC fields, you use attributes to define the data field specification that includes multiple parameters such as the data type, default value, and

40 Part 1: Maintenance Pages 40 field caption in the UI. The type attribute, such as PXDBString on the Country.CountryCD field from the code above, is the required attribute of a DAC field. For more information about attributes, see Acumatica Framework > API Reference > Attributes in the documentation.

41 Part 1: Maintenance Pages 41 Modifying the CountryMaint Graph In this lesson, you will add members to the graph that provide data and actions for the Countries maintenance page. Do the following: 1. Open the CountryMaint.cs file. 2. In the CountryMaint business logic controller, declare the Cancel and Save data manipulation actions and the Countries data view, as shown below. public class CountryMaint : PXGraph<CountryMaint> public PXCancel<Country> Cancel; public PXSave<Country> Save; public PXSelect<Country> Countries; Since the Countries page is intended for working with a country list, the Countries data view, which selects Country records from the database, will be specified as the primary data view for the page. The first type parameter of a data view specifies the main DAC. So, Country is the main DAC of the Countries data view. If you set the type parameter of an action to the main DAC of the primary view, the system automatically adds the button corresponding to this action to the page toolbar. So the Cancel and Save buttons will appear on the page toolbar. 3. Save changes and rebuild the project. Data views, which are declared in a graph, provide data for displaying in the container controls on the page. Now you can configure the page to display the list of countries obtained through the Countries data view. Data Views A data view is a graph member of one of PXSelectBase-derived types, such as PXSelect. The data view type is a BQL statement that selects data to be manipulated through the data view. The main DAC of a data view is the first type parameter in the declaration. The data view that is specified as the primary view for the page must be defined the first one in the graph. For more information on PXSelectBase types and BQL, see Acumatica Framework > API Reference > Core Classes > PXSelectBase and Acumatica Framework > API Reference > BQL in the documentation.

42 Part 1: Maintenance Pages 42 Configuring the Grid on the Page In this step, you will add columns to the grid on the page that displays the country list. Do the following: 1. Open the RB aspx page in design mode. 2. Select the ds PXDataSource control. 3. In the Properties window, set the following properties for the ds control: PrimaryView:Countries The TypeName and PrimaryView properties are the only required properties of the control (TypeName has been earlier specified for ds). The buttons are automatically added to the toolbar by the definition of graph actions that have the type parameter set to the main DAC of the primary view. The CountryMaint graph contains the declaration of two buttons, Save and Cancel, so these buttons appears on the page toolbar. If you do not see Countries in the PrimaryView combo box, make sure that you have built the project before switching to design mode. If the view is still not visible, right-click any page area and select Refresh to refresh controls on the page. Now you can configure the data source for the grid and generate columns to the control. 4. Select the grid PXGrid control. 5. In the Properties window, set the following property for the grid PXGrid control: DataMember:Countries DataMember and DataSourceID are two required properties of container controls. The DataMember property specifies the data view to obtain data records into the grid. 6. Click the smart tag of the grid, at the top right corner of the control, as shown below. Figure: Click the Smart Tag of the Grid 7. In the PXGrid Tasks window, click Edit Content Layout, as shown below. The Layout Editor window appears. Figure: Open the Grid Layout Editor 8. In Layout Editor, switch to the Fields tab at the right side of the window. The list of the data fields available through the data view appears. 9. Check both CountryCD and Description (see 1 on the screenshot below), and select the only Columns check box at the bottom of the window (2).

43 Part 1: Maintenance Pages Click Generate (3). The columns corresponding to the selected data fields are added to the bottom left Grid Columns list. Columns are required elements of a grid. When a user edits a row in a grid, they work with default controls generated automatically according the data field definition. 11. Click Ok to save changes to the grid and close Layout Editor. Figure: Generate Columns for the Grid 12. Save changes and refresh the page if the grid is not displayed correctly. Now you can add the URL of the Countries application page to the site map.

44 Part 1: Maintenance Pages 44 Adding the Page to the Site Map In this step, you will prepare the initial site map of the application and add navigation to the created RB aspx page by using the System > Customization > Site Map page. The site map already includes the top-level nodes for the RapidByte application as the following screenshot shows. Figure: Top-level menu nodes in the site map Proceed as follows: 1. Add the grouping nodes to the site map: a. Select the RapidByte > RapidByte > Configuration node in the tree and add the following nodes to it, by clicking Add Row (+): Setup Manage These are the grouping headers for the Work Area tab of the navigation pane, as planned in Application Pages. These headers are nodes to which you will add pages in the following lessons. b. For each of these grouping nodes, select the Expanded check box (the rightmost column in the grid) and leave other parameters by default. The Expanded check box controls whether the given node in the application menu is expanded or collapsed. In this step, you prepare the initial site map for further addition of application pages. You don't add all the application pages to the site map, because they don't exist at the moment. You will add the pages to the site map one by one as you create them while working through the lessons. In your own application, you are free to create any number of tabs and name them as you need. c. Click Save to save changes to the site map. You can see the resulting site map (that you get after the completion of the course) in Application Pages. 2. Now you can add the Countries page (RB201000) to the site map. a. Select the RapidByte > RapidByte > Configuration > Manage node and click Add Row(+) to add a new nested node.

45 Part 1: Maintenance Pages 45 b. Specify the following parameters for the new node: Screen ID: RB Title: Countries Icon: Empty URL: ~/Pages/RapidByte/RB aspx Expanded: Cleared Leave the default settings for the other columns, and click Save (see the screenshot below). Figure: Add the URL of the Countries page to the site map Now the Countries maintenance page is added to the site, and you can find the page on the Configuration tab of the RapidByte navigation pane (see the screenshot below). Figure: Open the Countries page on the website You can open the Countries page. Notice that the Save and Cancel buttons appear at the top of the page. These buttons correspond to the actions declared in the CountryMaint BLC.

46 Part 1: Maintenance Pages 46 To apply changes to the row that you are editing in a grid, press Ctrl+Enter. On pressing of this combination, the modified row is saved to the current session but not yet to the database. To save the changes to the database, click Save on the page toolbar.

47 Part 1: Maintenance Pages 47 Conclusion: Creation of Pages To create an Acumatica Framework application page, you have to: In the application project, define the data access classes that are used on the application page. In the application project, define the business logic controller (graph) that serves as the controller for the application page. The graph contains the definition of data views and actions that can be used on the application page. In the Site\Pages\<Module folder> folder, from one of provided templates, create the ASP.NET page and configure it for working with data provided by the graph. On the System > Customization > Site Map page of the website, add the page URL to the site map, which provides navigation to the page for users. Data access classes (DAC) consist of definition of data fields annotated with attributes. Attributes configure DAC fields in the object model of the application, including the data type, default value, and UI presentation. To generate the initial declaration of a data access class, you can use the Data Access Class Generator provided by Acumatica Framework. You can open the generator from any ASP.NET application page with the TypeName property specified, from the smart tag menu of the datasource control. Graphs, which are application classes derived from PXGraph, provide controllers for logic performed on application pages. A graph contains the definition of data views that provide data retrieval and manipulation and the definition of actions represented by toolbar buttons on the page. To configure ASP.NET container controls on a page, such as forms and grids, you can use the Layout Editor provided by Acumatica Framework. You can open the Layout Editor from the smart tag menu of the control. Layout Editor is the visual editor for the source code of the page. Now you have the first page of the RapidByte application, which represents the list of countries in a grid. In the next lesson, you will create a form for editing of customers.

48 Part 1: Maintenance Pages 48 Lesson 2: Creating the Customers Maintenance Page In this lesson, you will add another maintenance page, a page with a single form for working with customers. To create the page, you will define the Customer data access class and controller that provides data and actions to be used on the page, and then create the ASPX page that provides the user interface for working with Customer data records. The screenshot below shows the final Customers page on the RapidByte website. Figure: The Customers page on the website Lesson Objective In this lesson, you will create a form for editing of customers that can be selected for a sales order. You will also configure the very simple layout by arranging the controls into two columns on the form.

49 Part 1: Maintenance Pages 49 Adding the CustomerMaint Graph and Page RB In this step, you will create a new ASP.NET page to work with customers in the application and the business logic controller (graph) that works with this page. Do the following: 1. In the RapidByte folder of the application project, create the new CustomerMaint.cs file from the PXGraph template. namespace RB.RapidByte public class CustomerMaint : PXGraph<CustomerMaint> 2. Build the project. 3. In the Pages > RapidByte folder of Site, create the new RB aspx page from the FormView template. 4. Open the page in the design mode. 5. Specify the following property for the ds datasource control to bind the page to the gpaph: TypeName:RB.RapidByte.CustomerMaint Now you are ready to generate data access classes to work with the page.

50 Part 1: Maintenance Pages 50 Adding the Customer Class In this step, you will add the new Customer data access class (DAC) to the project. 1. Open Data Access Class Generator and select the Customer table (see the screenshot below). 2. Click CustomerID in the Columns And Attributes list and modify the attributes of this field: a. Remove IsKey = true from the constructor of the DB Identity attribute. b. Delete the UI Field attribute. The CustomerID field is not intended for the user. Figure: Configuring the Customer class in Data Access Class Generator 3. Click CustomerCD in the Columns And Attributes list and modify the following attributes: a. Add IsKey = true to the constructor of the DB String attribute. b. Remove the empty string from the constructor of the Default attribute to prevent insertion of empty strings into the database table. c. Change the display name in the constructor of the UI Field attribute to Customer ID. 4. Click CompanyName and change the display name in the UI Field attribute to Company Name. 5. Click ContactName and change the display name in the UI Field attribute to Contact Name. 6. Click CountryCD and change the display name in the UI Field attribute to Country ID. 7. Click PostalCode and change the display name in the UI Field attribute to Postal Code. 8. Click Generate. The new DAC will be added to DAC\Customer.cs. DAC fields will have the attributes that you have configured in Data Access Class Generator. You could click Generate at once and modify the attributes in code. The PXDefault attribute (the Default attribute in the Data Access Class Generator) specifies the default value for the data field. In PXDefault, you can also specify whether the data field is required for input. By default, the PXDefault attribute makes the field required. You can make the field optional by specifying the PersistentCheck = PXPersistentCheck.Nothing parameter in the attribute constructor. For more information on PXDefault, see Acumatica Framework > API Reference > Attributes > Default Values in the documentation. 9. Rebuild the project. The Customer DAC is ready for now. Go to the next step to add a data view to select data.

51 Part 1: Maintenance Pages 51 Configuring the CustomerMaint Graph and Page RB In this step, you will create a new ASP.NET page to work with products in the application. To add the page, perform the following instructions: 1. In the CustomerMaint class, declare the Customers data view that selects data to be represented on the page (see the code below). public PXSelect<Customer> Customers; The Customers data view provides retrieval and manipulation with instances of the Customer data access class and is used for the form control on the page. 2. Save changes to the file and rebuild the project. 3. Open the RB page in design mode. 4. Specify the following property for the ds datasource control: PrimaryView:Customers 5. Select the form PXFormView control on the page. 6. In the Properties window, set DataMember:Customers for the form control. 7. Save the changes you've made to the page. 8. Open the Layout Editor for the form control (by clicking the smart tag at the top right corner of the control and selecting Edit Content Layout). 9. On the Fields tab, select all fields. 10. Click Generate. The controls are added to the form under the form node. 11. Set the following properties for the Row PXLayoutRule object: ControlSize: XM LabelsWidth: S The Row layout rule adjusts the size and position of controls on the form and arranges the controls into a column. The Row layout rule should start any form layout. 12. Add the Column PXLayoutRule object as follows: a. Select the Row node in the tree and click Layout Rule on the toolbar. b. Move the new LayoutRule node up under the edfax node. c. Set the following properties for the LayoutRule node: StartColumn: True ControlSize: M LabelsWidth: S The resulting layout of the form looks as follows.

52 Part 1: Maintenance Pages 52 Figure: Review the resulting form layout 13. Click Ok to close Layout Editor. Save your changes to the page. 14. Add the page to the site map. To do this, open the System > Customization > Site Map page and add the RB aspx page under the Acumatica Company > RapidByte > RapidByte > Work Area > Manage node with the following parameters: Screen ID: RB Title: Customers Icon: Empty URL: ~/Pages/RapidByte/RB aspx Graph Type: Completed automatically Expanded: Cleared Now the page is ready. Open the Customers page in the RapidByte application in web browser to see how the form looks. The page doesn't include any toolbar buttons and all input controls are text boxes. In the next step, you will modify the graph and page to add standard toolbar buttons and selector controls. Figure: View the Customers page in a web browser

53 Part 1: Maintenance Pages 53 Adding Selectors to the Page In this step, you will modify the business logic controller (graph) of the Customers page and the page itself to add standard buttons to the page and add selector controls. Do the following: 1. In the declaration of the CustomerMaint class, specify Customer as the second type parameter of PXGraph as the following code shows. public class CustomerMaint : PXGraph<CustomerMaint, Customer> public PXSelect<Customer> Customers; Specifying a data access class in this way implicitly adds definition of stadard actions to the graph. For more details, see Standard Buttons of the Page Toolbar. 2. Save changes to the file and rebuild the project. Open the Customers page in the browser. Now it includes a toolbar with the buttons that can be used to save or revert changes, add and delete data records, and navigate back and forth over existing customers. See the screenshot below. Figure: The Customers page with the standard toolbar 3. In the Customer class, add the PXSelector attribute to the CustomerCD field as follows. [PXDBString(15, IsUnicode = true, IsKey = true)] [PXDefault] [PXUIField(DisplayName = "Customer ID")] [PXSelector( typeof(search<customer.customercd>), typeof(customer.customercd), typeof(customer.companyname))] public virtual string CustomerCD... The PXSelector attribute configures a lookup (selector) control that will let the user select existing customers and load them into the form. In the first parameter of the PXSelector attribute, you specify the key value that is inserted into the field. The next positional parameters is the list of data fields that should be displayed in the lookup. Since the application object model is represented by classes that are complex types, you specify the data fields by using the typeof operator. You can list any data fields retrieved by the Search<> BQL query specified in the first parameter of the attribute. [PXSelector(typeof(SalesOrder.orderNbr))] and [PXSelector(typeof(Search<SalesOrder.orderNbr>))] are equivalent definitions. 4. In the Customer class, add the PXSelector attribute to the CountryCD field as follows. [PXDBString(2, IsUnicode = true)]

54 Part 1: Maintenance Pages 54 [PXUIField(DisplayName = "Country ID")] [PXSelector( typeof(search<country.countrycd>), typeof(country.countrycd), typeof(country.description), DescriptionField = typeof(country.description))] public virtual string CountryCD... The PXSelector attribute here configures a selector that can be used to select from the list of existing Country data records. Here you additionally specify the DescriptionField property. The combination of DescriptionField and SelectorMode values defines the UI presentation of the value in the control. In the given case, the Description value is displayed in the UI next to the value that is assigned to the field. 5. Rebuild the project. 6. Open the RB page in design mode, click the form, and open Layout Editor. 7. Delete the edcustomercd and edcountrycd nodes from the tree. The corresponding fields will appear on the Fields tab. The value in the Control type column is Selector now because of the PXSelector attribute. 8. Select both CustomerCD and CountryCD field on the Fields tab and click Generate. 9. Position the new CustomerCD and CountryCD nodes in the tree as they were positioned before (CustomerCD under Row and CountryCD under edcity). 10. Click Ok and save changes to the page. If you open the Customers page in the browser, you will see that the Customer ID and Country ID fields are selectors now. You can click the search button to open a window with the list of data records, customers or countries. When you select a customer data record in the Customer ID selector, the fields of the selected customer are loaded into the form. Figure: Final look of the Customers page Standard Buttons of the Page Toolbar The standard page toolbar buttons include data manipulation (Insert, Delete, Save, Cancel), navigation (Next, Previous, First, Last), and clipboard buttons (Copy/Paste). Every toolbar button corresponds to the action declared in the graph. You can use explicit or implicit declaration of actions to add standard buttons to the toolbar.

55 Part 1: Maintenance Pages 55 In any declaration, the DAC that you specify for actions must be the same as the main DAC of the primary view of the page. The page toolbar manipulates with data records of the main DAC of the primary view. If an action has the DAC other than the main DAC of the primary view, the button will not appear on the toolbar. In the example of the CountryMaint graph, we used the explicit declaration of two actions that correspond to the standard toolbar buttons, Cancel and Save (see the code below). Users need only these two buttons on the Countries page. The users work with a table of records on the page and don't need the other standard buttons, such as Previous and Next for navigation. // Explicit definition of the needed standard buttons public class CountryMaint : PXGraph<CountryMaint> public PXCancel<Country> Cancel; public PXSave<Country> Save;... To add an implicit declaration of standard buttons, specify the second type parameter in the base PXGraph class as the following code shows. By this declaration, the system automatically adds the standard buttons for manipulating the Customer records to the page toolbar, if the main DAC of the primary view specified in the datasource control on the page is also Customer. Below are two equivalent declarations of actions for standard buttons that work with data records of the Customer DAC. All standard buttons are usually used on form edit pages. // Implicit declaration of standard actions public class CustomerMaint : PXGraph<CustomerMaint, Customer> public PXSelect<Customer> Customers; // Explicit declaration of standard actions public class CustomerMaint : PXGraph<CustomerMaint> public PXSave<Customer> Save; public PXCancel<Customer> Cancel; public PXInsert<Customer> Insert; public PXCopyPasteAction<Customer> CopyPaste; public PXDelete<Customer> Delete; public PXFirst<Customer> First; public PXPrevious<Customer> Previous; public PXNext<Customer> Next; public PXLast<Customer> Last; public PXSelect<Customer> Customers; The standard buttons on the page toolbar look like as the following screenshot shows. Figure: Standard buttons on the page toolbar

56 Part 1: Maintenance Pages 56 Conclusion: Simple Form Edit Pages Now you have one more application page, which is a form for editing of customers. You can configure form layout by using Layout Editor for the form. In Layout Editor, add layout rules to the tree of controls that define the size and positions of controls relatively to each other. Start any layout with a Row layout rule added to the topmost position in the tree of controls. Each Row starts a group of controls that are aligned in a column by default. You can add nested layout rules to get more complex layout and override size and positions of controls. In the next lesson, you will add code that clears the Region field once the CountryCD field changes.

57 Part 1: Maintenance Pages 57 Lesson 3: Adding Simple Business Logic to the Customers Page Until now, you've been implementing the application logic only declaratively, by adding attributes to DAC fields, defining graph members, and configuring properties of ASPX controls. For the first time, in this lesson, you will add procedural logic that modifies the current data record when a user modifies its Country ID field. Procedural logic is implemented in event handlers that are triggered by the system when the client posts new or modified data to the server. Lesson Objective Get acquainted with the way you implement business logic in Acumatica Framework-based applications Learn how to use the FieldUpdated event to modify values of the same data record. Get the first introduction to cache objects, which store the data modified by the user between round-trips

58 Part 1: Maintenance Pages 58 Adding Logic on Update of the CountryCD Field In this step, you will add code that clears the Customer.Region value when the Customer.CountryCD value changes. Do the following: 1. In the CustomerMaint.cs file, define the Customer_CountryCD_FieldUpdated() method in the CustomerMaint class as follows. protected void Customer_CountryCD_FieldUpdated( PXCache sender, PXFieldUpdatedEventArgs e) Customer row = (Customer)e.Row; row.region = null; The Customer_CountryCD_FieldUpdated() method is an event handler that meets the delegate type and complies with the event handler naming convention. At run time, the platform analyzes the method name and adds it as a handler of the FieldUpdated event raised on the Customer.CountryCD data field. For more information about events, see Acumatica Framework > API Reference > Event Model in the documentation. The platform triggers events when the data is committed to the server. Events are raised on cache objects each of which works with data records of a certain DAC. The cache object is created by the platform within the graph and provides the intermediate storage of data that is being viewed or modified by the user before it is updated in the database. The data stored in the cache object is preserved between the round-trips of client-server interaction. The cache object on which the event is raised is one of input parameters of the event handler (the PXCache Sender object). FieldUpdated is raised in a chain of row insertion and row updating events and intended for modification of other fields of the same data record. In Customer_CountryCD_FieldUpdated(), you get the currently processed Customer data record from the e.row property and set its Region field to null. 2. Rebuild the project. 3. On the RB aspx page, select the form control and open Layout Editor for it. Set the CommitChanges:true property for CountryCD to enable callback for the control. When the callback is enabled, the page posts the updated data immediately after the user changes the value in the control and moves focus out of the control. The server gets the updated data from the UI and triggers the events according to the event model. 4. Save your changes to the page. Run the Customers page in a web browser. To test the added business logic, open an existing customer, see that the Region value is not null, and select a new Country ID value. The Region value is immediately cleared (see the screenshot below).

59 Part 1: Maintenance Pages 59 Figure: Test the business logic on the Customers page If you do not enable callback for the Country ID control on the form, the platform will not raise the FieldUpdated event when the user updates the value in the control, because the page doesn't submit the data to the server. In this case, the logic will be executed when a user changes a value in another control with the enabled callback (all data from the form is posted to the server on callback), or initiates saving the row to the database (clicks the Save button on the page toolbar).

60 Part 1: Maintenance Pages 60 Conclusion: Business Logic Acumatica Framework-based applications work by the event-driven model. To implement procedural logic (validation of values, processing of data records), you have to handle the appropriate events. On the FieldUpdated event for Customer.CountryCD, you clear the Customer.Region value. Field events are used for validation and insertion of default values. Row events are used for controlling of UI presentation, calculations and complex validation of dependent values of the same row. A chain of events is raised on the server when the client submits the specific data. For more information on events, see Acumatica Framework > API Reference > Event Model in the documentation. In the next lesson, you will create the Sales Orders data entry page, which is the main page of the application.

61 Part 2: Data Entry Pages 61 Part 2: Data Entry Pages In this part of the course, you will create the main data entry page of the application, Sales Orders. On the page, you will add the logic of calculation of sales order totals and insertion the shipment information as soon the customer is specified for the sales order.

62 Part 2: Data Entry Pages 62 Lesson 4: Creating the Sales Order Data Entry Page In this lesson, you will create the Sales Orders page with basic functionality for working with sales orders. The screenshot below shows the final look of the Sales Orders webpage. Figure: The Sales Orders page on the website Lesson Objective Get acquainted with more attributes on DAC fields, PXDBDefault and PXParent, and learn more about PXSelector. Learn how to create master-detail pages based on the FormDetail template. Learn how to define data views that return master-detail data records.

63 Part 2: Data Entry Pages 63 Adding the SalesOrderEntry Graph and Page RB In this step, you will create a new ASP.NET page to work with sales orders in the application and the business logic controller that works with this page. Do the following: 1. In the RapidByte folder of the application project, create the new SalesOrderEntry.cs file from the PXGraph template. namespace RB.RapidByte public class SalesOrderEntry : PXGraph<SalesOrderEntry> 2. Build the project. 3. In the Pages > RapidByte folder of Site, create the new RB aspx page from the FormDetail template. The Acumatica Framework provides the following default Visual Studio templates for.aspx pages: Name Description FormDetail The master-detail editing page with FormView and Grid controls FormTab The record-editing page with FormView and Tab controls FormView The record-editing page with one FormView control ListView The record-editing page with one Grid control TabDetail The master-detail page with Tab and Grid controls TabView The record-editing page with one Tab control 4. Open the page in design mode. 5. Specify the following property for the ds datasource control to bind the page to the graph: TypeName:RB.RapidByte.SalesOrderEntry Now you are ready to generate data access classes to work with the page.

64 Part 2: Data Entry Pages 64 Adding the Product Class In this step, you will add the new Product data access class (DAC) to the project. The procedure is the same as for the Customer DAC. Do the following: 1. Open Data Access Class Generator and select the Product table. 2. Click ProductID (2) in the Columns And Attributes list and modify the attributes of this field: a. Remove IsKey = true from the constructor of the DB Identity attribute (3). b. Delete the UI Field attribute. The ProductID field is not intended for the user. Click ProductCD in the Columns And Attributes list and modify the following attributes: a. Add IsKey = true to the constructor of the DB String attribute. b. Remove the empty string from the constructor of the Default attribute to prevent insertion of empty strings into the database table. c. Change the display name in the constructor of the UI Field attribute to Product ID. Click ProductName in the Columns And Attributes list and modify the following attributes. a. Remove the empty string from the constructor of the Default attribute to prevent insertion of empty strings into the database table. b. Change the display name in the constructor of the UI Field attribute to Product Name. 5. Click Active in the Columns And Attributes list, change the parameter value to true and add PersistingCheck = PXPersistingCheck.Nothing to the constructor of the Default attribute. 6. Click StockUnit in the Columns And Attributes list and modify the following attributes a. Remove the empty string from the constructor of the Default attribute to prevent insertion of empty strings into the database table. b. Change the display name in the constructor of the UI Field attribute to Stock Unit. Click UnitPrice in the Columns And Attributes list and modify the following attributes: a. Change the parameter value in the constructor of the DB Decimal attribute to 2. b. Change the display name in the constructor of the UI Field attribute to Unit Price. Click MinAvailQty in the Columns And Attributes list and modify the following attributes: a. Change the parameter value in the constructor of the DB Decimal attribute to 2. b. Change the display name in the constructor of the UI Field attribute to Min. Avail. Qty. Click Generate. The new DAC will be added to DAC\Product.cs. Now the Product class is ready. In the following parts of the lesson, you will modify attributes of DAC fields in code.

65 Part 2: Data Entry Pages 65 Adding the SalesOrder Class In this step, you will add the SalesOrder data access class, which provide the master data for the Sales Orders page. 1. Open the Data Access Class Generator, and generate the SalesOrder DAC with all fields from the SalesOrder table. The new class is added in the DAC\SalesOrder.cs file. 2. In the SalesOrder.cs file, add the PXSelector attribute to the OrderNbr data field and change the field display name to Order Nbr. as follows. [PXDBString(15, IsKey = true, IsUnicode = true, InputMask=">CCCCCCCCCCCCCCC")] [PXDefault()] [PXUIField(DisplayName = "Order Nbr.")] [PXSelector( typeof(search<salesorder.ordernbr>), typeof(salesorder.ordernbr), typeof(salesorder.orderdate), typeof(salesorder.status), typeof(salesorder.customerid))] public virtual string OrderNbr... The PXSelector attribute defines the selection of data to be displayed in the Order Nbr. lookup control. In the first parameter, you specify the key field whose value is inserted into the SalesOrder.OrderNbr data field. 3. Modify the PXDefault attribute for the OrderDate data field with the typeof(accessinfo.businessdate) parameter, which enables insertion of the current business date for each new sales order. The OrderDate data field holds the creation date of the sales order. [PXDBDate()] [PXDefault(typeof(AccessInfo.businessDate))] [PXUIField(DisplayName = "Order Date")] public virtual DateTime? OrderDate For the PXDefault attribute of the Hold data field, set the PersistingCheck property to PXPersistingCheck.Nothing, so that the data field has a default value, but is not required for input. [PXDBBool()] [PXDefault(false, PersistingCheck = PXPersistingCheck.Nothing)] [PXUIField(DisplayName = "Hold")] public virtual bool? Hold... By default, the PersistentCheck parameter is set to PXPersistingCheck.Null and doesn't allow saving the null value in the field. 5. On the CustomerID data field, add the PXDefault and PXSelector attributes as shown below. [PXDBInt()] [PXDefault] [PXUIField(DisplayName = "Customer ID")]

66 Part 2: Data Entry Pages 66 [PXSelector( typeof(customer.customerid), typeof(customer.customercd), typeof(customer.companyname), SubstituteKey = typeof(customer.customercd))] public virtual int? CustomerID Add the PXDefault attribute with the PersistingCheck = PXPersistingCheck.Nothing parameter to the RequiredDate data field, to specify the default value without making the data field required for input. The Required Date contains the expected date of the order delivery. [PXDBDate()] [PXDefault( typeof(accessinfo.businessdate), PersistingCheck = PXPersistingCheck.Nothing)] [PXUIField(DisplayName = "Required Date")] public virtual DateTime? RequiredDate... Since the PXPersistingCheck.Nothing is specified for the data field, the user can delete the value from the field, which is equal to the current date but default, and then save the sales order without the required date specified. The PersistingCheck parameter can be set to one of the following values: Null - Used to check that the field value is not null. NullOrBlank - Used to check that the field value is not null and is not a string that contains only whitespace characters. Nothing - Used to do not check the field value. By default, the PersistentCheck parameter is set to PXPersistingCheck.Null and doesn't allow to save the null value in the field. 7. Change the display name of the ShippedDate field to Shipped Date. [PXDBDate()] [PXUIField(DisplayName = "Shipped Date")] public virtual DateTime? ShippedDate Set the decimal scale to 2, default value to 0.0, and disable editing of the LinesTotal and TaxTotal data fields. [PXDBDecimal(2)] [PXDefault(TypeCode.Decimal, "0.0")] [PXUIField(DisplayName = "Lines Total")] public virtual decimal? LinesTotal... [PXDBDecimal(2)] [PXDefault(TypeCode.Decimal, "0.0")] [PXUIField(DisplayName = "Tax Total")] public virtual decimal? TaxTotal...

67 Part 2: Data Entry Pages 67 The LinesTotal data field contains the total sales order cost without taxes. The TaxTotal data field contains the sum of taxes in the sales order. 9. On the OrderTotal data field, set the decimal scale to 2 and add the PXDefault attribute with the default value equal to 0.0. The default value simplifies handling of the null value in the OrderTotal field, which is the decimal field used in calculations. [PXDBDecimal(2)] [PXDefault(TypeCode.Decimal, "0.0")] [PXUIField(DisplayName = "Order Total")] public virtual decimal? OrderTotal Save changes and rebuild the project. Now the SalesOrder data access class is ready and you can go to the next step to add the OrderLine DAC to the project.

68 Part 2: Data Entry Pages 68 Adding the OrderLine Class In this step, you will add the OrderLine DAC that provides detail records for a sales order. Do the following: 1. In Data Access Class Generator, select the OrderLine table and generate the class with all fields from the table. The new class is added in the DAC\OrderLine.cs file. 2. Delete the UI Field attribute and add the PXDBDefault and PXParent attributes to the OrderNbr data field as shown below. [PXDBString(15, IsKey = true, IsUnicode = true)] [PXDBDefault(typeof(SalesOrder.orderNbr))] [PXParent(typeof(Select<SalesOrder, Where<SalesOrder.orderNbr, Equal<Current<OrderLine.orderNbr>>>>))] public virtual string OrderNbr... The PXDBDefault attribute specifies the value that is inserted into the OrderLine.OrderNbr field obtained from the SalesOrder.OrderNbr field of the master data record, from the one that is current at run time. Without the attribute, the user gets an error on insertion of an order detail, which says that the required OrderNbr value isn't specified. The PXParent attribute defines the master-detail relationship between the data access classes. In particular, the attribute enables cascade deletion of the detail records when the master data record is deleted. When a sales order is deleted, the corresponding order detail records that match the specified query will also be deleted. The PXParent attribute can be added to any data field of the class. However, we recommend to add it to the declaration of the first foreign key. 3. Add the PXSelector attribute to the ProductID data field that selects only active products, as shown below. [PXDBInt(IsKey = true)] [PXDefault] [PXUIField(DisplayName = "Product ID")] [PXSelector( typeof(search<product.productid, Where<Product.active, Equal<True>>>), typeof(product.productcd), typeof(product.productname), typeof(product.stockunit), typeof(product.unitprice), SubstituteKey = typeof(product.productcd))] public virtual int? ProductID... The SubstituteKey property specifies the field whose value should be shown in the control in the UI instead of the field that is specified in the Search<> command. Usually the property is used to replace a surrogate key for the corresponding natural key, which is presented in the user interface. 4. Specify 0.0 as the default value for the UnitPrice data field, since it is a decimal field used in calculations. [PXDBDecimal(6)] [PXDefault(TypeCode.Decimal, "0.0")] [PXUIField(DisplayName = "Unit Price")]

69 Part 2: Data Entry Pages 69 public virtual decimal? UnitPrice Specify 0.0 as the default value and reduce the decimal scale to 2 for the OrderQty data field as shown below. [PXDBDecimal(2)] [PXDefault(TypeCode.Decimal, "0.0")] [PXUIField(DisplayName = "Quantity")] public virtual decimal? OrderQty Change the display name of the StockUnit field to Stock Unit. [PXDBString(20, IsUnicode = true)] [PXUIField(DisplayName = "Stock Unit")] public virtual string StockUnit Specify 0.0 as the default value and reduce the decimal scale to 2 for the TaxAmt data field as shown below. [PXDBDecimal(2)] [PXDefault(TypeCode.Decimal, "0.0")] [PXUIField(DisplayName = "Tax Amount")] public virtual decimal? TaxAmt Specify 0.0 as the default value for the DiscPct data field as shown below. [PXDBDecimal(6)] [PXDefault(TypeCode.Decimal, "0.0")] [PXUIField(DisplayName = "Discount")] public virtual decimal? DiscPct Specify 0.0 as the default value, reduce the decimal scale to 2, and disable editing of the LinePrice data field in the UI, because the data field will be calculated automatically. [PXDBDecimal(2)] [PXDefault(TypeCode.Decimal, "0.0")] [PXUIField(DisplayName = "Ext. Price", Enabled = false)] public virtual decimal? LinePrice Rebuild the project. Now the two classes representing the master-detail data of a sales order are ready. Go to the next step, to configure a graph for working with sales orders.

70 Part 2: Data Entry Pages 70 Configuring the SalesOrderEntry Graph In this step, you will modify the business logic controller (graph) that works with the Sales Orders page. Do the following: 1. In the declaration of the SalesOrderEntry class, specify SalesOrder as the second type parameter of PXGraph as the following code shows. public class SalesOrderEntry : PXGraph<SalesOrderEntry, SalesOrder> 2. Define the Orders and OrderDetails data views in the graph as shown below. These data views will be used as data members for the form and grid controls on the application page. public PXSelect<SalesOrder> Orders; public PXSelect<OrderLine, Where<OrderLine.orderNbr, Equal<Current<SalesOrder.orderNbr>>>> OrderDetails; The framework automatically executes each data view that returns the selected data when the data view is requested from the UI. The Orders data view returns the master record, while the OrderDetails returns the list of details by the specified key, OrderNbr. The relationship between the data sets is defined by the Current<> BQL query parameter. The OrderDetails data view returns the detail data records for the current sales order obtained through the first data view. For more information, see the section below. Now the graph is ready for working with the application page. Go to the next step, to configure the ASP.NET page. Master-Detail Relationship Between Data Views The framework executes data views in the order requested by the webpage. You don't have to execute a data view to retrieve data for the UI. In case of the Sales Orders page, the framework first executes the Orders data view to retrieve the master data record, and then executes the OrderDetails data view. To pass the OrderNbr field value as a parameter to the OrderDetails data view, we use the Current property value of the Orders data view. The last data record retrieved by the Orders data view is available through the Current property of the data view. (We expect to have only one master record available at a time.) Also, when you create the new master data record, it also gets available through the Current property value of the Orders data view.

71 Part 2: Data Entry Pages 71 Configuring Page RB In this step, you will configure the ASP.NET page that works with sales orders in the application. To add the page, perform the following instructions: 1. Open the RB aspx page in design mode. 2. Specify the following property for the ds datasource control: PrimaryView:Orders 3. Select the form PXFormView control on the page. 4. In the Properties window, set DataMember:Orders. Now you can generate the controls for the form control. 5. Open Layout Editor for the form PXFormView control (by clicking the smart tag in the top right corner of the control and selecting Edit Content Layout). 6. On the Fields tab, select all fields and then click Generate. The corresponding controls will be added to form. 7. Organize the controls into three columns, as the screenshot below shows. Figure: Organize controls on the form To organize the controls into three columns, you have to add a row and two column layout rules to the tree of controls and split the data fields between them. The first column starts with the Row layout rule. To add a column, click Layout Rule and set StartColumn:True for the appeared LayoutRule. Drag and drop the controls into the columns or move the controls by using the Up and Down arrow buttons on the toolbar (see the screenshot below). Figure: Click Up or Down buttons to Move a control in the tree 8. Set the following additional properties for Row:

72 Part 2: Data Entry Pages ControlSize: S LabelsWidth: S Set the following additional properties for both Column node: ControlSize: XM LabelsWidth: S 10. Add one more LayoutRule object, place it above the eddescription node, and set the ColumnSpan property to 2 (see the screenshot below). Figure: Adding the ColumnSpan object A LayoutRule object with ColumnSpan set to 2 stretches the following control onto two columns. 11. Set the following property for the edshippeddate, edlinestotal, edtaxtotal and edordertotal nodes: Enabled: False 12. Click Ok to save the generated controls and to close Layout Editor. Now you can generate the columns and controls for the grid. 13. Select the grid PXGrid control at the bottom of the page. In the Properties window, set DataMember:OrderDetails. 14. Open Layout Editor for the grid PXGrid control. 15. On the Fields tab (see the screenshot below), select all fields by clicking Select All (a) and select the Columns check box below the field list (b). Clear the Controls check box (c), because we don't need to generate controls for this grid. Click Generate (d).

73 Part 2: Data Entry Pages 73 Figure: Adding columns to the grid Columns are the only required items for a grid. Controls are needed in certain cases. You can learn more about columns and controls of the grid in the T200 Acumatica Framework Fundamentals course. 16. Click Ok to save the generated controls and to close Layout Editor. Save changes. 17. Add the page to the site map. To do this, open the System > Customization > Site Map page and add the RB aspx page under the Acumatica Company > RapidByte > RapidByte > Work Area > Enter node with the following parameters: Screen ID: RB Title: Sales Orders Icon: Empty URL: ~/Pages/RapidByte/RB aspx Graph Type: Completed automatically Expanded: Cleared Now the page is ready and you can view it in a web browser. The Sales Orders data entry page provides only basic functionality. It allows a user to create new sales orders, edit or delete them, and add products to the order as order details.

74 Part 2: Data Entry Pages 74 Figure: The Sales Orders data entry page

75 Part 2: Data Entry Pages 75 Conclusion: Master-Detail Pages When you work with master-detail data access classes, the master key field is specified in the PXDBDefault attribute on the foreign key field of the detail class. To enable cascade deletion of detail records when a master record is being deleted, you have to add the PXParent attribute to one of foreign key fields of the detail class. For the page, the master-detail data is provided by two data views, in which the data view that retrieves the details is linked to the master data record by the Current parameter of the BQL query. Now you have created the Sales Orders page with two containers bound to data views of the SalesOrderEntry graph, as the figure below shows. Figure: Configuring the Sales Orders page The Orders is the first view in the SalesOrderEntry graph, so it is the primary data view. The SalesOrder is the main DAC of the Orders data view and the OrderLine is the main DAC of the OrderDetails data view. In the next lesson, you will add automatic insertion of product data taken from the product parameters specified for an order line.

76 Part 2: Data Entry Pages 76 Lesson 5: Adding Simple Business Logic to the Sales Orders Page In this short lesson, you will implement automatic insertion and update of product data, which is executed every time a user specifies the product for an order line. Lesson Objective Get aquainted how to configure a combo box by using the PXStringList attribute See once more how to use FieldUpdated event to autocomplete values of the same data record. Learn one of possible ways to retrieve a data record from the database in code by using the static PXSelectorAttribute.Select<>() method.

77 Part 2: Data Entry Pages 77 Configuring a Combo Box In this step, you will configure a combo box control for the Status field. Do the following: 1. In the SalesOrder.cs file, add the following OrderStatus class, which defines possible value for the status of a sales order, below the SalesOrder class. public class OrderStatus public const string Open = "O"; public const string Hold = "H"; public const string Approved = "A"; public const string Completed = "C"; 2. public class UI public const public const public const public const string string string string Open = "Open"; Hold = "On Hold"; Approved = "Approved"; Completed = "Completed"; Add the PXStringList attribute to the Status field of the SalesOrder data access class (DAC) and set the default value to OrderStatus.Open as follows. [PXDBString(1, IsFixed = true)] [PXDefault(OrderStatus.Open)] [PXUIField(DisplayName = "Status")] [PXStringList( new string[] OrderStatus.Open, OrderStatus.Hold, OrderStatus.Approved, OrderStatus.Completed, new string[] OrderStatus.UI.Open, OrderStatus.UI.Hold, OrderStatus.UI.Approved, OrderStatus.UI.Completed )] public virtual string Status... In the first parameter of the PXStringList constructor, you specify the list of possible values for the field, while in the second parameter, you specify the labels corresponding to the values and displayed in the UI. 3. Rebuild the project. 4. Open Layout Editor for the form control on the RB aspx page to regenerate the input control for the Status field. 5. Delete the edstatus node from the tree, check the box for the Status field on the Fields tab, and click Generate. 6. Move the new edstatus node in the tree to its former position and click Ok. 7. Save the changes to the page.

78 Part 2: Data Entry Pages 78 If you open the Sales Orders page in the browser now, you will see that the input control for the Status field is a combo box. You can select a value from Open, On Hold, Approved, and Completed (see the screenshot below). Figure: The combo box control for the Status field on the Sales Orders page

79 Part 2: Data Entry Pages 79 Setting the Combo Box Value at Run Time In this step, you will disable the Status field on the Sales Orders page and define an event handler that automatically sets the Status value when a user changes the Hold value. Do the following: 1. In the SalesOrderEntry.cs file, add the following SalesOrder_Hold_FieldUpdated() method to the SalesOrderEntry class. protected virtual void SalesOrder_Hold_FieldUpdated( PXCache sender, PXFieldUpdatedEventArgs e) SalesOrder order = (SalesOrder)e.Row; if (order.hold == true) order.status = OrderStatus.Hold; else order.status = OrderStatus.Open; The SalesOrder_Hold_FieldUpdated() method is a handler of the FieldUpdated event raised for the Hold field. The method is executed each time the Hold value changes, and the changes are committed to the server from the page. The framework treats the SalesOrder_Hold_FieldUpdated() method as the event handler by the method name and definition. The event triggers on the model level on the DAC field in the cache object that holds the SalesOrder records and not on the ASP.NET control. FieldUpdated is one of events raised in a chain according to the 'Updating a data record' scenario. The FieldUpdated event is used to insert values into the fields that depend from a field of the same DAC. When the server obtains the updated record from the UI, the application triggers the events according to the 'Updating a data record' scenario. For the event scenarios and the description of events, see in Acumatica Framework > API Reference > Event Model in the documentation. 2. Build the project. 3. Open Layout Editor for the form control on the RB aspx page. 4. Select the edhold node in the tree and set the CommitChanges property to True on the Properties tab. 5. Select the edstatus node in the tree and set the Enabled property to False. 6. Click Ok and save the changes to the page. Because you've set the CommitChanges property to true for the Hold field, each time you change the Hold value in the UI and move focus from the field the page sends a callback to the server. As a result, the FieldUpdated event handler is executed and sets the Status value (see the screenshot below). Notice that the Status field is disabled and you can't change its value manually.

80 Part 2: Data Entry Pages 80 Figure: Setting the status by changing the Hold value on the Sales Orders page

81 Part 2: Data Entry Pages 81 Inserting Product Details into an Order Line In this step, you will implement insertion of product data taken from the product parameters every time a user updates Product ID in an order line on the Sales Orders page. To do this, you will add the OrderLine_ProductID_FieldUpdated() event handler. Do the following: 1. In SalesOrderEntry.cs, add the OrderLine_ProductID_FieldUpdated() event handler to the SalesOrderEntry class as follows. protected virtual void OrderLine_ProductID_FieldUpdated( PXCache sender, PXFieldUpdatedEventArgs e) OrderLine line = (OrderLine)e.Row; Product product = PXSelectorAttribute.Select<OrderLine.productID>( sender, line) as Product; if (product!= null) line.unitprice = product.unitprice; line.stockunit = product.stockunit; else line.unitprice = null; line.stockunit = null; In the OrderLine_ProductID_FieldUpdated() method, you update the fields with values obtained from the database. In the method, you obtain the data record, which is being updated, from the event arguments passed in the e object. To get the product unit price and stock unit values, you invoke the static Select<>() method of the PXSelector attribute that executes the database query. In the type parameter of the method, you specify the OrderLine.productID data field, whose value is taken from the order object and passed to the SELECT query. On PXSelectorAttribute.Select<>(), the framework selects the data record from the database, where Product.productID (the key field of the selector on OrderLine.productID), is equal to the value obtained from the same field of the line data record. The PXSelectorAttribute.Select<>() method retrieves the data record as an object that you have to cast to the needed DAC, which is Product here. If no data record has been found in the database, the method returns null, and you also insert nulls into the shipment details. On the FieldUpdated event, you modify the data record in memory before it is updated in the cache object (see the 'Updating a data record' scenario) and do not save anything to the database. 2. Rebuild the project. 3. On the RB aspx page, select the grid control and open Layout Editor for it. Set the CommitChanges:true property for ProductID to enable callback for the column. This enables the event to trigger every time the user changes the value within the column and moves focus out of it. 4. Save the changes. Open the Sales Orders page in a web browser. Create a new sales order (see item 1 on the screenshot below), insert a new order line (2), and select the product for it (3). Check whether the product details are inserted correctly: unit price and stock unit. Select a different product in the Product ID column and check whether the order line details have been updated.

82 Part 2: Data Entry Pages 82 Figure: Compare the inserted values with values displayed in the selector

83 Part 2: Data Entry Pages 83 Conclusion: Usage of Combo Boxes and Autoinsertion of Values To configure a combo box as an input control for a data field, you use the PXStringList attribute. You place the attribute on the definition of the data field in the data access class. You specify the list of possible value assigned to the field and the list of labels that are displayed in the UI. Acumatica Framework events are raised at the model level and not on the UI. The events are raised on DAC fields and rows in cache objects of the graph, and have nothing to do with ASP.NET controls. To update fields of the same data record, you can handle the FieldUpdated event for the data field from which the other ones depend. The FieldUpdated event is raised in the data record insertion and update event chains before the row events are raised and the data record is updated in the cache object. If you want the event to trigger immediately after the user changes the value in the UI, enable the callback for the control or column by specifying the CommitChanges property to True for the control or column on the ASP.NET page. To obtain a data record in an event handler, you can invoke the PXSelectorAttribute.Select<>() method that uses the BQL query from PXSelector on the specified field. This method enables you to reuse the BQL query defined on the data field and supports maintainability of the code. You can also select a data record by using the Select() method on a data view, or the static Select<>() method of the needed data view type. You can learn more about retrieving data records from the database in code in the T200 Acumatica Framework Fundamentals course. In the next lesson, you will add calculation of sales order and detail totals that is automatically executed while the user edits the document.

84 Part 2: Data Entry Pages 84 Lesson 6: Calculating Totals In this lesson, you will implement automatic calculation of sales order and detail totals displayed on the Sales Orders page. Course Objective Get the basic understanding of the events to handle for calculation and update of data fields from code.

85 Part 2: Data Entry Pages 85 Calculating the Extended Price of an Order Line In this step, you will add calculation of the extended price of a order line by the given formula: extended price = product quantity * unit price * (1 - discount / 100). Since you need to update the LinePrice data field that depends on the data fields of the same record, UnitPrice, OrderQty, and DiscPct, you will recalculate the extended price on FieldUpdated events for the latter fields. Do the following: 1. In the SalesOrderEntry graph, define the CalcLinePrice() method as follows. protected decimal? CalcLinePrice(decimal? unitprice, decimal? qty, decimal? discount) return unitprice * qty * (1 - discount / 100); The CalcLinePrice method enables you to reuse the calculation code. Though the method takes nullable parameters, you don't have to check variables for null before they are used, because you've defined the default 0.0 value for each of these data fields in the OrderLine DAC. 2. In the SalesOrderEntry graph, invoke the CalcLinePrice() method in the FieldUpdated() event handlers for the UnitPrice, OrderQty, and DiscPct data fields as follows. protected virtual void OrderLine_UnitPrice_FieldUpdated( PXCache sender, PXFieldUpdatedEventArgs e) OrderLine line = (OrderLine)e.Row; line.lineprice = CalcLinePrice(line.UnitPrice, line.orderqty, line.discpct); protected virtual void OrderLine_OrderQty_FieldUpdated( PXCache sender, PXFieldUpdatedEventArgs e) OrderLine line = (OrderLine)e.Row; line.lineprice = CalcLinePrice(line.UnitPrice, line.orderqty, line.discpct); protected virtual void OrderLine_DiscPct_FieldUpdated( PXCache sender, PXFieldUpdatedEventArgs e) OrderLine line = (OrderLine)e.Row; line.lineprice = CalcLinePrice(line.UnitPrice, line.orderqty, line.discpct); As in the case of initialization of dependent fields (Inserting Product Details into an Order Line), in the code above, you implement calculation of each field, which depends from other fields of the same DAC, in the FieldUpdated event. 3. Rebuild the project. 4. On the RB aspx page, enable the callback by setting the CommitChanges:True property for the OrderQty column of the grid (as the screenshot demonstrates):

86 Part 2: Data Entry Pages 86 Figure: Enable the callback on the grid column 5. Save the changes. Open the Sales Orders page in a web browser. Create a new sales order and add a product to it. Specify the order line quantity and check whether the extended price has been updated. Because you've set CommitChanges to true for the OrderQty field, when you change its value and move the focus to the next field in the same line, the modifications to the line are immediately sent to the server. As a result, the system raises events on the OrderLine cache object and the extended price of the line recalculated. The page automatically commits changes to the server when you move to the next line or press the Ctrl +Enter key combination, which finishes the editing of the current line. For example, specify the discount and select another line or press Ctrl+Enter. You can see that the discount is immediately applied and the Ext. Price value is updated (see the screenshot below). Figure: Test the extended price calculation

87 Part 2: Data Entry Pages 87 Calculating the Lines Total and Tax Total of a Sales Order In this step, you will add calculation of the lines and tax totals of a sales order by the given formulas: lines total = sum of the extended prices on all order details, tax total = sum of the tax amounts on all order details. Since you update the master data fields, SalesOrder.LinesTotal and SalesOrder.TaxTotal, that depend on the data fields of the detail data record, OrderLine.LinePrice and OrderLine.TaxAmt you implement update in three event handlers for the detail data record, OrderLine_RowInserted(), OrderLine_RowUpdated(), and OrderLine_RowDeleted(). In these events, you update sales order totals after an order detail has been inserted, updated, or marked as deleted in the cache object. If you update master data fields before the order detail is modified in the cache object, you may get inconsistent data in the master record. For instance, if an order detail hasn't been added to the document due to a validation error, the lines total may have already been increased. Do the following: 1. In the SalesOrderEntry graph, define the OrderLine_RowInserted(), OrderLine_RowUpdated(), and OrderLine_RowDeleted() as follows. protected virtual void OrderLine_RowInserted( PXCache sender, PXRowInsertedEventArgs e) OrderLine line = (OrderLine)e.Row; SalesOrder order = Orders.Current; bool isupdated = false; if (line.lineprice!= null) order.linestotal += line.lineprice; isupdated = true; if (line.taxamt!= null) order.taxtotal += line.taxamt; isupdated = true; if (isupdated) Orders.Update(order); protected virtual void OrderLine_RowUpdated( PXCache sender, PXRowUpdatedEventArgs e) OrderLine newline = (OrderLine)e.Row; OrderLine oldline = (OrderLine)e.OldRow; SalesOrder order = Orders.Current; bool isupdated = false; if (!sender.objectsequal<orderline.lineprice>(newline, oldline)) if (oldline.lineprice!= null) order.linestotal -= oldline.lineprice; if (newline.lineprice!= null) order.linestotal += newline.lineprice; isupdated = true; if (!sender.objectsequal<orderline.taxamt>(newline, oldline)) if (oldline.taxamt!= null)

88 Part 2: Data Entry Pages 88 order.taxtotal -= oldline.taxamt; if (newline.taxamt!= null) order.taxtotal += newline.taxamt; isupdated = true; if (isupdated) Orders.Update(order); protected virtual void OrderLine_RowDeleted( PXCache sender, PXRowDeletedEventArgs e) OrderLine line = ( OrderLine)e.Row; SalesOrder order = Orders.Current; PXEntryStatus orderstatus = Orders.Cache.GetStatus(order); bool isdeleted = orderstatus == PXEntryStatus.InsertedDeleted orderstatus == PXEntryStatus.Deleted; if (isdeleted) return; bool isupdated = false; if (line.lineprice!= null) order.linestotal -= line.lineprice; isupdated = true; if (line.taxamt!= null) order.taxtotal -= line.taxamt; isupdated = true; if (isupdated) Orders.Update(order); In each of these events, you obtain the sales order to be updated through the Current property of the Orders data view that works with the SalesOrder cache object. The Current property of the Orders data view retrieves the data record that is currently selected in the UI. The order detail data record that has been inserted, updated, or marked as deleted in the cache object is obtained from the event arguments, the e.row object. At the end if each method, you invoke the Orders.Update(order) method to update the data record in the cache object that works with instances of the SalesOrder DAC. 2. Rebuild the project. Open the Sales Orders page in a web browser. Create a new sales order and add several products to it. Check whether the lines total and tax total are correctly calculated when you add products, modify their parameters, or delete products from the order (see the screenshot below).

89 Part 2: Data Entry Pages 89 Figure: Test calculation of the lines and tax totals

90 Part 2: Data Entry Pages 90 Calculating the Order Total Finally, you will add calculation of the sales order total by the given formula: order total = lines total + tax total. Since the SalesOrder.OrderTotal data field depends on the fields of the same record, SalesOrder.LinesTotal and SalesOrder.TaxTotal, you will recalculate the order total on FieldUpdated events for these fields. Do the following: 1. Add the SalesOrder_LinesTotal_FieldUpdated() and SalesOrder_TaxTotal_FieldUpdated() event handlers to the SalesOrderEntry class as follows. protected virtual void SalesOrder_LinesTotal_FieldUpdated( PXCache sender, PXFieldUpdatedEventArgs e) SalesOrder order = (SalesOrder)e.Row; order.ordertotal = order.linestotal + order.taxtotal; protected virtual void SalesOrder_TaxTotal_FieldUpdated( PXCache sender, PXFieldUpdatedEventArgs e) SalesOrder order = (SalesOrder)e.Row; order.ordertotal = order.linestotal + order.taxtotal; 2. Rebuild the project. Open the Sales Orders page in a web browser. Create a new sales order and add several products to it. Check whether the order total is calculated correctly as soon as either of Lines Total or Tax Total field is changed (see the screenshot below). Figure: Test the order total calculation

91 Part 2: Data Entry Pages 91 Conclusion: Calculations For the Sales Orders page, you've added the calculation logic of sales order and detail totals. To calculate a field of the same data record, you implemented the FieldUpdated event handlers for the data fields on which the calculated field depends. To find the sum of extended prices for the order total data field, you've implemented calculation in three RowInserted, RowUpdated, and RowDeleted events on the detail DAC. For calculations, instead of implementing a bunch of event handlers, you can use the PXFormula attribute. PXFormula handles the RowInserted, RowUpdated, and RowDeleted events in a similar way as you've handled these events to update SalesOrder.LinesTotal and SalesOrder.TaxTotal fields. You can see the examples of PXFormula use in the T200 Acumatica Framework Fundamentals course and in the documentation: Acumatica Framework > API Reference > Attributes > Referential integrity and Calculations.

92 Part 3: Inquiry Pages 92 Part 3: Inquiry Pages In this part of the course, you will create the Sales Order Inquiry page. Inquiry pages usually display a list of data records selected by the specified filter.

93 Part 3: Inquiry Pages 93 Lesson 7: Creating the Sales Order Inquiry Page In this lesson, you will create the Sales Order Inquiry page that provides the list of documents selected by the specified customer (see the screenshot of the page below). Figure: The Sales Orders Inquiry page on the website

94 Part 3: Inquiry Pages 94 Adding the SalesOrderInq Graph In this step, you will add the business logic controller that works with the Sales Order Inquiry page. Do the following: 1. In the RapidByte folder of the application project, create the new SalesOrderInq.cs file from the PXGraph template. The graph definition should look as follows. namespace RB.RapidByte public class SalesOrderInq : PXGraph<SalesOrderInq> 2. In the SalesOrderInq graph, define the SalesOrderFilter data access class with two unbound data fields,customerid and Status. Data fields of the SalesOrderFilter class will be used as filtering parameters on the inquiry page. The definition of the SalesOrderFilter DAC looks as follows. [Serializable] public class SalesOrderFilter : IBqlTable #region CustomerID public abstract class customerid : IBqlField [PXInt] [PXDefault] [PXUIField(DisplayName = "Customer ID")] [PXSelector( typeof(customer.customerid), typeof(customer.customercd), typeof(customer.companyname), SubstituteKey = typeof(customer.customercd))] public virtual int? CustomerID get; set; #endregion #region Status public abstract class status : PX.Data.IBqlField [PXString(1, IsFixed = true)] [PXUIField(DisplayName = "Status")] [PXStringList( new string[] OrderStatus.Open, OrderStatus.Hold, OrderStatus.Approved, OrderStatus.Completed, new string[] OrderStatus.UI.Open, OrderStatus.UI.Hold, OrderStatus.UI.Approved, OrderStatus.UI.Completed )] public virtual string Status get; set; #endregion The filter class is defined as an ordinary DAC that consists of only unbound data fields. Data fields are unbound because we use them only for UI and we do not retrieve data records of

95 Part 3: Inquiry Pages 95 this class from the database. We will use this class to compose the BQL query that returns data records selected by the customer specified in the filtering parameter displayed in the UI. 3. In the SalesOrderInq graph, define the Filter data view of the specific PXFilter type as follows. Define the Cancel action to add the Cancel button to the page that clears the filter. public PXCancel<SalesOrderFilter> Cancel; public PXFilter<SalesOrderFilter> Filter; The PXFilter type of data views is used to provide data selection parameters on pages. The data view of this type always returns one record that consists of the filtering parameters specified by the user in the UI. The PXFilter data view never requests data from the database. The type parameter of the PXFilter data view must be the DAC that provides filtering parameters, which is SalesOrderFilter in our case. The Filter data view must be declared as the first data view in the graph and specified as the primary view for the datasource control on the page. 4. In the SalesOrderInq graph, define the SalesOrders data view that retrieves all data records if no customer and status are specified in the filter, or the data records selected by the specified customer and status. public PXSelectReadonly<SalesOrder, Where2<Where<Current<SalesOrderFilter.customerID>, IsNull, Or<SalesOrder.customerID, Equal<Current<SalesOrderFilter.customerID>>>>, And<Where<Current<SalesOrderFilter.status>, IsNull, Or<SalesOrder.status, Equal<Current<SalesOrderFilter.status>>>>>>> Orders; The PXSelectReadonly type of the data view specifies that the data is displayed in read-only mode in the UI. Because of the data view type, the framework disables edit controls in the UI for data fields retrieved through the data view. The resulting definition of the SalesOrderInq graph is given below. public class SalesOrderInq : PXGraph<SalesOrderInq> [Serializable] public class SalesOrderFilter : IBqlTable #region CustomerID public abstract class customerid : IBqlField [PXInt] [PXDefault] [PXUIField(DisplayName = "Customer ID")] [PXSelector( typeof(search<customer.customerid>), typeof(customer.customercd), typeof(customer.companyname), SubstituteKey = typeof(customer.customercd))] public virtual int? CustomerID get; set; #endregion #region Status public abstract class status : PX.Data.IBqlField [PXString(1, IsFixed = true)] [PXUIField(DisplayName = "Status")] [PXStringList( new string[] OrderStatus.Open, OrderStatus.Hold,

96 Part 3: Inquiry Pages 96, OrderStatus.Approved, OrderStatus.Completed new string[] OrderStatus.UI.Open, OrderStatus.UI.Hold, OrderStatus.UI.Approved, OrderStatus.UI.Completed )] public virtual string Status get; set; #endregion public PXCancel<SalesOrderFilter> Cancel; public PXFilter<SalesOrderFilter> Filter; public PXSelectReadonly<SalesOrder, Where2<Where<Current<SalesOrderFilter.customerID>, IsNull, Or<SalesOrder.customerID, Equal<Current<SalesOrderFilter.customerID>>>>, And<Where<Current<SalesOrderFilter.status>, IsNull, Or<SalesOrder.status, Equal<Current<SalesOrderFilter.status>>>>>>> Orders; 5. Rebuild the project. Now the graph that works with the inquiry page is ready. Go to the next step to add the ASP.NET page.

97 Part 3: Inquiry Pages 97 Adding Page RB In this step, you will create a new ASP.NET page that provides inquiry of sales orders by the specified customer. To add the page, perform the following instructions: 1. In the Pages > RapidByte folder of Site, create the new RB aspx page from the FormDetail template. 2. Open the created page in design mode and specify the following properties for the ds datasource control: 3. TypeName: RB.RapidByte.SalesOrderInq PrimaryView: Filter Select the form PXFormView control on the page and set the DataMember:Filter property for it. Now you can generate controls for the form, which represent filtering parameters. 4. Open Layout Editor for the form control. 5. On the Fields tab, click Select All and Generate. 6. Select the Row node in the tree and set the following properties for it: Merge:True ControlSize: S LabelsWidth: S Set the following properties for the edcustomerid node: CommitChanges: True Size: XM Set the following properties for the edstatus node: CommitChanges: True LabelWidth: 50px Click Ok to close Layout Editor. 10. Select the grid PXGrid control on the page and set the following properties for it: DataMember: Orders SkinID: Inquire 11. Open Layout Editor for the grid. 12. On the Fields tab, select any fields that you want to see for each sales order on the inquiry page. In our example, we select the OrderNbr, OrderDate, Status, CustomerID, ShippedDate, and OrderTotal data fields. 13. Select the only Columns check box below the field list. Click Generate. 14. Close Layout Editor and save changes on the page. 15. Add the page to the site map. To do this, open the System > Customization > Site Map page and add the RB aspx page under the Acumatica Company > RapidByte > RapidByte > Work Area > Explore node with the following parameters: Screen ID: RB Title: Sales Order Inquiry Icon: Empty

98 Part 3: Inquiry Pages 98 URL: ~/Pages/RapidByte/RB aspx Graph Type: Completed automatically Expanded: Cleared Open the Sales Order Inquiry page in a web browser. Select a customer in the Customer ID filter and the status in the Status filter and check whether the list has been filtered by the specified values (see the screenshot below). Click Cancel to clear the filter. Figure: Test the filter on the Sales Order Inquiry Page

99 Part 3: Inquiry Pages 99 Conclusion: Inquiry Pages To provide filter for an inquiry page, you can use the specific PXFilter data view type. In the Filter data view of this type, you specify the class that provides filtering parameters. Typically, you define a separate DAC that consist of only unbound data fields to specify the class in the PXFilter data view. On the ASPX page, you have to enable the callbacks for controls that display the filtering parameters. In the data view that provides data for the grid on the inquiry page, you compose the BQL query that selects data records by the specified filter. Avoid using the PXFilter data view type with DACs which have at least one key field defined, i.e. contain fields having the IsKey=true parameter in the type attribute.

100 Part 4: Processing Pages 100 Part 4: Processing Pages In this part of the course, you will create the processing page that provides mass approval of sales orders.

101 Part 4: Processing Pages 101 Lesson 8: Creating the Approve Sales Orders Page In this lesson, you will create a page for processing of sales orders. The processing operation changes the status of a sales order to Approved. The screenshot below shows the Approve Sales Orders page on the RapidByte website. Figure: The Approve Sales Orders page on the website

102 Part 4: Processing Pages 102 Implementing the Approval Operation In this step, you will define the ApproveOrder() method that processes a sales order and sets the status to Approved. Also, you will add the Approve button to the Sales Orders page that invokes the method to process the sales order currently opened on the data entry page. The same ApproveOrder() method will be used on the processing page. Do the following: 1. In the SalesOrderEntry graph, define the ApproveOrder() method as follows. public void ApproveOrder(SalesOrder order, bool ismassprocess = false) Orders.Current = order; if (order.status == OrderStatus.Hold) throw new PXException(String.Format( "Order 0 is On Hold and cannot be approved.", order.ordernbr)); else if (order.status!= OrderStatus.Open) throw new PXException(String.Format( "Order 0 is already approved.", order.ordernbr)); order.status = OrderStatus.Approved; Orders.Update(order); Persist(); if (ismassprocess) PXProcessing.SetInfo(String.Format( "Order 0 has been successfully approved.", order.ordernbr)); In the ApproveOrder() method, you set the Status field to Approved flag for the order obtained from the input parameter of the method. To work with a SalesOrder data record, you use the SalesOrderEntry graph; after the status is set to Approved for the object in memory, you invoke the Orders.Update() method to update the order in the cache object, and then call the Persist() method to save changes to the database. The ismassprocess flag means that the method is invoked from the mass processing page, where a user can select multiple sales orders and run the operation for them. In the case of mass processing, you return the successful processing message to the UI by using the static PXProcessing.SetInfo() method. To return a processing error to the UI, you throw the PXException with the specified error message. For internationalization support and better maintainability of the application, you should use localizable constants instead of hard-coded strings in the application. For more information, see Acumatica Framework > Programming Tasks > Localizing Applications in the documentation. 2. In the SalesOrderEntry graph, define the Approve action as follows and invoke the processing method in the approve() handler for this action. public PXAction<SalesOrder> Approve; [PXProcessButton] [PXUIField(DisplayName = "Approve")] protected virtual IEnumerable approve(pxadapter adapter) foreach (SalesOrder order in adapter.get()) Actions.PressSave();

103 Part 4: Processing Pages 103 PXLongOperation.StartOperation(this, delegate() SalesOrderEntry graph = PXGraph.CreateInstance<SalesOrderEntry>(); graph.approveorder(order); ); yield return order; This is the typical definition of a processing action that is invoked from a data entry page. The approve() method meets the delegate type of an action handler. Also, the action handler must have the same name as the PXAction field but with another case of the first letter, as the code above shows. To run the ApproveOrder() processing method within the approve() action handler, you invoke the PXLongOperation.StartOperation() that takes the anonymous method in which you create a separate instance of the graph and invoke the ApproveOrder() method for processing of a sales order. The delegate you pass to StartOperation() is executed in a separate thread. Before you run the operation, you invoke the Actions.PressSave() method to save the last changes made on the data entry page to be sure to process the latest version of the sales order. Use the PXGraph.CreateInstance<T>() method to instantiate graphs. 3. Rebuild the project. Open the Sales Orders page in a web browser. Select a sales order and click Approve. As soon the document has been processed, the status of the sales order becomes Approved (see the screenshot below). Figure: Test the approval operation

104 Part 4: Processing Pages 104 Adding the SalesOrderProcess Graph In this step, you will add the business logic controller that works with the Approve Sales Order page. Do the following: 1. In the RapidByte folder of the application project, create the new SalesOrderProcess.cs file from the PXGraph template. 2. Define the Cancel action for the toolbar and the Orders data view that provides data records to be processed on the page, as follows. public class SalesOrderProcess : PXGraph<SalesOrderProcess> public PXCancel<SalesOrder> Cancel; public PXProcessing<SalesOrder> Orders; The Orders data view will be the primary view for the page. 3. In the SalesOrderProcess graph, define the constructor as follows. public SalesOrderProcess() Orders.SetProcessCaption("Approve"); Orders.SetProcessAllCaption("Approve All"); Orders.SetProcessDelegate<SalesOrderEntry>( delegate(salesorderentry graph, SalesOrder order) graph.clear(); graph.approveorder(order, true); ); The constructor overrides captions of two standard buttons that will be automatically added to the toolbar due to the PXProcessing type of the primary view of the page. By default, the framework adds the Process and Process All buttons to the page toolbar. To override the button captions, you use the SetProcessCaption() and the SetProcessAllCaption() methods. Also, the constructor specifies the processing delegate that is the required definition in graph. To specify the processing method, you invoke the Orders.SetProcessDelegate() method that takes the anonymous method with two input parameters. For such type of the delegate, the framework creates the specified graph and gets the list of orders selected on the page. For each order, the framework executes the specified anonymous method in which you invoke the ApproveOrder() method. Every time the anonymous method gets the same instance of the graph, so we first call the graph.clear() method, which deletes all data from cache objects within the graph, before we process the next order. 4. Rebuild the project. Now the graph is ready and you can create the ASP.NET page that displays the list of sales orders to process.

105 Part 4: Processing Pages 105 Adding Page RB In this step, you will create a new ASP.NET page for mass approval of sales orders. To add the page, perform the following instructions: 1. In the SalesOrder.cs file, add the unbound Selected data field to the SalesOrder data access class. #region Selected public abstract class selected : IBqlField [PXBool] [PXUIField(DisplayName = "Selected")] public virtual bool? Selected get; set; #endregion The Selected data field is unbound, which is defined by the PXBool type attribute. Selected will be used only for UI to display the check box for selection of multiple sales orders on the page. Selected is the default name of a DAC field that the framework uses for a check box that marks records on processing pages. You can learn more about processing pages in the T200 Acumatica Framework Fundamentals course. 2. Save the changes and rebuild the project. Now you can create a new ASP.NET page that displays the list of sales orders for processing. 3. In the Pages > RapidByte folder of Site, create the new RB aspx page from the ListView template. 4. Open the page in design mode and specify the following properties for the ds datasource control: 5. TypeName: RB.RapidByte.SalesOrderProcess PrimaryView: Orders Select the grid PXGrid control at the bottom of the page. In the Properties window, specify the following properties for it: DataMember:Orders SkinID: Inquire 6. Open Layout Editor for the grid PXGrid control. 7. On the Fields tab, select any fields that you'd want to see for each sales order in the list for processing. In our example, we select the Selected, OrderNbr, OrderDate, Status, CustomerID, ShippedDate, and OrderTotal fields from the list. 8. Select the Columns check box below the field list and clear the Controls check box. Click Generate. 9. Move the Selected column to the topmost position in the Grid Columns list and set AllowCheckAll: True for this column. As a result, the column header will contain a check box which you can use to select all data records in the grid. 10. Click Ok to save the generated controls and to close Layout Editor. 11. Save the changes. 12. Add the Daily node as a child of the Acumatica Company > RapidByte > RapidByte > Processes node.

106 Part 4: Processing Pages Add the page to the site map. To do this, open the System > Customization > Site Map page and add the RB aspx page under the Acumatica Company > RapidByte > RapidByte > Processes > Daily node with the following parameters: Screen ID: RB Title: Approve Sales Order Icon: Empty URL: ~/Pages/RapidByte/RB aspx Graph Type: Completed automatically Expanded: Cleared Open the Approve Sales Order page in a web browser. On the page, you can select one or multiple sales orders to launch processing for all of them at once. Select several sales orders and click Approve. The processing result appears on the page (see the screenshot below). The Cancel button clears the selection and refreshes the list of sales orders on the page. Notice that you can select all data records in the grid by checking the box in the header of the first column. Figure: Test the mass sales order approval

107 Part 4: Processing Pages 107 Conclusion: Processing Pages For the graph that works with the processing page, you have to: Use the specific PXProcessing (or derived) data view type to provide data records for the page. Define the processing delegate for the PXProcessing (or derived) data view in the graph constructor. The processing delegate is a method that executes for each data record selected on the page. To add a check box to the page that enables users to select multiple data records for processing, you have to define the unbound boolean field in the DAC whose data records are processed. Also, you have to add the column for this data field to the grid that lists the processed data records. The Process and Process All buttons are automatically added to the toolbar of the page whether you specify the PXProcessing data view as the primary view for the page or not.

108 Part 4: Processing Pages 108 Lesson 9: Setting Up the UI for Approved Sales Orders In this short lesson, you will set up the graph to display approved sales orders in read-only mode on the Sales Orders page. Lesson Objective See how to use the RowSelected event to dynamically set up the UI depending on the current data record.

109 Part 4: Processing Pages 109 Making Approved Sales Orders Read-only in the UI To make the page display approved sales orders in read-only mode, do the following: 1. In the SalesOrderEntry graph, define the SalesOrder_RowSelected() event handler as follows. protected virtual void SalesOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e) SalesOrder order = (SalesOrder)e.Row; if (order == null) return; bool editable = order.status!= OrderStatus.Approved && order.status!= OrderStatus.Completed; Orders.Cache.AllowUpdate = editable; Orders.Cache.AllowDelete = editable; PXUIFieldAttribute.SetEnabled(sender, order, editable); OrderDetails.Cache.AllowDelete = editable; OrderDetails.Cache.AllowInsert = editable; OrderDetails.Cache.AllowUpdate = editable; Approve.SetEnabled(editable && order.hold!= true); The framework raises the RowSelected() event for every data record displayed on the page. The event is raised in the end in all scenarios of events. The RowSelected event is used to set up the UI for a particular data record or the details grid. In the SalesOrder_RowSelected() event, you disable or enable editing of the currently selected data record, which depends on the Status value. If a sales order has the Approved or Completed status, the page displays the data record in read-only mode: users cannot update or delete the read-only data record. Otherwise, the Approve button is enabled only if the Hold value isn't true. The PXUIFieldAttribute.SetEnabled() method disables all controls on the page except for the first declared control that displays the key value. The user can select another key value to navigate between data records in the UI. The AllowDelete, AllowUpdate, AllowInsert properties disable the corresponding toolbar buttons that works with data records kept in the corresponding cache objects. Thus, the Orders.Cache.AllowDelete = false; property disables the Delete button for the sales order; the OrderDetails.Cache.AllowDelete = false; property disables the Delete button for the order details. To configure the Approve button, we use the Approve.SetEnabled(...) method. 2. Rebuild the project. Open the Sales Orders page in a web browser and select an approved document. Make sure the UI is disabled for the sales order and doesn't allow the user to edit the document (see the screenshot below).

110 Part 4: Processing Pages 110 Figure: View an approved sales order in read-only mode

111 Part 4: Processing Pages 111 Conclusion: UI Setup To make certain data records display in read-only mode, implement the UI setup in the RowSelected() event handler. By the specified condition, you can dynamically enable/disable controls and buttons for the currently selected data record on the page. Use the PXUIFieldAttribute.SetEnabled() method to disable/enable controls, and AllowDelete, AllowUpdate, and AllowInsert properties of the cache object to enable/disable buttons on the page. You have to implement both UI disabling and enabling logic, because the controls are not automatically enabled once you've disabled them from the code.

112 Part 5: Reports 112 Part 5: Reports In this part of the course, you will see how to create a report by using Report Designer, the visual tool provided with Acumatica Framework, on the example of the printable sales order page. The printable layout definition of a page is created in the same way as a report.

113 Part 5: Reports 113 Lesson 10: Creating the Sales Orders Printable Form In this lesson, you will design the report form for sales order printing. Printable pages are created in Report Designer in the same.rpx format as report forms. On the website, the form for generating printable documents looks the same as the form for building reports. While making the report, you will also add a report variable that provides row numbers in the detail section of the report. Additionally, you will add the status of a sales order to the printable page. The screenshot below shows the report that you will be able to generate by the end of this lesson. Figure: The Sales Orders form on the website

114 Part 5: Reports 114 Preparing Data for the Report The first step of creating a report is preparing the report query, which is called the 'report schema' in Report Designer. To configure the report schema, you have to complete the following steps: 1. Add the data access classes to the report that will provide the data required for the report, SalesOrder, OrderLine, Product, and Customer. 2. Specify the relationships between the selected DACs, which are left and inner joins. 3. Add the report parameters intended for user input, OrderNbr. 4. Specify filtering conditions based on the parameters and other requirements to the report. 5. Save the report form to the file in the web site folder, /Site/ReportsDefault. 1. Adding Data Access Classes to the Report To start configuring the report schema, you need to add the required data access classes to the report. 1. Start Report Designer located by default under All Programs > Acumatica in the Windows Start menu. The Report Designer visual editor opens a new blank report form. To create a new report, you can select File -> New from the main menu of Report Designer. 2. In the File menu, select Build schema. The Schema Builder dialog box appears. 3. In the dialog, select the Tables tab and enter the application URL, in the Web service URL field, as it is shown in the screenshot (1). 4. Set Login=admin (2) and Password=123 (3) in the text boxes at the right side of the dialog. You can specify any account to log in to the web site for loading of the DAC schema. In this lesson, you use the admin account with unrestricted access rights. 5. Click Load schema (4). The list of data access classes loaded from the web site appears. The list includes all data access classes of your application, including the system DACs that you do not need to add to the report. 6. In the list of DACs, select the SalesOrder, OrderLine, Product, and Customer (5) data access classes and move them to the selected list by clicking the right-arrow button. 7. Click Apply to apply the selected data access classes to the report schema (6).

115 Part 5: Reports 115 Figure: Selecting DACs for the report Your changes aren't saved to the file until you save the report by selecting File -> Save in the main menu. 2. Defining Relationships Between DACs After you have added the data access classes to the report, you need to specify the relationships between these DACs that represent data joining conditions. 1. On the Relationships tab of the Schema Builder dialog box, specify of the selected DACs. Row 1 (see the screenshot below): Parent Table: SalesOrder (1) Join type: Left (2) Child Table: OrderLine (3) After you select the child table, click at the table below to switch to the second table for specifying the join condition. Parent Field: SalesOrder.OrderNbr (4) Link Condition: Equal (5) Child Field: OrderLine.OrderNbr (6) Operator: And (7) Row 2: Parent Table: OrderLine Join type: Left Child Table: Product

116 Part 5: Reports 116 Parent Field: OrderLine.ProductID Link Condition: Equal Child Field: Product.ProductID Operator: And Row 3: Parent Table: SalesOrder Join type: Inner Child Table: Customer Parent Field: SalesOrder.CustomerID Link Condition: Equal Child Field: Customer.CustomerID Figure: Specifying join relationships for DACs The Join type parameter of a condition is equivalent to a join operation in SQL Server. You may use inner, left, right, full and cross joins to retrieve data records based on the corresponding logical relationships. The parent-child order of DACs is important. Do not specify the same data access class as the child in more than one relationship. To delete a relationship, select it from the first table and press Del. 2. Click Apply to apply changes to the report schema. 3. Adding Report Parameters Report parameters are usually intended for manual input on the page before a user runs the report. 1. On the Parameters tab of the Schema Builder dialog box, add the OrderNbr report parameter. To add a parameter, click Add below the list of parameters at the left of the dialog box (see 1 on the screenshot). Set the following properties for the OrderNbr parameter:

117 Part 5: Reports 117 Name: OrderNbr (2) Data Type: String (3) View name: =[SalesOrder.OrderNbr] (4) Prompt: Order Number (5) Allow Null: selected (6) Visible: selected (7) Required: selected (8) Figure: Adding the report parameters The Allow Null property determines whether the parameter must be provided by the user before running of the report. An optional parameter may have a null value during report execution. The Required property specifies that the parameter must be provided by the user before running the report. Otherwise, the report won't be generated. 2. Click Apply to apply the parameter to the report schema. 4. Specifying Data Filtering Conditions Report filters define which data is selected for the report based on the parameters and other conditions required for the report. 1. On the Filters tab of the Schema Builder dialog box, specify the data filtering condition (see the screenshot). SalesOrder.OrderNbr The report parameter name is preceded by '@' in the filter expression.

118 Part 5: Reports 118 Figure: Specifying filtering conditions In the filtering condition, you select the sales order by its number taken from the required report 2. Click OK to apply changes and to close the Schema Builder dialog box. Now the report schema provides the data to be displayed in the report. Save changes in the report file as it is described below. 5. Saving the Report to a File You can save the report to a file in the web site folder or to the database. Users who have no direct access to the site folder can save the report to the database. In this example, you save the report to the file. Do the following: 1. Select File > Save As from the main menu. To save the report to the database, you select Save On Server from the main menu. To save the created report form to the server, you need to specify an account having the Customizer user role. The admin account has unrestricted access rights, and so you can use this account for saving the report forms to the server. The report form (.rpx file) is saved to the UserReport table of the application database. In this case, you will not see the file in the /Site/ReportsDefault folder, but the report form is available for adding to the site map. To edit the report, you can open it from server by selecting Open From Server in the main menu. 2. In the dialog, open the /Site/ReportsDefault/ folder and save the report with the RB file name. The RB rpx report is saved to the web site folder. The website engine searches for reports and style template files in the /Site/ReportsDefault/ folder, which is specified in the PX.Reports.ReportFileManager.ReportsDir property in Site/ App_Code/Auxiliary/Initialization.cs. Now you can go to the next step to add a variable to the report.

119 Part 5: Reports 119 Adding a Variable to the Report In this step, you will add the RowNumber variable to the detail section of the report. Adding a Report Variable By using report variables, you can insert some calculated values related to the document, such as row numbers in the detail section. To sequentially numerate order detail rows in the printed document, add the RowNumber variable to the report. 1. On the Properties tab, select the detailsection1 DetailSection object from the drop-down list (see 1 on the screenshot). 2. In the Variables property, click the three ellipses button to open the variable collection editor (2). 3. In the ReportVariable Collection Editor dialog box, click Add (3). 4. Set the following properties for the new variable (4): 5. Name: RowNumber ProcessOrder: Always ResetGroup: OrderNbr Click OK to close the dialog box and to add the variable to the report. Save changes. Now you can use the variable in a text box value expression referred by its name preceded with the dollar $ sign, as follows: $RowNumber. This variable will be used for printing detail row numbers on the form. You can declare the same variable in several sections. In this case, the variable will be shared between them. Once modified in one section, the new value will be passed to the next section where the variable is used. The variable is initiated at the top-most section where it is referred. Then the variable is sequentially modified in the following sections by the order as they declared in the report. Figure: Adding the RowNumber variable to the detail section Now the schema is ready and the report is ready for layout design. Go to the next step to add text boxes to the form that display the report data.

120 Part 5: Reports 120 Configuring the Printable Page Layout In this step, you will add one group for the sales order information and place text boxes on the form that displays data on the printable page. You can also apply style templates to the text boxes that you add to the report (see the details below). Adding a Group to the Form Add the OrderNbr group for displaying the sales order information. Do the following: 1. Open the RB rpx report form in Report Designer. 2. On the Properties tab, select the report1 Report object from the drop-down list. To select the report form, you can also click the top left box located under the toolbar on the report form. The black marker will appear in the box. Figure: Select the report form by clicking the box at the top left corner of the form 3. On the Properties tab, click the three ellipses button (...) in the Groups property to open the Group Collection Editor. Figure: Open the Group Collection Editor 4. In the Group Collection Editor window, click Add to add a new group (see 1 on the screenshot below). 5. Specify the following properties of the group (2): KeepTogether:WholeGroup PrintEmpty:False (Name):OrderNbr 6. Click the three ellipses button (...) in the Grouping property of the OrderNbr group (3). 7. In the GroupExp Collection Editor window, click Add (4) and set DataField:SalesOrder.OrderNbr (5), by which the nested data records will be grouped. Click OK to apply the property and to close the window.

121 Part 5: Reports 121 Figure: Add the OrderNbr group to the report The OrderNbr group has been added to the report. Adding Text Boxes to Sections A report form consists of the page header and footer, group sections, and the detail section nested within the most internal group. You can group data by several parameters and nest groups one in another. The data records of each nested group are grouped by the data field specified in the higherlevel group. Each group consists of the two sections on the form, header and footer. The header section contains the group caption and captions for the detail data records. The footer is used to display sums and other aggregated values calculated by the detail data. Add the text boxes to the report sections as described below: 1. Add the Delivery Note text box to the printable page header and place a line at the border of the page header section. Adjust the height to 24px of this and of all other text boxes on the form. Figure: Page Header Elements

122 Part 5: Reports 122 To add a text box to the report form: Click TextBox on the toolbar and then click on the place where you want to position the box. Place the report name text box at the top right corner of the report. Double-click the added text box and type the displayed value. Type Delivery Note for the first text box. This is the value of the Value property of the text box. Enlarge the text box height by 8px by pulling the handle at the bottom of the box, so that the text box height becomes equal to 24px. Adjust the text box width so that the whole text is visible in the box. You can also specify the text box height on the Properties tab in the Size group. The style parameters, including the font and text align, are applied by using the style templates, which is demonstrated further. It is also possible to adjust the style in the Style group of the properties, but we don't recommend you to specify every style property for each text box individually. Figure: Enlarge the height of a text box 2. Select the OrderNbr group header section and set the PrintOnEveryPage property to True. Group header and footer sections has this property that enables repeating of the section content on every page in the report. 3. Add the text boxes that display the sales order information to the OrderNbr group header section and set the following values for them: To: =IsNull([Customer.CompanyName],'') + IsNull('br '+[Customer.Address],'') + ISNull('br '+[Customer.City],'') + IsNull('br '+[Customer.CountryCD],'') + IsNull('br '+[Customer.Region],'') + IsNull('br '+[Customer.PostalCode],'') Attn: =[Customer.ContactName] Order ID: =[SalesOrder.OrderNbr] Customer ID: =[Customer.CustomerCD] Order Date: =[SalesOrder.OrderDate] Shipment Date: =[SalesOrder.ShippedDate] Status: =[SalesOrder.Status]

123 Part 5: Reports 123 No. Product Item Stock Unit Quantity Unit Price Discount Extended Price Figure: Add the OrderNbr group header elements 4. Add the text boxes that display the order details to the detail section of the report and set the following values for them: =Assign('$RowNumber',$RowNumber+1) =[Product.ProductName] =[OrderLine.StockUnit] =[OrderLine.OrderQty] =[OrderLine.UnitPrice] =[OrderLine.DiscPct] =[OrderLine.LinePrice] Figure: Detail Section Elements 5. On the Properties tab, select the OrderNbr group footer section and specify the following properties for it: PrintAtBottom: True PrintOnEveryPage: True ProcessOrder: Always ResetPageNumber: True The PrintAtBottom property makes the group footer printed always at the bottom of a page. A page break is inserted after the section. The ProcessOrder property is commonly used for sections and particular text boxes. Once specified for a section, the property is applied to every text box in this section unless the property is overridden for this text box. The ProcessOrder property specifies when the text box value is processed during the report generation. A text box value can be processed when

124 Part 5: Reports 124 the data is read from the database (WhileRead), when the report is printed (WhilePrint), or in both cases (Always). In most cases, when a value is just read from the database and then displayed in the report, WhileRead is enough, for instance, for the employee's name. However, if the value is calculated depending on data that will be known only at the report rendering stage, the WhilePrint mode should be specified. In our example, the sales order total will have the conditional visibility depending on the page count. The sales order total should be printed on the last page of the report. You should use the WhilePrint mode for the sales order total, because the last page number will be known only at the report rendering stage. Document totals are typical data fields with the WhilePrint processing mode. The ProcessOrder property is also applied to sections. This property should be set to Always for those sections that have at least one text box with the WhilePrint processing mode. The ResetPageNumber property specifies whether the page number is reset after the section is printed. 6. Add the text boxes to the OrderNbr group footer section and specify the following values for them: ***Continued*** Lines Total: =[SalesOrder.LinesTotal] Tax Total: =[SalesOrder.TaxTotal] Order Total: =[SalesOrder.OrderTotal] ='Page: '+[PageOf] Figure: OrderNbr Group Footer Elements 7. On the Properties tab, set the following properties for the ***Continued*** text box: ProcessOrder: WhilePrint VisibleExpr: =([PageIndex]<[PageCount]) The ProcessOrder property makes the text box processed at the report rendering stage. The visibility condition specifies that the label appears on all pages except for the last page in the report. 8. Set the following properties for all text boxes from the group footer section, except for ***Continued*** and Page: ProcessOrder: WhilePrint VisibleExpr:=([PageIndex]=[PageCount]) These properties make the values printed on only the last page of the report. 9. Save the changes.

125 Part 5: Reports 125 Now the printable page is ready for running on the web site. Before you test the page, see how to format the report by using the style templates. Applying Style Templates Style templates are extremely useful for quick and uniform formatting of text displayed in a report. There are two files with default style templates located in the Site/ReportsDefault/ folder, TemplateReport.rpx and TemplateForm.rpx. The TemplateReport.rpx file contains styles that you can use for reports, while the styles from TemplateForm.rpx file are intended for printable pages. You can use these default styles, as well as define your own custom styles required for the application. Specify the styles template file for the report and apply style templates to text boxes, to make the report look neat. 1. On the Properties tab, select the report1 Report object from the drop-down list. 2. In the StyleTemplate property, click the three ellipses button (...) and select the TemplateForm.rpx file. You have specified the file containing the style templates for the printable page. Now you can apply styles defined in this file to text boxes on the form. 3. Select the Delivery Note text box on the form. 4. On the Properties tab, set StyleName:Report Name for the text box (see the screenshot below). Figure: Specify the Report Name style for the text box The appearance of the text box value has changed according to the applied style. In the same way, you can specify styles for other text boxes on the form. We recommend that you follow the design guidelines on creating reports in Report Designer, see Acumatica Framework > Report Designer > Recommendations in the documentation. Go to the next step to test the printable page on the website.

126 Part 5: Reports 126 Adding the Report URL to the Site Map In this step, you will add the URL to the report to the site map to make users able to run the report. Complete the following steps: 1. Open the System > Customization > Site Map page and add the Forms node under Acumatica Company > RapidByte > RapidByte > Reports. 2. Add a new node under Acumatica Company > RapidByte > RapidByte > Reports > Forms with the following parameters: 3. Screen ID: RB Title: Sales Orders Icon: Empty URL: ~/Frames/ReportLauncher.aspx?ID=RB rpx Graph Type: Completed automatically Expanded: Cleared Save the changes to the site map. Now you can open the Sales Orders page on the website.

127 Part 5: Reports 127 Running the Report Form Open the Sales Orders report launcher page on the website. To get a printable version of a sales order, select the Report Parameters tab item, specify the Order Number parameter and click Run Report (see the screenshot below). Figure: Run the report form The framework opens the sales order page for printing. The web browser Print dialog appears by clicking Print on the toolbar (see the screenshot).

128 Part 5: Reports 128 Figure: Run the report to get the printable document

129 Part 5: Reports 129 Conclusion: Reports A report or printable page is a separate.rpx file that is created in the visual report builder, Report Designer, a tool provided with Acumatica Framework. While making the report, you construct the query that is called the schema of the report; you design the position and style of text fields in the report. You can save the report file to the web site folder or application database. The report has the specific URL in the site map. Users run reports from the specific ReportLauncher page defined in the site map with a particular report ID. To build the report, the user specifies the parameters and clicks Run. Based on the parameters and layout defined in the.rpx file, the platform generates the report and then outputs the result in printable format.

130 Appendix: Application Design 130 Appendix: Application Design In this course, we have already designed the application for you. During the development of Acumatica Framework-based applications, you have to perform the following steps of application design: Analyse the requirements, plan the entity model of the application. Prepare the ORM that consists of the database schema and the data access class design. Plan the webpages that provide the user interface of the application. You create application pages from specific Acumatica Framework page templates. Plan the business logic controller (a graph) for each page, which encapsulate business processes and use-cases that should be implemented in the application. Each of these steps is iterated for multiple times as the development is progress.

131 Appendix: Application Design 131 Database Schema During the database design, you define how the main business objects will be stored in the database. Entity-Relationship Model Since the requirements, a sales order is the main object the application works with. Sales orders are in one-to-many relationship with order lines. Order lines are in many-to-one relationship with products. Multiple products can be associated with an order line, and the same product can be added to multiple order lines. Each order has a reference to a customer; these objects are in one-to-many relationship with sales orders. The customer is a person or company who ordered the products. The resulting model is shown in the diagram below. Figure: The entity-relationship model of the RapidByte application Database Schema You have to design the database schema that stores the application data. You have to create and maintain your own application tables in the database during the design and development of the application. The Acumatica Framework-based application template contains only the system tables that are required for the platform. You can modify your own application tables but not the Acumatica Framework system tables, because any changes to the system tables would be lost on Acumatica Framework upgrade. We have already designed the database of the RapidByte application. The RapidByte application uses five application tables: SalesOrder, OrderLine, Customer, Product, and Country (see the schema below).

132 Appendix: Application Design 132 Figure: The database schema of the RapidByte application In each application table, we have to set the primary key and define nullable columns. Foreign keys are not necessary; it depends on the database design approach you use. We do not define foreign keys in the database since we will use the approach according to which the database schema has only the primary key restrictions and all other restrictions are defined at the higher level of the application object model. The SalesOrder table uses the string OrderNbr column as the primary key. Users can manually input the sales order number and then search for a sales order by this number. The corresponding OrderNbr data field is set as the key in the data access class. Non-null columns are only the absolute required sales order attributes, OrderNbr, OrderDate, and CustomerID. The primary key of the OrderLine table consists of two columns, OrderNbr and ProductID. The corresponding data fields is set as the key fields in the data access class. The OrderNbr column links an order detail to the master record from the SalesOrder table. This link is set up in the data access class. The ProductID column is included in the primary key to support multiple products on a sales order. As for nullable columns, we consider that all columns can be null except for the primary key. The OrderLine.ProductID value is taken from the ProductID column of the Product table. The ProductID is the identity column set as the primary key in the Product table. Unlike the table,

133 Appendix: Application Design 133 the string ProductCD value, which is the product code, set as the key in the data access class. The different database-level and model-level keys are used to provide a user-friendly key of a product in the UI, which is the product code. Acumatica Framework keeps the ProductCD value unique for each product and handle the ProductID column automatically. Users work only with ProductCD values that identify products in the UI. As for nullable columns, we consider all product attributes as required and make all columns not-null. The Customer table has the CustomerID as the primary key, while the key of the data access class is CustomerCD. The Country table is a country dictionary that is referred from the Customer table. The Country table uses the string CountryCD column as the primary key since the list of dictionaries is rather fixed and short. In our application, the country identifier is a two-letter code from ISO At the same time as you plan the database schema, you can design the object model of your application. The object model is represented by data access classes that are mapped to the database tables of your application. For more information on database design, see Acumatica Framework > Design Guidelines > Database Design Conventions in the documentation.

134 Appendix: Application Design 134 Data Access Classes Planning and designing of database tables is performed simultaneously with designing of the application data access classes (DACs). DACs encapsulate working with database tables in the application. The application class diagram (which follows this paragraph) shows the relationships between data access classes of the RapidByte application. We could define these relationships as foreign keys at the database level, but we use the generic database schema approach and define these restrictions only at the object model level. In the application, you work only with classes that represent data on a higher, database-abstract level. To retrieve data you write BQL statements, which are transparently translated into SQL statements by the Acumatica Data Access Layer. Unique key fields for each data access class are marked on the diagram with gray. The relationships between DACs are defined declaratively in attributes on the DAC data fields. As you can see from the diagram, the data access classes directly correspond to the database tables we created at the previous step. A sales order may exist without any details, so the relationship is one-to-many (1-0..*). The relationship between the Product and OrderLine entities is also oneto-many (actually, 0-0..*), because an order detail cannot be saved without the specified product: OrderLine.ProductID is a required reference to a product from the Product table. In the Product and Customer classes, the CD data field is included in the key instead of ID. The ID field corresponds to the database identity column in each table; in the data access class, these identity fields are annotated with the PXDBIdentity attribute and not included in the key fields of the class. Also, an additional SalesOrderFilter filter class (not shown on the diagram) is used in the application. Filter classes are used only for data representation and they don't used for queries to the database or implementation of any business logic. Figure: The data access class diagram of the RapidByte application

135 Appendix: Application Design 135 Application Pages In Acumatica Framework-based applications, the user interface is provided through webpages. The user works with webpages and doesn't need to install any specific client. You create application pages from the specific Acumatica Framework ASP.NET templates. You can use the visual editors provided by Acumatica Framework to add controls to ASP.NET pages and configure properties of the controls. The sales order printable form is not an ASP.NET page, it is an.rpx definition file. The file contains the data definition and the page layout description for printing. The definition file is created in Report Designer. To create a printable form or report, you have to compose just the definition file, add the file to the website, and then add the specific report URL to the site map. To get the printable document, you run the printable form from the specific report launcher page provided by Acumatica Framework. The report launcher renders the output and generates the document for printing. Support for generating printable forms and reports is built-in in Acumatica Framework. You don't have to create any application pages or business logic controllers for rendering of reports and printable forms. In Acumatica Framework, every page has a unique identifier that encodes the module, type and number of the page. We will assign the following identifiers to the RapidByte pages, in which the first two symbols denote the module, the second two symbols denote the page type, and the last two symbols denote the sequential number of the page: Countries RB (maintenance) Customers RB (20 means maintenance) Sales Orders RB (30 means data entry) Sales Order Inquiry RB (40 means inquiry) Approve Sales Order RB (50 means processing) Sales Orders Form RB (60 means reports and printable layouts) We recommend the page identification convention for use in Acumatica Framework-based applications. For more information about the convention, see Acumatica Framework > Design Guidelines > Application Design Guidelines in the documentation. In Acumatica Framework-based applications, you usually create the following types of pages: data entry, maintenance, inquiry, and processing. Data entry pages are the most often used pages in the application. These pages provide input of business documents, such as sales orders. Maintenance pages are also used for data input, but more rare than the data entry pages. Maintenance pages are used to input of helper objects mostly during configuration and less used over time. Inquiry pages provide selection of data by the specified parameters. On inquiry pages, users specify the selection criteria and retrieve the records that match the criteria. Processing pages are dedicated to mass processing of records for instance, provides changing of the document status for a list of selected documents at once. You can learn more about pages of different types in the T200 Acumatica Framework Fundamentals course. The Navigation Menu and the Site Map In the user interface, all pages are typically grouped into four tabs of the navigation pane according to their purpose and frequency of use. The menu structure is composed in the site map that is configured on the System > Customization > Manage > Site Map page. For the RapidByte application, we suggest the following menu: Work Area tab ( ): Enter: Sales Orders

136 Appendix: Application Design 136 Manage: Customers Explore: Sales Order Inquiry Processes tab ( Daily: Approve Sales Orders Reports tab ( ): ): Forms: Sales Orders Configuration tab ( ): Manage: Countries For instance, the Work Area tab of the navigation pane will look as follows. Figure: Work Area Tab In the site map, the menu structure is configured as shown in the following screenshot.

137 Appendix: Application Design 137 Figure: The site map of the RapidByte application module menu

Copyright About the Customization Guide Introduction Getting Started...13

Copyright About the Customization Guide Introduction Getting Started...13 Contents 2 Contents Copyright...10 About the Customization Guide...11 Introduction... 12 Getting Started...13 Knowledge Pre-Requisites...14 To Prepare an Environment... 14 To Assign the Customizer Role

More information

Copyright...6. Acumatica Framework Guide...7. Acumatica Framework Overview... 8

Copyright...6. Acumatica Framework Guide...7. Acumatica Framework Overview... 8 Contents 2 Contents Copyright...6 Acumatica Framework Guide...7 Acumatica Framework Overview... 8 Acumatica Cloud xrp Platform...8 Acumatica Framework Development Tools... 11 Runtime Architecture of an

More information

Copyright...9. About the Guide Introduction Acumatica Customization Platform...12

Copyright...9. About the Guide Introduction Acumatica Customization Platform...12 Contents 2 Contents Copyright...9 About the Guide... 10 Introduction... 11 Acumatica Customization Platform...12 Customization Project... 12 Types of Items in a Customization Project... 13 Deployment of

More information

Copyright...4. Overview Managing Snapshots... 6

Copyright...4. Overview Managing Snapshots... 6 Contents 2 Contents Copyright...4 Overview... 5 Managing Snapshots... 6 Company Snapshots...6 Examples of Sensitive Data Preservation in Snapshots... 9 To Take a Snapshot...10 To Toggle the Visibility

More information

Copyright...3. Plug-In Development Guide Creating Widgets for Dashboards... 5

Copyright...3. Plug-In Development Guide Creating Widgets for Dashboards... 5 Contents 2 Contents Copyright...3 Plug-In Development Guide... 4 Creating Widgets for Dashboards... 5 Widget Creation...5 Use of the Widgets... 6 To Create a Simple Widget... 8 To Create an Inquiry-Based

More information

Copyright...6. Overview Preparing Data for Import and Export by Using Scenarios... 10

Copyright...6. Overview Preparing Data for Import and Export by Using Scenarios... 10 Contents 2 Contents Copyright...6 Overview... 7 Preparing Data for Import and Export by Using Scenarios... 10 Import and Export Scenarios... 10 Data Providers... 12 To Create a CSV Data Provider... 14

More information

F350 Analytical Reports

F350 Analytical Reports Financials F350 Analytical Reports Training Guide Last Revision: 08/05/2016 Acumatica ERP 5.3-6.0 Contents 2 Contents Copyright...3 Introduction... 4 How to Use This Course...5 Course Prerequisites...6

More information

Copyright...7. Overview of General Ledger Processes Configuration...11

Copyright...7. Overview of General Ledger Processes Configuration...11 Contents 2 Contents Copyright...7 Overview of General Ledger Processes... 8 Configuration...11 Preparation...11 Recommended Initial Configuration of the General Ledger Module... 11 Advanced Configuration...12

More information

CHAPTER 1: INTRODUCING C# 3

CHAPTER 1: INTRODUCING C# 3 INTRODUCTION xix PART I: THE OOP LANGUAGE CHAPTER 1: INTRODUCING C# 3 What Is the.net Framework? 4 What s in the.net Framework? 4 Writing Applications Using the.net Framework 5 What Is C#? 8 Applications

More information

COGNOS (R) 8 COGNOS CONNECTION USER GUIDE USER GUIDE THE NEXT LEVEL OF PERFORMANCE TM. Cognos Connection User Guide

COGNOS (R) 8 COGNOS CONNECTION USER GUIDE USER GUIDE THE NEXT LEVEL OF PERFORMANCE TM. Cognos Connection User Guide COGNOS (R) 8 COGNOS CONNECTION USER GUIDE Cognos Connection User Guide USER GUIDE THE NEXT LEVEL OF PERFORMANCE TM Product Information This document applies to Cognos (R) 8 Version 8.1.2 MR2 and may also

More information

DOT NET Syllabus (6 Months)

DOT NET Syllabus (6 Months) DOT NET Syllabus (6 Months) THE COMMON LANGUAGE RUNTIME (C.L.R.) CLR Architecture and Services The.Net Intermediate Language (IL) Just- In- Time Compilation and CLS Disassembling.Net Application to IL

More information

Talend Open Studio for MDM Web User Interface. User Guide 5.6.2

Talend Open Studio for MDM Web User Interface. User Guide 5.6.2 Talend Open Studio for MDM Web User Interface User Guide 5.6.2 Talend Open Studio for MDM Web User Interface Adapted for v5.6.2. Supersedes previous releases. Publication date: May 12, 2015 Copyleft This

More information

INTRODUCTION TO.NET. Domain of.net D.N.A. Architecture One Tier Two Tier Three Tier N-Tier THE COMMON LANGUAGE RUNTIME (C.L.R.)

INTRODUCTION TO.NET. Domain of.net D.N.A. Architecture One Tier Two Tier Three Tier N-Tier THE COMMON LANGUAGE RUNTIME (C.L.R.) INTRODUCTION TO.NET Domain of.net D.N.A. Architecture One Tier Two Tier Three Tier N-Tier THE COMMON LANGUAGE RUNTIME (C.L.R.) CLR Architecture and Services The.Net Intermediate Language (IL) Just- In-

More information

ECM Extensions xcp 2.2 xcelerator Abstract

ECM Extensions xcp 2.2 xcelerator Abstract ECM Extensions xcp 2.2 xcelerator Abstract These release notes outline how to install and use the ECM Extensions xcelerator. October 2015 Version 1.0 Copyright 2015 EMC Corporation. All Rights Reserved.

More information

Management Reports Centre. User Guide. Emmanuel Amekuedi

Management Reports Centre. User Guide. Emmanuel Amekuedi Management Reports Centre User Guide Emmanuel Amekuedi Table of Contents Introduction... 3 Overview... 3 Key features... 4 Authentication methods... 4 System requirements... 5 Deployment options... 5 Getting

More information

COGNOS (R) ENTERPRISE BI SERIES COGNOS REPORTNET (TM)

COGNOS (R) ENTERPRISE BI SERIES COGNOS REPORTNET (TM) COGNOS (R) ENTERPRISE BI SERIES COGNOS REPORTNET (TM) GETTING STARTED Cognos ReportNet Getting Started 07-05-2004 Cognos ReportNet 1.1MR1 Type the text for the HTML TOC entry Type the text for the HTML

More information

You can also check the videos at the bottom of this page:

You can also check the videos at the bottom of this page: This document is provided to give you an idea what R-Tag Version Control can do and how you can use it. If you decide that you need more information or you prefer to see a demo of the software please do

More information

Roadmap. Mike Chtchelkonogov Founder & Chief Technology Officer Acumatica

Roadmap. Mike Chtchelkonogov Founder & Chief Technology Officer Acumatica Roadmap Mike Chtchelkonogov Founder & Chief Technology Officer Acumatica mik@acumatica.com Andrew Boulanov Head of Platform Development Acumatica aboulanov@acumatica.com Acumatica xrp Priorities Platform

More information

Getting Started Tutorial - Eclipse Edition. Sybase Unwired Platform 1.2

Getting Started Tutorial - Eclipse Edition. Sybase Unwired Platform 1.2 Getting Started Tutorial - Eclipse Edition Sybase Unwired Platform 1.2 DOCUMENT ID: DC01017-01-0120-01 LAST REVISED: March, 2009 Copyright 2009 by Sybase, Inc. All rights reserved. This publication pertains

More information

Microsoft Visual Basic 2005: Reloaded

Microsoft Visual Basic 2005: Reloaded Microsoft Visual Basic 2005: Reloaded Second Edition Chapter 1 An Introduction to Visual Basic 2005 Objectives After studying this chapter, you should be able to: Explain the history of programming languages

More information

Black-Belt Development

Black-Belt Development Black-Belt Development Part 2 Sergey Marenich Solution Architect Acumatica sm@acumatica.com http://asiablog.acumatica.com Sergey Marenich Experience: 11 years at Acumatica 7 years as a system developer

More information

10267A CS: Developing Web Applications Using Microsoft Visual Studio 2010

10267A CS: Developing Web Applications Using Microsoft Visual Studio 2010 10267A CS: Developing Web Applications Using Microsoft Visual Studio 2010 Course Overview This instructor-led course provides knowledge and skills on developing Web applications by using Microsoft Visual

More information

Cognos Connection User Guide USER GUIDE. Cognos (R) 8 COGNOS CONNECTION USER GUIDE

Cognos Connection User Guide USER GUIDE. Cognos (R) 8 COGNOS CONNECTION USER GUIDE Cognos Connection User Guide USER GUIDE Cognos (R) 8 COGNOS CONNECTION USER GUIDE Product Information This document applies to Cognos (R) 8 Version 8.2 and may also apply to subsequent releases. To check

More information

ADF Mobile Code Corner

ADF Mobile Code Corner ADF Mobile Code Corner m03. Abstract: Dependent lists is a common functional requirement for web, desktop and also mobile applications. You can build dependent lists from dependent, nested, and from independent,

More information

SAP Workforce Performance Builder

SAP Workforce Performance Builder Additional Guides Workforce Performance Builder Document Version: 1.0 2016-07-15 2016 SAP SE or an SAP affiliate company. All rights reserved. CUSTOMER SAP Help Extension ECC Table of Contents 1 Introduction...

More information

Advance Dotnet ( 2 Month )

Advance Dotnet ( 2 Month ) Advance Dotnet ( 2 Month ) Course Content Introduction WCF Using.Net 4.0 Service Oriented Architecture Three Basic Layers First Principle Communication and Integration Integration Styles Legacy Applications

More information

MobileFast SyncStudio. A Complete Mobile Database Synchronization Solution. Quick-Start Manual. Release 1.61, May 2014

MobileFast SyncStudio. A Complete Mobile Database Synchronization Solution. Quick-Start Manual. Release 1.61, May 2014 MobileFast SyncStudio A Complete Mobile Database Synchronization Solution Quick-Start Manual Release 1.61, May 2014 Copyright 2014 by MobileFast Corporation All rights reserved Page 1 of 25 Edition Notes

More information

DOT NET SYLLABUS FOR 6 MONTHS

DOT NET SYLLABUS FOR 6 MONTHS DOT NET SYLLABUS FOR 6 MONTHS INTRODUCTION TO.NET Domain of.net D.N.A. Architecture One Tier Two Tier Three Tier N-Tier THE COMMON LANGUAGE RUNTIME (C.L.R.) CLR Architecture and Services The.Net Intermediate

More information

Oracle. SCM Cloud Configurator Modeling Guide. Release 13 (update 17D)

Oracle. SCM Cloud Configurator Modeling Guide. Release 13 (update 17D) Oracle SCM Cloud Release 13 (update 17D) Release 13 (update 17D) Part Number E89207-02 Copyright 2011-2017, Oracle and/or its affiliates. All rights reserved. Author: Mark Sawtelle This software and related

More information

BEA WebLogic. Server. MedRec Clustering Tutorial

BEA WebLogic. Server. MedRec Clustering Tutorial BEA WebLogic Server MedRec Clustering Tutorial Release 8.1 Document Date: February 2003 Revised: July 18, 2003 Copyright Copyright 2003 BEA Systems, Inc. All Rights Reserved. Restricted Rights Legend This

More information

End User s Guide Release 5.0

End User s Guide Release 5.0 [1]Oracle Application Express End User s Guide Release 5.0 E39146-04 August 2015 Oracle Application Express End User's Guide, Release 5.0 E39146-04 Copyright 2012, 2015, Oracle and/or its affiliates. All

More information

Information Design Tool User Guide SAP BusinessObjects Business Intelligence platform 4.0 Support Package 4

Information Design Tool User Guide SAP BusinessObjects Business Intelligence platform 4.0 Support Package 4 Information Design Tool User Guide SAP BusinessObjects Business Intelligence platform 4.0 Support Package 4 Copyright 2012 SAP AG. All rights reserved.sap, R/3, SAP NetWeaver, Duet, PartnerEdge, ByDesign,

More information

COPYRIGHTED MATERIAL. Contents. Part I: C# Fundamentals 1. Chapter 1: The.NET Framework 3. Chapter 2: Getting Started with Visual Studio

COPYRIGHTED MATERIAL. Contents. Part I: C# Fundamentals 1. Chapter 1: The.NET Framework 3. Chapter 2: Getting Started with Visual Studio Introduction XXV Part I: C# Fundamentals 1 Chapter 1: The.NET Framework 3 What s the.net Framework? 3 Common Language Runtime 3.NET Framework Class Library 4 Assemblies and the Microsoft Intermediate Language

More information

IBM. Database Database overview. IBM i 7.1

IBM. Database Database overview. IBM i 7.1 IBM IBM i Database Database overview 7.1 IBM IBM i Database Database overview 7.1 Note Before using this information and the product it supports, read the information in Notices, on page 39. This edition

More information

Mail & Deploy Reference Manual. Version 2.0.5

Mail & Deploy Reference Manual. Version 2.0.5 Mail & Deploy Reference Manual Version 2.0.5 Introduction TABLE OF CONTENTS Introduction... 4 General Introduction... 5 Architecture... 6 Server... 6 Repository... 6 Client... 6 Contact Us... 7 Server...

More information

BUILD YOUR OWN SAP FIORI APP IN THE CLOUD Exercise Week 5

BUILD YOUR OWN SAP FIORI APP IN THE CLOUD Exercise Week 5 BUILD YOUR OWN SAP FIORI APP IN THE CLOUD Exercise Week 5 Create an App from a Smart Template and Annotation File 1 INTRODUCTION 1.1 Goal Smart Templates in the SAP Web IDE of the SAP HANA Cloud Platform

More information

Oracle. Sales Cloud Integrating with Oracle Marketing Cloud. Release 13 (update 18B)

Oracle. Sales Cloud Integrating with Oracle Marketing Cloud. Release 13 (update 18B) Oracle Sales Cloud Integrating with Oracle Marketing Cloud Release 13 (update 18B) Release 13 (update 18B) Part Number E94441-01 Copyright 2011-2018, Oracle and/or its affiliates. All rights reserved.

More information

Beginning ASP.NET. 4.5 in C# Matthew MacDonald

Beginning ASP.NET. 4.5 in C# Matthew MacDonald Beginning ASP.NET 4.5 in C# Matthew MacDonald Contents About the Author About the Technical Reviewers Acknowledgments Introduction xxvii xxix xxxi xxxiii UPart 1: Introducing.NET. 1 & Chapter 1: The Big

More information

BEAWebLogic. Portal. MobileAware Interaction Server Installation Guide

BEAWebLogic. Portal. MobileAware Interaction Server Installation Guide BEAWebLogic Portal MobileAware Interaction Server Installation Guide Version 8.1 with Service Pack 3 (MobileAware Version 1.0) Document Revised: September 2004 Copyright Copyright 2004 BEA Systems, Inc.

More information

IBM Leads Version 9 Release 1 October 25, User Guide

IBM Leads Version 9 Release 1 October 25, User Guide IBM Leads Version 9 Release 1 October 25, 2013 User Guide Note Before using this information and the product it supports, read the information in Notices on page 35. This edition applies to version 9,

More information

GETTING STARTED WITH CODE ON TIME Got data? Generate modern web apps in minutes. Learn to create sophisticated web apps with Code On Time application

GETTING STARTED WITH CODE ON TIME Got data? Generate modern web apps in minutes. Learn to create sophisticated web apps with Code On Time application 2012 GETTING STARTED WITH CODE ON TIME Got data? Generate modern web apps in minutes. Learn to create sophisticated web apps with Code On Time application generator for ASP.NET, Azure, DotNetNuke, and

More information

Skill Area 336 Explain Essential Programming Concept. Programming Language 2 (PL2)

Skill Area 336 Explain Essential Programming Concept. Programming Language 2 (PL2) Skill Area 336 Explain Essential Programming Concept Programming Language 2 (PL2) 336.2-Apply Basic Program Development Techniques 336.2.1 Identify language components for program development 336.2.2 Use

More information

Connector for Microsoft SharePoint Product Guide - On Demand. Version

Connector for Microsoft SharePoint Product Guide - On Demand. Version Connector for Microsoft SharePoint Product Guide - On Demand Version 03.0.00 This Documentation, which includes embedded help systems and electronically distributed materials (hereinafter referred to as

More information

Using SAP NetWeaver Business Intelligence in the universe design tool SAP BusinessObjects Business Intelligence platform 4.1

Using SAP NetWeaver Business Intelligence in the universe design tool SAP BusinessObjects Business Intelligence platform 4.1 Using SAP NetWeaver Business Intelligence in the universe design tool SAP BusinessObjects Business Intelligence platform 4.1 Copyright 2013 SAP AG or an SAP affiliate company. All rights reserved. No part

More information

SAS Infrastructure for Risk Management 3.4: User s Guide

SAS Infrastructure for Risk Management 3.4: User s Guide SAS Infrastructure for Risk Management 3.4: User s Guide SAS Documentation March 2, 2018 The correct bibliographic citation for this manual is as follows: SAS Institute Inc. 2017. SAS Infrastructure for

More information

User Defined Fields for MAS 500 SM-1004

User Defined Fields for MAS 500 SM-1004 OVERVIEW User Defined Fields for MAS 500 SM-1004 This EASY Solution modifies MAS 500 entities to create new fields to store user defined data. In addition to supporting numerous additional fields, (up

More information

20486: Developing ASP.NET MVC 4 Web Applications (5 Days)

20486: Developing ASP.NET MVC 4 Web Applications (5 Days) www.peaklearningllc.com 20486: Developing ASP.NET MVC 4 Web Applications (5 Days) About this Course In this course, students will learn to develop advanced ASP.NET MVC applications using.net Framework

More information

Pricing Cloud: Upgrading to R13 - Manual Price Adjustments from the R11/R12 Price Override Solution O R A C L E W H I T E P A P E R A P R I L

Pricing Cloud: Upgrading to R13 - Manual Price Adjustments from the R11/R12 Price Override Solution O R A C L E W H I T E P A P E R A P R I L Pricing Cloud: Upgrading to R13 - Manual Price Adjustments from the R11/R12 Price Override Solution O R A C L E W H I T E P A P E R A P R I L 2 0 1 8 Disclaimer The following is intended to outline our

More information

SAS Web Report Studio 3.1

SAS Web Report Studio 3.1 SAS Web Report Studio 3.1 User s Guide SAS Documentation The correct bibliographic citation for this manual is as follows: SAS Institute Inc. 2006. SAS Web Report Studio 3.1: User s Guide. Cary, NC: SAS

More information

Interstage Business Process Manager Analytics V12.1 Studio Guide

Interstage Business Process Manager Analytics V12.1 Studio Guide Interstage Business Process Manager Analytics V12.1 Studio Guide Solaris April 2013 Studio Guide Trademarks Trademarks of other companies are used in this documentation only to identify particular products

More information

This document does not represent a commitment to implement any portion of this specification in any company s products.

This document does not represent a commitment to implement any portion of this specification in any company s products. Copyright Notice Copyright 2003 York University The companies and organizations listed above have granted the Open GIS Consortium, Inc. (OGC) a nonexclusive, royalty-free, paid up, worldwide license to

More information

Creating Reports in Access 2007 Table of Contents GUIDE TO DESIGNING REPORTS... 3 DECIDE HOW TO LAY OUT YOUR REPORT... 3 MAKE A SKETCH OF YOUR

Creating Reports in Access 2007 Table of Contents GUIDE TO DESIGNING REPORTS... 3 DECIDE HOW TO LAY OUT YOUR REPORT... 3 MAKE A SKETCH OF YOUR Creating Reports in Access 2007 Table of Contents GUIDE TO DESIGNING REPORTS... 3 DECIDE HOW TO LAY OUT YOUR REPORT... 3 MAKE A SKETCH OF YOUR REPORT... 3 DECIDE WHICH DATA TO PUT IN EACH REPORT SECTION...

More information

Accounts Payable Workflow Guide. Version 14.6

Accounts Payable Workflow Guide. Version 14.6 Accounts Payable Workflow Guide Version 14.6 Copyright Information Copyright 2017 Informa Software. All Rights Reserved. No part of this publication may be reproduced, transmitted, transcribed, stored

More information

[ Getting Started with Analyzer, Interactive Reports, and Dashboards ] ]

[ Getting Started with Analyzer, Interactive Reports, and Dashboards ] ] Version 5.3 [ Getting Started with Analyzer, Interactive Reports, and Dashboards ] ] https://help.pentaho.com/draft_content/version_5.3 1/30 Copyright Page This document supports Pentaho Business Analytics

More information

Contents I Introduction 1 Introduction to PL/SQL iii

Contents I Introduction 1 Introduction to PL/SQL iii Contents I Introduction Lesson Objectives I-2 Course Objectives I-3 Human Resources (HR) Schema for This Course I-4 Course Agenda I-5 Class Account Information I-6 Appendixes Used in This Course I-7 PL/SQL

More information

10264A CS: Developing Web Applications with Microsoft Visual Studio 2010

10264A CS: Developing Web Applications with Microsoft Visual Studio 2010 10264A CS: Developing Web Applications with Microsoft Visual Studio 2010 Course Number: 10264A Course Length: 5 Days Course Overview In this course, students will learn to develop advanced ASP.NET MVC

More information

Connector for Microsoft SharePoint Product Guide - On Premise. Version

Connector for Microsoft SharePoint Product Guide - On Premise. Version Connector for Microsoft SharePoint Product Guide - On Premise Version 03.0.00 This Documentation, which includes embedded help systems and electronically distributed materials, (hereinafter referred to

More information

DbSchema Forms and Reports Tutorial

DbSchema Forms and Reports Tutorial DbSchema Forms and Reports Tutorial Contents Introduction... 1 What you will learn in this tutorial... 2 Lesson 1: Create First Form Using Wizard... 3 Lesson 2: Design the Second Form... 9 Add Components

More information

Océ DS10. Operator s manual

Océ DS10. Operator s manual Océ DS10 Operator s manual Océ-Technologies B.V. Trademarks Products in this manual are referred to by their trade names. In most, if not all cases, these designations are claimed as trademarks or registered

More information

Report Designer Report Types Table Report Multi-Column Report Label Report Parameterized Report Cross-Tab Report Drill-Down Report Chart with Static

Report Designer Report Types Table Report Multi-Column Report Label Report Parameterized Report Cross-Tab Report Drill-Down Report Chart with Static Table of Contents Report Designer Report Types Table Report Multi-Column Report Label Report Parameterized Report Cross-Tab Report Drill-Down Report Chart with Static Series Chart with Dynamic Series Master-Detail

More information

EMC Documentum Composer

EMC Documentum Composer EMC Documentum Composer Version 6.0 SP1.5 User Guide P/N 300 005 253 A02 EMC Corporation Corporate Headquarters: Hopkinton, MA 01748 9103 1 508 435 1000 www.emc.com Copyright 2008 EMC Corporation. All

More information

Table of Contents. Table of Contents

Table of Contents. Table of Contents Powered by 1 Table of Contents Table of Contents Dashboard for Windows... 4 Dashboard Designer... 5 Creating Dashboards... 5 Printing and Exporting... 5 Dashboard Items... 5 UI Elements... 5 Providing

More information

HotDocs Document Services. Administrator s Guide

HotDocs Document Services. Administrator s Guide HotDocs Document Services Administrator s Guide Copyright 2014 HotDocs Limited. All rights reserved. No part of this product may be reproduced, transmitted, transcribed, stored in a retrieval system, or

More information

Access Review. 4. Save the table by clicking the Save icon in the Quick Access Toolbar or by pulling

Access Review. 4. Save the table by clicking the Save icon in the Quick Access Toolbar or by pulling Access Review Relational Databases Different tables can have the same field in common. This feature is used to explicitly specify a relationship between two tables. Values appearing in field A in one table

More information

SAS Data Integration Studio 3.3. User s Guide

SAS Data Integration Studio 3.3. User s Guide SAS Data Integration Studio 3.3 User s Guide The correct bibliographic citation for this manual is as follows: SAS Institute Inc. 2006. SAS Data Integration Studio 3.3: User s Guide. Cary, NC: SAS Institute

More information

Developing ASP.NET MVC 5 Web Applications. Course Outline

Developing ASP.NET MVC 5 Web Applications. Course Outline Developing ASP.NET MVC 5 Web Applications Course Outline Module 1: Exploring ASP.NET MVC 5 The goal of this module is to outline to the students the components of the Microsoft Web Technologies stack,

More information

Oracle Database: Program with PL/SQL Ed 2

Oracle Database: Program with PL/SQL Ed 2 Oracle University Contact Us: +38 61 5888 820 Oracle Database: Program with PL/SQL Ed 2 Duration: 5 Days What you will learn This Oracle Database: Program with PL/SQL training starts with an introduction

More information

Oracle Database: Program with PL/SQL

Oracle Database: Program with PL/SQL Oracle University Contact Us: + 420 2 2143 8459 Oracle Database: Program with PL/SQL Duration: 5 Days What you will learn This Oracle Database: Program with PL/SQL training starts with an introduction

More information

Apex TG India Pvt. Ltd.

Apex TG India Pvt. Ltd. (Core C# Programming Constructs) Introduction of.net Framework 4.5 FEATURES OF DOTNET 4.5 CLR,CLS,CTS, MSIL COMPILER WITH TYPES ASSEMBLY WITH TYPES Basic Concepts DECISION CONSTRUCTS LOOPING SWITCH OPERATOR

More information

Service Manager. Ops Console On-Premise User Guide

Service Manager. Ops Console On-Premise User Guide Service Manager powered by HEAT Ops Console On-Premise User Guide 2017.2.1 Copyright Notice This document contains the confidential information and/or proprietary property of Ivanti, Inc. and its affiliates

More information

6 Months Training Module in.net Module 1-Total Days-20

6 Months Training Module in.net Module 1-Total Days-20 6 Months Training Module in.net Visual Studio Version: 2008.net Framework: 3.5 Database: SQL Server 2005 Module 1-Total Days-20 Introduction to.net framework: History of.net.net framework.net version Features/advantages

More information

T-SQL Training: T-SQL for SQL Server for Developers

T-SQL Training: T-SQL for SQL Server for Developers Duration: 3 days T-SQL Training Overview T-SQL for SQL Server for Developers training teaches developers all the Transact-SQL skills they need to develop queries and views, and manipulate data in a SQL

More information

Introduction to Computer Science and Business

Introduction to Computer Science and Business Introduction to Computer Science and Business The Database Programming with PL/SQL course introduces students to the procedural language used to extend SQL in a programatic manner. This course outline

More information

Oracle Database 12c: Program with PL/SQL Duration: 5 Days Method: Instructor-Led

Oracle Database 12c: Program with PL/SQL Duration: 5 Days Method: Instructor-Led Oracle Database 12c: Program with PL/SQL Duration: 5 Days Method: Instructor-Led Course Description This training starts with an introduction to PL/SQL and then explores the benefits of this powerful programming

More information

Programming in Visual Basic with Microsoft Visual Studio 2010

Programming in Visual Basic with Microsoft Visual Studio 2010 Programming in Visual Basic with Microsoft Visual Studio 2010 Course 10550; 5 Days, Instructor-led Course Description This course teaches you Visual Basic language syntax, program structure, and implementation

More information

Microsoft Dynamics GP. Extender User s Guide

Microsoft Dynamics GP. Extender User s Guide Microsoft Dynamics GP Extender User s Guide Copyright Copyright 2009 Microsoft Corporation. All rights reserved. Complying with all applicable copyright laws is the responsibility of the user. Without

More information

Using the VMware vcenter Orchestrator Client. vrealize Orchestrator 5.5.1

Using the VMware vcenter Orchestrator Client. vrealize Orchestrator 5.5.1 Using the VMware vcenter Orchestrator Client vrealize Orchestrator 5.5.1 You can find the most up-to-date technical documentation on the VMware website at: https://docs.vmware.com/ If you have comments

More information

DbSchema Forms and Reports Tutorial

DbSchema Forms and Reports Tutorial DbSchema Forms and Reports Tutorial Introduction One of the DbSchema modules is the Forms and Reports designer. The designer allows building of master-details reports as well as small applications for

More information

If this is the first time you have run SSMS, I recommend setting up the startup options so that the environment is set up the way you want it.

If this is the first time you have run SSMS, I recommend setting up the startup options so that the environment is set up the way you want it. Page 1 of 5 Working with SQL Server Management Studio SQL Server Management Studio (SSMS) is the client tool you use to both develop T-SQL code and manage SQL Server. The purpose of this section is not

More information

Oracle Database 12c R2: Program with PL/SQL Ed 2 Duration: 5 Days

Oracle Database 12c R2: Program with PL/SQL Ed 2 Duration: 5 Days Oracle Database 12c R2: Program with PL/SQL Ed 2 Duration: 5 Days This Database Program with PL/SQL training shows you how to develop stored procedures, functions, packages and database triggers. You'll

More information

Use Case 2: Extending object/application to support a new object attribute and a validation for that attribute using either Scripting or Java.

Use Case 2: Extending object/application to support a new object attribute and a validation for that attribute using either Scripting or Java. Overview This use case in this document show how the tooling provided with the products based on Tivoli s process automation engine can help you add value through product extensions and/or integration

More information

SECURED PROGRAMMING IN.NET DETAILED TRAINING CONTENT INDUSTRIAL TRAINING PROGRAM ( )

SECURED PROGRAMMING IN.NET DETAILED TRAINING CONTENT INDUSTRIAL TRAINING PROGRAM ( ) SECURED PROGRAMMING IN.NET DETAILED TRAINING CONTENT INDUSTRIAL TRAINING PROGRAM (2013-2014) MODULE: C# PROGRAMMING CHAPTER 1: INTRODUCING.NET AND C# 1.1 INTRODUCTION TO LANGUAGES C++ C# DIFFERENCES BETWEEN

More information

Conditionally control code flow (loops, control structures). Create stored procedures and functions.

Conditionally control code flow (loops, control structures). Create stored procedures and functions. TEMARIO Oracle Database: Program with PL/SQL Ed 2 Duration: 5 Days What you will learn This Oracle Database: Program with PL/SQL training starts with an introduction to PL/SQL and then explores the benefits

More information

Microsoft Developing ASP.NET MVC 4 Web Applications

Microsoft Developing ASP.NET MVC 4 Web Applications 1800 ULEARN (853 276) www.ddls.com.au Microsoft 20486 - Developing ASP.NET MVC 4 Web Applications Length 5 days Price $4290.00 (inc GST) Version C Overview In this course, students will learn to develop

More information

PROGRAMMING IN VISUAL BASIC WITH MICROSOFT VISUAL STUDIO Course: 10550A; Duration: 5 Days; Instructor-led

PROGRAMMING IN VISUAL BASIC WITH MICROSOFT VISUAL STUDIO Course: 10550A; Duration: 5 Days; Instructor-led CENTER OF KNOWLEDGE, PATH TO SUCCESS Website: PROGRAMMING IN VISUAL BASIC WITH MICROSOFT VISUAL STUDIO 2010 Course: 10550A; Duration: 5 Days; Instructor-led WHAT YOU WILL LEARN This course teaches you

More information

SCM380 SAP MII - Manufacturing Integration and Intelligence Fundamentals

SCM380 SAP MII - Manufacturing Integration and Intelligence Fundamentals SCM380 SAP MII - Manufacturing Integration and Intelligence Fundamentals. COURSE OUTLINE Course Version: 10 Course Duration: 4 SAP Copyrights and Trademarks 2016 SAP SE or an SAP affiliate company. All

More information

A Guide to Quark Author Web Edition 2015

A Guide to Quark Author Web Edition 2015 A Guide to Quark Author Web Edition 2015 CONTENTS Contents Getting Started...4 About Quark Author - Web Edition...4 Smart documents...4 Introduction to the Quark Author - Web Edition User Guide...4 Quark

More information

Teamcenter 11.1 Systems Engineering and Requirements Management

Teamcenter 11.1 Systems Engineering and Requirements Management SIEMENS Teamcenter 11.1 Systems Engineering and Requirements Management Systems Architect/ Requirements Management Project Administrator's Manual REQ00002 U REQ00002 U Project Administrator's Manual 3

More information

Webnodes Developers Quick Guide

Webnodes Developers Quick Guide Webnodes Webnodes Developers Quick Guide Want to get started right away? Ole Gulbrandsen 1/1/2010 Webnodes Developers Quick Guide Want to get started right away? This guide is for C# developers and will

More information

B I Z I N S I G H T Release Notes. BizInsight 7.3 December 23, 2016

B I Z I N S I G H T Release Notes. BizInsight 7.3 December 23, 2016 B I Z I N S I G H T 7. 3 Release Notes BizInsight 7.3 December 23, 2016 Copyright Notice makes no representations or warranties with respect to the contents of this document and specifically disclaims

More information

CA IdentityMinder. Glossary

CA IdentityMinder. Glossary CA IdentityMinder Glossary 12.6.3 This Documentation, which includes embedded help systems and electronically distributed materials, (hereinafter referred to as the Documentation ) is for your informational

More information

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Primavera Portfolio Management 9.0 What s New Copyright 1999-2011, Oracle and/or its affiliates. The Programs (which include both the software and documentation) contain proprietary information; they are

More information

COURSE 20486B: DEVELOPING ASP.NET MVC 4 WEB APPLICATIONS

COURSE 20486B: DEVELOPING ASP.NET MVC 4 WEB APPLICATIONS ABOUT THIS COURSE In this course, students will learn to develop advanced ASP.NET MVC applications using.net Framework 4.5 tools and technologies. The focus will be on coding activities that enhance the

More information

IBM i Version 7.2. Database Database overview IBM

IBM i Version 7.2. Database Database overview IBM IBM i Version 7.2 Database Database overview IBM IBM i Version 7.2 Database Database overview IBM Note Before using this information and the product it supports, read the information in Notices on page

More information

Introduction to Microsoft.NET Programming Using Microsoft Visual Studio 2008 (C#) Course Overview. Prerequisites. Audience.

Introduction to Microsoft.NET Programming Using Microsoft Visual Studio 2008 (C#) Course Overview. Prerequisites. Audience. Introduction to Microsoft.NET Programming Using Microsoft Visual Studio 2008 (C#) Course Number: 6368A Course Length: 1 Day Course Overview This instructor-led course provides an introduction to developing

More information

BMC Remedy Action Request System Using a BIRT Editor to Create or Modify Web Reports

BMC Remedy Action Request System Using a BIRT Editor to Create or Modify Web Reports White Paper BMC Remedy Action Request System 7.6.04 Using a BIRT Editor to Create or Modify Web Reports September 2012 www.bmc.com Contacting BMC Software You can access the BMC Software website at http://www.bmc.com.

More information

Oracle Financial Services Governance, Risk, and Compliance Workflow Manager User Guide. Release February 2016 E

Oracle Financial Services Governance, Risk, and Compliance Workflow Manager User Guide. Release February 2016 E Oracle Financial Services Governance, Risk, and Compliance Workflow Manager User Guide Release 8.0.2.0.0 February 2016 E65393-01 Oracle Financial Services Governance, Risk, and Compliance Workflow Manager

More information

ADF Code Corner How-to bind custom declarative components to ADF. Abstract: twitter.com/adfcodecorner

ADF Code Corner How-to bind custom declarative components to ADF. Abstract: twitter.com/adfcodecorner ADF Code Corner 005. How-to bind custom declarative components to ADF Abstract: Declarative components are reusable UI components that are declarative composites of existing ADF Faces Rich Client components.

More information

BEA WebLogic. Integration. Tutorial: Building Your First Data Transformation

BEA WebLogic. Integration. Tutorial: Building Your First Data Transformation BEA WebLogic Integration Tutorial: Building Your First Data Transformation Version 8.1 Service Pack 4 Document Date: December 2004 Copyright Copyright 2004-2005 BEA Systems, Inc. All Rights Reserved. Restricted

More information

DEVELOPING WEB APPLICATIONS WITH MICROSOFT VISUAL STUDIO Course: 10264A; Duration: 5 Days; Instructor-led

DEVELOPING WEB APPLICATIONS WITH MICROSOFT VISUAL STUDIO Course: 10264A; Duration: 5 Days; Instructor-led CENTER OF KNOWLEDGE, PATH TO SUCCESS Website: DEVELOPING WEB APPLICATIONS WITH MICROSOFT VISUAL STUDIO 2010 Course: 10264A; Duration: 5 Days; Instructor-led WHAT YOU WILL LEARN In this course, students

More information