Merge branch 'develop'

This commit is contained in:
Rushabh Mehta 2016-07-26 09:24:00 +05:30
commit c85aa3d9c5
30 changed files with 153 additions and 81 deletions

View File

@ -2,7 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
__version__ = '7.0.3' __version__ = '7.0.4'
def get_default_company(user=None): def get_default_company(user=None):
'''Get default company for user''' '''Get default company for user'''

View File

@ -69,13 +69,13 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var me = this; var me = this;
// navigator.onLine // navigator.onLine
this.connection_status = false; this.connection_status = false;
this.page.set_indicator("Offline", "grey") this.page.set_indicator(__("Offline"), "grey")
frappe.call({ frappe.call({
method:"frappe.handler.ping", method:"frappe.handler.ping",
callback: function(r){ callback: function(r){
if(r.message){ if(r.message){
me.connection_status = true; me.connection_status = true;
me.page.set_indicator("Online", "green") me.page.set_indicator(__("Online"), "green")
} }
} }
}) })
@ -278,7 +278,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
"fieldtype": "Data", "fieldtype": "Data",
"label": "Item", "label": "Item",
"fieldname": "pos_item", "fieldname": "pos_item",
"placeholder": "Search Item" "placeholder": __("Search Item")
}, },
parent: this.wrapper.find(".search-area"), parent: this.wrapper.find(".search-area"),
only_input: true, only_input: true,

View File

@ -167,9 +167,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
target_doc.qty = -1* source_doc.qty target_doc.qty = -1* source_doc.qty
if doctype == "Purchase Receipt": if doctype == "Purchase Receipt":
target_doc.received_qty = -1* source_doc.qty target_doc.received_qty = -1* source_doc.qty
target_doc.prevdoc_doctype = source_doc.prevdoc_doctype target_doc.purchase_order = source_doc.purchase_order
target_doc.prevdoc_docname = source_doc.prevdoc_docname
target_doc.prevdoc_detail_docname = source_doc.prevdoc_detail_docname
elif doctype == "Purchase Invoice": elif doctype == "Purchase Invoice":
target_doc.received_qty = -1* source_doc.qty target_doc.received_qty = -1* source_doc.qty
target_doc.purchase_order = source_doc.purchase_order target_doc.purchase_order = source_doc.purchase_order

View File

@ -301,3 +301,5 @@ execute:frappe.delete_doc_if_exists("DocType", "Payment Tool Detail")
erpnext.patches.v7_0.setup_account_table_for_expense_claim_type_if_exists erpnext.patches.v7_0.setup_account_table_for_expense_claim_type_if_exists
erpnext.patches.v7_0.migrate_schools_to_erpnext erpnext.patches.v7_0.migrate_schools_to_erpnext
erpnext.patches.v7_0.remove_administrator_role_in_doctypes erpnext.patches.v7_0.remove_administrator_role_in_doctypes
erpnext.patches.v7_0.rename_fee_amount_to_fee_component
erpnext.patches.v7_0.calculate_total_costing_amount

View File

@ -0,0 +1,14 @@
import frappe
from frappe.utils import flt
def execute():
frappe.reload_doc('projects', 'doctype', 'timesheet')
for data in frappe.get_all('Timesheet', fields=["name, total_costing_amount"],
filters = [["docstatus", "<", "2"]]):
if flt(data.total_costing_amount) == 0.0:
ts = frappe.get_doc('Timesheet', data.name)
ts.update_cost()
ts.calculate_total_amounts()
ts.flags.ignore_validate_update_after_submit = True
ts.save()

View File

@ -0,0 +1,15 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.utils.rename_field import rename_field
def execute():
frappe.rename_doc("DocType", "Fee Amount", "Fee Component")
for dt in ("Fees", "Fee Structure"):
frappe.reload_doctype(dt)
rename_field(dt, "amount", "components")

View File

@ -5,11 +5,11 @@ cur_frm.add_fetch('employee', 'employee_name', 'employee_name');
frappe.ui.form.on("Timesheet", { frappe.ui.form.on("Timesheet", {
setup: function(frm) { setup: function(frm) {
frm.get_field('time_logs').grid.editable_fields = [ frm.get_field('time_logs').grid.editable_fields = [
{fieldname: 'billable', columns: 2}, {fieldname: 'billable', columns: 1},
{fieldname: 'activity_type', columns: 2}, {fieldname: 'activity_type', columns: 2},
{fieldname: 'from_time', columns: 2}, {fieldname: 'from_time', columns: 3},
{fieldname: 'hours', columns: 2}, {fieldname: 'hours', columns: 1},
{fieldname: 'to_time', columns: 2}, {fieldname: 'project', columns: 3}
]; ];
frm.fields_dict.employee.get_query = function() { frm.fields_dict.employee.get_query = function() {
@ -22,7 +22,8 @@ frappe.ui.form.on("Timesheet", {
child = locals[cdt][cdn]; child = locals[cdt][cdn];
return{ return{
filters: { filters: {
'project': child.project 'project': child.project,
'status': ["!=", "Closed"]
} }
} }
} }
@ -37,8 +38,7 @@ frappe.ui.form.on("Timesheet", {
refresh: function(frm) { refresh: function(frm) {
if(frm.doc.docstatus==1) { if(frm.doc.docstatus==1) {
if(!frm.doc.sales_invoice && frm.doc.total_billing_amount > 0 if(!frm.doc.sales_invoice && frm.doc.total_billing_amount > 0){
&& !frm.doc.production_order){
frm.add_custom_button(__("Make Sales Invoice"), function() { frm.trigger("make_invoice") }, frm.add_custom_button(__("Make Sales Invoice"), function() { frm.trigger("make_invoice") },
"icon-file-alt"); "icon-file-alt");
} }
@ -147,13 +147,16 @@ var calculate_time_and_amount = function(frm) {
var tl = frm.doc.time_logs || []; var tl = frm.doc.time_logs || [];
total_hr = 0; total_hr = 0;
total_billing_amount = 0; total_billing_amount = 0;
total_costing_amount = 0;
for(var i=0; i<tl.length; i++) { for(var i=0; i<tl.length; i++) {
if (tl[i].hours) { if (tl[i].hours) {
total_hr += tl[i].hours; total_hr += tl[i].hours;
total_billing_amount += tl[i].billing_amount; total_billing_amount += tl[i].billing_amount;
total_costing_amount += tl[i].costing_amount;
} }
} }
cur_frm.set_value("total_hours", total_hr); cur_frm.set_value("total_hours", total_hr);
cur_frm.set_value("total_billing_amount", total_billing_amount); cur_frm.set_value("total_billing_amount", total_billing_amount);
cur_frm.set_value("total_costing_amount", total_costing_amount);
} }

View File

@ -157,7 +157,7 @@
"no_copy": 1, "no_copy": 1,
"options": "Draft\nSubmitted\nBilled\nPayslip\nCompleted\nCancelled", "options": "Draft\nSubmitted\nBilled\nPayslip\nCompleted\nCancelled",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 1,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 1, "read_only": 1,
"report_hide": 0, "report_hide": 0,
@ -478,7 +478,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"default": "0", "default": "0",
"description": "updated via Time Logs", "description": "",
"fieldname": "total_hours", "fieldname": "total_hours",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -529,7 +529,7 @@
"collapsible": 0, "collapsible": 0,
"default": "0", "default": "0",
"depends_on": "", "depends_on": "",
"description": "updated via Time Logs", "description": "",
"fieldname": "total_billing_amount", "fieldname": "total_billing_amount",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -551,6 +551,31 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "total_costing_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Total Costing Amount",
"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
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -637,7 +662,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-07-13 23:44:05.086570", "modified": "2016-07-26 00:01:56.055046",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Projects", "module": "Projects",
"name": "Timesheet", "name": "Timesheet",

View File

@ -20,14 +20,21 @@ class OverProductionLoggedError(frappe.ValidationError): pass
class Timesheet(Document): class Timesheet(Document):
def validate(self): def validate(self):
self.set_status() self.set_status()
self.total_hours = 0.0
self.total_billing_amount = 0.0
self.validate_dates() self.validate_dates()
self.validate_time_logs() self.validate_time_logs()
self.update_cost() self.update_cost()
self.calculate_total_amounts()
def calculate_total_amounts(self):
self.total_hours = 0.0
self.total_billing_amount = 0.0
self.total_costing_amount = 0.0
for d in self.get("time_logs"): for d in self.get("time_logs"):
self.total_hours += flt(d.hours) self.total_hours += flt(d.hours)
if d.billable: self.total_billing_amount += flt(d.billing_amount) if d.billable:
self.total_billing_amount += flt(d.billing_amount)
self.total_costing_amount += flt(d.costing_amount)
def set_status(self): def set_status(self):
self.status = { self.status = {
@ -88,7 +95,7 @@ class Timesheet(Document):
frappe.throw(_("Row {0}: Completed Qty must be greater than zero.").format(data.idx)) frappe.throw(_("Row {0}: Completed Qty must be greater than zero.").format(data.idx))
if self.production_order and flt(pending_qty) < flt(data.completed_qty): if self.production_order and flt(pending_qty) < flt(data.completed_qty):
frappe.throw(_("Row {0}: Completed Qty cannot be more than {0} for operation {1}").format(data.idx, pending_qty, self.operation), frappe.throw(_("Row {0}: Completed Qty cannot be more than {1} for operation {2}").format(data.idx, pending_qty, data.operation),
OverProductionLoggedError) OverProductionLoggedError)
def update_production_order(self, time_sheet): def update_production_order(self, time_sheet):
@ -220,7 +227,7 @@ class Timesheet(Document):
def update_cost(self): def update_cost(self):
for data in self.time_logs: for data in self.time_logs:
if data.activity_type and not data.billing_amount: if data.activity_type and (not data.billing_amount or not data.costing_amount):
rate = get_activity_cost(self.employee, data.activity_type) rate = get_activity_cost(self.employee, data.activity_type)
hours = data.hours or 0 hours = data.hours or 0
if rate: if rate:

View File

@ -14,7 +14,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"depends_on": "eval:!parent.production_order", "depends_on": "",
"fieldname": "billable", "fieldname": "billable",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -27,7 +27,7 @@
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 1,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
@ -163,7 +163,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"depends_on": "eval:!parent.production_order", "depends_on": "billable",
"fieldname": "section_break_11", "fieldname": "section_break_11",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -265,7 +265,7 @@
"collapsible": 0, "collapsible": 0,
"default": "0", "default": "0",
"depends_on": "", "depends_on": "",
"description": "To display value check Billable", "description": "",
"fieldname": "billing_amount", "fieldname": "billing_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
@ -292,7 +292,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"default": "0", "default": "0",
"description": "To display value check Billable", "description": "",
"fieldname": "costing_amount", "fieldname": "costing_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
@ -532,7 +532,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-07-21 09:59:01.622745", "modified": "2016-07-26 00:07:58.267131",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Projects", "module": "Projects",
"name": "Timesheet Detail", "name": "Timesheet Detail",

View File

@ -1,14 +1,17 @@
[ [
{ {
"course_name": "_Test Course", "course_name": "_Test Course",
"course_code": "TC100" "course_code": "TC100",
"course_abbreviation": "TC"
}, },
{ {
"course_name": "_Test Course 1", "course_name": "_Test Course 1",
"course_code": "TC101" "course_code": "TC101",
"course_abbreviation": "TC1"
}, },
{ {
"course_name": "_Test Course 2", "course_name": "_Test Course 2",
"course_code": "TC102" "course_code": "TC102",
"course_abbreviation": "TC2"
} }
] ]

View File

@ -24,27 +24,27 @@ class TestCourseSchedule(unittest.TestCase):
cs1 = make_course_schedule_test_record(simulate= True) cs1 = make_course_schedule_test_record(simulate= True)
cs2 = make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time, cs2 = make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time,
student_group="_Test Student Group 1", room="RM0002", do_not_save= 1) student_group="TC2-TP-2014-2015-_Test Academic Term", room="RM0002", do_not_save= 1)
self.assertRaises(OverlapError, cs2.save) self.assertRaises(OverlapError, cs2.save)
def test_room_conflict(self): def test_room_conflict(self):
cs1 = make_course_schedule_test_record(simulate= True) cs1 = make_course_schedule_test_record(simulate= True)
cs2 = make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time, cs2 = make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time,
student_group="_Test Student Group 1", instructor="_T-Instructor-00002", do_not_save= 1) student_group="TC2-TP-2014-2015-_Test Academic Term", instructor="_T-Instructor-00002", do_not_save= 1)
self.assertRaises(OverlapError, cs2.save) self.assertRaises(OverlapError, cs2.save)
def test_no_conflict(self): def test_no_conflict(self):
cs1 = make_course_schedule_test_record(simulate= True) cs1 = make_course_schedule_test_record(simulate= True)
make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time, make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time,
student_group="_Test Student Group 1", instructor="_T-Instructor-00002", room="RM0002") student_group="TC2-TP-2014-2015-_Test Academic Term", instructor="_T-Instructor-00002", room="RM0002")
def make_course_schedule_test_record(**args): def make_course_schedule_test_record(**args):
args = frappe._dict(args) args = frappe._dict(args)
course_schedule = frappe.new_doc("Course Schedule") course_schedule = frappe.new_doc("Course Schedule")
course_schedule.student_group = args.student_group or "_Test Student Group" course_schedule.student_group = args.student_group or "TC-TP-2014-2015-_Test Academic Term"
course_schedule.course = args.course or "_Test Course" course_schedule.course = args.course or "_Test Course"
course_schedule.instructor = args.instructor or "_T-Instructor-00001" course_schedule.instructor = args.instructor or "_T-Instructor-00001"
course_schedule.room = args.room or "RM0001" course_schedule.room = args.room or "RM0001"

View File

@ -1,6 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_import": 0, "allow_import": 1,
"allow_rename": 0, "allow_rename": 0,
"autoname": "field:exam_name", "autoname": "field:exam_name",
"beta": 0, "beta": 0,
@ -480,7 +480,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2016-07-25 01:26:26.776581", "modified": "2016-07-25 06:24:11.126911",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "Examination", "name": "Examination",

View File

@ -79,7 +79,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2016-07-25 05:24:22.972715", "modified": "2016-07-25 08:42:24.309236",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "Fee Category", "name": "Fee Category",

View File

@ -104,10 +104,10 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-07-21 12:25:44.368245", "modified": "2016-07-25 08:43:25.405166",
"modified_by": "r@r.com", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "Fee Amount", "name": "Fee Component",
"name_case": "", "name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],

View File

@ -1,10 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and contributors # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt # For license information, please see license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.model.document import Document from frappe.model.document import Document
class FeeAmount(Document): class FeeComponent(Document):
pass pass

View File

@ -146,17 +146,17 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"fieldname": "amount", "fieldname": "components",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "Amount", "label": "Components",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Fee Amount", "options": "Fee Component",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@ -230,7 +230,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2016-07-25 01:25:22.796777", "modified": "2016-07-25 08:44:07.886467",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "Fee Structure", "name": "Fee Structure",

View File

@ -295,17 +295,17 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"fieldname": "amount", "fieldname": "components",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "Amount", "label": "Components",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Fee Amount", "options": "Fee Component",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@ -478,7 +478,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2016-07-25 01:27:43.220809", "modified": "2016-07-25 08:44:33.595812",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "Fees", "name": "Fees",

View File

@ -1,8 +1,10 @@
[ [
{ {
"program_name": "_Test Program" "program_name": "_Test Program",
"program_abbreviation": "TP"
}, },
{ {
"program_name": "_Test Program 2" "program_name": "_Test Program 2",
"program_abbreviation": "TP2"
} }
] ]

View File

@ -556,7 +556,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2016-07-25 01:27:04.145185", "modified": "2016-07-25 06:23:57.581538",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "Student", "name": "Student",

View File

@ -8,9 +8,12 @@ from erpnext.schools.utils import validate_duplicate_student
import frappe import frappe
class StudentBatch(Document): class StudentBatch(Document):
def validate(self): def autoname(self):
validate_duplicate_student(self.students)
prog_abb = frappe.db.get_value("Program", self.program, "program_abbreviation") prog_abb = frappe.db.get_value("Program", self.program, "program_abbreviation")
if not prog_abb: if not prog_abb:
prog_abb = self.program prog_abb = self.program
self.name = prog_abb + "-"+ self.student_batch_name + "-" + self.academic_year self.name = prog_abb + "-"+ self.student_batch_name + "-" + self.academic_year
def validate(self):
validate_duplicate_student(self.students)

View File

@ -1,7 +1,7 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_import": 0, "allow_import": 1,
"allow_rename": 0, "allow_rename": 1,
"autoname": "", "autoname": "",
"beta": 0, "beta": 0,
"creation": "2015-09-07 12:55:52.072792", "creation": "2015-09-07 12:55:52.072792",
@ -280,7 +280,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2016-07-25 01:32:57.819189", "modified": "2016-07-25 06:23:43.903111",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "Student Group", "name": "Student Group",

View File

@ -9,13 +9,7 @@ from frappe import _
from erpnext.schools.utils import validate_duplicate_student from erpnext.schools.utils import validate_duplicate_student
class StudentGroup(Document): class StudentGroup(Document):
def validate(self): def autoname(self):
self.set_name()
self.validate_strength()
self.validate_student_name()
validate_duplicate_student(self.students)
def set_name(self):
self.name = frappe.db.get_value("Course", self.course, "course_abbreviation") self.name = frappe.db.get_value("Course", self.course, "course_abbreviation")
if not self.name: if not self.name:
self.name = self.course self.name = self.course
@ -32,6 +26,11 @@ class StudentGroup(Document):
if self.academic_term: if self.academic_term:
self.name += "-" + self.academic_term self.name += "-" + self.academic_term
def validate(self):
self.validate_strength()
self.validate_student_name()
validate_duplicate_student(self.students)
def validate_strength(self): def validate_strength(self):
if self.max_strength and len(self.students) > self.max_strength: if self.max_strength and len(self.students) > self.max_strength:
frappe.throw(_("""Cannot enroll more than {0} students for this student group.""").format(self.max_strength)) frappe.throw(_("""Cannot enroll more than {0} students for this student group.""").format(self.max_strength))

View File

@ -1,13 +1,11 @@
[ [
{ {
"group_name": "_Test Student Group",
"program": "_Test Program", "program": "_Test Program",
"course": "_Test Course", "course": "_Test Course",
"academic_year": "2014-2015", "academic_year": "2014-2015",
"academic_term": "_Test Academic Term" "academic_term": "_Test Academic Term"
}, },
{ {
"group_name": "_Test Student Group 1",
"program": "_Test Program", "program": "_Test Program",
"course": "_Test Course 2", "course": "_Test Course 2",
"academic_year": "2014-2015", "academic_year": "2014-2015",

View File

@ -176,7 +176,7 @@
"label": "Courses", "label": "Courses",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "SG Creation Tool Course", "options": "Student Group Creation Tool Course",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@ -199,7 +199,7 @@
"issingle": 1, "issingle": 1,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-07-25 01:23:31.192112", "modified": "2016-07-25 06:40:46.107131",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "Student Group Creation Tool", "name": "Student Group Creation Tool",

View File

@ -147,10 +147,10 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-07-21 12:31:41.252860", "modified": "2016-07-25 06:40:49.000588",
"modified_by": "r@r.com", "modified_by": "Administrator",
"module": "Schools", "module": "Schools",
"name": "SG Creation Tool Course", "name": "Student Group Creation Tool Course",
"name_case": "", "name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],

View File

@ -1,10 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe and contributors # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt # For license information, please see license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.model.document import Document from frappe.model.document import Document
class SGCreationToolCourse(Document): class StudentGroupCreationToolCourse(Document):
pass pass

View File

@ -32,6 +32,9 @@ class Company(Document):
self.validate_currency() self.validate_currency()
def validate_abbr(self): def validate_abbr(self):
if not self.abbr:
self.abbr = ''.join([c[0] for c in self.company_name.split()]).upper()
self.abbr = self.abbr.strip() self.abbr = self.abbr.strip()
if self.get('__islocal') and len(self.abbr) > 5: if self.get('__islocal') and len(self.abbr) > 5: