Convert restId to the entryId with calling translateExchangeIds? - microsoft-graph-api

As a followup to Converting restId format type to old Outlook HexEntryId type :
Since user2250152's excellent answer indicates that I have to do some programming myself, I was wondering:
Can I also do the conversion for the restId to the entryId myself?
That would save a call to translateExchangeIds.
Example data from the translateExchangeIds call:
"sourceId": "AAMkADI2ZGIwY2FlLTA1NDQtNGFhYi1hNDJmLWEyMGJhZWU5NmM2YgBGAAAAAACrxyqss0H-T5iGuqwSXncoBwB1kc8DNbIxRK3H-NcbpuL8AAAAAAENAAB1kc8DNbIxRK3H-NcbpuL8AAKHvUXcAAA="
"targetId": "AAAAAKvHKqyzQf9PmIa6rBJedygHAHWRzwM1sjFErcf81xum4vwAAAAAAQ0AAHWRzwM1sjFErcf81xum4vwAAoe9RdwAAA2"
"sourceId": "AAMkADI2ZGIwY2FlLTA1NDQtNGFhYi1hNDJmLWEyMGJhZWU5NmM2YgBGAAAAAACrxyqss0H-T5iGuqwSXncoBwB1kc8DNbIxRK3H-NcbpuL8AAAAAAENAABV1BT8PvI4S78XiwEQP4DVAATuyF7bAAA="
"targetId": "AAAAAKvHKqyzQf9PmIa6rBJedygHAHWRzwM1sjFErcf81xum4vwAAAAAAQ0AAFXUFPw-8jhLvxeLARA_gNUABO7IXtsAAA2"
"sourceId": "AAMkADI2ZGIwY2FlLTA1NDQtNGFhYi1hNDJmLWEyMGJhZWU5NmM2YgBGAAAAAACrxyqss0H-T5iGuqwSXncoBwB1kc8DNbIxRK3H-NcbpuL8AAAAAAENAAB1kc8DNbIxRK3H-NcbpuL8AAJ2Kv4fAAA="
"targetId": "AAAAAKvHKqyzQf9PmIa6rBJedygHAHWRzwM1sjFErcf81xum4vwAAAAAAQ0AAHWRzwM1sjFErcf81xum4vwAAnYq_h8AAA2"

EWS and Graph/rest Id's (which are just a base64URL safe version of the ewsId) contain the EntryId + some flags that tell the backend how to open the item. Microsoft don't document the format because they consider it opaque and subject to change. So you can do it yourself but it won't be supported if you convert both of the values to Hex and work backwards you'll see what i means eg
0003240032366462306361652d303534342d346161622d613432662d61323062616565393663366200460000000000abc72aacb341fe4f9886baac125e772807007591cf0335b23144adc7f8d71ba6e2fc00000000010d00007591cf0335b23144adc7f8d71ba6e2fc0002762afe1f0000
00000000abc72aacb341ff4f9886baac125e772807007591cf0335b23144adc7fcd71ba6e2fc00000000010d00007591cf0335b23144adc7fcd71ba6e2fc0002762afe1f00000d

Related

Illegal sap.ui.model.odata.type.DateTimeOffset

Posting for prosperity. I had zero hits from google.
I'm writing a SAP Business One Web Client extension. I'm using the worklist template and have the b1s/v2/ Service Layer metadata (auto generated while setting up the template)
Running the sandbox version ("npm run start-local") it automatically generates fake data based on the metadata. My data included an edm.DateTimeOffset which is resolved by Fiori using the sap.ui.model.odata.type.DateTimeOffset model.
Here is an example response object from the test data proxy (all autogenerated)
{
DocEntry: 1,
U_CardCode: "U_CardCode_0",
U_CardName: "U_CardName_0",
U_DocCurrency: "U_DocCurrency_0",
U_DocTotal: "",
U_DueDate: "2017-04-13T14:50:39.000Z",
U_Status: "U_Status_0",
U_SupplierInvNo: "U_SupplierInvNo_0",
}
A perfectly normal U_DueDate value that, according to all the documentation I could find is an accepted format, doublely confirmed by the fact that it's a sap generated value.
This produces an error on screen
Illegal sap.ui.model.odata.type.DateTimeOffset
Adding a formatter doesn't work. If it's unable to parse the value then it won't pass it on to a formatter.
Turns out there is a way to override the expected type in the metadata. I couldn't find much documentation on it, but I changed the element from
text="{'U_DueDate'}" />
to
text="{
path: 'U_DueDate',
targetType: 'any',
formatter: '.formatter.date'
}" />
The date is now accepted as a string so I can use a custom formatter.
Here is the date function in the formetter:
date : function (sValue) {
if (!sValue) {
return "";
}
var date = new Date(sValue)
var asString = date.toLocaleDateString("en-GB")
return asString;
}
You don't have to hard code the localization, but my use case is that niche

Add term to listItem in Microsoft Graph API

How do I add a term to a listItem in Microsoft Graph API?
For simple String types (ProductSegment in the example) I do the following:
PATCH https://graph.microsoft.com/v1.0/sites/{{sharepoint_site_id}}/lists/{{sharepoint_list_id}}/items/{{num}}/fields
{
"DisplayedName": "asdasfsvsvdvsdbvdfb",
"DocumentType": "FLYER",
"ProductSegment": ["SEG1"],
"TEST_x0020_2_x0020_ProductSegment": [{
"TermGuid": "c252c37d-1fa3-4860-8d3e-ff2cdde1f673"
}],
"Active": true,
"ProductSegment#odata.type": "Collection(Edm.String)",
"TEST_x0020_2_x0020_ProductSegment#odata.type": "Collection(Edm.Term)"
}
Obviously it won't work for TEST_x0020_2_x0020_ProductSegment. But I just cannot find any hints in the documentation.
I got one step closer thanks to the duplicated issue. First I found the name (not the id) of the hidden field TEST 2 ProductSegment_0 (notice the _0 suffix). Then assembled the term value to send: -1;#MyLabel|c352c37d-1fa3-4860-8d3e-ff2cdde1f673.
PATCH https://graph.microsoft.com/v1.0/sites/{{sharepoint_site_id}}/lists/{{sharepoint_list_id}}/items/{{num}}/fields
{
"DisplayedName": "asdasfsvsvdvsdbvdfb",
"DocumentType": "FLYER",
"ProductSegment": ["SEG1"],
"i9da5ea20ec548bfb2097f0aefe49df8": "-1;#MyLabel|c352c37d-1fa3-4860-8d3e-ff2cdde1f673",
"Active": true,
"ProductSegment#odata.type": "Collection(Edm.String)"
}
and so I can add one item. I would need to add multiple, so I wanted to add the values to an array and set the field type (i9da5ea20ec548bfb2097f0aefe49df8#odata.type) to Collection(Edm.String).
Now I get an error with the code generalException as opposed to an invalidRequest.
As far as I know, graph API does not support updating SharePoint taxonomy. For now, you can go with classic SharePoint REST API for example to accomplish "advanced" things like updating taxonomy terms. Probably a duplicate of: Can't Update Sharepoint Managed Meta Data Field from Microsoft Graph Explorer
Finally I got it.
Thanks #Nikolay for the linked issue.
As I also added this to the end of the question, first you need the name (not the id!) of the hidden field TEST 2 ProductSegment_0 (notice the _0 suffix). Then assemble the term values to send: -1;#MyLabel|c352c37d-1fa3-4860-8d3e-ff2cdde1f673 and -1;#SecondLabel|1ef2af46-1fa3-4860-8d3e-ff2cdde1f673, and separate them with ;# (actually the content of the label is irrelevant but some string needs to be there).
Looks utterly ridiculous but works.
PATCH https://graph.microsoft.com/v1.0/sites/{{sharepoint_site_id}}/lists/{{sharepoint_list_id}}/items/{{num}}/fields
{
"DisplayedName": "asdasfsvsvdvsdbvdfb",
"DocumentType": "FLYER",
"ProductSegment": ["SEG1"],
"i9da5ea20ec548bfb2097f0aefe49df8": "-1;#MyLabel|c352c37d-1fa3-4860-8d3e-ff2cdde1f673";#-1;#SecondLabel|1ef2af46-1fa3-4860-8d3e-ff2cdde1f673,
"Active": true,
"ProductSegment#odata.type": "Collection(Edm.String)"
}

Microsoft Graph: Unable to filter by binary singleValueExtendedProperty

I'm trying to retrieve an event from the grapi api based on a binary extended property that I already have a value for. I have retrieved this value from the same api so I know that an event with this value exists. I also know that the property id is correct since I used this with .Expand() to get the value.
var value = "BAAAAIIA4AB0xbcQGoLgCAAAAAAwMvfBFvzUAQAAAAAAAAAAEAAAAEZ53uCfQ51AhtRf+FNQjOk=";
var cleanGlobalObjectIdPropertyId = "Binary {6ed8da90-450b-101b-98da-00aa003f1305} Id 0x23";
var events = await client.Users["myuser#example.com"].Events.Request()
.Filter($"singleValueExtendedProperties/Any(ep: ep/id eq '{cleanGlobalObjectIdPropertyId}' and ep/value eq '{value}')")
.GetAsync();
This is the error i get:
Microsoft.Graph.ServiceException : Code: ErrorInvalidUrlQueryFilter
Message: The filter expression for $filter does not match to a single extended property and a value restriction.
I have used the same filter syntax with an extended property of type string and that works fine, so I think the fact that this is a binary property is relevant to the problem.
I also faced to this problem. But I try to search for /messages against mapi property SearchKey.
I was thinking to use something like:
https://graph.microsoft.com/v1.0/me/messages?$filter=singleValueExtendedProperties%2FAny(ep%3A%20ep%2Fid%20eq%20'Binary%200x300B'%20and%20ep%2Fvalue%20eq%20'yxum+DwfxUy13C4qs5R6ig==')
According to https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752358
"The six comparison operators can be used with all primitive values except Edm.Binary, Edm.Stream, and the Edm.Geo types."
So I assume that binary should be casted or decoded from base64 somehow, or it's impossible at all.
UPDATE:
So I finally figure it out.
Let's say I got the value of singleValueExtendedProperty as:
{
"id": "Binary 0x300b",
"value": "yxum+DwfxUy13C4qs5R6ig=="
}
And I wanted to find message by value of this property. The problem here is that '+' should be encoded if exists. Also value should be casted to Edm.Binary. Correct query looks like this:
https://graph.microsoft.com/v1.0/me/messages?$filter=singleValueExtendedProperties%2FAny(ep%3A%20ep%2Fid%20eq%20'Binary%200x300B'%20and%20cast(%20ep%2Fvalue,Edm.Binary)%20eq%20binary'yxum%2BDwfxUy13C4qs5R6ig==')

Delphi & Absolute database : Delete Query

Why is it that my query does not work ?
Form1.ABSQuery1.Close;
Form1.ABSQuery1.SQL.Clear;
Form1.ABSQuery1.SQL.Text:='DELETE FROM LOG WHERE status = ''YES'' and DATE BETWEEN :d1 and :d2';
Form1.ABSQuery1.Params.ParamByName('d1').Value :=cxDateEdit1.Date;
Form1.ABSQuery1.Params.ParamByName('d2').Value :=cxDateEdit2.Date;
Form1.ABSQuery1.ExecSQL;
Form1.ABSTable1.Refresh;
I get this error :
You should be using AsDateTime in your Params setting code.
Form1.ABSQuery1.SQL.Text:='DELETE FROM LOG WHERE status = ''YES'' and DATE BETWEEN :d1 and :d2';
Form1.ABSQuery1.Params.ParamByName('d1').AsDateTime :=cxDateEdit1.Date;
Form1.ABSQuery1.Params.ParamByName('d2').AsDateTime :=cxDateEdit2.Date;
Form1.ABSQuery1.ExecSQL;
Using Value converts the cxDateEdit1.Date to a generic string format for assignment, and that doesn't properly convert it to the YYYY-MM-DD format that most databases (including ABS) expect. Properly using AsDateTime allows the database driver/component to convert to the specific date format the DBMS uses.
Also, is your database field really named DATE? Date is usually a reserved word or function name in most DBMS, and if it is it usually needs to be quoted.
Form1.ABSQuery1.Params.ParamByName('d1').DataType := ftDateTime;
Form1.ABSQuery1.Params.ParamByName('d1').Value :=cxDateEdit1.Date;
You must explicitly specify the data type of the parameter to it had no such problem, and then convert to a string does not need to

Highcharts tooltip formatting function

We recently purchased a highcharts license and have integrated it with our Grails application.
We're having some difficulty in that we're unable to specify a tool tip formatter in the JSON object that we're returning because it appears that the HighCharts JSON object doesn't conform to the JSON standards.
Specifically, it appears that JSON is not technically allowed to have JavaScript functions as an object property. From the www.json.org website:
A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.
So, when we output our formatting string, it gets wrapped in double quotes, like this:
"formatter": "this.x + ': ' + this.y",
Can we get an enhancement where we specify a tooltip (or tooltip-fn) property as a string, which is the name of a javascript function? For example:
"formatter": "myTooltipFn"
which calls a javascript function like:
myTooltipFn(chart) {
return chart.x
}
I've just fixed this after hours of labour. My solution was to add the formatter to the data AFTER the data is sent in JSON format to the browser.
So basically, in the js file that has this line:
$(blah).highcharts(data);
write BEFORE this line:
Data.tooltip.formatter = function() {
//write function here
}

Resources