class /HEC1/CL_CONFIG_SW_HELPER definition
  public
  final
  create public .

public section.

  interfaces /HEC1/IF_CONFIG_SW_HELPER .

  methods CONSTRUCTOR .
  class-methods GET_INSTANCE
    returning
      value(RO_INSTANCE) type ref to /HEC1/CL_CONFIG_SW_HELPER .
protected section.
private section.

  data MT_MATERIAL_LIST type /HEC1/T_CONFIG_MATERIAL_LIST .
  data MT_SOFTWARE_ITEM_LIST type /HEC1/T_CONFIG_SW_ITEM_LIST .
  class-data MO_INSTANCE type ref to /HEC1/CL_CONFIG_SW_HELPER .
ENDCLASS.



CLASS /HEC1/CL_CONFIG_SW_HELPER IMPLEMENTATION.


  METHOD /hec1/if_config_sw_helper~delete_solution_list.

    DELETE me->mt_material_list WHERE hec_node_solution = iv_solution_guid.

    DELETE me->mt_software_item_list WHERE hec_node_solution = iv_solution_guid.

  ENDMETHOD.


  METHOD /hec1/if_config_sw_helper~get_material_list.

    " IF apm, solution guid and solution node are not passed, the entire table is returned.
    IF iv_apm_guid IS INITIAL
      AND iv_solution_guid IS INITIAL
      AND iv_node_solution IS INITIAL.
      " return all
      rt_material_list = me->mt_material_list.

      RETURN. ">>>>
    ENDIF.

    " If there is no entry, create an entry.
    IF line_exists( me->mt_material_list[ hec_node_solution = iv_node_solution ] ).
      rt_material_list = VALUE #( FOR mat IN me->mt_material_list
                                  WHERE ( hec_node_solution = iv_node_solution )
                                  ( mat ) ).
    ELSE.
      " Fill Table
      me->/hec1/if_config_sw_helper~set_material_list( iv_apm_guid      = iv_apm_guid
                                                       iv_solution_guid = iv_solution_guid
                                                       iv_node_solution = iv_node_solution ).

      rt_material_list = VALUE #( FOR mat IN me->mt_material_list
                                  WHERE ( hec_node_solution = iv_node_solution )
                                  ( mat ) ).

    ENDIF.

  ENDMETHOD.


  METHOD /hec1/if_config_sw_helper~get_software_item_list.

    IF iv_apm_guid IS INITIAL
      AND iv_solution_guid IS INITIAL
      AND iv_node_solution IS INITIAL.
      " return all
      rt_software_item_list = me->mt_software_item_list.

      RETURN. ">>>>
    ENDIF.

    IF line_exists( me->mt_software_item_list[ hec_node_solution = iv_node_solution ] ).
      rt_software_item_list = VALUE #( FOR sw IN me->mt_software_item_list
                                       WHERE ( hec_node_solution = iv_node_solution )
                                       ( sw ) ).
    ELSE.
      " Fill Table
      me->/hec1/if_config_sw_helper~set_software_item_list( iv_apm_guid      = iv_apm_guid
                                                            iv_solution_guid = iv_solution_guid
                                                            iv_node_solution = iv_node_solution ).

      rt_software_item_list = VALUE #( FOR sw IN me->mt_software_item_list
                                 WHERE ( hec_node_solution = iv_node_solution )
                                 ( sw ) ).

    ENDIF.

  ENDMETHOD.


  METHOD /hec1/if_config_sw_helper~get_tier_list. "TODO_NW move to different location. This does not belong here
**********************************************************************
    "if we don't have yet Phase selected -> then we are not able to select Reference system yet
    IF iv_hec_phase_guid IS INITIAL.
      RETURN.
    ENDIF.

    "ls_solution = /hec1/cl_bopf_config_model_fac=>get_instance( )->/hec1/if_bopf_config_model_get~get_solution_single( iv_guid_solution =  iv_solution_guid ).
    DATA(lt_solutions) = /hec1/cl_bopf_config_model_fac=>get_instance( )->/hec1/if_bopf_config_model_get~get_solution_multi( ).
    DATA(lt_all_tiers) = /hec1/cl_bopf_config_model_fac=>get_instance( )->/hec1/if_bopf_config_model_get~get_tier_multi( ).
    READ TABLE lt_solutions  INTO DATA(ls_source_solution) WITH KEY hec_node_solution = iv_solution_guid.
    IF sy-subrc = 0.
      "remove our parent Solution - so we don't check it later.
      DELETE lt_solutions WHERE hec_node_solution = iv_solution_guid.
      "Remove our tier and Also remove all tiers without Phase defined!
      DELETE lt_all_tiers WHERE hec_node_tier  = iv_hec_node_tier OR hec_phase_guid  IS INITIAL.
      IF lt_all_tiers IS NOT INITIAL.
        "Remove Tiers coming from solutions with different solution Alias
        LOOP AT lt_solutions REFERENCE INTO DATA(lr_source_solution_delete) WHERE hec_solution_guid <> ls_source_solution-hec_solution_guid.
          DELETE lt_all_tiers WHERE parent_key  = lr_source_solution_delete->key.
        ENDLOOP.
      ENDIF.
      IF lt_all_tiers IS NOT INITIAL.
        "Check the Phase Start dates too  - no need to check the same Phase guids
        DATA(lt_phase) =  /hec1/cl_bopf_config_model_fac=>get_instance( )->/hec1/if_bopf_config_model_get~get_phase_multi( ).
        READ TABLE lt_phase REFERENCE INTO DATA(lr_tier_n_phase) WITH KEY hec_node_phase = iv_hec_phase_guid.
        IF sy-subrc = 0.
          LOOP AT lt_all_tiers REFERENCE INTO DATA(lr_tier_for_phase) WHERE hec_phase_guid <> iv_hec_phase_guid.
            READ TABLE lt_phase REFERENCE INTO DATA(lr_tier_r_phase) WITH KEY hec_node_phase = lr_tier_for_phase->hec_phase_guid.
            IF sy-subrc = 0.
              "System R must have a phase start date earlier than or equal to System n
              IF lr_tier_r_phase->hec_phase_start_date > lr_tier_n_phase->hec_phase_start_date.
                DELETE lt_all_tiers WHERE key  = lr_tier_for_phase->key.
              ENDIF.
            ENDIF.
          ENDLOOP.
        ENDIF.
      ENDIF.

    ENDIF.

    rt_tier = lt_all_tiers.
    SORT rt_tier BY hec_tier_descr ASCENDING hec_tier_sid ASCENDING.
  ENDMETHOD.


  METHOD /HEC1/IF_CONFIG_SW_HELPER~SELECT_MATERIAL.

    LOOP AT it_material_list INTO DATA(ls_mat_list).

      ASSIGN me->mt_material_list[ hec_node_solution            = ls_mat_list-hec_node_solution
                                   hec_material_guid            = ls_mat_list-hec_material_guid ] TO FIELD-SYMBOL(<fs_material_list>).
      IF <fs_material_list> IS ASSIGNED.
        <fs_material_list>-hec_mat_selection = ls_mat_list-hec_mat_selection.
      ENDIF.

    ENDLOOP.

  ENDMETHOD.


  METHOD /hec1/if_config_sw_helper~select_software_item.

    LOOP AT it_software_item_list INTO DATA(ls_sw_list).

      ASSIGN me->mt_software_item_list[ hec_node_solution            = ls_sw_list-hec_node_solution
                                        hec_material_guid            = ls_sw_list-hec_material_guid
                                        hec_sw_item_guid             = ls_sw_list-hec_sw_item_guid
                                        hec_sw_item_stack_type_value = ls_sw_list-hec_sw_item_stack_type_value ] TO FIELD-SYMBOL(<fs_software_item_list>).
      IF <fs_software_item_list> IS ASSIGNED.
        <fs_software_item_list>-hec_sw_selection = ls_sw_list-hec_sw_selection.
      ENDIF.

    ENDLOOP.

  ENDMETHOD.


  METHOD /hec1/if_config_sw_helper~set_material_list.

    " Check for existing materials
    DATA(lt_material) = /hec1/cl_bopf_config_model_fac=>get_instance( )->/hec1/if_bopf_config_model_get~get_material_multi( iv_guid_solution = iv_node_solution ).


    " Get solution material
    SELECT *
      FROM /HEC1/I_SolutionMaterialBasic
     WHERE hec_apm_guid      = @iv_apm_guid     AND
           hec_solution_guid = @iv_solution_guid
      INTO TABLE @DATA(lt_sol_material).

    " Set solution material
    DATA(lt_mat_solution) = VALUE /hec1/t_config_material_list( FOR wa_mat IN lt_sol_material
                                                              ( VALUE #( BASE CORRESPONDING #( wa_mat )
                                                                         hec_node_solution   = iv_node_solution
                                                                         hec_mat_selection   = COND #( WHEN wa_mat-hec_material_rel_value = /hec1/if_config_constants=>gc_material_rel-mandatory
                                                                                                         OR line_exists( lt_material[ hec_material_guid = wa_mat-hec_material_guid ] )
                                                                                                       THEN abap_true
                                                                                                       ELSE abap_false                                                                           )
                                                                         hec_field_read_only = COND #( WHEN wa_mat-hec_material_rel_value = /hec1/if_config_constants=>gc_material_rel-mandatory
                                                                                                       THEN abap_true
                                                                                                       ELSE abap_false
                                                                                                       ) ) ) ).

    " Make sure that the lines that are to be inserted do not exist yet
    LOOP AT lt_mat_solution ASSIGNING FIELD-SYMBOL(<fs_mat_list>)
      GROUP BY <fs_mat_list>-hec_node_solution.

      LOOP AT GROUP <fs_mat_list> ASSIGNING FIELD-SYMBOL(<fs_mat>).
        DELETE me->mt_material_list WHERE hec_node_solution = <fs_mat>-hec_node_solution.
      ENDLOOP.
    ENDLOOP. " LOOP AT lt_mat_solution ASSIGNING FIELD-SYMBOL(<fs_mat_list>)

    " Insert lines
    INSERT LINES OF lt_mat_solution
         INTO TABLE me->mt_material_list.


  ENDMETHOD.


  METHOD /hec1/if_config_sw_helper~set_software_item_list.

    " Check for existing software item
    DATA(lt_sw_item) = /hec1/cl_bopf_config_model_fac=>get_instance( )->/hec1/if_bopf_config_model_get~get_software_item_multi( iv_guid_solution = iv_node_solution ).

    SELECT hec_sol_hsp_mat_swi_guid,
           hec_sw_item_ppms_key,
           hec_sw_item_hsp_name,
           hec_sw_item_hsp_type_value,
           hec_sw_item_hsp_type_descr,
           hec_hsp_mat_swi_guid,
           hec_sw_item_mat_rel_value,
           hec_sw_item_mat_rel_descr,
           hec_sw_item_3rd_party,
           hec_sw_item_addon,
           \_solmatassocpath-hec_material_guid AS hec_material_guid,
           \_solmatassocpath-hec_solution_guid AS hec_solution_guid,
           \_swistackassocpath-hec_hsp_swi_stack_guid,
           \_swistackassocpath-hec_hsp_swi_stack_value,
           \_swistackassocpath-hec_hsp_swi_stack_descr,
           \_swistackinfo-hec_sw_item_pf_status_descr,
           \_swistackinfo-hec_sw_item_pf_status_value,
           \_swistackinfo-hec_calc_setup_dr
      FROM /hec1/i_softwitemwithassocpath ##ASSOC_TO_N_OK[_SWIASSOCPATH]
     WHERE hec_apm_guid      = @iv_apm_guid  AND
           \_solmatassocpath-hec_solution_guid = @iv_solution_guid
     INTO TABLE @DATA(lt_software_item).

    " Set Software Item ( including item stack )
    SORT lt_software_item.
    DELETE ADJACENT DUPLICATES FROM lt_software_item.

    DATA(lt_sw_item_list) = VALUE /hec1/t_config_sw_item_list( FOR wa_sw IN lt_software_item
                                                             ( VALUE #( BASE CORRESPONDING #( wa_sw )
                                                                        " begin of key
                                                                        hec_node_solution      = iv_node_solution
                                                                        hec_material_guid      = wa_sw-hec_material_guid
                                                                        hec_sw_item_guid       = wa_sw-hec_sol_hsp_mat_swi_guid
                                                                        hec_hsp_swi_stack_guid = wa_sw-hec_hsp_swi_stack_guid
                                                                        " end of key
                                                                        hec_sw_selection       = COND #( WHEN wa_sw-hec_sw_item_mat_rel_value = /hec1/if_config_constants=>gc_material_rel-mandatory
                                                                                                           OR line_exists( lt_sw_item[ hec_sw_item_guid  = wa_sw-hec_sol_hsp_mat_swi_guid ] )
                                                                                                         THEN abap_true
                                                                                                         ELSE abap_false                                                                            )
                                                                        hec_field_read_only    = COND #( WHEN wa_sw-hec_sw_item_mat_rel_value = /hec1/if_config_constants=>gc_material_rel-mandatory
                                                                                                         THEN abap_true
                                                                                                         ELSE abap_false
                                                                                                         ) ) ) ).

    " Make sure that the lines that are to be inserted do not exist yet
    LOOP AT lt_sw_item_list ASSIGNING FIELD-SYMBOL(<fs_sw_list>)
      GROUP BY <fs_sw_list>-hec_node_solution.

      LOOP AT GROUP <fs_sw_list> ASSIGNING FIELD-SYMBOL(<fs_sw>).
        DELETE me->mt_software_item_list WHERE hec_node_solution = <fs_sw>-hec_node_solution.
      ENDLOOP.
    ENDLOOP.

    " Insert lines
    INSERT LINES OF lt_sw_item_list
         INTO TABLE me->mt_software_item_list.

  ENDMETHOD.


  METHOD constructor.

    mo_instance = me.

  ENDMETHOD.


  METHOD get_instance.

    ro_instance = COND #( WHEN mo_instance IS BOUND
                          THEN mo_instance
                          ELSE NEW /hec1/cl_config_sw_helper( ) ).

  ENDMETHOD.


    METHOD /hec1/if_config_sw_helper~set_swi_list_selectable.

    LOOP AT me->mt_software_item_list ASSIGNING FIELD-SYMBOL(<fs_swi_list>)
      WHERE hec_node_solution = iv_node_solution_guid
        AND hec_material_guid = iv_material_guid.

      <fs_swi_list>-hec_row_selectable = iv_row_selectable.
      IF <fs_swi_list>-hec_field_mandatory = abap_true.
        <fs_swi_list>-hec_sw_selection = abap_true.
      ENDIF.

      " deactivate selection as well
      IF iv_row_selectable = abap_false.
        <fs_swi_list>-hec_sw_selection = abap_false.
      ENDIF.

    ENDLOOP.

  ENDMETHOD.
ENDCLASS.
