How to prevent deleting a row in child table, based on some conditions?

Hi all,

any hint on how to prevent to delete raw in child table if it’s stored in another doc?

Let’s say i’d like to prevent deleting a raw from Items in Delivery Note if it’s stored in an Packing List Item …how is possible to do?

Thx

@JoEz,

You can use the before_tablefieldname_remove trigger and validate the condition, if conditions are not met then you can just throw an error to prevent the row deletion

Thanks,
Makarand

@makarand_b big big thx!

@makarand_b it seems to be not working properly.

the code i used for items field:

frappe.ui.form.on('Stock Note', {
	before_items_remove: function(frm, cdt, cdn) {
	 	console.log("test");
	}
})

Stock Note is a custom doctype

erpnext 8.6.1
frappe 8.6.0

What’s wrong?

Edit, found the problem …it’s needed to be in child table doctype:

frappe.ui.form.on('Stock Note Item', {
	before_items_remove: function(frm, cdt, cdn) {
	 	console.log("test");
	}
})

@makarand_b sorry for bothering, it seems before_items_remove is triggered but it not prevent the item to be removed from child table, even if a frappe.throw is raised.

See video:

http://recordit.co/USMHt1Tjsm

Here is the code:

frappe.ui.form.on('Quotation Item', {
	before_items_remove: function (frm, cdt, cdn) {
		frappe.call({
			method: "bon_bon_custom.api.check_item_in_picking",
			args: {
				quotation: frm.docname,
				qi_name: cdn
			},
			callback: function (r) {
				if (!r.exc && r.message) {
					if(r.message === "false") {
						frappe.throw(__("Item cannot be deleted"))
					}
				}
			}
		});
	}
});

Any hint on how to prevent row to be removed?

1 Like

Can’t understand what i’m doing wrong, i found this code for Customize Form Fields and it seems to be working:

before_fields_remove: function(frm, doctype, name) {
		var row = frappe.get_doc(doctype, name);
		if(!(row.is_custom_field || row.__islocal)) {
			frappe.msgprint(__("Cannot delete standard field. You can hide it if you want"));
			throw "cannot delete custom field";
		}
	},

while following it’s not working:

frappe.ui.form.on('Quotation Item', {
	before_items_remove: function (frm, cdt, cdn) {
		frappe.call({
			method: "bon_bon_custom.api.check_item_in_picking",
			args: {
				quotation: frm.docname,
				qi_name: cdn
			},
			callback: function (r) {
				if (!r.exc && r.message) {
					if(r.message === "false") {
						frappe.msgprint(__("Item cannot be deleted"));
						throw "could not delete item";
					}
				}
			}
		});
	}
});

Any hint to find solution?

Thx

I am facing the same problem as you, the trigger is really “triggered” after the row has allready been deleted.

Will check the code that you mention.

Regards

1 Like

@Pau_Rosello_Van_Scho, any news on this?

For me in v8.6.4 it is failing even in Customize Form Field, the row is deleted before calling the trigger.

This is where the tigger is launched:

And it seems that it is an “asyncronous”, so the next line is executed before the trigger has been completed (as a long-shot I would say that this bug was introduced with the testing framework but I have no confirmation)

Just updated and checked in 8.6.4, I can confirm it is failing on Customization Form Filed as well.

It seems you’re right about next line is executed before the trigger has been completed.

@makarand_b any hint on how to fix it?

@makarand_b same problem here, do you have any news about this point ?

same issue. @nabinhait Is there a solution for this? We want to be able to prevent a child table row from being deleted under certain conditions…

I have been able to make this work with the following code:

frappe.ui.form.on("Team Registration", {
    before_team_table_remove: function(frm, dct, dcn){
      frappe.call({
		method: "avium_tournament.avium_tournament.doctype.registration.registration.check_remove_group_line",
		args: {
			dct: dct,
			dcn: dcn
		},
		always: function(r){
		    if(r.message.code == "st_judged"){
		       	frappe.throw(__("You cannot delete this row, as the template {0} has been judged already.", [r.message.template]))
		    }
		}
	  })
    }
});

Be careful as I am using the always method instead of the usual callback method

Regards!

3 Likes

Thx, I’ll test it on my use case

frappe.ui.form.on(‘Sales Campaign Agencies’,{
sales_agencies_remove:function(frm,cdt,cdn){
frappe.call({
method:‘property_sales.property_sales.doctype.property_sales_campaign.property_sales_campaign.getagencydata’,
freeze: true,
args: {
“parent”: frm.doc.name,
“name”: cdn
},
always: function(r){
console.log(r)
if(r.message.length>1){
frappe.msgprint(“You cannot delete this ro1w”);
frm.reload_doc()

	    }
	}
  })
}

});

use frm.reload_doc() if condition true else item will delete

Hey all,
anyone any solution to this? even i am looking for it.