How to calc and update a field before save?


I have a Produto doctype, with these fields: est, est_disp, est_res

est_disp = est - est_res

I only permit update the est field… est_res and est_disp is readonly…

So, when I make any update to the est field, I need to calculate… I want to make these automatically… so, no matter where I change, the calc is always called…

I tried these:

class Produto(Document):

    def validade(self):
        self.est_disp = (self.est or 0) - (self.est_res or 0)

    def on_update(self):
        self.est_disp = (self.est or 0) - (self.est_res or 0)

def calc_estoque(doc, method):
    doc.est_disp = (doc.est or 0) - (doc.est_res or 0)

and on hook I set these:

    "Produto": {
        "on_update": "erpbr.estoque.doctype.produto.produto.calc_estoque",
        "on_change": "erpbr.estoque.doctype.produto.produto.calc_estoque",

But, not happen…

How can I do that?


I think, I’m using on_update… so, maybe that’s start after save the doctype, and I can’t change anything… there’s any function like “before_save” ?

I’m using like these on other doctype:

produto = frappe.get_doc('Produto', i.produto)
produto.estoque_atual = produto.estoque_atual - i.qtde

If the change is triggered from the client, you have some options. If the change is initiated on the server, you can compare it to the previous version of the document with self.load_from_db.


I just want to change the value from a field… I update the message above with more info.

frappe.set_value("doctype", "specific_document", "field", "new_value")

Honestly, your question is really confusing. Me pergunte em português com mais contexto.

try to explain more…
I have these DocType: produto with these fields: est, est_res, est_disp

Every time I change the field est … I need to change est_disp too, but automatically using these expression: est_disp = est - est_res

So, I need to make these like a store_procedure, if I change est field value, need to re-calculate the other fields… but I need to be done regardless of where the change comes from… from server, client… using command…

According to the file, the save() methods is:

def _save(self, ignore_permissions=None, ignore_version=None):
“”"Save the current document in the database in the DocType’s table or
tabSingles (for single types).

  This will check for user permissions and execute
  `validate` before updating, `on_update` after updating triggers.

If I use, validate need to be called… but it’s not…

If I use these way:

produto = frappe.get_doc('Produto', i.produto)
produto.estoque_atual = produto.estoque_atual - i.qtde
produto.validate()   <<----------------------------------------

Works fine… call validade function and make the calc…

Just make calc_estoque a class method. Take it out of hooks.

def validade(self):

Alternatively you could call it on before_insert but validate is better since you have some not-less-than-zero logic in there.