Best practice guide for custom ABAP program developments

While SAP’s direction is to get to a cloud-first architecture with their cloud-based products, there are many enterprises who are already in on-premise SAP systems or are in the process of implementing them. Which means, the developers will often get requirements that has to be fulfilled through custom ABAP program developments on the workbench. This article is related to such instances.
 
For a developer, being tasked to work on a development from scratch is a refreshing opportunity. This means, you get to decide the flow, the design, the architecture and every aspect of the program instead of fixing and patching up somebody else’s work. While this may not happen every day, when it does, the task comes with a great responsibility: to create a solution that is efficient, robust, scalable, and easy to maintain.
 
Becoming a great ABAP developer is a life-long journey which needs constant improvement of the craft. So, obviously, one article cannot explain all the nuances and the factors to consider for a development. However, this article shares the importance of some key areas and shares questions that we should be thinking about when we work on an ABAP development.
 
The task of the developer begins way before you fire up that SE38 and ends much after the Ctrl + F3. This article shares some of the preparation work you should do before a development, several key best practices to follow during the development, and some post-development activities you can adopt to make the lives of everyone a little bit better.

Questions to ask before the development

Your BA/ functional consultant/ technical lead will probably share a specification document or a pseudo-code to outline what’s required from the development. But a good developer (or a technical consultant) is not someone who blindly converts the spec to code. It is a good developer’s responsibility to get any doubts cleared, assess if the proposed way is the best way, and improve the design to bring the most convenience to the user (of course, if you are a beginner, you may not have the expertise here and will have to rely on a senior colleague/lead).

What kind of a program is this?

Knowing this is quite helpful to determine the architecture of the program.

Is this a simple report program that takes in some selection criteria and outputs an ALV report? Then, we can opt to a conventional report program with local class to structure the code. Is it a complex tool that lists a selection of business documents and then allow several operations on them on GUI? Then, we can switch to MVC (Model-View-Controller). Is it a daily file download? Then we know that we also have to discuss and align on where the file is placed and get the folders provisioned. Is it a wrapper program to a standard report? Then we have to ensure we don’t have redundant logic and also handle program outputs accordingly. Or is it something else?

Likewise, the answer to the question not only helps us with the direction of the design, but also helps with a rough effort estimate, and gives clarity on any follow up questions to be asked. 

Who is executing the program and how?

Some programs are executed by end-users. These should be user-friendly and also be forgiving if a user makes a mistake. As it may not always be easy to rectify mistakes with some document changes, it’s best to place warnings and confirmation dialog boxes along the execution and before commits so the user has to make a conscious choice to proceed. The screen fields and error messages should be descriptive and self-explanatory. This should be common sense. But sadly, I’ve seen some systems where end-user executed programs having technical field names on the selection screen and also provides no output whatsoever upon execution to confirm if the execution was successful. Such programs would also benefit from having a transaction code assigned. Use user parameters to default the screen-field values where applicable and check appropriate authorization objects to control the execution. 

Some programs are executed only by the expert/technical users. Execution of these should only be allowed for specific users (use authorization) under specific circumstances. Such programs may not need so many warnings and confirmations because the ones who executes it know the consequences. Some examples of such programs are the corrective programs executed in one-off cases or special programs created for migration activities.

There could also be programs that are executed by batch-users (not an end-user nor an expert, but a scheduled job executes them as a technical user). For such programs, there should be no GUI based interactions (no pop-up dialogues, user interactions on ALVs, etc) except the selection screen. Assigning a transaction code wouldn’t be beneficial as a person is not using it. Even the output should be compatible with background execution (using a module pool screen to embed the ALV will cause a dump when executed in background). But it’s essential to have correct error handling and logging so the job log would give us the correct picture of the execution.

What are the inputs & outputs?

This is probably covered in the specification document. 

However, see which inputs are really required. Is there anything that we can default based on user parameters (some systems will use user parameters to store default sales org, company code, etc for each user)? Is there any fields that we can derive based on the input of another field? Which are the mandatory fields that would help with improving performance of the selection logic? Should we use standard value-helps or build custom ones and populate using the values maintained in a custom table?

When it comes to the output, get to the specifics. Is it an ALV, an excel file downloaded to front-end, a text file saved to AL11, a list output, a message that pops up saying execution successful, or what? Leave no room for ambiguity. If it’s an ALV, also check which ALV standard functions are required. Do we need the entire toolbar? Or, do we not need them at all? 

Data volumes handled by the program

This is something the developers usually overlook and later end up causing many issues. Knowing this is crucial to design how the code is compartmentalized. If the program is always executed for one document, the flow could be much straightforward. But, if it’s executed for hundreds or thousands of documents/ items/ materials in one go, we have to design the data fetching, loops, to avoid repeating expensive logics. The design can also factor in the use parallel processing to achieve better performance. Also, this gives an idea to the developer to do an stress-test to the program before handing it over.

Areas to focus during the development

Design

Having the answers to aforementioned questions coupled with the specification document will help decide the design of the program. Key areas of the design would be selection screen, data selection, data processing, output preparation, and the output of results. For each of these areas, we can consider many points.

Selection Screen

What are the input fields and their data types?Which ones are single values (parameters) vs select options (multiple values and ranges)?Which fields are mandatory?Which can be defaulted (constants or user parameters)?Which can be derived or restricted based on another field?Which needs value helps (and are these sourced from data element or custom look up tables)?Which fields can be validated at the screen level itself and stop processing the rest of the program?Use of screen blocks (how to group and categorize the input fields instead of listing everything in one giant block).

Data Selection

What are the CDS view models that can be used? With S/4HANA, it’s always advisable to use CDS view for data fetching. With the recent upgrades, the standard has given so many comprehensive views with necessary associations to make data selections easier.When writing the SELECT statements, ensure to specify the exact fields that are needed. Every extra field means a data transfer between the DB and the application layer and we don’t want that time and effort wasted transferring unused data to the application. It’s always a good practice to have the fields in the order they appear in the DB table.INNER-JOINs could be a better option than FOR ALL ENTRIES as the latter would generate a lengthy SQL query in the DB if the source internal table has a lot of entries. But, select which one to be used based on the scenario.Think of the usage of the selected data to decide the kind of the internal table used to store the retrieved data. Inline declaration can be used if the dataset is to be looped through and treated as a standard table. If READs are performed on the table using partial or full keys, it would be a better option to declare the table as a SORTED or HASHED table respectively instead of an inline declaration. If the selected data is treated differently in different sections of a complex logic, read into a STANDARD table but then pass to SORTED or HASHED tables with appropriate keys for respective logics. This will avoid multiple DB reads and also ensure better performance.When it’s needed to fetch data from different sources, think how it can be optimized. Does it make sense to have all data selections in one place at the start of the program? Or, would it make more sense to select the necessary data just before it’s used? Determine this based on the usage of data and the flow of the program. 

Data Processing

With sequential programming, we are quite used to looping through datasets for processing. This makes the code unnecessarily lengthy and hard to read and understand. It’s best to take the OO approach and see how to compartmentalize the data processing at object level. This will help to ensure that we are dealing only with the data related to the object and also makes life easier when analyzing issues in the logic.Despite taking a sequential or OO approach, always have a logical flow to the data processing and segregate the code using methods and functions.Be extra vigilant about performance impacts. Whenever there are internal tables, loops, check if the best internal table types are used for the scenario.Make use of buffered data and avoid unnecessary and repetitive DB calls.Direct table updates is a big no especially for standard tables. Look for standard FMs and BAPIs and use them.Based on the data volumes handled, consider the use of background processing and parallel processing.

Data Output

A conventional ALV output may not always be the best option to share the results of the program. Consider options.If it’s a simple output of the status, yes, an OO ALV would be good. But it will not be the best approach for a program that has to output a huge number of data entries because the memory consumption would be too much if we attempt to load that much data to an ALV. A list output, a file output would be a better option here.If the program is executed in background, writing the output to a pre-configured AL11 path would be an option if not the spool.Application Log is also a better way to share the results of the processing. This also works well with OO paradigm and the presentation is more user friendly.Likewise, depending on the use of the output, use the best technology instead of defaulting to ALV outputs all the time.

Architecture

Always take the object-oriented approach. This doesn’t mean you have to create global classes in the dictionary (SE24). Depending on the use-case, it can be decided to either go with local classes or dictionary.Even for the simplest program, declare a local class to represent the main object(s) of the program and define necessary class attributes and methods accordingly to better represent the object and the behaviors. This helps immensely with the readability and maintainability.Try to keep the user interactions (data input, output) and the data handling (DB selects, BAPI calls to update data, etc) separate. This separation helps with a better design and if the program needs to be evolved to support parallel processing, background schedules, etc.If it’s a complex development, opt for architectures like MVC (Model-View-Controller) where the data model(s) handles the operations on data, the view(s) handle the user interactions, and the controller handles the communication in-between. 

Coding

Follow clean code practices: Refer this GitHub link for the CleanABAP guide.Use new ABAP syntax. With inline declarations and many other features, a lot of the busy-work can be done in one sentence. This also helps when debugging as well because it’ll be a single F5 to step through instead of stepping through so many times to achieve the same thing (eg: using new syntax to build a new tab based on another table vs using the conventional loop).Add meaningful descriptions to the created objects (eg: An include by default will get the name “Include of <main program>”. But, wouldn’t it be better to rename it to “Local Class definition of <program>”?)Use standard interfaces for common constants (especially for message types, select option values) instead of locally re-defining them.

 

* Common practice
CONSTANTS lc_e TYPE msgty VALUE ‘E’.
CONSTANTS lc_s TYPE msgty VALUE ‘S’.
MESSAGE ‘This is an error’ TYPE lc_s DISPLAY LIKE lc_e.

* Better
MESSAGE ‘This is an error’
TYPE if_xo_const_message=>success
DISPLAY LIKE if_xo_const_message=>error.

 

 

Compartmentalize the code (one segment: one function). This helps with testing and debugging as well.Don’t declare constants, variables for the sake of declaring them or just because it’s the practice. Think of the usage, search-ability, readability, and reusability.Implement correct exception handling. Because we don’t want dumps when executing the program and if something didn’t work, we don’t want to leave the users in the dark with no proper information. Check for sy-subrc after DB reads and decide how the program should progress.Check for IS ASSIGNED after assigning to field-symbols.Have a sy-subrc <> 0 block after FMs/APIs that return exceptions and communicate such errors to users appropriately.Keep code comments to a minimum. Never use comments to repeat the code in speaking language. This is a common trap that developers fall into as we think we should explain the logic to a non-developer who will be going through the program at a later time. Avoid this.The code should be self-explanatory. If the clean code guides are followed, the code will become much more readable and self-explanatory. In case where you do add comments, use the comment to explain “why” or the “business purpose”.Aligning with the coding guidelines of the organization, add a comment block at the header of the program to give a summary of the purpose of the program, owner/developer, change request details/ documentation links.And if you happen to do modifications, you can add a new block below the header to mention change details. Then, rely on the SAP’s versioning feature to compare what was changed from the previous version instead of adding the developer name, TR details on every line that was changed. After a while, this makes the code too cluttered and unreadable.Make it a habit to execute the ATC check after the development and fix priority 1, 2 errors and minimize the priority 3 errors as well. 

After

Phew! Now you are done with the bigger part of the task. What to do after the development?

Test! Test for happy flow as well as exceptional flows. As a practice, request the test data and expected outcome from the BA/functional consultant/respective leads as you are starting the development. This will give them sufficient time to prepare the data and share.Use this data to do the developer’s unit test of the program and document the test results. This documentation helps ensure that you cover all relevant scenarios and also it will be proof that the program worked as requested. Besides the major execution flows, also test the program for higher volumes of data (stress testing). This is critical because usually the data volumes and system capabilities are drastically different between development and production systems. Maybe there will be practical limitations to getting a huge volume of data in the development system for tests. Then, at least try your best to do this in the test/quality system.Finally, document the development details on the chosen platform. Some organizations will opt for tools like Jira/Confluence whereas some would rely on Sharepoint/Word documents. Whichever it is, ensure that as soon as the development is complete, that you prepare the technical design documentation. It would be best if the documentation covers the business requirement, overall design, and then get to the specifics of the program. This shouldn’t be a copy-paste of the code or the pseudo-code. But, any key factors considered, decisions made, and special technical points must be emphasized and recorded. It’s best to complete the documentation as soon as the development is complete because there’s a higher chance of forgetting the crucial details as you move on to a different task.

 

Conclusion

Most of the points shared may seem like common sense. But, I’ve seen developers overlooking these details time and time again and ending up in the same kind of issues repeatedly. Hence, re-iterated some points with a hint of direction because common sense isn’t that common after all.
For a developer, the programs you develop are your artwork. Your product.
So, it’s best to factor in these points and create your masterpiece so it is something you can be proud of and something that makes life easier for everyone.
After all, the whole point of an ERP system is to make the lives of the business users easier and help the business run smoother!

 

​ While SAP’s direction is to get to a cloud-first architecture with their cloud-based products, there are many enterprises who are already in on-premise SAP systems or are in the process of implementing them. Which means, the developers will often get requirements that has to be fulfilled through custom ABAP program developments on the workbench. This article is related to such instances. For a developer, being tasked to work on a development from scratch is a refreshing opportunity. This means, you get to decide the flow, the design, the architecture and every aspect of the program instead of fixing and patching up somebody else’s work. While this may not happen every day, when it does, the task comes with a great responsibility: to create a solution that is efficient, robust, scalable, and easy to maintain. Becoming a great ABAP developer is a life-long journey which needs constant improvement of the craft. So, obviously, one article cannot explain all the nuances and the factors to consider for a development. However, this article shares the importance of some key areas and shares questions that we should be thinking about when we work on an ABAP development. The task of the developer begins way before you fire up that SE38 and ends much after the Ctrl + F3. This article shares some of the preparation work you should do before a development, several key best practices to follow during the development, and some post-development activities you can adopt to make the lives of everyone a little bit better.Questions to ask before the developmentYour BA/ functional consultant/ technical lead will probably share a specification document or a pseudo-code to outline what’s required from the development. But a good developer (or a technical consultant) is not someone who blindly converts the spec to code. It is a good developer’s responsibility to get any doubts cleared, assess if the proposed way is the best way, and improve the design to bring the most convenience to the user (of course, if you are a beginner, you may not have the expertise here and will have to rely on a senior colleague/lead).What kind of a program is this?Knowing this is quite helpful to determine the architecture of the program.Is this a simple report program that takes in some selection criteria and outputs an ALV report? Then, we can opt to a conventional report program with local class to structure the code. Is it a complex tool that lists a selection of business documents and then allow several operations on them on GUI? Then, we can switch to MVC (Model-View-Controller). Is it a daily file download? Then we know that we also have to discuss and align on where the file is placed and get the folders provisioned. Is it a wrapper program to a standard report? Then we have to ensure we don’t have redundant logic and also handle program outputs accordingly. Or is it something else?Likewise, the answer to the question not only helps us with the direction of the design, but also helps with a rough effort estimate, and gives clarity on any follow up questions to be asked. Who is executing the program and how?Some programs are executed by end-users. These should be user-friendly and also be forgiving if a user makes a mistake. As it may not always be easy to rectify mistakes with some document changes, it’s best to place warnings and confirmation dialog boxes along the execution and before commits so the user has to make a conscious choice to proceed. The screen fields and error messages should be descriptive and self-explanatory. This should be common sense. But sadly, I’ve seen some systems where end-user executed programs having technical field names on the selection screen and also provides no output whatsoever upon execution to confirm if the execution was successful. Such programs would also benefit from having a transaction code assigned. Use user parameters to default the screen-field values where applicable and check appropriate authorization objects to control the execution. Some programs are executed only by the expert/technical users. Execution of these should only be allowed for specific users (use authorization) under specific circumstances. Such programs may not need so many warnings and confirmations because the ones who executes it know the consequences. Some examples of such programs are the corrective programs executed in one-off cases or special programs created for migration activities.There could also be programs that are executed by batch-users (not an end-user nor an expert, but a scheduled job executes them as a technical user). For such programs, there should be no GUI based interactions (no pop-up dialogues, user interactions on ALVs, etc) except the selection screen. Assigning a transaction code wouldn’t be beneficial as a person is not using it. Even the output should be compatible with background execution (using a module pool screen to embed the ALV will cause a dump when executed in background). But it’s essential to have correct error handling and logging so the job log would give us the correct picture of the execution.What are the inputs & outputs?This is probably covered in the specification document. However, see which inputs are really required. Is there anything that we can default based on user parameters (some systems will use user parameters to store default sales org, company code, etc for each user)? Is there any fields that we can derive based on the input of another field? Which are the mandatory fields that would help with improving performance of the selection logic? Should we use standard value-helps or build custom ones and populate using the values maintained in a custom table?When it comes to the output, get to the specifics. Is it an ALV, an excel file downloaded to front-end, a text file saved to AL11, a list output, a message that pops up saying execution successful, or what? Leave no room for ambiguity. If it’s an ALV, also check which ALV standard functions are required. Do we need the entire toolbar? Or, do we not need them at all? Data volumes handled by the programThis is something the developers usually overlook and later end up causing many issues. Knowing this is crucial to design how the code is compartmentalized. If the program is always executed for one document, the flow could be much straightforward. But, if it’s executed for hundreds or thousands of documents/ items/ materials in one go, we have to design the data fetching, loops, to avoid repeating expensive logics. The design can also factor in the use parallel processing to achieve better performance. Also, this gives an idea to the developer to do an stress-test to the program before handing it over.Areas to focus during the developmentDesignHaving the answers to aforementioned questions coupled with the specification document will help decide the design of the program. Key areas of the design would be selection screen, data selection, data processing, output preparation, and the output of results. For each of these areas, we can consider many points.Selection ScreenWhat are the input fields and their data types?Which ones are single values (parameters) vs select options (multiple values and ranges)?Which fields are mandatory?Which can be defaulted (constants or user parameters)?Which can be derived or restricted based on another field?Which needs value helps (and are these sourced from data element or custom look up tables)?Which fields can be validated at the screen level itself and stop processing the rest of the program?Use of screen blocks (how to group and categorize the input fields instead of listing everything in one giant block).Data SelectionWhat are the CDS view models that can be used? With S/4HANA, it’s always advisable to use CDS view for data fetching. With the recent upgrades, the standard has given so many comprehensive views with necessary associations to make data selections easier.When writing the SELECT statements, ensure to specify the exact fields that are needed. Every extra field means a data transfer between the DB and the application layer and we don’t want that time and effort wasted transferring unused data to the application. It’s always a good practice to have the fields in the order they appear in the DB table.INNER-JOINs could be a better option than FOR ALL ENTRIES as the latter would generate a lengthy SQL query in the DB if the source internal table has a lot of entries. But, select which one to be used based on the scenario.Think of the usage of the selected data to decide the kind of the internal table used to store the retrieved data. Inline declaration can be used if the dataset is to be looped through and treated as a standard table. If READs are performed on the table using partial or full keys, it would be a better option to declare the table as a SORTED or HASHED table respectively instead of an inline declaration. If the selected data is treated differently in different sections of a complex logic, read into a STANDARD table but then pass to SORTED or HASHED tables with appropriate keys for respective logics. This will avoid multiple DB reads and also ensure better performance.When it’s needed to fetch data from different sources, think how it can be optimized. Does it make sense to have all data selections in one place at the start of the program? Or, would it make more sense to select the necessary data just before it’s used? Determine this based on the usage of data and the flow of the program. Data ProcessingWith sequential programming, we are quite used to looping through datasets for processing. This makes the code unnecessarily lengthy and hard to read and understand. It’s best to take the OO approach and see how to compartmentalize the data processing at object level. This will help to ensure that we are dealing only with the data related to the object and also makes life easier when analyzing issues in the logic.Despite taking a sequential or OO approach, always have a logical flow to the data processing and segregate the code using methods and functions.Be extra vigilant about performance impacts. Whenever there are internal tables, loops, check if the best internal table types are used for the scenario.Make use of buffered data and avoid unnecessary and repetitive DB calls.Direct table updates is a big no especially for standard tables. Look for standard FMs and BAPIs and use them.Based on the data volumes handled, consider the use of background processing and parallel processing.Data OutputA conventional ALV output may not always be the best option to share the results of the program. Consider options.If it’s a simple output of the status, yes, an OO ALV would be good. But it will not be the best approach for a program that has to output a huge number of data entries because the memory consumption would be too much if we attempt to load that much data to an ALV. A list output, a file output would be a better option here.If the program is executed in background, writing the output to a pre-configured AL11 path would be an option if not the spool.Application Log is also a better way to share the results of the processing. This also works well with OO paradigm and the presentation is more user friendly.Likewise, depending on the use of the output, use the best technology instead of defaulting to ALV outputs all the time.ArchitectureAlways take the object-oriented approach. This doesn’t mean you have to create global classes in the dictionary (SE24). Depending on the use-case, it can be decided to either go with local classes or dictionary.Even for the simplest program, declare a local class to represent the main object(s) of the program and define necessary class attributes and methods accordingly to better represent the object and the behaviors. This helps immensely with the readability and maintainability.Try to keep the user interactions (data input, output) and the data handling (DB selects, BAPI calls to update data, etc) separate. This separation helps with a better design and if the program needs to be evolved to support parallel processing, background schedules, etc.If it’s a complex development, opt for architectures like MVC (Model-View-Controller) where the data model(s) handles the operations on data, the view(s) handle the user interactions, and the controller handles the communication in-between. CodingFollow clean code practices: Refer this GitHub link for the CleanABAP guide.Use new ABAP syntax. With inline declarations and many other features, a lot of the busy-work can be done in one sentence. This also helps when debugging as well because it’ll be a single F5 to step through instead of stepping through so many times to achieve the same thing (eg: using new syntax to build a new tab based on another table vs using the conventional loop).Add meaningful descriptions to the created objects (eg: An include by default will get the name “Include of <main program>”. But, wouldn’t it be better to rename it to “Local Class definition of <program>”?)Use standard interfaces for common constants (especially for message types, select option values) instead of locally re-defining them. * Common practice
CONSTANTS lc_e TYPE msgty VALUE ‘E’.
CONSTANTS lc_s TYPE msgty VALUE ‘S’.
MESSAGE ‘This is an error’ TYPE lc_s DISPLAY LIKE lc_e.

* Better
MESSAGE ‘This is an error’
TYPE if_xo_const_message=>success
DISPLAY LIKE if_xo_const_message=>error.  Compartmentalize the code (one segment: one function). This helps with testing and debugging as well.Don’t declare constants, variables for the sake of declaring them or just because it’s the practice. Think of the usage, search-ability, readability, and reusability.Implement correct exception handling. Because we don’t want dumps when executing the program and if something didn’t work, we don’t want to leave the users in the dark with no proper information. Check for sy-subrc after DB reads and decide how the program should progress.Check for IS ASSIGNED after assigning to field-symbols.Have a sy-subrc <> 0 block after FMs/APIs that return exceptions and communicate such errors to users appropriately.Keep code comments to a minimum. Never use comments to repeat the code in speaking language. This is a common trap that developers fall into as we think we should explain the logic to a non-developer who will be going through the program at a later time. Avoid this.The code should be self-explanatory. If the clean code guides are followed, the code will become much more readable and self-explanatory. In case where you do add comments, use the comment to explain “why” or the “business purpose”.Aligning with the coding guidelines of the organization, add a comment block at the header of the program to give a summary of the purpose of the program, owner/developer, change request details/ documentation links.And if you happen to do modifications, you can add a new block below the header to mention change details. Then, rely on the SAP’s versioning feature to compare what was changed from the previous version instead of adding the developer name, TR details on every line that was changed. After a while, this makes the code too cluttered and unreadable.Make it a habit to execute the ATC check after the development and fix priority 1, 2 errors and minimize the priority 3 errors as well. AfterPhew! Now you are done with the bigger part of the task. What to do after the development?Test! Test for happy flow as well as exceptional flows. As a practice, request the test data and expected outcome from the BA/functional consultant/respective leads as you are starting the development. This will give them sufficient time to prepare the data and share.Use this data to do the developer’s unit test of the program and document the test results. This documentation helps ensure that you cover all relevant scenarios and also it will be proof that the program worked as requested. Besides the major execution flows, also test the program for higher volumes of data (stress testing). This is critical because usually the data volumes and system capabilities are drastically different between development and production systems. Maybe there will be practical limitations to getting a huge volume of data in the development system for tests. Then, at least try your best to do this in the test/quality system.Finally, document the development details on the chosen platform. Some organizations will opt for tools like Jira/Confluence whereas some would rely on Sharepoint/Word documents. Whichever it is, ensure that as soon as the development is complete, that you prepare the technical design documentation. It would be best if the documentation covers the business requirement, overall design, and then get to the specifics of the program. This shouldn’t be a copy-paste of the code or the pseudo-code. But, any key factors considered, decisions made, and special technical points must be emphasized and recorded. It’s best to complete the documentation as soon as the development is complete because there’s a higher chance of forgetting the crucial details as you move on to a different task. ConclusionMost of the points shared may seem like common sense. But, I’ve seen developers overlooking these details time and time again and ending up in the same kind of issues repeatedly. Hence, re-iterated some points with a hint of direction because common sense isn’t that common after all.For a developer, the programs you develop are your artwork. Your product.So, it’s best to factor in these points and create your masterpiece so it is something you can be proud of and something that makes life easier for everyone.After all, the whole point of an ERP system is to make the lives of the business users easier and help the business run smoother!   Read More Technology Blogs by Members articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author