The returned result is null after price is updated with java vdm generated for custom odata service - sap-cloud-sdk

We have a custom OData service(function import) to update price in S/4HANA on-premise system(1909). And I used Java VDM Generator to generate VDM for this OData Service.
OData Service to update price
/sap/opu/odata/SAP//ChangePrice?SalesOrganisation=''&Plant=''&MaterialNumber=''&ConditionAmount=2100&ConditionUnit='EUR'&ValidFrom=datetime'2019-01-01T00:00:00'&ValidTo=datetime'2019-12-31T00:00:00'
After I called the changePrice method and the price is updated in S/4HANA system but the returned entity (priceCondUpdated) is null.
TransferPriceCondition priceCondUpdated = service.changePrice(condUnit,
price,
materialNo,
plant,
LocalDateTime.of(2019, 1, 1, 0, 0, 0),
LocalDateTime.of(2019, 12, 31, 0, 0, 0),
salesOrg).execute(DestinationUtil.getHttpDestination());
I debugged the source code of SAP Cloud SDK and found that the OData Service gave a correct response.
OData response
{"__metadata":{"id":"http://host:port/sap/opu/odata/sap//TransferPriceCondition(SalesOrganisation='',Plant='',MaterialNumber='')","uri":"http://host:port/sap/opu/odata/sap//TransferPriceCondition(SalesOrganisation='',Plant='',MaterialNumber='')","type":".TransferPriceCondition"},"SalesOrganisation":"1709","Plant":"","MaterialNumber":"***","ConditionAmount":"123.000","ConditionUnit":"EUR","ValidFrom":"/Date(1546346659000)/","ValidTo":"/Date(1577796259000)/"}
When it was going to get entity from response in SDK, see source code below responseJsonObject does not contain edmFunctionImportName(changePrice). So it would return null.
Source code of FunctionImportResponseParser.java in Cloud SDK
#Nullable
<T> T getEntityFromResponse(
final InputStream responseContent,
final String edmFunctionImportName,
final Class<? extends T> entityJavaType )
throws IOException,
IllegalArgumentException
{
final JsonObject responseJsonObject = getJsonObjectFromResponse(responseContent);
if( responseJsonObject.has(edmFunctionImportName) ) {
final JsonElement jsonElement = responseJsonObject.get(edmFunctionImportName);
return getEntityFromJsonElement(jsonElement, entityJavaType);
}
return null;
}
Could you help to take a look at this issue?
SAP Cloud SDK Version: 3.3.1
S/4HANA On premise: 1909
Thanks,
Jerry

Thanks for the well documented question! Please use the SAP Cloud SDK version 3.6.0 and above. We fixed the parsing of OData function import results.
Best regards,
Alexander

Related

Complex Queries for Side-by-Side SuccessFactors extension using SAP Cloud SDK (NodeJS)

I am trying to create request builders using SAP Cloud SDK for calling Successfactors Odata APIs. I am facing issues with complex OData querying that includes $expand and maybe custom fields.
https://xxxx.xxxx.xx/odata/v2/WfRequest(11111L)?$expand=wfRequestUINav
I created the request builder as below for the above api:
WfRequest.requestBuilder()
.getByKey(11111)
.select(
WfRequest.WF_REQUEST_UI_NAV
)
.execute({
destinationName: "sfapi"
});
I am getting the below error:
OData get by key request failed!
So I modified the code by adding TO_ to WF_REQUEST_UI_NAV as below:
WfRequest.TO_WF_REQUEST_UI_NAV
but still getting the same error. So I thought it may be a custom field and changed the code as below:
const WF_REQUEST_UI_NAV = WfRequest.customField('wfRequestUINav');
function getWFRequestsDetail() {
return WfRequest
.requestBuilder()
.getByKey(11111)
.select(
WF_REQUEST_UI_NAV
)
.execute({
destinationName: "sfapi"
});
I got the below output, but not the expanded result:
{
"wfRequestUINav": {
"__deferred": {
"uri": "https://api12preview.sapsf.eu/odata/v2/WfRequest(11111L)/wfRequestUINav"
}
}
}
Can anyone help in fixing this issue?
Thanks & Regards,
Harish
I guess the answer can be found in the answers.sap.com as mentioned.

npgsql to PostGIS adds ::text, making st_intersects fail

I've seen numerous old posts about this but no clear solution.
We use PostGreSQL 9.3 with PostGIS 2; NHibernate 3.2.0-GA with Npgsql 2.1.2.
We have an ASP.NET website witch uses MySQL Spatial and we are now in the progress of switching to PostGIS.
My query that fails is send to NHibernate using this code:
string hql = string.Format("select item from {0} item
where NHSP.Intersects(item.Polygon,:boundary)
and item.Layer = :layer", typeof(Data.Item).Name);
IQuery query = CurrentSession.CreateQuery(hql);
query.SetParameter("boundary", boundary, GeometryType);
query.SetParameter("layer", layer);
return query.List<Data.Item>();
This should generate a query like this:
select * from fields
where layer = 'tst'
and st_intersects(polygon,
'0103000020000000000100000005000000F[..]4A40');
But it generates a query like this:
select * from fields
where layer = 'tst'
and st_intersects(polygon,
'0103000020000000000100000005000000F[..]4A40'::text);
Notice the ::text at the end. This results in the following exception:
Npgsql.NpgsqlException: ERROR: 42725: function st_intersects(geometry, text) is not unique
The reason is because the second argument is send as text to PostGIS instead of a geometry.
I've change some code in the NH Spatial library, as suggested elsewhere:
I added these lines to GeometryTypeBase.cs (NHibernate.Spatial)
protected GeometryTypeBase(NullableType nullableType, SqlType sqlTypeOverwrite)
: this(nullableType)
{
this.sqlType = sqlTypeOverwrite;
}
And changed
public PostGisGeometryType()
: base(NHibernateUtil.StringClob)
{
}
into
public PostGisGeometryType()
: base(NHibernateUtil.StringClob, new NHibernate.SqlTypes.SqlType(System.Data.DbType.Object))
{
}
in PostGisGeometryType.cs (PostGIS driver)
When I run my application I now get a cast exception on
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
this.nullableType.NullSafeSet(cmd, this.FromGeometry(value), index);
}
also in GeometryTypeBase.cs (NHibernate.Spatial):
System.InvalidCastException: Can't cast System.String into any valid DbType.
Any suggestion how to fix this is much appreciated.
I've kept on searching and altering my search string I've found the answer in https://github.com/npgsql/Npgsql/issues/201
In NpgsqlTypes.NpgsqlTypesHelper.cs
nativeTypeMapping.AddType("text_nonbinary", NpgsqlDbType.Text, DbType.Object, true);
nativeTypeMapping.AddDbTypeAlias("text_nonbinary", DbType.Object);
needs to be changed to
nativeTypeMapping.AddType("unknown", NpgsqlDbType.Text, DbType.Object, true);
nativeTypeMapping.AddDbTypeAlias("unknown", DbType.Object);
And also my earlier fix to PostGisGeometryType needs to be done.
Now I finally can get my geometry data from PostGIS.

How to get Azure service pricing details programmatically?

Can anybody please tell me how can I programmatically get Azure service pricing details (pricing for Compute, Data Services , App Services, Network Services) from Azure website?
Does Azure provide the pricing details in JSON format?
Windows Azure does'not provide any such API as of today, although it is a much asked feature and hopefully they are working on it.
Check here:
http://feedback.windowsazure.com/forums/170030-billing/suggestions/1143971-billing-usage-api#comments
The only way for now could be to build your own data store with details mentioned here : http://azure.microsoft.com/en-us/pricing/calculator/
Unit wise price will be mentioned in the usage data csv, but unfortunately the only way for now is to download this csv for your subscription here: https://account.windowsazure.com/Subscriptions
Azure now provides API's to get usage and billing data. You can have a look at this blog which gives an overview of these API's and the feedback form here which contains links to some useful pages.
In summary use the following API's to get usage and billing data:
Resource usage
Resource ratecard
Not sure, if i am too late to answer.
I was looking for the same thing and stumble upon this post on stack overflow: Azure pricing calculator api. I was able to generate JSON string using this git hub repo: https://github.com/Azure-Samples/billing-dotnet-ratecard-api.
Hope this helps!
Late to the party but I found myself looking for this and nothing here got me what I wanted. Then I found this https://learn.microsoft.com/en-us/rest/api/cost-management/retail-prices/azure-retail-prices
It is pretty straight forward. Add the reference to the Json.NET .NET 4.0 to your project It shows up in your references as Newtonsoft.Json
//You will need to add these usings
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Net.Http;
private void btnGetRates_Click(object sender, EventArgs e)
{
string strUrl = "https://prices.azure.com/api/retail/prices?$filter=serviceName eq 'Virtual Machines' and skuName eq 'E64 v4' and reservationTerm eq '3 Years'";
string response = GetDataFromAPI(strUrl);
// Here is am turning the Json response into a datatable and then loading that into a DataGridView.
//You can use the Json response any way you wish
DataTable dt = Tabulate(response);
dgvAzureSKU.DataSource = null;
dgvAzureSKU.DataSource = dt;
}
public string GetDataFromAPI(string url)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
var response = httpClient.GetStringAsync(new Uri(url)).Result;
return response;
}
}
public static DataTable Tabulate(string json)
{
var jsonLinq = JObject.Parse(json);
// Find the first array using Linq
var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
var trgArray = new JArray();
foreach (JObject row in srcArray.Children<JObject>())
{
var cleanRow = new JObject();
foreach (JProperty column in row.Properties())
{
if (column.Value is JValue) // Only include JValue types
{
cleanRow.Add(column.Name, column.Value);
}
}
trgArray.Add(cleanRow);
}
return JsonConvert.DeserializeObject<DataTable>(trgArray.ToString()); //This is what loads the data into the table
}
You can find some examples for that here https://learn.microsoft.com/en-us/azure/billing/billing-usage-rate-card-overview. Azure provides invoice, usage and ratecard APIs which can help you to do things like:
Azure spend during the month
Set up alerts
Predict bill
Pre-consumption cost analysis

How to get real T-SQL generated by Entity Framework with ToTraceString() not working

//get full list of active employees
public static object EmployeeList()
{
string traceFile = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var empList = (from emp in dbViews.EmployeeList
where emp.StatusID == 7
orderby emp.EmpNo
select new
{
emp.id,
emp.Name,
emp.EmpNo,
emp.Telephone,
emp.EmployeeType,
emp.DepartmentName,
emp.Supervisor,
emp.ImmediateSupervisor,
emp.StatusID
});
File.AppendAllText(traceFile, ((ObjectQuery)empList).ToTraceString());
return empList.ToList();
}
When executing the above code, am getting the error below and am not sure why
*
Unable to cast object of type
'System.Data.Entity.Infrastructure.DbQuery1[<>f__AnonymousType09[System.Int32,System.String,System.String,System.String,System.String,System.String,System.String,System.String,System.Nullable`1[System.Int32]]]'
to type 'System.Data.Objects.ObjectQuery'.
*
I just want to get the real T-SQL generated by the above Entity Framework code.
The error is at line below
File.AppendAllText(traceFile, ((ObjectQuery)empList).ToTraceString());
You are using DbContext API so you can use just empList.ToString().

How do I perform a MOSS FullTextSqlQuery and filter people results by the Skills managed property?

I am having trouble with a MOSS FulltextSqlQuery when attempting to filter People results on the Skills Managed Property using the CONTAINS predicate. Let me demonstrate:
A query with no filters returns the expected result:
SELECT AccountName, Skills
from scope()
where freetext(defaultproperties,'+Bob')
And ("scope" = 'People')
Result
Total Rows: 1
ACCOUNTNAME: MYDOMAIN\Bob
SKILLS: Numchucks | ASP.Net | Application Architecture
But when I append a CONTAINS predicate, I no longer get the expected result:
SELECT AccountName, Skills
from scope()
where freetext(defaultproperties,'+Bob')
And ("scope" = 'People')
And (CONTAINS(Skills, 'Numchucks'))
Result
Total Rows: 0
I do realize I can accomplish this using the SOME ARRAY predicate, but I would like to know why this is not working with the CONTAINS predicate for the Skills property. I have been successful using the CONTAINS predicate with a custom crawled property that is indicated as 'Multi-valued'. The Skills property (though it seems to be multi-valued) is not indicated as such on the Crawled Properties page in the SSP admin site:
http:///ssp/admin/_layouts/schema.aspx?ConsoleView=crawledPropertiesView&category=People
Anyone have any ideas?
So with the help of Mark Cameron (Microsoft SharePoint Developer Support), I figured out that certain managed properties have to be enabled for full text search using the ManagedProperty object model API by setting the FullTextQueriable property to true. Below is the method that solved this issue for me. It could be included in a Console app or as a Farm or Web Application scoped Feature Receiver.
using Microsoft.Office.Server;
using Microsoft.Office.Server.Search.Administration;
private void EnsureFullTextQueriableManagedProperties(ServerContext serverContext)
{
var schema = new Schema(SearchContext.GetContext(serverContext));
var managedProperties = new[] { "SKILLS", "INTERESTS" };
foreach (ManagedProperty managedProperty in schema.AllManagedProperties)
{
if (!managedProperties.Contains(managedProperty.Name.ToUpper()))
continue;
if (managedProperty.FullTextQueriable)
continue;
try
{
managedProperty.FullTextQueriable = true;
managedProperty.Update();
Log.Info(m => m("Successfully set managed property {0} to be FullTextQueriable", managedProperty.Name));
}
catch (Exception e)
{
Log.Error(m => m("Error updating managed property {0}", managedProperty.Name), e);
}
}
}
SELECT AccountName, Skills
from scope()
where freetext(defaultproperties,'+Bob')
And ("scope" = 'People')
And (CONTAINS(Skills, 'Numchucks*'))
use the * in the end.
You also have a few more options to try:
The following list identifies
additional query elements that are
supported only with SQL search syntax
using the FullTextSqlQuery class:
FREETEXT()
CONTAINS()
LIKE
Source

Resources