Merge pull request #3649 from rmehta/purchase-invoice-fix
[fix] supplier invoice number fix
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index 231c8ab..cdb32dc 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -5,13 +5,6 @@
"doctype": "DocType",
"fields": [
{
- "fieldname": "check_supplier_invoice_uniqueness",
- "fieldtype": "Check",
- "label": "Check Supplier Invoice Number Uniqueness",
- "permlevel": 0,
- "precision": ""
- },
- {
"default": "1",
"description": "If enabled, the system will post accounting entries for inventory automatically.",
"fieldname": "auto_accounting_for_stock",
@@ -45,12 +38,19 @@
"label": "Credit Controller",
"options": "Role",
"permlevel": 0
+ },
+ {
+ "fieldname": "check_supplier_invoice_uniqueness",
+ "fieldtype": "Check",
+ "label": "Check Supplier Invoice Number Uniqueness",
+ "permlevel": 0,
+ "precision": ""
}
],
"icon": "icon-cog",
"idx": 1,
"issingle": 1,
- "modified": "2015-06-11 06:06:34.047890",
+ "modified": "2015-07-14 00:51:48.095525",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
diff --git a/erpnext/change_log/current/paranthesis_in_images.md b/erpnext/change_log/current/paranthesis_in_images.md
new file mode 100644
index 0000000..4859e96
--- /dev/null
+++ b/erpnext/change_log/current/paranthesis_in_images.md
@@ -0,0 +1 @@
+- Display images in website's Item and Item List pages when the filename has paranthesis in its name
diff --git a/erpnext/change_log/current/readme.md b/erpnext/change_log/current/readme.md
new file mode 100644
index 0000000..e93bb75
--- /dev/null
+++ b/erpnext/change_log/current/readme.md
@@ -0,0 +1,3 @@
+Leave change log files in this folder for user release notes.
+
+(this file is just a place holder, don't delete it)
diff --git a/erpnext/change_log/current/shopping_cart.md b/erpnext/change_log/current/shopping_cart.md
new file mode 100644
index 0000000..77a5e5d
--- /dev/null
+++ b/erpnext/change_log/current/shopping_cart.md
@@ -0,0 +1,3 @@
+- Fixed inconsistent visibility of 'Add to Cart' button
+- Use Customer's Price List in Shopping Cart if found
+- Fixed Address creation from Shopping Cart
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index aa55876..8999f85 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -26,22 +26,29 @@
// show tasks
cur_frm.cscript.refresh = function(doc) {
if(!doc.__islocal) {
- cur_frm.add_custom_button(__("Gantt Chart"), function() {
- frappe.route_options = {"project": doc.name, "start": doc.expected_start_date, "end": doc.expected_end_date};
- frappe.set_route("Gantt", "Task");
- }, "icon-tasks", true);
- cur_frm.add_custom_button(__("Tasks"), function() {
- frappe.route_options = {"project": doc.name}
- frappe.set_route("List", "Task");
- }, "icon-list", true);
- cur_frm.add_custom_button(__("Time Logs"), function() {
- frappe.route_options = {"project": doc.name}
- frappe.set_route("List", "Time Log");
- }, "icon-list", true);
- cur_frm.add_custom_button(__("Expense Claims"), function() {
- frappe.route_options = {"project": doc.name}
- frappe.set_route("List", "Expense Claim");
- }, "icon-list", true);
+ if(frappe.model.can_read("Task")) {
+ cur_frm.add_custom_button(__("Gantt Chart"), function() {
+ frappe.route_options = {"project": doc.name, "start": doc.expected_start_date, "end": doc.expected_end_date};
+ frappe.set_route("Gantt", "Task");
+ }, "icon-tasks", true);
+ cur_frm.add_custom_button(__("Tasks"), function() {
+ frappe.route_options = {"project": doc.name}
+ frappe.set_route("List", "Task");
+ }, "icon-list", true);
+ }
+ if(frappe.model.can_read("Time Log")) {
+ cur_frm.add_custom_button(__("Time Logs"), function() {
+ frappe.route_options = {"project": doc.name}
+ frappe.set_route("List", "Time Log");
+ }, "icon-list", true);
+ }
+
+ if(frappe.model.can_read("Expense Claim")) {
+ cur_frm.add_custom_button(__("Expense Claims"), function() {
+ frappe.route_options = {"project": doc.name}
+ frappe.set_route("List", "Expense Claim");
+ }, "icon-list", true);
+ }
}
}
@@ -56,5 +63,5 @@
filters:{
'project_name': doc.name
}
- }
+ }
}
diff --git a/erpnext/projects/doctype/time_log/time_log.js b/erpnext/projects/doctype/time_log/time_log.js
index 536ddf8..776a75b 100644
--- a/erpnext/projects/doctype/time_log/time_log.js
+++ b/erpnext/projects/doctype/time_log/time_log.js
@@ -42,7 +42,7 @@
frappe.ui.form.on("Time Log", "to_time", function(frm) {
if(frm._setting_hours) return;
frm.set_value("hours", moment(cur_frm.doc.to_time).diff(moment(cur_frm.doc.from_time),
- "hours"));
+ "minutes") / 60);
});
@@ -98,5 +98,5 @@
filters:{
'project': doc.project
}
- }
+ }
}
diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py
index 841ef28..136362b 100644
--- a/erpnext/projects/doctype/time_log/time_log.py
+++ b/erpnext/projects/doctype/time_log/time_log.py
@@ -73,18 +73,20 @@
def validate_overlap_for(self, fieldname):
existing = self.get_overlap_for(fieldname)
if existing:
- frappe.throw(_("This Time Log conflicts with {0} for {1}").format(existing.name,
- self.meta.get_label(fieldname)), OverlapError)
+ frappe.throw(_("This Time Log conflicts with {0} for {1} {2}").format(existing.name,
+ self.meta.get_label(fieldname), self.get(fieldname)), OverlapError)
def get_overlap_for(self, fieldname):
if not self.get(fieldname):
return
- existing = frappe.db.sql("""select name, from_time, to_time from `tabTime Log` where `{0}`=%(val)s and
+ existing = frappe.db.sql("""select name, from_time, to_time from `tabTime Log`
+ where `{0}`=%(val)s and
(
- (from_time between %(from_time)s and %(to_time)s) or
- (to_time between %(from_time)s and %(to_time)s) or
- (%(from_time)s between from_time and to_time))
+ (from_time > %(from_time)s and from_time < %(to_time)s) or
+ (to_time > %(from_time)s and to_time < %(to_time)s) or
+ (%(from_time)s > from_time and %(from_time)s < to_time) or
+ (%(from_time)s = from_time and %(to_time)s = to_time))
and name!=%(name)s
and ifnull(task, "")=%(task)s
and docstatus < 2""".format(fieldname),
diff --git a/erpnext/public/js/pos/pos.js b/erpnext/public/js/pos/pos.js
index 70f3023..e28c718 100644
--- a/erpnext/public/js/pos/pos.js
+++ b/erpnext/public/js/pos/pos.js
@@ -401,7 +401,7 @@
this.with_modes_of_payment(function() {
// prefer cash payment!
- var default_mode = me.frm.doc.mode_of_payment ? me.frm.doc.mode_of_payment :
+ var default_mode = me.frm.doc.mode_of_payment ? me.frm.doc.mode_of_payment :
me.modes_of_payment.indexOf(__("Cash"))!==-1 ? __("Cash") : undefined;
// show payment wizard
@@ -450,8 +450,7 @@
if (is_cash && !dialog.get_value("change")) {
// set to nearest 5
- var paid_amount = 5 * Math.ceil(dialog.get_value("total_amount") / 5);
- dialog.set_value("paid_amount", paid_amount);
+ dialog.set_value("paid_amount", dialog.get_value("total_amount"));
dialog.get_input("paid_amount").trigger("change");
}
}).trigger("change");
@@ -487,6 +486,12 @@
});
erpnext.pos.make_pos_btn = function(frm) {
+ frm.page.add_menu_item(__("{0} View", [frm.page.current_view_name === "pos" ? "Form" : "Point-of-Sale"]), function() {
+ erpnext.pos.toggle(frm);
+ });
+
+ if(frm.pos_btn) return;
+
// Show POS button only if it is enabled from features setup
if (cint(sys_defaults.fs_pos_view)!==1 || frm.doctype==="Material Request") {
return;
@@ -494,7 +499,8 @@
if(!frm.pos_btn) {
frm.pos_btn = frm.page.add_action_icon("icon-th", function() {
- erpnext.pos.toggle(frm) });
+ erpnext.pos.toggle(frm);
+ });
}
if(erpnext.open_as_pos && frm.page.current_view_name !== "pos") {
diff --git a/erpnext/setup/doctype/notification_control/notification_control.json b/erpnext/setup/doctype/notification_control/notification_control.json
index f81801d..a77fe67 100644
--- a/erpnext/setup/doctype/notification_control/notification_control.json
+++ b/erpnext/setup/doctype/notification_control/notification_control.json
@@ -176,20 +176,13 @@
"icon": "icon-envelope",
"idx": 1,
"issingle": 1,
- "modified": "2015-03-04 01:13:46.715113",
+ "modified": "2015-07-13 06:24:05.436127",
"modified_by": "Administrator",
"module": "Setup",
"name": "Notification Control",
"owner": "Administrator",
"permissions": [
{
- "create": 0,
- "permlevel": 0,
- "read": 1,
- "role": "Guest",
- "write": 0
- },
- {
"create": 1,
"permlevel": 0,
"read": 1,
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 18bdba6..cfba98b 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -7,6 +7,7 @@
import frappe.defaults
from frappe.utils import cint, flt, get_fullname, fmt_money, cstr
from erpnext.utilities.doctype.address.address import get_address_display
+from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import get_shopping_cart_settings
from frappe.utils.nestedset import get_root_of
class WebsitePriceListMissingError(frappe.ValidationError): pass
@@ -162,7 +163,7 @@
else:
qdoc = frappe.get_doc({
"doctype": "Quotation",
- "naming_series": frappe.defaults.get_user_default("shopping_cart_quotation_series") or "QTN-CART-",
+ "naming_series": get_shopping_cart_settings().quotation_series or "QTN-CART-",
"quotation_to": party.doctype,
"company": frappe.db.get_value("Shopping Cart Settings", None, "company"),
"order_type": "Shopping Cart",
@@ -236,7 +237,9 @@
def set_price_list_and_rate(quotation, cart_settings, billing_territory):
"""set price list based on billing territory"""
- quotation.selling_price_list = cart_settings.get_price_list(billing_territory)
+
+ _set_price_list(quotation, cart_settings, billing_territory)
+
# reset values
quotation.price_list_currency = quotation.currency = \
quotation.plc_conversion_rate = quotation.conversion_rate = None
@@ -249,6 +252,18 @@
# 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):
+ # 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")
+
+ # else check for territory based price list
+ if not selling_price_list:
+ selling_price_list = cart_settings.get_price_list(billing_territory)
+
+ quotation.selling_price_list = selling_price_list
+
def set_taxes(quotation, cart_settings, billing_territory):
"""set taxes based on billing territory"""
quotation.taxes_and_charges = cart_settings.get_tax_master(billing_territory)
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 cdfe0fd..8fbf4a4 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
@@ -23,10 +23,6 @@
self.validate_tax_masters()
self.validate_exchange_rates_exist()
- def on_update(self):
- frappe.db.set_default("shopping_cart_enabled", self.get("enabled") or 0)
- frappe.db.set_default("shopping_cart_quotation_series", self.get("quotation_series"))
-
def validate_overlapping_territories(self, parentfield, fieldname):
# for displaying message
doctype = self.meta.get_field(parentfield).options
diff --git a/erpnext/shopping_cart/product.py b/erpnext/shopping_cart/product.py
index 85faa03..d7795d2 100644
--- a/erpnext/shopping_cart/product.py
+++ b/erpnext/shopping_cart/product.py
@@ -4,19 +4,19 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import cint, fmt_money, cstr
+from frappe.utils import cint, fmt_money
from erpnext.shopping_cart.cart import _get_cart_quotation
-from urllib import unquote
+from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import is_cart_enabled
@frappe.whitelist(allow_guest=True)
def get_product_info(item_code):
"""get product price / stock info"""
- if not cint(frappe.db.get_default("shopping_cart_enabled")):
+ if not is_cart_enabled():
return {}
cart_quotation = _get_cart_quotation()
- price_list = cstr(unquote(frappe.local.request.cookies.get("selling_price_list")))
+ price_list = cart_quotation.selling_price_list
warehouse = frappe.db.get_value("Item", item_code, "website_warehouse")
if warehouse:
diff --git a/erpnext/shopping_cart/utils.py b/erpnext/shopping_cart/utils.py
index 09bfa43..7794a8f 100644
--- a/erpnext/shopping_cart/utils.py
+++ b/erpnext/shopping_cart/utils.py
@@ -9,7 +9,7 @@
from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import is_cart_enabled
def show_cart_count():
- if (frappe.db.get_default("shopping_cart_enabled") and
+ if (is_cart_enabled() and
frappe.db.get_value("User", frappe.session.user, "user_type") == "Website User"):
return True
diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js
index b6f36e6..d5956f9 100644
--- a/erpnext/templates/includes/cart.js
+++ b/erpnext/templates/includes/cart.js
@@ -32,11 +32,11 @@
});
$("#cart-add-shipping-address").on("click", function() {
- window.location.href = "address?address_fieldname=shipping_address_name";
+ window.location.href = "addresses";
});
$("#cart-add-billing-address").on("click", function() {
- window.location.href = "address?address_fieldname=customer_address";
+ window.location.href = "address";
});
$(".btn-place-order").on("click", function() {
diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html
index aa44a17..0967e97 100644
--- a/erpnext/templates/includes/macros.html
+++ b/erpnext/templates/includes/macros.html
@@ -1,6 +1,6 @@
{% macro product_image_square(website_image, css_class="") %}
<div class="product-image product-image-square {% if not website_image -%} missing-image {%- endif %} {{ css_class }}"
- {% if website_image -%} style="background-image: url({{ website_image }});" {%- endif %}>
+ {% if website_image -%} style="background-image: url('{{ frappe.utils.quoted(website_image) }}');" {%- endif %}>
{% if not website_image -%}<i class="centered octicon octicon-device-camera"></i>{%- endif %}
</div>
{% endmacro %}
@@ -8,10 +8,9 @@
{% macro product_image(website_image, css_class="") %}
<div class="product-image {% if not website_image -%} missing-image {%- endif %} {{ css_class }}">
{% if website_image -%}
- <img src="{{ website_image }}" class="img-responsive">
+ <img src="{{ frappe.utils.quoted(website_image) }}" class="img-responsive">
{%- else -%}
<i class="centered octicon octicon-device-camera"></i>
{%- endif %}
</div>
{% endmacro %}
-
diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html
index 2ffdd5e..e4e4a6a 100644
--- a/erpnext/templates/pages/cart.html
+++ b/erpnext/templates/pages/cart.html
@@ -35,14 +35,14 @@
<div id="cart-shipping-address" class="panel-group"
data-fieldname="shipping_address_name"></div>
<button class="btn btn-default" type="button" id="cart-add-shipping-address">
- <span class="icon icon-plus"></span> {{ _("New Shipping Address") }}</button>
+ <span class="icon icon-list"></span> {{ _("Manage Addresses") }}</button>
</div>
<div class="col-md-6">
<h4>Billing Address</h4>
<div id="cart-billing-address" class="panel-group"
data-fieldname="customer_address"></div>
<button class="btn btn-default" type="button" id="cart-add-billing-address">
- <span class="icon icon-plus"></span> {{ _("New Billing Address") }}</button>
+ <span class="icon icon-list"></span> {{ _("Manage Addresses") }}</button>
</div>
</div>
<hr>