Post data to custom AL field in Business Central - dynamics-crm

I am trying to create an API call to add data into a custom field that was created on the Sales Order page using AL Extensions. The issue is when I try to do the api call through postman, I am getting "The Property "propertyName" does not exist on type 'Microsoft.NAV.salesOrder'". First of all, I don't even know if the API allows for this, so is it even possible? And secondly, if it is possible, is there a certain way to set up the API call or the Field through the AL Extension?
tableextension 50100 "AddProjectIdToSalesOrder" extends "Sales Header"
{
fields
{
field(50100; "CrmProjectId"; Guid)
{
Caption = 'Crm Project Id';
DataClassification = OrganizationIdentifiableInformation;
}
}
}
pageextension 50100 "AddProjectIdToSalesOrder" extends "Sales Order"
{
layout
{
addlast(General)
{
field("CRM Project Id"; Rec.CrmProjectId)
{
ApplicationArea = all;
ToolTip = 'The Guid of the related Project Record in the CRM environment';
}
}
}
}
This is how I am setting up the field with the AL extension, and for the post call, I am just creating a new Sales Order with a post and the body looks like:
{
"customerNumber" : "10000",
"CrmProjectId" : "random-guid"
}
And the error is "Bad Request": "The property 'CrmProjectId' does not exist on type 'Microsoft.NAV.salesOrder'. Make sure to only use property names that are defined by the type." Any help would be appreciated.

The Sales Order API is a separate page. It is not equivalent to the Sales Order page so you have to modify the API to accomplish what you want.
However the standard API's provided by Microsoft can't be extended.
You are left with two options:
Make a copy of the standard Sales Order API (this involves making a copy of all the linked APIs as well e.g. the Sales Line API).
Create a new API page with the single purpose of updating your new field. Then you would use the standard Sales Order API to create the Sales Order and then update CrmProjectId with a second call to your custom API page.

Related

Make column section width relative in D365 Business Central cloud

I am a seasoned MS CRM developer with very little experience in BC/AL development.
I have a current CRM client that also uses BC and has I small request I am trying to assist with.
When adding new column sections in a record, the client wants the column section widths to be relative so that the users don't have to scroll down to view the additional column section.
example below:
I have succeeded connecting VS Code to BC cloud tenant and have validated the connection with a simple "Hello World" function after deployed.
May someone point me in the right direction on how to approach the AL I need to use?
Regards.
I don't think there is an easy solution for what you are searching for.
You can take a look at "Grid Layout" for pages, but grid layouts are not that relative.
https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-arrange-fields-in-rows-and-columns-using-gridlayout-control
With Grid Layouts you can define columns and put your fields in these columns.
How i understand you want to change an existing page (item page) so you could try somthing like this:
pageextension 50100 ItemCardExtension extends "Item Card"
{
layout
{
modify(Item)
{
Visible = false;
}
addafter(Item)
{
grid(MyGrid)
{
group("Column1")
{
// Add fields here
}
group("Column2")
{
// Add fields here
}
group("Column3")
{
// Add fields here
}
}
}
}
}
But there will be some additional Problems, if you add all fields you need to implemnt all the exitsing Code (triggers on page level) by yourself (personally i wouldn't do this). Maybe you could try and add only one field by code for each group and add all other fields from the client with personalisation, but i never tried that.

Creating a filtered search based on different parameters

i need to create a filtered search based on different paramnters chosen by a user. So, for example, my app is a property app. I want them to be able to define the county, town, max,min bedrooms ect from a dropdown list and press search, and this returns all the properties that match the criteria.
How do I go about doing this? I can't find any tutorials online, but maybe I'm not phrasing it right.
Here is an image of what I'm after from a UI point of view.
https://imgur.com/a/YEEqt
The following is an easy to go solution considering your experience.
Create a new controller or a method in an existing one.
First create a simple form (method GET) in blade that will return predefined values from simple hidden fields
Create a new GET route in which the form must be submitted and link it to the controller method that you created
In your controller method get the submitted form data from your request, make the correct queries and return the blade template file that contains the form with the results
Modify blade template to show results
Finally replace the hidden fields with selects drop-downs and modify your controller in order to populate them
You can make the form submission process and the select drop-down fields population asynchronous but based on your experience with Laravel it should be hard. Following the steps above will do your job.
Always take a look to the official documentation. You will ge a lot of help from there.
You can try like this for filter options in your controller
public function filter(Request $request, Property $property)
{
$property = $property->newQuery();
// Search for a property based on country
if ($request->has('country')) {
return $property->where('country', $request->input('country'));
}
// Search for a property based on their area.
if ($request->has('areas')) {
return $property->where('areas', $request->input('areas'));
}
// Search for a property based on max_price
if ($request->has('max_price')) {
return $property->where('price','<=', $request->input('max_price'));
}
// Continue for all of the filters.
return $property->get();
}
For more info refer the link

How to share location with public tag with Glympse REST API

I am trying to share a location to a public tag in Glympse with their REST API. My application is creating a ticket with
/v2/users/self/create_ticket
After that I am trying to add that ticket to the public tag/group (which is already available).
/v2/tickets/${ticketid}/append_data
{
[
"t": ${timestamp},
"pid": 0,
"n": "card_id",
"v": card_id // I am putting the group ID here
]
}
After that I have no clue how to proceed. I find the Glympse API description very confusing, so I tried several API functions but none of them worked, like updating the card
/v2/cards/${groupdid}/ticket
error: { result: 'failure', response: {}, meta: { error: 'invalid_access',
error_detail: 'Error processing request',
time: 1506944558077 } }
or simply just adding location data (no error but nothing visible in the tag)
/v2/tickets/${ticketid}/append_location.
Can you help me with the flow how to share the data to a public tag? I cannot find anything like that for the REST API. I could find this link: https://developer.glympse.com/docs/core/client-sdk/guides/common/groups but it does not help me with JavaScript and REST.
Thank you
Cards are only for private groups. To share to a public group (public tag) after you create the ticket, you create an invite of type "group" where the address is the name of the tag.
https://developer.glympse.com/docs/core/api/reference/tickets/id/create_invite/post
The group type appears to be missing from that reference page, but that is the type to use.
For example, to share to a tag named "testtag123":
tickets/[ticket_id]/create_invite?locale=en_US&region=en_US&type=group&send=server&address=testtag123&name=testtag123

Apollo/React mutating two related tables

Say I have two tables, one containing products and the other containing prices.
In Graphql the query might look like this:
option {
id
price {
id
optionID
price
date
}
description
}
I present the user with a single form (in React) where they can enter the product detail and price at the same time.
When they submit the form I need to create an entry in the "product" table and then create a related entry in the "price" table.
I'm very new to Graphql, and React for that matter, and am finding it a steep learning curve and have been following an Apollo tutorial and reading docs but so far the solution to this task is remaining a mystery!
Could someone put me out of my misery and give me, or point me in the direction of, the simplest example of handling the mutations necessary for this?
Long story short, that's something that should actually be handled by your server if you want to optimize for as few requests as possible.
Problem: The issue here is that you have a dependency. You need the product to be created first and then with that product's ID, relate that to a new price.
Solution: The best way to implement this on the server is by adding another field to Product in your mutation input that allows you to input the details for Price as well in the same request input. This is called a "nested create" on Scaphold.
For example:
// Mutation
mutation CreateProduct ($input: CreateProductInput!) {
createProduct(input: $input) {
changedProduct {
id
name
price {
id
amount
}
}
}
}
// Variables
{
input: {
name: "My First Product",
price: {
amount: 1000
}
}
}
Then, on the server, you can parse out the price object in your resolver arguments and create the new price object while creating the product. Meanwhile, you can also relate them in one go on the server as well.
Hope this helps!

Retrieve all OptionSet values using OData in Dynamics CRM

I am quite new to Dynamics CRM. I am building an app which should update entity in Dynamics CRM. I can update simple types without any issues. Now the situation is, I have declared some custom Option Sets in Contact entity.
Is there any way to retrieve all the possible OptionSet values (text and value) so that my app can look for appropriate value and set it in the payload it is generating?
I can not find any endpoint in WebAPI as well as XRMServices/2011/OrganizationData.svc. Any help would be really awesome.
You can use either the Web API or Organisation Service to retrieve The metadata and data models in Microsoft Dynamics CRM. Check out the sub articles of that one for specific examples and details.
Web API example Querying EntityMetadata attributes.
The following query will return only the PicklistAttributeMetadata
attributes and will include the LogicalName as well as expanding the
OptionSet and GlobalOptionSet collection-valued navigation properties.
GET [Organization URI]/api/data/v8.1/EntityDefinitions(70816501-edb9-4740-a16c-6a5efbc05d84)/Attributes/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet,GlobalOptionSet
Another option would be to get the data via the StringMap entity:
[Organization URI]/api/data/v9.1/stringmaps?fetchXml=<fetch><entity name='stringmap'><filter><condition attribute='objecttypecodename' operator='in'><value>account</value><value>opportunity</value></condition></filter></entity></fetch>
Will provide data that looks like this:
{
"#odata.etag": "W/\"406742363\"",
"value": "Open",
"attributename": "statecode",
"langid": 1033,
"objecttypecode": "opportunity",
"attributevalue": 0,
"stringmapid": "0fe09734-3914-e711-80ef-e0071b6a7121",
"organizationid": "f95718b2-5c63-46df-adc3-c3b546cf686a",
"displayorder": 1
},
{
"#odata.etag": "W/\"406742364\"",
"value": "Won",
"attributename": "statecode",
"langid": 1033,
"objecttypecode": "opportunity",
"attributevalue": 1,
"stringmapid": "10e09734-3914-e711-80ef-e0071b6a7121",
"organizationid": "f95718b2-5c63-46df-adc3-c3b546cf686a",
"displayorder": 2
},
Simpler query:
[Organization URI]/api/data/v9.1/stringmaps?$filter=objecttypecode eq 'account' or objecttypecode eq 'opportunity'
If your options are global, this is the easiest way to get all options:
/api/data/v9.1/GlobalOptionSetDefinitions(Name='new_category')
Use below code to get specific option set for specific entity:
(replace EntityLogicalName and AttributeLogicalName with your input params)
GET [Organization URI]/api/data/v9.1/EntityDefinitions(LogicalName='EntityLogicalName')/Attributes/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet($select=Options),GlobalOptionSet($select=Options)&$filter=LogicalName eq 'AttributeLogicalName'
First, you need the attribute name and type, which you can find here:
/api/data/v9.1/EntityDefinitions(LogicalName='myEntity')?$select=LogicalName&$expand=Attributes($select=LogicalName)
Replace myEntity above with your entity name. The resulting page lists all the attributes that make up your entity. Locate the desired option set attribute and note its logical name and type.
Armed with that information, go here:
/api/data/v9.1/EntityDefinitions(LogicalName='myEntity')/Attributes(LogicalName='myAttribute')/Microsoft.Dynamics.CRM.MultiSelectPicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet($select=Options),GlobalOptionSet($select=Options)
Replace myEntity and myAttribute with your entity name and attribute name, respectively. If your attribute type is not MultiSelectPicklistAttributeMetadata, replace that with the correct type that was found on the previous page. This returns a list of all the possible values for the option set (both text and numeric values).

Resources