diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 32f1e01fcf1..6c8d7c89ec3 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.0.21' +__version__ = '10.0.22' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index de0b6f5add0..26cc59892f1 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -8,6 +8,10 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ setup: function(doc) { this.setup_posting_date_time_check(); this._super(doc); + + // formatter for material request item + this.frm.set_indicator_formatter('item_code', + function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" }) }, onload: function() { this._super(); @@ -20,10 +24,6 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ } else { this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total)); } - - // formatter for material request item - this.frm.set_indicator_formatter('item_code', - function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" }) }, refresh: function(doc) { diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 65bd07e828f..29beda0e8c2 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -410,6 +410,21 @@ def get_pdc_details(party_type): group by pref.reference_name""", party_type, as_dict=1): pdc_details.setdefault(pdc.invoice_no, pdc) + for pdc in frappe.db.sql(""" + select + jea.reference_name as invoice_no, jea.party, jea.party_type, + max(je.cheque_date) as pdc_date, sum(ifnull(je.total_amount,0)) as pdc_amount, + GROUP_CONCAT(je.cheque_no SEPARATOR ', ') as pdc_ref + from + `tabJournal Entry` as je inner join `tabJournal Entry Account` as jea + on + (jea.parent = je.name) + where + je.docstatus = 0 and je.cheque_date > je.posting_date + and jea.party_type = %s + group by jea.reference_name""", party_type, as_dict=1): + pdc_details.setdefault(pdc.invoice_no, pdc) + return pdc_details def get_dn_details(party_type): diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 51cec6921b5..d500081b396 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -12,7 +12,7 @@ frappe.ui.form.on("Purchase Order", { 'Purchase Invoice': 'Invoice', 'Stock Entry': 'Material to Supplier' } - + frm.set_query("reserve_warehouse", "supplied_items", function() { return { filters: { @@ -21,6 +21,9 @@ frappe.ui.form.on("Purchase Order", { } } }); + + frm.set_indicator_formatter('item_code', + function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" }) }, onload: function(frm) { @@ -34,9 +37,6 @@ frappe.ui.form.on("Purchase Order", { frm.toggle_display('get_last_purchase_rate', frm.doc.__onload.disable_fetch_last_purchase_rate); } - - frm.set_indicator_formatter('item_code', - function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" }) }, }); diff --git a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.js b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.js index a3a14147f2d..e7a704a28af 100644 --- a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.js +++ b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.js @@ -4,14 +4,14 @@ /* global frappe, refresh_field */ frappe.ui.form.on("Supplier Scorecard", { - - onload: function(frm) { - + setup: function(frm) { if (frm.doc.indicator_color !== "") { frm.set_indicator_formatter("status", function(doc) { return doc.indicator_color.toLowerCase(); }); } + }, + onload: function(frm) { if (frm.doc.__unsaved == 1) { loadAllCriteria(frm); loadAllStandings(frm); diff --git a/erpnext/config/education.py b/erpnext/config/education.py index 08846a202a7..e4e77f36d60 100644 --- a/erpnext/config/education.py +++ b/erpnext/config/education.py @@ -21,18 +21,7 @@ def get_data(): { "type": "doctype", "name": "Student Group" - }, - { - "type": "doctype", - "name": "Student Group Creation Tool" - }, - { - "type": "report", - "is_query_report": True, - "name": "Student and Guardian Contact Details", - "doctype": "Program Enrollment" } - ] }, { @@ -50,10 +39,6 @@ def get_data(): { "type": "doctype", "name": "Program Enrollment" - }, - { - "type": "doctype", - "name": "Program Enrollment Tool" } ] }, @@ -68,10 +53,6 @@ def get_data(): "type": "doctype", "name": "Student Leave Application" }, - { - "type": "doctype", - "name": "Student Attendance Tool" - }, { "type": "report", "is_query_report": True, @@ -84,21 +65,26 @@ def get_data(): "name": "Student Batch-Wise Attendance", "doctype": "Student Attendance" }, - { - "type": "report", - "is_query_report": True, - "name": "Student Monthly Attendance Sheet", - "doctype": "Student Attendance" - } ] }, { - "label": _("Schedule"), + "label": _("Tools"), "items": [ { "type": "doctype", - "name": "Course Schedule", - "route": "List/Course Schedule/Calendar" + "name": "Student Attendance Tool" + }, + { + "type": "doctype", + "name": "Assessment Result Tool" + }, + { + "type": "doctype", + "name": "Student Group Creation Tool" + }, + { + "type": "doctype", + "name": "Program Enrollment Tool" }, { "type": "doctype", @@ -125,28 +111,30 @@ def get_data(): { "type": "doctype", "name": "Assessment Criteria" - }, - { - "type": "doctype", - "name": "Assessment Criteria Group" - }, - { - "type": "doctype", - "name": "Assessment Result Tool" - }, + } + ] + }, + { + "label": _("Assessment Reports"), + "items": [ { "type": "report", "is_query_report": True, "name": "Course wise Assessment Report", "doctype": "Assessment Result" }, + { + "type": "report", + "is_query_report": True, + "name": "Final Assessment Grades", + "doctype": "Assessment Result" + }, { "type": "report", "is_query_report": True, "name": "Assessment Plan Status", "doctype": "Assessment Plan" }, - ] }, { @@ -167,17 +155,25 @@ def get_data(): { "type": "doctype", "name": "Fee Category" - }, - { - "type": "report", - "name": "Student Fee Collection", - "doctype": "Fees", - "is_query_report": True } ] }, { - "label": _("Setup"), + "label": _("Schedule"), + "items": [ + { + "type": "doctype", + "name": "Course Schedule", + "route": "List/Course Schedule/Calendar" + }, + { + "type": "doctype", + "name": "Course Scheduling Tool" + } + ] + }, + { + "label": _("Masters"), "items": [ { "type": "doctype", @@ -194,7 +190,12 @@ def get_data(): { "type": "doctype", "name": "Room" - }, + } + ] + }, + { + "label": _("Setup"), + "items": [ { "type": "doctype", "name": "Student Category" @@ -221,4 +222,27 @@ def get_data(): } ] }, + { + "label": _("Other Reports"), + "items": [ + { + "type": "report", + "is_query_report": True, + "name": "Student and Guardian Contact Details", + "doctype": "Program Enrollment" + }, + { + "type": "report", + "is_query_report": True, + "name": "Student Monthly Attendance Sheet", + "doctype": "Student Attendance" + }, + { + "type": "report", + "name": "Student Fee Collection", + "doctype": "Fees", + "is_query_report": True + } + ] + } ] diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index a64e76fdcac..6b18b826bd5 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -150,13 +150,16 @@ class SellingController(StockController): if not frappe.db.get_single_value("Selling Settings", "validate_selling_price"): return + if hasattr(self, "is_return") and self.is_return: + return + for it in self.get("items"): if not it.item_code: continue last_purchase_rate, is_stock_item = frappe.db.get_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"]) last_purchase_rate_in_sales_uom = last_purchase_rate / (it.conversion_factor or 1) - if flt(it.base_rate) < flt(last_purchase_rate_in_sales_uom) and not self.is_return: + if flt(it.base_rate) < flt(last_purchase_rate_in_sales_uom): throw_message(it.item_name, last_purchase_rate_in_sales_uom, "last purchase rate") last_valuation_rate = frappe.db.sql(""" @@ -166,7 +169,7 @@ class SellingController(StockController): """, (it.item_code, it.warehouse)) if last_valuation_rate: last_valuation_rate_in_sales_uom = last_valuation_rate[0][0] / (it.conversion_factor or 1) - if is_stock_item and flt(it.base_rate) < flt(last_valuation_rate_in_sales_uom) and not self.is_return: + if is_stock_item and flt(it.base_rate) < flt(last_valuation_rate_in_sales_uom): throw_message(it.name, last_valuation_rate_in_sales_uom, "valuation rate") diff --git a/erpnext/demo/data/drug_list.json b/erpnext/demo/data/drug_list.json index 51b029c1dd7..f34ca572d23 100644 --- a/erpnext/demo/data/drug_list.json +++ b/erpnext/demo/data/drug_list.json @@ -65,7 +65,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -151,7 +150,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -237,7 +235,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -323,7 +320,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -409,7 +405,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -495,7 +490,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -581,7 +575,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -667,7 +660,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -753,7 +745,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -839,7 +830,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -925,7 +915,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1011,7 +1000,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1097,7 +1085,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1183,7 +1170,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1269,7 +1255,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1355,7 +1340,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1441,7 +1425,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1527,7 +1510,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1613,7 +1595,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1699,7 +1680,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1785,7 +1765,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1871,7 +1850,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -1957,7 +1935,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2043,7 +2020,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2129,7 +2105,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2215,7 +2190,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2301,7 +2275,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2387,7 +2360,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2473,7 +2445,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2559,7 +2530,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2645,7 +2615,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2731,7 +2700,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2817,7 +2785,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2903,7 +2870,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -2989,7 +2955,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3075,7 +3040,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3161,7 +3125,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3247,7 +3210,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3333,7 +3295,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3419,7 +3380,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3505,7 +3465,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3591,7 +3550,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3677,7 +3635,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3763,7 +3720,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3849,7 +3805,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -3935,7 +3890,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4021,7 +3975,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4107,7 +4060,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4193,7 +4145,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4279,7 +4230,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4365,7 +4315,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4451,7 +4400,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4537,7 +4485,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4623,7 +4570,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4709,7 +4655,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4795,7 +4740,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4881,7 +4825,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -4967,7 +4910,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -5053,7 +4995,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -5139,7 +5080,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -5225,7 +5165,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -5311,7 +5250,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, @@ -5397,7 +5335,6 @@ "taxes": [], "thumbnail": null, "tolerance": 0.0, - "total_projected_qty": 0.0, "uoms": [ { "conversion_factor": 1.0, diff --git a/erpnext/education/doctype/fees/fees.json b/erpnext/education/doctype/fees/fees.json index c4e1f82f02f..971197cdbdb 100644 --- a/erpnext/education/doctype/fees/fees.json +++ b/erpnext/education/doctype/fees/fees.json @@ -4,7 +4,7 @@ "allow_import": 1, "allow_rename": 0, "autoname": "naming_series:", - "beta": 1, + "beta": 0, "creation": "2015-09-22 16:57:22.143710", "custom": 0, "docstatus": 0, @@ -1276,7 +1276,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-12-06 05:55:10.502567", + "modified": "2018-02-08 02:12:34.185245", "modified_by": "Administrator", "module": "Education", "name": "Fees", diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.json b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.json index e153f8c55b5..61976b4508b 100644 --- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.json +++ b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.json @@ -7,7 +7,7 @@ "doctype": "Report", "idx": 0, "is_standard": "Yes", - "modified": "2017-11-10 19:41:46.641227", + "modified": "2018-02-08 15:11:24.904628", "modified_by": "Administrator", "module": "Education", "name": "Course wise Assessment Report", @@ -17,7 +17,10 @@ "report_type": "Script Report", "roles": [ { - "role": "Academics User" + "role": "Instructor" + }, + { + "role": "Education Manager" } ] } \ No newline at end of file diff --git a/erpnext/education/report/final_assessment_grades/final_assessment_grades.json b/erpnext/education/report/final_assessment_grades/final_assessment_grades.json index 1efbb6e66df..e748efa8a4b 100644 --- a/erpnext/education/report/final_assessment_grades/final_assessment_grades.json +++ b/erpnext/education/report/final_assessment_grades/final_assessment_grades.json @@ -8,7 +8,7 @@ "idx": 0, "is_standard": "Yes", "letter_head": "Shishuvan Secondary School", - "modified": "2018-01-22 17:04:43.412054", + "modified": "2018-02-08 15:11:35.339434", "modified_by": "Administrator", "module": "Education", "name": "Final Assessment Grades", @@ -16,5 +16,12 @@ "ref_doctype": "Assessment Result", "report_name": "Final Assessment Grades", "report_type": "Script Report", - "roles": [] + "roles": [ + { + "role": "Instructor" + }, + { + "role": "Education Manager" + } + ] } \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_loan/employee_loan.py b/erpnext/hr/doctype/employee_loan/employee_loan.py index dadd7694bd4..17518355386 100644 --- a/erpnext/hr/doctype/employee_loan/employee_loan.py +++ b/erpnext/hr/doctype/employee_loan/employee_loan.py @@ -135,7 +135,7 @@ def get_employee_loan_application(employee_loan_application): return employee_loan.as_dict() @frappe.whitelist() -def make_jv_entry(employee_loan, company, employee_loan_account, employee, loan_amount, payment_account): +def make_jv_entry(employee_loan, company, employee_loan_account, employee, loan_amount, payment_account=None): journal_entry = frappe.new_doc('Journal Entry') journal_entry.voucher_type = 'Bank Entry' journal_entry.user_remark = _('Against Employee Loan: {0}').format(employee_loan) diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.py b/erpnext/hr/doctype/payroll_entry/payroll_entry.py index 77cece3cfe8..2a5b467845d 100644 --- a/erpnext/hr/doctype/payroll_entry/payroll_entry.py +++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.py @@ -252,7 +252,7 @@ class PayrollEntry(Document): journal_entry.user_remark = _('Accural Journal Entry for salaries from {0} to {1}')\ .format(self.start_date, self.end_date) journal_entry.company = self.company - journal_entry.posting_date = nowdate() + journal_entry.posting_date = self.posting_date accounts = [] payable_amount = 0 diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js index 8a86668fcd7..bba3e1ed6d5 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.js +++ b/erpnext/manufacturing/doctype/production_order/production_order.js @@ -79,6 +79,10 @@ frappe.ui.form.on("Production Order", { ] } }); + + // formatter for production order operation + frm.set_indicator_formatter('operation', + function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange" }); }, onload: function(frm) { @@ -94,10 +98,6 @@ frappe.ui.form.on("Production Order", { }); erpnext.production_order.set_default_warehouse(frm); } - - // formatter for production order operation - frm.set_indicator_formatter('operation', - function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange" }); }, refresh: function(frm) { diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py index 002f03b9201..76124615357 100644 --- a/erpnext/manufacturing/doctype/production_order/test_production_order.py +++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py @@ -10,7 +10,6 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_per from erpnext.manufacturing.doctype.production_order.production_order \ import make_stock_entry, ItemHasVariantError, stop_unstop from erpnext.stock.doctype.stock_entry import test_stock_entry -from erpnext.stock.doctype.item.test_item import get_total_projected_qty from erpnext.stock.utils import get_bin from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order @@ -81,7 +80,7 @@ class TestProductionOrder(unittest.TestCase): prod_order.set_production_order_operations() prod_order.insert() prod_order.submit() - + d = prod_order.operations[0] d.completed_qty = flt(d.completed_qty) @@ -89,7 +88,7 @@ class TestProductionOrder(unittest.TestCase): time_sheet_doc = frappe.get_doc('Timesheet', name) self.assertEqual(prod_order.company, time_sheet_doc.company) time_sheet_doc.submit() - + self.assertEqual(prod_order.name, time_sheet_doc.production_order) self.assertEqual((prod_order.qty - d.completed_qty), @@ -108,7 +107,7 @@ class TestProductionOrder(unittest.TestCase): self.assertEqual(prod_order.operations[0].actual_operation_time, 60) self.assertEqual(prod_order.operations[0].actual_operating_cost, 6000) - + time_sheet_doc1 = make_timesheet(prod_order.name, prod_order.company) self.assertEqual(len(time_sheet_doc1.get('time_logs')), 0) @@ -176,28 +175,6 @@ class TestProductionOrder(unittest.TestCase): self.assertEqual(self.bin1_at_start.projected_qty, cint(bin1_on_cancel.projected_qty)) - def test_projected_qty_for_production_and_sales_order(self): - before_production_order = get_bin(self.item, self.warehouse) - before_production_order.update_reserved_qty_for_production() - - self.pro_order = make_prod_order_test_record(item="_Test FG Item", qty=2, - source_warehouse=self.warehouse) - - after_production_order = get_bin(self.item, self.warehouse) - - sales_order = make_sales_order(item = self.item, qty = 2) - after_sales_order = get_bin(self.item, self.warehouse) - - self.assertEqual(cint(before_production_order.reserved_qty_for_production) + 2, - cint(after_sales_order.reserved_qty_for_production)) - self.assertEqual(cint(before_production_order.projected_qty), - cint(after_sales_order.projected_qty) + 2) - - total_projected_qty = get_total_projected_qty(self.item) - - item_doc = frappe.get_doc('Item', self.item) - self.assertEqual(total_projected_qty, item_doc.total_projected_qty) - def test_reserved_qty_for_production_on_stock_entry(self): test_stock_entry.make_stock_entry(item_code="_Test Item", target= self.warehouse, qty=100, basic_rate=100) @@ -230,7 +207,7 @@ class TestProductionOrder(unittest.TestCase): cint(bin1_on_start_production.reserved_qty_for_production)) self.assertEqual(cint(bin1_on_end_production.projected_qty), cint(bin1_on_end_production.projected_qty)) - + def test_reserved_qty_for_stopped_production(self): test_stock_entry.make_stock_entry(item_code="_Test Item", target= self.warehouse, qty=100, basic_rate=100) @@ -238,18 +215,18 @@ class TestProductionOrder(unittest.TestCase): target= self.warehouse, qty=100, basic_rate=100) # 0 0 0 - + self.test_reserved_qty_for_production_submit() - + #2 0 -2 s = frappe.get_doc(make_stock_entry(self.pro_order.name, "Material Transfer for Manufacture", 1)) s.submit() - + #1 -1 0 - + bin1_on_start_production = get_bin(self.item, self.warehouse) # reserved_qty_for_producion updated @@ -259,10 +236,10 @@ class TestProductionOrder(unittest.TestCase): # projected qty will now be 2 less (becuase of item movement) self.assertEqual(cint(self.bin1_at_start.projected_qty), cint(bin1_on_start_production.projected_qty) + 2) - + # STOP stop_unstop(self.pro_order.name, "Stopped") - + bin1_on_stop_production = get_bin(self.item, self.warehouse) # no change in reserved / projected diff --git a/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py b/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py index 97af20abc73..20ee814fda6 100644 --- a/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py +++ b/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py @@ -7,22 +7,10 @@ from erpnext.stock.doctype.bin.bin import update_item_projected_qty def execute(): repost_bin_qty() - repost_item_projected_qty() def repost_bin_qty(): - for bin in frappe.db.sql(""" select name from `tabBin` + for bin in frappe.db.sql(""" select name from `tabBin` where (actual_qty + ordered_qty + indented_qty + planned_qty- reserved_qty - reserved_qty_for_production) != projected_qty """, as_dict=1): bin_doc = frappe.get_doc('Bin', bin.name) bin_doc.set_projected_qty() bin_doc.db_set("projected_qty", bin_doc.projected_qty, update_modified = False) - -def repost_item_projected_qty(): - for data in frappe.db.sql(""" select - `tabBin`.item_code as item_code, - sum(`tabBin`.projected_qty) as projected_qty, - `tabItem`.total_projected_qty as total_projected_qty - from - `tabBin`, `tabItem` - where `tabBin`.item_code = `tabItem`.name - group by `tabBin`.item_code having projected_qty <> total_projected_qty """, as_dict=1): - update_item_projected_qty(data.item_code) diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py index 8d339b9ce69..3d94b5ce001 100644 --- a/erpnext/projects/doctype/timesheet/timesheet.py +++ b/erpnext/projects/doctype/timesheet/timesheet.py @@ -156,14 +156,18 @@ class Timesheet(Document): (self.production_order, operation_id), as_dict=1)[0] def update_task_and_project(self): + tasks, projects = [], [] + for data in self.time_logs: - if data.task: + if data.task and data.task not in tasks: task = frappe.get_doc("Task", data.task) task.update_time_and_costing() task.save() + tasks.append(data.task) - elif data.project: + elif data.project and data.project not in projects: frappe.get_doc("Project", data.project).update_project() + projects.append(data.project) def validate_dates(self): for data in self.time_logs: diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 8ae91a47774..e8c3262e1d1 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -704,7 +704,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } if(!this.in_apply_price_list) { - this.apply_price_list(); + this.apply_price_list(null, true); } }, @@ -776,7 +776,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ this.frm.toggle_reqd("plc_conversion_rate", !!(this.frm.doc.price_list_name && this.frm.doc.price_list_currency)); - if(this.frm.doc_currency!==this.frm.doc.currency) { + if(this.frm.doc_currency!==this.frm.doc.currency + || this.frm.doc_currency!==this.frm.doc.price_list_currency) { // reset names only when the currency is different var company_currency = this.get_company_currency(); @@ -1056,7 +1057,13 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ if(!price_list_rate_changed) me.calculate_taxes_and_totals(); }, - apply_price_list: function(item) { + apply_price_list: function(item, reset_plc_conversion) { + // We need to reset plc_conversion_rate sometimes because the call to + // `erpnext.stock.get_item_details.apply_price_list` is sensitive to its value + if (!reset_plc_conversion) { + this.frm.set_value("plc_conversion_rate", ""); + } + var me = this; var args = this._get_args(item); if (!((args.items && args.items.length) || args.price_list)) { diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index a6133c877af..a9eb7dbac12 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -13,6 +13,10 @@ frappe.ui.form.on("Sales Order", { 'Project': 'Project' } frm.add_fetch('customer', 'tax_id', 'tax_id'); + + // formatter for material request item + frm.set_indicator_formatter('item_code', + function(doc) { return (doc.stock_qty<=doc.delivered_qty) ? "green" : "orange" }) }, onload: function(frm) { erpnext.queries.setup_queries(frm, "Warehouse", function() { @@ -28,10 +32,6 @@ frappe.ui.form.on("Sales Order", { } }); - // formatter for material request item - frm.set_indicator_formatter('item_code', - function(doc) { return (doc.stock_qty<=doc.delivered_qty) ? "green" : "orange" }) - erpnext.queries.setup_warehouse_query(frm); }, diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index f8299611622..5e5c50d627f 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -5,7 +5,6 @@ import frappe from frappe.utils import flt, add_days import frappe.permissions import unittest -from erpnext.stock.doctype.item.test_item import get_total_projected_qty from erpnext.selling.doctype.sales_order.sales_order \ import make_material_request, make_delivery_note, make_sales_invoice, WarehouseRequired from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry @@ -155,17 +154,9 @@ class TestSalesOrder(unittest.TestCase): dn = create_dn_against_so(so.name, 15) self.assertEqual(get_reserved_qty(), existing_reserved_qty) - total_projected_qty = get_total_projected_qty('_Test Item') - item_doc_before_cancel = frappe.get_doc('Item', '_Test Item') - self.assertEqual(total_projected_qty, item_doc_before_cancel.total_projected_qty) - dn.cancel() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) - total_projected_qty = get_total_projected_qty('_Test Item') - item_doc_after_cancel = frappe.get_doc('Item', '_Test Item') - self.assertEqual(total_projected_qty, item_doc_after_cancel.total_projected_qty) - def test_reserved_qty_for_over_delivery_via_sales_invoice(self): make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) @@ -183,10 +174,6 @@ class TestSalesOrder(unittest.TestCase): si.insert() si.submit() - total_projected_qty = get_total_projected_qty('_Test Item') - item_doc = frappe.get_doc('Item', '_Test Item') - self.assertEqual(total_projected_qty, item_doc.total_projected_qty) - self.assertEqual(get_reserved_qty(), existing_reserved_qty) so.load_from_db() @@ -195,9 +182,6 @@ class TestSalesOrder(unittest.TestCase): si.cancel() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) - total_projected_qty = get_total_projected_qty('_Test Item') - item_doc = frappe.get_doc('Item', '_Test Item') - self.assertEqual(total_projected_qty, item_doc.total_projected_qty) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 0) @@ -229,10 +213,6 @@ class TestSalesOrder(unittest.TestCase): self.assertEqual(get_reserved_qty("_Test Item"), existing_reserved_qty_item1) self.assertEqual(get_reserved_qty("_Test Item Home Desktop 100"), existing_reserved_qty_item2) - total_projected_qty = get_total_projected_qty('_Test Item') - item_doc = frappe.get_doc('Item', '_Test Item') - self.assertEqual(total_projected_qty, item_doc.total_projected_qty) - # unclose so so.load_from_db() so.update_status('Draft') @@ -269,10 +249,6 @@ class TestSalesOrder(unittest.TestCase): dn = create_dn_against_so(so.name, 15) - total_projected_qty = get_total_projected_qty('_Test Item') - item_doc = frappe.get_doc('Item', '_Test Item') - self.assertEqual(total_projected_qty, item_doc.total_projected_qty) - self.assertEqual(get_reserved_qty("_Test Item"), existing_reserved_qty_item1) self.assertEqual(get_reserved_qty("_Test Item Home Desktop 100"), existing_reserved_qty_item2) @@ -495,13 +471,6 @@ class TestSalesOrder(unittest.TestCase): self.assertEquals(abs(flt(reserved_qty)), existing_reserved_qty_for_dn_item) - def test_total_projected_qty_against_sales_order(self): - so = make_sales_order(item = '_Test Item') - total_projected_qty = get_total_projected_qty('_Test Item') - - item_doc = frappe.get_doc('Item', '_Test Item') - self.assertEqual(total_projected_qty, item_doc.total_projected_qty) - def test_reserved_qty_for_closing_so(self): bin = frappe.get_all("Bin", filters={"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, fields=["reserved_qty"]) @@ -567,12 +536,12 @@ class TestSalesOrder(unittest.TestCase): "item_list": [{ "item_code": "_Test FG Item", "qty": 10, - "rate":100 + "rate":100 }, { "item_code": "_Test FG Item", "qty": 20, - "rate":200 + "rate":200 }] }) @@ -589,7 +558,7 @@ class TestSalesOrder(unittest.TestCase): }) so_item_name[item.get("sales_order_item")]= item.get("pending_qty") make_production_orders(json.dumps({"items":po_items}), so.name, so.company) - + # Check if Production Orders were raised for item in so_item_name: po_qty = frappe.db.sql("select sum(qty) from `tabProduction Order` where sales_order=%s and sales_order_item=%s", (so.name, item)) diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 5ca26181e32..aa5b3ba4983 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -118,6 +118,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ selling_price_list: function() { this.apply_price_list(); + this.set_dynamic_labels(); }, price_list_rate: function(doc, cdt, cdn) { diff --git a/erpnext/startup/notifications.py b/erpnext/startup/notifications.py index b8fce6e6c10..690ccf0f1c0 100644 --- a/erpnext/startup/notifications.py +++ b/erpnext/startup/notifications.py @@ -11,7 +11,6 @@ def get_notification_config(): "Warranty Claim": {"status": "Open"}, "Task": {"status": ("in", ("Open", "Overdue"))}, "Project": {"status": "Open"}, - "Item": {"total_projected_qty": ("<", 0)}, "Lead": {"status": "Open"}, "Contact": {"status": "Open"}, "Opportunity": {"status": "Open"}, diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py index fd344234838..430d9fb4043 100644 --- a/erpnext/stock/doctype/bin/bin.py +++ b/erpnext/stock/doctype/bin/bin.py @@ -15,9 +15,6 @@ class Bin(Document): self.validate_mandatory() self.set_projected_qty() - def on_update(self): - update_item_projected_qty(self.item_code) - def validate_mandatory(self): qf = ['actual_qty', 'reserved_qty', 'ordered_qty', 'indented_qty'] for f in qf: @@ -130,11 +127,5 @@ class Bin(Document): self.set_projected_qty() self.db_set('projected_qty', self.projected_qty) -def update_item_projected_qty(item_code): - '''Set total_projected_qty in Item as sum of projected qty in all warehouses''' - frappe.db.sql('''update tabItem set - total_projected_qty = ifnull((select sum(projected_qty) from tabBin where item_code=%s), 0) - where name=%s''', (item_code, item_code)) - def on_doctype_update(): frappe.db.add_index("Bin", ["item_code", "warehouse"]) diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 104eeb82ac1..ea705cb00d8 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -110,7 +110,7 @@ frappe.ui.form.on("Item", { const stock_exists = (frm.doc.__onload && frm.doc.__onload.stock_exists) ? 1 : 0; - ['has_serial_no', 'has_batch_no'].forEach((fieldname) => { + ['is_stock_item', 'has_serial_no', 'has_batch_no'].forEach((fieldname) => { frm.set_df_property(fieldname, 'read_only', stock_exists); }); }, diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index f33497390c4..04f9df3daed 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -172,6 +172,35 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "barcode", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Barcode", + "length": 0, + "no_copy": 1, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -357,7 +386,7 @@ "report_hide": 0, "reqd": 0, "search_index": 0, - "set_only_once": 1, + "set_only_once": 0, "unique": 0 }, { diff --git a/erpnext/stock/doctype/item/item_list.js b/erpnext/stock/doctype/item/item_list.js index db53ae96516..534b3419203 100644 --- a/erpnext/stock/doctype/item/item_list.js +++ b/erpnext/stock/doctype/item/item_list.js @@ -1,6 +1,6 @@ frappe.listview_settings['Item'] = { add_fields: ["item_name", "stock_uom", "item_group", "image", "variant_of", - "has_variants", "end_of_life", "disabled", "total_projected_qty"], + "has_variants", "end_of_life", "disabled"], filters: [["disabled", "=", "0"]], get_indicator: function(doc) { @@ -8,8 +8,6 @@ frappe.listview_settings['Item'] = { return [__("Disabled"), "grey", "disabled,=,Yes"]; } else if (doc.end_of_life && doc.end_of_life < frappe.datetime.get_today()) { return [__("Expired"), "grey", "end_of_life,<,Today"]; - } else if(doc.total_projected_qty < 0) { - return [__("Shortage"), "red", "total_projected_qty,<,0"]; } else if (doc.has_variants) { return [__("Template"), "orange", "has_variants,=,Yes"]; } else if (doc.variant_of) { diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index fb3182e5b4d..7241be3ef75 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -128,7 +128,7 @@ class TestItem(unittest.TestCase): def test_copy_fields_from_template_to_variants(self): frappe.delete_doc_if_exists("Item", "_Test Variant Item-XL", force=1) - + fields = [{'field_name': 'item_group'}, {'field_name': 'is_stock_item'}] allow_fields = [d.get('field_name') for d in fields] set_item_variant_settings(fields) @@ -292,12 +292,6 @@ def make_item_variant(): variant.item_name = "_Test Variant Item-S" variant.save() -def get_total_projected_qty(item): - total_qty = frappe.db.sql(""" select sum(projected_qty) as projected_qty from tabBin - where item_code = %(item)s""", {'item': item}, as_dict=1) - - return total_qty[0].projected_qty if total_qty else 0.0 - test_records = frappe.get_test_records('Item') def create_item(item_code, is_stock_item=None): diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js index ed0597cd98d..709c2c7d192 100644 --- a/erpnext/stock/doctype/material_request/material_request.js +++ b/erpnext/stock/doctype/material_request/material_request.js @@ -12,6 +12,10 @@ frappe.ui.form.on('Material Request', { 'Supplier Quotation': 'Supplier Quotation', 'Production Order': 'Production Order' } + + // formatter for material request item + frm.set_indicator_formatter('item_code', + function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange" }) }, onload: function(frm) { // add item, if previous view was item @@ -19,11 +23,6 @@ frappe.ui.form.on('Material Request', { //set schedule_date set_schedule_date(frm); - - // formatter for material request item - frm.set_indicator_formatter('item_code', - function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange" }), - frm.fields_dict["items"].grid.get_field("warehouse").get_query = function(doc, cdt, cdn){ return{ filters: {'company': doc.company} diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 3b5b4d3cf32..5a884ad0769 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -10,6 +10,7 @@ from erpnext.accounts.doctype.pricing_rule.pricing_rule import get_pricing_rule_ from erpnext.setup.utils import get_exchange_rate from frappe.model.meta import get_field_precision from erpnext.stock.doctype.batch.batch import get_batch_no +from erpnext import get_company_currency from six import string_types @@ -473,8 +474,8 @@ def get_projected_qty(item_code, warehouse): @frappe.whitelist() def get_bin_details(item_code, warehouse): return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse}, - ["projected_qty", "actual_qty", "ordered_qty"], as_dict=True) \ - or {"projected_qty": 0, "actual_qty": 0, "ordered_qty": 0} + ["projected_qty", "actual_qty"], as_dict=True) \ + or {"projected_qty": 0, "actual_qty": 0} @frappe.whitelist() def get_serial_no_details(item_code, warehouse, stock_qty, serial_no): @@ -591,11 +592,12 @@ def get_price_list_currency_and_exchange_rate(args): price_list_currency = get_price_list_currency(args.price_list) price_list_uom_dependant = get_price_list_uom_dependant(args.price_list) plc_conversion_rate = args.plc_conversion_rate + company_currency = get_company_currency(args.company) if (not plc_conversion_rate) or (price_list_currency and args.price_list_currency \ and price_list_currency != args.price_list_currency): # cksgb 19/09/2016: added args.transaction_date as posting_date argument for get_exchange_rate - plc_conversion_rate = get_exchange_rate(price_list_currency, args.currency, + plc_conversion_rate = get_exchange_rate(price_list_currency, company_currency, args.transaction_date) or plc_conversion_rate return frappe._dict({ diff --git a/erpnext/stock/report/item_variant_details/item_variant_details.py b/erpnext/stock/report/item_variant_details/item_variant_details.py index 67b6b5f2a0e..f1488f8eff1 100644 --- a/erpnext/stock/report/item_variant_details/item_variant_details.py +++ b/erpnext/stock/report/item_variant_details/item_variant_details.py @@ -17,7 +17,7 @@ def get_data(item): variant_results = frappe.db.sql("""select name from `tabItem` where variant_of = %s""", item, as_dict=1) - variants = ",".join(['"' + variant['name'] + '"' for variant in variant_results]) + variants = ",".join(['"' + frappe.db.escape(variant['name']) + '"' for variant in variant_results]) order_count_map = get_open_sales_orders_map(variants) stock_details_map = get_stock_details_map(variants)