Merge pull request #3531 from pdvyas/exchange-rate-api
Change currency exchange rate api to fixer.io
diff --git a/erpnext/__version__.py b/erpnext/__version__.py
index ca621e3..b0b41d3 100644
--- a/erpnext/__version__.py
+++ b/erpnext/__version__.py
@@ -1,2 +1,2 @@
from __future__ import unicode_literals
-__version__ = '5.0.26'
+__version__ = '5.0.29'
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 4e7928d..138cf23 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import flt, fmt_money, getdate, formatdate
+from frappe.utils import flt, fmt_money, getdate, formatdate, cstr
from frappe import _
from frappe.model.document import Document
@@ -118,7 +118,7 @@
bal = flt(frappe.db.sql("""select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
from `tabGL Entry`
where against_voucher_type=%s and against_voucher=%s
- and account = %s and party_type=%s and party=%s""",
+ and account = %s and ifnull(party_type, '')=%s and ifnull(party, '')=%s""",
(against_voucher_type, against_voucher, account, party_type, party))[0][0] or 0.0)
if against_voucher_type == 'Purchase Invoice':
@@ -127,8 +127,9 @@
against_voucher_amount = flt(frappe.db.sql("""
select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
from `tabGL Entry` where voucher_type = 'Journal Entry' and voucher_no = %s
- and account = %s and party_type=%s and party=%s and ifnull(against_voucher, '') = ''""",
- (against_voucher, account, party_type, party))[0][0])
+ and account = %s and ifnull(party_type, '')=%s and ifnull(party, '')=%s
+ and ifnull(against_voucher, '') = ''""",
+ (against_voucher, account, cstr(party_type), cstr(party)))[0][0])
if not against_voucher_amount:
frappe.throw(_("Against Journal Entry {0} is already adjusted against some other voucher")
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.json b/erpnext/accounts/doctype/journal_entry/journal_entry.json
index 6eb395d..249fcc4 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.json
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.json
@@ -53,7 +53,7 @@
"fieldname": "posting_date",
"fieldtype": "Date",
"in_filter": 1,
- "in_list_view": 1,
+ "in_list_view": 0,
"label": "Posting Date",
"no_copy": 1,
"oldfieldname": "posting_date",
@@ -445,7 +445,7 @@
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
- "modified": "2015-04-27 20:32:31.655580",
+ "modified": "2015-06-29 15:28:12.529019",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 753fcc3..7bf6c56 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -274,30 +274,28 @@
r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date)))
else:
msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError)
-
+
+ company_currency = get_company_currency(self.company)
+
for d in self.get('accounts'):
if d.against_invoice and d.credit:
- currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency")
-
- r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = currency), \
+ r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
d.against_invoice))
if d.against_sales_order and d.credit:
- currency = frappe.db.get_value("Sales Order", d.against_sales_order, "currency")
- r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = currency), \
+ r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
d.against_sales_order))
if d.against_voucher and d.debit:
- bill_no = frappe.db.sql("""select bill_no, bill_date, currency
+ bill_no = frappe.db.sql("""select bill_no, bill_date
from `tabPurchase Invoice` where name=%s""", d.against_voucher)
if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \
not in ['na', 'not applicable', 'none']:
- r.append(_('{0} against Bill {1} dated {2}').format(fmt_money(flt(d.debit), currency=bill_no[0][2]), bill_no[0][0],
+ r.append(_('{0} against Bill {1} dated {2}').format(fmt_money(flt(d.debit), currency=company_currency), bill_no[0][0],
bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d'))))
if d.against_purchase_order and d.debit:
- currency = frappe.db.get_value("Purchase Order", d.against_purchase_order, "currency")
- r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = currency), \
+ r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
d.against_purchase_order))
if self.user_remark:
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 3e16a31..d404851 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -224,3 +224,4 @@
else
cur_frm.pformat.print_heading = __("Purchase Invoice");
}
+
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index e192e76..dcbc605 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -926,12 +926,21 @@
"no_copy": 1,
"permlevel": 0,
"print_hide": 1
+ },
+ {
+ "depends_on": "eval:doc.is_recurring==1",
+ "fieldname": "recurring_print_format",
+ "fieldtype": "Link",
+ "label": "Recurring Print Format",
+ "options": "Print Format",
+ "permlevel": 0,
+ "precision": ""
}
],
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
- "modified": "2015-06-16 16:46:47.308287",
+ "modified": "2015-06-22 07:30:06.743438",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 8820c87..660b221 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -88,9 +88,7 @@
throw(_("Conversion rate cannot be 0 or 1"))
def validate_credit_to_acc(self):
- root_type, account_type = frappe.db.get_value("Account", self.credit_to, ["root_type", "account_type"])
- if root_type != "Liability":
- frappe.throw(_("Credit To account must be a liability account"))
+ account_type = frappe.db.get_value("Account", self.credit_to, "account_type")
if account_type != "Payable":
frappe.throw(_("Credit To account must be a Payable account"))
@@ -412,4 +410,4 @@
and tabAccount.company = '%(company)s'
and tabAccount.%(key)s LIKE '%(txt)s'
%(mcond)s""" % {'company': filters['company'], 'key': searchfield,
- 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype)})
+ 'txt': "%%%s%%" % frappe.db.escape(txt), 'mcond':get_match_cond(doctype)})
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 7d5613d..2c5bb12 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -36,7 +36,7 @@
if(locate(%(_name)s, i.item_name), locate(%(_name)s, i.item_name), 99999),
if(locate(%(_name)s, i.variant_of), locate(%(_name)s, i.variant_of), 99999),
if(locate(%(_name)s, i.item_group), locate(%(_name)s, i.item_group), 99999),"""
- args["name"] = "%%%s%%" % item
+ args["name"] = "%%%s%%" % frappe.db.escape(item)
args["_name"] = item.replace("%", "")
# locate function is used to sort by closest match from the beginning of the value
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index b35fa8a..3bb9aa0 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -392,8 +392,6 @@
}
}
-
-
cur_frm.set_query("debit_to", function(doc) {
return{
filters: [
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index a021be4..045678d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -1228,6 +1228,15 @@
"read_only": 0
},
{
+ "depends_on": "eval:doc.is_recurring==1",
+ "fieldname": "recurring_print_format",
+ "fieldtype": "Link",
+ "label": "Recurring Print Format",
+ "options": "Print Format",
+ "permlevel": 0,
+ "precision": ""
+ },
+ {
"fieldname": "against_income_account",
"fieldtype": "Small Text",
"hidden": 1,
@@ -1244,7 +1253,7 @@
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
- "modified": "2015-06-16 16:45:06.618286",
+ "modified": "2015-06-22 06:39:22.072544",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index fe5954e..87f723d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -235,9 +235,7 @@
reconcile_against_document(lst)
def validate_debit_to_acc(self):
- root_type, account_type = frappe.db.get_value("Account", self.debit_to, ["root_type", "account_type"])
- if root_type != "Asset":
- frappe.throw(_("Debit To account must be a liability account"))
+ account_type = frappe.db.get_value("Account", self.debit_to, "account_type")
if account_type != "Receivable":
frappe.throw(_("Debit To account must be a Receivable account"))
@@ -613,7 +611,7 @@
and tabAccount.company = '%(company)s'
and tabAccount.%(key)s LIKE '%(txt)s'
%(mcond)s""" % {'company': filters['company'], 'key': searchfield,
- 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype)})
+ 'txt': "%%%s%%" % frappe.db.escape(txt), 'mcond':get_match_cond(doctype)})
@frappe.whitelist()
def make_delivery_note(source_name, target_doc=None):
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 8fc785c..17fe922 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import flt, cstr
+from frappe.utils import flt, cstr, cint
from frappe import _
from frappe.model.meta import get_field_precision
from erpnext.accounts.utils import validate_expense_against_budget
@@ -82,14 +82,15 @@
gle.submit()
def validate_account_for_auto_accounting_for_stock(gl_map):
- if gl_map[0].voucher_type=="Journal Entry":
- aii_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
- where account_type = 'Warehouse' and ifnull(warehouse, '')!=''""")]
+ if cint(frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock")) \
+ and gl_map[0].voucher_type=="Journal Entry":
+ aii_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
+ where account_type = 'Warehouse' and ifnull(warehouse, '')!=''""")]
- for entry in gl_map:
- if entry.account in aii_accounts:
- frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
- .format(entry.account), StockAccountInvalidTransaction)
+ for entry in gl_map:
+ if entry.account in aii_accounts:
+ frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
+ .format(entry.account), StockAccountInvalidTransaction)
def round_off_debit_credit(gl_map):
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index dc1dfa4..f65ba40 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -868,12 +868,21 @@
"no_copy": 1,
"permlevel": 0,
"print_hide": 1
+ },
+ {
+ "depends_on": "eval:doc.is_recurring==1",
+ "fieldname": "recurring_print_format",
+ "fieldtype": "Link",
+ "label": "Recurring Print Format",
+ "options": "Print Format",
+ "permlevel": 0,
+ "precision": ""
}
],
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
- "modified": "2015-06-15 15:38:56.794601",
+ "modified": "2015-06-22 07:30:36.259753",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",
diff --git a/erpnext/change_log/v5/v5_0_28.md b/erpnext/change_log/v5/v5_0_28.md
new file mode 100644
index 0000000..6ad54e6
--- /dev/null
+++ b/erpnext/change_log/v5/v5_0_28.md
@@ -0,0 +1 @@
+- Open notification of Sales Order and Purchase Order based on whether Invoice is created against them. For eg. If a Sales Order is not Invoiced, it will be considered as open. Previously it was considered open if Delivery Note was created against Sales Order.
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 898dd23..4f35fea 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -194,7 +194,7 @@
and tabBOM.is_active=1
and tabBOM.%(key)s like "%(txt)s"
%(fcond)s %(mcond)s
- limit %(start)s, %(page_len)s """ % {'key': searchfield, 'txt': "%%%s%%" % txt,
+ limit %(start)s, %(page_len)s """ % {'key': searchfield, 'txt': "%%%s%%" % frappe.db.escape(txt),
'fcond': get_filters_cond(doctype, filters, conditions),
'mcond':get_match_cond(doctype), 'start': start, 'page_len': page_len})
@@ -207,7 +207,7 @@
where `tabProject`.status not in ("Completed", "Cancelled")
and %(cond)s `tabProject`.name like "%(txt)s" %(mcond)s
order by `tabProject`.name asc
- limit %(start)s, %(page_len)s """ % {'cond': cond,'txt': "%%%s%%" % txt,
+ limit %(start)s, %(page_len)s """ % {'cond': cond,'txt': "%%%s%%" % frappe.db.escape(txt),
'mcond':get_match_cond(doctype),'start': start, 'page_len': page_len})
def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, filters):
diff --git a/erpnext/controllers/recurring_document.py b/erpnext/controllers/recurring_document.py
index a46fa32..8c8af23 100644
--- a/erpnext/controllers/recurring_document.py
+++ b/erpnext/controllers/recurring_document.py
@@ -124,7 +124,7 @@
frappe.sendmail(new_rv.notification_email_address,
subject= _("New {0}: #{1}").format(new_rv.doctype, new_rv.name),
message = _("Please find attached {0} #{1}").format(new_rv.doctype, new_rv.name),
- attachments = [frappe.attach_print(new_rv.doctype, new_rv.name, file_name=new_rv.name)])
+ attachments = [frappe.attach_print(new_rv.doctype, new_rv.name, file_name=new_rv.name, print_format=new_rv.recurring_print_format)])
def notify_errors(doc, doctype, party, owner):
from frappe.utils.user import get_system_managers
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index b523416..12de2e5 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -75,8 +75,7 @@
return frappe.db.get_value("Customer", {"lead_name": self.name})
def has_opportunity(self):
- return frappe.db.get_value("Opportunity", {"lead": self.name, "docstatus": 1,
- "status": ["!=", "Lost"]})
+ return frappe.db.get_value("Opportunity", {"lead": self.name, "status": ["!=", "Lost"]})
@frappe.whitelist()
def make_customer(source_name, target_doc=None):
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index d36f269..d9262d4 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -5,7 +5,7 @@
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th"
app_color = "#e74c3c"
-app_version = "5.0.26"
+app_version = "5.0.29"
error_report_email = "support@erpnext.com"
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index c75c2bd..44fb6fd 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -339,6 +339,7 @@
events.append({
"doctype": "Leave Block List Date",
"from_date": block_date.block_date,
+ "to_date": block_date.block_date,
"title": _("Leave Blocked") + ": " + block_date.reason,
"name": "_" + str(cnt),
})
@@ -355,6 +356,7 @@
events.append({
"doctype": "Holiday",
"from_date": holiday.holiday_date,
+ "to_date": holiday.holiday_date,
"title": _("Holiday") + ": " + cstr(holiday.description),
"name": holiday.name
})
diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json
index 239df47..67e2b78 100644
--- a/erpnext/manufacturing/doctype/bom/bom.json
+++ b/erpnext/manufacturing/doctype/bom/bom.json
@@ -12,7 +12,7 @@
"fieldname": "item",
"fieldtype": "Link",
"in_filter": 1,
- "in_list_view": 0,
+ "in_list_view": 1,
"label": "Item",
"oldfieldname": "item",
"oldfieldtype": "Link",
@@ -54,7 +54,7 @@
"fieldname": "is_active",
"fieldtype": "Check",
"hidden": 0,
- "in_list_view": 0,
+ "in_list_view": 1,
"label": "Is Active",
"no_copy": 1,
"oldfieldname": "is_active",
@@ -67,7 +67,7 @@
"default": "1",
"fieldname": "is_default",
"fieldtype": "Check",
- "in_list_view": 0,
+ "in_list_view": 1,
"label": "Is Default",
"no_copy": 1,
"oldfieldname": "is_default",
@@ -279,7 +279,7 @@
"is_submittable": 1,
"issingle": 0,
"istable": 0,
- "modified": "2015-03-03 14:22:44.725097",
+ "modified": "2015-06-26 02:02:30.705279",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM",
diff --git a/erpnext/patches/v5_0/update_frozen_accounts_permission_role.py b/erpnext/patches/v5_0/update_frozen_accounts_permission_role.py
index 2f85513..14426f5 100644
--- a/erpnext/patches/v5_0/update_frozen_accounts_permission_role.py
+++ b/erpnext/patches/v5_0/update_frozen_accounts_permission_role.py
@@ -7,6 +7,6 @@
account_settings = frappe.get_doc("Accounts Settings")
if not account_settings.frozen_accounts_modifier and account_settings.bde_auth_role:
- frappe.db.set_value("Account Settings", None,
+ frappe.db.set_value("Accounts Settings", None,
"frozen_accounts_modifier", account_settings.bde_auth_role)
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 42717fd..f5541cc 100644
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -141,7 +141,7 @@
%(mcond)s
order by name
limit %(start)s, %(page_len)s """ % {'key': searchfield,
- 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype),
+ 'txt': "%%%s%%" % frappe.db.escape(txt), 'mcond':get_match_cond(doctype),
'start': start, 'page_len': page_len})
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index ca0a6cb..91601a4 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -37,6 +37,16 @@
if(this.frm.fields_dict["items"]) {
this["items_remove"] = this.calculate_taxes_and_totals;
}
+
+ if(this.frm.fields_dict["recurring_print_format"]) {
+ this.frm.set_query("recurring_print_format", function(doc) {
+ return{
+ filters: [
+ ['Print Format', 'doc_type', '=', cur_frm.doctype],
+ ]
+ }
+ });
+ }
},
onload_post_render: function() {
@@ -782,3 +792,5 @@
cur_frm.cscript.set_dynamic_labels();
cur_frm.cscript.calculate_taxes_and_totals();
})
+
+
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 7ede9d4..7f0b386 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -183,5 +183,3 @@
cur_frm.email_doc(frappe.boot.notification_settings.sales_order_message);
}
};
-
-;
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index ad62d57..59f54fb 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -1074,13 +1074,22 @@
"no_copy": 1,
"permlevel": 0,
"print_hide": 1
+ },
+ {
+ "depends_on": "eval:doc.is_recurring==1",
+ "fieldname": "recurring_print_format",
+ "fieldtype": "Link",
+ "label": "Recurring Print Format",
+ "options": "Print Format",
+ "permlevel": 0,
+ "precision": ""
}
],
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
"issingle": 0,
- "modified": "2015-06-15 15:36:38.898462",
+ "modified": "2015-06-22 07:29:24.379272",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",
diff --git a/erpnext/selling/page/sales_browser/sales_browser.js b/erpnext/selling/page/sales_browser/sales_browser.js
index 3b9e25a..98d34be 100644
--- a/erpnext/selling/page/sales_browser/sales_browser.js
+++ b/erpnext/selling/page/sales_browser/sales_browser.js
@@ -122,7 +122,7 @@
if(me.ctype == "Sales Person") {
fields.splice(-1, 0, {fieldtype:'Link', fieldname:'employee', label:__('Employee'),
- options:'Employee', description: __("Please enter Employee Id of this sales parson")});
+ options:'Employee', description: __("Please enter Employee Id of this sales person")});
}
// the dialog
diff --git a/erpnext/startup/notifications.py b/erpnext/startup/notifications.py
index e847cfa..4190f2d 100644
--- a/erpnext/startup/notifications.py
+++ b/erpnext/startup/notifications.py
@@ -14,7 +14,7 @@
"Contact": {"status": "Open"},
"Opportunity": {"status": "Open"},
"Quotation": {"docstatus": 0},
- "Sales Order": { "per_delivered": ("<", 100), "status": ("!=", "Stopped"), "docstatus": ("<", 2) },
+ "Sales Order": { "per_billed": ("<", 100), "status": ("!=", "Stopped"), "docstatus": ("<", 2) },
"Journal Entry": {"docstatus": 0},
"Sales Invoice": { "outstanding_amount": (">", 0), "docstatus": ("<", 2) },
"Purchase Invoice": {"docstatus": 0},
@@ -25,7 +25,7 @@
"Delivery Note": {"docstatus": 0},
"Stock Entry": {"docstatus": 0},
"Material Request": {"docstatus": 0},
- "Purchase Order": { "per_received": ("<", 100), "status": ("!=", "Stopped"), "docstatus": ("<", 2) },
+ "Purchase Order": { "per_billed": ("<", 100), "status": ("!=", "Stopped"), "docstatus": ("<", 2) },
"Production Order": { "status": "In Process" },
"BOM": {"docstatus": 0},
"Timesheet": {"docstatus": 0},
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 6659da5..8b10319 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -707,7 +707,7 @@
"fieldtype": "Link",
"ignore_user_permissions": 1,
"label": "Default BOM",
- "no_copy": 0,
+ "no_copy": 1,
"oldfieldname": "default_bom",
"oldfieldtype": "Link",
"options": "BOM",
@@ -879,7 +879,7 @@
"icon": "icon-tag",
"idx": 1,
"max_attachments": 1,
- "modified": "2015-05-22 02:16:57.435105",
+ "modified": "2015-06-26 17:20:18.204558",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 0b0246e..bac5441 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -180,7 +180,7 @@
where fieldname='serial_no' and fieldtype='Text'"""):
for item in frappe.db.sql("""select name, serial_no from `tab%s`
- where serial_no like '%%%s%%'""" % (dt[0], old)):
+ where serial_no like '%%%s%%'""" % (dt[0], frappe.db.escape(old))):
serial_nos = map(lambda i: i==old and new or i, item[1].split('\n'))
frappe.db.sql("""update `tab%s` set serial_no = %s
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index d823e7e..813a61b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -5,7 +5,7 @@
import frappe
import frappe.defaults
-from frappe.utils import cstr, cint, flt, comma_or, get_datetime
+from frappe.utils import cstr, cint, flt, comma_or, get_datetime, getdate
from frappe import _
from erpnext.stock.utils import get_incoming_rate
@@ -66,6 +66,7 @@
self.validate_valuation_rate()
self.set_total_incoming_outgoing_value()
self.set_total_amount()
+ self.validate_batch()
def on_submit(self):
self.update_stock_ledger()
@@ -359,8 +360,11 @@
if self.purpose == "Subcontract" and self.purchase_order:
purchase_order = frappe.get_doc("Purchase Order", self.purchase_order)
for se_item in self.items:
- total_allowed = [d.required_qty for d in purchase_order.supplied_items \
- if d.rm_item_code == se_item.item_code][0]
+ total_allowed = sum([flt(d.required_qty) for d in purchase_order.supplied_items \
+ if d.rm_item_code == se_item.item_code])
+ if not total_allowed:
+ frappe.throw(_("Item {0} not found in 'Raw Materials Supplied' table in Purchase Order {1}")
+ .format(se_item.item_code, self.purchase_order))
total_supplied = frappe.db.sql("""select sum(qty)
from `tabStock Entry Detail`, `tabStock Entry`
where `tabStock Entry`.purchase_order = %s
@@ -721,6 +725,13 @@
mreq_item.warehouse != (item.s_warehouse if self.purpose== "Material Issue" else item.t_warehouse):
frappe.throw(_("Item or Warehouse for row {0} does not match Material Request").format(item.idx),
frappe.MappingMismatchError)
+
+ def validate_batch(self):
+ if self.purpose == "Material Transfer for Manufacture":
+ for item in self.get("items"):
+ if item.batch_no:
+ if getdate(self.posting_date) > getdate(frappe.db.get_value("Batch", item.batch_no, "expiry_date")):
+ frappe.throw(_("Batch {0} of Item {1} has expired.").format(item.batch_no, item.item_code))
@frappe.whitelist()
def get_party_details(ref_dt, ref_dn):
diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
index d911975..69e1321 100644
--- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
+++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
@@ -54,7 +54,7 @@
return frappe.db.sql("""select item_code, batch_no, warehouse,
posting_date, actual_qty
from `tabStock Ledger Entry`
- where docstatus < 2 %s order by item_code, warehouse""" %
+ where docstatus < 2 and ifnull(batch_no, '') != '' %s order by item_code, warehouse""" %
conditions, as_dict=1)
def get_item_warehouse_batch_map(filters, float_precision):
diff --git a/erpnext/templates/includes/issue_row.html b/erpnext/templates/includes/issue_row.html
index 30b2ab0..16a8f7b 100644
--- a/erpnext/templates/includes/issue_row.html
+++ b/erpnext/templates/includes/issue_row.html
@@ -1,6 +1,6 @@
<div class="web-list-item">
<div class="row">
- <div class="col-sm-8">
+ <div class="col-sm-6">
<a class="no-decoration" href="/issues?name={{ doc.name }}" no-pjax>
{{ doc.subject }}
</a>
@@ -9,6 +9,11 @@
<span class="indicator {{ "red" if doc.status=="Open" else "blue" }}">
{{ doc.status }}</span>
</div>
+ <div class="col-sm-2">
+ <a class="text-muted text-right" href="/issues?name={{ doc.name }}" no-pjax>
+ {{ doc.name }}
+ </a>
+ </div>
<div class="col-sm-2 text-muted text-right small">
{{ frappe.format_date(doc.creation) }}
</div>
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index 60889c5..be74aeb 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -22,16 +22,21 @@
self.posting_time = now_datetime().strftime('%H:%M:%S')
def add_calendar_event(self, opts, force=False):
- if self.contact_by != cstr(self._prev.contact_by) or \
- self.contact_date != cstr(self._prev.contact_date) or force:
+ if cstr(self.contact_by) != cstr(self._prev.contact_by) or \
+ cstr(self.contact_date) != cstr(self._prev.contact_date) or force:
self.delete_events()
self._add_calendar_event(opts)
def delete_events(self):
- frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent`
- where ref_type=%s and ref_name=%s""", (self.doctype, self.name)),
- ignore_permissions=True)
+ events = frappe.db.sql_list("""select name from `tabEvent`
+ where ref_type=%s and ref_name=%s""", (self.doctype, self.name))
+ if events:
+ frappe.db.sql("delete from `tabEvent` where name in (%s)"
+ .format(", ".join(['%s']*len(events))), tuple(events))
+
+ frappe.db.sql("delete from `tabEvent Role` where parent in (%s)"
+ .format(", ".join(['%s']*len(events))), tuple(events))
def _add_calendar_event(self, opts):
opts = frappe._dict(opts)
diff --git a/setup.py b/setup.py
index 2cba2e8..ea74fa8 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
-version = "5.0.26"
+version = "5.0.29"
with open("requirements.txt", "r") as f:
install_requires = f.readlines()