Add doctype on dashboard

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