Configurator pricing issue

I am pulling my hair out over this one and cant work out what the hell is actually going on and why the system is doing this……

We have been working on V2 of one of our configurators for quite a while now to massively improve it as well as automate some of the misc charges (solution for this posted on the forum).

in our PILOT system, the price writes perfectly every time, i have tested it hundreds of times and never had any issues, whatever the total price is in the configurator, when we write the price to the quote or order, it remains the same..

here is a trace from it too showing what is happening on save….this is relevent!

not a lot happens on the save, it just does what it needs to!

NOW HERES THE FUN PART………

in our live system, we have copied the configurator over, set the part, document rules etc so everything is IDENTICAL to PILOT….we know its identical because we did a copy down from live just before the upgrade to 2025.2.5

every time we are saving the configurator, the unit price is changing and it is always chaning by the value of our UOM which is 1.19

when i have done the same trace from the same point we can see its doing a calculation…..

i dont want this calculation to happen, i dont know why its happening in LIVE when its not happening in PILOT…..

has ANYONE seen this before and know how the hell to stop it?

2 Likes

First thing I would check is if your configurable part has the same SalesUM in Pilot as it does in Live. I’m looking at your values here… is the configurator calculation coming up with the $62.40, and then Epicor is forcing the calculation down to $52.43697, or is it the reverse?

Hi Kevin,

Both systems are identical, copydown was done from Live to Pilot 4 weeks ago and no changes have been made in either system other than they are now both on 2025.2.5

And you are correct the configurator is pricing at 62.40 and the Live system is then rounding down to 52.43697

This is divided exactly by our UOM which is 1.19…but i dont understand why it is changing it based on the UOM anyway.

The UOM is set way before all the other fields and the price is set last

Does the configurator change the UOM? Also, is it possible a price list was added or had effective dates changed in Live since the pilot copy?

this particular part is our ‘Panel’ product…..

we sell it in widths of 1190mm, 1010mm, 1000mm, 900mm, 890mm

it is manufactured in LM but sold in M2 so we have a UOM for each width of panel we sell.

what i did find in pilot was if the UOM before doing anything was not in the part sales UOM i had pricing issues so based on that, the document rules sets the UOM to the sales UOM (1190)then does everything else it needs to do, then sets the price and finally sets the UOM to the correct one.

this has worked flawlessly in pilot during the hundreds of combinations of panel i have configured without issue and not a single error!

document rules are as follows:

if(Context.Entity == "QuoteDtl")
{
    QuoteDtl.ReadyToQuote = false;
    
    UDMethods.GetQuoteDetails(Context.QuoteNumber, Context.QuoteLineNumber);
    UDMethods.CustomCladCharge();

    QuoteDtl.SellingExpectedUM = "1190";

    QuoteDtl.CutLengths_c = true;
    QuoteDtl.PanelWidth_c = System.Convert.ToInt32( Inputs.PanelWidth_cmb.Value );
    QuoteDtl.BackGauge_c = Inputs.IntGauge_cmb.Value;
    QuoteDtl.BackProfile_c = Inputs.IntProfile_cmb.Value;
    QuoteDtl.BackSteel_c = Inputs.IntColour_cmb.Value;
    QuoteDtl.BackFilm_c = (Inputs.IntFilm_cmb.Value == "Yes" ? true : false);
    QuoteDtl.FrontGauge_c = Inputs.ExtGauge_cmb.Value;
    QuoteDtl.FrontProfile_c = Inputs.ExtProfile_cmb.Value;
    QuoteDtl.FaceSteel_c = Inputs.ExtColour_cmb.Value;
    QuoteDtl.FaceFilm_c = (Inputs.ExtFilm_cmb.Value == "Yes" ? true : false);
    QuoteDtl.PanelThickness_c = Inputs.CoreThickness_cmb.Value;
    QuoteDtl.LMWeight_c = Inputs.PanelLMWeight_dec.Value;
    QuoteDtl.LineDesc = Inputs.SalesPart_txt.Value;
    QuoteDtl.QuoteComment = Inputs.SalesDescription_txt.Value;
    QuoteDtl.ProdCode = Inputs.ProductCode_txt.Value;
    QuoteDtl.SellingExpectedQty = 0;
    QuoteDtl.OrderQty = 0;
    QuoteDtl.DocDiscount = 0;
    QuoteDtl.DiscountPercent = 0;
    QuoteDtl.Discount = 0;
    QuoteDtl.UD_Margin_c = Inputs.ProfitMargin_dec.Value;
    QuoteDtl.UD_ConfigPrice_c = System.Math.Round(Inputs.UnitCost_dec.Value,2);

    Pricing.QuotePrice = System.Math.Round(Inputs.UnitCost_dec.Value,2);

    QuoteDtl.SellingExpectedUM = Inputs.PanelWidth_cmb.Value;
    QuoteDtl.ReadyToQuote = true;
}

if(Context.Entity == "OrderDtl")
{
    UDMethods.CustomCladCharge();

    OrderDtl.SalesUM = "1190";
    OrderDtl.CutLengths_c = true;
    OrderDtl.SteelTypeBack_c = Inputs.IntBrand_cmb.Value + " " + Inputs.IntFinish_cmb.Value + " " + Inputs.IntColour_cmb.Value + " " + Inputs.IntGauge_cmb.Value;
    OrderDtl.SteelTypeFace_c = Inputs.ExtBrand_cmb.Value + " " + Inputs.ExtFinish_cmb.Value + " " + Inputs.ExtColour_cmb.Value + " " +Inputs.ExtGauge_cmb.Value;
    OrderDtl.PanelWidth_c = System.Convert.ToInt32( Inputs.PanelWidth_cmb.Value );
    OrderDtl.BackGauge_c = Inputs.IntGauge_cmb.Value;
    OrderDtl.BackProfile_c = Inputs.IntProfile_cmb.Value;
    OrderDtl.BackSteel_c = Inputs.IntColour_cmb.Value;
    OrderDtl.BackFilm_c = Inputs.IntFilm_cmb.Value == "Yes" ? true : false;
    OrderDtl.FrontGauge_c = Inputs.ExtGauge_cmb.Value;
    OrderDtl.FrontProfile_c = Inputs.ExtProfile_cmb.Value;
    OrderDtl.FaceSteel_c = Inputs.ExtColour_cmb.Value;
    OrderDtl.FaceFilm_c = Inputs.ExtFilm_cmb.Value == "Yes" ? true : false;
    OrderDtl.PanelThickness_c = Inputs.CoreThickness_cmb.Value;
    OrderDtl.LineDesc = Inputs.SalesPart_txt.Value;
    OrderDtl.ProdCode = Inputs.ProductCode_txt.Value;
    OrderDtl.OrderComment = Inputs.SalesDescription_txt.Value;
    OrderDtl.UD_Margin_c = Inputs.ProfitMargin_dec.Value;
    OrderDtl.LMWeight_c = Inputs.PanelLMWeight_dec.Value;
    OrderDtl.UD_ConfigPrice_c = System.Math.Round(Inputs.UnitCost_dec.Value,2);
    
    Pricing.OrderPrice = System.Math.Round(Inputs.UnitCost_dec.Value,2);
    OrderDtl.SalesUM = Inputs.PanelWidth_cmb.Value;
}

I see you are setting the SellingExpectedQty to 0. Are the users then entering the quantity? I’ve had issues with that before:

took out setting the qty for both qty fields…..still does the same thing…..

if(Context.Entity == "QuoteDtl")
{
    QuoteDtl.ReadyToQuote = false;
    
    UDMethods.GetQuoteDetails(Context.QuoteNumber, Context.QuoteLineNumber);
    UDMethods.CustomCladCharge();

    QuoteDtl.SellingExpectedUM = "1190";

    QuoteDtl.CutLengths_c = true;
    QuoteDtl.PanelWidth_c = System.Convert.ToInt32( Inputs.PanelWidth_cmb.Value );
    QuoteDtl.BackGauge_c = Inputs.IntGauge_cmb.Value;
    QuoteDtl.BackProfile_c = Inputs.IntProfile_cmb.Value;
    QuoteDtl.BackSteel_c = Inputs.IntColour_cmb.Value;
    QuoteDtl.BackFilm_c = (Inputs.IntFilm_cmb.Value == "Yes" ? true : false);
    QuoteDtl.FrontGauge_c = Inputs.ExtGauge_cmb.Value;
    QuoteDtl.FrontProfile_c = Inputs.ExtProfile_cmb.Value;
    QuoteDtl.FaceSteel_c = Inputs.ExtColour_cmb.Value;
    QuoteDtl.FaceFilm_c = (Inputs.ExtFilm_cmb.Value == "Yes" ? true : false);
    QuoteDtl.PanelThickness_c = Inputs.CoreThickness_cmb.Value;
    QuoteDtl.LMWeight_c = Inputs.PanelLMWeight_dec.Value;
    QuoteDtl.LineDesc = Inputs.SalesPart_txt.Value;
    QuoteDtl.QuoteComment = Inputs.SalesDescription_txt.Value;
    QuoteDtl.ProdCode = Inputs.ProductCode_txt.Value;
    //QuoteDtl.SellingExpectedQty = 0;
    //QuoteDtl.OrderQty = 0;
    QuoteDtl.DocDiscount = 0;
    QuoteDtl.DiscountPercent = 0;
    QuoteDtl.Discount = 0;
    QuoteDtl.UD_Margin_c = Inputs.ProfitMargin_dec.Value;
    QuoteDtl.UD_ConfigPrice_c = System.Math.Round(Inputs.UnitCost_dec.Value,2);

    Pricing.QuotePrice = System.Math.Round(Inputs.UnitCost_dec.Value,2);

    QuoteDtl.SellingExpectedUM = Inputs.PanelWidth_cmb.Value;
    QuoteDtl.ReadyToQuote = true;
}

if(Context.Entity == "OrderDtl")
{
    UDMethods.CustomCladCharge();

    OrderDtl.SalesUM = "1190";
    OrderDtl.CutLengths_c = true;
    OrderDtl.SteelTypeBack_c = Inputs.IntBrand_cmb.Value + " " + Inputs.IntFinish_cmb.Value + " " + Inputs.IntColour_cmb.Value + " " + Inputs.IntGauge_cmb.Value;
    OrderDtl.SteelTypeFace_c = Inputs.ExtBrand_cmb.Value + " " + Inputs.ExtFinish_cmb.Value + " " + Inputs.ExtColour_cmb.Value + " " +Inputs.ExtGauge_cmb.Value;
    OrderDtl.PanelWidth_c = System.Convert.ToInt32( Inputs.PanelWidth_cmb.Value );
    OrderDtl.BackGauge_c = Inputs.IntGauge_cmb.Value;
    OrderDtl.BackProfile_c = Inputs.IntProfile_cmb.Value;
    OrderDtl.BackSteel_c = Inputs.IntColour_cmb.Value;
    OrderDtl.BackFilm_c = Inputs.IntFilm_cmb.Value == "Yes" ? true : false;
    OrderDtl.FrontGauge_c = Inputs.ExtGauge_cmb.Value;
    OrderDtl.FrontProfile_c = Inputs.ExtProfile_cmb.Value;
    OrderDtl.FaceSteel_c = Inputs.ExtColour_cmb.Value;
    OrderDtl.FaceFilm_c = Inputs.ExtFilm_cmb.Value == "Yes" ? true : false;
    OrderDtl.PanelThickness_c = Inputs.CoreThickness_cmb.Value;
    OrderDtl.LineDesc = Inputs.SalesPart_txt.Value;
    OrderDtl.ProdCode = Inputs.ProductCode_txt.Value;
    OrderDtl.OrderComment = Inputs.SalesDescription_txt.Value;
    OrderDtl.UD_Margin_c = Inputs.ProfitMargin_dec.Value;
    OrderDtl.LMWeight_c = Inputs.PanelLMWeight_dec.Value;
    OrderDtl.UD_ConfigPrice_c = System.Math.Round(Inputs.UnitCost_dec.Value,2);
    
    Pricing.OrderPrice = System.Math.Round(Inputs.UnitCost_dec.Value,2);
    OrderDtl.SalesUM = Inputs.PanelWidth_cmb.Value;
}

Sorry, wasn’t clear. I think the recalculation might be happening when your users set the quantities after configuration.

Ah no the price is changing on save of the configuration, changing quantities after the fact makes no difference once this is set.

Hope that explains better

What happens if you have your configurator set the SellingExpectedQty and OrderQty to 1 as the very last line in the DocRule?


still no change,

also checked to make sure we dont have price lists ( i know we dont but checked anyways) and we do not have ANY price lists in the system at all

@kve i feel like such an idiot right now!!!

It was the sales uom that was wrong…because we had a full copy down from pilot to live and it was working in pilot i made a very silly assumption that both systems were the same…how wrong i was, there are Soooooo many differences when i have taken a dive into it, its actually shocking that epicor can call it a full systemml copy down!

Anyways the pricing works which is the main outcome of this!

1 Like