Insert process structure

Hi to all,
I’d like to understand what is the real process of inserting data into Database, I mean, After clisck save button on a form of a specific module (custom or standar) what are the steps and the files that are involved during this process.

For example if I’d like to modify some data before the insert, or launch another program (ETL file for example) after an insert, how can I do?


You need to use hooks to modify data before or after insert.

@schilgod Sunny’s answer is one way to do it but not the only. Personally, I don’t recommend modifications to hooks, but in your ETL use case, it is probably the best way to go. If you’re talking about manipulating document-level data before it is inserted, like validating a date, then that should be included in the validation for that doctype.
If you haven’t already done it, taking the tutorial will be worth all the time you would otherwise waste trying to figure things out on your own. If you want a complete list a database methods, the documentation used to be here, but you can find it by reading this python file.

For example, I have a problem with the standard way in which the purchase receipt in erpnext fulfill orders. I’d like to verify what file and what script provide this acitivity in order to modify it according to my needs.

Is it possible?

In Frappe, everything this possible. But If you’re talking about a core doctype like purchase invoice, I think that 1) someone else has had the same issue and 2) you’re more likely to find your solution by asking how to use it the way you want rather than how to modify it the way you want. Lots of ERPNext developers, myself included, are enticed by the siren song of easy modifications, but there’s so much good stuff there if you’re willing to learn how to use it.

The Purchase Receipt does not fulfill orders. Maybe you have a misunderstand about terminology? For newcomers, the ERPNext specific terminology is a little daunting and one expects things to be called what they are called in your previous system or experience, but that’s not always the case.
Fulfillment (change in stock) is handled by the Purchase Receipt in the buying side (or with the “update stock” option checked in Purchase Invoice, or with the Delivery Note on the selling side (decrease in stock qty, expense posted to COGS).

I’m referring to supplier orders, in what way they are closed and how the received quantities are updated. I show the case with an example to explain you:

I have two supply orders:


First Problem, in my case the same delivery note can contains materials from different supply orders, every DN row specify the reference of N. of order and position.

Example of Delivery Note:
1BATCH item C304 qty 2000Kg order PO1 position1
2BATCH item C304 qty 1000Kg order PO2 position1
3BATCH item C304 qty 500Kg order PO2 position1
4BATCH item A409 qty 3000Kg order PO2 position2

If I create a Purchase receipt directly from the PO (Make->Receipt), what I have is that in the detail row, the PO field is automatically filled and I can’t modify it.

So the first problem is thatusing thie method I can’t have a Purchase receipt with materials from different PO.
Instead if I create the Purchase Receipt from Stock menu, the Purchase Order field is not shown.

Second problem:

Example DN :
1BATCH item C304 qty 1000Kg order PO2 position1
2BATCH item C304 qty 500Kg order PO2 position1

The result should be PO2 row1 1500Kg received, instead after that the Purchase Receipt is saved, I have:

pos1 qty received: 1000kg.
pos3 qty received: 500kg.

Concluding, what I need is the possibility to choose for every Purchase Receipt row (so for every batch) what order and what position has to be updated (received qty), and in some case, decide directly from Purchase receipt if I have to close that row so if I have to consider row as completely delivered.

I can have for example that for 5000kg ordered the real quantity delivered will be 4800kg and for the supplier the order is considered closed. For this reason I need to be able to close that row in order to have the correct supply orders situation.

Thanks in advance for your help.

Anyone can help me to solve my problem?


If I understand you correctly then following video will show you how to achieve what you want without coding. ERPNext is very flexible and you can customize your workflow easily. This is just an example for you, you can separate batches if you want or create them using naming series in V11.

The closing of the purchase order by row is not possible but you create a custom field in the Purchase Receipt Item of type “Check” and just mark it when you don’t want to receive anymore of that item row but still need other items from the same purchase order.

Then you add a “WHERE” condition in “Items to be Received” report to filter those rows out, that way your report will show only non completed items which you have not marked. when the purchase order is done the you close it.

good luck

first of all thanks a lot for your suggest, It seems more or less what I need, but there is another thing not shown in your example.

I can have more batch that arriving with the DN that have to update the received quantity of the same purchase row order.
For thi reason I modified the doc type Purchase Recepit Item and I remove the check from the option “Hidden” and “Read Only” for the fields purchase_order and purchase_order_item.
In this way for every row, I can select exactly the order and the position that I want to update.

Now the problem is that in the DN is specified for example

  • ORDER A position 1 …
  • ORDER A position 3 …

the field purchase_order_item indeed don’t have the value of row position but an alphanumeric Key (example 9f41d20209) that the user doesnt’ know.

I’d like that the user insert PO number and position in two fields:
position 1

Then a Script automatically using that PO number and that row position (fields “parent” and “idx” of the database table “tabPurchase Order Item”) launch a database query, extract the alphanumeric Key and fill the field purchase_order_item with this value.

Is that possible? If yes can you suggest me how do it with an example?

Anyone can help me?