ttCustomer has more than one record error - BPM for email alert when new cust is added


I created a quick BPM that sends an alert email out when a new customer gets added which will send an email out according to the territory to the appropriate sales rep. However when the finance team tries to post AR invoices - they get an error:

“The table ttCustomer has more than one record”

It’s common for the tt record to have more than one. Most of the time it’s an unchanged and changed record so that the system can compare for changes. Other times it’s actually updating more than one record. Try and add a message box into the BPM with field or table query in the message and see how many, and what rows are in the BPM. If there is more than one, you’ll probably have to loop. (which can’t be done easily with widgets)

Hi - thank you for responding, I done some research and would a foreach loop work in this case?

Have you tried adding this to the GetCustomerTerritory - [GCT] method rather than a Data Directive? It would post pro on the GCT Method

Can I ask what are you setting in the ABC variable?

I am setting var TerritoryID to ttCustomer.TerritoryID to route where the emails are going. I am unfamiliar with the GetCustomerTerritory method. Can you point me towards the right direction?

Try this code

foreach(var row in ttCustomer.ToList())

  using(var txscope1 = IceContext.CreateDefaultTransactionScope()) {
        var salesRep = Db.SalesRep.Where(p =>
            p.Company == row.Company &&
            p.SalesRepCode == row.SalesRepCode

        if (salesRep != null) {
            Ice.Diagnostics.Log.WriteEntry($"Get Email");
            salesRep.EMailAddress = yourEmailVar;
            salesRep.Name = repName;
            Ice.Diagnostics.Log.WriteEntry($"Task has been completed, sucessfully..");

I have added some diagnostics in so you can check the server logs.

Then in your email just set yourEmailVar as the email address in the To box and let it do the rest.

You can also get another vars if you wish at the top of this code…

You can also add in some checks like Updated or Added etc.

This gives you a head-start, hope you get it sorted :slight_smile:

Should this come before the first condition?

Whats in your condition?

You should be able to just use a custom code block and a email block and be good to go. You can set conditions in the custom code block.


This is what I have for condition 0

Where exactly is this attached to?

I don’t think you should need the “Set Argument/Variable” block at all. If you have the first block as a “There is at least one added row in the ttCustomer table” condition to evaluate for new customers (to differentiate between added, updated, deleted, etc.), you should be able to go right into the other conditions and email blocks.

I would also say you could optimize the other conditions, as long as sales reps are setup and linked to your territories (in other words, have a single action to send to the primary sales rep for the selected territory instead of multiple condition and send email blocks), but that is just personal preference and for easy of maintenance, not something that would prevent the directive from working.

Here’s an example of a similar data directive that I have in place. This one emails the primary sales rep when a shipment with a specific ship via (Customer Pickup) is marked as “Shipped”, indicating that it’s ready to be picked up by the customer:

Diagram View

Condition 0

This checks if the package has been marked as “Shipped” and if the ShipVia is Customer Pickup.

In your case the condition should just be “There is at least one added row in the ttCustomer table”, I believe.

Set Argument/Variable 1

This just sets a custom variable that I created (CustomerName), since that field is not in the ShipHead dataset. This is simply so I can use that field in the email to the sales rep.

You probably won’t need this, since your data directive will be on the ttCustomer table, so it will already have the Customer Name and other relevant fields.

Set Argument/Variable 2

This sets another custom variable (CSMEmail) to the primary sales rep’s email address. It uses Linq to get the email address from the SalesRep table (joining through the Territory table, in my case). You would need something similar if you don’t want all of the various condition and email boxes. I will include the full text of the Linq query below, for reference:

(from Cust in Db.Customer 
join Ter in Db.SalesTer on new {Cust.Company, Cust.TerritoryID} equals new {Ter.Company, Ter.TerritoryID}
join Rep in Db.SalesRep on new {Ter.Company, SalesRepCode = Ter.PrimeSalesRepCode} equals new {Rep.Company, Rep.SalesRepCode}
where Cust.Company == ttShipHeadRow.Company && Cust.CustNum == ttShipHeadRow.CustNum select Rep.EMailAddress).FirstOrDefault()

Send E-mail


This uses the variables that were set in the last two blocks, as well as some fields from the ttShipHead dataset to send the email to the rep. Using this method allows one send email block to function for all the sales rep and doesn’t require hard-coding any emails or conditions for various territories/reps.

I hope that helps!