[website] [minor] moving to framework

This commit is contained in:
Anand Doshi
2013-09-10 18:29:39 +05:30
parent f2d0255031
commit b0d996ffb1
52 changed files with 606 additions and 199 deletions

View File

@@ -286,6 +286,9 @@ class DocType(SellingController):
def on_update(self):
pass
def get_portal_page(self):
return "order" if self.doc.docstatus==1 else None
def set_missing_values(source, target):
bean = webnotes.bean(target)
bean.run_method("onload_post_render")

View File

@@ -0,0 +1 @@
{% extends "app/portal/templates/sale.html" %}

View File

@@ -0,0 +1,16 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
no_cache = True
def get_context():
from portal.website_transactions import get_transaction_context
context = get_transaction_context("Sales Order", webnotes.form_dict.name)
context.update({
"parent_link": "orders",
"parent_title": "My Orders"
})
return context

View File

@@ -0,0 +1 @@
{% extends "app/portal/templates/sales_transactions.html" %}

View File

@@ -0,0 +1,25 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
no_cache = True
def get_context():
from portal.website_transactions import get_currency_context
context = get_currency_context()
context.update({
"title": "My Orders",
"method": "portal.templates.pages.orders.get_orders",
"icon": "icon-list",
"empty_list_message": "No Orders Yet",
"page": "order",
})
return context
@webnotes.whitelist()
def get_orders(start=0):
from portal.website_transactions import get_transaction_list
return get_transaction_list("Sales Order", start)

View File

@@ -0,0 +1,11 @@
# 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

View File

@@ -0,0 +1,36 @@
[
{
"creation": "2013-06-20 16:00:18",
"docstatus": 0,
"modified": "2013-08-09 14:47:15",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "DocType",
"istable": 1,
"module": "Selling",
"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"
}
]

View File

@@ -0,0 +1,10 @@
// 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;
}
}
});

View File

@@ -0,0 +1,149 @@
# 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]

View File

@@ -0,0 +1,125 @@
[
{
"creation": "2013-06-19 15:57:32",
"docstatus": 0,
"modified": "2013-07-15 17:33:15",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"description": "Default settings for Shopping Cart",
"doctype": "DocType",
"icon": "icon-shopping-cart",
"issingle": 1,
"module": "Selling",
"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"
}
]

View File

@@ -0,0 +1,81 @@
# 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 selling.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()

View File

@@ -0,0 +1,11 @@
# 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

View File

@@ -0,0 +1,36 @@
[
{
"creation": "2013-07-03 13:15:34",
"docstatus": 0,
"modified": "2013-07-10 14:54:25",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "DocType",
"istable": 1,
"module": "Selling",
"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"
}
]

View File

@@ -0,0 +1,11 @@
# 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

View File

@@ -0,0 +1,36 @@
[
{
"creation": "2013-06-20 16:57:03",
"docstatus": 0,
"modified": "2013-07-10 14:54:25",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "DocType",
"istable": 1,
"module": "Selling",
"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"
}
]

View File

@@ -65,6 +65,12 @@ wn.module_page["Selling"] = [
"doctype":"Selling Settings",
"description": "Settings for Selling Module"
},
{
"route":"Form/Shopping Cart Settings",
"label":wn._("Shopping Cart Settings"),
"description":wn._("Setup of Shopping Cart."),
doctype:"Shopping Cart Settings"
},
{
label: wn._("Sales Taxes and Charges Master"),
description: wn._("Sales taxes template."),