Add doctype on dashboard

Any help please :smiley:

Worked, but how I expected:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   erpnext/selling/doctype/customer/customer_dashboard.py

1 Like

How can I do that by custom script?

what exactly do you want to happen?

Exactly what’s on the image: add Maintenance Visit to dashboard of Customer by custom script not hard code

any help?

Sorry but i’ve done that by adding doctypename_dashboard.py. Not by custom script.

Hi Leonardo_Augusto

Pls try this way, This way is not good
I try to use custom script use JS to add link,

frappe.ui.form.on("Customer", {
    onload:  function(frm) {
        var div = $('[data-doctype="Quotation"]').closest('div').parent();
	div.append('<div class="document-link"><a href="#List/Maintenance Visit" class="badge-link small">Maintenance Visit</a></div>');
    }
});
1 Like

Nice @vinhnguyent090, but and the button of more(+)? Just a detail

Sorry for late

Hi @Leonardo_Augusto

but and the button of more(+)?
==> I notyet test it, when I done I will show you

1 Like

Thanks!

Hello @Leonardo_Augusto, Did you get succeed with this issue? If yes, can you please share a solution??

I’m also facing same situations, even my code is not helping to get a place there at Employee Dashboard, unless like your (+) functionality. Below, is my code, might be I’m missing something either in code or command.

from frappe import _

def get_data():
	return {
		'heatmap': True,
		'heatmap_message': _('This is based on the attendance of this Employee'),
		'fieldname': 'employee',
		'transactions': [
			{
				'label': _('Violation And Fines'),
				'items': ['Violation And Fines']
			}
		]
	}

and file name is employee_dashboard.py and used almost all commands, like bench build, migrate, clear-cache, restart respectively. Please help.

@asharamseervi Not yet my friend, and you?
The follow code works:

frappe.ui.form.on("Customer", {
    onload:  function(frm) {
        var div = $('[data-doctype="Quotation"]').closest('div').parent();
	div.append('<div class="document-link"><a href="#List/Maintenance Visit" class="badge-link small">Maintenance Visit</a></div>');
    }
});

But, this are acumulating the button on page, so if you load customer form 3 times, the button will appear 3 times.
Maybe clearing local cache works, not tried yet.

1 Like

No No No !! Click Count will not work :smile: !! Maybe some senior devs will look into this and suggest some solutions.

What are you trying to do?

Created a doctype to list Violation, made by employees and accordingly Penalties as per Violation. However, I do not yet succeed to show it as a deduction. So, have to insert this doctype into Employee Dashboard.

This Violation is a custom doctype?

Oh Yes, I tried to add a missing doctype. This is first doctype I ever added :stuck_out_tongue: !! Still, Learning !!

Hahaha
So did you solve? Or is missing something?

Hi @Leonardo_Augusto and all

I find the way to add link to dashboard, Hope can help you,

This code is add ProForma Invoice to Quotation dashboard. I’m lazy to change my code as your request. You can check and edit it as you want.

Steps

  1. create custom script.
  2. make API to count in your app : my_app.api.get_open_count

create custom script.

    frappe.ui.form.on('Quotation', {
    	refresh: function(frm) {
    		dashboard_link_doctype(frm, "ProForma Invoice");
    	}
    });


    dashboard_link_doctype = function (frm, doctype){

    	var parent = $('.form-dashboard-wrapper [data-doctype="Sales Order"]').closest('div').parent();
    	
    	parent.find('[data-doctype="'+doctype+'"]').remove();

    	parent.append(frappe.render_template("dashboard_link_doctype", {doctype:doctype}));

    	var self = parent.find('[data-doctype="'+doctype+'"]');

    	set_open_count(frm, doctype);

    	// bind links
    	self.find(".badge-link").on('click', function() {
    		frappe.route_options = {"quotation": frm.doc.name}
    		frappe.set_route("List", doctype);
    	});

    	// bind open notifications
    	self.find('.open-notification').on('click', function() {
    		frappe.route_options = {
    			"quotation": frm.doc.name,
    			"status": "Draft"
    		}
    		frappe.set_route("List", doctype);
    	});

    	// bind new
    	if(frappe.model.can_create(doctype)) {
    		self.find('.btn-new').removeClass('hidden');
    	}
    	self.find('.btn-new').on('click', function() {
    		frappe.new_doc(doctype,{
    			"quotation": frm.doc.name
    		});
    	});
    }

    set_open_count = function (frm, doctype){
    	
    	var method = '';
    	var links = {};

    	if(doctype=="ProForma Invoice"){
    		method = 'my_app.api.get_open_count';
    		links = {
    			'fieldname': 'prevdoc_docname',
    			'transactions': [
    				{
    					'label': __('ProForma Invoice'),
    					'items': ['ProForma Invoice']
    				},
    			]
    		};
    	}

    	if(method!=""){
    		frappe.call({
    			type: "GET",
    			method: method,
    			args: {
    				doctype: frm.doctype,
    				name: frm.doc.name,
    				links: links,
    			},
    			callback: function(r) {
    				// update badges
    				$.each(r.message.count, function(i, d) {
    					frm.dashboard.set_badge_count(d.name, cint(d.open_count), cint(d.count));
    				});
    			}
    		});
    	}
    }

    frappe.templates["dashboard_link_doctype"] = ' \
    	<div class="document-link" data-doctype="{{ doctype }}"> \
    	<a class="badge-link small">{{ __(doctype) }}</a> \
    	<span class="text-muted small count"></span> \
    	<span class="open-notification hidden" title="{{ __("Open {0}", [__(doctype)])}}"></span> \
    		<button class="btn btn-new btn-default btn-xs hidden" data-doctype="{{ doctype }}"> \
    				<i class="octicon octicon-plus" style="font-size: 12px;"></i> \
    		</button>\
    	</div>';

Make API to count in your app : my_app.api.get_open_count

@frappe.whitelist()
def get_open_count(doctype, name, links):
	'''Get open count for given transactions and filters

	:param doctype: Reference DocType
	:param name: Reference Name
	:param transactions: List of transactions (json/dict)
	:param filters: optional filters (json/list)'''

	frappe.has_permission(doc=frappe.get_doc(doctype, name), throw=True)

	meta = frappe.get_meta(doctype)
	#links = meta.get_dashboard_data()

	links = frappe._dict({
		'fieldname': 'prevdoc_docname',
		'transactions': [
			{
				'label': _('ProForma Invoice'),
				'items': ['ProForma Invoice']
			},
		]
	})
    #frappe.msgprint(str(links))
    #links = frappe._dict(links)
    #return {'count':0}


	# compile all items in a list
	items = []
	for group in links.transactions:
		items.extend(group.get('items'))

	out = []
	for d in items:
		if d in links.get('internal_links', {}):
			# internal link
			continue

		filters = get_filters_for(d)
		fieldname = links.get('non_standard_fieldnames', {}).get(d, links.fieldname)
        #return fieldname
		data = {'name': d}
		if filters:
			# get the fieldname for the current document
			# we only need open documents related to the current document
			filters[fieldname] = name
			total = len(frappe.get_all(d, fields='name',
				filters=filters, limit=100, distinct=True, ignore_ifnull=True))
			data['open_count'] = total

		total = len(frappe.get_all(d, fields='name',
			filters={fieldname: name}, limit=100, distinct=True, ignore_ifnull=True))
		data['count'] = total
		out.append(data)

	out = {
		'count': out,
	}

	module = frappe.get_meta_module(doctype)
	if hasattr(module, 'get_timeline_data'):
		out['timeline_data'] = module.get_timeline_data(doctype, name)
    
	return out

this code you can pass via JS but I notyet do it.

links = frappe._dict({
		'fieldname': 'prevdoc_docname',
		'transactions': [
			{
				'label': _('ProForma Invoice'),
				'items': ['ProForma Invoice']
			},
		]
	})
13 Likes