How to connect jira to power BI service and visualize - powerbi
I'm using power BI service inside an virtual machine. I want to connect to jira and whatever changes are made on any tickets, I need to capture in my power BI and visualize this.
Is this achievable?
how to achieve the same?
If you need this to Power BI Service, use Dataflow, blank query, and enter this. However, it's gonna work from anywhere. So even Power BI Desktop Power Query.
Change things that are unique for your case such as BaseUrl, JQL or Authentication
let
// Define the connection, JQL
BaseUrl = "https://jira.yoursite.com",
RelativePath = "/rest/api/2/search?",
JQL = "jql=project=XXX",
maxResults = "&maxResults=40",
startAt = "&startAt=",
// Save the records through paging
initialRequest = (Web.Contents(BaseUrl,
[RelativePath = RelativePath&JQL,
// For authorization, generate JIRA token for your profile and place it into parameter called "token", in order to make this work, or simple replace the token with the string
Headers=[Authorization="Bearer "& token]])),
LoadJson = Json.Document(initialRequest),
totalResults = LoadJson[total],
IssuesThroughPaging = List.Generate( () => 0, each _ <= totalResults, each _ + 40,
each
let
Request = (Web.Contents(BaseUrl,
[RelativePath = RelativePath&JQL&maxResults&startAt&Text.From(_),
Headers=[Authorization="Bearer "& token]])),
GetJson = Json.Document(Request),
RetrieveIssues = GetJson[issues]
in
RetrieveIssues
),
// Expand your lists
ExpandResult = List.Combine(List.Combine({IssuesThroughPaging})),
// Expand Key Column
GetKey = (ListOfIssues as list) =>
let
Keys = List.Transform(ListOfIssues, each Record.Field(_, "key"))
in
Keys,
// Expand Fields
GetFields = (ListOfIssues as list) =>
let
Fields = List.Transform(ListOfIssues, each Record.Field(_, "fields"))
in
Fields,
// Call Key and Field functions
AllKeys = GetKey(ExpandResult),
AllFields = GetFields(ExpandResult),
// Put Keys and Fields together
CreateTable = Table.FromColumns({AllKeys, AllFields}, {"key", "Records"}),
// Expand Needed Records
ExpandFields = Table.ExpandRecordColumn(CreateTable, "Records", {"resolution", "lastViewed", "labels", "issuelinks", "assignee", "subtasks", "reporter", "issuetype", "project", "resolutiondate", "updated", "description", "summary", "duedate", "priority", "status", "creator", "created"}, {"resolution", "lastViewed", "labels", "issuelinks", "assignee", "subtasks", "reporter", "issuetype", "project", "resolutiondate", "updated", "description", "summary", "duedate", "priority", "status", "creator", "created"})
in
ExpandFields
The paging is needed because JIRA returns only 50 rows per response, that's why there's function to gather the responses iteratively.
Thank you, Vojtěch.
It works.
Only one error was with "Authorization". But replacing it with "Prefer" fix it.
corrected parameter
Related
Data from web - DataSource.Error - unable to retrieve contents of page
I'm trying to get a table from a webpage, but I cannot seem to get PowerBI to correctly load that page. The url is https://www.argentorshop.be/verkoop-uw-edelmetaal-aan-argentorshop/verkoop-uw-goudstaven-en-of-gouden-munten-aan-argentor/ The table I'm trying to import is the GOLD KOERSEN table, highlighted in yellow in this screenshot. However, after entering the url, I get Followed by DataSource.Error We were unable to retrieve the contents of the web page. I already tried adding HTTP request headers and Command timeout but nothing seems to work. I also tried to first use a different (working) webpage, and modify the url in the Source step Source = Web.BrowserContents("https://www.w3schools.com/html/html_tables.asp") changed to Source = Web.BrowserContents("https://www.argentorshop.be/verkoop-uw-edelmetaal-aan-argentorshop/verkoop-uw-goudstaven-en-of-gouden-munten-aan-argentor/") but it yields the same error. Also, trying to wait for a specific Selector in the options of Web.BrowserContents(url,options) by using [WaitFor = [Selector = "#verkopen > div.bootstrap-table"]] doesn't do the trick. Does anyone know of a way to correctly import that table in PowerBI?
Try this. let Source = Web.Contents( "http://www.argentorshop.be/nl/graphql", [ Headers=[ #"Method"="POST", #"Content-Type"="application/json" ], Content=Text.ToBinary("{""query"": ""{sellMetalsGrid (metals: [GOLD]){products {entity_id,name,purchasing_price,buying_premium,spread_percentage,spread_currency,selling_premium,price,image,short_description,product_type,fine_metal_content,metal,url,stock_status}}}""}") ] ), #"JSON" = Json.Document(Source), data = JSON[data], sellMetalsGrid = data[sellMetalsGrid], products = sellMetalsGrid[products], #"Converted to Table" = Table.FromList(products, Splitter.SplitByNothing(), null, null, ExtraValues.Error), #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"entity_id", "name", "purchasing_price", "buying_premium", "spread_percentage", "spread_currency", "selling_premium", "price", "image", "short_description", "product_type", "fine_metal_content", "metal", "url", "stock_status"}, {"Column1.entity_id", "Column1.name", "Column1.purchasing_price", "Column1.buying_premium", "Column1.spread_percentage", "Column1.spread_currency", "Column1.selling_premium", "Column1.price", "Column1.image", "Column1.short_description", "Column1.product_type", "Column1.fine_metal_content", "Column1.metal", "Column1.url", "Column1.stock_status"}) in #"Expanded Column1"
Power BI query Connecting to API that uses HMAC Authentication
I am new to power bi, I need to connect to the web API using HMAC authentication. How I can send HMAC auth headers through web request? Or How to do HMAC encryption in the PowerBi query Thanks in advance
It took me forever to realise that the following can be done and is a lot of out of the box thinking. Create a function that generates a html document and have power query's built in rudimentary web browser execute JavaScript snippetes. If your JS code references packages, you need to load them or create links to CDN and change all double quotes to single quotes (I did in text edit with find/replace then copy/paste in code below between double quotes) The following code will do HMAC-SHA512 with secret key (2 args). New Blank Query and paste below code. It took me 2 years since I first tried to do it until it clicked. You're welcome!!! (secret as text, payload as text) => let Source = Web.Page( " <script> //the following are CDN's from https://cdnjs.com/libraries/crypto-js and all double quotes replaced with single quotes //core !function(t,n){'object'==typeof exports?module.exports=exports=n():'function'==typeof define&&define.amd?define([],n):t.CryptoJS=n()}(this,function(){return function(f){var i;if('undefined'!=typeof window&&window.crypto&&(i=window.crypto),'undefined'!=typeof self&&self.crypto&&(i=self.crypto),!(i=!(i=!(i='undefined'!=typeof globalThis&&globalThis.crypto?globalThis.crypto:i)&&'undefined'!=typeof window&&window.msCrypto?window.msCrypto:i)&&'undefined'!=typeof global&&global.crypto?global.crypto:i)&&'function'==typeof require)try{i=require('crypto')}catch(t){}var e=Object.create||function(t){return n.prototype=t,t=new n,n.prototype=null,t};function n(){}var t={},r=t.lib={},o=r.Base={extend:function(t){var n=e(this);return t&&n.mixIn(t),n.hasOwnProperty('init')&&this.init!==n.init||(n.init=function(){n.$super.init.apply(this,arguments)}),(n.init.prototype=n).$super=this,n},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var n in t)t.hasOwnProperty(n)&&(this[n]=t[n]);t.hasOwnProperty('toString')&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}},u=r.WordArray=o.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=null!=n?n:4*t.length},toString:function(t){return(t||a).stringify(this)},concat:function(t){var n=this.words,e=t.words,i=this.sigBytes,r=t.sigBytes;if(this.clamp(),i%4)for(var o=0;o<r;o++){var s=e[o>>>2]>>>24-o%4*8&255;n[i+o>>>2]|=s<<24-(i+o)%4*8}else for(var a=0;a<r;a+=4)n[i+a>>>2]=e[a>>>2];return this.sigBytes+=r,this},clamp:function(){var t=this.words,n=this.sigBytes;t[n>>>2]&=4294967295<<32-n%4*8,t.length=f.ceil(n/4)},clone:function(){var t=o.clone.call(this);return t.words=this.words.slice(0),t},random:function(t){for(var n=[],e=0;e<t;e+=4)n.push(function(){if(i){if('function'==typeof i.getRandomValues)try{return i.getRandomValues(new Uint32Array(1))[0]}catch(t){}if('function'==typeof i.randomBytes)try{return i.randomBytes(4).readInt32LE()}catch(t){}}throw new Error('Native crypto module could not be used to get secure random number.')}());return new u.init(n,t)}}),s=t.enc={},a=s.Hex={stringify:function(t){for(var n=t.words,e=t.sigBytes,i=[],r=0;r<e;r++){var o=n[r>>>2]>>>24-r%4*8&255;i.push((o>>>4).toString(16)),i.push((15&o).toString(16))}return i.join('')},parse:function(t){for(var n=t.length,e=[],i=0;i<n;i+=2)e[i>>>3]|=parseInt(t.substr(i,2),16)<<24-i%8*4;return new u.init(e,n/2)}},c=s.Latin1={stringify:function(t){for(var n=t.words,e=t.sigBytes,i=[],r=0;r<e;r++){var o=n[r>>>2]>>>24-r%4*8&255;i.push(String.fromCharCode(o))}return i.join('')},parse:function(t){for(var n=t.length,e=[],i=0;i<n;i++)e[i>>>2]|=(255&t.charCodeAt(i))<<24-i%4*8;return new u.init(e,n)}},p=s.Utf8={stringify:function(t){try{return decodeURIComponent(escape(c.stringify(t)))}catch(t){throw new Error('Malformed UTF-8 data')}},parse:function(t){return c.parse(unescape(encodeURIComponent(t)))}},d=r.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new u.init,this._nDataBytes=0},_append:function(t){'string'==typeof t&&(t=p.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(t){var n,e=this._data,i=e.words,r=e.sigBytes,o=this.blockSize,s=r/(4*o),a=(s=t?f.ceil(s):f.max((0|s)-this._minBufferSize,0))*o,r=f.min(4*a,r);if(a){for(var c=0;c<a;c+=o)this._doProcessBlock(i,c);n=i.splice(0,a),e.sigBytes-=r}return new u.init(n,r)},clone:function(){var t=o.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),h=(r.Hasher=d.extend({cfg:o.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){d.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){return t&&this._append(t),this._doFinalize()},blockSize:16,_createHelper:function(e){return function(t,n){return new e.init(n).finalize(t)}},_createHmacHelper:function(e){return function(t,n){return new h.HMAC.init(e,n).finalize(t)}}}),t.algo={});return t}(Math)}); //x64-core !function(t,e){'object'==typeof exports?module.exports=exports=e(require('./core')):'function'==typeof define&&define.amd?define(['./core'],e):e(t.CryptoJS)}(this,function(t){var e,o,n,i;return o=(e=t).lib,n=o.Base,i=o.WordArray,(e=e.x64={}).Word=n.extend({init:function(t,e){this.high=t,this.low=e}}),e.WordArray=n.extend({init:function(t,e){t=this.words=t||[],this.sigBytes=null!=e?e:8*t.length},toX32:function(){for(var t=this.words,e=t.length,o=[],r=0;r<e;r++){var n=t[r];o.push(n.high),o.push(n.low)}return i.create(o,this.sigBytes)},clone:function(){for(var t=n.clone.call(this),e=t.words=this.words.slice(0),o=e.length,r=0;r<o;r++)e[r]=e[r].clone();return t}}),t}); //sha512 !function(i,h){'object'==typeof exports?module.exports=exports=h(require('./core'),require('./x64-core')):'function'==typeof define&&define.amd?define(['./core','./x64-core'],h):h(i.CryptoJS)}(this,function(r){return function(){var i=r,h=i.lib.Hasher,o=i.x64,e=o.Word,n=o.WordArray,o=i.algo;function t(){return e.create.apply(e,arguments)}var i1=[t(1116352408,3609767458),t(1899447441,602891725),t(3049323471,3964484399),t(3921009573,2173295548),t(961987163,4081628472),t(1508970993,3053834265),t(2453635748,2937671579),t(2870763221,3664609560),t(3624381080,2734883394),t(310598401,1164996542),t(607225278,1323610764),t(1426881987,3590304994),t(1925078388,4068182383),t(2162078206,991336113),t(2614888103,633803317),t(3248222580,3479774868),t(3835390401,2666613458),t(4022224774,944711139),t(264347078,2341262773),t(604807628,2007800933),t(770255983,1495990901),t(1249150122,1856431235),t(1555081692,3175218132),t(1996064986,2198950837),t(2554220882,3999719339),t(2821834349,766784016),t(2952996808,2566594879),t(3210313671,3203337956),t(3336571891,1034457026),t(3584528711,2466948901),t(113926993,3758326383),t(338241895,168717936),t(666307205,1188179964),t(773529912,1546045734),t(1294757372,1522805485),t(1396182291,2643833823),t(1695183700,2343527390),t(1986661051,1014477480),t(2177026350,1206759142),t(2456956037,344077627),t(2730485921,1290863460),t(2820302411,3158454273),t(3259730800,3505952657),t(3345764771,106217008),t(3516065817,3606008344),t(3600352804,1432725776),t(4094571909,1467031594),t(275423344,851169720),t(430227734,3100823752),t(506948616,1363258195),t(659060556,3750685593),t(883997877,3785050280),t(958139571,3318307427),t(1322822218,3812723403),t(1537002063,2003034995),t(1747873779,3602036899),t(1955562222,1575990012),t(2024104815,1125592928),t(2227730452,2716904306),t(2361852424,442776044),t(2428436474,593698344),t(2756734187,3733110249),t(3204031479,2999351573),t(3329325298,3815920427),t(3391569614,3928383900),t(3515267271,566280711),t(3940187606,3454069534),t(4118630271,4000239992),t(116418474,1914138554),t(174292421,2731055270),t(289380356,3203993006),t(460393269,320620315),t(685471733,587496836),t(852142971,1086792851),t(1017036298,365543100),t(1126000580,2618297676),t(1288033470,3409855158),t(1501505948,4234509866),t(1607167915,987167468),t(1816402316,1246189591)],h1=[];!function(){for(var i=0;i<80;i++)h1[i]=t()}();o=o.SHA512=h.extend({_doReset:function(){this._hash=new n.init([new e.init(1779033703,4089235720),new e.init(3144134277,2227873595),new e.init(1013904242,4271175723),new e.init(2773480762,1595750129),new e.init(1359893119,2917565137),new e.init(2600822924,725511199),new e.init(528734635,4215389547),new e.init(1541459225,327033209)])},_doProcessBlock:function(i,h){for(var o=this._hash.words,e=o[0],n=o[1],t=o[2],r=o[3],l=o[4],w=o[5],a=o[6],s=o[7],c=e.high,g=e.low,f=n.high,u=n.low,d=t.high,_=t.low,p=r.high,H=r.low,v=l.high,y=l.low,x=w.high,S=w.low,A=a.high,m=a.low,B=s.high,o=s.low,b=c,k=g,q=f,z=u,W=d,j=_,C=p,D=H,F=v,J=y,M=x,P=S,R=A,X=m,E=B,G=o,I=0;I<80;I++){var K,L,N=h1[I];I<16?(L=N.high=0|i[h+2*I],K=N.low=0|i[h+2*I+1]):($=(O=h1[I-15]).high,V=O.low,U=(Y=h1[I-2]).high,T=Y.low,Q=(Z=h1[I-7]).high,O=Z.low,Z=(Y=h1[I-16]).high,L=(L=(($>>>1|V<<31)^($>>>8|V<<24)^$>>>7)+Q+((K=(Q=(V>>>1|$<<31)^(V>>>8|$<<24)^(V>>>7|$<<25))+O)>>>0<Q>>>0?1:0))+((U>>>19|T<<13)^(U<<3|T>>>29)^U>>>6)+((K+=V=(T>>>19|U<<13)^(T<<3|U>>>29)^(T>>>6|U<<26))>>>0<V>>>0?1:0),K+=$=Y.low,N.high=L=L+Z+(K>>>0<$>>>0?1:0),N.low=K);var O=F&M^~F&R,Q=J&P^~J&X,T=b&q^b&W^q&W,U=(k>>>28|b<<4)^(k<<30|b>>>2)^(k<<25|b>>>7),V=i1[I],Y=V.high,Z=V.low,$=G+((J>>>14|F<<18)^(J>>>18|F<<14)^(J<<23|F>>>9)),N=E+((F>>>14|J<<18)^(F>>>18|J<<14)^(F<<23|J>>>9))+($>>>0<G>>>0?1:0),V=U+(k&z^k&j^z&j),E=R,G=X,R=M,X=P,M=F,P=J,F=C+(N=(N=(N=N+O+(($=$+Q)>>>0<Q>>>0?1:0))+Y+(($=$+Z)>>>0<Z>>>0?1:0))+L+(($=$+K)>>>0<K>>>0?1:0))+((J=D+$|0)>>>0<D>>>0?1:0)|0,C=W,D=j,W=q,j=z,q=b,z=k,b=N+(((b>>>28|k<<4)^(b<<30|k>>>2)^(b<<25|k>>>7))+T+(V>>>0<U>>>0?1:0))+((k=$+V|0)>>>0<$>>>0?1:0)|0}g=e.low=g+k,e.high=c+b+(g>>>0<k>>>0?1:0),u=n.low=u+z,n.high=f+q+(u>>>0<z>>>0?1:0),_=t.low=_+j,t.high=d+W+(_>>>0<j>>>0?1:0),H=r.low=H+D,r.high=p+C+(H>>>0<D>>>0?1:0),y=l.low=y+J,l.high=v+F+(y>>>0<J>>>0?1:0),S=w.low=S+P,w.high=x+M+(S>>>0<P>>>0?1:0),m=a.low=m+X,a.high=A+R+(m>>>0<X>>>0?1:0),o=s.low=o+G,s.high=B+E+(o>>>0<G>>>0?1:0)},_doFinalize:function(){var i=this._data,h=i.words,o=8*this._nDataBytes,e=8*i.sigBytes;return h[e>>>5]|=128<<24-e%32,h[30+(128+e>>>10<<5)]=Math.floor(o/4294967296),h[31+(128+e>>>10<<5)]=o,i.sigBytes=4*h.length,this._process(),this._hash.toX32()},clone:function(){var i=h.clone.call(this);return i._hash=this._hash.clone(),i},blockSize:32});i.SHA512=h._createHelper(o),i.HmacSHA512=h._createHmacHelper(o)}(),r.SHA512}); //hmac !function(e,t){'object'==typeof exports?module.exports=exports=t(require('./core')):'function'==typeof define&&define.amd?define(['./core'],t):t(e.CryptoJS)}(this,function(e){var t,a;t=e.lib.Base,a=e.enc.Utf8,e.algo.HMAC=t.extend({init:function(e,t){e=this._hasher=new e.init,'string'==typeof t&&(t=a.parse(t));var i=e.blockSize,n=4*i;(t=t.sigBytes>n?e.finalize(t):t).clamp();for(var e=this._oKey=t.clone(),t=this._iKey=t.clone(),s=e.words,r=t.words,o=0;o<i;o++)s[o]^=1549556828,r[o]^=909522486;e.sigBytes=t.sigBytes=n,this.reset()},reset:function(){var e=this._hasher;e.reset(),e.update(this._iKey)},update:function(e){return this._hasher.update(e),this},finalize:function(e){var t=this._hasher,e=t.finalize(e);return t.reset(),t.finalize(this._oKey.clone().concat(e))}})}); !function(e,r){'object'==typeof exports?module.exports=exports=r(require('./core'),require('./x64-core'),require('./sha512'),require('./hmac')):'function'==typeof define&&define.amd?define(['./core','./x64-core','./sha512','./hmac'],r):r(e.CryptoJS)}(this,function(e){return e.HmacSHA512}); </script> <script> z= CryptoJS.HmacSHA512( """&payload&""", """&secret&""" ); document.write(z); </script> "), Data = Source{0}[Data], Children = Data{0}[Children], Children1 = Children{1}[Children], Text = Children1{0}[Text] in Text
Recently I have collected data for clients using oAuth2 API. You can connect to any API using Power/M Query. Following is the sample code for my case, where in the first part I have collected the access_token and in second step, I have collected data using that access token. hope this will give you some idea on connecting to any API using Power Query. let url = "your_authentication_url_here", body = "{ ""client_id"": ""****"", ""client_secret"": ""****"", ""grant_type"": ""****"", ""audience"":""****""}", tokenResponse = Json.Document(Web.Contents(url,[Headers = [#"Content-Type"="application/json"], Content = Text.ToBinary(body) ] )), AccessToken = tokenResponse[access_token], AccessTokenHeader = "Bearer " & AccessToken, data_url = "your_main_url_here", data_body = "{ ""authorization"": """& AccessTokenHeader & """, ""content-type"": ""application/json"" }", GetGroups = Json.Document( Web.Contents( data_url, [ Headers = Json.Document(data_body) ] ) ), categories = GetGroups[categories], --Category here will be changed as per your retrned data #"Converted to Table" = Table.FromList(categories, Splitter.SplitByNothing(), null, null, ExtraValues.Error), #"Expanded Column1" = Table.ExpandRecordColumn ( #"Converted to Table", "Column1", {"ext_id", "shared", "report", "query", "_id", "description"}, --This is column returned from your data set {"ext_id", "shared", "report", "query", "_id", "description"} -- Rename columns accordingly ) in #"Expanded Column1"
Use the Power BI Connector through that you can use Crypto.CreateHmac function and create HMAC auth headers https://www.sqlgene.com/2019/02/19/create-a-power-query-custom-data-connector-in-10-minutes
How to add a dropdown list with parameters that user chooses and append to API request?
In a power query custom connector I can make the user input some text that gets appended to the url to an API request. // Example in the navigator: (optional time_range as text) as table => GetSomething(time_range) // And the actual function GetSomething = (optional time_range as text) => let _time_range = if time_range <> null then time_range else "medium_term", options = [Headers = [#"Content-Type" = "application/Json"], Query = [limit = "50", time_range=_time_range]], source = Web.Contents("https://example.com/v1/me/", options), json = Json.Document(source), listOfItems = json[items] in listOfItems; My goal would be to make the user select from a dropdown list with those three values (short, medium, long), instead of making him write and possible compromise the request. Do you know how to achieve this? I'm searching at the moment. If I find I'll post here.
So, I found the answer in this blogpost: https://blog.crossjoin.co.uk/2014/11/27/specifying-allowed-values-sample-values-and-descriptions-for-function-parameters-in-power-querypart-1/ // just add a type for the parameters and enter AllowedValues GetSomethingParamType = type text meta [Documentation.Description = "Please enter a time range", Documentation.AllowedValues = {"short_term","medium_term","long_term"}], // the type for the function GetSomethingType = type function( _time_range as GetSomethingParamType) as list, // the type replacement GetSomethingV2 = Value.ReplaceType(GetSomething, GetSomethingType)
Dynamics Navision 2017 - Insert Sales Order using Web Services
We have Navision Dynamics 2017 which has Sales Orders exposed as a SOAP web service. Technically, I am supposed to be able to create sales orders via this web service. We also have another system built in C# .NET that has staff sales orders that need to go into Navision. This ordering system has all the information like customer, item, quantity, price etc to be able to create a valid order in Navision. Can someone tell me how I can call the service and create a sales header and Line from the staff sales orders system into Navision.. Preferably a walk through tutorial would be ideal. I've searched and can't seem to find one that I can follow
The classic 'goto' for NAV services was always the following blog post, albeit it's an example for PHP. Take into account changes are required in NAV to be able to interact with the service (Hint: Activate NTLM): https://blogs.msdn.microsoft.com/freddyk/2010/01/19/connecting-to-nav-web-services-from-php/ There is now an updated version by the same autor, complementing the original post: https://blogs.msdn.microsoft.com/freddyk/2016/11/06/connecting-to-nav-web-services-from-php-take-2/ Example for C#: https://blogs.msdn.microsoft.com/freddyk/2010/01/19/connecting-to-nav-web-services-from-c-using-web-reference/ Example for completing a Sales Order: https://blogs.msdn.microsoft.com/freddyk/2009/11/17/extending-page-web-services-and-creating-a-sales-order-again/
I googled it for you. Is for Nav 2013, but it is all the same in 2017. https://community.dynamics.com/nav/b/ishwarsblogspot/archive/2016/09/26/register-and-consume-codeunit-as-a-web-service-in-nav-2013-r2
Here's what I did in the rest API that I developed with .NET Core 5, I created 2 pages (one for sales header and one for sales lines) and one code-unit for invoking calculate discount action on NAV. [Route("order")] [HttpPost] private async Task<dynamic> createOrder(orderDTO request) { var systemService = this.OrderServiceProvider.GetProxy(); List<OrderServiceReference.Sales_Quote_Line> lineList = new List<OrderServiceReference.Sales_Quote_Line>(); foreach (OrderLine orderLine in request.Sales_Quote_Line) { Sales_Quote_Line line = new Sales_Quote_Line() { Type = OrderServiceReference.Type.Item, TypeSpecified = true, No = orderLine.No, Quantity = orderLine.Quantity, QuantitySpecified = true }; lineList.Add(line); } var task = await systemService.CreateAsync(new OrderServiceReference.Create() { Dis_SQ = new Dis_SQ() { Salesperson_Code = request.Salesperson_Code, Sell_to_Customer_No = request.Sell_to_Customer_No, Order_Date = new DateTime(), SalesLines = lineList.ToArray() } }); var salesQuotes = task.Dis_SQ; // var systemService2 = new DiscountServiceReference.Dis_Discount_Cal_PortClient(); var calculateSystemWebService = this.CalculateDiscountServiceProvider.GetProxy(); await calculateSystemWebService.CalcOffersSHAsync(new CalcOffersSH() { Body = new CalcOffersSHBody() { pDocNo = salesQuotes.No, pDocType = 0 } }); // get sales lines var systemService1 = this.OrderLinesServiceProvider.GetProxy(); var task1 = await systemService1.ReadMultipleAsync(new SalesOrderServiceReference.ReadMultiple() { filter = new HHT_SO_Filter[] { new HHT_SO_Filter() { Criteria = salesQuotes.No, Field = HHT_SO_Fields.Document_No } }, bookmarkKey = "", setSize = 200 }); return new { sales_header = task.Dis_SQ, sales_line = task1.ReadMultiple_Result1 }; } If you need any more help comment below.
Unit testing with Effort - Adding records with identity off
I am using using Effort (for EF4) to do some unit tests. var ctx= Effort.ObjectContextFactory.CreateTransient<TheContext>(Shared.Connection); ctx.companies.AddObject(new company() { ID = 100, name = "Agent", is_agent = true }); ctx.SaveChanges(System.Data.Objects.SaveOptions.DetectChangesBeforeSave); The ID column in the company is an identity field. After executing the above query, it turns out the ID value is 1 instead of 100. Is there any way to control Identity_insert while using Effort
This is just to add the solution on this thread. #MrBlueSky add the archieved links of the solution on the comments above. But, DbConfiguration which is used on the link, does not exists anymore on the latest Effort. The solution still exists on Effort.EF6 [version="1.3.0"]. And you can use the method SetIdentityFields on EffortConnection.DbManager to turn on or off the identity fields if (Effort.DbConnectionFactory.CreateTransient() is EffortConnection connection) { connection.Open(); connection.DbManager.SetIdentityFields(false); connection.DbManager.ClearMigrationHistory(); connection.Close(); } Turning on // Add data with explicitly set id Person initPerson = new Person { Id = 5, FirstName = "John", LastName = "Doe" }; dataInitContext.People.Add(initPerson); dataInitContext.SaveChanges(); Assert.AreEqual(5, initPerson.Id); // Enable identity field connection.Open(); connection.DbManager.SetIdentityFields(true); connection.Close();