Error connecting to External BAQ using RESTful

We are running Epicor 10.1.600.9 and have created an External BAQ that links to our Mattec system. We have defined an external BAQ (glhExtTest) that links into a SQL View in Mattec called vw_SIST_DashboardMachine.
When the view has the query
SELECT MachNo, CycleNo, Status, DownNo, HelpNo, HelpStart, StatTime, TimeInStat, EndOfJob, AutoSpcFlag, ManualSqcFlag, VariableSqcFlag, AttributeSqcFlag, SecondaryCommFlag, MiuCommError, MiuPartNumber, MiuPartRevision, MiuPartDate, MiuPldRevision, MiuBiosDate, StartUp, ParameterRecordingCycles, ver, ClientOnlyCurrentShiftSeq, ClientOnlyCurrentShiftName, ClientOnlyPreviousShiftSeq, ClientOnlyPreviousShiftName, ClientOnlyCurrentShiftWorking, ClientOnlyPreviousShiftWorking, SelectedDownNo FROMdbo.MachInfo
the rest URL
https://erp-app01.sistemaplastics.com/EpicorERP10/api/help/baq//glhExtTest/index#!/OData/execute
returns a result just fine. However changing the query to

SELECT TOP (100) PERCENT a.DeptNo, b.DeptName, dbo.CalculateOEEDashboard(a.ExpProdQty, a.CalProdQty, a.SumWtDownQty, a.DefectQty, a.SumDefQty, a.WtTotTime, a.WtDownTime, a.CycleEfficiencyNumerator) AS OEE CASE WHEN WtTotTime - WtDownTime > 0 THEN CycleEfficiencyNumerator / (WtTotTime - WtDownTime) ELSE 0 END AS CycleEfficiency, CASE WHEN ExpProdQty != 0 THEN 100 * (CalProdQty – DefectQty / ExpProdQty ELSE 0 END AS YieldEfficiency, CASE WHEN SumCycTm != 0 AND CycCnt != 0 THEN SumCycTm / CycCnt ELSE - 1 END AS AverageCycleTime, CASE WHEN CalProdQty != 0 THEN 100 * DefectQty / CalProdQty ELSE - 1 END AS ScrapPercent, CASE WHEN WtTotTime != 0 THEN 100 * WtDownTime / WtTotTime ELSE - 1 END AS DownPercent, CASE WHEN CalProdQty > DefectQty THEN CalProdQty - DefectQty ELSE 0 END AS GoodProduction, a.CalProdQty AS TotalProduction, CASE WHEN CalProdQty > DefectQty AND CalProdQty > 0 THEN 100 * (CalProdQty - DefectQty) / CalProdQty ELSE 0 END AS GoodPercent, CASE WHEN WtTotTime != 0 THEN 100 * (WtTotTime - WtDownTime) / WtTotTime ELSE 0 END AS RunEfficency, 0 AS Special1, 0 AS Special2, 0 AS Special3, dbo.CalculateBerry105Efficiency(a.BerryExpProdQty, a.CalProdQty, a.DefectQty, a.PakProdQty) AS Berry105Efficiency, dbo.CalculateBerryMeefEfficiency(a.WtTotTime, a.IdleWtQty, a.PmWtQty, a.WtDownTime) AS BerryMeefEfficiency FROM (SELECT b.DeptNo, SUM(b.CalProdQty) AS CalProdQty, SUM(b.DefectQty) AS DefectQty, SUM(b.PakProdQty) AS PakProdQty, SUM(b.ExpProdQty) AS ExpProdQty, SUM(b.WtTotTime) AS WtTotTime, SUM(b.WtDownTime AS WtDownTime, SUM(b.SumCycTm) AS SumCycTm, SUM(b.CycCnt) AS CycCnt, SUM(b.WtCycCnt) AS WtCycCnt, SUM(b.IdleWtQty) AS IdleWtQty, SUM(b.PmWtQty) AS PmWtQty, SUM(b.SumDownQty)AS SumDownQty, SUM(b.SumWtDownQty) AS SumWtDownQty, SUM(b.SumDefQty) AS SumDefQty, SUM(dbo.CalculateCycleEfficiencyNumerator(b.ExpCycTm, b.CycCnt, b.SumCycTm, b.WtTotTime, b.WtDownTime, b.MiuMachSpeedUnit)) AS CycleEfficiencyNumerator, SUM(CASE WHEN ExpCycTm != 0 THEN NuMCavs * (WtTotTime - WtDownTime) / (dbo.Convert_CycleTime_Rate(ExpCycTm, b.MiuMachSpeedUnit, b.TimeDivisor, b.LinearRateMultiplier) / 0.95) ELSE 0 END) AS BerryExpProdQty FROM dbo.vShiftProd AS b INNER JOIN dbo.vCurrentShiftSeq AS d ON b.MachNo = d.MachNo AND b.ShiftSeq = d.ShiftSeq WHERE (b.Active = 1)GROUP BY b.DeptNo) AS a INNER JOIN dbo.Department AS b ON a.DeptNo = b.DeptNo ORDER BY b.DeptName

Gives a result
Sorry! Something went wrong. Please contact your system administrator.

And the Curl text auto sets to accept plain text
curl -X GET --header ‘Accept: text/plain’ ‘https://erp-app01.sistemaplastics.com/EpicorERP10/api/v1/BaqSvc/glhExtTest/

Any ideas why this would happen?

The “Sorry something went wrong” error populates an actual error in the Epicor Server Event Viewer, what does that say?
Also turn off custom errors in your web config to surface the actual errors to the response body

<system.web>
<customErrors mode="Off" />
</system.web>
1 Like

One thing not noted is that wen running the more complex version of the BAQ in Epicor there is no issue
Error from the Event viewer is
Microsoft.Data.OData.ODataException: An incompatible primitive type ‘Edm.Byte[Nullable=False]’ was found for an item that was expected to be of type ‘Edm.String[Nullable=True]’.
at Microsoft.Data.OData.ValidationUtils.ValidateMetadataPrimitiveType(IEdmTypeReference expectedTypeReference, IEdmTypeReference typeReferenceFromValue)
at Microsoft.Data.OData.JsonLight.ODataJsonLightValueSerializer.WritePrimitiveValue(Object value, IEdmTypeReference expectedTypeReference)
at Microsoft.Data.OData.JsonLight.ODataJsonLightPropertySerializer.WriteProperty(ODataProperty property, IEdmStructuredType owningType, Boolean isTopLevel, Boolean allowStreamProperty, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, ProjectedPropertiesAnnotation projectedProperties)
at Microsoft.Data.OData.JsonLight.ODataJsonLightPropertySerializer.WriteProperties(IEdmStructuredType owningType, IEnumerable`1 properties, Boolean isComplexValue, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, ProjectedPropertiesAnnotation projectedProperties)
at Microsoft.Data.OData.JsonLight.ODataJsonLightWriter.EndEntry(ODataEntry entry)
at Microsoft.Data.OData.ODataWriterCore.b__16()
at Microsoft.Data.OData.ODataWriterCore.InterceptException(Action action)
at Microsoft.Data.OData.ODataWriterCore.WriteEnd()
at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteEntry(Object graph, ODataWriter writer, ODataSerializerContext writeContext)
at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext)
at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)
at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Owin.HttpMessageHandlerAdapter.d__13.MoveNext()

So it looks like it is assuming a certain data type and getting another. Have a look at the External Data Source Metadata Entry and make sure its getting the correct information regarding the data types.

For now only types supported in Epicor tables are translated in the Odata model. In this case, you use byte and I think you will have to change it in BAQ - make it integer or string with the help of calculated field.

2 Likes

So
I changed all fields to String format

Using Get Metadata Document https://erp-app01.sistemaplastics.com/EpicorERP10/api/v1/BaqSvc/glhExtTest(SISTNZ)/$metadata

Response Body

<?xml version="1.0" encoding="utf-8"?>

<edmx:Edmx Version=“1.0” xmlns:edmx=“http://schemas.microsoft.com/ado/2007/06/edmx”> <edmx:DataServices m:DataServiceVersion=“3.0” m:MaxDataServiceVersion=“3.0” xmlns:m=“http://schemas.microsoft.com/ado/2007/08/dataservices/metadata”>













            <Property Name="vw_SIST_DashboardMachine_DeptName" Type="Edm.String" />

            <Property Name="vw_SIST_DashboardMachine_OEE" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_CycleEfficiency" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_YieldEfficiency" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_AverageCycleTime" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_ScrapPercent" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_DownPercent" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_GoodProduction" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_TotalProduction" Type="Edm.String" />

            <Property Name="vw_SIST_DashboardMachine_GoodPercent" Type="Edm.String" />

            <Property Name="vw_SIST_DashboardMachine_RunEfficency" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_Berry105Efficiency" Type="Edm.String" />
            <Property Name="vw_SIST_DashboardMachine_BerryMeefEfficiency" Type="Edm.String" />
            <Property Name="RowIdent" Type="Edm.Guid" Nullable="false" />
        </EntityType>
    </Schema>
</edmx:DataServices>

</edmx:Edmx>

All strings. apart from RowIdent which is not part of Query

Image of BAQ Column formats


and BAQ return

Nothing that could be construed as anything other than a string yet still

and server error
Level Date and Time Source Event ID Task Category
Error 20/09/2017 10:02:36 AM IceAppServer 0 None “Microsoft.Data.OData.ODataException: An incompatible primitive type ‘Edm.Byte[Nullable=False]’ was found for an item that was expected to be of type ‘Edm.String[Nullable=True]’.
at Microsoft.Data.OData.ValidationUtils.ValidateMetadataPrimitiveType(IEdmTypeReference expectedTypeReference, IEdmTypeReference typeReferenceFromValue)
at Microsoft.Data.OData.JsonLight.ODataJsonLightValueSerializer.WritePrimitiveValue(Object value, IEdmTypeReference expectedTypeReference)
at Microsoft.Data.OData.JsonLight.ODataJsonLightPropertySerializer.WriteProperty(ODataProperty property, IEdmStructuredType owningType, Boolean isTopLevel, Boolean allowStreamProperty, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, ProjectedPropertiesAnnotation projectedProperties)
at Microsoft.Data.OData.JsonLight.ODataJsonLightPropertySerializer.WriteProperties(IEdmStructuredType owningType, IEnumerable`1 properties, Boolean isComplexValue, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, ProjectedPropertiesAnnotation projectedProperties)
at Microsoft.Data.OData.JsonLight.ODataJsonLightWriter.EndEntry(ODataEntry entry)
at Microsoft.Data.OData.ODataWriterCore.b__16()
at Microsoft.Data.OData.ODataWriterCore.InterceptException(Action action)
at Microsoft.Data.OData.ODataWriterCore.WriteEnd()
at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteEntry(Object graph, ODataWriter writer, ODataSerializerContext writeContext)
at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext)
at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)
at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Owin.HttpMessageHandlerAdapter.d__13.MoveNext()”

String format does not mean string type.
EDM uses string in the case it cannot understand the type.

So the question is what is the actual type in those BAQ columns.
I think DeptNo is the most probably byte field. Can you remove it from BAQ temporarily and look if error changes?
Also, what database engine it is?

So for anyone coming up against a similar issue as this, and to thank Olga and Jose for their efforts here’s the outcome
Apparently ther is a known issue and it was reported to us by Epicor support

The error appears to be a known issue with Microsoft’s OData DLL which relies on OData.lib. The exception is thrown Exception when two types inherit from the same BaseType and use the same name for a property but with different property Types. Since the Mattec DB uses many user defined types, I would expect the exception to come up. It has been discussed on this link and a workaround is also suggested.

This links back to suggestions both from Jose and Olga

After reading the link and understanding about 10% I decided to redefine my BAQ and only use Calculated fields for the output (I did try only defining a few but still had the same issue so I ended up having to do all of them). This worked.

1 Like