public QuickInputSemesterScoreForm(JHStudentRecord student) : this() { _student = student; JHScoreCalcRuleRecord record = student.ScoreCalcRule; _calculator = new ScoreCalculator(record); _util = new SemesterHistoryUtility(JHSemesterHistory.SelectByStudentID(student.ID)); _semesterScoreRecordList = JHSemesterScore.SelectByStudentID(_student.ID); errorProvider.SetError(cboSchoolYear, "無效的學年度"); errorProvider.SetError(cboSemester, "無效的學期"); }
public ScoreCalculator(JHScoreCalcRuleRecord record) { if (record == null) { return; } XmlElement content = record.Content; XmlElement subject = (XmlElement)content.SelectSingleNode("成績計算規則/各項成績計算位數/科目成績計算"); XmlElement domain = (XmlElement)content.SelectSingleNode("成績計算規則/各項成績計算位數/領域成績計算"); XmlElement learnDomain = (XmlElement)content.SelectSingleNode("成績計算規則/各項成績計算位數/學習領域成績計算"); XmlElement graduate = (XmlElement)content.SelectSingleNode("成績計算規則/各項成績計算位數/畢業成績計算"); if (subject != null) { _subjectRound.SetData(int.Parse(subject.GetAttribute("位數")), subject.GetAttribute("進位方式")); } if (domain != null) { _domainRound.SetData(int.Parse(domain.GetAttribute("位數")), domain.GetAttribute("進位方式")); } if (learnDomain != null) { _learnDomainRound.SetData(int.Parse(learnDomain.GetAttribute("位數")), learnDomain.GetAttribute("進位方式")); } if (graduate != null) { _graduateRound.SetData(int.Parse(graduate.GetAttribute("位數")), graduate.GetAttribute("進位方式")); } //ScoreCalcRule> // <成績計算規則> // <各項成績計算位數> // <學期科目成績計算 位數="2" 進位方式="四捨五入"/> // <學期領域成績計算 位數="2" 進位方式="四捨五入"/> // <學期學習領域成績計算 位數="2" 進位方式="四捨五入"/> // <畢業成績計算 位數="2" 進位方式="四捨五入"/> }
public static void Calculate(List <StudentRecord> students) { const string LearnDomain = "學習領域"; const string CourseLearn = "課程學習"; ScoreCalcRule.Instance.SyncAllBackground(); //SemesterScore.Instance.SyncAllBackground(); Dictionary <string, List <JHSemesterScoreRecord> > studentSemesterScoreRecordCache = new Dictionary <string, List <JHSchool.Data.JHSemesterScoreRecord> >(); foreach (JHSemesterScoreRecord record in JHSemesterScore.SelectByStudentIDs(students.AsKeyList())) { if (!studentSemesterScoreRecordCache.ContainsKey(record.RefStudentID)) { studentSemesterScoreRecordCache.Add(record.RefStudentID, new List <JHSchool.Data.JHSemesterScoreRecord>()); } studentSemesterScoreRecordCache[record.RefStudentID].Add(record); } List <GradScoreRecordEditor> editors = new List <GradScoreRecordEditor>(); BackgroundWorker worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; MultiThreadBackgroundWorker <GradScoreRecordEditor> multiWorker = new MultiThreadBackgroundWorker <GradScoreRecordEditor>(); multiWorker.WorkerReportsProgress = true; multiWorker.AutoReportsProgress = true; multiWorker.PackageSize = 50; multiWorker.Loading = MultiThreadLoading.Light; worker.DoWork += delegate { Dictionary <string, ScoreCalculator> calc = new Dictionary <string, ScoreCalculator>(); double studentTotal = students.Count; double studentCount = 0; foreach (StudentRecord student in students) { studentCount++; #region 取得成績計算規則 string calcID = string.Empty; ScoreCalcRuleRecord calcRecord = student.GetScoreCalcRuleRecord(); if (calcRecord != null) { calcID = calcRecord.ID; if (!calc.ContainsKey(calcID)) { JHScoreCalcRuleRecord record = null; List <JHScoreCalcRuleRecord> list = JHScoreCalcRule.SelectByIDs(new string[] { calcRecord.ID }); if (list.Count > 0) { record = list[0]; } calc.Add(calcID, new ScoreCalculator(record)); } } else { if (!calc.ContainsKey(string.Empty)) { calc.Add(string.Empty, new ScoreCalculator(null)); } } #endregion #region 取得各學期成績 List <JHSemesterScoreRecord> semesterScoreRecordList; if (studentSemesterScoreRecordCache.ContainsKey(student.ID)) { semesterScoreRecordList = studentSemesterScoreRecordCache[student.ID]; } else { semesterScoreRecordList = new List <JHSemesterScoreRecord>(); } Dictionary <string, List <decimal> > domainScores = new Dictionary <string, List <decimal> >(); foreach (JHSemesterScoreRecord record in semesterScoreRecordList) { foreach (K12.Data.DomainScore domain in record.Domains.Values) { if (!domainScores.ContainsKey(domain.Domain)) { domainScores.Add(domain.Domain, new List <decimal>()); } if (domain.Score.HasValue) { domainScores[domain.Domain].Add(domain.Score.Value); } } if (!domainScores.ContainsKey(LearnDomain)) { domainScores.Add(LearnDomain, new List <decimal>()); } if (record.LearnDomainScore.HasValue) { domainScores[LearnDomain].Add(record.LearnDomainScore.Value); } if (!domainScores.ContainsKey(CourseLearn)) { domainScores.Add(CourseLearn, new List <decimal>()); } if (record.CourseLearnScore.HasValue) { domainScores[CourseLearn].Add(record.CourseLearnScore.Value); } } #endregion #region 產生畢業成績資料 GradScoreRecordEditor editor; GradScoreRecord gradScoreRecord = GradScore.Instance.Items[student.ID]; if (gradScoreRecord != null) { editor = gradScoreRecord.GetEditor(); } else { editor = new GradScoreRecordEditor(student); } editor.LearnDomainScore = null; editor.CourseLearnScore = null; editor.Domains.Clear(); foreach (string domain in domainScores.Keys) { decimal total = 0; decimal count = domainScores[domain].Count; if (count <= 0) { continue; } foreach (decimal score in domainScores[domain]) { total += score; } total = total / count; total = calc[calcID].ParseGraduateScore(total); if (domain == LearnDomain) { editor.LearnDomainScore = total; } else if (domain == CourseLearn) { editor.CourseLearnScore = total; } else { if (!editor.Domains.ContainsKey(domain)) { editor.Domains.Add(domain, new GradDomainScore(domain)); } editor.Domains[domain].Score = total; } } editors.Add(editor); #endregion worker.ReportProgress((int)(studentCount * 100 / studentTotal)); } }; worker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { FISCA.Presentation.MotherForm.SetStatusBarMessage("計算畢業成績中", e.ProgressPercentage); }; worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) { MsgBox.Show("計算畢業成績時發生錯誤。" + e.Error.Message); editors.Clear(); } else { multiWorker.RunWorkerAsync(editors); } }; multiWorker.DoWork += delegate(object sender, PackageDoWorkEventArgs <GradScoreRecordEditor> e) { IEnumerable <GradScoreRecordEditor> list = e.Items; list.SaveAllEditors(); }; multiWorker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { FISCA.Presentation.MotherForm.SetStatusBarMessage("上傳畢業成績中", e.ProgressPercentage); }; multiWorker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) { MsgBox.Show("上傳畢業成績時發生錯誤。" + e.Error.Message); } else { FISCA.Presentation.MotherForm.SetStatusBarMessage("上傳畢業成績完成"); } }; worker.RunWorkerAsync(); }
public ScoreCalculator(JHScoreCalcRuleRecord record) : base(record) { }
private void CalcWorker_DoWork(object sender, DoWorkEventArgs e) { bool error = false; List <StudentRecord> students = _students; List <string> student_ids = new List <string>(); foreach (StudentRecord each in students) { student_ids.Add(each.ID); } double total = students.Count; double count = 0; #region 寫入學期歷程 if (_studentHistoryDict != null && _studentHistoryDict.Count > 0) { try { List <JHSchool.Data.JHSemesterHistoryRecord> list = new List <JHSchool.Data.JHSemesterHistoryRecord>(); int size = 50; double count2 = 0; double total2 = _studentHistoryDict.Count; foreach (JHSchool.Data.JHSemesterHistoryRecord record in _studentHistoryDict.Values) { if (_calc_worker.CancellationPending) { return; } list.Add(record); count2++; if (list.Count == size) { JHSchool.Data.JHSemesterHistory.Update(list); list.Clear(); _calc_worker.ReportProgress((int)(count2 * 100 / total2), "寫入學期歷程中…"); } } if (list.Count > 0) { JHSchool.Data.JHSemesterHistory.Update(list); list.Clear(); _calc_worker.ReportProgress(100, "學期歷程寫入完成"); } } catch (Exception ex) { MsgBox.Show("寫入學期歷程失敗。" + ex.Message); e.Result = null; return; } } #endregion #region 計算課程成績 _viewer.Clear(); _viewer.SetHeader("課程"); _calc_worker.ReportProgress(0, "計算課程成績…"); if (_calc_worker.CancellationPending) { return; } _raw_data = new CourseDataLoader(); _raw_data.LoadCalculationData(this, _students, intSchoolYear.Value, intSemester.Value); foreach (CW.Course course in _raw_data.Courses.Values) { if (string.IsNullOrEmpty(course.ExamTemplateId) && course.ExamRequired) { _viewer.SetMessage(course.CourseName, new List <string>(new string[] { "缺少評量設定" })); error = true; } } if (error) { e.Result = error; return; } _viewer.Clear(); if (_calc_worker.CancellationPending) { return; } CourseScoreCalculate calculate = new CourseScoreCalculate(_raw_data.Courses); calculate.Calculate(); foreach (CW.Course course in _raw_data.Courses.Values) { Dictionary <string, string> examLacks = new Dictionary <string, string>(); Dictionary <string, int> examScoreLacks = new Dictionary <string, int>(); Dictionary <string, int> examEffortLacks = new Dictionary <string, int>(); List <CW.SCAttend> scattends = new List <CW.SCAttend>(); List <CW.SCAttend> no_exam_scattends = new List <CW.SCAttend>(); foreach (CW.SCAttend scattend in course.SCAttends.Values) { if (student_ids.Contains(scattend.StudentIdentity)) { if (scattend.ContainsLack) { scattends.Add(scattend); } if (scattend.NoExam) { no_exam_scattends.Add(scattend); } } } foreach (CW.SCAttend scattend in scattends) { foreach (string exam in scattend.ScoreLack) { if (!examLacks.ContainsKey(exam)) { examLacks.Add(exam, ""); } if (!examScoreLacks.ContainsKey(exam)) { examScoreLacks.Add(exam, 0); } examScoreLacks[exam]++; } foreach (string exam in scattend.EffortLack) { if (!examLacks.ContainsKey(exam)) { examLacks.Add(exam, ""); } if (!examEffortLacks.ContainsKey(exam)) { examEffortLacks.Add(exam, 0); } examEffortLacks[exam]++; } } if (scattends.Count > 0) { List <string> msgs = new List <string>(); foreach (string exam in new List <string>(examLacks.Keys)) { if (examScoreLacks.ContainsKey(exam)) { examLacks[exam] += "有" + examScoreLacks[exam] + "位學生缺少分數評量,"; } if (examEffortLacks.ContainsKey(exam)) { examLacks[exam] += "有" + examEffortLacks[exam] + "位學生缺少努力程度,"; } if (!string.IsNullOrEmpty(examLacks[exam])) { examLacks[exam] = examLacks[exam].Substring(0, examLacks[exam].Length - 1); } msgs.Add(exam + ":" + examLacks[exam]); } _viewer.SetMessage(course.CourseName, msgs); error = true; } if (no_exam_scattends.Count > 0) { _viewer.SetMessage(course.CourseName, new List <string>(new string[] { "沒有設定各次評量" })); error = true; } } if (error) { e.Result = true; return; } if (_calc_worker.CancellationPending) { return; } CourseScoreUpdater updater = new CourseScoreUpdater(_raw_data.Courses, this, false); updater.UpdateToServer(); #endregion #region 計算學期成績 //List<SemesterScoreRecordEditor> editors = new List<SemesterScoreRecordEditor>(); List <JHSemesterScoreRecord> semesterScoreRecordList = new List <JHSchool.Data.JHSemesterScoreRecord>(); JHSchool.Evaluation.SCAttend.Instance.SyncAllBackground(); Dictionary <string, List <JHSemesterScoreRecord> > studentSemesterScoreCache = new Dictionary <string, List <JHSchool.Data.JHSemesterScoreRecord> >(); foreach (JHSemesterScoreRecord record in JHSemesterScore.SelectByStudentIDs(students.AsKeyList())) { if (!studentSemesterScoreCache.ContainsKey(record.RefStudentID)) { studentSemesterScoreCache.Add(record.RefStudentID, new List <JHSchool.Data.JHSemesterScoreRecord>()); } studentSemesterScoreCache[record.RefStudentID].Add(record); } count = 0; foreach (StudentRecord each in students) { count++; ScoreCalcRuleRecord old = GetScoreCalcRuleRecord(each); JHScoreCalcRuleRecord dalrecord = null; if (old != null) { List <JHScoreCalcRuleRecord> list = JHScoreCalcRule.SelectByIDs(new string[] { old.ID }); if (list.Count > 0) { dalrecord = list[0]; } } ScoreCalculator calculator = new ScoreCalculator(dalrecord); List <SCAttendRecord> scattends = new List <SCAttendRecord>(); foreach (SCAttendRecord scattend in JHSchool.Evaluation.SCAttend.Instance.GetStudentAttend(each.ID)) { CourseRecord course = scattend.Course; if (course.SchoolYear == intSchoolYear.Value && course.Semester == intSemester.Value && !string.IsNullOrEmpty(course.RefAssessmentSetupID) && course.CalculationFlag == "1" ) { scattends.Add(scattend); } } if (scattends.Count > 0) { List <K12.Data.SubjectScore> subjectScores = _inner_calculator.CalculateSubjectScore(scattends); foreach (K12.Data.SubjectScore subject in subjectScores) { subject.Score = calculator.ParseSubjectScore((decimal)subject.Score); } List <K12.Data.DomainScore> domainScores = _inner_calculator.CalculateDomainScore(subjectScores); foreach (K12.Data.DomainScore domain in domainScores) { domain.Score = calculator.ParseDomainScore((decimal)domain.Score); } List <K12.Data.DomainScore> domainListWithoutElastic = new List <K12.Data.DomainScore>(); bool hasElasticCourse = false; foreach (K12.Data.DomainScore domain in domainScores) { if (domain.Domain == "彈性課程") { hasElasticCourse = true; } else { domainListWithoutElastic.Add(domain); } } decimal?learnDomainScore = calculator.ParseLearnDomainScore(_inner_calculator.CalculateTotalDomainScore(domainListWithoutElastic)); decimal?courseLearnScore = null; if (hasElasticCourse) { courseLearnScore = calculator.ParseLearnDomainScore(_inner_calculator.CalculateTotalDomainScore(domainScores)); } JHSemesterScoreRecord current = null; if (studentSemesterScoreCache.ContainsKey(each.ID)) { foreach (JHSemesterScoreRecord record in studentSemesterScoreCache[each.ID]) { if (record.SchoolYear == intSchoolYear.Value && record.Semester == intSemester.Value) { current = record; } } } if (current != null) { //editor = current.GetEditor(); current.Subjects = new Dictionary <string, K12.Data.SubjectScore>(); current.Domains = new Dictionary <string, K12.Data.DomainScore>(); } else { //current = new SemesterScoreRecordEditor(each, intSchoolYear.Value, intSemester.Value, _gradeYears[each.ID]); current = new JHSchool.Data.JHSemesterScoreRecord(); current.RefStudentID = each.ID; current.SchoolYear = intSchoolYear.Value; current.Semester = intSemester.Value; } foreach (K12.Data.SubjectScore subject in subjectScores) { current.Subjects.Add(subject.Subject, subject); } foreach (K12.Data.DomainScore domain in domainScores) { current.Domains.Add(domain.Domain, domain); } current.LearnDomainScore = learnDomainScore; current.CourseLearnScore = courseLearnScore; //editors.Add(editor); semesterScoreRecordList.Add(current); } _calc_worker.ReportProgress((int)((double)count * 100 / (double)total), "計算學期成績…"); } e.Result = semesterScoreRecordList; #endregion }