REPORT {{p}}bake_sales. DATA gv_shop TYPE {{p}}deliv-shop. PARAMETERS p_date TYPE d OBLIGATORY. SELECT-OPTIONS s_shop FOR gv_shop. CLASS lcl_report DEFINITION FINAL. PUBLIC SECTION. TYPES: BEGIN OF ty_raw, shop TYPE {{p}}deliv-shop, loaves TYPE {{p}}deliv-loaves, unit_price TYPE {{p}}deliv-unit_price, END OF ty_raw. TYPES tt_raw TYPE STANDARD TABLE OF ty_raw. TYPES: BEGIN OF ty_line, shop TYPE {{p}}deliv-shop, loaves TYPE i, revenue TYPE {{p}}deliv-unit_price, deliveries TYPE i, END OF ty_line. TYPES tt_line TYPE STANDARD TABLE OF ty_line. METHODS aggregate IMPORTING it_raw TYPE tt_raw CHANGING ct_lines TYPE tt_line. METHODS display CHANGING ct_lines TYPE tt_line. ENDCLASS. CLASS lcl_report IMPLEMENTATION. METHOD aggregate. DATA lt_sorted TYPE tt_raw. DATA ls_raw TYPE ty_raw. DATA ls_line TYPE ty_line. CLEAR ct_lines. lt_sorted = it_raw. SORT lt_sorted BY shop. LOOP AT lt_sorted INTO ls_raw. AT NEW shop. CLEAR ls_line. ls_line-shop = ls_raw-shop. ENDAT. ls_line-loaves = ls_line-loaves + ls_raw-loaves. ls_line-revenue = ls_line-revenue + ls_raw-loaves * ls_raw-unit_price. ls_line-deliveries = ls_line-deliveries + 1. AT END OF shop. APPEND ls_line TO ct_lines. ENDAT. ENDLOOP. SORT ct_lines BY revenue DESCENDING shop ASCENDING. ENDMETHOD. METHOD display. DATA lo_alv TYPE REF TO cl_salv_table. DATA 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. DATA go_report TYPE REF TO lcl_report. DATA gt_raw TYPE lcl_report=>tt_raw. DATA gt_lines TYPE lcl_report=>tt_line. START-OF-SELECTION. SELECT * FROM {{p}}deliv WHERE deliv_date = p_date AND shop IN s_shop INTO CORRESPONDING FIELDS OF TABLE gt_raw. CREATE OBJECT go_report. go_report->aggregate( EXPORTING it_raw = gt_raw CHANGING ct_lines = gt_lines ). go_report->display( CHANGING ct_lines = gt_lines ). CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. PRIVATE SECTION. METHODS add_raw IMPORTING iv_shop TYPE {{p}}deliv-shop iv_loaves TYPE i iv_price TYPE {{p}}deliv-unit_price CHANGING ct_raw TYPE lcl_report=>tt_raw. METHODS sums_one_shop FOR TESTING. METHODS sorts_by_revenue FOR TESTING. METHODS keeps_shops_apart FOR TESTING. ENDCLASS. CLASS ltc_report IMPLEMENTATION. METHOD add_raw. DATA ls_raw TYPE lcl_report=>ty_raw. ls_raw-shop = iv_shop. ls_raw-loaves = iv_loaves. ls_raw-unit_price = iv_price. APPEND ls_raw TO ct_raw. ENDMETHOD. METHOD sums_one_shop. DATA lt_raw TYPE lcl_report=>tt_raw. DATA lt_lines TYPE lcl_report=>tt_line. DATA ls_line TYPE lcl_report=>ty_line. DATA lo_report TYPE REF TO lcl_report. DATA lv_exp TYPE {{p}}deliv-unit_price. DATA lv_count TYPE i. add_raw( EXPORTING iv_shop = 'NORD' iv_loaves = 10 iv_price = '2.00' CHANGING ct_raw = lt_raw ). add_raw( EXPORTING iv_shop = 'NORD' iv_loaves = 5 iv_price = '4.00' CHANGING ct_raw = lt_raw ). CREATE OBJECT lo_report. lo_report->aggregate( EXPORTING it_raw = lt_raw CHANGING ct_lines = lt_lines ). DESCRIBE TABLE lt_lines LINES lv_count. cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_count ). READ TABLE lt_lines INTO ls_line INDEX 1. cl_abap_unit_assert=>assert_subrc( exp = 0 ). cl_abap_unit_assert=>assert_equals( exp = 15 act = ls_line-loaves ). cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_line-deliveries ). lv_exp = '40.00'. cl_abap_unit_assert=>assert_equals( exp = lv_exp act = ls_line-revenue ). ENDMETHOD. METHOD sorts_by_revenue. DATA lt_raw TYPE lcl_report=>tt_raw. DATA lt_lines TYPE lcl_report=>tt_line. DATA ls_line TYPE lcl_report=>ty_line. DATA lo_report TYPE REF TO lcl_report. DATA lv_exp TYPE {{p}}deliv-shop. add_raw( EXPORTING iv_shop = 'A' iv_loaves = 10 iv_price = '1.00' CHANGING ct_raw = lt_raw ). add_raw( EXPORTING iv_shop = 'B' iv_loaves = 10 iv_price = '9.00' CHANGING ct_raw = lt_raw ). CREATE OBJECT lo_report. lo_report->aggregate( EXPORTING it_raw = lt_raw CHANGING ct_lines = lt_lines ). READ TABLE lt_lines INTO ls_line INDEX 1. cl_abap_unit_assert=>assert_subrc( exp = 0 ). lv_exp = 'B'. cl_abap_unit_assert=>assert_equals( exp = lv_exp act = ls_line-shop ). ENDMETHOD. METHOD keeps_shops_apart. DATA lt_raw TYPE lcl_report=>tt_raw. DATA lt_lines TYPE lcl_report=>tt_line. DATA lo_report TYPE REF TO lcl_report. DATA lv_count TYPE i. add_raw( EXPORTING iv_shop = 'A' iv_loaves = 1 iv_price = '1.00' CHANGING ct_raw = lt_raw ). add_raw( EXPORTING iv_shop = 'B' iv_loaves = 1 iv_price = '1.00' CHANGING ct_raw = lt_raw ). CREATE OBJECT lo_report. lo_report->aggregate( EXPORTING it_raw = lt_raw CHANGING ct_lines = lt_lines ). DESCRIBE TABLE lt_lines LINES lv_count. cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_count ). ENDMETHOD. ENDCLASS.