I am new to functions in epicor and trying to make a function that will run a few sql statements. I added the reference to System.Data.SqlClient and the using statement but I am getting this error and I am not sure what it means or how to go about resolving it: System.Drawing.Bitmap CS1069 The type name ‘SqlConnection’ could not be found in the namespace ‘System.Data.SqlClient’. This type has been forwarded to assembly ‘System.Data.SqlClient, Version=4.6.1.6, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ Consider adding a reference to that assembly.
Back up, give us more context.
What db are you thinking of connecting to?
I am connecting to my epicor db. My company is in the process of moving to kinetic and I am trying to replicate a customization that I have in classic. Here is the code that is in my classic customization:
private void FixACHChecks()
{
try
{
Cursor.Current = Cursors.WaitCursor;
connection = new SqlConnection(connectionString);
connection.Open();
cmd = connection.CreateCommand();
cmd.CommandText = "update erp.prempded set bankaccttype = 'C' where bankaccttype like 'CHK%'";
cmd.ExecuteNonQuery();
cmd.CommandText = "update erp.prempded set bankaccttype = 'S' where bankaccttype like 'SAV%'";
cmd.ExecuteNonQuery();
cmd.CommandText = "delete from erp.prchkded where (deductionID like 'SAV%' or deductionID like 'CHK%') and scheduledamt = '0' and Deductionamt = '0'";
cmd.ExecuteNonQuery();
connection.Close();
connection.Open();
cmd.Connection.CreateCommand();
cmd.CommandText = "update erp.PRChkDtl set paytypeID = PROTCode_c " +
"from erp.prchkdtl " +
"join erp.prempmas on erp.prchkdtl.EmpLink = erp.prempmas.EmpLink " +
"join erp.PREmpMas_UD on erp.PREmpMas_UD.ForeignSysRowID = erp.prempmas.SysRowID " +
"where erp.prchkdtl.CheckDate IS NULL " +
"and erp.prchkdtl.PayTypeID = 'REG' " +
"and erp.PREmpMas_UD.PROTCODE_c <> PaytypeID";
cmd.ExecuteNonQuery();
connection.Close();
Cursor.Current = Cursors.Default;
MessageBox.Show("Finished");
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
This is my connection string
private const String connectionString = “Data Source=mfa-db;Initial Catalog=EpicorERP;Persist Security Info=True;User ID=sa;Password=**”;
You are gonna get dogpiled
That is so far from best practice you can’t even see it from here. Best to do data changes via a BAQ or BO if possible, and even if that isn’t possible you should be using Epicor’s DB objects
You are not meant to do that, and while it is technically possible to do so, I would not recommend it.
There are more sanctioned ways to solve your problem.
Especially after reading that sql lol.
But seriously, we are here to help.
What is the business problem you are trying to solve? We’ll show you the “proper” way to do it.
Can you suggest a better way to do this?
Yes, read one post up, we posted again at the same time.
Give us the full context on the business problem so we can advise properly.
Another option for mass updates is DMT. But like Kevin said, we can’t give informed answers without the business goal you are trying to achieve.
To me, it looks like you are trying too hard to do it the hard way… Epicor functions, and epicor BPMs are already connected to the SQL database. You simply need to access the data records you want to use. as someone above said, it is BEST to use business objects to do this, but there are times when you can also simply do queries in c# and get to the data you need. There are MANY examples of c# linq queries in this forum (search for LINQ or LINQ UPDATE)… you can see both good and bad examples.
LINQ is the c# equivalent of a SQL query, but written in C#. It allows you to query and get individual records, or entire sets of records all at once.
in classic we created a button in in the action’s menu for payroll that would run these few updates and delete statements instead of IT having to run them for them before they prosses payroll. I would like to do the same in kinetic. (See statements above)
You are on the right track to use a function. @Evan_Purdy 's comment summarizes what you need to do.
There’s lots of examples on the forum that use Business Objects or DB objects. You just need to rewrite your code to use these.
Well, its the right track if what he wants to do even makes sense. He hasn’t explained why ACH checks need to be ‘fixed’ every payroll. Its possible the root cause could be solved and this code wouldn’t even be needed.
Very true. I stopped reading what he was actually trying to do once I saw the SQL statements
Evergreen post.
Ok, enough dogpiling. He’s gonna think he’s on Stack Overflow.
update erp.prempded set bankaccttype = 'C' where bankaccttype like 'CHK%'
update erp.prempded set bankaccttype = 'S' where bankaccttype like 'SAV%'
delete from erp.prchkded where (deductionID like 'SAV%' or deductionID like 'CHK%') and scheduledamt = '0' and Deductionamt = '0'
update erp.PRChkDtl set paytypeID = PROTCode_c
from erp.prchkdtl
join erp.prempmas on erp.prchkdtl.EmpLink = erp.prempmas.EmpLink
join erp.PREmpMas_UD on erp.PREmpMas_UD.ForeignSysRowID = erp.prempmas.SysRowID
where erp.prchkdtl.CheckDate IS NULL
and erp.prchkdtl.PayTypeID = 'REG'
and erp.PREmpMas_UD.PROTCODE_c <> PaytypeID";
Here is what he’s doing in classic, broken out in a little bit easier to read format.
@cbastijanic what is the explanation as to why this is needed?
We can probably help to fix the underlying issue, and if not, at least massage it into something more acceptable.
System Information
==================
AppServer Connection: https://epicor1.mi.mayfran.com/epicorerp
Form Name: Epicor Functions Maintenance
Customization Name:
Menu ID: BPMN1450
Software Version: 4.3.100.0
============
Application Error
Exception caught in: Epicor.ServiceModel
Error Detail
============
##!Message:##! Invalid token.
##!Program:##! Epicor.ServiceModel.dll
##!Method:##! CallWithCommunicationFailureRetry
Client Stack Trace
==================
at Epicor.ServiceModel.Channels.ImplBase.CallWithCommunicationFailureRetry(String methodName, ProxyValuesIn valuesIn, ProxyValuesOut valuesOut, RestRpcValueSerializer serializer)
at Epicor.ServiceModel.Channels.ImplBase.CallWithMultistepBpmHandling(String methodName, ProxyValuesIn valuesIn, ProxyValuesOut valuesOut, Boolean useSparseCopy)
at Epicor.ServiceModel.Channels.ImplBase.Call(String methodName, ProxyValuesIn valuesIn, ProxyValuesOut valuesOut, Boolean useSparseCopy)
at Ice.Proxy.Lib.EfxLibraryDesignerImpl.ApplyChangesWithDiagnostics(EfxLibraryDataSet libraryTableset, IEnumerable1& diagnostics) at Ice.UI.EfxLibraryMaintenance.Services.LibraryService.<>c__DisplayClass2_0.<ApplyChangesWithDiagnostics>b__0(EfxLibraryDesignerImpl svc) at Ice.Blaq.Client.EfxLibraryDesigner.LibraryInfoService.CallSvc(Action
1 func)
at Ice.UI.EfxLibraryMaintenance.Services.LibraryService.ApplyChangesWithDiagnostics(EfxLibraryDataSet& input, IEnumerable1& diagnostics) at Ice.UI.EfxLibraryMaintenance.MainTransaction.ApplyChangesWithDiagnostics(String lastSelectedLibrary, IEnumerable
1& diagnostics)
at Ice.UI.EfxLibraryMaintenance.MainTransaction.adapterUpdate()
at Ice.Lib.Framework.EpiMultiViewTransaction.Update(IEnumerable`1 dataSets)
Here are the details for the saving error of the function
I closed functions maintenance and opened it with the desktop app for kinetic and it let me save it this time. Before I had opened functions maintenance from the web app.
Interesting, I would report that to support.