XrmDefinitelyTyped icon indicating copy to clipboard operation
XrmDefinitelyTyped copied to clipboard

Typings for standard and custom actions

Open mktange opened this issue 8 years ago • 2 comments

The Web API supports calling both standard and custom actions as seen in the docs.

We need to support both bound and unbound actions, which will likely need two different function calls in XrmQuery to work properly with how the queries are constructed.

Unbound actions

Not bound to a specific entity, and just needs an object with the input fields for the action. This is the simpler version to implement.

Function in XrmQuery:

XrmQuery.unboundAction(x => x.WinOpportunity)
  .executeWith({ 
    Status: opportunity_statuscode.Won,
    OpportunityClose: {
      subject: "Won Opportunity",
      opportunityid_bind$opportunities: "b3828ac8-917a-e511-80d2-00155d2a68d2"
    }
  });

Which will result in the following request:

POST [Organization URI]/api/data/v8.2/WinOpportunity HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0

{
 "Status": 3,
 "OpportunityClose": {
  "subject": "Won Opportunity",
  "[email protected]": "[Organization URI]/api/data/v8.2/opportunities(b3828ac8-917a-e511-80d2-00155d2a68d2)"
 }
}

The return value is to be typed as the corresponding interface which describes the response of calling the action (or undefined/void if none).

Bound actions

Bound to a specific entity, which means we also need the logical name(s) and GUID of the record besides the action name.

Function in XrmQuery:

XrmQuery.boundAction(x => x.AddToQueue, x => x.queues, "56ae8258-4878-e511-80d4-00155d2a68d1")
  .executeWith({
    Target: {
      activityid: "59ae8258-4878-e511-80d4-00155d2a68d1",
      $type: "letter"
 }
});

It may be possible/necessary to have use one of the following signatures instead:

XrmQuery.boundAction(x => x.AddToQueue, "queues", "56ae8258-4878-e511-80d4-00155d2a68d1")
XrmQuery.boundAction(x => x.AddToQueue_$queues, "56ae8258-4878-e511-80d4-00155d2a68d1")

The call should result in the following request:

POST [Organization URI]/api/data/v8.2/queues(56ae8258-4878-e511-80d4-00155d2a68d1)/Microsoft.Dynamics.CRM.AddToQueue HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0

{
 "Target": {
  "activityid": "59ae8258-4878-e511-80d4-00155d2a68d1",
  "@odata.type": "Microsoft.Dynamics.CRM.letter"
 }
}

mktange avatar Jun 21 '17 08:06 mktange

I played around with how the typings can look for unbound actions. The idea is to generate new x.d.ts files for each action. Similar to the entity .d.ts for web. A file would look something like this:

declare namespace XDT {
    interface WinOpportuinity_Input {
        State: string;
    }
    interface WinOpportuinity_Result {
        Data: string;
    }
}
interface UnboundAction {
    WinOpportunity: WebMappingUnboundAction<XDT.WinOpportuinity_Input, XDT.WinOpportuinity_Result>;
}

The dg.xrmquery.web.ts will be extended with new methods

namespace XrmQuery {
  function executeUnboundAction<IInput, Result>(actionPicker: (x: UnboundAction) => WebMappingUnboundAction<IInput, Result>, input: IInput): XQW.UnboundActionExecute<IInput, Result>; 
}
interface UnboundAction {
}
interface WebMappingUnboundAction<IInput, Result> {
    _UnboundExecute: IInput;
}
declare namespace XQW {
  class UnboundActionExecute<IInput, Result>{
    promise(): Promise<Result>;
  }
}

The WinOpportunity action can then be called as following:

let r = await XrmQuery.executeUnboundAction(x => x.WinOpportunity,
  {
    State: "test"
  }).promise();
console.log(r.Data);

This is a bit different from the original suggestion where the input is added through the .executeWith method

TomMalow avatar Feb 26 '20 11:02 TomMalow

Any news about this enhancement?

It would be very useful. I currently implemented my own http-request to call manually the bound and unbound actions. It would be very nice, if I could take the advantage generating all entities with all their actions.

AleksandrAlpatskov avatar Dec 03 '21 10:12 AleksandrAlpatskov