Merge branch 'responsive' of github.com:webnotes/erpnext into responsive
diff --git a/config.json b/config.json
index 5f9ac5e..bdc8748 100644
--- a/config.json
+++ b/config.json
@@ -134,7 +134,8 @@
},
"profile": {
"no_cache": true,
- "template": "app/website/templates/pages/profile"
+ "template": "app/website/templates/pages/profile",
+ "args_method": "startup.webutils.get_profile_args"
},
"cart": {
"no_cache": true,
diff --git a/home/page/latest_updates/latest_updates.js b/home/page/latest_updates/latest_updates.js
index ea6ff49..60539db 100644
--- a/home/page/latest_updates/latest_updates.js
+++ b/home/page/latest_updates/latest_updates.js
@@ -21,7 +21,7 @@
var $tbody = $('<table class="table table-bordered"><tbody></tbody></table>')
.appendTo(parent).find("tbody");
$.each(r.message, function(i, log) {
- if(log.message.indexOf("minor")!==-1 && log.message.indexOf("[")!==-1) {
+ if(log.message.indexOf("minor")===1 && log.message.indexOf("[")!==-1) {
log.message = log.message.replace(/(\[[^\]]*\])/g,
function(match, p1, offset, string) {
match = match.toLowerCase();
diff --git a/patches/patch_list.py b/patches/patch_list.py
index 114c6e0..032297f 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -21,7 +21,6 @@
"execute:webnotes.reload_doc('core', 'doctype', 'report')",
"execute:webnotes.reload_doc('core', 'doctype', 'doctype') # 2013-07-08",
"execute:webnotes.reload_doc('core', 'doctype', 'page') # 2013-06-24",
- "patches.mar_2012.so_rv_mapper_fix",
"patches.mar_2012.clean_property_setter",
"patches.april_2012.naming_series_patch",
"patches.mar_2012.cleanup_control_panel",
diff --git a/public/js/complete_setup.js b/public/js/complete_setup.js
index 4fb29e3..a93aae6 100644
--- a/public/js/complete_setup.js
+++ b/public/js/complete_setup.js
@@ -75,6 +75,7 @@
if(!data) return;
$(this).set_working();
$c_obj('Setup Control','setup_account',data,function(r, rt){
+ $(this).done_working();
if(!r.exc) {
sys_defaults = r.message;
user_fullname = r.message.user_fullname;
@@ -84,12 +85,16 @@
wn.container.wntoolbar.set_user_name();
setTimeout(function() { window.location.reload(); }, 3000);
- } else {
- $(this).done_working();
}
});
};
-
+
+ d.fields_dict.company_name.input.onchange = function() {
+ var parts = d.get_input("company_name").val().split(" ");
+ var abbr = $.map(parts, function(p) { return p ? p.substr(0,1) : null }).join("");
+ d.get_input("company_abbr").val(abbr.toUpperCase());
+ }
+
d.fields_dict.country.input.onchange = function() {
var country = d.fields_dict.country.input.value;
var $timezone = $(d.fields_dict.timezone.input);
diff --git a/public/js/website_utils.js b/public/js/website_utils.js
index e714514..519d630 100644
--- a/public/js/website_utils.js
+++ b/public/js/website_utils.js
@@ -95,6 +95,8 @@
$("#user-full-name").text(full_name);
}
+ wn.cart.set_cart_count();
+
$("#user-tools a").tooltip({"placement":"bottom"});
$("#user-tools-post-login a").tooltip({"placement":"bottom"});
});
@@ -212,8 +214,16 @@
callback: function(r) {
if(opts.callback)
opts.callback(r);
+
+ wn.cart.set_cart_count();
}
});
}
},
+
+ set_cart_count: function() {
+ var cart_count = getCookie("cart_count");
+ if(cart_count)
+ $(".cart-count").html("( "+ cart_count +" )")
+ }
});
\ No newline at end of file
diff --git a/selling/doctype/customer/customer.py b/selling/doctype/customer/customer.py
index 2820fb3..9022cb5 100644
--- a/selling/doctype/customer/customer.py
+++ b/selling/doctype/customer/customer.py
@@ -132,8 +132,15 @@
self.doc.name, raise_exception=1)
def delete_customer_address(self):
- for rec in sql("select * from `tabAddress` where customer=%s", (self.doc.name,), as_dict=1):
- sql("delete from `tabAddress` where name=%s", (rec['name']))
+ addresses = webnotes.conn.sql("""select name, lead from `tabAddress`
+ where customer=%s""", (self.doc.name,))
+
+ for name, lead in addresses:
+ if lead:
+ webnotes.conn.sql("""update `tabAddress` set customer=null, customer_name=null
+ where name=%s""", name)
+ else:
+ webnotes.conn.sql("""delete from `tabAddress` where name=%s""", name)
def delete_customer_contact(self):
for rec in sql("select * from `tabContact` where customer=%s", (self.doc.name,), as_dict=1):
diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py
index a97611e..79b296b 100644
--- a/selling/doctype/lead/lead.py
+++ b/selling/doctype/lead/lead.py
@@ -99,6 +99,9 @@
@webnotes.whitelist()
def make_customer(source_name, target_doclist=None):
+ _make_customer(source_name, target_doclist)
+
+def _make_customer(source_name, target_doclist=None, ignore_permissions=False):
from webnotes.model.mapper import get_mapped_doclist
def set_missing_values(source, target):
@@ -120,7 +123,7 @@
"contact_no": "phone_1",
"fax": "fax_1"
}
- }}, target_doclist, set_missing_values)
+ }}, target_doclist, set_missing_values, ignore_permissions=ignore_permissions)
return [d.fields for d in doclist]
diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py
index 5bf8510..6020c93 100644
--- a/selling/doctype/quotation/quotation.py
+++ b/selling/doctype/quotation/quotation.py
@@ -230,8 +230,18 @@
@webnotes.whitelist()
def make_sales_order(source_name, target_doclist=None):
+ return _make_sales_order(source_name, target_doclist)
+
+def _make_sales_order(source_name, target_doclist=None, ignore_permissions=False):
from webnotes.model.mapper import get_mapped_doclist
-
+
+ customer = _make_customer(source_name, ignore_permissions)
+
+ def set_missing_values(source, target):
+ if customer:
+ target[0].customer = customer.doc.name
+ target[0].customer_name = customer.doc.customer_name
+
doclist = get_mapped_doclist("Quotation", source_name, {
"Quotation": {
"doctype": "Sales Order",
@@ -255,12 +265,38 @@
"Sales Team": {
"doctype": "Sales Team",
}
- }, target_doclist)
+ }, target_doclist, set_missing_values, ignore_permissions=ignore_permissions)
# postprocess: fetch shipping address, set missing values
return [d.fields for d in doclist]
+def _make_customer(source_name, ignore_permissions=False):
+ quotation = webnotes.conn.get_value("Quotation", source_name, ["lead", "order_type"])
+ if quotation and quotation[0]:
+ lead_name = quotation[0]
+ customer_name = webnotes.conn.get_value("Customer", {"lead_name": lead_name})
+ if not customer_name:
+ from selling.doctype.lead.lead import _make_customer
+ customer_doclist = _make_customer(lead_name, ignore_permissions=ignore_permissions)
+ customer = webnotes.bean(customer_doclist)
+ customer.ignore_permissions = ignore_permissions
+ if quotation[1] == "Shopping Cart":
+ customer.doc.customer_group = webnotes.conn.get_value("Shopping Cart Settings", None,
+ "default_customer_group")
+
+ try:
+ customer.insert()
+ return customer
+ except NameError, e:
+ if webnotes.defaults.get_global_default('cust_master_name') == "Customer Name":
+ customer.run_method("autoname")
+ customer.doc.name += "-" + lead_name
+ customer.insert()
+ return customer
+ else:
+ raise e
+
def quotation_details(doctype, txt, searchfield, start, page_len, filters):
from controllers.queries import get_match_cond
@@ -297,4 +333,4 @@
return webnotes.conn.sql(""" select name, item_name, description from `tabItem` item
where %s %s and %s like %s order by name desc limit %s, %s""" %
("%s", get_match_cond(doctype, searchfield), searchfield, "%s", "%s", "%s"),
- (filters["cond"], "%%%s%%" % txt, start, page_len))
\ No newline at end of file
+ (filters["cond"], "%%%s%%" % txt, start, page_len))
diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py
index 2761f7e..a65490b 100644
--- a/selling/doctype/sales_order/sales_order.py
+++ b/selling/doctype/sales_order/sales_order.py
@@ -319,7 +319,7 @@
# find customer id
customer = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user},
"customer")
-
+
if customer:
orders = webnotes.conn.sql("""select
name, creation, currency from `tabSales Order`
@@ -334,6 +334,7 @@
from `tabSales Order Item`
where parent=%s
order by idx""", order.name, as_dict=1)
+
return orders
else:
return []
diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py
index ea3d1b9..968296c 100644
--- a/setup/doctype/company/company.py
+++ b/setup/doctype/company/company.py
@@ -39,6 +39,7 @@
where company=%s and docstatus<2 limit 1""", self.doc.name):
self.create_default_accounts()
self.create_default_warehouses()
+ self.create_default_web_page()
if not self.doc.cost_center:
self.create_default_cost_center()
@@ -52,8 +53,46 @@
for whname in ("Stores", "Work In Progress", "Finished Goods"):
webnotes.bean({
"doctype":"Warehouse",
+ "warehouse_name": whname,
"company": self.doc.name
}).insert()
+
+ def create_default_web_page(self):
+ if not webnotes.conn.get_value("Website Settings", None, "home_page"):
+ import os
+ with open(os.path.join(os.path.dirname(__file__), "sample_home_page.html"), "r") as webfile:
+ webpage = webnotes.bean({
+ "doctype": "Web Page",
+ "title": self.doc.name + " Home",
+ "published": 1,
+ "description": "Standard Home Page for " + self.doc.company,
+ "main_section": webfile.read() % self.doc.fields
+ }).insert()
+
+ # update in home page in settings
+ website_settings = webnotes.bean("Website Settings", "Website Settings")
+ website_settings.doc.home_page = webpage.doc.name
+ website_settings.doc.banner_html = """<h3 style='margin-bottom: 20px;'>""" + self.doc.name + "</h3>"
+ website_settings.doc.copyright = self.doc.name
+ website_settings.doclist.append({
+ "doctype": "Top Bar Item",
+ "parentfield": "top_bar_items",
+ "label":"Home",
+ "url": webpage.doc.name
+ })
+ website_settings.doclist.append({
+ "doctype": "Top Bar Item",
+ "parentfield": "top_bar_items",
+ "label":"Contact",
+ "url": "contact"
+ })
+ website_settings.doclist.append({
+ "doctype": "Top Bar Item",
+ "parentfield": "top_bar_items",
+ "label":"Blog",
+ "url": "blog"
+ })
+ website_settings.save()
def create_default_accounts(self):
self.fld_dict = {'account_name':0,'parent_account':1,'group_or_ledger':2,'is_pl_account':3,'account_type':4,'debit_or_credit':5,'company':6,'tax_rate':7}
diff --git a/setup/doctype/company/sample_home_page.html b/setup/doctype/company/sample_home_page.html
new file mode 100644
index 0000000..32e58bd
--- /dev/null
+++ b/setup/doctype/company/sample_home_page.html
@@ -0,0 +1,22 @@
+<h2 style="text-align: center;"><i class="icon-home"></i> Sample Home Page</h2>
+<br>
+<p>This is a sample home page for your company <b>%(name)s's</b> website. This was
+ created from the Website Module inside ERPNext. ERPNext provides you with simple
+ tools to build and update your website. You can add sections like your Product Catalog,
+ Blog, Contact Us, About Us and so on. Messages entered in the "Contact" page are
+ automatically added as Leads in the system.
+
+<h5>What you can do with your website:</h5>
+
+<ul>
+ <li>Automatically generate products / services catalog from your Items.
+ <li>Capture Leads from your website.
+ <li>Communicate with your customers by sharing your thoughts in your Blog.
+ <li>Introduce your company and team in the About Us page.
+</ul>
+
+<p>Infact,
+ <a href="https://erpnext.com" target="_blank">erpnext.com</a>
+ website is built on ERPNext itself.</p>
+
+<p class="text-muted">For more help, click here</p>
diff --git a/setup/doctype/notification_control/notification_control.txt b/setup/doctype/notification_control/notification_control.txt
index c1f559b..81e08a5 100644
--- a/setup/doctype/notification_control/notification_control.txt
+++ b/setup/doctype/notification_control/notification_control.txt
@@ -2,7 +2,7 @@
{
"creation": "2012-07-12 23:29:45",
"docstatus": 0,
- "modified": "2013-07-10 14:54:11",
+ "modified": "2013-07-10 19:24:07",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -12,6 +12,7 @@
"allow_print": 1,
"description": "Send automatic emails to Contacts on Submitting transactions.",
"doctype": "DocType",
+ "icon": "icon-envelope",
"issingle": 1,
"module": "Setup",
"name": "__common__"
diff --git a/setup/doctype/setup_control/setup_control.py b/setup/doctype/setup_control/setup_control.py
index c6b0b6c..a85384b 100644
--- a/setup/doctype/setup_control/setup_control.py
+++ b/setup/doctype/setup_control/setup_control.py
@@ -65,7 +65,7 @@
webnotes.bean([{
"doctype":"Fiscal Year",
'year': curr_fiscal_year,
- 'year_start_date': fy_start_date,
+ 'year_start_date': fy_start_date
}]).insert()
curr_fiscal_year, fy_start_date, fy_abbr = self.get_fy_details(args.get('fy_start'))
@@ -79,9 +79,10 @@
# Company
webnotes.bean([{
"doctype":"Company",
+ 'domain': args.get("industry"),
'company_name':args.get('company_name'),
'abbr':args.get('company_abbr'),
- 'default_currency':args.get('currency')
+ 'default_currency':args.get('currency'),
}]).insert()
self.curr_fiscal_year = curr_fiscal_year
@@ -148,7 +149,7 @@
# control panel
cp = webnotes.doc("Control Panel", "Control Panel")
- for k in ['industry', 'country', 'timezone', 'company_name']:
+ for k in ['country', 'timezone', 'company_name']:
cp.fields[k] = args[k]
cp.save()
diff --git a/startup/event_handlers.py b/startup/event_handlers.py
index f0c73a5..cd5cebf 100644
--- a/startup/event_handlers.py
+++ b/startup/event_handlers.py
@@ -6,7 +6,6 @@
import webnotes
import home
-
def on_login_post_session(login_manager):
"""
called after login
@@ -30,7 +29,14 @@
'%s logged in at %s' % (get_user_fullname(login_manager.user), nowtime()),
login_manager.user=='Administrator' and '#8CA2B3' or '#1B750D')
webnotes.conn.commit()
-
+
+ if webnotes.cookies.get("full_name"):
+ from website.helpers.cart import set_cart_count
+ set_cart_count()
+
+def on_logout(login_manager):
+ webnotes.add_cookies["cart_count"] = ""
+
def check_if_expired():
"""check if account is expired. If expired, do not allow login"""
import conf
diff --git a/startup/install.py b/startup/install.py
index 5b948a9..896a6cd 100644
--- a/startup/install.py
+++ b/startup/install.py
@@ -146,9 +146,6 @@
{'doctype': 'Supplier Type', 'supplier_type': 'Hardware'},
{'doctype': 'Supplier Type', 'supplier_type': 'Pharmaceutical'},
{'doctype': 'Supplier Type', 'supplier_type': 'Distributor'},
-
- # Workstation
- {'doctype': 'Workstation', 'name': 'Default Workstation', 'workstation_name': 'Default Workstation', 'warehouse': 'Default Warehouse'},
# Sales Person
{'doctype': 'Sales Person', 'sales_person_name': 'Sales Team', 'is_group': "Yes", "parent_sales_person": ""},
@@ -166,12 +163,11 @@
from webnotes.modules import scrub
for r in records:
- if not webnotes.conn.exists(r['doctype'], r['name']):
- bean = webnotes.bean(r)
-
- # ignore mandatory for root
- parent_link_field = ("parent_" + scrub(bean.doc.doctype))
- if parent_link_field in bean.doc.fields and not bean.doc.fields.get(parent_link_field):
- bean.ignore_mandatory = True
-
- bean.insert()
\ No newline at end of file
+ bean = webnotes.bean(r)
+
+ # ignore mandatory for root
+ parent_link_field = ("parent_" + scrub(bean.doc.doctype))
+ if parent_link_field in bean.doc.fields and not bean.doc.fields.get(parent_link_field):
+ bean.ignore_mandatory = True
+
+ bean.insert()
\ No newline at end of file
diff --git a/startup/website.py b/startup/webutils.py
similarity index 69%
rename from startup/website.py
rename to startup/webutils.py
index dfaba02..4c1f528 100644
--- a/startup/website.py
+++ b/startup/webutils.py
@@ -62,6 +62,30 @@
args.url = quote(str(get_request_site_address(full_address=True)), str(""))
args.encoded_title = quote(encode(args.title or ""), str(""))
+ args.shopping_cart_enabled = cint(webnotes.conn.get_default("shopping_cart_enabled"))
return args
-
\ No newline at end of file
+
+@webnotes.whitelist()
+def update_profile(fullname, password=None, company_name=None, mobile_no=None, phone=None):
+ from website.helpers.cart import update_party
+ update_party(fullname, company_name, mobile_no, phone)
+
+ from core.doctype.profile import profile
+ return profile.update_profile(fullname, password)
+
+def get_profile_args():
+ from website.helpers.cart import get_lead_or_customer
+ party = get_lead_or_customer()
+ if party.doctype == "Lead":
+ mobile_no = party.mobile_no
+ phone = party.phone
+ else:
+ mobile_no, phone = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user,
+ "customer": party.name})
+
+ return {
+ "company_name": party.customer_name if party.doctype == "Customer" else party.company_name,
+ "mobile_no": mobile_no,
+ "phone": phone
+ }
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 9f88774..47c0a75 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -665,11 +665,15 @@
return result and result[0] or {}
def get_cust_addr(self):
+ from utilities.transaction_base import get_default_address, get_address_display
res = sql("select customer_name from `tabCustomer` where name = '%s'"%self.doc.customer)
- addr = self.get_address_text(customer = self.doc.customer)
+ address_display = None
+ customer_address = get_default_address("customer", self.doc.customer)
+ if customer_address:
+ address_display = get_address_display(customer_address)
ret = {
'customer_name' : res and res[0][0] or '',
- 'customer_address' : addr and addr[0] or ''}
+ 'customer_address' : address_display}
return ret
@@ -682,12 +686,17 @@
return result and result[0] or {}
def get_supp_addr(self):
+ from utilities.transaction_base import get_default_address, get_address_display
res = sql("""select supplier_name from `tabSupplier`
where name=%s""", self.doc.supplier)
- addr = self.get_address_text(supplier = self.doc.supplier)
+ address_display = None
+ supplier_address = get_default_address("customer", self.doc.customer)
+ if supplier_address:
+ address_display = get_address_display(supplier_address)
+
ret = {
'supplier_name' : res and res[0][0] or '',
- 'supplier_address' : addr and addr[0] or ''}
+ 'supplier_address' : address_display }
return ret
def validate_with_material_request(self):
diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py
index 74a75e6..db5cc07 100644
--- a/utilities/transaction_base.py
+++ b/utilities/transaction_base.py
@@ -32,6 +32,41 @@
return get_default_address_and_contact(party_field, party_name,
fetch_shipping_address=True if self.meta.get_field("shipping_address_name") else False)
+ def set_address_fields(self):
+ party_type, party_name = self.get_party_type_and_name()
+
+ if party_type in ("Customer", "Lead"):
+ if self.doc.customer_address:
+ self.doc.address_display = get_address_display(self.doc.customer_address)
+
+ if self.doc.shipping_address_name:
+ self.doc.shipping_address = get_address_display(self.doc.shipping_address_name)
+
+ elif self.doc.supplier_address:
+ self.doc.address_display = get_address_display(self.doc.supplier_address)
+
+ def set_contact_fields(self):
+ party_type, party_name = self.get_party_type_and_name()
+
+ if party_type == "Lead":
+ contact_dict = map_lead_contact_details(party_name)
+ else:
+ contact_dict = map_party_contact_details(self.doc.contact_person, party_type, party_name)
+
+ for fieldname, value in contact_dict.items():
+ if self.meta.get_field(fieldname):
+ self.doc.fields[fieldname] = value
+
+ def get_party_type_and_name(self):
+ if not hasattr(self, "_party_type_and_name"):
+ for party_type in ("Lead", "Customer", "Supplier"):
+ party_field = party_type.lower()
+ if self.meta.get_field(party_field) and self.doc.fields.get(party_field):
+ self._party_type_and_name = (party_type, self.doc.fields.get(party_field))
+ break
+
+ return self._party_type_and_name
+
def get_customer_defaults(self):
out = self.get_default_address_and_contact("customer")
@@ -53,12 +88,7 @@
3. Clears existing Sales Team and fetches the one mentioned in Customer
"""
customer_defaults = self.get_customer_defaults()
-
- # hack! TODO - add shipping_address_field in Delivery Note
- if self.doc.doctype == "Delivery Note":
- customer_defaults["customer_address"] = customer_defaults["shipping_address_name"]
- customer_defaults["address_display"] = customer_defaults["shipping_address"]
-
+
customer_defaults["price_list"] = customer_defaults["price_list"] or \
webnotes.conn.get_value("Customer Group", self.doc.customer_group, "default_price_list") or \
self.doc.price_list
@@ -110,91 +140,35 @@
# -----------------------
def get_customer_address(self, args):
args = load_json(args)
- address_text, address_name = self.get_address_text(address_name=args['address'])
ret = {
- 'customer_address' : address_name,
- 'address_display' : address_text,
+ 'customer_address' : args["address"],
+ 'address_display' : get_address_display(args["address"]),
}
- ret.update(self.get_contact_text(contact_name=args['contact']))
-
- return ret
-
- # Get Address Text
- # -----------------------
- def get_address_text(self, customer=None, address_name=None, supplier=None, is_shipping_address=None):
- if customer:
- cond = customer and 'customer="%s"' % customer or 'name="%s"' % address_name
- elif supplier:
- cond = supplier and 'supplier="%s"' % supplier or 'name="%s"' % address_name
- else:
- cond = 'name="%s"' % address_name
+ ret.update(map_party_contact_details(args['contact']))
- if is_shipping_address:
- details = webnotes.conn.sql("select name, address_line1, address_line2, city, country, pincode, state, phone, fax from `tabAddress` where %s and docstatus != 2 order by is_shipping_address desc, is_primary_address desc limit 1" % cond, as_dict = 1)
- else:
- details = webnotes.conn.sql("select name, address_line1, address_line2, city, country, pincode, state, phone, fax from `tabAddress` where %s and docstatus != 2 order by is_primary_address desc limit 1" % cond, as_dict = 1)
-
- address_display = ""
-
- if details:
- address_display = get_address_display(details[0])
+ return ret
- address_name = details and details[0]['name'] or ''
-
- return address_display, address_name
-
- # Get Contact Text
- # -----------------------
- def get_contact_text(self, customer=None, contact_name=None, supplier=None):
- if customer:
- cond = customer and 'customer="%s"' % customer or 'name="%s"' % contact_name
- elif supplier:
- cond = supplier and 'supplier="%s"' % supplier or 'name="%s"' % contact_name
- else:
- cond = 'name="%s"' % contact_name
-
- details = webnotes.conn.sql("select name, first_name, last_name, email_id, phone, mobile_no, department, designation from `tabContact` where %s and docstatus != 2 order by is_primary_contact desc limit 1" % cond, as_dict = 1)
-
- extract = lambda x: details and details[0] and details[0].get(x,'') or ''
- contact_fields = [('','first_name'),(' ','last_name')]
- contact_display = ''.join([a[0]+cstr(extract(a[1])) for a in contact_fields if extract(a[1])])
- if contact_display.startswith('\n'): contact_display = contact_display[1:]
-
- return {
- "contact_display": contact_display,
- "contact_person": details and details[0]["name"] or "",
- "contact_email": details and details[0]["email_id"] or "",
- "contact_mobile": details and details[0]["mobile_no"] or "",
- "contact_designation": details and details[0]["designation"] or "",
- "contact_department": details and details[0]["department"] or "",
- }
-
# TODO deprecate this - used only in sales_order.js
def get_shipping_address(self, name):
- details = webnotes.conn.sql("select name, address_line1, address_line2, city, country, pincode, state, phone from `tabAddress` where customer = '%s' and docstatus != 2 order by is_shipping_address desc, is_primary_address desc limit 1" %(name), as_dict = 1)
-
- address_display = ""
- if details:
- address_display = get_address_display(details[0])
-
- ret = {
- 'shipping_address_name' : details and details[0]['name'] or '',
- 'shipping_address' : address_display
+ shipping_address = get_default_address("customer", name, is_shipping_address=True)
+ return {
+ 'shipping_address_name' : shipping_address,
+ 'shipping_address' : get_address_display(shipping_address) if shipping_address else None
}
- return ret
# Get Supplier Default Primary Address - first load
# -----------------------
def get_default_supplier_address(self, args):
if isinstance(args, basestring):
args = load_json(args)
- address_text, address_name = self.get_address_text(supplier=args['supplier'])
+
+ address_name = get_default_address("supplier", args["supplier"])
ret = {
'supplier_address' : address_name,
- 'address_display' : address_text,
+ 'address_display' : get_address_display(address_name),
}
- ret.update(self.get_contact_text(supplier=args['supplier']))
+ ret.update(map_party_contact_details(None, "supplier", args["supplier"]))
ret.update(self.get_supplier_details(args['supplier']))
return ret
@@ -202,12 +176,11 @@
# -----------------------
def get_supplier_address(self, args):
args = load_json(args)
- address_text, address_name = self.get_address_text(address_name=args['address'])
ret = {
- 'supplier_address' : address_name,
- 'address_display' : address_text,
+ 'supplier_address' : args['address'],
+ 'address_display' : get_address_display(args["address"]),
}
- ret.update(self.get_contact_text(contact_name=args['contact']))
+ ret.update(map_party_contact_details(contact_name=args['contact']))
return ret
# Get Supplier Details
@@ -322,23 +295,24 @@
[d[0] for d in fields], as_dict=1)
for field, condition in fields:
- self.validate_value(field, condition, prevdoc_values[field], doc)
+ if prevdoc_values[field] is not None:
+ self.validate_value(field, condition, prevdoc_values[field], doc)
def get_default_address_and_contact(party_field, party_name, fetch_shipping_address=False):
out = {}
# get addresses
- billing_address = get_address_dict(party_field, party_name)
+ billing_address = get_default_address(party_field, party_name)
if billing_address:
- out[party_field + "_address"] = billing_address["name"]
+ out[party_field + "_address"] = billing_address
out["address_display"] = get_address_display(billing_address)
else:
out[party_field + "_address"] = out["address_display"] = None
if fetch_shipping_address:
- shipping_address = get_address_dict(party_field, party_name, is_shipping_address=True)
+ shipping_address = get_default_address(party_field, party_name, is_shipping_address=True)
if shipping_address:
- out["shipping_address_name"] = shipping_address["name"]
+ out["shipping_address_name"] = shipping_address
out["shipping_address"] = get_address_display(shipping_address)
else:
out["shipping_address_name"] = out["shipping_address"] = None
@@ -346,39 +320,47 @@
# get contact
if party_field == "lead":
out["customer_address"] = out.get("lead_address")
- out.update(map_lead_fields(party_name))
+ out.update(map_lead_contact_details(party_name))
else:
- out.update(map_contact_fields(party_field, party_name))
+ out.update(map_party_contact_details(None, party_field, party_name))
return out
-
-def get_address_dict(party_field, party_name, is_shipping_address=None):
- order_by = "is_shipping_address desc, is_primary_address desc, name asc" if \
- is_shipping_address else "is_primary_address desc, name asc"
-
- address = webnotes.conn.sql("""select * from `tabAddress` where `%s`=%s order by %s
- limit 1""" % (party_field, "%s", order_by), party_name, as_dict=True,
- update={"doctype": "Address"})
- return address[0] if address else None
-
+def get_default_address(party_field, party_name, is_shipping_address=False):
+ if is_shipping_address:
+ order_by = "is_shipping_address desc, is_primary_address desc, name asc"
+ else:
+ order_by = "is_primary_address desc, name asc"
+
+ address = webnotes.conn.sql("""select name from `tabAddress` where `%s`=%s order by %s
+ limit 1""" % (party_field, "%s", order_by), party_name)
+
+ return address[0][0] if address else None
+
+def get_default_contact(party_field, party_name):
+ contact = webnotes.conn.sql("""select name from `tabContact` where `%s`=%s
+ order by is_primary_contact desc, name asc limit 1""" % (party_field, "%s"),
+ (party_name,))
+
+ return contact[0][0] if contact else None
+
def get_address_display(address_dict):
- def _prepare_for_display(a_dict, sequence):
- display = ""
- for separator, fieldname in sequence:
- if a_dict.get(fieldname):
- display += separator + a_dict.get(fieldname)
-
- return display.strip()
+ if not isinstance(address_dict, dict):
+ address_dict = webnotes.conn.get_value("Address", address_dict, "*", as_dict=True)
meta = webnotes.get_doctype("Address")
- address_sequence = (("", "address_line1"), ("\n", "address_line2"), ("\n", "city"),
+ sequence = (("", "address_line1"), ("\n", "address_line2"), ("\n", "city"),
("\n", "state"), ("\n" + meta.get_label("pincode") + ": ", "pincode"), ("\n", "country"),
("\n" + meta.get_label("phone") + ": ", "phone"), ("\n" + meta.get_label("fax") + ": ", "fax"))
- return _prepare_for_display(address_dict, address_sequence)
+ display = ""
+ for separator, fieldname in sequence:
+ if address_dict.get(fieldname):
+ display += separator + address_dict.get(fieldname)
+
+ return display.strip()
-def map_lead_fields(party_name):
+def map_lead_contact_details(party_name):
out = {}
for fieldname in ["contact_display", "contact_email", "contact_mobile", "contact_phone"]:
out[fieldname] = None
@@ -395,15 +377,19 @@
return out
-def map_contact_fields(party_field, party_name):
+def map_party_contact_details(contact_name=None, party_field=None, party_name=None):
out = {}
for fieldname in ["contact_person", "contact_display", "contact_email",
"contact_mobile", "contact_phone", "contact_designation", "contact_department"]:
out[fieldname] = None
+ if not contact_name:
+ contact_name = get_default_contact(party_field, party_name)
+
contact = webnotes.conn.sql("""select * from `tabContact` where `%s`=%s
order by is_primary_contact desc, name asc limit 1""" % (party_field, "%s"),
(party_name,), as_dict=True)
+
if contact:
contact = contact[0]
out.update({
diff --git a/website/css/website.css b/website/css/website.css
index 816b3ef..3ced12f 100644
--- a/website/css/website.css
+++ b/website/css/website.css
@@ -41,6 +41,10 @@
margin-left: 5px;
}
+div.web-footer {
+ border-top: 1px solid #dddddd;
+ padding-top: 10px;
+}
.web-footer-menu ul {
list-style: none;
@@ -136,6 +140,10 @@
padding-left: 10px;
}
+fieldset {
+ margin-bottom: 20px;
+}
+
/* buttons */
.btn-default {
color: #ffffff;
diff --git a/website/doctype/shopping_cart_settings/shopping_cart_settings.txt b/website/doctype/shopping_cart_settings/shopping_cart_settings.txt
index 8cb1480..7455864 100644
--- a/website/doctype/shopping_cart_settings/shopping_cart_settings.txt
+++ b/website/doctype/shopping_cart_settings/shopping_cart_settings.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-06-19 15:57:32",
"docstatus": 0,
- "modified": "2013-07-05 14:55:05",
+ "modified": "2013-07-10 18:42:29",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -46,6 +46,19 @@
},
{
"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",
@@ -54,6 +67,24 @@
},
{
"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": "section_break_6",
+ "fieldtype": "Section Break"
+ },
+ {
+ "doctype": "DocField",
"fieldname": "price_lists",
"fieldtype": "Table",
"label": "Shopping Cart Price Lists",
@@ -62,14 +93,6 @@
},
{
"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": "DocField",
"fieldname": "shipping_rules",
"fieldtype": "Table",
"label": "Shopping Cart Shipping Rules",
@@ -78,11 +101,16 @@
},
{
"doctype": "DocField",
- "fieldname": "company",
- "fieldtype": "Link",
- "label": "Company",
- "options": "Company",
- "reqd": 1
+ "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"
diff --git a/website/doctype/style_settings/custom_template.css b/website/doctype/style_settings/custom_template.css
index 996774e..eb422c9 100644
--- a/website/doctype/style_settings/custom_template.css
+++ b/website/doctype/style_settings/custom_template.css
@@ -9,7 +9,7 @@
background-color: #{{ doc.background_color }};
background-image: none;
{% else %}
- background-color: #edede7;
+ background-color: #ffffff;
{% endif %}
{% if doc.font or doc.google_web_font_for_text %}
font-family: '{{ doc.google_web_font_for_text or doc.font }}', 'Helvetica Neue', Arial, Sans !important;
diff --git a/website/doctype/website_settings/website_settings.js b/website/doctype/website_settings/website_settings.js
index 57c32e9..2322b7c 100644
--- a/website/doctype/website_settings/website_settings.js
+++ b/website/doctype/website_settings/website_settings.js
@@ -34,7 +34,7 @@
url: function(doc, cdt, cdn) {
this.label(doc, cdt, cdn);
- }
+ },
set_parent_label_options: function() {
wn.meta.get_docfield("Top Bar Item", "parent_label", cur_frm.docname).options =
diff --git a/website/doctype/website_settings/website_settings.txt b/website/doctype/website_settings/website_settings.txt
index b3828a2..f8ceafe 100644
--- a/website/doctype/website_settings/website_settings.txt
+++ b/website/doctype/website_settings/website_settings.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-04-30 12:58:46",
"docstatus": 0,
- "modified": "2013-07-05 15:02:50",
+ "modified": "2013-07-10 20:37:38",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/website/helpers/cart.py b/website/helpers/cart.py
index d4ab64d..ea72e40 100644
--- a/website/helpers/cart.py
+++ b/website/helpers/cart.py
@@ -3,17 +3,26 @@
from __future__ import unicode_literals
import webnotes
+from webnotes import msgprint, _
import webnotes.defaults
-from webnotes.utils import flt, get_fullname, fmt_money
+from webnotes.utils import flt, get_fullname, fmt_money, cstr
class WebsitePriceListMissingError(webnotes.ValidationError): pass
+def set_cart_count(quotation=None):
+ if not quotation:
+ quotation = _get_cart_quotation()
+ webnotes.add_cookies["cart_count"] = cstr(len(quotation.doclist.get(
+ {"parentfield": "quotation_details"})) or "")
+
@webnotes.whitelist()
def get_cart_quotation(doclist=None):
party = get_lead_or_customer()
if not doclist:
- doclist = _get_cart_quotation(party).doclist
+ quotation = _get_cart_quotation(party)
+ doclist = quotation.doclist
+ set_cart_count(quotation)
return {
"doclist": decorate_quotation_doclist(doclist),
@@ -21,6 +30,26 @@
for address in get_address_docs(party)],
"shipping_rules": get_applicable_shipping_rules(party)
}
+
+@webnotes.whitelist()
+def place_order():
+ quotation = _get_cart_quotation()
+ controller = quotation.make_controller()
+ for fieldname in ["customer_address", "shipping_address_name"]:
+ if not quotation.doc.fields.get(fieldname):
+ msgprint(_("Please select a") + " " + _(controller.meta.get_label(fieldname)), raise_exception=True)
+
+ quotation.ignore_permissions = True
+ quotation.submit()
+
+ from selling.doctype.quotation.quotation import _make_sales_order
+ sales_order = webnotes.bean(_make_sales_order(quotation.doc.name, ignore_permissions=True))
+ sales_order.ignore_permissions = True
+ sales_order.insert()
+ sales_order.submit()
+ webnotes.add_cookies["cart_count"] = ""
+
+ return sales_order.doc.name
@webnotes.whitelist()
def update_cart(item_code, qty, with_doclist=0):
@@ -46,6 +75,8 @@
quotation.ignore_permissions = True
quotation.save()
+ set_cart_count(quotation)
+
if with_doclist:
return get_cart_quotation(quotation.doclist)
else:
@@ -192,11 +223,47 @@
"__islocal": 1,
(party.doctype.lower()): party.name
})
+
+ # map_contact_fields(qbean, party)
+
qbean.run_method("onload_post_render")
apply_cart_settings(party, qbean)
return qbean
+
+def update_party(fullname, company_name=None, mobile_no=None, phone=None):
+ party = get_lead_or_customer()
+
+ if party.doctype == "Lead":
+ party.company_name = company_name
+ party.lead_name = fullname
+ party.mobile_no = mobile_no
+ party.phone = phone
+ else:
+ party.customer_name = company_name or fullname
+ party.customer_type == "Company" if company_name else "Individual"
+
+ contact_name = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user,
+ "customer": party.name})
+ contact = webnotes.bean("Contact", contact_name)
+ contact.doc.first_name = fullname
+ contact.doc.last_name = None
+ contact.doc.customer_name = party.customer_name
+ contact.doc.mobile_no = mobile_no
+ contact.doc.phone = phone
+ contact.ignore_permissions = True
+ contact.save()
+ party_bean = webnotes.bean(party.fields)
+ party_bean.ignore_permissions = True
+ party_bean.save()
+
+ qbean = _get_cart_quotation(party)
+ qbean.doc.customer_name = company_name or fullname
+ qbean.run_method("set_contact_fields")
+ qbean.ignore_permissions = True
+ qbean.save()
+
def apply_cart_settings(party=None, quotation=None):
if not party:
party = get_lead_or_customer()
@@ -237,8 +304,8 @@
quotation.doc.charge = cart_settings.get_tax_master(billing_territory)
# clear table
- quotation.doclist = quotation.doc.clear_table(quotation.doclist, "other_charges")
-
+ quotation.set_doclist(quotation.doclist.get({"parentfield": ["!=", "other_charges"]}))
+
# append taxes
controller = quotation.make_controller()
controller.append_taxes_from_master("other_charges", "charge")
diff --git a/website/templates/html/navbar.html b/website/templates/html/navbar.html
index 635cf34..11f2fb0 100644
--- a/website/templates/html/navbar.html
+++ b/website/templates/html/navbar.html
@@ -1,4 +1,4 @@
-<div class="navbar navbar-inverse" style="">
+<div class="navbar" style="margin: 0px -15px">
{%- if brand_html %}<a class="navbar-brand" href="index">{{ brand_html }}</a>{% endif -%}
<div class="container">
<button type="button" class="navbar-toggle" data-toggle="collapse"
diff --git a/website/templates/html/outer.html b/website/templates/html/outer.html
index cc1181c..0102acd 100644
--- a/website/templates/html/outer.html
+++ b/website/templates/html/outer.html
@@ -10,8 +10,10 @@
<div class="pull-right hide" style="margin:4px;" id="user-tools-post-login">
<a href="profile" title="My Profile" id="user-full-name"></a> |
<a href="account" title="My Account">My Account</a> |
+ {% if shopping_cart_enabled -%}
<a href="cart" title="Shopping Cart"><i class="icon-shopping-cart"></i>
<span class="cart-count"></span></a> |
+ {%- endif %}
<a href="server.py?cmd=web_logout" title="Sign Out"><i class="icon-signout"></i></a>
</div>
<div class="clearfix"></div>
diff --git a/website/templates/html/product_page.html b/website/templates/html/product_page.html
index b3e8be2..73520ef 100644
--- a/website/templates/html/product_page.html
+++ b/website/templates/html/product_page.html
@@ -32,7 +32,7 @@
<p class="help">Item Code: <span itemprop="productID">{{ name }}</span></p>
<h4>Product Description</h4>
<div itemprop="description">
- {{ web_long_description or web_short_description or
+ {{ web_long_description or web_short_description or description or
"[No description given]" }}
</div>
<div style="min-height: 100px; margin: 10px 0;">
diff --git a/website/templates/js/cart.js b/website/templates/js/cart.js
index 27f604f..bb3fcb9 100644
--- a/website/templates/js/cart.js
+++ b/website/templates/js/cart.js
@@ -17,8 +17,6 @@
// js inside blog page
$(document).ready(function() {
- // make list of items in the cart
- // wn.cart.render();
wn.cart.bind_events();
wn.call({
type: "POST",
@@ -36,6 +34,7 @@
wn.cart.show_error("Oops!", "Something went wrong.");
}
} else {
+ wn.cart.set_cart_count();
wn.cart.render(r.message);
}
}
@@ -75,6 +74,10 @@
$("#cart-add-billing-address").on("click", function() {
window.location.href = "address?address_fieldname=customer_address";
});
+
+ $(".btn-place-order").on("click", function() {
+ wn.cart.place_order();
+ });
},
render: function(out) {
@@ -282,5 +285,27 @@
$address_wrapper.find('.accordion-body[data-address-name="'+ address_name +'"]')
.collapse("show");
+ },
+
+ place_order: function() {
+ wn.call({
+ type: "POST",
+ method: "website.helpers.cart.place_order",
+ callback: function(r) {
+ if(r.exc) {
+ var msg = "";
+ if(r._server_messages) {
+ msg = JSON.parse(r._server_messages || []).join("<br>");
+ }
+
+ $("#cart-error")
+ .empty()
+ .html(msg || "Something went wrong!")
+ .toggle(true);
+ } else {
+ window.location.href = "order?name=" + encodeURIComponent(r.message);
+ }
+ }
+ });
}
});
\ No newline at end of file
diff --git a/website/templates/pages/address.html b/website/templates/pages/address.html
index 5b90928..cf1fc4b 100644
--- a/website/templates/pages/address.html
+++ b/website/templates/pages/address.html
@@ -112,12 +112,4 @@
};
})();
</script>
-{% endblock %}
-
-{% block css %}
-<style>
-fieldset {
- margin-bottom: 20px;
-}
-</style>
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/cart.html b/website/templates/pages/cart.html
index cefcb5a..5bfca33 100644
--- a/website/templates/pages/cart.html
+++ b/website/templates/pages/cart.html
@@ -13,8 +13,9 @@
<div class="progress-bar progress-bar-info" style="width: 100%;"></div>
</div>
<div id="cart-container" class="hide">
- <button class="btn btn-success pull-right" type="button">Place Order</button>
+ <button class="btn btn-success pull-right btn-place-order" type="button">Place Order</button>
<div class="clearfix"></div>
+ <div id="cart-error" class="alert alert-danger" style="display: none;"></div>
<hr>
<div class="row">
<div class="col col-lg-9 col-sm-9">
@@ -50,7 +51,7 @@
</div>
<hr>
</div>
- <button class="btn btn-success pull-right" type="button">Place Order</button>
+ <button class="btn btn-success pull-right btn-place-order" type="button">Place Order</button>
</div>
</div>
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/profile.html b/website/templates/pages/profile.html
index 993839e..61ae1b0 100644
--- a/website/templates/pages/profile.html
+++ b/website/templates/pages/profile.html
@@ -12,24 +12,28 @@
<h2><i class="icon-user"></i> My Profile</h2>
<hr>
<div class="alert" id="message" style="display: none;"></div>
- <form class="form-horizontal">
- <div class="control-group">
- <label class="control-label" for="fullname">Full Name</label>
- <div class="controls">
- <input type="text" id="fullname" placeholder="Your Name">
- </div>
- </div>
- <div class="control-group">
- <label class="control-label" for="password">Password</label>
- <div class="controls">
- <input type="password" id="password" placeholder="Password">
- </div>
- </div>
- <div class="control-group">
- <div class="controls">
- <button id="update_profile" type="submit" class="btn btn-default">Update</button>
- </div>
- </div>
+ <form>
+ <fieldset>
+ <label>Full Name</label>
+ <input type="text" id="fullname" placeholder="Your Name">
+ </fieldset>
+ <fieldset>
+ <label>Password</label>
+ <input type="password" id="password" placeholder="Password">
+ </fieldset>
+ <fieldset>
+ <label>Company Name</label>
+ <input type="text" id="company_name" placeholder="Company Name" value="{{ company_name }}">
+ </fieldset>
+ <fieldset>
+ <label>Mobile No</label>
+ <input type="text" id="mobile_no" placeholder="Mobile No" value="{{ mobile_no }}">
+ </fieldset>
+ <fieldset>
+ <label>Phone</label>
+ <input type="text" id="phone" placeholder="Phone" value="{{ phone }}">
+ </fieldset>
+ <button id="update_profile" type="submit" class="btn btn-default">Update</button>
</form>
</div>
<script>
@@ -37,11 +41,14 @@
$("#fullname").val(getCookie("full_name") || "");
$("#update_profile").click(function() {
wn.call({
- method: "core.doctype.profile.profile.update_profile",
+ method: "startup.webutils.update_profile",
type: "POST",
args: {
fullname: $("#fullname").val(),
- password: $("#password").val()
+ password: $("#password").val(),
+ company_name: $("#company_name").val(),
+ mobile_no: $("#mobile_no").val(),
+ phone: $("#phone").val()
},
btn: this,
msg: $("#message"),
@@ -53,4 +60,4 @@
})
})
</script>
-{% endblock %}
+{% endblock %}
\ No newline at end of file