Author: Rudramani Pandey

  • Everything you need to know about SAP ABAP Unit Test

    SAP ABAP Unit Test is a feature in the SAP Advanced Business Application Programming (ABAP) environment that allows developers to create and run unit tests for their code. This promotes better code quality, readability, and maintainability. Let’s delve deep into the concept:

    Introduction

    • ABAP Unit is SAP’s native framework for creating and executing unit tests in the ABAP development environment.
    • Unit tests are designed to test individual parts (units) of the software, typically at the method or function level.
    • It allows developers to test individual units of code, such as methods, function modules, and subroutines. This can help to identify and fix bugs early in the development process, and improve the overall quality of the code.

    Purpose of ABAP Unit Test

    • Quality Assurance: Ensures that individual units of source code are working as expected.
    • Refactoring Security: Allows developers to make changes to the codebase without fear of unintentionally introducing errors.
    • Documentation: Unit tests can serve as documentation because they demonstrate how certain functionality is expected to work.

    How It Works

    • ABAP Unit tests are written in the ABAP language itself.
    • The tests are generally located in the same development object or class they’re testing, but they are clearly separated from the actual implementation.
    • The tests can be executed in the ABAP development environment. The system provides instant feedback on whether the tests pass or fail.

    Key Concepts

    • Test Classes: These are special classes in ABAP where unit tests are defined. They typically end with the suffix _UT.
    • Test Methods: These are methods inside test classes that contain the actual test logic. They are marked with the addition FOR TESTING.
    • Test Fixtures: Methods that set up a consistent test environment before each test run. They are often used to initialize data or configurations needed for the tests.
    • Assertions: Used to check if a particular condition is met. If an assertion fails, the test fails.

    Benefits

    • Immediate Feedback: Developers receive immediate feedback after making changes, allowing for quicker debugging.
    • Consistency: Helps in maintaining consistency across the development environment as all developers can run the same tests.
    • Reduces Bugs: By catching issues early in the development process, it can significantly reduce the number of bugs in the production environment.
    • Facilitates Collaboration: Makes it easier for teams to collaborate as they can rely on tests to ensure the integrity of their code.

    Best Practices

    • Isolation: Unit tests should be isolated and independent. The result of a test should not be dependent on whether other tests pass or fail.
    • Granularity: Test only one aspect or behavior at a time.
    • Automate: Ideally, run unit tests as part of an automated build or integration process.
    • Consistency: Ensure that unit tests are consistently maintained and updated as the codebase evolves.

    Limitations

    • Unit tests in ABAP or any language are not a substitute for other testing levels like integration tests or end-to-end tests.
    • They don’t typically interact with external systems like databases or third-party services, so while they can ensure a function works as expected in isolation, they can’t guarantee broader system functionality.

    Creation in ABAP

    • Local Test Classes: Within the ABAP environment, developers can create local classes (within programs or global classes) to write unit tests. These are typically nested within the main program or global class.
      CLASS lcl_test DEFINITION FOR TESTING INHERITING FROM cl_b2p_call.
      
        PRIVATE SECTION.
          DATA: lt_key       TYPE TABLE OF /bobf/t_frw_key,
                lt_messages  TYPE TABLE OF symsg_tab,
                lv_error_msg TYPE string.
      
        METHODS:
          setup,
          teardown,
          test_send_outbproxy_success,
          test_send_outbproxy_error.
      
      ENDCLASS.
      
      CLASS lcl_test IMPLEMENTATION.
      
        METHOD setup.
          CLEAR lt_key.
          CLEAR lt_messages.
        ENDMETHOD.
      
        METHOD teardown.
          " Clean up if necessary
        ENDMETHOD.
      
        METHOD test_send_outbproxy_success.
          DATA: lt_key TYPE TABLE OF /bobf/t_frw_key,
                ls_key TYPE /bobf/t_frw_key.
      
          " Prepare input data
          ls_key-key = 'B7036E6334A61EEE96EC134C77E96235'.
          APPEND ls_key TO lt_key.
      
          " Call the method being tested
          CALL METHOD send_outbproxy
            EXPORTING
              it_key      = lt_key
            IMPORTING
              et_messages = lt_messages
              ev_error    = lv_error_msg.
      
          " Assertions
          cl_abap_unit_assert=>assert_equals( act = lv_error_msg
                                              exp = ''
                                              msg = 'Expected no error message for success.' ).
          
          cl_abap_unit_assert=>assert_equals( act = lines( lt_messages )
                                              exp = 1
                                              msg = 'Expected one message in the message table for success.' ).
      
          " Add more assertions based on your specific success criteria.
      
        ENDMETHOD.
      
        METHOD test_send_outbproxy_error.
          DATA: lt_key TYPE TABLE OF /bobf/t_frw_key,
                ls_key TYPE /bobf/t_frw_key.
      
          " Prepare input data
          ls_key-key = 'InvalidKey'.  " Simulate an invalid key
          APPEND ls_key TO lt_key.
      
          " Call the method being tested
          CALL METHOD send_outbproxy
            EXPORTING
              it_key      = lt_key
            IMPORTING
              et_messages = lt_messages
              ev_error    = lv_error_msg.
      
          " Assertions
          cl_abap_unit_assert=>assert_not_equals( act = lv_error_msg
                                                  exp = ''
                                                  msg = 'Expected an error message for invalid input.' ).
          
          cl_abap_unit_assert=>assert_equals( act = lines( lt_messages )
                                              exp = 1
                                              msg = 'Expected one message in the message table for error.' ).
      
          " Add more assertions based on your specific error criteria.
      
        ENDMETHOD.
      
      ENDCLASS.
      

      In this example:

      • The setup and teardown methods are used for initialization and cleanup.
      • test_send_outbproxy_success and test_send_outbproxy_error are test methods.
      • In each test method, you prepare the input data (lt_key), call the method being tested (send_outbproxy), and then perform assertions to check if the method behaves as expected for success and error cases.

      You can adjust the assertions and test data based on your specific requirements and the behavior of the SEND_OUTBPROXY method.

    • Methods: Within these classes, specific methods are marked with the addition FOR TESTING to indicate they are test methods.
    • Assertions: Inside the test methods, you use ABAP statements like ASSERT or ASSERT_EQUALS to validate the expected outcomes.

    Test in ADT and ABAP SE24

    • ADT (ABAP Development Tools): This is essentially the Eclipse-based IDE for ABAP. Developers can write and execute unit tests directly from here.
    • SE24: This is the Class Builder in the SAP GUI. You can create global classes, which include your test classes and test methods, and execute them directly from this transaction.

    Checkman T Code in SAP

    • CHECKMAN is the T-code for the Code Inspector, a tool for static code analysis in the SAP environment.
    • It helps in identifying performance issues, security vulnerabilities, and violations of coding conventions.
    • While it’s not directly a unit testing tool, it’s vital for ensuring code quality and adherence to best practices.

    Execute Unit Test in ABAP

    • After writing the unit tests, they can be executed directly from the ABAP environment.
    • When you run the unit tests, ABAP provides a detailed log of which tests passed and which failed.
    • For any failed test, you get an error message pointing out the assertion or the line of code causing the failure.

    ABAP Coverage

    • Test coverage in ABAP measures the amount of your codebase that’s tested by unit tests.
    • The ABAP Test Cockpit and ABAP Development Tools in Eclipse provide insights into which lines of code, methods, or classes have been executed during the tests.
    • This is crucial because high test coverage often correlates with fewer bugs, though it’s not a guarantee of software quality by itself.

    ATC Errors during ABAP Unit Test

    • ATC (ABAP Test Cockpit): It’s a central tool for developers to check the quality of their ABAP code.
    • While executing unit tests, you might come across ATC errors. These could be due to a range of issues, from syntax errors to violations of best practices or custom checks defined in your SAP environment.
    • Addressing ATC errors ensures your code is not only functionally correct but also adheres to established coding standards.

    Conclusion

    The ABAP Unit Test framework is a powerful tool in the SAP development toolkit. When used effectively, it can greatly enhance code quality, reduce debugging time, and ensure smoother deployments. Like all testing methodologies, it’s most effective when used in conjunction with other testing and quality assurance practices.

  • Action Control in SAP

    Introduction

    In the vast world of SAP, Action Control serves as a mechanism to automate specific actions based on certain conditions or events. Whether it’s sending out notifications, changing the status of an order, or triggering workflows, Action Control plays a pivotal role in enhancing SAP’s efficiency and minimizing manual interventions. Let’s delve deeper into the concept and understand its significance.

    What is Action Control

    Action Control, often referred to within SAP as “Actions,” provides a way to automate certain tasks or activities based on predefined conditions. For instance, once a sales order is approved, Action Control can be configured to automatically send a notification to the warehouse to prepare for shipment.

    Actions are typically defined by:

    1. Conditions: These are the criteria that determine when a particular action should be triggered.
    2. Methods: These dictate what happens once the action is triggered.

    Benefits of Action Control

    1. Automation: Reduces the need for manual intervention in various business processes.
    2. Consistency: Ensures standard procedures are followed across the organization.
    3. Efficiency: Speeds up processes by automating routine tasks, ensuring faster response times.
    4. Flexibility: Allows for customization to cater to specific business needs.

    Where is Action Control used?

    Action Control can be employed across various modules in SAP, such as:

    1. SAP Customer Relationship Management (CRM): For example, upon creating a service request, an automatic email can be sent to the customer confirming the receipt of their request.
    2. SAP Sales and Distribution (SD): Actions can be used to notify the logistics department once an order is approved.
    3. SAP Supplier Relationship Management (SRM): For instance, after a purchase order is accepted by a vendor, a notification can be sent to the relevant department.
    4. SAP Human Capital Management (HCM): Like sending reminders for training or performance reviews.
    5. SAP EWM: In SAP Supply To Production and Supply To Customer, it is used to define actions that would happen in case the creation of JIT is executed. The JIT triggers other functionalities like EWM update and Proxy calls to Supply To Customer.

    Configuring Action Control

    To leverage the benefits of Action Control, one needs to configure it in the SAP system:

    1. Define Action Profiles and Actions: This involves creating a profile and defining the individual actions within it.
    2. Condition Maintenance: Here, you set the specific conditions under which the action will be triggered.
    3. Determine Processing Time: Decide whether the action should be immediate or scheduled for a specific time.
    4. Link Actions with Business Processes: Integrate the defined actions with the relevant business processes or documents.

    How to implement Action Control in SAP using T Code SAP IMG

    Action Control, a key automation feature in SAP, can be implemented using the SAP Implementation Guide (IMG) through specific T-Codes. The step-by-step guide below will help you set up Action Control in your SAP system using the IMG [This is just a use case, and can vary for different modules]

    Implementing Action Control in SAP through SAP IMG:

    1. Accessing SAP IMG:
      • Log in to your SAP system.
      • Enter T-Code SPRO in the command field. This will open up the SAP IMG screen.
    2. Navigate to Action Control Configuration: Depending on the SAP module you are working in, you will navigate to the relevant path. For instance, in SAP Customer Relationship Management (CRM), you might navigate as:
      • SAP IMG → Customer Relationship Management → Basic Functions → Actions.
    3. Define Action Profiles & Actions:
      • Under the “Actions” section, choose “Define Action Profiles and Actions.”
      • Here, you can create a new action profile or modify an existing one.
      • Within an action profile, define individual actions by providing an action definition, description, and relevant processing class.
    4. Condition Maintenance:
      • Back in the “Actions” section, select “Define Conditions” or “Change Conditions.”
      • For each action, define the criteria or conditions under which the action will be triggered. This can involve setting up conditions based on field values, document statuses, or other relevant criteria.
    5. Determine Processing Time:
      • Still in the “Actions” section, opt for “Determine Processing Time.”
      • Decide whether each action should be triggered immediately, scheduled for a later time, or manually by the user.
    6. Set Up Partner-Dependent Actions (if necessary):
      • If your actions depend on specific partners (like customers or suppliers), navigate to “Define Partner-Dependent Actions.”
      • Here, specify which actions should be linked with which partners.
    7. Integrate Actions with Transactions:
      • Finally, ensure that your actions are integrated with the specific transactions or business processes they relate to.
      • This is crucial to ensure that the action is triggered at the right moment in the process flow.
    8. Testing & Verification:
      • After configuration, it’s a good practice to test the actions in a sandbox or development environment.
      • Create or use an existing transaction that meets the conditions for the action. Ensure that the action gets triggered as expected.
    9. Documentation:
      • Keep detailed documentation of the action profiles, actions, conditions, and any other relevant settings. This will aid future modifications or troubleshooting.
    10. Transport to Production:
    • Once thoroughly tested, transport the configuration to your production system.

    Conclusion

    Action Control in SAP provides an efficient way to automate repetitive tasks, ensure consistency across processes, and enhance overall productivity. By understanding and properly configuring this feature, businesses can significantly improve their operational efficiency and responsiveness. Whether you’re just starting with SAP or looking to refine existing processes, taking a closer look at Action Control can be a game-changer.

  • SAP Next-generation Just-In-Time Supply to Production

    SAP Next-generation Just-In-Time Supply to Production

    Introduction

    In the modern, fast-paced manufacturing world, companies strive to optimize their processes for efficiency, cost-saving, and customer satisfaction. SAP’s next-generation Just-In-Time (JIT) Supply to Production provides an integrated solution that allows manufacturing entities to streamline their production processes, reduce inventory costs, and ensure that the right components arrive just when needed. Let’s dive into this state-of-the-art solution.

    SAP Next-generation Just-In-Time Supply to Production

    What is SAP Just-In-Time Supply to Production

    SAP Just-In-Time Supply to Production is an innovative approach designed for manufacturing setups that thrive on JIT principles. With the challenges posed by varied customer demands and limited storage space, manufacturers need a sophisticated solution. The SAP JIT ensures that components, whether sourced externally or from internal warehouses, are delivered in the right quantity and at the precise moment they’re needed for production, ensuring optimal workflow and reducing unnecessary inventory overhead.

    JIT-Process Architecture

    JIT-Process Architecture

    This architecture represents a flowchart detailing the Just-In-Time (JIT) Supply to Production process in an SAP environment. The diagram shows how various components and functionalities of SAP interrelate, especially in the context of materials management, production planning, logistics execution, and transportation. Let’s break it down:

    1. Production Planning:
      • The process begins with “Production Order (PP)”, which may derive from a “Planned Order” either from PP-REM or PPDS.
      • These planned orders create demands for either JIT (Just-In-Time) or JIS (Just-In-Sequence) processes.
    2. JIT Supply to Production:
      • Master data and communication group management are fundamental components.
      • The control cycles of JIT are managed and modified, leading to various processes like JIT call management, planning of supply to production, scheduling of JIT replenishments, and more.
      • The JIT calls, whether summarized or sequenced, influence the internal replenishment processes and stock transfers.
    3. OEM/Customer (Original Equipment Manufacturer):
      • This section provides an overview and analytics of the JIT supply to production, highlighting potential changes in the plan and monitoring of JIT calls and their components.
    4. Materials Management:
      • This is where scheduling agreements and schedule lines come into play. As materials are planned and ordered, updates to quantities (Qty Updates) are made, which then lead to the creation of various logistics and transportation processes.
    5. Logistics Execution:
      • Before the goods are received, there’s a series of actions such as updating status, delivery creation, setting transfers, and eventually posting the goods receipt.
      • This interacts closely with the Transportation Management and Warehouse Management processes.
    6. Transportation Management:
      • The system manages the transportation of goods via various stages like creating consignment orders, assigning freight units, managing freight orders, and handling advanced shipping & receiving protocols. External replenishments might also be noted via SOAP messages.
    7. Extended Warehouse Management:
      • Once goods are in the warehouse, processes like pick/prepare management, route train loading, and pick execution are carried out. Internal replenishments are managed, and unloading points for goods are defined.
      • The production supply areas and storage bins for different production lines are clearly depicted.
    8. Integration Points:
      • Red dotted lines typically signify integration or informational flow between processes.
      • Green solid lines might indicate a direct flow or process sequence.
    9. Storage and Stock Management:
      • The architecture demonstrates the flow of stock and its management, transitioning between IM-managed source storage locations, destination areas, and EWM-managed areas.

    In essence, this architecture provides a holistic view of how JIT supply to production processes are executed within the SAP environment, integrating production planning, materials management, logistics, transportation, and warehouse management for efficient and streamlined operations.

    Fiori Apps in Just-In-Time Supply to Production

    The SAP Fiori design language brings user experience to the fore, ensuring that processes are not only efficient but also user-friendly. Here are some core apps within the SAP JIT Supply to Production ecosystem:

    a) Manage JIT Calls: This app offers a centralized platform to oversee all JIT calls. You can create, modify, or track JIT calls, ensuring you’re always in sync with your supply needs.

    b) Manage JIT Control Cycles: A control cycle determines the supply frequency and quantity. This app aids in setting up, modifying, or monitoring these cycles, which act as the backbone for your JIT system.

    c) Request Replenishments for Control Cycles: Occasionally, manual intervention may be required to request specific replenishments. This app allows users to make such bespoke requests aligned with established control cycles.

    d) Plan Supply to Production: An intuitive planning tool that integrates with your JIT control cycles, ensuring that your production lines are never starved of the components they need.

    e) Manage JIS calls and Reorder: Just-In-Sequence (JIS) is an extension of JIT, ensuring components arrive not just in time, but also in the sequence they’re needed. This app also provides reordering functionalities in case of unforeseen supply issues.

    f) Monitor Customer JIT Calls: Keeping an eye on the end customer is crucial. This app provides insights into customer JIT calls, enabling manufacturers to foresee and plan for demand spikes or changes.

    g) Manage JIT Delivery Confirmations: Once the components are delivered, confirming their receipt is crucial for inventory tracking and supplier relations. This app streamlines this confirmation process.

    h) Stock Availability Analysis: Real-time visibility into stock levels is critical in a JIT setup. This app provides analytics, trends, and insights into stock availability, ensuring decision-makers are always informed.

    i) Manage Production Supply Areas: Different production lines or units might have distinct supply needs. This app allows for the efficient management of these individualized production supply zones.


    In conclusion, SAP’s next-generation Just-In-Time Supply to Production system is revolutionizing how manufacturers operate. With integrated Fiori apps ensuring a seamless user experience, manufacturers can now optimize their processes, cut down on wastage, and cater to their customers more effectively than ever before. Embracing this solution ensures a competitive edge in the challenging landscape of modern manufacturing.

     

  • Inbound Vs Outbound JIT

    Inbound Vs Outbound JIT

    Introduction

    Have you ever wondered about the intricate dance of products and materials moving in and out of a manufacturing facility? It’s not just a matter of stocking up and shipping out. In the world of Just-In-Time (JIT) manufacturing, the flow is finely tuned to perfection. Let’s delve deeper into the realm of Inbound and Outbound JIT, and see how they differ from each other.

    Inbound Vs Outbound JIT Banner

    Inbound JIT

    Imagine a bustling car manufacturing plant. Now, instead of having months’ worth of parts stocked up in a warehouse, the facility gets its components delivered just when they’re about to be used in production. That’s Inbound JIT for you.

    Inbound JIT focuses on the timely delivery of materials and parts from suppliers to the manufacturing facility. It’s all about reducing storage costs, minimizing the space required for inventory, and ensuring that parts are fresh off the delivery truck and straight into production. This methodology requires a strong and reliable relationship with suppliers. The idea is to have components arrive not a moment too early or a second too late.

    Outbound JIT

    Now, let’s flip the script. Once our cars are assembled, they don’t just pile up waiting for someone to buy them. Outbound JIT is all about ensuring that the finished products are delivered to dealerships or end customers precisely when they’re needed.

    Instead of producing large quantities of products and then finding customers for them, manufacturers relying on Outbound JIT produce based on actual demand or close forecasts. This means lower storage costs for finished products and faster delivery times. It’s about ensuring that the time from the end of the production line to the customer’s driveway is as short as possible.

    Inbound Vs Outbound JIT

    At first glance, Inbound and Outbound JIT might seem like two sides of the same coin. And in a way, they are. Both revolve around the concept of ‘just in time’ – minimizing storage and maximizing efficiency. But here’s the difference:

    • Focus: While Inbound JIT is concerned with materials coming into the production line, Outbound JIT focuses on getting the finished product out to the customers efficiently.
    • Relationships: For Inbound JIT, the manufacturer’s relationship with its suppliers is crucial. Reliable and timely deliveries are the name of the game. On the other hand, Outbound JIT is more about understanding customer demand and ensuring that production schedules align with it.
    • Benefits: Both methods aim to reduce storage costs. Inbound JIT ensures fresher components and minimizes the risk of inventory obsolescence. Outbound JIT, meanwhile, ensures that finished products don’t languish in storage, which can be particularly vital for products that are time-sensitive or have short shelf lives.

    Inbound Vs Outbound JIT

    When the influx of raw materials and parts are made within supplier and manufacturing plants then it involves Inbound JIT. When the movement of final goods is made from supplier to end users, then it involves Outbound JIT. Read more about Inbound Delivery and Outbound Delivery.

    In conclusion, while both Inbound and Outbound JIT share a common philosophy, their applications are distinct yet complementary. In the finely-tuned ballet of modern manufacturing, both play essential roles in ensuring that companies remain efficient, responsive, and cost-effective. And that, my friend, is the magic of JIT in action!

  • Just-In-Time (JIT) and Just-In-Sequence (JIS) Processing in SAP S/4HANA

    Just-In-Time (JIT) and Just-In-Sequence (JIS) Processing in SAP S/4HANA

    Introduction

    The automotive industry is all about speed, precision, and meeting customer needs. A significant part of this involves ensuring that components are available exactly when they’re needed, and in the correct order. This is where Just-in-time (JIT) and Just-in-sequence (JIS) processing come into play. Today, we’re diving into how SAP S/4HANA, a leading enterprise resource planning software, is revolutionizing this process.

    SAP JIT

    What is Just-In-Time (JIT)?

    JIT, or Just-In-Time, is a production method rooted in the principle of reducing in-process inventory. Given the sheer variety of configurations automotive manufacturers offer, there’s a need to have a multitude of components on hand. However, with space at a premium on production lines, it’s crucial to keep inventory lean. This means having suppliers or internal warehouses deliver small quantities of components multiple times a day. In a JIT environment, the sequence in which these parts are delivered doesn’t matter.

    Just-in-Time inventory, commonly referred to as JIT, is an inventory management strategy in which raw materials arrive as soon as production is scheduled to begin but no sooner. The goal is high-volume production with minimal inventory on hand to meet demand and eliminate waste.

    What is JIT in SAP?

    JIT calls in SAP are created for a supplier based upon demands that can be either planned or production orders and even based upon the safety stocks in case of consumption-driven scenarios.

    SAP provides multiple T-Codes to manage the JIT scenarios. SAP has also introduced Fiori Apps to manage JIT for S/4 HANA customers.

    It is important to note that JIT is a very complex process as it highly depends upon the efficacy of the ordering system so that items are delivered with the right amount at the right time.

    SAP JIT Types

    Based on scenarios JIT can be divided into two structures

    • JIT Supply to Customer: Also, known as JIT S2C covers the JIT processes from the perspective of a supplier.
    • JIT Supply to Production: Also, known as JIT S2P covers the JIT processes from the perspective of Manufacturers.

    JIT in R/3 ABAP

    SAP on-premise system provides all the methods that can be used to maintain a plan, create scheduling agreements, create a JIT order, plan a JIT forecast order, and many other relevant operations. Various Reports and T-codes are available to create and manage the same such as:

    JIT in S/4 HANA

    SAP S/4 HANA provides various Fiori Apps that can be used to create, manage and plan a JIT. Different Apps provide different functionality. The technologies involved for the same include ABAP CDS, BOPF, ABAP RAP, and Fiori.

    What is Just-In-Sequence (JIS)

    Unlike JIT, Just-In-Sequence (JIS) focuses on delivering the right components to the production line in the exact sequence they are needed. This becomes especially crucial when suppliers are building complex modules or sets that are directly delivered to the line.

    Just-In-Time (JIT) and Just-In-Sequence (JIS) Processing in SAP S/4HANA

    SAP S/4HANA has risen to the occasion, offering next-gen JIT and JIS processing, catering to both automotive manufacturers and their wider ecosystems. It provides support for both summarized JIT calls and sequenced JIT calls from both outbound and inbound perspectives.

    JIT Supply to Production

    Delving deeper into the JIT Supply to Production, we see a demand-triggered pull signal to either internal or external supply sources. The highlights of this process include:

    • Flexibility: You can cater to both summarized and sequenced JIT calls.
    • Integration: Seamless linkage with SAP S/4HANA inventory management and SAP Extended Warehouse Management (SAP EWM) means tasks can be directly created in embedded EWM.
    • Adaptability: Reordering of sequenced JIT calls in case of damage or quality issues is possible, ensuring production isn’t halted.
    • Real-time Transparency: With embedded analytics, companies can have an instant overview of their operational system, facilitating better decision-making.

    What’s more, the use of communication groups for multiple JIS call recipients and lifecycle management for control cycles ensures that this system can be tailored to fit specific customer needs.

    JIT Supply to Customer

    Switching gears to JIT Supply to Customer, we find a similarly robust system. Key takeaways here include:

    • End-to-End Process Support: With both summarized and sequenced JIT calls being supported, companies have a comprehensive toolkit at their disposal.
    • Flexibility: Rules-based component group determination, combined with simplified grouping of sequenced JIT calls, allows for precise and efficient packing and delivery.
    • Usability: The new SAP Fiori user interface, combined with a monitoring app for JIT calls, ensures that the system is both powerful and user-friendly.
    • Transparency: Thanks to SAP S/4HANA’s embedded analytics, companies can get a clearer view of their stock availability and demand analysis.

    In essence, SAP S/4HANA’s next-gen JIT solutions elevate the JIT processing, offering automotive companies the tools they need to streamline processes, enhance reliability, and ultimately, boost customer satisfaction.

    In conclusion, as the automotive world becomes more complex and customer-centric, systems like SAP S/4HANA’s JIT and JIS processes will be the linchpin holding production lines together, ensuring that the right part is always at the right place, at the right time.

  • Everything you need to know about SAP ABAP New Syntax 7.5

    Everything you need to know about SAP ABAP New Syntax 7.5

    Introduction

    Hey, code enthusiasts! Remember the days when SAP ABAP felt a bit like trying to chat using an old-school rotary phone? Well, not anymore! With SAP ABAP 7.5, we’ve entered the age of smartphones! (Okay, not literally, but in the syntax sense.)

    Comparison between old and new syntax with example

    Before I bore you with words, let’s see a quick example to show off this shiny new syntax.

    Old Way:

    DATA: lt_materials TYPE TABLE OF mara,
          ls_material  TYPE mara.
    SELECT * FROM mara INTO TABLE lt_materials WHERE matnr = '1000'.
    READ TABLE lt_materials INTO ls_material WITH KEY matnr = '1000'.
    

    New, Cooler Way in 7.5:

    DATA(lt_materials) = VALUE #( SELECT * FROM mara WHERE matnr = '1000' ).
    DATA(ls_material)  = VALUE #( lt_materials[ matnr = '1000' ] ).
    

    See the difference? The new syntax is more concise and feels modern. It’s like comparing texting with emojis to writing a full-blown letter. Both get the message across, but one’s definitely snazzier!

    Why we should use the new SAP Syntax

    So, you might be thinking, “Cool example, but why should I change?” Well, here are some compelling reasons:

    • It’s Efficient: The new syntax is more streamlined, which means less code and quicker results. And let’s be honest, who doesn’t want that?
    • Readability: If you’ve ever tried deciphering someone else’s code (or even your own from months ago), you know the struggle. With the new syntax, the code structure is clearer, making it easier to read, understand, and maintain.
    • It’s Modern: Just like updating your phone or your favorite app, updating your syntax keeps you current. It aligns with the latest programming paradigms and makes sure you’re ready for whatever SAP throws next.

     

    Old and new ABAP syntax – overview sheet

    If you see this Consider using this
    DATA and FIELD-SYMBOLS declarations Inline declarations
    MOVE CORRESPONDING Constructor expression CORRESPONDING, or CL_ABAP_CORRESPONDING
    struc1-field1 = struc2-fielda
    struc1-field2 = struc2-fieldb
    Constructor expression CORRESPONDING, or CL_ABAP_CORRESPONDING;

    Constructor expression VALUE

    CREATE DATA / CREATE OBJECT Constructor expression NEW
    GET REFERENCE OF Constructor expression REF
    variable only used once, e.g. parameter for a method call Constructor expression VALUEInline declarations
    helper variable for type conversion Constructor expression CONV
    ?= Constructor expression CAST
    assigning a value to a single variable within several case or if blocks, e.g. IF cond. var = 1. ELSE. var = 2. ENDIF. Constructor expressions SWITCH or COND
    READ TABLE Table expressions; Note: throws exception, while READ TABLE sets sy-subrc. Catch exception and handle error case, or use a standard value
    READ TABLE … TRANSPORTING NO FIELDS line_exists( … ) or line_index( … )
    internal table WITH DEFAULT KEY suitable key, or WITH EMPTY KEY
    LOOP AT… FOR … IN in constructor expressions
    [result of method call] IS (NOT) INITIAL, or [result of method call] = abap_true/abap_false predicative method call ( omit the ” = abap_true” part )
    DO / WHILE FOR … UNTIL / WHILE in constructor expressions
    calculating or otherwise assembling one result from input data, e.g. from table rows Constructor expression REDUCE; Note: “one result” can be a value, but also a table or complex object
    LOOP AT … AT NEW, or other means of going through grouped data LOOP AT … GROUP BY … / LOOP AT GROUP
    LOOP + DELETE Constructor expression FILTER
    type checking (?= with TRY/CATCH block, or usage of CL_ABAP_TYPEDESCR) IS INSTANCE OF, CASE TYPE OF
    CONCATENATE; string literals String templates
    SELECT new SQL expressions; use @ to escape host variables

    The above difference is taken from here.

    ABAP Syntax 7.5

    You can read the latest updates over here.

    And there you have it – a quick trip down SAP ABAP 7.5 lane. So, next time you’re about to dive into an ABAP project, give this new syntax a spin. You might just find it as refreshing as a cold drink on a hot day! 🍹🔆 Happy coding! 🚀

  • Difference between SAP ERP, SAP ByDesign and SAP Business One

    Difference between SAP ERP, SAP ByDesign and SAP Business One

    Introduction

    Ever found yourself lost in the maze of SAP products? 🤔 We’ve all been there. Today, let’s unravel the mystery behind SAP ERP, SAP ByDesign, and SAP Business One. By the end of this article, you’ll be an expert!

    SAP ERP Business One

    What is SAP ERP?

    Imagine running a huge multinational company. You’ve got countless departments, and all of them need to talk to each other, right? That’s where SAP ERP comes in. It’s like the backbone software, connecting everything from finance, HR, and supply chain to procurement. It’s the granddaddy of SAP products, ideal for large enterprises.

    What is SAP ByDesign?

    Picture this: you’re running a growing mid-sized business, and you need something robust but not overly complex. Enter SAP ByDesign! It’s a cloud-based (yes, everything’s on the cloud ☁️) ERP solution. Perfect for mid-sized businesses, it manages everything from finance to HR but without the heavy-duty setup of SAP ERP.

    What is SAP Business One?

    Now, for the small but mighty businesses, SAP hasn’t forgotten about you. SAP Business One is tailored just for you! It’s a one-stop-shop for all things business, covering everything from finance to customer relationship management. Simple, streamlined, and no fuss!

    Difference between SAP ERP, SAP ByDesign, and SAP Business One

    Alright, quick recap time:

    • SAP ERP: It’s the heavy lifter, designed for large enterprises. Think of it as a Swiss army knife with a tool for every department.
    • SAP ByDesign: Cloud-based, mid-sized perfection. It’s like the nimble, smart cousin of SAP ERP.
    • SAP Business One: Small business superstar. It’s like that compact, multi-tool gadget that’s easy to carry and gets all the basic jobs done.

    What to choose between SAP ERP, SAP ByDesign, and SAP Business One

    Decision time! 🤓

    • If you’re a large company with a complex structure, SAP ERP is your best bet.
    • Growing business, looking for something comprehensive but easy? Go with SAP ByDesign.
    • And for those small businesses wanting an all-in-one solution without any of the complications, SAP Business One is the one (pun intended) for you!

    There you have it! SAP decoded. Remember, the best solution is the one that aligns with your business size, needs, and goals. Happy SAP-ing! 🚀

  • How to create introduction guides in SAP UI5

    Introduction

    In modern web applications, ensuring that users understand and navigate through the interface efficiently is paramount. This becomes especially vital in comprehensive platforms like SAP UI5, where complex functionalities and data-driven interfaces are the norms. “How to create introduction guides in SAP UI5” serves as a comprehensive guide to set up intuitive step-by-step onboarding instructions for your SAP UI5 application. From header bars, filters, tables, to footer buttons, this guide elucidates how to create a guided tour, ensuring that users have a clear understanding of each interface element. Dive in to provide your users with a smooth introduction to your UI5 application’s functionalities.

    How to create introduction guides in SAP UI5

    How to create introduction guides in SAP UI5

    To implement the introduction guide along with the described page, you can leverage the sap.m library of SAP UI5 and the sap.ui.core.delegate.ItemNavigation class for the guided introduction. Let’s go step-by-step:

    1. Initial Setup

    Include the required libraries in your XML view:

    xmlns:m="sap.m"
    xmlns:core="sap.ui.core"
    

    2. Setup View with hardcoded data

    <mvc:View controllerName="IntroductionGuides.IntroductionGuides.controller.View1" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"
        xmlns="sap.m" xmlns:core="sap.ui.core">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page title="My Page">
                        <customHeader>
                            <Bar>
                                <contentRight>
                                    <Button text="Profile" id="profileBtn"/>
                                    <Button text="Logout" id="logoutBtn"/>
                                </contentRight>
                            </Bar>
                        </customHeader>
                        <content>
                            <VBox>
                                <!-- Filter Section -->
                                <HBox>
                                    <Input placeholder="Search..." id="searchFilter"/>
                                    <ComboBox>
                                        <core:Item key="1" text="Item 1"/>
                                        <core:Item key="2" text="Item 2"/>
                                    </ComboBox>
                                </HBox>
                                <!-- Table Section -->
                                <Table id="dataTable">
                                    <columns>
                                        <Column width="12em">
                                            <Text text="Product"/>
                                        </Column>
                                        <Column minScreenWidth="Tablet" demandPopin="true">
                                            <Text text="Supplier"/>
                                        </Column>
                                    </columns>
                                    <items>
                                        <ColumnListItem>
                                            <cells>
                                                <Text text="Product 1"/>
                                                <Text text="SupplierName 1"/>
                                            </cells>
                                        </ColumnListItem>
                                    </items>
                                </Table>
                            </VBox>
                        </content>
                        <footer>
                            <Bar id="footerBar">
                                <contentRight>
                                    <Button text="Button 1"/>
                                    <Button text="Button 2"/>
                                </contentRight>
                            </Bar>
                        </footer>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

    3. Build the Page Layout

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/m/Popover"
    ], function (Controller, Popover) {
        "use strict";
    
        return Controller.extend("IntroductionGuides.IntroductionGuides.controller.View1", {
    
            onAfterRendering: function () {
                this.getView().setModel(new sap.ui.model.json.JSONModel({
                    hardcodedData: [ /* your data here */ ],
                    hardcodedFilters: [ /* your filter data here */ ]
                }));
    
                // Start the introduction guide once the UI is rendered
                this.startIntroduction();
            },
    
            startIntroduction: function () {
                var aSteps = [{
                    id: "profileBtn",
                    text: "This is the profile button."
                }, {
                    id: "logoutBtn",
                    text: "Click here to log out."
                }, {
                    id: "searchFilter",
                    text: "Search using this filter."
                }, {
                    id: "comboFilter",
                    text: "Choose filters from this dropdown."
                }, {
                    id: "dataTable",
                    text: "This is your main data table."
                }, {
                    id: "footerBar",
                    text: "Footer contains various operations."
                }];
    
                var iCurrentStep = 0;
    
                var fnShowStep = function () {
                    if (iCurrentStep >= aSteps.length) {
                        // Completed the introduction
                        return;
                    }
    
                    var oControl = this.getView().byId(aSteps[iCurrentStep].id);
                    if (!oControl) {
                        iCurrentStep++;
                        fnShowStep.call(this);
                        return;
                    }
    
                    var oPopover = new Popover({
                        title: "Step " + (iCurrentStep + 1),
                        content: new sap.m.Text({
                            text: aSteps[iCurrentStep].text
                        }),
                        contentWidth: "350px", // set the desired width here
                        placement: sap.m.PlacementType.Bottom, // initially set to show below the control
                        footer: new sap.m.Toolbar({
                            content: [
                                new sap.m.ToolbarSpacer(),
                                new sap.m.Button({
                                    text: "Next",
                                    press: function () {
                                        oPopover.close();
                                        iCurrentStep++;
                                        fnShowStep.call(this);
                                    }.bind(this)
                                })
                            ]
                        })
                    });
    
                    var oControlPosition = oControl.getDomRef().getBoundingClientRect();
                    if (oControlPosition.top > window.innerHeight / 2) {
                        oPopover.setPlacement(sap.m.PlacementType.Top); // if control is in the bottom half of the screen, show popover above it
                    }
    
                    oPopover.openBy(oControl);
                };
    
                fnShowStep.call(this);
            }
    
        });
    });

    The startIntroduction method will contain the logic for showcasing different sections. This logic can use modals, popovers, or tooltips to display guidance text. For brevity, I’ve not implemented the detailed logic in the example, but you can use libraries like Intro.js or write custom logic to guide users through the different sections.

    The general idea is to highlight and provide information for each section, making the UI interactive and user-friendly for new users.

  • How to Display Disclaimer Page for GDPR in SAP UI5?

    Introduction

    Learn the straightforward approach to displaying a GDPR-compliant disclaimer page in SAP UI5. In this guide, we walk you through the steps to create a popup that appears as your application starts, ensuring users read and acknowledge the disclaimer before proceeding. This method, leveraging the sap.m.Dialog and sap.m.VBox controls, is crucial for applications needing to meet GDPR requirements. Follow along to integrate this solution into your SAP UI5 application.

    How to Display Disclaimer Page for GDPR in SAP UI5

    How to Display Disclaimer Page for GDPR in SAP UI5?

    To achieve this in SAP UI5, you can use a Dialog control with a CheckBox inside. Here’s a step-by-step guide to create this functionality:

    1. Add necessary libraries: Ensure you’ve added the following libraries to your SAP UI5 project’s index.html or as per your application structure:

    <script src="resources/sap/m/library.js" id="sap-ui-bootstrap"></script>
    <script src="resources/sap/ui/layout/library.js"></script>
    

     

    2. Create the Disclaimer Dialog: You can add this in your Component.js or App.controller.js‘s onInit function or any initial function that loads as soon as the app starts.

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/m/Dialog",
        "sap/m/Text",
        "sap/m/CheckBox",
        "sap/m/Button"
    ], function(Controller, Dialog, Text, CheckBox, Button) {
        "use strict";
    
        return Controller.extend("your.controller.path", {
            onInit: function() {
                this._showDisclaimer();
            },
    
            _showDisclaimer: function() {
        var oVBox = new sap.m.VBox({
            items: [
                new sap.m.Text({ 
                    text: 'Your GDPR compliance related content here. By continuing to use this application, you accept the data terms and conditions.' 
                }),
                new sap.m.CheckBox({ 
                    text: 'I have read and understood the disclaimer', 
                    selected: false 
                })
            ]
        });
    
        var oDisclaimerDialog = new sap.m.Dialog({
            title: 'Disclaimer',
            content: [oVBox],
            beginButton: new sap.m.Button({
                text: 'Continue',
                enabled: false,  // Disabled initially
                press: function() {
                    oDisclaimerDialog.close();
                    
                    // Logic to save acceptance in the database would be here.
                    
                    // Display the success message
                    sap.m.MessageToast.show("Your acceptance is saved in the database, you will not be asked again!");
                }
            }),
            afterClose: function() {
                oDisclaimerDialog.destroy();
            }
        });
    
        oDisclaimerDialog.open();
    
        // Enabling the continue button only when the checkbox is selected
        oVBox.getItems()[1].attachSelect(function(oEvent) {
            var bSelected = oEvent.getParameter("selected");
            oDisclaimerDialog.getBeginButton().setEnabled(bSelected);
        });
    }
    
        });
    });
    

    The above code snippet places the Text and CheckBox inside a VBox. This VBox is then set as the content of the Dialog. This arrangement ensures a neat vertical alignment of the disclaimer content and the checkbox.

    In the press event of the “Continue” button, right after closing the dialog, the sap.m.MessageToast is used to display a success message. Note that you will need to incorporate the logic to save this acceptance to the database where I have added the comment.

  • Print Full Screen in SAP UI5

    Introduction

    Learn how to print a full screen in SAP UI5 using this straightforward guide. Using HTML and JavaScript, we’ll walk you through the steps to integrate efficient printing capabilities in your SAP UI5 application. Whether it’s an entire page or specific sections, this tutorial ensures you capture the details you need. Enhance your SAP UI5 user experience by adding this practical feature. Thus, you will learn How to print UI5 page.

    Print in SAP UI5 using Windows Function

    To perform a print in SAP UI5 using HTML and JavaScript, you can utilize the `window.print()` method. This method prompts the user to print the current page. You can just use CTRL + P in your keyboard to trigger print in Windows laptops.

    Here’s a simple way to do it:

    1. Create a Button in your XML View:

    <Button text="Print" press="onPrint"/>
    

    2. Define the onPrint function in your Controller:

    onPrint: function() {
        window.print();
    }
    

    When the button is pressed, the `onPrint` function will be executed, and the user will be prompted to print the current page.

    Print in SAP UI5 after converting to Image

    HTML Code:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.3/html2canvas.min.js"></script>

    View Code:

    <Button text="Print after converting to Image" press="onPrinCapturet"/>

    Controller Code:

    onPrinCapturet: function () {
                var oPage = this.getView().byId("page"); // Assuming "page" is the id of your main Page or container in the XML view
    
                if (oPage && oPage.getDomRef()) {
                    var oDomElement = oPage.getDomRef();
    
                    html2canvas(oDomElement).then(canvas => {
                        var oImgData = canvas.toDataURL("image/png");
    
                        // Open a new window or iframe and load the image data to print
                        var oPrintWindow = window.open('', '_blank');
                        oPrintWindow.document.write('<img src="' + oImgData + '" onload="window.print();"/>');
                    });
                }
            },

    Print specific content in SAP UI5

    However, if you want to print specific content (not the entire page), you can utilize a hidden `iframe`:

    1. Create a Hidden iFrame in your HTML:

    <iframe id="printFrame" style="display:none;"></iframe>
    

    2. Add the Print Button in the View:

    Add id as “idFrame” to the view.

    <Button text="PrintFrame" press="onPrint"/>
    

    3. JavaScript to load content and print:

    onPrintFrame: function () {
        var oFrame = document.getElementById("printFrame");
        var oContentWindow = oFrame.contentWindow;
        var oDoc = oContentWindow.document;
        // var oViewContent = this.getView().getContent()[0]; // get content of the whole view
        var oViewContent = this.getView().byId("idFrame");  // get content of the vbox view
        var sHtml = oViewContent.getDomRef().outerHTML;
        oDoc.open();
        oDoc.write("<html><head><title>Print Content</title></head><body>");
        // oDoc.write("<h1>This is the content to print</h1>"); // Replace this with the content you want to print
        oDoc.write(sHtml);  // passing the content of the UI5 view
        oDoc.write("</body></html>");
        oDoc.close();
        oContentWindow.print();
    }

    In the example above, the content to print is loaded into the hidden iFrame and then printed. This way, only the specific content (and not the entire UI5 application) gets printed.

    Please note: Printing from a web application can vary based on the browser, so always test your printing function on different browsers to ensure compatibility.

     

    Full Code

    HTML

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>My Project Ideas</title>
            <link rel="icon" type="image/x-icon" href="https://myprojectideas.com/wp-content/uploads/2021/08/cropped-Screenshot-2021-07-26-at-1.39.04-PM.png"/>
            <script id="sap-ui-bootstrap"
                src="resources/sap-ui-core.js"
                data-sap-ui-theme="sap_fiori_3"
                data-sap-ui-resourceroots='{"PrintPage.PrintPage": "./"}'
                data-sap-ui-compatVersion="edge"
                data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
                data-sap-ui-async="true"
                data-sap-ui-frameOptions="trusted">
            </script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.3/html2canvas.min.js"></script>
        </head>
        <body class="sapUiBody">
            <iframe id="printFrame" style="display:none;"></iframe>
            <div data-sap-ui-component data-name="PrintPage.PrintPage" data-id="container" data-settings='{"id" : "PrintPage"}'></div>
        </body>
    </html>
    

     

    View

    <mvc:View controllerName="PrintPage.PrintPage.controller.View1" xmlns:core="sap.ui.core" xmlns:layout="sap.ui.layout"
        xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
        <Shell id="shell">
            <App id="app">
                <pages>
                    <Page id="page">
                        <content>
                            <VBox id="idFrame" justifyContent="Center" alignItems="Center" class="sapUiMediumMargin">
                                <!-- Invoice Heading -->
                                <Title text="Invoice" level="H1" class="sapUiSmallMarginBottom"/>
                                <!-- Invoice Date -->
                                <HBox justifyContent="Center" class="sapUiSmallMarginBottom">
                                    <Label text="Invoice Date:" class="sapUiSmallMarginEnd"/>
                                    <Text text="20.09.2023"/>
                                </HBox>
                                <!-- Company Name -->
                                <HBox justifyContent="Center" class="sapUiSmallMarginBottom">
                                    <Label text="Company Name:" class="sapUiSmallMarginEnd"/>
                                    <Text text="RUDE LABS Pvt Ltd"/>
                                </HBox>
                                <!-- Address -->
                                <HBox justifyContent="Center" class="sapUiSmallMarginBottom">
                                    <Label text="Address:" class="sapUiSmallMarginEnd"/>
                                    <Text text="123, Web Street, Noida, 45678"/>
                                </HBox>
                                <!-- Service Details -->
                                <Title text="Service Details" level="H2" class="sapUiSmallMarginBottom"/>
                                <Table class="sapUiMediumMarginBottom">
                                    <columns>
                                        <Column><Text text="Service Name"/></Column>
                                        <Column><Text text="Description"/></Column>
                                        <Column><Text text="Amount"/></Column>
                                    </columns>
                                    <items>
                                        <ColumnListItem>
                                            <cells>
                                                <Text text="Website Development "/>
                                                <Text text="First Installment"/>
                                                <Text text="1000 USD"/>
                                            </cells>
                                        </ColumnListItem>
                                    </items>
                                </Table>
                                <!-- Total Amount -->
                                <HBox justifyContent="End" class="sapUiSmallMarginBottom">
                                    <Label text="Total Amount:" class="sapUiSmallMarginEnd"/>
                                    <Text text="1000 USD"/>
                                </HBox>
                                <!-- Footer Note -->
                                <Text text="Thank you for doing business with us!" class="sapUiSmallMarginTop"/>
                            </VBox>
                            <Button text="Default Print" press="onPressPrint"/>
                            <Button text="Print after converting to Image" press="onPrinCapturet"/>
                            <Button text="PrintFrame" press="onPrintFrame"/>
                        </content>
                    </Page>
                </pages>
            </App>
        </Shell>
    </mvc:View>

     

    Controller

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ], function (Controller) {
        "use strict";
    
        return Controller.extend("PrintPage.PrintPage.controller.View1", {
            onInit: function () {
    
            },
    
            onPrinCapturet: function () {
                var oPage = this.getView().byId("page"); // Assuming "page" is the id of your main Page or container in the XML view
    
                if (oPage && oPage.getDomRef()) {
                    var oDomElement = oPage.getDomRef();
    
                    html2canvas(oDomElement).then(canvas => {
                        var oImgData = canvas.toDataURL("image/png");
    
                        // Open a new window or iframe and load the image data to print
                        var oPrintWindow = window.open('', '_blank');
                        oPrintWindow.document.write('<img src="' + oImgData + '" onload="window.print();"/>');
                    });
                }
            },
    
            onPressPrint: function (oEvent) {
                window.print();
            },
    
            onPrintFrame: function () {
                var oFrame = document.getElementById("printFrame");
                var oContentWindow = oFrame.contentWindow;
                var oDoc = oContentWindow.document;
                // var oViewContent = this.getView().getContent()[0]; // get content of the whole view
                var oViewContent = this.getView().byId("idFrame");  // get content of the vbox view
                // var sHtml = oViewContent.getDomRef().outerHTML;
                oDoc.open();
                oDoc.write("<html><head><title>Print Content</title></head><body>");
                // oDoc.write("<h1>This is the content to print</h1>"); // Replace this with the content you want to print
                oDoc.write(sHtml);  // passing the content of the UI5 view
                oDoc.write("</body></html>");
                oDoc.close();
                oContentWindow.print();
            }
    
        });
    });