From b2b238323b7ed41c757700bfecbb1e1ee4dcdd12 Mon Sep 17 00:00:00 2001 From: manqala Date: Sat, 3 Sep 2016 16:35:06 +0100 Subject: [PATCH] Suggested Changes to School (#6223) * Linkage of academic term to academic year * School improvements. Modifications to Academic Term, Assessment, Fees, Student Batch, Student Group. Addition of Grading System. * Removed Grading System from Assessment and put it on Program * Removed the field Grading System from Program and added it back to Assessment. Added some validations for dates in controller of Academic Term and Academic Year * Added validation comparing term start dates with academic year start dates and term end dates with academic year end dates where both are available. * Renamed Grading System to Grading Structure. Implemented the code in Assessment.js to derive the Grade Code from the result entered for the student. Assumes that result is always a number. Will rename the field result in Results to score. * Added validation to check if any grade intervals were overlapping when a Grading Structure is being saved. * Corrections to error in autonaming for Academic Term * Correction in white_list method get_grade in Assessment. Solves problem with grades not being derived when the score is at the boundaries of a grade interval * Correction to setup_wizard.py to make sure that creation of academic terms in create_academic_term includes the academic_year which is now mandatory * Corrections to test_records.json for doctype Academic Term * Correction of test_records.json in doctype Student Groups * Correction of test_records.json for doctype Student Group 2 * Correction to test_course_schedule.py in doctype Course Schedule * More corrections to test_course_schedule.py in doctype Course Schedule * Corrections to test_course_schedule.py * Updates to Student DocType. Enrollment date, Nationality * Linkage of academic term to academic year * School improvements. Modifications to Academic Term, Assessment, Fees, Student Batch, Student Group. Addition of Grading System. * Removed Grading System from Assessment and put it on Program * Removed the field Grading System from Program and added it back to Assessment. Added some validations for dates in controller of Academic Term and Academic Year * Added validation comparing term start dates with academic year start dates and term end dates with academic year end dates where both are available. * Renamed Grading System to Grading Structure. Implemented the code in Assessment.js to derive the Grade Code from the result entered for the student. Assumes that result is always a number. Will rename the field result in Results to score. * Added validation to check if any grade intervals were overlapping when a Grading Structure is being saved. * Corrections to error in autonaming for Academic Term --- erpnext/config/schools.py | 4 + .../doctype/academic_term/academic_term.json | 108 ++- .../doctype/academic_term/academic_term.py | 30 +- .../doctype/academic_term/test_records.json | 26 +- .../doctype/academic_year/academic_year.py | 6 +- .../schools/doctype/assessment/assessment.js | 20 + .../doctype/assessment/assessment.json | 28 +- .../schools/doctype/assessment/assessment.py | 75 +- .../assessment_result/assessment_result.json | 27 +- .../course_schedule/test_course_schedule.py | 8 +- erpnext/schools/doctype/fees/fees.js | 19 + erpnext/schools/doctype/fees/fees.json | 14 +- .../doctype/grade_interval/__init__.py | 0 .../grade_interval/grade_interval.json | 137 +++ .../doctype/grade_interval/grade_interval.py | 11 + .../doctype/grading_structure/__init__.py | 0 .../grading_structure/grading_structure.js | 8 + .../grading_structure/grading_structure.json | 185 ++++ .../grading_structure/grading_structure.py | 25 + .../test_grading_structure.py | 12 + erpnext/schools/doctype/program/program.json | 2 +- .../program_enrollment/program_enrollment.js | 18 + erpnext/schools/doctype/student/student.json | 9 +- .../student_applicant/student_applicant.json | 5 +- .../doctype/student_batch/student_batch.js | 11 + .../doctype/student_batch/student_batch.json | 2 +- .../doctype/student_batch/student_batch.py | 18 +- .../doctype/student_group/student_group.js | 17 +- .../doctype/student_group/student_group.json | 14 +- .../doctype/student_group/test_records.json | 4 +- .../student_group_creation_tool.js | 10 + erpnext/setup/setup_wizard/setup_wizard.py | 859 +++++++++--------- patches.txt | 1 + 33 files changed, 1201 insertions(+), 512 deletions(-) create mode 100644 erpnext/schools/doctype/grade_interval/__init__.py create mode 100644 erpnext/schools/doctype/grade_interval/grade_interval.json create mode 100644 erpnext/schools/doctype/grade_interval/grade_interval.py create mode 100644 erpnext/schools/doctype/grading_structure/__init__.py create mode 100644 erpnext/schools/doctype/grading_structure/grading_structure.js create mode 100644 erpnext/schools/doctype/grading_structure/grading_structure.json create mode 100644 erpnext/schools/doctype/grading_structure/grading_structure.py create mode 100644 erpnext/schools/doctype/grading_structure/test_grading_structure.py create mode 100644 patches.txt diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py index 5e73fce0b50..857a4223b0b 100644 --- a/erpnext/config/schools.py +++ b/erpnext/config/schools.py @@ -120,6 +120,10 @@ def get_data(): "type": "doctype", "name": "Course" }, + { + "type": "doctype", + "name": "Grading Structure" + }, { "type": "doctype", "name": "Program" diff --git a/erpnext/schools/doctype/academic_term/academic_term.json b/erpnext/schools/doctype/academic_term/academic_term.json index 9d9c9e0c2dc..ca10ebf4d42 100644 --- a/erpnext/schools/doctype/academic_term/academic_term.json +++ b/erpnext/schools/doctype/academic_term/academic_term.json @@ -2,7 +2,7 @@ "allow_copy": 0, "allow_import": 1, "allow_rename": 1, - "autoname": "field:term_name", + "autoname": "field:title", "beta": 0, "creation": "2015-09-08 17:19:19.158228", "custom": 0, @@ -11,6 +11,32 @@ "document_type": "Setup", "editable_grid": 0, "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "academic_year", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Academic Year", + "length": 0, + "no_copy": 0, + "options": "Academic Year", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -31,6 +57,81 @@ "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "term_start_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Term Start Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "term_end_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Term End Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "title", + "fieldtype": "Data", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Title", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, @@ -47,7 +148,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-07-25 05:24:23.032319", + "modified": "2016-08-27 23:02:03.565866", "modified_by": "Administrator", "module": "Schools", "name": "Academic Term", @@ -78,7 +179,8 @@ "quick_entry": 1, "read_only": 0, "read_only_onload": 0, - "sort_field": "modified", + "sort_field": "name", "sort_order": "DESC", + "title_field": "title", "track_seen": 0 } \ No newline at end of file diff --git a/erpnext/schools/doctype/academic_term/academic_term.py b/erpnext/schools/doctype/academic_term/academic_term.py index 1a4526b3ebb..891feb86798 100644 --- a/erpnext/schools/doctype/academic_term/academic_term.py +++ b/erpnext/schools/doctype/academic_term/academic_term.py @@ -4,7 +4,35 @@ from __future__ import unicode_literals import frappe +from frappe import msgprint, _ +from frappe.utils import get_datetime, get_datetime_str from frappe.model.document import Document class AcademicTerm(Document): - pass + def autoname(self): + self.name = self.academic_year + " ({})".format(self.term_name) if self.term_name else "" + + def validate(self): + #Check if entry with same academic_year and the term_name already exists + validate_duplication(self) + self.title = self.academic_year + " ({})".format(self.term_name) if self.term_name else "" + + #Check that start of academic year is earlier than end of academic year + if self.term_start_date and self.term_end_date and self.term_start_date > self.term_end_date: + frappe.throw(_("The Term End Date cannot be earlier than the Term Start Date. Please correct the dates and try again.")) + + """Check that the start of the term is not before the start of the academic year and end of term is not after + the end of the academic year""" + year = frappe.get_doc("Academic Year",self.academic_year) + if self.term_start_date and get_datetime_str(year.year_start_date) and (self.term_start_date < get_datetime_str(year.year_start_date)): + frappe.throw(_("The Term Start Date cannot be earlier than the Year Start Date of the Academic Year to which the term is linked (Academic Year {}). Please correct the dates and try again.").format(self.academic_year)) + + if self.term_end_date and get_datetime_str(year.year_end_date) and (self.term_end_date > get_datetime_str(year.year_end_date)): + frappe.throw(_("The Term End Date cannot be later than the Year End Date of the Academic Year to which the term is linked (Academic Year {}). Please correct the dates and try again.").format(self.academic_year)) + + +def validate_duplication(self): + term = frappe.db.sql("""select name from `tabAcademic Term` where academic_year= %s and term_name= %s + and docstatus<2 and name != %s""", (self.academic_year, self.term_name, self.name)) + if term: + frappe.throw(_("An academic term with this 'Academic Year' {0} and 'Term Name' {1} already exists. Please modify these entries and try again.").format(self.academic_year,self.term_name)) diff --git a/erpnext/schools/doctype/academic_term/test_records.json b/erpnext/schools/doctype/academic_term/test_records.json index 9807221053a..2d84383b1d3 100644 --- a/erpnext/schools/doctype/academic_term/test_records.json +++ b/erpnext/schools/doctype/academic_term/test_records.json @@ -1,11 +1,17 @@ [ - { - "term_name": "_Test Academic Term" - }, - { - "term_name": "_Test Academic Term 1" - }, - { - "term_name": "_Test Academic Term 2" - } -] \ No newline at end of file + { + "doctype": "Academic Term", + "academic_year": "2014-2015", + "term_name": "_Test Academic Term" + }, + { + "doctype": "Academic Term", + "academic_year": "2014-2015", + "term_name": "_Test Academic Term 1" + }, + { + "doctype": "Academic Term", + "academic_year": "2014-2015", + "term_name": "_Test Academic Term 2" + } +] \ No newline at end of file diff --git a/erpnext/schools/doctype/academic_year/academic_year.py b/erpnext/schools/doctype/academic_year/academic_year.py index 4b955de5c74..f2858a42d4b 100644 --- a/erpnext/schools/doctype/academic_year/academic_year.py +++ b/erpnext/schools/doctype/academic_year/academic_year.py @@ -4,7 +4,11 @@ from __future__ import unicode_literals import frappe +from frappe import msgprint, _ from frappe.model.document import Document class AcademicYear(Document): - pass + def validate(self): + #Check that start of academic year is earlier than end of academic year + if self.year_start_date and self.year_end_date and self.year_start_date > self.year_end_date: + frappe.throw(_("The Year End Date cannot be earlier than the Year Start Date. Please correct the dates and try again.")) diff --git a/erpnext/schools/doctype/assessment/assessment.js b/erpnext/schools/doctype/assessment/assessment.js index 799ae7ba8c9..efadbd66a26 100644 --- a/erpnext/schools/doctype/assessment/assessment.js +++ b/erpnext/schools/doctype/assessment/assessment.js @@ -28,4 +28,24 @@ frappe.ui.form.on("Assessment" ,{ }); } } +}); + +frappe.ui.form.on("Assessment Result" ,{ + result : function(frm, cdt, cdn) { + if(frm.doc.grading_structure){ + var assessment_result = locals[cdt][cdn]; + frappe.call({ + method:"erpnext.schools.doctype.assessment.assessment.get_grade", + args:{ + grading_structure: frm.doc.grading_structure, + result: assessment_result.result + }, + callback: function(r){ + if(r.message){ + frappe.model.set_value(cdt, cdn, 'grade', r.message); + } + } + }); + } + } }); \ No newline at end of file diff --git a/erpnext/schools/doctype/assessment/assessment.json b/erpnext/schools/doctype/assessment/assessment.json index 30ac1ed962b..e978d086451 100644 --- a/erpnext/schools/doctype/assessment/assessment.json +++ b/erpnext/schools/doctype/assessment/assessment.json @@ -87,6 +87,32 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "grading_structure", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Grading Structure", + "length": 0, + "no_copy": 0, + "options": "Grading Structure", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -506,7 +532,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-08-05 04:57:41.018614", + "modified": "2016-08-27 14:18:51.852078", "modified_by": "Administrator", "module": "Schools", "name": "Assessment", diff --git a/erpnext/schools/doctype/assessment/assessment.py b/erpnext/schools/doctype/assessment/assessment.py index a23d5cc8517..de6a6539677 100644 --- a/erpnext/schools/doctype/assessment/assessment.py +++ b/erpnext/schools/doctype/assessment/assessment.py @@ -8,39 +8,56 @@ import frappe from frappe import _ class Assessment(Document): - def validate(self): - self.validate_overlap() - - def validate_overlap(self): - """Validates overlap for Student Group, Supervisor, Room""" + def validate(self): + self.validate_overlap() + + def validate_overlap(self): + """Validates overlap for Student Group, Supervisor, Room""" - from erpnext.schools.utils import validate_overlap_for + from erpnext.schools.utils import validate_overlap_for - validate_overlap_for(self, "Assessment", "student_group") - validate_overlap_for(self, "Course Schedule", "student_group" ) - - if self.room: - validate_overlap_for(self, "Assessment", "room") - validate_overlap_for(self, "Course Schedule", "room") + validate_overlap_for(self, "Assessment", "student_group") + validate_overlap_for(self, "Course Schedule", "student_group" ) + + if self.room: + validate_overlap_for(self, "Assessment", "room") + validate_overlap_for(self, "Course Schedule", "room") - if self.supervisor: - validate_overlap_for(self, "Assessment", "supervisor") - validate_overlap_for(self, "Course Schedule", "instructor", self.supervisor) + if self.supervisor: + validate_overlap_for(self, "Assessment", "supervisor") + validate_overlap_for(self, "Course Schedule", "instructor", self.supervisor) def get_assessment_list(doctype, txt, filters, limit_start, limit_page_length=20): - user = frappe.session.user - student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user) - if student: - return frappe. db.sql('''select course, schedule_date, from_time, to_time, sgs.name from `tabAssessment` as assessment, - `tabStudent Group Student` as sgs where assessment.student_group = sgs.parent and sgs.student = %s and assessment.docstatus=1 - order by assessment.name asc limit {0} , {1}''' - .format(limit_start, limit_page_length), student, as_dict = True) + user = frappe.session.user + student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user) + if student: + return frappe. db.sql('''select course, schedule_date, from_time, to_time, sgs.name from `tabAssessment` as assessment, + `tabStudent Group Student` as sgs where assessment.student_group = sgs.parent and sgs.student = %s and assessment.docstatus=1 + order by assessment.name asc limit {0} , {1}''' + .format(limit_start, limit_page_length), student, as_dict = True) def get_list_context(context=None): - return { - "show_sidebar": True, - 'no_breadcrumbs': True, - "title": _("Assessment Schedule"), - "get_list": get_assessment_list, - "row_template": "templates/includes/assessment/assessment_row.html" - } + return { + "show_sidebar": True, + 'no_breadcrumbs': True, + "title": _("Assessment Schedule"), + "get_list": get_assessment_list, + "row_template": "templates/includes/assessment/assessment_row.html" + } + +@frappe.whitelist() +def get_grade(grading_structure, result): + grade = frappe.db.sql("""select gi.from_score, gi.to_score, gi.grade_code, gi.grade_description + from `tabGrading Structure` as gs, `tabGrade Interval` as gi + where gs.name = gi.parent and gs.name = %(grading_structure)s and gi.from_score <= %(result)s + and gi.to_score >= %(result)s""".format(), + { + "grading_structure":grading_structure, + "result": result + }, + as_dict=True) + + return grade[0].grade_code if grade else "" + +def validate_grade(score, grade): + pass \ No newline at end of file diff --git a/erpnext/schools/doctype/assessment_result/assessment_result.json b/erpnext/schools/doctype/assessment_result/assessment_result.json index 19339eb712f..91e580d40b6 100644 --- a/erpnext/schools/doctype/assessment_result/assessment_result.json +++ b/erpnext/schools/doctype/assessment_result/assessment_result.json @@ -109,6 +109,31 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "grade", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Grade", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], "hide_heading": 0, @@ -121,7 +146,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-08-01 10:37:23.571679", + "modified": "2016-08-27 12:15:01.923000", "modified_by": "Administrator", "module": "Schools", "name": "Assessment Result", diff --git a/erpnext/schools/doctype/course_schedule/test_course_schedule.py b/erpnext/schools/doctype/course_schedule/test_course_schedule.py index b527303c823..e9fce4b45f1 100644 --- a/erpnext/schools/doctype/course_schedule/test_course_schedule.py +++ b/erpnext/schools/doctype/course_schedule/test_course_schedule.py @@ -24,27 +24,27 @@ class TestCourseSchedule(unittest.TestCase): cs1 = make_course_schedule_test_record(simulate= True) cs2 = make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time, - student_group="TC2-TP-2014-2015-_Test Academic Term", room="RM0002", do_not_save= 1) + student_group="TC2-TP-2014-2015-2014-2015 (_Test Academic Term)", room="RM0002", do_not_save= 1) self.assertRaises(OverlapError, cs2.save) def test_room_conflict(self): cs1 = make_course_schedule_test_record(simulate= True) cs2 = make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time, - student_group="TC2-TP-2014-2015-_Test Academic Term", instructor="_T-Instructor-00002", do_not_save= 1) + student_group="TC2-TP-2014-2015-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", do_not_save= 1) self.assertRaises(OverlapError, cs2.save) def test_no_conflict(self): cs1 = make_course_schedule_test_record(simulate= True) make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time, - student_group="TC2-TP-2014-2015-_Test Academic Term", instructor="_T-Instructor-00002", room="RM0002") + student_group="TC2-TP-2014-2015-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", room="RM0002") def make_course_schedule_test_record(**args): args = frappe._dict(args) course_schedule = frappe.new_doc("Course Schedule") - course_schedule.student_group = args.student_group or "TC-TP-2014-2015-_Test Academic Term" + course_schedule.student_group = args.student_group or "TC-TP-2014-2015-2014-2015 (_Test Academic Term)" course_schedule.course = args.course or "_Test Course" course_schedule.instructor = args.instructor or "_T-Instructor-00001" course_schedule.room = args.room or "RM0001" diff --git a/erpnext/schools/doctype/fees/fees.js b/erpnext/schools/doctype/fees/fees.js index 22c6d8a014a..7c35de438b0 100644 --- a/erpnext/schools/doctype/fees/fees.js +++ b/erpnext/schools/doctype/fees/fees.js @@ -2,6 +2,25 @@ cur_frm.add_fetch("student", "title", "student_name"); frappe.ui.form.on("Fees", { + + onload: function(frm){ + cur_frm.set_query("academic_term",function(){ + return{ + "filters":{ + "academic_year": (frm.doc.academic_year) + } + }; + }); + + cur_frm.set_query("fee_structure",function(){ + return{ + "filters":{ + "academic_term": (frm.doc.academic_term) + } + }; + }); + }, + refresh: function(frm) { if (frm.doc.docstatus === 1 && (frm.doc.total_amount > frm.doc.paid_amount)) { frm.add_custom_button(__("Collect Fees"), function() { diff --git a/erpnext/schools/doctype/fees/fees.json b/erpnext/schools/doctype/fees/fees.json index ce911ad6d7c..5682ef93298 100644 --- a/erpnext/schools/doctype/fees/fees.json +++ b/erpnext/schools/doctype/fees/fees.json @@ -41,17 +41,17 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "academic_term", + "fieldname": "academic_year", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Academic Term", + "label": "Academic Year", "length": 0, "no_copy": 0, - "options": "Academic Term", + "options": "Academic Year", "permlevel": 0, "precision": "", "print_hide": 0, @@ -67,17 +67,17 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "academic_year", + "fieldname": "academic_term", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Academic Year", + "label": "Academic Term", "length": 0, "no_copy": 0, - "options": "Academic Year", + "options": "Academic Term", "permlevel": 0, "precision": "", "print_hide": 0, @@ -480,7 +480,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-07-27 03:52:28.509757", + "modified": "2016-08-26 02:28:48.877990", "modified_by": "Administrator", "module": "Schools", "name": "Fees", diff --git a/erpnext/schools/doctype/grade_interval/__init__.py b/erpnext/schools/doctype/grade_interval/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/schools/doctype/grade_interval/grade_interval.json b/erpnext/schools/doctype/grade_interval/grade_interval.json new file mode 100644 index 00000000000..79ef9f40a6a --- /dev/null +++ b/erpnext/schools/doctype/grade_interval/grade_interval.json @@ -0,0 +1,137 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2016-08-26 03:11:09.591049", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "grade_code", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Grade Code", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "from_score", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "From Score", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "1", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "to_score", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "To Score", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "1", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "grade_description", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Grade Description", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2016-08-27 15:45:04.657328", + "modified_by": "Administrator", + "module": "Schools", + "name": "Grade Interval", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/schools/doctype/grade_interval/grade_interval.py b/erpnext/schools/doctype/grade_interval/grade_interval.py new file mode 100644 index 00000000000..c8ded136ecc --- /dev/null +++ b/erpnext/schools/doctype/grade_interval/grade_interval.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class GradeInterval(Document): + def validate(self): + pass \ No newline at end of file diff --git a/erpnext/schools/doctype/grading_structure/__init__.py b/erpnext/schools/doctype/grading_structure/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/schools/doctype/grading_structure/grading_structure.js b/erpnext/schools/doctype/grading_structure/grading_structure.js new file mode 100644 index 00000000000..36f45042c0c --- /dev/null +++ b/erpnext/schools/doctype/grading_structure/grading_structure.js @@ -0,0 +1,8 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Grading Structure', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/schools/doctype/grading_structure/grading_structure.json b/erpnext/schools/doctype/grading_structure/grading_structure.json new file mode 100644 index 00000000000..cda6bd4e4f2 --- /dev/null +++ b/erpnext/schools/doctype/grading_structure/grading_structure.json @@ -0,0 +1,185 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 1, + "autoname": "field:grading_system_name", + "beta": 0, + "creation": "2016-08-26 03:06:53.922972", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "grading_system_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Grading System Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "description", + "fieldtype": "Text", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Description", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_3", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "grading_intervals_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Grading Intervals", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "grade_intervals", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Grade Intervals", + "length": 0, + "no_copy": 0, + "options": "Grade Interval", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2016-08-27 14:20:50.709823", + "modified_by": "Administrator", + "module": "Schools", + "name": "Grading Structure", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Academics User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "grading_system_name", + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/schools/doctype/grading_structure/grading_structure.py b/erpnext/schools/doctype/grading_structure/grading_structure.py new file mode 100644 index 00000000000..1b5d6a8d2ed --- /dev/null +++ b/erpnext/schools/doctype/grading_structure/grading_structure.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document +from frappe import _ +from frappe.utils import cstr + +class GradingStructure(Document): + def validate(self): + grade_intervals = self.get("grade_intervals") + check_overlap(grade_intervals, self) + +#Check if any of the grade intervals for this grading structure overlap +def check_overlap(grade_intervals, parent_doc): + for interval1 in grade_intervals: + for interval2 in grade_intervals: + if interval1.name == interval2.name: + pass + else: + if (interval1.from_score <= interval2.from_score and interval1.to_score >= interval2.from_score) or (interval1.from_score <= interval2.to_score and interval1.to_score >= interval2.to_score): + frappe.throw(_("""The intervals for Grade Code {0} overlaps with the grade intervals for other grades. + Please check intervals {0} and {1} and try again""".format(interval1.grade_code, interval2.grade_code))) \ No newline at end of file diff --git a/erpnext/schools/doctype/grading_structure/test_grading_structure.py b/erpnext/schools/doctype/grading_structure/test_grading_structure.py new file mode 100644 index 00000000000..0e360806788 --- /dev/null +++ b/erpnext/schools/doctype/grading_structure/test_grading_structure.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +# test_records = frappe.get_test_records('Grading Structure') + +class TestGradingStructure(unittest.TestCase): + pass diff --git a/erpnext/schools/doctype/program/program.json b/erpnext/schools/doctype/program/program.json index acd5a8ecf60..ca6e1dfac6e 100644 --- a/erpnext/schools/doctype/program/program.json +++ b/erpnext/schools/doctype/program/program.json @@ -250,7 +250,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-07-25 01:33:56.912243", + "modified": "2016-08-27 03:21:35.806511", "modified_by": "Administrator", "module": "Schools", "name": "Program", diff --git a/erpnext/schools/doctype/program_enrollment/program_enrollment.js b/erpnext/schools/doctype/program_enrollment/program_enrollment.js index 038afd98869..72fc6f2e6b4 100644 --- a/erpnext/schools/doctype/program_enrollment/program_enrollment.js +++ b/erpnext/schools/doctype/program_enrollment/program_enrollment.js @@ -18,5 +18,23 @@ frappe.ui.form.on("Program Enrollment", { } }); } + }, + + onload: function(frm, cdt, cdn){ + cur_frm.set_query("academic_term", "fees", function(){ + return{ + "filters":{ + "academic_year": (frm.doc.academic_year) + } + }; + }); + + cur_frm.fields_dict['fees'].grid.get_field('fee_structure').get_query = function(doc, cdt, cdn) { + var d = locals[cdt][cdn]; + return { + filters: {'academic_term': d.academic_term} + } + }; + } }); diff --git a/erpnext/schools/doctype/student/student.json b/erpnext/schools/doctype/student/student.json index 22b8c4e76e2..454aeb2f9fe 100644 --- a/erpnext/schools/doctype/student/student.json +++ b/erpnext/schools/doctype/student/student.json @@ -165,7 +165,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "default": "Today", + "default": "", "fieldname": "joining_date", "fieldtype": "Date", "hidden": 0, @@ -180,7 +180,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 1, + "read_only": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -371,7 +371,7 @@ "bold": 0, "collapsible": 0, "fieldname": "nationality", - "fieldtype": "Data", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -380,6 +380,7 @@ "label": "Nationality", "length": 0, "no_copy": 0, + "options": "Country", "permlevel": 0, "precision": "", "print_hide": 0, @@ -456,7 +457,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-07-25 07:22:57.581638", + "modified": "2016-08-21 05:41:34.091353", "modified_by": "Administrator", "module": "Schools", "name": "Student", diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.json b/erpnext/schools/doctype/student_applicant/student_applicant.json index b9505a56240..8dbd22a4ccf 100644 --- a/erpnext/schools/doctype/student_applicant/student_applicant.json +++ b/erpnext/schools/doctype/student_applicant/student_applicant.json @@ -525,7 +525,7 @@ "bold": 0, "collapsible": 0, "fieldname": "nationality", - "fieldtype": "Data", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -534,6 +534,7 @@ "label": "Nationality", "length": 0, "no_copy": 0, + "options": "Country", "permlevel": 0, "precision": "", "print_hide": 0, @@ -633,7 +634,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-07-25 01:24:27.384647", + "modified": "2016-08-26 01:01:45.669665", "modified_by": "Administrator", "module": "Schools", "name": "Student Applicant", diff --git a/erpnext/schools/doctype/student_batch/student_batch.js b/erpnext/schools/doctype/student_batch/student_batch.js index 73d4faae01a..931e41b6d2d 100644 --- a/erpnext/schools/doctype/student_batch/student_batch.js +++ b/erpnext/schools/doctype/student_batch/student_batch.js @@ -4,7 +4,18 @@ frappe.ui.form.on('Student Batch', { refresh: function(frm) { + }, + + onload: function(frm){ + cur_frm.set_query("academic_term",function(){ + return{ + "filters":{ + "academic_year": (frm.doc.academic_year) + } + }; + }); } + }); cur_frm.add_fetch("student", "title", "student_name"); diff --git a/erpnext/schools/doctype/student_batch/student_batch.json b/erpnext/schools/doctype/student_batch/student_batch.json index a806ae32f75..fa7e6b5cf08 100644 --- a/erpnext/schools/doctype/student_batch/student_batch.json +++ b/erpnext/schools/doctype/student_batch/student_batch.json @@ -199,7 +199,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-07-22 09:19:51.141234", + "modified": "2016-08-24 05:32:00.585277", "modified_by": "Administrator", "module": "Schools", "name": "Student Batch", diff --git a/erpnext/schools/doctype/student_batch/student_batch.py b/erpnext/schools/doctype/student_batch/student_batch.py index 107ef933b52..ec2dc799030 100644 --- a/erpnext/schools/doctype/student_batch/student_batch.py +++ b/erpnext/schools/doctype/student_batch/student_batch.py @@ -8,12 +8,12 @@ from erpnext.schools.utils import validate_duplicate_student import frappe class StudentBatch(Document): - def autoname(self): - prog_abb = frappe.db.get_value("Program", self.program, "program_abbreviation") - if not prog_abb: - prog_abb = self.program - self.name = prog_abb + "-"+ self.student_batch_name + "-" + self.academic_year - - def validate(self): - validate_duplicate_student(self.students) - \ No newline at end of file + def autoname(self): + prog_abb = frappe.db.get_value("Program", self.program, "program_abbreviation") + if not prog_abb: + prog_abb = self.program + self.name = prog_abb + "-"+ self.student_batch_name + "-" + self.academic_year + + def validate(self): + validate_duplicate_student(self.students) + \ No newline at end of file diff --git a/erpnext/schools/doctype/student_group/student_group.js b/erpnext/schools/doctype/student_group/student_group.js index eed3342f530..784f557f6cf 100644 --- a/erpnext/schools/doctype/student_group/student_group.js +++ b/erpnext/schools/doctype/student_group/student_group.js @@ -16,4 +16,19 @@ frappe.ui.form.on("Student Group", "refresh", function(frm) { frappe.set_route("List", "Assessment"); }); } -}); \ No newline at end of file +}); + +frappe.ui.form.on("Student Group", "onload", function(frm){ + cur_frm.set_query("academic_term",function(){ + return{ + "filters":{ + "academic_year": (frm.doc.academic_year) + } + }; + }); +}); + +//If Student Batch is entered, deduce program, academic_year and academic term from it +cur_frm.add_fetch("student_batch", "program", "program"); +cur_frm.add_fetch("student_batch", "academic_term", "academic_term"); +cur_frm.add_fetch("student_batch", "academic_year", "academic_year"); diff --git a/erpnext/schools/doctype/student_group/student_group.json b/erpnext/schools/doctype/student_group/student_group.json index e4b4ea3e214..a0584e30c8a 100644 --- a/erpnext/schools/doctype/student_group/student_group.json +++ b/erpnext/schools/doctype/student_group/student_group.json @@ -41,17 +41,17 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "academic_term", + "fieldname": "academic_year", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 1, - "label": "Academic Term", + "label": "Academic Year", "length": 0, "no_copy": 0, - "options": "Academic Term", + "options": "Academic Year", "permlevel": 0, "precision": "", "print_hide": 0, @@ -67,17 +67,17 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "academic_year", + "fieldname": "academic_term", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 1, - "label": "Academic Year", + "label": "Academic Term", "length": 0, "no_copy": 0, - "options": "Academic Year", + "options": "Academic Term", "permlevel": 0, "precision": "", "print_hide": 0, @@ -280,7 +280,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-07-25 06:23:43.903111", + "modified": "2016-08-24 05:21:05.058875", "modified_by": "Administrator", "module": "Schools", "name": "Student Group", diff --git a/erpnext/schools/doctype/student_group/test_records.json b/erpnext/schools/doctype/student_group/test_records.json index a14f670d8e1..27cd181bd10 100644 --- a/erpnext/schools/doctype/student_group/test_records.json +++ b/erpnext/schools/doctype/student_group/test_records.json @@ -3,12 +3,12 @@ "program": "_Test Program", "course": "_Test Course", "academic_year": "2014-2015", - "academic_term": "_Test Academic Term" + "academic_term": "2014-2015 (_Test Academic Term)" }, { "program": "_Test Program", "course": "_Test Course 2", "academic_year": "2014-2015", - "academic_term": "_Test Academic Term" + "academic_term": "2014-2015 (_Test Academic Term)" } ] \ No newline at end of file diff --git a/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.js b/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.js index 056574ca378..9c796bb4745 100644 --- a/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.js +++ b/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.js @@ -20,4 +20,14 @@ frappe.ui.form.on("Student Group Creation Tool", "get_courses", function(frm) { } } }) +}); + +frappe.ui.form.on("Student Group Creation Tool", "onload", function(frm){ + cur_frm.set_query("academic_term",function(){ + return{ + "filters":{ + "academic_year": (frm.doc.academic_year) + } + }; + }); }); \ No newline at end of file diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py index 191f1699b20..945dfb116c2 100644 --- a/erpnext/setup/setup_wizard/setup_wizard.py +++ b/erpnext/setup/setup_wizard/setup_wizard.py @@ -15,538 +15,541 @@ from frappe.core.doctype.communication.comment import add_info_comment from erpnext.setup.setup_wizard.domainify import setup_domain def setup_complete(args=None): - if frappe.db.sql("select name from tabCompany"): - frappe.throw(_("Setup Already Complete!!")) + if frappe.db.sql("select name from tabCompany"): + frappe.throw(_("Setup Already Complete!!")) - install_fixtures.install(args.get("country")) + install_fixtures.install(args.get("country")) - create_price_lists(args) - create_fiscal_year_and_company(args) - create_users(args) - set_defaults(args) - create_territories() - create_feed_and_todo() - create_email_digest() - create_letter_head(args) - create_taxes(args) - create_items(args) - create_customers(args) - create_suppliers(args) + create_price_lists(args) + create_fiscal_year_and_company(args) + create_users(args) + set_defaults(args) + create_territories() + create_feed_and_todo() + create_email_digest() + create_letter_head(args) + create_taxes(args) + create_items(args) + create_customers(args) + create_suppliers(args) - if args.domain.lower() == 'education': - create_academic_term() - create_academic_year() - create_program(args) - create_course(args) - create_instructor(args) - create_room(args) + if args.domain.lower() == 'education': + create_academic_year() + create_academic_term() + create_program(args) + create_course(args) + create_instructor(args) + create_room(args) - if args.get('setup_website'): - website_maker(args) + if args.get('setup_website'): + website_maker(args) - create_logo(args) + create_logo(args) - frappe.local.message_log = [] - setup_domain(args.get('domain')) + frappe.local.message_log = [] + setup_domain(args.get('domain')) - frappe.db.commit() - login_as_first_user(args) + frappe.db.commit() + login_as_first_user(args) - frappe.db.commit() - frappe.clear_cache() + frappe.db.commit() + frappe.clear_cache() - if args.get("add_sample_data"): - try: - make_sample_data() - frappe.clear_cache() - except: - # clear message - if frappe.message_log: - frappe.message_log.pop() + if args.get("add_sample_data"): + try: + make_sample_data() + frappe.clear_cache() + except: + # clear message + if frappe.message_log: + frappe.message_log.pop() - pass + pass def create_fiscal_year_and_company(args): - if (args.get('fy_start_date')): - curr_fiscal_year = get_fy_details(args.get('fy_start_date'), args.get('fy_end_date')) - frappe.get_doc({ - "doctype":"Fiscal Year", - 'year': curr_fiscal_year, - 'year_start_date': args.get('fy_start_date'), - 'year_end_date': args.get('fy_end_date'), - }).insert() - args["curr_fiscal_year"] = curr_fiscal_year + if (args.get('fy_start_date')): + curr_fiscal_year = get_fy_details(args.get('fy_start_date'), args.get('fy_end_date')) + frappe.get_doc({ + "doctype":"Fiscal Year", + 'year': curr_fiscal_year, + 'year_start_date': args.get('fy_start_date'), + 'year_end_date': args.get('fy_end_date'), + }).insert() + args["curr_fiscal_year"] = curr_fiscal_year - # Company - if (args.get('company_name')): - frappe.get_doc({ - "doctype":"Company", - 'company_name':args.get('company_name').strip(), - 'abbr':args.get('company_abbr'), - 'default_currency':args.get('currency'), - 'country': args.get('country'), - 'chart_of_accounts': args.get(('chart_of_accounts')), - 'domain': args.get('domain') - }).insert() + # Company + if (args.get('company_name')): + frappe.get_doc({ + "doctype":"Company", + 'company_name':args.get('company_name').strip(), + 'abbr':args.get('company_abbr'), + 'default_currency':args.get('currency'), + 'country': args.get('country'), + 'chart_of_accounts': args.get(('chart_of_accounts')), + 'domain': args.get('domain') + }).insert() - #Enable shopping cart - enable_shopping_cart(args) + #Enable shopping cart + enable_shopping_cart(args) - # Bank Account - create_bank_account(args) + # Bank Account + create_bank_account(args) def enable_shopping_cart(args): - frappe.get_doc({ - "doctype": "Shopping Cart Settings", - "enabled": 1, - 'company': args.get('company_name').strip(), - 'price_list': frappe.db.get_value("Price List", {"selling": 1}), - 'default_customer_group': _("Individual"), - 'quotation_series': "QTN-", - }).insert() + frappe.get_doc({ + "doctype": "Shopping Cart Settings", + "enabled": 1, + 'company': args.get('company_name').strip(), + 'price_list': frappe.db.get_value("Price List", {"selling": 1}), + 'default_customer_group': _("Individual"), + 'quotation_series': "QTN-", + }).insert() def create_bank_account(args): - if args.get("bank_account"): - company_name = args.get('company_name').strip() - bank_account_group = frappe.db.get_value("Account", - {"account_type": "Bank", "is_group": 1, "root_type": "Asset", - "company": company_name}) - if bank_account_group: - bank_account = frappe.get_doc({ - "doctype": "Account", - 'account_name': args.get("bank_account"), - 'parent_account': bank_account_group, - 'is_group':0, - 'company': company_name, - "account_type": "Bank", - }) - try: - return bank_account.insert() - except RootNotEditable: - frappe.throw(_("Bank account cannot be named as {0}").format(args.get("bank_account"))) - except frappe.DuplicateEntryError: - # bank account same as a CoA entry - pass + if args.get("bank_account"): + company_name = args.get('company_name').strip() + bank_account_group = frappe.db.get_value("Account", + {"account_type": "Bank", "is_group": 1, "root_type": "Asset", + "company": company_name}) + if bank_account_group: + bank_account = frappe.get_doc({ + "doctype": "Account", + 'account_name': args.get("bank_account"), + 'parent_account': bank_account_group, + 'is_group':0, + 'company': company_name, + "account_type": "Bank", + }) + try: + return bank_account.insert() + except RootNotEditable: + frappe.throw(_("Bank account cannot be named as {0}").format(args.get("bank_account"))) + except frappe.DuplicateEntryError: + # bank account same as a CoA entry + pass def create_price_lists(args): - for pl_type, pl_name in (("Selling", _("Standard Selling")), ("Buying", _("Standard Buying"))): - frappe.get_doc({ - "doctype": "Price List", - "price_list_name": pl_name, - "enabled": 1, - "buying": 1 if pl_type == "Buying" else 0, - "selling": 1 if pl_type == "Selling" else 0, - "currency": args["currency"] - }).insert() + for pl_type, pl_name in (("Selling", _("Standard Selling")), ("Buying", _("Standard Buying"))): + frappe.get_doc({ + "doctype": "Price List", + "price_list_name": pl_name, + "enabled": 1, + "buying": 1 if pl_type == "Buying" else 0, + "selling": 1 if pl_type == "Selling" else 0, + "currency": args["currency"] + }).insert() def set_defaults(args): - # enable default currency - frappe.db.set_value("Currency", args.get("currency"), "enabled", 1) + # enable default currency + frappe.db.set_value("Currency", args.get("currency"), "enabled", 1) - global_defaults = frappe.get_doc("Global Defaults", "Global Defaults") - global_defaults.update({ - 'current_fiscal_year': args.curr_fiscal_year, - 'default_currency': args.get('currency'), - 'default_company':args.get('company_name').strip(), - "country": args.get("country"), - }) + global_defaults = frappe.get_doc("Global Defaults", "Global Defaults") + global_defaults.update({ + 'current_fiscal_year': args.curr_fiscal_year, + 'default_currency': args.get('currency'), + 'default_company':args.get('company_name').strip(), + "country": args.get("country"), + }) - global_defaults.save() + global_defaults.save() - frappe.db.set_value("System Settings", None, "email_footer_address", args.get("company")) + frappe.db.set_value("System Settings", None, "email_footer_address", args.get("company")) - accounts_settings = frappe.get_doc("Accounts Settings") - accounts_settings.auto_accounting_for_stock = 1 - accounts_settings.save() + accounts_settings = frappe.get_doc("Accounts Settings") + accounts_settings.auto_accounting_for_stock = 1 + accounts_settings.save() - stock_settings = frappe.get_doc("Stock Settings") - stock_settings.item_naming_by = "Item Code" - stock_settings.valuation_method = "FIFO" - stock_settings.default_warehouse = frappe.db.get_value('Warehouse', {'warehouse_name': _('Stores')}) - stock_settings.stock_uom = _("Nos") - stock_settings.auto_indent = 1 - stock_settings.auto_insert_price_list_rate_if_missing = 1 - stock_settings.automatically_set_serial_nos_based_on_fifo = 1 - stock_settings.save() + stock_settings = frappe.get_doc("Stock Settings") + stock_settings.item_naming_by = "Item Code" + stock_settings.valuation_method = "FIFO" + stock_settings.default_warehouse = frappe.db.get_value('Warehouse', {'warehouse_name': _('Stores')}) + stock_settings.stock_uom = _("Nos") + stock_settings.auto_indent = 1 + stock_settings.auto_insert_price_list_rate_if_missing = 1 + stock_settings.automatically_set_serial_nos_based_on_fifo = 1 + stock_settings.save() - selling_settings = frappe.get_doc("Selling Settings") - selling_settings.cust_master_name = "Customer Name" - selling_settings.so_required = "No" - selling_settings.dn_required = "No" - selling_settings.save() + selling_settings = frappe.get_doc("Selling Settings") + selling_settings.cust_master_name = "Customer Name" + selling_settings.so_required = "No" + selling_settings.dn_required = "No" + selling_settings.save() - buying_settings = frappe.get_doc("Buying Settings") - buying_settings.supp_master_name = "Supplier Name" - buying_settings.po_required = "No" - buying_settings.pr_required = "No" - buying_settings.maintain_same_rate = 1 - buying_settings.save() + buying_settings = frappe.get_doc("Buying Settings") + buying_settings.supp_master_name = "Supplier Name" + buying_settings.po_required = "No" + buying_settings.pr_required = "No" + buying_settings.maintain_same_rate = 1 + buying_settings.save() - notification_control = frappe.get_doc("Notification Control") - notification_control.quotation = 1 - notification_control.sales_invoice = 1 - notification_control.purchase_order = 1 - notification_control.save() + notification_control = frappe.get_doc("Notification Control") + notification_control.quotation = 1 + notification_control.sales_invoice = 1 + notification_control.purchase_order = 1 + notification_control.save() - hr_settings = frappe.get_doc("HR Settings") - hr_settings.emp_created_by = "Naming Series" - hr_settings.save() + hr_settings = frappe.get_doc("HR Settings") + hr_settings.emp_created_by = "Naming Series" + hr_settings.save() def create_feed_and_todo(): - """update Activity feed and create todo for creation of item, customer, vendor""" - add_info_comment(**{ - "subject": _("ERPNext Setup Complete!") - }) + """update Activity feed and create todo for creation of item, customer, vendor""" + add_info_comment(**{ + "subject": _("ERPNext Setup Complete!") + }) def create_email_digest(): - from frappe.utils.user import get_system_managers - system_managers = get_system_managers(only_name=True) - if not system_managers: - return + from frappe.utils.user import get_system_managers + system_managers = get_system_managers(only_name=True) + if not system_managers: + return - companies = frappe.db.sql_list("select name FROM `tabCompany`") - for company in companies: - if not frappe.db.exists("Email Digest", "Default Weekly Digest - " + company): - edigest = frappe.get_doc({ - "doctype": "Email Digest", - "name": "Default Weekly Digest - " + company, - "company": company, - "frequency": "Weekly", - "recipient_list": "\n".join(system_managers) - }) + companies = frappe.db.sql_list("select name FROM `tabCompany`") + for company in companies: + if not frappe.db.exists("Email Digest", "Default Weekly Digest - " + company): + edigest = frappe.get_doc({ + "doctype": "Email Digest", + "name": "Default Weekly Digest - " + company, + "company": company, + "frequency": "Weekly", + "recipient_list": "\n".join(system_managers) + }) - for df in edigest.meta.get("fields", {"fieldtype": "Check"}): - if df.fieldname != "scheduler_errors": - edigest.set(df.fieldname, 1) + for df in edigest.meta.get("fields", {"fieldtype": "Check"}): + if df.fieldname != "scheduler_errors": + edigest.set(df.fieldname, 1) - edigest.insert() + edigest.insert() - # scheduler errors digest - if companies: - edigest = frappe.new_doc("Email Digest") - edigest.update({ - "name": "Scheduler Errors", - "company": companies[0], - "frequency": "Daily", - "recipient_list": "\n".join(system_managers), - "scheduler_errors": 1, - "enabled": 1 - }) - edigest.insert() + # scheduler errors digest + if companies: + edigest = frappe.new_doc("Email Digest") + edigest.update({ + "name": "Scheduler Errors", + "company": companies[0], + "frequency": "Daily", + "recipient_list": "\n".join(system_managers), + "scheduler_errors": 1, + "enabled": 1 + }) + edigest.insert() def get_fy_details(fy_start_date, fy_end_date): - start_year = getdate(fy_start_date).year - if start_year == getdate(fy_end_date).year: - fy = cstr(start_year) - else: - fy = cstr(start_year) + '-' + cstr(start_year + 1) - return fy + start_year = getdate(fy_start_date).year + if start_year == getdate(fy_end_date).year: + fy = cstr(start_year) + else: + fy = cstr(start_year) + '-' + cstr(start_year + 1) + return fy def create_taxes(args): - for i in xrange(1,6): - if args.get("tax_" + str(i)): - # replace % in case someone also enters the % symbol - tax_rate = cstr(args.get("tax_rate_" + str(i)) or "").replace("%", "") + for i in xrange(1,6): + if args.get("tax_" + str(i)): + # replace % in case someone also enters the % symbol + tax_rate = cstr(args.get("tax_rate_" + str(i)) or "").replace("%", "") - try: - tax_group = frappe.db.get_value("Account", {"company": args.get("company_name"), - "is_group": 1, "account_type": "Tax", "root_type": "Liability"}) - if tax_group: - account = make_tax_head(args, i, tax_group, tax_rate) - make_sales_and_purchase_tax_templates(account) + try: + tax_group = frappe.db.get_value("Account", {"company": args.get("company_name"), + "is_group": 1, "account_type": "Tax", "root_type": "Liability"}) + if tax_group: + account = make_tax_head(args, i, tax_group, tax_rate) + make_sales_and_purchase_tax_templates(account) - except frappe.NameError, e: - if e.args[2][0]==1062: - pass - else: - raise - except RootNotEditable, e: - pass + except frappe.NameError, e: + if e.args[2][0]==1062: + pass + else: + raise + except RootNotEditable, e: + pass def make_tax_head(args, i, tax_group, tax_rate): - return frappe.get_doc({ - "doctype":"Account", - "company": args.get("company_name").strip(), - "parent_account": tax_group, - "account_name": args.get("tax_" + str(i)), - "is_group": 0, - "report_type": "Balance Sheet", - "account_type": "Tax", - "tax_rate": flt(tax_rate) if tax_rate else None - }).insert(ignore_permissions=True) + return frappe.get_doc({ + "doctype":"Account", + "company": args.get("company_name").strip(), + "parent_account": tax_group, + "account_name": args.get("tax_" + str(i)), + "is_group": 0, + "report_type": "Balance Sheet", + "account_type": "Tax", + "tax_rate": flt(tax_rate) if tax_rate else None + }).insert(ignore_permissions=True) def make_sales_and_purchase_tax_templates(account): - doc = { - "doctype": "Sales Taxes and Charges Template", - "title": account.name, - "taxes": [{ - "category": "Valuation and Total", - "charge_type": "On Net Total", - "account_head": account.name, - "description": "{0} @ {1}".format(account.account_name, account.tax_rate), - "rate": account.tax_rate - }] - } + doc = { + "doctype": "Sales Taxes and Charges Template", + "title": account.name, + "taxes": [{ + "category": "Valuation and Total", + "charge_type": "On Net Total", + "account_head": account.name, + "description": "{0} @ {1}".format(account.account_name, account.tax_rate), + "rate": account.tax_rate + }] + } - # Sales - frappe.get_doc(copy.deepcopy(doc)).insert() + # Sales + frappe.get_doc(copy.deepcopy(doc)).insert() - # Purchase - doc["doctype"] = "Purchase Taxes and Charges Template" - frappe.get_doc(copy.deepcopy(doc)).insert() + # Purchase + doc["doctype"] = "Purchase Taxes and Charges Template" + frappe.get_doc(copy.deepcopy(doc)).insert() def create_items(args): - for i in xrange(1,6): - item = args.get("item_" + str(i)) - if item: - item_group = args.get("item_group_" + str(i)) - is_sales_item = args.get("is_sales_item_" + str(i)) - is_purchase_item = args.get("is_purchase_item_" + str(i)) - is_stock_item = item_group!=_("Services") - default_warehouse = "" - if is_stock_item: - default_warehouse = frappe.db.get_value("Warehouse", filters={ - "warehouse_name": _("Finished Goods") if is_sales_item else _("Stores"), - "company": args.get("company_name").strip() - }) + for i in xrange(1,6): + item = args.get("item_" + str(i)) + if item: + item_group = args.get("item_group_" + str(i)) + is_sales_item = args.get("is_sales_item_" + str(i)) + is_purchase_item = args.get("is_purchase_item_" + str(i)) + is_stock_item = item_group!=_("Services") + default_warehouse = "" + if is_stock_item: + default_warehouse = frappe.db.get_value("Warehouse", filters={ + "warehouse_name": _("Finished Goods") if is_sales_item else _("Stores"), + "company": args.get("company_name").strip() + }) - try: - frappe.get_doc({ - "doctype":"Item", - "item_code": item, - "item_name": item, - "description": item, - "show_in_website": 1, - "is_sales_item": is_sales_item, - "is_purchase_item": is_purchase_item, - "is_stock_item": is_stock_item and 1 or 0, - "item_group": item_group, - "stock_uom": args.get("item_uom_" + str(i)), - "default_warehouse": default_warehouse - }).insert() + try: + frappe.get_doc({ + "doctype":"Item", + "item_code": item, + "item_name": item, + "description": item, + "show_in_website": 1, + "is_sales_item": is_sales_item, + "is_purchase_item": is_purchase_item, + "is_stock_item": is_stock_item and 1 or 0, + "item_group": item_group, + "stock_uom": args.get("item_uom_" + str(i)), + "default_warehouse": default_warehouse + }).insert() - if args.get("item_img_" + str(i)): - item_image = args.get("item_img_" + str(i)).split(",") - if len(item_image)==3: - filename, filetype, content = item_image - fileurl = save_file(filename, content, "Item", item, decode=True).file_url - frappe.db.set_value("Item", item, "image", fileurl) + if args.get("item_img_" + str(i)): + item_image = args.get("item_img_" + str(i)).split(",") + if len(item_image)==3: + filename, filetype, content = item_image + fileurl = save_file(filename, content, "Item", item, decode=True).file_url + frappe.db.set_value("Item", item, "image", fileurl) - if args.get("item_price_" + str(i)): - item_price = flt(args.get("item_price_" + str(i))) + if args.get("item_price_" + str(i)): + item_price = flt(args.get("item_price_" + str(i))) - if is_sales_item: - price_list_name = frappe.db.get_value("Price List", {"selling": 1}) - make_item_price(item, price_list_name, item_price) + if is_sales_item: + price_list_name = frappe.db.get_value("Price List", {"selling": 1}) + make_item_price(item, price_list_name, item_price) - if is_purchase_item: - price_list_name = frappe.db.get_value("Price List", {"buying": 1}) - make_item_price(item, price_list_name, item_price) + if is_purchase_item: + price_list_name = frappe.db.get_value("Price List", {"buying": 1}) + make_item_price(item, price_list_name, item_price) - except frappe.NameError: - pass + except frappe.NameError: + pass def make_item_price(item, price_list_name, item_price): - frappe.get_doc({ - "doctype": "Item Price", - "price_list": price_list_name, - "item_code": item, - "price_list_rate": item_price - }).insert() + frappe.get_doc({ + "doctype": "Item Price", + "price_list": price_list_name, + "item_code": item, + "price_list_rate": item_price + }).insert() def create_customers(args): - for i in xrange(1,6): - customer = args.get("customer_" + str(i)) - if customer: - try: - doc = frappe.get_doc({ - "doctype":"Customer", - "customer_name": customer, - "customer_type": "Company", - "customer_group": _("Commercial"), - "territory": args.get("country"), - "company": args.get("company_name").strip() - }).insert() + for i in xrange(1,6): + customer = args.get("customer_" + str(i)) + if customer: + try: + doc = frappe.get_doc({ + "doctype":"Customer", + "customer_name": customer, + "customer_type": "Company", + "customer_group": _("Commercial"), + "territory": args.get("country"), + "company": args.get("company_name").strip() + }).insert() - if args.get("customer_contact_" + str(i)): - create_contact(args.get("customer_contact_" + str(i)), - "customer", doc.name) - except frappe.NameError: - pass + if args.get("customer_contact_" + str(i)): + create_contact(args.get("customer_contact_" + str(i)), + "customer", doc.name) + except frappe.NameError: + pass def create_suppliers(args): - for i in xrange(1,6): - supplier = args.get("supplier_" + str(i)) - if supplier: - try: - doc = frappe.get_doc({ - "doctype":"Supplier", - "supplier_name": supplier, - "supplier_type": _("Local"), - "company": args.get("company_name").strip() - }).insert() + for i in xrange(1,6): + supplier = args.get("supplier_" + str(i)) + if supplier: + try: + doc = frappe.get_doc({ + "doctype":"Supplier", + "supplier_name": supplier, + "supplier_type": _("Local"), + "company": args.get("company_name").strip() + }).insert() - if args.get("supplier_contact_" + str(i)): - create_contact(args.get("supplier_contact_" + str(i)), - "supplier", doc.name) - except frappe.NameError: - pass + if args.get("supplier_contact_" + str(i)): + create_contact(args.get("supplier_contact_" + str(i)), + "supplier", doc.name) + except frappe.NameError: + pass def create_contact(contact, party_type, party): - """Create contact based on given contact name""" - contact = contact.strip().split(" ") + """Create contact based on given contact name""" + contact = contact.strip().split(" ") - frappe.get_doc({ - "doctype":"Contact", - party_type: party, - "first_name":contact[0], - "last_name": len(contact) > 1 and contact[1] or "" - }).insert() + frappe.get_doc({ + "doctype":"Contact", + party_type: party, + "first_name":contact[0], + "last_name": len(contact) > 1 and contact[1] or "" + }).insert() def create_letter_head(args): - if args.get("attach_letterhead"): - frappe.get_doc({ - "doctype":"Letter Head", - "letter_head_name": _("Standard"), - "is_default": 1 - }).insert() + if args.get("attach_letterhead"): + frappe.get_doc({ + "doctype":"Letter Head", + "letter_head_name": _("Standard"), + "is_default": 1 + }).insert() - attach_letterhead = args.get("attach_letterhead").split(",") - if len(attach_letterhead)==3: - filename, filetype, content = attach_letterhead - fileurl = save_file(filename, content, "Letter Head", _("Standard"), decode=True).file_url - frappe.db.set_value("Letter Head", _("Standard"), "content", "" % fileurl) + attach_letterhead = args.get("attach_letterhead").split(",") + if len(attach_letterhead)==3: + filename, filetype, content = attach_letterhead + fileurl = save_file(filename, content, "Letter Head", _("Standard"), decode=True).file_url + frappe.db.set_value("Letter Head", _("Standard"), "content", "" % fileurl) def create_logo(args): - if args.get("attach_logo"): - attach_logo = args.get("attach_logo").split(",") - if len(attach_logo)==3: - filename, filetype, content = attach_logo - fileurl = save_file(filename, content, "Website Settings", "Website Settings", - decode=True).file_url - frappe.db.set_value("Website Settings", "Website Settings", "brand_html", - " {1}".format(fileurl, args.get("company_name").strip())) + if args.get("attach_logo"): + attach_logo = args.get("attach_logo").split(",") + if len(attach_logo)==3: + filename, filetype, content = attach_logo + fileurl = save_file(filename, content, "Website Settings", "Website Settings", + decode=True).file_url + frappe.db.set_value("Website Settings", "Website Settings", "brand_html", + " {1}".format(fileurl, args.get("company_name").strip())) def create_territories(): - """create two default territories, one for home country and one named Rest of the World""" - from frappe.utils.nestedset import get_root_of - country = frappe.db.get_default("country") - root_territory = get_root_of("Territory") - for name in (country, _("Rest Of The World")): - if name and not frappe.db.exists("Territory", name): - frappe.get_doc({ - "doctype": "Territory", - "territory_name": name.replace("'", ""), - "parent_territory": root_territory, - "is_group": "No" - }).insert() + """create two default territories, one for home country and one named Rest of the World""" + from frappe.utils.nestedset import get_root_of + country = frappe.db.get_default("country") + root_territory = get_root_of("Territory") + for name in (country, _("Rest Of The World")): + if name and not frappe.db.exists("Territory", name): + frappe.get_doc({ + "doctype": "Territory", + "territory_name": name.replace("'", ""), + "parent_territory": root_territory, + "is_group": "No" + }).insert() def login_as_first_user(args): - if args.get("email") and hasattr(frappe.local, "login_manager"): - frappe.local.login_manager.login_as(args.get("email")) + if args.get("email") and hasattr(frappe.local, "login_manager"): + frappe.local.login_manager.login_as(args.get("email")) def create_users(args): - if frappe.session.user == 'Administrator': - return + if frappe.session.user == 'Administrator': + return - # create employee for self - emp = frappe.get_doc({ - "doctype": "Employee", - "employee_name": " ".join(filter(None, [args.get("first_name"), args.get("last_name")])), - "user_id": frappe.session.user, - "status": "Active", - "company": args.get("company_name") - }) - emp.flags.ignore_mandatory = True - emp.insert(ignore_permissions = True) + # create employee for self + emp = frappe.get_doc({ + "doctype": "Employee", + "employee_name": " ".join(filter(None, [args.get("first_name"), args.get("last_name")])), + "user_id": frappe.session.user, + "status": "Active", + "company": args.get("company_name") + }) + emp.flags.ignore_mandatory = True + emp.insert(ignore_permissions = True) - for i in xrange(1,5): - email = args.get("user_email_" + str(i)) - fullname = args.get("user_fullname_" + str(i)) - if email: - if not fullname: - fullname = email.split("@")[0] + for i in xrange(1,5): + email = args.get("user_email_" + str(i)) + fullname = args.get("user_fullname_" + str(i)) + if email: + if not fullname: + fullname = email.split("@")[0] - parts = fullname.split(" ", 1) + parts = fullname.split(" ", 1) - user = frappe.get_doc({ - "doctype": "User", - "email": email, - "first_name": parts[0], - "last_name": parts[1] if len(parts) > 1 else "", - "enabled": 1, - "user_type": "System User" - }) + user = frappe.get_doc({ + "doctype": "User", + "email": email, + "first_name": parts[0], + "last_name": parts[1] if len(parts) > 1 else "", + "enabled": 1, + "user_type": "System User" + }) - # default roles - user.append_roles("Projects User", "Stock User", "Support Team") + # default roles + user.append_roles("Projects User", "Stock User", "Support Team") - if args.get("user_sales_" + str(i)): - user.append_roles("Sales User", "Sales Manager", "Accounts User") - if args.get("user_purchaser_" + str(i)): - user.append_roles("Purchase User", "Purchase Manager", "Accounts User") - if args.get("user_accountant_" + str(i)): - user.append_roles("Accounts Manager", "Accounts User") + if args.get("user_sales_" + str(i)): + user.append_roles("Sales User", "Sales Manager", "Accounts User") + if args.get("user_purchaser_" + str(i)): + user.append_roles("Purchase User", "Purchase Manager", "Accounts User") + if args.get("user_accountant_" + str(i)): + user.append_roles("Accounts Manager", "Accounts User") - user.flags.delay_emails = True + user.flags.delay_emails = True - if not frappe.db.get_value("User", email): - user.insert(ignore_permissions=True) + if not frappe.db.get_value("User", email): + user.insert(ignore_permissions=True) - # create employee - emp = frappe.get_doc({ - "doctype": "Employee", - "employee_name": fullname, - "user_id": email, - "status": "Active", - "company": args.get("company_name") - }) - emp.flags.ignore_mandatory = True - emp.insert(ignore_permissions = True) + # create employee + emp = frappe.get_doc({ + "doctype": "Employee", + "employee_name": fullname, + "user_id": email, + "status": "Active", + "company": args.get("company_name") + }) + emp.flags.ignore_mandatory = True + emp.insert(ignore_permissions = True) def create_academic_term(): - at = ["Semester 1", "Semester 2", "Semester 3"] - for d in at: - academic_term = frappe.new_doc("Academic Term") - academic_term.term_name = d - academic_term.save() + at = ["Semester 1", "Semester 2", "Semester 3"] + ay = ["2013-14", "2014-15", "2015-16", "2016-17", "2017-18"] + for y in ay: + for t in at: + academic_term = frappe.new_doc("Academic Term") + academic_term.academic_year = y + academic_term.term_name = t + academic_term.save() def create_academic_year(): - ac = ["2013-14", "2014-15", "2015-16", "2016-17", "2017-18"] - for d in ac: - academic_year = frappe.new_doc("Academic Year") - academic_year.academic_year_name = d - academic_year.save() + ac = ["2013-14", "2014-15", "2015-16", "2016-17", "2017-18"] + for d in ac: + academic_year = frappe.new_doc("Academic Year") + academic_year.academic_year_name = d + academic_year.save() def create_program(args): - for i in xrange(1,6): - if args.get("program_" + str(i)): - program = frappe.new_doc("Program") - program.program_name = args.get("program_" + str(i)) - program.save() + for i in xrange(1,6): + if args.get("program_" + str(i)): + program = frappe.new_doc("Program") + program.program_name = args.get("program_" + str(i)) + program.save() def create_course(args): - for i in xrange(1,6): - if args.get("course_" + str(i)): - course = frappe.new_doc("Course") - course.course_name = args.get("course_" + str(i)) - course.save() + for i in xrange(1,6): + if args.get("course_" + str(i)): + course = frappe.new_doc("Course") + course.course_name = args.get("course_" + str(i)) + course.save() def create_instructor(args): - for i in xrange(1,6): - if args.get("instructor_" + str(i)): - instructor = frappe.new_doc("Instructor") - instructor.instructor_name = args.get("instructor_" + str(i)) - instructor.save() + for i in xrange(1,6): + if args.get("instructor_" + str(i)): + instructor = frappe.new_doc("Instructor") + instructor.instructor_name = args.get("instructor_" + str(i)) + instructor.save() def create_room(args): - for i in xrange(1,6): - if args.get("room_" + str(i)): - room = frappe.new_doc("Room") - room.room_name = args.get("room_" + str(i)) - room.seating_capacity = args.get("room_capacity_" + str(i)) - room.save() + for i in xrange(1,6): + if args.get("room_" + str(i)): + room = frappe.new_doc("Room") + room.room_name = args.get("room_" + str(i)) + room.seating_capacity = args.get("room_capacity_" + str(i)) + room.save() diff --git a/patches.txt b/patches.txt new file mode 100644 index 00000000000..8f127fe427e --- /dev/null +++ b/patches.txt @@ -0,0 +1 @@ +bench.patches.v3.deprecate_old_config