Merge branch 'master' into edge
diff --git a/public/js/website_utils.js b/public/js/website_utils.js
index 502b5eb..65f7a69 100644
--- a/public/js/website_utils.js
+++ b/public/js/website_utils.js
@@ -1,36 +1,87 @@
var erpnext = {};
+var wn = {};
+// Add / update a new Lead / Communication
// subject, sender, description
erpnext.send_message = function(opts) {
+ wn.call({
+ type: "POST",
+ method: "website.helpers.contact.send_message",
+ args: opts,
+ callback: opts.callback
+ })
+}
+
+wn.call = function(opts) {
if(opts.btn) {
+ var $spinner = $('<img src="lib/images/ui/button-load.gif">').appendTo($(opts.btn).parent())
$(opts.btn).attr("disabled", "disabled");
}
-
+
+ if(opts.msg) {
+ $(opts.msg).toggle(false);
+ }
+
+ // get or post?
+ if(!opts.args._type) {
+ opts.args._type = opts.type || "GET";
+ }
+
+ // method
+ if(opts.method) {
+ opts.args.cmd = opts.method;
+ }
+
+ // stringify
+ $.each(opts.args, function(key, val) {
+ if(typeof val != "string") {
+ opts.args[key] = JSON.stringify(val);
+ }
+ });
+
$.ajax({
type: "POST",
url: "server.py",
- data: {
- cmd: "website.helpers.contact.send_message",
- subject: opts.subject,
- sender: opts.sender,
- status: opts.status,
- _type: "POST",
- message: typeof opts.message == "string"
- ? opts.message
- : JSON.stringify(opts.message)
- },
+ data: opts.args,
dataType: "json",
success: function(data) {
if(opts.btn) {
$(opts.btn).attr("disabled", false);
+ $spinner.remove();
}
- if(opts.callback)
+ if(data.exc) {
+ console.log(data.exc);
+ }
+ if(opts.msg && data.message) {
+ $(opts.msg).html(data.message).toggle(true);
+ }
+ if(opts.callback)
opts.callback(data);
}
});
+
+ return false;
}
+// Setup the user tools
+//
+$(document).ready(function() {
+ // update login
+ var full_name = getCookie("full_name");
+ if(full_name) {
+ $("#user-tools").html(repl('<a href="account" title="My Account" id="user-full-name">%(full_name)s</a> | \
+ <a href="cart" title="Shopping Cart"><i class="icon-shopping-cart"></i> (%(count)s)</a> | \
+ <a href="server.py?cmd=web_logout" title="Sign Out"><i class="icon-signout"></i></a>', {
+ full_name: full_name,
+ count: getCookie("cart_count") || "0"
+ }));
+ $("#user-tools a").tooltip({"placement":"bottom"});
+ }
+})
+
+// Utility functions
+
function valid_email(id) {
if(id.toLowerCase().search("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")==-1)
return 0; else return 1; }
@@ -55,3 +106,54 @@
}
return s;
}
+
+function getCookie(name) {
+ return getCookies()[name];
+}
+
+function getCookies() {
+ var c = document.cookie, v = 0, cookies = {};
+ if (document.cookie.match(/^\s*\$Version=(?:"1"|1);\s*(.*)/)) {
+ c = RegExp.$1;
+ v = 1;
+ }
+ if (v === 0) {
+ c.split(/[,;]/).map(function(cookie) {
+ var parts = cookie.split(/=/, 2),
+ name = decodeURIComponent(parts[0].trimLeft()),
+ value = parts.length > 1 ? decodeURIComponent(parts[1].trimRight()) : null;
+ if(value.charAt(0)==='"') {
+ value = value.substr(1, value.length-2);
+ }
+ cookies[name] = value;
+ });
+ } else {
+ c.match(/(?:^|\s+)([!#$%&'*+\-.0-9A-Z^`a-z|~]+)=([!#$%&'*+\-.0-9A-Z^`a-z|~]*|"(?:[\x20-\x7E\x80\xFF]|\\[\x00-\x7F])*")(?=\s*[,;]|$)/g).map(function($0, $1) {
+ var name = $0,
+ value = $1.charAt(0) === '"'
+ ? $1.substr(1, -1).replace(/\\(.)/g, "$1")
+ : $1;
+ cookies[name] = value;
+ });
+ }
+ return cookies;
+}
+
+if (typeof String.prototype.trimLeft !== "function") {
+ String.prototype.trimLeft = function() {
+ return this.replace(/^\s+/, "");
+ };
+}
+if (typeof String.prototype.trimRight !== "function") {
+ String.prototype.trimRight = function() {
+ return this.replace(/\s+$/, "");
+ };
+}
+if (typeof Array.prototype.map !== "function") {
+ Array.prototype.map = function(callback, thisArg) {
+ for (var i=0, n=this.length, a=[]; i<n; i++) {
+ if (i in this) a[i] = callback.call(thisArg, this[i]);
+ }
+ return a;
+ };
+}
diff --git a/setup/doctype/backup_manager/backup_dropbox.py b/setup/doctype/backup_manager/backup_dropbox.py
index 2c7fda6..3cc565e 100644
--- a/setup/doctype/backup_manager/backup_dropbox.py
+++ b/setup/doctype/backup_manager/backup_dropbox.py
@@ -105,6 +105,7 @@
return sess
def upload_file_to_dropbox(filename, folder, dropbox_client):
+ from dropbox import rest
size = os.stat(filename).st_size
f = open(filename,'r')
if size > 4194304:
diff --git a/setup/doctype/contact_control/contact_control.py b/setup/doctype/contact_control/contact_control.py
index 3c37ecf..54a2fcc 100644
--- a/setup/doctype/contact_control/contact_control.py
+++ b/setup/doctype/contact_control/contact_control.py
@@ -1,99 +1,7 @@
-# Please edit this list and import only required elements
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import set_default
-from webnotes.model import db_exists
-from webnotes.model.doc import Document
-from webnotes.model.bean import copy_doclist
-from webnotes.model.code import get_obj
-from webnotes import msgprint
-
-sql = webnotes.conn.sql
-
-
-
class DocType:
- def __init__(self,doc,doclist=[]):
- self.doc = doc
- self.doclist = doclist
-
- def enable_login(self,arg):
- arg = eval(arg)
- sql("update tabContact set disable_login = 'No' where name=%s",arg['contact'])
- sql("update tabProfile set enabled=1 where name=%s",arg['email'])
-
- def disable_login(self,arg):
- arg = eval(arg)
- sql("update tabContact set disable_login = 'Yes' where name=%s",arg['contact'])
- sql("update tabProfile set enabled=0 where name=%s",arg['email'])
-
- def create_login(self,arg):
- arg = eval(arg)
- cont_det = sql("select * from tabContact where name=%s",(arg['contact']),as_dict=1)
- if cont_det[0]['docstatus'] !=0:
- msgprint('Please save the corresponding contact first')
- raise Exception
-
- if sql("select name from tabProfile where name=%s",cont_det[0]['email_id']):
- msgprint('Profile with same name already exist.')
- raise Exception
- else:
- p = Document('Profile')
- p.name = cont_det[0]['email_id']
- p.first_name = cont_det[0]['first_name']
- p.last_name = cont_det[0]['last_name']
- p.email = cont_det[0]['email_id']
- p.cell_no = cont_det[0]['contact_no']
- p.password = 'password'
- p.enabled = 1
- p.user_type = 'Partner';
- p.save(1)
-
- get_obj(doc=p).on_update()
-
- role = []
- if cont_det[0]['contact_type'] == 'Individual':
- role = ['Customer']
- else:
- if cont_det[0]['is_customer']:
- role.append('Customer')
- if cont_det[0]['is_supplier']:
- role.append('Supplier')
- if cont_det[0]['is_sales_partner']:
- role.append('Partner')
-
- if role:
- prof_nm = p.name
- for i in role:
- r = Document('UserRole')
- r.parent = p.name
- r.role = i
- r.parenttype = 'Profile'
- r.parentfield = 'userroles'
- r.save(1)
-
- if i == 'Customer':
- def_keys = ['from_company','customer_name','customer']
- def_val = cont_det[0]['customer_name']
- self.set_default_val(def_keys,def_val,prof_nm)
-
- if i == 'Supplier':
- def_keys = ['supplier_name','supplier']
- def_val = cont_det[0]['supplier_name']
- self.set_default_val(def_keys,def_val,prof_nm)
-
- sql("update tabContact set has_login = 'Yes' where name=%s",cont_det[0]['name'])
- sql("update tabContact set disable_login = 'No' where name=%s",cont_det[0]['name'])
- msgprint('User login is created.')
-
- #------set default values---------
- def set_default_val(self,def_keys,def_val,prof_nm):
- for d in def_keys:
- kv = Document('DefaultValue')
- kv.defkey = d
- kv.defvalue = def_val
- kv.parent = prof_nm
- kv.parenttype = 'Profile'
- kv.parentfield = 'defaults'
- kv.save(1)
\ No newline at end of file
+ def __init__(self,doc,doclist=[]):
+ self.doc = doc
+ self.doclist = doclist
diff --git a/website/doctype/blog_post/blog_post.txt b/website/doctype/blog_post/blog_post.txt
index 480bca4..4144e40 100644
--- a/website/doctype/blog_post/blog_post.txt
+++ b/website/doctype/blog_post/blog_post.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-03-08 11:36:50",
"docstatus": 0,
- "modified": "2013-03-11 15:23:21",
+ "modified": "2013-03-18 13:55:53",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -65,6 +65,7 @@
"doctype": "DocField",
"fieldname": "blogger",
"fieldtype": "Link",
+ "in_list_view": 1,
"label": "Blogger",
"options": "Blogger",
"reqd": 1
@@ -73,6 +74,7 @@
"doctype": "DocField",
"fieldname": "blog_category",
"fieldtype": "Link",
+ "in_list_view": 1,
"label": "Blog Category",
"options": "Blog Category"
},
@@ -86,6 +88,7 @@
"doctype": "DocField",
"fieldname": "blog_intro",
"fieldtype": "Small Text",
+ "in_list_view": 1,
"label": "Blog Intro",
"reqd": 1
},
diff --git a/website/doctype/style_settings/style_settings.py b/website/doctype/style_settings/style_settings.py
index 1cc3467..71478a4 100644
--- a/website/doctype/style_settings/style_settings.py
+++ b/website/doctype/style_settings/style_settings.py
@@ -89,7 +89,7 @@
self.doc.at_import = ""
for f in fonts:
- self.doc.at_import += "\n@import url(http://fonts.googleapis.com/css?family=%s:400,700);" % f.replace(" ", "+")
+ self.doc.at_import += "\n@import url(https://fonts.googleapis.com/css?family=%s:400,700);" % f.replace(" ", "+")
def on_update(self):
diff --git a/website/helpers/account.py b/website/helpers/account.py
new file mode 100644
index 0000000..2bab370
--- /dev/null
+++ b/website/helpers/account.py
@@ -0,0 +1,23 @@
+# Copyright (c) 2012 Web Notes Technologies Pvt Ltd.
+# License: GNU General Public License (v3). For more information see license.txt
+
+from __future__ import unicode_literals
+
+import webnotes
+from webnotes.utils import cstr
+
+@webnotes.whitelist()
+def get_orders():
+ # find customer id
+ customer = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user},
+ "customer")
+
+ if customer:
+ orders = webnotes.conn.sql("""select name, creation, currency from `tabSales Order`
+ where customer=%s""", customer, as_dict=1)
+ for order in orders:
+ order.items = webnotes.conn.sql("""select item_name, qty, export_rate, delivered_qty
+ from `tabSales Order Item` where parent=%s order by idx""", order.name, as_dict=1)
+ return orders
+ else:
+ return []
\ No newline at end of file
diff --git a/website/templates/css/login.css b/website/templates/css/login.css
index c2a7af2..4120807 100644
--- a/website/templates/css/login.css
+++ b/website/templates/css/login.css
@@ -4,9 +4,17 @@
margin: 70px auto;
}
+ #login_wrapper,
+ #login_wrapper h3 {
+ color: #333;
+ }
+
+ #login_wrapper a {
+ color: #0088cc;
+ }
+
.layout-wrapper {
background-color: #fff;
- color: #333;
padding: 10px;
box-shadow: 1px 1px 3px 3px #ccc;
font-size: 12px;
@@ -32,7 +40,4 @@
text-align: center;
padding: 15px;
}
- .login-footer, .login-footer a {
- color: #999;
- }
</style>
\ No newline at end of file
diff --git a/website/templates/html/navbar.html b/website/templates/html/navbar.html
index 8112499..4663a2f 100644
--- a/website/templates/html/navbar.html
+++ b/website/templates/html/navbar.html
@@ -47,9 +47,6 @@
{% endif %}
{% endfor %}
</ul>
- <ul class="nav pull-right">
- <li id="login-topbar-item"><a href="login">Login</a></li>
- </ul>
</div>
</div>
</div>
diff --git a/website/templates/html/outer.html b/website/templates/html/outer.html
index f7296e4..c46aaa7 100644
--- a/website/templates/html/outer.html
+++ b/website/templates/html/outer.html
@@ -1,9 +1,11 @@
{% extends "html/base.html" %}
{% block body %}
- <header>
- </header>
<div class="container">
+ <div class="pull-right" style="margin:4px;" id="user-tools">
+ <a id="login-link" href="login">Login</a>
+ </div>
+ <div class="clearfix"></div>
{% if banner_html %}<div class="row" style="margin-top: 30px;">
<div class="span12">{{ banner_html }}</div>
</div>{% endif %}
diff --git a/website/templates/js/login.js b/website/templates/js/login.js
index 96b820a..06ea4c5 100644
--- a/website/templates/js/login.js
+++ b/website/templates/js/login.js
@@ -17,27 +17,53 @@
// Login
login.do_login = function(){
-
var args = {};
- args['usr']=$("#login_id").val();
- args['pwd']=$("#password").val();
+ if(window.is_sign_up) {
+ args.cmd = "core.doctype.profile.profile.sign_up";
+ args.email = $("#login_id").val();
+ args.full_name = $("#full_name").val();
- if(!args.usr || !args.pwd) {
- login.set_message("Both login and password required.");
+ if(!args.email || !valid_email(args.email) || !args.full_name) {
+ login.set_message("Valid email and name required.");
+ return false;
+ }
+ } else if(window.is_forgot) {
+ args.cmd = "reset_password";
+ args.user = $("#login_id").val();
+
+ if(!args.user) {
+ login.set_message("Valid Login Id required.");
+ return false;
+ }
+
+ } else {
+ args.cmd = "login"
+ args.usr = $("#login_id").val();
+ args.pwd = $("#password").val();
+
+ if(!args.usr || !args.pwd) {
+ login.set_message("Both login and password required.");
+ return false;
+ }
}
$('#login_btn').attr("disabled", "disabled");
+ $("#login-spinner").toggle(true);
$('#login_message').toggle(false);
$.ajax({
type: "POST",
url: "server.py",
- data: {cmd:"login", usr:args.usr, pwd: args.pwd},
+ data: args,
dataType: "json",
success: function(data) {
+ $("input").val("");
+ $("#login-spinner").toggle(false);
$('#login_btn').attr("disabled", false);
if(data.message=="Logged In") {
window.location.href = "app.html";
+ } else if(data.message=="No App") {
+ window.location.href = "index";
} else {
login.set_message(data.message);
}
@@ -47,28 +73,23 @@
return false;
}
-login.show_forgot_password = function(){
- // create dialog
- var login_id = $("#login_id").val();
- if(!login_id || !valid_email(login_id)) {
- login.set_message("Please set your login id (which is your email where the password will be sent);");
- return;
- }
- login.set_message("Sending email with new password...");
- $("#forgot-password").remove();
+login.sign_up = function() {
+ $("#login_wrapper h3").html("Sign Up");
+ $("#login-label").html("Email Id");
+ $("#password-row, #sign-up-wrapper, #login_message").toggle(false);
+ $("#full-name-row").toggle(true);
+ $("#login_btn").html("Register");
+ $("#forgot-wrapper").html("<a onclick='location.reload()' href='#'>Login</a>")
+ window.is_sign_up = true;
+}
- $.ajax({
- method: "POST",
- url: "server.py",
- data: {
- cmd: "reset_password",
- user: login_id,
- _type: "POST"
- },
- success: function(data) {
- login.set_message("A new password has been sent to your email id.", "GREEN");
- }
- })
+login.show_forgot_password = function() {
+ $("#login_wrapper h3").html("Forgot");
+ $("#login-label").html("Email Id");
+ $("#password-row, #sign-up-wrapper, #login_message").toggle(false);
+ $("#login_btn").html("Send Password");
+ $("#forgot-wrapper").html("<a onclick='location.reload()' href='#'>Login</a>")
+ window.is_forgot = true;
}
login.set_message = function(message, color) {
diff --git a/website/templates/pages/account.html b/website/templates/pages/account.html
new file mode 100644
index 0000000..9724651
--- /dev/null
+++ b/website/templates/pages/account.html
@@ -0,0 +1,65 @@
+{% extends "html/page.html" %}
+
+{% set title="My Account" %}
+
+{% block content %}
+<div class="span12">
+ <p class="pull-right"><a href="profile">Change my name, password</a></p>
+ <h3>My Orders</h3>
+ <div id="order-list">
+ <div class="progress progress-striped active">
+ <div class="bar" style="width: 100%;"></div>
+ </div>
+ </div>
+ <hr>
+ <h3>My Tickets</h3>
+ <div id="ticket-list">
+ <div class="progress progress-striped active">
+ <div class="bar" style="width: 100%;"></div>
+ </div>
+ </div>
+</div>
+<script>
+$(document).ready(function() {
+ var order_start = 0,
+ ticket_start = 0;
+
+ wn.call({
+ method: "website.helpers.account.get_orders",
+ args: {
+ start: order_start
+ },
+ callback: function(r) {
+ $("#order-list .progress").remove();
+ var $list = $("#order-list");
+
+ if(!(r.message && r.message.length)) {
+ $list.html("<div class='alert'>No Orders Yet</div>");
+ return;
+ }
+
+ $.each(r.message, function(i, order) {
+
+ // parent
+ var $order = $(repl('<div class="row">\
+ <div class="span4"><a href="order?id=%(name)s">%(name)s</a></span3>\
+ </div>', order)).appendTo($list);
+
+ // items
+ $.each(order.items || [], function(i, item) {
+ var $item = $(repl('<div class="span8">\
+ <div class="row">\
+ <div class="span4">%(item_name)s</div>\
+ <div class="span2">%(export_rate)s</div>\
+ <div class="span2">%(status)s</div>\
+ </div>\
+ </div>', item)).appendTo($order);
+ });
+
+ $("<hr>").appendTo($order);
+ });
+ }
+ })
+})
+</script>
+{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/login.html b/website/templates/pages/login.html
index ef9b7bb..6b847ff 100644
--- a/website/templates/pages/login.html
+++ b/website/templates/pages/login.html
@@ -10,7 +10,7 @@
{% set title="Login" %}
{% block body %}
- <div id='login_wrapper'>
+ <div class="container" id='login_wrapper'>
<div class='layout-wrapper layout-main'>
<p id="login_message" class="alert" style="display: none;"></p>
<h3><i class="icon-lock" style="margin-top: 7px"></i> Login</h3>
@@ -18,34 +18,45 @@
<table border="0" class="login-box">
<tbody>
<tr>
- <td style="text-align: right; padding: 3px;">Login Id</td>
+ <td style="text-align: right; padding: 3px;"
+ id="login-label">Login Id</td>
<td><input id="login_id" type="text" style="width: 180px"/></td>
</tr>
- <tr>
- <td style="text-align: right; padding: 3px;">Password</td>
+ <tr id="password-row">
+ <td style="text-align: right; padding: 3px;" >Password</td>
<td><input id="password" type="password" style="width: 180px" /></td>
</tr>
+ <tr id="full-name-row" style="display: none;">
+ <td style="text-align: right; padding: 3px;">Full Name</td>
+ <td><input id="full_name" type="text" style="width: 180px" /></td>
+ </tr>
<tr>
<td> </td>
<td>
<button type="submit" id="login_btn"
class="btn btn-small btn-primary">Login</button>
+ <img src="lib/images/ui/button-load.gif" id="login-spinner"
+ style="display: none;">
</td>
</tr>
</tbody>
</table>
</form>
<br>
- <p style="text-align: center"><a id="forgot-password"
+ <p style="text-align: center" id="forgot-wrapper">
+ <a id="forgot-password" style="cursor:pointer"
onclick="return login.show_forgot_password()">Forgot Password</a></p>
+ <p style="text-align: center" id="sign-up-wrapper">
+ New user? <a id="sign-up" style="cursor:pointer"
+ onclick="return login.sign_up()">Sign Up</a></p>
</div>
- <div class="login-footer">
- <a href="index.html">Home</a> |
- <a href="https://erpnext.com">ERPNext</a><br><br>
- {% if copyright %}
- <div class="web-footer-copyright">© {{ copyright }}
- {% endif %}
- </div>
+ </div>
+ <div class="web-footer login-footer container">
+ <a href="index.html">Home</a> |
+ <a href="https://erpnext.com">ERPNext</a><br><br>
+ {% if copyright %}
+ <div class="web-footer-copyright">© {{ copyright }}
+ {% endif %}
</div>
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/print.html b/website/templates/pages/print.html
new file mode 100644
index 0000000..a8decdf
--- /dev/null
+++ b/website/templates/pages/print.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Print Format</title>
+ <meta name="generator" content="wnframework">
+</head>
+<body>
+ {{ body }}
+</body>
+</html>
\ No newline at end of file
diff --git a/website/templates/pages/profile.html b/website/templates/pages/profile.html
new file mode 100644
index 0000000..d0d4059
--- /dev/null
+++ b/website/templates/pages/profile.html
@@ -0,0 +1,51 @@
+{% extends "html/page.html" %}
+
+{% set title="My Profile" %}
+
+{% block content %}
+<div class="span9">
+ <h2>My Profile</h2>
+ <hr>
+ <div class="alert" id="message" style="display: none;"></div>
+ <form class="form-horizontal">
+ <div class="control-group">
+ <label class="control-label" for="fullname">Full Name</label>
+ <div class="controls">
+ <input type="text" id="fullname" placeholder="Your Name">
+ </div>
+ </div>
+ <div class="control-group">
+ <label class="control-label" for="password">Password</label>
+ <div class="controls">
+ <input type="password" id="password" placeholder="Password">
+ </div>
+ </div>
+ <div class="control-group">
+ <div class="controls">
+ <button id="update_profile" type="submit" class="btn">Update</button>
+ </div>
+ </div>
+ </form>
+</div>
+<script>
+$(document).ready(function() {
+ $("#fullname").val(getCookie("full_name") || "");
+ $("#update_profile").click(function() {
+ wn.call({
+ method: "core.doctype.profile.profile.update_profile",
+ type: "POST",
+ args: {
+ fullname: $("#fullname").val(),
+ password: $("#password").val()
+ },
+ btn: this,
+ msg: $("#message"),
+ callback: function(r) {
+ if(!r.exc) $("#user-full-name").html($("#fullname").val());
+ }
+ });
+ return false;
+ })
+})
+</script>
+{% endblock %}
diff --git a/website/utils.py b/website/utils.py
index 443bde0..811a40d 100644
--- a/website/utils.py
+++ b/website/utils.py
@@ -43,10 +43,11 @@
"about": "website.doctype.about_us_settings.about_us_settings.get_args",
"contact": "Contact Us Settings",
"blog": "website.helpers.blog.get_blog_template_args",
- "writers": "website.helpers.blog.get_writers_args"
+ "writers": "website.helpers.blog.get_writers_args",
+ "print": "core.doctype.print_format.print_format.get_args"
}
-no_cache = "message"
+no_cache = ["message", "print"]
def render(page_name):
"""render html page"""