My first Custo: with API calls

Greetings, quite new to Epicor here and learning everything about customization.

I have several questions ( and I might be trying to do this the wrong way, so feel free to propose alternate solutions).

I want to call an external API to get currency exchange rate every morning. Doing so in a simple C# project took me about 10 minutes , nothing fancy there.

However, when I try to do a custom function in epicor it won’t let me use System.net.http (a very common dll from microsoft) as an assembly ( and uploading custom .dll for my very first project sounds like a horrible idea).

Secondly, I’m almost completely lost as to how display that information once I get it / where to save it in the database or even where to get such information, as documentation about programming with epicor is pretty rare on the internet…

Thanks for your time,

Welcome Vincent!

Couple of thoughts. First, post what you’ve tried. Are you using Epicor Functions (10.2.500+)? Are you using a customization to the Currency form? Does someone have to remember to run this or are you trying to schedule it? Do you have a backup plan if Epicor is down or goes down in the middle of the load?

Hi Mark.

Yes, I’m on 10.2.600.0

the form is brand new, Heck, our epicor training instance is basically brand new; a few new UD column have been added, few new field in some form… but that’s simple enough.

I’m creating a new epicor custom function in the Epicor Functions Maintenance forms.

The function itself is about 10 lines. … HttpClient client( www.externalApi.com), followed by client.getResult… play a little bit with the result string to extract the USD-CAD, USD-MXN and USD-EUR currency exchanges rate. That part works and can be done in 10 minute in a brand new visual studio project. ( Epicor seems to have issues with the System.Net.Http dll however)

Now, ideally this function would run automatically every morning at X time and update the lists found in Exchange Rate Entry … but, as a plan B, I wouldn’T mind (for the moment) if that function is called on the load() event of the exchange rate entry form, and as a plan C someone must manually run it every day. but neither plan B or C appear particularly relevant since my issues are with one specific DLL and how to find the appropriate object/value to update once I have the data.

As far as epicor going down in the middle of the load… hold on, do you mean all those custom function aren’t asynchronous by default and any error would freeze the whole system? Right now, if that function fail for wathever reason, the worst that can happen is the user must manually update the exchange rate that day.

Hey Vincent,

The Epicor ICE Tools user guide is a solid resource if you don’t have it already, you can get it off the epicweb. There’s a portion about functions, and they use an epicor library in examples to make REST calls to Epicor. I would think you would be able to use it for other REST services outside of Epicor. It’s called Ice.Lib.RestClient.

As for what to do with the data once you get it, you can use a BO widget in your function that will update the fields you see in Exchange Rate Entry. A trace on the process would show what objects/methods.

What issues were you having with this dll specifically?

neither capitalizing System.Net.Http or Ice.Lib.RestClient working here.

issue:

same error with the net.http one, and RestClient isn’t part of Ice.Lib apparently.

between the next 2 meeting i’ll open up that Ice.Lib dll in VS to see what’s up.

Thanks for the suggestion!

Well it looks like Epicor.Ice.Lib.RestClient.dll is only saved in the client folder (hence the name) so it wouldn’t be available in a function unless you moved it unfortunately.

Well, since you’re new here, some people might say that I’m kinda of a “cloud guy” or something like that. :thinking:

Anyway, this changes the way I think of architecture these days. If it were me, I would split the flow up into two pieces of responsibility:

  • Downloading the Rates from the Web Service
  • Uploading the Rates into Epicor.

Should downloading the rates be dependent on somebody remembering to run the command? What if that person is out? What if the service is down? Holidays?

So I would use a PowerShell script or C# function that runs on a schedule (Azure Function). I would then take that download and select the bits I need (currency, date, and rate) and save it. Again, being a :cloud: guy, I would do this in Azure Storage. It would be completely free at this number of transactions. I would store the results in Azure Table for history and Queue storage - 0.005/GB. I would have a trigger fire when something was written to the Queue to make a REST call to an Epicor Function to add the rates to the daily table. For completeness, I’d have a script read the rates (again an Epicor Function call) and if they exist, we’re done - maybe send a notification of the rates that were loaded. If not, requeue the rates, set a delay before running again, and send notification to have someone check it.

There is only one Epicor Function Library with two functions (AddRates, GetRates). You can use it for multiple companies. You have a full history, even if your Epicor Database is restored for a disaster of some kind. It is less fragile and you can recover this process if almost anything goes wrong.

Just food for thought…

2 Likes

Most likely you need to add the DLL as an external reference.

Or not. :wink:

We do this every day automatically with just a little bit of code on a BPM that fires off based on the Task Scheduler table entry.

When the schedule fires, it updates its “next run” date and when that field changes it fires the BPM that runs the code to go get Exchange Rates from OANDA API Service. Then it just pushes them in to the exchange rate table using the BO like @Asz0ka mentioned.

3 Likes

You can use
using System.Net;
var req = WebRequest.Create(“YourUrl”);

2 Likes