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();
        }
Пример #2
0
        protected override void OnSaveButtonClick(EventArgs e)
        {
            dgv.EndEdit();

            if (!IsValid())
            {
                MsgBox.Show("請先修正錯誤。");
                return;
            }

            GradScoreRecordEditor editor;

            if (_record != null)
            {
                editor = _record.GetEditor();
            }
            else
            {
                editor = new GradScoreRecordEditor(Student.Instance.Items[PrimaryKey]);
            }

            foreach (DataGridViewRow row in dgv.Rows)
            {
                string domain = "" + row.Cells[chDomain.Index].Value;
                string value  = "" + row.Cells[chScore.Index].Value;

                if ("" + row.Tag == "LearnDomain")
                {
                    if (!string.IsNullOrEmpty(value))
                    {
                        editor.LearnDomainScore = decimal.Parse(value);
                    }
                    else
                    {
                        editor.LearnDomainScore = null;
                    }
                }
                else if ("" + row.Tag == "CourseLearn")
                {
                    if (!string.IsNullOrEmpty(value))
                    {
                        editor.CourseLearnScore = decimal.Parse(value);
                    }
                    else
                    {
                        editor.CourseLearnScore = null;
                    }
                }
                else
                {
                    if (!editor.Domains.ContainsKey(domain))
                    {
                        editor.Domains.Add(domain, new GradDomainScore(domain));
                    }

                    if (!string.IsNullOrEmpty(value))
                    {
                        editor.Domains[domain].Score = decimal.Parse(value);
                    }
                    else
                    {
                        editor.Domains[domain].Score = null;
                    }
                }
            }

            //foreach (TextBox txt in _txtBoxes)
            //{
            //    string domain = "" + txt.Tag;
            //    if (!editor.Domains.ContainsKey(domain))
            //        editor.Domains.Add(domain, new GradDomainScore(domain));

            //    if (!string.IsNullOrEmpty(txt.Text))
            //        editor.Domains[domain].Score = decimal.Parse(txt.Text);
            //}

            //if (!string.IsNullOrEmpty(txtLearnDomain.Text))
            //    editor.LearnDomainScore = decimal.Parse(txtLearnDomain.Text);

            //if (!string.IsNullOrEmpty(txtCourseLearn.Text))
            //    editor.CourseLearnScore = decimal.Parse(txtCourseLearn.Text);

            editor.Save();
            SaveLog(editor);
            _listener.Reset();
            SaveButtonVisible = CancelButtonVisible = false;

            base.OnSaveButtonClick(e);
        }
Пример #3
0
        public override void InitializeImport(SmartSchool.API.PlugIn.Import.ImportWizard wizard)
        {
            Dictionary <string, int>             _ID_SchoolYear_Semester_GradeYear = new Dictionary <string, int>();
            Dictionary <string, List <string> >  _ID_SchoolYear_Semester_Subject   = new Dictionary <string, List <string> >();
            Dictionary <string, JHStudentRecord> _StudentCollection = new Dictionary <string, JHStudentRecord>();
            Dictionary <JHStudentRecord, Dictionary <int, decimal> > _StudentPassScore = new Dictionary <JHStudentRecord, Dictionary <int, decimal> >();

            wizard.PackageLimit = 3000;
            wizard.ImportableFields.AddRange("領域", "分數評量");
            wizard.RequiredFields.AddRange("領域", "分數評量");

            wizard.ValidateStart += delegate(object sender, SmartSchool.API.PlugIn.Import.ValidateStartEventArgs e)
            {
                #region ValidateStart
                _ID_SchoolYear_Semester_GradeYear.Clear();
                _ID_SchoolYear_Semester_Subject.Clear();
                _StudentCollection.Clear();

                List <JHStudentRecord> list = JHStudent.SelectByIDs(e.List);

                MultiThreadWorker <JHStudentRecord> loader = new MultiThreadWorker <JHStudentRecord>();
                loader.MaxThreads     = 3;
                loader.PackageSize    = 250;
                loader.PackageWorker += delegate(object sender1, PackageWorkEventArgs <JHStudentRecord> e1)
                {
                    GradScore.Instance.SyncDataBackground(e.List);
                };
                loader.Run(list);

                foreach (JHStudentRecord stu in list)
                {
                    if (!_StudentCollection.ContainsKey(stu.ID))
                    {
                        _StudentCollection.Add(stu.ID, stu);
                    }
                }
                #endregion
            };
            wizard.ValidateRow += delegate(object sender, SmartSchool.API.PlugIn.Import.ValidateRowEventArgs e)
            {
                #region ValidateRow
                int             t;
                decimal         d;
                JHStudentRecord student;
                if (_StudentCollection.ContainsKey(e.Data.ID))
                {
                    student = _StudentCollection[e.Data.ID];
                }
                else
                {
                    e.ErrorMessage = "壓根就沒有這個學生" + e.Data.ID;
                    return;
                }
                bool inputFormatPass = true;
                #region 驗各欄位填寫格式
                foreach (string field in e.SelectFields)
                {
                    string value = e.Data[field];
                    switch (field)
                    {
                    default:
                        break;

                    case "領域":
                        //if (value == "")
                        //{
                        //    inputFormatPass &= false;
                        //    e.ErrorFields.Add(field, "必須填寫");
                        //}
                        //else if (!Domains.Contains(value))
                        //{
                        //    inputFormatPass &= false;
                        //    e.ErrorFields.Add(field, "必須為七大領域、學習領域、課程學習");
                        //}
                        break;

                    case "分數評量":
                        if (value != "" && !decimal.TryParse(value, out d))
                        {
                            inputFormatPass &= false;
                            e.ErrorFields.Add(field, "必須填入空白或數值");
                        }
                        break;
                    }
                }
                #endregion
                //輸入格式正確才會針對情節做檢驗
                if (inputFormatPass)
                {
                    string errorMessage = "";

                    string key  = e.Data.ID;
                    string skey = e.Data["領域"];

                    if (!_ID_SchoolYear_Semester_Subject.ContainsKey(key))
                    {
                        _ID_SchoolYear_Semester_Subject.Add(key, new List <string>());
                    }
                    if (_ID_SchoolYear_Semester_Subject[key].Contains(skey))
                    {
                        errorMessage += (errorMessage == "" ? "" : "\n") + "同一學生不允許多筆相同畢業領域的資料";
                    }
                    else
                    {
                        _ID_SchoolYear_Semester_Subject[key].Add(skey);
                    }

                    e.ErrorMessage = errorMessage;
                }
                #endregion
            };

            wizard.ImportPackage += delegate(object sender, SmartSchool.API.PlugIn.Import.ImportPackageEventArgs e)
            {
                #region ImportPackage
                Dictionary <string, List <RowData> > id_Rows = new Dictionary <string, List <RowData> >();
                #region 分包裝
                foreach (RowData data in e.Items)
                {
                    if (!id_Rows.ContainsKey(data.ID))
                    {
                        id_Rows.Add(data.ID, new List <RowData>());
                    }
                    id_Rows[data.ID].Add(data);
                }
                #endregion

                Dictionary <string, GradScoreRecordEditor> gradDict = new Dictionary <string, GradScoreRecordEditor>();

                //交叉比對各學生資料
                #region 交叉比對各學生資料
                foreach (string id in id_Rows.Keys)
                {
                    JHStudentRecord studentRec = _StudentCollection[id];

                    GradScoreRecord       record = GradScore.Instance.Items[studentRec.ID];
                    GradScoreRecordEditor editor = null;
                    if (record != null)
                    {
                        editor = record.GetEditor();
                    }
                    else
                    {
                        editor = new GradScoreRecordEditor(Student.Instance.Items[studentRec.ID]);
                    }

                    if (!gradDict.ContainsKey(studentRec.ID))
                    {
                        gradDict.Add(studentRec.ID, editor);
                    }

                    //要匯入的學期科目成績
                    Dictionary <string, RowData> importScoreDictionary = new Dictionary <string, RowData>();

                    #region 整理要匯入的資料
                    foreach (RowData row in id_Rows[id])
                    {
                        int    t;
                        string domain = row["領域"];

                        if (!importScoreDictionary.ContainsKey(domain))
                        {
                            importScoreDictionary.Add(domain, row);
                        }
                    }
                    #endregion

                    //開始處理ImportScore
                    foreach (string domain in importScoreDictionary.Keys)
                    {
                        RowData data = importScoreDictionary[domain];
                        if (domain == "學習領域")
                        {
                            decimal d;
                            if (decimal.TryParse(data["分數評量"], out d))
                            {
                                editor.LearnDomainScore = d;
                            }
                            else
                            {
                                editor.LearnDomainScore = null;
                            }
                        }
                        else if (domain == "課程學習")
                        {
                            decimal d;
                            if (decimal.TryParse(data["分數評量"], out d))
                            {
                                editor.CourseLearnScore = d;
                            }
                            else
                            {
                                editor.CourseLearnScore = null;
                            }
                        }
                        else
                        {
                            if (!editor.Domains.ContainsKey(domain))
                            {
                                editor.Domains.Add(domain, new GradDomainScore(domain));
                            }
                            decimal d;
                            if (decimal.TryParse(data["分數評量"], out d))
                            {
                                editor.Domains[domain].Score = d;
                            }
                            else
                            {
                                editor.Domains[domain].Score = null;
                            }
                        }
                    }
                }
                #endregion

                if (gradDict.Values.Count > 0)
                {
                    #region 分批次兩路上傳
                    List <List <GradScoreRecordEditor> > updatePackages  = new List <List <GradScoreRecordEditor> >();
                    List <List <GradScoreRecordEditor> > updatePackages2 = new List <List <GradScoreRecordEditor> >();
                    {
                        List <GradScoreRecordEditor> package = null;
                        int count = 0;
                        foreach (GradScoreRecordEditor var in gradDict.Values)
                        {
                            if (count == 0)
                            {
                                package = new List <GradScoreRecordEditor>(30);
                                count   = 30;
                                if ((updatePackages.Count & 1) == 0)
                                {
                                    updatePackages.Add(package);
                                }
                                else
                                {
                                    updatePackages2.Add(package);
                                }
                            }
                            package.Add(var);
                            count--;
                        }
                    }
                    Thread threadUpdateSemesterSubjectScore = new Thread(new ParameterizedThreadStart(updateSemesterSubjectScore));
                    threadUpdateSemesterSubjectScore.IsBackground = true;
                    threadUpdateSemesterSubjectScore.Start(updatePackages);
                    Thread threadUpdateSemesterSubjectScore2 = new Thread(new ParameterizedThreadStart(updateSemesterSubjectScore));
                    threadUpdateSemesterSubjectScore2.IsBackground = true;
                    threadUpdateSemesterSubjectScore2.Start(updatePackages2);

                    threadUpdateSemesterSubjectScore.Join();
                    threadUpdateSemesterSubjectScore2.Join();
                    #endregion
                }

                FISCA.LogAgent.ApplicationLog.Log("成績系統.匯入匯出", "匯入畢業成績", "總共匯入" + gradDict.Values.Count + "筆畢業成績。");
                #endregion
            };
            wizard.ImportComplete += delegate
            {
                //EventHub.Instance.InvokScoreChanged(new List<string>(_StudentCollection.Keys).ToArray());
            };
        }