-
-
- {{ doc.subject }}
-
+
+
+ {{ doc.name }}
+
+ {{ doc.subject }}
-
-
- {{ doc.status }}
-
-
-
+
{{ frappe.format_date(doc.creation) }}
+
diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html
index 6748a5ebd2..487968ba81 100644
--- a/erpnext/templates/includes/macros.html
+++ b/erpnext/templates/includes/macros.html
@@ -6,11 +6,25 @@
{% endmacro %}
{% macro product_image(website_image, css_class="") %}
-
- {% if website_image -%}
-
 | abs_url }})
- {%- else -%}
-
- {%- endif %}
-
+
+ {% if website_image -%}
+
 | abs_url }})
+ {%- else -%}
+
+ {%- endif %}
+
+{% endmacro %}
+
+{% macro item_name_and_description(d) %}
+
+
+
+ {{ product_image_square(d.image) }}
+
+
+
+ {{ d.item_code }}
+
{{ d.description }}
+
+
{% endmacro %}
diff --git a/erpnext/templates/includes/order.css b/erpnext/templates/includes/order.css
new file mode 100644
index 0000000000..54c8d0ffe2
--- /dev/null
+++ b/erpnext/templates/includes/order.css
@@ -0,0 +1,25 @@
+.order-container {
+ margin: 50px 0px;
+}
+
+.order-items {
+ margin: 20px 0px;
+}
+
+.order-item-table {
+ margin: 0px -15px;
+}
+
+.order-item-header {
+ border-bottom: 1px solid #d1d8dd;
+}
+
+.order-image-col {
+ padding-right: 0px;
+}
+
+.order-image {
+ max-width: 55px;
+ max-height: 55px;
+ margin-top: -5px;
+}
diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js
index 4f4f11c9f3..98331a4f20 100644
--- a/erpnext/templates/includes/product_page.js
+++ b/erpnext/templates/includes/product_page.js
@@ -1,10 +1,10 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-$(document).ready(function() {
+frappe.ready(function() {
var item_code = $('[itemscope] [itemprop="productID"]').text().trim();
var qty = 0;
-
+
frappe.call({
type: "POST",
method: "erpnext.shopping_cart.product.get_product_info",
@@ -12,10 +12,12 @@ $(document).ready(function() {
item_code: "{{ name }}"
},
callback: function(r) {
+ console.log(r.message);
+ $(".item-cart").toggleClass("hide", !!!r.message.price);
if(r.message && r.message.price) {
$(".item-price")
.html(r.message.price.formatted_price + " per " + r.message.uom);
-
+
if(r.message.stock==0) {
$(".item-stock").html("
Not in stock
");
}
@@ -23,18 +25,17 @@ $(document).ready(function() {
$(".item-stock").html("
\
Available (in stock)
");
}
-
- $(".item-price-info").toggle(true);
-
+
if(r.message.qty) {
qty = r.message.qty;
- toggle_update_cart(qty);
- $("#item-update-cart input").val(qty);
+ toggle_update_cart(r.message.qty);
+ } else {
+ toggle_update_cart(0);
}
}
}
})
-
+
$("#item-add-to-cart button").on("click", function() {
shopping_cart.update_cart({
item_code: item_code,
@@ -45,10 +46,10 @@ $(document).ready(function() {
qty = 1;
}
},
- btn: this,
+ btn: this,
});
});
-
+
$("#item-update-cart button").on("click", function() {
shopping_cart.update_cart({
item_code: item_code,
@@ -63,7 +64,7 @@ $(document).ready(function() {
},
});
});
-
+
if(localStorage && localStorage.getItem("pending_add_to_cart") && full_name) {
localStorage.removeItem("pending_add_to_cart");
$("#item-add-to-cart button").trigger("click");
@@ -75,4 +76,4 @@ var toggle_update_cart = function(qty) {
$("#item-update-cart")
.toggle(qty ? true : false)
.find("input").val(qty);
-}
\ No newline at end of file
+}
diff --git a/erpnext/templates/includes/transaction_row.html b/erpnext/templates/includes/transaction_row.html
index a677fa5ad3..9b9fd52350 100644
--- a/erpnext/templates/includes/transaction_row.html
+++ b/erpnext/templates/includes/transaction_row.html
@@ -1,29 +1,22 @@
-{% set doc = frappe.get_doc(doc) %}
-
+
-
{{ doc.customer or doc.supplier }}
+
+
{{ doc.name }}
+
{{ doc.items_preview }}
+
- {%- if doc.status_percent > 0 -%}
- {%- if doc.status_percent % 100 == 0 -%}
- {{ doc.status_display }}
- {%- else -%}
- {{ doc.status_display }}
- {%- endif -%}
- {%- elif doc.status -%}
- {{ doc.status }}
- {%- endif -%}
+
+ {{ doc.indicator_title or doc.status or "Submitted" }}
+
{{ doc.get_formatted("grand_total") }}
-
- {{ doc.name }}
-
{{ frappe.utils.pretty_date(doc.creation) }}
diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html
index e4e4a6a6c1..2e1572869f 100644
--- a/erpnext/templates/pages/cart.html
+++ b/erpnext/templates/pages/cart.html
@@ -3,53 +3,84 @@
{% block header %}
{{ _("My Cart") }}
{% endblock %}
{% block script %}{% include "templates/includes/cart.js" %}{% endblock %}
+{% block style %}{% include "templates/includes/cart.css" %}{% endblock %}
{% block content %}
+
+{% from "erpnext/templates/includes/macros.html" import item_name_and_description %}
+
-
{{ _("Loading") }}...
-
-
-
+
{{ _("Loading") }}...
+
+
-
-
-
-
-
{{ _("Item Details") }}
-
-
-
{{ _("Qty, Amount") }}
-
-
-
-
-
-
-
-
-
-
-
-
{{ _("Shipping Address") }}
-
-
-
-
-
Billing Address
-
-
-
-
-
-
-
-
+
+ {% if doc.items %}
+ {% for d in doc.items %}
+
+
+
+ {{ item_name_and_description(d) }}
+
+
+
+
+ {{ _("Rate") + ': ' + d.get_formatted("rate") }}
+
+
+ {{ d.get_formatted("amount") }}
+
+
+
+ {% endfor %}
+ {% else %}
+
{{ _("Cart is Empty") }}
+ {% endif %}
+
+
+
+
+
+
+
+
+
{{ _("Shipping Address") }}
+
+
+
+
+
Billing Address
+
+
+
+
+
+
+
+
diff --git a/erpnext/templates/pages/cart.py b/erpnext/templates/pages/cart.py
index fe50f0fe47..bb8645d816 100644
--- a/erpnext/templates/pages/cart.py
+++ b/erpnext/templates/pages/cart.py
@@ -2,7 +2,13 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
-from __future__ import unicode_literals
-
no_cache = 1
-no_sitemap = 1
\ No newline at end of file
+no_sitemap = 1
+
+import frappe
+from erpnext.shopping_cart.cart import get_cart_quotation
+
+def get_context(context):
+ context.update(get_cart_quotation())
+
+ print context
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html
new file mode 100644
index 0000000000..c3bca5bb50
--- /dev/null
+++ b/erpnext/templates/pages/order.html
@@ -0,0 +1,90 @@
+{% block header %}
+{{ doc.name }}
+
+{% endblock %}
+
+{% block style %}{% include "templates/includes/order.css" %}{% endblock %}
+
+{% block content %}
+
+{% from "erpnext/templates/includes/macros.html" import item_name_and_description %}
+
+
+
+
+ {{ doc.indicator_title or doc.status or "Submitted" }}
+
+
+
+ {{ doc.get_formatted("transaction_date") }}
+
+
+
+{% if doc._header %}
+{{ doc._header }}
+{% endif %}
+
+
+
+
+
+
+ {% for d in doc.items %}
+
+
+ {{ item_name_and_description(d) }}
+
+
+ {{ d.qty }}
+ {% if d.delivered_qty != None %}
+
{{
+ _("Delivered: {0}").format(d.delivered_qty) }}
+ {% endif %}
+
+
+ {{ d.get_formatted("amount") }}
+
{{
+ _("Rate: {0}").format(d.get_formatted("rate")) }}
+
+
+ {% endfor %}
+
+
+
+
+
+
+ {% if doc.taxes %}
+
+
{{ _("Net Total") }}
+
+ {{ doc.get_formatted("net_total") }}
+
+ {% endif %}
+ {% for d in doc.taxes %}
+
+
{{ d.description }}
+
+ {{ d.get_formatted("total") }}
+
+ {% endfor %}
+
+
{{ _("Grand Total") }}
+
+ {{ doc.get_formatted("grand_total") }}
+
+
+
+
+
+{% endblock %}
diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py
new file mode 100644
index 0000000000..260490d129
--- /dev/null
+++ b/erpnext/templates/pages/order.py
@@ -0,0 +1,15 @@
+# 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 _
+
+def get_context(context):
+ context.no_cache = 1
+ context.doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name)
+ context.parents = frappe.form_dict.parents
+
+ if not context.doc.has_permission("read"):
+ frappe.throw(_("Not Permitted"), frappe.PermissionError)
diff --git a/erpnext/utilities/doctype/address/address.py b/erpnext/utilities/doctype/address/address.py
index b3f67175e5..8ae7c4da6f 100644
--- a/erpnext/utilities/doctype/address/address.py
+++ b/erpnext/utilities/doctype/address/address.py
@@ -70,6 +70,9 @@ class Address(Document):
(is_address_type, fieldname, "%s", "%s"), (self.get(fieldname), self.name))
break
+ def get_display(self):
+ return get_address_display(self.as_dict())
+
@frappe.whitelist()
def get_address_display(address_dict):
if not address_dict:
From 3d76686b82e49b35456fdf825781c3d80a1ccdeb Mon Sep 17 00:00:00 2001
From: Rushabh Mehta
Date: Wed, 16 Sep 2015 18:52:52 +0530
Subject: [PATCH 2/7] [shopping-cart] cart via Jinja WIP
---
.../doctype/sales_invoice/sales_invoice.py | 33 ++++---
.../controllers/website_list_for_contact.py | 3 +
erpnext/shopping_cart/cart.py | 3 +-
erpnext/templates/includes/cart.css | 20 ++++-
erpnext/templates/includes/cart.js | 61 ++++++-------
.../templates/includes/cart/cart_address.html | 24 +++++
.../includes/cart/cart_item_line.html | 16 ++++
.../templates/includes/cart/cart_macros.html | 21 +++++
erpnext/templates/includes/macros.html | 13 ---
.../templates/includes/{ => order}/order.css | 0
.../includes/order/order_macros.html | 15 ++++
.../templates/includes/order/order_taxes.html | 19 ++++
erpnext/templates/pages/cart.html | 89 ++++++++-----------
erpnext/templates/pages/cart.py | 2 -
erpnext/templates/pages/order.html | 24 +----
erpnext/templates/pages/order.py | 3 +
16 files changed, 208 insertions(+), 138 deletions(-)
create mode 100644 erpnext/templates/includes/cart/cart_address.html
create mode 100644 erpnext/templates/includes/cart/cart_item_line.html
create mode 100644 erpnext/templates/includes/cart/cart_macros.html
rename erpnext/templates/includes/{ => order}/order.css (100%)
create mode 100644 erpnext/templates/includes/order/order_macros.html
create mode 100644 erpnext/templates/includes/order/order_taxes.html
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 030fddbb99..885e7bd160 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -35,6 +35,15 @@ class SalesInvoice(SellingController):
'overflow_type': 'billing'
}]
+ def set_indicator(self):
+ """Set indicator for portal"""
+ if self.outstanding_amount > 0:
+ self.indicator_color = "orange"
+ self.indicator_title = _("Unpaid")
+ else:
+ self.indicator_color = "green"
+ self.indicator_title = _("Paid")
+
def validate(self):
super(SalesInvoice, self).validate()
self.validate_posting_time()
@@ -90,7 +99,7 @@ class SalesInvoice(SellingController):
# this sequence because outstanding may get -ve
self.make_gl_entries()
-
+
if not self.is_return:
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
self.check_credit_limit()
@@ -161,10 +170,10 @@ class SalesInvoice(SellingController):
'extra_cond': """ and exists (select name from `tabSales Invoice` where name=`tabSales Invoice Item`.parent and update_stock=1 and is_return=1)"""
}
])
-
+
def check_credit_limit(self):
from erpnext.selling.doctype.customer.customer import check_credit_limit
-
+
validate_against_credit_limit = False
for d in self.get("items"):
if not (d.sales_order or d.delivery_note):
@@ -282,7 +291,7 @@ class SalesInvoice(SellingController):
reconcile_against_document(lst)
def validate_debit_to_acc(self):
- account = frappe.db.get_value("Account", self.debit_to,
+ account = frappe.db.get_value("Account", self.debit_to,
["account_type", "report_type", "account_currency"], as_dict=True)
if account.report_type != "Balance Sheet":
@@ -290,7 +299,7 @@ class SalesInvoice(SellingController):
if self.customer and account.account_type != "Receivable":
frappe.throw(_("Debit To account must be a Receivable account"))
-
+
self.party_account_currency = account.account_currency
def validate_fixed_asset_account(self):
@@ -437,18 +446,18 @@ class SalesInvoice(SellingController):
if cint(self.is_pos) == 1:
if flt(self.paid_amount) == 0:
if self.cash_bank_account:
- frappe.db.set(self, 'paid_amount',
- flt(flt(self.grand_total) - flt(self.write_off_amount), self.precision("paid_amount")))
+ frappe.db.set(self, 'paid_amount',
+ flt(flt(self.grand_total) - flt(self.write_off_amount), self.precision("paid_amount")))
else:
# show message that the amount is not paid
frappe.db.set(self,'paid_amount',0)
frappe.msgprint(_("Note: Payment Entry will not be created since 'Cash or Bank Account' was not specified"))
else:
frappe.db.set(self,'paid_amount',0)
-
- frappe.db.set(self, 'base_paid_amount',
+
+ frappe.db.set(self, 'base_paid_amount',
flt(self.paid_amount*self.conversion_rate, self.precision("base_paid_amount")))
-
+
def check_prev_docstatus(self):
for d in self.get('items'):
if d.sales_order and frappe.db.get_value("Sales Order", d.sales_order, "docstatus") != 1:
@@ -487,7 +496,7 @@ class SalesInvoice(SellingController):
from erpnext.accounts.general_ledger import merge_similar_entries
gl_entries = []
-
+
self.make_customer_gl_entry(gl_entries)
self.make_tax_gl_entries(gl_entries)
@@ -586,7 +595,7 @@ class SalesInvoice(SellingController):
# write off entries, applicable if only pos
if self.write_off_account and self.write_off_amount:
write_off_account_currency = frappe.db.get_value("Account", self.write_off_account, "account_currency")
-
+
gl_entries.append(
self.get_gl_dict({
"account": self.debit_to,
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
index 9ec94eb3f8..51fb0a5889 100644
--- a/erpnext/controllers/website_list_for_contact.py
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -66,6 +66,9 @@ def post_process(doctype, data):
doc.status_percent += flt(doc.per_delivered)
doc.status_display.append(_("Delivered") if doc.per_delivered==100 else _("{0}% Delivered").format(doc.per_delivered))
+ if hasattr(doc, "set_indicator"):
+ doc.set_indicator()
+
doc.status_display = ", ".join(doc.status_display)
doc.items_preview = ", ".join([d.item_name for d in doc.items])
result.append(doc)
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index e219d8ed5f..6ff164b229 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -122,7 +122,8 @@ def update_cart_address(address_fieldname, address_name):
quotation.flags.ignore_permissions = True
quotation.save()
- return get_cart_quotation(quotation)
+ return frappe.render_template("templates/includes/cart/cart_address.html",
+ get_cart_quotation(quotation))
def guess_territory():
territory = None
diff --git a/erpnext/templates/includes/cart.css b/erpnext/templates/includes/cart.css
index ed98846a8d..7a18530286 100644
--- a/erpnext/templates/includes/cart.css
+++ b/erpnext/templates/includes/cart.css
@@ -1,7 +1,25 @@
.cart-content {
min-height: 400px;
+ margin-top: 60px;
}
.cart-header, .cart-footer {
- margin-bottom: 40px;
+ margin-bottom: 60px;
+}
+
+.cart-item-header {
+ padding-bottom: 10px;
+ margin-bottom: 10px;
+ border-bottom: 1px solid #d1d8dd;
+}
+
+.tax-grand-total-row {
+ font-size: 14px;
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+.cart-addresses {
+ margin-top: 80px;
+ margin-bottom: 60px;
}
diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js
index 349e2f5ed8..e0706f7fce 100644
--- a/erpnext/templates/includes/cart.js
+++ b/erpnext/templates/includes/cart.js
@@ -13,6 +13,8 @@ $.extend(shopping_cart, {
},
bind_events: function() {
+ shopping_cart.bind_address_select();
+
// bind update button
$(document).on("click", ".item-update-cart button", function() {
var item_code = $(this).attr("data-item-code");
@@ -31,19 +33,36 @@ $.extend(shopping_cart, {
});
});
- $("#cart-add-shipping-address").on("click", function() {
- window.location.href = "addresses";
- });
-
- $("#cart-add-billing-address").on("click", function() {
- window.location.href = "address";
- });
-
$(".btn-place-order").on("click", function() {
shopping_cart.place_order(this);
});
},
+ bind_address_select: function() {
+ $(".cart-addresses").find('input[data-address-name]').on("click", function() {
+ if($(this).prop("checked")) {
+ var me = this;
+
+ return frappe.call({
+ type: "POST",
+ method: "erpnext.shopping_cart.cart.update_cart_address",
+ args: {
+ address_fieldname: $(this).attr("data-fieldname"),
+ address_name: $(this).attr("data-address-name")
+ },
+ callback: function(r) {
+ if(!r.exc) {
+ $('.cart-addresses').html(r.message);
+ }
+ }
+ });
+ } else {
+ return false;
+ }
+ });
+
+ },
+
render: function(out) {
var doc = out.doc;
var addresses = out.addresses;
@@ -209,32 +228,6 @@ $.extend(shopping_cart, {
+$(this).attr("data-address-name")+'"]').collapse("toggle");
});
- $address_wrapper.find('input[type="checkbox"]').on("click", function() {
- if($(this).prop("checked")) {
- var me = this;
- $address_wrapper.find('input[type="checkbox"]').each(function(i, chk) {
- if($(chk).attr("data-address-name")!=$(me).attr("data-address-name")) {
- $(chk).prop("checked", false);
- }
- });
-
- return frappe.call({
- type: "POST",
- method: "erpnext.shopping_cart.cart.update_cart_address",
- args: {
- address_fieldname: $address_wrapper.attr("data-fieldname"),
- address_name: $(this).attr("data-address-name")
- },
- callback: function(r) {
- if(!r.exc) {
- shopping_cart.render(r.message);
- }
- }
- });
- } else {
- return false;
- }
- });
$address_wrapper.find('input[type="checkbox"][data-address-name="'+ address_name +'"]')
.prop("checked", true);
diff --git a/erpnext/templates/includes/cart/cart_address.html b/erpnext/templates/includes/cart/cart_address.html
new file mode 100644
index 0000000000..44964da47c
--- /dev/null
+++ b/erpnext/templates/includes/cart/cart_address.html
@@ -0,0 +1,24 @@
+{% from "erpnext/templates/includes/cart/cart_macros.html"
+ import show_address %}
+
+
+
{{ _("Shipping Address") }}
+
+ {% for address in addresses %}
+ {{ show_address(address, doc, "shipping_address_name") }}
+ {% endfor %}
+
+
+ {{ _("Manage Addresses") }}
+
+
+
Billing Address
+
+ {% for address in addresses %}
+ {{ show_address(address, doc, "customer_address") }}
+ {% endfor %}
+
+
+
diff --git a/erpnext/templates/includes/cart/cart_item_line.html b/erpnext/templates/includes/cart/cart_item_line.html
new file mode 100644
index 0000000000..cd157634a0
--- /dev/null
+++ b/erpnext/templates/includes/cart/cart_item_line.html
@@ -0,0 +1,16 @@
+{% from "erpnext/templates/includes/order/order_macros.html" import item_name_and_description %}
+
+
+
+ {{ item_name_and_description(d) }}
+
+
+
{{ d.get_formatted('qty') }}
+
+ {{ _("Rate") + ': ' + d.get_formatted("rate") }}
+
+
+
+ {{ d.get_formatted("amount") }}
+
+
diff --git a/erpnext/templates/includes/cart/cart_macros.html b/erpnext/templates/includes/cart/cart_macros.html
new file mode 100644
index 0000000000..250b487920
--- /dev/null
+++ b/erpnext/templates/includes/cart/cart_macros.html
@@ -0,0 +1,21 @@
+{% macro show_address(address, doc, fieldname) %}
+{% set selected=address.name==doc.get(fieldname) %}
+
+
+
+
+ {{ address.name }}
+
+
+
+
+
+
{{ address.display }}
+
+
+{% endmacro %}
diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html
index 487968ba81..81a10c2779 100644
--- a/erpnext/templates/includes/macros.html
+++ b/erpnext/templates/includes/macros.html
@@ -15,16 +15,3 @@
{% endmacro %}
-{% macro item_name_and_description(d) %}
-
-
-
- {{ product_image_square(d.image) }}
-
-
-
- {{ d.item_code }}
-
{{ d.description }}
-
-
-{% endmacro %}
diff --git a/erpnext/templates/includes/order.css b/erpnext/templates/includes/order/order.css
similarity index 100%
rename from erpnext/templates/includes/order.css
rename to erpnext/templates/includes/order/order.css
diff --git a/erpnext/templates/includes/order/order_macros.html b/erpnext/templates/includes/order/order_macros.html
new file mode 100644
index 0000000000..af974aad2f
--- /dev/null
+++ b/erpnext/templates/includes/order/order_macros.html
@@ -0,0 +1,15 @@
+{% from "erpnext/templates/includes/macros.html" import product_image_square %}
+
+{% macro item_name_and_description(d) %}
+
+
+
+ {{ product_image_square(d.image) }}
+
+
+
+ {{ d.item_code }}
+
{{ d.description }}
+
+
+{% endmacro %}
diff --git a/erpnext/templates/includes/order/order_taxes.html b/erpnext/templates/includes/order/order_taxes.html
new file mode 100644
index 0000000000..510e1a3d89
--- /dev/null
+++ b/erpnext/templates/includes/order/order_taxes.html
@@ -0,0 +1,19 @@
+{% if doc.taxes %}
+
+
{{ _("Net Total") }}
+
+ {{ doc.get_formatted("net_total") }}
+
+{% endif %}
+{% for d in doc.taxes %}
+
+
{{ d.description }}
+
+ {{ d.get_formatted("base_tax_amount") }}
+
+{% endfor %}
+
+
{{ _("Grand Total") }}
+
+ {{ doc.get_formatted("grand_total") }}
+
diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html
index 2e1572869f..837df3b056 100644
--- a/erpnext/templates/pages/cart.html
+++ b/erpnext/templates/pages/cart.html
@@ -5,81 +5,62 @@
{% block script %}{% include "templates/includes/cart.js" %}{% endblock %}
{% block style %}{% include "templates/includes/cart.css" %}{% endblock %}
+
+{% block header_actions %}
+{% if doc.items %}
+
+{% endif %}
+{% endblock %}
+
{% block content %}
-{% from "erpnext/templates/includes/macros.html" import item_name_and_description %}
+{% from "templates/includes/macros.html" import item_name_and_description %}
-
{{ _("Loading") }}...
-
-
+
+
{% if doc.items %}
{% for d in doc.items %}
-
-
- {{ item_name_and_description(d) }}
-
-
-
-
- {{ _("Rate") + ': ' + d.get_formatted("rate") }}
-
-
- {{ d.get_formatted("amount") }}
-
-
+ {% include "templates/includes/cart/cart_item_line.html" %}
{% endfor %}
{% else %}
{{ _("Cart is Empty") }}
{% endif %}
-
-
+ {% if doc.items %}
+
+
+
+
+ {% include "templates/includes/order/order_taxes.html" %}
+
+
-
-
-
-
{{ _("Shipping Address") }}
-
-
-
-
-
Billing Address
-
-
-
-
+
+ {% include "templates/includes/cart/cart_address.html" %}
-
+ {% endif %}
diff --git a/erpnext/templates/pages/cart.py b/erpnext/templates/pages/cart.py
index bb8645d816..c57d826130 100644
--- a/erpnext/templates/pages/cart.py
+++ b/erpnext/templates/pages/cart.py
@@ -10,5 +10,3 @@ from erpnext.shopping_cart.cart import get_cart_quotation
def get_context(context):
context.update(get_cart_quotation())
-
- print context
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html
index c3bca5bb50..73763921f8 100644
--- a/erpnext/templates/pages/order.html
+++ b/erpnext/templates/pages/order.html
@@ -3,11 +3,11 @@
{% endblock %}
-{% block style %}{% include "templates/includes/order.css" %}{% endblock %}
+{% block style %}{% include "templates/includes/order/order.css" %}{% endblock %}
{% block content %}
-{% from "erpnext/templates/includes/macros.html" import item_name_and_description %}
+{% from "erpnext/templates/includes/order/order_macros.html" import item_name_and_description %}
@@ -64,25 +64,7 @@
- {% if doc.taxes %}
-
-
{{ _("Net Total") }}
-
- {{ doc.get_formatted("net_total") }}
-
- {% endif %}
- {% for d in doc.taxes %}
-
-
{{ d.description }}
-
- {{ d.get_formatted("total") }}
-
- {% endfor %}
-
-
{{ _("Grand Total") }}
-
- {{ doc.get_formatted("grand_total") }}
-
+ {% include "erpnext/templates/includes/order/order_taxes.html" %}
diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py
index 260490d129..36444d1f30 100644
--- a/erpnext/templates/pages/order.py
+++ b/erpnext/templates/pages/order.py
@@ -9,6 +9,9 @@ from frappe import _
def get_context(context):
context.no_cache = 1
context.doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name)
+ if hasattr(context.doc, "set_indicator"):
+ context.doc.set_indicator()
+
context.parents = frappe.form_dict.parents
if not context.doc.has_permission("read"):
From 8ffd483e242187998d513a9c71ede7c87e6c05bf Mon Sep 17 00:00:00 2001
From: Rushabh Mehta
Date: Thu, 17 Sep 2015 16:28:30 +0530
Subject: [PATCH 3/7] [wip] shopping cart shipping rule, price list cleanup
---
.../doctype/shipping_rule/shipping_rule.json | 14 +-
.../doctype/shipping_rule_country/__init__.py | 0
.../shipping_rule_country.json | 53 +++++
.../shipping_rule_country.py | 10 +
erpnext/public/js/shopping_cart.js | 2 +-
erpnext/shopping_cart/cart.py | 15 +-
.../shopping_cart_settings.py | 83 +-------
.../stock/doctype/price_list/price_list.json | 18 +-
.../stock/doctype/price_list/price_list.py | 13 --
.../doctype/price_list_country/__init__.py | 0
.../price_list_country.json | 53 +++++
.../price_list_country/price_list_country.py | 10 +
erpnext/templates/includes/cart.js | 189 +++---------------
.../includes/cart/cart_item_line.html | 16 --
.../templates/includes/cart/cart_items.html | 23 +++
erpnext/templates/includes/issue_row.html | 6 +-
.../templates/includes/order/order_taxes.html | 5 +-
erpnext/templates/pages/cart.html | 8 +-
18 files changed, 216 insertions(+), 302 deletions(-)
create mode 100644 erpnext/accounts/doctype/shipping_rule_country/__init__.py
create mode 100644 erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.json
create mode 100644 erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.py
create mode 100644 erpnext/stock/doctype/price_list_country/__init__.py
create mode 100644 erpnext/stock/doctype/price_list_country/price_list_country.json
create mode 100644 erpnext/stock/doctype/price_list_country/price_list_country.py
delete mode 100644 erpnext/templates/includes/cart/cart_item_line.html
create mode 100644 erpnext/templates/includes/cart/cart_items.html
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.json b/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
index 97828d6f1b..62d5cb8e0c 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
@@ -141,17 +141,17 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "description": "Specify a list of Territories, for which, this Shipping Rule is valid",
- "fieldname": "territories",
+ "fieldname": "countries",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Valid For Territories",
+ "label": "Valid for Countries",
"no_copy": 0,
- "options": "Applicable Territory",
+ "options": "Shipping Rule Country",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
@@ -296,7 +296,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
- "modified": "2015-09-07 15:51:26",
+ "modified": "2015-09-17 06:44:05.127516",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Shipping Rule",
@@ -304,7 +304,7 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
+ "apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -324,7 +324,7 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
+ "apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
diff --git a/erpnext/accounts/doctype/shipping_rule_country/__init__.py b/erpnext/accounts/doctype/shipping_rule_country/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.json b/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.json
new file mode 100644
index 0000000000..90fe3d3dd3
--- /dev/null
+++ b/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.json
@@ -0,0 +1,53 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "creation": "2015-09-17 06:43:22.767534",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Other",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "country",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Country",
+ "no_copy": 0,
+ "options": "Country",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "modified": "2015-09-17 06:43:22.767534",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Shipping Rule Country",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.py b/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.py
new file mode 100644
index 0000000000..b9646cfc29
--- /dev/null
+++ b/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class ShippingRuleCountry(Document):
+ pass
diff --git a/erpnext/public/js/shopping_cart.js b/erpnext/public/js/shopping_cart.js
index cff831d714..f52c296e3d 100644
--- a/erpnext/public/js/shopping_cart.js
+++ b/erpnext/public/js/shopping_cart.js
@@ -30,7 +30,7 @@ $.extend(shopping_cart, {
args: {
item_code: opts.item_code,
qty: opts.qty,
- with_doc: opts.with_doc || 0
+ with_items: opts.with_items || 0
},
btn: opts.btn,
callback: function(r) {
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 6ff164b229..0d28406f06 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -28,6 +28,8 @@ def get_cart_quotation(doc=None):
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}
@@ -63,7 +65,7 @@ def place_order():
return sales_order.name
@frappe.whitelist()
-def update_cart(item_code, qty, with_doc):
+def update_cart(item_code, qty, with_items=False):
quotation = _get_cart_quotation()
qty = flt(qty)
@@ -95,8 +97,15 @@ def update_cart(item_code, qty, with_doc):
set_cart_count(quotation)
- if with_doc:
- return get_cart_quotation(quotation)
+
+ if with_items:
+ context = get_cart_quotation(quotation)
+ return {
+ "items": frappe.render_template("templates/includes/cart/cart_items.html",
+ context),
+ "taxes": frappe.render_template("templates/includes/order/order_taxes.html",
+ context),
+ }
else:
return quotation.name
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
index da7d27af10..a8a4b7653f 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
@@ -8,8 +8,7 @@ import frappe
from frappe import _, msgprint
from frappe.utils import comma_and
from frappe.model.document import Document
-from frappe.utils.nestedset import get_ancestors_of, get_root_of
-from erpnext.utilities.doctype.address.address import get_territory_from_address
+from frappe.utils.nestedset import get_root_of
class ShoppingCartSetupError(frappe.ValidationError): pass
@@ -19,57 +18,8 @@ class ShoppingCartSettings(Document):
def validate(self):
if self.enabled:
- self.validate_price_lists()
+ self.validate_tax_masters()
self.validate_exchange_rates_exist()
- self.validate_tax_rule()
-
- 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:
- frappe.throw(_("{0} {1} has a common territory {2}").format(_(doctype), comma_and(names), territory), ShoppingCartSetupError)
-
- return territory_name_map
-
- def validate_price_lists(self):
- self.validate_overlapping_territories("price_lists", "selling_price_list")
-
- # validate that a Shopping Cart Price List exists for the default territory as a catch all!
- price_list_for_default_territory = self.get_name_from_territory(self.default_territory, "price_lists",
- "selling_price_list")
-
- if not price_list_for_default_territory:
- msgprint(_("Please specify a Price List which is valid for Territory") +
- ": " + self.default_territory, raise_exception=ShoppingCartSetupError)
-
- def get_territory_name_map(self, parentfield, fieldname):
- territory_name_map = {}
-
- # entries in table
- names = [doc.get(fieldname) for doc in self.get(parentfield)]
- if names:
- # for condition in territory check
- parenttype = frappe.get_meta(self.meta.get_options(parentfield)).get_options(fieldname)
- # 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 = frappe.db.sql("""select `territory`, `parent`
- from `tabApplicable 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)"""
@@ -102,20 +52,6 @@ class ShoppingCartSettings(Document):
msgprint(_("Missing Currency Exchange Rates for {0}").format(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")
if not (price_list and price_list[0]):
@@ -123,11 +59,11 @@ class ShoppingCartSettings(Document):
"price_lists", "selling_price_list")
return price_list and price_list[0] or None
-
+
def validate_tax_rule(self):
if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart" : 1}, "name"):
frappe.throw(frappe._("Set Tax Rule for shopping cart"), ShoppingCartSetupError)
-
+
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")
@@ -136,15 +72,6 @@ class ShoppingCartSettings(Document):
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):
- 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]
-
def validate_cart_settings(doc, method):
frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings").run_method("validate")
@@ -163,4 +90,4 @@ def get_default_territory():
def check_shopping_cart_enabled():
if not get_shopping_cart_settings().enabled:
frappe.throw(_("You need to enable Shopping Cart"), ShoppingCartSetupError)
-
+
diff --git a/erpnext/stock/doctype/price_list/price_list.json b/erpnext/stock/doctype/price_list/price_list.json
index fcd204c18e..0d2baa461f 100644
--- a/erpnext/stock/doctype/price_list/price_list.json
+++ b/erpnext/stock/doctype/price_list/price_list.json
@@ -163,21 +163,21 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "description": "Specify a list of Territories, for which, this Price List is valid",
- "fieldname": "territories",
+ "fieldname": "countries",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Valid for Territories",
+ "label": "Applicable for Countries",
"no_copy": 0,
- "options": "Applicable Territory",
+ "options": "Price List Country",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -193,7 +193,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 1,
- "modified": "2015-09-14 02:55:58.919822",
+ "modified": "2015-09-17 06:50:31.465221",
"modified_by": "Administrator",
"module": "Stock",
"name": "Price List",
@@ -201,7 +201,7 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
+ "apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -241,7 +241,7 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
+ "apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -281,7 +281,7 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
+ "apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
diff --git a/erpnext/stock/doctype/price_list/price_list.py b/erpnext/stock/doctype/price_list/price_list.py
index 6b03bb6b0e..8773b9c33f 100644
--- a/erpnext/stock/doctype/price_list/price_list.py
+++ b/erpnext/stock/doctype/price_list/price_list.py
@@ -13,19 +13,6 @@ class PriceList(Document):
if not cint(self.buying) and not cint(self.selling):
throw(_("Price List must be applicable for Buying or Selling"))
- try:
- # at least one territory
- self.validate_table_has_rows("territories")
- except frappe.EmptyTableError:
- # if no territory, set default territory
- if frappe.defaults.get_user_default("territory"):
- self.append("territories", {
- "doctype": "Applicable Territory",
- "territory": frappe.defaults.get_user_default("territory")
- })
- else:
- raise
-
def on_update(self):
self.set_default_if_missing()
self.update_item_price()
diff --git a/erpnext/stock/doctype/price_list_country/__init__.py b/erpnext/stock/doctype/price_list_country/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/erpnext/stock/doctype/price_list_country/price_list_country.json b/erpnext/stock/doctype/price_list_country/price_list_country.json
new file mode 100644
index 0000000000..be02c202cc
--- /dev/null
+++ b/erpnext/stock/doctype/price_list_country/price_list_country.json
@@ -0,0 +1,53 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "creation": "2015-09-17 06:49:51.810318",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "country",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Country",
+ "no_copy": 0,
+ "options": "Country",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "modified": "2015-09-17 06:49:51.810318",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Price List Country",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/price_list_country/price_list_country.py b/erpnext/stock/doctype/price_list_country/price_list_country.py
new file mode 100644
index 0000000000..db1a0607e6
--- /dev/null
+++ b/erpnext/stock/doctype/price_list_country/price_list_country.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class PriceListCountry(Document):
+ pass
diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js
index e0706f7fce..e6ce25a6a8 100644
--- a/erpnext/templates/includes/cart.js
+++ b/erpnext/templates/includes/cart.js
@@ -14,28 +14,9 @@ $.extend(shopping_cart, {
bind_events: function() {
shopping_cart.bind_address_select();
+ shopping_cart.bind_place_order();
+ shopping_cart.bind_change_qty();
- // bind update button
- $(document).on("click", ".item-update-cart button", function() {
- var item_code = $(this).attr("data-item-code");
- shopping_cart.update_cart({
- item_code: item_code,
- qty: $('input[data-item-code="'+item_code+'"]').val(),
- with_doc: 1,
- btn: this,
- callback: function(r) {
- if(!r.exc) {
- shopping_cart.render(r.message);
- var $button = $('button[data-item-code="'+item_code+'"]').addClass("btn-success");
- setTimeout(function() { $button.removeClass("btn-success"); }, 1000);
- }
- },
- });
- });
-
- $(".btn-place-order").on("click", function() {
- shopping_cart.place_order(this);
- });
},
bind_address_select: function() {
@@ -63,95 +44,31 @@ $.extend(shopping_cart, {
},
- render: function(out) {
- var doc = out.doc;
- var addresses = out.addresses;
-
- var $cart_items = $("#cart-items").empty();
- var $cart_taxes = $("#cart-taxes").empty();
- var $cart_totals = $("#cart-totals").empty();
- var $cart_billing_address = $("#cart-billing-address").empty();
- var $cart_shipping_address = $("#cart-shipping-address").empty();
-
- var no_items = $.map(doc.items || [],
- function(d) { return d.item_code || null;}).length===0;
- if(no_items) {
- shopping_cart.show_error("Cart Empty", frappe._("Go ahead and add something to your cart."));
- $("#cart-addresses").toggle(false);
- return;
- }
-
- var shipping_rule_added = false;
- var taxes_exist = false;
- var shipping_rule_labels = $.map(out.shipping_rules || [], function(rule) { return rule[1]; });
-
- $.each(doc.items || [], function(i, d) {
- shopping_cart.render_item_row($cart_items, d);
+ bind_place_order: function() {
+ $(".btn-place-order").on("click", function() {
+ shopping_cart.place_order(this);
});
-
- $.each(doc.taxes || [], function(i, d) {
- if(out.shipping_rules && out.shipping_rules.length &&
- shipping_rule_labels.indexOf(d.description)!==-1) {
- shipping_rule_added = true;
- shopping_cart.render_tax_row($cart_taxes, d, out.shipping_rules);
- } else {
- shopping_cart.render_tax_row($cart_taxes, d);
- }
-
- taxes_exist = true;
- });
-
- if(out.shipping_rules && out.shipping_rules.length && !shipping_rule_added) {
- shopping_cart.render_tax_row($cart_taxes, {description: "", formatted_tax_amount: ""},
- out.shipping_rules);
- taxes_exist = true;
- }
-
- if(taxes_exist)
- $('
').appendTo($cart_taxes);
-
- shopping_cart.render_tax_row($cart_totals, {
- description: "",
- formatted_tax_amount: __("Total") + ": " + doc.formatted_grand_total_export + ""
- });
-
- if(!(addresses && addresses.length)) {
- $cart_shipping_address.html(''+frappe._("Please add a new address")+'
');
- } else {
- shopping_cart.render_address($cart_shipping_address, addresses, doc.shipping_address_name);
- shopping_cart.render_address($cart_billing_address, addresses, doc.customer_address);
- }
},
- render_item_row: function($cart_items, doc) {
- doc.image_html = doc.website_image ?
- '': "";
+ bind_change_qty: function() {
+ // bind update button
+ $(".cart-items").on("change", ".cart-qty", function() {
+ var item_code = $(this).attr("data-item-code");
+ shopping_cart.update_cart({
+ item_code: item_code,
+ qty: $(this).val(),
+ with_items: 1,
+ btn: this,
+ callback: function(r) {
+ if(!r.exc) {
+ $(".cart-items").html(r.message.items);
+ $(".cart-tax-items").html(r.message.taxes);
+ }
+ $(".tax-grand-total").temp_highlight();
+ },
+ });
+ });
- if(doc.description === doc.item_name) doc.description = "";
-
- $(repl('\
-
\
-
\
-
%(image_html)s
\
-
\
-
\
-
%(description)s
\
-
\
-
\
-
\
-
\
-
\
-
' + __("Rate") + ': %(formatted_rate)s
\
-
%(formatted_amount)s\
-
\
-
', doc)).appendTo($cart_items);
},
render_tax_row: function($cart_taxes, doc, shipping_rules) {
@@ -201,46 +118,6 @@ $.extend(shopping_cart, {
});
},
- render_address: function($address_wrapper, addresses, address_name) {
- $.each(addresses, function(i, address) {
- $(repl('', address))
- .css({"margin": "10px auto"})
- .appendTo($address_wrapper);
- });
-
- $address_wrapper.find(".panel-heading")
- .find(".address-title")
- .css({"cursor": "pointer"})
- .on("click", function() {
- $address_wrapper.find('.panel-collapse[data-address-name="'
- +$(this).attr("data-address-name")+'"]').collapse("toggle");
- });
-
-
- $address_wrapper.find('input[type="checkbox"][data-address-name="'+ address_name +'"]')
- .prop("checked", true);
-
- $address_wrapper.find(".panel-collapse").collapse({
- parent: $address_wrapper,
- toggle: false
- });
-
- $address_wrapper.find('.panel-collapse[data-address-name="'+ address_name +'"]')
- .collapse("show");
- },
-
place_order: function(btn) {
return frappe.call({
type: "POST",
@@ -267,24 +144,4 @@ $.extend(shopping_cart, {
$(document).ready(function() {
shopping_cart.bind_events();
- // return frappe.call({
- // type: "POST",
- // method: "erpnext.shopping_cart.cart.get_cart_quotation",
- // callback: function(r) {
- // $("#cart-container").removeClass("hide");
- // $(".loading").remove();
- // if(r.exc) {
- // if(r.exc.indexOf("WebsitePriceListMissingError")!==-1) {
- // shopping_cart.show_error("Configuration Error", frappe._("Price List not configured."));
- // } else if(r["403"]) {
- // shopping_cart.show_error("Not Allowed", frappe._("You need to be logged in to view your cart."));
- // } else {
- // shopping_cart.show_error("Error", frappe._("Something went wrong."));
- // }
- // } else {
- // shopping_cart.set_cart_count();
- // shopping_cart.render(r.message);
- // }
- // }
- // });
});
diff --git a/erpnext/templates/includes/cart/cart_item_line.html b/erpnext/templates/includes/cart/cart_item_line.html
deleted file mode 100644
index cd157634a0..0000000000
--- a/erpnext/templates/includes/cart/cart_item_line.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% from "erpnext/templates/includes/order/order_macros.html" import item_name_and_description %}
-
-
-
- {{ item_name_and_description(d) }}
-
-
-
{{ d.get_formatted('qty') }}
-
- {{ _("Rate") + ': ' + d.get_formatted("rate") }}
-
-
-
- {{ d.get_formatted("amount") }}
-
-
diff --git a/erpnext/templates/includes/cart/cart_items.html b/erpnext/templates/includes/cart/cart_items.html
new file mode 100644
index 0000000000..f7efa78709
--- /dev/null
+++ b/erpnext/templates/includes/cart/cart_items.html
@@ -0,0 +1,23 @@
+{% from "erpnext/templates/includes/order/order_macros.html" import item_name_and_description %}
+
+{% for d in doc.items %}
+
+
+
+ {{ item_name_and_description(d) }}
+
+
+
+
+
+ {{ _("Rate") + ': ' + d.get_formatted("rate") }}
+
+
+
+ {{ d.get_formatted("amount") }}
+
+
+
+{% endfor %}
diff --git a/erpnext/templates/includes/issue_row.html b/erpnext/templates/includes/issue_row.html
index 8e87fcae7b..2935a24ea4 100644
--- a/erpnext/templates/includes/issue_row.html
+++ b/erpnext/templates/includes/issue_row.html
@@ -2,13 +2,13 @@
-
+
{{ doc.name }}
{{ doc.subject }}
-
- {{ frappe.format_date(doc.creation) }}
+
+ {{ frappe.format_date(doc.modified) }}
diff --git a/erpnext/templates/includes/order/order_taxes.html b/erpnext/templates/includes/order/order_taxes.html
index 510e1a3d89..8c8e88621b 100644
--- a/erpnext/templates/includes/order/order_taxes.html
+++ b/erpnext/templates/includes/order/order_taxes.html
@@ -15,5 +15,8 @@
{{ _("Grand Total") }}
- {{ doc.get_formatted("grand_total") }}
+
+ {{ doc.get_formatted("grand_total") }}
+
+
diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html
index 837df3b056..a97e65876c 100644
--- a/erpnext/templates/pages/cart.html
+++ b/erpnext/templates/pages/cart.html
@@ -35,11 +35,9 @@
{% if doc.items %}
- {% for d in doc.items %}
-
- {% include "templates/includes/cart/cart_item_line.html" %}
+
+ {% include "templates/includes/cart/cart_items.html" %}
- {% endfor %}
{% else %}
{{ _("Cart is Empty") }}
{% endif %}
@@ -48,7 +46,7 @@
-
+
{% include "templates/includes/order/order_taxes.html" %}
From 72fbf902d7167cba5b3d150cac4ecd8d8acadb30 Mon Sep 17 00:00:00 2001
From: Rushabh Mehta
Date: Thu, 17 Sep 2015 18:29:44 +0530
Subject: [PATCH 4/7] [cleanup] added single price list for shopping cart,
removed Applicable Territory
---
.../sales_taxes_and_charges_template.json | 27 +----
.../sales_taxes_and_charges_template.py | 5 -
.../doctype/shipping_rule/shipping_rule.json | 63 ++++++-----
.../doctype/shipping_rule/shipping_rule.py | 3 +
erpnext/accounts/party.py | 19 +++-
erpnext/patches.txt | 2 +
.../v6_3}/__init__.py | 0
.../v6_3/convert_applicable_territory.py | 17 +++
.../applicable_territory.json | 50 ---------
.../applicable_territory.py | 12 ---
erpnext/shopping_cart/cart.py | 71 ++++++------
.../shopping_cart_price_list/__init__.py | 0
.../shopping_cart_price_list.json | 49 ---------
.../shopping_cart_price_list.py | 12 ---
.../shopping_cart_settings.json | 101 ++----------------
.../shopping_cart_settings.py | 11 +-
.../test_shopping_cart_settings.py | 42 ++------
erpnext/shopping_cart/test_shopping_cart.py | 32 +++---
erpnext/templates/includes/cart.js | 4 +-
19 files changed, 149 insertions(+), 371 deletions(-)
rename erpnext/{setup/doctype/applicable_territory => patches/v6_3}/__init__.py (100%)
create mode 100644 erpnext/patches/v6_3/convert_applicable_territory.py
delete mode 100644 erpnext/setup/doctype/applicable_territory/applicable_territory.json
delete mode 100644 erpnext/setup/doctype/applicable_territory/applicable_territory.py
delete mode 100644 erpnext/shopping_cart/doctype/shopping_cart_price_list/__init__.py
delete mode 100644 erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.json
delete mode 100644 erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.py
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json
index 9a3a4580f5..d01866e447 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json
@@ -164,29 +164,6 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "description": "Specify a list of Territories, for which, this Taxes Master is valid",
- "fieldname": "territories",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Valid for Territories",
- "no_copy": 0,
- "options": "Applicable Territory",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
}
],
"hide_heading": 0,
@@ -198,7 +175,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
- "modified": "2015-09-11 12:19:46.488710",
+ "modified": "2015-09-17 07:09:28.797959",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Taxes and Charges Template",
@@ -206,7 +183,7 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
+ "apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
index b36287b691..886400e5f9 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
@@ -5,7 +5,6 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from erpnext.controllers.accounts_controller import validate_taxes_and_charges, validate_inclusive_tax
-from frappe.utils.nestedset import get_root_of
class SalesTaxesandChargesTemplate(Document):
def validate(self):
@@ -20,10 +19,6 @@ def valdiate_taxes_and_charges_template(doc):
where ifnull(is_default,0) = 1 and name != %s and company = %s""".format(doc.doctype),
(doc.name, doc.company))
- if doc.meta.get_field("territories"):
- if not doc.territories:
- doc.append("territories", {"territory": get_root_of("Territory") })
-
for tax in doc.get("taxes"):
validate_taxes_and_charges(tax)
validate_inclusive_tax(tax, doc)
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.json b/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
index 62d5cb8e0c..be65baf9de 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
@@ -35,14 +35,16 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "column_break_2",
- "fieldtype": "Column Break",
+ "fieldname": "disabled",
+ "fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
+ "label": "Disabled",
"no_copy": 0,
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
@@ -78,6 +80,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "depends_on": "eval:!doc.disabled",
"fieldname": "rule_conditions_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -121,12 +124,14 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "depends_on": "eval:!doc.disabled",
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
+ "label": "Valid for Countries",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
@@ -141,6 +146,29 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "fieldname": "worldwide_shipping",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Worldwide Shipping",
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "depends_on": "eval:!doc.worldwide_shipping",
"fieldname": "countries",
"fieldtype": "Table",
"hidden": 0,
@@ -164,8 +192,9 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "column_break_8",
- "fieldtype": "Column Break",
+ "depends_on": "eval:!doc.disabled",
+ "fieldname": "section_break_10",
+ "fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
@@ -206,8 +235,8 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "section_break_10",
- "fieldtype": "Section Break",
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
@@ -244,26 +273,6 @@
"set_only_once": 0,
"unique": 0
},
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "column_break_12",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
{
"allow_on_submit": 0,
"bold": 0,
@@ -296,7 +305,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
- "modified": "2015-09-17 06:44:05.127516",
+ "modified": "2015-09-17 08:30:57.226342",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Shipping Rule",
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
index dbd121a45e..a2ee820b48 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
@@ -22,6 +22,9 @@ class ShippingRule(Document):
self.sort_shipping_rule_conditions()
self.validate_overlapping_shipping_rule_conditions()
+ if self.worldwide_shipping:
+ self.countries = []
+
def validate_from_to_values(self):
zero_to_values = []
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 1a6e85bf77..9596b44074 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -103,6 +103,19 @@ def set_other_values(out, party, party_type):
if party.get("default_" + f):
out[f] = party.get("default_" + f)
+def get_default_price_list(party):
+ """Return default price list for party (Document object)"""
+ if party.default_price_list:
+ return party.default_price_list
+
+ if party.doctype == "Customer":
+ price_list = frappe.db.get_value("Customer Group",
+ party.customer_group, "default_price_list")
+ if price_list:
+ return price_list
+
+ return None
+
def set_price_list(out, party, party_type, given_price_list):
# price list
price_list = filter(None, get_user_permissions().get("Price List", []))
@@ -110,11 +123,7 @@ def set_price_list(out, party, party_type, given_price_list):
price_list = price_list[0] if len(price_list)==1 else None
if not price_list:
- price_list = party.default_price_list
-
- if not price_list and party_type=="Customer":
- price_list = frappe.db.get_value("Customer Group",
- party.customer_group, "default_price_list")
+ price_list = get_default_price_list(party)
if not price_list:
price_list = given_price_list
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index e20aab0b2e..51356e5ed9 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -209,3 +209,5 @@ erpnext.patches.v6_0.fix_planned_qty
erpnext.patches.v6_0.multi_currency
erpnext.patches.v6_2.remove_newsletter_duplicates
erpnext.patches.v6_2.fix_missing_default_taxes_and_lead
+erpnext.patches.v5_8.tax_rule
+erpnext.patches.v6_3.convert_applicable_territory
diff --git a/erpnext/setup/doctype/applicable_territory/__init__.py b/erpnext/patches/v6_3/__init__.py
similarity index 100%
rename from erpnext/setup/doctype/applicable_territory/__init__.py
rename to erpnext/patches/v6_3/__init__.py
diff --git a/erpnext/patches/v6_3/convert_applicable_territory.py b/erpnext/patches/v6_3/convert_applicable_territory.py
new file mode 100644
index 0000000000..3054ecc879
--- /dev/null
+++ b/erpnext/patches/v6_3/convert_applicable_territory.py
@@ -0,0 +1,17 @@
+import frappe
+
+def execute():
+ # for price list
+ countries = frappe.db.sql_list("select name from tabCountry")
+
+ for doctype in ("Price List", "Shipping Rule"):
+ for at in frappe.db.sql("""select name, parent, territory from `tabApplicable Territory` where
+ parenttype = %s """, doctype, as_dict=True):
+ if at.territory in countries:
+ parent = frappe.get_doc(doctype, at.parent)
+ if not parent.countries:
+ parent.append("countries", {"country": at.territory})
+ parent.save()
+
+
+ frappe.delete_doc("DocType", "Applicable Territory")
diff --git a/erpnext/setup/doctype/applicable_territory/applicable_territory.json b/erpnext/setup/doctype/applicable_territory/applicable_territory.json
deleted file mode 100644
index 6fc549faa6..0000000000
--- a/erpnext/setup/doctype/applicable_territory/applicable_territory.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "creation": "2013-06-20 12:48:38",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "description": "",
- "fieldname": "territory",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Territory",
- "no_copy": 0,
- "options": "Territory",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- }
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 1,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "modified": "2015-01-01 14:29:58.724652",
- "modified_by": "Administrator",
- "module": "Setup",
- "name": "Applicable Territory",
- "owner": "Administrator",
- "permissions": [],
- "read_only": 0,
- "read_only_onload": 0
-}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/applicable_territory/applicable_territory.py b/erpnext/setup/doctype/applicable_territory/applicable_territory.py
deleted file mode 100644
index 5e0ab4092a..0000000000
--- a/erpnext/setup/doctype/applicable_territory/applicable_territory.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
-
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-
-from frappe.model.document import Document
-
-class ApplicableTerritory(Document):
- pass
\ No newline at end of file
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 0d28406f06..74d9e64436 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -131,8 +131,11 @@ def update_cart_address(address_fieldname, address_name):
quotation.flags.ignore_permissions = True
quotation.save()
- return frappe.render_template("templates/includes/cart/cart_address.html",
- get_cart_quotation(quotation))
+ context = get_cart_quotation(quotation)
+ return {
+ "taxes": frappe.render_template("templates/includes/order/order_taxes.html",
+ context),
+ }
def guess_territory():
territory = None
@@ -224,21 +227,19 @@ def apply_cart_settings(party=None, quotation=None):
quotation = _get_cart_quotation(party)
cart_settings = frappe.get_doc("Shopping Cart Settings")
- billing_territory = get_address_territory(quotation.customer_address) or \
- party.territory or get_root_of("Territory")
- set_price_list_and_rate(quotation, cart_settings, billing_territory)
+ set_price_list_and_rate(quotation, cart_settings)
quotation.run_method("calculate_taxes_and_totals")
- set_taxes(quotation, cart_settings, billing_territory)
+ set_taxes(quotation, cart_settings)
_apply_shipping_rule(party, quotation, cart_settings)
-def set_price_list_and_rate(quotation, cart_settings, billing_territory):
+def set_price_list_and_rate(quotation, cart_settings):
"""set price list based on billing territory"""
- _set_price_list(quotation, cart_settings, billing_territory)
+ _set_price_list(quotation, cart_settings)
# reset values
quotation.price_list_currency = quotation.currency = \
@@ -252,24 +253,29 @@ def set_price_list_and_rate(quotation, cart_settings, billing_territory):
# 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, billing_territory):
+def _set_price_list(quotation, cart_settings):
+ """Set price list based on customer or shopping cart default"""
+ if quotation.selling_price_list:
+ return
+
# check if customer price list exists
selling_price_list = None
if quotation.customer:
- selling_price_list = frappe.db.get_value("Customer", quotation.customer, "default_price_list")
+ from erpnext.accounts.party import get_default_price_list
+ selling_price_list = get_default_price_list(frappe.get_doc("Customer", quotation.customer))
# else check for territory based price list
if not selling_price_list:
- selling_price_list = cart_settings.get_price_list(billing_territory)
+ selling_price_list = cart_settings.price_list
quotation.selling_price_list = selling_price_list
-def set_taxes(quotation, cart_settings, billing_territory):
+def set_taxes(quotation, cart_settings):
"""set taxes based on billing territory"""
from erpnext.accounts.party import set_taxes
-
+
customer_group = frappe.db.get_value("Customer", quotation.customer, "customer_group")
-
+
quotation.taxes_and_charges = set_taxes(quotation.customer, "Customer", \
quotation.transaction_date, quotation.company, customer_group, None, \
quotation.customer_address, quotation.shipping_address_name, 1)
@@ -331,38 +337,39 @@ def apply_shipping_rule(shipping_rule):
return get_cart_quotation(quotation)
def _apply_shipping_rule(party=None, quotation=None, cart_settings=None):
- shipping_rules = get_shipping_rules(party, quotation, cart_settings)
+ if not quotation.shipping_rule:
+ shipping_rules = get_shipping_rules(quotation, cart_settings)
- if not shipping_rules:
- return
+ if not shipping_rules:
+ return
- elif quotation.shipping_rule not in shipping_rules:
- quotation.shipping_rule = shipping_rules[0]
+ elif quotation.shipping_rule not in shipping_rules:
+ quotation.shipping_rule = shipping_rules[0]
- quotation.run_method("apply_shipping_rule")
- quotation.run_method("calculate_taxes_and_totals")
+ if quotation.shipping_rule:
+ quotation.run_method("apply_shipping_rule")
+ quotation.run_method("calculate_taxes_and_totals")
def get_applicable_shipping_rules(party=None, quotation=None):
- shipping_rules = get_shipping_rules(party, quotation)
+ shipping_rules = get_shipping_rules(quotation)
if shipping_rules:
rule_label_map = frappe.db.get_values("Shipping Rule", shipping_rules, "label")
# we need this in sorted order as per the position of the rule in the settings page
return [[rule, rule_label_map.get(rule)] for rule in shipping_rules]
-def get_shipping_rules(party=None, quotation=None, cart_settings=None):
- if not party:
- party = get_lead_or_customer()
+def get_shipping_rules(quotation=None, cart_settings=None):
if not quotation:
quotation = _get_cart_quotation()
- if not cart_settings:
- cart_settings = frappe.get_doc("Shopping Cart Settings")
- # set shipping rule based on shipping territory
- shipping_territory = get_address_territory(quotation.shipping_address_name) or \
- party.territory
-
- shipping_rules = cart_settings.get_shipping_rules(shipping_territory)
+ shipping_rules = []
+ if quotation.shipping_address_name:
+ country = frappe.db.get_value("Address", quotation.shipping_address_name, "country")
+ if country:
+ shipping_rules = frappe.db.sql_list("""select distinct sr.name
+ from `tabShipping Rule Country` src, `tabShipping Rule` sr
+ where src.country = %s and
+ sr.disabled != 1 and sr.name = src.parent""", country)
return shipping_rules
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_price_list/__init__.py b/erpnext/shopping_cart/doctype/shopping_cart_price_list/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.json b/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.json
deleted file mode 100644
index e91731e8b3..0000000000
--- a/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "creation": "2013-06-20 16:00:18",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "selling_price_list",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Price List",
- "no_copy": 0,
- "options": "Price List",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- }
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 1,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "modified": "2013-12-20 19:30:47",
- "modified_by": "Administrator",
- "module": "Shopping Cart",
- "name": "Shopping Cart Price List",
- "owner": "Administrator",
- "permissions": [],
- "read_only": 0,
- "read_only_onload": 0
-}
\ No newline at end of file
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.py b/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.py
deleted file mode 100644
index 53c38d01a3..0000000000
--- a/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-
-from frappe.model.document import Document
-
-class ShoppingCartPriceList(Document):
- pass
\ No newline at end of file
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
index 881ff4e377..fbc9ba0220 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
@@ -75,17 +75,17 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "description": "Add / Edit",
- "fieldname": "default_territory",
+ "fieldname": "price_list",
"fieldtype": "Link",
"hidden": 0,
- "ignore_user_permissions": 1,
+ "ignore_user_permissions": 0,
"in_filter": 0,
- "in_list_view": 1,
- "label": "Default Territory",
+ "in_list_view": 0,
+ "label": "Price List",
"no_copy": 0,
- "options": "Territory",
+ "options": "Price List",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
@@ -118,7 +118,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "description": "Add / Edit",
+ "description": "",
"fieldname": "default_customer_group",
"fieldtype": "Link",
"hidden": 0,
@@ -157,91 +157,6 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "section_break_6",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "price_lists",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Price Lists",
- "no_copy": 0,
- "options": "Shopping Cart Price List",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "column_break_10",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "shipping_rules",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Shipping Rules",
- "no_copy": 0,
- "options": "Shopping Cart Shipping Rule",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
}
],
"hide_heading": 0,
@@ -253,7 +168,7 @@
"is_submittable": 0,
"issingle": 1,
"istable": 0,
- "modified": "2015-09-11 19:03:54.750937",
+ "modified": "2015-09-17 07:56:09.176098",
"modified_by": "Administrator",
"module": "Shopping Cart",
"name": "Shopping Cart Settings",
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
index a8a4b7653f..4fac3a814d 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
@@ -18,7 +18,6 @@ class ShoppingCartSettings(Document):
def validate(self):
if self.enabled:
- self.validate_tax_masters()
self.validate_exchange_rates_exist()
def validate_exchange_rates_exist(self):
@@ -29,7 +28,7 @@ class ShoppingCartSettings(Document):
raise_exception=ShoppingCartSetupError)
price_list_currency_map = frappe.db.get_values("Price List",
- [d.selling_price_list for d in self.get("price_lists")],
+ [self.price_list],
"currency")
# check if all price lists have a currency
@@ -52,14 +51,6 @@ class ShoppingCartSettings(Document):
msgprint(_("Missing Currency Exchange Rates for {0}").format(comma_and(missing)),
raise_exception=ShoppingCartSetupError)
- def get_price_list(self, billing_territory):
- price_list = self.get_name_from_territory(billing_territory, "price_lists", "selling_price_list")
- if not (price_list and price_list[0]):
- price_list = self.get_name_from_territory(self.default_territory or get_root_of("Territory"),
- "price_lists", "selling_price_list")
-
- return price_list and price_list[0] or None
-
def validate_tax_rule(self):
if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart" : 1}, "name"):
frappe.throw(frappe._("Set Tax Rule for shopping cart"), ShoppingCartSetupError)
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
index b18cece44a..66be927bcc 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
@@ -11,55 +11,29 @@ from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings
class TestShoppingCartSettings(unittest.TestCase):
def setUp(self):
frappe.db.sql("""delete from `tabSingles` where doctype="Shipping Cart Settings" """)
- frappe.db.sql("""delete from `tabShopping Cart Price List`""")
- frappe.db.sql("""delete from `tabShopping Cart Shipping Rule`""")
-
+
def get_cart_settings(self):
return frappe.get_doc({"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.append("price_lists", {
- "doctype": "Shopping Cart Price List",
- "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
- controller.validate_overlapping_territories("price_lists", "selling_price_list")
-
- _add_price_list("_Test Price List 2")
-
- controller = cart_settings
- self.assertRaises(ShoppingCartSetupError, controller.validate_overlapping_territories,
- "price_lists", "selling_price_list")
-
- return cart_settings
-
+
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)
-
+
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()
-
+
def test_tax_rule_validation(self):
frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 0")
frappe.db.commit()
-
+
cart_settings = self.get_cart_settings()
- cart_settings.enabled = 1
+ cart_settings.enabled = 1
if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart": 1}, "name"):
self.assertRaises(ShoppingCartSetupError, cart_settings.validate_tax_rule)
-
+
diff --git a/erpnext/shopping_cart/test_shopping_cart.py b/erpnext/shopping_cart/test_shopping_cart.py
index bd0b138d45..dc3b4fe2ab 100644
--- a/erpnext/shopping_cart/test_shopping_cart.py
+++ b/erpnext/shopping_cart/test_shopping_cart.py
@@ -25,7 +25,7 @@ class TestShoppingCart(unittest.TestCase):
# 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"),
+ self.assertEquals(frappe.db.get_value("Lead", quotation.lead, "email_id"),
"test_cart_user@example.com")
self.assertEquals(quotation.customer, None)
self.assertEquals(quotation.contact_email, frappe.session.user)
@@ -61,7 +61,7 @@ class TestShoppingCart(unittest.TestCase):
# 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()
@@ -109,12 +109,12 @@ class TestShoppingCart(unittest.TestCase):
quotation = self.test_get_cart_lead()
self.assertEquals(quotation.net_total, 0)
self.assertEquals(len(quotation.get("items")), 0)
-
-
- def test_taxe_rule(self):
+
+
+ def test_tax_rule(self):
self.login_as_customer()
quotation = self.create_quotation()
-
+
from erpnext.accounts.party import set_taxes
tax_rule_master = set_taxes(quotation.customer, "Customer", \
@@ -123,12 +123,12 @@ class TestShoppingCart(unittest.TestCase):
self.assertEquals(quotation.taxes_and_charges, tax_rule_master)
self.assertEquals(quotation.total_taxes_and_charges, 1000.0)
-
+
self.remove_test_quotation(quotation)
-
+
def create_quotation(self):
quotation = frappe.new_doc("Quotation")
-
+
values = {
"doctype": "Quotation",
"quotation_to": "Customer",
@@ -146,13 +146,13 @@ class TestShoppingCart(unittest.TestCase):
"taxes": frappe.get_doc("Sales Taxes and Charges Template", "_Test Tax 1").taxes,
"company": "_Test Company"
}
-
+
quotation.update(values)
-
+
quotation.insert(ignore_permissions=True)
-
+
return quotation
-
+
def remove_test_quotation(self, quotation):
frappe.set_user("Administrator")
quotation.delete()
@@ -180,7 +180,7 @@ class TestShoppingCart(unittest.TestCase):
])
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
@@ -239,11 +239,11 @@ class TestShoppingCart(unittest.TestCase):
"lead_name": "_Test Website Lead",
"phone": "+91 0000000000"
}).insert(ignore_permissions=True)
-
+
def remove_all_items_from_cart(self):
quotation = get_quotation()
quotation.set("items", [])
quotation.save(ignore_permissions=True)
-
+
test_dependencies = ["Sales Taxes and Charges Template", "Price List", "Item Price", "Shipping Rule", "Currency Exchange",
"Customer Group", "Lead", "Customer", "Contact", "Address", "Item", "Tax Rule"]
diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js
index e6ce25a6a8..cc321579bf 100644
--- a/erpnext/templates/includes/cart.js
+++ b/erpnext/templates/includes/cart.js
@@ -33,7 +33,7 @@ $.extend(shopping_cart, {
},
callback: function(r) {
if(!r.exc) {
- $('.cart-addresses').html(r.message);
+ $(".cart-tax-items").html(r.message.taxes);
}
}
});
@@ -54,12 +54,14 @@ $.extend(shopping_cart, {
// bind update button
$(".cart-items").on("change", ".cart-qty", function() {
var item_code = $(this).attr("data-item-code");
+ frappe.freeze();
shopping_cart.update_cart({
item_code: item_code,
qty: $(this).val(),
with_items: 1,
btn: this,
callback: function(r) {
+ frappe.unfreeze();
if(!r.exc) {
$(".cart-items").html(r.message.items);
$(".cart-tax-items").html(r.message.taxes);
From 52dfc32eca72fcf7058813bfe96783038df7194c Mon Sep 17 00:00:00 2001
From: Anand Doshi
Date: Mon, 21 Sep 2015 17:03:47 +0530
Subject: [PATCH 5/7] [fix] validate_valuation_rate for Repack
---
erpnext/manufacturing/doctype/bom/bom.js | 2 +-
.../stock/doctype/stock_entry/stock_entry.py | 114 +++++++++---------
2 files changed, 60 insertions(+), 56 deletions(-)
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 3bad2f081e..9883ba30f6 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -147,7 +147,7 @@ cur_frm.fields_dict['project_name'].get_query = function(doc, dt, dn) {
cur_frm.fields_dict['items'].grid.get_field('item_code').get_query = function(doc) {
return{
query: "erpnext.controllers.queries.item_query",
- filters: [["Item", "name", "!=", doc.item]]
+ filters: [["Item", "name", "!=", cur_frm.doc.item]]
}
}
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 5f85ef91a8..68274d1b42 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -49,7 +49,7 @@ class StockEntry(StockController):
self.validate_finished_goods()
self.validate_with_material_request()
self.validate_batch()
-
+
self.set_actual_qty()
self.calculate_rate_and_amount()
@@ -212,10 +212,10 @@ class StockEntry(StockController):
if fg_qty_already_entered >= qty:
frappe.throw(_("Stock Entries already created for Production Order ")
+ self.production_order + ":" + ", ".join(other_ste), DuplicateEntryForProductionOrderError)
-
+
def set_actual_qty(self):
allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock"))
-
+
for d in self.get('items'):
previous_sle = get_previous_sle({
"item_code": d.item_code,
@@ -232,7 +232,7 @@ class StockEntry(StockController):
frappe.throw(_("""Row {0}: Qty not avalable in warehouse {1} on {2} {3}.
Available Qty: {4}, Transfer Qty: {5}""").format(d.idx, d.s_warehouse,
self.posting_date, self.posting_time, d.actual_qty, d.transfer_qty), NegativeStockError)
-
+
def get_stock_and_rate(self):
self.set_actual_qty()
self.calculate_rate_and_amount()
@@ -244,7 +244,7 @@ class StockEntry(StockController):
self.validate_valuation_rate()
self.set_total_incoming_outgoing_value()
self.set_total_amount()
-
+
def set_basic_rate(self, force=False):
"""get stock and incoming rate on posting date"""
raw_material_cost = 0.0
@@ -269,9 +269,9 @@ class StockEntry(StockController):
d.basic_amount = flt(flt(d.transfer_qty) * flt(d.basic_rate), d.precision("basic_amount"))
if not d.t_warehouse:
raw_material_cost += flt(d.basic_amount)
-
+
self.set_basic_rate_for_finished_goods(raw_material_cost)
-
+
def set_basic_rate_for_finished_goods(self, raw_material_cost):
if self.purpose in ["Manufacture", "Repack"]:
number_of_fg_items = len([t.t_warehouse for t in self.get("items") if t.t_warehouse])
@@ -279,11 +279,11 @@ class StockEntry(StockController):
if d.bom_no or (d.t_warehouse and number_of_fg_items == 1):
d.basic_rate = flt(raw_material_cost / flt(d.transfer_qty), d.precision("basic_rate"))
d.basic_amount = flt(raw_material_cost, d.precision("basic_amount"))
-
+
def distribute_additional_costs(self):
if self.purpose == "Material Issue":
self.additional_costs = []
-
+
self.total_additional_costs = sum([flt(t.amount) for t in self.get("additional_costs")])
total_basic_amount = sum([flt(t.basic_amount) for t in self.get("items") if t.t_warehouse])
@@ -292,11 +292,11 @@ class StockEntry(StockController):
d.additional_cost = (flt(d.basic_amount) / total_basic_amount) * self.total_additional_costs
else:
d.additional_cost = 0
-
+
def update_valuation_rate(self):
for d in self.get("items"):
d.amount = flt(d.basic_amount + flt(d.additional_cost), d.precision("amount"))
- d.valuation_rate = flt(flt(d.basic_rate) + flt(d.additional_cost) / flt(d.transfer_qty),
+ d.valuation_rate = flt(flt(d.basic_rate) + flt(d.additional_cost) / flt(d.transfer_qty),
d.precision("valuation_rate"))
def validate_valuation_rate(self):
@@ -373,7 +373,7 @@ class StockEntry(StockController):
def update_stock_ledger(self):
sl_entries = []
- for d in self.get('items'):
+ for d in self.get('items'):
if cstr(d.s_warehouse) and self.docstatus == 1:
sl_entries.append(self.get_sl_entries(d, {
"warehouse": cstr(d.s_warehouse),
@@ -399,15 +399,15 @@ class StockEntry(StockController):
}))
self.make_sl_entries(sl_entries, self.amended_from and 'Yes' or 'No')
-
+
def get_gl_entries(self, warehouse_account):
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
-
+
gl_entries = super(StockEntry, self).get_gl_entries(warehouse_account)
-
+
for d in self.get("items"):
additional_cost = flt(d.additional_cost, d.precision("additional_cost"))
- if additional_cost:
+ if additional_cost:
gl_entries.append(self.get_gl_dict({
"account": expenses_included_in_valuation,
"against": d.expense_account,
@@ -415,7 +415,7 @@ class StockEntry(StockController):
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": additional_cost
}))
-
+
gl_entries.append(self.get_gl_dict({
"account": d.expense_account,
"against": expenses_included_in_valuation,
@@ -521,7 +521,7 @@ class StockEntry(StockController):
def get_items(self):
self.set('items', [])
self.validate_production_order()
-
+
if not self.posting_date or not self.posting_time:
frappe.throw(_("Posting date and posting time is mandatory"))
@@ -548,7 +548,7 @@ class StockEntry(StockController):
for item in item_dict.values():
item["to_warehouse"] = self.pro_doc.wip_warehouse
self.add_to_stock_entry_detail(item_dict)
-
+
elif self.production_order and self.purpose == "Manufacture" and \
frappe.db.get_single_value("Manufacturing Settings", "backflush_raw_materials_based_on")== "Material Transferred for Manufacture":
self.get_transfered_raw_materials()
@@ -578,10 +578,14 @@ class StockEntry(StockController):
to_warehouse = self.pro_doc.fg_warehouse
else:
item_code = frappe.db.get_value("BOM", self.bom_no, "item")
- to_warehouse = ""
+ to_warehouse = self.to_warehouse
item = frappe.db.get_value("Item", item_code, ["item_name",
- "description", "stock_uom", "expense_account", "buying_cost_center", "name"], as_dict=1)
+ "description", "stock_uom", "expense_account", "buying_cost_center", "name", "default_warehouse"], as_dict=1)
+
+ if not self.production_order and not to_warehouse:
+ # in case of BOM
+ to_warehouse = item.default_warehouse
self.add_to_stock_entry_detail({
item.name: {
@@ -600,57 +604,57 @@ class StockEntry(StockController):
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
# item dict = { item_code: {qty, description, stock_uom} }
- item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty,
+ item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty,
fetch_exploded = self.use_multi_level_bom)
for item in item_dict.values():
item.from_warehouse = self.from_warehouse or item.default_warehouse
return item_dict
-
+
def get_transfered_raw_materials(self):
transferred_materials = frappe.db.sql("""
- select
- item_name, item_code, sum(qty) as qty, sed.t_warehouse as warehouse,
- description, stock_uom, expense_account, cost_center
- from `tabStock Entry` se,`tabStock Entry Detail` sed
- where
- se.name = sed.parent and se.docstatus=1 and se.purpose='Material Transfer for Manufacture'
- and se.production_order= %s and ifnull(sed.t_warehouse, '') != ''
+ select
+ item_name, item_code, sum(qty) as qty, sed.t_warehouse as warehouse,
+ description, stock_uom, expense_account, cost_center
+ from `tabStock Entry` se,`tabStock Entry Detail` sed
+ where
+ se.name = sed.parent and se.docstatus=1 and se.purpose='Material Transfer for Manufacture'
+ and se.production_order= %s and ifnull(sed.t_warehouse, '') != ''
group by sed.item_code, sed.t_warehouse
""", self.production_order, as_dict=1)
-
+
materials_already_backflushed = frappe.db.sql("""
- select
- item_code, sed.s_warehouse as warehouse, sum(qty) as qty
- from
- `tabStock Entry` se, `tabStock Entry Detail` sed
- where
- se.name = sed.parent and se.docstatus=1 and se.purpose='Manufacture'
- and se.production_order= %s and ifnull(sed.s_warehouse, '') != ''
+ select
+ item_code, sed.s_warehouse as warehouse, sum(qty) as qty
+ from
+ `tabStock Entry` se, `tabStock Entry Detail` sed
+ where
+ se.name = sed.parent and se.docstatus=1 and se.purpose='Manufacture'
+ and se.production_order= %s and ifnull(sed.s_warehouse, '') != ''
group by sed.item_code, sed.s_warehouse
""", self.production_order, as_dict=1)
-
+
backflushed_materials= {}
for d in materials_already_backflushed:
backflushed_materials.setdefault(d.item_code,[]).append({d.warehouse: d.qty})
-
+
po_qty = frappe.db.sql("""select qty, produced_qty, material_transferred_for_manufacturing from
`tabProduction Order` where name=%s""", self.production_order, as_dict=1)[0]
manufacturing_qty = flt(po_qty.qty)
produced_qty = flt(po_qty.produced_qty)
trans_qty = flt(po_qty.material_transferred_for_manufacturing)
-
+
for item in transferred_materials:
qty= item.qty
-
+
if manufacturing_qty > (produced_qty + flt(self.fg_completed_qty)):
qty = (qty/trans_qty) * flt(self.fg_completed_qty)
-
+
elif backflushed_materials.get(item.item_code):
for d in backflushed_materials.get(item.item_code):
if d.get(item.warehouse):
qty-= d.get(item.warehouse)
-
+
if qty > 0:
self.add_to_stock_entry_detail({
item.item_code: {
@@ -729,7 +733,7 @@ class StockEntry(StockController):
se_child.s_warehouse = self.from_warehouse
if se_child.t_warehouse==None:
se_child.t_warehouse = self.to_warehouse
-
+
# in stock uom
se_child.transfer_qty = flt(item_dict[d]["qty"])
se_child.conversion_factor = 1.00
@@ -761,7 +765,7 @@ class StockEntry(StockController):
def get_production_order_details(production_order):
production_order = frappe.get_doc("Production Order", production_order)
pending_qty_to_produce = flt(production_order.qty) - flt(production_order.produced_qty)
-
+
return {
"from_bom": 1,
"bom_no": production_order.bom_no,
@@ -771,7 +775,7 @@ def get_production_order_details(production_order):
"fg_completed_qty": pending_qty_to_produce,
"additional_costs": get_additional_costs(production_order, fg_qty=pending_qty_to_produce)
}
-
+
def get_additional_costs(production_order=None, bom_no=None, fg_qty=None):
additional_costs = []
operating_cost_per_unit = get_operating_cost_per_unit(production_order, bom_no)
@@ -780,33 +784,33 @@ def get_additional_costs(production_order=None, bom_no=None, fg_qty=None):
"description": "Operating Cost as per Production Order / BOM",
"amount": operating_cost_per_unit * flt(fg_qty)
})
-
+
if production_order and production_order.additional_operating_cost:
additional_operating_cost_per_unit = \
flt(production_order.additional_operating_cost) / flt(production_order.qty)
-
+
additional_costs.append({
"description": "Additional Operating Cost",
"amount": additional_operating_cost_per_unit * flt(fg_qty)
})
-
+
return additional_costs
-
+
def get_operating_cost_per_unit(production_order=None, bom_no=None):
operating_cost_per_unit = 0
if production_order:
if not bom_no:
bom_no = production_order.bom_no
-
+
for d in production_order.get("operations"):
if flt(d.completed_qty):
operating_cost_per_unit += flt(d.actual_operating_cost) / flt(d.completed_qty)
else:
operating_cost_per_unit += flt(d.planned_operating_cost) / flt(production_order.qty)
-
+
# Get operating cost from BOM if not found in production_order.
if not operating_cost_per_unit and bom_no:
bom = frappe.db.get_value("BOM", bom_no, ["operating_cost", "quantity"], as_dict=1)
operating_cost_per_unit = flt(bom.operating_cost) / flt(bom.quantity)
-
- return operating_cost_per_unit
\ No newline at end of file
+
+ return operating_cost_per_unit
From 06ad308ca1e3c3e66d4ae8ae78f3bbc0ac4c40dd Mon Sep 17 00:00:00 2001
From: Anand Doshi
Date: Wed, 23 Sep 2015 12:46:59 +0530
Subject: [PATCH 6/7] [fixes] setup wizard and other fixes related to cart
---
.../sales_taxes_and_charges_template.js | 3 -
.../test_records.json | 56 +-
.../doctype/shipping_rule/shipping_rule.js | 5 -
.../doctype/shipping_rule/shipping_rule.json | 714 +++++++++---------
.../doctype/shipping_rule/shipping_rule.py | 3 +
.../doctype/shipping_rule/test_records.json | 156 ++--
erpnext/accounts/doctype/tax_rule/tax_rule.py | 34 +-
erpnext/public/js/utils.js | 16 +-
.../setup/page/setup_wizard/setup_wizard.py | 9 +-
erpnext/shopping_cart/__init__.py | 101 ---
erpnext/shopping_cart/cart.py | 97 +--
.../shopping_cart_settings.py | 4 -
.../test_shopping_cart_settings.py | 8 +-
erpnext/shopping_cart/test_shopping_cart.py | 111 +--
.../stock/doctype/price_list/price_list.js | 6 +-
.../doctype/price_list/test_records.json | 89 +--
erpnext/templates/pages/user.py | 23 +-
17 files changed, 574 insertions(+), 861 deletions(-)
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
index d7a4f5ad7f..8828e0c8e6 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
@@ -5,6 +5,3 @@ cur_frm.cscript.tax_table = "Sales Taxes and Charges";
{% include "public/js/controllers/accounts.js" %}
-frappe.ui.form.on("Sales Taxes and Charges Template", "onload", function(frm) {
- erpnext.add_applicable_territory();
-});
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/test_records.json b/erpnext/accounts/doctype/sales_taxes_and_charges_template/test_records.json
index 69dbd8e9a6..2b737b9804 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/test_records.json
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/test_records.json
@@ -20,19 +20,7 @@
"rate": 6.36
}
],
- "title": "_Test Sales Taxes and Charges Template",
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "All Territories"
- },
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory Rest Of The World"
- }
- ]
+ "title": "_Test Sales Taxes and Charges Template"
},
{
"company": "_Test Company",
@@ -115,14 +103,7 @@
"row_id": 7
}
],
- "title": "_Test India Tax Master",
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory India"
- }
- ]
+ "title": "_Test India Tax Master"
},
{
"company": "_Test Company",
@@ -145,14 +126,7 @@
"rate": 4
}
],
- "title": "_Test Sales Taxes and Charges Template - Rest of the World",
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory Rest Of The World"
- }
- ]
+ "title": "_Test Sales Taxes and Charges Template - Rest of the World"
},
{
"company": "_Test Company",
@@ -175,14 +149,7 @@
"rate": 4
}
],
- "title": "_Test Sales Taxes and Charges Template 1",
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory Rest Of The World"
- }
- ]
+ "title": "_Test Sales Taxes and Charges Template 1"
},
{
"company": "_Test Company",
@@ -205,14 +172,7 @@
"rate": 4
}
],
- "title": "_Test Sales Taxes and Charges Template 2",
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory Rest Of The World"
- }
- ]
+ "title": "_Test Sales Taxes and Charges Template 2"
},
{
"doctype" : "Sales Taxes and Charges Template",
@@ -224,9 +184,6 @@
"cost_center": "Main - _TC",
"description": "Test Shopping cart taxes with Tax Rule",
"tax_amount": 1000
- }],
- "territories":[{
- "territory" : "All Territories"
}]
},
{
@@ -239,9 +196,6 @@
"cost_center": "Main - _TC",
"description": "Test Shopping cart taxes with Tax Rule",
"tax_amount": 200
- }],
- "territories":[{
- "territory" : "All Territories"
}]
}
]
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js
index 233bea1782..17f2083983 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js
@@ -1,8 +1,3 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-$.extend(cur_frm.cscript, {
- onload: function() {
- erpnext.add_applicable_territory();
- }
-});
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.json b/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
index be65baf9de..1c5d979dd4 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.json
@@ -1,397 +1,397 @@
{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "field:label",
- "creation": "2013-06-25 11:48:03",
- "custom": 0,
- "description": "Specify conditions to calculate shipping amount",
- "docstatus": 0,
- "doctype": "DocType",
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:label",
+ "creation": "2013-06-25 11:48:03",
+ "custom": 0,
+ "description": "Specify conditions to calculate shipping amount",
+ "docstatus": 0,
+ "doctype": "DocType",
"fields": [
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "description": "example: Next Day Shipping",
- "fieldname": "label",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Shipping Rule Label",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "description": "example: Next Day Shipping",
+ "fieldname": "label",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Shipping Rule Label",
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "disabled",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Disabled",
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "disabled",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Disabled",
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "default": "Net Total",
- "fieldname": "calculate_based_on",
- "fieldtype": "Select",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Calculate Based On",
- "no_copy": 0,
- "options": "Net Total\nNet Weight",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "default": "Net Total",
+ "fieldname": "calculate_based_on",
+ "fieldtype": "Select",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Calculate Based On",
+ "no_copy": 0,
+ "options": "Net Total\nNet Weight",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "eval:!doc.disabled",
- "fieldname": "rule_conditions_section",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Shipping Rule Conditions",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "depends_on": "eval:!doc.disabled",
+ "fieldname": "rule_conditions_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Shipping Rule Conditions",
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "conditions",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Shipping Rule Conditions",
- "no_copy": 0,
- "options": "Shipping Rule Condition",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "conditions",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Shipping Rule Conditions",
+ "no_copy": 0,
+ "options": "Shipping Rule Condition",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "eval:!doc.disabled",
- "fieldname": "section_break_6",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Valid for Countries",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "depends_on": "eval:!doc.disabled",
+ "fieldname": "section_break_6",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Valid for Countries",
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "worldwide_shipping",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Worldwide Shipping",
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "worldwide_shipping",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Worldwide Shipping",
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "eval:!doc.worldwide_shipping",
- "fieldname": "countries",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Valid for Countries",
- "no_copy": 0,
- "options": "Shipping Rule Country",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "depends_on": "eval:!doc.worldwide_shipping",
+ "fieldname": "countries",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Valid for Countries",
+ "no_copy": 0,
+ "options": "Shipping Rule Country",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "eval:!doc.disabled",
- "fieldname": "section_break_10",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "depends_on": "eval:!doc.disabled",
+ "fieldname": "section_break_10",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Company",
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Company",
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "column_break_12",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Shipping Account",
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Shipping Account",
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "cost_center",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Cost Center",
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Cost Center",
+ "no_copy": 0,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
}
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "icon-truck",
- "idx": 1,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "modified": "2015-09-17 08:30:57.226342",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "Shipping Rule",
- "owner": "Administrator",
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "icon-truck",
+ "idx": 1,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "modified": "2015-09-22 08:30:57.226342",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Shipping Rule",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "apply_user_permissions": 1,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 1,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 1,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Sales User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 1,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Sales User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Sales Master Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Sales Master Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
}
- ],
- "read_only": 0,
+ ],
+ "read_only": 0,
"read_only_onload": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
index a2ee820b48..80e4fb7415 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
@@ -25,6 +25,9 @@ class ShippingRule(Document):
if self.worldwide_shipping:
self.countries = []
+ elif not len([d.country for d in self.countries if d.country]):
+ frappe.throw(_("Please specify a country for this Shipping Rule or check Worldwide Shipping"))
+
def validate_from_to_values(self):
zero_to_values = []
diff --git a/erpnext/accounts/doctype/shipping_rule/test_records.json b/erpnext/accounts/doctype/shipping_rule/test_records.json
index 96e7770d5a..a271009b2b 100644
--- a/erpnext/accounts/doctype/shipping_rule/test_records.json
+++ b/erpnext/accounts/doctype/shipping_rule/test_records.json
@@ -1,116 +1,100 @@
[
{
- "account": "_Test Account Shipping Charges - _TC",
- "calculate_based_on": "Net Total",
- "company": "_Test Company",
- "cost_center": "_Test Cost Center - _TC",
- "doctype": "Shipping Rule",
- "label": "_Test Shipping Rule",
- "name": "_Test Shipping Rule",
+ "account": "_Test Account Shipping Charges - _TC",
+ "calculate_based_on": "Net Total",
+ "company": "_Test Company",
+ "cost_center": "_Test Cost Center - _TC",
+ "doctype": "Shipping Rule",
+ "label": "_Test Shipping Rule",
+ "name": "_Test Shipping Rule",
"conditions": [
{
- "doctype": "Shipping Rule Condition",
- "from_value": 0,
- "parentfield": "conditions",
- "shipping_amount": 50.0,
+ "doctype": "Shipping Rule Condition",
+ "from_value": 0,
+ "parentfield": "conditions",
+ "shipping_amount": 50.0,
"to_value": 100
- },
+ },
{
- "doctype": "Shipping Rule Condition",
- "from_value": 101,
- "parentfield": "conditions",
- "shipping_amount": 100.0,
+ "doctype": "Shipping Rule Condition",
+ "from_value": 101,
+ "parentfield": "conditions",
+ "shipping_amount": 100.0,
"to_value": 200
- },
+ },
{
- "doctype": "Shipping Rule Condition",
- "from_value": 201,
- "parentfield": "conditions",
+ "doctype": "Shipping Rule Condition",
+ "from_value": 201,
+ "parentfield": "conditions",
"shipping_amount": 0.0
}
- ],
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory"
- }
- ]
- },
+ ],
+ "worldwide_shipping": 1
+ },
{
- "account": "_Test Account Shipping Charges - _TC",
- "calculate_based_on": "Net Total",
- "company": "_Test Company",
- "cost_center": "_Test Cost Center - _TC",
- "doctype": "Shipping Rule",
- "label": "_Test Shipping Rule - India",
- "name": "_Test Shipping Rule - India",
+ "account": "_Test Account Shipping Charges - _TC",
+ "calculate_based_on": "Net Total",
+ "company": "_Test Company",
+ "cost_center": "_Test Cost Center - _TC",
+ "doctype": "Shipping Rule",
+ "label": "_Test Shipping Rule - India",
+ "name": "_Test Shipping Rule - India",
"conditions": [
{
- "doctype": "Shipping Rule Condition",
- "from_value": 0,
- "parentfield": "conditions",
- "shipping_amount": 50.0,
+ "doctype": "Shipping Rule Condition",
+ "from_value": 0,
+ "parentfield": "conditions",
+ "shipping_amount": 50.0,
"to_value": 100
- },
+ },
{
- "doctype": "Shipping Rule Condition",
- "from_value": 101,
- "parentfield": "conditions",
- "shipping_amount": 100.0,
+ "doctype": "Shipping Rule Condition",
+ "from_value": 101,
+ "parentfield": "conditions",
+ "shipping_amount": 100.0,
"to_value": 200
- },
+ },
{
- "doctype": "Shipping Rule Condition",
- "from_value": 201,
- "parentfield": "conditions",
+ "doctype": "Shipping Rule Condition",
+ "from_value": 201,
+ "parentfield": "conditions",
"shipping_amount": 0.0
}
- ],
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory India"
- }
+ ],
+ "countries": [
+ {"country": "India"}
]
- },
+ },
{
- "account": "_Test Account Shipping Charges - _TC",
- "calculate_based_on": "Net Total",
- "company": "_Test Company",
- "cost_center": "_Test Cost Center - _TC",
- "doctype": "Shipping Rule",
- "label": "_Test Shipping Rule - Rest of the World",
- "name": "_Test Shipping Rule - Rest of the World",
+ "account": "_Test Account Shipping Charges - _TC",
+ "calculate_based_on": "Net Total",
+ "company": "_Test Company",
+ "cost_center": "_Test Cost Center - _TC",
+ "doctype": "Shipping Rule",
+ "label": "_Test Shipping Rule - Rest of the World",
+ "name": "_Test Shipping Rule - Rest of the World",
"conditions": [
{
- "doctype": "Shipping Rule Condition",
- "from_value": 0,
- "parentfield": "conditions",
- "shipping_amount": 500.0,
+ "doctype": "Shipping Rule Condition",
+ "from_value": 0,
+ "parentfield": "conditions",
+ "shipping_amount": 500.0,
"to_value": 1000
- },
+ },
{
- "doctype": "Shipping Rule Condition",
- "from_value": 1001,
- "parentfield": "conditions",
- "shipping_amount": 1000.0,
+ "doctype": "Shipping Rule Condition",
+ "from_value": 1001,
+ "parentfield": "conditions",
+ "shipping_amount": 1000.0,
"to_value": 2000
- },
+ },
{
- "doctype": "Shipping Rule Condition",
- "from_value": 2001,
- "parentfield": "conditions",
+ "doctype": "Shipping Rule Condition",
+ "from_value": 2001,
+ "parentfield": "conditions",
"shipping_amount": 1500.0
}
- ],
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory Rest Of The World"
- }
- ]
+ ],
+ "worldwide_shipping": 1
}
-]
\ No newline at end of file
+]
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py
index 0a9bb1114b..1e306e9eb7 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py
@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
+from frappe.model import default_fields
from frappe.model.document import Document
from frappe.utils import cstr
@@ -13,6 +14,9 @@ class IncorrectSupplierType(frappe.ValidationError): pass
class ConflictingTaxRule(frappe.ValidationError): pass
class TaxRule(Document):
+ def __setup__(self):
+ self.flags.ignore_these_exceptions_in_test = [ConflictingTaxRule]
+
def validate(self):
self.validate_tax_template()
self.validate_customer_group()
@@ -25,7 +29,7 @@ class TaxRule(Document):
self.purchase_tax_template = self.supplier = self.supplier_type= None
else:
self.sales_tax_template= self.customer = self.customer_group= None
-
+
if not (self.sales_tax_template or self.purchase_tax_template):
frappe.throw(_("Tax Template is mandatory."))
@@ -34,7 +38,7 @@ class TaxRule(Document):
if not frappe.db.get_value("Customer", self.customer, "customer_group") == self.customer_group:
frappe.throw(_("Customer {0} does not belong to customer group {1}"). \
format(self.customer, self.customer_group), IncorrectCustomerGroup)
-
+
def validate_supplier_type(self):
if self.supplier and self.supplier_type:
if not frappe.db.get_value("Supplier", self.supplier, "supplier_type") == self.supplier_type:
@@ -60,28 +64,28 @@ class TaxRule(Document):
"shipping_country": self.shipping_country,
"company": self.company
}
-
+
conds=""
for d in filters:
if conds:
conds += " and "
conds += """ifnull({0}, '') = '{1}'""".format(d, frappe.db.escape(cstr(filters[d])))
-
+
if self.from_date and self.to_date:
conds += """ and ((from_date > '{from_date}' and from_date < '{to_date}') or
(to_date > '{from_date}' and to_date < '{to_date}') or
('{from_date}' > from_date and '{from_date}' < to_date) or
('{from_date}' = from_date and '{to_date}' = to_date))""".format(from_date=self.from_date, to_date=self.to_date)
-
+
elif self.from_date and not self.to_date:
conds += """ and to_date > '{from_date}'""".format(from_date = self.from_date)
elif self.to_date and not self.from_date:
conds += """ and from_date < '{to_date}'""".format(to_date = self.to_date)
-
+
tax_rule = frappe.db.sql("select name, priority \
- from `tabTax Rule` where {0} and name != '{1}'".format(conds, self.name), as_dict=1)
-
+ from `tabTax Rule` where {0} and name != '{1}'".format(conds, self.name), as_dict=1)
+
if tax_rule:
if tax_rule[0].priority == self.priority:
frappe.throw(_("Tax Rule Conflicts with {0}".format(tax_rule[0].name)), ConflictingTaxRule)
@@ -95,10 +99,10 @@ def get_party_details(party, party_type, args=None):
else:
billing_filters= {party_type: party, "is_primary_address": 1}
shipping_filters= {party_type:party, "is_shipping_address": 1}
-
+
billing_address= frappe.get_all("Address", fields=["city", "state", "country"], filters= billing_filters)
shipping_address= frappe.get_all("Address", fields=["city", "state", "country"], filters= shipping_filters)
-
+
if billing_address:
out["billing_city"]= billing_address[0].city
out["billing_state"]= billing_address[0].state
@@ -108,7 +112,7 @@ def get_party_details(party, party_type, args=None):
out["shipping_city"]= shipping_address[0].city
out["shipping_state"]= shipping_address[0].state
out["shipping_country"]= shipping_address[0].country
-
+
return out
def get_tax_template(posting_date, args):
@@ -121,14 +125,14 @@ def get_tax_template(posting_date, args):
matching = frappe.db.sql("""select * from `tabTax Rule`
where {0}""".format(" and ".join(conditions)), as_dict = True)
-
+
if not matching:
return None
-
+
for rule in matching:
rule.no_of_keys_matched = 0
for key in args:
if rule.get(key): rule.no_of_keys_matched += 1
-
+
rule = sorted(matching, lambda b, a: cmp(a.no_of_keys_matched, b.no_of_keys_matched) or cmp(a.priority, b.priority))[0]
- return rule.sales_tax_template or rule.purchase_tax_template
\ No newline at end of file
+ return rule.sales_tax_template or rule.purchase_tax_template
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 68a447b601..7f69202522 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -49,18 +49,6 @@ $.extend(erpnext, {
}
},
- add_applicable_territory: function() {
- if(cur_frm.doc.__islocal && (cur_frm.doc.territories || []).length===0) {
- var default_territory = frappe.defaults.get_user_default("territory");
- if(default_territory) {
- var territory = frappe.model.add_child(cur_frm.doc, "Applicable Territory",
- "territories");
- territory.territory = default_territory;
- }
-
- }
- },
-
setup_serial_no: function() {
var grid_row = cur_frm.open_grid_row();
if(!grid_row.fields_dict.serial_no ||
@@ -131,8 +119,8 @@ $.extend(erpnext.utils, {
}
);
}
- },
-
+ },
+
copy_value_in_all_row: function(doc, dt, dn, table_fieldname, fieldname) {
var d = locals[dt][dn];
if(d[fieldname]){
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.py b/erpnext/setup/page/setup_wizard/setup_wizard.py
index 77ad90a0b7..a1370333ad 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.py
@@ -174,10 +174,7 @@ def create_price_lists(args):
"enabled": 1,
"buying": 1 if pl_type == "Buying" else 0,
"selling": 1 if pl_type == "Selling" else 0,
- "currency": args["currency"],
- "territories": [{
- "territory": get_root_of("Territory")
- }]
+ "currency": args["currency"]
}).insert()
def set_defaults(args):
@@ -304,7 +301,7 @@ def get_fy_details(fy_start_date, fy_end_date):
return fy
def create_taxes(args):
-
+
for i in xrange(1,6):
if args.get("tax_" + str(i)):
# replace % in case someone also enters the % symbol
@@ -324,7 +321,7 @@ def create_taxes(args):
raise
except RootNotEditable, e:
pass
-
+
def make_tax_head(args, i, tax_group, tax_rate):
return frappe.get_doc({
"doctype":"Account",
diff --git a/erpnext/shopping_cart/__init__.py b/erpnext/shopping_cart/__init__.py
index 1858c0d842..db44f94b52 100644
--- a/erpnext/shopping_cart/__init__.py
+++ b/erpnext/shopping_cart/__init__.py
@@ -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()
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 74d9e64436..b6acf20d4e 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -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(),
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
index 4fac3a814d..d8d00efa96 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
@@ -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)
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
index 66be927bcc..10bbcfe85a 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
@@ -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")
diff --git a/erpnext/shopping_cart/test_shopping_cart.py b/erpnext/shopping_cart/test_shopping_cart.py
index dc3b4fe2ab..61536acc87 100644
--- a/erpnext/shopping_cart/test_shopping_cart.py
+++ b/erpnext/shopping_cart/test_shopping_cart.py
@@ -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)
diff --git a/erpnext/stock/doctype/price_list/price_list.js b/erpnext/stock/doctype/price_list/price_list.js
index 54a77732a9..f109633fdd 100644
--- a/erpnext/stock/doctype/price_list/price_list.js
+++ b/erpnext/stock/doctype/price_list/price_list.js
@@ -2,10 +2,6 @@
// License: GNU General Public License v3. See license.txt
$.extend(cur_frm.cscript, {
- onload: function() {
- erpnext.add_applicable_territory();
- },
-
refresh: function() {
cur_frm.add_custom_button(__("Add / Edit Prices"), function() {
frappe.route_options = {
@@ -14,4 +10,4 @@ $.extend(cur_frm.cscript, {
frappe.set_route("Report", "Item Price");
}, "icon-money");
}
-});
\ No newline at end of file
+});
diff --git a/erpnext/stock/doctype/price_list/test_records.json b/erpnext/stock/doctype/price_list/test_records.json
index d91f8872db..ca8a620d23 100644
--- a/erpnext/stock/doctype/price_list/test_records.json
+++ b/erpnext/stock/doctype/price_list/test_records.json
@@ -1,67 +1,34 @@
[
{
- "buying": 1,
- "currency": "INR",
- "doctype": "Price List",
- "enabled": 1,
- "price_list_name": "_Test Price List",
- "selling": 1,
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "All Territories"
- }
- ]
- },
+ "buying": 1,
+ "currency": "INR",
+ "doctype": "Price List",
+ "enabled": 1,
+ "price_list_name": "_Test Price List",
+ "selling": 1
+ },
{
- "buying": 1,
- "currency": "INR",
- "doctype": "Price List",
- "enabled": 1,
- "price_list_name": "_Test Price List 2",
- "selling": 1,
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory Rest Of The World"
- }
- ]
- },
+ "buying": 1,
+ "currency": "INR",
+ "doctype": "Price List",
+ "enabled": 1,
+ "price_list_name": "_Test Price List 2",
+ "selling": 1
+ },
{
- "buying": 1,
- "currency": "INR",
- "doctype": "Price List",
- "enabled": 1,
- "price_list_name": "_Test Price List India",
- "selling": 1,
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory India"
- }
- ]
- },
+ "buying": 1,
+ "currency": "INR",
+ "doctype": "Price List",
+ "enabled": 1,
+ "price_list_name": "_Test Price List India",
+ "selling": 1
+ },
{
- "buying": 1,
- "currency": "USD",
- "doctype": "Price List",
- "enabled": 1,
- "price_list_name": "_Test Price List Rest of the World",
- "selling": 1,
- "territories": [
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory Rest Of The World"
- },
- {
- "doctype": "Applicable Territory",
- "parentfield": "territories",
- "territory": "_Test Territory United States"
- }
- ]
+ "buying": 1,
+ "currency": "USD",
+ "doctype": "Price List",
+ "enabled": 1,
+ "price_list_name": "_Test Price List Rest of the World",
+ "selling": 1
}
-]
\ No newline at end of file
+]
diff --git a/erpnext/templates/pages/user.py b/erpnext/templates/pages/user.py
index c944289661..5ab5545d87 100644
--- a/erpnext/templates/pages/user.py
+++ b/erpnext/templates/pages/user.py
@@ -5,36 +5,31 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cstr
-from erpnext.shopping_cart.cart import get_lead_or_customer
+from erpnext.shopping_cart.cart import get_customer
no_cache = 1
no_sitemap = 1
def get_context(context):
- party = get_lead_or_customer()
- if party.doctype == "Lead":
- mobile_no = party.mobile_no
- phone = party.phone
- else:
- mobile_no, phone = frappe.db.get_value("Contact", {"email_id": frappe.session.user,
- "customer": party.name}, ["mobile_no", "phone"])
-
+ party = get_customer()
+ mobile_no, phone = frappe.db.get_value("Contact", {"email_id": frappe.session.user,
+ "customer": party.name}, ["mobile_no", "phone"])
+
return {
"company_name": cstr(party.customer_name if party.doctype == "Customer" else party.company_name),
"mobile_no": cstr(mobile_no),
"phone": cstr(phone)
}
-
+
@frappe.whitelist()
def update_user(fullname, password=None, company_name=None, mobile_no=None, phone=None):
from erpnext.shopping_cart.cart import update_party
update_party(fullname, company_name, mobile_no, phone)
-
+
if not fullname:
return _("Name is required")
-
+
frappe.db.set_value("User", frappe.session.user, "first_name", fullname)
frappe.local.cookie_manager.set_cookie("full_name", fullname)
-
+
return _("Updated")
-
\ No newline at end of file
From 307978fea956c9bddaf0dc01dc01f0affe7eb71b Mon Sep 17 00:00:00 2001
From: Rushabh Mehta
Date: Wed, 23 Sep 2015 15:43:09 +0530
Subject: [PATCH 7/7] [test-fixes]
---
erpnext/accounts/doctype/tax_rule/tax_rule.py | 6 ++-
erpnext/accounts/party.py | 2 +-
erpnext/shopping_cart/cart.py | 20 +++-------
erpnext/shopping_cart/test_shopping_cart.py | 37 ++++++++++++++-----
4 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py
index 1e306e9eb7..bcbd5595d4 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py
@@ -5,7 +5,6 @@
from __future__ import unicode_literals
import frappe
from frappe import _
-from frappe.model import default_fields
from frappe.model.document import Document
from frappe.utils import cstr
@@ -121,7 +120,10 @@ def get_tax_template(posting_date, args):
conditions = []
for key, value in args.iteritems():
- conditions.append("ifnull({0}, '') in ('', '{1}')".format(key, frappe.db.escape(cstr(value))))
+ if key in "use_for_shopping_cart":
+ conditions.append("use_for_shopping_cart = {0}".format(1 if value else 0))
+ else:
+ conditions.append("ifnull({0}, '') in ('', '{1}')".format(key, frappe.db.escape(cstr(value))))
matching = frappe.db.sql("""select * from `tabTax Rule`
where {0}""".format(" and ".join(conditions)), as_dict = True)
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 9596b44074..baa237e07d 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -280,7 +280,7 @@ def set_taxes(party, party_type, posting_date, company, customer_group=None, sup
billing_address=None, shipping_address=None, use_for_shopping_cart=None):
from erpnext.accounts.doctype.tax_rule.tax_rule import get_tax_template, get_party_details
args = {
- party_type: party,
+ party_type.lower(): party,
"customer_group": customer_group,
"supplier_type": supplier_type,
"company": company
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index b6acf20d4e..c4f3db0395 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -73,10 +73,6 @@ def update_cart(item_code, qty, with_items=False):
qty = flt(qty)
if qty == 0:
quotation.set("items", quotation.get("items", {"item_code": ["!=", item_code]}))
- if not quotation.get("items") and \
- not quotation.get("__islocal"):
- quotation.__delete = True
-
else:
quotation_items = quotation.get("items", {"item_code": item_code})
if not quotation_items:
@@ -90,16 +86,11 @@ def update_cart(item_code, qty, with_items=False):
apply_cart_settings(quotation=quotation)
- if hasattr(quotation, "__delete"):
- frappe.delete_doc("Quotation", quotation.name, ignore_permissions=True)
- quotation = _get_cart_quotation()
- else:
- quotation.flags.ignore_permissions = True
- quotation.save()
+ quotation.flags.ignore_permissions = True
+ quotation.save()
set_cart_count(quotation)
-
if with_items:
context = get_cart_quotation(quotation)
return {
@@ -160,11 +151,12 @@ def _get_cart_quotation(party=None):
if not party:
party = get_customer()
- quotation = frappe.db.get_value("Quotation",
- {party.doctype.lower(): party.name, "order_type": "Shopping Cart", "docstatus": 0})
+ quotation = frappe.get_all("Quotation", fields=["name"], filters=
+ {party.doctype.lower(): party.name, "order_type": "Shopping Cart", "docstatus": 0},
+ order_by="modified desc", limit_page_length=1)
if quotation:
- qdoc = frappe.get_doc("Quotation", quotation)
+ qdoc = frappe.get_doc("Quotation", quotation[0].name)
else:
qdoc = frappe.get_doc({
"doctype": "Quotation",
diff --git a/erpnext/shopping_cart/test_shopping_cart.py b/erpnext/shopping_cart/test_shopping_cart.py
index 61536acc87..41f7442b7c 100644
--- a/erpnext/shopping_cart/test_shopping_cart.py
+++ b/erpnext/shopping_cart/test_shopping_cart.py
@@ -52,11 +52,14 @@ class TestShoppingCart(unittest.TestCase):
# add first item
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
update_cart("_Test Item 2", 1)
quotation = self.test_get_cart_customer()
@@ -86,6 +89,7 @@ class TestShoppingCart(unittest.TestCase):
# remove first item
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)
@@ -149,16 +153,29 @@ class TestShoppingCart(unittest.TestCase):
def enable_shopping_cart(self):
settings = frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings")
- if settings.get("price_lists"):
- settings.enabled = 1
- else:
- settings.update({
- "enabled": 1,
- "company": "_Test Company",
- "default_customer_group": "_Test Customer Group",
- "quotation_series": "_T-Quotation-",
- "price_list": "_Test Price List India"
- })
+ settings.update({
+ "enabled": 1,
+ "company": "_Test Company",
+ "default_customer_group": "_Test Customer Group",
+ "quotation_series": "_T-Quotation-",
+ "price_list": "_Test Price List India"
+ })
+
+ # insert item price
+ if not frappe.db.get_value("Item Price", {"price_list": "_Test Price List India",
+ "item_code": "_Test Item"}):
+ frappe.get_doc({
+ "doctype": "Item Price",
+ "price_list": "_Test Price List India",
+ "item_code": "_Test Item",
+ "price_list_rate": 10
+ }).insert()
+ frappe.get_doc({
+ "doctype": "Item Price",
+ "price_list": "_Test Price List India",
+ "item_code": "_Test Item 2",
+ "price_list_rate": 20
+ }).insert()
settings.save()
frappe.local.shopping_cart_settings = None