Improvements in product page and its listing
Login page rendered via a template
diff --git a/build.json b/build.json
index 7b1dfe6..6efbbc3 100644
--- a/build.json
+++ b/build.json
@@ -23,7 +23,4 @@
"public/js/complete_setup.js": [
"erpnext/startup/js/complete_setup.js",
],
- "public/js/product_category.js": [
- "erpnext/website/js/product_category.js",
- ],
}
\ No newline at end of file
diff --git a/erpnext/patches/june_2012/cms2.py b/erpnext/patches/june_2012/cms2.py
index 48f0152..08174cb 100644
--- a/erpnext/patches/june_2012/cms2.py
+++ b/erpnext/patches/june_2012/cms2.py
@@ -18,6 +18,12 @@
delete from `tabPage`
where module='Website' and ifnull(web_page, 'No') = 'Yes'""")
+ # change show_in_website value in item table to 0 or 1
+ webnotes.conn.sql("""\
+ update `tabItem`
+ set show_in_website = if(show_in_website = 'Yes', 1, 0)
+ where show_in_website is not null""")
+
def save_pages():
"""save all web pages, blogs to create content"""
import webnotes
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 65698c1..572a790 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -29,8 +29,23 @@
}
$c_obj(make_doclist(doc.doctype, doc.name),'check_if_sle_exists','',callback);
}
+
+ cur_frm.cscript.hide_website_fields(doc);
}
+cur_frm.cscript.hide_website_fields = function(doc) {
+ var website_fields_list = ['page_name', 'website_image', 'web_short_description',
+ 'web_long_description']
+ if (cint(doc.show_in_website)) {
+ unhide_field(website_fields_list);
+ } else {
+ hide_field(website_fields_list);
+ }
+}
+
+cur_frm.cscript.show_in_website = function(doc, dt, dn) {
+ cur_frm.cscript.hide_website_fields(doc);
+}
cur_frm.fields_dict['default_bom'].get_query = function(doc) {
//var d = locals[this.doctype][this.docname];
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 85af0bb..b2c9235 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -225,37 +225,6 @@
def on_rename(self,newdn,olddn):
sql("update tabItem set item_code = %s where name = %s", (newdn, olddn))
- # def make_page(self):
- # if self.doc.show_in_website=='Yes':
- #
- # import website.utils
- #
- # if self.doc.page_name:
- # import webnotes.model
- # webnotes.model.delete_doc('Page', self.doc.page_name)
- #
- # p = website.utils.add_page("Product " + self.doc.item_name)
- # self.doc.page_name = p.name
- #
- # from jinja2 import Template
- # import markdown2
- # import os
- #
- #
- # self.doc.long_description_html = markdown2.markdown(self.doc.description or '')
- #
- # with open(os.path.join(os.path.dirname(__file__), 'template.html'), 'r') as f:
- # p.content = Template(f.read()).render(doc=self.doc)
- #
- # with open(os.path.join(os.path.dirname(__file__), 'product_page.js'), 'r') as f:
- # p.script = Template(f.read()).render(doc=self.doc)
- #
- # p.save()
- #
- # website.utils.add_guest_access_to_page(p.name)
- #
- # del self.doc.fields['long_description_html']
- #
def clear_web_cache(self):
import website.web_cache
@@ -263,14 +232,22 @@
self.doc.page_name != self.old_page_name:
website.web_cache.delete_web_cache(self.old_page_name)
- if self.doc.show_in_website == 'Yes':
+ if self.doc.show_in_website:
website.web_cache.clear_web_cache(self.doc.doctype, self.doc.name, self.doc.page_name)
else:
website.web_cache.delete_web_cache(self.doc.page_name)
def update_page_name(self):
import website.utils
- self.doc.page_name = website.utils.page_name(self.doc.name + " " + self.doc.item_name)
+
+ # if same name, do not repeat twice
+ if self.doc.name == self.doc.item_name:
+ page_name = self.doc.name
+ else:
+ page_name = self.doc.name + " " + self.doc.item_name
+
+ self.doc.page_name = website.utils.page_name(page_name)
+
webnotes.conn.set_value('Item', self.doc.name, 'page_name', self.doc.page_name)
# no need to check for uniqueness, as name is unique
@@ -279,5 +256,3 @@
import markdown2
self.doc.web_description_html = markdown2.markdown(self.doc.description or '',
extras=["wiki-tables"])
-
-
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/item.txt b/erpnext/stock/doctype/item/item.txt
index 8a079b8..06806ba 100644
--- a/erpnext/stock/doctype/item/item.txt
+++ b/erpnext/stock/doctype/item/item.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-04-30 18:33:53',
+ 'creation': '2012-06-08 12:54:51',
'docstatus': 0,
- 'modified': '2012-06-07 16:16:24',
+ 'modified': '2012-07-04 11:10:29',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -59,73 +59,6 @@
# DocPerm
{
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Material Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Material Manager',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Material User',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 0,
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Material User',
- 'submit': 0,
- 'write': 0
- },
-
- # DocPerm
- {
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Material Master Manager',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 0,
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'Material Master Manager',
- 'write': 0
- },
-
- # DocPerm
- {
'cancel': 1,
'create': 1,
'doctype': u'DocPerm',
@@ -136,11 +69,78 @@
# DocPerm
{
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Material Master Manager',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Material Master Manager',
+ 'write': 1
+ },
+
+ # DocPerm
+ {
'doctype': u'DocPerm',
'permlevel': 1,
'role': u'System Manager'
},
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Material Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Material Manager',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Material User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Material User',
+ 'submit': 0,
+ 'write': 0
+ },
+
# DocField
{
'doctype': u'DocField',
@@ -734,26 +734,6 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'show_in_website',
- 'fieldtype': u'Select',
- 'label': u'Show in Website',
- 'options': u'No\nYes',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'website_image',
- 'fieldtype': u'Select',
- 'label': u'website_image',
- 'options': u'attach_files:',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
'fieldname': u'max_discount',
'fieldtype': u'Currency',
'label': u'Max Discount (%)',
@@ -796,17 +776,6 @@
# DocField
{
- 'colour': u'White:FFF',
- 'description': u'website page link',
- 'doctype': u'DocField',
- 'fieldname': u'page_name',
- 'fieldtype': u'Data',
- 'label': u'Page Name',
- 'permlevel': 1
- },
-
- # DocField
- {
'doctype': u'DocField',
'fieldname': u'column_break3',
'fieldtype': u'Column Break',
@@ -994,5 +963,63 @@
'no_copy': 1,
'permlevel': 0,
'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'website_section',
+ 'fieldtype': u'Section Break',
+ 'label': u'Website',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'show_in_website',
+ 'fieldtype': u'Check',
+ 'label': u'Show in Website',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'website page link',
+ 'doctype': u'DocField',
+ 'fieldname': u'page_name',
+ 'fieldtype': u'Data',
+ 'label': u'Page Name',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'website_image',
+ 'fieldtype': u'Select',
+ 'label': u'Image',
+ 'options': u'attach_files:',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'web_short_description',
+ 'fieldtype': u'Text',
+ 'label': u'Short Description',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'web_long_description',
+ 'fieldtype': u'Code',
+ 'label': u'Long Description',
+ 'options': u'Markdown',
+ 'permlevel': 0
}
]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/product_page.js b/erpnext/stock/doctype/item/product_page.js
deleted file mode 100644
index 926ef69..0000000
--- a/erpnext/stock/doctype/item/product_page.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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/>.
-
-wn.require('erpnext/website/js/product_category.js');
-
-pscript["onload_{{ doc.page_name }}"] = function(wrapper) {
- wrapper.product_group = "{{ doc.item_group }}";
- wrapper.product_name = "{{ doc.name }}";
- erpnext.make_product_categories(wrapper);
- $(wrapper).find('.product-inquiry').click(function() {
- loadpage('contact', function() {
- $('#content-contact-us [name="contact-message"]').val("Hello,\n\n\
- Please send me more information on {{ doc.title }} (Item Code:{{ doc.item }})\n\n\
- My contact details are:\n\nThank you!\
- ");
- })
- });
-
- // similar products
- wrapper.similar = new wn.ui.Listing({
- parent: $(wrapper).find('.similar-products').get(0),
- hide_refresh: true,
- page_length: 5,
- get_query: function() {
- args = {
- cat: wrapper.product_group,
- name: wrapper.product_name
- };
- 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 t1.name != "%(name)s" \
- and t2.item_group="%(cat)s" order by t1.modified desc', args)
- },
- render_row: function(parent, data) {
- if(data.short_description.length > 100) {
- data.short_description = data.short_description.substr(0,100) + '...';
- }
- parent.innerHTML = repl('<div style="float:left; width: 60px;">\
- <img src="files/%(thumbnail_image)s" style="width:55px;"></div>\
- <div style="float:left; width: 180px">\
- <b><a href="#!%(page_name)s">%(title)s</a></b>\
- <p>%(short_description)s</p></div>\
- <div style="clear: both; margin-bottom: 15px;"></div>', data);
- }
- });
- wrapper.similar.run();
-}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/template.html b/erpnext/stock/doctype/item/template.html
deleted file mode 100644
index 8a2f4a9..0000000
--- a/erpnext/stock/doctype/item/template.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<div class="layout-wrapper layout-wrapper-background">
- <div class="web-content" id="content-product-{{ doc.name }}">
- <div class="layout-main-section">
- <h1>{{ doc.item_name }}</h1>
- <div style="float: left;">
- <br><br>
- <image src="files/{{ doc.website_image }}" style="width: 300px;
- margin-left: 15px;" />
- <br><br>
- {{ doc.long_description_html }}
- <button class="btn primary product-inquiry"
- data-product="{{ doc.name }}"
- data-description="{{ doc.short_description }}">Send Inquiry</button>
- </div>
- </div>
- <div class="layout-side-section">
- <h4>More Categories</h4>
- <div class="more-categories"></div>
- <br>
- <h4>Similar Products</h4>
- <div class="similar-products"></div>
- </div>
- <div style="clear: both"></div>
- </div>
-</div>
\ No newline at end of file
diff --git a/erpnext/website/product.py b/erpnext/website/product.py
new file mode 100644
index 0000000..7c6603a
--- /dev/null
+++ b/erpnext/website/product.py
@@ -0,0 +1,97 @@
+import webnotes
+
+@webnotes.whitelist(allow_guest=True)
+def get_product_list(args=None):
+ """
+ args = {
+ 'limit_start': 0,
+ 'limit_page_length': 20,
+ 'search': '',
+ 'product_group': '',
+ }
+ """
+ import webnotes
+ from webnotes.utils import cstr, cint
+
+ if not args: args = webnotes.form_dict
+
+ # dict to be passed to sql function
+ query_args = {
+ 'limit_start': cint(args.get('limit_start')),
+ 'limit_page_length': cint(args.get('limit_page_length'))
+ }
+
+ # base query
+ query = """\
+ select name, item_name, page_name, website_image,
+ description, web_short_description
+ from `tabItem`
+ where is_sales_item = 'Yes'
+ and docstatus = 0
+ and show_in_website = 1"""
+
+ # search term condition
+ if args.get('search'):
+ query += """
+ and (
+ web_short_description like %(search)s or
+ web_long_description like %(search)s or
+ description like %(search)s or
+ item_name like %(search)s or
+ name like %(search)s
+ )"""
+ query_args['search'] = "%" + cstr(args.get('search')) + "%"
+
+ # product group condition
+ if args.get('product_group') and args.get('product_group') != 'All Products':
+ query += """
+ and item_group = %(product_group)s"""
+ query_args['product_group'] = args.get('product_group')
+
+ # order by
+ query += """
+ order by item_name asc, name asc"""
+
+ if args.get('limit_page_length'):
+ query += """
+ limit %(limit_start)s, %(limit_page_length)s"""
+
+ return webnotes.conn.sql(query, query_args, as_dict=1)
+
+@webnotes.whitelist(allow_guest=True)
+def get_product_category_list():
+ import webnotes
+
+ result = webnotes.conn.sql("""\
+ select count(name) as items, item_group
+ from `tabItem`
+ where is_sales_item = 'Yes'
+ and docstatus = 0
+ and show_in_website = 1
+ group by item_group
+ order by items desc""", as_dict=1)
+
+ # add All Products link
+ total_count = sum((r.get('items') or 0 for r in result))
+ result = [{'items': total_count, 'item_group': 'All Products'}] + (result or [])
+
+ return result
+
+@webnotes.whitelist(allow_guest=True)
+def get_similar_product_list(args=None):
+ import webnotes
+
+ if not args: args = webnotes.form_dict
+
+ result = webnotes.conn.sql("""\
+ select name, item_name, page_name, website_image,
+ description, web_short_description
+ from `tabItem`
+ where is_sales_item = 'Yes'
+ and docstatus = 0
+ and show_in_website = 1
+ and name != %(product_name)s
+ and item_group = %(product_group)s
+ order by item_name""", args, as_dict=1)
+
+ return result
\ No newline at end of file
diff --git a/erpnext/website/templates/login/login.html b/erpnext/website/templates/login/login.html
new file mode 100644
index 0000000..834fc27
--- /dev/null
+++ b/erpnext/website/templates/login/login.html
@@ -0,0 +1,53 @@
+{% extends "login/login.js" %}
+
+{% block css %}
+ <style>
+ #login_wrapper {
+ width: 300px !important;
+ margin: 20px auto;
+ }
+
+ .login-banner {
+ margin-bottom: 20px;
+ }
+ </style>
+{% endblock %}
+
+{% block content %}
+ <div class="layout-wrapper layout-wrapper-appframe" id='login_wrapper'>
+ <div class="appframe-area"></div>
+ <div class="layout-main" style="padding: 15px;">
+ <form autocomplete="on">
+ <table border="0" cellspacing="8">
+ <tbody>
+ <tr>
+ <td>Login Id</td>
+ <td><input id="login_id" type="text" style="width: 180px"/></td>
+ </tr>
+ <tr>
+ <td>Password</td>
+ <td><input id="password" type="password" style="width: 180px" /></td>
+ </tr>
+ <tr>
+ <td style="text-align:right"><input id="remember_me" type="checkbox" /></td>
+ <td>Remember Me</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td id="login_message"> </td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>
+ <button type="submit" id="login_btn" class="btn btn-small btn-primary">Login</button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+ <p style="margin-left: 72px;"><span class="link_type"
+ onclick="erpnext.login.show_forgot_password()">Forgot Password</span></p>
+ </div>
+ </div>
+
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/templates/login/login.js b/erpnext/website/templates/login/login.js
new file mode 100644
index 0000000..d6b6b24
--- /dev/null
+++ b/erpnext/website/templates/login/login.js
@@ -0,0 +1,103 @@
+{% extends "page.html" %}
+
+{% block javascript %}
+{{ super() }}
+// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
+//
+// MIT License (MIT)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+wn.provide('erpnext.login');
+
+wn.pages["{{ name }}"].onload = function(wrapper) {
+ wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'));
+ wrapper.appframe.title('Login');
+ wrapper.appframe.$w.find('.close').toggle(false);
+
+ var lw = $i('login_wrapper');
+ $bs(lw, '1px 1px 3px #888');
+
+ $('#login_btn').click(erpnext.login.doLogin)
+
+ $('#password').keypress(function(ev){
+ if(ev.which==13 && $('#password').val()) {
+ $('form').submit(function() {
+ erpnext.login.doLogin();
+ return false;
+ });
+ }
+ });
+ $(document).trigger('login_rendered');
+}
+
+// Login Callback
+erpnext.login.onLoginReply = 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>';
+ //if(r.exc)alert(r.exc);
+ }
+}
+
+
+// Login
+erpnext.login.doLogin = function(){
+
+ var args = {};
+ args['usr']=$i("login_id").value;
+ args['pwd']=$i("password").value;
+ if($i('remember_me').checked)
+ args['remember_me'] = 1;
+
+ $('#login_btn').set_working();
+
+ $c("login", args, erpnext.login.onLoginReply);
+
+ return false;
+}
+
+
+erpnext.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'}
+ ]
+ });
+
+ $(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();
+ }
+ })
+ })
+ d.show();
+}
+
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/templates/product/product.html b/erpnext/website/templates/product/product.html
index 5d3c3da..6f33ec9 100644
--- a/erpnext/website/templates/product/product.html
+++ b/erpnext/website/templates/product/product.html
@@ -1,23 +1,30 @@
{% extends "product/product.js" %}
-{% block title %}{{ item_name }} [{{ name }}]{% endblock %}
+{% block title %}
+ {% if item_name != name %}
+ {{ item_name }} [{{ name }}]
+ {% else %}
+ {{ item_name }}
+ {% endif %}
+{% endblock %}
{% block content %}
<div class="layout-wrapper layout-wrapper-background">
<div class="web-content" id="content-product-{{ name }}">
<div class="layout-main-section">
<h1>{{ item_name }}</h1>
- <div style="float: left;">
+ <div class="product-page-content">
<br><br>
{% if website_image %}
- <image src="files/{{ website_image }}" style="width: 300px;
- margin-left: 15px;" />
- <br><br>
+ <image src="files/{{ website_image }}" />
+ {% else %}
+ <div class="img-area"></div>
+ <span style="font-size: 11px">This is an auto-generated Image</span>
{% endif %}
+ <br><br>
+ <div class="web-long-description">
{{ web_description_html }}
- <button class="btn primary product-inquiry"
- data-product="{{ name }}"
- data-description="{{ description }}">Send Inquiry</button>
+ </div>
</div>
</div>
<div class="layout-side-section">
@@ -31,3 +38,40 @@
</div>
</div>
{% endblock %}
+
+{% block css %}
+ <style>
+ .web-long-description {
+ font-size: 18px;
+ line-height: 200%;
+ }
+ .product-page-content {
+ float: left;
+ }
+ /* product page image css */
+ .product-page-content img {
+ max-width: 100%;
+ }
+
+ /* similar products listing */
+ .similar-products .img-area img {
+ max-width: 55px;
+ max-height: 55px;
+ }
+
+ .similar-products .img-area {
+ float: left;
+ width: 30%;
+ margin-top: 0.3em;
+ }
+
+ .similar-product-description {
+ float: left;
+ width: 70%;
+ }
+
+ .similar-product-description span {
+ font-size: 12px;
+ }
+</style>
+{% endblock %}
diff --git a/erpnext/website/templates/product/product.js b/erpnext/website/templates/product/product.js
index 3475204..9e51334 100644
--- a/erpnext/website/templates/product/product.js
+++ b/erpnext/website/templates/product/product.js
@@ -22,52 +22,60 @@
wrapper.product_group = "{{ item_group }}";
wrapper.product_name = "{{ name }}";
erpnext.products.make_product_categories(wrapper);
+ erpnext.products.make_similar_products(wrapper);
+
+ // if website image missing, autogenerate one
+ var $img = $('.product-page-content').find('.img-area');
+ if ($img && $img.length > 0) {
+ $img.append(wn.dom.placeholder(160, "{{ item_name }}"));
+ }
- // TODO make this working
- $(wrapper).find('.product-inquiry').click(function() {
- loadpage('contact', function() {
- $('#content-contact-us [name="contact-message"]').val("Hello,\n\n\
- Please send me more information on {{ item_name }} (Item Code:{{ name }})\n\n\
- My contact details are:\n\nThank you!\
- ");
- })
- });
+ // adjust page height based on sidebar height
+ var $main_page = $('.layout-main-section');
+ var $sidebar = $('.layout-side-section');
+ if ($sidebar.height() > $main_page.height()) {
+ $main_page.height($sidebar.height());
+ }
+
+}
+
+erpnext.products.make_similar_products = function(wrapper) {
+ if (!wrapper) { wrapper = erpnext.products.wrapper; }
+ if (!wrapper) { return; }
// similar products
wrapper.similar = new wn.ui.Listing({
parent: $(wrapper).find('.similar-products').get(0),
hide_refresh: true,
page_length: 5,
- get_query: function() {
- args = {
- cat: wrapper.product_group,
- name: wrapper.product_name
- };
- var query = repl('select name, item_name, website_image, \
- page_name, description \
- from tabItem \
- where is_sales_item="Yes" \
- and ifnull(show_in_website, "No")="Yes" \
- and name != "%(name)s" and docstatus = 0 \
- and item_group="%(cat)s" order by modified desc', args)
- return query
+ method: 'website.product.get_similar_product_list',
+ get_args: function() {
+ return {
+ product_group: wrapper.product_group,
+ product_name: wrapper.product_name
+ }
},
render_row: function(parent, data) {
- if(data.description.length > 100) {
- data.description = data.description.substr(0,100) + '...';
+ if (!data.web_short_description) {
+ data.web_short_description = data.description;
+ }
+ if(data.web_short_description.length > 100) {
+ data.web_short_description =
+ data.web_short_description.substr(0,100) + '...';
}
parent.innerHTML = repl('\
- <div style="float:left; width: 60px; padding-bottom: 5px" class="img-area"></div>\
- <div style="float:left; width: 180px">\
- <b><a href="%(page_name)s.html">%(item_name)s</a></b>\
- <p>%(description)s</p></div>\
- <div style="clear: both; margin-bottom: 15px;"></div>', data);
+ <a href="%(page_name)s.html"><div class="img-area"></div></a>\
+ <div class="similar-product-description">\
+ <h5><a href="%(page_name)s.html">%(item_name)s</a></h5>\
+ <span>%(web_short_description)s</span>\
+ </div>\
+ <div style="clear:both"></div>', data);
if(data.website_image) {
$(parent).find('.img-area').append(repl(
- '<img src="files/%(website_image)s" style="width:55px;">', data))
+ '<img src="files/%(website_image)s" />', data))
} else {
- $(parent).find('.img-area').append(wn.dom.placeholder(50,
+ $(parent).find('.img-area').append(wn.dom.placeholder(55,
data.item_name));
}
}
diff --git a/erpnext/website/templates/product/product_category.js b/erpnext/website/templates/product/product_category.js
index d8b09b3..e1905ac 100644
--- a/erpnext/website/templates/product/product_category.js
+++ b/erpnext/website/templates/product/product_category.js
@@ -8,12 +8,7 @@
wrapper.category_list = new wn.ui.Listing({
parent: $(wrapper).find('.more-categories').get(0),
- query: 'select count(name) as items, item_group \
- from tabItem \
- where is_sales_item="Yes" and \
- ifnull(show_in_website, "No")="Yes" and \
- docstatus = 0 \
- group by item_group order by items desc',
+ method: 'website.product.get_product_category_list',
hide_refresh: true,
render_row: function(parent, data) {
parent.innerHTML = repl(
diff --git a/erpnext/website/templates/product/product_list.html b/erpnext/website/templates/product/product_list.html
index 100bfca..24d5590 100644
--- a/erpnext/website/templates/product/product_list.html
+++ b/erpnext/website/templates/product/product_list.html
@@ -2,17 +2,6 @@
{% block title %}Products{% endblock %}
-{% block css %}
- <style>
- h3 > a, h3 > a:link, h3 > a:visited, h3 > a:active,
- h3 > a:hover, h3 > a:focus {
- text-decoration: none;
- color: inherit;
- }
- </style>
-{% endblock %}
-
-
{% block content %}
<div class="layout-wrapper layout-wrapper-background">
<div class="web-content" id="content-products">
@@ -29,10 +18,24 @@
</div>
<div class="layout-side-section">
- <h3><a href="products.html">Categories</a></h3>
+ <h3>Categories</h3>
<div class="more-categories"></div>
</div>
<div style="clear: both"></div>
</div>
</div>
+{% endblock %}
+
+{% block css %}
+ <style>
+ .img-area {
+ float:left;
+ width: 115px;
+ }
+
+ .product-list-description {
+ float:left;
+ width: 400px;
+ }
+ </style>
{% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/templates/product/product_list.js b/erpnext/website/templates/product/product_list.js
index 5166fed..1c6f934 100644
--- a/erpnext/website/templates/product/product_list.js
+++ b/erpnext/website/templates/product/product_list.js
@@ -31,8 +31,6 @@
// make lists
erpnext.products.make_product_list(wrapper);
- // erpnext.products.product_list.run();
-
// bind search button or enter key
$(wrapper).find('.products-search .btn').click(function() {
erpnext.products.product_list.run();
@@ -51,30 +49,22 @@
parent: $(wrapper).find('#products-list').get(0),
run_btn: $(wrapper).find('.products-search .btn').get(0),
no_toolbar: true,
- get_query: function() {
- var srch = $('input[name="products-search"]').val()
- var search_cond = 'and (description like "%%(srch)s%"\
- or item_name like "%%(srch)s%")';
- var product_group_cond = 'and item_group="%(group)s"';
- var cur_group = erpnext.products.cur_group
- args = {
- search_cond: srch ? repl(search_cond, {srch:srch}) : '',
- cat: cur_group ? repl(product_group_cond, {group: cur_group}) : '',
+ method: 'website.product.get_product_list',
+ get_args: function() {
+ return {
+ search: $('input[name="products-search"]').val() || '',
+ product_group: erpnext.products.cur_group || '',
};
- return repl('select name, item_name, website_image, \
- description, page_name \
- from tabItem \
- where is_sales_item="Yes" \
- %(cat)s \
- and docstatus = 0 and ifnull(show_in_website, "No")="Yes"\
- %(search_cond)s', args)
},
render_row: function(parent, data) {
+ if (!data.web_short_description) {
+ data.web_short_description = data.description;
+ }
parent.innerHTML = repl('\
- <div style="float:left; width: 115px;" class="img-area"></div>\
- <div style="float:left; width: 400px">\
- <p><b><a href="%(page_name)s.html">%(item_name)s</a></b></p>\
- <p>%(description)s</p></div>\
+ <a href="%(page_name)s.html"><div class="img-area"></div></a>\
+ <div class="product-list-description">\
+ <h4><a href="%(page_name)s.html">%(item_name)s</a></h4>\
+ <p>%(web_short_description)s</p></div>\
<div style="clear: both;"></div>', data);
if(data.website_image) {
diff --git a/erpnext/website/web_cache.py b/erpnext/website/web_cache.py
index 42bd1d1..dbed844 100644
--- a/erpnext/website/web_cache.py
+++ b/erpnext/website/web_cache.py
@@ -32,7 +32,8 @@
where name = %s""", page_name)
# if page doesn't exist, raise exception
- if not res and page_name not in ['404', 'index', 'blog', 'products']:
+ page_exception_list = ['404', 'index', 'blog', 'products', 'login-page']
+ if not res and page_name not in page_exception_list:
raise Exception, "Page %s not found" % page_name
html, doc_type, doc_name = res and res[0] or (None, None, None)
@@ -55,7 +56,7 @@
import webnotes
outer_env_dict = get_outer_env()
- if page_name in ['404', 'blog', 'products']:
+ if page_name in ['404', 'blog', 'products', 'login-page']:
args = outer_env_dict
args.update({
'name': page_name,
@@ -80,12 +81,14 @@
args.update({ 'insert_code': 1 })
elif doc_type == 'Web Page':
template = 'web_page.html'
- elif page_name == 'blog':
- template = 'blog/blog_list.html'
+ else:
args.update({ 'insert_code': 1 })
- elif page_name == 'products':
- template = 'product/product_list.html'
- args.update({ 'insert_code': 1 })
+ if page_name == 'blog':
+ template = 'blog/blog_list.html'
+ elif page_name == 'products':
+ template = 'product/product_list.html'
+ elif page_name == 'login-page':
+ template = 'login/login.html'
html = build_html(args, template)
diff --git a/public/js/product_category.js b/public/js/product_category.js
deleted file mode 100644
index da50d78..0000000
--- a/public/js/product_category.js
+++ /dev/null
@@ -1,10 +0,0 @@
-
-/*
- * erpnext/website/js/product_category.js
- */
-erpnext.make_product_categories=function(wrapper){wrapper.category_list=new wn.ui.Listing({parent:$(wrapper).find('.more-categories').get(0),query:'select count(name) as items, item_group \
- from tabItem \
- where is_sales_item="Yes" and \
- ifnull(show_in_website, "No")="Yes" and \
- docstatus = 0 \
- group by item_group order by items desc',hide_refresh:true,render_row:function(parent,data){parent.innerHTML=repl('<a href="#!products/%(item_group)s">%(item_group)s</a> (%(items)s)',data);}});wrapper.category_list.run();console.log('product categories made');}
\ No newline at end of file