dashboards = [ { 'type': 'account', 'account': 'Income', 'title': 'Income', 'fillColor': '#90EE90' }, { 'type': 'account', 'account': 'Expenses', 'title': 'Expenses', 'fillColor': '#90EE90' }, { 'type': 'receivables', 'title': 'Receivables', 'fillColor': '#FFE4B5' }, { 'type': 'payables', 'title': 'Payables', 'fillColor': '#FFE4B5' }, { 'type': 'collection', 'title': 'Collection', 'comment':'This info comes from the accounts your have marked as "Bank or Cash"', 'fillColor': '#DDA0DD' }, { 'type': 'payments', 'title': 'Payments', 'comment':'This info comes from the accounts your have marked as "Bank or Cash"', 'fillColor': '#DDA0DD' }, { 'type': 'creation', 'doctype': 'Quotation', 'title': 'New Quotations', 'fillColor': '#ADD8E6' }, { 'type': 'creation', 'doctype': 'Sales Order', 'title': 'New Orders', 'fillColor': '#ADD8E6' } ] class DashboardWidget: def __init__(self, company, start, end, interval): from webnotes.utils import getdate from webnotes.model.code import get_obj import webnotes self.company = company self.abbr = webnotes.conn.get_value('Company', company, 'abbr') self.start = getdate(start) self.end = getdate(end) self.interval = interval self.glc = get_obj('GL Control') self.cash_accounts = [d[0] for d in webnotes.conn.sql(""" select name from tabAccount where account_type='Bank or Cash' and company = %s and docstatus = 0 """, company)] self.receivables_group = webnotes.conn.get_value('Company', company,'receivables_group') self.payables_group = webnotes.conn.get_value('Company', company,'payables_group') # list of bank and cash accounts self.bc_list = [s[0] for s in webnotes.conn.sql("select name from tabAccount where account_type='Bank or Cash'")] def timeline(self): """ get the timeline for the dashboard """ import webnotes from webnotes.utils import add_days tl = [] if self.start > self.end: webnotes.msgprint("Start must be before end", raise_exception=1) curr = self.start tl.append(curr) while curr < self.end: curr = add_days(curr, self.interval, 'date') tl.append(curr) tl.append(self.end) return tl def generate(self, opts): """ Generate the dasboard """ from webnotes.utils import flt tl = self.timeline() self.out = [] for i in range(len(tl)-1): self.out.append([tl[i+1].strftime('%Y-%m-%d'), flt(self.value(opts, tl[i], tl[i+1])) or 0]) return self.out def get_account_balance(self, acc, start): """ Get as on account balance """ import webnotes # add abbreviation to company if not acc.endswith(self.abbr): acc += ' - ' + self.abbr # get other reqd parameters try: globals().update(webnotes.conn.sql('select debit_or_credit, lft, rgt from tabAccount where name=%s', acc, as_dict=1)[0]) except Exception,e: webnotes.msgprint('Wrongly defined account: ' + acc) print acc raise e fiscal_year = self.get_fiscal_year(start) if fiscal_year: return self.glc.get_as_on_balance(acc, fiscal_year, start, debit_or_credit, lft, rgt) else: webnotes.msgprint('Please select the START DATE and END DATE such that\ they fall within fiscal year(s) as defined in\ Setup > System > Fiscal Year.', raise_exception=1) def get_fiscal_year(self, dt): """ get fiscal year from date """ import webnotes fiscal_year = webnotes.conn.sql(""" select name from `tabFiscal Year` where year_start_date <= %s and DATE_ADD(year_start_date, INTERVAL 1 YEAR) >= %s """, (dt, dt)) return fiscal_year and (fiscal_year[0] and fiscal_year[0][0]) or None def get_creation_trend(self, doctype, start, end): """ Get creation # of creations in period """ import webnotes return int(webnotes.conn.sql(""" select count(*) from `tab%s` where creation between %s and %s and docstatus=1 """ % (doctype, '%s','%s'), (start, end))[0][0]) def get_account_amt(self, acc, start, end, debit_or_credit): """ Get debit, credit over a period """ import webnotes # add abbreviation to company if not acc.endswith(self.abbr): acc += ' - ' + self.abbr ret = webnotes.conn.sql(""" select ifnull(sum(ifnull(t1.debit,0)),0), ifnull(sum(ifnull(t1.credit,0)),0) from `tabGL Entry` t1, tabAccount t2 where t1.account = t2.name and t2.is_pl_account = 'Yes' and t2.debit_or_credit=%s and ifnull(t1.is_cancelled, 'No')='No' and t1.posting_date between %s and %s """, (debit_or_credit, start, end))[0] return debit_or_credit=='Credit' and float(ret[1]-ret[0]) or float(ret[0]-ret[1]) def get_bank_amt(self, debit_or_credit, master_type, start, end): """ Get collection (reduction in receivables over a period) """ import webnotes reg = '('+'|'.join(self.bc_list) + ')' return webnotes.conn.sql(""" select sum(t1.%s) from `tabGL Entry` t1, tabAccount t2 where t1.account = t2.name and t2.master_type='%s' and t1.%s > 0 and t1.against REGEXP '%s' and ifnull(t1.is_cancelled, 'No')='No' and t1.posting_date between '%s' and '%s' """ % (debit_or_credit, master_type, debit_or_credit, reg, start, end))[0][0] def value(self, opts, start, end): """ Value of the series on a particular date """ import webnotes if opts['type']=='account': debit_or_credit = 'Debit' if opts['account']=='Income': debit_or_credit = 'Credit' return self.get_account_amt(opts['account'], start, end, debit_or_credit) elif opts['type']=='receivables': return self.get_account_balance(self.receivables_group, end)[2] elif opts['type']=='payables': return self.get_account_balance(self.payables_group, end)[2] elif opts['type']=='collection': return self.get_bank_amt('credit', 'Customer', start, end) elif opts['type']=='payments': return self.get_bank_amt('debit', 'Supplier', start, end) elif opts['type']=='creation': return self.get_creation_trend(opts['doctype'], start, end) def load_dashboard(args): """ Get dashboard based on 1. Company (default company) 2. Start Date (last 3 months) 3. End Date (today) 4. Interval (7 days) """ dl = [] import json args = json.loads(args) dw = DashboardWidget(args['company'], args['start'], args['end'], int(args['interval'])) # render the dashboards for d in dashboards: dl.append([d, dw.generate(d)]) return dl if __name__=='__main__': import sys sys.path.append('/var/www/webnotes/wnframework/cgi-bin') from webnotes.db import Database import webnotes webnotes.conn = Database(use_default=1) webnotes.session = {'user':'Administrator'} print load_dashboard("""{ "company": "My Test", "start": "2011-05-01", "end": "2011-08-01", "interval": "7" }""")