C# QuickBooks Cannot add Check - c#

I'm attempting to add the ability to transfer commission payments from my system to QuickBooks using C#, and I've got a whole bunch of it working except for the add check requests. Currently, I'm getting this output
CheckAdd
ExpenseLineAddList:
element(2) - Required object is empty
End of ExpenseLineAddList
End of CheckAdd
and here's the code. It's a little long unfortunately, but that's just what surrounds the necessary bits.
MySql.Data.MySqlClient.MySqlConnection CheckConn = new MySql.Data.MySqlClient.MySqlConnection();
MySqlCommand CheckCmd = new MySqlCommand();
CheckConn.ConnectionString = myConnectionString;
CheckConn.Open();
CheckCmd.Connection = CheckConn;
CheckCmd.CommandText = "select `companies`.`ParentCompanyName`, `DateTimeStart`, `DateTimeEnd` from `commissiontransfers` join `orders` using (`InvoiceID`) join `companies` using (`CompanyID`) where `Transfered`=0 group by `ParentCompanyName`;";
MySqlDataReader CheckReader = CheckCmd.ExecuteReader();
DataTable Checks;
using (CheckReader)
{
Checks = new System.Data.DataTable();
Checks.Load(CheckReader);
}
CheckReader.Close();
CheckReader.Dispose();
CheckConn.Close();
CheckConn.Dispose();
foreach (DataRow Check in Checks.Rows)
{
IMsgSetRequest AddCheckMsgSet = sessionManager.CreateMsgSetRequest("US", 8, 0);
AddCheckMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
ICheckAdd CheckAddRq = AddCheckMsgSet.AppendCheckAddRq();
CheckAddRq.AccountRef.FullName.SetValue("Bank Account");
CheckAddRq.PayeeEntityRef.FullName.SetValue(Convert.ToString(Check["ParentCompanyName"]));
CheckAddRq.Memo.SetValue("Date Range: From " + Convert.ToDateTime(Check["DateTimeStart"]).ToString("MM/dd/yyyy") + " to " + Convert.ToDateTime(Check["DateTimeEnd"]).ToString("MM/dd/yyyy"));
CheckAddRq.IsToBePrinted.SetValue(true);
MySql.Data.MySqlClient.MySqlConnection CommissionTransferConn = new MySql.Data.MySqlClient.MySqlConnection();
MySqlCommand CommissionTransferCmd = new MySqlCommand();
CommissionTransferConn.ConnectionString = myConnectionString;
CommissionTransferConn.Open();
CommissionTransferCmd.Connection = CommissionTransferConn;
CommissionTransferCmd.CommandText = "select `CommissionTransferID`, round(`OrderCommission`-`FactoryCommission`-`ShippingCommission`, 2) `Total`, `orders`.`DateTimePaid`, `companies`.`OldQBName`, `orders`.`Customer` from `commissiontransfers` join `orders` using (`InvoiceID`) join `companies` using (`CompanyID`) where `Transfered`=0;";
MySqlDataReader CommissionTransferReader = CommissionTransferCmd.ExecuteReader();
DataTable CommissionTransfers;
using (CommissionTransferReader)
{
CommissionTransfers = new System.Data.DataTable();
CommissionTransfers.Load(CommissionTransferReader);
}
CommissionTransferReader.Close();
CommissionTransferReader.Dispose();
CommissionTransferConn.Close();
CommissionTransferConn.Dispose();
foreach (DataRow CommissionTransfer in CommissionTransfers.Rows)
{
IExpenseLineAdd ExpenseLineAdd = CheckAddRq.ExpenseLineAddList.Append();
ExpenseLineAdd = CheckAddRq.ExpenseLineAddList.Append();
ExpenseLineAdd.AccountRef.FullName.SetValue("Contract Labor:1099's");
ExpenseLineAdd.Amount.SetValue(Convert.ToDouble(CommissionTransfer["Total"]));
ExpenseLineAdd.Memo.SetValue(Convert.ToString(CommissionTransfer["Customer"]) + " - " + Convert.ToDateTime(CommissionTransfer["DateTimePaid"]).ToString("MM/dd/yyyy"));
ExpenseLineAdd.ClassRef.FullName.SetValue(Convert.ToString(CommissionTransfer["OldQBName"]));
GetFirstRow("update `commissiontransfers` set `Transfered`=1 where `CommissionTransferID`='" + CommissionTransfer["CommissionTransferID"] + "';");
}
CheckAddRq.IncludeRetElementList.Add("TxnID");
try {
IMsgSetResponse CheckResponseMsgSet = sessionManager.DoRequests(AddCheckMsgSet);
IResponse CheckResponse = CheckResponseMsgSet.ResponseList.GetAt(0);
MessageBox.Show(CheckResponse.StatusCode + ": " + CheckResponse.StatusMessage);
}
catch (Exception ex)
{
Console.WriteLine("{0} Exception caught.", ex);
}
It seems to be acting like my AddCheckMsgSet variable is empty, but I can't for the life of me figure out why it would be. Any help is much appreciated!

Of course, I spend three hours stuck on this problem, and then solve it myself right after I post it here. Well, the problem had to do with these lines
IExpenseLineAdd ExpenseLineAdd = CheckAddRq.ExpenseLineAddList.Append();
ExpenseLineAdd = CheckAddRq.ExpenseLineAddList.Append();
All I needed to do was get rid of the second line, since I was already appending a new expense line, and the second append caused the first request to be blank. Hope this helps someone in the future, since I've had only problems with trying to connect to QuickBooks.

Related

C# Bizarre Object Reference Not Set error with custom class [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I have a strange issue where a piece of code that I run all the time is suddenly throwing a "System.NullReferenceException: Object reference not set to an instance of an object." error.
The error occurs on a line involving a custom class that I made to simplify running TSQL action queries with parameters. With the class, I just have to use the naming convention #Param0, #Param1, etc, and pass an array of this type:
public struct SQLParam
{
private SqlDbType m_Type;
private dynamic m_Value;
public SqlDbType Type
{
get { return m_Type; }
set { m_Type = value; }
}
public dynamic Value
{
get { return m_Value; }
set { m_Value = value; }
}
public SQLParam (SqlDbType ValType, dynamic val)
{
m_Value = val;
m_Type = ValType;
}
public SQLParam(SqlParameter sqlParameter)
{
m_Value = sqlParameter.Value;
m_Type = sqlParameter.SqlDbType;
}
}
...into a method of an object of the class GCDB, called "ActionQueryWithParams", and it works. Except this one time.
Here's the code that's having trouble. I'm including various examples of code that DOES work, and marking the code that DOESN'T in comments:
GCDB GeekConn = new GCDB();
string sID = "";
string sRecurrenceID = JobRecurrenceID.Text.ToString();
if (string.IsNullOrEmpty(JobID.Text.ToString())) //added record
{
//insert job --- THIS WORKS
SQLParam[] paramslist = new SQLParam[6];
string sSQL = "INSERT INTO [dbo].[Jobs] ([CustomerID], [JobName], [JobDescription], [IsRecurringJob], [JobStatusID], [LastModifiedByStaffID]) " +
"OUTPUT INSERTED.JobID " +
"VALUES(#Param0, #Param1, #Param2, #Param3, #Param4, #Param5)";
paramslist[0] = new SQLParam(SqlDbType.Int, Convert.ToInt32(cboCustomerID.SelectedValue));
paramslist[1] = new SQLParam(SqlDbType.VarChar, JobName.Text);
paramslist[2] = new SQLParam(SqlDbType.VarChar, JobDescription.Text);
paramslist[3] = new SQLParam(SqlDbType.Bit, Convert.ToBoolean(IsRecurringJob.Checked));
paramslist[4] = new SQLParam(SqlDbType.Int, Convert.ToInt32(cboJobStatusID.SelectedValue));
paramslist[5] = new SQLParam(SqlDbType.Int, System.Web.HttpContext.Current.Session["StaffID"]);
GeekConn.ActionQueryWithParams(sSQL, paramslist);
if (GeekConn.InsertedID != null)
{
sID = GeekConn.InsertedID.ToString();
}
paramslist = null;
//insert new assignment (if applicable - if adding a job to a staff person's list) -- THIS WORKS
if (!string.IsNullOrEmpty(AssignedToStaffID.Text.ToString()))
{
paramslist = new SQLParam[2];
sSQL = "INSERT INTO [dbo].[JobAssignments] ([JobID], [StaffID]) " +
"SELECT #Param0 AS JobID, #Param1 AS StaffID " +
"WHERE NOT EXISTS(SELECT * FROM[dbo].[JobAssignments] WHERE JobID = #Param0 AND StaffID = #Param1)";
paramslist[0] = new SQLParam(SqlDbType.Int, Convert.ToInt32(sID));
paramslist[1] = new SQLParam(SqlDbType.Int, Convert.ToInt32(AssignedToStaffID.Text.ToString()));
GeekConn.ActionQueryWithParams(sSQL, paramslist);
}
paramslist = null;
}
else //edited record
{
//do the main update -- THIS WORKS
SQLParam[] paramslist = new SQLParam[7];
string sSQL = "UPDATE[dbo].[Jobs] " +
"SET [CustomerID] = #Param0 " +
",[JobName] = #Param1 " +
",[JobDescription] = #Param2 " +
",[IsRecurringJob] = #Param3 " +
",[JobStatusID] = #Param4 " +
",[LastModifiedByStaffID] = #Param5 " +
",[DateModified] = getdate() " +
"WHERE [JobID] = #Param6";
paramslist[0] = new SQLParam(SqlDbType.Int, Convert.ToInt32(cboCustomerID.SelectedValue));
paramslist[1] = new SQLParam(SqlDbType.VarChar, JobName.Text);
paramslist[2] = new SQLParam(SqlDbType.VarChar, JobDescription.Text);
paramslist[3] = new SQLParam(SqlDbType.Bit, Convert.ToBoolean(IsRecurringJob.Checked));
paramslist[4] = new SQLParam(SqlDbType.Int, Convert.ToInt32(cboJobStatusID.SelectedValue));
paramslist[5] = new SQLParam(SqlDbType.Int, System.Web.HttpContext.Current.Session["StaffID"]);
paramslist[6] = new SQLParam(SqlDbType.Int, Convert.ToInt32(JobID.Text));
GeekConn.ActionQueryWithParams(sSQL, paramslist);
paramslist = null;
//auto insert new occurrence (if this is a recurring job and there are no occurrences already) -- THIS THROWS AN ERROR
if ((IsRecurringJob.Checked) && (JobRecurrenceID.Text.ToString() == ""))
{
paramslist = new SQLParam[2];
sSQL = "INSERT INTO [dbo].[JobRecurrences] ([JobID], [StatusLastModified], [LastModifiedByStaffID]) " +
"OUTPUT INSERTED.[JobRecurrenceID] " +
"SELECT #Param0 AS JobID, getdate(), #Param1 AS StaffID " +
"WHERE NOT EXISTS (SELECT * FROM [dbo].[JobRecurrences] WHERE JobID = #Param0)";
paramslist[0] = new SQLParam(SqlDbType.Int, Convert.ToInt32(JobID.Text));
paramslist[1] = new SQLParam(SqlDbType.Int, System.Web.HttpContext.Current.Session["StaffID"]);
// ERROR IS HERE: System.NullReferenceException: Object reference not set to an instance of an object.
GeekConn.ActionQueryWithParams(sSQL, paramslist);
if (GeekConn.InsertedID != null)
{
sRecurrenceID = GeekConn.InsertedID.ToString();
}
}
paramslist = null;
}
GeekConn = null;
I've confirmed that the SQL statement for auto-inserting a new occurrence works in SSMS. And, as far as I can tell, there's nothing in the broken code that isn't also in the working code. Can anybody spot anything I'm missing?
Many thanks!
Many thanks, all! The problem appears to have fixed itself when I fixed another issue (where it wasn't always loading the most recent JobRecurrence into JobRecurrenceID.Text on load).
I ran another test (using the debugger, as recommended), and it does appear to work correctly when the query is actually inserting a record. The issue was that I sometimes had the query run but, because of the WHERE condition (NOT EXISTS), it wasn't actually inserting a record, and it seems it was probably breaking this line of code in the GCDB.ActionQueryWithParams method (only including relevant code):
bool bolIsInsert = (sSQLUpper.Contains("OUTPUT INSERTED."));
try
{
if (bolIsInsert)
{
cmd.Parameters.Add("#ID", SqlDbType.Int, 4).Direction = ParameterDirection.Output;
InsertedID = (int)cmd.ExecuteScalar();
} else
{
cmd.ExecuteNonQuery();
}
}
catch (SqlException e)
{
Error = e.Message.ToString();
}
Apparently I need to include a way to handle INSERT statements that did not actually insert anything. Hmm... Well, that's a separate question. :)

Defensive opening of a database connection with option to retry

Occasionally I am getting a SqlException exception on the line marked below.
It occurs when we have network problems and the server cannot be found.
public void markComplete(int aTKey)
{
SqlCommand mySqlCommand = null;
SqlConnection myConnect = null;
mySqlCommand = new SqlCommand();
try
{
myConnect = new SqlConnection(ConfigurationManager.ConnectionStrings["foo"].ConnectionString);
mySqlCommand.Connection = myConnect;
mySqlCommand.Connection.Open(); //<<<<<<<< EXCEPTION HERE <<<<<<<<<<<<<<<<<<
mySqlCommand.CommandType = CommandType.Text;
mySqlCommand.CommandText =
" UPDATE dbo.tb_bar " +
" SET LastUpdateTime = CONVERT(Time,GETDATE()) " +
" WHERE AKey = " + aTKey;
mySqlCommand.ExecuteNonQuery();
mySqlCommand.Connection.Close();
}
finally
{
if(mySqlCommand != null)
{
mySqlCommand.Dispose();
}
}
}
I have two questions so maybe should split into 2 SO questions:
Is my finally statement sufficiently defensive ?
Rather than just failing how involved would it be to amend the method so instead of crashing it waits for say 10 minutes and then tries again to open the connection - tries a maximum of 3 times and if still no valid connection it moves on?
Use parameters. Do not concatenate strings to create SQL statements. Read about SQL Injection.
Instead of using try...finally you can simplify your code with the using statement. You need to dispose all the instances that implements the IDisposable interface, so you also need to use the using statement with the SqlConnection. In fact, it's even more important then disposing the SqlCommand, since it allows ADO.Net to use connection pooling.
You don't need to do the entire procedure again and again, just the connection.Open and the ExecuteNonQuery.
Using the constructor that accepts a string an SqlConnection saves you the need to set them via properties.
You don't need to specify CommandType.Text - it's the default value.
Here is a basic implementation of retry logic with some improvements to your code:
public void markComplete(int aTKey)
{
var sql = " UPDATE dbo.tb_bar " +
" SET LastUpdateTime = CONVERT(Time,GETDATE()) " +
" WHERE AKey = #aTKey";
using(var myConnect = new SqlConnection(ConfigurationManager.ConnectionStrings["foo"].ConnectionString))
{
using(var mySqlCommand = new SqlCommand(sql, myConnect))
{
mySqlCommand.Parameters.Add("#aTKey", SqlDbType.Int).Value = aTKey;
var success = false;
var attempts = 0;
do
{
attempts++;
try
{
mySqlCommand.Connection.Open();
mySqlCommand.ExecuteNonQuery();
success = true;
}
catch(Exception ex)
{
// Log exception here
Threading.Thread.Sleep(1000);
}
}while(attempts < 3 || !success);
}
}
}
Update:
Well, I've had some free time and I remember writing a general retry method a few years back. Couldn't find it but here is the general idea:
static void RetryOnException(Action action, int numberOfRetries, int timeoutBetweenRetries)
{
var success = false;
var exceptions = new List<Exception>();
var currentAttempt = 0;
do
{
currentAttempt++;
try
{
action();
success = true;
}
catch(Exception ex)
{
exceptions.Add(ex);
Threading.Thread.Sleep(timeoutBetweenRetries);
}
} while(!success || currentAttempt < numberOfRetries);
// Note: The Exception will only be thrown in case all retries fails.
// If the action completes without throwing an exception at any point, all exceptions before will be swallowed by this method. You might want to log them for future analysis.
if(!success && exceptions.Count > 0)
{
throw new AggregateException("Failed all {numberOfRetries} retries.", exceptions);
}
}
Using this method you can retry all sort of things, while keeping your methods simpler and cleaner.
So here is how it should be used:
public void markComplete(int aTKey)
{
var sql = " UPDATE dbo.tb_bar " +
" SET LastUpdateTime = CONVERT(Time,GETDATE()) " +
" WHERE AKey = #aTKey";
using(var myConnect = new SqlConnection(ConfigurationManager.ConnectionStrings["foo"].ConnectionString))
{
using(var mySqlCommand = new SqlCommand(sql, myConnect))
{
mySqlCommand.Parameters.Add("#aTKey", SqlDbType.Int).Value = aTKey;
// You can do this inside a `try...catch` block or let the AggregateException propagate to the calling method
RetryOnException(
() => {
mySqlCommand.Connection.Open();
mySqlCommand.ExecuteNonQuery();
}, 3, 1000);
}
}
}

Create a local db in winform and get data from server in the background

I'm looking for a way to enhance the performance of my application which excessively uses the database that is hosted on a server, The application needs to remotely access the database thus, causing it to be slow, so I was thinking about creating a local database and populating it from the server the minute the application is run, and afterwards performing updates on a regular basis to the hosted mySQl database after every hour or when the user decides to logout, the main issue I have is I will be having 10-20 users, they don't update the same kind of data but how will I know which tables have been updated and according to that I would apply the changes over my hosted database? and is there any article or link that has further explanation regarding this issue?
My Application is a C# windows form application and the database is mysql database.
One of the queries that I have and takes too long to execute is this one:
/**
* getting the schedule based on the submitted id
* */
public static Schedule2 getTeachersSchedule(String therapistID, int weekday, int period, int school_year)
{
// connecting to mysql database
try
{
using (MySqlConnection myConn = new MySqlConnection(connectionString))
{
using (MySqlCommand command = new MySqlCommand("Select * FROM student_schedule2, weekday, school_year, period, task where school_year_id = school_year_id_fk AND therapist_id_fk =" + therapistID + " AND weekday_id = weekday_id_fk AND period_id=period_id_fk AND task_id=task_id_fk AND weekday_id=" + weekday + " AND period_id=" + period + " AND school_year_id =" + school_year, myConn))
{
MySqlDataReader reader;
myConn.Open();
reader = command.ExecuteReader();
Schedule2 schedule = null;
while (reader.Read())
{
schedule = new Schedule2();
schedule.ID = reader.GetInt32("student_schedule2_id");
try
{
if (reader["student_id_fk"] != DBNull.Value)
schedule.student = getStudent(reader.GetString("student_id_fk"));
else
schedule.student = null;
Weekday weekDay = new Weekday();
weekDay.ID = reader.GetInt32("weekday_id");
weekDay.weekdayName = reader.GetString("weekday_name");
schedule.weekday = weekDay;
schedule.semesterName = reader.GetString("semester_name");
Period periodObj = new Period();
SchoolYear schoolYEar = new SchoolYear();
periodObj.ID = reader.GetInt32("period_id");
periodObj.period_name = reader.GetString("period_name");
schedule.period = periodObj;
schoolYEar.ID = reader.GetInt32("school_year_id");
schoolYEar.year_name = reader.GetString("school_year_name");
schedule.schoolYear = schoolYEar;
Task course = new Task();
course.ID = reader.GetInt32("task_id");
course.taskName = reader.GetString("task_name");
schedule.task = course;
schedule.therapist = getTherapist(reader.GetString("therapist_id_fk"));
}
catch
{
}
}
myConn.Close();
return schedule;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
Your approach will be prone to stale data and most likely be slower, since all data will be sent over the network.
I suggest you look at your SQL queries and determine why they are slow. Adding indexes to the table will help enormously.

Is there a way to use DBMS_Alert to notify a Winform application of a database change

I am trying to get a winform app to refresh an embedded browser on a database change using Oracle 10g. The only problem is that I am not allowed to use Database Change Notification. I am curious if anyone has a way of using the built-in package of DBMS_Alert and have had some action happen to a winform app on a database change.
Thanks, Andrew
food for thought...
if you are using ODP, you could use Oracle Advanced Queuing/Streams
and here.
this way your form app can subscribe to a queue and be notified of a change.
This may, however, be massive overkill for your application if you just want to add a new PO # into a drop down!
I have used streams before and it works as expected, but it had a nice level of research and trial & error to get things to click.
I had to do it like this for it to work. It holds the window in lock until an event occurs i know, but at least it works with DBMS_Alert. I set this code inside a timer:
OracleConnection conn = new OracleConnection(ConnectionString);
conn.Open();
OracleCommand cmd = new OracleCommand("DECLARE\n" +
"MESSAGE VARCHAR2(1800) := null;\n" +
"STATUS INTEGER;\n" +
"BEGIN\n" +
"DBMS_ALERT.REGISTER('ALERT');\n" +
"DBMS_ALERT.WAITONE('ALERT', MESSAGE, STATUS);\n" +
"DBMS_ALERT.REMOVE('ALERT');\n" +
"END;", conn);
cmd.ExecuteNonQuery();
wbMain.Refresh();
conn.Dispose();
This gives me what I need. I don't know if there is a better way to do it, but this is the only solution I could come up with.
It is better to use without timer. The below code sample is with background thread
Here is the code snippet
privateThread DBMSAlertThread;
private void DBMSAlert(bool Register)
{
try
{
string sSql;
if (Register)
sSql = "call dbms_alert.register('XYZ')";
else
sSql = "call dbms_alert.remove('XYZ')";
dbmsAlert = new OracleCommand();
dbmsAlert.CommandText = sSql;
dbmsAlert.ExecuteNonQuery();
if (Register) //start the background thread
{
DBMSAlertThread = new Thread(AlertEvent);
DBMSAlertThread.IsBackground = true;
DBMSAlertThread.Start();
}
}
catch (Exception LclExp)
{
//Show error or capture in eventlog
}
}
private void AlertEvent(object sender)
{
while (true)
{
string Message = "";
int Status = -1;
bool bStatus;
OracleParameter param;
try
{
OracleCommand dbmsAlert = new OracleCommand();
dbmsAlertScan.SQL.Add("call dbms_alert.WaitOne('XYZ', :Message, :Status, 0)"); //Last parameter indicate wait time
param = new OracleParameter("Message", OracleDbType.Varchar2, ParameterDirection.Output);
dbmsAlert.Parameters.Add(param);
param = new OracleParameter("Status", OracleDbType.Varchar2, ParameterDirection.Output);
dbmsAlert.Parameters.Add(param);
OracleParameter.ExceuteNonQuery();
Message = dbmsAlert.Parameters["Message"].Value.ToString();
bStatus = int.TryParse(dbmsAlert.Parameters["Status"].Value.ToString(), out Status);
if (Status == 0) //0 = Alert Received, 1 = Timed out
{
//notify or do ur stuff
}
}
catch (Exception Exp)
{
//raise an error
}
}
}

How to move to next row in datatable if one row catches an error? C# 2.0

I am getting data from a mySql database and I am inserting it into another system. If a column has data in an incorrect format I log this and go to next row in the datatable. It works as expected but now if I have a search function in my method that gets some additional data and this function fails I want to immediately log this and go to next row. As it is now I just log it but it still gets inserted (without the value that didn't meet the search criteria).
My code:
private void updateCustomer()
{
MySqlConnection connection = new MySqlConnection("server=myServer;database=myDatabase;uid=myID;password=myPass");
MySqlCommand command = new MySqlCommand(#"mySelectCommand", connection);
DataTable customerTbl = new DataTable();
MySqlDataReader reader;
try
{
connection.Open();
reader = command.ExecuteReader();
if (reader.HasRows)
{
customerTbl.Load(reader);
}
reader.Close();
}
catch (Exception ex)
{
_out.error("Could not connect to mySql database");
}
finally
{
connection.Close();
}
foreach (DataRow row in customerTbl.Rows)
{
// Declare the customer variables
string customerID = Encoding.ASCII.GetString((byte[])row["Customer ID"]);
string ChildOf = row["Child of"].ToString();
// Create the customer object
Customer customer = new Customer();
customer.entityId = customerID;
if (ChildOf != "")
{
RecordRef parentRef = new RecordRef();
try
{
parentRef.internalId = searchCustomer(ChildOf);
}
catch
{
// If it fails here I want to log the customerID and then go to the next row in the datatable (could not find the internalid for ChildOf
_out.error(customerID + " was not updated. Error: invalid format Parent string");
}
finally
{
parentRef.typeSpecified = false;
customer.parent = parentRef;
}
}
// Invoke update() operation
WriteResponse response = _service.update(customer);
// Process the response
if (response.status.isSuccess)
{
}
else
{
_out.error(customerID + " was not updated. Error: " + getStatusDetails(response.status));
}
}
}
You need to remove the row in the catch block, and change the foreach loop to a backwards for loop to handle the removals.
I realized that I want to log the other failed fields as well. Maybe it's an inefficient way but I did something like:
bool findParent = true;
if (ChildOf != "")
{
try
{
RecordRef parentRef = new RecordRef();
parentRef.internalId = searchCustomer(ChildOf);
parentRef.typeSpecified = false;
customer.parent = parentRef;
}
catch
{
findParent = false;
_out.error(customerID + " was not inserted. Error: invalid format Parent string");
}
}
And then an if statement before trying to insert:
if (findPartner == true && findParent == true)
{
response = _service.add(customer);
// Process the response
if (response.status.isSuccess)
{
}
else
{
_out.error(customerID + " was not inserted. Error: " + getStatusDetails(response.status));
}
}
else
{
//_out.error(customerID + " was not updated. Error: " + getStatusDetails(response.status));
}
Use the row.HasError property.

Categories

Resources