Merge branch 'master' of github.com:webnotes/erpnext

This commit is contained in:
Nabin Hait 2012-12-19 10:35:40 +05:30
commit 08196f59ec
25 changed files with 528 additions and 618 deletions

View File

@ -149,7 +149,8 @@ class DocType:
def manage_default_bom(self):
""" Uncheck others if current one is selected as default, update default bom in item master"""
webnotes.conn.set(self.doc, "is_default", cint(self.doc.is_default))
if self.doc.is_default and self.doc.is_active == 'Yes':
sql("update `tabBOM` set is_default = 0 where name != %s and item=%s", (self.doc.name, self.doc.item))

View File

@ -33,7 +33,7 @@ KBItemToolbar = function(args, kb) {
this.make_timestamp = function() {
this.line1.innerHTML = repl('By %(name)s | %(when)s', {
name: wn.utils.full_name(this.det.first_name, this.det.last_name),
name: wn.user_info(this.det.owner).fullname,
when: wn.datetime.comment_when(this.det.modified)
});

View File

@ -17,6 +17,9 @@
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
cur_frm.cscript.set_root_readonly(doc);
cur_frm.add_custom_button("Item Group Tree", function() {
wn.set_route("Sales Browser", "Item Group");
})
}
cur_frm.cscript.set_root_readonly = function(doc) {

View File

@ -24,4 +24,21 @@ class DocType(DocTypeNestedSet):
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
self.nsm_parent_field = 'parent_item_group';
self.nsm_parent_field = 'parent_item_group';
def on_update(self):
if self.doc.show_in_website:
# webpage updates
from website.utils import update_page_name
page_name = self.doc.name
if webnotes.conn.get_value("Website Settings", None,
"default_product_category")==self.doc.name:
page_name = "products"
update_page_name(self.doc, self.doc.name)
def prepare_template_args(self):
self.doc.sub_groups = webnotes.conn.sql("""select name, page_name
from `tabItem Group` where parent_item_group=%s
and ifnull(show_in_website,0)=1""", self.doc.name, as_dict=1)

View File

@ -4,7 +4,7 @@
"docstatus": 0,
"creation": "2012-12-07 15:15:28",
"modified_by": "Administrator",
"modified": "2012-12-17 15:00:01"
"modified": "2012-12-18 16:23:48"
},
{
"in_create": 1,
@ -12,11 +12,13 @@
"module": "Setup",
"autoname": "field:item_group_name",
"document_type": "Master",
"description": "Item Classification",
"allow_attach": 1,
"issingle": 0,
"name": "__common__",
"allow_rename": 1,
"doctype": "DocType"
"description": "Item Classification",
"doctype": "DocType",
"max_attachments": 3
},
{
"name": "__common__",
@ -49,33 +51,6 @@
"search_index": 0,
"reqd": 1
},
{
"description": "Check this if you want to show in website",
"no_copy": 0,
"search_index": 0,
"doctype": "DocField",
"label": "Show in Website",
"fieldname": "show_in_website",
"fieldtype": "Check"
},
{
"depends_on": "show_in_website",
"doctype": "DocField",
"label": "Featured Items HTML",
"fieldname": "featured_items_html",
"fieldtype": "HTML",
"options": "<h4>Featured Items</h4>"
},
{
"description": "Items Featured on the Item Group Page",
"depends_on": "show_in_website",
"doctype": "DocField",
"label": "Featured Items",
"fieldname": "featured_items",
"fieldtype": "Table",
"hidden": 1,
"options": "Featured Item"
},
{
"doctype": "DocField",
"label": "Page Name",
@ -112,6 +87,45 @@
"reqd": 1,
"options": "\nYes\nNo"
},
{
"doctype": "DocField",
"label": "Website Settings",
"fieldname": "sb9",
"fieldtype": "Section Break"
},
{
"description": "Check this if you want to show in website",
"no_copy": 0,
"search_index": 0,
"doctype": "DocField",
"label": "Show in Website",
"fieldname": "show_in_website",
"fieldtype": "Check"
},
{
"depends_on": "show_in_website",
"doctype": "DocField",
"label": "Description",
"fieldname": "description",
"fieldtype": "Text Editor"
},
{
"depends_on": "show_in_website",
"doctype": "DocField",
"label": "Featured Items",
"fieldname": "featured_items_html",
"fieldtype": "Section Break"
},
{
"description": "Items Featured on the Item Group Page",
"depends_on": "show_in_website",
"doctype": "DocField",
"label": "Featured Items",
"fieldname": "featured_items",
"fieldtype": "Table",
"hidden": 0,
"options": "Featured Item"
},
{
"print_hide": 1,
"no_copy": 1,
@ -154,6 +168,22 @@
"options": "Item Group",
"report_hide": 1
},
{
"doctype": "DocField",
"label": "file_list",
"fieldname": "file_list",
"fieldtype": "Text",
"hidden": 1
},
{
"print_hide": 1,
"no_copy": 1,
"doctype": "DocField",
"label": "File List",
"fieldname": "file_list",
"fieldtype": "Text",
"hidden": 1
},
{
"amend": 0,
"create": 0,

View File

@ -4,7 +4,7 @@
"docstatus": 0,
"creation": "2012-12-17 14:56:32",
"modified_by": "Administrator",
"modified": "2012-12-17 16:02:00"
"modified": "2012-12-18 14:23:19"
},
{
"allow_attach": 1,
@ -823,11 +823,12 @@
"permlevel": 0
},
{
"description": "Will appear in search",
"depends_on": "show_in_website",
"doctype": "DocField",
"label": "Short Description",
"fieldname": "web_short_description",
"fieldtype": "Text",
"fieldtype": "Text Editor",
"permlevel": 0
},
{

View File

@ -15,7 +15,7 @@ wn.doclistviews['Support Ticket'] = wn.views.ListView.extend({
label_style: {
"status": {
"Open": "danger",
"Open": "important",
"Closed": "success",
"Hold": "info",
"Waiting for Customer": "info"

View File

@ -35,7 +35,7 @@ def get_questions():
conds += ' and t1._user_tags like "%'+ t +'%"'
return webnotes.conn.sql("""select t1.name, t1.owner, t1.question, t1.modified, t1._user_tags,
t2.first_name, t2.last_name, (select count(*) from tabAnswer where
(select count(*) from tabAnswer where
tabAnswer.question = t1.name) as answers
from tabQuestion t1, tabProfile t2
where t1.docstatus!=2

View File

@ -1,256 +1,217 @@
# DocType, Website Settings
[
# These values are common in all dictionaries
{
'creation': '2012-05-21 15:54:09',
'docstatus': 0,
'modified': '2012-07-09 16:20:58',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
# These values are common for all DocType
{
'_last_update': u'1329115882',
'allow_attach': 1,
'colour': u'White:FFF',
'doctype': 'DocType',
'document_type': u'Other',
'issingle': 1,
'max_attachments': 10,
'module': u'Website',
'name': '__common__',
'section_style': u'Simple',
'show_in_menu': 0,
'version': 1
},
# These values are common for all DocField
{
'doctype': u'DocField',
'name': '__common__',
'parent': u'Website Settings',
'parentfield': u'fields',
'parenttype': u'DocType'
},
# These values are common for all DocPerm
{
'doctype': u'DocPerm',
'name': '__common__',
'parent': u'Website Settings',
'parentfield': u'permissions',
'parenttype': u'DocType',
'read': 1
},
# DocType, Website Settings
{
'doctype': 'DocType',
'name': u'Website Settings'
},
# DocPerm
{
'create': 1,
'doctype': u'DocPerm',
'permlevel': 0,
'role': u'System Manager',
'write': 1
},
# DocPerm
{
'create': 1,
'doctype': u'DocPerm',
'permlevel': 0,
'role': u'Website Manager',
'write': 1
},
# DocPerm
{
'doctype': u'DocPerm',
'permlevel': 1,
'role': u'All'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'top_bar',
'fieldtype': u'Section Break',
'label': u'Top Bar',
'permlevel': 0
},
# DocField
{
'colour': u'White:FFF',
'description': u'The name of your company / website as you want to appear on browser title bar. All pages will have this as the prefix to the title.',
'doctype': u'DocField',
'fieldname': u'title_prefix',
'fieldtype': u'Data',
'label': u'Title Prefix',
'permlevel': 0
},
# DocField
{
'colour': u'White:FFF',
'description': u'The "Web Page" that is the website home page',
'doctype': u'DocField',
'fieldname': u'home_page',
'fieldtype': u'Link',
'label': u'Home Page',
'options': u'Web Page',
'permlevel': 0,
'reqd': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'default_product_category',
'fieldtype': u'Link',
'label': u'Default Product Category',
'options': u'Item Group',
'permlevel': 0
},
# DocField
{
'colour': u'White:FFF',
'description': u'Brand is what appears on the top-right of the toolbar. If it is an image, make sure it\nhas a transparent background and use the &lt;img /&gt; tag',
'doctype': u'DocField',
'fieldname': u'brand_html',
'fieldtype': u'Text',
'label': u'Brand HTML',
'permlevel': 0
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'top_bar_items',
'fieldtype': u'Table',
'label': u'Top Bar Items',
'options': u'Top Bar Item',
'permlevel': 0
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'footer',
'fieldtype': u'Section Break',
'label': u'Footer',
'permlevel': 0
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'address',
'fieldtype': u'Text',
'label': u'Address',
'permlevel': 0
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'copyright',
'fieldtype': u'Data',
'label': u'Copyright',
'permlevel': 0
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'footer_items',
'fieldtype': u'Table',
'label': u'Footer Items',
'options': u'Top Bar Item',
'permlevel': 0
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'misc_section',
'fieldtype': u'Section Break',
'label': u'Misc',
'permlevel': 0
},
# DocField
{
'colour': u'White:FFF',
'description': u'An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [<a href="http://favicon-generator.org/" target="_blank">favicon-generator.org</a>]',
'doctype': u'DocField',
'fieldname': u'favicon',
'fieldtype': u'Select',
'label': u'FavIcon',
'options': u'attach_files:',
'permlevel': 0
},
# DocField
{
'description': u'Sub-domain provided by erpnext.com',
'doctype': u'DocField',
'fieldname': u'subdomain',
'fieldtype': u'Text',
'label': u'Subdomain',
'permlevel': 1,
'reqd': 0
},
# DocField
{
'description': u'Enter domain names associated to this website, each on a new line',
'doctype': u'DocField',
'fieldname': u'domain_list',
'fieldtype': u'Text',
'hidden': 1,
'label': u'Domain List',
'permlevel': 0,
'reqd': 0
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'file_list',
'fieldtype': u'Text',
'hidden': 1,
'label': u'File List',
'no_copy': 1,
'permlevel': 0,
'print_hide': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'analytics',
'fieldtype': u'Section Break',
'label': u'Startup',
'permlevel': 0
},
# DocField
{
'colour': u'White:FFF',
'description': u'Bind events on startup and page change',
'doctype': u'DocField',
'fieldname': u'startup_code',
'fieldtype': u'Code',
'label': u'Startup Code',
'options': u'Javascript',
'permlevel': 0
}
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-07-12 23:29:36",
"modified_by": "Administrator",
"modified": "2012-12-18 16:15:43"
},
{
"issingle": 1,
"allow_attach": 1,
"doctype": "DocType",
"module": "Website",
"max_attachments": 10,
"document_type": "Other",
"name": "__common__"
},
{
"name": "__common__",
"parent": "Website Settings",
"doctype": "DocField",
"parenttype": "DocType",
"parentfield": "fields"
},
{
"name": "__common__",
"parent": "Website Settings",
"read": 1,
"doctype": "DocPerm",
"parenttype": "DocType",
"parentfield": "permissions"
},
{
"name": "Website Settings",
"doctype": "DocType"
},
{
"doctype": "DocField",
"label": "Landing Page",
"fieldname": "sb0",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"description": "The \"Web Page\" that is the website home page",
"doctype": "DocField",
"label": "Home Page",
"options": "Web Page",
"fieldname": "home_page",
"fieldtype": "Link",
"reqd": 1,
"permlevel": 0
},
{
"description": "The name of your company / website as you want to appear on browser title bar. All pages will have this as the prefix to the title.",
"doctype": "DocField",
"label": "Title Prefix",
"fieldname": "title_prefix",
"fieldtype": "Data",
"permlevel": 0
},
{
"doctype": "DocField",
"fieldname": "cb4",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"description": "Only Items / Groups under this Groups will be shown on the website. This will also represent the \"Products\" Home Page.",
"doctype": "DocField",
"label": "Default Product Category",
"options": "Item Group",
"fieldname": "default_product_category",
"fieldtype": "Link",
"permlevel": 0
},
{
"description": "If checked, the Home page will be the default Item Group for the website.",
"doctype": "DocField",
"label": "Home Page is Products",
"fieldname": "home_page_is_products",
"fieldtype": "Check",
"permlevel": 0
},
{
"doctype": "DocField",
"label": "Top Bar",
"fieldname": "top_bar",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"description": "Brand is what appears on the top-right of the toolbar. If it is an image, make sure it\nhas a transparent background and use the &lt;img /&gt; tag. Keep size as 200px x 30px",
"doctype": "DocField",
"label": "Brand HTML",
"fieldname": "brand_html",
"fieldtype": "Text",
"permlevel": 0
},
{
"doctype": "DocField",
"label": "Top Bar Items",
"options": "Top Bar Item",
"fieldname": "top_bar_items",
"fieldtype": "Table",
"permlevel": 0
},
{
"doctype": "DocField",
"label": "Footer",
"fieldname": "footer",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"doctype": "DocField",
"label": "Address",
"fieldname": "address",
"fieldtype": "Text",
"permlevel": 0
},
{
"doctype": "DocField",
"label": "Copyright",
"fieldname": "copyright",
"fieldtype": "Data",
"permlevel": 0
},
{
"doctype": "DocField",
"label": "Footer Items",
"options": "Top Bar Item",
"fieldname": "footer_items",
"fieldtype": "Table",
"permlevel": 0
},
{
"doctype": "DocField",
"label": "Misc",
"fieldname": "misc_section",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"description": "An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [<a href=\"http://favicon-generator.org/\" target=\"_blank\">favicon-generator.org</a>]",
"doctype": "DocField",
"label": "FavIcon",
"options": "attach_files:",
"fieldname": "favicon",
"fieldtype": "Select",
"permlevel": 0
},
{
"description": "Sub-domain provided by erpnext.com",
"doctype": "DocField",
"label": "Subdomain",
"fieldname": "subdomain",
"fieldtype": "Text",
"reqd": 0,
"permlevel": 1
},
{
"description": "Enter domain names associated to this website, each on a new line",
"doctype": "DocField",
"label": "Domain List",
"fieldname": "domain_list",
"fieldtype": "Text",
"reqd": 0,
"hidden": 1,
"permlevel": 0
},
{
"print_hide": 1,
"no_copy": 1,
"doctype": "DocField",
"label": "File List",
"fieldname": "file_list",
"fieldtype": "Text",
"hidden": 1,
"permlevel": 0
},
{
"doctype": "DocField",
"label": "Startup",
"fieldname": "analytics",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"description": "Bind events on startup and page change",
"doctype": "DocField",
"label": "Startup Code",
"options": "Javascript",
"fieldname": "startup_code",
"fieldtype": "Code",
"permlevel": 0
},
{
"create": 1,
"doctype": "DocPerm",
"write": 1,
"role": "System Manager",
"permlevel": 0
},
{
"create": 1,
"doctype": "DocPerm",
"write": 1,
"role": "Website Manager",
"permlevel": 0
},
{
"doctype": "DocPerm",
"role": "All",
"permlevel": 1
}
]

View File

@ -25,30 +25,23 @@ def get_product_info(item_code):
@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
if not args: args = webnotes.form_dict
if not args.search: args.search = ""
# base query
query = """\
select name, item_name, page_name, website_image,
description, web_short_description
select name, item_name, page_name, website_image, item_group,
if(ifnull(web_short_description,'')='', web_long_description,
web_short_description) as web_short_description
from `tabItem`
where is_sales_item = 'Yes'
and docstatus = 0
and show_in_website = 1"""
where docstatus = 0
and show_in_website = 1 """
# search term condition
if args.get('search'):
if args.search:
query += """
and (
web_short_description like %(search)s or
@ -62,78 +55,9 @@ def get_product_list(args=None):
# product group condition
if args.get('product_group') and args.get('product_group') != 'All Products':
query += """
and item_group = %(product_group)s"""
and item_group = %(product_group)s """
# order by
query += """
order by item_name asc, name asc"""
query += """order by item_name asc, name asc limit %s, 10""" % args.start
from webnotes.widgets.query_builder import add_limit_to_query
query, args = add_limit_to_query(query, args)
return webnotes.conn.sql(query, args, as_dict=1)
@webnotes.whitelist(allow_guest=True)
def get_product_category_list(args=None):
"""
args = {
'limit_start': 0,
'limit_page_length': 5,
}
"""
import webnotes
if not args: args = webnotes.form_dict
query = """\
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"""
from webnotes.widgets.query_builder import add_limit_to_query
query, args = add_limit_to_query(query, args)
result = webnotes.conn.sql(query, args, 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):
"""
args = {
'limit_start': 0,
'limit_page_length': 5,
'product_name': '',
'product_group': '',
}
"""
import webnotes
if not args: args = webnotes.form_dict
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
and name != %(product_name)s
and item_group = %(product_group)s
order by item_name"""
from webnotes.widgets.query_builder import add_limit_to_query
query, args = add_limit_to_query(query, args)
result = webnotes.conn.sql(query, args, as_dict=1)
return result
return webnotes.conn.sql(query, args, as_dict=1)

View File

@ -1,11 +0,0 @@
<style>
.img-area {
float:left;
width: 115px;
}
.product-list-description {
float:left;
width: 400px;
}
</style>

View File

@ -1 +1,35 @@
{% extends "html/page.html" %}
{% block content %}
<div class="layout-wrapper layout-wrapper-background">
<div class="web-content" id="content-product_group">
<div class="layout-main" style="padding: 30px;">
{% include 'html/product_search_box.html' %}
{% if description %}
<div>{{ description or ""}}</div>
{% else %}
<h3>{{ name }}</h3>
{% endif %}
{% if sub_groups %}
<div class="well">
<div class="container-fluid">
{% for d in sub_groups %}
<div class="span2">
<i class="icon-chevron-right"></i>
<a href="{{ d.page_name }}">{{ d.name }}</a></div>
{% endfor %}
</div>
</div>
{% endif %}
{% if obj.doclist.get({"doctype":"Featured Item"}) %}
<hr>
<h3>Featured Products</h3>
{% endif %}
</div>
</div>
</div>
{% endblock %}

View File

@ -20,15 +20,20 @@
<div class="layout-wrapper layout-wrapper-background">
<div class="web-content" id="content-product-{{ name }}">
<div class="layout-main" style="padding: 30px;">
{% include 'html/product_search.html' %}
{% include 'html/product_search_box.html' %}
<h1>{{ item_name }}</h1>
<p class="help">Item Code: {{ name }}</p>
<div class="product-page-content">
<div class="span6">
{% if website_image %}
<image class="item-main-image" src="files/{{ website_image }}" />
{% else %}
<div class="img-area"></div>
<span style="font-size: 11px">This is an auto-generated Image</span>
<div class="img-area">
<div style='background-color: #eee; padding: 40px;
width: 32px; font-size: 32px; color: #888;' title='No Image'>
<i class='icon-camera'></i></div>
</div>
{% endif %}
<br><br>
</div>
@ -42,7 +47,8 @@
<div class="span9">
<h3>Product Description</h3>
<div>
{{ web_long_description or web_short_description }}
{{ web_long_description or web_short_description or
"[No description given]" }}
</div>
<hr>
{% if obj.doclist.get({"doctype":"Item Website Specification"}) %}
@ -51,7 +57,7 @@
{% for d in obj.doclist.get(
{"doctype":"Item Website Specification"}) %}
<tr>
<td>{{ d.label }}</td>
<td style="min-width: 150px;">{{ d.label }}</td>
<td>{{ d.description }}</td>
</tr>
{% endfor %}

View File

@ -1,9 +0,0 @@
<div class="pull-right">
<form class="form-search">
<div class="input-append">
<input type="text" class="span2 search-query" id="product-search">
<button class="btn"><i class="icon-search"></i></button>
</div>
</form>
</div>
<div class="clearfix"></div>

View File

@ -0,0 +1,26 @@
<div class="pull-right" style="margin-top:-15px;">
<form class="form-search">
<div class="input-append">
<input type="text" class="span2 search-query"
id="product-search" placeholder="Product Search...">
<button class="btn" id="btn-product-search">
<i class="icon-search"></i></button>
</div>
</form>
<script>
// redirect to product search page
$(document).ready(function() {
$("#btn-product-search").click(function() {
var txt = $("#product-search").val();
if(txt) {
window.location.href="product_search.html?q=" + txt;
}
return false;
});
$("#product-search").keypress(function(e) {
if(e.which==13) $("#product-search-btn").click();
})
})
</script>
</div>
<div class="clearfix"></div>

View File

@ -59,10 +59,17 @@ var blog = {
<p><a href="%(page_name)s">Read with comments...</a></p>\
<hr /><br />', b)).appendTo($wrap);
});
blog.start += data.length;
blog.start += (data.length || 0);
if(!data.length) {
$("#next-page").toggle(false)
.parent().append("<div class='alert'>Nothing more to show.</div>");
if(blog.start) {
$("#next-page").toggle(false)
.parent().append("<div class='alert'>Nothing more to show.</div>");
} else {
$("#next-page").toggle(false)
.parent().append("<div class='alert'>No blogs written yet.</div>");
}
} else {
$("#next-page").toggle(true);
}
}
}

View File

@ -1,33 +0,0 @@
wn.provide('erpnext.blog');
(function() {
$('body').on('click', '.btn-blog-subscribe', function() {
var d = new wn.ui.Dialog({
title: "Get Blog Updates via Email",
fields: [
{label: "Your Name", fieldtype:"Data", reqd:1},
{label: "Your Email Address", fieldtype:"Data", reqd:1
,description: "You can unsubscribe anytime."},
{label: "Subscribe", fieldtype:"Button"}
]
});
$(d.fields_dict.subscribe.input).click(function() {
var args = d.get_values();
if(!args) return;
wn.call({
method: 'website.helpers.blog.add_subscriber',
args: args,
callback: function(r) {
if(r.exc) {
msgprint('Opps there seems to be some error, Please check back after some time.');
} else {
msgprint('Thanks for subscribing!');
}
d.hide();
},
btn: this
})
})
d.show()
})
})()

View File

@ -1,18 +0,0 @@
wn.provide('erpnext.products');
erpnext.products.make_product_categories = function(wrapper) {
if (!wrapper) { wrapper = erpnext.products.wrapper; }
if (!wrapper) { return; }
wrapper.category_list = new wn.ui.Listing({
parent: $(wrapper).find('.more-categories').get(0),
method: 'website.helpers.product.get_product_category_list',
hide_refresh: true,
render_row: function(parent, data) {
parent.innerHTML = repl(
'<a href="products.html#!products/%(item_group)s">%(item_group)s</a> (%(items)s)',
data);
}
});
wrapper.category_list.run();
}

View File

@ -1,106 +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/>.
// js inside blog page
{% include "js/product_category.js" %}
wn.pages['{{ name }}'].onload = function(wrapper) {
erpnext.products.wrapper = wrapper;
// make product categories in the sidebar
erpnext.products.make_product_categories(wrapper);
// make lists
erpnext.products.make_product_list(wrapper);
// bind search button or enter key
$(wrapper).find('.products-search .btn').click(function() {
erpnext.products.product_list.run();
});
$(wrapper).find('.products-search input').keypress(function(ev) {
if(ev.which==13) $(wrapper).find('.products-search .btn').click();
});
}
erpnext.products.make_product_list = function(wrapper) {
if (!wrapper) { wrapper = erpnext.products.wrapper; }
if (!wrapper) { return; }
erpnext.products.product_list = new wn.ui.Listing({
parent: $(wrapper).find('#products-list').get(0),
run_btn: $(wrapper).find('.products-search .btn').get(0),
no_toolbar: true,
method: 'website.helpers.product.get_product_list',
get_args: function() {
return {
search: $('input[name="products-search"]').val() || '',
product_group: erpnext.products.cur_group || '',
};
},
render_row: function(parent, data) {
if (!data.web_short_description) {
data.web_short_description = data.description;
}
parent.innerHTML = repl('\
<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) {
$(parent).find('.img-area').append(repl(
'<img src="files/%(website_image)s" style="width:100px;">', data))
} else {
$(parent).find('.img-area').append(wn.dom.placeholder(100,
data.item_name));
}
}
});
}
wn.pages['{{ name }}'].onshow = function(wrapper) {
// show default product category
erpnext.products.set_group();
}
erpnext.products.set_group = function() {
var cat = erpnext.products.get_group();
// get erpnext.products.default_category
var wrapper = erpnext.products.wrapper;
$(wrapper).find('h1').html(cat.label);
erpnext.products.product_list.run();
}
erpnext.products.get_group = function() {
route = wn.get_route();
if(route && route.length>1) {
// from url
var grp = route[1];
var label = route[1];
erpnext.products.cur_group = grp;
} else {
// default
var grp = 'Products';
var label = 'Products';
erpnext.products.cur_group = null;
}
return {grp:grp, label:label};
}

View File

@ -3,7 +3,7 @@
{% block content %}
<div class="content">
<div class="layout-wrapper layout-main">
<h3>Page missing or moved</h3>
<h3><i class="icon-exclamation-sign"></i> Page missing or moved</h3>
<br>
<p>We are very sorry for this, but the page you are looking for is missing
(this could be because of a typo in the address) or moved.</p>

View File

@ -17,11 +17,12 @@
<div class="layout-main">
<h1>Blog</h1>
<br>
<div id="blog-list" style="min-height: 400px;">
<div id="blog-list">
<!-- blog list will be generated dynamically -->
</div>
<div style="text-align: center;">
<button id="next-page" class="btn">More...</button>
<button id="next-page" class="btn"
style="display:none;">More...</button>
</div>
</div>
</div>

View File

@ -0,0 +1,11 @@
{% extends "html/outer.html" %}
{% block content %}
<div class="content">
<div class="layout-wrapper layout-main">
<h3><i class="icon-exclamation-sign"></i> Oops, a server error has occured</h3>
<br>
<pre>%(error)s</pre>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,97 @@
{% extends "html/page.html" %}
{% block title %}Product Search{% endblock %}
{% block content %}
<script>
$(document).ready(function() {
var txt = get_url_arg("q");
$(".search-results").html("Search results for: " + txt);
window.start = 0;
var get_list = function() {
$.ajax({
method: "GET",
url: "server.py",
dataType: "json",
data: {
cmd: "website.helpers.product.get_product_list",
start: window.start,
search: txt
},
dataType: "json",
success: function(data) {
render(data.message);
}
})
}
var render = function(data) {
if(data.length) {
var table = $("#search-list .table");
if(!table.length)
var table = $("<table class='table'>").appendTo("#search-list");
$.each(data, function(i, d) {
if(!d.web_short_description)
d.web_short_description = "No description given."
var $tr = $(repl('<tr>\
<td style="width: 30%;">\
<img class="product-image" style="width: 80%;" src="files/%(website_image)s">\
</td>\
<td>\
<h4><a href="%(page_name)s">%(item_name)s</a></h4>\
<p class="help">Item Code: %(name)s</p>\
<p>%(web_short_description)s</p>\
</td>\
</tr>', d)).appendTo(table);
if(!d.website_image) {
$tr.find(".product-image").replaceWith("<div\
style='background-color: #eee; padding: 40px; \
width: 32px; font-size: 32px; color: #888;'>\
<i class='icon-camera'></i></div>");
}
});
}
if(data.length < 10) {
if(!table) {
$(".more-btn")
.replaceWith("<div class='alert'>No results found for your search.</div>");
} else {
$(".more-btn")
.replaceWith("<div class='alert'>Nothing more to show.</div>");
}
} else {
$(".more-btn").toggle(true)
}
window.start += (data.length || 0);
}
get_list();
$(".more-btn .btn").click(function() {
get_list()
});
});
</script>
<div class="layout-wrapper layout-wrapper-background">
<div class="web-content" id="content-product_search">
<div class="layout-main" style="padding: 30px;">
{% include 'html/product_search_box.html' %}
<h3 class="search-results">Search Results</h3>
<div id="search-list">
</div>
<div style="text-align: center;">
<div class="more-btn"
style="display: none; text-align: center;">
<button class="btn">More...</button>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,37 +0,0 @@
{% extends "html/page.html" %}
{% block javascript %}
{% include "js/products.js" %}
{% endblock %}
{% block css %}
{% include "css/products.css" %}
{% endblock %}
{% block title %}
Products
{% endblock %}
{% block content %}
<div class="layout-wrapper layout-wrapper-background">
<div class="web-content" id="content-products">
<div class="layout-main-section">
<h1 class="products-category"></h1>
<div class="products-search" style="margin-bottom: 15px;">
<input name="products-search" />
<button class="btn" style="margin-left: 7px">Search</button>
</div>
<div id="products-list">
<!-- product list will be generated dynamically -->
</div>
</div>
<div class="layout-side-section">
<h3>Categories</h3>
<div class="more-categories"></div>
</div>
<div style="clear: both"></div>
</div>
</div>
{% endblock %}

View File

@ -48,7 +48,7 @@ def render(page_name):
else:
html = get_html('index')
except Exception, e:
html = get_html('404')
html = get_html('error')
from webnotes.handler import eprint, print_zip
eprint("Content-Type: text/html")
@ -57,32 +57,29 @@ def render(page_name):
def get_html(page_name):
"""get page html"""
page_name = scrub_page_name(page_name)
comments = get_comments(page_name)
html = ''
# load from cache, if auto cache clear is falsy
if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0):
html = webnotes.cache().get_value("page:" + page_name)
from_cache = True
if html:
comments += "\nload status: cache"
else:
if not html:
html = load_into_cache(page_name)
comments += "\nload status: fresh"
from_cache = False
# insert comments
html += """\n<!-- %s -->""" % webnotes.utils.cstr(comments)
if not html:
html = get_html("404")
if page_name=="error":
html = html % {"error": webnotes.getTraceback()}
else:
comments = "\n\npage:"+page_name+\
"\nload status: " + (from_cache and "cache" or "fresh")
html += """\n<!-- %s -->""" % webnotes.utils.cstr(comments)
return html
def get_comments(page_name):
if page_name == '404':
comments = """error: %s""" % webnotes.getTraceback()
else:
comments = """page: %s""" % page_name
return comments
def scrub_page_name(page_name):
if page_name.endswith('.html'):
@ -114,6 +111,8 @@ def update_page_name(doc, title):
def load_into_cache(page_name):
args = prepare_args(page_name)
if not args:
return ""
html = build_html(args)
webnotes.cache().set_value("page:" + page_name, html)
return html
@ -141,6 +140,9 @@ def prepare_args(page_name):
else:
args = get_doc_fields(page_name)
if not args:
return False
args.update(get_outer_env())
return args
@ -156,6 +158,9 @@ def get_template_pages():
def get_doc_fields(page_name):
doc_type, doc_name = get_source_doc(page_name)
if not doc_type:
return False
obj = webnotes.get_obj(doc_type, doc_name, with_children=True)
if hasattr(obj, 'prepare_template_args'):