REPORT {{p}}planetarium. TYPES: BEGIN OF ty_visit, show_id TYPE {{p}}visit-show_id, tickets TYPE {{p}}visit-tickets, ticket_price TYPE {{p}}visit-ticket_price, END OF ty_visit. TYPES tt_visit TYPE STANDARD TABLE OF ty_visit. TYPES: BEGIN OF ty_line, show_id TYPE {{p}}visit-show_id, tickets TYPE i, revenue TYPE p LENGTH 15 DECIMALS 2, END OF ty_line. TYPES tt_line TYPE STANDARD TABLE OF ty_line. DATA gv_show_id TYPE {{p}}visit-show_id. PARAMETERS p_from TYPE d OBLIGATORY. SELECT-OPTIONS s_show FOR gv_show_id. CLASS lcl_report DEFINITION FINAL. PUBLIC SECTION. METHODS aggregate IMPORTING it_visits TYPE tt_visit CHANGING ct_lines TYPE tt_line. METHODS display CHANGING ct_lines TYPE tt_line. ENDCLASS. CLASS lcl_report IMPLEMENTATION. METHOD aggregate. DATA: ls_visit TYPE ty_visit, ls_line TYPE ty_line. LOOP AT it_visits INTO ls_visit. READ TABLE ct_lines INTO ls_line WITH KEY show_id = ls_visit-show_id. IF sy-subrc = 0. ls_line-tickets = ls_line-tickets + ls_visit-tickets. ls_line-revenue = ls_line-revenue + ls_visit-tickets * ls_visit-ticket_price. MODIFY ct_lines FROM ls_line INDEX sy-tabix. ELSE. CLEAR ls_line. ls_line-show_id = ls_visit-show_id. ls_line-tickets = ls_visit-tickets. ls_line-revenue = ls_visit-tickets * ls_visit-ticket_price. APPEND ls_line TO ct_lines. ENDIF. ENDLOOP. SORT ct_lines BY revenue DESCENDING show_id ASCENDING. ENDMETHOD. METHOD display. DATA: lo_alv TYPE REF TO cl_salv_table, lx_error TYPE REF TO cx_salv_msg. TRY. cl_salv_table=>factory( IMPORTING r_salv_table = lo_alv CHANGING t_table = ct_lines ). lo_alv->display( ). CATCH cx_salv_msg INTO lx_error. MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. ENDTRY. ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA: lt_visits TYPE tt_visit, lt_lines TYPE tt_line, lo_report TYPE REF TO lcl_report. SELECT show_id tickets ticket_price FROM {{p}}visit INTO TABLE lt_visits WHERE visit_date >= p_from AND show_id IN s_show AND tickets <= 0. CREATE OBJECT lo_report. lo_report->aggregate( EXPORTING it_visits = lt_visits CHANGING ct_lines = lt_lines ). lo_report->display( CHANGING ct_lines = lt_lines ). CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. PRIVATE SECTION. METHODS sums_by_show FOR TESTING. METHODS sorted_by_revenue FOR TESTING. METHODS tie_break_by_show FOR TESTING. ENDCLASS. CLASS ltc_report IMPLEMENTATION. METHOD sums_by_show. DATA: lt_visits TYPE tt_visit, lt_lines TYPE tt_line, ls_visit TYPE ty_visit, ls_line TYPE ty_line, lv_exp TYPE p LENGTH 15 DECIMALS 2, lo_report TYPE REF TO lcl_report. CLEAR ls_visit. ls_visit-show_id = 'A'. ls_visit-tickets = 10. ls_visit-ticket_price = '12.00'. APPEND ls_visit TO lt_visits. CLEAR ls_visit. ls_visit-show_id = 'A'. ls_visit-tickets = 5. ls_visit-ticket_price = '12.00'. APPEND ls_visit TO lt_visits. CLEAR ls_visit. ls_visit-show_id = 'B'. ls_visit-tickets = 4. ls_visit-ticket_price = '15.00'. APPEND ls_visit TO lt_visits. CREATE OBJECT lo_report. lo_report->aggregate( EXPORTING it_visits = lt_visits CHANGING ct_lines = lt_lines ). cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). READ TABLE lt_lines INTO ls_line INDEX 1. cl_abap_unit_assert=>assert_equals( exp = 'A' act = ls_line-show_id ). cl_abap_unit_assert=>assert_equals( exp = 15 act = ls_line-tickets ). lv_exp = 15 * 12. cl_abap_unit_assert=>assert_equals( exp = lv_exp act = ls_line-revenue ). READ TABLE lt_lines INTO ls_line INDEX 2. cl_abap_unit_assert=>assert_equals( exp = 'B' act = ls_line-show_id ). cl_abap_unit_assert=>assert_equals( exp = 4 act = ls_line-tickets ). lv_exp = 4 * 15. cl_abap_unit_assert=>assert_equals( exp = lv_exp act = ls_line-revenue ). ENDMETHOD. METHOD sorted_by_revenue. DATA: lt_visits TYPE tt_visit, lt_lines TYPE tt_line, ls_visit TYPE ty_visit, ls_line TYPE ty_line, lo_report TYPE REF TO lcl_report. CLEAR ls_visit. ls_visit-show_id = 'C'. ls_visit-tickets = 1. ls_visit-ticket_price = '5.00'. APPEND ls_visit TO lt_visits. CLEAR ls_visit. ls_visit-show_id = 'D'. ls_visit-tickets = 10. ls_visit-ticket_price = '5.00'. APPEND ls_visit TO lt_visits. CREATE OBJECT lo_report. lo_report->aggregate( EXPORTING it_visits = lt_visits CHANGING ct_lines = lt_lines ). READ TABLE lt_lines INTO ls_line INDEX 1. cl_abap_unit_assert=>assert_equals( exp = 'D' act = ls_line-show_id ). ENDMETHOD. METHOD tie_break_by_show. DATA: lt_visits TYPE tt_visit, lt_lines TYPE tt_line, ls_visit TYPE ty_visit, ls_line TYPE ty_line, lo_report TYPE REF TO lcl_report. CLEAR ls_visit. ls_visit-show_id = 'Z'. ls_visit-tickets = 2. ls_visit-ticket_price = '5.00'. APPEND ls_visit TO lt_visits. CLEAR ls_visit. ls_visit-show_id = 'A'. ls_visit-tickets = 2. ls_visit-ticket_price = '5.00'. APPEND ls_visit TO lt_visits. CREATE OBJECT lo_report. lo_report->aggregate( EXPORTING it_visits = lt_visits CHANGING ct_lines = lt_lines ). READ TABLE lt_lines INTO ls_line INDEX 1. cl_abap_unit_assert=>assert_equals( exp = 'A' act = ls_line-show_id ). READ TABLE lt_lines INTO ls_line INDEX 2. cl_abap_unit_assert=>assert_equals( exp = 'Z' act = ls_line-show_id ). ENDMETHOD. ENDCLASS.