MorphX Integration
MorphX Integration
Disclaimer: This material is for informational purposes only. Microsoft Business Solutions ApS disclaims all warranties and conditions with regard to use of the material for other purposes. Microsoft Business Solutions ApS shall not, at any time, be liable for any special, direct, indirect or consequential damages, whether in an action of contract, negligence or other action arising out of or in connection with the use or performance of the material. Nothing herein should be construed as constituting any kind of warranty.
Copyright Notice: Copyright © 2002 Microsoft Business Solutions ApS, Denmark.
Trademark Notice: Microsoft, Great Plains, bCentral and Microsoft Windows 2000 are either registered trademarks or trademarks of Microsoft Corporation or Microsoft Business Solutions Corporation in the United States and/or other countries. Microsoft Business Solutions Corporation and Microsoft Business Solutions ApS are wholly owned subsidiaries of Microsoft Corporation. Navision is a registered trademark of Microsoft Business Solutions ApS in the United States and/or other countries. The names of actual companies and products mentioned herein may be the trademarks of their respective owners. No part of this document may be reproduced or transmitted in any form or by any means, whole or in part without the prior written permission of Microsoft Business Solutions ApS. Information in this document is subject to change without notice. Any rights not expressly granted herein are reserved
TABLE OF CONTENTS
LESSON 1. WELCOME TO MICROSOFT® BUSINESS SOLUTIONS– 1-1 AXAPTA® MORPHX INTEGRATION 1.1 Introduction
1-1
LESSON 2. BASIC GUIDELINES
2-1
2.1 Project Design Guidelines
2-1
2.2 Integration Possibilities
2-2
LESSON 3. AXAPTEL
3-1
3.1 Axaptel
3-2
3.2 Exercises
3-3
LESSON 4. USING THE JOURNALS
4-1
4.1 Journals
4-1
4.2 Creating the Journal
4-2
4.3 Creating Transactions
4-3
4.4 Posting Journals
4-4
4.5 Exercises
4-7
LESSON 5. USING API
5-1
5.1 Using APIs
5-1
5.2 APIs in General Ledger
5-2
5.3 Trade Series APIs
5-6
5.4 Inventory Management APIs
5-13
5.5 Production Series
5-15
5.6 Number Sequences
5-16
5.7 Exercises
5-21
LESSON 6. USING THE COM INTERFACE
6-1
6.1 What Are COM Objects
6-1
6.2 MS-Agent
6-2
6.3 Axapta Business Connector
6-3
6.4 Exercises
6-4
LESSON 7. ACTIVE X
7-1
7.1 What Is ActiveX
7-1
7.2 ActiveX Explorer
7-2
7.3 Exercises
7-3
LESSON 8. EDITOR SCRIPTS
8-1
8.1 Editor Scripts
8-1
8.2 Exercises
8-2
LESSON 9.
DYNAMIC LINK LIBRARY
9-1
9.1 Use of Dynamic Link Libraries
9-1
9.2 WinApi
9-2
9.3 VarChart
9-3
9.4 Exercises
9-4
LESSON 10. THE RUNBASE CLASS
10-1
10.1 The RunBase class
10-2
10.2 Exercises
10-9
LESSON 11. THE BATCH SYSTEM
11-1
11.1 The Batch System
11-1
11.2 RunBaseBatch
11-2
11.3 Exercises
11-4
LESSON 12. FOUNDATION CLASSES
12-1
12.1 Foundation Classes
12-2
12.2 List
12-3
12.3 Set
12-5
12.4 Map
12-6
12.5 Array
12-7
12.6 Struct
12-8
12.7 Exercises
12-9
LESSON 13. GANTT CLASSES
13-1
13.1 Gantt Classes
13-2
13.2 Projects, Inquiry, Gantt Chart
13-3
13.3 Exercises
13-4
APPENDIX A. WELCOME TO AXAPTA INTEGRATION
I
General Information
II
Before You Start the Class:
IV
Beginning the Course
V
Notes to Introduction Lesson
VI
APPENDIX B. BASIC GUIDELINES
I
Basic Guidelines
II
APPENDIX C. AXAPTEL
I
Axaptel
II
Exercise Solutions
III
APPENDIX D. USING THE JOURNALS
I
Instructor Notes
II
Exercise Solutions
IV
APPENDIX E. USING API
I
Instructor Notes
II
Exercise Solutions
V
APPENDIX F. USING THE COM INTERFACE
I
Using the COM Interface
II
Exercise Solutions
IV
APPENDIX G. ACTIVE X
I
Instructor Notes
II
Exercise Solutions
III
APPENDIX H. EDITOR SCRIPTS
I
Instructor Notes
II
Exercise Solutions
III
APPENDIX I. DYNAMIC LINK LIBRARY
I
Instructor Notes
II
Exercise Solutions
III
APPENDIX J. THE RUNBASE CLASS
I
Instructor Notes
II
Exercise solutions
III
APPENDIX K. THE BATCH SYSTEM
I
Instructor Notes
II
Exercise Solutions
III
APPENDIX L. FOUNDATION CLASSES
I
Instructor Notes
II
Exercise Solutions
III
APPENDIX M. GANTT CLASSES
I
Instructor Notes
II
Exercise Solutions
III
Lesson 1. Welcome to Microsoft® Business Solutions–Axapta® MorphX Integration
At the end of this course, you are expected to be able to: Understand the basic concepts of integration to Axapta Have reviewed the philosophy of several main application programming interfaces used in Axapta Have viewed examples of several main application programming interfaces used in Axapta Be prepared to build your own integrated Axapta applications. Have learned about the COM interface
AX-300-ILT-053-v01.00-ENUS
Welcome to Microsoft® Business Solutions–Axapta® MorphX Integration
1-1
1.1 INTRODUCTION Now you are finished with the MorphX Standards class, and know what the standards of programming are in Axapta. To make your product ready for market, you must integrate your product into Axapta. This course will guide you through the integration process.
About this class In this class you will understand how to create your own projects and integrate those into Axapta. You will get the basic concepts of how additional modules, such as the API (Application Programming Interface) classes can be added to Axapta. Furthermore, you will learn about best practices when developing new projects and how journals can be used in connection with integration to Axapta. The main objective of this course is that the students can create new projects integrated with the standard application.
Course Prerequisites •
Successful completion of the MorphX Essentials and the X++ Basic online courses.
•
It is highly recommended that you have completed the X++ Advanced Classroom course.
•
At least 6 month working knowledge of the application and development environment.
General This Course is comprised of a series of lessons, each explaining a range of specific subjects and functionalities which belong together in Axapta. All lessons are developed in relation to common business logic, and the subjects and functionalities are presented within the perspective of the usual business procedures familiar to most users. This material is a supplement to the instructor’s explanation during the course and not tailored for individual studies without tutoring. In the beginning of each lesson you will find a brief overview of the lesson and a list of objectives, informing you what subjects and functionalities you will get to know in the specific lesson. In each lesson there will be examples; the examples make it easier for you to refer the theoretical
Welcome to Microsoft® Business Solutions–Axapta® MorphX Integration
1-2
aspects of the course to how Axapta works outside classroom training. At the end of each lesson you will find exercises. The exercises are designed to give you a hands-on experience with the functionality described.
Lesson 2. Basic Guidelines
AX-300-ILT-054-v01.00-ENUS
Basic Guidelines
2-1
2.1 PROJECT DESIGN GUIDELINES When a new project is created in Axapta, it should be designed in a manner so that the least possible changes in main Axapta need to be made in the standard application. This will result in efficient time management in updating your product when new versions of Axapta are released. Items like APIs and journals are not likely to change. This consistency is the key to successful Axapta integration. APIs –Application Programming Interface classes, are especially developed for easy integration into Axapta. As a first step in planning your project, find out what kind of APIs are in Axapta and how they can be used.
General Recommendations ∙
For all third party projects in Axapta, it is strongly recommended that the project “stands alone” as much as possible.
∙
Do not, unless absolutely necessary, change the standard Axapta application itself.
Basic Guidelines
2-2
2.2 INTEGRATION POSSIBILITIES There are two basic ways of product integration into Axapta: using Journals and using APIs.
Journals Journals are meant to be tables with lists of transactions to be performed. The functions used to enter data into journals are simple. So it is very easy to use them as a mode of integration into Axapta. Indigenous to your project you can create a method for entering data in a journal, and then post the journal manually or by calling journal posting and finally give the user the possibility to post the journal automatically. In this manner, you will be ensured that transactions are created and controlled on basis of the Axapta Business Logic (the rules applied in the standard application) since all your data will be checked, and posted by Axapta routines. This manner also results in the flexibility to overview your journal and post it manually.
APIs To use APIs is another way of doing the job, but developing wise it is more complex. This method will result in better performance since transactions are directly made using the same classes that Axapta uses. APIs are classes especially designed to be reused in other parts of the application, in order to get direct access to a specific module. Since Axapta applications are made by several groups of programmers, APIs from each group are slightly different. The difference is in the way these APIs can be used: One group of APIs requires only initialization of an instance and then parses parameters to it. Other groups of APIs need to be loaded into a new class. For more detailed information about groups of APIs, and specific instances, see the Lesson – Using APIs, in this document.
Lesson 3. Axaptel
At the end of this lesson, you are expected to be able to: Know about the data model which you will use throughout this course
AX-300-ILT-055-v01.00-ENUS
Axaptel
3-2
3.1 AXAPTEL A new module for hotel management will be developed for Axapta. Primarily, the module will enable customers to make room reservations within specified date intervals. It should also be possible to keep an account of the extra costs associated with the hotel bill, for example, room service, minibar or nightclub. The database design for this module will resemble the following:
Base Enums
HotelRoomType
Extended Data Types
HotelBookingId
STR 10
Tables
HotelBookingTable
ENUM
Single
Ref: HotelBookingTable.
HotelRoomTable
HotelBookingId
Double
HotelRoomId STR 10
Executive
Ref: HotelRoomTable. HotelRoomId
HotelExpenseType Restaurant Minibar Nightclub Transport
Fields HotelRoomTable:
HotelGuestExpenses
Axaptel
3-2
HotelRoomId
STR
HotelRoomType ENUM LedgerAccount STR Rate REAL HotelBookingTable: HotelBookingId STR HotelRoomId
STR
ToDate DATE FromDate DATE CustAccount STR Invoiced ENUM NoYes HotelGuestExpenses: HotelBookingId STR HotelExpenseType ENUM TransDate DATE Amount REAL
Axaptel
3-3
3.2 EXERCISES
Exercise 1
System construction
Import the project: Ax30MXIDemoProject.xpo
Exercise 2
System construction Enter data in the forms
Lesson 4. Using the Journals
At the end of this lesson, you are expected to be able to: Access existing journals and set up lines. Set up journals. Post journals. Know about different journal types Understand the complexity of creating transactions.
AX-300-ILT-056-v01.00-ENUS
Using the Journals
4-1
4.1 JOURNALS In this chapter the word Journal is used for journals like General Journal in General Ledger module, like Payment Journal in Accounts Receivable, or like Invoice Approval Journal in the Accounts Payable module. The general concept behind using journals can be transferred to other types of journals. However, when doing so, you need to investigate the function and data model of the journal. All journals we will write here have a common data model. Thus, it is easy to learn how to use them, once you know how to use at least one of them. Journals are the easiest way of integrating into Axapta. Using Journals you need not learn about the complex logic behind the transactions. Using a Journal lines table, you fill it in with data from your project, and call upon Axapta’s method for posting the journal. All error checking and posting will be simultaneously performed without additional programming.
General Guidelines There are several ways of using Journals for posting the project: •
Creating or using an already created Journal
•
Posting transactions to journal lines
•
Posting or checking Journals
Using the Journals
4-2
4.2 CREATING THE JOURNAL In order to make your project very flexible, every time you post, you create a new journal for this particular posting. In your project, specify what journal name should be used for the new journal. Journal names for different modules are located in xJournalName tables, where “x” is name of the module.
Example LedgerJournalName, InventJournalName
or ProdJournalName.
There is one more type of grouping journal: field JournalType. This enumerated data type field indicates where specific journal names should be used: for payments, periodic, daily journals and so on. All journals are stored in specific module tables, such as: LedgerJournalTable, InventJournalTable and ProdJournalTable. Depending in which module you use, either create, or use an already created journal in these tables. For the creation of a new record, you should fill at least two fields of the record, For example, if you are creating Ledger journal:
Example ledgerJournalTable.JournalName = ’CustPay’; ledgerJournalTable.Name = ’TestJournal’ ledgerJournalTable.insert();
After ledgerJournalTable.Insert (), a record in LedgerJournalTable is created and unique batch number will be assigned to the record. In LedgerJournalTable case, it is the JournalNum field. This unique number is needed in posting transactions; it is a relationship field between the LedgerJournalTable and LedgerJournalTrans table. The same function exists in other modules.
Using the Journals
4-3
4.3 CREATING TRANSACTIONS All transactions must be posted in a journal line table, which usually has the postfix “Trans”, for example: LedgerJournalTrans, InventJournalTrans and so on. Posting to the journal lines is simply the creation of new records in the JournalLines table. You need to fill the record with data and then insert it. There are two important fields to be filled every time you insert a new record: xJournalTrans.JournalNum (xJounalTrans.JournalId in Inventory and Production modules) – a unique number identifying the journal (relationship to JournalTable). This field is mandatory, because transactions are assigned to one of the journals. In our case it is the journal number that we have created, or a previously existing journal number. JournalTrans.Voucher – Transaction voucher number. This number can either be generated automatically, or if you know the exact voucher number you can define it yourself. For automatic generation use the NumberSeq class:
Example NumberSeq numSeq; numberSeq = NumberSeq::newGetNumFromCode(LedgerjournalName::Find('CustPay').Vo ucherSeries);; xJournalTrans.Voucher = numSeq.Num();
In this example xJournalName is the table of journal names in a given module. JournalName (parameter for Find method) is journal name, which you are using. xJournalTrans – table for transactions posting. Another and easier way to get voucher numbers is to use the voucher API to allocate voucher numbers. Other fields in transaction table should be filled in, if necessary. In inventory and production modules, specify quantities, in Ledger amount, to be transferred. Also, fill in the specifications of accounts, transaction texts, approvals and so on. Fields for those types of data are easily accessed. Check xJournalTrans table definitions in modules, for more detailed information. Note: The General Ledger module currency field is mandatory, so you must fill in the currency and exchange rate fields.
Using the Journals
4-4
4.4 POSTING JOURNALS After your transactions are posted to the journal, you need to check and post the journal. Modules have different classes for checking and posting journals.
For checking and posting in modules use: In General Ledger; use the class LedgerJournalCheckPost. The easiest way to do it is to create instance of this class using newLedgerJournalTable static method and then run the class: newLedgerJournalTable – method used when you have a record in the LedgerJournalTable, and want to post all lines in that journal. Parameters for this method are: _ledgerJournalTable - record in LedgerJournalTable representing the journal, which should be posted. _post – NoYes parameter for specifying, if it will be only checking a journal or both checking and posting. Value Yes indicates that after checking, posting should be done. _transferErrors – NoYes parameter for transferring vouchers with errors to another journal. If Yes, all vouchers with errors will be transferred into a new journal with the same name and description, but with different batch numbers. The default value is No.
Example: LedgerJournalCheckPost ledgerJCP; LedgerJCP = LedgerJournalCheckPost::newLedgerJournalTable(lJournalTable,NoYes: :Yes); ledgerJCP.run();
Here lJournalTable exemplifies a record in LedgerJournalTable. A journal can be checked in the same way
Using the Journals
4-5
In Inventory module, use the class InventJournalCheckPost. The easiest way to do it is to create an instance of this class using the newJournalCheckPost static method and then run the class: newJournalCheckPost – method used when you have a journal number from InventJournalTable, and want to post all lines in that journal. Parameters for this method are:
_journalCheckPostType – JournalCheckPostType parameter for specifying, if it will only check a journal or both check and post. Value Post indicates that after checking, posting should be made and value Check indicates it that only checking will be performed. _inventJournalTable - record in inventJournalTable representing the journal, which should be posted.
Example //check inventJournalCheckPost inventJCP; Intg056_1_HotelJournalPost Hjp; ; Hjp = new Intg056_1_HotelJournalPost(); inventJCP = inventJournalCheckPost::newJournalCheckPost(JournalCheckPostType:: check,inventJournalTable::find(Hjp.journalId())); inventJCP.run(); //post inventJournalCheckPost inventJCP; Intg056_1_HotelJournalPost Hjp; ; Hjp = new Intg056_1_HotelJournalPost();
Using the Journals
4-6
inventJCP = inventJournalCheckPost::newJournalCheckPost(JournalCheckPostType:: Post,inventJournalTable::find(Hjp.journalId())); inventJCP.run();
Here inventJournalTable exemplifies a record in InventJournalTable. A journal can be checked in the same way. In the Production module you use one child class from ProdJournalCheckPost depending of the journal that you use in this module. The easiest way to do it is to create an instance of this class using the newJournalCheckPost static method and then run the class: newJournalCheckPost – method used when you have a journal ID in XProdJournalTable, and want to post all lines in that journal. In the ProductionModule exists more than one tables of type xJournalTable. Parameters for this method are: _autoblock – NoYes parameter for specifying if the journal will be blocked or Not. _showInfoResult - NoYes parameter for specifying if the results of posting will appear in Infolog. _journalCheckPostType – JournalCheckPostType parameter for specifying, if it will be only checking a journal or both checking and posting. Value Post indicates that after checking, posting should be made and value Check indicates it will be only checking. _tableId – ID of xProdJournalTable. _JournalId – Identification of Journal that has been created. In other modules there are common functions for working with journals. Note: Remember to use transactions control statements, to be sure that all data will be posted as required. Task: Refer to, Appendixes, Task1 – Creating and posting to the General Journal to have a better understanding how posting a journal works. Then try to implement it.
Using the Journals
4-7
4.5 EXERCISES
Exercise 3
Journal lines
Every time a hotel guest checks out, a transaction needs to be made on the customer’s account, and a sales account added to the ledger module. Create a new class that checks for created lines, or uses an existing journal and which can create journal lines. Make sure that these features can be activated using a button on the form that is used for reservation administration.
Exercise 4
Automatic Posting
Prepare the class above, such that when the user press the check out button the field Invoiced is set to ‘Yes’ and a new journal and line will be created and posted automatically.
Exercise 5 Optional
Consumption
Each day a hotel room has been used, a stock transaction should be made for items that are included in room maintenance, for example, towels or toilet paper. Make sure that these transactions are automatically registered and posted using a stock journal as shown in previous tasks. You must create a button in the HotelRoomTable form for this registration and create a table and a form where Item is included for each Room. You have to create a new field in the HotelRoomTable of the type Date1980. When you
Using the Journals
4-8
run the registration you must write the date of the system in the new field. You need to make sure that two registrations per day are not allowed.
Lesson 5. Using API
At the end of this lesson, you are expected to be able to: Use APIs for posting transactions Use API for purchase and sales lines Use API for automatic number sequences And know about: API Classes in general.
AX-300-ILT-057-v01.00-ENUS
Using API
5-1
5.1 USING APIS APIs are classes providing interface to complex structures, calculations and other processes in the application. The general idea is not to reprogram everything, but to reuse code as much as possible. The APIs function with quite a simple interface. This enables you to follow the rules already defined by Axapta programmers. APIs have different interfaces as there are modules in Axapta written by several groups of programmers. So, in order to use one particular API, you need to check exactly what interface this API provides. If you want to use an API, which is not described in this course, first of all check for similar interface types. Then follow the directions specified, and analyze the new API you want to use. The most commonly used APIs are briefly described below:
Using API
5-2
5.2 APIS IN GENERAL LEDGER Posting Transactions The class LedgerVoucher is the class that harnesses the posting of multiple vouchers at one time. It checks that the posting is correct, and that the voucher balances. Possible rounding of postings is carried out if necessary. The LedgerVoucher class will hold all of the transactions in a temporary storage until the End method is called. The End method will create ledger transaction records from the temporary postings. Each voucher in the LedgerVoucher will be contained in a LedgerVoucherObject. Each transaction in each voucher will be contained in a LedgerVoucherTransObject.. In short, the procedure is: 1.
Instantiating the LedgerVoucher class
2.
Looping over the vouchers to instantiate LedgerVoucherObject classes, and registering these in the LedgerVoucher class.
3.
For each voucher, looping over the transactions to instantiate LedgerVoucherTransObject classes, and registering these in the LedgerVoucher class.
Note If default values for the voucher object will suffice, step number two can be omitted. This means that all transactions will be posted as one voucher.
A more detailed description of the steps involved follows:
Instantiation of LedgerVoucher LedgerVoucher::newLedgerPost(_ detailSummary, sysModule, numberSeqCode); }
Using API
5-3
Parameters: ∙
DetailSummary _detailSummary - value specifying either summary or details. Specifying summary will result in summarizing the amounts per account, date and voucher.
∙
SysModule _sysModule – System module, from which transactions are made. This value can also be used for posting transactions from your own modules.
∙
NumbersequenceCode _numberSeqCode – reference to the number sequence used for numbering the vouchers.
Instantiation of LedgerVoucherObject LedgerVoucherObject::newVoucher( voucher, transactionDate, sysModule, transType, creditNote, _operationsTax); 1.
Voucher _voucher number – number of the voucher
2.
TransactionDate _transactionDate – Date of transaction. Default value – current date.
3.
SysModule _sysModule – System module, from which transactions are made. This value can also be used for posting transactions from your own modules.
4.
LedgerTransType _transType – Ledger transaction type. To see all available ledger transaction types, refer to base enum LedgerTransType. Default value LedgerTransType:None.
5.
NoYes creditnote – indicates whether the voucher is a credit note.
6.
OperationsTax operationsTax – Indicates what kind of operation tax should be used when posting a transaction. The default value is OperationsTax::Current. For all available OperationTax codes, look in the base enum OperationsTax details.
Using API
5-4
Providing additional information to LedgerVoucherObject ledgerVoucherObject.parmDocument(transdate, voucher); ledgerVoucherObject.parmTaxReference(tax.taxReference() ); 7.
ParmDocument is used to set original document number and date. The default values are blank and no date.
8.
ParmTaxReference is used to specify a custom link between tax transactions. A typical use is linking tax transactions residing in different tables.
Registering the LedgerVoucherObject with the LedgerVoucher ledgerVoucher.AddVoucher(ledgerVoucherObject);
Instantiation of LedgerVoucherTransObject LedgerVoucherTransObject::newCreateTrans( ledgerVoucherObject, ledgerPostingType, ledgerAccount , dimension, currencyCode, amountCur, _recId)
1.
LedgerVoucherObject _ledgerVoucherObject - is the object containing the corresponding voucher.
2.
LedgerPostingType _ledgerPostingType – is a type of posting. For all available posting types, look in base enum LedgerPostingType details.
3.
LedgerAccount _ledgerAccount– the ledger account number on which transactions will be made.
4.
Dimension _dimension - transaction dimension.
5.
CurrencyCode _currencyCode – currency in which transactions will be made.
6.
AmountCur _amountCur – the amount in currency (specified in step 4.)
Using API
5-5
7.
Recid _recid – the registration ID of the originating row
Providing the transaction text ledgerVoucherTransObject.parmTransTxt(_transTxt); TransTxt _transTxt – Transaction text. Default value ''.
Registering the LedgerVoucherTransObject with the LedgerVoucher ledgerVoucher.addTrans(ledgerVoucherTransObject);
Finalizing the posting ledgerVoucher.addTrans(ledgerVoucherTransObject); LedgerVoucher.end(); A coding example using the ledgerVoucher class is provided in the application as the class TutorialLedgerVoucher. The method runSalesPost exemplifies posting a sales order with its lines. The method runJournalPost exemplifies posting from a journal.
Using API
5-6
5.3 TRADE SERIES APIS CustVendVoucher Used for: This class is used for posting Customers and Vendors transactions. It is tightly connected with LedgerVoucher posting. Methods: Commonly used methods are: New – Initializes new instance of CustVendVoucher class. For all parameters see CustVendVoucher/New, or use Construct method. New is opened from the method construct which is a static method that can be used to create an object from either CustVoucher & VendVoucher. Both are derived Classes from CustVendVoucher. Construct – static method, which creates new instance of CustVoucher or VendVoucher, according to SysModule parameter. Parameters: 1.
SysModule _module – module, where transaction will be created. Two modules are supported: SysModule::Cust and SysModule::Vend. According to this field, CustVoucher or VendVoucher object will be created.
2.
LedgerVoucher_ledgerVoucher – LedgerVoucher. Should be previously instantiated
3.
CustVendAC _accountNum – Customer or vendor account number.
4.
AmountCur _amount – Amount for posting.
5.
CurrencyCode _currencyCode – currency code used in transaction.
6.
LedgerTransTxt _transTxtType - Transaction text for use with new transactions. For all possible transaction texts see base enum LedgerTransTxt declaration.
7.
Dimension _dimension – Transaction dimension. Default value is ''.
8.
PostingProfile _postingProfile – Posting profile being processed. Default value is ''.
9.
LedgerPostingType _posting - Transaction posting type is the specification of the type of transaction. Default value is 0. For all available types see base enum LedgerPostingType declaration.
Using API
5-7
10. PaymCode _paymCode – Terms of payment. Default value is ''. 11. SettlementType _settlement – Specifies how settlement takes place. Default value is SettlementType::None. For all available settlement types see base enum SettlementType declaration. 12. EmplId _approvedBy – User ID, which approved current voucher. Default value is curuserid(), Example: ledgerVoucher = ledgerVoucher::newLedgerPost( DetailSummary::Detail, SysModule::Cust, CustParameters::numRefCustAccount(). NumberSequence); LedgerVoucher.AddVoucher( LedgerVoucherObject::newVoucher(numseq.num (), today(), Sysmodule::Cust, LedgerTransType::Sales)); //CustVoucher custVoucher = CustVendVoucher::construct(SysModule::Cust, //Module ledgerVoucher, customer account, amountCur,
// Amount
CompanyInfo::find().currencyCode, LedgerTransTxt::CustInvoiceCust)
//Currency ;
ledgerVoucherTransObject = LedgerVoucherTransObject::newCreateTrans( ledgerVoucher.findLedgerVoucherObject(), LedgerPostingType::CustPayment, ledgerAccount, dimension, CompanyInfo::standardCurrency(),
Using API
5-8
amountcur, recId); //Transacion text ledgerVoucherTransObject.parmTransTxt(txt); //add transaction ledgerVoucher.addTrans(ledgerVoucherTransObject); //Creo la transaccion de cliente custVoucher.post(custTrans); ledgerVoucher.end(); numseq.used(); ttsCommit; CustVendVoucher class is used together with CustVoucher and VendVoucher classes, which extends to some of the functions in the CustVendVoucher class.
Additional functionality Creating new customers Some customers who are only one-time clients do not need to be created permanently in the CustomersTable. On the sales order table (SalesTable), it is possible to mark a new order, as an order which is specific to a onetime customer. The user does not need to type in a customer number. Instead, Axapta creates a new customer classification based on information from an existing customer, which is used as a template. This template is specified in Accounts receivable, Setup, Parameters. The creation of the customer is done by calling the static method CustTable::createOneTimeAccount(Common). The method can be called with either a SalesTable record or a CustInvoiceJour table record. It calls a method to copy information either from the SalesTable record or the CustInvoiceJour record to the new CustTable record.
Creating new orders Using APIs for purchase and sales orders is done throughout other parts of the Axapta application. The APIs that is used are the PurchAutoCreate and SalesAutoCreate classes. These classes are specifically meant to be used from other modules. If you are integrating into the sales and purchase
Using API
5-9
modules it is recommended that you duplicate the structure used in these classes to do the interface. However, if you just need to create, for example, a sales order with lines, this can also be done in a more direct way. You do this by inserting the tables and using the SalesLine.CreateLines() method together with the SalesTableType class. Make sure that the salestype is set correct and the customer account. The method SalesTable.InitFromCustTable() can, for instance, be used to make sure the right values from the customer table are initialized. The API used in other parts of the application is used as follows: PurchAutoCreate which is derived in PurchAutoCreate_Invent, PurchAutoCreate_Prod, PurchAutoCreate_Purch and PurchAutoCreate_Sales. Thus a derived class for each module that needs to create a purchase order. This is done via the method createPurchLine. When new purchase orders should be created, you should use a PurchAutoCreate class hierarchy. This hierarchy is used for creating purchase orders from sales orders, production orders and master planning. The PurchAutoCreate class basically can create a purchase order with only one line by overriding the method PurchAutoCreate.createPurchLine() An example of how the PurchAutoCreate_Sales Class is used can be seen in PurchCreateFromSalesOrder.run(). Here records with the same vendor account number are created in a temporary table, and passed on as parameters to the static method PurchAutoCreate::construct (Common, Object). PurchAutoCreate.create() creates one record in PurchTable and creates as many records in PurchLine as there are records in the temporary table. A similar class hierarchy to SalesAutoCreate is also made for sales orders. PurchAutoCreate and SalesAutoCreate classes use the following methods: SalesLine.createLine(Boolean = false, Boolean = false, Boolean = false, Boolean = false, Boolean = true, Boolean = false, Boolean = false)
Using API
5-10
PurchLine.createLine(Boolean = false, Boolean = false, Boolean = false, Boolean = false, Boolean = true, Boolean = false) Depending on the parameters, these can initiate order lines from the order header, inventory table, trade agreements, and miscellaneous charges. For more information about these methods, see PurchAutoCreate and SalesAutoCreate class declarations.
Invoicing orders The SalesFormLetter and PurchFormLetter class hierarchies are used for printing and posting sales and purchase order journals. These classes can be called in order to post or print a journal for a single sales or purchase order. The following description is valid for SalesFormLetter class as well as for the PurchFormLetter class hierarchy. The posting or printing is done by first calling the static method SalesFormLetter::construct(DocumentStatus , Boolean = true). The DocumentStatus parameter is a base enum, stating with which kind of journal should be posted or printed, for example, DocumentStatus::Confirmation. The Boolean parameter is optional with the default value = true, stating whether a parameter ID should be retrieved from the Parameter ID number sequence. If this parameters is false, the method SalesFormLetter.parmId(ParmId) should be called in order to set the parameter ID. Thereafter the following method should be called. SalesFormLetter.update(Common, Today(), SalesUpdate = SalesUpdate::All, AccountOrder = AccountOrder::None, NoYes = NoYes::No, NoYes = NoYes::No)
Using API
5-11
The method posts or prints a journal for a sales order according to the parameters parsed: 1.
The first parameter should be the SalesTable record. This journal should be posted or printed. The rest of the parameters are optional.
2.
The second parameter is the transaction date.
3.
The third parameter states which quantity should be used in the journal.
4.
The fourth parameter states whether orders should be summary updated (this parameter is obsolete, as only one sales order can be updated at a time).
5.
The fifth parameter tells the class whether the journal should be posted or if only a proforma journal should be created.
6.
The last parameter states whether the journal should be printed or not.
The only difference between the use of the SalesFormLetter and PurchFormLetter classes is the parameters for the update method. The following method should be called with a PurchTable record as the first parameter. PurchFormLetter.update(Common, Num, Today(), NoYes = NoYes::No, NoYes = NoYes::Yes) The second parameter is the vendors packing slip number or invoice number. The last two parameters are the same as in the SalesFormLetter.update method. The method in connection with purchases is written like this: purchFormLetter.update(
Common, Num, transDate, PurchUpdate::All, AccountOrder::None,
Using API
5-12
NoYes::No, NoYes::Yes)
The method takes the following parameters: 1.
A record from the PurchTable.
2.
Labels/Invoice number
3.
Transaction Date
4.
How many are needed
5.
In which order should the purchase orders be handled.
6.
Pro forma
7.
Do you want a printout?
Using API
5-13
5.4 INVENTORY MANAGEMENT APIS Inventory APIs must be used in a slightly different way than the financial or trade series APIs. In this module, in order to use APIs you should: 1.
create your own class
2.
inherit the API you want to use
3.
overwrite several methods
Only then you will be ready to use this API.
Posting transactions InventMovement class hierarchy The InventMovement class hierarchy is used to provide a uniform access to different tables. You could say that it remedies the fact that the databases supported aren’t object oriented databases where tables can extend other tables. Think of the inventory movement as a data carrier class. InventMovement is a super class in a system of classes used for handling information about Inventory movement. Instance of this class could be created using data from different modules, such as Sales or Purchase. For that reason, a new class should be created and the main class InventMovement should be inherited. In the new class you need to overwrite some of the parent class methods. Most of these methods are designed to provide you with data from different sources. Example: You need to define the transactions date. In the Sales table it is the field confirmedDlv. In PurchTable it should be confirmedDlv if specified and deliveryDate if confirmedDlv is not specified. Then TransDate method in InventMov_Sales should be defined as follows: TransDate transDate() { return salesOrderLine.confirmedDlv; } And in the InventMov_Purch: TransDate transDate()
Using API
5-14
{ return purchLine.confirmedDlv? purchLine.confirmedDlv : purchLine.deliveryDate; } The same concept is used for overwriting other methods, where you can provide the necessary information. Good examples include how InventMovement class can be used for inheritance in classes InventMov_Sales and InventMov_Purch.
Inventory Update The InventUpdate class hierarchy is used to handle different status updates of all kinds of inventory movements. The InventUpdate classes doesn’t reference the origins (for example, sales lines, purchase lines or production orders) directly but accesses these through the InventMovement classes. Think of the InventUpdate classes at the engine. InventUpdate is a super class in a system of classes used for handling information about Inventory updating. It allows changing quantities, locations and so on. You have to create instance of InventMovement class (or child class of it) and then use it in inventory movement. One of the most useful classes in InventUpdate class hierarchy is the InventUpd_Financial class. It has two static methods for creating Purchase or Sales invoice: newPurchInvoice and newSalesInvoice. After creating this class instance with these methods, you should use updateNow method for actual posting.
Example: inventUpd_Financial = InventUpd_Financial:: newPurchInvoice(purchLine, inventVoucherTransPost, number, lineValue, purchLine.currencyCode, purchParmLine); inventUpd_Financial.updateNow();
Using API
5-15
5.5 PRODUCTION SERIES There are several classes for handling production series as well. API’s in this module use the same structure as used in the Inventory module. There are two major classes in the Production series: ProdStatusType – this class and its hierarchy are used for receiving information about manipulating the production process, for a specific status. ProdTableType – this class and its hierarchy is used for handling information from Production status, planning, and so on.
Using API
5-16
5.6 NUMBER SEQUENCES There are a lot of places where automatic number sequences are used. All number sequences are set up in Main Menu, Basic, Setup, Number Sequences. Usually Number sequences are connected to some specific parts of program using references – fixed list of Axapta predefined functionality. Number sequences can be set up by using the setup wizard. Examples of existing references: •
Customer account
•
Sales Order – Quotation number
•
Ledger – Journal Voucher
There can only be one Number sequence assigned to a reference. Several references may be assigned to the same number sequence. In some cases, modules can use number sequence directly without the use of references:
Program element
Number sequence
NumberSeq class handles all number sequences in Axapta. This class is used to get new or to reserve number from specific number sequence. Class description follows:
NumberSeq This class is used for getting new numbers from a specific number sequence. Methods In order to get new number from a number sequence, you need to have an instance of class NumberSeq. There are several static methods that help to create a new instance:
Using API
5-17
newGetNum newGetNum (newGetNumFromCode) newGetNum(NumberSequenceReference _numberSequenceReference, boolean MakeDecisionLater = FALSE, boolean dontThrowOnMissingRefSetUp = FALSE)
Creates a new instance of NumberSeq class and generates a new number in a number sequence related to the number sequence type specified as a parameter. A new number could be accessed by calling a non-static method Num in the class instance: mySeq.Num() Note: In this and in all following methods, postfix “FromCode” to a method name means that instead of specifying a number sequence type, an exact number sequence code will be specified as a first parameter.
newGetVoucher newGetVoucher (newGetVoucherFromCode) static NumberSeq newGetVoucher(NumberSequenceReference _numberSequenceReference, boolean _makeDecisionLater = FALSE, boolean _dontThrowOnMissingRefSetUp = FALSE) Creates a new instance of NumberSeq class and generates a new voucher code for the number sequence type specified as a first parameter. A new voucher code could be accessed by calling the non-static method Voucher().
newGetNumAndVoucher newGetNumAndVoucher (newGetNumAndVoucherFromCode) static NumberSeq newGetNumAndVoucher( NumberSequenceReference _ _ _ _numberSequenceReference, NumberSequenceReference
_ _voucherSequenceReference,
Using API
5-18
boolean _makeDecisionLater = FALSE, boolean _dontThrowOnMissingRefSetUp = FALSE) Creates a new instance of NumberSeq class and generates a new number and voucher codes for the number sequences specified as the first and second parameters. A new number could be accessed by calling the nonstatic method Num(), and a new voucher by calling the non-static method Voucher().
NewReserveNum NewReserveNum (newReserveNumFromCode) and NewReserveVoucher (newReserveVoucherFromCode) static NumberSeq newReserveNum(NumberSequenceReference _numberSequenceReference, boolean _makeDecisionLater = FALSE, boolean _dontThrowOnMissingRefSetUp = FALSE) Creates a new instance of NumberSeq class, and reserves new number (voucher) for a future use. A reserved number could be released by calling the static method release(), (for details see below).
Non static methods Parameter methods:
parmMakeDecisionLater: sets or returns the MakeDecisionLater value. The makeDecisionLater parameter is used when suggesting numbers in a form that the user can use. An example of how to use number sequences in forms can be seen in the form CustTable. 1.
parmNumberSequenceCode: sets or returns the NumberSequenceCode value
2.
ParmVoucherSequenceCode: sets or returns the VoucherSequenceCode value.
Using API
5-19
Corresponding methods for vouchers 1.
Num: Returns a new number from an initialized number sequence.
2.
Voucher: Returns a new voucher from an initialized number sequence.
3.
Abort: Aborts the new number calculation. The number becomes available again.
4.
NumAndVoucher: Returns a container of a new number and new voucher from initialized sequences.
Additional static methods Release static boolean release(NumberSequenceCode _numberSequenceCode, Num _num) Releases a reserved number (_num) in a specified number sequence (_numSequenceCode). This number will be available to use as a new number (use methods newGetNum or newGetVoucher). Returns TRUE if the number was successfully released and FALSE otherwise. highest static Integer highest(NumberSequenceCode _numberSequenceCode) Returns the highest value in a number sequence specified as a parameter. lowest static Integer lowest(NumberSequenceCode _numberSequenceCode)
Returns the lowest value in a number sequence specified as a parameter.
numInsertFormat
Using API
5-20
public static client server num numInsertFormat(Integer num,
NumberSequenceFormat format) Returns a number inserted into a mask. For example: if the parameters are _num=1562 and mask=’SN#####L’, returns ‘SN01562L’. numRemoveFormat public static client server Integer numRemoveFormat(Num num,
NumberSequenceFormat
format )
Removes the mask from a number. The function is opposite to the numInserTemplate().
NumberSeqReference Number sequences cannot be used without references. A reference is a record in the table NumberSeqReference for each use of a number sequence. When, for instance, a number sequence is used for a sales order ID, a record exists specifically for that in the reference table. A class hierarchy for the number sequences exists, including the setup of references.
Using API
5-21
5.7 EXERCISES
Exercise 6
Automatic depreciation
You want to post the depreciation on hotel rooms depending on how often they are used. On this basis, ensure that whenever an invoice is posted, this will cause an automatic depreciation on the buildings. For example, a unit of currency for each day the room has been used. This should be done using LedgerVoucher.
Exercise 7
Purchase order
The hotel offers transport of guests (car rental and limo service). This service is not handled internally but is carried out by a vendor. When a line of the type ‘transport’ is created in HotelGuestExpenses, the user is prompted if they should create a purchase order. Make sure that if the answer is positive, a purchase order will be created automatically.
Exercise 8
Number Sequences
When a reservation is created in HotelBookingTable, the HotelBookingId field should be allocated an automatically generated number.
Lesson 6. Using the COM Interface
At the end of this lesson, you are expected to be able to: Know about the purpose of COM objects. Use a COM object from Axapta. Use the Axapta Business Connector.
AX-300-ILT-058-v01.00-ENUS
Using the COM Interface
6-1
6.1 WHAT ARE COM OBJECTS COM is short for Component Object Module. In short, that means an external application being used as an object. We have previously seen how classes in Axapta can be created and how these classes can be used to create objects. The use of COM objects can to a very large extent be compared with the use of objects from Axapta’s own classes. This applies even if a COM object is an external application. As with Dynamic Link Libraries, you also normally have special classes, serving the purpose of interface between Axapta and COM objects.
Using the COM Interface
6-2
6.2 MS-AGENT A good example of a COM Object, which is relatively easy to use and which we will use with the exercises of this lesson, is the Microsoft Agent, MS-Agent. MS-Agent is a small application, which can be used for user dialog in different scenarios. MS-Agent generates a cartoon like character at a specified location on the screen. The character can, through a speech bubble and speech synthesis, give the user the required information. The Interface to this COM Object is the class SysMicrosoftAgent and an example of how to use its methods can be seen in the form tutorial_COMAgent. Note that the application to be used as a COM object has to be installed before the code in the above example gives the expected result. This is irrelevant for newer versions of Windows.
Using the COM Interface
6-3
6.3 AXAPTA BUSINESS CONNECTOR Using the Axapta Business Connector third party products like Visual Basic, Java, or MS Office products, enables you to use Axapta as a COM object. This implies access to the data and business logic of Axapta. This enables the use of applications as front ends, other than Axapta. An example of the use of this could be a web page designed as an order form. The result is that the customer places his orders directly as an Axapta sales order. The business logic of Axapta then ensures that, for example, the correct discounts are given, or calculates backorders.
Example:
You can copy the code below into a job in Axapta. This example will open a Word session and write the text ‘Hello from Axapta’, save the text in a document called c:\Axapta COM Document1.doc, and finally close the Word session. COM COM COM COM ;
wordApplication; wordDocuments; wordDocument; wordRange;
wordApplication = new COM("word.application"); wordApplication.visible(TRUE); wordDocuments
= wordApplication.Documents();
wordDocument = wordDocuments.add(); wordDocument.saveas("c:\\Axapta COM Document1.doc"); wordDocument.activate(); wordRange = wordDocument.range(0,0); wordRange.insertafter("Hello from Axapta"); wordRange = wordDocument.range(6,19); wordRange.bold(true); wordRange = wordDocument.range(11,26); wordRange.italic(true); wordDocument.save(); wordDocument.close(); wordApplication.quit();
Using the COM Interface
6-4
6.4 EXERCISES
Exercise 9
Exercise 10
Use MS-Agent in a form
∙
Create a new form, MSAgentDemo, which uses the class SysMicrosoftAgent, so that ’Merlin’ is automatically displayed when the form is opened, and disappears when the form closes.
∙
Using buttons on the form, it must be possible to have Merlin say different sentences. Note that the tone can be changed using ! or ?
Launch MS Word from Axapta
Sometimes it is handy to use other applications for special purposes, such as writing letters in MS Word. It is then convenient to be able to bring over some information from the current record in Axapta. ∙
Add a new button with the text ’Word’ to the Customers form (CustTable). When the user presses the button, MS Word must be launched, using the necessary code to launch Word and inserting the name and address of the customer.
Hint: You can find some hints on how to control MS Word as a COM object in the class DocuActionCom_Word.
Exercise 11
Use the Axapta Business Connector
From MS Excel, it should be possible to get the names of all customers in Axapta having transactions. This should be possible by clicking a button in MS Excel.
Using the COM Interface
6-5
∙
Make sure that the password and other settings for the current active configuration in the Axapta Configuration Utility are valid.
∙
Create a new document in MS Excel and then create a button in the document.
∙
Open the Visual Basic Editor for the button method. Make sure that under Tools, References, that AxaptaComConnector is selected.
∙
Now add the following BASIC code to the button method and see the result when the code is activated (by pressing the button). Dim Axapta As AxaptaCOMConnector.Axapta2 Dim AxaptaQuery As AxaptaCOMConnector.IAxaptaObject
Dim AxaptaDataSource As AxaptaCOMConnector.IAxaptaObject Dim CustTableBuffer As AxaptaCOMConnector.IAxaptaRecord ' Log on to Axapta Set Axapta = CreateObject("AxaptaCOMConnector.Axapta2") Axapta.Logon "", "", "", "" 'Table ID CustTable = 77 Set AxaptaQuery = Axapta.CreateObject("Query") Set AxaptaDataSource = AxaptaQuery.Call("AddDataSource", CustTable) Set AxaptaQueryRun = Axapta.CreateObject("QueryRun", AxaptaQuery)
I = 1 While (AxaptaQueryRun.Call("Next")) Set CustTableBuffer = AxaptaQueryRun.Call("GetNo", 1)
Cells(I, 1).Value = CustTableBuffer.field("AccountNum")
Using the COM Interface
6-6
Cells(I, 2).Value = CustTableBuffer.field("Name")
I = I + 1 Wend
' Log off Axapta.Logoff Set Axapta = Nothing
Lesson 7. Active X
At the end of this lesson, you are expected to be able to: Know some of the possibilities of using ActiveX controls. Know how to use Active X in Axapta.
AX-300-ILT-059-v01.00-ENUS
Active X
7-1
7.1 WHAT IS ACTIVEX ActiveX controls are 3rd party programs like DLLs (Dynamic Link Libraries) and COM objects. They provide us with functionality not present in the standard Axapta product. What makes ActiveX controls special compared to DLLs and COM objects is that they can have a user interface and can be associated with controls in Axapta forms. When a control is inserted in a form, it is possible to select a control type of ActiveX. Then the developer must select the actual ActiveX control (the program) to be used. Note that the use of ActiveX controls requires that the ActiveX control is registered on all computers/clients using the ActiveX control.
Active X
7-2
7.2 ACTIVEX EXPLORER When an ActiveX control is inserted, the ActiveX Explorer can be activated from the right-hand mouse button menu.
This tool has 2 purposes: ∙
To show the developer which events and methods are present for the actual ActiveX control, and which parameters is received and returned.
∙
To give the developer an overview of the events occurred during execution of the ActiveX. It also allows the developer to add X++ to be executed on the events. For debugging purposes, a trace of the ActiveX events can be enabled from the user options form.
Active X
7-3
7.3 EXERCISES
Exercise 12
Use the ActiveXMovieControl Object
In this exercise we will use an ActiveX control. As an example we will use the ActiveMovieControl object. This object could be used to play assembly instructions for items if a field with the file path was added to the item master. ∙
Exercise 13
Create a form with an ActiveX control of the ActiveMovieObject type. Also add a string field allowing the user to specify the relevant file.
Try ActiveX trace
Enable the ActiveX trace and then open the form from exercise 1. Take a look at the events occurred.
Lesson 8. Editor Scripts
At the end of this lesson, you are expected to be able to: Create new editor scripts, And know about: The classes used with editor scripts.
AX-300-ILT-060-v01.00-ENUS
Editor Scripts
8-1
8.1 EDITOR SCRIPTS In the Axapta editor it is possible, using the toolbar or ALT+M, to execute a script. A script is an action, like having a comment inserted (similar functionality is also present in many word processors, often referred to as macros). In Axapta we can create our own new scripts if needed. The secret is in the class called EditorScripts. Every existing script is a method in this class. If you want to create a new script, you simply create a new method in this class. If the name of the method contains an underscore, the method will appear in a submenu, breaking the name with the underscores, when using the add-ins menu (ALT+M). Let’s take a look at one of the methods: void template_flow_if(Editor editor) { xppSource xppSource = new xppSource(editor.columnNo()); Source template = xppSource.if(); ; editor.insertLines(template); } All methods in the class have a void return data type (they never return a value), and always receive an object of the type Editor. This object is a system class and contains a number of methods available in the editor, like insertLines(), which makes it possible to insert text. Another method is columnNo(), which gives you the current horizontal position of the cursor in the editor. The remaining methods can be found in the AOT under System Documentation\Classes\Editor. Last but not least, a class called xppSource exists. This class contains methods returning templates that comply with the code standard for certain X++ statements, as for example, if, while, for.
Editor Scripts
8-2
8.2 EXERCISES
Exercise 14
Create a new script
Find the class EditorScripts and create a new script. The script should be a sub item of the sendTo menu when using ALT+M When using the script, the selected text should be displayed in the infolog. Optionally, it should be possible in the infolog to select an Edit button. This should reopen the editor in the same method, and be positioned on the same line and column (hint: use the SysInfoAction_Editor class when adding to the infolog).
Lesson 9. Dynamic Link Library
At the end of this lesson, you are expected to be able to: Learn the purpose of using DLL’s. Try to use a specific DLL.
AX-300-ILT-061-v01.00-ENUS
Dynamic Link Library
9-1
9.1 USE OF DYNAMIC LINK LIBRARIES This lesson deals with Dynamic Link Libraries (DLL), which are individual or whole groups of program parts that can be run in windows. A DLL can hence be associated with a specific application that uses program parts. Alternatively, a DLL could be independent of a particular application and may be, for example, installed from a CD or downloaded from Internet. The interface between Axapta and the various DLLs, takes the form of classes with methods, each of which can activate the program parts found in the different DLLs.
Dynamic Link Library
9-2
9.2 WINAPI Perhaps, without further thought, we have already used DLLs via the class WinAPI. If we go in and look at the code in WinAPI’s methods, we will see that each one calls a DLL that lies outside Axapta. In practice, these calls could be made independent of WinAPI’s methods if one wanted to call a particular DLL. This is however not a recommended procedure as the code will use more space and will be more difficult to read. Therefore, if you want to install new DLLs and use them in Axapta, you should create one or more classes with methods to be used as an interface.
Dynamic Link Library
9-3
9.3 VARCHART VarChart is a German product that generates graphics for administrative systems. Axapta contains several classes that function as an interface to this product. One of the classes that is relevant to this lesson is called Graphics_Period and can be used to make a graphical presentation of transactions over a given period.
Dynamic Link Library
9-4
9.4 EXERCISES
Exercise 15
Exercise 16
Check the WinAPI class
∙
Have a look at the code in some of the methods.
∙
Identify which DLLs WinAPI uses.
Use WinAPI
Make a count of the seconds spent when joining between ledgerTable and ledgerTrans tables. You have to use the GetTickCount Function of Kernel32.dll.
Lesson 10. The RunBase Class
At the end of this lesson, you are expected to be able to: Know about the RunBase Class Know about the methods used with the RunBase Class Know about the general recommendations used with the RunBase Class
lesson: AX-300-ILT-172-v01.00-ENUS
The RunBase Class
10-2
10.1 THE RUNBASE CLASS Axapta has a high-level programming interface for executing various processes and tasks. Every time when you need to collect information and then execute a task, use the RunBase class function. This class has dialog, last value saving, query range definitions and many more useful functions inside. RunBase class is a parent class. It can be used in all classes: class MyClass extends RunBase A more detailed description of each method in this class follows.
Methods used in new classes ClassDeclaration – in this section you should: 1.
Declare that your new class is a child-class to RunBase class. Example: class MyClass extends RunBase
2.
Declare the dialog object. Example: DialogRunbase dialogRunbase;
3.
Declare DialogField objects and variables where data form dialog will be saved. Example: DialogField dialogCustAccount; CustAccount custAccount;
4.
Declare QueryRun object if you specify ranges for a query in the dialog (Select button with all functionalities will appear automatically). Example: QueryRun queryRun;
5.
It is highly recommended that you declare two macros in ClassDeclaration. One of them specifying the version of data to be used (usually 1), and the other – a list of all variables that store information from the dialog. This should be saved for the next time users open the same dialog. Commas should separate variables.
The RunBase Class
10-3
The declaration looks as follows: #define.CurrentVersion(1) #localmacro.CurrentList series, caseNo, nameTemplate #endmacro public boolean canGoBatch() – This method is reserved for use with RunBaseBatch class. If you want to use the batch system you should extend RunBaseBatch class, and look for the method descriptions in the next chapter of this document. In RunBase class this method returns false. protected void cleanupDialog() – this method should be overridden if any cleanup is required after calling the dialog. protected Object dialog() – This method should be always overridden in order to specify what should be placed in the dialog. If you need to modify the query with, for example, ranges, in this method you should: 1.
Call super() method. super();
2.
Initialize DialogRunBase class object declared in ClassDeclaration section. dialogRunBase = new DialogRunBase(“My Dialog Caption”,this);
3.
Initialize the dialog field objects and define the values by calling value() method with the parameter value-storing variable. Example: dialogSeries = dialogRunBase.addField(typeID(SourceC oumnNum)); dialogSeries.value(series);
The RunBase Class
10-4
dialogCaseNo = dialogRunBase.addField(typeID(Case)); dialogCaseNo.value(caseNo); 4.
Add the “Select” button if a query will be used in the dialog. Example: dialogRunBase.addMenuItemButton(MenuItemTyp e::Action,IdentifierStr(RunBaseQueryDialog) ,false);
5.
Return initialized DialogRunBase object: Return dialogRunBase;
If you do not need to modify ranges you can just do the following instead: •
Declare the FormRun query and return it FormRun formRun = classFactory.createQueryForm(this); ; formRun.init(); return formRun;
public void getLast() – This method packs and unpacks last saved values. This method should not be overridden. If no last saved value is found, it calls initParmDefault() method described below. GetLast() should be called before prompt() method when using your own class. public void initParmDefault() – This method will be called if no last value is found in the system. It should be overridden if necessary and default dialog parameters should be specified. Example: series = 1; caseNo = 0; abstract public container pack() – This method should be overridden and packing to a container. If you have declared two macros in
The RunBase Class
10-5
ClassDeclaration then there is quite a simple way to implement it. If you are not using a query in your dialog, then the code should look like this: return [#CurrentVersion,#CurrentList]; If you are using a query, and queryRun is declared in the ClassDeclaration section as a QueryRun object, then your code should look like this: return [#CurrentVersion,#CurrentList,queryRun.Pack ()]; public RunbaseProgress parmProgress(RunbaseProgress _progress = progress) – Set/Get progress class instance, which will be used in your run() method, if needed. By default, progress will return a variable which is declared in the RunBase ClassDeclaration section. public void progressInit(str caption, int total, Filename animation, int updateInterval = 1) - method used for progress initialization. Here, caption – progress window caption, total – total number of steps in progress, animation – name of animation file (it is recommended that you take it as one of the descriptions in #AviFiles macro libraries), updateInterval – time interval in seconds, when progress should be updated. Example of usage progressInit and parmProgress methods: #Macrolib.AviFiles this.progressInit("My Progress", 10, #AviUpdate); for (i=1;i<10;i++) { this.ParmProgress().incCount(); // Could be used addCounter(n) // Do something }
public boolean prompt() – Shows the dialog box. This method should normally never be overridden and only called when you need to show the dialog form. If any last values should be loaded before, use getLast()
The RunBase Class
10-6
method of this class. public QueryRun queryRun() – If you are using a query in the dialog box, then this method should be overridden and your query should be passed as a return value. Before any dialog calls, you should initialize the queryRun object. It could be done in the new() method. Please remember if you are packing query range definitions as last values, an initialized query could be overwritten in the update() method. If you do not want to do that, you should create an unpack() method in your own way. Example (Initialization): Query query = new Query(); ; query.addDataSource(TableNum(CustTable)); queryRun = new QueryRun(query); public void run() – In this overridden method your executable code should be written. It could be, for example, posting of transactions, or generating new records or any other process. public Runbase runBase() – This method returns RunBase class instance of overridden class. Abstract public boolean unpack(container packedClass) – This method should be overridden. If two macros mentioned in the ClassDeclaration section are declared, then the code for the dialog without a query could look like this: Integer _Version = conpeek(PackedClass,1); switch (_Version) { case(#CurrentVersion) : [_Version,#CurrentList] = PackedClass; break; default : return false;
The RunBase Class
10-7
} return true; If you are using a query, the code may look like this: Integer _version = conpeek(packedClass,1); container _packedQuery; switch (_version) { case #CurrentVersion: [_version,#CurrentList,_packedQuery] = packedClass; if (_packedQuery) queryRun = new QueryRun(_packedQuery); break; default: return false; } return true; public protected boolean validate() – This method should be overridden if any validations on data are to be made after the dialog is closed, but before this prompt() method returns true. Here you can place some data validation rules, and if the data is incorrect, it returns False. By default, the return value is True. Client server static ClassDescription description() – This static method should exist in each class. The method returns a description of the class string (extended to ClassDescription) value, explaining what is the purpose of a class. Client server static Object makeObject(ClassId _classNum) – this static method makes an instance of class (RunBase or any child-class of it).
The RunBase Class
10-8
General recommendations for RunBase class usage To get/set parameters in the class; create methods named by the variable name, and prefixed with 'Parm', for example, ParmTransDate. Methods which set other variables in the class should be prefixed with 'InitParm' instead. These methods are used, for example, when the dialog is a form, created in the tree, each edit method, can make a call back to the class Parm and InitParm methods. When the Dialog class is used, the variables are set in the Dialog method, and the values from the Dialog are set in the GetFromDialog method. Use of a RunBase class: { MyRunBase My; My = new MyRunBase(); if (My.Prompt()) My.Run(); } Or when you need to set a variable, which is saved in the SysLastValue table: { MyRunBase My;
My = new MyRunBase(); My.GetLast(); My.ParmMyDate(SystemDateGet()); if (My.Prompt()) My.Run(); }
The RunBase Class
10-9
10.2 EXERCISES
Exercise 17
Runbase Processes 1.
Create a table which should contain information about persons. Call it “Persons”.
The table should contain three fields: •
PersonID
•
Name
•
DateCalc
2.
Create an extended data type, call it “Person”, int. Ref: Persons, PersonID
3.
Create a new class which extends the RunBase class. It should contain a dialog method. The dialog method will define the three fields in the dialog. The fields are: •
Date of the calculation
•
From PersonID (from the extended data type you created before)
•
To PersonID (from the extended data type you created before)
4.
Create validation: The field date of the calculation should be mandatory to fill in.
5.
Make sure that the class packs and unpacks the last values
6.
The run method must update the field DateCalc in the table, but only for the PersonID entered.
Lesson 11. The Batch System
At the end of this lesson, you are expected to be able to: Know the purpose of the batch system Make certain code execute as a batch job.
AX-300-ILT-063-v01.00-ENUS
The Batch System
11-1
11.1 THE BATCH SYSTEM One of very important parts of process management tools in Axapta is the batch system. This system allows you to run various functions and processes on other workstations. Using the batch system allows you to distribute tasks over the network as well as schedule them. Axapta has a batch execution system, which is capable of executing a list of batch entries. Any function in Axapta that is designed to use the batch system can be put into the batch list when executed instead of being run immediately. The only difference to the user is that if he is executing the function designed to run a batch, he will see a ‘Batch’ button besides the ‘OK’ button and therefore be able to decide whether or not to run it in batch. How to use the batch system in the application is described in Axapta Developers’ Guide.
The Batch System
11-2
11.2 RUNBASEBATCH The class RunBaseBatch makes it possible to execute code on a batch server. All classes extending RunBaseBatch will be batch executable, so to make your code batch executable you should create a class extending RunBaseBatch. In addition to extending RunBaseBatch the new class should also override a number of methods from the base classes (RunBaseBatch and RunBase). One way of finding out which methods to override, is to find one or more classes using RunBaseBatch, but an easier option exists. We will look at that option in the next section. Remember that RunBaseBatch class has RunBase class as a parent-class, so it has all functionality as RunBase, and some additional methods described below.
Methods that could be used in new classes ClassDeclaration – Remember to have RunBaseBatch class as a parent for your new class. All other declarations should be made in the same way as was done in the RunBase class. boolean canGoBatch() – This method should normally be overridden. It should return True, if you want to have a batch execution available, otherwise False. protected boolean canGoBatchJournal() – This method should return true if the class could be listed in the batch journal. Otherwise, it should be overridden and returned as false. public void initBatch(Batch batch) – In this method you should define initial batch values. The parameter is Batch table record. For more details see Batch table description in the AOT.
Tutorial_RunbaseBatch Tutorial_RunbaseBatch is exactly what we need in this lesson. The idea of this class is to serve as a base for new batch executable code. We can thus make a copy of Tutorial_RunbaseBatch (use duplicate command) and rename the class, add code and perhaps methods. We can do this
The Batch System
11-3
every time we need to create a class for batch executable code. Another class we could have used is the LedgerRecalcPeriod class. Notice the similarities between the 2 classes.
The Batch System
11-4
11.3 EXERCISES
Exercise 18
Examine Tutorial_RunbaseBatch
Tutorial_RunbaseBatch is a good template for batch executable code ∙
Exercise 19
Examine the methods in this class.
Create a new class
∙
Using Tutorial_RunbaseBatch as a template, create a new class called RunbaseBatchDemo. The purpose of the new class is to be able to go through ledger accounts and put the account number and name in the info log. The user should have the option of selecting which accounts to include using the standard query dialog.
Lesson 12. Foundation Classes
At the end of this lesson, you are expected to be able to: Know the reason for using Foundation Classes. Know how Foundation Classes can be used.
AX-300-ILT-064-v01.00-ENUS
Foundation Classes
12-2
12.1 FOUNDATION CLASSES You can use variables in Axapta that can contain more than one value. This is made possible by declaring the variable as an array, or by declaring the data type as a container. There is however a limitation in both cases in that neither table buffers nor objects can be saved. This problem is solved to a certain extent by using temporary tables, but there is still a problem with objects. Foundation classes solve all these problems. Some of the most important advantages of using foundation classes are as follows: ∙
Access to data is quick.
∙
Traffic on the network is limited (if used correctly)
∙
Objects can be saved in the database.
Axapta contains the following types of foundation classes: ∙
List
∙
Map
∙
Set
∙
Array
∙
Struct
Foundation Classes
12-3
12.2 LIST These foundation classes are similar in that they can all contain a data series. The first three classes each have a matching class that starts with the same name (List, Map or Set), and followed by an Iterator. These classes are used to choose the individual data items.
Example List l = new List(Types::STRING); ; l.addEnd("Arvid"); l.addEnd("Mogens"); l.addStart("Claus");
print l.elements(); print l.definitionString(); print l.toString(); pause;
The example above shows how we can add data first or last, and how some of the methods can subsequently be used to retrieve information about the data set. If you would like to retrieve information on the individual data, this can be done as follows: ListIterator li; // l declared as above li = new ListIterator(l); while (li.more()) { print li.value(); li.next();
Foundation Classes
12-4
} pause; In addition to being able to create and save data, other possibilities exist when we use classes as shown above. By using the method equalTo(), you can compare two sets of data. The method will return ‘true’ if they are identical. Pack() is also a useful method, which can be used to pack the data set in a container which can then be saved in a database.
Foundation Classes
12-5
12.3 SET Above we have seen examples of the classes List and ListIterator. The classes called Set and SetIterator work in a similar way. The main difference is that in a data set from the object ‘Set’, unlike ‘List’, it is not possible to create identical data, as all values should be different. In Set, data is added using the method add().
Example Set s = new Set(Types::STRING); ; s.add("Claus"); s.add("Mogens"); s.add("Arvid"); print s.elements(); print s.definitionString(); print s.toString(); pause;
Set gives you other possibilities that List doesn’t have. The method in() makes it possible for us to search for a particular value. If the value is found, ‘true’ is returned. The same applies for the method remove() which is used to delete elements. The following three static methods are also unique for this class: intersection() which returns a Set that contains the data which is common to the two Sets of data, Union() which returns a Set which is the combined amount of the two Sets of data, and difference() which returns the first Set minus the data which is common to the two Sets of data. SetIterator, which contains the same methods as ListIterator, can be used to search a Set data set. The difference is that the data is sorted logically as opposed to List where the data is sorted according to its physical position.
Foundation Classes
12-6
12.4 MAP Map and MapIterator work in a different way from the two classes we have just looked at. The main difference is that Map consists of a data set that contains a key and a corresponding value, where the key is unique but the value can be repeated several times. The key and value need not be from the same data type.
Example: Map m = new Map(Types::STRING,Types::INTEGER); ; m.insert("Arvid",35); m.insert("Mogens",36); m.insert("Claus",42); print m.elements(); print m.definitionString(); print m.toString(); pause; Correspondingly, List and Set are found in connection with Map, in a class called MapIterator. Mapiterator works in the same way as we have seen in the other classes. The only difference is that the two methods, key() and value(), are used to retrieve a key or its corresponding value respectively. The common factor for all three foundation classes we have seen up to now is that one should ensure that both objects, for example List and ListIterator, are created at the same place (Client or Server). If this rule is not observed, there is a risk that there could soon be a situation where the network is loaded unnecessarily and the system’s performance is not optimal.
Foundation Classes
12-7
12.5 ARRAY Arrays function the same way as ordinary arrays, the main difference being that table buffers and objects can be used as contents.
Example: array oarray = new array (Types::CLASS); oarray.value(1,new Query()); oarray.value(2,new Query()); oarray.value(4,new Query()); print oarray.lastIndex(); print oarray.toString(); print oarray.definitionString(); pause;
Foundation Classes
12-8
12.6 STRUCT Struct (abbreviation of Structures) can contain an arbitrary number of elements of a variety of data types. In contrast to the other foundation classes we have seen, it is possible to construct object in this class by either using the enum called Types, or by referring to the data type desired for use in each element, which is desired for use in the current object.
Example: Struct
s
= new struct(Types::INTEGER,"age",
Types::STRING,"name"); Struct s1 = new struct("int age; str name"); Struct
copy;
Container
c;
int
i;
print s.definitionString(); print s1.definitionString(); s.value("age",35); s.value("name","Arvid"); print s.toString(); for(i=1;i<=s.fields();i++) { print s.fieldName(i)," ",s.fieldType(i)," ,s.valueIndex(i); } s.add("ShoeSize", 44); print s.definitionString(); print s.toString(); c
= s.pack();
copy = struct::create(c); print copy.definitionString(); print copy.toString(); pause;
Foundation Classes
12-9
12.7 EXERCISES
Exercise 20
List
Occasionally, complaints are received in connection with shortages in some of the hotel rooms. To find out if there is any pattern (certain rooms or certain time of year), it is desirable to save the dates for these complaints. Create a new field of the type Container on the table used to register hotel rooms. Then create a new class with the following features:
Exercise 21
•
Using a dialog box, it should be possible to type one or more complaint dates for a certain room. These complaints should be saved in a container using List and ListIterator.
•
After the final entry of complaints, they are written to infolog and saved in the database.
•
Create a button named “Complaint” launching this process.
Set
As the system functions just now, it is possible to create several complaints on the same date for the same room. •
Create a new feature that prints out rooms with the same date and remove these dates.
•
Then create a feature where using a dialog, one can select 2 rooms and afterwards a printout will be obtained giving all the complaint dates for both rooms.
•
Create a button named “Combine Complaints” launching this process.
Foundation Classes
Exercise 22
12-10
Map
Using a map, we wish to compare rooms and number of complaints.
Exercise 23
•
Create a feature that collects this data in a map and allows the user to print out rooms with a user-defined amount of relevant complaints.
•
Create a button named “Total Complaints” launching this process.
Array
•
Create a new field in the HotelRoomTable of the type: Container. This field is for saving the records of bookings.
•
Create a new button in the Rooms form. Call the button: “Save container”. This button must call a method that saves all bookings of the current record in the new container.
•
Create another new button in the same form. Call it: “Read Container”. This button must check that all bookings exist in the table and furthermore it should update all data in the container.
Note for the last two points: you need to use the Array foundation class and the methods you use must show an infolog showing information about the records saved in the container.
Lesson 13. Gantt Classes
At the end of this lesson, you are expected to be able to: Develop classes that make it possible to display data in a Gantt chart.
AX-300-ILT-065-v01.00-ENUS
Gantt Classes
13-2
13.1 GANTT CLASSES In MPS and the Project module, it is possible to display activities in the form of a Gantt chart (a graphical presentation where each activity is shown as a function of time). The first thing to do if you do not know this feature is to open a project module and see what a Gantt chart looks like in the module.
Gantt Classes
13-3
13.2 PROJECTS, INQUIRY, GANTT CHART The Gantt chart shows how resources are tied to certain tasks in a certain time period. What we will look at here is how we can use the classes that are used to present data in connection with a new module. The Gantt form is used to show the Gantt chart, regardless of the module. Changes should NOT be made on this form. The first thing to do is to make a new result based on 2 base enums.
GanttGroupBy and GanttNodes In all, there are 6 class hierarchies in the system, therefore it will be necessary to create 6 new classes, each of which inherit one of the classes from the top of the hierarchy. The relevant classes are as follows: ∙
GanttClient, GanttList and GanttNode. These classes are held by the client.
Next comes: ∙
GanttServer, GanttLink and GantSetup. These classes are held by the server.
In order to find out which methods you need to create/replace, you are recommended to refer to the classes belonging to the project module, for example, ProjGanttClient or ProjGanttLink. Finally, the following should be changed on the 2 existing classes: On GanttClient: •
Create a new method (see the code in main())
•
Correct main()
Correct Construct() On GanttLink: •
Correct Construct()
Gantt Classes
13-4
13.3 EXERCISES Exercise 24
Gant Classes in Axapta 3.0
The Gantt classes used in production and project have been rewritten in Axapta. Now it is easier to apply a Gantt chart to whatever data structure you have. Explore the TutorialGantt form for an example of this.
Appendix A. Welcome to Axapta Integration
This appendix contains: Guidelines for instructors prior to and starting the course Information about the requirements for the course e.g. equipment, prerequisites Notes to instructors
AX-300-APP-037-v01.00-ENUS
Welcome to Axapta Integration
II
GENERAL INFORMATION Prerequisites •
Successful completion of the General Axapta Application Test, the X++ Basic online course and the X++ Advanced Classroom Course. It is highly recommended that you have worked with the X++ language and MorphX Development environment for at least 6 months before this class.
∙
Access to an Axapta installation with a clean (that is, without additional transactions or any other alterations) demo data file imported into it.
∙
Programming skills are a MUST. Try not to get side tracked by such topics, or you will not complete course in the designated time. Perhaps even refer participants to other courses covering such topics – as well as additional areas of training in the Axapta curriculum. Have several copies of your curriculum handy for participants who want to know more…
Note It cannot be emphasized strongly enough to enforce the prerequisites! Course prerequisites are important for gaining the most from this course (or any course). Learners need to experience some success – it gets very demotivating to continuously run into problems and rely on the instructor (or other participants). Participants lacking the necessary prerequisites for a particular course may be dismissed from the classroom at their own expense, at the discretion of the instructor. Please communicate this message clearly with NSC participants. Every country must strive to make the learning experience as productive and efficient as possible. Screening students to insure a common starting basis for this class (and other classes) is an effective way to optimize the time spent in the classroom. The centrally determined prerequisites are set with this in mind. This course requires a successfully passed test in order to register and you can monitor that every potential participant meets this criteria via the eAcademy client. The Training responsible person in each NTR has received access to this client, along with instructions on how to use it.
Welcome to Axapta Integration
III
Please contact this person in your NTR or Michael Aksglæde (Project Manager for e-Academy), if you experience problems with this client.
In addition to these prerequisites, it is also recommended that participants have completed the “Essential” online courses and the General Axapta Application Workshop. However they are not compulsory, and hence not a prerequisite for this course. Although not prerequisites, the training development team strongly recommends these courses as this course was developed with these courses in mind as recommended preparation. Hence, you could say that knowledge equivalent to these courses is a prerequisite (successful completion of the General Axapta Application Test is satisfactory evidence of this).
Welcome to Axapta Integration
IV
BEFORE YOU START THE CLASS: Pre course Before the course, you need to: ∙
Thoroughly familiarize yourself with the training material. Read the material and appendices, paying particular attention to the guidelines to instructors.
∙
Inform participants what to bring (see Equipment below for more information).
Equipment required ∙
One flipchart with white board markers
∙
Whiteboard and whiteboard markers
∙
It is also a good idea to bring some small rewards (for example, small items from the Web Shop, marketing posters or pens) as incentives for participants
∙
A projector for the instructor to utilize the PowerPoint presentation and provide demos in Axapta, when necessary.
Note For information regarding course schedule, target audience, related certification, and so on, please consult the Axapta V3.0 Training Guide – available on the Academy site on Base Camp.
Welcome to Axapta Integration
V
BEGINNING THE COURSE Supporting files: Presentation: MorphX Integrations.ppt Base Project: Ax30MXIBaseProject.xpo: Contains the data model for Axaptel. Demo Project: Ax30MXIDemoProject.xpo: Contains the Demonstration Examples used throughout the course. Demo Data: MXIDemo.def and MXIDemo.dat: Contains the demo data used for this course. Solutions: COM Solution: COMExercise3.xls COM advanced suggested solution: Axapta COM adv Solution.xls Exercise solutions: Ax30morphx_Integration The project is grouped under the name of the lesson and the unique number within the doc ID. (refer to the first page of each lesson) Example: ax30_Int_55_Axaptel (where ax30 means Axapta version 3.0 , int stands for MorphX Integration, 55 is the unique number from the doc ID and Axaptel is the name of the lesson.) The solutions in this xpo file are suggested ways of approaching the exercises. The training development team at the Vedbæk campus is always interested in hearing your comments and feedback. Also, if you make changes or additions to this xpo file, or any of the material, we would like you to share it with us and your colleagues in NTRs. Please send your feedback or input for this course to: Pernille Halberg at
[email protected].
Welcome to Axapta Integration
VI
NOTES TO INTRODUCTION LESSON
Time
Topic Introduction
What to do/say
Medium
Introduce course objectives
ppp
Prerequisites: the students should start by importing the demo
In their
data and the demo project.
own installatio n of axapta
Appendix B. Basic Guidelines
This appendix contains: ∙
Notes and guidelines to instructors
AX-300-APP-038-v01.00-ENUS
Basic Guidelines
II
BASIC GUIDELINES
Time 5
Topic Introduction
5
What to do/say
Medium
Introduce lesson objectives
ppp
Go through the concepts of API and Journals, (later on we will go
ppp
through them in depth. Integration possibilities: We change the standard application from version to version, BUT we never change the APIs
10
Mention Best Practice on Technet, Developer guide and maybe use 10 minutes of time to browse them for Best Practice Review
Any questions so far?
dialog
Appendix C. Axaptel
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-039-v01.00-ENUS
Axaptel
II
AXAPTEL
Time
Topic
What to do/say
Medium
Go through the Base project: Ax30MXIBaseProject.xpo
Instructor Preparation
before you start. The students will have to import the project in their own installation. You will have to have this project in another installation because during the course you will make modifications to the data model. So you have two projects: 1 basic + one with all the solutions.
Introduction
Introduce the case
ppp
Exercise 1
Import the project with the basic components
Axapta
Comprehensi
Go through the data model with the students
Axapta
on/
Monolog
Visualization Exercise 2
Enter data in the forms:
Axapta
Starting by HotelRoomTable form where you press Booking and then enter data in the HotelBookingTable form, then press Expenses and enter data in the HotelGuestExpenses form. Review
Any questions?
dialog
Axaptel
III
EXERCISE SOLUTIONS
Exercise 1
System Construction
The data model with tables, fields, index, data types and base enum: Reference toAx30MXIDemoProject.xpo project. Exercise 2
System construction
Appendix D. Using the Journals
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-040-v01.00-ENUS
Using the Journals
II
INSTRUCTOR NOTES Note: The exercises solutions have not been tested thoroughly and might need corrections.
Time
Topic Introduction
What to do/say Journals, slide 1
Medium Ppp, slide 1
The integration and the steps when creating a journal
Ppp, slide 2
Drawing
Ledger Module: these tables are covering also ledger, sales,
Ppp:
vendors, fixed assets, projects and cost accounting modules
Journal Example
Comprehension
Comprehension and demonstration of the concepts in the
/
application. Show this in Axapta:
Visualization
1. We have journals in all modules, show example: main
Axapta
menu, (all modules), Journals. 2. Example: go into Ledger module journals and open the Journal setup form: show the names, the journal type (in general ledger you have for instance 4 different types of journals)
Show how to create a journal in the General Ledger, journal form. Journal lines and posting and validate look-up buttons. Show the form and the tables in the AOT: General Ledger Journal Form = the information from the table: LedgerJournalTable General Ledger Journal Form, Lines= the data from the table: LedgerJournalTrans Show the 3 steps: create, create transaction and post journal
Use the imported Demo project
Using the Journals
III
Slide10: in the demo project show Journals, Ledger Journal,
Ppp and
Post journals
the demo
Slide 11: Journals, InventJournals, InventPostJournal
project in Axapta
Slide 12: slide example of a Production Journal Exercise 1
Now we are going to do the same in an exercise where it is
In Axapta
our task to program it. Solution: Ax30morphx_Integration, Ax30int_56_1_2_3Journals. Exercise 2
Solution: Ax30morphx_Integration, Ax30int_56_1_2_3Journals.
Exercise 3
Optional: Solution: Ax30morphx_Integration, Ax30int_56_1_2_3Journals.
Post exercise
Use some time to go through the exercise solution with the students.
Review
Any problems encountered?
dialog
Using the Journals
IV
EXERCISE SOLUTIONS Note: The exercises solutions have not been tested thoroughly and might need corrections. Exercise 3
Journal lines
Reference to Ax30morphx_Integration.xpo project: Section :: Ax30int_56_1_2_3Journals
Exercise 4
Automatic Posting
Reference to Ax30morphx_Integration.xpo project: Section :: Ax30int_56_1_2_3Journals
Exercise 5
Consumption
Reference to Ax30morphx_Integration.xpo project: Section :: Ax30int_56_1_2_3Journals
Appendix E. Using API
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-041-v01.00-ENUS
Using API
II
INSTRUCTOR NOTES
Time
Topic Overall
What to do/say
Medium
It is recommended that you get into the General Ledger API, the Trade series APIs, number sequences in depth, and then just mention overall the Inventory management and Production series since these are not widely used.
Introduction
Overall idea of API NOTE: Documentation on API is hard to find, so use the
Ppp, slide 14
examples in this course for reference General
API in General Ledger: explain the 3 classes and use the demo
Ppp,
Ledger
project: API’s, Ledger Module:
slide 15
The first job is to create LedgerVoucher with 3 transactions.
&
The second job is to create a Ledger Voucher grouping
Demo-
transactions by accounts
project
Another way of saying the same thing as in slide 15
Ppp: slide 16,17,18
Exercise 1:
Solution: Ax30_Int_57_API
Axapta
Start the section about trade series:
Slide 20
Automatic depreciation Trade series
1. Show the object model slide
Trade series
Show slide 21 and demonstrate a job: APIs, Trade,
Slide 21
CreateCustTrans.
and
After having run the job: If you have time you can show the transactions in the main menu Accounts receivable,
demoproject
Customers. Customer 4001 Trade series
Show: New customer template is created in the Accounts receivable, Setup, Parameters. On the General tab: Customer,
Slide 22 Demo-
Using API
III
One-time customer account.
project
Demoproject: CrearSalesOrder: in this example you can see both methods used for creating customers and creating orders. NOTE: you can recommend the students to use the methods: InitFromXTable X=name of the original table Trade series
Demo examples below the Trade node:
Slide 23
InvoicingSales: show how to invoice a sales order
Demo-
InvoicingPurch: Show how to invoice a purchase order Exercise 2:
project
Solution: Ax30_Int_57_API
Purchase Orders Inventory
Demonstration in the AOT:
Ppp +
management
InventMovement: View the methods: TransDate() in the
Axapta
API
classes: InventMov_Sales and InventMov_Purch. InventUpdate: view the methods: newPurchInvoice() and newSalesInvoice() in the class InventUpd_Financial These methods create purchasing invoices and sales invoices. After this you should call the updateNow() method for posting.
Production
This section is not very elaborated so just mention that you can
ppp
series
use API in production areas as well
Number
While introducing on slide 28 you can show the forms in the
Ppp-
Sequences
main menu and the reference form in the same path to clarify
slide 28
the difference between number sequences and references. Number
NumSeq Class: show the class in the AOT, show the methods
Sequences
described in the document
Number
Form level: after you show this code example you can show
Sequences
where to find it: in the CustTable Form. Where you can explore all the methods.
Slide29
Slide 30
Using API
IV
Number
Transactions: you can find an example in the demo project:
Sequences
CrearSalesOrder
Number
How to create a reference.
Sequences
Slide 31
Slide 32
After this use the demo project to demonstrate all objects used in the steps of how to create a reference. Section: NumberSeq After this open the reference form , then the class will be executed and the references will be created.
Exercise 3: Number sequences
Solution: Ax30_Int_57_API.
Axapta
NOTE: you have to create the number sequences: “Hotel_01” if it doesn’t exist. (It is included in the demo data provided with this course )
Post
Use some time to go through the exercise solution with the
exercise
students.
Review
Any problems encountered?
dialog
Using API
V
EXERCISE SOLUTIONS
Exercise 6
Automatic depreciation
Reference to Ax30morphx_Integration.xpo project: Section :: Ax30_Int_57_API
Exercise 7
Purchase order
Reference to Ax30morphx_Integration.xpo project: Section :: Ax30_Int_57_API
Exercise 8
Number Sequences
Reference to Ax30morphx_Integration.xpo project: Section :: Ax30_Int_57_API
Appendix F. Using the COM Interface
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-042-v01.00-ENUS
Using the COM Interface
II
USING THE COM INTERFACE
Time 5
Topic Introduction
What to do/say
Medium
Present the agenda
Dialog/
Present the objectives
White board
10
Comprehension / Visualization
WHAT ARE COM OBJECTS.
Dialog
Question to start with Have you ever heard the expressions COM (or COM object)? Answer: External application being used as objects (maybe throw in a bit of COM object history:…was developed by, for)
10
DEMO
MS-Agent
Example MS-
Explain shortly what it is
Agent
•
Monolog
Small application with Class(class SysMicrosoftAgent )
•
methods-show them?
Axapta
AOT, data dictionary, forms, tutorial_COMAgent Animate Merlin (remember the sound) Speech to text and additional agent Downloads can be found on www.microsoft.com/agents 20
Exercise 1
Use MS-Agent in a form
Axapta
Perhaps show the example with another agent like Peedy Comprehensio n/ Vizualization
The Axapta Business Connector(ABC):
Dialog
Have you ever worked in one application and wanted to integrate data from another, e.g. excel spreadsheet data which you then have to copy/paste…… Draw data architecture that shows the Axapta Business Connector as a connector between Axapta and different applications (MS products, visual basic, java).
White board + graphics
Using the COM Interface
III
Axapta back end, other application: front end 20
Exercise 2
Launch MS-Agent in a form (maybe you can split the above up in two so you have a little gap in between these two exercises
20
Exercise 3
Use the Axapta Business Connector (ABC): Attached solution Excel sheets:
Ppp, Axapta, excel
COMExercise3.xls: is the solution to exercise 3: “Use the Axapta Business Connector” Axapta COM adv Solution.xls: Is a more complex solution where you can view customers, create new customer, create journals, create transactions, and posting journals. In the demo-project there are three extra examples of COM functionality: •
COM, ActiveX (this example you can use in the next lesson: Active X)
5-10
Summary
•
COM, AGENT
•
COM, FromAxaptaToExcel
We have learned: Purpose… Q: •
What is a COM object?
•
The ABC?
•
Can anyone give me an example where you use another application and Axapta together and where it is handy with the ABC?
How to ….
dialog
Using the COM Interface
IV
EXERCISE SOLUTIONS
Exercise 9
Use MS-Agent in a form
Reference to Ax30morphx_Integration.xpo project: Section : Ax30_Int_58_COM, MSAgent Demo
Exercise 10
Launch MS Word from Axapta
Reference to Ax30morphx_Integration.xpo project: Section: Ax30_Int_58_COM, Cust Table
Exercise 11
Use the Axapta Business Connector
Reference to COMExercise3.xsl
Exercise/Exampl e
Additional Axapta/ COM Exercise & Example
Reference to Axapta COM adv Solution.xls
It is another example of COM Connector where It is possible to execute 5 scripts in Visual basic ( 5 sheets ) for viewing Axapta customers, to create a new customer and creating and posting a journal.
Appendix G. Active X
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-043-v01.00-ENUS
Active X
II
INSTRUCTOR NOTES
Time
Topic Introduction
What to do/say
Medium
Present the agenda
Dialog/
Present the objectives
White board
Comprehensio
ppp
n/ Vizualization Demonstration
Use the demo-project beneath the COM Node called Active
Demo
X:
Project This demo shows a form where you use Active X. When you have shown the example in the demo project, you are recommended to create a new form showing all the steps from the slide.
Exercise: Use the ActiveXMovieC ontrol Object
Solution: ax30_Int_59_ActiveX
Ppp, Axapta
Active X
III
EXERCISE SOLUTIONS
Exercise 12
Use the ActiveXMovieControl Object
Function
Procedure
New Form
From AOT\Forms
CTRL + N
Rename the form ActiveXDemo
F2
Add ActiveX
Keystroke
On the node
Right
Forms\ActiveXDemo\Designs\Design
Mouse
In the ActiveX Browser select
‘New
‘ActiveMovieControl object’ and press OK
Control\Ac tiveX’
Play file
Override the run method on the form After the super() line insert the following lines:
ActiveX.FileName(xInfo::directory(DirectoryTyp e::Include) + '\\jmgsignin.avi'); activeX.AutoStart(true); Show time
Exercise 13
Open the form
Active X Trace
No solution, it should be obvious what happens
CTRL + O
Appendix H. Editor Scripts
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-044-v01.00-ENUS
Editor Scripts
II
INSTRUCTOR NOTES
Time
Topic Comprehension
What to do/say Slide 39
Medium ppp
/ Visualization
Examples
Exercise: Summary
Axapta
Create a new script. Solution: ax30_Int_60_EditorScript
Axapta dialog
Editor Scripts
III
EXERCISE SOLUTIONS
Exercise 14
Create a new script
Reference to Ax30morphx_Integration.xpo project: Section :ax30_Int_60_EditorScript
void sendTo_infolog(Editor e) { TreeNodePath
path
= e.path();
int
startLine
= e.selectionStartLine();
int
startCol
= e.selectionStartCol();
SysInfoAction_Editor
sysInfoAction_Editor;
; sysInfoAction_Editor = SysInfoAction_Editor::newLineColumn(path, startLine, startCol); info(EditorScripts::getSelectedText(e), '', sysInfoAction_Editor); }
Appendix I. Dynamic Link Library
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-045-v01.00-ENUS
Dynamic Link Library
II
INSTRUCTOR NOTES
Time
Topic Comprehension / Visualization
What to do/say Slide 41:
Medium Ppp
Best Practices: Talk about the best practice of not calling the external DLL directly, but to create a new class with methods as an
Axapta
interface. This can then be used by forms, tables etc. all together and warn not to create the same code over and over again in many different places. VarChart: check out the three last methods in the Graphic_Period class. These methods show how to draw and display graphics in Axapta Exercise:
No solution for this
Check the
Axapta + dialog
WinApi class Exercise: Use Varchart
Section : ax30_Int_61_DLL , Count Time job
Axapta
Dynamic Link Library
EXERCISE SOLUTIONS
Exercise 15
Check the WinAPI class
Reference to Ax30morphx_Integration.xpo project: Section : ax30_Int_61_DLL,
Exercise 16
Use Varchart
Reference to Ax30morphx_Integration.xpo project: Section : ax30_Int_61_DLL , Count Time job
III
Appendix J. The RunBase Class
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-140-v01.00-ENUS
The RunBase Class
II
INSTRUCTOR NOTES Time
Topic Comprehension / Visualization
What to do/say Slide 43:
Medium ppp
Slide 44: the methods to override – a deeper explanation of each method can be found in the lesson. After this slide there is an example in the demo project on how to run the RunBase class:
Demo
The demo project contains one table and one runbase class. The table is empty from the start. In the demonstration you should add data (using the table browser) in the SalesID field. After this: execute the class, choose a date, and check via the table browser that the date you have chosen has been added. Next you can go through and explain the methods in the RunBase class.
Exercise:
Before starting the exercises you can show them the solution.
Axapta
Runbase Processes Summary
dialog
The RunBase Class
III
EXERCISE SOLUTIONS Exercise 17
Runbase Processes Reference to the RunBase project
Appendix K. The Batch System
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-047-v01.00-ENUS
The Batch System
II
INSTRUCTOR NOTES
Time
Topic Comprehension
What to do/say
Medium
Slide 45-47
ppp
Tutorial_RunBaseBatch:
Axapta
/ Visualization
Exercise: Examine Tutorial_Runba seBatch Exercise:
Look at the methods within and try to execute the class Section : ax30_Int_63_BatchSystem
Axapta
Create a new class Summary
dialog
The Batch System
III
EXERCISE SOLUTIONS Exercise 18
Examine Tutorial_RunbaseBatch
No solution needed
Exercise 19
Create a new class Reference to Ax30morphx_Integration.xpo project: Section : ax30_Int_63_BatchSystem
Appendix L. Foundation Classes
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-048-v01.00-ENUS
Foundation Classes
II
INSTRUCTOR NOTES
Time
Topic Comprehension/ Visualization
What to do/say Slide 49:
Medium ppp
Explain what foundation classes are, and the advantages of them. Explain the different kinds and their purpose Slide 50:
ppp
The list class is here expanded as an example of a deeper go through of one of the 5 classes.
Pre- Exercises
Before starting the exercise you are advised to display the final form as it should look. (ax30_Int_64_FoundationClasses) This might help the students in solving the exercises.
Exercise List:
Axapta
Exercise Set:
Axapta
Exercise Map:
Axapta
Exercise Array:
Axapta
Summary
dialog
Foundation Classes
III
EXERCISE SOLUTIONS
Exercise 20
List
Reference to Ax30morphx_Integration.xpo project: Section : ax30_Int_64_FoundationClasses
Exercise 21
Set
Reference to Ax30morphx_Integration.xpo project: Section : ax30_Int_64_FoundationClasses
Exercise 22
Map
Reference to Ax30morphx_Integration.xpo project: Section : ax30_Int_64_FoundationClasses
Exercise 23
Array and Struct
Reference to Ax30morphx_Integration.xpo project: Section : ax30_Int_64_FoundationClasses
Appendix M. Gantt Classes
This appendix contains: ∙
Notes and guidelines to instructors
∙
Solutions to exercises
AX-300-APP-049-v01.00-ENUS
Gantt Classes
II
INSTRUCTOR NOTES
Time
Topic Comprehension / Visualization
Exercise: Gant
What to do/say
Medium
Slide
Ppp
Show the Gantt Chart: Main menu, Project, Inquiry, Gantt
Axapta
Chart
Explore in the TutorialGantt form in Axapta
Axapta
Classes in Axapta 3.0 Summary
dialog
Gantt Classes
III
EXERCISE SOLUTIONS
Exercise 24
Gantt Classes in Axapta No solution needed