@@ -35,57 +35,5 @@ | |||
"color": "#16a085", | |||
"icon": "icon-globe" | |||
} | |||
}, | |||
"web": { | |||
"pages": { | |||
"404": { | |||
"template": "lib/website/templates/404.html" | |||
}, | |||
"error": { | |||
"no_cache": true, | |||
"template": "lib/website/templates/error.html" | |||
}, | |||
"login": { | |||
"template": "lib/website/templates/login.html" | |||
}, | |||
"message": { | |||
"no_cache": true, | |||
"template": "lib/website/templates/message.html" | |||
}, | |||
"print": { | |||
"no_cache": true, | |||
"template": "lib/website/templates/print.html", | |||
"args_method": "core.doctype.print_format.print_format.get_args" | |||
}, | |||
"index": { | |||
"template": "lib/website/doctype/web_page/templates/index.html" | |||
}, | |||
"writers": { | |||
"template": "lib/website/doctype/blogger/templates/writers.html", | |||
"args_method": "website.doctype.blogger.blogger.get_writers_args" | |||
}, | |||
"blog": { | |||
"template": "lib/website/doctype/blog_post/templates/blog_post.html", | |||
"args_method": "website.doctype.blog_post.blog_post.get_blog_template_args" | |||
}, | |||
"contact": { | |||
"template": "lib/website/doctype/contact_us_settings/templates/contact.html", | |||
"args_doctype": "Contact Us Settings" | |||
}, | |||
"about": { | |||
"template": "lib/website/doctype/about_us_settings/templates/about.html", | |||
"args_method": "website.doctype.about_us_settings.about_us_settings.get_args" | |||
} | |||
}, | |||
"generators": { | |||
"Web Page": { | |||
"template": "lib/website/doctype/web_page/templates/web_page.html", | |||
"condition_field": "published" | |||
}, | |||
"Blog Post": { | |||
"template": "lib/website/doctype/blog_post/templates/blog_post.html", | |||
"condition_field": "published" | |||
} | |||
} | |||
} | |||
} |
@@ -119,36 +119,24 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s | |||
def set_portal_link(sent_via, comm): | |||
"""set portal link in footer""" | |||
from webnotes.webutils import is_portal_enabled, get_portal_links | |||
from webnotes.webutils import is_signup_enabled | |||
from webnotes.utils import get_url, cstr | |||
import urllib | |||
footer = None | |||
if is_portal_enabled(): | |||
portal_opts = get_portal_links().get(sent_via.doc.doctype) | |||
if portal_opts: | |||
valid_recipient = cstr(sent_via.doc.email or sent_via.doc.email_id or | |||
if is_signup_enabled() and hasattr(sent_via, "get_portal_page"): | |||
portal_page = sent_via.get_portal_page() | |||
if portal_page: | |||
is_valid_recipient = cstr(sent_via.doc.email or sent_via.doc.email_id or | |||
sent_via.doc.contact_email) in comm.recipients | |||
if not valid_recipient: | |||
attach_portal_link = False | |||
else: | |||
attach_portal_link = True | |||
if portal_opts.get("conditions"): | |||
for fieldname, val in portal_opts["conditions"].items(): | |||
if sent_via.doc.fields.get(fieldname) != val: | |||
attach_portal_link = False | |||
break | |||
if attach_portal_link: | |||
url = "%s/%s?name=%s" % (get_url(), portal_opts["page"], | |||
urllib.quote(sent_via.doc.name)) | |||
if is_valid_recipient: | |||
url = "%s/%s?name=%s" % (get_url(), portal_page, urllib.quote(sent_via.doc.name)) | |||
footer = """<!-- Portal Link --><hr> | |||
<a href="%s" target="_blank">View this on our website</a>""" % url | |||
return footer | |||
def get_user(doctype, txt, searchfield, start, page_len, filters): | |||
from controllers.queries import get_match_cond | |||
return webnotes.conn.sql("""select name, concat_ws(' ', first_name, middle_name, last_name) | |||
@@ -477,26 +477,25 @@ def get_list(doctype, filters=None, fields=None, docstatus=None, | |||
return webnotes.widgets.reportview.execute(doctype, filters=filters, fields=fields, docstatus=docstatus, | |||
group_by=group_by, order_by=order_by, limit_start=limit_start, limit_page_length=limit_page_length, | |||
as_list=as_list, debug=debug) | |||
_config = None | |||
def get_config(): | |||
global _config | |||
if not _config: | |||
import webnotes.utils, json | |||
_config = _dict() | |||
def update_config(path): | |||
try: | |||
with open(path, "r") as configfile: | |||
this_config = json.loads(configfile.read()) | |||
for k in ("app_name", "base_template"): | |||
_config[k] = this_config.get(k) | |||
_config.modules.update(this_config["modules"]) | |||
_config.web.pages.update(this_config["web"]["pages"]) | |||
_config.web.generators.update(this_config["web"]["generators"]) | |||
for key, val in this_config.items(): | |||
if isinstance(val, dict): | |||
_config.setdefault(key, _dict()).update(val) | |||
else: | |||
_config[key] = val | |||
except IOError: | |||
pass | |||
_config = _dict({"modules": {}, "web": _dict({"pages": {}, "generators": {}})}) | |||
update_config(webnotes.utils.get_path("lib", "config.json")) | |||
update_config(webnotes.utils.get_path("app", "config.json")) | |||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals | |||
import conf | |||
import webnotes | |||
from webnotes import _ | |||
import webnotes.utils | |||
class PageNotFoundError(Exception): pass | |||
@@ -56,7 +57,6 @@ def render_page(page_name): | |||
def build_page(page_name): | |||
from jinja2 import Environment, FileSystemLoader | |||
import os | |||
if not webnotes.conn: | |||
webnotes.connect() | |||
@@ -91,7 +91,7 @@ def build_page(page_name): | |||
else: | |||
# page | |||
context = webnotes._dict({ 'name': page_name }) | |||
if module: | |||
if module and hasattr(module, "get_context"): | |||
context.update(module.get_context()) | |||
context.update(get_website_settings()) | |||
@@ -114,7 +114,6 @@ def build_sitemap(): | |||
for g in config["generators"].values(): | |||
g["is_generator"] = True | |||
module = webnotes.get_module(g["controller"]) | |||
doctype = module.doctype | |||
for name in webnotes.conn.sql_list("""select page_name from `tab%s` where | |||
ifnull(%s, 0)=1""" % (module.doctype, module.condition_field)): | |||
sitemap[name] = g | |||
@@ -133,7 +132,7 @@ def get_home_page(): | |||
return page_name | |||
def build_website_sitemap_config(): | |||
import os, json | |||
import os | |||
config = {"pages": {}, "generators":{}} | |||
basepath = webnotes.utils.get_base_path() | |||
@@ -167,9 +166,8 @@ def build_website_sitemap_config(): | |||
return config | |||
def get_website_settings(): | |||
from webnotes.utils import get_request_site_address | |||
from webnotes.utils import get_request_site_address, encode, cint | |||
from urllib import quote | |||
from webnotes.utils import cint, encode | |||
all_top_items = webnotes.conn.sql("""\ | |||
select * from `tabTop Bar Item` | |||
@@ -199,11 +197,14 @@ def get_website_settings(): | |||
}) | |||
settings = webnotes.doc("Website Settings", "Website Settings") | |||
for k in ["banner_html", "brand_html", "copyright", "address", "twitter_share_via", | |||
for k in ["banner_html", "brand_html", "copyright", "twitter_share_via", | |||
"favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", | |||
"disable_signup"]: | |||
if k in settings.fields: | |||
context[k] = settings.fields.get(k) | |||
if settings.address: | |||
context["footer_address"] = settings.address | |||
for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share", | |||
"disable_signup"]: | |||
@@ -228,6 +229,8 @@ def clear_cache(page_name=None): | |||
cache = webnotes.cache() | |||
for p in get_all_pages(): | |||
cache.delete_value("page:" + p) | |||
cache.delete_value("website_sitemap") | |||
cache.delete_value("website_sitemap_config") | |||
def get_all_pages(): | |||
return webnotes.cache().get_value("website_sitemap", build_sitemap).keys() | |||
@@ -267,44 +270,25 @@ def scrub_page_name(page_name): | |||
return page_name | |||
def get_portal_links(): | |||
portal_args = {} | |||
for page, opts in webnotes.get_config()["web"]["pages"].items(): | |||
if opts.get("portal"): | |||
portal_args[opts["portal"]["doctype"]] = { | |||
"page": page, | |||
"conditions": opts["portal"].get("conditions") | |||
} | |||
return portal_args | |||
_is_portal_enabled = None | |||
def is_portal_enabled(): | |||
global _is_portal_enabled | |||
if _is_portal_enabled is None: | |||
_is_portal_enabled = True | |||
_is_signup_enabled = None | |||
def is_signup_enabled(): | |||
global _is_signup_enabled | |||
if _is_signup_enabled is None: | |||
_is_signup_enabled = True | |||
if webnotes.utils.cint(webnotes.conn.get_value("Website Settings", | |||
"Website Settings", "disable_signup")): | |||
_is_portal_enabled = False | |||
_is_signup_enabled = False | |||
return _is_portal_enabled | |||
return _is_signup_enabled | |||
def update_page_name(doc, title): | |||
"""set page_name and check if it is unique""" | |||
webnotes.conn.set(doc, "page_name", page_name(title)) | |||
if doc.page_name in get_all_pages(): | |||
webnotes.conn.sql("""Page Name cannot be one of %s""" % ', '.join(get_standard_pages())) | |||
webnotes.throw("%s: %s. %s: %s" % (doc.page_name, _("Page already exists"), | |||
_("Please change the value"), title)) | |||
res = webnotes.conn.sql("""\ | |||
select count(*) from `tab%s` | |||
where page_name=%s and name!=%s""" % (doc.doctype, '%s', '%s'), | |||
(doc.page_name, doc.name)) | |||
if res and res[0][0] > 0: | |||
webnotes.msgprint("""A %s with the same title already exists. | |||
Please change the title of %s and save again.""" | |||
% (doc.doctype, doc.name), raise_exception=1) | |||
delete_page_cache(doc.page_name) | |||
def page_name(title): | |||
@@ -1,3 +1,7 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
def get_context(): | |||
@@ -144,10 +144,14 @@ def add_comment(args=None): | |||
webnotes.webutils.clear_cache(page_name) | |||
args['comment_date'] = webnotes.utils.global_date_format(comment.doc.creation) | |||
template_args = { 'comment_list': [args], 'template': 'app/website/templates/html/comment.html' } | |||
template_args = { 'comment_list': [args]} | |||
# get html of comment row | |||
comment_html = webnotes.webutils.build_html(template_args) | |||
from jinja2 import Environment, FileSystemLoader | |||
jenv = Environment(loader = FileSystemLoader(webnotes.utils.get_base_path())) | |||
template = jenv.get_template("lib/website/doctype/blog_post/templates/includes/comment.html") | |||
comment_html = template.render(template_args) | |||
# notify commentors | |||
commentors = [d[0] for d in webnotes.conn.sql("""select comment_by from tabComment where | |||
@@ -2,13 +2,13 @@ | |||
{% block javascript %} | |||
<script> | |||
{% include "lib/website/doctype/blog_post/templates/includes/blog_page.js" %} | |||
{% include "lib/website/doctype/blog_post/templates/includes/blog_post.js" %} | |||
</script> | |||
{% endblock %} | |||
{% block css %} | |||
<style> | |||
{% include "lib/website/doctype/blog_post/templates/includes/blog_page.css" %} | |||
{% include "lib/website/doctype/blog_post/templates/includes/blog_post.css" %} | |||
</style> | |||
{% endblock %} | |||
@@ -1,5 +1,5 @@ | |||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
// License: GNU General Public License v3. See license.txt | |||
// MIT License. See license.txt | |||
// js inside blog page | |||
@@ -10,15 +10,6 @@ class DocType: | |||
def __init__(self, d, dl): | |||
self.doc, self.doclist = d, dl | |||
def onload(self): | |||
"""load address""" | |||
if self.doc.query_options: | |||
self.query_options = filter(None, self.doc.query_options.replace(",", "\n").split()) | |||
else: | |||
self.query_options = ["Sales", "Support", "General"] | |||
if self.doc.address: | |||
self.address = webnotes.bean("Address", self.doc.address).doc | |||
def on_update(self): | |||
from webnotes.webutils import clear_cache | |||
clear_cache("contact") |
@@ -10,57 +10,58 @@ | |||
{% block content %} | |||
<div class="col-md-12"> | |||
<h3>{{ obj.doc.heading or "Contact Us"}}</h3> | |||
<h3>{{ heading or "Contact Us"}}</h3> | |||
<div class="row"> | |||
<div class="web-form col-md-8"> | |||
<div class="col-md-8"> | |||
<p id="contact-alert" class="alert alert-warning" | |||
style="display: none;"> </p> | |||
<p> | |||
<div class="form-group"> | |||
<select name="subject" class="form-control"> | |||
{% if obj.query_options -%} | |||
{% for option in obj.query_options -%} | |||
{% if query_options -%} | |||
{% for option in query_options -%} | |||
<option value="{{ option }}">{{ option }}</option> | |||
{%- endfor %} | |||
{% else %} | |||
<option value="General">General</option> | |||
{% endif %} | |||
</select> | |||
</p> | |||
<p> | |||
</div> | |||
<div class="form-group"> | |||
<input class="form-control" name="email" type="text" | |||
placeholder="Your Email Address" /> | |||
</p> | |||
<p> | |||
</div> | |||
<div class="form-group"> | |||
<textarea rows="10" name="message" class="form-control"></textarea> | |||
</p> | |||
<p> | |||
</div> | |||
<div class="form-group"> | |||
<button class="btn btn-primary btn-send">Send</button> | |||
</p> | |||
</div> | |||
</div> | |||
{% if obj.doc.address %} | |||
<div class="col-md-3 col-md-offset-1 alert alert-warning" style="margin-top: 20px;" itemscope itemtype="http://schema.org/PostalAddress"> | |||
<h4><i class="icon-map-marker"></i> {{ obj.address.address_title }}</h4> | |||
{% if obj.address.address_line1 %} | |||
<span itemprop="streetAddress">{{ obj.address.address_line1 }}</span><br> | |||
{% if address %} | |||
<div class="col-md-3 col-md-offset-1 alert alert-warning" | |||
itemscope itemtype="http://schema.org/PostalAddress"> | |||
<h4><i class="icon-map-marker"></i> {{ address.address_title }}</h4> | |||
{% if address.address_line1 %} | |||
<span itemprop="streetAddress">{{ address.address_line1 }}</span><br> | |||
{% endif %} | |||
{% if obj.address.address_line2 %} | |||
<span itemprop="streetAddress">{{ obj.address.address_line2 }}</span><br> | |||
{% if address.address_line2 %} | |||
<span itemprop="streetAddress">{{ address.address_line2 }}</span><br> | |||
{% endif %} | |||
{% if obj.address.city %} | |||
<span itemprop="addressLocality">{{ obj.address.city }}</span><br> | |||
{% if address.city %} | |||
<span itemprop="addressLocality">{{ address.city }}</span><br> | |||
{% endif %} | |||
{% if obj.address.state %} | |||
<span itemprop="addressRegion">{{ obj.address.state }}</span><br> | |||
{% if address.state %} | |||
<span itemprop="addressRegion">{{ address.state }}</span><br> | |||
{% endif %} | |||
{% if obj.address.pincode %} | |||
<span itemprop="postalCode">{{ obj.address.pincode }}</span><br> | |||
{% if address.pincode %} | |||
<span itemprop="postalCode">{{ address.pincode }}</span><br> | |||
{% endif %} | |||
{% if obj.address.country %} | |||
<span itemprop="addressCountry">{{ obj.address.country }}</span><br> | |||
{% if address.country %} | |||
<span itemprop="addressCountry">{{ address.country }}</span><br> | |||
{% endif %} | |||
</div> | |||
{% endif %} | |||
</div> | |||
{{ obj.doc.introduction }} | |||
{{ introduction }} | |||
</div> | |||
{% endblock %} |
@@ -1,6 +1,16 @@ | |||
import webnotes | |||
def get_context(): | |||
bean = webnotes.bean("Contact Us Settings", "Contact Us Settings") | |||
query_options = filter(None, bean.doc.query_options.replace(",", "\n").split()) if \ | |||
bean.doc.query_options else ["Sales", "Support", "General"] | |||
address = webnotes.bean("Address", bean.doc.address).doc if bean.doc.address else None | |||
return { | |||
"obj": webnotes.bean("Contact Us Settings", "Contact Us Settings").get_controller() | |||
} | |||
"query_options": query_options, | |||
"address": address, | |||
"heading": bean.doc.heading, | |||
"introduction": bean.doc.introduction | |||
} |
@@ -1,11 +0,0 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# License: GNU General Public License v3. See license.txt | |||
# For license information, please see license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
class DocType: | |||
def __init__(self, d, dl): | |||
self.doc, self.doclist = d, dl |
@@ -1,36 +0,0 @@ | |||
[ | |||
{ | |||
"creation": "2013-06-20 16:00:18", | |||
"docstatus": 0, | |||
"modified": "2013-08-09 14:47:12", | |||
"modified_by": "Administrator", | |||
"owner": "Administrator" | |||
}, | |||
{ | |||
"doctype": "DocType", | |||
"istable": 1, | |||
"module": "Website", | |||
"name": "__common__" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "selling_price_list", | |||
"fieldtype": "Link", | |||
"in_list_view": 1, | |||
"label": "Price List", | |||
"name": "__common__", | |||
"options": "Price List", | |||
"parent": "Shopping Cart Price List", | |||
"parentfield": "fields", | |||
"parenttype": "DocType", | |||
"permlevel": 0, | |||
"reqd": 1 | |||
}, | |||
{ | |||
"doctype": "DocType", | |||
"name": "Shopping Cart Price List" | |||
}, | |||
{ | |||
"doctype": "DocField" | |||
} | |||
] |
@@ -1,10 +0,0 @@ | |||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
// License: GNU General Public License v3. See license.txt | |||
$.extend(cur_frm.cscript, { | |||
onload: function() { | |||
if(cur_frm.doc.__quotation_series) { | |||
cur_frm.fields_dict.quotation_series.df.options = cur_frm.doc.__quotation_series; | |||
} | |||
} | |||
}); |
@@ -1,149 +0,0 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# License: GNU General Public License v3. See license.txt | |||
# For license information, please see license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes import _, msgprint | |||
from webnotes.utils import comma_and | |||
from webnotes.model.controller import DocListController | |||
class ShoppingCartSetupError(webnotes.ValidationError): pass | |||
class DocType(DocListController): | |||
def onload(self): | |||
self.doc.fields["__quotation_series"] = webnotes.get_doctype("Quotation").get_options("naming_series") | |||
def validate(self): | |||
if self.doc.enabled: | |||
self.validate_price_lists() | |||
self.validate_tax_masters() | |||
self.validate_exchange_rates_exist() | |||
def on_update(self): | |||
webnotes.conn.set_default("shopping_cart_enabled", self.doc.fields.get("enabled") or 0) | |||
webnotes.conn.set_default("shopping_cart_quotation_series", self.doc.fields.get("quotation_series")) | |||
def validate_overlapping_territories(self, parentfield, fieldname): | |||
# for displaying message | |||
doctype = self.meta.get_field(parentfield).options | |||
# specify atleast one entry in the table | |||
self.validate_table_has_rows(parentfield, raise_exception=ShoppingCartSetupError) | |||
territory_name_map = self.get_territory_name_map(parentfield, fieldname) | |||
for territory, names in territory_name_map.items(): | |||
if len(names) > 1: | |||
msgprint(_("Error for") + " " + _(doctype) + ": " + comma_and(names) + | |||
" " + _("have a common territory") + ": " + territory, | |||
raise_exception=ShoppingCartSetupError) | |||
return territory_name_map | |||
def validate_price_lists(self): | |||
territory_name_map = self.validate_overlapping_territories("price_lists", | |||
"selling_price_list") | |||
# validate that a Shopping Cart Price List exists for the root territory | |||
# as a catch all! | |||
from setup.utils import get_root_of | |||
root_territory = get_root_of("Territory") | |||
if root_territory not in territory_name_map.keys(): | |||
msgprint(_("Please specify a Price List which is valid for Territory") + | |||
": " + root_territory, raise_exception=ShoppingCartSetupError) | |||
def validate_tax_masters(self): | |||
self.validate_overlapping_territories("sales_taxes_and_charges_masters", | |||
"sales_taxes_and_charges_master") | |||
def get_territory_name_map(self, parentfield, fieldname): | |||
territory_name_map = {} | |||
# entries in table | |||
names = [doc.fields.get(fieldname) for doc in self.doclist.get({"parentfield": parentfield})] | |||
if names: | |||
# for condition in territory check | |||
parenttype = self.meta.get_field(fieldname, parentfield=parentfield).options | |||
# to validate territory overlap | |||
# make a map of territory: [list of names] | |||
# if list against each territory has more than one element, raise exception | |||
territory_name = webnotes.conn.sql("""select `territory`, `parent` | |||
from `tabFor Territory` | |||
where `parenttype`=%s and `parent` in (%s)""" % | |||
("%s", ", ".join(["%s"]*len(names))), tuple([parenttype] + names)) | |||
for territory, name in territory_name: | |||
territory_name_map.setdefault(territory, []).append(name) | |||
if len(territory_name_map[territory]) > 1: | |||
territory_name_map[territory].sort(key=lambda val: names.index(val)) | |||
return territory_name_map | |||
def validate_exchange_rates_exist(self): | |||
"""check if exchange rates exist for all Price List currencies (to company's currency)""" | |||
company_currency = webnotes.conn.get_value("Company", self.doc.company, "default_currency") | |||
if not company_currency: | |||
msgprint(_("Please specify currency in Company") + ": " + self.doc.company, | |||
raise_exception=ShoppingCartSetupError) | |||
price_list_currency_map = webnotes.conn.get_values("Price List", | |||
[d.selling_price_list for d in self.doclist.get({"parentfield": "price_lists"})], | |||
"currency") | |||
expected_to_exist = [currency + "-" + company_currency | |||
for currency in price_list_currency_map.values() | |||
if currency != company_currency] | |||
if expected_to_exist: | |||
exists = webnotes.conn.sql_list("""select name from `tabCurrency Exchange` | |||
where name in (%s)""" % (", ".join(["%s"]*len(expected_to_exist)),), | |||
tuple(expected_to_exist)) | |||
missing = list(set(expected_to_exist).difference(exists)) | |||
if missing: | |||
msgprint(_("Missing Currency Exchange Rates for" + ": " + comma_and(missing)), | |||
raise_exception=ShoppingCartSetupError) | |||
def get_name_from_territory(self, territory, parentfield, fieldname): | |||
name = None | |||
territory_name_map = self.get_territory_name_map(parentfield, fieldname) | |||
if territory_name_map.get(territory): | |||
name = territory_name_map.get(territory) | |||
else: | |||
territory_ancestry = self.get_territory_ancestry(territory) | |||
for ancestor in territory_ancestry: | |||
if territory_name_map.get(ancestor): | |||
name = territory_name_map.get(ancestor) | |||
break | |||
return name | |||
def get_price_list(self, billing_territory): | |||
price_list = self.get_name_from_territory(billing_territory, "price_lists", "selling_price_list") | |||
return price_list and price_list[0] or None | |||
def get_tax_master(self, billing_territory): | |||
tax_master = self.get_name_from_territory(billing_territory, "sales_taxes_and_charges_masters", | |||
"sales_taxes_and_charges_master") | |||
return tax_master and tax_master[0] or None | |||
def get_shipping_rules(self, shipping_territory): | |||
return self.get_name_from_territory(shipping_territory, "shipping_rules", "shipping_rule") | |||
def get_territory_ancestry(self, territory): | |||
from setup.utils import get_ancestors_of | |||
if not hasattr(self, "_territory_ancestry"): | |||
self._territory_ancestry = {} | |||
if not self._territory_ancestry.get(territory): | |||
self._territory_ancestry[territory] = get_ancestors_of("Territory", territory) | |||
return self._territory_ancestry[territory] |
@@ -1,125 +0,0 @@ | |||
[ | |||
{ | |||
"creation": "2013-06-19 15:57:32", | |||
"docstatus": 0, | |||
"modified": "2013-07-15 17:33:05", | |||
"modified_by": "Administrator", | |||
"owner": "Administrator" | |||
}, | |||
{ | |||
"description": "Default settings for Shopping Cart", | |||
"doctype": "DocType", | |||
"icon": "icon-shopping-cart", | |||
"issingle": 1, | |||
"module": "Website", | |||
"name": "__common__" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"name": "__common__", | |||
"parent": "Shopping Cart Settings", | |||
"parentfield": "fields", | |||
"parenttype": "DocType", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"create": 1, | |||
"doctype": "DocPerm", | |||
"name": "__common__", | |||
"parent": "Shopping Cart Settings", | |||
"parentfield": "permissions", | |||
"parenttype": "DocType", | |||
"permlevel": 0, | |||
"read": 1, | |||
"role": "Website Manager", | |||
"write": 1 | |||
}, | |||
{ | |||
"doctype": "DocType", | |||
"name": "Shopping Cart Settings" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "enabled", | |||
"fieldtype": "Check", | |||
"label": "Enable Shopping Cart" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "section_break_2", | |||
"fieldtype": "Section Break" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "company", | |||
"fieldtype": "Link", | |||
"label": "Company", | |||
"options": "Company", | |||
"reqd": 1 | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "default_territory", | |||
"fieldtype": "Link", | |||
"label": "Default Territory", | |||
"options": "Territory", | |||
"reqd": 1 | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "column_break_4", | |||
"fieldtype": "Column Break" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "default_customer_group", | |||
"fieldtype": "Link", | |||
"label": "Default Customer Group", | |||
"options": "Customer Group", | |||
"reqd": 1 | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "quotation_series", | |||
"fieldtype": "Select", | |||
"label": "Quotation Series", | |||
"reqd": 1 | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "section_break_6", | |||
"fieldtype": "Section Break" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "price_lists", | |||
"fieldtype": "Table", | |||
"label": "Shopping Cart Price Lists", | |||
"options": "Shopping Cart Price List", | |||
"reqd": 0 | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "shipping_rules", | |||
"fieldtype": "Table", | |||
"label": "Shopping Cart Shipping Rules", | |||
"options": "Shopping Cart Shipping Rule", | |||
"reqd": 0 | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "column_break_10", | |||
"fieldtype": "Column Break" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "sales_taxes_and_charges_masters", | |||
"fieldtype": "Table", | |||
"label": "Shopping Cart Taxes and Charges Masters", | |||
"options": "Shopping Cart Taxes and Charges Master", | |||
"reqd": 0 | |||
}, | |||
{ | |||
"doctype": "DocPerm" | |||
} | |||
] |
@@ -1,81 +0,0 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# License: GNU General Public License v3. See license.txt | |||
# For license information, please see license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
import unittest | |||
from website.doctype.shopping_cart_settings.shopping_cart_settings import ShoppingCartSetupError | |||
class TestShoppingCartSettings(unittest.TestCase): | |||
def setUp(self): | |||
webnotes.conn.sql("""delete from `tabSingles` where doctype="Shipping Cart Settings" """) | |||
webnotes.conn.sql("""delete from `tabShopping Cart Price List`""") | |||
webnotes.conn.sql("""delete from `tabShopping Cart Taxes and Charges Master`""") | |||
webnotes.conn.sql("""delete from `tabShopping Cart Shipping Rule`""") | |||
def get_cart_settings(self): | |||
return webnotes.bean({"doctype": "Shopping Cart Settings", | |||
"company": "_Test Company"}) | |||
def test_price_list_territory_overlap(self): | |||
cart_settings = self.get_cart_settings() | |||
def _add_price_list(price_list): | |||
cart_settings.doclist.append({ | |||
"doctype": "Shopping Cart Price List", | |||
"parentfield": "price_lists", | |||
"selling_price_list": price_list | |||
}) | |||
for price_list in ("_Test Price List Rest of the World", "_Test Price List India", | |||
"_Test Price List"): | |||
_add_price_list(price_list) | |||
controller = cart_settings.make_controller() | |||
controller.validate_overlapping_territories("price_lists", "selling_price_list") | |||
_add_price_list("_Test Price List 2") | |||
controller = cart_settings.make_controller() | |||
self.assertRaises(ShoppingCartSetupError, controller.validate_overlapping_territories, | |||
"price_lists", "selling_price_list") | |||
return cart_settings | |||
def test_taxes_territory_overlap(self): | |||
cart_settings = self.get_cart_settings() | |||
def _add_tax_master(tax_master): | |||
cart_settings.doclist.append({ | |||
"doctype": "Shopping Cart Taxes and Charges Master", | |||
"parentfield": "sales_taxes_and_charges_masters", | |||
"sales_taxes_and_charges_master": tax_master | |||
}) | |||
for tax_master in ("_Test Sales Taxes and Charges Master", "_Test India Tax Master"): | |||
_add_tax_master(tax_master) | |||
controller = cart_settings.make_controller() | |||
controller.validate_overlapping_territories("sales_taxes_and_charges_masters", | |||
"sales_taxes_and_charges_master") | |||
_add_tax_master("_Test Sales Taxes and Charges Master 2") | |||
controller = cart_settings.make_controller() | |||
self.assertRaises(ShoppingCartSetupError, controller.validate_overlapping_territories, | |||
"sales_taxes_and_charges_masters", "sales_taxes_and_charges_master") | |||
def test_exchange_rate_exists(self): | |||
webnotes.conn.sql("""delete from `tabCurrency Exchange`""") | |||
cart_settings = self.test_price_list_territory_overlap() | |||
controller = cart_settings.make_controller() | |||
self.assertRaises(ShoppingCartSetupError, controller.validate_exchange_rates_exist) | |||
from setup.doctype.currency_exchange.test_currency_exchange import test_records as \ | |||
currency_exchange_records | |||
webnotes.bean(currency_exchange_records[0]).insert() | |||
controller.validate_exchange_rates_exist() | |||
@@ -1,11 +0,0 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# License: GNU General Public License v3. See license.txt | |||
# For license information, please see license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
class DocType: | |||
def __init__(self, d, dl): | |||
self.doc, self.doclist = d, dl |
@@ -1,36 +0,0 @@ | |||
[ | |||
{ | |||
"creation": "2013-07-03 13:15:34", | |||
"docstatus": 0, | |||
"modified": "2013-07-10 14:54:23", | |||
"modified_by": "Administrator", | |||
"owner": "Administrator" | |||
}, | |||
{ | |||
"doctype": "DocType", | |||
"istable": 1, | |||
"module": "Website", | |||
"name": "__common__" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "shipping_rule", | |||
"fieldtype": "Link", | |||
"in_list_view": 1, | |||
"label": "Shipping Rule", | |||
"name": "__common__", | |||
"options": "Shipping Rule", | |||
"parent": "Shopping Cart Shipping Rule", | |||
"parentfield": "fields", | |||
"parenttype": "DocType", | |||
"permlevel": 0, | |||
"reqd": 1 | |||
}, | |||
{ | |||
"doctype": "DocType", | |||
"name": "Shopping Cart Shipping Rule" | |||
}, | |||
{ | |||
"doctype": "DocField" | |||
} | |||
] |
@@ -1,11 +0,0 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# License: GNU General Public License v3. See license.txt | |||
# For license information, please see license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
class DocType: | |||
def __init__(self, d, dl): | |||
self.doc, self.doclist = d, dl |
@@ -1,36 +0,0 @@ | |||
[ | |||
{ | |||
"creation": "2013-06-20 16:57:03", | |||
"docstatus": 0, | |||
"modified": "2013-07-10 14:54:23", | |||
"modified_by": "Administrator", | |||
"owner": "Administrator" | |||
}, | |||
{ | |||
"doctype": "DocType", | |||
"istable": 1, | |||
"module": "Website", | |||
"name": "__common__" | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
"fieldname": "sales_taxes_and_charges_master", | |||
"fieldtype": "Link", | |||
"in_list_view": 1, | |||
"label": "Tax Master", | |||
"name": "__common__", | |||
"options": "Sales Taxes and Charges Master", | |||
"parent": "Shopping Cart Taxes and Charges Master", | |||
"parentfield": "fields", | |||
"parenttype": "DocType", | |||
"permlevel": 0, | |||
"reqd": 1 | |||
}, | |||
{ | |||
"doctype": "DocType", | |||
"name": "Shopping Cart Taxes and Charges Master" | |||
}, | |||
{ | |||
"doctype": "DocField" | |||
} | |||
] |
@@ -64,12 +64,6 @@ wn.module_page["Website"] = [ | |||
"description":wn._("Setup of fonts and background."), | |||
doctype:"Style Settings" | |||
}, | |||
{ | |||
"route":"Form/Shopping Cart Settings", | |||
"label":wn._("Shopping Cart Settings"), | |||
"description":wn._("Setup of Shopping Cart."), | |||
doctype:"Shopping Cart Settings" | |||
}, | |||
] | |||
}, | |||
{ | |||
@@ -1,5 +1,5 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# License: GNU General Public License v3. See license.txt | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
@@ -34,7 +34,7 @@ | |||
</ul> | |||
</div> | |||
{% if copyright %}<div class="web-footer-copyright">© {{ copyright }}</div>{% endif %} | |||
{% if address %}{{ address }}{% endif %} | |||
{% if footer_address %}{{ footer_address }}{% endif %} | |||
{% block extension %}{% endblock %} | |||
</div> | |||
</div> | |||
@@ -1,4 +1,4 @@ | |||
{% extends "lib/website/templates/base.html" %} | |||
{% extends base_template %} | |||
{% set title="Not Found" %} | |||
@@ -0,0 +1 @@ | |||
from __future__ import unicode_literals |
@@ -1,4 +1,4 @@ | |||
{% extends "lib/website/templates/base.html" %} | |||
{% extends base_template %} | |||
{% set title="Error" %} | |||
@@ -0,0 +1,6 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
no_cache = True |
@@ -1,4 +1,4 @@ | |||
{% extends "lib/website/templates/base.html" %} | |||
{% extends base_template %} | |||
{% set title=webnotes.message_title %} | |||
@@ -0,0 +1,6 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
no_cache = True |
@@ -0,0 +1,6 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
no_cache = True |