Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/public/build.json b/public/build.json
index 95fb8f0..375150a 100644
--- a/public/build.json
+++ b/public/build.json
@@ -7,10 +7,11 @@
 		"app/public/js/startup.css"
 	],
 	"public/js/all-web.js": [
-		"app/public/js/startup.js",
-		"app/public/js/conf.js"
+		"app/public/js/website_utils.js"
 	],
 	"public/js/all-app.js": [
+		"app/public/js/startup.js",
+		"app/public/js/conf.js",
 		"app/public/js/modules.js",
 		"app/public/js/toolbar.js",
 		"app/public/js/feature_setup.js",
diff --git a/public/js/startup.js b/public/js/startup.js
index a5ed4c4..10c9791 100644
--- a/public/js/startup.js
+++ b/public/js/startup.js
@@ -135,23 +135,6 @@
 	wn.updates.id = setInterval(erpnext.update_messages, 60000);
 }
 
-// subject, sender, description
-erpnext.send_message = function(opts) {
-	if(opts.btn) {
-		$(opts.btn).start_working();
-	}
-	wn.call({
-		method: 'website.send_message',
-		args: opts,
-		callback: function(r) { 
-			if(opts.btn) {
-				$(opts.btn).done_working();
-			}
-			if(opts.callback)opts.callback(r) 
-		}
-	});
-}
-
 erpnext.hide_naming_series = function() {
 	if(cur_frm.fields_dict.naming_series) {
 		hide_field('naming_series');
diff --git a/public/js/website_utils.js b/public/js/website_utils.js
new file mode 100644
index 0000000..eb6363f
--- /dev/null
+++ b/public/js/website_utils.js
@@ -0,0 +1,45 @@
+
+var erpnext = {};
+
+// subject, sender, description
+erpnext.send_message = function(opts) {
+	if(opts.btn) {
+		$(opts.btn).attr("disabled", "disabled");
+	}
+		
+	$.ajax({
+		method: "POST",
+		url: "server.py",
+		data: {
+			cmd: "website.send_message",
+			subject: opts.subject,
+			sender: opts.sender,
+			message: typeof opts.message == "string"
+				? opts.message
+				: JSON.stringify(opts.message)
+		},
+		dataType: "json",
+		success: function(data) {
+			if(opts.btn) {
+				$(opts.btn).attr("disabled", false);
+			}
+			if(opts.callback) 
+				opts.callback(data);
+		}
+	});
+}
+
+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; }
+
+function get_url_arg(name) {
+	name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
+	var regexS = "[\\?&]"+name+"=([^&#]*)";
+	var regex = new RegExp( regexS );
+	var results = regex.exec( window.location.href );
+	if(results == null)
+		return "";
+	else
+		return decodeURIComponent(results[1]);		
+}
\ No newline at end of file
diff --git a/stock/doctype/featured_item/featured_item.py b/stock/doctype/featured_item/featured_item.py
new file mode 100644
index 0000000..7f48feb
--- /dev/null
+++ b/stock/doctype/featured_item/featured_item.py
@@ -0,0 +1,22 @@
+# 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
+
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d, dl
\ No newline at end of file
diff --git a/website/__init__.py b/website/__init__.py
index 1a5a338..32d7116 100644
--- a/website/__init__.py
+++ b/website/__init__.py
@@ -6,6 +6,8 @@
 
 import webnotes
 
+max_tickets_per_hour = 200
+
 @webnotes.whitelist(allow_guest=True)
 def send_message():
 	from webnotes.model.doc import Document
@@ -17,15 +19,21 @@
 	d.raised_by = webnotes.form_dict.get('sender')
 	
 	if not d.description:
-		webnotes.msgprint('Please write something', raise_exception=True)
+		webnotes.response["message"] = 'Please write something'
+		return
 		
 	if not d.raised_by:
-		webnotes.msgprint('Please give us your email id so that we can write back to you', raise_exception=True)
+		webnotes.response["message"] = 'Email Id Required'
+		return
 	
-	# make lead or contact
+	# guest method, cap max writes per hour
+	if webnotes.conn.sql("""select count(*) from `tabSupport Ticket`
+		where TIMEDIFF(NOW(), modified) < '01:00:00'""")[0][0] > max_tickets_per_hour:
+		webnotes.response["message"] = "Sorry: we believe we have received an unreasonably high number of requests of this kind. Please try later"
+		return
 	
 	d.save()
-	webnotes.msgprint('Thank you!')
+	webnotes.response["message"] = 'Thank You'
 	
 def get_site_address():
 	from webnotes.utils import get_request_site_address
diff --git a/website/templates/css/login.css b/website/templates/css/login.css
index 1f36e53..b7b7fca 100644
--- a/website/templates/css/login.css
+++ b/website/templates/css/login.css
@@ -5,6 +5,7 @@
 		}
 
 		.layout-wrapper {
+			background-color: #fff;
 			padding: 10px;
 			box-shadow: 1px 1px 3px 3px #ccc;
 			font-size: 12px;
diff --git a/website/templates/html/page.html b/website/templates/html/page.html
index e2eb6f4..11d7b0f 100644
--- a/website/templates/html/page.html
+++ b/website/templates/html/page.html
@@ -5,28 +5,12 @@
 {% block header %}
 	{{ super() }}
 	<script>
-	window.page_name = "{{ name }}";
-
-	$(document).bind('app_ready', function() {
-		var _page = new wn.views.Page(window.page_name);
-	
-		// page script
-		{% block javascript %}
-		{% endblock %}
-	
-		// trigger onload
-		_page.trigger('onload');
-	
-		// activate page
-		wn.container.change_to(window.page_name);
-	});
+	{% block javascript %}
+	{% endblock %}
 	</script>
-	
 	{% block css %}
-	{% if insert_style %}
-	
+	{% if insert_style %}	
 	<style>{{ css }}</style>
-
 	{% endif %}
 	{% endblock %}
 {% endblock %}
diff --git a/website/templates/html/product_group.html b/website/templates/html/product_group.html
new file mode 100644
index 0000000..d5e1871
--- /dev/null
+++ b/website/templates/html/product_group.html
@@ -0,0 +1 @@
+{% extends "html/page.html" %}
diff --git a/website/templates/js/login.js b/website/templates/js/login.js
index eb3a65c..b57db49 100644
--- a/website/templates/js/login.js
+++ b/website/templates/js/login.js
@@ -1,13 +1,13 @@
 
-wn.provide('erpnext.login');
+var login = {};
 
 $(document).ready(function(wrapper) {
-	$('#login_btn').click(erpnext.login.doLogin)
+	$('#login_btn').click(login.do_login)
 		
 	$('#password').keypress(function(ev){
 		if(ev.which==13 && $('#password').val()) {
 			$('form').submit(function() {
-				erpnext.login.doLogin();
+				login.do_login();
 				return false;
 			});
 		}
@@ -16,54 +16,60 @@
 })
 
 // Login
-erpnext.login.doLogin = function(){
+login.do_login = function(){
 
     var args = {};
     args['usr']=$("#login_id").val();
     args['pwd']=$("#password").val();
 
 	if(!args.usr || !args.pwd) {
-		msgprint("Sorry, you can't login if you don't enter both the email id and password.")
+		login.set_message("Both login and password required.");
 	}
 
-	$('#login_btn').set_working();
-	$('#login_message').empty();
+	$('#login_btn').attr("disabled", "disabled");
+	$('#login_message').toggle(false);
 	
-    $c("login", args, function(r, rtext) {
-		$('#login_btn').done_working();
-	    if(r.message=="Logged In"){
-	        window.location.href='app.html' + (get_url_arg('page') 
-				? ('?page='+get_url_arg('page')) : '');
-	    } else {
-	        $i('login_message').innerHTML = '<span style="color: RED;">'
-				+(r.message)+'</span>';
-	    }
-	});
-
+	$.ajax({
+		type: "POST",
+		url: "server.py",
+		data: {cmd:"login", usr:args.usr, pwd: args.pwd},
+		dataType: "json",
+		success: function(data) {
+			$('#login_btn').attr("disabled", false);
+			if(data.message=="Logged In") {
+				window.location.href = "app.html";
+			} else {
+				login.set_message(data.message);
+			}
+		}
+	})
+	
 	return false;
 }
 
-
-erpnext.login.show_forgot_password = function(){
+login.show_forgot_password = function(){
     // create dialog
-	var d = new wn.ui.Dialog({
-		title:"Forgot Password",
-		fields: [
-			{'label':'Email Id', 'fieldname':'email_id', 'fieldtype':'Data', 'reqd':true},
-			{'label':'Email Me A New Password', 'fieldname':'run', 'fieldtype':'Button'}
-		]
-	});
+	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();
 
-	$(d.fields_dict.run.input).click(function() {
-		var values = d.get_values();
-		if(!values) return;
-		wn.call({
-			method:'reset_password',
-			args: { user: values.email_id },
-			callback: function() {
-				d.hide();
-			}
-		})
+	$.ajax({
+		method: "POST",
+		url: "server.py",
+		data: {
+			cmd: "reset_password",
+			user: login_id
+		},
+		success: function(data) {
+			login.set_message("A new password has been sent to your email id.", "GREEN");
+		}
 	})
-	d.show();
+}
+
+login.set_message = function(message, color) {
+    $('#login_message').html(message).toggle(true);	
 }
\ No newline at end of file
diff --git a/website/templates/pages/login.html b/website/templates/pages/login.html
index a81b2f5..0828f65 100644
--- a/website/templates/pages/login.html
+++ b/website/templates/pages/login.html
@@ -14,6 +14,7 @@
 {% block body %}
 	<div 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>
 			<form autocomplete="on">
 				<table border="0" class="login-box">
@@ -33,15 +34,12 @@
 									class="btn btn-small btn-primary">Login</button>
 							</td>
 						</tr>
-						<tr>
-							<td>&nbsp;</td>
-							<td id="login_message">&nbsp;</td>
-						</tr>
 						</tbody>
 				</table>
 			</form>
-			<p style="text-align: center"><span class="link_type" 
-				onclick="erpnext.login.show_forgot_password()">Forgot Password</span></p>
+			<br>
+			<p style="text-align: center"><a id="forgot-password"
+				onclick="return login.show_forgot_password()">Forgot Password</a></p>
 		</div>
 		<div class="login-footer">
 			<a href="index.html">Home</a> | 
diff --git a/website/utils.py b/website/utils.py
index 991a486..0fc5f98 100644
--- a/website/utils.py
+++ b/website/utils.py
@@ -33,6 +33,10 @@
 	'Item': webnotes._dict({
 		"template": 'html/product_page.html',
 		"condition_field": "show_in_website",
+	}),
+	'Item Group': webnotes._dict({
+		"template": "html/product_group.html",
+		"condition_field": "show_in_website"
 	})
 }