diff --git a/.gitignore b/.gitignore index e9e476b0a9e..28fcc8833aa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ *.comp.js .DS_Store server_tools +services +user_files patch.log lib versions-local.db diff --git a/erpnext/selling/page/customers/__init__.py b/blank.html similarity index 100% rename from erpnext/selling/page/customers/__init__.py rename to blank.html diff --git a/config/conf.py b/config/conf.py deleted file mode 100644 index 1cf35e21cb8..00000000000 --- a/config/conf.py +++ /dev/null @@ -1,7 +0,0 @@ -index_path = '/' - -include_paths = [ - 'erpnext', - 'lib/py', - 'lib/py/legacy' -] \ No newline at end of file diff --git a/erpnext/accounts/__init__.py b/erpnext/accounts/__init__.py index c3c50052e47..65d023130e6 100644 --- a/erpnext/accounts/__init__.py +++ b/erpnext/accounts/__init__.py @@ -2,6 +2,7 @@ import webnotes from webnotes.utils import flt from webnotes.model.code import get_obj +@webnotes.whitelist() def get_default_bank_account(): """ Get default bank account for a company @@ -14,7 +15,7 @@ def get_default_bank_account(): if res: return res[0][0] - +@webnotes.whitelist() def get_new_jv_details(): """ Get details which will help create new jv on sales/purchase return diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js index 51cacdaf367..b07bb9c3870 100644 --- a/erpnext/accounts/doctype/account/account.js +++ b/erpnext/accounts/doctype/account/account.js @@ -15,7 +15,7 @@ cur_frm.cscript.account_type = function(doc, cdt, cdn) { cur_frm.cscript.onload = function(doc, cdt, cdn) { cur_frm.cscript.account_type(doc, cdt, cdn); // hide India specific fields - var cp = locals['Control Panel']['Control Panel']; + var cp = wn.control_panel; if(cp.country == 'India') unhide_field(['pan_number', 'tds_applicable', 'tds_details', 'TDS']); else diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.js b/erpnext/accounts/doctype/journal_voucher/journal_voucher.js index b63f448430c..699d17bbd7b 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.js +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.js @@ -1,6 +1,6 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) { - var cp = locals['Control Panel']['Control Panel']; - + var cp = wn.control_panel; + if (!doc.voucher_date) doc.voucher_date = dateutil.obj_to_str(new Date()); if(cp.country == 'India') { @@ -11,7 +11,6 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) { } cur_frm.cscript.load_defaults(doc, cdt, cdn); - } diff --git a/erpnext/accounts/doctype/payable_voucher/payable_voucher.js b/erpnext/accounts/doctype/payable_voucher/payable_voucher.js index 3bdeadddd88..d4ce9e40ee2 100644 --- a/erpnext/accounts/doctype/payable_voucher/payable_voucher.js +++ b/erpnext/accounts/doctype/payable_voucher/payable_voucher.js @@ -7,10 +7,10 @@ $import(Purchase Common) // On Load // -------- cur_frm.cscript.onload = function(doc,dt,dn) { - var cp = locals['Control Panel']['Control Panel']; - + var cp = wn.control_panel; + if(!doc.voucher_date) set_multiple(dt,dn,{voucher_date:get_today()}); - if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()}); + if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()}); if(cp.country == 'India') { unhide_field(['TDS','tds_applicable','tds_category','Get TDS','tax_code','rate','ded_amount','total_tds_on_voucher','tds_amount_on_advance']); diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js index c12c2fb3036..aa12ab88a4d 100644 --- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js +++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js @@ -73,7 +73,7 @@ cur_frm.cscript.hide_fields = function(doc, cdt, cdn) { } // India related fields - var cp = locals['Control Panel']['Control Panel']; + var cp = wn.control_panel; if (cp.country == 'India') unhide_field(['c_form_applicable', 'c_form_no']); else hide_field(['c_form_applicable', 'c_form_no']); diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py index 22294c583c3..d8eb7614659 100644 --- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py +++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py @@ -11,7 +11,8 @@ from webnotes.utils.scheduler import set_event, cancel_event, Scheduler in_transaction = webnotes.conn.in_transaction convert_to_lists = webnotes.conn.convert_to_lists - +session = webnotes.session + # ----------------------------------------------------------------------------------------- from utilities.transaction_base import TransactionBase diff --git a/erpnext/accounts/page/accounts_browser/accounts_browser.js b/erpnext/accounts/page/accounts_browser/accounts_browser.js index 61b36d2131d..13416e6a534 100644 --- a/erpnext/accounts/page/accounts_browser/accounts_browser.js +++ b/erpnext/accounts/page/accounts_browser/accounts_browser.js @@ -1,4 +1,5 @@ pscript['onload_Accounts Browser'] = function(){ + wn.require('lib/js/legacy/widgets/tree.js'); // if the user directly loads the page, ask to select the chart var parent = $i('ab_body'); parent.innerHTML = 'Please select your chart: ' @@ -124,7 +125,7 @@ pscript.make_ac_tree = function() { var imgsrc=null; var has_children = true; if(cl[i].group_or_ledger=='Ledger') { - var imgsrc = 'lib/images/icons/page.gif'; + var imgsrc = 'lib/images/icons/page.png'; has_children = false; } var t = tree.addNode(n, cl[i].account_name, imgsrc,tree.std_onclick, has_children ? tree.std_onexp : null); @@ -137,7 +138,7 @@ pscript.make_ac_tree = function() { var imgsrc=null; var has_children = true; if(cl[i].group_or_ledger=='Ledger') { - var imgsrc = 'lib/images/icons/page.gif'; + var imgsrc = 'lib/images/icons/page.png'; has_children = false; } var t = tree.addNode(n, cl[i].cost_center_name, imgsrc,tree.std_onclick, has_children ? tree.std_onexp : null); diff --git a/erpnext/accounts/page/financial_statements/financial_statements.html b/erpnext/accounts/page/financial_statements/financial_statements.html index 6e69bc29026..e6735facdc1 100644 --- a/erpnext/accounts/page/financial_statements/financial_statements.html +++ b/erpnext/accounts/page/financial_statements/financial_statements.html @@ -1,6 +1,5 @@
-
diff --git a/erpnext/erpnext_version.py b/erpnext/erpnext_version.py deleted file mode 100644 index 48e45d5d313..00000000000 --- a/erpnext/erpnext_version.py +++ /dev/null @@ -1,3 +0,0 @@ -# version info - -version='1.0.0' diff --git a/erpnext/home/__init__.py b/erpnext/home/__init__.py index 8969695aa12..75556e39370 100644 --- a/erpnext/home/__init__.py +++ b/erpnext/home/__init__.py @@ -31,26 +31,42 @@ feed_dict = { # 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'] + 'Support Ticket': ['[%(status)s] %(subject)s', '#000080'], + + # Website + 'Web Page': ['%(title)s', '#000080'], + 'Blog': ['%(title)s', '#000080'] } -def make_feed(doc, subject, color): +def make_feed(feedtype, doctype, name, owner, subject, color): "makes a new Feed record" #msgprint(subject) from webnotes.model.doc import Document - webnotes.conn.sql("delete from tabFeed where doc_type=%s and doc_name=%s", (doc.doctype, doc.name)) + from webnotes.utils import get_full_name + + 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.doc_type = doc.doctype - f.doc_name = doc.name + f.owner = owner + f.feed_type = feedtype + f.doc_type = doctype + f.doc_name = name f.subject = subject f.color = color - f.save(1) + f.full_name = get_full_name(owner) + f.save() def update_feed(doc, method=None): "adds a new feed" - if method=='validate': - return - subject, color = feed_dict.get(doc.doctype, [None, None]) - if subject: - subject = subject % doc.fields - make_feed(doc, subject, color) + if method=='on_update': + subject, color = feed_dict.get(doc.doctype, [None, None]) + if subject: + make_feed('', doc.doctype, doc.name, doc.owner, subject % doc.fields, color) diff --git a/erpnext/home/doctype/feed/feed.txt b/erpnext/home/doctype/feed/feed.txt index 5aa4f910e46..62d6633a0b4 100644 --- a/erpnext/home/doctype/feed/feed.txt +++ b/erpnext/home/doctype/feed/feed.txt @@ -3,71 +3,87 @@ # These values are common in all dictionaries { - 'creation': '2011-04-08 10:50:41', + 'creation': '2011-04-06 18:11:38', 'docstatus': 0, - 'modified': '2011-04-05 09:16:57', - 'modified_by': 'Administrator', - 'owner': 'Administrator' + 'modified': '2012-02-08 11:35:40', + 'modified_by': u'Administrator', + 'owner': u'Administrator' }, # These values are common for all DocType { - 'autoname': '_FEED.#####', - 'colour': 'White:FFF', + 'autoname': u'_FEED.#####', + 'colour': u'White:FFF', + 'default_print_format': u'Standard', 'doctype': 'DocType', - 'module': 'Home', + 'module': u'Home', 'name': '__common__', - 'section_style': 'Simple', + 'section_style': u'Simple', 'show_in_menu': 0, - 'version': 1 + 'version': 3 }, # These values are common for all DocField { - 'doctype': 'DocField', - 'fieldtype': 'Data', + 'doctype': u'DocField', 'name': '__common__', - 'parent': 'Feed', - 'parentfield': 'fields', - 'parenttype': 'DocType', + 'parent': u'Feed', + 'parentfield': u'fields', + 'parenttype': u'DocType', 'permlevel': 0 }, # DocType, Feed { 'doctype': 'DocType', - 'name': 'Feed' + 'name': u'Feed' }, # DocField { - 'doctype': 'DocField', - 'fieldname': 'doc_type', - 'idx': 1, - 'label': 'Doc Type' + 'doctype': u'DocField', + 'fieldname': u'feed_type', + 'fieldtype': u'Select', + 'label': u'Feed Type' }, # DocField { - 'doctype': 'DocField', - 'fieldname': 'doc_name', - 'idx': 2, - 'label': 'Doc Name' + 'doctype': u'DocField', + 'fieldname': u'doc_type', + 'fieldtype': u'Data', + 'label': u'Doc Type' }, # DocField { - 'doctype': 'DocField', - 'fieldname': 'subject', - 'idx': 3, - 'label': 'Subject' + 'doctype': u'DocField', + 'fieldname': u'doc_name', + 'fieldtype': u'Data', + 'label': u'Doc Name' }, # DocField { - 'doctype': 'DocField', - 'fieldname': 'color', - 'idx': 4, - 'label': 'Color' + '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' } ] \ No newline at end of file diff --git a/erpnext/home/doctype/home_control/home_control.py b/erpnext/home/doctype/home_control/home_control.py index ce15bfd57ac..9d821532cd1 100644 --- a/erpnext/home/doctype/home_control/home_control.py +++ b/erpnext/home/doctype/home_control/home_control.py @@ -197,7 +197,10 @@ class DocType: return count def get_todo_list(self): - return convert_to_lists(sql("select name, description, date, priority,checked from `tabToDo Item` where owner=%s order by field(priority,'High','Medium','Low') asc, date asc", session['user'])) + return sql("""select name, description, date, + priority, checked, reference_type, reference_name from `tabToDo Item` + where owner=%s order by field(priority,'High','Medium','Low') asc, date asc""", \ + session['user'], as_dict=1) def add_todo_item(self,args): args = json.loads(args) diff --git a/erpnext/home/page/dashboard/dashboard.js b/erpnext/home/page/dashboard/dashboard.js index aac42a3e3b8..e8f2992208d 100644 --- a/erpnext/home/page/dashboard/dashboard.js +++ b/erpnext/home/page/dashboard/dashboard.js @@ -1,6 +1,6 @@ pscript.onload_dashboard = function() { // load jqplot - $.scriptPath = 'js/' + wn.require('lib/css/jqpot.css'); wn.require('lib/js/legacy/jquery/jquery.jqplot.min.js'); wn.require('lib/js/legacy/jquery/jqplot-plugins/jqplot.barRenderer.js'); wn.require('lib/js/legacy/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js'); diff --git a/erpnext/home/page/dashboard/dashboard.py b/erpnext/home/page/dashboard/dashboard.py index c2378d3155e..e8f11fbc5cd 100644 --- a/erpnext/home/page/dashboard/dashboard.py +++ b/erpnext/home/page/dashboard/dashboard.py @@ -54,11 +54,12 @@ dashboards = [ } ] +import webnotes + 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') @@ -233,7 +234,7 @@ class DashboardWidget: elif opts['type']=='creation': return self.get_creation_trend(opts['doctype'], start, end) - +@webnotes.whitelist() def load_dashboard(args): """ Get dashboard based on diff --git a/erpnext/home/page/event_updates/complete_registration.js b/erpnext/home/page/event_updates/complete_registration.js new file mode 100644 index 00000000000..e7e05742211 --- /dev/null +++ b/erpnext/home/page/event_updates/complete_registration.js @@ -0,0 +1,108 @@ +// complete my company registration +// -------------------------------- +pscript.complete_registration = function(is_complete, profile) { + if(is_complete == 'No'){ + var d = new Dialog(400, 200, "Setup your Account"); + if(user != 'Administrator'){ + d.no_cancel(); // Hide close image + $('header').toggle(false); + } + + d.make_body([ + ['HTML', 'Your Profile Details', '

Your Profile Details

'], + ['Data', 'First Name'], + ['Data', 'Last Name'], + ['HTML', 'Company Details', '

Create your first company

'], + ['Data','Company Name','Example: Your Company LLC'], + ['Data','Company Abbreviation', 'Example: YC (all your acconts will have this as a suffix)'], + ['Select','Fiscal Year Start Date'], + ['Select','Default Currency'], + ['Button','Save'], + ]); + + // if company name is set, set the input value + // and disable it + if(wn.control_panel.company_name) { + d.widgets['Company Name'].value = wn.control_panel.company_name; + d.widgets['Company Name'].disabled = 1; + } + + if(profile && profile.length>0) { + if(profile[0].first_name && profile[0].first_name!='None') { + d.widgets['First Name'].value = profile[0].first_name; + } + + if(profile[0].last_name && profile[0].last_name!='None') { + d.widgets['Last Name'].value = profile[0].last_name; + } + } + + + //d.widgets['Save'].disabled = true; // disable Save button + pscript.make_dialog_field(d); + + // submit details + d.widgets['Save'].onclick = function() + { + d.widgets['Save'].set_working(); + + flag = pscript.validate_fields(d); + if(flag) + { + var args = [ + d.widgets['Company Name'].value, + d.widgets['Company Abbreviation'].value, + d.widgets['Fiscal Year Start Date'].value, + d.widgets['Default Currency'].value, + d.widgets['First Name'].value, + d.widgets['Last Name'].value + ]; + + $c_obj('Setup Control','setup_account',JSON.stringify(args),function(r, rt){ + sys_defaults = r.message; + user_fullname = r.message.user_fullname; + d.hide(); + $('header').toggle(true); + page_body.wntoolbar.set_user_name(); + }); + } else { + d.widgets['Save'].done_working(); + } + } + d.show(); + } +} + +// make dialog fields +// ------------------ +pscript.make_dialog_field = function(d) +{ + // fiscal year format + fisc_format = d.widgets['Fiscal Year Start Date']; + add_sel_options(fisc_format, ['', '1st Jan', '1st Apr', '1st Jul', '1st Oct']); + + // default currency + currency_list = ['', 'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BTN', 'BYR', 'BZD', 'CAD', 'CDF', 'CFA', 'CFP', 'CHF', 'CLP', 'CNY', 'COP', 'CRC', 'CUC', 'CZK', 'DJF', 'DKK', 'DOP', 'DZD', 'EEK', 'EGP', 'ERN', 'ETB', 'EUR', 'EURO', 'FJD', 'FKP', 'FMG', 'GBP', 'GEL', 'GHS', 'GIP', 'GMD', 'GNF', 'GQE', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'INR', 'IQD', 'IRR', 'ISK', 'JMD', 'JOD', 'JPY', 'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LTL', 'LVL', 'LYD', 'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRO', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZM', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NRs', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RMB', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SCR', 'SDG', 'SDR', 'SEK', 'SGD', 'SHP', 'SOS', 'SRD', 'STD', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TRY', 'TTD', 'TWD', 'TZS', 'UAE', 'UAH', 'UGX', 'USD', 'USh', 'UYU', 'UZS', 'VEB', 'VND', 'VUV', 'WST', 'XAF', 'XCD', 'XDR', 'XOF', 'XPF', 'YEN', 'YER', 'YTL', 'ZAR', 'ZMK', 'ZWR']; + currency = d.widgets['Default Currency']; + add_sel_options(currency, currency_list); +} + + +// validate fields +// --------------- +pscript.validate_fields = function(d) +{ + var lst = ['First Name', 'Company Name', 'Company Abbreviation', 'Fiscal Year Start Date', 'Default Currency']; + var msg = 'Please enter the following fields'; + var flag = 1; + for(var i=0; i%(reference_name)s', + det)) + } // if expired & open, then in red - if(!det[4] && dateutil.str_to_obj(det[2]) < new Date()) { + if(!det.checked && dateutil.str_to_obj(det.date) < new Date()) { $y(span,{color:'RED'}); - $a($td(tab, 0, 1), 'div', '', {fontSize:'10px', color:'#666'}, dateutil.str_to_user(det[2]) + ' (Overdue)'); + $a($td(tab, 0, 1), 'div', '', {fontSize:'10px', color:'#666'}, + dateutil.str_to_user(det.date) + ' (Overdue)'); } else { - $a($td(tab, 0, 1), 'div', '', {fontSize:'10px', color:'#666'}, dateutil.str_to_user(det[2])); + $a($td(tab, 0, 1), 'div', '', {fontSize:'10px', color:'#666'}, + dateutil.str_to_user(det.date)); } } @@ -371,10 +383,10 @@ HomeToDo.prototype.clear_dialog = function() { HomeToDo.prototype.set_dialog_values = function(det) { var d = this.widget.dialog; d.set_values({ - date: det[2], - priority: det[3], - description: det[1], - checked: det[4] + date: det.date, + priority: det.priority, + description: det.description, + checked: det.checked }); d.det = det; } @@ -389,8 +401,7 @@ HomeToDo.prototype.save = function(btn) { return; } - det.name = d.det ? d.det[0] : ''; - + det.name = d.det.name; var callback = function(r,rt) { btn.done_working(); me.widget.dialog.hide(); @@ -420,9 +431,6 @@ FeedList.prototype.make_head = function() { // head $a(this.head,'h1','', {display:'inline'}, 'Home'); - $a(this.head,'span','link_type', {marginLeft:'7px', fontSize:'11px'}, 'help', function() { - msgprint('What appears here? This is where you get updates of everything you are permitted to follow') - }) // refresh $a(this.head,'span','link_type', @@ -442,51 +450,35 @@ FeedList.prototype.run = function() { } FeedList.prototype.make_list = function() { - this.list_area = $a(this.wrapper,'div') - this.no_result = $a(this.wrapper, 'div','help_box',{display:'none'},'Nothing to show yet. Your feed will be updated as you start your activities') - - var l = new Listing('Feed List',1); var me = this; - - // style - l.colwidths = ['100%']; l.page_len = 20; - l.opts.cell_style = {padding:'0px'}; - l.opts.hide_rec_label = 1; + this.list_area = $a(this.wrapper,'div') - // build query - l.get_query = function(){ - this.query = repl('select \ - distinct t1.name, t1.doc_type, t1.doc_name, t1.subject, t1.modified_by, \ - concat(ifnull(t2.first_name,""), " ", ifnull(t2.last_name,"")), t1.modified, t1.color \ - from tabFeed t1, tabProfile t2, tabUserRole t3, tabDocPerm t4 \ + this.list = new wn.widgets.Listing({ + parent: this.list_area, + query: repl('select \ + distinct t1.name, t1.feed_type, t1.doc_type, t1.doc_name, t1.subject, t1.modified_by, \ + if(ifnull(t1.full_name,"")="", t1.owner, t1.full_name) as full_name, \ + t1.modified, t1.color \ + from tabFeed t1, tabUserRole t3, tabDocPerm t4 \ where t1.doc_type = t4.parent \ - and t2.name = t1.owner \ and t3.parent = "%(user)s" \ and t4.role = t3.role \ and ifnull(t4.`read`,0) = 1 \ - order by t1.modified desc', {user:user}) - this.query_max = '' - } - - // render list ui - l.show_cell = function(cell,ri,ci,d){ me.render_feed(cell,ri,ci,d); } - - // onrun - l.onrun = function(){ $(me.wrapper).fadeIn(); if(me.after_run) me.after_run(); } - - // make - l.make(this.list_area); - $dh(l.btn_area); - - this.list = l; + order by t1.modified desc', {user:user}), + no_result_message: 'Nothing to show yet. Your feed will be updated as you start your activities', + render_row: function(parent, data) { + me.render_feed(parent, data) + }, + onrun: function() { + $(me.wrapper).fadeIn(); + if(me.after_run) me.after_run(); + }, + hide_refresh: true + }); } -FeedList.prototype.after_run = function() { - this.list.has_data() ? $dh(this.no_result) : $ds(this.no_result) -} - -FeedList.prototype.render_feed = function(cell,ri,ci,d) { - new FeedItem(cell, d[ri], this); +FeedList.prototype.render_feed = function(parent, data) { + new FeedItem(parent, data, this); } // Item @@ -502,13 +494,11 @@ FeedItem = function(cell, det, feedlist) { this.tab = make_table(this.wrapper, 1, 2, '100%', [(100/7)+'%', (600/7)+'%']); $y(this.tab,{tableLayout:'fixed'}) - // image $y($td(this.tab,0,0),{textAlign:'right',paddingRight:'4px'}); // text this.text_area = $a($td(this.tab,0,1), 'div'); - this.render_references(this.text_area, det); - + this.render_references(this.text_area, det); this.render_tag(det); // add day separator @@ -520,12 +510,12 @@ FeedItem = function(cell, det, feedlist) { FeedItem.prototype.add_day_sep = function(det) { var me = this; - var prev_date = det[6].split(' ')[0]; + var prev_date = det.modified.split(' ')[0]; var make_div = function() { var div = $a(me.head, 'div', '', {borderBottom:'1px solid #888', margin:'8px 0px', padding:'2px 0px', color:'#888', fontSize:'11px'}); - div.innerHTML = comment_when(det[6], 1); + div.innerHTML = comment_when(det.modified, 1); // today? if(prev_date==get_today()) { @@ -544,35 +534,47 @@ FeedItem.prototype.add_day_sep = function(det) { // ------------------------------------------------- FeedItem.prototype.render_tag = function(det) { + // type is the name tag = $a($td(this.tab,0,0), 'div', '', - {color:'#FFF', padding:'3px', textAlign:'right', fontSize:'11px', whiteSpace:'nowrap', overflow:'hidden', cursor:'pointer'}); + {color:'#FFF', padding:'3px', textAlign:'right', fontSize:'11px', + whiteSpace:'nowrap', overflow:'hidden', cursor:'pointer'}); $br(tag,'3px'); - $y(tag, {backgroundColor:(det[7] ? det[7] : '#273')}); - tag.innerHTML = get_doctype_label(det[1]); - tag.dt = det[1] - tag.onclick = function() { loaddocbrowser(this.dt); } + $y(tag, {backgroundColor:(det.color || '#273')}); + + // tag label + tag.innerHTML = det.feed_type || get_doctype_label(det.doc_type); + + // not comment / label + if(!det.feed_type) { + tag.dt = det.doc_type; + tag.onclick = function() { loaddocbrowser(this.dt); } + } } FeedItem.prototype.render_references = function(div, det) { // name - div.tab = make_table(div, 1, 2, '100%', [null, '15%']) - //div.innerHTML = '' + (strip(det[11]) ? det[11] : det[2]) + ' (' + cint(det[12]) + '): has ' + det[7] + ' '; - - var dt = det[1]; var dn = det[2] + div.tab = make_table(div, 1, 2, '100%', [null, '15%']) + var dt = det.doc_type; var dn = det.doc_name // link - var allow = in_list(profile.can_read, dt); - var span = $a($td(div.tab,0,0), 'span', (allow ? 'link_type': ''), null, det[2]); - span.dt = dt; span.dn = dn; - if(allow) span.onclick = function() { loaddoc(this.dt, this.dn); } + if(det.feed_type=='Login') { + // nothing - no link + } else { + var allow = in_list(profile.can_read, dt); + var span = $a($td(div.tab,0,0), 'span', (allow ? 'link_type': ''), null, + det.doc_name); + span.dt = dt; span.dn = dn; + if(allow) span.onclick = function() { loaddoc(this.dt, this.dn); } + } // subject - if(det[3]) { - $a($td(div.tab,0,0), 'span', '', {marginLeft:'7px', color:'#444'}, det[3]); + if(det.subject) { + $a($td(div.tab,0,0), 'span', '', {marginLeft:'7px', color:'#444'}, det.subject); } // by - $y($td(div.tab,0,1), {fontSize:'11px'}).innerHTML = (strip(det[5]) ? det[5] : det[4]); + $y($td(div.tab,0,1), {fontSize:'11px'}).innerHTML = + (strip(det.full_name) ? det.full_name : det.modified_by); } HomeStatusBar = function() { @@ -583,11 +585,6 @@ HomeStatusBar = function() { this.render = function(r) { this.wrapper.innerHTML = ''; - this.profile_settings = $a($a(this.wrapper, 'p'), 'span', 'link_type', {fontWeight:'bold'}); - this.profile_settings.innerHTML = user_fullname + ' (Profile Settings)'; - this.profile_settings.id = "user_fullname"; - this.profile_settings.onclick = function() { loadpage('profile-settings'); } - this.span = $a($a(this.wrapper, 'p'), 'span', 'link_type', {fontWeight:'bold'}); this.span.onclick = function() { loadpage('My Company') } @@ -615,6 +612,7 @@ pscript.home_make_status = function() { // complete registration if(in_list(user_roles,'System Manager')) { + wn.require("erpnext/home/page/event_updates/complete_registration.js"); pscript.complete_registration(r.message.registration_complete, r.message.profile); } @@ -626,114 +624,6 @@ pscript.home_make_status = function() { ); } -// complete my company registration -// -------------------------------- -pscript.complete_registration = function(is_complete, profile) { - if(is_complete == 'No'){ - var d = new Dialog(400, 200, "Setup your Account"); - if(user != 'Administrator'){ - d.no_cancel(); // Hide close image - $dh(page_body.wntoolbar.wrapper); - } - - d.make_body([ - ['HTML', 'Your Profile Details', '

Your Profile Details

'], - ['Data', 'First Name'], - ['Data', 'Last Name'], - ['HTML', 'Company Details', '

Create your first company

'], - ['Data','Company Name','Example: Your Company LLC'], - ['Data','Company Abbreviation', 'Example: YC (all your acconts will have this as a suffix)'], - ['Select','Fiscal Year Start Date'], - ['Select','Default Currency'], - ['Button','Save'], - ]); - - // if company name is set, set the input value - // and disable it - if(locals['Control Panel']['Control Panel'].company_name) { - d.widgets['Company Name'].value = locals['Control Panel']['Control Panel'].company_name; - d.widgets['Company Name'].disabled = 1; - } - - if(profile && profile.length>0) { - if(profile[0].first_name && profile[0].first_name!='None') { - d.widgets['First Name'].value = profile[0].first_name; - } - - if(profile[0].last_name && profile[0].last_name!='None') { - d.widgets['Last Name'].value = profile[0].last_name; - } - } - - //d.widgets['Save'].disabled = true; // disable Save button - pscript.make_dialog_field(d); - - // submit details - d.widgets['Save'].onclick = function() - { - d.widgets['Save'].set_working(); - - flag = pscript.validate_fields(d); - if(flag) - { - var args = [ - d.widgets['Company Name'].value, - d.widgets['Company Abbreviation'].value, - d.widgets['Fiscal Year Start Date'].value, - d.widgets['Default Currency'].value, - d.widgets['First Name'].value, - d.widgets['Last Name'].value - ]; - - $c_obj('Setup Control','setup_account',JSON.stringify(args),function(r, rt){ - sys_defaults = r.message.sys_defaults; - user_fullname = r.message.user_fullname; - d.hide(); - $ds(page_body.wntoolbar.wrapper); - $('#user_fullname').html(user_fullname + " (Profile Settings)"); - }); - } else { - d.widgets['Save'].done_working(); - } - } - d.show(); - } -} - -// make dialog fields -// ------------------ -pscript.make_dialog_field = function(d) -{ - // fiscal year format - fisc_format = d.widgets['Fiscal Year Start Date']; - add_sel_options(fisc_format, ['', '1st Jan', '1st Apr', '1st Jul', '1st Oct']); - - // default currency - currency_list = ['', 'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BTN', 'BYR', 'BZD', 'CAD', 'CDF', 'CFA', 'CFP', 'CHF', 'CLP', 'CNY', 'COP', 'CRC', 'CUC', 'CZK', 'DJF', 'DKK', 'DOP', 'DZD', 'EEK', 'EGP', 'ERN', 'ETB', 'EUR', 'EURO', 'FJD', 'FKP', 'FMG', 'GBP', 'GEL', 'GHS', 'GIP', 'GMD', 'GNF', 'GQE', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'INR', 'IQD', 'IRR', 'ISK', 'JMD', 'JOD', 'JPY', 'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LTL', 'LVL', 'LYD', 'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRO', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZM', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NRs', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RMB', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SCR', 'SDG', 'SDR', 'SEK', 'SGD', 'SHP', 'SOS', 'SRD', 'STD', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TRY', 'TTD', 'TWD', 'TZS', 'UAE', 'UAH', 'UGX', 'USD', 'USh', 'UYU', 'UZS', 'VEB', 'VND', 'VUV', 'WST', 'XAF', 'XCD', 'XDR', 'XOF', 'XPF', 'YEN', 'YER', 'YTL', 'ZAR', 'ZMK', 'ZWR']; - currency = d.widgets['Default Currency']; - add_sel_options(currency, currency_list); -} - - -// validate fields -// --------------- -pscript.validate_fields = function(d) -{ - var lst = ['First Name', 'Company Name', 'Company Abbreviation', 'Fiscal Year Start Date', 'Default Currency']; - var msg = 'Please enter the following fields\n'; - var flag = 1; - for(var i=0; i +
 
+

Subscribe

+

+ + RSS Feed +

+
+
+ + \ No newline at end of file diff --git a/erpnext/website/page/blog/blog.js b/erpnext/website/page/blog/blog.js new file mode 100644 index 00000000000..9e89acdca83 --- /dev/null +++ b/erpnext/website/page/blog/blog.js @@ -0,0 +1,38 @@ + +pscript.onload_blog = function(wrapper) { + wrapper.blog_list = new wn.widgets.Listing({ + parent: $(wrapper).find('.web-main-section').get(0), + query: 'select tabBlog.name, title, left(content, 300) as content, tabBlog.modified, \ + ifnull(first_name, "") as first_name, ifnull(last_name, "") as last_name \ + from tabProfile, tabBlog\ + where ifnull(published,1)=1 and tabBlog.owner = tabProfile.name', + hide_refresh: true, + render_row: function(parent, data) { + if(data.content.length==300) data.content += '...'; + data.date = prettyDate(data.modified); + parent.innerHTML = repl('

%(title)s

\ +

By %(first_name)s %(last_name)s on %(date)s

\ +
%(content)s

', data); + }, + page_length: 10 + }); + wrapper.blog_list.run(); + + // subscribe button + $('#blog-subscribe').click(function() { + var email = $(wrapper).find('input[name="blog-subscribe"]').val(); + if(!validate_email(email)) { + msgprint('Please enter a valid email!'); + } + wn.call({ + module:'website', + page:'blog', + method:'subscribe', + args:email, + btn: this, + callback: function() { + $(wrapper).find('input[name="blog-subscribe"]').val(''); + } + }); + }) +} \ No newline at end of file diff --git a/erpnext/website/page/blog/blog.py b/erpnext/website/page/blog/blog.py new file mode 100644 index 00000000000..2773624f4b8 --- /dev/null +++ b/erpnext/website/page/blog/blog.py @@ -0,0 +1,13 @@ +import webnotes + +@webnotes.whitelist() +def subscribe(arg): + """subscribe to blog (blog_subscriber)""" + if webnotes.conn.sql("""select name from `tabBlog Subscriber` where name=%s""", arg): + webnotes.msgprint("Already a subscriber. Thanks!") + else: + from webnotes.model.doc import Document + d = Document('Blog Subscriber') + d.name = arg + d.save() + webnotes.msgprint("Thank you for subscribing!") \ No newline at end of file diff --git a/erpnext/website/page/blog/blog.txt b/erpnext/website/page/blog/blog.txt new file mode 100644 index 00000000000..4443ec813d9 --- /dev/null +++ b/erpnext/website/page/blog/blog.txt @@ -0,0 +1,44 @@ +# Page, blog +[ + + # These values are common in all dictionaries + { + 'creation': '2012-01-27 15:47:52', + 'docstatus': 0, + 'modified': '2012-01-27 15:47:52', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Page + { + 'doctype': 'Page', + 'module': 'Website', + 'name': '__common__', + 'page_name': 'blog', + 'standard': 'Yes', + 'title': 'Blog' + }, + + # These values are common for all Page Role + { + '__islocal': 1, + 'doctype': 'Page Role', + 'name': '__common__', + 'parent': 'blog', + 'parentfield': 'roles', + 'parenttype': 'Page', + 'role': 'Guest' + }, + + # Page, blog + { + 'doctype': 'Page', + 'name': 'blog' + }, + + # Page Role + { + 'doctype': 'Page Role' + } +] \ No newline at end of file diff --git a/erpnext/website/page/contact/__init__.py b/erpnext/website/page/contact/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/website/page/contact/contact.js b/erpnext/website/page/contact/contact.js new file mode 100644 index 00000000000..e05023b3664 --- /dev/null +++ b/erpnext/website/page/contact/contact.js @@ -0,0 +1,30 @@ +pscript.onload_contact = function(wrapper) { + $('#content-contact-us .btn.primary').click(function() { + var me = this; + var args = {}; + args.name = $('#content-contact-us [name="contact-name"]').val(); + args.email = $('#content-contact-us [name="contact-email"]').val(); + args.message = $('#content-contact-us [name="contact-message"]').val(); + + if(!validate_email(args.email)) { + msgprint('Please enter a valid email id'); + return; + } + + if(args.name && args.email && args.message) { + $(this).set_working(); + $c_page('website', 'contact', 'send', args, function(r) { + $('#content-contact-us [name*="contact"]').val(''); + $(me).done_working(); + }); + } else { + msgprint("Please enter info in all the fields.") + } + }); + + $('#content-contact-us :input').keyup(function(ev) { + if(ev.which == 13) { + $('#content-contact-us .btn.primary').click(); + } + }); +} \ No newline at end of file diff --git a/erpnext/website/page/contact/contact.py b/erpnext/website/page/contact/contact.py new file mode 100644 index 00000000000..2fd00f7681e --- /dev/null +++ b/erpnext/website/page/contact/contact.py @@ -0,0 +1,16 @@ +import json, webnotes + +@webnotes.whitelist() +def send(args): + """create support ticket""" + args = json.loads(args) + + from webnotes.model.doc import Document + d = Document('Support Ticket') + d.raised_by = args['email'] + d.description = 'From: ' + args['name'] + '\n\n' + args['message'] + d.subject = 'Website Query' + d.status = 'Open' + d.owner = 'Guest' + d.save(1) + webnotes.msgprint("Thank you for your query. We will respond as soon as we can.") \ No newline at end of file diff --git a/erpnext/website/page/contact/contact.txt b/erpnext/website/page/contact/contact.txt new file mode 100644 index 00000000000..6051c6f2c95 --- /dev/null +++ b/erpnext/website/page/contact/contact.txt @@ -0,0 +1,42 @@ +# Page, contact +[ + + # These values are common in all dictionaries + { + 'creation': '2012-01-25 16:02:15', + 'docstatus': 0, + 'modified': '2012-01-25 16:02:15', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Page + { + 'doctype': 'Page', + 'module': 'Website', + 'name': '__common__', + 'page_name': 'contact', + 'standard': 'Yes' + }, + + # These values are common for all Page Role + { + 'doctype': 'Page Role', + 'name': '__common__', + 'parent': 'contact', + 'parentfield': 'roles', + 'parenttype': 'Page', + 'role': 'Guest' + }, + + # Page, contact + { + 'doctype': 'Page', + 'name': 'contact' + }, + + # Page Role + { + 'doctype': 'Page Role' + } +] \ No newline at end of file diff --git a/erpnext/website/page/products/README.md b/erpnext/website/page/products/README.md new file mode 100644 index 00000000000..e40b44629f1 --- /dev/null +++ b/erpnext/website/page/products/README.md @@ -0,0 +1,27 @@ +## Products + +Contains + +- List of Products tagged by Item master + - image + - short description (md) + - pricing info (if public) (public pricelist) + - stock info (website warehouse) +- Search +- Sidebar contains categories (# of items in each category) + +When Item is Saved, a page for that item is created with + +- Large image +- Smaller images +- Long Description +- Pricing info +- Stock info +- Contact Button (instead of Buy / Add to cart) + +### Steps + +- update item master +- update item category (show in web + priority) (or in a products settings page) +- # of public items in each category +- validation - item cannot have show in item if parent does not have it \ No newline at end of file diff --git a/erpnext/website/page/products/__init__.py b/erpnext/website/page/products/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/website/page/products/products.html b/erpnext/website/page/products/products.html new file mode 100644 index 00000000000..6c4fa97b174 --- /dev/null +++ b/erpnext/website/page/products/products.html @@ -0,0 +1,13 @@ +
+

+
+ +
+
+

Categories

+
+
+
+
\ No newline at end of file diff --git a/erpnext/website/page/products/products.js b/erpnext/website/page/products/products.js new file mode 100644 index 00000000000..b9fa167514f --- /dev/null +++ b/erpnext/website/page/products/products.js @@ -0,0 +1,87 @@ +erpnext.products = {} + +wn.require('erpnext/website/js/product_category.js'); + +pscript.onload_products = function(wrapper) { + sys_defaults.default_product_category = JSON.parse(sys_defaults.default_product_category); + erpnext.products.wrapper = wrapper; + + // make lists + erpnext.make_product_categories(wrapper); + erpnext.products.make_product_list(wrapper); + + // button + $(wrapper).find('.products-search .btn').click(function() { + wrapper.mainlist.run(); + }); + + $(wrapper).find('.products-search input').keypress(function(ev) { + if(ev.which==13) $(wrapper).find('.products-search .btn').click(); + }); +} + +pscript.onshow_products = function(wrapper) { + // show default product category + erpnext.products.set_group(); +} + +erpnext.products.get_group = function() { + var route = window.location.hash.split('/'); + if(route.length>1) { + // from url + var grp = erpnext.product_item_group[route[1]]; + var label = route[1]; + } else { + // default + var grp = sys_defaults.default_product_category.item_group; + var label = sys_defaults.default_product_category.label; + } + erpnext.products.cur_group = grp; + return {grp:grp, label:label}; +} + +erpnext.products.make_product_list = function(wrapper) { + wrapper.mainlist = new wn.widgets.Listing({ + parent: $(wrapper).find('.web-main-section').get(0), + run_btn: $(wrapper).find('.products-search .btn').get(0), + hide_refresh: true, + get_query: function() { + var srch = $('input[name="products-search"]').val() + var search_cond = 'and (t1.short_description like "%%(srch)s%"\ + or t1.title like "%%(srch)s%")'; + args = { + search_cond: srch ? repl(search_cond, {srch:srch}) : '', + cat: erpnext.products.cur_group + }; + return repl('select t1.name, t1.title, t1.thumbnail_image, \ + t1.page_name, t1.short_description \ + from tabProduct t1, tabItem t2 \ + where t1.item = t2.name \ + and ifnull(t1.published,0)=1 \ + and t2.item_group="%(cat)s" \ + %(search_cond)s', args) + }, + render_row: function(parent, data) { + parent.innerHTML = repl('
\ +
\ +
\ + %(title)s\ +

%(short_description)s

\ +
', data); + } + }); +} + +erpnext.products.set_group = function() { + var cat = erpnext.products.get_group(); + if(!cat.grp) { + // still nothing + setTimeout('erpnext.products.set_group()', 1000); + return; + } + // get erpnext.products.default_category + var wrapper = erpnext.products.wrapper; + + $(wrapper).find('h1').html(cat.label); + wrapper.mainlist.run(); +} diff --git a/erpnext/website/page/products/products.txt b/erpnext/website/page/products/products.txt new file mode 100644 index 00000000000..f00a05b8e84 --- /dev/null +++ b/erpnext/website/page/products/products.txt @@ -0,0 +1,43 @@ +# Page, products +[ + + # These values are common in all dictionaries + { + 'creation': '2012-01-30 10:49:01', + 'docstatus': 0, + 'modified': '2012-01-30 10:49:01', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Page + { + 'doctype': 'Page', + 'module': 'Website', + 'name': '__common__', + 'page_name': 'products', + 'standard': 'Yes', + 'title': 'Products' + }, + + # These values are common for all Page Role + { + 'doctype': 'Page Role', + 'name': '__common__', + 'parent': 'products', + 'parentfield': 'roles', + 'parenttype': 'Page', + 'role': 'Guest' + }, + + # Page, products + { + 'doctype': 'Page', + 'name': 'products' + }, + + # Page Role + { + 'doctype': 'Page Role' + } +] \ No newline at end of file diff --git a/erpnext/website/page/unsubscribe/__init__.py b/erpnext/website/page/unsubscribe/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/website/page/unsubscribe/unsubscribe.html b/erpnext/website/page/unsubscribe/unsubscribe.html new file mode 100644 index 00000000000..7b2b68ee9c6 --- /dev/null +++ b/erpnext/website/page/unsubscribe/unsubscribe.html @@ -0,0 +1,13 @@ +
+
+

Unsubscribe

+
+
+ + +
+
+
+
+
+
\ No newline at end of file diff --git a/erpnext/website/page/unsubscribe/unsubscribe.js b/erpnext/website/page/unsubscribe/unsubscribe.js new file mode 100644 index 00000000000..7cbed37f4ad --- /dev/null +++ b/erpnext/website/page/unsubscribe/unsubscribe.js @@ -0,0 +1,21 @@ +pscript.onload_unsubscribe = function(wrapper) { + var email = window.location.hash.split('/').splice(-1); + $(wrapper).find('input[name="unsubscribe"]').val(email) + + $('#btn-unsubscribe').click(function() { + var email = $(wrapper).find('input[name="unsubscribe"]').val(); + if(email) { + var btn = this; + wn.call({ + module:'website', + page:'unsubscribe', + method:'unsubscribe', + args:email, + btn: this, + callback: function() { + $(wrapper).find('input[name="unsubscribe"]').val(''); + } + }); + } + }); +} \ No newline at end of file diff --git a/erpnext/website/page/unsubscribe/unsubscribe.py b/erpnext/website/page/unsubscribe/unsubscribe.py new file mode 100644 index 00000000000..c310c61dec5 --- /dev/null +++ b/erpnext/website/page/unsubscribe/unsubscribe.py @@ -0,0 +1,10 @@ +import webnotes + +@webnotes.whitelist() +def unsubscribe(arg): + """unsubscribe from lists""" + lists = [['Blog Subscriber', 'name']] + for l in lists: + webnotes.conn.sql("""delete from `tab%s` where %s=%s""" % (l[0], l[1], '%s'), arg) + + webnotes.msgprint('Unsubscribed!') \ No newline at end of file diff --git a/erpnext/website/page/unsubscribe/unsubscribe.txt b/erpnext/website/page/unsubscribe/unsubscribe.txt new file mode 100644 index 00000000000..2cc3b58a351 --- /dev/null +++ b/erpnext/website/page/unsubscribe/unsubscribe.txt @@ -0,0 +1,43 @@ +# Page, unsubscribe +[ + + # These values are common in all dictionaries + { + 'creation': '2012-01-27 17:19:02', + 'docstatus': 0, + 'modified': '2012-01-27 17:19:02', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Page + { + 'doctype': 'Page', + 'module': 'Website', + 'name': '__common__', + 'page_name': 'unsubscribe', + 'standard': 'Yes', + 'title': 'Unsubscribe' + }, + + # These values are common for all Page Role + { + 'doctype': 'Page Role', + 'name': '__common__', + 'parent': 'unsubscribe', + 'parentfield': 'roles', + 'parenttype': 'Page', + 'role': 'Guest' + }, + + # Page, unsubscribe + { + 'doctype': 'Page', + 'name': 'unsubscribe' + }, + + # Page Role + { + 'doctype': 'Page Role' + } +] \ No newline at end of file diff --git a/erpnext/website/utils.py b/erpnext/website/utils.py new file mode 100644 index 00000000000..66be4d2bb5f --- /dev/null +++ b/erpnext/website/utils.py @@ -0,0 +1,54 @@ +import webnotes +from webnotes.model.doc import Document + +def make_template(doc, path, convert_fields = ['main_section', 'side_section']): + """make template""" + import os, jinja2 + + markdown(doc, convert_fields) + + # write template + with open(path, 'r') as f: + temp = jinja2.Template(f.read()) + + return temp.render(doc = doc.fields) + +def markdown(doc, fields): + """convert fields to markdown""" + import markdown2 + # markdown + for f in fields: + doc.fields[f + '_html'] = markdown2.markdown(doc.fields[f] or '', \ + extras=["wiki-tables"]) + + +def page_name(title): + """make page name from title, and check that there is no duplicate""" + import re + name = title.lower() + name = re.sub('[~!@#$%^&*()<>,."\']', '', name) + return '-'.join(name.split()[:4]) + +def add_page(title): + """add a custom page with title""" + name = page_name(title) + if webnotes.conn.sql("""select name from tabPage where name=%s""", name): + p = Document('Page', name) + else: + p = Document('Page') + + p.title = title + p.name = p.page_name = name + p.module = 'Website' + p.standard = 'No' + + return p + +def add_guest_access_to_page(page): + """add Guest in Page Role""" + if not webnotes.conn.sql("""select parent from `tabPage Role` + where role='Guest' and parent=%s""", page): + d = Document('Page Role') + d.parent = page + d.role = 'Guest' + d.save() diff --git a/images/feed.png b/images/feed.png new file mode 100755 index 00000000000..315c4f4fa62 Binary files /dev/null and b/images/feed.png differ diff --git a/index.cgi b/index.cgi index 3d61c560521..3ec31e7985e 100755 --- a/index.cgi +++ b/index.cgi @@ -9,33 +9,35 @@ sys.path.append('lib/py') sys.path.append('erpnext') import webnotes +import webnotes.handler +import webnotes.auth -webnotes.form = cgi.FieldStorage() +def init(): + # make the form_dict + webnotes.form = cgi.FieldStorage(keep_blank_values=True) + for key in webnotes.form.keys(): + webnotes.form_dict[key] = webnotes.form.getvalue(key) -# make the form_dict -for key in webnotes.form.keys(): - webnotes.form_dict[key] = webnotes.form.getvalue(key) + # init request + try: + webnotes.http_request = webnotes.auth.HTTPRequest() + except Exception, e: + if webnotes.response['message']=='Authentication Failed': + pass + else: + raise e -# url comes with sid, redirect to html, sid set and all -if 'sid' in webnotes.form_dict: - import webnotes.auth - import webnotes.widgets.page_body - - webnotes.auth.HTTPRequest() - - print "Content-Type: text/html" - - # print cookies, if there ar additional cookies defined during the request, add them here - if webnotes.cookies or webnotes.add_cookies: - for c in webnotes.add_cookies.keys(): - webnotes.cookies[c] = webnotes.add_cookies[c] - - print webnotes.cookies - - print - print webnotes.widgets.page_body.redirect_template % ('Redirecting...', 'index.html') - -else: - # pass on to legacy handler - import webnotes.handler +def respond(): + import webnotes + if 'cmd' in webnotes.form_dict: + webnotes.handler.handle() + else: + import webnotes.cms.index + print "Content-Type: text/html" + webnotes.handler.print_cookies() + print + print webnotes.cms.index.get() +if __name__=="__main__": + init() + respond() diff --git a/index.html b/index.html deleted file mode 100644 index 150a2cf730e..00000000000 --- a/index.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - ERPNext - - - - -
- - -
- - -
- Loading... -
-
- -
- diff --git a/js/app.js b/js/app.js index 5a8597d48ba..cba6a8493f3 100644 --- a/js/app.js +++ b/js/app.js @@ -1,8 +1,17 @@ +wn.app = { + name: 'ERPNext', + license: 'GNU/GPL - Usage Condition: All "erpnext" branding must be kept as it is', + source: 'https://github.com/webnotes/erpnext', + publisher: 'Web Notes Technologies Pvt Ltd, Mumbai', + copyright: '© Web Notes Technologies Pvt Ltd', + version: '2.' + window._version_number +} + +wn.modules_path = 'erpnext'; wn.settings.no_history = true; wn.require('lib/js/lib/jquery.min.js'); wn.require('lib/js/legacy/tiny_mce_33/jquery.tinymce.js'); -wn.require('lib/js/wn/ui/status_bar.js'); // for datepicker wn.require('lib/js/legacy/jquery/jquery-ui.min.js') @@ -11,4 +20,8 @@ wn.require('lib/css/legacy/default.css'); $(document).bind('ready', function() { startup(); -}); \ No newline at end of file +}); + +$(document).bind('toolbar_setup', function() { + $('.brand').html('erpnext'); +}) \ No newline at end of file diff --git a/rss.xml b/rss.xml new file mode 100755 index 00000000000..f69724b493c --- /dev/null +++ b/rss.xml @@ -0,0 +1,18 @@ +#!/usr/bin/python + +import cgi, cgitb, os, sys +cgitb.enable() + +# import libs +sys.path.append('lib/py') + +import webnotes +import webnotes.auth + +if __name__=='__main__': + webnotes.http_request = webnotes.auth.HTTPRequest() + from webnotes.cms import feed + xml = feed.generate() + print 'Content-Type: text/xml' + print + print xml \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100755 index 00000000000..04e565bc574 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,19 @@ +#!/usr/bin/python + +import cgi, cgitb, os, sys +cgitb.enable() + +# import libs +sys.path.append('lib/py') + +import webnotes +import webnotes.auth + +if __name__=='__main__': + webnotes.http_request = webnotes.auth.HTTPRequest() + domain = os.environ.get('HTTP_HOST') + protocol = os.environ.get('HTTPS') and 'https://' or 'http://' + from webnotes.cms import sitemap + print 'Content-Type: text/xml' + print + print sitemap.generate(protocol + domain + '/') \ No newline at end of file diff --git a/templates/index.html b/templates/index.html deleted file mode 100644 index af0b8e5f79e..00000000000 --- a/templates/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - ERPNext - - - - -
- - -
- - -
- Loading... -
-
- -
- diff --git a/version.num b/version.num index bc768da71aa..1380537bfd7 100644 --- a/version.num +++ b/version.num @@ -1 +1 @@ -146 \ No newline at end of file +385 \ No newline at end of file diff --git a/wnf.py b/wnf.py new file mode 100755 index 00000000000..4f18187fccb --- /dev/null +++ b/wnf.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python + +import os, sys + +def replace_code(start, txt1, txt2, extn): + """replace all txt1 by txt2 in files with extension (extn)""" + import os, re + for wt in os.walk(start, followlinks=1): + for fn in wt[2]: + if fn.split('.')[-1]==extn: + fpath = os.path.join(wt[0], fn) + with open(fpath, 'r') as f: + content = f.read() + + if re.search(txt1, content): + a = raw_input('Change in %s [y/n]?' % fpath) + if a=='y': + with open(fpath, 'w') as f: + f.write(re.sub(txt1, txt2, content)) + + print 'updated in %s' % fpath + +def setup_options(): + from optparse import OptionParser + parser = OptionParser() + parser.add_option("-b", "--build", default=False, action="store_true", + help="minify + concat js files") + parser.add_option("-c", "--clear", default=False, action="store_true", + help="increment version") + parser.add_option("--replace", nargs=3, default=False, + metavar = "search replace_by extension", + help="file search-replace") + parser.add_option("--status", default=False, action="store_true", + help="git status") + parser.add_option("--pull", nargs=2, default=False, + metavar = "remote branch", + help="git pull (both repos)") + parser.add_option("--push", nargs=3, default=False, + metavar = "remote branch comment", + help="git commit + push (both repos) [remote] [branch] [comment]") + parser.add_option("-l", "--latest", + action="store_true", dest="run_latest", default=False, + help="Apply the latest patches") + parser.add_option("-p", "--patch", nargs=1, dest="patch_list", metavar='patch_module', + action="append", + help="Apply patch") + parser.add_option("-f", "--force", + action="store_true", dest="force", default=False, + help="Force Apply all patches specified using option -p or --patch") + parser.add_option("-d", "--db", + dest="db_name", + help="Apply the patches on given db") + parser.add_option('--reload_doc', nargs=3, metavar = "module doctype docname", + help="reload doc") + parser.add_option('--export_doc', nargs=2, metavar = "doctype docname", + help="export doc") + parser.add_option('--install', nargs=3, metavar = "rootpassword dbname source", + help="install fresh db") + parser.add_option('--sync_with_gateway', nargs=1, metavar = "1/0", help="Set or Unset Sync with Gateway") + + return parser.parse_args() + +def run(): + sys.path.append('lib') + sys.path.append('lib/py') + import webnotes + import webnotes.defs + sys.path.append(webnotes.defs.modules_path) + + (options, args) = setup_options() + + + from webnotes.db import Database + import webnotes.modules.patch_handler + + # connect + if options.db_name is not None: + webnotes.connect(options.db_name) + + # build + if options.build: + import build.project + build.project.build() + + elif options.clear: + from build.project import increment_version + print "Version:" + str(increment_version()) + + # code replace + elif options.replace: + replace_code('.', options.replace[0], options.replace[1], options.replace[2]) + + # git + elif options.status: + os.system('git status') + os.chdir('lib') + os.system('git status') + + elif options.pull: + os.system('git pull %s %s' % (options.pull[0], options.pull[1])) + os.chdir('lib') + os.system('git pull %s %s' % (options.pull[0], options.pull[1])) + + elif options.push: + os.system('git commit -a -m "%s"' % options.push[2]) + os.system('git push %s %s' % (options.push[0], options.push[1])) + os.chdir('lib') + os.system('git commit -a -m "%s"' % options.push[2]) + os.system('git push %s %s' % (options.push[0], options.push[1])) + + # patch + elif options.patch_list: + # clear log + webnotes.modules.patch_handler.log_list = [] + + # run individual patches + for patch in options.patch_list: + webnotes.modules.patch_handler.run_single(\ + patchmodule = patch, force = options.force) + + print '\n'.join(webnotes.modules.patch_handler.log_list) + + # reload + elif options.reload_doc: + webnotes.modules.patch_handler.reload_doc(\ + {"module":options.reload_doc[0], "dt":options.reload_doc[1], "dn":options.reload_doc[2]}) + print '\n'.join(webnotes.modules.patch_handler.log_list) + + elif options.export_doc: + from webnotes.modules import export_doc + export_doc(options.export_doc[0], options.export_doc[1]) + + # run all pending + elif options.run_latest: + webnotes.modules.patch_handler.run_all() + print '\n'.join(webnotes.modules.patch_handler.log_list) + + elif options.install: + from webnotes.install_lib.install import Installer + inst = Installer('root', options.install[0]) + inst.import_from_db(options.install[1], source_path=options.install[2], \ + password='admin', verbose = 1) + + elif options.sync_with_gateway: + if int(options.sync_with_gateway[0]) in [0, 1]: + webnotes.conn.begin() + webnotes.conn.sql("""\ + UPDATE `tabSingles` SET value=%s + WHERE field='sync_with_gateway' AND doctype='Control Panel'""", int(options.sync_with_gateway[0])) + webnotes.conn.commit() + webnotes.message_log.append("sync_with_gateway set to %s" % options.sync_with_gateway[0]) + else: + webnotes.message_log.append("ERROR: sync_with_gateway can be either 0 or 1") + + # print messages + if webnotes.message_log: + print '\n'.join(webnotes.message_log) + +if __name__=='__main__': + run()