Merge branch 'master' into develop
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
index 11dcfe7..0aaed8f 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
@@ -62,13 +62,13 @@
for d in entries:
row = self.append('payment_entries', {})
-
- d.amount = fmt_money(d.debit if d.debit else d.credit, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
+ amount = d.debit if d.debit else d.credit
+ d.amount = fmt_money(amount, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
d.pop("credit")
d.pop("debit")
d.pop("account_currency")
row.update(d)
- self.total_amount += flt(d.amount)
+ self.total_amount += flt(amount)
def update_clearance_date(self):
clearance_date_updated = False
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
index 49af59b..777b34b 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:title",
@@ -12,6 +13,7 @@
"editable_grid": 0,
"fields": [
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -40,6 +42,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -69,6 +72,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -99,6 +103,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -129,6 +134,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -159,6 +165,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -189,6 +196,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -217,6 +225,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -247,6 +256,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -275,6 +285,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -303,6 +314,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -331,6 +343,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -359,6 +372,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -387,6 +401,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -417,6 +432,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -447,6 +463,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -477,6 +494,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -507,6 +525,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -537,6 +556,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -567,6 +587,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -597,6 +618,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -627,6 +649,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -655,6 +678,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -683,6 +707,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -711,6 +736,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -739,6 +765,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -767,6 +794,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -796,6 +824,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -824,6 +853,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -851,6 +881,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -880,6 +911,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -910,6 +942,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -941,6 +974,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -969,6 +1003,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1000,6 +1035,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1028,6 +1064,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1058,6 +1095,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1085,6 +1123,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1114,6 +1153,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1143,6 +1183,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1173,6 +1214,39 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.price_or_discount==\"Price\"",
+ "fieldname": "currency",
+ "fieldtype": "Link",
+ "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": "Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Currency",
+ "permlevel": 0,
+ "precision": "",
+ "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,
"bold": 0,
"collapsible": 0,
@@ -1202,6 +1276,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1230,18 +1305,18 @@
"unique": 0
}
],
+ "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-gift",
"idx": 1,
"image_view": 0,
"in_create": 0,
- "in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-02-17 16:21:28.446208",
+ "modified": "2017-06-26 19:35:50.651619",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule",
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 71897d4..af31d9b 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -23,6 +23,7 @@
self.validate_price_or_discount()
self.validate_max_discount()
+ if self.price_or_discount != 'Price': self.currency = None
if not self.margin_type: self.margin_rate_or_amount = 0.0
def validate_mandatory(self):
@@ -179,9 +180,15 @@
item_details.margin_type = pricing_rule.margin_type
item_details.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
if pricing_rule.price_or_discount == "Price":
+ if pricing_rule.get('currency') and \
+ pricing_rule.currency == args.currency:
+ price_list_rate = pricing_rule.price * (args.conversion_factor or 1.0)
+ else:
+ price_list_rate = (pricing_rule.price/flt(args.conversion_rate)) * args.conversion_factor or 1.0 \
+ if args.conversion_rate else 0.0
+
item_details.update({
- "price_list_rate": (pricing_rule.price/flt(args.conversion_rate)) * args.conversion_factor or 1.0 \
- if args.conversion_rate else 0.0,
+ "price_list_rate": price_list_rate,
"discount_percentage": 0.0
})
else:
@@ -240,7 +247,7 @@
conditions = item_variant_condition = ""
values = {"item_code": args.get("item_code"), "brand": args.get("brand")}
- for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
+ for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner", "currency"]:
if args.get(field):
conditions += " and ifnull("+field+", '') in (%("+field+")s, '')"
values[field] = args.get(field)
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 270ad53..b6c4fd2 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -10,7 +10,7 @@
from erpnext.accounts.utils import get_fiscal_year
-def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
+def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
company=None, reset_period_on_fy_change=True):
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
Periodicity can be (Yearly, Quarterly, Monthly)"""
@@ -85,8 +85,8 @@
return period_list
def get_fiscal_year_data(from_fiscal_year, to_fiscal_year):
- fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date,
- max(year_end_date) as year_end_date from `tabFiscal Year` where
+ fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date,
+ max(year_end_date) as year_end_date from `tabFiscal Year` where
name between %(from_fiscal_year)s and %(to_fiscal_year)s""",
{'from_fiscal_year': from_fiscal_year, 'to_fiscal_year': to_fiscal_year}, as_dict=1)
@@ -110,7 +110,7 @@
label = formatdate(from_date, "MMM YY") + "-" + formatdate(to_date, "MMM YY")
return label
-
+
def get_data(company, root_type, balance_must_be, period_list, filters=None,
accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False,
ignore_accumulated_values_for_fy=False):
@@ -119,16 +119,16 @@
return None
accounts, accounts_by_name, parent_children_map = filter_accounts(accounts)
-
+
company_currency = frappe.db.get_value("Company", company, "default_currency")
gl_entries_by_account = {}
for root in frappe.db.sql("""select lft, rgt from tabAccount
where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1):
-
- set_gl_entries_by_account(company,
+
+ set_gl_entries_by_account(company,
period_list[0]["year_start_date"] if only_current_fiscal_year else None,
- period_list[-1]["to_date"],
+ period_list[-1]["to_date"],
root.lft, root.rgt, filters,
gl_entries_by_account, ignore_closing_entries=ignore_closing_entries)
@@ -136,7 +136,7 @@
accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values)
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
out = filter_out_zero_value_rows(out, parent_children_map)
-
+
if out:
add_total_row(out, root_type, balance_must_be, period_list, company_currency)
@@ -151,13 +151,13 @@
if entry.posting_date <= period.to_date:
if (accumulated_values or entry.posting_date >= period.from_date) and \
- (not ignore_accumulated_values_for_fy or
+ (not ignore_accumulated_values_for_fy or
entry.fiscal_year == period.to_date_fiscal_year):
d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
if entry.posting_date < period_list[0].year_start_date:
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
-
+
def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
"""accumulate children's values in parent accounts"""
for d in reversed(accounts):
@@ -165,7 +165,7 @@
for period in period_list:
accounts_by_name[d.parent_account][period.key] = \
accounts_by_name[d.parent_account].get(period.key, 0.0) + d.get(period.key, 0.0)
-
+
accounts_by_name[d.parent_account]["opening_balance"] = \
accounts_by_name[d.parent_account].get("opening_balance", 0.0) + d.get("opening_balance", 0.0)
@@ -173,15 +173,15 @@
data = []
year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d")
year_end_date = period_list[-1]["year_end_date"].strftime("%Y-%m-%d")
-
+
for d in accounts:
# add to output
has_value = False
total = 0
row = frappe._dict({
- "account_name": d.account_name,
- "account": d.name,
- "parent_account": d.parent_account,
+ "account_name": _(d.account_name),
+ "account": _(d.name),
+ "parent_account": _(d.parent_account),
"indent": flt(d.indent),
"year_start_date": year_start_date,
"year_end_date": year_end_date,
@@ -192,7 +192,7 @@
if d.get(period.key) and balance_must_be=="Credit":
# change sign based on Debit or Credit, since calculation is done using (debit - credit)
d[period.key] *= -1
-
+
row[period.key] = flt(d.get(period.key, 0.0), 3)
if abs(row[period.key]) >= 0.005:
@@ -203,9 +203,9 @@
row["has_value"] = has_value
row["total"] = total
data.append(row)
-
+
return data
-
+
def filter_out_zero_value_rows(data, parent_children_map, show_zero_values=False):
data_with_value = []
for d in data:
@@ -224,8 +224,8 @@
def add_total_row(out, root_type, balance_must_be, period_list, company_currency):
total_row = {
- "account_name": "'" + _("Total {0} ({1})").format(root_type, balance_must_be) + "'",
- "account": "'" + _("Total {0} ({1})").format(root_type, balance_must_be) + "'",
+ "account_name": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
+ "account": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
"currency": company_currency
}
@@ -235,11 +235,11 @@
total_row.setdefault(period.key, 0.0)
total_row[period.key] += row.get(period.key, 0.0)
row[period.key] = ""
-
+
total_row.setdefault("total", 0.0)
total_row["total"] += flt(row["total"])
row["total"] = ""
-
+
if total_row.has_key("total"):
out.append(total_row)
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index b3bbb92..7e5020a 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -270,6 +270,9 @@
doc = get_mapped_doc("Purchase Order", source_name, {
"Purchase Order": {
"doctype": "Purchase Receipt",
+ "field_map": {
+ "per_billed": "per_billed"
+ },
"validation": {
"docstatus": ["=", 1],
}
diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py
index c54f808..b984578 100644
--- a/erpnext/config/schools.py
+++ b/erpnext/config/schools.py
@@ -137,7 +137,14 @@
{
"type": "doctype",
"name": "Assessment Result Tool"
- }
+ },
+ {
+ "type": "report",
+ "is_query_report": True,
+ "name": "Course wise Assessment Report",
+ "doctype": "Assessment Result"
+ },
+
]
},
{
diff --git a/erpnext/schools/report/course_wise_assessment_report/__init__.py b/erpnext/schools/report/course_wise_assessment_report/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/schools/report/course_wise_assessment_report/__init__.py
diff --git a/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.js b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.js
new file mode 100644
index 0000000..42b19eb
--- /dev/null
+++ b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.js
@@ -0,0 +1,34 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.query_reports["Course wise Assessment Report"] = {
+ "filters": [
+ {
+ "fieldname":"assessment_group",
+ "label": __("Assessment Group"),
+ "fieldtype": "Link",
+ "options": "Assessment Group",
+ "reqd": 1,
+ "get_query": function() {
+ return{
+ filters: {
+ 'is_group': 0
+ }
+ };
+ }
+ },
+ {
+ "fieldname":"course",
+ "label": __("Course"),
+ "fieldtype": "Link",
+ "options": "Course",
+ "reqd": 1
+ },
+ {
+ "fieldname":"student_group",
+ "label": __("Student Group"),
+ "fieldtype": "Link",
+ "options": "Student Group"
+ }
+ ]
+};
diff --git a/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.json b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.json
new file mode 100644
index 0000000..6b089d2
--- /dev/null
+++ b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.json
@@ -0,0 +1,23 @@
+{
+ "add_total_row": 0,
+ "apply_user_permissions": 1,
+ "creation": "2017-05-05 14:46:13.776133",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2017-05-05 14:47:18.080385",
+ "modified_by": "Administrator",
+ "module": "Schools",
+ "name": "Course wise Assessment Report",
+ "owner": "Administrator",
+ "ref_doctype": "Assessment Result",
+ "report_name": "Course wise Assessment Report",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Academics User"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.py b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.py
new file mode 100644
index 0000000..b5a2fc1
--- /dev/null
+++ b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.py
@@ -0,0 +1,122 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from collections import defaultdict
+
+def execute(filters=None):
+ args = frappe._dict()
+ args["assessment_group"] = filters.get("assessment_group")
+ if args["assessment_group"] == "All Assessment Groups":
+ frappe.throw(_("Please select the assessment group other than 'All Assessment Groups'"))
+
+ args["course"] = filters.get("course")
+ args["student_group"] = filters.get("student_group")
+ if args["student_group"]:
+ cond = "and ap.student_group=%(student_group)s"
+ else:
+ cond = ''
+
+ # find all assessment plan linked with the filters provided
+ assessment_plan = frappe.db.sql('''
+ select
+ ap.name, ap.student_group, apc.assessment_criteria, apc.maximum_score as max_score
+ from
+ `tabAssessment Plan` ap, `tabAssessment Plan Criteria` apc
+ where
+ ap.assessment_group=%(assessment_group)s and ap.course=%(course)s and
+ ap.name=apc.parent and ap.docstatus=1 {0}
+ order by
+ apc.assessment_criteria'''.format(cond), (args), as_dict=1)
+
+ assessment_plan_list = set([d["name"] for d in assessment_plan])
+ if not assessment_plan_list:
+ frappe.throw(_("No assessment plan linked with this assessment group"))
+
+ student_group_list = set([d["student_group"] for d in assessment_plan])
+ assessment_result = frappe.db.sql('''select ar.student, ard.assessment_criteria, ard.grade, ard.score
+ from `tabAssessment Result` ar, `tabAssessment Result Detail` ard
+ where ar.assessment_plan in (%s) and ar.name=ard.parent and ar.docstatus=1
+ order by ard.assessment_criteria''' %', '.join(['%s']*len(assessment_plan_list)),
+ tuple(assessment_plan_list), as_dict=1)
+
+ result_dict = defaultdict(dict)
+ kounter = defaultdict(dict)
+ for result in assessment_result:
+ result_dict[result.student].update({frappe.scrub(result.assessment_criteria): result.grade,
+ frappe.scrub(result.assessment_criteria)+"_score": result.score})
+ if result.grade in kounter[result.assessment_criteria]:
+ kounter[result.assessment_criteria][result.grade] += 1
+ else:
+ kounter[result.assessment_criteria].update({result.grade: 1})
+
+ student_list = frappe.db.sql('''select sgs.student, sgs.student_name
+ from `tabStudent Group` sg, `tabStudent Group Student` sgs
+ where sg.name = sgs.parent and sg.name in (%s)
+ order by sgs.group_roll_number asc''' %', '.join(['%s']*len(student_group_list)),
+ tuple(student_group_list), as_dict=1)
+
+ for student in student_list:
+ student.update(result_dict[student.student])
+ data = student_list
+
+ columns = get_column(list(set([(d["assessment_criteria"],d["max_score"]) for d in assessment_plan])))
+
+ grading_scale = frappe.db.get_value("Assessment Plan", list(assessment_plan_list)[0], "grading_scale")
+ grades = frappe.db.sql_list('''select grade_code from `tabGrading Scale Interval` where parent=%s''',
+ (grading_scale))
+ assessment_criteria_list = list(set([d["assessment_criteria"] for d in assessment_plan]))
+ chart = get_chart_data(grades, assessment_criteria_list, kounter)
+
+ return columns, data, None, chart
+
+def get_column(assessment_criteria):
+ columns = [{
+ "fieldname": "student",
+ "label": _("Student ID"),
+ "fieldtype": "Link",
+ "options": "Student",
+ "width": 90
+ },
+ {
+ "fieldname": "student_name",
+ "label": _("Student Name"),
+ "fieldtype": "Data",
+ "width": 160
+ }]
+ for d in assessment_criteria:
+ columns.append({
+ "fieldname": frappe.scrub(d[0]),
+ "label": d[0],
+ "fieldtype": "Data",
+ "width": 110
+ })
+ columns.append({
+ "fieldname": frappe.scrub(d[0]) +"_score",
+ "label": "Score(" + str(int(d[1])) + ")",
+ "fieldtype": "Float",
+ "width": 100
+ })
+ return columns
+
+def get_chart_data(grades, assessment_criteria_list, kounter):
+ grades = sorted(grades)
+ chart_data = []
+ chart_data.append(["x"] + assessment_criteria_list)
+ for grade in grades:
+ tmp = [grade]
+ for ac in assessment_criteria_list:
+ if grade in kounter[ac]:
+ tmp.append(kounter[ac][grade])
+ else:
+ tmp.append(0)
+ chart_data.append(tmp)
+ return {
+ "data": {
+ "x": "x",
+ "columns": chart_data
+ },
+ "chart_type": 'bar',
+ }
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 647eb67..f60eb6a 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -119,7 +119,8 @@
frappe.db.set(self, 'status', 'Submitted')
self.update_prevdoc_status()
- self.update_billing_status()
+ if self.per_billed < 100:
+ self.update_billing_status()
if not self.is_return:
update_last_purchase_rate(self, 1)