SAP BAPI Transaction is not committing from WCF - c#

From my WCF Service, I need to create a purchase order in SAP system and it's creating. But when I tried to commit the transaction it's not effecting in SAP system.
I am getting PONumber from SAP and it's not committing.
Can any one help me on this issue.
Here is my code:
NFCLMasters.ZMASTERDATA zmobj = new NFCLMasters.ZMASTERDATA();
NFCLMasters.ZMASTERDATAResponse zmresponse = new NFCLMasters.ZMASTERDATAResponse();
NFCLMasters.ZSM_WH_MST[] zmwarehousemaster = new NFCLMasters.ZSM_WH_MST[10];
NFCLMasters.zws_mst mst = new NFCLMasters.zws_mst();
zmobj.IWHMST = "X";
zmobj.WHMST_LINES = zmwarehousemaster;
zmresponse = mst.ZMASTERDATA(zmobj);
NFCLTransactions.BAPI_PO_CREATE1 Zpo = new NFCLTransactions.BAPI_PO_CREATE1();
NFCLTransactions.BAPI_PO_CREATE1Response Zporesponse = new NFCLTransactions.BAPI_PO_CREATE1Response();
NFCLTransactions.zws_lo SapTrasactions = new NFCLTransactions.zws_lo ();
// Data objects
NFCLTransactions.BAPIMEPOHEADER poheader = new NFCLTransactions.BAPIMEPOHEADER();
NFCLTransactions.BAPIMEPOHEADERX poheaderx = new NFCLTransactions.BAPIMEPOHEADERX();
NFCLTransactions.BAPIMEPOITEM[] poitem = new NFCLTransactions.BAPIMEPOITEM[1];
NFCLTransactions.BAPIMEPOITEMX[] poitemx = new NFCLTransactions.BAPIMEPOITEMX[1];
NFCLTransactions.BAPIMEPOSCHEDULE[] poschedule = new NFCLTransactions.BAPIMEPOSCHEDULE[1];
NFCLTransactions.BAPIMEPOSCHEDULX[] poschedulex = new NFCLTransactions.BAPIMEPOSCHEDULX[1];
NFCLTransactions.BAPIITEMSHIP[] poitemship = new NFCLTransactions.BAPIITEMSHIP[1];
NFCLTransactions.BAPIITEMSHIPX[] poitemshipx = new NFCLTransactions.BAPIITEMSHIPX[1];
NFCLTransactions.BAPIRET2[] Bapireturn = new NFCLTransactions.BAPIRET2[100];
// ASSIGNING VALUES TO EACH OBJECT AND ADDING MAIN BAPI
poheader.COMP_CODE = "NFCL"; poheader.DOC_TYPE = "ZPPS"; poheader.PURCH_ORG = "MKTG"; poheader.PUR_GROUP = "M13"; poheader.DOC_DATE = "2015-02-06";
poheader.SUPPL_PLNT = "1311"; poheader.OUR_REF = "R006";
Zpo.POHEADER = poheader;
poheaderx.COMP_CODE = "X"; poheaderx.DOC_TYPE = "X"; poheaderx.PMNTTRMS = "X"; poheaderx.PURCH_ORG = "X"; poheaderx.PUR_GROUP = "X";
poheaderx.SUPPL_PLNT = "X"; poheaderx.OUR_REF = "X";
Zpo.POHEADERX = poheaderx;
poitem[0] = new NFCLTransactions.BAPIMEPOITEM();
poitem[0].PO_ITEM = "00001"; poitem[0].MATERIAL = "U01016501F"; poitem[0].PLANT = "1311"; poitem[0].STGE_LOC = "K038"; poitem[0].QUANTITY = 10;
poitem[0].PERIOD_IND_EXPIRATION_DATE = "D";
Zpo.POITEM = poitem;
poitemx[0] = new NFCLTransactions.BAPIMEPOITEMX();
poitemx[0].PO_ITEM = "00001"; poitemx[0].MATERIAL = "X"; poitemx[0].PLANT = "X"; poitemx[0].STGE_LOC = "X"; poitemx[0].QUANTITY = "X";
poitemx[0].VAL_TYPE = "X"; poitemx[0].BATCH = "X";
Zpo.POITEMX = poitemx;
poschedule[0] = new NFCLTransactions.BAPIMEPOSCHEDULE();
poschedule[0].PO_ITEM = "00001"; poschedule[0].DELIVERY_DATE = "06.02.2015"; poschedule[0].QUANTITY = 10;
//poschedule[0].DELIV_TIME = 'X';
// poschedule[0].GR_END_TIME
Zpo.POSCHEDULE = poschedule;
poschedulex[0] = new NFCLTransactions.BAPIMEPOSCHEDULX();
poschedulex[0].PO_ITEM = "00001"; poschedulex[0].PO_ITEMX = "X"; poschedulex[0].DELIVERY_DATE = "X"; poschedulex[0].QUANTITY = "X";
Zpo.POSCHEDULEX = poschedulex;
poitemship[0] = new NFCLTransactions.BAPIITEMSHIP();
poitemship[0].PO_ITEM = "00001"; poitemship[0].SHIP_POINT = "R006";
Zpo.POSHIPPING = poitemship;
poitemshipx[0] = new NFCLTransactions.BAPIITEMSHIPX();
poitemshipx[0].PO_ITEM = "00001"; poitemshipx[0].SHIP_POINT = "X";
Zpo.POSHIPPINGX = poitemshipx;
Zpo.RETURN = Bapireturn;
NFCLTransactions.BAPI_TRANSACTION_COMMIT transcommit = new NFCLTransactions.BAPI_TRANSACTION_COMMIT();
transcommit.WAIT = "X";
Zporesponse = SapTrasactions.BAPI_PO_CREATE1(Zpo);
response = Zporesponse.EXPPURCHASEORDER;
NFCLTransactions.BAPI_TRANSACTION_COMMITResponse resp = SapTrasactions.BAPI_TRANSACTION_COMMIT(transcommit);

Your two BAPI calls are currently executed in individual contexts. Therefore the second call to BAPI_TRANSACTION_COMMIT won't work because the second call context doesn't know anything about the results from the first call. You need to execute both calls within the same context. I don't know how to do that with the old, deprecated SAP .Net Connector, but with the current SAP Nco 3 you can achive it by using the methods RfcSessionManager.BeginContext() and RfcSessionManager.EndContext().
If the BAPIs are only exposed as web services, a commit probably won't succeed because all calls to those web services are executed in their own context, so you have the same problem again. A workaround for using web services and BAPI_TRANSACTION_COMMIT would be to create a custom function module in the SAP system that first calls your BAPI and if that call succeeds, calls BAPI_TRANSACTION_COMMIT. That function module would have to be RFC capable and could be exposed as a web service for you. The parameters for that custom function module would (at least) be the same as for the BAPI you need, maybe an additional "COMMIT" parameter to allow you calling it without committing anything. Creating such a function module is relatively easy and shouldn't be a problem for a company familiar with SAP ERP.

Related

"CSOMUnknownUser" It occurrs when I execute the draft project query

I am trying to create a new project in MS Project Server 2016 using PSI C#. It creates a new project along with the task but when I tried to set the values of some custom fields and try to load/execute the query, it returns "CSOMUnknownUser" error.
Can anyone help me out to sort out this problem. my sample code is here
worker = new Classes.ProjectServerWorker();
worker.projContext = new Microsoft.ProjectServer.Client.ProjectContext(SPContext.Current.Web.Url);
NetworkCredential cred = new NetworkCredential();
cred.Domain = "abc";
cred.UserName = "abc";
cred.Password = "abc";
worker.projContext.Credentials = cred;
ProjectCreationInformation newProj = new ProjectCreationInformation();
//ProjectContext projContext = new ProjectContext(SPContext.Current.Web.Url + "/sites/PWA");
try
{
newProj.Id = Guid.NewGuid();
string strGuidID = newProj.Id.ToString();
newProj.Name = "new project title";
newProj.Description = "new project requirement details";
PublishedProject newPublishedProj = worker.projContext.Projects.Add(newProj);
QueueJob qJob = worker.projContext.Projects.Update();
//jobState = worker.projContext.WaitForQueue(qJob, timeoutSeconds);
IsProjectCreated = true;
worker.projContext.Load(worker.projContext.Projects);
worker.projContext.ExecuteQuery();
var proj = worker.projContext.Projects.First(p => p.Name == newProj.Name);
worker.projContext.ExecuteQuery();
var draftProj = proj.CheckOut();
// Creating Task under project
TaskCreationInformation newtask = new TaskCreationInformation();
newtask.Name = "First Task";
newtask.Start = DateTime.Today;
newtask.Finish = DateTime.Today.AddDays(35);
newtask.Id = Guid.NewGuid();
newtask.IsManual = false;
DraftTask drafttask = draftProj.Tasks.Add(newtask);
draftProj.Update();
draftProj.Publish(true); // Publish and check-in the project
worker.projContext.ExecuteQuery();
// Setting Custom Fields data
var guidID = new Guid(strGuidID);
var projcs = worker.projContext.Projects.GetByGuid(guidID);
var draftProjCS = projcs.CheckOut().IncludeCustomFields;
worker.projContext.Load(draftProjCS);
worker.projContext.ExecuteQuery();
string WorkRequestTitle = "new project";
var field1 = worker.projContext.CustomFields.Where(a => a.InternalName== ProjectFields.WorkRequestTitle).FirstOrDefault();
draftProjCS.SetCustomFieldValue(field1.InternalName, WorkRequestTitle);

CreatePushAsync not working: VssServiceException: The parameters supplied are not valid. Parameter name: newPush

I am trying to replicate the post request as given in the doc: https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pushes/create?view=azure-devops-rest-5.0#update_a_file
using the .Net libraries for making an extension.
I have checked that the refUpdate and OldObjectId are correct through trial and error.
changes, item, repo are all defined and not null.
GitPush push = new GitPush();
GitCommit gitCommit = new GitCommit();
GitChange change = new GitChange();
ItemContent content = new ItemContent();
content.Content = changeString;
content.ContentType = ItemContentType.RawText;
change.NewContent = new ItemContent();
change.ChangeType = VersionControlChangeType.Edit;
change.Item = item;
List<GitChange> changes = new List<GitChange>();
changes.Add(change);
gitCommit.Changes = changes;
gitCommit.Comment = "updated app.cpp";
GitRefUpdate refUpdate = new GitRefUpdate();
refUpdate.Name = "refs/heads/dev";
refUpdate.OldObjectId = oldObjectId;
List<GitCommit> commits = new List<GitCommit>();
commits.Add(gitCommit);
List<GitRefUpdate> refUpdates = new List<GitRefUpdate>();
refUpdates.Add(refUpdate);
push.Commits = commits;
push.RefUpdates = refUpdates;
GitPush pushed = gitClient.CreatePushAsync(push, repo.Id).Result;
On the last line the debugger gives the exception that parameter "newPush" is not defined.

Issue on updating line item of journal entry on Netsuite using suite talk API

I am updating journal entry on Net suite using suite talk API.
I can add new lines for the record. but on updating existing line using line ID in am getting below error.
You do not have permissions to set a value for element line.line due to one of the following reasons: 1) The field is read-only; 2) An associated feature is disabled; 3) The field is available either when a record is created or updated, but not in both cases.
i can update lines using GUI but not using API
NetSuiteServiceBridge nsServiceBridge = NetSuiteServiceBridge.serviceInstance;
JournalEntry j = new JournalEntry();
//j.subsidiary =new RecordRef {internalId="2",type=RecordType.subsidiary };
j.internalId = "115939";
JournalEntryLineList jl = new JournalEntryLineList();
JournalEntryLine line1 = new JournalEntryLine();
line1.startDate = DateTime.Now;
line1.startDateSpecified = true;
line1.line = 5;
line1.lineSpecified = true;
line1.account = new RecordRef { internalId = "206", type = RecordType.account };
line1.department = new RecordRef { internalId = "1", type = RecordType.department };
line1.credit = 100;
line1.creditSpecified = true;
jl.line = new JournalEntryLine[] {line1};
jl.replaceAll = false;
j.lineList = jl;
WriteResponse r= nsServiceBridge.UpdateRecords(j);
Web Services has its own permissions separate the the native GUI
This is by design

Expedia hotel API

I am working on Expedia hotel API.All the function are working except booking.All the other request using GET method for requesting.But in booking we have to use the POST method with different URL.So i changed the URL for request but still getting the error.
My codes are
HotelServicesImplService client = new HotelServicesImplService();
HotelRoomReservationRequest bookreq = new HotelRoomReservationRequest();
HotelRoomReservationResponse bookres = new HotelRoomReservationResponse();
addressInfo bookad = new addressInfo();
reservationInfo bookinfo = new reservationInfo();
client.Url = "https://book.api.ean.com/ean-services/rs/hotel/v3";
//bookreq.minorRevSpecified = true;
//bookreq.minorRev = 25;
bookreq.hotelId = 106347;
bookreq.apiKey = "api";
bookreq.cid = "cid";
bookreq.arrivalDate = "12/11/2013";
bookreq.departureDate = "12/13/2013";
bookreq.supplierType = SupplierType.E;
bookreq.rateKey = "af00b688-acf4-409e-8bdc-fcfc3d1cb80c";
bookreq.roomTypeCode = "198058";
bookreq.rateCode = "484072";
bookreq.RoomGroup = new[] { new Room
{
numberOfAdults=Convert.ToInt32(2),
numberOfChildren=Convert.ToInt32(0),
childAges=new int[] {} ,
firstName="Test Booking",
lastName="Test Booking",
bedTypeId="23",
smokingPreference=SmokingPreference.NS,
}};
float i = float.Parse("231.18");
bookreq.currencyCode = "USD";
bookreq.chargeableRate = i;
bookinfo.email = "ranaabhi007#yahoo.com";
bookinfo.firstName = "TestBooking";
bookinfo.lastName = "TestBooking";
bookinfo.homePhone = "2145370159";
bookinfo.workPhone = "2145370159";
bookinfo.creditCardType = "CA";
bookinfo.creditCardNumber = "5401999999999999";
bookinfo.creditCardIdentifier = "TestBooking";
bookinfo.creditCardExpirationMonth = "12";
bookinfo.creditCardExpirationYear = "2015";
bookad.city = "Seattle";
bookad.stateProvinceCode = "WA";
bookad.countryCode = "US";
bookad.postalCode = "98004";
bookreq.ReservationInfo = bookinfo;
bookad.address1 = "travelnow";
//bookad.city = txtCity.Text;
//bookad.stateProvinceCode = txtState.Text;
//bookad.countryCode = txtCountry.Text;
//bookad.postalCode = txtPostal.Text;
bookreq.AddressInfo = bookad;
bookres = client.getReservation(bookreq);
// HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(client);
Response.Write(bookres.confirmationNumbers);
Response.Write(bookres.departureDate);
Response.Write(bookres.drivingDirections);
Response.Write(bookres.CouponInformationResponse);
but i am still getting the error
The request failed with HTTP status 404: Not Found.
Are you sure your URL is correct? According to the documentation, it should be
https://book.api.ean.com/ean-services/rs/hotel/v3/res

DateTime missing from WCF request?

I have a program that is consuming an external web service. 1 of the fields I need to send in the request is a DateTime field however it seems to never be present even though I have set it, along with many others in the same object, and they are passed fine.
I put a message inspector and had a look at what it is sending, here is the request:
<bettingRequest xmlns="">
<accountPin>0</accountPin>
<betDetailsRequestList>
<acceptPartial>0</acceptPartial>
<accumulatorBet>false</accumulatorBet>
<accumulatorId>0</accumulatorId>
<allUpFormula>0</allUpFormula>
<betAmountList>
<amountInvested>25</amountInvested>
<returnsPerBet>0</returnsPerBet>
</betAmountList>
<betRefId>0</betRefId>
<betType>Parimutuel</betType>
<scheduledType>1</scheduledType>
<fixedOddsProdCode>0</fixedOddsProdCode>
<flexiBet>false</flexiBet>
<legList>
<prodCode>1</prodCode>
<propositionNumber>0</propositionNumber>
<raceNumber>2</raceNumber>
<selectionList>
<selectionName>TIM FIN</selectionName>
<selectionNumber>6</selectionNumber>
<selectionSeparator />
</selectionList>
</legList>
<mystery>false</mystery>
<notifyMethod>0</notifyMethod>
<numMultiParlayBet>0</numMultiParlayBet>
<ordinalNumber>1</ordinalNumber>
<meetingCode>13</meetingCode>
</betDetailsRequestList>
</bettingRequest>
and here is what creates it:
bettingRequest betReq = new bettingRequest();
betDetailsReq betDetReq = new betDetailsReq();
List<legDetailsReq> leglist = new List<legDetailsReq>();
List<betSelection> sellist = new List<betSelection>();
List<betAmount> betamtlist = new List<betAmount>();
List<betDetailsReq> betdetaillist = new List<betDetailsReq>();
betSelection sel = new betSelection();
sel.selectionNumber = selection.ToString();
sel.selectionName = Runner;
sel.selectionSeparator = "";
sellist.Add(sel);
legDetailsReq leg = new legDetailsReq();
leg.prodCode = 1;
leg.propositionNumber = 0;
leg.raceNumber = racenum;
leg.selectionList = sellist.ToArray();
leglist.Add(leg);
betAmount betAmt = new betAmount();
betAmt.amountInvested = betamt;
betAmt.returnsPerBet = "0";
betamtlist.Add(betAmt);
betDetReq.betType = "Parimutuel";
betDetReq.betAmountList = betamtlist.ToArray();
betDetReq.legList = leglist.ToArray();
betDetReq.allUpFormula = "0";
betDetReq.acceptPartial = 0;
betDetReq.accumulatorBet = false;
betDetReq.betRefId = 0;
betDetReq.scheduledType = 1;
betDetReq.fixedOddsProdCode = 0;
betDetReq.flexiBet = false;
betDetReq.mystery = false;
betDetReq.notifyMethod = 0;
betDetReq.ordinalNumber = 1;
betDetReq.meetingCode = meetingcode;
betDetReq.meetingDate = DateTime.Now;
betdetaillist.Add(betDetReq);
betReq.betDetailsRequestList = betdetaillist.ToArray();
bettingResponse resp = bet.validateBet(meta, betReq);
and here is the code for the serialization:
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=11)]
public System.DateTime meetingDate {
get {
return this.meetingDateField;
}
set {
this.meetingDateField = value;
this.RaisePropertyChanged("meetingDate");
}
}
The attribute that is missing is the betDetReq.meetingDate, the WSDL can be viewed at https://api.tab.com.au/tabapi/services/betting?wsdl
Can someone tell me where I am going wrong please? I have tried many different variations of DataTime all with the same missing result.
Thanks
Dean
Ensure you have set the "Specified" property to true.
betDetReq.meetingDate = DateTime.Now;
betDetReq.meetingDateSpecified = true;
If you have an optional field (i.e. one where the minOccurs attribute is 0), then the proxy includes a "Specified" property. Unless you set this to true, the field does not get added to the request body.

Categories