mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-05 14:38:26 +00:00
moved directory structure
This commit is contained in:
89
home/__init__.py
Normal file
89
home/__init__.py
Normal file
@@ -0,0 +1,89 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes import msgprint
|
||||
|
||||
feed_dict = {
|
||||
# Project
|
||||
'Project': ['[%(status)s]', '#000080'],
|
||||
|
||||
# Sales
|
||||
'Lead': ['%(lead_name)s', '#000080'],
|
||||
'Quotation': ['[%(status)s] To %(customer_name)s worth %(currency)s %(grand_total_export)s', '#4169E1'],
|
||||
'Sales Order': ['[%(status)s] To %(customer_name)s worth %(currency)s %(grand_total_export)s', '#4169E1'],
|
||||
|
||||
# Purchase
|
||||
'Supplier': ['%(supplier_name)s, %(supplier_type)s', '#6495ED'],
|
||||
'Purchase Order': ['[%(status)s] %(name)s To %(supplier_name)s for %(currency)s %(grand_total_import)s', '#4169E1'],
|
||||
|
||||
# Stock
|
||||
'Delivery Note': ['[%(status)s] To %(customer_name)s', '#4169E1'],
|
||||
'Purchase Receipt': ['[%(status)s] From %(supplier)s', '#4169E1'],
|
||||
|
||||
# Accounts
|
||||
'Journal Voucher': ['[%(voucher_type)s] %(name)s', '#4169E1'],
|
||||
'Purchase Invoice': ['To %(supplier_name)s for %(currency)s %(grand_total_import)s', '#4169E1'],
|
||||
'Sales Invoice':['To %(customer_name)s for %(currency)s %(grand_total_export)s', '#4169E1'],
|
||||
|
||||
# HR
|
||||
'Expense Claim': ['[%(approval_status)s] %(name)s by %(employee_name)s', '#4169E1'],
|
||||
'Salary Slip': ['%(employee_name)s for %(month)s %(fiscal_year)s', '#4169E1'],
|
||||
'Leave Transaction':['%(leave_type)s for %(employee)s', '#4169E1'],
|
||||
|
||||
# Support
|
||||
'Customer Issue': ['[%(status)s] %(description)s by %(customer_name)s', '#000080'],
|
||||
'Maintenance Visit':['To %(customer_name)s', '#4169E1'],
|
||||
'Support Ticket': ["[%(status)s] %(subject)s", '#000080'],
|
||||
|
||||
# Website
|
||||
'Web Page': ['%(title)s', '#000080'],
|
||||
'Blog': ['%(title)s', '#000080']
|
||||
}
|
||||
|
||||
def make_feed(feedtype, doctype, name, owner, subject, color):
|
||||
"makes a new Feed record"
|
||||
#msgprint(subject)
|
||||
from webnotes.model.doc import Document
|
||||
from webnotes.utils import get_fullname
|
||||
|
||||
if feedtype in ('Login', 'Comment', 'Assignment'):
|
||||
# delete old login, comment feed
|
||||
webnotes.conn.sql("""delete from tabFeed where
|
||||
datediff(curdate(), creation) > 7 and doc_type in ('Comment', 'Login', 'Assignment')""")
|
||||
else:
|
||||
# one feed per item
|
||||
webnotes.conn.sql("""delete from tabFeed
|
||||
where doc_type=%s and doc_name=%s
|
||||
and ifnull(feed_type,'') != 'Comment'""", (doctype, name))
|
||||
|
||||
f = Document('Feed')
|
||||
f.owner = owner
|
||||
f.feed_type = feedtype
|
||||
f.doc_type = doctype
|
||||
f.doc_name = name
|
||||
f.subject = subject
|
||||
f.color = color
|
||||
f.full_name = get_fullname(owner)
|
||||
f.save()
|
||||
|
||||
def update_feed(doc, method=None):
|
||||
"adds a new feed"
|
||||
if method in ['on_update', 'on_submit']:
|
||||
subject, color = feed_dict.get(doc.doctype, [None, None])
|
||||
if subject:
|
||||
make_feed('', doc.doctype, doc.name, doc.owner, subject % doc.fields, color)
|
||||
1
home/doctype/__init__.py
Normal file
1
home/doctype/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
1
home/doctype/company_control/__init__.py
Normal file
1
home/doctype/company_control/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
107
home/doctype/company_control/company_control.py
Normal file
107
home/doctype/company_control/company_control.py
Normal file
@@ -0,0 +1,107 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d,dl
|
||||
|
||||
# All roles of Role Master
|
||||
def get_all_roles(self):
|
||||
r_list=sql("select name from `tabRole` where name not in ('All','Guest','Administrator','Customer','Supplier') and docstatus != 2")
|
||||
if r_list[0][0]:
|
||||
r_list = [x[0] for x in r_list]
|
||||
return r_list
|
||||
|
||||
# Get all permissions for given role
|
||||
def get_permission(self,role):
|
||||
perm = sql("select distinct t1.`parent`, t1.`read`, t1.`write`, t1.`create`, t1.`submit`,t1.`cancel`,t1.`amend` from `tabDocPerm` t1, `tabDocType` t2 where t1.`role` ='%s' and t1.docstatus !=2 and ifnull(t1.permlevel, 0) = 0 and t1.`read` = 1 and t2.module != 'Recycle Bin' and t1.parent=t2.name " % role)
|
||||
return perm or ''
|
||||
|
||||
# Get roles for given user
|
||||
def get_user_roles(self,usr):
|
||||
r_list=sql("select role from `tabUserRole` where parent=%s and role not in ('All','Guest')",usr)
|
||||
if r_list:
|
||||
return [r[0] for r in r_list]
|
||||
else:
|
||||
return ''
|
||||
|
||||
# Update roles of given user
|
||||
def update_roles(self,arg):
|
||||
arg = eval(arg)
|
||||
sql("delete from `tabUserRole` where parenttype='Profile' and parent ='%s'" % (cstr(arg['usr'])))
|
||||
role_list = arg['role_list'].split(',')
|
||||
for r in role_list:
|
||||
pr=Document('UserRole')
|
||||
pr.parent = arg['usr']
|
||||
pr.parenttype = 'Profile'
|
||||
pr.role = r
|
||||
pr.parentfield = 'userroles'
|
||||
pr.save(1)
|
||||
|
||||
# Update Membership Type at Gateway
|
||||
from webnotes.utils import cint
|
||||
|
||||
sql("delete from __SessionCache where user=%s", cstr(arg['usr']))
|
||||
|
||||
# Save profile
|
||||
def save_profile(self,arg):
|
||||
arg = eval(arg)
|
||||
p = Document('Profile', session['user'])
|
||||
for k in arg:
|
||||
p.fields[k] = arg[k]
|
||||
p.save()
|
||||
|
||||
def get_login_url(self):
|
||||
return session['data']['login_from']
|
||||
|
||||
def get_user_info(self):
|
||||
|
||||
usr = sql("select count(name) from tabProfile where docstatus != 2 and name not in ('Guest','Administrator')")
|
||||
usr = usr and usr[0][0] or 0
|
||||
|
||||
ol = sql("select count(distinct t1.name) from tabProfile t1, tabSessions t2 where t1.name = t2.user and t1.name not in('Guest','Administrator') and TIMESTAMPDIFF(HOUR,t2.lastupdate,NOW()) <= 1 and t1.docstatus != 2 and t1.enabled=1")
|
||||
ol = ol and ol[0][0] or 0
|
||||
|
||||
ac = sql("select count(name) from tabProfile where enabled=1 and docstatus != 2 and name not in ('Guest', 'Administrator')")
|
||||
ac = ac and ac[0][0] or 0
|
||||
|
||||
inac = sql("select count(name) from tabProfile where (enabled=0 or enabled is null or enabled = '') and docstatus != 2 and name not in ('Guest','Administrator')")
|
||||
inac = inac and inac[0][0] or 0
|
||||
|
||||
return usr, ol, ac, inac
|
||||
|
||||
def get_sm_count(self) :
|
||||
return sql("select count(t1.parent) from tabUserRole t1, tabProfile t2 where t1.role='System Manager' and t1.parent = t2.name and t2.enabled=1")[0][0] or 0
|
||||
30
home/doctype/company_control/company_control.txt
Normal file
30
home/doctype/company_control/company_control.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
# DocType, Company Control
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:35:52',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:35:52',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'issingle': 1,
|
||||
'module': u'Home',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'version': 13
|
||||
},
|
||||
|
||||
# DocType, Company Control
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Company Control'
|
||||
}
|
||||
]
|
||||
1
home/doctype/feed/__init__.py
Normal file
1
home/doctype/feed/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
39
home/doctype/feed/feed.py
Normal file
39
home/doctype/feed/feed.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
89
home/doctype/feed/feed.txt
Normal file
89
home/doctype/feed/feed.txt
Normal file
@@ -0,0 +1,89 @@
|
||||
# DocType, Feed
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:35:52',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:35:52',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'_FEED.#####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'module': u'Home',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'show_in_menu': 0,
|
||||
'version': 3
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Feed',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Feed
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Feed'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'feed_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Feed Type'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'doc_type',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Doc Type'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'doc_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Doc Name'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'subject',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Subject'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'color',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Color'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'full_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Full Name'
|
||||
}
|
||||
]
|
||||
1
home/doctype/home_control/__init__.py
Normal file
1
home/doctype/home_control/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
371
home/doctype/home_control/home_control.py
Normal file
371
home/doctype/home_control/home_control.py
Normal file
@@ -0,0 +1,371 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes import session, msgprint, errprint
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
try: import json
|
||||
except: import simplejson as json
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d,dl
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------
|
||||
# ------------------------------------- Home page module details -----------------------------------------
|
||||
|
||||
def delete_cache(self):
|
||||
com = sql("select abbr, name from tabCompany")
|
||||
for d in com:
|
||||
sql("update `tabCompany` set receivables_group = '%s' where (receivables_group = '%s' or receivables_group = '' or receivables_group is null) and name = '%s'" % ('Accounts Receivable - '+cstr(d[0]), 'Accounts Receivables - '+cstr(d[0]), d[1]))
|
||||
sql("update `tabCompany` set payables_group = '%s' where (payables_group = '%s' or payables_group = '' or payables_group is null) and name = '%s'" % ('Accounts Payable - '+cstr(d[0]), 'Accounts Payables - '+cstr(d[0]), d[1]))
|
||||
|
||||
def get_modules(self):
|
||||
rl = webnotes.user.get_roles()
|
||||
ml = sql("select distinct t1.name, t1.module_icon, t1.module_label, t1.module_desc, t1.module_page from `tabModule Def` t1, `tabModule Def Role` t2 where t2.role in ('%s') and t1.disabled !='Yes' and ifnull(t1.is_hidden, 'No') != 'Yes' and t1.name = t2.parent order by t1.module_seq asc" % "','".join(rl), as_dict=1)
|
||||
webnotes.response['login_url'] = session['data'].get('login_from', '')
|
||||
|
||||
return ml
|
||||
|
||||
def get_module_details(self,m):
|
||||
ret = {}
|
||||
ret['il'] = sql('select doc_type, doc_name, display_name, icon, description, fields, click_function, idx from `tabModule Def Item` where parent=%s and ifnull(`hide`,0)=0 order by idx asc', m, as_dict=1)
|
||||
ret['wl'] = sql('select widget_code from `tabModule Def` where name =%s', m)[0][0] or ''
|
||||
ret['custom_reports'] = sql('''
|
||||
SELECT DISTINCT t1.criteria_name AS `display_name`, t1.description, t1.doc_type AS `doc_name`, 'Custom Reports' AS `doc_type`
|
||||
FROM `tabSearch Criteria` t1, `tabDocPerm` t2
|
||||
WHERE t1.module = "%s"
|
||||
AND IFNULL(t1.disabled,0) = 0
|
||||
AND (t1.doc_type=t2.parent OR t1.parent_doc_type = t2.parent)
|
||||
AND t2.permlevel = 0
|
||||
AND t2.read=1
|
||||
AND t2.role IN ("%s")
|
||||
AND ifnull(standard,"No")="No"''' % (m, '", "'.join(webnotes.user.get_roles())), as_dict=1)
|
||||
|
||||
return ret
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
# ----------------------------------------------- Home page updates ----------------------------------------------
|
||||
|
||||
def get_events_list(self):
|
||||
import webnotes, webnotes.utils
|
||||
from webnotes.widgets.event import get_cal_events
|
||||
|
||||
dl = get_cal_events(nowdate(), add_days(nowdate(), 7))
|
||||
el = []
|
||||
for d in dl:
|
||||
#el.append([d.name, d.event_date, d.event_hour, d.event_name, d.description or '', d.ref_type or '', d.ref_name or '', d.owner])
|
||||
dict = {
|
||||
'name': d.name,
|
||||
'event_date': d.event_date,
|
||||
'event_hour': d.event_hour,
|
||||
'event_name': d.event_name,
|
||||
'description': d.description,
|
||||
'notes': d.notes,
|
||||
'event_type': d.event_type,
|
||||
'ref_type': d.ref_type,
|
||||
'ref_name': d.ref_name,
|
||||
'owner' : d.owner
|
||||
}
|
||||
|
||||
el.append(dict)
|
||||
return el
|
||||
|
||||
|
||||
def get_activity_list(self):
|
||||
out = {}
|
||||
import webnotes
|
||||
rt = webnotes.user.can_read
|
||||
|
||||
dt_list = [d[0] for d in sql("select distinct t2.name from tabDocField t1, tabDocType t2 where t1.fieldname='status' and t1.docstatus=0 and (t2.istable is null or t2.istable = 0) and t1.parent = t2.name")]
|
||||
if not dt_list:
|
||||
return out
|
||||
|
||||
# get list of activity dt
|
||||
for dt in dt_list:
|
||||
if dt in rt:
|
||||
out[dt] = {}
|
||||
# get status list
|
||||
sl = sql("select distinct status from `tab%s`" % dt)
|
||||
|
||||
for s in sl:
|
||||
if s[0]:
|
||||
# get count
|
||||
cnt = sql("select count(*) from `tab%s` where status = '%s' and modified > '%s'" % (dt, s[0], add_days(nowdate(), -7)))[0][0]
|
||||
out[dt][s[0]] = cint(cnt)
|
||||
return out
|
||||
|
||||
def get_dt_help(self,dt):
|
||||
return sql("select description from tabDocType where name=%s",dt)[0][0] or ''
|
||||
|
||||
# get dashboard counts
|
||||
# --------------------
|
||||
def get_wip_counts(self):
|
||||
#dtl = ['Lead', 'Enquiries', 'Sales Order', 'Invoices', 'Purchase Request', 'Purchase Order', 'Bills', 'Tasks', 'Delivery Note', 'Maintenance']
|
||||
can_read_dt = ['Lead', 'Opportunity', 'Sales Order', 'Sales Invoice', 'Purchase Request', 'Purchase Order', 'Purchase Invoice', 'Delivery Note', 'Task', 'Serial No']
|
||||
dt = {}
|
||||
for d in can_read_dt:
|
||||
args = {}
|
||||
|
||||
# if Lead
|
||||
if d=='Lead':
|
||||
args = {'To follow up':sql("select count(name) from tabLead where status!='Converted' and status!='Lead Lost' and status!='Not Interested'")}
|
||||
|
||||
# if Opportunity
|
||||
elif d=='Opportunity':
|
||||
args['Quotations to be sent'] = sql("select count(distinct(t2.name)) from `tabQuotation`t1, `tabOpportunity`t2 where t1.enq_no!=t2.name and t2.docstatus=1")
|
||||
args['To follow up'] = sql("select count(distinct(t2.name)) from `tabQuotation`t1, `tabOpportunity`t2 where t1.enq_no=t2.name and t2.docstatus=1 and t1.docstatus=1")
|
||||
|
||||
# if Sales Order
|
||||
elif d=='Sales Order':
|
||||
args['To be delivered'] = sql("select count(name) from `tabSales Order` where ifnull(per_delivered,0)<100 and delivery_date>now() and docstatus=1")
|
||||
args['To be billed'] = sql("select count(name) from `tabSales Order` where ifnull(per_billed,0)<100 and docstatus=1")
|
||||
args['Overdue'] = sql("select count(name) from `tabSales Order` where ifnull(per_delivered,0)<100 and delivery_date<now() and docstatus=1")
|
||||
args['To be submitted'] = sql("select count(name) from `tabSales Order` where docstatus=0 and status='Draft'") #Draft
|
||||
|
||||
# if Sales Invoice
|
||||
elif d=='Sales Invoice':
|
||||
args['To receive payment'] = sql("select count(name) from `tabSales Invoice` where docstatus=1 and due_date>now() and outstanding_amount!=0")
|
||||
args['Overdue'] = sql("select count(name) from `tabSales Invoice` where docstatus=1 and due_date<now() and outstanding_amount!=0")
|
||||
args['To be submitted'] = sql("select count(name) from `tabSales Invoice` where docstatus=0") #Draft
|
||||
|
||||
# if Purchase Request
|
||||
elif d=='Purchase Request':
|
||||
args['Purchase Order to be made'] = sql("select count(name) from `tabPurchase Request` where ifnull(per_ordered,0)<100 and docstatus=1")
|
||||
args['To be submitted'] = sql("select count(name) from `tabPurchase Request` where status='Draft'") #Draft
|
||||
|
||||
# if Purchase Order
|
||||
elif d=='Purchase Order':
|
||||
args['To receive items'] = sql("select count(name) from `tabPurchase Order` where ifnull(per_received,0)<100 and docstatus=1")
|
||||
args['To be billed'] = sql("select count(name) from `tabPurchase Order` where ifnull(per_billed,0)<100 and docstatus=1")
|
||||
args['To be submitted'] = sql("select count(name) from `tabPurchase Order` where status='Draft'") #Draft
|
||||
|
||||
# if Purchase Invoice
|
||||
elif d=='Purchase Invoice':
|
||||
args['To be paid'] = sql("select count(name) from `tabPurchase Invoice` where docstatus=1 and outstanding_amount!=0")
|
||||
args['To be submitted'] = sql("select count(name) from `tabPurchase Invoice` where docstatus=0") #Draft
|
||||
|
||||
# if Delivery Note
|
||||
elif d=='Delivery Note':
|
||||
args['To be submitted'] = sql("select count(name) from `tabDelivery Note` where status='Draft' and docstatus=0")
|
||||
args['To be billed'] = sql("select count(name) from `tabDelivery Note` where docstatus=1 and docstatus=1 and ifnull(per_billed,0)<100")
|
||||
|
||||
# if Tasks
|
||||
elif d=='Task':
|
||||
args = {'Open': sql("select count(name) from `tabTask` where status='Open'")}
|
||||
|
||||
# if Serial No
|
||||
elif d=='Serial No':
|
||||
args['AMC expiring this month'] = sql("select count(name) from `tabSerial No` where docstatus!=2 and maintenance_status = 'Under AMC' and status!='Scrapped' and status!='Not in Use' and month(now()) = month(amc_expiry_date) and year(now()) = year(amc_expiry_date)")
|
||||
args['Warranty expiring this month'] = sql("select count(name) from `tabSerial No` where docstatus!=2 and maintenance_status = 'Under Warranty' and status!='Scrapped' and status!='Not in Use' and month(now()) = month(ifnull(warranty_expiry_date,0)) and year(now())=year(ifnull(warranty_expiry_date,0))")
|
||||
|
||||
for a in args:
|
||||
args[a] = args[a] and args[a][0][0] or 0
|
||||
|
||||
dt[d] = args
|
||||
return dt
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------
|
||||
|
||||
def get_todo_count(self):
|
||||
count = sql("select count(distinct name) from `tabToDo` where owner=%s", session['user'])
|
||||
count = count and count[0][0] or 0
|
||||
return count
|
||||
|
||||
def get_todo_list(self):
|
||||
res = sql("""select name, description, `date`,
|
||||
priority, checked, reference_type, reference_name from `tabToDo`
|
||||
where owner=%s order by field(priority,'High','Medium','Low') asc, date asc""", \
|
||||
session['user'], as_dict=1)
|
||||
return res
|
||||
|
||||
def add_todo_item(self,args):
|
||||
args = json.loads(args)
|
||||
|
||||
d = Document('ToDo', args.get('name') or None)
|
||||
d.description = args['description']
|
||||
d.date = args['date']
|
||||
d.priority = args['priority']
|
||||
d.checked = args.get('checked', 0)
|
||||
d.owner = session['user']
|
||||
d.save(not args.get('name') and 1 or 0)
|
||||
|
||||
if args.get('name') and d.checked:
|
||||
self.notify_assignment(d)
|
||||
|
||||
return d.name
|
||||
|
||||
def remove_todo_item(self,nm):
|
||||
d = Document('ToDo', nm or None)
|
||||
if d and d.name:
|
||||
self.notify_assignment(d)
|
||||
sql("delete from `tabToDo` where name = %s",nm)
|
||||
|
||||
def notify_assignment(self, d):
|
||||
doc_type = d.fields.get('reference_type')
|
||||
doc_name = d.fields.get('reference_name')
|
||||
assigned_by = d.fields.get('assigned_by')
|
||||
if doc_type and doc_name and assigned_by:
|
||||
from webnotes.widgets.form import assign_to
|
||||
assign_to.notify_assignment(assigned_by, d.owner, doc_type, doc_name)
|
||||
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------
|
||||
|
||||
def dismiss_message(self, arg=''):
|
||||
msg_id = webnotes.conn.get_global('system_message_id')
|
||||
webnotes.conn.set_global('system_message_id', msg_id, session['user'])
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------
|
||||
|
||||
def get_todo_reminder(self):
|
||||
return convert_to_lists(sql("select name, description, date, priority,checked from `tabToDo` where owner=%s and date=%s and checked=1 order by priority, date", (session['user'], nowdate())))
|
||||
|
||||
# get user details
|
||||
def get_users(self):
|
||||
ret = {}
|
||||
ret['usr'] = convert_to_lists(sql("select distinct name, concat_ws(' ', first_name, last_name), ifnull(messanger_status,'Available') from tabProfile where name=%s", session['user']))
|
||||
ret['on'] = convert_to_lists(sql("select distinct t1.name, concat_ws(' ', t1.first_name, t1.last_name), ifnull(t1.messanger_status,'Available') from tabProfile t1, tabSessions t2 where t1.name = t2.user and t1.name not in('Guest',%s) and TIMESTAMPDIFF(HOUR,t2.lastupdate,NOW()) <= 1", session['user']))
|
||||
ret['off'] = convert_to_lists(sql("select distinct t1.name, concat_ws(' ', t1.first_name, t1.last_name), ifnull(t1.messanger_status,'Offline') from tabProfile t1, tabSessions t2 where t1.name != t2.user and t1.name not in('Guest',%s) and t1.name not in(select distinct t1.name from tabProfile t1, tabSessions t2 where t1.name = t2.user and t1.name not in('Guest',%s) and (t1.messanger_status !='Invisible' or t1.messanger_status is null) and TIMESTAMPDIFF(HOUR,t2.lastupdate,NOW()) <= 1)", (session['user'], session['user'])))
|
||||
|
||||
return ret
|
||||
|
||||
# Delete event
|
||||
def delete_event(self,id):
|
||||
sql("delete from tabEvent where name=%s", id)
|
||||
|
||||
# edit event
|
||||
def edit_event(self,arg):
|
||||
arg = json.loads(arg)
|
||||
d = Document('Event', arg.get('name') or None)
|
||||
for k in arg:
|
||||
d.fields[k] = str(arg[k])
|
||||
d.save(not arg.get('name') and 1 or 0)
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------
|
||||
# module settings
|
||||
# -------------------------------------------------------------------------------------------------------
|
||||
def get_module_order(self):
|
||||
show_list = ['Home','Setup','Accounts','Selling','Buying','Support','Stock','HR','Projects','Analysis','Production']
|
||||
ml = filter(lambda x: x[0] in show_list, \
|
||||
sql("select name, module_label, module_seq, is_hidden from `tabModule Def` where docstatus<2 order by module_seq asc, module_label asc"))
|
||||
return convert_to_lists(ml)
|
||||
|
||||
def set_module_order(self,arg):
|
||||
arg = eval(arg)
|
||||
for k in arg:
|
||||
sql("update `tabModule Def` set module_seq = %s, is_hidden = %s where name = %s", (cint(arg[k]['module_seq']) + 1, arg[k]['is_hidden'], k))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------
|
||||
|
||||
def get_bd_list(self):
|
||||
bl = convert_to_lists(sql("select name,concat_ws(' ',first_name,last_name),birth_date from tabProfile where (birth_date is not null and birth_date != '') and (enabled is not null and enabled !='')"))
|
||||
|
||||
nd = nowdate().split('-')
|
||||
d = cint(nd[2])
|
||||
m = cint(nd[1])
|
||||
|
||||
tb = []
|
||||
for b in bl:
|
||||
if b[2] and b[2].find('-') != -1:
|
||||
if cint(b[2].split('-')[2]) == d and cint(b[2].split('-')[1]) == m:
|
||||
tb.append(b)
|
||||
|
||||
return tb
|
||||
|
||||
# obtain account id for webforms
|
||||
def get_acc_id(self):
|
||||
acc_id = sql("select value from `tabSingles` where field='account_id' and doctype='Control Panel'")
|
||||
acc_id = acc_id and acc_id[0][0] or ''
|
||||
if acc_id:
|
||||
return cstr(acc_id)
|
||||
else:
|
||||
msgprint("Account Id not specified")
|
||||
raise Exception
|
||||
|
||||
#update serial no status
|
||||
def update_serial_status(self, lst, status):
|
||||
lst11=[]
|
||||
for y1 in lst:
|
||||
sql("update `tabSerial No` set maintenance_status = %s where name=%s", (status,y1))
|
||||
lst11.append(y1)
|
||||
msgprint("Status updated as '"+status+"' for "+cstr(lst11))
|
||||
|
||||
# chk to set serial no status as 'Out of warranty'
|
||||
def set_for_out_of_warranty(self):
|
||||
chk_for_out_of_wrnty = sql("select name from `tabSerial No` where ifnull(warranty_expiry_date, '2200-12-12') < CURDATE() and ifnull(warranty_expiry_date, '0000-00-00') != '0000-00-00' and ifnull(amc_expiry_date, '0000-00-00') ='0000-00-00' and ifnull(maintenance_status, '') != 'Out of Warranty'")
|
||||
if chk_for_out_of_wrnty:
|
||||
lst1 = [x1[0] for x1 in chk_for_out_of_wrnty]
|
||||
self.update_serial_status(lst1, 'Out Of Warranty')
|
||||
|
||||
# chk to set serial no status as 'Out of amc'
|
||||
def set_for_out_of_amc(self):
|
||||
chk_for_out_of_amc = sql("select name from `tabSerial No` where ifnull(warranty_expiry_date, '0000-00-00')< CURDATE() and ifnull(amc_expiry_date, '2200-12-12') < CURDATE() and ifnull(amc_expiry_date, '0000-00-00') !='0000-00-00' and ifnull(maintenance_status, '') !='Out of AMC'")
|
||||
if chk_for_out_of_amc:
|
||||
lst2 = [x2[0] for x2 in chk_for_out_of_amc]
|
||||
self.update_serial_status(lst2, 'Out Of AMC')
|
||||
|
||||
# chk to set serial no status as 'under amc'
|
||||
def set_for_under_amc(self):
|
||||
chk_for_under_amc = sql("select name from `tabSerial No` where ifnull(warranty_expiry_date, '0000-00-00')< CURDATE() and ifnull(amc_expiry_date, '2200-12-12') >= CURDATE() and ifnull(amc_expiry_date, '0000-00-00') !='0000-00-00' and ifnull(maintenance_status, '') !='Under AMC'")
|
||||
if chk_for_under_amc:
|
||||
lst3 = [x3[0] for x3 in chk_for_under_amc]
|
||||
self.update_serial_status(lst3, 'Under AMC')
|
||||
|
||||
# chk to set serial no status as 'under warranty'
|
||||
def set_for_under_warranty(self):
|
||||
chk_for_under_wrnty = sql("select name from `tabSerial No` where ifnull(warranty_expiry_date, '2200-12-12') >= CURDATE() and ifnull(warranty_expiry_date, '0000-00-00') != '0000-00-00' and ifnull(amc_expiry_date, '0000-00-00') ='0000-00-00' and ifnull(maintenance_status, '') != 'Under Warranty'")
|
||||
if chk_for_under_wrnty:
|
||||
lst4 = [x4[0] for x4 in chk_for_under_wrnty]
|
||||
self.update_serial_status(lst4, 'Under Warranty')
|
||||
|
||||
# check maintenance status for all serial nos only for 1st login each day
|
||||
def set_serial_no_status(self):
|
||||
|
||||
chk_serial_no_update_date = webnotes.conn.get_global('maintenance_status_update_date')
|
||||
|
||||
# check status only for 1st login each day.... if maintenance date already updated means it is checked
|
||||
if getdate(chk_serial_no_update_date) != nowdate():
|
||||
# chk to set serial no status as 'Out of warranty'
|
||||
self.set_for_out_of_warranty()
|
||||
|
||||
# chk to set serial no status as 'Out of amc'
|
||||
self.set_for_out_of_amc()
|
||||
|
||||
# chk to set serial no status as 'under amc'
|
||||
self.set_for_under_amc()
|
||||
|
||||
# chk to set serial no status as 'under warranty'
|
||||
self.set_for_under_warranty()
|
||||
|
||||
#set maintenance_status_update_date
|
||||
webnotes.conn.set_global('maintenance_status_update_date', nowdate())
|
||||
|
||||
# get user fullname
|
||||
def get_user_fullname(self,usr):
|
||||
return sql("select concat_ws(' ',first_name, last_name) from tabProfile where name=%s", usr)[0][0] or ''
|
||||
56
home/doctype/home_control/home_control.txt
Normal file
56
home/doctype/home_control/home_control.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
# DocType, Home Control
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:35:53',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:35:53',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'issingle': 1,
|
||||
'module': u'Home',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 6
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Home Control',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'read': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocType, Home Control
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Home Control'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Guest'
|
||||
}
|
||||
]
|
||||
1
home/page/__init__.py
Normal file
1
home/page/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
1
home/page/activity/__init__.py
Normal file
1
home/page/activity/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
23
home/page/activity/activity.css
Normal file
23
home/page/activity/activity.css
Normal file
@@ -0,0 +1,23 @@
|
||||
#activity-list .label {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
#activity-list .label-info {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#activity-list .user-info {
|
||||
float: right;
|
||||
color: #777;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#activity-list .date-sep {
|
||||
margin-bottom: 11px;
|
||||
padding: 5px 0px;
|
||||
border-bottom: 1px solid #aaa;
|
||||
color: #555;
|
||||
font-size: 10px;
|
||||
}
|
||||
7
home/page/activity/activity.html
Normal file
7
home/page/activity/activity.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<div class="layout-wrapper layout-wrapper-appframe">
|
||||
<div class="layout-appframe"></div>
|
||||
<div class="layout-main">
|
||||
<div id="activity-list">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
67
home/page/activity/activity.js
Normal file
67
home/page/activity/activity.js
Normal file
@@ -0,0 +1,67 @@
|
||||
wn.pages['activity'].onload = function(wrapper) {
|
||||
wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.layout-appframe'));
|
||||
wrapper.appframe.title('Activity');
|
||||
var list = new wn.ui.Listing({
|
||||
appframe: wrapper.appframe,
|
||||
method: 'home.page.activity.activity.get_feed',
|
||||
parent: $('#activity-list'),
|
||||
render_row: function(row, data) {
|
||||
new erpnext.ActivityFeed(row, data);
|
||||
}
|
||||
});
|
||||
list.run();
|
||||
}
|
||||
|
||||
erpnext.last_feed_date = false;
|
||||
erpnext.ActivityFeed = Class.extend({
|
||||
init: function(row, data) {
|
||||
this.scrub_data(data);
|
||||
this.add_date_separator(row, data);
|
||||
$(row).append(sprintf('<div style="margin: 0px">\
|
||||
<span class="avatar-small"><img src="%(imgsrc)s" /></span> \
|
||||
<span %(onclick)s class="label %(add_class)s">%(feed_type)s</span>\
|
||||
%(link)s %(subject)s <span class="user-info">%(by)s</span></div>', data));
|
||||
},
|
||||
scrub_data: function(data) {
|
||||
data.by = wn.user_info(data.owner).fullname;
|
||||
data.imgsrc = wn.user_info(data.owner).image;
|
||||
|
||||
// feedtype
|
||||
if(!data.feed_type) {
|
||||
data.feed_type = get_doctype_label(data.doc_type);
|
||||
data.add_class = "label-info";
|
||||
data.onclick = repl('onclick="window.location.href=\'#!List/%(feed_type)s\';"', data)
|
||||
}
|
||||
|
||||
// color for comment
|
||||
if(data.feed_type=='Comment') {
|
||||
data.add_class = "label-important";
|
||||
}
|
||||
|
||||
if(data.feed_type=='Assignment') {
|
||||
data.add_class = "label-warning";
|
||||
}
|
||||
|
||||
// link
|
||||
if(data.doc_name && data.feed_type!='Login') {
|
||||
data.link = repl('<a href="#!Form/%(doc_type)s/%(doc_name)s">%(doc_name)s</a>', data)
|
||||
}
|
||||
},
|
||||
add_date_separator: function(row, data) {
|
||||
var date = dateutil.str_to_obj(data.modified);
|
||||
var last = erpnext.last_feed_date;
|
||||
|
||||
if((last && dateutil.obj_to_str(last) != dateutil.obj_to_str(date)) || (!last)) {
|
||||
var diff = dateutil.get_day_diff(new Date(), date);
|
||||
if(diff < 1) {
|
||||
pdate = 'Today';
|
||||
} else if(diff < 2) {
|
||||
pdate = 'Yesterday';
|
||||
} else {
|
||||
pdate = dateutil.global_date_format(date);
|
||||
}
|
||||
$(row).html(repl('<div class="date-sep">%(date)s</div>', {date: pdate}));
|
||||
}
|
||||
erpnext.last_feed_date = date;
|
||||
}
|
||||
})
|
||||
17
home/page/activity/activity.py
Normal file
17
home/page/activity/activity.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_feed(arg=None):
|
||||
"""get feed"""
|
||||
return webnotes.conn.sql("""select
|
||||
distinct t1.name, t1.feed_type, t1.doc_type, t1.doc_name, t1.subject, t1.owner,
|
||||
t1.modified
|
||||
from tabFeed t1, tabDocPerm t2
|
||||
where t1.doc_type = t2.parent
|
||||
and t2.role in ('%s')
|
||||
and ifnull(t2.`read`,0) = 1
|
||||
order by t1.modified desc
|
||||
limit %s, %s""" % ("','".join(webnotes.get_roles()),
|
||||
webnotes.form_dict['limit_start'], webnotes.form_dict['limit_page_length']),
|
||||
as_dict=1)
|
||||
28
home/page/activity/activity.txt
Normal file
28
home/page/activity/activity.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
# Page, activity
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-02-29 11:59:13',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-02-29 12:11:46',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Page
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'module': u'Home',
|
||||
'name': '__common__',
|
||||
'page_name': u'activity',
|
||||
'standard': u'Yes',
|
||||
'title': u'Activity'
|
||||
},
|
||||
|
||||
# Page, activity
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'name': u'activity'
|
||||
}
|
||||
]
|
||||
1
home/page/attributions/__init__.py
Normal file
1
home/page/attributions/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
0
home/page/attributions/attributions.css
Normal file
0
home/page/attributions/attributions.css
Normal file
93
home/page/attributions/attributions.html
Normal file
93
home/page/attributions/attributions.html
Normal file
@@ -0,0 +1,93 @@
|
||||
<div class="layout-wrapper">
|
||||
<a class="close" onclick="window.history.back();">×</a>
|
||||
<h1>Attributions</h1>
|
||||
<hr>
|
||||
<p><b>Source Code:</b> <a href="https://github.com/webnotes/erpnext">
|
||||
https://github.com/webnotes/erpnext</a></p>
|
||||
<p><b>Website:</b> <a href="https://erpnext.com">
|
||||
https://erpnext.com</a></p>
|
||||
<hr>
|
||||
<p class="help">ERPNext is an Open Source project and is possible because of the work of
|
||||
thousands of software developers, companies and designers who have contributed their
|
||||
work to the community. We have tried to list as many projects as possible that are
|
||||
used by ERPNext, but this list may not be exhaustive.</p>
|
||||
|
||||
|
||||
<h4>Server</h4>
|
||||
<ul>
|
||||
<li>Linux (GNU)</li>
|
||||
<li>Apache HTTPD server (web server)</li>
|
||||
<li>MySQL (database, Percona build)</li>
|
||||
<li>Git (source code control via Github)</li>
|
||||
</ul>
|
||||
|
||||
<h4>Programming Languages & Libraries</h4>
|
||||
<ul>
|
||||
<li><a href="http://python.org">Python</a></li>
|
||||
<ul>
|
||||
<li>Python-MySQL</li>
|
||||
<li>pytz (timezones)</li>
|
||||
<li>jinja2 (templating)</li>
|
||||
<li>markdown2 (markdown parser)</li>
|
||||
<li>jsmin (javascript minifier)</li>
|
||||
</ul>
|
||||
<li>Javascript</li>
|
||||
<ul>
|
||||
<li>JQuery</li>
|
||||
<li>JQuery UI (datepicker, sortable)</li>
|
||||
<li>TinyMCE - text editor</li>
|
||||
<li>Twitter Bootstrap</li>
|
||||
<li>Ace - code editor</li>
|
||||
<li>Slick Grid - report grid</li>
|
||||
<li>jQPlot - graphs</li>
|
||||
<li><a href="http://taitems.github.com/jQuery.Gantt/">JQuery.Gantt</a> - Gantt Chart</li>
|
||||
<li>JSON2 - JSON builder, parser</li>
|
||||
<li>JSColor - color picker</li>
|
||||
<li><a href="https://github.com/dcneiner/Downloadify">Downloadify</a> - Export CSV files from the browser</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h4>CSS Frameworks</h4>
|
||||
<ul>
|
||||
<li>Twitter Bootstrap</li>
|
||||
</ul>
|
||||
|
||||
<h4>Icons</h4>
|
||||
<ul>
|
||||
<li>The Noun Project</li>
|
||||
<li>Glyphicons</li>
|
||||
</ul>
|
||||
|
||||
<h4>Web Frameworks</h4>
|
||||
<ul>
|
||||
<li>wnframework</li>
|
||||
</ul>
|
||||
|
||||
<h4>Web Browsers</h4>
|
||||
<ul>
|
||||
<li>Mozilla Firefox</li>
|
||||
<ul>
|
||||
<li>Firebug (debugger)</li>
|
||||
</ul>
|
||||
<li>Apple Safari</li>
|
||||
<li>Google Chorme</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2>ERPNext License</h2>
|
||||
<p><b>ERPNext - Open Source, web based ERP</b></p>
|
||||
<p>Copyright © 2008 onwards, Web Notes Technologies Pvt Ltd, India</p>
|
||||
|
||||
<p>This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the <b>GNU General Public License</b> as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.</p>
|
||||
|
||||
<p>This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.</p>
|
||||
|
||||
<p>For complete license see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a></p>
|
||||
<hr>
|
||||
<p>For more information please write to us at support@erpnext.com</p>
|
||||
</div>
|
||||
1
home/page/attributions/attributions.js
Normal file
1
home/page/attributions/attributions.js
Normal file
@@ -0,0 +1 @@
|
||||
wn.pages['attributions'].onload = function(wrapper) { }
|
||||
2
home/page/attributions/attributions.py
Normal file
2
home/page/attributions/attributions.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
28
home/page/attributions/attributions.txt
Normal file
28
home/page/attributions/attributions.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
# Page, attributions
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-01 12:30:42',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-01 12:30:42',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Page
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'module': u'Home',
|
||||
'name': '__common__',
|
||||
'page_name': u'attributions',
|
||||
'standard': u'Yes',
|
||||
'title': u'Attributions'
|
||||
},
|
||||
|
||||
# Page, attributions
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'name': u'attributions'
|
||||
}
|
||||
]
|
||||
1
home/page/dashboard/__init__.py
Normal file
1
home/page/dashboard/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
12
home/page/dashboard/dashboard.css
Normal file
12
home/page/dashboard/dashboard.css
Normal file
@@ -0,0 +1,12 @@
|
||||
div.dashboard_table td {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
div.dashboard-title {
|
||||
font-weight: bold;
|
||||
padding: '3px 0px';
|
||||
}
|
||||
|
||||
div.dashboard-graph {
|
||||
height: 180px;
|
||||
}
|
||||
8
home/page/dashboard/dashboard.html
Normal file
8
home/page/dashboard/dashboard.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<div class="layout_wrapper dashboard">
|
||||
<div class="header"></div>
|
||||
<div class="body">
|
||||
<!-- 4x2 table to show the dashboards-->
|
||||
<div class="help_box">Loading...</div>
|
||||
<div class="dashboard_table"></div>
|
||||
</div>
|
||||
</div>
|
||||
170
home/page/dashboard/dashboard.js
Normal file
170
home/page/dashboard/dashboard.js
Normal file
@@ -0,0 +1,170 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pscript.onload_dashboard = function() {
|
||||
// load jqplot
|
||||
wn.require('lib/js/lib/jqplot/css/jqplot.css');
|
||||
wn.require('lib/js/lib/jqplot/jquery.jqplot.min.js');
|
||||
wn.require('lib/js/lib/jqplot/jqplot-plugins/jqplot.barRenderer.js');
|
||||
wn.require('lib/js/lib/jqplot/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js');
|
||||
wn.require('lib/js/lib/jqplot/jqplot-plugins/jqplot.canvasTextRenderer.min.js');
|
||||
wn.require('lib/js/lib/jqplot/jqplot-plugins/jqplot.categoryAxisRenderer.min.js');
|
||||
|
||||
|
||||
pscript.dashboard_settings = {
|
||||
company: sys_defaults.company,
|
||||
start: (function() {
|
||||
var start_date = dateutil.add_days(new Date(), -180);
|
||||
var year_start_date = dateutil.str_to_obj(sys_defaults.year_start_date);
|
||||
if (start_date < year_start_date) { start_date = year_start_date; }
|
||||
console.log(start_date);
|
||||
return dateutil.obj_to_str(start_date);
|
||||
})(),
|
||||
end: (function() {
|
||||
var end_date = new Date();
|
||||
var year_end_date = dateutil.str_to_obj(sys_defaults.year_end_date);
|
||||
if (end_date > year_end_date) { end_date = year_end_date; }
|
||||
console.log(end_date);
|
||||
return dateutil.obj_to_str(end_date);
|
||||
})(),
|
||||
interval: 30
|
||||
}
|
||||
|
||||
var ph = new PageHeader($('.dashboard .header').get(0), 'Dashboard');
|
||||
var db = new Dashboard();
|
||||
|
||||
ph.add_button('Settings', db.show_settings);
|
||||
|
||||
db.refresh();
|
||||
|
||||
}
|
||||
|
||||
Dashboard = function() {
|
||||
var me = this;
|
||||
$.extend(me, {
|
||||
refresh: function() {
|
||||
$('.dashboard .help_box').css('display', 'block');
|
||||
$c_page('home', 'dashboard', 'load_dashboard', JSON.stringify(pscript.dashboard_settings), function(r,rt) {
|
||||
$('.dashboard .help_box').css('display', 'none');
|
||||
me.render(r.message);
|
||||
})
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
$('.dashboard_table').html('');
|
||||
var t = make_table($('.dashboard_table').get(0), 4, 2, '100%', ['50%', '50%'], {padding: '5px'});
|
||||
var ridx=0; var cidx=0;
|
||||
for(var i=0; i< data.length; i++) {
|
||||
// switch columns and rows
|
||||
if(cidx==2) { cidx=0; ridx++}
|
||||
|
||||
// give an id!
|
||||
var cell = $td(t,ridx,cidx);
|
||||
var title = $a(cell, 'div', 'dashboard-title', '', data[i][0].title);
|
||||
var parent = $a(cell, 'div', 'dashboard-graph');
|
||||
if(data[i][0].comment);
|
||||
var comment = $a(cell, 'div', 'comment', '', data[i][0].comment)
|
||||
|
||||
parent.id = '_dashboard' + ridx + '-' + cidx;
|
||||
|
||||
// render graph
|
||||
me.render_graph(parent.id, data[i][1], data[i][0].fillColor);
|
||||
cidx++;
|
||||
}
|
||||
},
|
||||
|
||||
render_graph: function(parent, values, fillColor) {
|
||||
var vl = [];
|
||||
$.each(values, function(i,v) {
|
||||
vl.push([dateutil.str_to_user(v[0]), v[1]]);
|
||||
});
|
||||
$.jqplot(parent, [vl], {
|
||||
seriesDefaults:{
|
||||
renderer:$.jqplot.BarRenderer,
|
||||
rendererOptions: {fillToZero: true},
|
||||
},
|
||||
axes: {
|
||||
// Use a category axis on the x axis and use our custom ticks.
|
||||
xaxis: {
|
||||
min: 0,
|
||||
renderer: $.jqplot.CategoryAxisRenderer,
|
||||
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
|
||||
tickOptions: {
|
||||
angle: -30,
|
||||
fontSize: '8pt'
|
||||
}
|
||||
},
|
||||
// Pad the y axis just a little so bars can get close to, but
|
||||
// not touch, the grid boundaries. 1.2 is the default padding.
|
||||
yaxis: {
|
||||
min: 0,
|
||||
pad: 1.05,
|
||||
tickOptions: {formatString: '%d'}
|
||||
}
|
||||
},
|
||||
seriesColors: [fillColor]
|
||||
});
|
||||
},
|
||||
|
||||
show_settings: function() {
|
||||
var d = new wn.widgets.Dialog({
|
||||
title: 'Set Company Settings',
|
||||
width: 500,
|
||||
fields: [
|
||||
{
|
||||
label:'Company',
|
||||
reqd: 1,
|
||||
fieldname:'company',
|
||||
fieldtype:'Link',
|
||||
options: 'Company'
|
||||
},
|
||||
{
|
||||
label:'Start Date',
|
||||
reqd: 1,
|
||||
fieldname:'start',
|
||||
fieldtype:'Date',
|
||||
},
|
||||
{
|
||||
label:'End Date',
|
||||
reqd: 1,
|
||||
fieldname:'end',
|
||||
fieldtype:'Date',
|
||||
},
|
||||
{
|
||||
label:'Interval',
|
||||
reqd: 1,
|
||||
fieldname:'interval',
|
||||
fieldtype:'Int'
|
||||
},
|
||||
{
|
||||
label:'Regenerate',
|
||||
fieldname:'refresh',
|
||||
fieldtype:'Button'
|
||||
}
|
||||
]
|
||||
});
|
||||
d.onshow = function() {
|
||||
d.set_values(pscript.dashboard_settings);
|
||||
}
|
||||
d.fields_dict.refresh.input.onclick = function() {
|
||||
pscript.dashboard_settings = d.get_values();
|
||||
me.refresh();
|
||||
d.hide();
|
||||
}
|
||||
d.show();
|
||||
}
|
||||
})
|
||||
}
|
||||
286
home/page/dashboard/dashboard.py
Normal file
286
home/page/dashboard/dashboard.py
Normal file
@@ -0,0 +1,286 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
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'
|
||||
}
|
||||
]
|
||||
|
||||
import webnotes
|
||||
|
||||
class DashboardWidget:
|
||||
def __init__(self, company, start, end, interval):
|
||||
from webnotes.utils import getdate
|
||||
from webnotes.model.code import get_obj
|
||||
|
||||
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 <b>fiscal year(s)</b> 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)
|
||||
|
||||
@webnotes.whitelist()
|
||||
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"
|
||||
}""")
|
||||
49
home/page/dashboard/dashboard.txt
Normal file
49
home/page/dashboard/dashboard.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
# Page, dashboard
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2011-08-25 16:22:44',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-08-25 16:22:54',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Page
|
||||
{
|
||||
'category': 'Standard',
|
||||
'doctype': 'Page',
|
||||
'module': 'Home',
|
||||
'name': '__common__',
|
||||
'page_name': 'Dashboard',
|
||||
'standard': 'Yes'
|
||||
},
|
||||
|
||||
# These values are common for all Page Role
|
||||
{
|
||||
'doctype': 'Page Role',
|
||||
'name': '__common__',
|
||||
'parent': 'dashboard',
|
||||
'parentfield': 'roles',
|
||||
'parenttype': 'Page'
|
||||
},
|
||||
|
||||
# Page, dashboard
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'name': 'dashboard'
|
||||
},
|
||||
|
||||
# Page Role
|
||||
{
|
||||
'doctype': 'Page Role',
|
||||
'role': 'System Manager'
|
||||
},
|
||||
|
||||
# Page Role
|
||||
{
|
||||
'doctype': 'Page Role',
|
||||
'role': 'Accounts Manager'
|
||||
}
|
||||
]
|
||||
1
home/page/desktop/__init__.py
Normal file
1
home/page/desktop/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
119
home/page/desktop/desktop.css
Normal file
119
home/page/desktop/desktop.css
Normal file
@@ -0,0 +1,119 @@
|
||||
/* Sprite CSS */
|
||||
.sprite-account{ background-position: 0 0; width: 32px; height: 40px; }
|
||||
.sprite-buying{ background-position: 0 -90px; width: 40px; height: 40px; }
|
||||
.sprite-calendar{ background-position: 0 -180px; width: 35px; height: 40px; }
|
||||
.sprite-dashboard{ background-position: 0 -270px; width: 40px; height: 29px; }
|
||||
.sprite-feed{ background-position: 0 -349px; width: 32px; height: 40px; }
|
||||
.sprite-hr{ background-position: 0 -439px; width: 40px; height: 32px; }
|
||||
.sprite-kb{ background-position: 0 -521px; width: 24px; height: 39px; }
|
||||
.sprite-messages{ background-position: 0 -610px; width: 40px; height: 26px; }
|
||||
.sprite-production{ background-position: 0 -686px; width: 40px; height: 33px; }
|
||||
.sprite-project{ background-position: 0 -769px; width: 40px; height: 22px; }
|
||||
.sprite-report{ background-position: 0 -841px; width: 29px; height: 40px; }
|
||||
.sprite-selling{ background-position: 0 -931px; width: 34px; height: 40px; }
|
||||
.sprite-setting{ background-position: 0 -1021px; width: 37px; height: 40px; }
|
||||
.sprite-stock{ background-position: 0 -1111px; width: 34px; height: 39px; }
|
||||
.sprite-support{ background-position: 0 -1200px; width: 40px; height: 40px; }
|
||||
.sprite-todo{ background-position: 0 -1290px; width: 40px; height: 34px; }
|
||||
.sprite-website{ background-position: 0 -1374px; width: 40px; height: 40px; }
|
||||
|
||||
.sprite-image { background-image: url("images/sprite-desktop.png"); }
|
||||
|
||||
|
||||
.sprite-account{ margin-top: 8px; margin-left: 12px; }
|
||||
.sprite-selling{ margin-top: 8px; margin-left: 12px; }
|
||||
.sprite-stock{ margin-top: 8px; margin-left: 8px; }
|
||||
.sprite-buying{ margin-top: 8px; margin-left: 8px; }
|
||||
.sprite-support{ margin-top: 8px; margin-left: 8px; }
|
||||
.sprite-hr{ margin-top: 12px; margin-left: 8px; }
|
||||
.sprite-project{ margin-top: 16px; margin-left: 8px; }
|
||||
.sprite-production{ margin-top: 10px; margin-left: 8px; }
|
||||
.sprite-website{ margin-top: 8px; margin-left: 8px; }
|
||||
.sprite-setting{ margin-top: 8px; margin-left: 8px; }
|
||||
.sprite-dashboard{ margin-top: 14px; margin-left: 8px; }
|
||||
.sprite-report{ margin-top: 8px; margin-left: 14px; }
|
||||
|
||||
.sprite-messages{ margin-top: 14px; margin-left: 8px; }
|
||||
.sprite-todo{ margin-top: 10px; margin-left: 10px; }
|
||||
.sprite-calendar{ margin-top: 8px; margin-left: 10px; }
|
||||
.sprite-kb{ margin-top: 8px; margin-left: 16px; }
|
||||
.sprite-feed{ margin-top: 8px; margin-left: 14px; }
|
||||
|
||||
.case-border {
|
||||
border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border: 4px solid white;
|
||||
box-shadow: 0 0 4px 1px black;
|
||||
-moz-box-shadow: 0 0 4px 1px black;
|
||||
-webkit-box-shadow: 0 0 4px 1px black;
|
||||
-o-box-shadow: 0 0 4px 1px black;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.case-wrapper {
|
||||
margin: 24px;
|
||||
float: left;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.case-label {
|
||||
color: white;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
text-shadow: 1px 1px 2px #000, 1px 1px 2px #000, 1px 1px 2px #000, 0px 0px 2px #000;
|
||||
}
|
||||
|
||||
/* Hover and click effects */
|
||||
.case-border:hover, .circle:hover, .hover-effect {
|
||||
box-shadow: 0 0 2px 0px black, 0 0 4px 1px white !important;
|
||||
-moz-box-shadow: 0 0 2px 0px black, 0 0 4px 1px white !important;
|
||||
-webkit-box-shadow: 0 0 2px 0px black, 0 0 4px 1px white !important;
|
||||
-o-box-shadow: 0 0 2px 0px black, 0 0 10px 1px white !important;
|
||||
}
|
||||
|
||||
.case-border:active, .case-border:focus, .case-border-click {
|
||||
transform: scale(0.98, 0.98);
|
||||
-ms-transform: scale(0.98, 0.98); /* IE 9 */
|
||||
-webkit-transform: scale(0.98, 0.98); /* Safari and Chrome */
|
||||
-o-transform: scale(0.98, 0.98); /* Opera */
|
||||
-moz-transform: scale(0.98, 0.98); /* Firefox */
|
||||
}
|
||||
|
||||
.circle:active, .circle:focus, .circle-click {
|
||||
transform: scale(1, 1);
|
||||
-ms-transform: scale(1, 1); /* IE 9 */
|
||||
-webkit-transform: scale(1, 1); /* Safari and Chrome */
|
||||
-o-transform: scale(1, 1); /* Opera */
|
||||
-moz-transform: scale(1, 1); /* Firefox */
|
||||
}
|
||||
|
||||
.circle {
|
||||
border-radius: 30px;
|
||||
-moz-border-radius: 30px;
|
||||
-webkit-border-radius: 30px;
|
||||
height: 15px;
|
||||
line-height: 12px;
|
||||
min-width: 15px;
|
||||
background: #B00D07;
|
||||
padding: 3px;
|
||||
float: right;
|
||||
margin-top: -74px;
|
||||
margin-right: 10px;
|
||||
border: 2px solid white;
|
||||
box-shadow: 0 0 4px 1px black;
|
||||
-moz-box-shadow: 0 0 4px 1px black;
|
||||
-webkit-box-shadow: 0 0 4px 1px black;
|
||||
-o-box-shadow: 0 0 4px 1px black;
|
||||
}
|
||||
|
||||
.circle-text {
|
||||
color: white;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
6
home/page/desktop/desktop.html
Normal file
6
home/page/desktop/desktop.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<div style="min-height: 500px; background: None; text-align: center;
|
||||
margin: 0px auto;">
|
||||
<div id="icon-grid">
|
||||
</div>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
139
home/page/desktop/desktop.js
Normal file
139
home/page/desktop/desktop.js
Normal file
@@ -0,0 +1,139 @@
|
||||
wn.provide('erpnext.desktop');
|
||||
|
||||
erpnext.desktop.gradient = "<style>\
|
||||
.case-%(name)s {\
|
||||
background: %(start)s; /* Old browsers */\
|
||||
background: -moz-radial-gradient(center, ellipse cover, %(start)s 0%, %(middle)s 44%, %(end)s 100%); /* FF3.6+ */\
|
||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,%(start)s), color-stop(44%,%(middle)s), color-stop(100%,%(end)s)); /* Chrome,Safari4+ */\
|
||||
background: -webkit-radial-gradient(center, ellipse cover, %(start)s 0%,%(middle)s 44%,%(end)s 100%); /* Chrome10+,Safari5.1+ */\
|
||||
background: -o-radial-gradient(center, ellipse cover, %(start)s 0%,%(middle)s 44%,%(end)s 100%); /* Opera 12+ */\
|
||||
background: -ms-radial-gradient(center, ellipse cover, %(start)s 0%,%(middle)s 44%,%(end)s 100%); /* IE10+ */\
|
||||
background: radial-gradient(center, ellipse cover, %(start)s 0%,%(middle)s 44%,%(end)s 100%); /* W3C */\
|
||||
}\
|
||||
</style>"
|
||||
|
||||
erpnext.desktop.refresh = function() {
|
||||
erpnext.desktop.add_classes();
|
||||
erpnext.desktop.render();
|
||||
}
|
||||
|
||||
erpnext.desktop.add_classes = function() {
|
||||
var classes = [
|
||||
{ name: 'red', start: '#A90329', middle: '#8F0222', end: '#6D0019' },
|
||||
{ name: 'brown', start: '#723e02', middle: '#633501', end: '#4a2700' },
|
||||
{ name: 'green', start: '#4b5602', middle: '#3f4901', end: '#313800' },
|
||||
{ name: 'blue', start: '#026584', middle: '#025770', end: '#004256' },
|
||||
{ name: 'yellow', start: '#be7902', middle: '#a66a02', end: '#865500' },
|
||||
{ name: 'purple', start: '#4d017d', middle: '#410169', end: '#310050' },
|
||||
{ name: 'ocean', start: '#02a47e', middle: '#018d6c', end: '#006a51' },
|
||||
{ name: 'pink', start: '#a40281', middle: '#8d016e', end: '#6a0053' },
|
||||
{ name: 'grey', start: '#545454', middle: '#484848', end: '#363636' },
|
||||
{ name: 'dark-red', start: '#68021a', middle: '#590116', end: '#440010' },
|
||||
{ name: 'leaf-green', start: '#b0a400', middle: '#968c00', end: '#726a00' },
|
||||
//{ name: 'dark-blue', start: '#023bae', middle: '#013295', end: '#002672' },
|
||||
{ name: 'bright-green', start: '#03ad1f', middle: '#02941a', end: '#007213' },
|
||||
{ name: 'bright-yellow', start: '#ffd65e', middle: '#febf04', end: '#ed9017' },
|
||||
{ name: 'peacock', start: '#026584', middle: '#026584', end: '#322476' },
|
||||
{ name: 'violet', start: '#50448e', middle: '#473b7f', end: '#3a3169' },
|
||||
{ name: 'ultra-dark-green', start: '#014333', middle: '#01372b', end: '#002a20' },
|
||||
];
|
||||
$.each(classes, function(i, v) {
|
||||
$(repl(erpnext.desktop.gradient, v)).appendTo('head');
|
||||
});
|
||||
}
|
||||
|
||||
erpnext.desktop.render = function() {
|
||||
var icons = {
|
||||
'Accounts': { gradient: 'blue', sprite: 'account', label: 'Accounts'},
|
||||
'Selling': { gradient: 'green', sprite: 'selling', label: 'Selling'},
|
||||
'Stock': { gradient: 'yellow', sprite: 'stock', label: 'Stock'},
|
||||
'Buying': { gradient: 'red', sprite: 'buying', label: 'Buying'},
|
||||
'Support': { gradient: 'purple', sprite: 'support', label: 'Support'},
|
||||
'HR': { gradient: 'ocean', sprite: 'hr', label: 'Human<br />Resources'},
|
||||
'Projects': { gradient: 'violet', sprite: 'project', label: 'Projects'},
|
||||
'Production': { gradient: 'dark-red', sprite: 'production', label: 'Production'},
|
||||
'Website': { gradient: 'leaf-green', sprite: 'website', label: 'Website'},
|
||||
'Activity': { gradient: 'brown', sprite: 'feed', label: 'Activity'},
|
||||
'Setup': { gradient: 'grey', sprite: 'setting', label: 'Setup'},
|
||||
'Dashboard': { gradient: 'bright-green', sprite: 'dashboard', label: 'Dashboard'},
|
||||
'To Do': { gradient: 'bright-yellow', sprite: 'todo', label: 'To Do'},
|
||||
'Messages': { gradient: 'pink', sprite: 'messages', label: 'Messages'},
|
||||
'Calendar': { gradient: 'peacock', sprite: 'calendar', label: 'Calendar'},
|
||||
'Knowledge Base': { gradient: 'ultra-dark-green', sprite: 'kb', label: 'Knowledge<br />Base'}
|
||||
}
|
||||
|
||||
|
||||
var add_icon = function(m) {
|
||||
var icon = icons[m];
|
||||
icon.link = erpnext.modules[m];
|
||||
$('#icon-grid').append(repl('\
|
||||
<div id="%(sprite)s" class="case-wrapper"><a href="#!%(link)s">\
|
||||
<div class="case-border case-%(gradient)s">\
|
||||
<div class="sprite-image sprite-%(sprite)s"></div>\
|
||||
</div></a>\
|
||||
<div class="case-label">%(label)s</div>\
|
||||
</div>', icon));
|
||||
}
|
||||
|
||||
// setup
|
||||
|
||||
for(var i in wn.boot.modules_list) {
|
||||
var m = wn.boot.modules_list[i];
|
||||
if(!in_list(['Setup', 'Dashboard'], m) && wn.boot.profile.allow_modules.indexOf(m)!=-1)
|
||||
add_icon(m);
|
||||
}
|
||||
|
||||
if(user_roles.indexOf('Accounts Manager')!=-1)
|
||||
add_icon('Dashboard')
|
||||
|
||||
if(user_roles.indexOf('System Manager')!=-1)
|
||||
add_icon('Setup')
|
||||
|
||||
// apps
|
||||
erpnext.desktop.show_pending_notifications();
|
||||
|
||||
}
|
||||
|
||||
erpnext.desktop.show_pending_notifications = function() {
|
||||
var add_circle = function(str_module, id, title) {
|
||||
var module = $('#'+str_module);
|
||||
module.find('a:first').append(
|
||||
repl('<div id="%(id)s" class="circle" title="%(title)s" style="display: None">\
|
||||
<span class="circle-text"></span>\
|
||||
</div>', {id: id, title: title}));
|
||||
|
||||
var case_border = module.find('.case-border');
|
||||
var circle = module.find('.circle');
|
||||
|
||||
var add_hover_and_click = function(primary, secondary, hover_class, click_class) {
|
||||
primary
|
||||
.hover(
|
||||
function() { secondary.addClass(hover_class); },
|
||||
function() { secondary.removeClass(hover_class); })
|
||||
.mousedown(function() { secondary.addClass(click_class); })
|
||||
.mouseup(function() { secondary.removeClass(click_class); })
|
||||
.focusin(function() { $(this).mousedown(); })
|
||||
.focusout(function() { $(this).mouseup(); })
|
||||
}
|
||||
|
||||
add_hover_and_click(case_border, circle, 'hover-effect', 'circle-click');
|
||||
add_hover_and_click(circle, case_border, 'hover-effect', 'case-border-click');
|
||||
|
||||
}
|
||||
|
||||
add_circle('messages', 'unread_messages', 'Unread Messages');
|
||||
add_circle('support', 'open_support_tickets', 'Open Support Tickets');
|
||||
add_circle('todo', 'things_todo', 'Things To Do');
|
||||
add_circle('calendar', 'todays_events', 'Todays Events');
|
||||
add_circle('project', 'open_tasks', 'Open Tasks');
|
||||
add_circle('kb', 'unanswered_questions', 'Unanswered Questions');
|
||||
|
||||
erpnext.update_messages();
|
||||
|
||||
}
|
||||
|
||||
pscript.onload_desktop = function() {
|
||||
// load desktop
|
||||
erpnext.desktop.refresh();
|
||||
}
|
||||
|
||||
28
home/page/desktop/desktop.txt
Normal file
28
home/page/desktop/desktop.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
# Page, desktop
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-02-24 11:37:43',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-02-24 11:37:43',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Page
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'module': u'Home',
|
||||
'name': '__common__',
|
||||
'page_name': u'desktop',
|
||||
'standard': u'Yes',
|
||||
'title': u'Desktop'
|
||||
},
|
||||
|
||||
# Page, desktop
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'name': u'desktop'
|
||||
}
|
||||
]
|
||||
1
home/page/profile_settings/__init__.py
Normal file
1
home/page/profile_settings/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
5
home/page/profile_settings/profile_settings.html
Normal file
5
home/page/profile_settings/profile_settings.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<div class="layout-wrapper layout-wrapper-appframe">
|
||||
<div class="layout-appframe"></div>
|
||||
<div class="layout-main">
|
||||
</div>
|
||||
</div>
|
||||
149
home/page/profile_settings/profile_settings.js
Normal file
149
home/page/profile_settings/profile_settings.js
Normal file
@@ -0,0 +1,149 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pscript['onload_profile-settings'] = function() {
|
||||
var wrapper = wn.pages['profile-settings'];
|
||||
pscript.myprofile = new MyProfile(wrapper)
|
||||
}
|
||||
|
||||
MyProfile = function(wrapper) {
|
||||
this.wrapper = wrapper;
|
||||
var me = this;
|
||||
|
||||
this.make = function() {
|
||||
this.wrapper.appframe = new wn.ui.AppFrame($(this.wrapper).find('.layout-appframe'), 'Profile Settings');
|
||||
this.wrapper.appframe.add_button('Change Password', this.change_password);
|
||||
this.wrapper.appframe.add_button('Change Background', this.change_background);
|
||||
|
||||
this.tab = make_table($a($(this.wrapper).find('.layout-main').get(0), 'div', '', {marginTop:'19px'}),
|
||||
1, 2, '90%', ['50%', '50%'], {padding:'11px'})
|
||||
this.img = $a($td(this.tab, 0, 0), 'img', '', {width: '120px', maxHeight:'200px'});
|
||||
this.img.src = wn.user_info(user).image;
|
||||
|
||||
$btn($a($td(this.tab, 0, 0), 'div', '', {marginTop:'11px'}), 'Change Image', this.change_image);
|
||||
|
||||
this.make_form();
|
||||
this.load_details();
|
||||
}
|
||||
|
||||
this.load_details = function() {
|
||||
$c_page('home','profile_settings','get_user_details','',function(r, rt) {
|
||||
me.form.set_values(r.message);
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
// form
|
||||
//
|
||||
this.make_form = function() {
|
||||
var div = $a($td(this.tab, 0, 1), 'div');
|
||||
this.form = new wn.widgets.FieldGroup()
|
||||
this.form.make_fields(div, [
|
||||
{fieldname:'first_name', fieldtype:'Data',label:'First Name',reqd:1},
|
||||
{fieldname:'last_name', fieldtype:'Data',label:'Last Name'},
|
||||
{fieldname:'bio', fieldtype:'Text',label:'Bio'},
|
||||
{fieldname:'update', fieldtype:'Button',label:'Update'}
|
||||
]);
|
||||
|
||||
this.form.fields_dict.update.input.onclick = function() {
|
||||
var v = me.form.get_values();
|
||||
if(v) {
|
||||
this.set_working();
|
||||
var btn = this;
|
||||
$c_page('home','profile_settings','set_user_details',v,function(r, rt) {
|
||||
btn.done_working();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// change password
|
||||
//
|
||||
this.change_password = function() {
|
||||
var d = new wn.widgets.Dialog({
|
||||
title:'Change Password',
|
||||
width: 400,
|
||||
fields: [
|
||||
{fieldname:'old_password', fieldtype:'Password', label:'Old Password', reqd:1 },
|
||||
{fieldname:'new_password', fieldtype:'Password', label:'New Password', reqd:1 },
|
||||
{fieldname:'new_password1', fieldtype:'Password', label:'Re-type New Password', reqd:1 },
|
||||
{fieldname:'change', fieldtype:'Button', label:'Change'}
|
||||
]
|
||||
})
|
||||
d.make();
|
||||
d.fields_dict.change.input.onclick = function() {
|
||||
var v = d.get_values();
|
||||
if(v) {
|
||||
if(v.new_password != v.new_password1) {
|
||||
msgprint('Passwords must match'); return;
|
||||
}
|
||||
this.set_working();
|
||||
$c_page('home','profile_settings','change_password',v,function(r,rt) {
|
||||
if(!r.message && r.exc) { msgprint(r.exc); return; }
|
||||
d.hide();
|
||||
})
|
||||
}
|
||||
}
|
||||
d.show();
|
||||
}
|
||||
|
||||
//
|
||||
// change image
|
||||
//
|
||||
|
||||
this.change_image = function() {
|
||||
var d = new wn.widgets.Dialog({
|
||||
title: 'Set your Profile'
|
||||
});
|
||||
|
||||
wn.upload.make({
|
||||
parent: d.body,
|
||||
args: {
|
||||
method: 'home.page.profile_settings.profile_settings.set_user_image'
|
||||
},
|
||||
callback: function(fid) {
|
||||
if(fid) {
|
||||
d.hide();
|
||||
wn.boot.user_info[user].image = 'files/' + fid;
|
||||
pscript.myprofile.img.src = 'files/' + fid;
|
||||
}
|
||||
}
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
|
||||
this.change_background = function() {
|
||||
var d = new wn.widgets.Dialog({
|
||||
title: 'Set Background Image'
|
||||
})
|
||||
|
||||
wn.upload.make({
|
||||
parent: d.body,
|
||||
args: {
|
||||
method: 'home.page.profile_settings.profile_settings.set_user_background'
|
||||
},
|
||||
callback: function(fid) {
|
||||
if(fid) {
|
||||
d.hide();
|
||||
erpnext.set_user_background(fid);
|
||||
}
|
||||
}
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
this.make();
|
||||
}
|
||||
112
home/page/profile_settings/profile_settings.py
Normal file
112
home/page/profile_settings/profile_settings.py
Normal file
@@ -0,0 +1,112 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import load_json, cint, nowdate
|
||||
|
||||
|
||||
def check_demo():
|
||||
demo_user = 'demo@webnotestech.com'
|
||||
if webnotes.session['user']==demo_user:
|
||||
webnotes.msgprint("Can't change in demo", raise_exception=1)
|
||||
|
||||
|
||||
@webnotes.whitelist()
|
||||
def change_password(arg):
|
||||
"""
|
||||
Change password
|
||||
"""
|
||||
check_demo()
|
||||
arg = load_json(arg)
|
||||
|
||||
if not webnotes.conn.sql("""select * from `__Auth` where `user`=%s
|
||||
and password=password(%s)""",
|
||||
(webnotes.session["user"], arg["old_password"])):
|
||||
webnotes.msgprint('Old password is not correct', raise_exception=1)
|
||||
|
||||
webnotes.conn.sql("""update `__Auth` set password=password(%s)
|
||||
where `user`=%s""", (arg["new_password"], webnotes.session["user"]))
|
||||
|
||||
webnotes.msgprint('Password Updated');
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_user_details(arg=None):
|
||||
"""
|
||||
Returns user first name, last name and bio
|
||||
"""
|
||||
return webnotes.conn.sql("select first_name, last_name, bio from tabProfile where name=%s", webnotes.user.name, as_dict=1)[0]
|
||||
|
||||
@webnotes.whitelist()
|
||||
def set_user_details(arg=None):
|
||||
"""
|
||||
updates user details given in argument
|
||||
"""
|
||||
check_demo()
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
p = Document('Profile', webnotes.user.name)
|
||||
arg_dict = load_json(arg)
|
||||
if not 'bio' in arg_dict: arg_dict['bio'] = None
|
||||
if not 'last_name' in arg_dict: arg_dict['last_name'] = None
|
||||
p.fields.update(arg_dict)
|
||||
p.save()
|
||||
webnotes.msgprint('Updated')
|
||||
|
||||
@webnotes.whitelist()
|
||||
def set_user_image():
|
||||
"""
|
||||
Set uploaded image as user image
|
||||
"""
|
||||
check_demo()
|
||||
from webnotes.utils.file_manager import add_file_list, remove_file, save_uploaded
|
||||
user = webnotes.session['user']
|
||||
|
||||
fid, fname = save_uploaded()
|
||||
|
||||
# remove old file
|
||||
old_image = webnotes.conn.get_value('Profile', user, 'user_image')
|
||||
if old_image:
|
||||
remove_file('Profile', user, old_image)
|
||||
|
||||
# add new file
|
||||
add_file_list('Profile', user, fname, fid)
|
||||
webnotes.conn.set_value('Profile', user, 'user_image', fid)
|
||||
|
||||
return fid
|
||||
|
||||
@webnotes.whitelist()
|
||||
def set_user_background():
|
||||
"""
|
||||
Set uploaded image as user image
|
||||
"""
|
||||
check_demo()
|
||||
from webnotes.utils.file_manager import add_file_list, remove_file, save_uploaded
|
||||
user = webnotes.session['user']
|
||||
|
||||
fid, fname = save_uploaded()
|
||||
|
||||
# remove old file
|
||||
old_image = webnotes.conn.get_value('Profile', user, 'background_image')
|
||||
if old_image:
|
||||
remove_file('Profile', user, old_image)
|
||||
|
||||
# add new file
|
||||
add_file_list('Profile', user, fname, fid)
|
||||
webnotes.conn.set_value('Profile', user, 'background_image', fid)
|
||||
|
||||
return fid
|
||||
27
home/page/profile_settings/profile_settings.txt
Normal file
27
home/page/profile_settings/profile_settings.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
# Page, profile-settings
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2011-04-18 10:19:10',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-04-13 12:08:59',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Page
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'module': 'Home',
|
||||
'name': '__common__',
|
||||
'page_name': 'Profile Settings',
|
||||
'standard': 'Yes'
|
||||
},
|
||||
|
||||
# Page, profile-settings
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'name': 'profile-settings'
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user