mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-05 05:09:11 +00:00
[fixes] setup wizard and other fixes related to cart
This commit is contained in:
committed by
Rushabh Mehta
parent
52dfc32eca
commit
06ad308ca1
@@ -1,103 +1,2 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import get_fullname, flt
|
||||
from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import check_shopping_cart_enabled, get_default_territory
|
||||
|
||||
# TODO
|
||||
# validate stock of each item in Website Warehouse or have a list of possible warehouses in Shopping Cart Settings
|
||||
# Below functions are used for test cases
|
||||
|
||||
def get_quotation(user=None):
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
if user == "Guest":
|
||||
raise frappe.PermissionError
|
||||
|
||||
check_shopping_cart_enabled()
|
||||
party = get_party(user)
|
||||
values = {
|
||||
"order_type": "Shopping Cart",
|
||||
party.doctype.lower(): party.name,
|
||||
"docstatus": 0,
|
||||
"contact_email": user,
|
||||
"selling_price_list": "_Test Price List Rest of the World",
|
||||
"currency": "USD"
|
||||
}
|
||||
|
||||
try:
|
||||
quotation = frappe.get_doc("Quotation", values)
|
||||
|
||||
except frappe.DoesNotExistError:
|
||||
quotation = frappe.new_doc("Quotation")
|
||||
quotation.update(values)
|
||||
if party.doctype == "Customer":
|
||||
quotation.contact_person = frappe.db.get_value("Contact", {"customer": party.name, "email_id": user})
|
||||
quotation.insert(ignore_permissions=True)
|
||||
|
||||
return quotation
|
||||
|
||||
def set_item_in_cart(item_code, qty, user=None):
|
||||
validate_item(item_code)
|
||||
quotation = get_quotation(user=user)
|
||||
qty = flt(qty)
|
||||
quotation_item = quotation.get("items", {"item_code": item_code})
|
||||
if qty==0:
|
||||
if quotation_item:
|
||||
# remove
|
||||
quotation.get("items").remove(quotation_item[0])
|
||||
else:
|
||||
# add or update
|
||||
if quotation_item:
|
||||
quotation_item[0].qty = qty
|
||||
else:
|
||||
quotation.append("items", {
|
||||
"doctype": "Quotation Item",
|
||||
"item_code": item_code,
|
||||
"qty": qty
|
||||
})
|
||||
quotation.save(ignore_permissions=True)
|
||||
return quotation
|
||||
|
||||
def validate_item(item_code):
|
||||
item = frappe.db.get_value("Item", item_code, ["item_name", "show_in_website"], as_dict=True)
|
||||
if not item.show_in_website:
|
||||
frappe.throw(_("{0} cannot be purchased using Shopping Cart").format(item.item_name))
|
||||
|
||||
def get_party(user):
|
||||
def _get_party(user):
|
||||
customer = frappe.db.get_value("Contact", {"email_id": user}, "customer")
|
||||
if customer:
|
||||
return frappe.get_doc("Customer", customer)
|
||||
|
||||
lead = frappe.db.get_value("Lead", {"email_id": user})
|
||||
if lead:
|
||||
return frappe.get_doc("Lead", lead)
|
||||
|
||||
# create a lead
|
||||
lead = frappe.new_doc("Lead")
|
||||
lead.update({
|
||||
"email_id": user,
|
||||
"lead_name": get_fullname(user),
|
||||
"territory": guess_territory()
|
||||
})
|
||||
lead.insert(ignore_permissions=True)
|
||||
|
||||
return lead
|
||||
|
||||
if not getattr(frappe.local, "shopping_cart_party", None):
|
||||
frappe.local.shopping_cart_party = {}
|
||||
|
||||
if not frappe.local.shopping_cart_party.get(user):
|
||||
frappe.local.shopping_cart_party[user] = _get_party(user)
|
||||
|
||||
return frappe.local.shopping_cart_party[user]
|
||||
|
||||
def guess_territory():
|
||||
territory = None
|
||||
if frappe.session.get("session_country"):
|
||||
territory = frappe.db.get_value("Territory", frappe.session.get("session_country"))
|
||||
return territory or get_default_territory()
|
||||
|
||||
@@ -17,19 +17,19 @@ def set_cart_count(quotation=None):
|
||||
if not quotation:
|
||||
quotation = _get_cart_quotation()
|
||||
cart_count = cstr(len(quotation.get("items")))
|
||||
frappe.local.cookie_manager.set_cookie("cart_count", cart_count)
|
||||
|
||||
if hasattr(frappe.local, "cookie_manager"):
|
||||
frappe.local.cookie_manager.set_cookie("cart_count", cart_count)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_cart_quotation(doc=None):
|
||||
party = get_lead_or_customer()
|
||||
party = get_customer()
|
||||
|
||||
if not doc:
|
||||
quotation = _get_cart_quotation(party)
|
||||
doc = quotation
|
||||
set_cart_count(quotation)
|
||||
|
||||
print get_applicable_shipping_rules(party)
|
||||
|
||||
return {
|
||||
"doc": decorate_quotation_doc(doc),
|
||||
"addresses": [{"name": address.name, "display": address.display}
|
||||
@@ -60,7 +60,9 @@ def place_order():
|
||||
sales_order.flags.ignore_permissions = True
|
||||
sales_order.insert()
|
||||
sales_order.submit()
|
||||
frappe.local.cookie_manager.delete_cookie("cart_count")
|
||||
|
||||
if hasattr(frappe.local, "cookie_manager"):
|
||||
frappe.local.cookie_manager.delete_cookie("cart_count")
|
||||
|
||||
return sales_order.name
|
||||
|
||||
@@ -156,7 +158,7 @@ def decorate_quotation_doc(doc):
|
||||
|
||||
def _get_cart_quotation(party=None):
|
||||
if not party:
|
||||
party = get_lead_or_customer()
|
||||
party = get_customer()
|
||||
|
||||
quotation = frappe.db.get_value("Quotation",
|
||||
{party.doctype.lower(): party.name, "order_type": "Shopping Cart", "docstatus": 0})
|
||||
@@ -176,9 +178,9 @@ def _get_cart_quotation(party=None):
|
||||
(party.doctype.lower()): party.name
|
||||
})
|
||||
|
||||
if party.doctype == "Customer":
|
||||
qdoc.contact_person = frappe.db.get_value("Contact", {"email_id": frappe.session.user,
|
||||
"customer": party.name})
|
||||
qdoc.contact_person = frappe.db.get_value("Contact", {"email_id": frappe.session.user,
|
||||
"customer": party.name})
|
||||
qdoc.contact_email = frappe.session.user
|
||||
|
||||
qdoc.flags.ignore_permissions = True
|
||||
qdoc.run_method("set_missing_values")
|
||||
@@ -187,27 +189,21 @@ def _get_cart_quotation(party=None):
|
||||
return qdoc
|
||||
|
||||
def update_party(fullname, company_name=None, mobile_no=None, phone=None):
|
||||
party = get_lead_or_customer()
|
||||
party = get_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"
|
||||
party.customer_name = company_name or fullname
|
||||
party.customer_type == "Company" if company_name else "Individual"
|
||||
|
||||
contact_name = frappe.db.get_value("Contact", {"email_id": frappe.session.user,
|
||||
"customer": party.name})
|
||||
contact = frappe.get_doc("Contact", contact_name)
|
||||
contact.first_name = fullname
|
||||
contact.last_name = None
|
||||
contact.customer_name = party.customer_name
|
||||
contact.mobile_no = mobile_no
|
||||
contact.phone = phone
|
||||
contact.flags.ignore_permissions = True
|
||||
contact.save()
|
||||
contact_name = frappe.db.get_value("Contact", {"email_id": frappe.session.user,
|
||||
"customer": party.name})
|
||||
contact = frappe.get_doc("Contact", contact_name)
|
||||
contact.first_name = fullname
|
||||
contact.last_name = None
|
||||
contact.customer_name = party.customer_name
|
||||
contact.mobile_no = mobile_no
|
||||
contact.phone = phone
|
||||
contact.flags.ignore_permissions = True
|
||||
contact.save()
|
||||
|
||||
party_doc = frappe.get_doc(party.as_dict())
|
||||
party_doc.flags.ignore_permissions = True
|
||||
@@ -222,7 +218,7 @@ def update_party(fullname, company_name=None, mobile_no=None, phone=None):
|
||||
|
||||
def apply_cart_settings(party=None, quotation=None):
|
||||
if not party:
|
||||
party = get_lead_or_customer()
|
||||
party = get_customer()
|
||||
if not quotation:
|
||||
quotation = _get_cart_quotation(party)
|
||||
|
||||
@@ -250,8 +246,9 @@ def set_price_list_and_rate(quotation, cart_settings):
|
||||
# refetch values
|
||||
quotation.run_method("set_price_list_and_item_details")
|
||||
|
||||
# set it in cookies for using in product page
|
||||
frappe.local.cookie_manager.set_cookie("selling_price_list", quotation.selling_price_list)
|
||||
if hasattr(frappe.local, "cookie_manager"):
|
||||
# set it in cookies for using in product page
|
||||
frappe.local.cookie_manager.set_cookie("selling_price_list", quotation.selling_price_list)
|
||||
|
||||
def _set_price_list(quotation, cart_settings):
|
||||
"""Set price list based on customer or shopping cart default"""
|
||||
@@ -286,32 +283,38 @@ def set_taxes(quotation, cart_settings):
|
||||
# # append taxes
|
||||
quotation.append_taxes_from_master()
|
||||
|
||||
def get_lead_or_customer():
|
||||
customer = frappe.db.get_value("Contact", {"email_id": frappe.session.user}, "customer")
|
||||
def get_customer(user=None):
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
||||
customer = frappe.db.get_value("Contact", {"email_id": user}, "customer")
|
||||
if customer:
|
||||
return frappe.get_doc("Customer", customer)
|
||||
|
||||
lead = frappe.db.get_value("Lead", {"email_id": frappe.session.user})
|
||||
if lead:
|
||||
return frappe.get_doc("Lead", lead)
|
||||
else:
|
||||
lead_doc = frappe.get_doc({
|
||||
"doctype": "Lead",
|
||||
"email_id": frappe.session.user,
|
||||
"lead_name": get_fullname(frappe.session.user),
|
||||
"territory": guess_territory(),
|
||||
"status": "Open" # TODO: set something better???
|
||||
customer = frappe.new_doc("Customer")
|
||||
fullname = get_fullname(user)
|
||||
customer.update({
|
||||
"customer_name": fullname,
|
||||
"customer_type": "Individual",
|
||||
"customer_group": get_shopping_cart_settings().default_customer_group,
|
||||
"territory": get_root_of("Territory")
|
||||
})
|
||||
customer.insert(ignore_permissions=True)
|
||||
|
||||
if frappe.session.user not in ("Guest", "Administrator"):
|
||||
lead_doc.flags.ignore_permissions = True
|
||||
lead_doc.insert()
|
||||
contact = frappe.new_doc("Contact")
|
||||
contact.update({
|
||||
"customer": customer.name,
|
||||
"first_name": fullname,
|
||||
"email_id": user
|
||||
})
|
||||
contact.insert(ignore_permissions=True)
|
||||
|
||||
return lead_doc
|
||||
return customer
|
||||
|
||||
def get_address_docs(doctype=None, txt=None, filters=None, limit_start=0, limit_page_length=20, party=None):
|
||||
if not party:
|
||||
party = get_lead_or_customer()
|
||||
party = get_customer()
|
||||
|
||||
address_docs = frappe.db.sql("""select * from `tabAddress`
|
||||
where `{0}`=%s order by name limit {1}, {2}""".format(party.doctype.lower(),
|
||||
|
||||
@@ -8,7 +8,6 @@ import frappe
|
||||
from frappe import _, msgprint
|
||||
from frappe.utils import comma_and
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils.nestedset import get_root_of
|
||||
|
||||
class ShoppingCartSetupError(frappe.ValidationError): pass
|
||||
|
||||
@@ -75,9 +74,6 @@ def get_shopping_cart_settings():
|
||||
def is_cart_enabled():
|
||||
return get_shopping_cart_settings().enabled
|
||||
|
||||
def get_default_territory():
|
||||
return get_shopping_cart_settings().default_territory or get_root_of("Territory")
|
||||
|
||||
def check_shopping_cart_enabled():
|
||||
if not get_shopping_cart_settings().enabled:
|
||||
frappe.throw(_("You need to enable Shopping Cart"), ShoppingCartSetupError)
|
||||
|
||||
@@ -19,14 +19,14 @@ class TestShoppingCartSettings(unittest.TestCase):
|
||||
def test_exchange_rate_exists(self):
|
||||
frappe.db.sql("""delete from `tabCurrency Exchange`""")
|
||||
|
||||
cart_settings = self.test_price_list_territory_overlap()
|
||||
controller = cart_settings
|
||||
self.assertRaises(ShoppingCartSetupError, controller.validate_exchange_rates_exist)
|
||||
cart_settings = self.get_cart_settings()
|
||||
cart_settings.price_list = "_Test Price List Rest of the World"
|
||||
self.assertRaises(ShoppingCartSetupError, cart_settings.validate_exchange_rates_exist)
|
||||
|
||||
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records as \
|
||||
currency_exchange_records
|
||||
frappe.get_doc(currency_exchange_records[0]).insert()
|
||||
controller.validate_exchange_rates_exist()
|
||||
cart_settings.validate_exchange_rates_exist()
|
||||
|
||||
def test_tax_rule_validation(self):
|
||||
frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 0")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
from erpnext.shopping_cart import get_quotation, set_item_in_cart, get_party
|
||||
from erpnext.shopping_cart.cart import _get_cart_quotation, update_cart, get_customer
|
||||
|
||||
class TestShoppingCart(unittest.TestCase):
|
||||
"""
|
||||
@@ -23,23 +23,11 @@ class TestShoppingCart(unittest.TestCase):
|
||||
self.login_as_new_user()
|
||||
|
||||
# test if lead is created and quotation with new lead is fetched
|
||||
quotation = get_quotation()
|
||||
self.assertEquals(quotation.quotation_to, "Lead")
|
||||
self.assertEquals(frappe.db.get_value("Lead", quotation.lead, "email_id"),
|
||||
quotation = _get_cart_quotation()
|
||||
self.assertEquals(quotation.quotation_to, "Customer")
|
||||
self.assertEquals(frappe.db.get_value("Contact", {"customer": quotation.customer}, "email_id"),
|
||||
"test_cart_user@example.com")
|
||||
self.assertEquals(quotation.customer, None)
|
||||
self.assertEquals(quotation.contact_email, frappe.session.user)
|
||||
|
||||
return quotation
|
||||
|
||||
def test_get_cart_lead(self):
|
||||
self.login_as_lead()
|
||||
|
||||
# test if quotation with lead is fetched
|
||||
quotation = get_quotation()
|
||||
self.assertEquals(quotation.quotation_to, "Lead")
|
||||
self.assertEquals(quotation.lead, frappe.db.get_value("Lead", {"email_id": "test_cart_lead@example.com"}))
|
||||
self.assertEquals(quotation.customer, None)
|
||||
self.assertEquals(quotation.lead, None)
|
||||
self.assertEquals(quotation.contact_email, frappe.session.user)
|
||||
|
||||
return quotation
|
||||
@@ -48,7 +36,7 @@ class TestShoppingCart(unittest.TestCase):
|
||||
self.login_as_customer()
|
||||
|
||||
# test if quotation with customer is fetched
|
||||
quotation = get_quotation()
|
||||
quotation = _get_cart_quotation()
|
||||
self.assertEquals(quotation.quotation_to, "Customer")
|
||||
self.assertEquals(quotation.customer, "_Test Customer")
|
||||
self.assertEquals(quotation.lead, None)
|
||||
@@ -57,21 +45,21 @@ class TestShoppingCart(unittest.TestCase):
|
||||
return quotation
|
||||
|
||||
def test_add_to_cart(self):
|
||||
self.login_as_lead()
|
||||
self.login_as_customer()
|
||||
|
||||
# remove from cart
|
||||
self.remove_all_items_from_cart()
|
||||
|
||||
# add first item
|
||||
set_item_in_cart("_Test Item", 1)
|
||||
quotation = self.test_get_cart_lead()
|
||||
update_cart("_Test Item", 1)
|
||||
quotation = self.test_get_cart_customer()
|
||||
self.assertEquals(quotation.get("items")[0].item_code, "_Test Item")
|
||||
self.assertEquals(quotation.get("items")[0].qty, 1)
|
||||
self.assertEquals(quotation.get("items")[0].amount, 10)
|
||||
|
||||
# add second item
|
||||
set_item_in_cart("_Test Item 2", 1)
|
||||
quotation = self.test_get_cart_lead()
|
||||
update_cart("_Test Item 2", 1)
|
||||
quotation = self.test_get_cart_customer()
|
||||
self.assertEquals(quotation.get("items")[1].item_code, "_Test Item 2")
|
||||
self.assertEquals(quotation.get("items")[1].qty, 1)
|
||||
self.assertEquals(quotation.get("items")[1].amount, 20)
|
||||
@@ -83,8 +71,8 @@ class TestShoppingCart(unittest.TestCase):
|
||||
self.test_add_to_cart()
|
||||
|
||||
# update first item
|
||||
set_item_in_cart("_Test Item", 5)
|
||||
quotation = self.test_get_cart_lead()
|
||||
update_cart("_Test Item", 5)
|
||||
quotation = self.test_get_cart_customer()
|
||||
self.assertEquals(quotation.get("items")[0].item_code, "_Test Item")
|
||||
self.assertEquals(quotation.get("items")[0].qty, 5)
|
||||
self.assertEquals(quotation.get("items")[0].amount, 50)
|
||||
@@ -96,8 +84,8 @@ class TestShoppingCart(unittest.TestCase):
|
||||
self.test_add_to_cart()
|
||||
|
||||
# remove first item
|
||||
set_item_in_cart("_Test Item", 0)
|
||||
quotation = self.test_get_cart_lead()
|
||||
update_cart("_Test Item", 0)
|
||||
quotation = self.test_get_cart_customer()
|
||||
self.assertEquals(quotation.get("items")[0].item_code, "_Test Item 2")
|
||||
self.assertEquals(quotation.get("items")[0].qty, 1)
|
||||
self.assertEquals(quotation.get("items")[0].amount, 20)
|
||||
@@ -105,11 +93,11 @@ class TestShoppingCart(unittest.TestCase):
|
||||
self.assertEquals(len(quotation.get("items")), 1)
|
||||
|
||||
# remove second item
|
||||
set_item_in_cart("_Test Item 2", 0)
|
||||
quotation = self.test_get_cart_lead()
|
||||
self.assertEquals(quotation.net_total, 0)
|
||||
self.assertEquals(len(quotation.get("items")), 0)
|
||||
update_cart("_Test Item 2", 0)
|
||||
quotation = self.test_get_cart_customer()
|
||||
|
||||
self.assertEquals(len(quotation.get("items")), 0)
|
||||
self.assertEquals(quotation.net_total, 0)
|
||||
|
||||
def test_tax_rule(self):
|
||||
self.login_as_customer()
|
||||
@@ -133,7 +121,7 @@ class TestShoppingCart(unittest.TestCase):
|
||||
"doctype": "Quotation",
|
||||
"quotation_to": "Customer",
|
||||
"order_type": "Shopping Cart",
|
||||
"customer": get_party(frappe.session.user).name,
|
||||
"customer": get_customer(frappe.session.user).name,
|
||||
"docstatus": 0,
|
||||
"contact_email": frappe.session.user,
|
||||
"selling_price_list": "_Test Price List Rest of the World",
|
||||
@@ -167,20 +155,10 @@ class TestShoppingCart(unittest.TestCase):
|
||||
settings.update({
|
||||
"enabled": 1,
|
||||
"company": "_Test Company",
|
||||
"default_territory": "_Test Territory Rest Of The World",
|
||||
"default_customer_group": "_Test Customer Group",
|
||||
"quotation_series": "_T-Quotation-"
|
||||
"quotation_series": "_T-Quotation-",
|
||||
"price_list": "_Test Price List India"
|
||||
})
|
||||
settings.set("price_lists", [
|
||||
# price lists
|
||||
{"doctype": "Shopping Cart Price List", "parentfield": "price_lists",
|
||||
"selling_price_list": "_Test Price List India"},
|
||||
{"doctype": "Shopping Cart Price List", "parentfield": "price_lists",
|
||||
"selling_price_list": "_Test Price List Rest of the World"}
|
||||
])
|
||||
settings.set("shipping_rules", {"doctype": "Shopping Cart Shipping Rule", "parentfield": "shipping_rules",
|
||||
"shipping_rule": "_Test Shipping Rule - India"})
|
||||
|
||||
|
||||
settings.save()
|
||||
frappe.local.shopping_cart_settings = None
|
||||
@@ -194,54 +172,11 @@ class TestShoppingCart(unittest.TestCase):
|
||||
def login_as_new_user(self):
|
||||
frappe.set_user("test_cart_user@example.com")
|
||||
|
||||
def login_as_lead(self):
|
||||
self.create_lead()
|
||||
frappe.set_user("test_cart_lead@example.com")
|
||||
|
||||
def login_as_customer(self):
|
||||
frappe.set_user("test_contact_customer@example.com")
|
||||
|
||||
def create_lead(self):
|
||||
if frappe.db.get_value("Lead", {"email_id": "test_cart_lead@example.com"}):
|
||||
return
|
||||
|
||||
lead = frappe.get_doc({
|
||||
"doctype": "Lead",
|
||||
"email_id": "test_cart_lead@example.com",
|
||||
"lead_name": "_Test Website Lead",
|
||||
"status": "Open",
|
||||
"territory": "_Test Territory Rest Of The World",
|
||||
"company": "_Test Company"
|
||||
})
|
||||
lead.insert(ignore_permissions=True)
|
||||
|
||||
frappe.get_doc({
|
||||
"doctype": "Address",
|
||||
"address_line1": "_Test Address Line 1",
|
||||
"address_title": "_Test Cart Lead Address",
|
||||
"address_type": "Office",
|
||||
"city": "_Test City",
|
||||
"country": "United States",
|
||||
"lead": lead.name,
|
||||
"lead_name": "_Test Website Lead",
|
||||
"is_primary_address": 1,
|
||||
"phone": "+91 0000000000"
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
frappe.get_doc({
|
||||
"doctype": "Address",
|
||||
"address_line1": "_Test Address Line 1",
|
||||
"address_title": "_Test Cart Lead Address",
|
||||
"address_type": "Personal",
|
||||
"city": "_Test City",
|
||||
"country": "India",
|
||||
"lead": lead.name,
|
||||
"lead_name": "_Test Website Lead",
|
||||
"phone": "+91 0000000000"
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
def remove_all_items_from_cart(self):
|
||||
quotation = get_quotation()
|
||||
quotation = _get_cart_quotation()
|
||||
quotation.set("items", [])
|
||||
quotation.save(ignore_permissions=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user