Price Lookup via BPM

I have a need to display the price that a customer would receive on a qty of a part. I have tried the Price List Inquiry, but it does not seem to work exactly the same as Order Entry because there are differing UOMs.
I would like to populate some fields with the Unit Price, Disc%, and Disc Amount without creating a Sales Order Line. Is this possible via a BPM?
I can run through all the tables (Customer, Customer Group, Price List, Discount Price List, etc), but I would hope there is something like:
EpiLib.GetCustomerPrice(int CustNum, string partNum, decimal Quantity, string UOM, out decimal UnitPrice, out decimal DiscPercent, out decimal DiscAmt);

Erp.Internal.Lib.Shared.dll has a potential option, but it isn’t quite it. While this will work to a small degree, it doesn’t take into account quantities. I will keep looking unless someone has the magic sauce :wink:
Get_PriceBrk2(int Inp_CustNum, string Inp_ShipToNum, string Inp_Warehouse, string Inp_PartNum, string Inp_ProdCode, string Inp_UOMCode, DateTime? Inp_EntryDate, string Inp_CurrencyCode, out Guid FoundRowid, out string FoundTable)
or
Get_PriceBrk(int Inp_CustNum, string Inp_ShipToNum, string Inp_Warehouse, string Inp_PartNum, string Inp_ProdCode, string Inp_UOMCode, DateTime? Inp_EntryDate, string Inp_CurrencyCode, out Guid FoundRowid, out string FoundTable)

I didn’t want to jump in because it would be nice to know if someone has the all-in-one ready-packaged solution.

But the only way I found of getting this functionality was to create a BAQ with the price variables required as parameters (customer, part, quantity etc) and use that as a look-up. It isn’t quite as easy as a built-in call would be, but it does only need doing once and then you can use it anywhere, and also does have the compensation that you know exactly how it’s coming up with its results and can tweak if business procedures change.

plpartbreak and pricelstparts table are probably where you could look and they will support using different uom’s and quantities. You could in theory populate these tables with some base numbers and have a bpm look them up and do some calculations on the fly based on this data.

If I understand you correctly you want to enter a cust num, part num, quantity and uom and have it display an undiscounted price (pricelstparts.baseprice), discounted percentage (pricelstparts.discountpercent 1-5) and a discounted price (pricelstparts.unitprice 1-5)

You could associate the pricelist with a customer, set an expiry date in the past so as it does not apply to orders.

I am maybe oversimplifying what you want to achieve though.

That’s what our BAQ does, and then we call it from within BPMs or customizations as necessary, using the appropriate parameters. We have a fairly complicated pricing set-up due to the nature of our market.

I think @Jason_Woods was hoping for something more pre-packaged, though.

We are on 10.0.7.4 so I can’t comment on later releases but the customer price list functionality is useful but also quite weak - for example no out of the box way to enforce moq’s.

The price list I have works flawlessly. My difficulty is it uses Customer, Customer group, product group and part to figure the price and discounts.
While I can manually make a LINQ query to get there (or multiple with IF statements), I wondered if there was a simple code snippet.
Order Entry does this already so the code is there, but I am guessing it just gets the price list and discount list. I would then still need to get the actual price and discount values.

We used to do ours with Linq. It proved more maintainable (and, oddly, better for performance) to do it in a BAQ and call on that from any BPM or customization that needs it, but otherwise we only ever got as far as you already have.

So I must say I’ll be very interested to see if there IS a more elegant way.

What I did as POC to export a Customers Full Part Price List (since I couldn’t find anything built-in) was to make an updatable BAQ (using the Advance BPM option) of all saleable parts and using the Post Processing functionality of the Get List Method to run each part through the GetPriceListInquiry in the Price List Inquiry Service (after it return the SQL results) and assign the break value to a calculated field. It’s not the most efficient when running 10K parts but it returns all the correct prices using the same logic as the Order Entry.

In your case where if want to mock up a sales order, I would make an Updatable BAQ using the Advance BPM, with Calculated Fields(at least with all the required fields for the Price List Inquiry service) that are marked as updateable and allow adding new. Then then the dashboard will allow you to add multiple lines. Then I would put the code I used in my POC, as the Base Update method. It obviously won’t save anything to the Db but it will return the newly calculated values for each record. I mean you could go a step further and place the code in the OnChangeField events for real time calculations.

This is all of the top my head, I’m sure there is more things that would have to be done in the Dashboard to make it more user friendly.

The updateable BAQ can be pretty powerful. If done correctly, you can almost write your own BO (that can even be called via REST!).

image

Some Code

using (var service = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.PriceListInquirySvcContract>(this.Db, false))
{
	foreach(var s in ttResults)
	{

		int pageSize = 0;
		int absolutePage = 0;
		bool morePages = false;

		string icCompany = s["Calculated_Company"].ToString();
		string icPartNum = s["Calculated_PartNum"].ToString();
		string icCustID = s["Calculated_CustID"].ToString();
		string icShipToNum = "";
		string icCustGroupCode = s["Calculated_GroupCode"].ToString();
		string icProductCode = s["Calculated_ProdCode"].ToString();
		decimal idQuantity = (decimal)s["Calculated_Quantity"];
		string icUOMCode = s["Calculated_QuantityUOM"].ToString();
		string icWarehouseCode = "ALL";
		string icCurrencyCode = s["Calculated_CurrencyCode"].ToString();
		decimal icExchangeRate = (decimal)s["Calculated_ExchangeRate"];
		
		decimal discountAmnt = 0;
		
	  
		var pricelistTS = service.GetPriceListInquiry(icCustID, icShipToNum, icPartNum, icCustGroupCode, icProductCode, idQuantity, icUOMCode, icWarehouseCode, icCurrencyCode, pageSize, absolutePage, out morePages);

		var ttPriceListInquiryRow = pricelistTS.PriceListInquiry.FirstOrDefault();
		if (ttPriceListInquiryRow != null)
		{
			discountAmnt = (ttPriceListInquiryRow.BasePrice - ttPriceListInquiryRow.NetPrice) * idQuantity;
			if(discountAmnt == 0)
			{
			  s["Calculated_Message"] = string.Format("Using Price List {0} ", ttPriceListInquiryRow.ListCode);  
			  s["Calculated_RowMod"] = "";       
			}
			else
			{
			  s["Calculated_DiscAmount"] = discountAmnt;
			  s["Calculated_UnitPrice"] = ttPriceListInquiryRow.PartUnitPrice;
			  s["Calculated_BasePrice"] = ttPriceListInquiryRow.BasePrice;
			  s["Calculated_BreakPrice"] = ttPriceListInquiryRow.BreakPrice;
			  s["Calculated_NetPrice"] = ttPriceListInquiryRow.NetPrice;
			  s["Calculated_Message"] = string.Format("Using Price List {0} ", ttPriceListInquiryRow.ListCode); 
			}
		}
		else
		{
		  s["Calculated_Message"] = "No Price List Found";      
		}
	}
}

Unfortunately, the Price List inquiry doesn’t work EXACTLY the same as Order Entry
If I have a “Unit Price” price list setup in EACH and a “Discount” price list setup in CASE, I can sell a CASE of something (12 EACHs with Part Specific UOM) and the Price List on Order Entry populates both Price and Discount lists. In Price Inquiry, ony brings back the Discount list for CASE. (10.2.200.14).

I see… Hmm… I feel like those should match. What’s the point of Price List inquiry??? Just curious, if you were to add the “CASE” UOM to your “Unit Price” price list, do you think Price List inquiry might work different?

Yes. It works then. But that isn’t how Order Entry works. It also requires duplication of every part.