Setting Prices on a per Project Basis


In my company, we’re trading hardware on a per project basis. This means the selling and buying prices both change for each project.

In order to acheive that:

  • I emptied the default selling and buying price lists.
  • In Selling Settings, I checked Allow user to edit Price List Rate in transactions and unchecked Maintain Same Rate Throughout Sales Cycle and Validate Selling Price for Item against Purchase Rate or Valuation Rate.
  • In Buying Settins, I unchecked Maintain same rate throughout purchase cycle.

When doing a quotation, I enter the buying price in the Price List Rate field, and the selling price in the Rate field.
After a quotation is submitted, a Sale Order (SO) is made. In it, the gross profit is OK, so I conclude ERPNext and me are talking about the same thing!

However, when creating a Purchase Order (PO) from that SO, the prices (so buying prices here) are set to 0. Specifically, the Rate and Price List Rate are set to 0.

I guess I’m doing something wrong. Can you help me to figure out what?
Especially, did I modeled correctly the process in ERPNext?

Thanks a lot for your help!

I’m planning to make a custom script on the Purchase Order (PO) that will

  1. fetch the corresponding Sale Order (SO),
  2. read the Price List Rate of the SO items,
  3. use them to fill in the Price List Rate (or Rate?) of the PO items.

Is that a good approach?

Are you wanting to arrive at Project Profitability? Are you trying to ensure that you buy at a price that is X% lower than your selling rate? Or is it the other way round? Meaning you want to sell at a rate X% higher than your buying rate?

I mean you are listing the details. But unless you write down (for yourself too) how you want a structured data system (such as ERPNext) to help your business, you will get an ERP (and a wonderful ERP at that with ERPNext), but your business may not be able to accrue all the benefits that are possible.

Not sure if that helps. But I am missing the woods for the trees here.



Thanks a lot for your response!

Basically, our process is as follow:

  1. A client (generally a public institution) publicly says it want something particular to be build for itself.
  2. We plan to apply for this contract, so we ask our suppliers for a quotation on the hardware we’ll need.
  3. If the supplier quotation is OK for us, we add our margin on it and make a quotation to the client.
  4. If the client chooses us, we make the purchase to the supplier.
  5. We pay the supplier for the hardware and are paid by the client for the contract.

At this point, if we apply to a client contract and are chosen, we are profitable (unless something goes wrong after, but it’s not the point here).

In our current “system”, each project is split across multiple excel files, with a few more excel files to glue the different projects together. The point of using an ERP is to centralise everything in one place, and having automagic report of everything (like the clients that haven’t paid yet, the gross profit per client or per month, the expected income/outcome of money for the next month, and so on). Thus the point in using an ERP system is not to increase our profitability but in saving time and effort.

Moreover, please note that step 2 is a bit hazy, so I don’t plan to add in the ERP.

Here’s how I model our process in ERPNext:

When we’re sending the quotation to the client (step 3), we already know the final buying and selling prices. Hence, I can fill in the ERPNext’s quotation form with them (the buying price being Price List Rate and the selling price being Rate, right?).

When the client chooses us and accept the quotation (step 4), I make a Sale Order (SO) from the quotation. The newly created SO fetches the different rates and prices from the quotation, everything’s fine.

At step 4, I also need to buy the hardware to the supplier. I create a Purchase Order (PO) from the SO, and the problem is here. The items are correctly fetched, as well as the other information, but the Price List Rate and Rate in the newly created PO are set to 0.

My question is: How can I make a Purchase Order gets the prices of its items from the corresponding Sale Order items?

Thanks again for your help.

1 Like

custom script can be used to achieve your goal

Can’t you make a set of pricelist for each project? So you don’t have to empty the standard price list every time.

the server script is something like this( tested on my local instance)

for item in doc.items:
    if item.sales_order_item:
        rate = frappe.db.get_value('Sales Order Item', item.sales_order_item,'price_list_rate')
        item.price_list_rate = rate
        item.rate = rate

Thanks a lot for these responses!

I’ll try @szufisher’s solution and let you know the results.

About @rahy’s solution, what would be the pros and cons of doing it that way?

You can have multi pricelist so you can have a set of sell/buy pricelist per project. And you can even duplicate them as basis for the new one and only change what is necessary.
First create item with Standard Pricelist. So you can have standard pricelist.
Then when making new quotation (and further documents), select the project’s pricelist from the Currency and Pricelist tab. Any update on price in the item table will go to this pricelist then.

If later you do similar project you can reuse this pricelist.

Thanks for the explanation.

It seems interesting, I’ll definitely consider that!

Hi everyone and Happy New Year!

I tried @szufisher’s solution but that did not work, so I wrote mine.

It’s a custom client script, that I paste here in case someone has the same requirement as me.

frappe.ui.form.on('Purchase Order', {
    refresh(frm) {
        // If the document already exists, we don't want to erase its prices.
        if(frm.is_new()) {
            $.each(frm.doc.items, function(index, item) {
                // First, we get the sales order document
                let so = frappe.get_doc('Sales Order', item.sales_order);
                // Second, we get the same item in the SO
                let so_item = so.items.find(itm => == item.sales_order_item);
                // We extract its price
                let price = so_item.price_list_rate;
                // We set the price of the PO item
                item.price_list_rate = price;
                item.rate = price;

If you see any bad practice, feel free to comment!