private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            _raw_data = new CourseDataLoader();
            _raw_data.LoadCalculationData(this);

            CourseScoreCalculate calculate = new CourseScoreCalculate(_raw_data.Courses);

            calculate.Calculate();
        }
        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
        }