on 06-19-2014 10:00 AM
Hi,
I have been trying to create a sales order using the SAP NCo from Visual Studio (C#) and I'm stuck.
The code I have used is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SAP.Middleware.Connector;
namespace ConsoleApplication2
{
class Program : IDestinationConfiguration
{
static void Main(string[] args)
{
RfcDestinationManager.RegisterDestinationConfiguration(new Program());
RfcDestination destination = RfcDestinationManager.GetDestination("EHP6");
try
{
RfcRepository repo = destination.Repository;
IRfcFunction salesDoc = repo.CreateFunction("BAPI_SALESORDER_CREATEFROMDAT2");
IRfcFunction salesDocCommit = repo.CreateFunction("BAPI_TRANSACTION_COMMIT");
IRfcStructure salesHeader = salesDoc.GetStructure("ORDER_HEADER_IN");
IRfcTable salesItems = salesDoc.GetTable("ORDER_ITEMS_IN");
IRfcTable salesPartners = salesDoc.GetTable("ORDER_PARTNERS");
IRfcStructure salesItemsStruct = salesItems.Metadata.LineType.CreateStructure();
IRfcStructure salesPartnersStruct = salesPartners.Metadata.LineType.CreateStructure();
//Sales Header
salesHeader.SetValue("DOC_TYPE", "MOR");
salesHeader.SetValue("DOC_DATE", Convert.ToDateTime("2014-06-19"));
salesHeader.SetValue("SALES_ORG", "M210");
salesHeader.SetValue("DISTR_CHAN", "01");
salesHeader.SetValue("DIVISION", "M1");
salesHeader.SetValue("CURRENCY", "USD");
//Sales Items
salesItemsStruct.SetValue("ITM_NUMBER", "000010");
salesItemsStruct.SetValue("MATERIAL", "MP_SHEET_22");
salesItemsStruct.SetValue("SHORT_TEXT", "Sheet Grade B, BWT 20lb/75gsm");
salesItemsStruct.SetValue("PLANT", "M210");
salesItemsStruct.SetValue("TARGET_QTY", "2000");
salesItemsStruct.SetValue("TARGET_QU","LBR");
salesItemsStruct.SetValue("TARGET_VAL", "11655.67");
// Partner
salesPartnersStruct.SetValue("PARTN_ROLE", "SP");
salesPartnersStruct.SetValue("PARTN_NUMB", "MP-CUST201");
RfcSessionManager.BeginContext(destination);
salesDoc.Invoke(destination);
salesDocCommit.Invoke(destination);
RfcSessionManager.EndContext(destination);
Console.WriteLine("Sales Order Created!!");
Console.ReadLine();
}
catch (RfcCommunicationException e)
{
e.ToString();
Console.WriteLine(e);
Console.ReadLine();
}
catch (RfcLogonException e)
{
e.ToString();
Console.WriteLine(e);
Console.ReadLine();
}
catch (RfcAbapRuntimeException e)
{
e.ToString();
Console.WriteLine(e);
Console.ReadLine();
}
catch (RfcAbapBaseException e)
{
e.ToString();
Console.WriteLine(e);
Console.ReadLine();
}
}
public RfcConfigParameters GetParameters(String destinationName)
{
if ("EHP6".Equals(destinationName))
{
RfcConfigParameters parms = new RfcConfigParameters();
parms.Add(RfcConfigParameters.AppServerHost, "xx.xxx.xxx.xx");
parms.Add(RfcConfigParameters.SystemNumber, "00");
parms.Add(RfcConfigParameters.SystemID, "IE6");
parms.Add(RfcConfigParameters.User, "user");
parms.Add(RfcConfigParameters.Password, "password");
parms.Add(RfcConfigParameters.Client, "800");
parms.Add(RfcConfigParameters.Language, "EN");
return parms;
}
else return null;
}
}
}
It returns me no error and even displays "Sales Order Created!!" from the try block. But when I check in VBAK, no Sales Order is being created.
Can somebody help me understand, if I have missed out something or if I'm going wrong somewhere?
All dependencies have been added correctly, platform being set to x64. No build/run-time errors.
Thank you for the heads up everybody. I finally solved the error.
Thanks to Venkata for pointing out the IRfcTable bapiTable = salesDoc.GetTable("RETURN"); part.
The error was in sold-to-party/ship-to-party which is actually the partner number.
There is nothing wrong with the code. It's just that sold-to-party/ship-to-party should have the role AG while creating the sales order, otherwise it doesn't get created.
I have attached the entire code, in case it helps someone.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
if sales document is created then you can get the value from
string orderNo = salesDoc.GetValue("SD_NO").ToString();
if there is an error you can get the details from this piece of code
IRfcTable bapiTable = salesDoc.GetTable("RETURN");
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Sreyan Choudhury
have you check if you have completed all the mandatory field?
the partner "SP" is the customer in your system?
here an example on how I've used this bapi in a webdynpro:
* Order Header Details
CLEAR w_order_header_in.
w_order_header_in-doc_type = zauart.
w_order_header_in-sales_org = zvkorg.
w_order_header_in-distr_chan = stru_order_header-distr_chan.
w_order_header_in-division = 'GN'.
w_order_header_in-purch_no_c = stru_order_header-purch_no_s.
w_order_header_in-purch_no_s = stru_order_header-purch_no_s.
w_order_header_in-sales_grp = zvkgrp.
w_order_header_in-sales_off = zvkbur.
w_order_header_in-compl_dlv = stru_order_header-compl_dlv.
w_order_header_in-req_date_h = stru_order_header-req_date_h.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = w_order_items_in-material
IMPORTING
output = w_order_items_in-material.
* Order Partner Details
CLEAR: i_order_partners,w_order_partners.
w_order_partners-partn_role = 'AG'.
w_order_partners-partn_numb = stru_order_partners-partn_numb.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = w_order_partners-partn_numb
IMPORTING
output = w_order_partners-partn_numb.
APPEND w_order_partners TO i_order_partners.
*partener roles
SELECT * INTO w_agenti FROM zagenti WHERE vkgrp = zvkgrp.
CLEAR w_order_partners.
w_order_partners-partn_role = w_agenti-parvw.
w_order_partners-partn_numb = w_agenti-lifnr.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = w_order_partners-partn_numb
IMPORTING
output = w_order_partners-partn_numb.
APPEND w_order_partners TO i_order_partners.
ENDSELECT.
* Order Items
LOOP AT stru_order_items INTO i_order_items.
CLEAR: w_order_items_in.
MOVE-CORRESPONDING i_order_items TO w_order_items_in.
w_order_items_in-store_loc = i_order_items-lgort.
w_order_items_in-itm_number = sy-tabix * 10.
w_order_items_in-item_categ = 'TAN'.
w_order_items_in-ship_point = 'LS00'.
w_order_items_in-plant = 'DS00'.
APPEND w_order_items_in TO i_order_items_in.
w_order_items_inx-itm_number = w_order_items_in-itm_number.
w_order_items_inx-target_qty = 'X'.
w_order_items_inx-item_categ = 'X'.
w_order_items_inx-ship_point = 'X'.
w_order_items_inx-plant = 'X'.
IF w_order_items_in-batch IS NOT INITIAL.
w_order_items_inx-batch = 'X'.
ENDIF.
IF w_order_items_in-store_loc IS NOT INITIAL.
w_order_items_inx-store_loc = 'X'.
ENDIF.
APPEND w_order_items_inx TO i_order_items_inx.
w_order_schedules_in-itm_number = w_order_items_in-itm_number.
w_order_schedules_in-sched_line = '0001'.
w_order_schedules_in-req_qty = w_order_items_in-target_qty.
APPEND w_order_schedules_in TO i_order_schedules_in.
w_order_schedules_inx-itm_number = w_order_items_in-itm_number.
w_order_schedules_inx-sched_line = '0001'.
w_order_schedules_inx-req_qty = 'X'.
w_order_schedules_inx-updateflag = 'I'.
APPEND w_order_schedules_inx TO i_order_schedules_inx.
* Order Condition Details
IF i_order_items-prriga <> i_order_items-prnet AND
i_order_items-prriga <> i_order_items-prbase.
CLEAR: w_order_conditions_in.
w_order_conditions_in-itm_number = w_order_items_in-itm_number.
w_order_conditions_in-cond_type = 'ZMAN'. “manual
price condition
w_order_conditions_in-cond_value = i_order_items-prriga / 10.
APPEND w_order_conditions_in TO i_order_conditions_in.
ENDIF.
DATA: v_message_riga TYPE string.
* Get message manager
DATA: l_current_controller TYPE REF TO if_wd_controller,
l_message_manager TYPE REF TO if_wd_message_manager.
l_current_controller ?= wd_this->wd_get_api( ).
CALL METHOD l_current_controller->get_message_manager
RECEIVING
message_manager = l_message_manager.
IF i_order_items-prriga = 0 AND i_order_items-omaggio = ''.
CONCATENATE 'Error during the creation '
'empty line INTO v_message_riga.
* v_message_riga = 'Errore durante la creazione. Riga non
*valorizzata'.
* Report Error message
CALL METHOD l_message_manager->report_error_message
EXPORTING
message_text = v_message_riga.
i_bloccasalva = 'X'.
ENDIF.
ENDLOOP.
CLEAR v_sales_doc.
IF i_bloccasalva NE 'X'.
* Create Sales Order BAPI Call
CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2'
EXPORTING
order_header_in = w_order_header_in
IMPORTING
salesdocument = v_sales_doc
TABLES
return = i_return
order_items_in = i_order_items_in
order_schedules_in = i_order_schedules_in
order_items_inx = i_order_items_inx
order_partners = i_order_partners
order_conditions_in = i_order_conditions_in.
* order_text = i_order_text.
ENDIF.
DATA: v_message_text TYPE string.
* When Sales Order is created commit the data
IF NOT v_sales_doc IS INITIAL.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
me->registra_bolla(
EXPORTING
sales_order = v_sales_doc
IMPORTING
delivery = v_delivery_doc
bolla = v_xab ).
LOOP AT i_return INTO w_return.
CONCATENATE v_message_text '/' w_return-message
INTO v_message_text SEPARATED BY space.
ENDLOOP.
wd_context->invalidate( ).
node_order_header = wd_context->get_child_node( 'ORDER_HEADER' ).
node_order_header->set_attribute( EXPORTING name = 'REQ_DATE_H'
value = sy-datum ).
* Report Success message
CALL METHOD l_message_manager->report_success
EXPORTING
message_text = v_message_text.
ELSE.
v_message_text = 'Error during the creation.'.
LOOP AT i_return INTO w_return.
CONCATENATE v_message_text '/' w_return-message INTO v_message_text
SEPARATED BY space.
ENDLOOP.
* Report Error message
CALL METHOD l_message_manager->report_error_message
EXPORTING
message_text = v_message_text.
ENDIF.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Federico,
The partner "SP" is correct. It's not required anyway. I used the data from an existing Sales Order to create a new one. When using Gateway, the above fields were enough to create a Sales Order and also I've seen only these fields as the required fields, in examples, to create a Sales Order.
The mandatory structures are ORDER_HEADER_IN and ORDER_PARTNERS and the necessary fields in the structure have been populated, I think. This is for BAPI_SALESORDER_CREATEFROMDAT2.
Shouldn't it return an error if all the mandatory fields are not populated?
I also tried the above directly using SAP Web-services instead of NCo, but same problem.
Using the values from the code in SE37, Sales Order is getting created perfectly. Just running BAPI_TRANSACTION_COMMIT in test succession after BAPI_SALESORDER_CREATEFROMDAT2 does the job. Even in the code I call BAPI_TRANSACTION_COMMIT after invoking sales order creation BAPI, but no Sales Order is getting created.
Can't seem to find the error in any way.
I may have missed it, but I can't see where you're adding your structure rows to your rfctable. I think you should try this:
// Partner
// salesPartnersStruct.SetValue("PARTN_ROLE", "SP");
// salesPartnersStruct.SetValue("PARTN_NUMB", "MP-CUST201");
salesPartners.Insert(); // This adds a new row
salesPartners.CurrentIndex = salesPartners.Count - 1; // this puts you in the "last" row of the table, if you have multiple rows to insert
salesPartners.SetValue("PARTN_ROLE", "SP");
salesPartners.SetValue("PARTN_NUMB", "MP-CUST201");
RfcSessionManager.BeginContext(destination);
salesDoc.Invoke(destination);
salesDocCommit.Invoke(destination);
RfcSessionManager.EndContext(destination);
etc...
There are other ways of adding rows to rfctables, but this is pretty concise, I think.
User | Count |
---|---|
84 | |
10 | |
10 | |
10 | |
7 | |
6 | |
6 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.