private MailLogBase InitMailLog(UDT.CSConfiguration Conf_Subject, UDT.CSConfiguration Conf_Content, string EmailCategory)
 {
     dynamic course = (this.cboCourse.Items[this.cboCourse.SelectedIndex] as ComboItem).Tag;
     int SchoolYear = int.Parse(course.SchoolYear + "");
     int Semester = int.Parse(course.Semester + "");
     string user_account = FISCA.Authentication.DSAServices.UserAccount;
     string Subject = Conf_Subject.Content;
     string Content = Conf_Content.Content;
     MailLogBase mailLogBase = new MailLogBase(SchoolYear, Semester, user_account, this.from_email, this.from_name, Subject, Content, EmailCategory, Guid.NewGuid().ToString());
     return mailLogBase;
 }
        public MailLog(bool IsCC, MailLogBase MailLogBase)
        {
            this.IsCC = IsCC;
            this.MailLogBase = MailLogBase;

            this.SectionIDs = new List<string>();
        }
        private void SendEMail(MailLogBase MailLogBase, int AttendNo)
        {
            dynamic course = (this.cboCourse.Items[this.cboCourse.SelectedIndex] as ComboItem).Tag;

            List<string> StudentIDs = new List<string>();
            Dictionary<string, Dictionary<int, string>> dicSections = new Dictionary<string, Dictionary<int, string>>();
            Dictionary<string, string> dicAttendNos = new Dictionary<string, string>();
            List<string> ErrorMessages = new List<string>();
            foreach (DataGridViewRow row in this.dg.Rows)
            {
                if (row.IsNewRow)
                    continue;

                bool is_cancel = false;
                if (bool.TryParse(row.Cells[3].Value + "", out is_cancel) && is_cancel)
                    continue;

                string StudentID = row.Tag + "";

                bool bChecked = false;
                bool.TryParse(row.Cells[4].Value + "", out bChecked);

                int attend_no = 0;
                int.TryParse(row.Cells[2].Value + "", out attend_no);
                if ((attend_no < AttendNo) && bChecked)
                    ErrorMessages.Add(string.Format("學號「{0}」,姓名「{1}」,缺課次數「{2}」", row.Cells[0].Value + "", row.Cells[1].Value + "", row.Cells[2].Value + ""));

                if (!dicAttendNos.ContainsKey(StudentID))
                    dicAttendNos.Add(StudentID, attend_no.ToString());

                if (bChecked && this.dg.Columns.Count > 6)
                {
                    StudentIDs.Add(StudentID);

                    if (!dicSections.ContainsKey(StudentID))
                        dicSections.Add(StudentID, new Dictionary<int, string>());

                    for (int j = 7; j < this.dg.Columns.Count; j++)
                    {
                        if (row.Cells[j].Value + "" != "缺")
                            continue;

                        object[] sections = this.dg.Columns[j].Tag as object[];
                        DateTime begin_time = DateTime.Parse(sections[0] + "");
                        DateTime end_time = DateTime.Parse(sections[1] + "");
                        string sDate = begin_time.Year.ToString().Length == 4 ? begin_time.ToString("yyyy/MM/dd") : (begin_time.Year + 1911) + "/" + begin_time.Month.ToString("00") + "/" + begin_time.Day.ToString("00");
                        string bTime =begin_time.Hour.ToString("00") + ":" + begin_time.Minute.ToString("00");
                        string eTime = end_time.Hour.ToString("00") + ":" + end_time.Minute.ToString("00");
                        string section_time = sDate + " " + bTime + "~" + eTime;

                        dicSections[StudentID].Add(j, section_time);
                    }
                }
            }
            if (ErrorMessages.Count > 0)
                throw new Exception(string.Format("待寄出之缺課通知為缺課{0}次通知,但下列學生缺課未達寄發之缺課次數:\n\n" + string.Join("\n", ErrorMessages), AttendNo));

            MandrillApi mandrill = new MandrillApi(this.MandrillAPIKey, false);

            string pong = string.Empty;

            try
            {
                pong = mandrill.Ping();
            }
            catch (Exception ex)
            {
                MessageBox.Show("未正確設定「MandrillAPIKey」, 錯誤訊息:" + ex.Message);
                this.btnSend.Enabled = true;
                this.btnSend2.Enabled = true;
                this.circularProgress.Visible = false;
                this.circularProgress.IsRunning = false;
                return;
            }
            if (!pong.ToUpper().Contains("PONG!"))
            {
                MessageBox.Show("未正確設定「MandrillAPIKey」。");
                this.btnSend.Enabled = true;
                this.btnSend2.Enabled = true;
                this.circularProgress.Visible = false;
                this.circularProgress.IsRunning = false;
                return;
            }

            Task<List<UDT.MailLog>> task = Task < List<UDT.MailLog>>.Factory.StartNew(() =>
            {
                List<UDT.MailLog> MandrillSendLogs = new List<UDT.MailLog>();
                this.SendEmails(StudentIDs, course, dicSections, dicAttendNos, MailLogBase, mandrill, MandrillSendLogs);
                return MandrillSendLogs;
            });
            task.ContinueWith((x) =>
            {
                this.btnSend.Enabled = true;
                this.btnSend2.Enabled = true;
                this.circularProgress.Visible = false;
                this.circularProgress.IsRunning = false;

                if (x.Exception != null)
                    MessageBox.Show(x.Exception.InnerException.Message);
                else
                {
                    x.Result.SaveAll();
                    this.UpdateLogShow(x.Result);
                    MessageBox.Show("已寄出缺課通知。");
                }

            }, TaskScheduler.FromCurrentSynchronizationContext());
        }
        /// <summary>
        /// 批次寄送缺課通知
        /// </summary>
        /// <param name="StudentIDs"></param>
        /// <param name="Course"></param>
        /// <param name="dicSections"></param>
        /// <param name="dicAttendNos"></param>
        /// <param name="Subject"></param>
        /// <param name="Content"></param>
        /// <param name="template_name"></param>
        /// <param name="mandrill"></param>
        private void SendEmails(List<string> StudentIDs, dynamic Course, Dictionary<string, Dictionary<int, string>> dicSections, Dictionary<string, string> dicAttendNos, MailLogBase MailLogBase, MandrillApi mandrill, List<UDT.MailLog> MandrillSendLogs)
        {
            if (StudentIDs.Count == 0)
                throw new Exception("請先勾選學生。");

            List<string> ErrorEmails = this.GetErrorEmails(StudentIDs);
            if (ErrorEmails.Count > 0)
            {
                string error_email_alert_message = "下列學生及其電子郵件格式有誤,請先修正:\n\n";
                ErrorEmails.ForEach((x) => error_email_alert_message += (x + "\n"));

                throw new Exception(error_email_alert_message);
            }

            MailLog mail_log = new MailLog(false, MailLogBase);
            foreach (string StudentID in StudentIDs)
            {
                if (!this.dicStudentEmails.ContainsKey(StudentID))
                    continue;

                List<dynamic> emails = dicStudentEmails[StudentID];
                List<string> Emails = new List<string>();
                string StudentName = string.Empty;
                foreach (dynamic o in emails)
                {
                    string student_number = o.學號 + "";
                    StudentName = o.學生姓名 + "";
                    string e0 = o.登入帳號 + "";
                    string e1 = o.電子郵件一 + "";
                    string e2 = o.電子郵件二 + "";
                    string e3 = o.電子郵件三 + "";
                    string e4 = o.電子郵件四 + "";
                    string e5 = o.電子郵件五 + "";

                    if (!string.IsNullOrEmpty(e0))
                        Emails.Add(e0);
                    if (!string.IsNullOrEmpty(e1))
                        Emails.Add(e1);
                    if (!string.IsNullOrEmpty(e2))
                        Emails.Add(e2);
                    if (!string.IsNullOrEmpty(e3))
                        Emails.Add(e3);
                    if (!string.IsNullOrEmpty(e4))
                        Emails.Add(e4);
                    if (!string.IsNullOrEmpty(e5))
                        Emails.Add(e5);
                }
                mail_log = new MailLog(false, MailLogBase);
                mail_log.StudentID = StudentID;
                mail_log.CourseID = Course.CourseID + "";
                List<int> ColumnIndexs = dicSections[StudentID].Keys.ToList();
                ColumnIndexs.ForEach((x) => mail_log.AddSectionID(this.SectionIDs[x-7].ToString()));

                //  2014/06/07 09:00~12:40(補)
                List<string> absence = dicSections[StudentID].Values.ToList();
                string absence_dates = string.Join("、", absence.Select(x => x.Split(new char[]{' '}).ElementAt(0)));
                string absence_times = string.Empty;

                //.ToString("yyyy/MM/dd hh:mm:ss");
                if (absence.Count == 1)
                    absence_times = absence.ElementAt(0).Split(new char[] { ' ' }).ElementAt(1);
                else
                    absence_times = string.Join("、", absence);

                this.Emailing(mail_log, Emails.Distinct().ToList(), StudentName, Course.CourseName + "", dicAttendNos[StudentID], absence_times, mandrill, MandrillSendLogs, absence_dates);

                if (this.validated_cc.Count() > 0)
                {
                    mail_log = new MailLog(true, MailLogBase);
                    mail_log.StudentID = StudentID;
                    mail_log.CourseID = Course.CourseID + "";
                    ColumnIndexs.ForEach((x) => mail_log.AddSectionID(this.SectionIDs[x - 7].ToString()));
                    this.Emailing(mail_log, this.validated_cc.Distinct().ToList(), StudentName, Course.CourseName + "", dicAttendNos[StudentID], absence_times, mandrill, MandrillSendLogs, absence_dates);
                }
            }
        }
        private void SendEMail(MailLogBase MailLogBase)
        {
            dynamic course = (this.cboCourse.Items[this.cboCourse.SelectedIndex] as ComboItem).Tag;

            List<string> StudentIDs = new List<string>();
            Dictionary<string, Dictionary<int, string>> dicSections = new Dictionary<string, Dictionary<int, string>>();
            Dictionary<string, string> dicAttendNos = new Dictionary<string, string>();
            Dictionary<int, object> CheckedColumns = new Dictionary<int, object>();

            foreach(DataGridViewColumn column in this.dg.Columns)
            {
                if (column.HeaderCell.GetType().Name != "DatagridViewCheckBoxHeaderCell")
                    continue;

                if ((column.HeaderCell as DatagridViewCheckBoxHeaderCell).Checked)
                    CheckedColumns.Add(column.Index, column.Tag);
            }
            if (CheckedColumns.Count == 0)
                throw new Exception("請先勾選日期。");

            foreach (DataGridViewRow row in this.dg.Rows)
            {
                if (row.IsNewRow)
                    continue;

                bool is_cancel = false;
                if (bool.TryParse(row.Cells[3].Value + "", out is_cancel) && is_cancel)
                    continue;

                string StudentID = row.Tag + "";

                int attend_no = 0;
                bool dirty = false;
                foreach (int j in CheckedColumns.Keys)
                {
                    if (string.IsNullOrEmpty(row.Cells[j].Value + ""))
                        continue;

                    dirty = true;

                    if (!dicSections.ContainsKey(StudentID))
                        dicSections.Add(StudentID, new Dictionary<int, string>());

                    object[] sections = this.dg.Columns[j].Tag as object[];
                    DateTime begin_time = DateTime.Parse(sections[0] + "");
                    DateTime end_time = DateTime.Parse(sections[1] + "");
                    string sDate = begin_time.Year.ToString().Length == 4 ? begin_time.ToString("yyyy/MM/dd") : (begin_time.Year + 1911) + "/" + begin_time.Month.ToString("00") + "/" + begin_time.Day.ToString("00");
                    string bTime = begin_time.Hour.ToString("00") + ":" + begin_time.Minute.ToString("00");
                    string eTime = end_time.Hour.ToString("00") + ":" + end_time.Minute.ToString("00");
                    string section_time = sDate + " " + bTime + "~" + eTime + ((row.Cells[j].Value + "").Contains("補") ? "(補)" : "");

                    dicSections[StudentID].Add(j, section_time);

                    if (!(row.Cells[j].Value + "").Contains("補"))
                        attend_no += 1;
                }
                if (dirty)
                {
                    StudentIDs.Add(StudentID);

                    if (!dicAttendNos.ContainsKey(StudentID))
                        dicAttendNos.Add(StudentID, attend_no.ToString());
                }
            }

            if (StudentIDs.Count == 0)
                throw new Exception("勾選日期沒有學生缺(補)課。");

            MandrillApi mandrill = new MandrillApi(this.MandrillAPIKey, false);

            string pong = string.Empty;

            try
            {
                pong = mandrill.Ping();
            }
            catch (Exception ex)
            {
                MessageBox.Show("未正確設定「MandrillAPIKey」, 錯誤訊息:" + ex.Message);
                this.btnSend.Enabled = true;
                this.btnSend2.Enabled = true;
                this.circularProgress.Visible = false;
                this.circularProgress.IsRunning = false;
                return;
            }
            if (!pong.ToUpper().Contains("PONG!"))
            {
                MessageBox.Show("未正確設定「MandrillAPIKey」。");
                this.btnSend.Enabled = true;
                this.btnSend2.Enabled = true;
                this.circularProgress.Visible = false;
                this.circularProgress.IsRunning = false;
                return;
            }

            Task<List<UDT.MailLog>> task = Task<List<UDT.MailLog>>.Factory.StartNew(() =>
            {
                List<UDT.MailLog> MandrillSendLogs = new List<UDT.MailLog>();
                this.SendEmails(StudentIDs, course, dicSections, dicAttendNos, MailLogBase, mandrill, MandrillSendLogs);
                return MandrillSendLogs;
            });
            task.ContinueWith((x) =>
            {
                this.btnSend.Enabled = true;
                this.btnSend2.Enabled = true;
                this.circularProgress.Visible = false;
                this.circularProgress.IsRunning = false;

                if (x.Exception != null)
                    MessageBox.Show(x.Exception.InnerException.Message);
                else
                {
                    x.Result.SaveAll();
                    this.UpdateLogShow(x.Result);
                    MessageBox.Show("已寄出缺課通知。");
                }

            }, TaskScheduler.FromCurrentSynchronizationContext());
        }