REPORT zqm_batch_attributes_display.
*---------------------------------------------------------------------*
* Batch Attributes Migration - Display ALV sample
* Purpose
* MCHB (Plant) + MCH1 (Batch Master) + AUSP (Classification)
* -> ZAQMR0140-like display layout for migration validation.
*
* Safety
* Read only. This report does not update MCHB, MCH1, AUSP or CABN.
* Validate authorization objects in PFCG/SU24 before production use.
*
* Join implemented here (US11 option)
* MCHB-MATNR/CHARG -> MCH1-MATNR/CHARG
* MCH1-CUOBJ_BM -> AUSP-OBJEK (18-character object key)
* AUSP-ATINN -> CABN-ATINN -> CABN-ATNAM
*
* Project confirmation required
* - Lilly Z_BATCH join is project-specific and is not enabled here.
* - Confirm class assignment through KSSK/INOB for the target system.
* - Confirm characteristic aliases and date conversion in DEV/QA.
*---------------------------------------------------------------------*
TABLES: mchb, mch1, ausp.
SELECT-OPTIONS: s_matnr FOR mch1-matnr,
s_charg FOR mch1-charg,
s_werks FOR mchb-werks.
PARAMETERS: p_klart TYPE ausp-klart DEFAULT '023' OBLIGATORY,
p_class TYPE klah-class DEFAULT 'ZBCH_CLASS_001' OBLIGATORY.
TYPES: BEGIN OF ty_base,
matnr TYPE mch1-matnr,
werks TYPE mchb-werks,
charg TYPE mch1-charg,
cuobj_bm TYPE mch1-cuobj_bm,
hsdat TYPE mch1-hsdat,
vfdat TYPE mch1-vfdat,
lvorm TYPE mch1-lvorm,
zustd TYPE mch1-zustd,
lwedt TYPE mch1-lwedt,
licha TYPE mch1-licha,
lifnr TYPE mch1-lifnr,
END OF ty_base.
TYPES: BEGIN OF ty_ausp,
objek TYPE ausp-objek,
atinn TYPE ausp-atinn,
atwrt TYPE ausp-atwrt,
atflv TYPE ausp-atflv,
klart TYPE ausp-klart,
END OF ty_ausp.
TYPES: BEGIN OF ty_cabn,
atinn TYPE cabn-atinn,
atnam TYPE cabn-atnam,
adzhl TYPE cabn-adzhl,
END OF ty_cabn.
TYPES: BEGIN OF ty_objek_key,
objek TYPE ausp-objek,
END OF ty_objek_key.
TYPES: BEGIN OF ty_atinn_key,
atinn TYPE ausp-atinn,
END OF ty_atinn_key.
TYPES: BEGIN OF ty_out,
status TYPE char10,
werks TYPE mchb-werks,
matnr TYPE mch1-matnr,
charg TYPE mch1-charg,
klart TYPE ausp-klart,
class TYPE klah-class,
batch_use TYPE char50,
pct_act TYPE char30,
orig_mfr TYPE char50,
mfg_start TYPE char30,
first_gr TYPE char30,
sites TYPE char80,
exp_date TYPE char30,
next_insp TYPE char30,
lobm_hsdat TYPE char30,
hsdat TYPE mch1-hsdat,
vfdat TYPE mch1-vfdat,
lvorm TYPE mch1-lvorm,
zustd TYPE mch1-zustd,
lwedt TYPE mch1-lwedt,
licha TYPE mch1-licha,
lifnr TYPE mch1-lifnr,
cuobj_bm TYPE mch1-cuobj_bm,
objek TYPE ausp-objek,
message TYPE char255,
END OF ty_out.
DATA: gt_base TYPE STANDARD TABLE OF ty_base,
gt_ausp TYPE STANDARD TABLE OF ty_ausp,
gt_cabn TYPE STANDARD TABLE OF ty_cabn,
gt_out TYPE STANDARD TABLE OF ty_out.
DATA: gt_objek TYPE SORTED TABLE OF ty_objek_key
WITH UNIQUE KEY objek,
gt_atinn TYPE SORTED TABLE OF ty_atinn_key
WITH UNIQUE KEY atinn.
START-OF-SELECTION.
PERFORM select_base.
PERFORM select_classification.
PERFORM build_output.
PERFORM display_alv.
FORM select_base.
SELECT DISTINCT
m1~matnr,
mb~werks,
m1~charg,
m1~cuobj_bm,
m1~hsdat,
m1~vfdat,
m1~lvorm,
m1~zustd,
m1~lwedt,
m1~licha,
m1~lifnr
FROM mch1 AS m1
LEFT OUTER JOIN mchb AS mb
ON mb~matnr = m1~matnr
AND mb~charg = m1~charg
WHERE m1~matnr IN @s_matnr
AND m1~charg IN @s_charg
AND mb~werks IN @s_werks
INTO CORRESPONDING FIELDS OF TABLE @gt_base.
LOOP AT gt_base ASSIGNING FIELD-SYMBOL().
IF -cuobj_bm IS INITIAL.
CONTINUE.
ENDIF.
INSERT VALUE #( objek = CONV ausp-objek( -cuobj_bm ) )
INTO TABLE gt_objek.
ENDLOOP.
ENDFORM.
FORM select_classification.
IF gt_objek IS INITIAL.
RETURN.
ENDIF.
SELECT objek, atinn, atwrt, atflv, klart
FROM ausp
FOR ALL ENTRIES IN @gt_objek
WHERE objek = @gt_objek-objek
AND klart = @p_klart
INTO TABLE @gt_ausp.
LOOP AT gt_ausp ASSIGNING FIELD-SYMBOL().
INSERT VALUE #( atinn = -atinn ) INTO TABLE gt_atinn.
ENDLOOP.
IF gt_atinn IS INITIAL.
RETURN.
ENDIF.
SELECT atinn, atnam, adzhl
FROM cabn
FOR ALL ENTRIES IN @gt_atinn
WHERE atinn = @gt_atinn-atinn
INTO TABLE @gt_cabn.
SORT gt_cabn BY atinn adzhl.
DELETE ADJACENT DUPLICATES FROM gt_cabn COMPARING atinn.
ENDFORM.
FORM build_output.
LOOP AT gt_base INTO DATA(ls_base).
DATA(ls_out) = VALUE ty_out(
werks = ls_base-werks
matnr = ls_base-matnr
charg = ls_base-charg
klart = p_klart
class = p_class
hsdat = ls_base-hsdat
vfdat = ls_base-vfdat
lvorm = ls_base-lvorm
zustd = ls_base-zustd
lwedt = ls_base-lwedt
licha = ls_base-licha
lifnr = ls_base-lifnr
cuobj_bm = ls_base-cuobj_bm ).
IF ls_base-cuobj_bm IS INITIAL.
ls_out-status = 'ERROR'.
ls_out-message = 'CUOBJ_BM is initial; classification is not assigned'.
APPEND ls_out TO gt_out.
CONTINUE.
ENDIF.
ls_out-objek = CONV ausp-objek( ls_base-cuobj_bm ).
DATA(lv_matched) = abap_false.
LOOP AT gt_ausp INTO DATA(ls_ausp) WHERE objek = ls_out-objek.
READ TABLE gt_cabn INTO DATA(ls_cabn)
WITH KEY atinn = ls_ausp-atinn BINARY SEARCH.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
lv_matched = abap_true.
PERFORM apply_characteristic USING ls_ausp ls_cabn-atnam
CHANGING ls_out.
ENDLOOP.
IF lv_matched = abap_false.
ls_out-status = 'ERROR'.
ls_out-message = |No AUSP match for OBJEK { ls_out-objek }|.
ELSEIF ls_out-batch_use IS INITIAL
OR ls_out-pct_act IS INITIAL
OR ls_out-orig_mfr IS INITIAL
OR ls_out-mfg_start IS INITIAL
OR ls_out-first_gr IS INITIAL
OR ls_out-sites IS INITIAL
OR ls_out-werks IS INITIAL.
ls_out-status = 'WARNING'.
ls_out-message = 'Required migration value or MCHB Plant is missing'.
ELSE.
ls_out-status = 'READY'.
ls_out-message = 'AUSP join and required values confirmed'.
ENDIF.
APPEND ls_out TO gt_out.
ENDLOOP.
ENDFORM.
FORM apply_characteristic USING is_ausp TYPE ty_ausp
iv_atnam TYPE cabn-atnam
CHANGING cs_out TYPE ty_out.
CASE iv_atnam.
WHEN 'ZBCH_BATCH_USE_REST' OR 'Z_LOBM_LLY_BATCH_USE_REST'.
cs_out-batch_use = is_ausp-atwrt.
WHEN 'ZBCH_POTENCY_PERCENT'.
PERFORM float_to_text USING is_ausp-atflv 6
CHANGING cs_out-pct_act.
WHEN 'ZBCH_ORIGINAL_MANUFACTURER' OR 'Z_ORIGINAL_MANUFACTURER'.
cs_out-orig_mfr = is_ausp-atwrt.
WHEN 'ZBCH_LOBM_EXP_MFG_REFDT' OR 'Z_LOBM_LLY_EXP_MFG_REFDT'.
PERFORM float_to_text USING is_ausp-atflv 0
CHANGING cs_out-mfg_start.
WHEN 'ZBCH_FIRST_GOODS_RECEIPT_DAT'
OR 'Z_FIRST_GOODS_RECEIPT_DAT'
OR 'Z_LOBM_FIRST_GOODS_RECEIPT_DAT'.
PERFORM float_to_text USING is_ausp-atflv 0
CHANGING cs_out-first_gr.
WHEN 'ZBCH_LOBM_SITES' OR 'Z_LOBM_PACKAGING_SITE'.
cs_out-sites = is_ausp-atwrt.
WHEN 'LOBM_VFDAT'.
PERFORM float_to_text USING is_ausp-atflv 0
CHANGING cs_out-exp_date.
WHEN 'LOBM_QNDAT'.
PERFORM float_to_text USING is_ausp-atflv 0
CHANGING cs_out-next_insp.
WHEN 'LOBM_HSDAT'.
PERFORM float_to_text USING is_ausp-atflv 0
CHANGING cs_out-lobm_hsdat.
ENDCASE.
ENDFORM.
FORM float_to_text USING iv_value TYPE ausp-atflv
iv_decimals TYPE i
CHANGING cv_text TYPE any.
IF iv_value IS INITIAL.
CLEAR cv_text.
RETURN.
ENDIF.
IF iv_decimals = 0.
WRITE iv_value TO cv_text NO-GROUPING DECIMALS 0.
ELSE.
WRITE iv_value TO cv_text NO-GROUPING DECIMALS 6.
ENDIF.
CONDENSE cv_text NO-GAPS.
ENDFORM.
FORM display_alv.
DATA lo_alv TYPE REF TO cl_salv_table.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = gt_out ).
lo_alv->get_functions( )->set_all( abap_true ).
lo_alv->get_columns( )->set_optimize( abap_true ).
lo_alv->get_display_settings( )->set_striped_pattern( abap_true ).
lo_alv->get_display_settings( )->set_list_header(
|Batch Attributes Migration - Class { p_class }| ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_salv).
MESSAGE lx_salv->get_text( ) TYPE 'I'.
ENDTRY.
ENDFORM.
*---------------------------------------------------------------------*
* Verification checklist before productive use
* 1. SE11: confirm MCH1-CUOBJ_BM and AUSP-OBJEK conversion.
* 2. SE16N: reconcile sample MCHB/MCH1/AUSP/CABN rows.
* 3. Validate characteristic aliases and ATFLV date representation.
* 4. Validate Class 023 assignment with KSSK/INOB as required.
* 5. Add approved authorization checks from PFCG/SU24 design.
* 6. Compare ALV rows with ZAQMR0140 Display in DEV/QA.
*---------------------------------------------------------------------*