understanding bapi

75
Understanding BAPI: The most powerful tool in the SAP consultant's kit By Scott Robinson November 1, 2002, 8:00am PST SAP R/3 is typical of enterprise platforms in that it forces its users to reconceptualize the way information is used in a company. Integration and data transport become the keywords, and data ceases to be treasure in the vault—it becomes a living thing, flowing through the company like water. Think of the pre-ERP universe as a series of small lakes, some connected, some not. Each lake (company) is filled with data. Occasionally, boats venture from the shore to the middle of the lake for some data. Occasionally, one of these boats transfers data from one lake to another. With the advent of ERP, a canal system—SAP R/3—is installed. A vast network of bidirectional waterways takes the place of the lakes. Small, powerful ships and barges populate these waterways, keeping data in constant motion. For the SAP consultant, IDocs are the barges. And Business Application Programming Interfaces—BAPIs—are the small, powerful ships that keep these barges of data moving. First in a series This is the first installment in a series that examines the significance of Business Application Programming Interfaces, how to use them, and their role in designing applications. Building canals for the client An understanding of how SAP changes the structure of a business is the first conceptual step in becoming an effective SAP consultant. A solid knowledge of SAP’s data-handling mechanisms, of which BAPI is the most

Upload: bharathsajja

Post on 08-Nov-2014

110 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: Understanding BAPI

Understanding BAPI: The most powerful tool in the SAP consultant's kitBy Scott Robinson

November 1, 2002, 8:00am PST

SAP R/3 is typical of enterprise platforms in that it forces its users to reconceptualize the way information is used in a company. Integration and data transport become the keywords, and data ceases to be treasure in the vault—it becomes a living thing, flowing through the company like water.

Think of the pre-ERP universe as a series of small lakes, some connected, some not. Each lake (company) is filled with data. Occasionally, boats venture from the shore to the middle of the lake for some data. Occasionally, one of these boats transfers data from one lake to another.

With the advent of ERP, a canal system—SAP R/3—is installed. A vast network of bidirectional waterways takes the place of the lakes. Small, powerful ships and barges populate these waterways, keeping data in constant motion.

For the SAP consultant, IDocs are the barges. And Business Application Programming Interfaces—BAPIs—are the small, powerful ships that keep these barges of data moving.

First in a seriesThis is the first installment in a series that examines the significance of Business Application Programming Interfaces, how to use them, and their role in designing applications.

Building canals for the clientAn understanding of how SAP changes the structure of a business is the first conceptual step in becoming an effective SAP consultant. A solid knowledge of SAP’s data-handling mechanisms, of which BAPI is the most central, is the first practical step.

BAPI is the most powerful tool in the SAP consultant’s toolkit. Think of a BAPI as a business object—say, a master record, such as a client profile, or a transactional record, such as an invoice. It’s easy to confuse a BAPI with an IDoc (another central SAP data transport feature). The difference is that IDocs are about moving data between systems or modules; BAPIs are about calling data in and out of SAP in the first place.

Their place in SAP and your toolboxSAP R/3 arrives with a bundle of BAPIs ready for your immediate use. There are several hundred of

Page 2: Understanding BAPI

them, in categories such as accounting, human resources, and logistics. They perform a vast array of functions, from creating jobs in SAP to launching IDocs, from posting sales orders to changing passwords, from listing employee benefits to tracking a shipment. They can be used out of the box or modified to create new business objects specific to your client’s needs.

BAPI is one of a set of tools at your disposal for interfacing with an SAP R/3 system. It’s important to understand its role among them, and to have an idea of what each does in relation to the other.

SAP AssistantThis stand-alone program is, in essence, the toolbox you carry with you as a hands-on SAP consultant. Its contents give you access to SAP R/3’s objects. All the information you need for setting up remote function calls from outside SAP is found here. Most importantly, SAP Assistant holds your set of keys to SAP’s business objects, allowing you access to what’s there, and enabling you to create what you need (see Figure A).

Figure A

Where BAPI fits in among SAP automation components

Page 3: Understanding BAPI

Remote Function CallsBAPI is ultimately a mechanism for getting data out of SAP R/3. If a BAPI is a ship pushing a barge (data), the engine of that ship is a Remote Function Call (RFC). An RFC is a function module in a system that is called from some other system. This, of course, covers a great deal of ground. The two systems can both be SAP, or they can be different platforms, or an RFC may be used on the spot in real time by any party making an inquiry of an SAP system from the outside (including you, sitting at your laptop).

How do RFCs relate to BAPIs? An RFC is the means by which the business object represented by a BAPI is implemented. A BAPI is a business object; an RFC is functional code.

The Business Object RepositoryA great deal goes on in the Business Object Repository (BOR), and you must know it well. It’s not overstating the case to say that the BOR is the core of SAP. If an SAP R/3 system can be described as the animation of otherwise lifeless data, the BOR describes the living cells of this new body. Cells come in many different types, and that’s what the BOR holds: all the different types of data comprising an SAP system of databases.

The BOR’s contents essentially define the implementing company’s business model. The information it holds includes the definitions of all business objects internal to the company, as well as the defining information of all interfaces to other companies.

Another new languageBAPI is, like many aspects of SAP R/3, another new lexicon of concepts, terms, and tools a consultant must absorb to be effective. However, it will rapidly be clear to even a less experienced consultant that these concepts are firmly rooted in the object-oriented methodology that is now every IT professional’s stock-in-trade.

It is critical that you, as an SAP consultant, understand the dynamic nature of data handling in an SAP environment, the manner in which this mutates business processes, and most importantly, the way in which BAPI and related tools interface with this new, living database. Once you understand these concepts, the hands-on skills to create applications become simple.

Programming Methods for Sub-Objects

Use

If a business object type consists of sub-objects, you can implement the following standardized BAPIs to add or remove sub-objects:

Add

Page 4: Understanding BAPI

This method adds a sub-object to an object type.

Remove

This method removes a sub-object from an object.

For example, to add or remove the sub-object purchase order item to the business object type purchase order, the BAPIs AddItem() and RemoveItem() could be implemented for the object type, purchase order.

The BAPIs Add and Remove are instance methods.

Features

Import Parameters

Both BAPIs' import parameters must contain in the function module the data that uniquely identifies the sub-object as well as the key fields of the business object.If required, you can create also create these parameters:

A test run parameter for checking the entry for an object instance before actually creating the instance in the database.

A change parameter to identify parameter fields containing modified values and parameter fields that have not been modified.For more information about these parameters see Standardized Parameters.Export Parameters

You should only create the export parameter RETURN in the BAPI Remove to return messages from the method call to the calling program. For more information about this parameter see Return Parameters (Error Handling).To make the object key available to the calling program, the key fields of the object type must also be returned in the export parameters of the BAPI Add as well as in the export parameter Return.

Extension parameters

You can create extension parameters to enable customers to enhance the functionality of BAPIs without making modifications. For information about extension parameters see Customer Enhancement Concept for BAPIs.

Locking

We recommend that you implement methods of sub-objects without the locking function and create your own BAPIs instead that lock the relevant data.

Page 5: Understanding BAPI

If you are implementing BAPIs that create or change data you should consider using buffering. For further information see Buffering for Write BAPIs.BAPIs for Mass Processing

The BAPIs listed in the above section, "BAPIs for Creating or Changing Data", can also be used for mass processing. Here, when a BAPI is called, several business object instances are processed at the same time.

With BAPIs for mass processing, the suffix "Multiple" is added to the method name, for example, ChangeMultiple(), CreateMultiple(), DeleteMultiple(). The BAPIs here are always class methods.

We strongly recommend that you create instance-dependent BAPIs with buffering instead of Multiple() BAPIs. For further information see Buffering with Write BAPIs.BAPIs for Replicating Business Object InstancesThe following BAPIs are used for replicating business object instances:Replicate() and SaveReplica()The BAPIs Replicate() and SaveReplica() are implemented as methods of replicable business object types(). They enable specific instances of an object type to be copied to one or more different systems. These BAPIs are used mainly to transfer data between distributed systems within the context of Application Link Enabling (ALE). These BAPIs are class methods.

Buffering with Write BAPIs

Use

To save external systems each having to define their own data, predefined buffering mechanisms should be implemented in all write BAPIs (i.e. BAPIs that create and change data).

For SAP internal use this is particularly relevant for BAPIs developed as of Release 4.6A. If you want to implement a buffer for BAPIs in an earlier release, you should first contact a colleague in the central BAPI development group.

For BAPIs standard R/3 System mechanisms can be used to buffer application data. Data to be created or changed by a BAPI is not created in the update buffer, it is first collected in the global buffer of the BAPI function module group. Then the whole buffer is updated at a specified time.

This has the following advantages:

Improvement in performance of the whole system.The updating of individual operations is delayed and they can all be updated together. Techniques such as "array insert" improve system performance. If buffering is not used, each change must be updated separately.

Page 6: Understanding BAPI

Several changes to an application instanceWith the first change the data is read from the database into the buffer and the change is made in the buffer. With the next change, the system recognizes that the data already exists in the buffer and also makes the change in the buffer. If buffering were not used, the first change would have to be updated before a second change could be made.

Using in Application Link EnablingBAPIs with buffering are especially suited in situations where mass data is exchanged between systems via Application Link Enabling (ALE).The buffering mechanism enables application instances to be processed separately in the ALE layer, while still enabling the instances to be updated together. Unlike multiple BAPIs, such as, SaveReplicaMultiple(), this procedure allows error handling of individual instances.

BAPIs with buffering mean that there is no need to use or implement multiple BAPIs.

Integration

The Transaction Model for BAPIs Without Commit in use since Release 4.0 can be enhanced on the basis of these advantages:

Within one Logical Unit of Work (LUW) several changes or detailed changes can be carried out for one instance.

All changes (to one or more instances) are updated together by the BAPI BapiService.TransactionCommit().

Prerequisites

The buffering mechanism for BAPIs must be implicit, that is, the caller must not have to control the buffering. A calling program must be able to use, for example, a Create()or Change() BAPI with buffering as well as it can use a BAPI without buffering. The buffer is updated implicitly in R/3.

If buffering has been implemented for a business object type, all write BAPIs of this business object type must also be implemented with buffering.If write BAPIs with buffering have been implemented for a business object type, this affects the read BAPIs of this object type. Refer to the information in the Activities section below.

Features

For BAPIs with buffering, in addition to the standard guidelines, the following implementation steps and characteristics described below are required.

Function Modules for Updating the Contents of the Buffer

Page 7: Understanding BAPI

As BAPIs with buffering can only create or change instances in the buffer, you have to provide one or more function modules to carry out the final update of the buffer contents. These update modules transfer the entire contents of the buffer to the update program.

These function modules should not be implemented as BAPIs, as these are only used in the system in which the buffer is also used.The naming convention for these function modules is:_SAVEBUFFER.

Exceptions must not be defined for the update modules, as these are not run until the end of the program, when error handling is no longer possible.

Function Modules for Deleting the Contents of the Buffer

To ensure that the buffer is empty at the start of a transaction, you must provide a function module that deletes the contents of the buffer. This delete function module deletes the entire contents of the buffer and removes any locks on the instances. Neither should you implement this function module as a BAPI, because it is only used in the system in which the buffer is also used.

The naming convention for this function module is:

_CLEARBUFFER.

No exceptions can be defined for delete modules because these are not run until the end of the transaction, when error handling is no longer possible (see Special Characteristics below).

Special Characteristics

BAPIs with buffering need to have special characteristics. For example, these BAPIs must be able to deal with errors because a caller cannot reprocess data in the buffer. As data is buffered implicitly, no administration BAPIs are provided for callers.

Consistency of the Buffer Contents

A BAPI with buffering must carry out all the processing steps, except for updating. The consistency of all instances created or changed in the buffer must be guaranteed by the application.

This means that:

Only operations that can be updated with consistency guaranteed can be carried out in the buffer. The update module itself cannot perform consistency checks.

All other steps required before updating, such as assigning numbers or creating application blocks, must be carried out before calling the update module.

Page 8: Understanding BAPI

For operations that cannot be updated consistently, no action can take place. In these cases the error situation must be reported in the BAPI return parameter.Calling Update Modules

After the buffer operations have been successfully carried out, using the commandPERFORM ON COMMITcall a form routine which then calls the update module(s).The update modules must be called using the commandCALL _SAVEBUFFER IN UPDATE TASKto flag the execution in the update program.

By adding 'ON COMMIT' to the command PERFORM ON COMMIT, updating is not carried out immediately,it is carried out in the next COMMIT WORK. This way any number of BAPI calls can be collected together. The final COMMIT WORK command that is executed via the BAPI BapiService.TransactionCommit(), executes the form routine and also each update module once only. For this reason error handling cannot be performed in this form routine or in the function module.

Subscribing the Delete Module

At the start of each LUW the buffer must be empty. Any instances that may exist in the buffer, which were updated in an earlier LUW, are no longer blocked and may be older than the versions in the database. If this instance is updated again, inconsistencies would result.

At the end of each LUW, the buffer contents must be deleted by calling the delete module. This can only be done by the BAPIs BapiService.TransactionCommit() and BapiService.TransactionRollback(). To supply these BAPIs with the necessary information, BAPIs with buffering must subscribe their delete module for the BAPI BapiService.TransactionCommit() bow. BapiService.TransactionRollback().

The delete module is subscribed by calling the central function module BUFFER_SUBSCRIBE_FOR_REFRESH, whereby the parameter NAME_OF_DELETEFUNC must contain the name of the delete module.

No COMMIT WORK or ROLLBACK WORK CommandBAPIs with buffering must not execute COMMIT WORK or ROLLBACK WORK commands.

Documentation

Each BAPI with buffering must be explicitly documented as such.

Activities

Keep in mind the following important information about how write BAPIs with buffering interact with read BAPIs of the same business object.Write BAPIs with Buffering and Read BAPIs for the Same Business ObjectNo Buffering for Read BAPIs

Page 9: Understanding BAPI

If write BAPIs with buffering are implemented for the same business object type, read BAPIs are not allowed to use the buffer for the same business object type, so that data read from the database can be stored, thereby avoiding further database accesses.

As the imported data is not locked, the corresponding data in the buffer would become outdated over time. Subsequent read operations would first access the buffer and read the potentially out-of-date data, as data in the database can only be read, if this data is not in the buffer.Buffer Instances Are "Real" Instances

All instances created or changed by write BAPIs in the buffer are consistent. They can be used by other change BAPIs for further processing within the same LUW.To guarantee the consistent behavior, all read BAPIs must handle existing instances that are in the buffer, and not yet in the database, as valid instances. Read BAPIs must be implemented in such a way that they first try to read an instance in the buffer and only start searching the database, if the instance is not found in the buffer.

A buffer instance is therefore "real" instance. For example, a BAPI ExistenceCheck() must search for the existence of an instance in the buffer also.Documenting Read BAPIsEach read BAPI that handles the buffering of corresponding write methods must be documented.

Prerequisites

The buffering mechanism for BAPIs must be implicit, that is, the caller must not have to control the buffering. A calling program must be able to use, for example, a Create()or Change() BAPI with buffering as well as it can use a BAPI without buffering. The buffer is updated implicitly in R/3.If buffering has been implemented for a business object type, all write BAPIs of this business object type must also be implemented with buffering.

If write BAPIs with buffering have been implemented for a business object type, this affects the read BAPIs of this object type. Refer to the information in the Activities section below.

Features

For BAPIs with buffering, in addition to the standard guidelines, the following implementation steps and characteristics described below are required.Function Modules for Updating the Contents of the BufferAs BAPIs with buffering can only create or change instances in the buffer, you have to provide one or more function modules to carry out the final update of the buffer contents. These update modules transfer the entire contents of the buffer to the update program.

These function modules should not be implemented as BAPIs, as these are only used in the system in which the buffer is also used.The naming convention for these function modules is:

Page 10: Understanding BAPI

_SAVEBUFFER.

Exceptions must not be defined for the update modules, as these are not run until the end of the program, when error handling is no longer possible (see Special Characteristics below).

Function Modules for Deleting the Contents of the Buffer

To ensure that the buffer is empty at the start of a transaction, you must provide a function module that deletes the contents of the buffer. This delete function module deletes the entire contents of the buffer and removes any locks on the instances. Neither should you implement this function module as a BAPI, because it is only used in the system in which the buffer is also used.

The naming convention for this function module is:

_CLEARBUFFER.No exceptions can be defined for delete modules because these are not run until the end of the transaction, when error handling is no longer possible (see Special Characteristics below).

Special Characteristics

BAPIs with buffering need to have special characteristics. For example, these BAPIs must be able to deal with errors because a caller cannot reprocess data in the buffer. As data is buffered implicitly, no administration BAPIs are provided for callers.

Consistency of the Buffer Contents

A BAPI with buffering must carry out all the processing steps, except for updating. The consistency of all instances created or changed in the buffer must be guaranteed by the application.

This means that:• Only operations that can be updated with consistency guaranteed can be carried out in the buffer. The update module itself cannot perform consistency checks.• All other steps required before updating, such as assigning numbers or creating application blocks, must be carried out before calling the update module.• For operations that cannot be updated consistently, no action can take place. In these cases the error situation must be reported in the BAPI return parameter.Calling Update Modules

After the buffer operations have been successfully carried out, using the commandPERFORM ON COMMITcall a form routine which then calls the update module(s).The update modules must be called using the commandCALL _SAVEBUFFER IN UPDATE TASKto flag the execution in the update program.

Page 11: Understanding BAPI

By adding 'ON COMMIT' to the command PERFORM ON COMMIT, updating is not carried out immediately,it is carried out in the next COMMIT WORK. This way any number of BAPI calls can be collected together. The final COMMIT WORK command that is executed via the BAPI BapiService.TransactionCommit(), executes the form routine and also each update module once only. For this reason error handling cannot be performed in this form routine or in the function module.Subscribing the Delete ModuleAt the start of each LUW the buffer must be empty. Any instances that may exist in the buffer, which were updated in an earlier LUW, are no longer blocked and may be older than the versions in the database. If this instance is updated again, inconsistencies would result.

At the end of each LUW, the buffer contents must be deleted by calling the delete module. This can only be done by the BAPIs BapiService.TransactionCommit() and BapiService.TransactionRollback(). To supply these BAPIs with the necessary information, BAPIs with buffering must subscribe their delete module for the BAPI BapiService.TransactionCommit() bzw. BapiService.TransactionRollback().The delete module is subscribed by calling the central function module BUFFER_SUBSCRIBE_FOR_REFRESH, whereby the parameter NAME_OF_DELETEFUNC must contain the name of the delete module.No COMMIT WORK or ROLLBACK WORK Command

BAPIs with buffering must not execute COMMIT WORK or ROLLBACK WORK commands.

Documentation

Each BAPI with buffering must be explicitly documented as such.

Activities

Keep in mind the following important information about how write BAPIs with buffering interact with read BAPIs of the same business object.Write BAPIs with Buffering and Read BAPIs for the Same Business ObjectNo Buffering for Read BAPIs

If write BAPIs with buffering are implemented for the same business object type, read BAPIs are not allowed to use the buffer for the same business object type, so that data read from the database can be stored, thereby avoiding further database accesses.

As the imported data is not locked, the corresponding data in the buffer would become outdated over time. Subsequent read operations would first access the buffer and read the potentially out-of-date data, as data in the database can only be read, if this data is not in the buffer.

Buffer Instances Are "Real" Instances

All instances created or changed by write BAPIs in the buffer are consistent. They can be used by other change BAPIs for further processing within the same LUW.To guarantee the consistent behavior, all read BAPIs must handle existing instances that are in the

Page 12: Understanding BAPI

buffer, and not yet in the database, as valid instances. Read BAPIs must be implemented in such a way that they first try to read an instance in the buffer and only start searching the database, if the instance is not found in the buffer.

A buffer instance is therefore "real" instance. For example, a BAPI ExistenceCheck() must search for the existence of an instance in the buffer also.Documenting Read BAPIs

Each read BAPI that handles the buffering of corresponding write methods must be documented.

Defining a BAPI and Its Interface

Purpose

After you have carried out the review of the BAPI concept and it has been accepted, you can start defining the BAPI itself.

In this step, you will decide on the names, parameters, and characteristics of the BAPI and determine the structures in the ABAP Dictionary, which the BAPI will be based on. Only after you have planned and defined these required details can you start to implement the BAPI and create the required programming objects.

The table below illustrates where the planned information is written and how it fits together.

Information in the BOR, Function Builder and ABAP Dictionary

Standardized BAPIs

Use

Some BAPIs and methods provide basic functions and can be used for most SAP business object types. Such BAPIs are known as "standardized" BAPIs.

Features

With object methods and especially with BAPIs, you can differentiate between instance methods and class methods. Instance methods refer to precisely one instance (one specific occurrence) of an SAP Business Object type, for example, to one explicitly specified customer order. Whereas class methods are instance-independent.

BAPIs for Reading Data

The following BAPIs provide you with read-only access to data in the associated business object type:

Page 13: Understanding BAPI

GetList()With the BAPI GetList() you can select a range of object key values, for example, company codes and material numbers. The BAPIs GetList() is a class method.

Programming GetList() BAPIs

Use

With the BAPI GetList() you can select a range of object key values, for example, company codes and material numbers. The key values returned by this BAPI can be passed on to another BAPI for further processing, for example, the BAPI GetDetail().The BAPIs GetList() is a class method (instance-independent).

Features

Provide all the relevant fields in the interface of the GetList() BAPI. How complex and extensive you structure the interface, depends on the requirements the BAPI is to fulfill.

Import Parameters

The interface of a GetList() BAPI must provide selection parameters, in which the required selection criteria can be passed on by the calling program. The structure of selection parameters is described in the section Selection Parameters.

You must also create the parameter MaxRows that enables you to limit the number of entries selected. This parameter prevents too large a value set from being selected, if the selection parameter specification is not very precise. Use the data element BAPIMAXROW as the reference type for the MaxRows parameter.

Export Parameters

The key values selected by the BAPI GetList() are returned to the calling program in a table, together with other useful information, for example, short texts.To report messages from the method call back to the calling program, you should create the export parameter RETURN. For more information about this parameter seeReturn Parameters (Error Handling).

Extension parameters

You can create extension parameters to enable customers to enhance the functionality of BAPIs without making modifications. For information about extension parameters see Customer Enhancement Concept for BAPIs.

GetDetail()The BAPI GetDetail() uses a key to retrieve details about an instance (one specific

Page 14: Understanding BAPI

occurrence) of a business object type and returns this data to the calling program. Then this information is reported back to the calling program. The BAPI GetDetail() is an instance method.

Programming GetDetail() BAPIs

Use

The BAPI GetDetail() is used to read details of specific object instances.The BAPI GetDetail() is an instance method.

Features

Import Parameters

The import parameters of the GetDetail() BAPI must contain the key fields of the business object type.

For the associated method definition in the BOR, the key fields must not also be specified as method parameters. For this reason, the BOR/BAPI Wizard does not include the function module parameters for the key fields in the method definition, when it creates a BAPI.

Export Parameters

The export parameters of a BAPI contain details of the instance. According to the amount of information, this should be structured in several parameters with meaningful names.

To report messages from the method call back to the calling program, you should create the export parameter Return. For more information about this parameter see Return Parameters (Error Handling).

Extension Parameters

You can create extension parameters to enable customers to enhance the functionality of BAPIs without making modifications. For information about extension parameters see Customer Enhancement Concept for BAPIs.

GetStatus()

The BAPI GetStatus() is used to query the status of an SAP business object instance, for example, the processing status of a sales order. This BAPI is used only for displaying the status of an object and does not retrieve full details like the BAPI GetDetail(). The BAPI GetStatus() is an instance method.

Programming GetStatus() BAPIs

Page 15: Understanding BAPI

Use

With the BAPI GetStatus() you can retrieve information about the status of a particular object instance.The BAPI GetStatus() is an instance method.

Features

Import ParametersThe import parameters of the GetStatus() BAPI must contain the key fields of the business object type.

For the associated method definition in the BOR, the key fields must not also be specified as parameters. For this reason, the BOR/BAPI Wizard does not include the function module parameters for the key fields in the method definition, when it creates a BAPI.

Export Parameters

The export parameters of the BAPI contain information about the status of an object instance.

To report messages from the method call back to the calling program, you should create the export parameter RETURN. For more information about this parameter see Return Parameters (Error Handling).

Extension Parameters

You can create extension parameters to enable customers to enhance the functionality of BAPIs without making modifications. For information about extension parameters see Customer Enhancement Concept for BAPIs.

ExistenceCheck()

The BAPI ExistenceCheck() checks whether an entry exists for a business object instance, for example, whether the customer master has been created. The ExistenceCheck() BAPI is an instance method.

Programming ExistenceCheck() BAPIs

Use

The BAPI ExistenceCheck() checks whether an entry exists in the database for an SAP business object type, for example, whether the customer master has been created.The ExistenceCheck() BAPI is an instance method.

Page 16: Understanding BAPI

Features

You can implement this method as a BAPI and/or as a method of SAP Business Workflow. If you implement this method as a BAPI, it only has to be implemented once, because an ExistenceCheck() BAPI can also be used by SAP Business Workflow.

To get the highest possible performance from the BAPI ExistenceCheck(), you should reduce the number of columns to as few as possible before selecting the table rows.select single bukrs from bkpf into lv_bukrswhere bukrs = bkpf-bukrsand belnr = bkpf-belnrand gjahr = bkpf-gjahr.instead ofselect single * from bkpfwhere bukrs = bkpf-bukrsand belnr = bkpf-belnrand gjahr = bkpf-gjahr.

Import Parameters

The BAPI's import parameters in the function module only contain the key fields of the business object type.

Export Parameters

To report messages from the method call back to the calling program, you should create only the export parameter Return . For more information about this parameter see Return Parameters (Error Handling).

Activities

When a business object type is created, as the default, it inherits a definition of the method ExistenceCheck() through the interface IFSAP. For this reason, you can create an ExistenceCheck() BAPI using the BOR/BAPI Wizard, as the method name ExistenceCheck() already exists for the business object type.

We recommend therefore, that you redefine the existing method ExistenceCheck() manually in the BOR, via the menu path Edit Redefine.

• Enter the function module that implements the ExistenceCheck() BAPI.• Create the method parameter RETURN (the key fields of the business object type are not included in the method definition in the BOR).

BAPIs for Creating or Changing Data

Page 17: Understanding BAPI

The following BAPIs can create, change or delete instances of a business object type:Create() or CreateFromData()The BAPI Create() or CreateFromData() creates an instance of an SAP business object type, for example, a purchase order. These BAPIs are class methods.

Programming Create() BAPIs

Use

The BAPI Create() creates one instance of an SAP business object type. Likewise, the BAPI CreateMultiple() creates several instances of a business object type simultaneously.

If a workflow method called Create already exists for the business object type in question, you can use the name CreateFromData() for your BAPI. Create() is the preferred name for this BAPI.

The BAPIs Create() and CreateMultiple() are class methods (instance-independent).For each Create() BAPI a method must be provided with which the created business object instance can be deleted or cancelled. To do this, depending on the business application practice, you should implement one of the BAPIs below:

• Delete(), which deletes a business object instance from the database. For more information see Programming Delete() BAPIs.• Cancel() which cancels a business object instance. For more information see Programming Cancel() BAPIs.

Features

Import Parameters

The BAPI's import parameters in the function module contain the data required to uniquely identify an instance. For this you can either enter all object keys or else you must ensure that these can be derived.

If required, you can also use a test run parameter to check the entry for an object instance before actually creating the instance in the database. For further information see Test Run Parameters.

You can create a change parameter to identify the values to create the instance with and to tell differentiate these values from the initial values when the BAPI is called. We recommend that you identify the change-relevant fields by flagging them.For more information see Change Parameters.

Export Parameters

Page 18: Understanding BAPI

To make the object key available to the calling program, the entire key fields must be returned in the export parameters.To report messages from the method call back to the calling program, you should create the export parameter RETURN. For more information about this parameter see Return Parameters (Error Handling).

Extension parameters

You can create extension parameters to enable customers to enhance the functionalityof BAPIs without making modifications. For information about extension parameters see Customer Enhancement Concept for BAPIs.Avoiding Incompatibilities with Customizing SettingsIt could be possible that certain values set by Customizing appear differently in the BAPI interface. These values cannot be overwritten by a Create() BAPI.To avoid any incompatibility with Customizing settings, you should implement a Create() BAPI in the following way:

• The BAPI should transfer all the fields and check them against the Customizing settings. If the Customizing settings write-protect a field, the data in this field cannot be overwritten by data in the BAPI interface.• For every incidence of incompatibility an error message must be returned to the calling program. For example, "Customizing settings do not allow the field 'MyAsset-AssetName' to be modified ".• All the fields that are assigned default values by Customizing and are therefore write-protected, must be documented.

External Key AssignmentFor Create() BAPIs with an external key assignment the caller transfers the key (ID) to the object instance to be created, for example, to a document number.Keep in mind that you have to convert the specified keys explicitly in upper case letters in the source code of this type of Create() BAPIs. Otherwise keys are created that cannot be used in dialog applications. This is because with dialog applications external keys are always converted implicitly in upper case letters.

Locking

We recommend that you implement Create() BAPIs without the locking function and create your own BAPIs instead that lock the relevant data.

Change()The BAPI Change() changes an existing instance of a SAP business object type, for example, a purchase order. The Change() BAPI is an instance method.

Page 19: Understanding BAPI

Programming Change() BAPIs

Use

The BAPI Change() changes an existing instance of an SAP business object type, for example, a sales order.

The BAPI Change() is an instance method, whereas the BAPI ChangeMultiple() is a class method (instance-independent).

Features

Import Parameters

The import parameters of the Change() BAPI must contain the key fields of the business object type.

If required, you can create also create these parameters:• A test run parameter for checking the entry for an object instance before actually creating/changing the instance in the database.• A change parameter to identify parameter fields containing modified values and parameter fields that have not been modified.For more information about these parameters see Standardized Parameters.Export ParametersTo make the object key available to the calling program, the entire key fields must be returned in the export parameters.To report messages from the method call back to the calling program, you should create the export parameter RETURN. For more information about this parameter see Return Parameters (Error Handling).Extension parametersYou can create extension parameters to enable customers to enhance the functionality of BAPIs without making modifications. For information about extension parameters see Customer Enhancement Concept for BAPIs.Avoiding Incompatibilities with Customizing SettingsIt could be possible that certain values set by Customizing appear differently in the BAPI interface. These values cannot be overwritten by a Change() BAPI.

To avoid incompatibility with Customizing settings, you should implement a Change() BAPI in the following way:

• The BAPI should transfer all the fields and check them against the Customizing settings. If the Customizing settings write-protect a field, the data in this field cannot be overwritten by data in the BAPI interface.• For every incidence of incompatibility an error message must be returned in the return parameter to the calling program. For example, "Customizing settings do not allow the field

Page 20: Understanding BAPI

'MyAsset-AssetName' to be modified ".• All the fields that are assigned default values by Customizing and are therefore write-protected, must be documented.

Locking

We recommend that you implement Change() BAPIs without the locking function and create your own BAPIs instead that lock the relevant data.

Delete() and Undelete()The BAPI Delete() deletes an instance of an SAP business object type from the database, for example, a purchase order.The BAPI Undelete() removes a deletion flag.These BAPIs are instance methods.

Programming Delete() BAPIs

Use

The BAPI Delete() deletes an instance of an SAP business object type from the database. Likewise, the BAPI DeleteMultiple() deletes several instances of a business object type. Delete() BAPIs must always delete entire instances, for example, a whole material master.

(Whereas the BAPI Cancel() cancels an instance of a business object, that is the instance to be cancelled remains in the database and an additional instance is created that is canceled. For more information see Programming Cancel() BAPIs).

A delete() BAPI can delete immediately or at a later time by setting the deletion flag. The type of deletion you use in your BAPI is irrelevant to the caller, so you do not have to include these details in the BAPI interface.

The BAPI Undelete() is used to reset a deletion flag that has been set for a specific object.

The BAPIs Delete() and Undelete() are instance methods, whereas the BAPIs DeleteMutliple() and UndeleteMutliple() are class methods (instance-independent).

Features

The interfaces of the Delete() and Undelete() BAPIs should be identical.Import ParametersThe BAPI's import parameters have to identify the business object instances to be deleted.

• If an instance is to be deleted, you have to create a parameter for each key field in the business object type.• If several instances are to be deleted, you must create a table for the key fields of the

Page 21: Understanding BAPI

business object type. You can do this using a range table.If required, you can create also create these parameters:• A test run parameter for checking the entry for an object instance before actually deleting the instance from the database.• When the BAPI DeleteMultiple() is used, it must be possible to use the selection criteria to select the object instances to be deleted. To do this you can create selection parameters.

Implement the interface of a Delete() BAPI so that it is not possible to delete all the instances simply by parameterizing the interface, for example by specifying default settings.

Export Parameters

To report messages from the method call back to the calling program, you should create only the export parameter Return . For more information about this parameter see Return Parameters (Error Handling).

Extension parameters

You can create extension parameters to enable customers to enhance the functionality of BAPIs without making modifications. For information about extension parameters see Customer Enhancement Concept for BAPIs.

Locking

We recommend that you implement Delete() BAPIs without the locking function and create your own BAPIs instead that lock the relevant data.

Cancel()Unlike the BAPI Delete () the BAPI Cancel() cancels an instance of a business object, that is the instance to be cancelled remains in the database and an additional instance is created that is canceled).The Cancel() BAPI is an instance method.

Programming Cancel() BAPIsUseThe Cancel() BAPI cancels one instance of a business object.Unlike the BAPI Delete(), which deletes an object instance from the database, with the BAPI Cancel():

• The canceled instance of the business object is not deleted• An additional instance is created with which the instance of the business object is deletedThe Cancel() BAPI is used to cancel business processes such as goods movements or invoice

Page 22: Understanding BAPI

receipts.The Cancel() BAPI is an instance method.

Features

Import Parameters

The data of the instance to be created comes from the data of the business object instance to be cancelled.

You can also create further parameters to specify information relevant for the actual cancellation process, for example, the name of the user performing the cancellation.

If required, you can also create a test run parameter, which can check the details of the object instance before it is actually canceled. For more information about this parameter see Test Run Parameters.

Export Parameters

To report messages from the method call back to the calling program, you should create the parameter Return. For more information about this parameter see Return Parameters (Error Handling).You have to put the key of the created instance in another export parameter.LockingWe recommend that you implement Cancel() BAPIs without the locking function and create your own BAPIs instead that lock the relevant data.

Add and RemoveThe BAPI Add adds a sub-object to an existing object instance and the BAPI and Remove removes a sub-object from an object instance. These BAPIs are instance methods.

http://careerabap.blogspot.in/2010/12/real-time-example-on-using-bapi.htmlBAPI Step by Step ExampleWritten by Henrik Frank

See our ABAP Tips and Tricks Database

Contributed by Henrik Frank

1. About the Example

2. STEP 1 - Define a structures for the BAPI

3. STEP 2 - Write Function Module

4. STEP 3 - Create the API Method Using the BAPI WIZARD

5. STEP 4 - Final steps

About the exampleThis BAPI reads system status for a production order from table JEST and system status text from table TJ02T

Page 23: Understanding BAPI

Name ZGetOrderStatus

Function group ZBAPISTATUS

Function module: Z_BAPI_GET_ORDER_STATUS

Import parameters:

ORDER_STATUS_IMPORT type ZBAPI_ORDER_STATUS_IMPORT:

AUFNR Order number (Keyfield) SPRAS Language ExcludeInactive - Checkbox - Exclude inactive

status

Tables T_BAPISTAT type ZBAPISTAT:

OBJNR like JEST-OBJNR STAT like JEST-STAT INACT like JEST-INACT TXT04 like TJ02T-TXT04 TXT30 likeTJ02T-TXT30

Export parameters

RETURN like BAPIRETURN

STEP 1 - DEFINE A STRUCTURES FOR THE BAPI

In this step a structures for the parameters and tables of the function module used for the BAPI are defined.

Use Data type -> Structure

Define the following structures:

ZBAPI_ORDER_STATUS_IMPORT which contains the following fields:

ORDERID Order number (Keyfield) SPRAS Language ExcludeInactive - Checkbox - Exclude inactive status

ZBAPISTAT:

OBJNR like JEST-OBJNR

STAT like JEST-STAT INACT like JEST-INACT TXT04 like TJ02T-TXT04 TXT30 likeTJ02T-TXT30

Important note:

You will have to define a structure for every parameter in the BAPI. You cannot use the same structures used in existing applications because BAPI structures are frozen when BAPIs are released and then there are restrictions on changing them.

Page 24: Understanding BAPI

ZBAPI_ORDER_STATUS_IMPORT 

ZBAPISTAT

STEP 2 - WRITE FUNCTION MODULE

Important notes:

Each BAPI must have its own function group.

Page 25: Understanding BAPI

Under the attributes tab remember to select Processing Type Remote Enabled module, otherwise the function module cannot be invoked via RFC and used as a BAPI

Import/Export parameters can only be BY VALUE for an RFC enabled function module We are only creating one BAPI in this example, but you can create related BAPIs in the same function pool,

so they will be able to share global data.

Attributes 

Import Parameters

Export Parameters

Page 26: Understanding BAPI

  

Tables  

CodeNotes:

The subroutine SET_RETURN_MESSAGE is a standard routine used for BAPIs that use the BAPIRETURN structure

Page 27: Understanding BAPI

In form Z_BAPI_GET_ORDER_SYSTEM_STATUS there is a test IF 1 = 2. If the test is true a message is displayed. The condition will obviously never be true, and we will never want to display a message in a BAPI. The reason why it is included is, that it create a reference for the message, so that the WHERE USED functionality can be used for the message. This is the SAP standard way to handle it, copied from the Company Code GetList BAPI.

INCLUDE LZBAPISTATUSUXX

*************************************************   THIS FILE IS GENERATED BY THE FUNCTION LIBRARY.**   NEVER CHANGE IT MANUALLY, PLEASE!              ***************************************************INCLUDE LZBAPISTATUSU02.                    "Z_BAPI_GET_ORDER_SYSTEM_STATUSINCLUDE LZBAPISTATUSTOP - Global dataFUNCTION-POOL ZBAPISTATUS.                  "MESSAGE-ID Z3Types:  begin of Type_tj02t,    istat  like tj02t-istat,    txt04  like tj02t-txt04,    txt30  like tj02t-txt30,  end of type_tj02t.DATA:* Declarations for TABLE parameter  T_BAPISTAT like ZBAPISTAT occurs 0,  G_BAPISTAT like ZBAPISTAT,* Table for object texts  t_tj02t    type type_tj02t occurs 0,  g_tj02t    type type_tj02t.* Structure for return messagesDATA:  BEGIN OF MESSAGE,    MSGTY LIKE SY-MSGTY,    MSGID LIKE SY-MSGID,    MSGNO LIKE SY-MSGNO,    MSGV1 LIKE SY-MSGV1,    MSGV2 LIKE SY-MSGV2,    MSGV3 LIKE SY-MSGV3,    MSGV4 LIKE SY-MSGV4,  END OF MESSAGE.INCLUDE LZBAPISTATUSF01 - Subroutines***INCLUDE LZBAPISTATUSF01 .*----------------------------------------------------------------------**&---------------------------------------------------------------------**&      Form  SET_RETURN_MESSAGE*&---------------------------------------------------------------------** This routine is used for setting the BAPI return message.* The routine is a standard routine for BAPIs that handles the message* structure for the BAPIRETURN structure. It has been copied from the* BAPI Company Code Getlist*----------------------------------------------------------------------**      -->P_MESSAGE  text*      <--P_RETURN  text*----------------------------------------------------------------------*form SET_RETURN_MESSAGE

Page 28: Understanding BAPI

USING    VALUE(P_MESSAGE)   LIKE MESSAGE                        CHANGING P_RETURN  LIKE BAPIRETURN.  CHECK NOT MESSAGE IS INITIAL.  CALL FUNCTION 'BALW_BAPIRETURN_GET'       EXPORTING            TYPE       = P_MESSAGE-MSGTY            CL         = P_MESSAGE-MSGID            NUMBER     = P_MESSAGE-MSGNO            PAR1       = P_MESSAGE-MSGV1            PAR2       = P_MESSAGE-MSGV2            PAR3       = P_MESSAGE-MSGV3            PAR4       = P_MESSAGE-MSGV4*          LOG_NO     = ' '*          LOG_MSG_NO = ' '       IMPORTING            BAPIRETURN = P_RETURN       EXCEPTIONS            OTHERS     = 1.endform.                    " SET_RETURN_MESSAGEFUNCTION Z_BAPI_GET_ORDER_STATUSFUNCTION z_bapi_get_order_system_status.*"----------------------------------------------------------------------*"*"Local interface:*"  IMPORTING*"     VALUE(I_AUFNR) TYPE  AUFNR*"     VALUE(I_SPRAS) TYPE  SPRAS DEFAULT SY-LANGU*"     VALUE(I_EXCLUDEINACTIVE) TYPE  CHAR1 OPTIONAL*"  EXPORTING*"     VALUE(RETURN) TYPE  BAPIRETURN*"  TABLES*"      T_BAPISTAT STRUCTURE  ZBAPISTAT*"---------------------------------------------------------------------- DATA:   l_aufnr LIKE afko-aufnr,   l_objnr LIKE jest-objnr.****************************** Check if order exists*****************************SELECT SINGLE aufnr    FROM afko    INTO  l_aufnr    WHERE aufnr = BAPI_ORDER_STATUS_IMPORT-orderid.  IF sy-subrc NE 0.    CLEAR message.    message-msgty = 'E'.    message-msgid = 'Z3'.    message-msgno = '000'.    message-msgv1 = BAPI_ORDER_STATUS_IMPORT-orderid.    PERFORM set_return_message USING    message                               CHANGING return.    IF 1 = 2.*     The only reason to include this statement, that will obviously*     never execute, is that it will create a referecence so that you*     can find out where a particular message

Page 29: Understanding BAPI

is being used. This*     functionality is used by the BAPIs programmed by SAP      MESSAGE e000(z3).    ENDIF.  ENDIF.  CHECK return IS INITIAL.********************************************* Read order status********************************************CONCATENATE 'OR' BAPI_ORDER_STATUS_IMPORT-orderid INTO l_objnr.  IF BAPI_ORDER_STATUS_IMPORT-i_excludeinactive = 'X'.    SELECT objnr stat inact      FROM  jest      INTO  TABLE t_bapistat      WHERE objnr = l_objnr AND            inact <> 'X'.  ELSE.    SELECT objnr stat inact      FROM  jest      INTO  TABLE t_bapistat      WHERE objnr = l_objnr.  ENDIF.  IF sy-subrc <> 0.*   No object status found    CLEAR message.    message-msgty = 'E'.    message-msgid = 'Z3'.    message-msgno = '001'.    message-msgv1 = BAPI_ORDER_STATUS_IMPORT-orderid.    PERFORM set_return_message USING    message                               CHANGING return.    IF 1 = 2.      MESSAGE e001(z3).    ENDIF.  ENDIF.  CHECK return IS INITIAL.

********************************************* Read order status texts********************************************  SELECT istat txt04 txt30    FROM tj02t    INTO TABLE t_tj02t    FOR ALL ENTRIES IN t_bapistat    WHERE istat = t_bapistat-stat AND          spras = BAPI_ORDER_STATUS_IMPORT-i_spras.

  SORT t_tj02t BY istat.

  LOOP AT t_bapistat INTO g_bapistat.    READ TABLE t_tj02t      WITH KEY istat = g_bapistat-stat BINARY SEARCH     INTO g_tj02t.    IF sy-subrc = 0.      MOVE:

Page 30: Understanding BAPI

        g_tj02t-txt04 TO g_bapistat-txt04,        g_tj02t-txt30 TO g_bapistat-txt30.      MODIFY t_bapistat FROM g_bapistat TRANSPORTING txt04 txt30.    ENDIF. ENDLOOP.ENDFUNCTION.

STEP 3 - CREATE THE API METHOD USING THE BAPI WIZARD

The BAPI wizard is used toTo expose the remote function module as a BAPI. The wizard will generate some additional code, so the function module is a valid method of the BOR. This allows the BAPi to be called as a workflow method in addition to be called by an outside program.

Note:

Each function module corresponds to a method in the BORGo to the Business Object Builder SWO1.

You can either create the new Object type as a subtype of an existing business object or create a new business object from scratch. In this example it would be obvious to create the Object type as a subtype of BUS2005 Production order. However, to illustrate how to create a new Object type from scratch, we will do this.

In the Object/Interface type field write the name of the new Business Object: ZORDERSTAT. Press enter and fill in the additional fields necessary to create the object type.

Supertype: Not relevant because we are creating our object from scratch

Program. This is the name of the program where the wizard generates code for the Object type, NOT the function module we created earlier. The program name must not be the name of an existing program.

Page 31: Understanding BAPI

Press enter and create the new business object. Note that when you create the business object a standard interface, an attribute ObjectType and the methods ExistenceCheck and Display are automatically generated. These cannot be changed !

The next step is to add the Z_BAPI_GET_ORDER_STATUS method to the business object. Select Utilities -> API methods -> Add method and write the name of the function module in the dialog box. Next the dialog ox show below will be shown. This is the start screen of the BAPI wizard. Proceed with wizard by pressing the  button.

Page 32: Understanding BAPI

After you have finished the wizard, you will notice that the ZGetOrderStatus has been added to the business object:

You can double-click on the method to see its properties. To use the business object you must change the Object type status to Implemented. Use menu Edit->Change releases status->Object type->To implemented. No you can test the object (Press F8).

Note that the BAPI wizard has added a wrapper class for the function module so it can be sued as method in the business object. Choose menu Goto->Program to display the program:

*****           Implementation of object type ZORDERSTAT           *****INCLUDE <OBJECT>.BEGIN_DATA OBJECT. " Do not change.. DATA is generated* only private members may be inserted into structure privateDATA:" begin of private,"   to declare private attributes remove comments and"   insert private attributes here ..." end of private,      KEY LIKE SWOTOBJID-OBJKEY.END_DATA OBJECT. " Do not change.. DATA is generated

BEGIN_METHOD ZGETORDERSTATUS CHANGING CONTAINER.DATA:      BAPIORDERSTATUSIMPORT LIKE ZBAPI_ORDER_STATUS_IMPORT,      RETURN LIKE BAPIRETURN,      TBAPISTAT LIKE ZBAPISTAT OCCURS 0.  SWC_GET_ELEMENT CONTAINER 'BapiOrderStatusImport'       BAPIORDERSTATUSIMPORT.  SWC_GET_TABLE CONTAINER 'TBapistat' TBAPISTAT.  CALL FUNCTION 'Z_BAPI_GET_ORDER_STATUS'    EXPORTING

Page 33: Understanding BAPI

      BAPI_ORDER_STATUS_IMPORT = BAPIORDERSTATUSIMPORT    IMPORTING      RETURN = RETURN    TABLES      T_BAPISTAT = TBAPISTAT    EXCEPTIONS      OTHERS = 01.  CASE SY-SUBRC.    WHEN 0.            " OK    WHEN OTHERS.       " to be implemented  ENDCASE.  SWC_SET_ELEMENT CONTAINER 'Return' RETURN.  SWC_SET_TABLE CONTAINER 'TBapistat' TBAPISTAT.END_METHOD.

STEP 4 - FINAL STEPS

When the Business object has been checked and the documentation created, the following steps must be carried out:

Release the BAPI function module (in the Function Builder).

Release the business object type (in the BOR ObjectType -> Change release status to -> Implemented ).

Release the BAPI as a method in the BOR (Release the methods you has created - Set the cursor on the method thenEdit -> Change release status -> Object type component -> To released )

For potential write BAPIs: Release the IDoc and its segments

You can now display the BAPI in the BAPI Explorer:

Page 34: Understanding BAPI

A real-time example on using BAPI (Complete program)

Please note that there are some custom fields added in the VBAP table, custom message class and

custom include program used in this program. Unfortunately, the contributor couldn't provide us with the

functional/technical specifications for this program.

REPORT ZAUTO_DEBIT_VENDOR NO STANDARD PAGE HEADING LINE-SIZE 250 LINE-COUNT 65(2) MESSAGE-ID ZSCM.

************************************************************************* Program name : ZAUTO_DEBIT_VENDOR* Type : Report* Description : Automatic Vendor Dedit Postings************************************************************************

*---------------------------------------------------------------------** TABLES*---------------------------------------------------------------------*TABLES: VBAK, ADR6, TRDYSE01CM.

*---------------------------------------------------------------------** INCLUDE*---------------------------------------------------------------------*INCLUDE ZZUTI_STD_HEADER_FOOTER. "Standard header and footer

Page 35: Understanding BAPI

*----------------------------------------------------------------------** TYPES DECLARATION*----------------------------------------------------------------------*TYPES: BEGIN OF T_CRMEMO, VBELN TYPE VBAK-VBELN, POSNR TYPE VBAP-POSNR, ERDAT TYPE VBAK-ERDAT, AUART TYPE VBAK-AUART, AUGRU TYPE VBAK-AUGRU, WAERK TYPE VBAK-WAERK, VKORG TYPE VBAK-VKORG, VTWEG TYPE VBAK-VTWEG, SPART TYPE VBAK-SPART, VDATU TYPE VBAK-VDATU, BSTNK TYPE VBAK-BSTNK, BSARK TYPE VBAK-BSARK, BSTDK TYPE VBAK-BSTDK, AEDAT TYPE VBAK-AEDAT, BUKRS_VF TYPE VBAK-BUKRS_VF, MATNR TYPE VBAP-MATNR, ZMENG TYPE VBAP-ZMENG, ZIEME TYPE VBAP-ZIEME, END OF T_CRMEMO,

BEGIN OF T_CRMEMO_CHANGE, VBELN(90) TYPE C, POSNR TYPE VBAP-POSNR, ERDAT TYPE VBAK-ERDAT, AUART TYPE VBAK-AUART, AUGRU TYPE VBAK-AUGRU, WAERK TYPE VBAK-WAERK, VKORG TYPE VBAK-VKORG, VTWEG TYPE VBAK-VTWEG, SPART TYPE VBAK-SPART, VDATU TYPE VBAK-VDATU, BSTNK TYPE VBAK-BSTNK, BSARK TYPE VBAK-BSARK, BSTDK TYPE VBAK-BSTDK, AEDAT TYPE VBAK-AEDAT, BUKRS_VF TYPE VBAK-BUKRS_VF, MATNR TYPE VBAP-MATNR, ZMENG TYPE VBAP-ZMENG, ZIEME TYPE VBAP-ZIEME, END OF T_CRMEMO_CHANGE,

BEGIN OF T_MVKE, MATNR TYPE MVKE-MATNR, VKORG TYPE MVKE-VKORG, VTWEG TYPE MVKE-VTWEG, MTPOS TYPE MVKE-MTPOS, END OF T_MVKE,

BEGIN OF T_ORDERS, VBELV TYPE VBFA-VBELV, POSNV TYPE VBFA-POSNV,

Page 36: Understanding BAPI

VBELN TYPE VBFA-VBELN, POSNN TYPE VBFA-POSNN, VBTYP_N TYPE VBFA-VBTYP_N, END OF T_ORDERS,

BEGIN OF T_EKPO, EBELN TYPE EKKO-EBELN, EBELP TYPE EKPO-EBELP, WAERS TYPE EKKO-WAERS, MENGE TYPE EKPO-MENGE, MEINS TYPE EKPO-MEINS, NETPR TYPE EKPO-NETPR, PEINH TYPE EKPO-PEINH, mwskz TYPE EKPO-mwskz, TXJCD TYPE EKPO-TXJCD, END OF T_EKPO,

BEGIN OF T_EKBE, EBELN TYPE EKBE-EBELN, EBELP TYPE EKBE-EBELP, ZEKKN TYPE EKBE-ZEKKN, VGABE TYPE EKBE-VGABE, GJAHR TYPE EKBE-GJAHR, BELNR TYPE EKBE-BELNR, BUZEI TYPE EKBE-BUZEI, END OF T_EKBE,

BEGIN OF T_RBKP, BELNR TYPE RBKP-BELNR, GJAHR TYPE RBKP-GJAHR, BLDAT TYPE RBKP-BLDAT, BUDAT TYPE RBKP-BUDAT, XBLNR TYPE RBKP-XBLNR, LIFNR TYPE RBKP-LIFNR, RMWWR TYPE RBKP-RMWWR, WMWST1 TYPE RBKP-WMWST1, XRECH TYPE RBKP-XRECH, STBLG TYPE RBKP-STBLG, END OF T_RBKP,

BEGIN OF T_CDHDR, OBJECTCLAS TYPE CDHDR-OBJECTCLAS, OBJECTID TYPE CDHDR-OBJECTID, CHANGENR TYPE CDHDR-CHANGENR, UDATE TYPE CDHDR-UDATE, UTIME TYPE CDHDR-UTIME, END OF T_CDHDR,

BEGIN OF T_CDPOS, OBJECTCLAS TYPE CDHDR-OBJECTCLAS, OBJECTID TYPE CDHDR-OBJECTID, CHANGENR TYPE CDHDR-CHANGENR, TABNAME TYPE CDPOS-TABNAME, TABKEY TYPE CDPOS-TABKEY, FNAME TYPE CDPOS-FNAME, CHNGIND TYPE CDPOS-CHNGIND,

Page 37: Understanding BAPI

VALUE_NEW TYPE CDPOS-VALUE_NEW, VALUE_OLD TYPE CDPOS-VALUE_OLD, END OF T_CDPOS,

BEGIN OF T_CHANGE_DOCS, OBJECTCLAS TYPE CDHDR-OBJECTCLAS, OBJECTID TYPE CDHDR-OBJECTID, CHANGENR TYPE CDHDR-CHANGENR, UDATE TYPE CDHDR-UDATE, UTIME TYPE CDHDR-UTIME, TABNAME TYPE CDPOS-TABNAME, TABKEY TYPE CDPOS-TABKEY, FNAME TYPE CDPOS-FNAME, CHNGIND TYPE CDPOS-CHNGIND, VALUE_NEW TYPE CDPOS-VALUE_NEW, VALUE_OLD TYPE CDPOS-VALUE_OLD, END OF T_CHANGE_DOCS,

BEGIN OF T_SUCCESS, crmemo TYPE VBAK-vbeln, cmemo TYPE VBAK-vbeln, orders TYPE VBAK-vbeln, po TYPE VBAK-vbeln, miro_no TYPE VBAK-vbeln, text(20) TYPE C, END OF T_SUCCESS,

BEGIN OF T_ERROR, crmemo TYPE VBAK-vbeln, cmemo TYPE VBAK-vbeln, orders TYPE VBAK-vbeln, po TYPE VBAK-vbeln, miro_no TYPE VBAK-vbeln, text(100) TYPE C, END OF T_ERROR.

*----------------------------------------------------------------------** WORKAREA DECLARATION*----------------------------------------------------------------------*DATA: WA_CRMEMO TYPE T_CRMEMO, WA_CRMEMO_CHANGE TYPE T_CRMEMO_CHANGE, WA_MVKE TYPE T_MVKE, WA_ORDERS TYPE T_ORDERS, WA_CMEMO TYPE T_ORDERS, WA_PO TYPE T_ORDERS, WA_EKPO TYPE T_EKPO, WA_EKBE TYPE T_EKBE, WA_EKBE_TEMP TYPE T_EKBE, WA_RBKP TYPE T_RBKP, WA_RBKP_TMP TYPE T_RBKP, WA_CDHDR TYPE T_CDHDR, WA_CDPOS TYPE T_CDPOS, WA_CHANGE_DOCS TYPE T_CHANGE_DOCS, WA_CRMEMO_MR8M TYPE T_CRMEMO, WA_SUCCESS TYPE T_SUCCESS,

Page 38: Understanding BAPI

WA_ERROR TYPE T_ERROR, WA_SUCCESS_MR8M TYPE T_SUCCESS, WA_ERROR_MR8M TYPE T_ERROR.

*--Work area for all the internal tables used for Sending MailDATA : WA_OBJPACK TYPE SOPCKLSTI1, WA_OBJHEAD TYPE SOLISTI1, WA_OBJBIN TYPE SOLISTI1, WA_OBJTXT TYPE SOLISTI1, WA_RECLIST TYPE SOMLRECI1 .

DATA:*-- Structure to hold Invoice Header Data x_docheader LIKE bapi_incinv_create_header,*-- Structure to hold Reversal Posting Data x_rev_post LIKE BAPI_INCINV_FLD.

*----------------------------------------------------------------------** INTERNAL TAABLE DECLARATION*----------------------------------------------------------------------*DATA: IT_CRMEMO TYPE STANDARD TABLE OF T_CRMEMO WITH HEADER LINE, IT_CRMEMO_CHANGE TYPE STANDARD TABLE OF T_CRMEMO_CHANGE WITH HEADER LINE, IT_MVKE TYPE STANDARD TABLE OF T_MVKE WITH HEADER LINE, IT_CRMEMO_MIRO TYPE STANDARD TABLE OF T_CRMEMO WITH HEADER LINE, IT_CRMEMO_MR8M TYPE STANDARD TABLE OF T_CRMEMO WITH HEADER LINE, IT_ORDERS TYPE STANDARD TABLE OF T_ORDERS WITH HEADER LINE, IT_CMEMO TYPE STANDARD TABLE OF T_ORDERS WITH HEADER LINE, IT_PO TYPE STANDARD TABLE OF T_ORDERS WITH HEADER LINE, IT_EKPO TYPE STANDARD TABLE OF T_EKPO WITH HEADER LINE, IT_EKBE TYPE STANDARD TABLE OF T_EKBE WITH HEADER LINE, IT_EKBE_TEMP TYPE STANDARD TABLE OF T_EKBE WITH HEADER LINE, IT_RBKP TYPE STANDARD TABLE OF T_RBKP WITH HEADER LINE, IT_CDHDR TYPE STANDARD TABLE OF T_CDHDR WITH HEADER LINE, IT_CDPOS TYPE STANDARD TABLE OF T_CDPOS WITH HEADER LINE, IT_CHANGE_DOCS TYPE STANDARD TABLE OF T_CHANGE_DOCS WITH HEADER LINE, IT_SUCCESS TYPE STANDARD TABLE OF T_SUCCESS WITH HEADER LINE, IT_ERROR TYPE STANDARD TABLE OF T_ERROR WITH HEADER LINE, IT_SUCCESS_MR8M TYPE STANDARD TABLE OF T_SUCCESS WITH HEADER LINE, IT_ERROR_MR8M TYPE STANDARD TABLE OF T_ERROR WITH HEADER LINE.

*-- Internal table to hold Invoice Item DataDATA:BEGIN OF it_itemdata OCCURS 0. INCLUDE STRUCTURE bapi_incinv_create_item.DATA:END OF it_itemdata.

*-- Internal table to hold Invoice Acct Assignment DataDATA:BEGIN OF it_ACCOUNTingdata OCCURS 0. INCLUDE STRUCTURE BAPI_INCINV_CREATE_ACCOUNT.DATA:END OF it_accountingdata.

*-- Internal table to hold BAPI return dataDATA: BEGIN OF it_return OCCURS 0. INCLUDE STRUCTURE bapiret2. "Return Parameter.

Page 39: Understanding BAPI

DATA: END OF it_return.

*-- Internal table to hold BAPI return dataDATA: BEGIN OF it_return_mr8m OCCURS 0. INCLUDE STRUCTURE bapiret2. "Return Parameter.DATA: END OF it_return_mr8m.

*--MAIL related Internal tablesDATA: X_DOC_CHNG TYPE SODOCCHGI1, " document attributes IT_OBJPACK TYPE STANDARD TABLE OF SOPCKLSTI1, " attachment table IT_OBJHEAD TYPE STANDARD TABLE OF SOLISTI1, " object header table IT_OBJBIN TYPE STANDARD TABLE OF SOLISTI1, " binary table IT_OBJTXT TYPE STANDARD TABLE OF SOLISTI1, " object text IT_RECLIST TYPE STANDARD TABLE OF SOMLRECI1, " mail recipients it_compressed_list TYPE STANDARD TABLE OF SOLI, it_pdf_list TYPE STANDARD TABLE OF TLINE, it_pdf TYPE tline OCCURS 10 WITH HEADER LINE, it_html TYPE solisti1 OCCURS 10 WITH HEADER LINE,*-- Internal table for MIME data (in CHAR format) it_temp TYPE bapiqcmime OCCURS 10 WITH HEADER LINE,*-- Internal table for storing data it_mime(255) TYPE c OCCURS 10 WITH HEADER LINE.

*----------------------------------------------------------------------** GLOBAL VARIABLES **----------------------------------------------------------------------*DATA: V_PGM_ID TYPE SY-REPID, " Program id v_zterm TYPE lfb1-zterm, " Payment Terms v_text(75) TYPE c, " To store error or success text v_itemno(6) TYPE n, " To Increment Item No. for BAPI v_docnr LIKE bapi_incinv_fld-inv_doc_no, " For MIRO document number v_year1 LIKE bapi_incinv_fld-fisc_year, " For MIRO Fiscal year v_spono type TSP01-RQIDENT, " For Spool No. v_type type SOODK-OBJTP, " For Spool Type V_CRMEMO_QTY TYPE VBAP-ZMENG, " For CR Memo Qty. V_LINE_AMOUNT TYPE EKPO-NETPR, " For CR Memo Item Qty. V_GROSSAMT TYPE EKPO-NETPR, " For CR Memo Grand Qty. v_tax_per(3) type n, " For CR Memo Tax amount % v_tax_amt TYPE EKPO-NETPR, " For CR Memo Tax amount v_flag(1) type c, " Flag to process fruther v_tot_s_mr8m TYPE i, " For MR8M Success Records v_tot_e_mr8m TYPE i, " For MR8M Error Records V_DATE TYPE SY-DATUM, " For Sel. Screen Date V_DATE2(10) TYPE C, " For EMail Date V_TIME(10) TYPE C, " For EMail Time V_TIME2(10) TYPE C, " For EMail Time V_INFO(100) TYPE C, " For EMail Body Text V_TABLE_LINES TYPE SY-TABIX, " To Increment Email Count V_TEXT2 TYPE STRING , " For EMail Id text v_lines TYPE i, " To Store PDF Lines v_temp(500) TYPE c, " To Convert to 255 char format v_offset TYPE p, " To Convert to 255 char format v_lineslen TYPE i, " To Convert to 255 char format v_mimelen TYPE i, " To Convert to 255 char format v_tabix type sy-tabix. " To Convert to 255 char format

Page 40: Understanding BAPI

*----------------------------------------------------------------------** CONSTANTS **----------------------------------------------------------------------*CONSTANTS: C_X(1) TYPE C VALUE 'X', " Constant X or Flag C_E(1) TYPE C VALUE 'E', " For Error check c_v(1) TYPE C VALUE 'V', " For PO Docs c_o(1) TYPE C VALUE 'O', " For Order Docs c_c(1) TYPE C VALUE 'C', " For Credit Memo Docs c_k(1) TYPE C VALUE 'K', " For CR Memo Docs c_u(1) TYPE C VALUE 'U', " For Change tables Update c_ali(3) TYPE C VALUE 'ALI', " For ALI Format c_vbak(4) TYPE C VALUE 'VBAK', " For Change docs table C_01(2) TYPE C VALUE '01', " For Serial No. & Reversal Reason C_02(2) TYPE C VALUE '02', " For Reversal Reason c_blart TYPE bkpf-blart VALUE 'RE', " Document type C_MTPOS TYPE MVKE-MTPOS VALUE 'BANS', " Item Category group C_AUGRU(5) TYPE C VALUE 'AUGRU', " Reason Code C_0000500205(10) TYPE C VALUE '0000500205', " GL Account # C_VERKBELEG(9) TYPE C VALUE 'VERKBELEG'. " For Object Class

*-- Horizontal tab & line feed constantsCLASS CL_ABAP_CHAR_UTILITIES DEFINITION LOAD.CONSTANTS: C_TAB TYPE C VALUE CL_ABAP_CHAR_UTILITIES=>HORIZONTAL_TAB, C_CR_LF TYPE C VALUE CL_ABAP_CHAR_UTILITIES=>CR_LF .

*----------------------------------------------------------------------** SELECTION SCREEN*----------------------------------------------------------------------**-- Select OptonsSELECTION-SCREEN: BEGIN OF BLOCK B01 WITH FRAME TITLE TEXT-001. SELECT-OPTIONS: S_AUART FOR VBAK-AUART OBLIGATORY NO INTERVALS, " Sales Document Type S_AUGRU FOR VBAK-AUGRU OBLIGATORY NO INTERVALS, " Order reason S_ERDAT FOR VBAK-ERDAT OBLIGATORY. " Date on which the record was createdSELECTION-SCREEN: END OF BLOCK B01.

*-- Mail Sending OptionsSELECTION-SCREEN BEGIN OF BLOCK B2 WITH FRAME TITLE TEXT-004. PARAMETERS:P_EMAIL AS CHECKBOX DEFAULT SPACE USER-COMMAND V_COM . PARAMETERS : P_MODE TYPE SO_ESCAPE default 'U' MODIF ID US1. SELECT-OPTIONS: S_EMAIL FOR ADR6-SMTP_ADDR NO INTERVALS MODIF ID US2.* SELECT-OPTIONS: S_EMAIL FOR TRDYSE01CM-USERNAME* NO INTERVALS MODIF ID US2.

SELECTION-SCREEN: BEGIN OF LINE. SELECTION-SCREEN: COMMENT 55(40) TEXT-019 MODIF ID US2. SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN END OF BLOCK B2.

*----------------------------------------------------------------------*

Page 41: Understanding BAPI

* WORK AREA for SELECT-OPTIONS*----------------------------------------------------------------------*DATA : X_EMAIL LIKE S_EMAIL. "Work area for EMAIL select-options

*----------------------------------------------------------------------** INITIALIZATION*----------------------------------------------------------------------*INITIALIZATION.*-- Default values for Sales Document Type CLEAR S_AUART[]. S_AUART-SIGN = 'I'. S_AUART-OPTION = 'EQ'. S_AUART-LOW = 'CR'. APPEND S_AUART. CLEAR S_AUART.

*-- Default values for Date on which the record was created V_DATE = ( SY-DATUM - 1 ). CLEAR S_ERDAT[]. S_ERDAT-SIGN = 'I'. S_ERDAT-OPTION = 'EQ'. S_ERDAT-LOW = SY-DATUM. S_ERDAT-HIGH = SY-DATUM. APPEND S_ERDAT. CLEAR S_ERDAT.

*----------------------------------------------------------------------** TOP OF PAGE **----------------------------------------------------------------------*TOP-OF-PAGE.*-- Displaying standard header. PERFORM std_top_of_page USING sy-title.

*----------------------------------------------------------------------** A T S E L E C T I O N S C R E E N O U T P U T*----------------------------------------------------------------------**-- For modifying the selection screen layoutAT SELECTION-SCREEN OUTPUT. PERFORM F_MODIFY_SCREEN.

*----------------------------------------------------------------------** AT SELECTION SCREEN. **----------------------------------------------------------------------*AT SELECTION-SCREEN.*-- Subroutine to Validate selection screen fields PERFORM f_validate.

*----------------------------------------------------------------------** START-OF-SELECTION **----------------------------------------------------------------------*START-OF-SELECTION.*-- Fetch the Credit Memo Requests documents PERFORM F_GET_CREDIT_MEMO_REQUEST.

IF NOT IT_CRMEMO[] IS INITIAL.*-- Fetch Item Category Group

Page 42: Understanding BAPI

PERFORM F_GET_MVKE_DOCS.

*-- Fetch Sales Order documents, PO Documents and Credit Memos PERFORM F_GET_SO_PO_DOCS. ENDIF.

*-- If Credit memo request internal table have an change records then* fetch the change documents from CDHDR and CDPOS IF NOT IT_CRMEMO_CHANGE[] IS INITIAL.*-- Fetch Change Documents for CR Memos from CDHDR and CDPOS tables PERFORM F_GET_CHANGED_DOCS. ENDIF.

*-- Fetch Purchasing Document Item Details IF NOT IT_PO[] IS INITIAL. PERFORM F_GET_EKPO. ENDIF.

*-- Fetch MIRO Vendor based on the PO Details IF NOT IT_EKPO[] IS INITIAL. PERFORM F_GET_VENDOR. ENDIF.

*----------------------------------------------------------------------** END-OF-SELECTION **----------------------------------------------------------------------* if v_flag is initial.*-- Process Vendor Debit Postings PERFORM F_PROCESS_MIRO.

*-- Process Reversal Postings of Vendor Automatic Debits using TCODE MR8M PERFORM F_PROCESS_MR8M.

*-- Send mail,if user enters Email id's and Email Mode is not initial IF P_EMAIL = C_X AND P_MODE IS NOT INITIAL AND S_EMAIL[] IS NOT INITIAL.

*-- Get spool id perform f_spool_id.

*-- EMail Logic PERFORM F_MAIL_LOGIC. ENDIF.

*-- display the EMail RSCONN01 and Sussess and Error records of MIRO and MR8M perform f_display_report.

else.*-- Else exit the process exit. endif.

*&---------------------------------------------------------------------**& Form F_MODIFY_SCREEN*&---------------------------------------------------------------------** A Form routine to modify the screen*----------------------------------------------------------------------*

Page 43: Understanding BAPI

FORM F_MODIFY_SCREEN .

*-- To Modify Mail Sending Options LOOP AT SCREEN. IF P_EMAIL = C_X. IF SCREEN-GROUP1 = 'US1' . SCREEN-INVISIBLE = 0. SCREEN-ACTIVE = 1. SCREEN-INPUT = 0. MODIFY SCREEN. ENDIF. IF SCREEN-GROUP2 = 'US2' . SCREEN-INVISIBLE = 0. SCREEN-ACTIVE = 1. MODIFY SCREEN. ENDIF. ELSEIF P_EMAIL = SPACE. IF SCREEN-GROUP1 = 'US1' . SCREEN-INVISIBLE = 1. SCREEN-ACTIVE = 0. MODIFY SCREEN. ENDIF. IF SCREEN-GROUP1 = 'US2' . SCREEN-INVISIBLE = 1. SCREEN-ACTIVE = 0. MODIFY SCREEN. ENDIF. ENDIF. ENDLOOP.

ENDFORM. " F_MODIFY_SCREEN

*&---------------------------------------------------------------------**& Form f_validate*&---------------------------------------------------------------------** Validation of Selection-Screen Inputs*----------------------------------------------------------------------*FORM f_validate .

*-- Validate Sales Document Type if not s_AUART[] is initial. select AUART into s_AUART-low from TVAK up to 1 rows where AUART in s_AUART. endselect. if sy-subrc <> 0. message E000 with 'Invalid Sales Document Type'(e01) . endif. ENDIF.

*-- Validate Order reason (reason for the business transaction) if not s_AUGRU[] is initial. select AUGRU into s_AUGRU-low from TVAU up to 1 rows

Page 44: Understanding BAPI

where AUGRU in s_AUGRU. endselect. if sy-subrc <> 0. message E000 with 'Invalid Order reason'(e02) . endif. endif.ENDFORM. " f_validate

*&---------------------------------------------------------------------**& Form F_GET_CREDIT_MEMO_REQUEST*&---------------------------------------------------------------------** Fetch Credit memo requests from VBAK & VBAP*----------------------------------------------------------------------*FORM F_GET_CREDIT_MEMO_REQUEST .

SELECT A~VBELN B~POSNR A~ERDAT A~AUART A~AUGRU A~WAERK A~VKORG A~VTWEG A~SPART A~VDATU A~BSTNK A~BSARK A~BSTDK A~AEDAT A~BUKRS_VF B~MATNR B~ZMENG B~ZIEME INTO TABLE IT_CRMEMO FROM ( VBAK AS A INNER JOIN VBAP AS B ON A~VBELN = B~VBELN ) WHERE ( A~ERDAT IN S_ERDAT OR A~AEDAT IN S_ERDAT ) AND A~AUART IN S_AUART. IF SY-SUBRC = 0. SORT IT_CRMEMO BY VBELN POSNR. ELSE. MESSAGE I000 WITH 'No Credit Memo Request selected'(002). v_flag = C_X. stop. ENDIF.

ENDFORM. " F_GET_CREDIT_MEMO_REQUEST

*&---------------------------------------------------------------------**& Form F_GET_MVKE_DOCS*&---------------------------------------------------------------------** Fetch Sales Data for Material*----------------------------------------------------------------------*FORM F_GET_MVKE_DOCS .

Page 45: Understanding BAPI

DATA: LV_TABIX TYPE SY-TABIX.

*-- Fetch Sales Data for Material SELECT MATNR " Material Number VKORG " Sales Organization VTWEG " Distribution Channel MTPOS " Item category group from material master FROM MVKE " Sales Data for Material INTO TABLE IT_MVKE FOR ALL ENTRIES IN IT_CRMEMO WHERE MATNR = IT_CRMEMO-MATNR AND VKORG = IT_CRMEMO-VKORG AND VTWEG = IT_CRMEMO-VTWEG. IF SY-SUBRC = 0. SORT IT_MVKE BY MATNR VKORG VTWEG MTPOS. ENDIF.

*-- Validate Item category group if MVKE-MTOPS <> 'BANS' then ignore CM Request line item LOOP AT IT_CRMEMO INTO WA_CRMEMO. LV_TABIX = SY-TABIX. READ TABLE IT_MVKE INTO WA_MVKE WITH KEY MATNR = WA_CRMEMO-MATNR VKORG = WA_CRMEMO-VKORG VTWEG = WA_CRMEMO-VTWEG MTPOS = C_MTPOS BINARY SEARCH. IF SY-SUBRC <> 0. DELETE IT_CRMEMO INDEX LV_TABIX. " Delete CR memo records ELSE.*-- Else check for credit memo request change date is not initial, and* append those records to IT_CRMEMO_CHANGE internal table to retrive* change documents IF NOT WA_CRMEMO-AEDAT IS INITIAL. WA_CRMEMO_CHANGE-VBELN = WA_CRMEMO-VBELN. WA_CRMEMO_CHANGE-POSNR = WA_CRMEMO-POSNR. WA_CRMEMO_CHANGE-ERDAT = WA_CRMEMO-ERDAT. WA_CRMEMO_CHANGE-AUART = WA_CRMEMO-AUART. WA_CRMEMO_CHANGE-AUGRU = WA_CRMEMO-AUGRU. WA_CRMEMO_CHANGE-WAERK = WA_CRMEMO-WAERK. WA_CRMEMO_CHANGE-VKORG = WA_CRMEMO-VKORG. WA_CRMEMO_CHANGE-VTWEG = WA_CRMEMO-VTWEG. WA_CRMEMO_CHANGE-SPART = WA_CRMEMO-SPART. WA_CRMEMO_CHANGE-VDATU = WA_CRMEMO-VDATU. WA_CRMEMO_CHANGE-BSTNK = WA_CRMEMO-BSTNK. WA_CRMEMO_CHANGE-BSARK = WA_CRMEMO-BSARK. WA_CRMEMO_CHANGE-BSTDK = WA_CRMEMO-BSTDK. WA_CRMEMO_CHANGE-AEDAT = WA_CRMEMO-AEDAT. WA_CRMEMO_CHANGE-BUKRS_VF = WA_CRMEMO-BUKRS_VF. WA_CRMEMO_CHANGE-MATNR = WA_CRMEMO-MATNR. WA_CRMEMO_CHANGE-ZMENG = WA_CRMEMO-ZMENG. WA_CRMEMO_CHANGE-ZIEME = WA_CRMEMO-ZIEME. APPEND WA_CRMEMO_CHANGE TO IT_CRMEMO_CHANGE. CLEAR WA_CRMEMO_CHANGE. ENDIF. ENDIF. ENDLOOP.

Page 46: Understanding BAPI

ENDFORM. " F_GET_MVKE_DOCS

*&---------------------------------------------------------------------**& Form F_GET_SO_PO_DOCS*&---------------------------------------------------------------------** Fetch the Sales Order documents, PO documents, & Credit Memo*----------------------------------------------------------------------*FORM F_GET_SO_PO_DOCS.

*-- Fetch Preceding sales orders based on the credit memo request SELECT VBELV POSNV VBELN POSNN VBTYP_N FROM VBFA INTO TABLE IT_ORDERS FOR ALL ENTRIES IN IT_CRMEMO WHERE VBELN = IT_CRMEMO-VBELN AND POSNN = IT_CRMEMO-POSNR AND VBTYP_N = C_K AND VBTYP_V = C_C. IF SY-SUBRC = 0. SORT IT_ORDERS BY VBELV POSNV.

*-- Fetch Subsequent PO documents & Credit Memo based on the sales orders SELECT VBELV POSNV VBELN POSNN VBTYP_N FROM VBFA INTO TABLE IT_PO FOR ALL ENTRIES IN IT_ORDERS WHERE VBELV = IT_ORDERS-VBELV AND POSNV = IT_ORDERS-POSNV AND VBTYP_N IN (C_V,C_O) AND VBTYP_V = C_C. IF SY-SUBRC = 0. SORT IT_PO BY VBTYP_N.

*-- Copy the IT_PO internal table contents to IT_CMEMO internal table IT_CMEMO[] = IT_PO[].

*-- Delete PO documents from IT_CMEMO internal table DELETE IT_CMEMO WHERE VBTYP_N = C_V. SORT IT_CMEMO BY VBELN POSNN. IF IT_CMEMO[] IS INITIAL. MESSAGE I000 WITH 'No Credit Memo are available for CM Request'(003).* v_flag = c_x.* stop. ENDIF.

*-- Delete Credit Memo documents from IT_PO internal table DELETE IT_PO WHERE VBTYP_N = C_O. SORT IT_PO BY VBELN POSNN.

Page 47: Understanding BAPI

ENDIF. ENDIF.

ENDFORM. " F_GET_SO_PO_DOCS

*&---------------------------------------------------------------------**& Form F_GET_CHANGED_DOCS*&---------------------------------------------------------------------** Fetch Change Documents for CR Memos from CDHDR and CDPOS tables*----------------------------------------------------------------------*FORM F_GET_CHANGED_DOCS .

*-- Fetch Change Documents for CR Memos from CDHDR SELECT OBJECTCLAS OBJECTID CHANGENR UDATE UTIME FROM CDHDR INTO TABLE IT_CDHDR FOR ALL ENTRIES IN IT_CRMEMO_CHANGE WHERE OBJECTCLAS = C_VERKBELEG AND OBJECTID = IT_CRMEMO_CHANGE-VBELN* AND UDATE = IT_CRMEMO_CHANGE-AEDAT . IF SY-SUBRC = 0. SORT IT_CDHDR BY OBJECTCLAS OBJECTID CHANGENR.

*-- Fetch Change Documents for CR Memos from CDPOS SELECT OBJECTCLAS OBJECTID CHANGENR TABNAME TABKEY FNAME CHNGIND VALUE_NEW VALUE_OLD FROM CDPOS INTO TABLE IT_CDPOS FOR ALL ENTRIES IN IT_CDHDR WHERE OBJECTCLAS = C_VERKBELEG AND OBJECTID = IT_CDHDR-OBJECTID AND CHANGENR = IT_CDHDR-CHANGENR AND TABNAME = C_VBAK AND FNAME = C_AUGRU AND CHNGIND = C_U. IF SY-SUBRC = 0. SORT IT_CDPOS BY OBJECTCLAS OBJECTID CHANGENR. ENDIF. ENDIF.

ENDFORM. " F_GET_CHANGED_DOCS

*&---------------------------------------------------------------------*

Page 48: Understanding BAPI

*& Form F_GET_EKPO*&---------------------------------------------------------------------** Fetch Purchasing Document Item Details*----------------------------------------------------------------------*FORM F_GET_EKPO .

*-- Fetch Purchasing Document Item Details SELECT A~EBELN B~EBELP A~WAERS B~MENGE B~MEINS B~NETPR B~PEINH B~mwskz B~TXJCD INTO TABLE IT_EKPO FROM ( EKKO AS A INNER JOIN EKPO AS B ON A~EBELN = B~EBELN ) FOR ALL ENTRIES IN IT_PO WHERE A~EBELN = IT_PO-VBELN AND B~EBELP = IT_PO-POSNN+1(5). IF SY-SUBRC = 0. SORT IT_EKPO BY EBELN EBELP. ENDIF.

ENDFORM. " F_GET_EKPO

*&---------------------------------------------------------------------**& Form F_GET_VENDOR*&---------------------------------------------------------------------** Fetch MIRO Vendor details based on the PO Details*----------------------------------------------------------------------*FORM F_GET_VENDOR .

DATA: LV_TABIX TYPE SY-TABIX.

*-- Fetch History per Purchasing Document records for all the PO records SELECT EBELN EBELP ZEKKN VGABE GJAHR BELNR BUZEI FROM EKBE INTO TABLE IT_EKBE FOR ALL ENTRIES IN IT_EKPO WHERE EBELN = IT_EKPO-EBELN AND EBELP = IT_EKPO-EBELP AND VGABE = '2'.* and STBLG = space. IF SY-SUBRC = 0. SORT IT_EKBE BY BELNR GJAHR.

*-- Fetch the vendor details based on table IT_EKBE internal table

Page 49: Understanding BAPI

SELECT BELNR GJAHR BLDAT BUDAT XBLNR LIFNR RMWWR WMWST1 XRECH STBLG FROM RBKP INTO TABLE IT_RBKP FOR ALL ENTRIES IN IT_EKBE WHERE BELNR = IT_EKBE-BELNR AND GJAHR = IT_EKBE-GJAHR. IF SY-SUBRC = 0. SORT IT_RBKP BY BELNR GJAHR. ENDIF. ENDIF.

*-- Sort PO History documents based on PO # and PO Item SORT IT_EKBE BY EBELN EBELP.

*-- Copy the PO History documents into IT_EKBE_TEMP internal table IT_EKBE_TEMP[] = IT_EKBE[].

*-- Delete PO History documents from IT_EKBE_TEMP internal table* comparing with IT_RBKP where (STBLG) Reversal document number* is initial LOOP AT IT_EKBE_TEMP INTO WA_EKBE_TEMP. LV_TABIX = SY-TABIX. READ TABLE IT_RBKP INTO WA_RBKP WITH KEY BELNR = WA_EKBE_TEMP-BELNR GJAHR = WA_EKBE_TEMP-GJAHR* XRECH = SPACE STBLG = SPACE. IF SY-SUBRC <> 0. DELETE IT_EKBE_TEMP INDEX LV_TABIX. ENDIF. CLEAR: WA_EKBE_TEMP, WA_RBKP. ENDLOOP.

ENDFORM. " F_GET_VENDOR

*&---------------------------------------------------------------------**& Form F_PROCESS_MIRO*&---------------------------------------------------------------------** Process MIRO*----------------------------------------------------------------------*FORM F_PROCESS_MIRO . DATA: lv_itemno TYPE i, lv_tabix type sy-index, lc_check(1) TYPE c VALUE 'X', V_FILL_ITEM, lv_rbkp_bldat type sy-datum.

Page 50: Understanding BAPI

clear : it_itemdata, it_accountingdata, IT_CRMEMO_MIRO, IT_CRMEMO_MR8M. refresh : it_itemdata, it_accountingdata, IT_CRMEMO_MIRO, IT_CRMEMO_MR8M.

*-- Copy all the CR Memo Docs and delete order reason not in S_AUGRU IT_CRMEMO_MR8M[] = IT_CRMEMO[].

*-- Delete Reversal postings which are not in S_AUGRU DELETE IT_CRMEMO_MR8M WHERE AUGRU IN S_AUGRU.

*-- Delete Reversal postings where AEDAT is initial DELETE IT_CRMEMO_MR8M where aedat is initial.

*-- Delete order reason which are not in S_AUGRU DELETE IT_CRMEMO WHERE AUGRU NOT IN S_AUGRU.

*-- Loop through the credit memo request records LOOP AT IT_CRMEMO INTO WA_CRMEMO. lv_tabix = sy-tabix.

*-- If credit memo request change date is not initial then* send change date (AEDAT) to lv_rbkp_bldat if not WA_CRMEMO-aedat is initial. lv_rbkp_bldat = WA_CRMEMO-aedat. else.*-- If credit memo request change date is initial then* send create date (ERDAT) to lv_rbkp_bldat lv_rbkp_bldat = WA_CRMEMO-erdat. endif.

READ TABLE IT_ORDERS INTO WA_ORDERS WITH KEY VBELN = WA_CRMEMO-VBELN POSNN = WA_CRMEMO-POSNR. IF SY-SUBRC = 0. READ TABLE IT_PO INTO WA_PO WITH KEY VBELV = WA_ORDERS-VBELV POSNV = WA_ORDERS-POSNV. IF SY-SUBRC = 0. READ TABLE IT_EKPO INTO WA_EKPO WITH KEY EBELN = WA_PO-VBELN EBELP = WA_PO-POSNN. IF SY-SUBRC = 0.*-- Read IT_EKBE_TEMP internal table which contains records which are not reversed READ TABLE IT_EKBE_TEMP INTO WA_EKBE_TEMP WITH KEY EBELN = WA_EKPO-EBELN EBELP = WA_EKPO-EBELP. IF SY-SUBRC = 0.*-- Read IT_RBKP internal table with XRECH (Indicator: post invoice) = 'X' ,* check for invoice records for the correspnding CR Memo records READ TABLE IT_RBKP INTO WA_RBKP WITH KEY BELNR = WA_EKBE_TEMP-BELNR GJAHR = WA_EKBE_TEMP-GJAHR XRECH = C_X. IF SY-SUBRC = 0.*-- Read IT_RBKP internal table with XRECH (Indicator: post invoice) = SPACE,* and document date = CR Memo creation date* and reference document number = PO number READ TABLE IT_RBKP INTO WA_RBKP_TMP WITH KEY BELNR = WA_EKBE_TEMP-BELNR GJAHR = WA_EKBE_TEMP-GJAHR BLDAT = WA_CRMEMO-ERDAT XRECH = ' '

Page 51: Understanding BAPI

XBLNR+0(10) = WA_EKBE_TEMP-ebeln.* STBLG = SPACE. IF SY-SUBRC = 0. CONTINUE. ELSE.*-- Quantity Conversion (Get the Credit Memo Quantity by passing CMR unit per one PO unit) perform f_quantity_conv.

*-- Filling the Line items data

*-- Incrementing the item no lv_itemno = lv_itemno + 1. v_itemno = lv_itemno.

it_itemdata-invoice_doc_item = v_itemno. it_itemdata-po_number = WA_ekPO-ebeln. it_itemdata-po_item = WA_EKPO-EBELP. it_itemdata-tax_code = WA_ekpo-mwskz. it_itemdata-TAXJURCODE = WA_ekpo-TXJCD.

*-- Converting SAP amount to BAPI format by passing line item amount and currency PERFORM f_currency_amount_sap_to_bapi USING WA_EKPO-waers V_LINE_AMOUNT CHANGING it_itemdata-item_amount .

it_itemdata-quantity = ( WA_CRMEMO-ZMENG * V_CRMEMO_QTY ). it_itemdata-po_unit = WA_EKPO-MEINS. APPEND it_itemdata.

*-- Populate Account Assignment data IT_ACCOUNTINGDATA-INVOICE_DOC_ITEM = v_itemno. IT_ACCOUNTINGDATA-XUNPL = space. IT_ACCOUNTINGDATA-SERIAL_NO = C_01. IT_ACCOUNTINGDATA-TAX_CODE = it_itemdata-tax_code. IT_ACCOUNTINGDATA-TAXJURCODE = it_itemdata-TAXJURCODE. IT_ACCOUNTINGDATA-ITEM_AMOUNT = it_itemdata-item_amount. IT_ACCOUNTINGDATA-QUANTITY = it_itemdata-quantity. IT_ACCOUNTINGDATA-PO_UNIT = it_itemdata-po_unit. IT_ACCOUNTINGDATA-GL_ACCOUNT = C_0000500205. append IT_ACCOUNTINGDATA. clear IT_ACCOUNTINGDATA.

CLEAR it_itemdata. endif. endif. ENDIF. ENDIF. ENDIF. ENDIF.*-- At end of each credit memo request fill the header details of BAPI FM and*-- post the BAPI AT END OF VBELN. read table it_crmemo into wa_crmemo index lv_tabix.

*-- Populate the document Header*-- Getting the header data for invoice

Page 52: Understanding BAPI

x_docheader-invoice_ind = space. x_docheader-doc_type = c_blart. x_docheader-doc_date = lv_rbkp_bldat. x_docheader-pstng_date = lv_rbkp_bldat. x_docheader-ref_doc_no = WA_RBKP-XBLNR. x_docheader-comp_code = WA_CRMEMO-BUKRS_VF. x_docheader-CURRENCY = WA_CRMEMO-WAERK. x_docheader-calc_tax_ind = lc_check.

*-- Logic to find the Tax % v_tax_per = ( WA_RBKP-WMWST1 / ( WA_RBKP-RMWWR - WA_RBKP-WMWST1 ) ) * 100. v_tax_amt = ( V_GROSSAMT * v_tax_per ) / 100. V_GROSSAMT = ( V_GROSSAMT + v_tax_amt ). x_docheader-gross_amount = V_GROSSAMT.

CLEAR:v_docnr, v_year1.

*-- Calling BAPI to create PO invoice document CHECK NOT IT_ITEMDATA[] IS INITIAL. CALL FUNCTION 'BAPI_INCOMINGINVOICE_CREATE' EXPORTING headerdata = x_docheader IMPORTING invoicedocnumber = v_docnr fiscalyear = v_year1 TABLES itemdata = it_itemdata[] ACCOUNTingDATA = it_ACCOUNTingDATA[]* GLACCOUNTDATA =* taxdata = return = it_return.

*-- Commit work IF NOT v_docnr IS INITIAL. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.*-- Move the data to Success Internal Table wa_success-crmemo = wa_crmemo-vbeln. wa_success-cmemo = wa_cmemo-vbeln. wa_success-orders = wa_orders-vbelv. wa_success-po = wa_po-vbeln. wa_success-miro_no = v_docnr. wa_success-text = 'MIRO is Posted'. append wa_success TO it_success. clear wa_success.

ENDIF.*-- Read the values in the table IT_RETURN. CLEAR it_return. READ TABLE it_return INDEX 1.* If message type is error then roll back the work IF it_return-type = C_E.*-- Roll back CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

Page 53: Understanding BAPI

*-- Move the data to Error Internal Table wa_error-crmemo = wa_crmemo-vbeln. wa_error-cmemo = wa_cmemo-vbeln. wa_error-orders = wa_orders-vbelv. wa_error-po = wa_po-vbeln. wa_error-text = it_return-MESSAGE. append wa_error TO it_error. clear wa_error.

ENDIF.

refresh: it_return, it_itemdata, it_accountingdata. clear: V_GROSSAMT, it_return, it_itemdata, wa_crmemo, wa_orders, wa_po, wa_ekpo, WA_EKBE_TEMP, wa_rbkp, wa_rbkp_tmp, v_docnr, v_year1, WA_SUCCESS, WA_ERROR, it_accountingdata, v_tax_per, v_tax_amt, V_FILL_ITEM, lv_rbkp_bldat. ENDAT. ENDLOOP.

ENDFORM. " F_PROCESS_MIRO

*&---------------------------------------------------------------------**& Form f_quantity_conv*&---------------------------------------------------------------------** Quantity Conversion*----------------------------------------------------------------------*FORM f_quantity_conv .

*-- Quantity Conversion (Get the Credit Memo Quantity by passing CMR unit per one PO unit) CLEAR: V_LINE_AMOUNT, V_CRMEMO_QTY.

call function 'MC_UNIT_CONVERSION' EXPORTING MATNR = WA_CRMEMO-MATNR nach_meins = WA_EKPO-MEINS von_meins = WA_CRMEMO-ZIEME IMPORTING UMREF = V_CRMEMO_QTY EXCEPTIONS CONVERSION_NOT_FOUND = 1 MATERIAL_NOT_FOUND = 2 NACH_MEINS_MISSING = 3 OVERFLOW = 4 VON_MEINS_MISSING = 5 OTHERS = 6. if sy-subrc <> 0. MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ELSE. V_LINE_AMOUNT = ( V_CRMEMO_QTY * WA_CRMEMO-ZMENG * WA_EKPO-peinh * WA_EKPO-NETPR ). V_GROSSAMT = V_GROSSAMT + V_LINE_AMOUNT. ENDIF.

ENDFORM. " f_quantity_conv

*&---------------------------------------------------------------------*

Page 54: Understanding BAPI

*& Form f_currency_amount_sap_to_bapi*&---------------------------------------------------------------------** SAP Amount to BAPI Amount*----------------------------------------------------------------------*FORM f_currency_amount_sap_to_bapi USING p_waers p_kbetr CHANGING p_amt_doccur.

DATA : lv_waers LIKE tcurc-waers, lv_sapamount LIKE bapicurr-bapicurr, lv_bapi_amount LIKE bapicurr-bapicurr.

lv_waers = p_waers. lv_sapamount = p_kbetr.

CALL FUNCTION 'CURRENCY_AMOUNT_SAP_TO_BAPI' EXPORTING currency = lv_waers sap_amount = lv_sapamount IMPORTING bapi_amount = lv_bapi_amount.

p_amt_doccur = lv_bapi_amount.

ENDFORM. " f_currency_amount_sap_to_bapi

*&---------------------------------------------------------------------**& Form f_display_report*&---------------------------------------------------------------------** Display Report*----------------------------------------------------------------------*FORM f_display_report .

*-- Success Report IF NOT IT_SUCCESS[] IS INITIAL. ULINE AT /1(129). WRITE:/1 sy-vline, 'CR Memo', 19 sy-vline, 'Credit Memo', 39 sy-vline, 'Sales Order', 59 sy-vline, 'Purchase Order', 79 sy-vline, 'MIRO Number', 99 sy-vline, 'Text', 129 sy-vline. ULINE AT /1(129).

LOOP AT it_success into wa_success. WRITE:/1 sy-vline, wa_success-crmemo, 19 sy-vline, wa_success-cmemo, 39 sy-vline, wa_success-orders, 59 sy-vline, wa_success-po, 79 sy-vline, wa_success-miro_no, 99 sy-vline, wa_success-text, 129 sy-vline.

ENDLOOP.

Page 55: Understanding BAPI

ULINE AT /1(129). SKIP 2.

ENDIF.

*-- Error Report IF NOT IT_ERROR[] IS INITIAL.

ULINE AT /1(179). WRITE:/1 sy-vline, 'CR Memo', 19 sy-vline, 'Credit Memo', 39 sy-vline, 'Sales Order', 59 sy-vline, 'Purchase Order', 79 sy-vline, 'Error Text', 179 sy-vline. ULINE AT /1(179).

LOOP AT IT_ERROR into WA_ERROR. WRITE:/1 sy-vline, WA_ERROR-crmemo, 19 sy-vline, WA_ERROR-cmemo, 39 sy-vline, WA_ERROR-orders, 59 sy-vline, WA_ERROR-po, 79 sy-vline, WA_ERROR-text, 179 sy-vline. ENDLOOP. ULINE AT /1(179).

ENDIF.

IF NOT IT_SUCCESS_MR8M[] IS INITIAL. ULINE AT /1(129). WRITE:/1 sy-vline, 'CR Memo', 19 sy-vline, 'Credit Memo', 39 sy-vline, 'Sales Order', 59 sy-vline, 'Purchase Order', 79 sy-vline, 'Reversal Posting No.', 99 sy-vline, 'Text', 129 sy-vline. ULINE AT /1(129).

LOOP AT it_success_mr8m into wa_success_mr8m. WRITE:/1 sy-vline, wa_success_mr8m-crmemo, 19 sy-vline, wa_success_mr8m-cmemo, 39 sy-vline, wa_success_mr8m-orders, 59 sy-vline, wa_success_mr8m-po, 79 sy-vline, wa_success_mr8m-miro_no, 99 sy-vline, wa_success_mr8m-text, 129 sy-vline.

ENDLOOP. ULINE AT /1(129). SKIP 2.

ENDIF.

Page 56: Understanding BAPI

*-- Error Report IF NOT IT_ERROR_MR8M[] IS INITIAL.

ULINE AT /1(179). WRITE:/1 sy-vline, 'CR Memo', 19 sy-vline, 'Credit Memo', 39 sy-vline, 'Sales Order', 59 sy-vline, 'Purchase Order', 79 sy-vline, 'Error Text', 179 sy-vline. ULINE AT /1(179).

LOOP AT IT_ERROR_MR8M into WA_ERROR_MR8M. WRITE:/1 sy-vline, WA_ERROR_MR8M-crmemo, 19 sy-vline, WA_ERROR_MR8M-cmemo, 39 sy-vline, WA_ERROR_MR8M-orders, 59 sy-vline, WA_ERROR_MR8M-po, 79 sy-vline, WA_ERROR_MR8M-text, 179 sy-vline. ENDLOOP. ULINE AT /1(179).

ENDIF.

ENDFORM. " f_display_report

*&---------------------------------------------------------------------**& Form F_PROCESS_MR8M*&---------------------------------------------------------------------** Process Reversal postings*----------------------------------------------------------------------*FORM F_PROCESS_MR8M .

clear: wa_CRMEMO_MR8M.

LOOP AT IT_CRMEMO_MR8M into WA_CRMEMO_MR8M. read table it_cdpos into wa_cdpos with key OBJECTID = WA_CRMEMO_MR8M-VBELN. if sy-subrc <> 0. CONTINUE. ELSE. if wa_cdpos-value_old in s_augru. READ TABLE IT_ORDERS INTO WA_ORDERS WITH KEY VBELN = wa_CRMEMO_MR8M-VBELN POSNN = wa_CRMEMO_MR8M-POSNR. IF SY-SUBRC = 0.* READ TABLE IT_CMEMO INTO WA_CMEMO WITH KEY VBELV = WA_ORDERS-VBELV* POSNV = WA_ORDERS-POSNV.* IF SY-SUBRC = 0. READ TABLE IT_PO INTO WA_PO WITH KEY VBELV = WA_ORDERS-VBELV POSNV = WA_ORDERS-POSNV. IF SY-SUBRC = 0. READ TABLE IT_EKPO INTO WA_EKPO WITH KEY EBELN = WA_PO-VBELN EBELP = WA_PO-POSNN. IF SY-SUBRC = 0.* READ TABLE IT_EKBE INTO WA_EKBE WITH KEY EBELN = WA_EKPO-EBELN* EBELP = WA_EKPO-EBELP.* IF SY-SUBRC = 0.

Page 57: Understanding BAPI

LOOP AT IT_EKBE into WA_EKBE WHERE EBELN = WA_EKPO-EBELN AND EBELP = WA_EKPO-EBELP. READ TABLE IT_RBKP INTO WA_RBKP WITH KEY BELNR = WA_EKBE-BELNR GJAHR = WA_EKBE-GJAHR* BLDAT = WA_CRMEMO_MR8M-AEDAT XBLNR+0(10) = WA_EKBE-EBELN XRECH = SPACE STBLG = SPACE.

IF SY-SUBRC = 0. move: WA_RBKP-BELNR TO X_REV_POST-INV_DOC_NO, WA_RBKP-GJAHR TO X_REV_POST-FISC_YEAR, WA_RBKP-BUDAT TO X_REV_POST-PSTNG_DATE. IF WA_RBKP-BUDAT+4(2) = SY-DATUM+4(2). X_REV_POST-REASON_REV = C_01. ELSE. X_REV_POST-REASON_REV = C_02. ENDIF. ENDIF. ENDLOOP.*-- Call the FM for MIRO reversal CALL FUNCTION 'BAPI_INCOMINGINVOICE_CANCEL' EXPORTING INVOICEDOCNUMBER = X_REV_POST-INV_DOC_NO FISCALYEAR = X_REV_POST-FISC_YEAR REASONREVERSAL = X_REV_POST-REASON_REV POSTINGDATE = X_REV_POST-PSTNG_DATE IMPORTING INVOICEDOCNUMBER_REVERSAL = X_REV_POST-INV_DOC_NO FISCALYEAR_REVERSAL = X_REV_POST-FISC_YEAR TABLES RETURN = it_return_mr8m.*-- Commit work IF NOT X_REV_POST-INV_DOC_NO IS INITIAL. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.*-- Move the data to Success Internal Table wa_success_mr8m-crmemo = wa_crmemo-vbeln. wa_success_mr8m-cmemo = wa_cmemo-vbeln. wa_success_mr8m-orders = wa_orders-vbelv. wa_success_mr8m-po = wa_po-vbeln. wa_success_mr8m-text = 'MR8M Done'. append wa_success_mr8m TO it_success_mr8m. clear wa_success_mr8m. ENDIF.*-- Read the values in the table IT_RETURN. CLEAR it_return_mr8m. READ TABLE it_return_mr8m INDEX 1.*-- If message type is error then roll back the work IF it_return_mr8m-type = 'E' .*-- Roll back CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.*-- Move the data to Error Internal Table wa_error_mr8m-crmemo = wa_crmemo-vbeln. wa_error_mr8m-cmemo = wa_cmemo-vbeln.

Page 58: Understanding BAPI

wa_error_mr8m-orders = wa_orders-vbelv. wa_error_mr8m-po = wa_po-vbeln. wa_error_mr8m-text = it_return_mr8m-MESSAGE. append wa_error_mr8m TO it_error_mr8m. clear wa_error_mr8m.

ENDIF.* ENDIF.* ENDIF. ENDIF. ENDIF.* ENDIF. ENDIF. ENDIF. ENDIF. CLEAR: wa_error_mr8m, wa_SUCCESS_mr8m, X_REV_POST, wa_CRMEMO_MR8M, wa_orders, wa_po, wa_ekpo, wa_ekbe, wa_rbkp, wa_cmemo. REFRESH: IT_RETURN_MR8M.

endloop.

ENDFORM. " F_PROCESS_MR8M

*&---------------------------------------------------------------------**& Form F_spool_id*&---------------------------------------------------------------------** Create a new spool ID*----------------------------------------------------------------------*FORM F_spool_id .

*-- Create a new spool from the data in data_tab*-- new-page line-size sy-linsz print on new-page line-size 255 print on destination 'LOCL'(p19) "<<== my printer*-- receiver 'TJOSVOB' cover text 'Spool title'(p20) " <<== Title or Spool req. name list name 'List name'(p21) list dataset 'List Dataset'(p22) immediately ' ' " X means print now keep in spool c_x " X means keep spool new list identification c_x no dialog .

*-- Writing Report*-- In this perform you will write the code for displaying the list perform f_display_report.

*-- new-page print off new-page print off.

ENDFORM. " F_spool_id

*&---------------------------------------------------------------------**& Form F_MAIL_LOGIC*&---------------------------------------------------------------------** Logic to send a mail for the given Email ID's

Page 59: Understanding BAPI

*----------------------------------------------------------------------*FORM F_MAIL_LOGIC .

data : wa_tsp01sys type tsp01sys. clear v_spono.

v_spono = sy-spono.* v_attach_desc = sy-title.*-- Convert the Spool ID into PDF format perform f_pdf_conversion tables it_compressed_list it_pdf_list using v_spono.

*-- Send the Mail in PDF Format perform f_send_mail.

ENDFORM. " F_MAIL_LOGIC

*&---------------------------------------------------------------------**& Form f_pdf_conversion*&---------------------------------------------------------------------** Read the spool and convert into PDF format*----------------------------------------------------------------------** -->P_ITAB_COMPRESSED_LIST text* -->P_ITAB_PDF_LIST text* -->P_V_SPONO text*----------------------------------------------------------------------*FORM f_pdf_conversion TABLES it_compressed_list structure soli it_pdf_list structure tline using lv_spooln type tsp01-rqident.

clear: it_compressed_list, it_pdf_list.refresh: it_compressed_list, it_pdf_list.

*-- Call the FM "RSPO_RETURN_SPOOLJOB" to read the spool by passing the spool number call function 'RSPO_RETURN_SPOOLJOB' exporting rqident = lv_spooln desired_type = v_type importing real_type = v_type tables buffer = it_compressed_list buffer_pdf = it_pdf_list exceptions no_such_job = 1 job_contains_no_data = 2 selection_empty = 3 no_permission = 4 can_not_access = 5 read_error = 6 type_no_match = 7 others = 8. if sy-subrc <> 0. message I000 with 'Error in spool reading'(017). endif.

Page 60: Understanding BAPI

*-- If the List type is ALI call the FM "CONVERT_ABAPSPOOLJOB_2_PDF"* to convert list into PDF Format if v_type = c_ali. " for List it is ALI call function 'CONVERT_ABAPSPOOLJOB_2_PDF' exporting src_spoolid = lv_spooln tables pdf = it_pdf exceptions err_no_abap_spooljob = 1 err_no_spooljob = 2 err_no_permission = 3 err_conv_not_possible = 4 err_bad_destdevice = 5 user_cancelled = 6 err_spoolerror = 7 err_temseerror = 8 err_btcjob_open_failed = 9 err_btcjob_submit_failed = 10 err_btcjob_close_failed = 11 others = 12. if sy-subrc <> 0. message e000 with'Error in convertion of list into PDF format'(018). endif.

*-- Logic to convert the given format into 255 character format in IT_PDF describe table it_pdf lines v_lines. describe field it_pdf length v_lineslen IN character MODE. describe field it_temp length v_mimelen IN character MODE. LOOP AT it_pdf. v_tabix = sy-tabix. MOVE it_pdf TO v_temp+v_offset. IF v_tabix = v_lines. v_lineslen = strlen( it_pdf ). ENDIF.

v_offset = v_offset + v_lineslen. IF v_offset GE v_mimelen. CLEAR it_temp. it_temp = v_temp(v_mimelen). APPEND it_temp. SHIFT v_temp BY v_mimelen PLACES. v_offset = v_offset - v_mimelen. ENDIF.

IF v_tabix = v_lines. IF v_offset GT 0. CLEAR it_temp. it_temp = v_temp(v_offset). APPEND it_temp. ENDIF. ENDIF. ENDLOOP.

Page 61: Understanding BAPI

LOOP AT it_temp. it_mime(255) = it_temp-line. APPEND it_mime. ENDLOOP.

*-- Final Data to send to EMail it_html[] = it_mime[]. endif.

ENDFORM. " f_pdf_conversion

*&---------------------------------------------------------------------**& Form f_send_mail*&---------------------------------------------------------------------** Send EMail Logic*----------------------------------------------------------------------*FORM f_send_mail .

data : wa_tsp01sys type tsp01sys.

*-- Populate Mail Id's WA_RECLIST-REC_TYPE = P_MODE. WA_RECLIST-EXPRESS = C_X.

*-- Loop through the Emial select options LOOP AT S_EMAIL INTO X_EMAIL. WA_RECLIST-RECEIVER = X_EMAIL-LOW.*-- append receiver table APPEND WA_RECLIST TO IT_RECLIST. ENDLOOP.

*-- If receiver table is not initial CHECK IT_RECLIST[] IS NOT INITIAL.*--To check Mail ID's internal table should not be Empty.*--populate document attributes

*-- Mail subject line CLEAR: X_DOC_CHNG. X_DOC_CHNG-OBJ_NAME = 'HEADING'. CONCATENATE 'Automatic Vendor Dedit Postings'(005) SY-DATUM INTO X_DOC_CHNG-OBJ_DESCR SEPARATED BY SPACE.

*-- Mail body CONCATENATE 'Automatic Vendor Dedit Postings'(005) ' is attached.'(006) INTO WA_OBJTXT SEPARATED BY SPACE. APPEND WA_OBJTXT TO IT_OBJTXT.

*-- Append Date and Time into Body of email. MOVE 'File is generated on'(007) TO V_INFO. V_TIME = SY-UZEIT. CONCATENATE V_TIME+0(2) V_TIME+2(2)

Page 62: Understanding BAPI

V_TIME+4(2) INTO V_TIME2 SEPARATED BY ':'. CONCATENATE SY-DATUM+4(2) '/' SY-DATUM+6(2) '/' SY-DATUM+0(4) INTO V_DATE2. CONCATENATE V_INFO V_DATE2 'At' V_TIME2 INTO V_INFO SEPARATED BY SPACE. WA_OBJTXT = V_INFO. APPEND WA_OBJTXT TO IT_OBJTXT.

*-- Document size CLEAR : V_TABLE_LINES. DESCRIBE TABLE IT_OBJTXT LINES V_TABLE_LINES. READ TABLE IT_OBJTXT INTO WA_OBJTXT INDEX V_TABLE_LINES . X_DOC_CHNG-DOC_SIZE = ( V_TABLE_LINES - 1 ) * 255 + STRLEN( WA_OBJTXT ).

*-- Populate packing list for body text WA_OBJPACK-HEAD_START = 1. WA_OBJPACK-HEAD_NUM = 0. WA_OBJPACK-BODY_START = 1. WA_OBJPACK-BODY_NUM = V_TABLE_LINES. WA_OBJPACK-DOC_TYPE = 'RAW'. APPEND WA_OBJPACK TO IT_OBJPACK. CLEAR WA_OBJPACK.

if v_type = c_ali. loop at it_html. wa_objbin-line = it_html-line. APPEND WA_OBJBIN TO IT_OBJBIN. CLEAR WA_OBJBIN. endloop. v_type = 'PDF'. endif.

*-- Get total no.of lines of Object table(attachment) CLEAR : V_TABLE_LINES. DESCRIBE TABLE IT_OBJBIN LINES V_TABLE_LINES.

*-- Populate object header(attachment name) WA_OBJHEAD = 'Automatic Vendor Dedit Postings log'(014). APPEND WA_OBJHEAD TO IT_OBJHEAD. CLEAR WA_OBJHEAD.

*-- Packing list for attachment WA_OBJPACK-TRANSF_BIN = C_X. WA_OBJPACK-HEAD_START = 1. WA_OBJPACK-HEAD_NUM = 1.

Page 63: Understanding BAPI

WA_OBJPACK-BODY_START = 1. WA_OBJPACK-BODY_NUM = V_TABLE_LINES . WA_OBJPACK-DOC_TYPE = v_type .

WA_OBJPACK-OBJ_NAME = 'Auto_Debit'. WA_OBJPACK-OBJ_DESCR = 'attachment'. WA_OBJPACK-DOC_SIZE = V_TABLE_LINES * 255. APPEND WA_OBJPACK TO IT_OBJPACK. CLEAR WA_OBJPACK.

*-- Sending the EMail document in given format CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1' EXPORTING DOCUMENT_DATA = X_DOC_CHNG PUT_IN_OUTBOX = C_X COMMIT_WORK = C_X TABLES PACKING_LIST = IT_OBJPACK OBJECT_HEADER = IT_OBJHEAD CONTENTS_BIN = IT_OBJBIN CONTENTS_TXT = IT_OBJTXT RECEIVERS = IT_RECLIST EXCEPTIONS TOO_MANY_RECEIVERS = 1 DOCUMENT_NOT_SENT = 2 DOCUMENT_TYPE_NOT_EXIST = 3 OPERATION_NO_AUTHORIZATION = 4 PARAMETER_ERROR = 5 X_ERROR = 6 ENQUEUE_ERROR = 7 OTHERS = 8.

IF SY-SUBRC <> 0. MESSAGE E000 WITH 'Error occurred in sending mail'(015). ELSE.*-- Wait upto 2 secounds wait up to 2 seconds.

*-- Call the RSCONN01 (SAPconnect: Start Send Process) SUBMIT RSCONN01 WITH MODE = 'INT'* WITH output = 'X' AND RETURN.

PERFORM F_DISPLAY_SENT_MAIL_STATUS. ENDIF.

* To delete the spool request wa_tsp01sys-rqident = sy-spono. call function 'RSPO_IDELETE_SPOOLREQ' exporting spoolreq = wa_tsp01sys. if sy-subrc <> 0. endif.

ENDFORM. " f_send_mail

Page 64: Understanding BAPI

*&---------------------------------------------------------------------**& Form F_DISPLAY_SENT_MAIL_STATUS*&---------------------------------------------------------------------** Display Mail Sent status to the user*----------------------------------------------------------------------*FORM F_DISPLAY_SENT_MAIL_STATUS .

ULINE AT /1(60). WRITE :/ SY-VLINE, 'Mail sent Successfully to'(016) COLOR 5 INTENSIFIED ON, 60 SY-VLINE.

LOOP AT S_EMAIL INTO X_EMAIL. V_TABLE_LINES = STRLEN( X_EMAIL-LOW ). MOVE X_EMAIL-LOW+0(V_TABLE_LINES) TO V_TEXT2.

WRITE :/ SY-VLINE, 2 SY-TABIX LEFT-JUSTIFIED, 5 ')', V_TEXT2, 60 SY-VLINE. ENDLOOP.

ULINE AT /1(60).

ENDFORM. " F_DISPLAY_SENT_MAIL_STATUS