My requirement was to add an attachment to Freight Order in the "Attachments" section & Also, Send Tracking Email Notification to Customer with Tracking URL & Shipment details.
This was achieved using a Custom PPF Action maintained in Transaction SPPFCADM.
For this requirement I created an Adobe form in SFP.
Printed it in runtime and then added it to the Freight Order using the ROOT key in Schedule
Custom PPF Configuration Steps:
1. Run Transaction: SPPFCADM.
2. Define Action Profile and Actions
3. Custom Action.
4. Set Processing Types.
5. Condition of Configuration.
6. Technical Names->Schedule Condition.
7. Schedule Condition.
8. Schedule Condition Value: Z_US_TM_SCH_PPF_HAZARD_FORM.
Is a BADI Implementation Filter Value given for that BADI Implementation.
Schedule Condition BADI Implementation Code Below:
Action of:
BADI-EVAL_SCHEDCOND_PPF
Implementation method-IF_EX_EVAL_SCHEDCOND_PPF~EVALUATE_SCHEDULE_CONDITION
Below is the code snippet I used to Schedule the PPF Action for Email to Customer.
METHOD if_ex_eval_schedcond_ppf~evaluate_schedule_condition.
TYPES: BEGIN OF lty_atf_doc,
attachment_type TYPE /bobf/s_atf_document_k-attachment_type,
external_link_web_uri TYPE /bobf/s_atf_document_k-external_link_web_uri,
END OF lty_atf_doc.
CONSTANTS: lc_email_to_cust TYPE zi_us_tm_setleaf-setid VALUE 'EMAIL_TO_CUSTOMER',
lc_freight_ord_notif TYPE /bofu/s_ppf_act-ppf_action VALUE 'ZTM_TOR_TRACKNO_NTF',
lc_link TYPE /bobf/s_atf_document_k-attachment_type VALUE 'LINK',
lc_04 TYPE /scmtms/s_tor_root_k-confirmation VALUE '04',
lc_05 TYPE /scmtms/s_tor_root_k-confirmation VALUE '05'.
CONSTANTS: lc_obj TYPE cl_bali_header_setter=>ty_object VALUE 'ZUS_TM_FO_LOG',
lc_subobj TYPE cl_bali_header_setter=>ty_subobject VALUE 'ZUS_TM_FO_PPF_LOG',
lc_ext_id TYPE cl_bali_header_setter=>ty_external_id VALUE 'ZUS_TM_FO_PPF_ACTION_LOG'.
DATA: lt_key TYPE /bobf/t_frw_key,
lt_attachment_key TYPE /bobf/t_frw_key,
lo_context TYPE REF TO cl_context_ppf,
lo_ppf_context TYPE REF TO /bofu/cl_ppf_context,
lt_tor_root_before TYPE /scmtms/t_tor_root_k,
lt_tor_root_after TYPE /scmtms/t_tor_root_k,
lt_atf_doc_temp TYPE STANDARD TABLE OF lty_atf_doc,
lr_doc_status TYPE RANGE OF /scmtms/s_tor_root_k-confirmation.
DATA: lo_appl_log TYPE REF TO if_bali_log,
lv_msg(200) TYPE c.
*--Default the Schedule Condition to Error.
ep_rc = 4.
*--Log Creation Logic.
TRY.
lo_appl_log = cl_bali_log=>create_with_header(
header = cl_bali_header_setter=>create(
object = lc_obj
subobject = lc_subobj
external_id = lc_ext_id ) ).
CATCH cx_bali_runtime.
ENDTRY.
*--MACRO for Log Messages.
DEFINE log_free_text.
IF lo_appl_log IS BOUND.
TRY.
lo_appl_log->add_item(
item = cl_bali_free_text_setter=>create(
severity = &1
text = &2 ) ).
CATCH cx_bali_runtime.
ENDTRY.
ENDIF.
END-OF-DEFINITION.
*--MACRO for saving the log and returning.
DEFINE save_log_and_return.
IF lo_appl_log IS BOUND.
TRY.
cl_bali_log_db=>get_instance( )->save_log( log = lo_appl_log ).
CATCH cx_bali_runtime.
ENDTRY.
ENDIF.
RETURN.
END-OF-DEFINITION.
*--PPF Action Start Marker.
log_free_text if_bali_constants=>c_severity_status
'PPF Action: Send Tracking Notification to Customer - Started'.
*--Fetch the Root Key.
IF io_context IS BOUND.
TRY.
lo_context ?= io_context.
lo_ppf_context ?= lo_context.
DATA(lv_root_key) = lo_ppf_context->applkey.
CATCH cx_sy_move_cast_error INTO DATA(lx_cast).
log_free_text if_bali_constants=>c_severity_error
'PPF context cast failed (cx_sy_move_cast_error) – Cannot Proceed'.
save_log_and_return.
CATCH cx_sy_ref_is_initial INTO DATA(lx_ref).
log_free_text if_bali_constants=>c_severity_error
'PPF context reference is initial – Cannot Proceed'.
save_log_and_return.
CATCH cx_root INTO DATA(lx_root_ctx).
log_free_text if_bali_constants=>c_severity_error
'Unexpected error fetching PPF context – Cannot Proceed'.
save_log_and_return.
ENDTRY.
ENDIF.
APPEND INITIAL LINE TO lt_key ASSIGNING FIELD-SYMBOL(<lfs_key>).
<lfs_key>-key = lv_root_key.
*--Service Manager Initiation.
DATA(lo_srv_mgr) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /scmtms/if_tor_c=>sc_bo_key ).
CASE ip_ttype.
WHEN lc_freight_ord_notif. "ZTM_TOR_TRACKNO_NTF
*--------------------------------------------------------------------------
*--Validation Check Start
*--------------------------------------------------------------------------
*--Only If Tracking URL, Tracking ID & Confirmation Status is 04/05.
*--Then only trigger the email to customer.
*--Fetch the Status of the Document before Status Change.
lo_srv_mgr->retrieve(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_before_image = abap_true
iv_fill_data = abap_true
IMPORTING
et_data = lt_tor_root_before
eo_message = DATA(lo_message) ).
IF lt_tor_root_before IS NOT INITIAL.
DATA(lv_doc_status_before) = VALUE #( lt_tor_root_before[ 1 ]-confirmation OPTIONAL ).
ENDIF.
*--Fetch the Status of the Document after Status Change.
lo_srv_mgr->retrieve(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_fill_data = abap_true
IMPORTING
et_data = lt_tor_root_after
eo_message = lo_message ).
IF lt_tor_root_after IS NOT INITIAL.
DATA(lv_doc_status_after) = VALUE #( lt_tor_root_after[ 1 ]-confirmation OPTIONAL ).
DATA(lv_purch_org) = VALUE #( lt_tor_root_after[ 1 ]-purch_org_id OPTIONAL ).
DATA(lv_tracking_no) = VALUE #( lt_tor_root_after[ 1 ]-partner_mbl_id OPTIONAL ).
DATA(lv_fo_no) = VALUE #( lt_tor_root_after[ 1 ]-tor_id OPTIONAL ).
DATA(lv_fo) = lv_fo_no+10(10).
ENDIF.
TRY.
*--Fetch ATTACHMENT Folder Details.
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_tor_c=>sc_association-root-attachmentfolder
IMPORTING
et_key_link = DATA(lt_key_link) ).
IF lt_key_link IS NOT INITIAL.
APPEND INITIAL LINE TO lt_attachment_key ASSIGNING FIELD-SYMBOL(<lfs_attachment_key>).
<lfs_attachment_key>-key = lt_key_link[ 1 ]-source_key.
ENDIF.
CATCH /bobf/cx_frw_contrct_violation.
ENDTRY.
*--Fetch URL & Attachment PDF Data.
TRY.
CALL METHOD /scmtms/cl_atf_helper=>get_atf_data
EXPORTING
iv_bo_key = /scmtms/if_tor_c=>sc_bo_key
iv_source_node = /scmtms/if_tor_c=>sc_node-root
iv_node = /scmtms/if_tor_c=>sc_node-attachmentfolder
iv_association = /scmtms/if_tor_c=>sc_association-root-attachmentfolder
it_key = lt_attachment_key
IMPORTING
et_root = DATA(lt_atf_root)
et_document = DATA(lt_atf_doc)
et_file_content = DATA(lt_atf_file).
CATCH cx_root INTO DATA(ls_exception).
ENDTRY.
*--Tracking URL
IF lt_atf_doc IS NOT INITIAL.
lt_atf_doc_temp = CORRESPONDING #( lt_atf_doc ).
SORT lt_atf_doc_temp BY attachment_type.
READ TABLE lt_atf_doc_temp WITH KEY attachment_type = lc_link
ASSIGNING FIELD-SYMBOL(<lfs_atf_doc_temp>) BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_tracking_url) = <lfs_atf_doc_temp>-external_link_web_uri.
ENDIF.
ENDIF.
APPEND INITIAL LINE TO lr_doc_status ASSIGNING FIELD-SYMBOL(<lfs_doc_status>).
<lfs_doc_status>-sign = cl_abap_range=>sign-including.
<lfs_doc_status>-option = cl_abap_range=>option-equal.
<lfs_doc_status>-low = lc_04.
APPEND INITIAL LINE TO lr_doc_status ASSIGNING <lfs_doc_status>.
<lfs_doc_status>-sign = cl_abap_range=>sign-including.
<lfs_doc_status>-option = cl_abap_range=>option-equal.
<lfs_doc_status>-low = lc_05.
*--Validation: Status not changed.
IF lv_doc_status_before = lv_doc_status_after.
lv_msg = |FO: { lv_fo } Status Unchanged ({ lv_doc_status_after }) – PPF action skipped|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
save_log_and_return.
ENDIF.
*--Validation: Status must be 04 or 05, tracking number and URL must be populated.
*--If Document Status is not Confirmed/Send to Confirmation
IF lv_doc_status_after NOT IN lr_doc_status.
lv_msg = |FO: { lv_fo } Document Status is not Confirmed/Send to Confirmation - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
save_log_and_return.
ENDIF.
*--Trigger the Enhancement only If tracking number and tracking url is maintained.
IF lv_tracking_no IS INITIAL.
lv_msg = |Freight Order: { lv_fo } Tracking Number not found - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
save_log_and_return.
ENDIF.
IF lv_tracking_url IS INITIAL.
lv_msg = |Freight Order: { lv_fo } Tracking URL not found - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
save_log_and_return.
ENDIF.
*--------------------------------------------------------------------------
*--Validation Check End.
*--------------------------------------------------------------------------
*--Check if Purchase Org is maintained in the Control Table.
IF lv_purch_org IS NOT INITIAL.
SELECT SINGLE setrangefromvalue
FROM zi_us_tm_setleaf
WHERE setid = @LC_email_to_cust
AND setrangefromvalue = @LV_purch_org
INTO @DATA(lv_value).
IF sy-subrc IS NOT INITIAL.
lv_msg = 'Purch Org not found in Control Table: ZI_US_TM_SETLEAF Set Id: EMAIL_TO_CUSTOMER - PPF action skipped'.
log_free_text if_bali_constants=>c_severity_error lv_msg.
save_log_and_return.
ELSE.
lv_msg = 'Purch Org validated in control table - PPF action will trigger'.
log_free_text if_bali_constants=>c_severity_status lv_msg.
ep_rc = 0.
ENDIF.
ELSE.
log_free_text if_bali_constants=>c_severity_error
'Purchase Org is not maintained in ROOT - PPF action skipped'.
save_log_and_return.
ENDIF.
WHEN OTHERS.
ENDCASE.
ENDMETHOD.Below is the code snippet I used to Attach Attachment to the Freight Order.
METHOD if_ex_eval_schedcond_ppf~evaluate_schedule_condition.
TYPES: BEGIN OF lty_tor_item,
item_cat TYPE /scmtms/s_tor_item_tr_k-item_cat,
main_cargo_item TYPE /scmtms/s_tor_item_tr_k-main_cargo_item,
product_id TYPE /scmtms/s_tor_item_tr_k-product_id,
END OF lty_tor_item.
CONSTANTS: lc_prd TYPE /scmtms/s_tor_item_tr_k-item_cat VALUE 'PRD',
lc_formname TYPE fpname VALUE 'ZAF_US_TM_HAZARDOUS_MATERIAL',
lc_mara TYPE bapi1003_key-objecttable VALUE 'MARA',
lc_matclass TYPE bapi1003_key-classnum VALUE 'MATCLASSHZD',
lc_classtype TYPE bapi1003_key-classtype VALUE '001',
lc_hazard TYPE zi_us_tm_setleaf-setid VALUE 'HAZARDOUS_FORM',
lc_hazard_form_attch TYPE /bofu/s_ppf_act-ppf_action VALUE 'ZTM_TOR_HAZARD_FORM',
lc_mimetype TYPE /bobf/s_atf_a_create_file-mime_code VALUE 'application/pdf',
lc_atcmt TYPE /bobf/s_atf_a_create_file-attachment_type VALUE 'ATCMT',
lc_default TYPE /bobf/s_atf_a_create_file-attachment_schema VALUE 'DEFAULT',
lc_mercury TYPE bapi1003_alloc_values_char-value_char VALUE 'MERCURY',
lc_char_desc TYPE bapi1003_alloc_values_char-charact_descr VALUE 'MERCURY OR PERCHLORAT'.
CONSTANTS: lc_04 TYPE /scmtms/s_tor_root_k-confirmation VALUE '04',
lc_05 TYPE /scmtms/s_tor_root_k-confirmation VALUE '05'.
DATA: lt_key TYPE /bobf/t_frw_key,
lt_tor_root_before TYPE /scmtms/t_tor_root_k,
lt_tor_root_after TYPE /scmtms/t_tor_root_k,
lo_context TYPE REF TO cl_context_ppf,
lo_ppf_context TYPE REF TO /bofu/cl_ppf_context,
lr_doc_status TYPE RANGE OF /scmtms/s_tor_root_k-confirmation.
DATA: lv_fm_name TYPE rs38l_fnam,
ls_outputparams TYPE sfpoutputparams,
ls_docparams TYPE sfpdocparams,
ls_result TYPE sfpjoboutput,
ls_formoutput TYPE fpformoutput.
DATA: lt_atf_key TYPE /bobf/t_frw_key,
lt_failed_key TYPE /bobf/t_frw_key,
lt_tor_item TYPE /scmtms/t_tor_item_tr_k,
lt_tor_item_temp TYPE STANDARD TABLE OF lty_tor_item,
lt_mod TYPE /bobf/t_frw_modification,
ls_mod TYPE /bobf/s_frw_modification,
lv_rejected TYPE boole_d,
lv_action_key TYPE /bobf/conf_key,
lv_tor_key TYPE /bobf/conf_key,
ls_parameters TYPE /bobf/s_atf_a_create_file,
lr_action_par TYPE REF TO /bobf/s_atf_a_create_file,
lr_atf_root TYPE REF TO /bobf/s_atf_root_k.
DATA: lt_allocvalueschar TYPE TABLE OF bapi1003_alloc_values_char,
lt_allocvaluesnum TYPE TABLE OF bapi1003_alloc_values_num,
lt_allocvaluescurr TYPE TABLE OF bapi1003_alloc_values_curr,
lt_return_cls TYPE TABLE OF bapiret2.
ep_rc = 4.
*--Fetch the Root Key.
IF io_context IS BOUND.
TRY.
lo_context ?= io_context.
lo_ppf_context ?= lo_context.
DATA(lv_root_key) = lo_ppf_context->applkey.
CATCH /bobf/cx_frw_contrct_violation.
RETURN.
CATCH cx_root.
RETURN.
ENDTRY.
ENDIF.
APPEND INITIAL LINE TO lt_key ASSIGNING FIELD-SYMBOL(<lfs_key>).
<lfs_key>-key = lv_root_key.
*--Invoke Service Manger & Transaction Manager.
TRY.
DATA(lo_srv_tor) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /scmtms/if_tor_c=>sc_bo_key ).
DATA(lo_tra_tor) = /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( ).
CATCH /bobf/cx_frw_contrct_violation.
RETURN.
CATCH cx_root.
RETURN.
ENDTRY.
CASE ip_ttype.
WHEN lc_hazard_form_attch. "ZTM_TOR_HAZARD_FORM
* =========================================================================
* PART 1: Validation Check for Enhancement Check & Hazardous Material Check
* =========================================================================
*--TOR Root Details before Status Change.
TRY.
lo_srv_tor->retrieve(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_before_image = abap_true
iv_fill_data = abap_true
IMPORTING
et_data = lt_tor_root_before
eo_message = DATA(lo_message) ).
IF lt_tor_root_before IS NOT INITIAL.
DATA(lv_doc_status_before) = VALUE #( lt_tor_root_before[ 1 ]-confirmation OPTIONAL ).
ENDIF.
*--TOR Root Details after Status Change.
lo_srv_tor->retrieve(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_fill_data = abap_true
IMPORTING
et_data = lt_tor_root_after
eo_message = lo_message ).
IF lt_tor_root_after IS NOT INITIAL.
DATA(lv_purch_org) = VALUE #( lt_tor_root_after[ 1 ]-purch_org_id OPTIONAL ).
DATA(lv_doc_status_after) = VALUE #( lt_tor_root_after[ 1 ]-confirmation OPTIONAL ).
APPEND INITIAL LINE TO lr_doc_status ASSIGNING FIELD-SYMBOL(<lfs_doc_status>).
<lfs_doc_status>-sign = cl_abap_range=>sign-including.
<lfs_doc_status>-option = cl_abap_range=>option-equal.
<lfs_doc_status>-low = lc_04.
APPEND INITIAL LINE TO lr_doc_status ASSIGNING <lfs_doc_status>.
<lfs_doc_status>-sign = cl_abap_range=>sign-including.
<lfs_doc_status>-option = cl_abap_range=>option-equal.
<lfs_doc_status>-low = lc_05.
*--If the Freight Order Status is not 04/05 Enhancement not applicable.
IF lv_doc_status_before = lv_doc_status_after.
RETURN.
ENDIF.
IF lv_doc_status_after NOT IN lr_doc_status.
RETURN.
ENDIF.
*--Read the SET value from Enhancement Control Table.
*--If Purchase Org Not Present in the Enh. Control Table Enhancement not applicable.
IF lv_purch_org IS NOT INITIAL.
SELECT SINGLE setrangefromvalue
FROM zi_us_tm_setleaf
WHERE setid = @LC_hazard "HAZARDOUS_FORM
AND setrangefromvalue = @LV_purch_org
INTO @DATA(lv_plant).
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
*--Fetch Item Details.
lo_srv_tor->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_tor_c=>sc_association-root-item_tr
iv_fill_data = abap_true
iv_edit_mode = /bobf/if_conf_c=>sc_edit_read_only
IMPORTING
et_data = lt_tor_item
eo_message = lo_message ).
IF lt_tor_item IS NOT INITIAL.
lt_tor_item_temp = CORRESPONDING #( lt_tor_item ).
SORT lt_tor_item_temp BY item_cat main_cargo_item.
IF lt_tor_item_temp IS NOT INITIAL.
READ TABLE lt_tor_item_temp WITH KEY item_cat = lc_prd main_cargo_item = abap_true
ASSIGNING FIELD-SYMBOL(<lfs_tor_item_temp>) BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_product) = <lfs_tor_item_temp>-product_id.
ENDIF.
ENDIF.
ENDIF.
*--Get Material Classification Details.
IF lv_product IS NOT INITIAL.
CALL FUNCTION 'BAPI_OBJCL_GETDETAIL'
EXPORTING
objectkey = CONV bapi1003_key-object( lv_product )
objecttable = lc_mara "'MARA'
classnum = lc_matclass "'MATCLASSHZD'
classtype = lc_classtype "'001'
TABLES
allocvaluesnum = lt_allocvaluesnum
allocvalueschar = lt_allocvalueschar
allocvaluescurr = lt_allocvaluescurr
return = lt_return_cls.
SORT lt_return_cls BY type.
READ TABLE lt_return_cls WITH KEY type = 'S' TRANSPORTING NO FIELDS BINARY SEARCH.
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
*--If there is NO Hazardous Material RETURN.
SORT lt_allocvalueschar BY charact_descr.
READ TABLE lt_allocvalueschar INTO DATA(ls_hazard_cls)
WITH KEY charact_descr = lc_char_desc BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_hazard_type) = ls_hazard_cls-value_char.
IF lv_hazard_type <> lc_mercury. "'MERCURY'.
RETURN.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
CATCH /bobf/cx_frw_contrct_violation.
RETURN.
CATCH cx_root.
RETURN.
ENDTRY.
*--Fetch Company Address
IF lv_purch_org IS NOT INITIAL.
SELECT SINGLE b~addressid
FROM zi_us_tm_hrp5561 AS a
INNER JOIN i_buspartaddress AS b
ON b~businesspartner = a~partner
WHERE a~objid = @LV_purch_org
INTO @DATA(lv_adrs).
ENDIF.
* =====================================================================
* PART 2: Create the Hazard Warning Adobe Form
* =====================================================================
ls_outputparams-nodialog = abap_true.
ls_outputparams-getpdf = abap_true.
ls_docparams-langu = sy-langu.
CALL FUNCTION 'FP_JOB_OPEN'
CHANGING
ie_outputparams = ls_outputparams
EXCEPTIONS
cancel = 1
usage_error = 2
system_error = 3
internal_error = 4
OTHERS = 5.
IF sy-subrc IS INITIAL.
TRY.
CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
EXPORTING
i_name = lc_formname "'ZAF_US_TM_HAZARDOUS_MATERIAL'
IMPORTING
e_funcname = lv_fm_name.
CATCH cx_fp_api_repository cx_fp_api_usage cx_fp_api_internal.
ENDTRY.
CALL FUNCTION lv_fm_name
EXPORTING
/1bcdwb/docparams = ls_docparams
iv_addrs_number = lv_adrs
IMPORTING
/1bcdwb/formoutput = ls_formoutput
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc IS INITIAL.
CALL FUNCTION 'FP_JOB_CLOSE'
IMPORTING
e_result = ls_result
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc IS INITIAL AND ls_formoutput-pdf IS NOT INITIAL.
DATA(lv_pdf_xstring) = ls_formoutput-pdf.
ENDIF.
ENDIF.
ENDIF.
* =====================================================================
* PART 3: Attach PDF to Freight Order - Separate Save
* =====================================================================
IF lv_pdf_xstring IS NOT INITIAL.
ep_rc = 0.
*--Call the Attachment Add Logic with the Save sequence in separate task.
CALL FUNCTION 'Z_US_TM_FO_EMAIL_NOTIFICATION' STARTING NEW TASK 'Z_US_TM_FO_EMAIL_NOTIFICATION'
EXPORTING
iv_root_key = lv_root_key
iv_pdf_data = lv_pdf_xstring.
ENDIF.
WHEN OTHERS.
ENDCASE.
ENDMETHOD.
Code of the FM: Z_US_TM_FO_EMAIL_NOTIFICATION.
FUNCTION z_us_tm_fo_email_notification.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(IV_ROOT_KEY) TYPE /BOBF/CONF_KEY
*" VALUE(IV_PDF_DATA) TYPE FPCONTENT
*"----------------------------------------------------------------------
CONSTANTS: lc_mimetype TYPE /bobf/s_atf_a_create_file-mime_code VALUE 'application/pdf',
lc_atcmt TYPE /bobf/s_atf_a_create_file-attachment_type VALUE 'ATCMT',
lc_default TYPE /bobf/s_atf_a_create_file-attachment_schema VALUE 'DEFAULT'.
DATA: lt_key TYPE /bobf/t_frw_key,
ls_parameters TYPE /bobf/s_atf_a_create_file,
lr_action_par TYPE REF TO /bobf/s_atf_a_create_file,
lr_atf_root TYPE REF TO /bobf/s_atf_root_k,
lt_mod TYPE /bobf/t_frw_modification,
ls_mod TYPE /bobf/s_frw_modification.
APPEND INITIAL LINE TO lt_key ASSIGNING FIELD-SYMBOL(<lfs_key>).
<lfs_key>-key = iv_root_key.
*--Invoke Service Manger & Transaction Manager.
TRY.
DATA(lo_srv_tor) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /scmtms/if_tor_c=>sc_bo_key ).
DATA(lo_tra_tor) = /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( ).
CATCH /bobf/cx_frw_contrct_violation.
RETURN.
CATCH cx_root.
RETURN.
ENDTRY.
*--Fetch the ATTACHMENTFOLDER key.
TRY.
lo_srv_tor->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_tor_c=>sc_association-root-attachmentfolder
iv_edit_mode = /bobf/if_conf_c=>sc_edit_read_only
IMPORTING
et_target_key = DATA(lt_atf_key)
et_failed_key = DATA(lt_failed_key) ).
CATCH /bobf/cx_frw_contrct_violation.
RETURN.
CATCH cx_root.
RETURN.
ENDTRY.
*--If the ATTACHMENTFOLDER is blank and there is NO Attachment attached to it.
*--Create the Folder First.
IF lt_atf_key IS INITIAL.
TRY.
CREATE DATA lr_atf_root.
lr_atf_root->key = lo_srv_tor->get_new_key( ).
lr_atf_root->parent_key = /scmtms/if_tor_c=>sc_node-root.
ls_mod-change_mode = /bobf/if_frw_c=>sc_modify_create.
ls_mod-association = /scmtms/if_tor_c=>sc_association-root-attachmentfolder.
ls_mod-source_node = /scmtms/if_tor_c=>sc_node-root.
ls_mod-node = /scmtms/if_tor_c=>sc_node-attachmentfolder.
ls_mod-source_key = iv_root_key.
ls_mod-key = lr_atf_root->key.
ls_mod-data = lr_atf_root.
INSERT ls_mod INTO TABLE lt_mod.
lo_srv_tor->modify(
EXPORTING
it_modification = lt_mod
IMPORTING
eo_change = DATA(lo_change)
eo_message = DATA(lo_message) ).
*** lo_tra_tor->save(
*** IMPORTING
*** ev_rejected = DATA(lv_rejected)
*** eo_change = lo_change
*** eo_message = lo_message ).
INSERT VALUE #( key = lr_atf_root->key ) INTO TABLE lt_atf_key.
CATCH /bobf/cx_frw_contrct_violation.
RETURN.
CATCH cx_root.
RETURN.
ENDTRY.
ENDIF.
*--Populate the Attachment Details.
ls_parameters-file_name = 'Hazardous Material Information.pdf'(001).
ls_parameters-alternative_name = 'Hazardous Material Information.pdf'(001).
ls_parameters-name = 'Hazardous Material Information.pdf'(001).
ls_parameters-content = iv_pdf_data.
ls_parameters-mime_code = lc_mimetype. "'application/pdf'.
ls_parameters-description_language_code = sy-langu.
ls_parameters-description = 'Hazardous Material Information.pdf'(001).
ls_parameters-description_content = 'Hazardous Material Information.pdf'(001).
ls_parameters-visibility_type = abap_true.
ls_parameters-attachment_type = lc_atcmt. "'ATCMT'.
ls_parameters-attachment_schema = lc_default. "'DEFAULT'.
GET REFERENCE OF ls_parameters INTO lr_action_par.
TRY.
/scmtms/cl_common_helper=>get_do_keys_4_action(
EXPORTING
iv_host_bo_key = /scmtms/if_tor_c=>sc_bo_key
iv_host_do_node_key = /scmtms/if_tor_c=>sc_node-attachmentfolder
iv_do_action_key = /bobf/if_attachment_folder_c=>sc_action-root-create_file
IMPORTING
ev_action_key = DATA(lv_action_key) ).
CATCH /bobf/cx_frw_contrct_violation.
RETURN.
CATCH cx_root.
RETURN.
ENDTRY.
IF lv_action_key IS INITIAL.
RETURN.
ENDIF.
TRY.
lo_srv_tor->do_action(
EXPORTING
iv_act_key = lv_action_key
it_key = lt_atf_key
is_parameters = lr_action_par
IMPORTING
et_failed_key = DATA(lt_failed_key_atf)
eo_change = lo_change
eo_message = lo_message ).
lo_tra_tor->save(
IMPORTING
ev_rejected = DATA(lv_rejected)
eo_change = lo_change
eo_message = lo_message ).
CATCH /bobf/cx_frw_contrct_violation.
RETURN.
CATCH cx_root.
RETURN.
ENDTRY.
ENDFUNCTION.
Note:
I had added the create attachment logic in a RFC Function Module and called it from PPF-Schedule Action BADI Implementation method STARTING NEW TASK.
As, the BADI implementation won't allow explicit SAVE.
9. Similarly for Start Condition as well.
Inside the Badi Impl we set the flags to value "4" if our conditions not met.
10. Maintain Entry in Schedule Condition.
11. Create a child class of Standard class: /SCMTMS/CL_PPF_SERV_TOR_B2B
Redefine your required methods.
METHOD method_call_by_abap.
*--------------------------------------------------------------------------
*--Types Declaration
*--------------------------------------------------------------------------
TYPES: BEGIN OF lty_docref_data,
btd_tco TYPE /scmtms/s_tor_docref_k-btd_tco,
btd_id TYPE /scmtms/s_tor_docref_k-btd_id,
END OF lty_docref_data,
BEGIN OF lty_stop_data,
stop_seq_pos TYPE /scmtms/s_tor_stop_k-stop_seq_pos,
plan_trans_time TYPE /scmtms/s_tor_stop_k-plan_trans_time,
END OF lty_stop_data,
BEGIN OF lty_tor_item,
item_cat TYPE /scmtms/s_tor_item_tr_k-item_cat,
main_cargo_item TYPE /scmtms/s_tor_item_tr_k-main_cargo_item,
loading_point_id TYPE /scmtms/s_tor_item_tr_k-loading_point_id,
END OF lty_tor_item,
BEGIN OF lty_soldtoparty,
party_rco TYPE /scmtms/s_tor_party_k-party_rco,
party_id TYPE /scmtms/s_tor_party_k-party_id,
END OF lty_soldtoparty,
BEGIN OF lty_atf_doc,
attachment_type TYPE /bobf/s_atf_document_k-attachment_type,
external_link_web_uri TYPE /bobf/s_atf_document_k-external_link_web_uri,
END OF lty_atf_doc.
*--------------------------------------------------------------------------
*--Data Declaration & Constants
*--------------------------------------------------------------------------
CONSTANTS: lc_pdf TYPE soodk-objtp VALUE 'PDF',
lc_type TYPE w3conttype VALUE 'image/bmp',
lc_set TYPE i_setleaf-setid VALUE 'EMAIL_TO_CUSTOMER',
lc_73 TYPE /scmtms/s_tor_docref_k-btd_tco VALUE '73',
lc_114 TYPE /scmtms/s_tor_docref_k-btd_tco VALUE '114',
lc_prd TYPE /scmtms/s_tor_item_tr_k-item_cat VALUE 'PRD',
lc_sp TYPE /scmtms/s_tor_party_k-party_rco VALUE 'AG',
lc_us_tm004 TYPE zi_tvarvctableforcusto-changeid VALUE 'US_TM004',
lc_04 TYPE /scmtms/s_tor_root_k-confirmation VALUE '04',
lc_05 TYPE /scmtms/s_tor_root_k-confirmation VALUE '05',
lc_l TYPE /scmtms/s_tor_stop_k-stop_seq_pos VALUE 'L',
lc_comp1 TYPE zi_us_tm_setleaf-setrangefromvalue VALUE '500001',
lc_comp2 TYPE zi_us_tm_setleaf-setrangefromvalue VALUE '500002',
lc_email_trigger TYPE /bofu/s_ppf_act-ppf_action VALUE 'ZTM_TOR_TRACKNO_NTF',
lc_hazard_form TYPE /bofu/s_ppf_act-ppf_action VALUE 'ZTM_TOR_HAZARD_FORM',
lc_name1 TYPE zi_tvarvctableforcusto-name VALUE 'Z_EMAIL1',
lc_name2 TYPE zi_tvarvctableforcusto-name VALUE 'Z_EMAIL2',
lc_mimetype TYPE /bobf/s_atf_file_content_k-mime_code VALUE 'application/pdf',
lc_link TYPE /bobf/s_atf_document_k-attachment_type VALUE 'LINK'.
CONSTANTS: lc_company1 TYPE tdobname VALUE 'ZCOMPANY1_LOGO',
lc_company2 TYPE tdobname VALUE 'ZCOMPANY2_LOGO',
lc_graphics TYPE tdobjectgr VALUE 'GRAPHICS',
lc_bmap TYPE tdidgr VALUE 'BMAP',
lc_bcol TYPE tdbtype VALUE 'BCOL'.
CONSTANTS: lc_obj TYPE cl_bali_header_setter=>ty_object VALUE 'ZTM_FO_LOG',
lc_subobj TYPE cl_bali_header_setter=>ty_subobject VALUE 'ZTM_FO_PPF_LOG',
lc_ext_id TYPE cl_bali_header_setter=>ty_external_id VALUE 'ZTM_FO_PPF_ACTION_LOG'.
DATA: lt_docref_data_temp TYPE STANDARD TABLE OF lty_docref_data,
lt_stop_data_temp TYPE STANDARD TABLE OF lty_stop_data,
lt_tor_item_temp TYPE STANDARD TABLE OF lty_tor_item,
lt_soldtoparty_temp TYPE STANDARD TABLE OF lty_soldtoparty,
lt_atf_doc_temp TYPE STANDARD TABLE OF lty_atf_doc.
DATA: lv_html TYPE string,
lv_html_item TYPE string.
DATA: lt_attachment_key TYPE /bobf/t_frw_key,
lt_key TYPE /bobf/t_frw_key,
lt_stop_data TYPE /scmtms/t_tor_stop_k,
lt_tor_root_before TYPE /scmtms/t_tor_root_k,
lt_tor_root_after TYPE /scmtms/t_tor_root_k,
lt_soldtoparty TYPE /scmtms/t_tor_party_k,
lt_docref_data TYPE /scmtms/t_tor_docref_k,
lt_tor_item TYPE /scmtms/t_tor_item_tr_k,
lv_sales_order TYPE i_salesdocument-salesdocument,
lv_delv_doc TYPE i_deliverydocument-deliverydocument,
lv_ship_date TYPE string,
lv_temp_date TYPE string,
ls_addrs_sel TYPE addr1_sel,
lv_qty TYPE p DECIMALS 2.
DATA: lv_hama_logo TYPE xstring,
lv_ener_logo TYPE xstring,
lv_company_logo TYPE string,
lv_root_key TYPE /bobf/conf_key,
lv_read_key TYPE char25,
lo_container TYPE REF TO /bofu/cl_ppf_container,
lo_message TYPE REF TO /bobf/if_frw_message,
lr_name TYPE RANGE OF zi_tvarvctableforcusto-name,
lr_doc_status TYPE RANGE OF /scmtms/s_tor_root_k-confirmation.
DATA: lv_attach_size TYPE sood-objlen,
lv_file_name TYPE sood-objdes,
ls_html_body TYPE soli,
ls_logo_solix TYPE solix,
lt_binary_tab TYPE solix_tab,
lt_html_body TYPE soli_tab.
DATA: lo_appl_log TYPE REF TO if_bali_log,
lv_msg(200) TYPE c.
*--Log Creation Logic.
TRY.
lo_appl_log = cl_bali_log=>create_with_header(
header = cl_bali_header_setter=>create(
object = lc_obj
subobject = lc_subobj
external_id = lc_ext_id ) ).
CATCH cx_bali_runtime.
ENDTRY.
*--MACRO for Log Messages.
DEFINE log_free_text.
IF lo_appl_log IS BOUND.
TRY.
lo_appl_log->add_item(
item = cl_bali_free_text_setter=>create(
severity = &1
text = &2 ) ).
CATCH cx_bali_runtime.
ENDTRY.
ENDIF.
END-OF-DEFINITION.
*--MACRO for saving the log and returning.
DEFINE save_log_and_return.
IF lo_appl_log IS BOUND.
TRY.
cl_bali_log_db=>get_instance( )->save_log( log = lo_appl_log ).
CATCH cx_bali_runtime.
ENDTRY.
ENDIF.
RETURN.
END-OF-DEFINITION.
*--Get the BO Root Key.
TRY.
IF io_container IS BOUND.
lo_container ?= io_container.
lv_root_key = lo_container->get_bo_root_key( ).
ENDIF.
CATCH: cx_sy_move_cast_error cx_sy_ref_is_initial cx_root.
ENDTRY.
APPEND INITIAL LINE TO lt_key ASSIGNING FIELD-SYMBOL(<lfs_key>).
<lfs_key>-key = lv_root_key.
*--Service Manager Initiation.
DATA(lo_srv_mgr) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /scmtms/if_tor_c=>sc_bo_key ).
CASE is_ppf_act-ppf_action.
WHEN lc_email_trigger. "ZTM_TOR_TRACKNO_NTF
*--------------------------------------------------------------------------
*--Validation Check Start
*--------------------------------------------------------------------------
TRY.
*--Only If Tracking URL, Tracking ID & Confirmation Status is 04/05.
*--Then only trigger the email to customer.
*--Fetch the Status of the Document before Status Change.
lo_srv_mgr->retrieve(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_before_image = abap_true
iv_fill_data = abap_true
IMPORTING
et_data = lt_tor_root_before
eo_message = lo_message ).
IF lt_tor_root_before IS NOT INITIAL.
DATA(lv_doc_status_before) = VALUE #( lt_tor_root_before[ 1 ]-confirmation OPTIONAL ).
ENDIF.
*--Fetch the Status of the Document after Status Change.
lo_srv_mgr->retrieve(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_fill_data = abap_true
IMPORTING
et_data = lt_tor_root_after
eo_message = lo_message ).
IF lt_tor_root_after IS NOT INITIAL.
DATA(lv_doc_status_after) = VALUE #( lt_tor_root_after[ 1 ]-confirmation OPTIONAL ).
DATA(lv_tracking_no) = VALUE #( lt_tor_root_after[ 1 ]-partner_mbl_id OPTIONAL ).
DATA(lv_carrier) = VALUE #( lt_tor_root_after[ 1 ]-tspid OPTIONAL ).
DATA(lv_terms) = VALUE #( lt_tor_root_after[ 1 ]-transsrvlvl_code OPTIONAL ).
DATA(lv_consignee_id) = VALUE #( lt_tor_root_after[ 1 ]-consigneeid OPTIONAL ).
DATA(lv_purch_orgid) = VALUE #( lt_tor_root_after[ 1 ]-purch_org_id OPTIONAL ).
IF lv_purch_orgid IS NOT INITIAL.
SELECT SINGLE setrangefromvalue
FROM zi_us_tm_setleaf
WHERE setid = @lc_set "'EMAIL_TO_CUSTOMER'
AND setrangefromvalue = @lv_purch_orgid
INTO @DATA(lv_purch_org).
IF sy-subrc IS NOT INITIAL.
lv_msg = |Purch Org: { lv_purch_orgid } not maintained in Table: ZI_US_TM_SETLEAF| &&
|Set-Id: EMAIL_TO_CUSTOMER.|.
log_free_text if_bali_constants=>c_severity_status lv_msg.
rp_status = 2.
save_log_and_return.
ENDIF.
ENDIF.
ENDIF.
CATCH /bobf/cx_frw_contrct_violation.
ENDTRY.
*--Fetch ATTACHMENT Folder Details.
TRY.
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_tor_c=>sc_association-root-attachmentfolder
IMPORTING
et_key_link = DATA(lt_key_link)
et_target_key = DATA(lt_target_key)
et_failed_key = DATA(lt_failed_key) ).
IF lt_key_link IS NOT INITIAL.
APPEND INITIAL LINE TO lt_attachment_key ASSIGNING FIELD-SYMBOL(<lfs_attachment_key>).
<lfs_attachment_key>-key = lt_key_link[ 1 ]-source_key.
ENDIF.
CATCH /bobf/cx_frw_contrct_violation.
ENDTRY.
*--Fetch URL & Attachment PDF Data.
TRY.
CALL METHOD /scmtms/cl_atf_helper=>get_atf_data
EXPORTING
iv_bo_key = /scmtms/if_tor_c=>sc_bo_key
iv_source_node = /scmtms/if_tor_c=>sc_node-root
iv_node = /scmtms/if_tor_c=>sc_node-attachmentfolder
iv_association = /scmtms/if_tor_c=>sc_association-root-attachmentfolder
it_key = lt_attachment_key
IMPORTING
et_root = DATA(lt_atf_root)
et_document = DATA(lt_atf_doc)
et_file_content = DATA(lt_atf_file).
CATCH cx_root INTO DATA(ls_exception).
ENDTRY.
*--Tracking URL
IF lt_atf_doc IS NOT INITIAL.
lt_atf_doc_temp = CORRESPONDING #( lt_atf_doc ).
SORT lt_atf_doc_temp BY attachment_type.
READ TABLE lt_atf_doc_temp WITH KEY attachment_type = lc_link
ASSIGNING FIELD-SYMBOL(<lfs_atf_doc_temp>) BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_tracking_url) = <lfs_atf_doc_temp>-external_link_web_uri.
ENDIF.
ENDIF.
APPEND INITIAL LINE TO lr_doc_status ASSIGNING FIELD-SYMBOL(<lfs_doc_status>).
<lfs_doc_status>-sign = cl_abap_range=>sign-including.
<lfs_doc_status>-option = cl_abap_range=>option-equal.
<lfs_doc_status>-low = lc_04.
APPEND INITIAL LINE TO lr_doc_status ASSIGNING <lfs_doc_status>.
<lfs_doc_status>-sign = cl_abap_range=>sign-including.
<lfs_doc_status>-option = cl_abap_range=>option-equal.
<lfs_doc_status>-low = lc_05.
*--If Document Status is Unchanged RETURN the Control.
IF lv_doc_status_before = lv_doc_status_after.
lv_msg = |Document Status Unchanged - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
rp_status = 2.
save_log_and_return.
ENDIF.
*--If Document Status is not Confirmed/Send to Confirmation
IF lv_doc_status_after NOT IN lr_doc_status.
lv_msg = |Document Status is not Confirmed/Send to Confirmation - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
rp_status = 2.
save_log_and_return.
ENDIF.
*--Trigger the Enhancement only If tracking number and tracking url is maintained.
IF lv_tracking_no IS INITIAL.
lv_msg = |Freight Order Tracking Number not found - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
rp_status = 2.
save_log_and_return.
ENDIF.
IF lv_tracking_url IS INITIAL.
lv_msg = |Freight Order Tracking URL not found - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
rp_status = 2.
save_log_and_return.
ENDIF.
*--------------------------------------------------------------------------
*--Validation Check End.
*--------------------------------------------------------------------------
TRY.
*--Fetch Sales Order & Delivery Number Document
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_tor_c=>sc_association-root-docreference
iv_fill_data = abap_true
iv_edit_mode = /bobf/if_conf_c=>sc_edit_read_only
IMPORTING
et_data = lt_docref_data
et_target_key = DATA(lt_target_keys)
et_key_link = DATA(lt_key_links)
eo_message = lo_message ).
IF lt_docref_data IS NOT INITIAL.
lt_docref_data_temp = CORRESPONDING #( lt_docref_data ).
SORT lt_docref_data_temp BY btd_tco.
READ TABLE lt_docref_data_temp WITH KEY btd_tco = lc_114 INTO DATA(ls_docref) BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_so_no) = ls_docref-btd_id.
ENDIF.
READ TABLE lt_docref_data_temp WITH KEY btd_tco = lc_73 INTO ls_docref BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_delv_no) = ls_docref-btd_id.
ENDIF.
*--Fetch Delivery Document Details
IF lv_delv_no IS NOT INITIAL.
lv_delv_doc = lv_delv_no+25(10).
SELECT SINGLE a~deliverydocument,a~documentdate,a~shippingcondition,
b~materialbycustomer,b~actualdeliveryquantity,
c~shippingconditionname
FROM i_deliverydocument AS a
INNER JOIN i_deliverydocumentitem AS b
ON b~deliverydocument = b~deliverydocument
INNER JOIN i_shippingconditiontext AS c
ON c~shippingcondition = a~shippingcondition
WHERE a~deliverydocument = @lv_delv_doc
INTO @DATA(ls_delv_det).
IF sy-subrc IS NOT INITIAL.
CLEAR: ls_delv_det.
ENDIF.
ENDIF.
*--Fetch Purchase Order Number.
IF lv_so_no IS NOT INITIAL.
lv_sales_order = lv_so_no+25(10).
SELECT SINGLE purchaseorderbycustomer
FROM i_salesdocument
WHERE salesdocument = @lv_sales_order
INTO @DATA(lv_po_no).
IF sy-subrc IS NOT INITIAL.
CLEAR: lv_po_no.
ENDIF.
ENDIF.
ENDIF.
CATCH /bobf/cx_frw_contrct_violation.
ENDTRY.
TRY.
*--Shipment Date
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_tor_c=>sc_association-root-stop
iv_fill_data = abap_true
iv_edit_mode = /bobf/if_conf_c=>sc_edit_read_only
IMPORTING
et_data = lt_stop_data
eo_message = lo_message ).
IF lt_stop_data IS NOT INITIAL.
lt_stop_data_temp = CORRESPONDING #( lt_stop_data ).
SORT lt_stop_data_temp BY stop_seq_pos.
READ TABLE lt_stop_data_temp WITH KEY stop_seq_pos = lc_l
ASSIGNING FIELD-SYMBOL(<lfs_stop_data>) BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_ship_timestamp) = <lfs_stop_data>-plan_trans_time.
ENDIF.
IF lv_ship_timestamp IS NOT INITIAL.
lv_temp_date = lv_ship_timestamp.
lv_ship_date = lv_temp_date+4(2) && |/| && lv_temp_date+6(2) && |/| && lv_temp_date+0(4).
ENDIF.
ENDIF.
CATCH /bobf/cx_frw_contrct_violation.
ENDTRY.
*--Ship to Address
IF lv_consignee_id IS NOT INITIAL.
SELECT addressid
FROM zi_us_tm_apo_location
WHERE location = @lv_consignee_id
ORDER BY PRIMARY KEY
INTO @DATA(lv_adrs_no) UP TO 1 ROWS.
ENDSELECT.
IF sy-subrc IS INITIAL.
SELECT SINGLE addressid,cityname,postalcode,streetname,housenumber,country,region,addresseename1
FROM i_addrorgnamepostaladdress WITH PRIVILEGED ACCESS
WHERE addressid = @lv_adrs_no
INTO @DATA(ls_shipto_addrs).
IF sy-subrc IS NOT INITIAL.
CLEAR: ls_shipto_addrs.
ENDIF.
ENDIF.
ENDIF.
TRY.
*--Item Details
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_tor_c=>sc_association-root-item_tr
iv_fill_data = abap_true
iv_edit_mode = /bobf/if_conf_c=>sc_edit_read_only
IMPORTING
et_data = lt_tor_item
eo_message = lo_message ).
IF lt_tor_item IS NOT INITIAL.
lt_tor_item_temp = CORRESPONDING #( lt_tor_item ).
SORT lt_tor_item_temp BY item_cat main_cargo_item.
IF lt_tor_item_temp IS NOT INITIAL.
READ TABLE lt_tor_item_temp WITH KEY item_cat = lc_prd main_cargo_item = abap_true
ASSIGNING FIELD-SYMBOL(<lfs_tor_item_temp>) BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_plant) = <lfs_tor_item_temp>-loading_point_id.
ENDIF.
ENDIF.
ENDIF.
CATCH /bobf/cx_frw_contrct_violation.
ENDTRY.
TRY.
*--Sold to Party
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_tor_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_tor_c=>sc_association-root-party
iv_fill_data = abap_true
iv_edit_mode = /bobf/if_conf_c=>sc_edit_read_only
IMPORTING
et_data = lt_soldtoparty
eo_message = lo_message ).
IF lt_soldtoparty IS NOT INITIAL.
lt_soldtoparty_temp = CORRESPONDING #( lt_soldtoparty ).
SORT lt_soldtoparty_temp BY party_rco.
READ TABLE lt_soldtoparty_temp WITH KEY party_rco = lc_sp
ASSIGNING FIELD-SYMBOL(<lfs_soldtoparty>) BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_soldtoparty) = <lfs_soldtoparty>-party_id.
ENDIF.
ENDIF.
CATCH /bobf/cx_frw_contrct_violation.
ENDTRY.
*--Customer Email Address
IF lv_soldtoparty IS NOT INITIAL.
SELECT b~emailaddress
FROM i_buspartaddress WITH PRIVILEGED ACCESS AS a
INNER JOIN i_addressemailaddress_2 WITH PRIVILEGED ACCESS AS b
ON b~addressid = a~addressid
WHERE a~businesspartner = @lv_soldtoparty
INTO TABLE @DATA(lt_customer_email).
ENDIF.
*--Account Detail
SELECT SINGLE b~addresseename1 FROM i_buspartaddress WITH PRIVILEGED ACCESS AS a
INNER JOIN i_addrorgnamepostaladdress AS b ON b~addressid = a~addressid
WHERE a~businesspartner = @lv_consignee_id
INTO @DATA(lv_account).
IF lv_purch_org = lc_comp1. "'50000207'.
*--company1 Logo from se78.
CALL METHOD cl_ssf_xsf_utilities=>get_bds_graphic_as_bmp
EXPORTING
p_object = lc_graphics
p_name = lc_company1
p_id = lc_bmap
p_btype = lc_bcol
RECEIVING
p_bmp = lv_hama_logo
EXCEPTIONS
not_found = 1
internal_error = 2
OTHERS = 3.
IF sy-subrc IS INITIAL.
DATA(lv_logo_xstring) = lv_hama_logo.
ENDIF.
ELSEIF lv_purch_org = lc_comp2. "'50000201'.
*--company2 Logo from se78.
CALL METHOD cl_ssf_xsf_utilities=>get_bds_graphic_as_bmp
EXPORTING
p_object = lc_graphics
p_name = lc_company2
p_id = lc_bmap
p_btype = lc_bcol
RECEIVING
p_bmp = lv_ener_logo
EXCEPTIONS
not_found = 1
internal_error = 2
OTHERS = 3.
IF sy-subrc IS INITIAL.
lv_logo_xstring = lv_ener_logo.
ENDIF.
ENDIF.
*--Fetch Sender's Email Id.
APPEND INITIAL LINE TO lr_name ASSIGNING FIELD-SYMBOL(<lfs_name>).
<lfs_name>-sign = cl_abap_range=>sign-including.
<lfs_name>-option = cl_abap_range=>option-equal.
<lfs_name>-low = lc_name1.
APPEND INITIAL LINE TO lr_name ASSIGNING <lfs_name>.
<lfs_name>-sign = cl_abap_range=>sign-including.
<lfs_name>-option = cl_abap_range=>option-equal.
<lfs_name>-low = lc_name2.
SELECT changeid,name,low FROM zi_tvarvctableforcusto
WHERE changeid = @lc_us_tm004
AND name IN @lr_name ORDER BY PRIMARY KEY
INTO TABLE @DATA(lt_tvarvc).
IF sy-subrc IS INITIAL.
IF lv_purch_org = lc_comp1.
READ TABLE lt_tvarvc WITH KEY name = lc_name1 ASSIGNING FIELD-SYMBOL(<lfs_tvarvc>) BINARY SEARCH.
IF sy-subrc IS INITIAL.
DATA(lv_sender_email) = <lfs_tvarvc>-low.
ENDIF.
ELSEIF lv_purch_org = lc_comp2.
READ TABLE lt_tvarvc WITH KEY name = lc_name2 ASSIGNING <lfs_tvarvc> BINARY SEARCH.
IF sy-subrc IS INITIAL.
lv_sender_email = <lfs_tvarvc>-low.
ENDIF.
ENDIF.
ENDIF.
IF lv_sender_email IS INITIAL.
lv_msg = |Sender Email not maintained in Table: ZI_TVARVCTABLEFORCUSTO - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
rp_status = 2.
save_log_and_return.
ENDIF.
**************************************************************************
*--EMAIL SENDING LOGIC
**************************************************************************
IF lt_customer_email IS NOT INITIAL.
TRY.
DATA(lo_mail) = cl_bcs_mail_message=>create_instance( ).
lo_mail->set_sender( CONV #( lv_sender_email ) ).
LOOP AT lt_customer_email ASSIGNING FIELD-SYMBOL(<lfs_cust_emails>).
lo_mail->add_recipient( CONV #( <lfs_cust_emails>-emailaddress ) ).
ENDLOOP.
lo_mail->set_subject( TEXT-001 ).
*--Add Logo to Body of Email.
lv_company_logo = 'Company Logo'(002).
lo_mail->add_attachment( cl_bcs_mail_binarypart=>create_instance(
iv_content = lv_logo_xstring
iv_content_type = lc_type "'image/bmp'
iv_filename = lv_company_logo ) ).
lv_html =
|<html>| &&
|<body style="font-family: Arial, sans-serif;">| &&
|<div style="text-align:left;">| &&
|<img src="cid:{ lv_company_logo }" width="1000" height="150" alt="Company Logo" /> <br>| &&
|</div>| &&
|<hr/>| &&
|<p><b>Your company1 order has been shipped - PO# { lv_po_no } on { lv_ship_date }.</b></p>| &&
|<p>Thank you for your recent order. The items on your order have been shipped. See below for details.</p><br> | &&
|<table cellpadding="5" style="border-collapse: collapse; width: 80%;">| &&
|<tr><th style="border: none; text-align: left;"><b>Order Details</b></th>| &&
|<th style="border: none; text-align: left;"><b>Shipping Address</b></th></tr>| &&
*--Tags for Order Details & Shipping Address
|<tr><td style="border: none;">Order no: { |{ lv_sales_order ALPHA = OUT }| }</td>| &&
|<td style="border: none;">{ ls_shipto_addrs-addresseename1 }</td></tr>| &&
|<tr><td style="border: none;">Shipping Method: { ls_delv_det-shippingcondition } - { ls_delv_det-shippingconditionname }</td>| &&
|<td style="border: none;">{ ls_shipto_addrs-housenumber },{ ls_shipto_addrs-streetname }</td></tr>| &&
|<tr><td style="border: none;">Ship Date: { lv_ship_date }</td>| &&
|<td style="border: none;">{ ls_shipto_addrs-cityname },{ ls_shipto_addrs-region },| &&
|{ ls_shipto_addrs-postalcode }</td></tr>| &&
|<tr><td style="border: none;">Tracking no: { lv_tracking_no }</td>| &&
|<td style="border: none;">{ ls_shipto_addrs-country }</td></tr></table><br>| &&
*--Dark Lines
|<hr style="margin-bottom: 0.6cm; border: 1px solid black;"/>| &&
|<hr style="border: 1px solid black;"/>| &&
*--Populate Item Details
|<table cellpadding="5" style="border-collapse: collapse; width: 80%;">| &&
|<tr>| &&
|<th style="border: none; text-align: left;"><b>Item Number</b></th>| &&
|<th style="border: none; text-align: left;"><b>Material Number</b></th>| &&
|<th style="border: none; text-align: left;"><b>Description</b></th>| &&
|<th style="border: none; text-align: left;"><b>Order Quantity</b></th>| &&
|</tr>|.
LOOP AT lt_tor_item ASSIGNING FIELD-SYMBOL(<lfs_item>).
IF <lfs_item>-item_cat = lc_prd AND <lfs_item>-main_cargo_item = abap_true.
lv_qty = <lfs_item>-qua_pcs_val.
lv_html_item = lv_html_item &&
|<tr>| &&
|<td style="border: none;">{ |{ <lfs_item>-item_id ALPHA = OUT }| }</td>| &&
|<td style="border: none;">{ |{ <lfs_item>-product_id ALPHA = OUT }| }</td>| &&
|<td style="border: none;">{ <lfs_item>-item_descr }</td>| &&
|<td style="border: none;">{ lv_qty }</td>| &&
|</tr>|.
CLEAR: lv_qty.
ENDIF.
ENDLOOP.
IF lv_html_item IS NOT INITIAL.
lv_html = lv_html && lv_html_item.
ENDIF.
*--Dark Lines
lv_html = lv_html && |</table>| && |<hr style="margin-bottom: 0.6cm; border: 1px solid black;"/>| &&
|<hr style="border: 1px solid black;"/>| &&
|<b>Tracking URL</b><br>| &&
|<a href="{ lv_tracking_url }" style="color: #87CEEB; text-decoration: underline;" target="_blank">{ lv_tracking_url }</a>| &&
|<br/>| &&
|</body></html>|.
LOOP AT lt_atf_file ASSIGNING FIELD-SYMBOL(<lfs_atf_file>).
IF <lfs_atf_file>-content IS NOT INITIAL.
lo_mail->add_attachment(
cl_bcs_mail_binarypart=>create_instance(
iv_content = <lfs_atf_file>-content
iv_content_type = lc_mimetype "'application/pdf'
iv_filename = CONV #( <lfs_atf_file>-file_name )
)
).
ENDIF.
ENDLOOP.
lo_mail->set_main( cl_bcs_mail_textpart=>create_text_html( lv_html ) ).
lo_mail->send( IMPORTING ev_mail_status = DATA(lv_status) ).
IF lv_status = 'E'.
lv_msg = |Email Sending Failed - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
rp_status = 2.
save_log_and_return.
ELSE.
lv_msg = |Email Sent Successfully|.
log_free_text if_bali_constants=>c_severity_status lv_msg.
rp_status = 1.
save_log_and_return.
ENDIF.
CATCH cx_bcs_mail INTO DATA(lx_mail).
ENDTRY.
ELSE.
lv_msg = |Customer Email not maintained in Customer Master - Return|.
log_free_text if_bali_constants=>c_severity_error lv_msg.
rp_status = 2.
save_log_and_return.
ENDIF.
WHEN lc_hazard_form. "ZTM_TOR_HAZARD_FORM.
rp_status = 1.
WHEN OTHERS.
ENDCASE.
ENDMETHOD.