0% found this document useful (0 votes)
41 views134 pages

Overview of Dynamics 365 ERP and CRM

Dynamics 365 is a suite of AI-powered ERP and CRM applications designed to enhance business operations across sales, service, finance, and supply chain. It enables businesses of all sizes to unify data and processes for improved efficiency and customer engagement. The platform supports both standalone and integrated use of its applications to drive growth and innovation.

Uploaded by

ibrahem mahmoud
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views134 pages

Overview of Dynamics 365 ERP and CRM

Dynamics 365 is a suite of AI-powered ERP and CRM applications designed to enhance business operations across sales, service, finance, and supply chain. It enables businesses of all sizes to unify data and processes for improved efficiency and customer engagement. The platform supports both standalone and integrated use of its applications to drive growth and innovation.

Uploaded by

ibrahem mahmoud
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd

What is Dynamics 365?

What is Dynamics 365?

 Dynamics 365 offers AI-powered ERP and CRM applications to help


you better manage sales, service, finance, and supply chain
operations.

 Use them individually or together to connect teams, processes, and


data for improved efficiency and new insights.
What is Dynamics 365 Used for?

 Dynamics 365 unifies business data and processes to streamline


operations, enhance customer engagement, and drive growth.
 Retailers use Dynamics 365 to manage inventory and personalize
experiences
 financial firms use it to automate onboarding and gain insights
 manufacturers optimize production, manage supply chains, and improve
quality control.
is Dynamics 365 an ERP Or CRM?

 Dynamics 365 offers AI-powered solutions—including autonomous agents to enhance both


CRM and ERP processes.

The CRM applications help manage sales, marketing, and customer service,
The ERP applications connect finance, inventory, and HR to streamline operations.
What Size Of Business Does Dynamic 365 Work
For?

 Scalable Dynamics 365 solutions work for businesses of all sizes


 Enterprise
 small
 medium-sized businesses
What can you do with Dynamics
365?

 Discover how to become more agile, data-driven, and innovative with


flexible, AI-powered applications that adapt to your needs.
 Connect your Data across Department
 Remove barriers to innovation
 adapt to anything
 Deliver more value in less time

Choose one, some, or all. Dynamics 365 applications are made to work together
What is CRM?

 Customer relationship management (CRM)


 is a set of integrated, data-driven software solutions that allow your company to manage,
track, and store information related to your current and potential customers.

 By keeping this information in a centralized system,


 business teams have access to the insights they need, the moment they need
them.
What does a CRM do?

Streamlining customer data


 Not too long ago,
o companies tracked customer-related data with spreadsheets, email, address books, and other siloed, often
paper-based CRM solutions.
o A lack of integration and automation prevented people within and across teams from quickly finding and
sharing up-to-date information
 Fast forward to today.
o CRM systems automatically collect a wealth of information about existing and prospective customers,
including email addresses, phone numbers, company websites.
o The CRM system then unifies the data and generates consolidated profiles that are shared with appropriate
teams.
o CRM systems also connect with other business tools,
o including online chat and document-sharing apps.
Key features of a CRM

 Because CRMs help centralize customer data, these systems make it easier for your team to
manage relationships ,track progress, and ultimately drive growth.
 they also help you build stronger, more personalized connections with clients.
 Here are the key features to look for in a CRM:
 Centralized database: All customer information is stored in one place, making it easy to access and
update, ensuring everyone on your team is on the same page.
 Sales tracking: CRMs help track customer interactions, sales activities, and opportunities, so you can
monitor the sales pipeline and forecast revenue more accurately.
 Automation: Modern CRM systems help allow your teams to automate routine tasks like follow-up
emails or data entry. This saves time, reduces errors, and empowers employees to focus on more
important, strategic goals.
 Customer segmentation: CRMs allow you to organize customers based on various criteria, such as
industry, location, and purchase history. This helps your team send more targeted communications and
improve conversion rates.
 AI capabilities: Modern CRMs incorporate AI-powered tools to provide insights into customer behavior,
predict sales trends, and suggest actions that can improve customer engagement.
Benefits of a CRM

 A CRM system is a central tool that gathers all customer data in one
place, allowing your team to access information quickly and efficiently. It
doesn’t just store data—it makes customer-related processes faster,
smarter, and more organized.
 Practical benefits:
 Increase sales.
 Get real-time performance data through sales monitoring
 Plan your next steps.
 Optimize workflows with automation.
 Track customer interactions for greater impact.
 Connect across multiple platforms for superior customer engagement.
 Accelerate growth and gain a competitive advantage.
What is ERP ?

 Enterprise Resource Planning (ERP) integrates and automates core


business processes, improving efficiency and decision-making.

 Cloud-based ERP solutions use AI to


 Streamline operations
 provide real-time insights
 connect data across financial
 supply chain
Fundamentals of ERP systems

 ERP systems help businesses integrate and streamline operations across various
departments.
 ERP centralizes data and processes, enabling better collaboration, accuracy, and
decision-making.

 ERP systems are used to:


 Integrate Business Functions: Connect all departments—Finance, Supply Chain,
Manufacturing, HR—on one platform for smoother operations.
 Centralize Data: Keep all information in one place for accurate, consistent, and reliable
decision-making.
 Automate Tasks: Reduce manual work like invoicing or order processing to save time and
increase efficiency.
 Real-Time Insights: Get instant reports and dashboards to track performance and make
smarter decisions.
 Cloud & AI-Enabled: Use cloud-based ERP with AI to improve forecasting, maintenance, and
customer experiences.
The history of ERP:
From basic systems to modern solutions
 1960s–1970s – The Beginning
ERP started as MRP (Material Requirement Planning), focused on
manufacturing and inventory management.
 1980s – Business Expansion
MRP evolved into MRP II, adding finance, contracts, and scheduling —
building the base for integrated business systems.
 1990s – Rise of ERP
The term ERP appeared. Systems began combining all business functions
into one platform, mostly on-premises and highly customized.
 2000s – Digital Integration
ERP systems went online, connecting global operations but still worked
separately across business areas.
 Today – Cloud ERP
Modern ERP is cloud-based, AI-powered, and fully integrated, providing real-
time insights, scalability, and strong security.
Five ERP Implementation Challenges
for Businesses

1) Choosing the Right ERP Solution


Many ERP options exist, so selecting the right one can be hard. Businesses should choose a
system that fits their current processes and integrates well across departments.
2) Managing Costs
Implementing ERP doesn’t have to be all at once. Using a modular or phased approach (like
Dynamics 365) helps reduce initial costs and disruption.
3) Integrating with Existing Systems
Older systems may not work easily with ERP. Cloud-based ERP systems use APIs to integrate
smoothly with existing tools.
4) Ensuring Employee Adoption
Employees may resist change or find the system difficult. Training and showing the benefits of
ERP helps adoption. AI-powered interfaces also make it easier.
5) Data Migration and Accuracy
Moving data from old systems can be difficult. Data must be cleaned and validated. AI tools can
help detect errors before migration.
What business functions can ERP
optimize?
6. Customer Relationship Management (CRM)
1. Commerce
1. ERP Predicts customer needs, personalizes interactions, and improve
1. ERP connects in-store and online operations, delivers seamless shopping customer service using AI and automation.
experiences, improves inventory management, and reduces fraud.
7. Data & Analytics
2. Finance
1. Provides real-time insights, predictive analytics, and visual dashboard
1. Automates accounting and reporting, ensures compliance, and provides for smarter, faster decision-making.
AI-powered insights for accurate financial forecasting.
8. Project Management)
3. Human Resources (HR)
1. Improves planning, budgeting, and collaboration, ensuring projects a
1. Streamlines payroll, hiring, and performance tracking while improving with business goals and timelines..
employee engagement and retention.
9. Procurement
4. Manufacturing
1. Automates vendor management, spend analysis, and purchase
1. Optimizes production planning, resource allocation, and delivery workflows for cost efficiency and transparency.
accuracy through automation and real-time insights.
10. Marketing Automation
5. Supply Chain
1. Uses AI to automate campaigns, analyze performance, and align
1. Uses IoT and analytics for real-time tracking, demand forecasting, and
marketing with sales and service data.
minimizing supply disruptions.
11. IT Management & Security
1. Monitors system health, automates updates, and enhances cybersecurity w
AI-powered monitoring and compliance tools
X++ language
X++ language

 X++ is an object-oriented, application-aware, and data-aware


programming language used in enterprise resource planning (ERP)
programming and in database applications.
 It provides system classes for a broad range of system programming
areas, highlighted in the following table.
Common Intermediate Language

 X++ compiles to Microsoft .NET CIL (Common Intermediate Language)


 The advantages of compiling to CIL include:
 Your code runs much faster than in previous versions (AX2012 and earlier).
 It's easier to write application logic in other managed languages and integrated that logic into your X++ app.
 Your X++ apps can efficiently reference classes that are available in other .NET assembly DLL files.
 The CIL can be operated on by the many .NET tools.

If you are upgrading code from previous versions (AX2012 and earlier),
note that the CIL helper methods such as Global::runClassMethodIL have been removed, because they're no longer
relevant.
The Ignore list

 It’s a temporary workaround for testing or staged migration.


 It lives in an XML suppression file.
 It tells the compiler to skip certain best practice checks.
 Not safe to keep once the app goes to production.
X++ variables

 A variable is an identifier that points to a memory location where information of a specific data type is
stored. The size, precision, default value, implicit and explicit conversion functions, and range depend
on the variable's data type.
 The scope of a variable defines the area in the code where an item can be accessed.
 Instance variables are declared in class declarations, and can be accessed from any methods in the
class or from methods that extend the class.
 Local variables can be accessed only in the block where they were defined.
 When a variable is declared, memory is allocated, and the variable is initialized to the default value.
 You can assign values to both static fields and instance fields as part of the declaration statement.
 Variables can be declared anywhere in a code block in a method. They don't have to be declared at the
beginning of a method.
 Constants are variables where the value can't be changed when the variable is declared. They use
the const or readonly keyword.
var

 You can declare a variable without explicitly providing the type of the variable

 if the compiler can determine the type from the initialization expression.

 You can use var only on declarations where initialization expressions are provided.

 You should use var to declare local variables in these situations:


 When the type of the variable is obvious from the right side of the assignment
 When the exact type isn't important
 For the declarations of for loop counters
 For disposable objects inside using statements

Don't use var when the type isn't clear from the initialization expression.
The lifetime of the variable is the scope that it’s declared in.
Variable Scope

 You can provide declarations immediately before the variable is used, and you don’t have to
declare all the variables in one place. Therefore, you have precise control over the scope of
your variables.
 You can give variables smaller scopes, outside which the variables can’t be referenced.
 The lifetime of the variable is the scope that it’s declared in

 There are several advantages to making scopes small:


 Readability is enhanced.
 You reduce the risk that a variable will be reused in an inappropriate manner during long-term
maintenance of the code.
 It's easier to refactor code. You can copy in code without having to worry that variables might be
reused in contexts where they shouldn’t be reused.
Example,
we declare the loop counter inside the for statement that it's used in.
Constants, read-only variables, and macros

 The concept of macros is fully supported. Constants have the following advantages over
macros:
 You can add a documentation comment to a constant but not to the value of a macro. Eventually, the
language service will pick up this comment and provide useful information to the user.
 A constant is known by IntelliSense.
 A constant is cross-referenced. Therefore, you can find all references for a specific constant but not for
a macro.
 A constant is subject to access modifiers. You can use the private, protected, and public modifiers.
The accessibility of macros isn't rigorously defined.
 Constant variables have scope, whereas macros don't have scope.
 You can see the value of a constant or a read-only variable in the debugger.
Null values for data types

 The concept of null values that is available in many other database


management systems (DBMSs) is not supported.
 A variable in X++ always has a type and a value
 each data type, one value is considered null
 example, when the validateField table method is run
Casting

 Casting refers to assignments between variables whose declared types are both in the
same inheritance chain.
 A cast is either a down-cast or an up-cast.

You should use the is and asoperators liberally in your code.

 The is operator can be used if the expression provided is of a particular type (including derived
types).
 The as operator will perform casting into the given type and return null if a cast isn't possible.
X++ Syntax Overview

 X++ has a set of reserved keywords and operators that are fundamental to the language. You cannot
use these for variable names or custom identifiers.
 Data Types & Modifiers
int, int64, real, str, date, datetime
Operat
abstract, final, static, public, private, protected Meaning Example
or
 Expressions & Statements
+ Addition A+B
 Expressions: Can be mathematical or logical.
- Subtraction A-B
Arithmetic: A + B / C
Logical: (A > 3 ? true : false) Multiplication / A * B or select * from
*
Static method call: Debtor::Find("1")
wildcard CustTable
 Statements: == Equality check if (A == B)
Conditional: if, else, switch != Not equal if (A != B)
Loops: for, while, do...while
&& Logical AND if (A && B)
Database: select, insert_recordset, update_recordset, delete_from
:: Call static method ClassName::methodName()
Exception handling: try, catch, throw
X++ Primitive data types

 The primitive data types in X++


are anytype, boolean, date, enum, guid, int, int64, real, str, timeOfDay, utcdatetime.
 The anytype data type is a placeholder for any data type.
 the actual underlying type is determined by the first assignment, otherwise, a run-time error occurs
 After you've assigned anytype, you can't convert it to another data type.
 The boolean data type contains a value that is evaluated as either true or false.
 The date data type contains the day, month, and year.
 An enum is a list of literals. Before you can use an enum, you must declare it in Application Explorer.
 The guid data type holds a globally unique identifier (GUID) value.
 A real variable can hold decimal values in addition to integral values.
 A str variable, string, is a sequence of unicode characters that are used as texts, help lines, addresses, telephone numbers, and so on.
 The timeOfDay (time) data type is an integer value that represents the number of seconds that have passed since midnight.
 The utcdatetime data type combines the date type and the timeOfDay type.
X++ composite data types

 The composite data types in X++ are arrays, containers, classes as data types, delegates as data
types, and tables as data types.
 An array is a variable that contains a list of items that have the same data type.
 There are three kinds of arrays: dynamic arrays, fixed-length arrays, and partly on disk
arrays.
• Dynamic arrays – These arrays are declared by using an empty array option. In other words, they have only brackets ([]).
• Fixed-length arrays – These arrays can hold the number of items that is specified in the declaration.
• Partly on disk arrays – These arrays are declared as either dynamic arrays or fixed-length arrays that have an extra option
• that declares how many items should be held in memory.

 you can't directly create multiple array indexes


 because only one-dimensional arrays are supported.
X++ composite data types

 A container object is a dynamic list of items that contains primitive


data types or composite data types.
 A container is useful when you must pass various types of values
between the client and server tiers
 A container is one of the column types that you can select when you
use Application Explorer to add a column to a table.
X++ composite data types

 A class is a type definition that describes both variables and methods for instances of the
class. (The instances of a class are also known as objects.)
 A class is only a definition for objects, and all objects are null when they are declared.
X++ composite data types

 A delegate collects methods that subscribe to it.


 the parameter signature that all its subscriber methods must share.
 When the delegate is called, the delegate calls each of its subscribers.
 A delegate never returns a value and can't have a default value.
 There is no limit on the number of parameters that a delegate can
declare, and there is no limitation on the type of those parameters.
 The delegate body is always empty, because the delegate's only
purpose is to define the contract that subscribers must conform to.
X++ composite data types

 All tables can be treated as class definitions.


 A table variable can be considered an instance (object) of the table (class) definition.
 For every field in a table variable, the default value is empty. You can address fields
and create methods on tables.
 You can't allocate space for table variables. Allocation is done implicitly.
 Fields in table variables are public. You can reference them anywhere.
 Fields in table variables can be referenced by using expressions.

 You can't access tables that don't have table variables.


 The principles for declaring table variables and objects are the same, except with
regard to the allocation of space.
X++ collection classes

 Collection classes are used to store objects. They let you create arrays, lists, sets, maps, and structs that
can hold any data type, even objects. For maximum performance, the classes are implemented in C++
(they are system classes).
 Collection classes were previously known as foundation classes.
 The collection classes are Array, List, Map, Set, and Struct.
 Array – This class resembles the array type in the X++ language, but it can hold values of any single type, even
objects and records. Objects are accessed in a specific order.
 List – This class contains elements that are accessed sequentially. Unlike an array, the List class provides an
addStart method. Like the Set class, the List class provides the getEnumerator and getIterator methods. You can use
an iterator to insert and delete items from a List object.
 Map – This class associates a key value with another value.
 Set – This class holds values of any single type. Values aren't stored in the sequence in which they are added.
Instead, the Set object stores the value in a manner that optimizes performance for the in method. A Set object
ignores any attempt to add a value that the Set object is already storing. Unlike the Array class, the Set class
provides the in and remove methods.
 Struct – This class can contain values of more than one type. It's used to group information about a specific entity.
Extended data types

 Extended data types are user-defined types that are based on


the boolean, int, int64, real, str, and date primitive data types, and
on the container composite type.

 An EDT is a primitive data type or container that has a supplementary


name and additional properties.
Comments, print statement, TODO
comments

 Comments make a program easier to read and understand. Comments are


ignored when the program is compiled.
 You use the print statement to output text
through [Link] to the Visual Studio Output window.
 During testing, the print statement is an alternative to the Global::info method
 the print statement automatically converting any date type to a string.

 The compiler detects the keyword TODO at the start of a comment and lists it in
Visual Studio’s Task List, showing where unfinished tasks exist in the code.
 Works with both comment styles: // and /* */.
 Unsupported statements:
 pause and window are no longer valid in X++.
 Using them will cause compilation errors.
 Ignored statements:
 server and client keywords (used in AX 2012 to control execution location) are now
ignored,
 since all X++ code runs as .NET CIL on the server.
 They don’t cause errors but shouldn’t be used in new code.
 Using clauses:
 Allow you to avoid typing full namespace paths.
 Must appear before the class definition.
 You can create aliases for namespaces or classes.
Using statements:

The using statement helps guarantee that objects that implement IDisposable are disposed of
correctly.

 When you use an IDisposable object, you should declare and instantiate it in a using statement.
 Simplifies resource management (like files or streams).
if and if...else statements

 The if statement evaluates a conditional expression, and then executes


a statement if the conditional expression is evaluated as true
 You can use the else clause to provide an alternative statement that's
executed if the condition is evaluated as false.

 he syntax for an if...else statement is:


 if ( expression ) statement [else statement ]
switch statements

 The switch statement is a multibranch language construct that has the same behavior as nested if statement
 The expression after the switch keyword is evaluated and checked against each case value.
 If a case constant matches the switch expression, the case statement is executed.
 If the case contains a break statement, the program then jumps out of the switch.
 If the case doesn't contain a break statement, the program continues and executes the next case statements.
 If no matches are found, the default statement is executed.
 If there are no matches and no default statement, none of the statements inside the switch statement are executed.

 Here is the syntax for a switch statement:


 switch ( expression ) { { case } [default: statement ] }
Ternary operator (?)

 The ternary operator (?:) is a conditional expression that is resolved to


one of two values.
 Here's the syntax for the ternary operator:
 expression1 ? expression2 : expression3
for loops

 The syntax of a for loop is:


 for ( initialization ; test ; increment ) { statement }

 The for loop repeatedly executes statement for as long as the conditional
expression test is true
 statement can be a block of statements.
 The body of the for loop (statement) might be executed zero or more times, depending on
the results of test.

 A for loop differs from other loops


 Because an initial value can be assigned to a control variable,
 because there is a statement for incrementing or decrementing the variable.
while loops

 The syntax of a while loop is:


 while ( expression ) statement
 A while loop repeatedly executes statement for as long as the
conditional expression is true.
 statement can be replaced by a block of statements.
 statement is executed as many times as the condition is met (zero to many).
do...while loops

 The syntax of the do...while loop is:


 do { statement } while ( expression ) ;
 The do...while loop is similar to the while loop, but the condition
appears after the statement that must be executed.
 statement can be a block of statements.
 The statement is always executed at least one time,
 because the condition is tested after statement is executed.
Continue ,break statement

 The continue statement causes execution to move directly to the next


iteration of a for, while, or do...while loop. For do or while, the test
is executed immediately.
 For a for statement, the increment step is executed.

 The break statement within a loop is used to terminate that loop.


Execution then moves to the first statement after the loop.
X++ exception handling

 throw statements
 You use the throw keyword to throw an Exception enum value.
 For example, the following statement throws an error exception.
 best practice is to use the output of the Global::error method as the
operand for throw.
try, catch, finally, and retry
statements

 When an exception is thrown, it's first processed through the catch list
of the innermost try block.
 if a catch block is found that handles the kind of exception that is
being thrown, program control jumps to that catch block.
Assignment operators

 An assignment changes the value of a variable or field. The following table shows
the X++ assignment operators. There is no difference between prefix and postfix
operators.
Arithmetic operators

 You use arithmetic operators to perform numeric calculations.


Expression operators
 The as and is expression operators control downcast assignments.
Downcast assignments involve class or table inheritance.
 You can use the as keyword to make your downcasts explicit.
 You can use the is keyword to test whether a downcast is valid at run
time.
Relational operators

 The following table lists the relational operators that can be used in X+
+.
 Most of the operators are binary and take two operands.
 the not (!) operator is unary and takes only one operand
 Syntax for binary operators:
 expression1 relationalOperator expression2
 Syntax for unary operators:
 relationalOperator expression1
Operator precedence

 The order in which a compound expression is evaluated is important.


 If you do not explicitly tell the compiler the order that you want
operations to be performed in, the order is based on operator
precedence.
 You can use parentheses ( ) to explicitly tell the X++ compiler how you
want an expression to be evaluated.
 Order of operator precedence
Classes

 A class defines the data and methods of the instances that are later
constructed from that class. The class is an abstraction of an object in
the problem domain.
 The instances that can be constructed from the class are known
as instances or objects.
 The data represents the state of the object and the methods represent
the behavior of the object.
 All classes are public by default.
 You can specify other modifiers on the class declaration, such
as final, internal, static, and abstract.
Fields

 Instance fields are protected by default.


 You can modify an instance field declaration by using the private, protected,
or public keywords.

 Field attributes
 You can decorate a field with an attribute, in the same way that attributes can
decorate classes and methods.
 example
 decorates the myField field with the MyAtribute attribute.
Methods

 Instance methods
 Instance methods are called with an instance of the class so you must instantiate
the object before you can use the method.
 Static methods
 Static methods, which are also known as class methods,
 belong to a class and are defined by using the static keyword.
 Static methods can access the values of the class static fields and call static methods.
 Main methods
 A main method is a class method that can be run directly from a menu option.
 The _args parameter lets you transfer data to the method.
Method
 Method modifiers
 display - The method's return value should be shown on a page or a report. The value can't be modified on
the page or report. Typically, the return value is a calculated value, such as a sum.
 edit - The method's return type used to provide information for a field that is used on a page. The value in the
field can be modified.
 final - The method can't be overridden in any class that derives from its class.
 public - Methods that are declared as public can be accessed anywhere that the class is accessible, and they
can be overridden by subclasses. Methods without an access modifier are implicitly public.
 protected - Methods that are declared as protected can only be called from methods in the class and in
subclasses that extend the class where the method is declared.
 private - Methods that are declared as private can only be called from methods in the class where the
private method is declared.
 internal - Methods that are declared as internal can only be called from methods in the class that are
defined in the same model as the class where the method is defined.
 static - The method is a class method. Static methods can't refer to instance fields. They aren't invoked on an
instance of the class. Instead, they're invoked by using the class name (for example,
 abstract - The method is declared but isn't implemented. The method must be overridden in all subclasses. If
you try to create an object from a subclass where one or more abstract methods that belong to the parent
class haven't been overridden,
Local functions

 You can declare functions inside a method. These are called local functions.
 Code that's inside the local function can access variables that are declared before
it's in the method that contains the local function.
 Code that's outside the local function can't access variables that are declared in
the local function.
Extension methods

 The extension method feature adds extension methods to a target class by writing
the methods in a separate extension class.
 The following rules apply:
 The extension class must be static.
 The name of the extension class must end with the ten-character suffix _Extension.
 Every extension method in the extension class must be declared as public static.
 The first parameter in every extension method is the type that the extension method
extends

 The target of an extension method must be one of the following types:


 Class
 Table
 View
 Map
X++ attribute classes

 An attribute is a non-abstract class that extends (inherits from)


the SysAttribute class.
 Attributes represent or store metadata about types and methods.
 An attribute can be attached to a class, a class field, a class method, an
interface, or a table.
 Attributes are applied to the handlers of delegates and methods, to
map the handlers to those targets.
TransientSqlConnectionError X++ exception

 During an X++ SQL query execution, when a transient SQL


connection error occurs on the server side, a
TransientSqlConnectionError X++ exception will occur.
 the application should catch and handle the exception.
 This exception usually occurs during a large transaction or
when the database is under a lot of processing pressure.
Select statement

 The select statement fetches data from the database.


 All select statements use a table variable to fetch records. The type of this
variable is a Table that is defined in the Application Object Tree. This variable must
be declared before a select statement can be run.
 The select statement fetches only one record, or field. To fetch or traverse
multiple records, you can use the next statement or the while select statement.
 The next statement fetches the next record in the table. If no select statement
precedes the next statement, an error occurs.
 It's more appropriate to use a while select statement to traverse multiple records
example
Syntax of the select statement
Aggregate functions

 Aggregate functions
 The aggregate functions perform calculations on a single field over a
group of records.
 Grouping and ordering the query results
 A query can have multiple group by clauses, but the fields can be qualified
by a table name in only one group by clause.
 The order by clause follows the same syntax patterns as group by
Join tables

 The following example shows how an inner join can be performed as


part of a select statement. The example also shows an order
by clause where each field is qualified by a table name. Therefore, you
can use just one order by clause to control how the retrieved records
are sorted.
Using where, order by, and index hint together in a query

Example
Asc,Avg keyword

 asc keyword
 The asc keyword is an option on the order by or group by clause.

 avg keyword
 The avg keyword returns the average of the fields.
Count, crossCompany keyword

 count keyword
 The count keyword returns the number of records.

 crossCompany keyword
 The crossCompany keyword returns data for all companies that the user is
authorized to read from.
 You can add a container to reduce the number of companies that are
involved.
Desc,exists keyword

 desc keyword
 The desc keyword is an option on the order by or group by clause. It specifies
a descending sort order. If neither asc nor desc is specified, the sort is
ascending.

 exists keyword
 The exists keyword is a method that returns a Boolean value and a join clause.
firstFast keyword

 firstFast keyword
 The firstFast keyword is a priority hint. The first row appears more quickly,
but the total return time for this option might be slower. The firstFast hint is
automatically issued from all pages.
firstOnly keywords

 The firstOnly keywords speed up the fetch by returning a limited number of


rows.
forceLiterals keyword

 The forceLiterals keyword instructs the kernel to reveal the actual


values that are used in where clauses to the Microsoft SQL Server
database at the time of optimization.
 The forceLiterals and forcePlaceholders keywords are mutually
exclusive.
forcePlaceholders keyword

 The forcePlaceholders keyword instructs the kernel not to reveal the


actual values that are used in where clauses to the SQL Server
database at the time of optimization.
forceNestedLoop keyword

 The forceNestedLoop keyword forces the SQL Server database to use


a nested-loop algorithm to process a particular SQL statement that
contains a join algorithm.
 a record from the first table is fetched before any records from the
second table are fetched.
forceSelectOrder keyword

 The forceSelectOrder keyword forces the SQL Server database to


access the tables in a join in the specified order.
 If two tables are joined, the first table in the statement is always
accessed first. This keyword is often combined with
the forceNestedLoop keyword.
forUpdate keyword

 The forUpdate keyword selects records for update only. Depending on


the underlying database, the records might be locked for other users.
group by keyword

 The group by keyword instructs the database to group selected records by


fields.
in keyword

 The in keyword filters rows where a value is contained in a list.


 If you don't use the in keyword, the code that you write will resemble
the following example.
Index,index hint keyword

 The index keyword instructs the database to sort the selected records
as specified by the index.
 The index hint keyword forces SQL Server to use a specific index.
Using index hint keyword, means you take away the control of which
index to use from the Query Optimizer.
join keyword

 The join keyword is used to join tables on a column that is shared by both tables.
Maxof,minof keyword

 The maxof keyword returns the maximum of the fields.

 The minof keyword returns the minimum of the fields.


noFetch,notExists keyword

 The noFetch keyword indicates that no records should be fetched now.


Typically, this keyword is used when the result of the select statement
is passed on to another application object, such as a query that
performs the actual fetch.

 The notExists keyword checks for the absence of related records in the
joined table. If a match does exist, teh record is excluded from the
results. If no match is found, the record is included in the results.
optimisticLock,pessimisticLock keyword

 The optimisticLock keyword forces a statement to run by using


optimistic concurrency control, even if a different value is set on the
table.

 The pessimisticLock keyword forces a statement to run by using


pessimistic concurrency control, even if a different value is set on the
table.
Order by,outer keyword

 The order by keyword instructs the database to sort the selected


records by the fields in the order by list. The by keyword is optional.

 The outer keyword returns all rows from the table that is named first,
even rows that have no match in the table that is named second.
repeatableRead,reverse keyword

 This repeatableRead keyword specifies that the current transaction


must be completed before other transactions can modify data that has
been read by logic inside the current transaction.

 The reverse keyword returns records in reverse order.


Sum,validTimeState keyword

 The sum keyword returns the sum of the fields. It can be used to sum
all accounts, order lines, and so on.

 The validTimeState keyword selects rows from a table where


the ValidTimeStateFieldType property is set to a value other
than None.
where keyword

 The where keyword filters rows from a table where the expression is true.

 The following example finds a customer that has an AccountNum value that is more
than 100.
Insert , Update, Delete example

Example
 inserts a new record into the CustTable table. The AccountNum column of the new
record is set to 2000, and the CustGroup column is set to 1.
Example
 Only the record where the value of the AccountNum field equals 2000 are updated.
 Because there is no call to next
Example,
 all records in the CustTable table where the AccountNum field equals 2000 are
deleted
While select statement

 A while select statement is used to handle data.


 It's the most widely used form of the select statement.
 The while select statement loops over many records that meet specific criteria

 The results of the while select statement are returned in a table buffer variable.
 If you use a field list in the select statement, only those fields are available in the table
variable.
 Any Boolean expressions that are added to the while select statement (for example, iCounter < 1)
are tested only one time.
select statement

 You can use a select statement as an expression. This type of select statement is known as
an expression select statement.
 You can't use a table buffer variable in an expression select statement.
 The name of the table must be used in the from clause.
 The join keyword isn't supported.
 The table name can't be used to qualify a field name in the order by clause.
 In a where clause, the table name must be used as a qualifier of the field.
 You can mention only one table in an expression select statement. Therefore, subselects aren't supported as a
workaround for the unsupported join keyword.
 The only column that can be filled with data is the column that is named before the from clause in the select clause.
 After the closing parenthesis, the name of a column is used to reference the data value.

Here is a simpler way to achieve the same result as the previous example.
Insert data

 to insert one or more rows into tables that are stored in the database.
 insert method – Insert one row at a time.
 doInsert method – Insert one row at a time.
 insert_recordset statement – Copy multiple records directly from one or more tables into
another table in one database trip.
 [Link] – Insert multiple rows at the same time in one database trip.
Use this construct when you don't have to sort the data.
 [Link] – Insert multiple rows at the same time in one database trip.
insert method

 The insert method inserts one record at a time. It generates values for
the RecId field and system fields, and then inserts the contents of the buffer (that
is, the column values) into the database.
doInsert method

 The doInsert method generates values for the RecId field and other system
fields, and then inserts the contents of the buffer into the database. Use this
method when the insert method on the table must be bypassed.
insert_recordset statement

 The insert_recordset statement copies data directly from one or more


source tables into one destination table in one server trip.
 It's faster to use insert_recordset than an array insert
([Link] or [Link]
abase).
insert_recordset:
Inserting data from another table

 example, the Value column in the NameValuePair table is summed for


each Name value. The results of the aggregation are stored in the ValueSumByName
table.
insert_recordset:
Inserting data from variables

Example
shows that the insert_recordset statement can insert variable data.
 Include the firstonly keyword to insert only one new record. If you omit firstonly, a record
is inserted for each record in the CustTable table.
 Literals, such as 128 or "this literal string", can't be used in the query as a source of data
that is inserted.
 The columns in the source table don't have to correspond to the target table.
insert_recordset:
Inserting data by using a join
Example
 shows a join of three tables on an insert_recordset statement that has a subselect. It
also shows a while select statement that has a similar join. A variable is used to
supply the inserted value for one column. The str variable must be declared, and it
must have a length that is less than or equal to the maximum length of the
corresponding database field.
Update data

 You can use SQL statements, either interactively or in source code, to update
one or more rows in a table that is stored in the database.
 update method – Update the current record with the contents of the buffer. Also
update the appropriate system fields.
 doUpdate method – Update one row at a time.
 update_recordset statement – Update multiple records in one database trip. By
using the update_recordset statement,
 you reduce communication between the application and the database. Therefore, you
help increase performance. In some situations, record set–based operations can fall
back to record-by-record operations.
update method

 The update method updates the current record with the contents of
the buffer. It also updates the appropriate system fields.
doUpdate method

 To override the behavior of the update method, use the doUpdate method.
The doUpdate method updates the current record with the contents of the buffer.
 It also updates the appropriate system fields. You should use
the doUpdate method when the update method on the table must be bypassed.
update_recordset statement

 The update_recordset operator is a record set–based operator that


updates multiple records in one trip to the server.
Delete data

 You can use SQL statements, either interactively or in source code, to


delete one or more rows from tables that are stored in the database.
• delete method – Delete one row at a time.
• doDelete method – Delete one row at a time.
• delete_from statement – Delete multiple rows at the same time. By using
the delete_from statement, you reduce communication between the
application and the database. Therefore, you help increase performance. In
some situations, this set-based operation can fall back to a record-by-record
operation.
delete method

 The delete method deletes the current record from the database. To
use this method, use a where clause to specify the rows to delete. One
record at a time is then removed from the specified table.
doDelete method

 Like the delete table method, the doDelete table method deletes the current record from
the database. Use the doDelete method if the delete table method has been overridden,
and you want to run the original (base) version of that method instead of the overridden
version.
delete_from statement

 The delete_from operator is a record set–based operator that removes multiple


records at the same time. This approach can be more efficient and faster than an
approach that uses the delete method in a loop to delete one record at a time.
X++ transactional integrity

Two internal checking features help ensure the integrity of transactions:


 A forUpdate check
 helps ensure that a record can be updated or deleted only if it has first been selected for update. You can
select a record for update by using either the forUpdate keyword in the select statement or
the selectForUpdate method on the table.
 A ttsLevel check
 helps ensure that a record can be updated or deleted only in the same transaction scope where it was
selected for update.
 Example of code that is rejected by the forUpdate check

 Example of code that is rejected by the ttsLevel check


X++ transactional integrity

The following statements are used to help ensure integrity:


 ttsBegin – This statement marks the beginning of a transaction. It helps ensure data
integrity and also helps ensure that all updates that are done until the transaction ends
(through ttsCommit or ttsAbort) are consistent.
 ttsCommit – This statement marks the successful end of a transaction. It ends and
commits a transaction. The finance and operations app ensures that a transaction that
has been committed will be performed according to intentions.
 ttsAbort – This statement lets you explicitly discard all changes in the current
transaction. In this case, the database is rolled back to the original state, where nothing
has been changed. Typically, you use this statement if you've detected that the user
wants to break the current job. The ttsAbort statement helps ensure that the database
is consistent.
Conversion of Operations from
Set-Based to Record-by-Record
 In Finance and Operations, set-based operations like delete_from,
update_recordset, and insert_recordset are used to improve performance by
sending bulk operations to the database instead of processing one record at a
time.
 in some cases, these operations are automatically converted into record-by-
record operations, which are slower because they require more communication
with the database.
Access data by using the SysDa classes

 The extensible SysDa API provides almost all the data access possibilities
that are available in X++. In fact, the APIs are wrappers around the code that
the X++ compiler would generate.
 The SysDa APIs include an extensive set of APIs for creating custom queries.
 there is a smaller set of types that drives the primary query activities:
 Select: SysDaQueryObject, SysDaSearchObject, and SysDaSearchStatement
 Update: SysDaUpdateObject and SysDaUpdateStatement
 Insert: SysDaInsertObject and SysDaInsertStatement
 Delete: SysDaQueryObject, SysDaDeleteObject, and SysDaDeleteStatement
Select query

 To run a select query, follow these steps.


1. Create and configure a SysDaQueryObject object that specifies the table instance that will contain the designated
records.
2. Create a SysDaSearchObject object, and pass the SysDaQueryObject object to the constructor.
3. Iterate over the results of the query by passing the SysDaSearchObject object to
the [Link]() method.

Example
Retrieves all records where intField <= 5.
Update statement

 To run an update statement, follow these steps.


1. Create and configure a SysDaUpdateObject object.
2. Update data by passing the SysDaUpdateObject object to the [Link]() object.

Because updates modify the data in the database, you must call to execute in ttsbegin and ttscommit statements.

Example
Updates stringField to "fifty" for all rows where intField = 50.
Insert statement
 To run an insert statement, follow these steps.
1. Create and configure a SysDaInsertObject object to specify which fields are updated during the insertion.
2. Create and configure a SysDaQueryObject object that specifies the source of the rows to insert. The order of the fields
in [Link]() must match the order of the fields in [Link]().
3. Assign the SysDaQueryObject object to the SysDaInsertObject object.
4. Insert the new row by passing the SysDaInsertObject object
to the [Link]() method.

Example
Inserts a new record with stringField = "en-us" and intField = 40.
Delete statement

 To run a delete statement, follow these steps.


1. Create and configure a SysDaQueryObject object to specify which rows to delete.
2. Create a SysDaDeleteObject object, and pass the SysDaQueryObject object to the constructor.
3. Delete the rows by passing the SysDaDeleteObject object to
the [Link]() method.

Example
Deletes all records where intField is even.
SysDa queries

 SysDa queries support several clauses:


 WhereClause – Filters data (e.g., SysDaEqualsExpression, SysDaLessThanExpression)
 OrderByClause – Sorts the results
 GroupByClause – Groups results
 JoinClause – Joins multiple tables
 SettingClause – Defines fields for update or insert

 SysDa supports hints and expressions for advanced tuning:


 Joins: Inner, Outer, Exists, Not Exists
 Aggregations: COUNT, SUM, AVG, MIN, MAX
 Comparison operators: ==, <>, >, >=, <, <=, LIKE
 Performance hints: firstOnly, forceNestedLoop, forceSelectOrder, etc.
 Troubleshooting
 Use .toString() on any SysDa object (like SysDaQueryObject or SysDaUpdateObject) to see the final SQL
Mitigate a SQL injection attack

 An SQL injection attack occurs when malicious data values are passed to
Microsoft SQL Server in a query string.
 SQL injection can occur if you aren't careful about how you use a query to pass
data that comes from an uncontrolled source, such as user input, to SQL Server.
When you build SQL queries by concatenating user input directly into strings.
The database executes the input as part of the SQL command.

 The Fix: Use SQL Parameters


 Microsoft introduced a new API (starting from version 10.0.17) that prevents SQL injection.
 Instead of adding raw values to the query, you use parameters.
VHD Development Setup

 Phase 1: VHD Download & Extraction


 [Link] LCS Asset Library -> Download all VHD parts.  Phase 4: Development & Deployment
 [Link] [Link] -> Extract to create the single .vhd file.  [Link] VS: D365 > Model Management > Create model.
 Phase 2: Hyper-V & VM Configuration  [Link] code -> D365 > Build models
  (with optional DB Sync).
[Link] Hyper-V feature in Windows -> Restart PC.
 [Link] Deployment Package (.zip) for testing/deployment.
 [Link] Hyper-V Manager -> New Virtual Machine.
 Phase 5: VHD Upgrade (Maintenance)
 [Link] VM: Name, Generation 1, Assign >= GB RAM.
 [Link] new update package (.zip) from LCS -> Unlock file properties.
 [Link] Networking to Default Switch.
 [Link] contents (e.g., to C:/Temp).
 [Link] the Existing .vhd file -> Finish.
 [Link] Command Prompt (Admin) -> Execut [Link] devin
 Phase 3: Post-Setup & Visual Studio  [Link] install: Compile and Sync in Visual Studio.
 [Link] VM -> Open Visual Studio (Admin) -> Sign In.
 [Link] VS D365 Options (e.g., Organize projects by element type).
 10.(Optional) Check SQL Server Management Studio connection to AXDB.
Create and build projects

 Developers use Visual Studio to create and customize elements and perform other
developer operations.
 The Element Designer is used to create elements, while the Application Explorer is
used to manage elements.
 It is important to synchronize any data changes with the database to Ensure that all
elements are up to date in the Application Object Tree (AOT).
Create and build projects

 Creating a project in Visual Studio is essential for organizing, managing, and deploying your code
effectively.
 It groups related elements, manages dependencies, and controls builds, making it easier to navigate
your solution.
 solution is a container that organizes one or more related projects.
 Solutions represent different parts of an application, such as business logic, UI components, and
services.
 To create a new project,
 Go to File > New > Project, or hold Ctrl + Shift while pressing the N key.
 Under the project templates, select Finance Operations, then select Next.
 In the project wizard, name your project and make sure to select the model where it belongs. The model is
difficult to change when you start adding files to the project, so getting it right early on is important.
Build, rebuild, and clean

 To compile your code, you have multiple options: you can build, rebuild,
or clean your project from the Solution Explorer.
 A build compiles any changes.
 A rebuild compiles all components from scratch.
 clean removes previous build outputs.
Create and use label files

Using label files is the best practice for all text in the user interface (UI) to support multiple languages
seamlessly.
Do not modify standard labels; create custom ones.

 Phase 1: Create Custom Label Files


 [Link] the Wizard: Right-click your project in Solution Explorer -> Add -> New Item.
 [Link] Type: Choose Label and Resources -> Label file.
 [Link] ID: Enter a clear Label file ID (e.g., matching your solution name) -> Select required languages.
 [Link]: Select Next/Finish. The system creates one label file for each language in your project.

 Phase 2: Add Labels to the File


 [Link] File: Open the newly created label file in the designer.
 [Link]: Select New to create a new label row.
 [Link]: Enter a unique Label ID (e.g., CustName) and the corresponding Label string (text).
 [Link]: If supporting multiple languages, create the same Label ID in the corresponding language file.

Create and use label files
 Phase 3: Use Labels in UI or Code
 Labels are used for element properties (Label, Description, Help text) and in X++ code for messages (Info, Error,
etc.).
Usage Action Example

Copy the full label reference from the


@MyLabelFile:CustName (Format:
In Properties designer -> Paste it into the desired
@LabelFileID:LabelID)
property field.

Use the strFmt or Info functions to display


In X++ Code Info(strFmt('@MyLabelFile:CustName'));
the label.

 If you need to change a standard label (e.g., Sys:StdLabel), you can override it using an extension:
 1. Create a new custom label file using the wizard, adding the postfix _Extension (e.g., Sys_Extension).
 2. Create a new label in this file with the exact same Label ID as the standard label you want to change.
 3. Provide the new text string. The system will now use your custom label text instead of the standard one.
metadata

 In Visual Studio, all objects that define the application's structure and functionality-such as tables,
forms, classes, and workflows-are stored within the Application Object Tree (AOT).
 The AOT serves as a centralized repository, organizing these elements for easy access and
management during development and customization.
 Metadata types
 Extended Data Types (EDTs) - If you have programmed before, you might think of these as primitive types:
Boolean, String, Real, Integer, Globally Unique Identifier (GUID), Container, Time, Date, and Enum.
 Enums - A type with a value that is chosen from a predefined list.
 Tables - Organize data into rows and columns.
 Forms - User interface elements that get their own page in finance and operations apps.
 Data entities - An abstraction of database tables that are used for integrations, data import/export, and more.
Views Types

 The Application Explorer contains the Application Object Tree (AOT), which has two views: the
model view and the classic view.
 To access these views, right-click the AOT node and select model view or classic view.

Model view : organizes metadata by the model that contains it.


 useful when you are browsing for elements that are related to a certain model's features.

Classic view : groups metadata elements by their type.


 helpful when you know what kind of element that you need but not which module contains it.
Build Deployment Packages (SDP)

 To apply your code changes to a non-development environment, build a Software Deployable Package
(SDP) and upload it to Lifecycle Services.
 To build an SDP from Visual Studio, follow these steps.
 Go to Builds in Team Explorer.
 Right-click the desired build definition.
 Select Queue New Build.
 In the browser window that opens, sign in to Azure DevOps (unless you are automatically signed in).
 Use the Queue button to open the build queue dialog box.
 Enter any parameters that you need to in the dialog box.
 Select Confirm to queue the build.
 After the build completes:
 Logs and built code are available to download.
 The code is available as just the models it includes or as an AX Deployable Runtime.
 All downloads are accessible via the Artifacts button on the build’s status page.
Synchronize data changes with the database

 When you add or change elements, you must synchronize the database so that it
knows in which fields (columns) that it needs to store these elements.
 To do that:
 select Synchronize Database from the Dynamics 365 menu and then use
the Synchronize button in the dialog box.
 select Synchronize Database on Build on the Options tab of the Build Models dialog
box to automatically synchronize the database after a successful build.
Create new elements

 A developer for Dynamics 365 may need to create new elements to meet the requirements of a
customization or modification being made to the application.
 The Element Designer is the central development tool in Visual Studio, where you use it to
edit and configure elements.
 New elements can be created and modified here, and existing elements within the AOT can
be extended to fit specific needs within this window.

 Creating a new element starts in the Solution Explorer window:


 Right-click the project and select Add new item.
 This opens a dialog box where you can choose what kind of object to add and then give it a name.
then the element will appear in the Solution Explorer window.
 Select the element in the Solution Explorer window, which will bring it into the Element Designer for editing.
 To extend an element from the AOT, right-click it and select Extend. This will add it to the Solution
Explorer window.
Create new elements

 The appearance of the Element Designer varies by element type but generally:
 Contains a hierarchical view of element data and related elements or code.
 Allows drag and drop of elements where structurally appropriate.
 Lets you view properties of any selected node in the Properties window.
 By right-clicking code elements, you can open them in a code editor and modify them using familiar
Visual Studio features like Intellisense.

Forms Layout
 Forms have three main windows:
1. Form Designer – Shows a hierarchical view of the form's structure.
2. Normal Element Designer – Displays the selected node in the view.
3. Pattern Designer – Helps match existing form layouts and UI conventions.
Extended Data Types, Enumerations

 EDTs extend primitive data types with custom properties, making data structures more consistent and
maintainable.
 Enumerations simplify the management of predefined sets of values. Together
 While base enums and EDTs are not new to all developers, it's important to understand how these
data types are used in development for finance and operations apps.
 The following primitive data types exist in the AOT and can be created in Visual Studio:
 Booleans - Can only contain the values "false" and "true."
 Dates - Contain the numbers for day, month, and year.
 Enums - An abbreviation for "enumerated text," or a set of literals.
 GUIDs - Globally unique identifiers.
 Integers - Numbers without a decimal point.
 Real - Numbers with a decimal point and are sometimes called decimals.
 String - A series of characters, such as a text block.
 TimeofDay - Contain the numbers for hour, minute, and second.
Benefits of using EDTs

 1. Improved Readability
 Code becomes easier to understand with meaningful variable names.
 Example: Using a string variable named “Name” for a user input field

 2. Consistency Across the System


 Properties defined for an EDT are reused across all its instances.
 Example: AccountNum data type keeps the same format everywhere in the system.

 3. Inheritance and Flexibility


 EDTs can form hierarchies, inheriting parent properties while allowing customization.
 Example: ItemCode → MarkupItemCode, PriceDiscItemCode.

 4. Reusability
 Once created, an EDT can be used across multiple tables and forms.
 5. Enhanced Behavior and UI Features
 EDTs can enable lookup and drop-down list behaviors.
 Support for multiline string controls with lookup capabilities.
base enum

 A base Enum is a list of literals with an assigned value. You will need to create base
enumerations in Visual Studio before you can use them in X++ code.
 Enum values are represented internally as integers, and they are stored in the
database as a number instead of the value.
 To add a base enum to your project,
 right-click your project,
 select Add > New Item.
 under Dynamics 365 Items, select Data Types > Base Enum.
Data Models

 The data model in finance and operations apps consists of tables,


views, queries, and other components.
 All data in finance and operations apps is stored in tables and managed
in the data model in Visual Studio.
Create tables and table fields

 Tables contain rows and columns, just like a spreadsheet.


 They are stored in a database and work together to deliver data to the user in
outputs such as forms and reports.
 Tables are made up of fields, which are organized into field groups.

 Adding Fields to a Table


 Creating Tables
 You can add fields in multiple ways:
 right-clicking the project
 Drag and drop from your project or Application
 selecting Add > New item. Explorer.
 table designer and Properties windows.  Right-click the table name → Add > New Field.
 modify these tables  In the Properties window, select the element type:
 Base Enum or EDT.
Table Designer

 The Table Designer in Dynamics 365 shows the table name and its main parts:
 Fields: Store data in the table, usually using base enums or extended data types (EDTs).
 Field Groups: Group related fields for easy reuse in forms and reports.
 Indexes: Speed up data searches.
 Relations: Link the table to others.
 Delete Actions: Define what happens when related records are deleted.
 State Machines: Handle state changes in workflows without extra code.
 Mappings: Connect fields between different tables.
 Methods: Code that runs when certain actions occur.
 Events: Trigger code before or after methods run.

You might also like