Application Development and Automation Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
mmcisme1
Active Contributor
21,727
My requirement was to create a customer statement - easy enough.  The next requirement was a little harder.  It was to use the invoice OPD to determine e-mail or print.  If it was e-mail then where to send it.

To start out, I'm on HANA On-Premise version 1709.

If you need help with setting up OPD, there are some very nice blogs out there:

Output Management via BRF+

New Output Management for Billing

My problem was really not the setup, it was how to add it to my program.   Once I added it, I needed to understand how it worked.  It took me longer than I thought it would.   (By the way you can use this for BFR+ too)  So it was something nice to learn.

So as usual I'm pressed for time.   Let's get started:

First I found the OPD, in BRF+.   Transaction code BRF+.  Keep in mind this was developed via Webdynpro so switching from client to client you'll have to sign in on the html page.



Aha - my OPD applications



Next I opened up the billing document.  There was a lot of great information here.  But I needed to find something specific.  So I opened up the function.



At this point you can run a simulation to test what will come up.    Very nice.  You can also do this via the OPD transaction.   In the OPD transaction you can see the data that has been added.  So now I'm switching to OPD as it is easier - at least for me - to work with.



I found the function I really wanted was channel.  So next I started programming.  Here are some snippets.
  data: lo_factory    type ref to if_fdt_factory,
c_test_app_id type fdt_uuid,
lo_query type ref to if_fdt_query,
lt_ids type if_fdt_types=>ts_object_id,
ls_ids type if_fdt_types=>id.
types:
lt_ids type sorted table of if_fdt_types=>id
with unique default key .

data: lo_fdt_query type ref to if_fdt_query.

clear lt_ids.
call method cl_fdt_query=>get_instance
receiving
ro_query = lo_fdt_query.
* get application id

call method lo_fdt_query->get_ids
exporting
iv_name = 'OPD_V3_BILLING_DOCUMENT'
importing
ets_object_id = lt_ids.

read table lt_ids into ls_ids index 1.

"get factory for application
lo_factory = cl_fdt_factory=>get_instance( exporting iv_application_id = ls_ids ).
* returning c_test_app_id = lo_factory ).

This just pulled in the id that I needed for the billing document.   I retrieved the id for the function.  Now those of you reading this - I skipped some functions.  That was because they were 1 to 1 relationship.  You'll want to modify for your purpose.  (Try/Catch would be nice to add as well.)
  lo_query = lo_factory->get_query( iv_object_type = if_fdt_constants=>gc_object_type_function ).
lo_query->get_ids(
exporting
iv_name = 'FUNC_CHANNEL'
importing
ets_object_id = lt_ids ).
read table lt_ids into ls_ids index 1.
if sy-subrc = 0.
gv_channel_id = ls_ids.
else.
* Move to error table
endif.

Next was the actual work.  I've read not to use the following as it takes too long.  I've also read this is the best way  to do it.  I wanted to avoid using the actual ids without the names.
        lo_context->set_value( iv_name = 'OUTPUT_TYPE' ia_value = lv_form ).
lo_context->set_value( iv_name = 'ROLE' ia_value = lv_role ).
lo_context->set_value( iv_name = 'BUSINESS_PARTNER_ID' ia_value = lv_kunnr ).

lv_function_id = gv_channel_id.

try.

data lt_abap_parbind type abap_parmbind_tab.
data _v_timestamp2 type if_fdt_types=>timestamp.

field-symbols <fs_any> type any.


clear lr_data.
get reference of lt_out into lr_data.

****************************************************************************************************
* Trigger function processing
****************************************************************************************************
assign lr_data->* to <fs_any>.
call method cl_fdt_function_process=>process
exporting
iv_function_id = lv_function_id
iv_timestamp = _v_timestamp2
io_context = lo_context
importing
ea_result = <fs_any>
changing
ct_name_value = lt_abap_parbind.
lt_out = <fs_any>.

read table lt_out into ls_out
with key exclusive_ind = abap_true.
if sy-subrc = 0 and
ls_out-channel = 'EMAIL'.
gv_print = abap_false.
else.
gv_print = abap_true.
endif.

Now I had if the document should be e-mailed or printed.   I found that our e-mail addresses were stored in transaction BP and not in the OPD.  So I pulled the default e-mail address.

After you've read all this keep in mind.   BRF+ will generate the code for you.  I didn't like all the hard coding.

BRF+ Basics

You can also take all your coding out of it by generating a function module.  Again this is in BRF+, but OPD is really part of BRF+.  You want to be inside your function.  Then click on tools.  There will be an option to generate a function module.  Again the hard coding made me hesitant to use it. I like more control.



More details in the following and you'll notice some duplication from my post and this one.  It really helped me a lot.

My learnings in BRF+

 

Pretty cool.  Now I can think of a lot of uses for BRF+.   Those custom tables that I have that determine something like highest dollar amount, those could easily be switched to BRF+.

That's my quick example.  Now a challenge - if you have a better way of doing this - please add it in the comments.
26 Comments
Nice one Michelle
mmcisme1
Active Contributor
0 Kudos
Thank you!
ChrisSolomon
Active Contributor
0 Kudos
Very nice!!! I actually like BRF+ a LOT but sadly, it just isn't used all that much at clients (at least from what I have seen). Not sure why (maybe "another thing" for the tech folks to have to learn?) because it is pretty dang simple to pick up for all the "power" it can give you.

Keep 'em coming! I like to see actual work in the trenches and not yet another marketing blog disguised as something I might like because it used technical terms in the title. hahaha

 
SyambabuAllu
Contributor
Good Information ..Surely,I will try this.

 
mmcisme1
Active Contributor
I'm laughing.  A marketing blog this is not.   But my next paragraph could be considered marketing.

I bought the BRFPlus Business Rule Management for ABAP Application book.  I've gotten to look at it a little but I am still on "hot" projects.  So I haven't had a chance to use this in any other project yet.

When I think about all those Z tables I've set up over the years to contain generic data, and then had to code if/then/case statements, I just shake my head.   Using BRF+ for all of that makes so much sense.   Of course I may change my mind but I doubt it.

Thank you for the nice comment!

Michelle

 
mmcisme1
Active Contributor
Thank you!  With the way OPD is set up BRF+ is a nice skill to have.   It also can be used in many different places - I think.  I'm going to keep trying to use it when it makes sense.
0 Kudos
Hi folks, very helpfully

I am struggling looking a way to determine the Form Template Country in output control for PURCHASE ORDER, user needs to enter manually every time they need to send by EMAIL the PO even when the message is determined correctly but Template Country field remains in blank, any clue to determine this field automatically?

Thanks

mmcisme1
Active Contributor
0 Kudos
I believe you are looking for the t001 table.   SPRO->Enterprise Structure->Definition->Financial Accounting->Edit, Copy, Delete, Check Company Code ->Edit Company Code Data.  Enter the Country for the company code.
0 Kudos
Thanks Michelle, but Company Code has defined Country field. As I told my problem is with field Template Country the one in the picture:


Thanks...
mmcisme1
Active Contributor
0 Kudos
OK - I'll look a bit more.   Country code is usually supplied on the SAP backend.   Not in the output determination.  It is used in output determination, as you noted, in finding the e-mail.

What version are you on?  Are you in the cloud or on-premise?
0 Kudos
I really appreciate your advice, our system is On-Premise, here are the version:

0 Kudos
Hi, I appreciate any clue regarding this issue. Thanks in advance!
mmcisme1
Active Contributor
0 Kudos
OK - I'll try.   Country is defined in different places.   So a lot of it depends on what you have configured.

You checked company.

  • In configuration - I believe - you can check the plant/storage location combination.  In configuration check the sales organization.

  • Check the purchase organization in SPRO.


 

The next thing I would do is check the master data.

  • check the vendor in transaction BP.  Display the financial Services role and check it.


How is your PO created?  Check the transaction data.

  • If it's create from a sales order - take a look at the sales order.   What country was used?

  • If it's created from the purchase transaction without referencing a purchase requisition.   Then it should automatically be filled.   But take a look at the purchase order anyway.

  • If it's created from an info-record, take a look at the info-record.  Is country filled in?

  • Is there any custom code used?  Could it effect the country?


Last but not least, try posting a question in the forums.  Their are a lot more people there who might help you out.    Remember when you post, it is not a problem with Output Determination.   It is a problem with the purchase order country code.  That way you can ask the correct question.

If all else fails, and it shouldn't, then you can make some custom changes to the code. (BADI, user exit, or enhancement point)  But I would really discourage you from doing that until you've tried all other options.

Best of luck!

Michelle

 
Sijin_Chandran
Active Contributor
0 Kudos
Hi Michelle,

First thanks for this write up.

Will the approach detailed here be useful for my below requirement ?

https://answers.sap.com/questions/13085900/badi-for-manipulating-receiver-email-address-for-p.html

Please suggest on this.

Thanks,

Sijin
0 Kudos
Thanks Michelle  for the detailed information on BRF+.

I wanted to know if is it possible to have editable Email body for the outputs which we setup using BRF+ so that a note is added by user. Currently user is using Medium 7 to send mails to multiple recipients  and also adding a note to the email.  Using BRF+ we can send mails to multiple recipients. But is it possible to add email body every time a mail is sent?
former_member663595
Discoverer
0 Kudos
Hi Michelle,

Excellent document.  Appreciate the effort and sharing the document.

I have a question about how to enable "Messages" tab at a PO without hitting Save.  Is it possible to do this without ABAP code?

Thank you,

Johnson Li
mmcisme1
Active Contributor
0 Kudos
Not to my knowledge.  I know we used to use ME9F.  But I believe that will only work for purchase orders defined the "old" way with NAST.
former_member663595
Discoverer
0 Kudos
Michelle:

 

Thank you.

 

Johnson Li
lisa_demoor
Discoverer
0 Kudos
Hi Hector and Michelle, I am bumping into the same issue but then for sales order. Did you find the solution by any chance?

Looking forward hearing from you.

Best regards,

Lisa
mmcisme1
Active Contributor
0 Kudos
Did you try looking at note 2575996?  It might help you out.
lisa_demoor
Discoverer
Hi Michelle,

I eventually solved the issue with adding other role to receiver. So problem is solved, thank you! Your blog is really helpful.
mmcisme1
Active Contributor
Perfect!  Now the next person knows.
former_member136556
Discoverer
0 Kudos
Hi,

 

I have to change recipient email address in EMAIL channel output in PO BRF+. I implemented BADI BADI_MM_PO_OC_EMAIL method IF_BADI_MM_PO_OC_EMAIL~CHANGE_RECIPIENTS, but BADI is not triggered.

I'm wandering what am I missing? Any help is appreciated.

 

Thanks,

Lena
Hi

I also tested this BADI but it was not working with OPD.

I found another solutions :

1) Using your Callback Class -> method GET_DATA_FROM_ROLES

This solution is simple. But we can only add 1 TO email adress.

 

Please let me know if you found something else 😉

Regards,

David.
mmcisme1
Active Contributor
I think it depends on what you are doing.  For me I had to add more than one e-mail to my output.   To do this it required a enhancement to the program itself.  It worked - not sure if it is a recommended approach.

To create multiple emails I used IF_APOC_OR_PARAM_DETERMINATION~DETERMINE_EMAIL_RECEIVER and set an enhancement point at the end of the method.

I checked the object type and the channel.  Here's what it looked like.
IF is_or_item-appl_object_type = 'PURCHASE_CONTRACT' AND
is_or_item-channel = 'EMAIL'.
data(lv_zpc) = iv_appl_object_id(10).
*
* Save default fields
READ TABLE et_email_receiver INTO DATA(ls_zrec) INDEX 1.

SELECT *
INTO TABLE @DATA(lt_zemail)
FROM zpurcon_intemail
WHERE ebeln = @lv_zpc.
IF sy-subrc = 0 AND
lt_zemail IS NOT INITIAL.
CLEAR et_email_receiver.
LOOP AT lt_zemail INTO DATA(ls_zemail).
CLEAR: ls_zrec-email_role, ls_zrec-email_uri.
IF ls_zemail-zemail_or_cc = abap_true. "Copy
ls_zrec-email_role = 'CC'.
ELSE.
ls_zrec-email_role = 'TO'.
ENDIF.
ls_zrec-email_uri = ls_zemail-zemail.
APPEND ls_zrec TO et_email_receiver.
ENDLOOP.
ENDIF.
ENDIF.
0 Kudos
Hi c436ae948d684935a91fce8b976e5aa7

I have 2 output

1- order confirmation

2- order confirmation change

i want second output should trigger when any changes made in sales order,

 

Avika
Labels in this area