global class CampaignSendMailBatch implements Database.Batchable<sObject> , Database.Stateful {
  public boolean isService;
  public boolean isServiceReport;
  private boolean result;
  private string Errorstr;
  private string logstr;
  global CampaignSendMailBatch(boolean isService) {
    this.isService = isService;
    //this.isServiceReport = false;
    this.result = true;
    this.Errorstr = '';
    this.logstr = '';
  }

  global CampaignSendMailBatch() {
    this.isService = false;
    //this.isServiceReport = false;
    this.result = true;
    this.Errorstr = '';
    this.logstr = '';
  }

  global CampaignSendMailBatch(string ServiceReport) {
    this.isServiceReport = true;
    this.isService = false;
    this.result = true;
    this.Errorstr = '';
    this.logstr = '';
  }

  global Database.QueryLocator start(Database.BatchableContext BC) {
    if (isServiceReport != null) {
      return Database.getQueryLocator(
                 [select Id, OwnerId, Owner.Dept__c, Owner.Email, Society_Type__c, Open_scope__c, Name2__c,
                  JingliApprovalManager__c, JingliApprovalManager__r.Email, BuchangApprovalManager__c, BuchangApprovalManager__r.Email,
                  WorkshopPlace__c, Workshop_category__c, StartDate__c,
                  EndDate__c, StartDate, EndDate,
                  CancleReason__c,
                  Mailflg_after45__c, Mailflg_cancel__c, Mailflg_before15__c, Mailflg_before7__c, Mailflg_after3__c
                  // 服务技师培训 2019/1/7 张玉山 start
                  , ServiceDesignDep__c, ServiceDesignDep__r.Email, Province__c, owner.Name, Status, Name, Cover_Area__c,
                  Salesdepartment__c,
                  Mailflg_6Month_service__c,  Mailflg_Approval_service__c, Mailflg_before7_service__c,
                  Mailflg_Cancel_Service__c , Mailflgafter3serviceDate__c, Mailflgafter3FinalserviceDate__c,
                  Lesson1Date__c, Lesson2Date__c, Lesson3Date__c, Lesson4Date__c, Lesson5Date__c,
                  Lesson6Date__c, Lesson7Date__c, Lesson8Date__c, FinalExamDate__c,
                  TrainingType__c, TeachingFrequency__c
                  // 服务技师培训 2019/1/7 张玉山 end
                  from Campaign
                  limit 1]
             );
    }
    return Database.getQueryLocator(
               [select Id, OwnerId, Owner.Dept__c, Owner.Email, Society_Type__c, Open_scope__c, Name2__c,
                JingliApprovalManager__c, JingliApprovalManager__r.Email, BuchangApprovalManager__c, BuchangApprovalManager__r.Email,
                WorkshopPlace__c, Workshop_category__c, StartDate__c,
                EndDate__c, StartDate, EndDate,
                CancleReason__c,
                Mailflg_after45__c, Mailflg_cancel__c, Mailflg_before15__c, Mailflg_before7__c, Mailflg_after3__c
                // 服务技师培训 2019/1/7 张玉山 start
                , ServiceDesignDep__c, ServiceDesignDep__r.Email, Province__c, owner.Name, Status, Name, Cover_Area__c,
                Salesdepartment__c,
                Mailflg_6Month_service__c,  Mailflg_Approval_service__c, Mailflg_before7_service__c,
                Mailflg_Cancel_Service__c , Mailflgafter3serviceDate__c, Mailflgafter3FinalserviceDate__c,
                Lesson1Date__c, Lesson2Date__c, Lesson3Date__c, Lesson4Date__c, Lesson5Date__c,
                Lesson6Date__c, Lesson7Date__c, Lesson8Date__c, FinalExamDate__c,
                TrainingType__c, TeachingFrequency__c
                // 服务技师培训 2019/1/7 张玉山 end
                from Campaign
                where Mailflg_after45__c = true
                                           or Mailflg_cancel__c = true
                                                   or Mailflg_before15__c = true
                                                           or Mailflg_before7__c = true
                                                                   or Mailflg_after3__c = true
                                                                           // 服务技师培训 2019/1/7 张玉山 start
                                                                           or (Mailflg_6Month_service__c > 0
                                                                                   and  ( Lesson8Date__c < : Date.today()
                                                                                           or (Lesson8Date__c = null
                                                                                                   and  Lesson4Date__c < : Date.today())
                                                                                        )
                                                                              )
                                                                           or FinalExamDate__c = : Date.today().addDays(-3)
                                                                                   or ( Lesson1Date__c = : Date.today().addDays(-3)
                                                                                           and
                                                                                           TeachingFrequency__c != '连续四天'
                                                                                      )
                                                                                   or ( Lesson2Date__c = : Date.today().addDays(-3)
                                                                                           and
                                                                                           TeachingFrequency__c != '连续四天'
                                                                                      )
                                                                                   or ( Lesson3Date__c = : Date.today().addDays(-3)
                                                                                           and
                                                                                           TeachingFrequency__c != '连续四天')
                                                                                   or ( Lesson4Date__c = : Date.today().addDays(-3)
                                                                                           and
                                                                                           TeachingFrequency__c != '连续四天')
                                                                                   or ( Lesson5Date__c = : Date.today().addDays(-3)
                                                                                           and
                                                                                           TeachingFrequency__c != '连续四天')
                                                                                   or ( Lesson6Date__c = : Date.today().addDays(-3)
                                                                                           and
                                                                                           TeachingFrequency__c != '连续四天')
                                                                                   or ( Lesson7Date__c = : Date.today().addDays(-3)
                                                                                           and
                                                                                           TeachingFrequency__c != '连续四天')
                                                                                   or ( Lesson8Date__c = : Date.today().addDays(-3)
                                                                                           and
                                                                                           TeachingFrequency__c != '连续四天')

                                                                                   or Mailflg_Approval_service__c = true
                                                                                           or Mailflg_before7_service__c = true
                                                                                                   or Mailflg_Cancel_Service__c = true
                                                                                                           // 服务技师培训 2019/1/7 张玉山 end
               ]
           );

  }



  global void execute(Database.BatchableContext BC, List<sObject> campaign) {

    List<Campaign> campaignList = campaign;
    List<Campaign> after45_List = new List<Campaign>();
    List<Campaign> cancel_List = new List<Campaign>();
    List<Campaign> before15_List = new List<Campaign>();
    List<Campaign> before7_List = new List<Campaign>();
    List<Campaign> after3_List = new List<Campaign>();

    // 服务技师培训 2019/1/7 张玉山 start
    // 检索出批准的带教报告发邮件
    List<Instruct_report__c> Instruct_reportList =
        [select Id, Name, Campaign__r.OwnerId, Campaign__r.Owner.Dept__c, Campaign__r.Owner.Email , Campaign__r.Owner.Name
         , Campaign__r.ServiceDesignDep__c, Campaign__r.ServiceDesignDep__r.Email  , Campaign__r.Status, campaign__r.Salesdepartment__c,
         campaign__r.Province__c, campaign__c, campaign__r.Name
         from Instruct_report__c
         where MailFlag_Approved__c = true
        ];
    // 检索出批准的授课、考核报告发邮件
    List<AssessmentReport__c> AssessmentReportList =
        [select Id, Name, Campaign__r.OwnerId, Campaign__r.Owner.Dept__c, Campaign__r.Owner.Email , Campaign__r.Owner.Name
         , Campaign__r.ServiceDesignDep__c, Campaign__r.ServiceDesignDep__r.Email , Campaign__r.Status , campaign__r.Salesdepartment__c,
         campaign__r.Province__c, campaign__c, Type__c, campaign__r.Name
         from AssessmentReport__c
         where MailFlag_Approved__c = true
        ];
    /*
     * 符合发邮件的服务技师培养项目，其中包括：
     *  考核结束后连续6个月每月第一个工作日提醒填写带教报告 ：sixMonthServiceList
     *  授课三天提醒提交授课报告 ： after3ServiceList
     *  考核三天提醒提交考核报告 ： after3FinalServiceList
     *  主页面审批通过： ApprovalServiceList
     *  开班前7天提醒 ： before7ServiceList
     *  主页面取消申请审批通过 ：CancelServiceList
     *
     */

    List<Campaign> sixMonthServiceList = new List<Campaign>();
    List<Campaign> after3ServiceList = new List<Campaign>();
    List<Campaign> after3FinalServiceList = new List<Campaign>();
    List<Campaign> ApprovalServiceList = new List<Campaign>();
    List<Campaign> before7ServiceList = new List<Campaign>();
    List<Campaign> CancelServiceList = new List<Campaign>();


    //每月到今天的工作日
    Date toDate = Date.today();
    Date yesterDate = toDate.addDays(-1);
    Date mon1stDate = Date.newInstance(toDate.year(), toDate.month(), 1);
    Integer workdays = UpdateUserTextColBatch.getOlympusWorkDayCount(mon1stDate, toDate);
    //每月到昨天的工作日
    Integer workdays1 = UpdateUserTextColBatch.getOlympusWorkDayCount(mon1stDate, yesterDate);

    Integer OSFBacth_Execute_Day = Integer.valueOf(System.Label.OSFBacth_Execute_Day);

    // 服务技师培训 2019/1/7 张玉山 end

    for (Campaign c : campaignList) {
      //system.debug('Campaign:' + c);
      Date startDate = c.StartDate;
      Date today = Date.today();
      if (!isService && isServiceReport == null ) {
        if (c.Mailflg_after45__c == true) {
          after45_List.add(c);
        }
        if (c.Mailflg_cancel__c == true) {
          cancel_List.add(c);
        }
        if (c.Mailflg_before15__c == true && startDate != null && today.daysBetween(startDate) >= 10) {
          before15_List.add(c);
        }
        if (c.Mailflg_before7__c == true  && startDate != null && today.daysBetween(startDate) >= 5) {
          before7_List.add(c);
        }
        if (c.Mailflg_after3__c == true) {
          after3_List.add(c);
        }
      }
      if (isService && isServiceReport == null) {
        // 服务技师培训 2019/1/7 张玉山 start
        // 考核结束后连续6个月每月第一个工作日提醒填写带教报告
        if (c.Mailflg_6Month_service__c > 0 && c.Mailflg_6Month_service__c < 7
                && workdays1 != OSFBacth_Execute_Day
                && workdays == OSFBacth_Execute_Day
           ) {
          sixMonthServiceList.add(c);
        }
        // 授课后三天提醒提交授课报告， 判断今天是否是否是各次授课后三天或者上次发送邮件失败了
        if (c.Status != null && c.Status.equals('公开中') && c.TeachingFrequency__c != null &&
                ((
                     c.EndDate__c == Date.today().addDays(-3)
                     && c.TeachingFrequency__c.equals('连续四天'))
                 ||
                 (c.TeachingFrequency__c != '连续四天' && (
                      c.Lesson1Date__c == Date.today().addDays(-3) ||
                      c.Lesson2Date__c == Date.today().addDays(-3) ||
                      c.Lesson3Date__c == Date.today().addDays(-3) ||
                      c.Lesson4Date__c == Date.today().addDays(-3) ||
                      c.Lesson5Date__c == Date.today().addDays(-3) ||
                      c.Lesson6Date__c == Date.today().addDays(-3) ||
                      c.Lesson7Date__c == Date.today().addDays(-3) ||
                      c.Lesson8Date__c == Date.today().addDays(-3)))
                 || c.Mailflgafter3serviceDate__c == true
                )
           ) {
          after3ServiceList.add(c);
        }
        if (c.FinalExamDate__c == Date.today().addDays(-3)
                ||  c.Mailflgafter3FinalserviceDate__c == true) {
          after3FinalServiceList.add(c);
        }

        if (c.Mailflg_Approval_service__c == true) {
          ApprovalServiceList.add(c);
        }

        if (c.Mailflg_before7_service__c == true
                && c.Status != '取消'
                && startDate != null
                && today.daysBetween(startDate) < 8
                && today.daysBetween(startDate) >= 4
           ) {
          before7ServiceList.add(c);
        }
        if (c.Mailflg_Cancel_Service__c == true ) {
          CancelServiceList.add(c);
        }
        // 服务技师培训 2019/1/7 张玉山 end
      }
    }

    boolean rs1 = true;
    boolean rs2 = true;
    boolean rs3 = true;
    boolean rs4 = true;
    boolean rs5 = true;
    // 服务技师培训 2019/1/7 张玉山 start
    boolean rs6   = true;

    boolean rs7   = true;
    boolean rs14   = true;
    boolean rs8     = true;
    boolean rs9   = true;
    boolean rs10   = true;

    boolean rs11   = true;
    boolean rs12   = true;
    boolean rs13   = true;

    system.debug('sixMonthServiceList:' + sixMonthServiceList);
    system.debug('after3ServiceList:' + after3ServiceList);
    system.debug('after3FinalServiceList:' + after3ServiceList);


    system.debug('ApprovalServiceList:' + ApprovalServiceList);
    system.debug('before7ServiceList:' + before7ServiceList);
    system.debug('CancelServiceList:' + CancelServiceList);

    system.debug('Instruct_reportList:' + Instruct_reportList);
    system.debug('AssessmentReportList:' + AssessmentReportList);



    if (isService && isServiceReport == null) {
      if (sixMonthServiceList.size() > 0) rs6 = sendMailService(sixMonthServiceList, 'sixMonthService');
      if (after3ServiceList.size() > 0) rs7 = sendMailService(after3ServiceList, 'after3Service');
      if (after3FinalServiceList.size() > 0) rs14 = sendMailService(after3FinalServiceList, 'after3FinalService');
      if (ApprovalServiceList.size() > 0) rs8 = sendMailService(ApprovalServiceList, 'ApprovalService');
      if (before7ServiceList.size() > 0) rs9 = sendMailService(before7ServiceList, 'before7Service');
      if (CancelServiceList.size() > 0) rs10 = sendMailService(CancelServiceList, 'CancelService');
    }
    if (AssessmentReportList.size() > 0 && isServiceReport != null) rs11 = sendMailAssessmentReport(AssessmentReportList);
    if (Instruct_reportList.size() > 0 && isServiceReport != null) rs12 = sendMailInstructReport(Instruct_reportList);
    if (date.today().month() == 11  && date.today().day()  == 30 && isServiceReport != null) {
      rs13 = sendMailAllFSE();
    }
    //sendMailAllFSE();
    // 服务技师培训 2019/1/7 张玉山 end
    if (!isService && isServiceReport == null) {
      if (after45_List.size() > 0) rs1 = sendMail(after45_List, 'after45');
      if (cancel_List.size() > 0) rs2 = sendMail(cancel_List, 'cancel');
      if (before15_List.size() > 0) rs3 = sendMail(before15_List, 'before15');
      if (before7_List.size() > 0) rs4 = sendMail(before7_List, 'before7');
      if (after3_List.size() > 0) rs5 = sendMail(after3_List, 'after3');
    }


    if (rs1 == false) system.debug('=====after45 failer');
    if (rs2 == false) system.debug('=====cancel failer');
    if (rs3 == false) system.debug('=====before15 failer');
    if (rs4 == false) system.debug('=====before7 failer');
    if (rs5 == false) system.debug('=====after3 failer');

    // 服务技师培训 2019/1/7 张玉山 start
    if (rs6 == false) system.debug('=====sixMonthService failer');
    if (rs7 == false) system.debug('=====after3Service failer');
    if (rs14 == false) system.debug('=====after3FinalService failer');
    if (rs8 == false) system.debug('=====ApprovalService failer');


    if (rs9 == false) system.debug('=====before7Service failer');
    if (rs10 == false) system.debug('=====CancelService failer');
    if (rs11 == false) system.debug('=====AssessmentReport failer');
    if (rs12 == false) system.debug('=====Instruct_report failer');
    if (rs13 == false) system.debug('=====sendMailAllFSE failer');
    if (isService && isServiceReport == null) {
      for (Campaign c : campaignList) {
        if (rs6 && c.Mailflg_6Month_service__c > 0
                && workdays1 != OSFBacth_Execute_Day
                && workdays == OSFBacth_Execute_Day
           ) {
          c.Mailflg_6Month_service__c--;
        }

        if (!rs7 && after3ServiceList.size() > 0) {
          c.Mailflgafter3serviceDate__c = true;
        } else if (after3ServiceList.size() > 0) {
          c.Mailflgafter3serviceDate__c = false;
        }
        if (!rs14 && after3FinalServiceList.size() > 0) {
          c.Mailflgafter3FinalserviceDate__c = true;
        } else if (after3FinalServiceList.size() > 0) {
          c.Mailflgafter3FinalserviceDate__c = false;
        }
        if (ApprovalServiceList.size() > 0 && rs8) {
          c.Mailflg_Approval_service__c = false;
        }
        if (before7ServiceList.size() > 0 && rs9) {
          c.Mailflg_before7_service__c = false;
        }
        if (CancelServiceList.size() > 0 && rs10) {
          c.Mailflg_Cancel_Service__c = false;
        }
      }
    }

    // 服务技师培训 2019/1/7 张玉山 end
    if (!isService && isServiceReport == null) {
      if (rs1 && rs2 && rs3 && rs4 && rs5) {
        for (Campaign c : campaignList) {
          if (after45_List.size() > 0) {
            c.Mailflg_after45__c = false;
          }
          if (cancel_List.size() > 0) {
            c.Mailflg_cancel__c = false;
          }
          if (before15_List.size() > 0) {
            c.Mailflg_before15__c = false;
          }
          if ( before7_List.size() > 0) {
            c.Mailflg_before7__c = false;
          }
          if (after3_List.size() > 0) {
            c.Mailflg_after3__c = false;
          }

        }
      }
    }
    if (rs11 && isServiceReport != null) {
      for (AssessmentReport__c AssessmentReport : AssessmentReportlist) {
        AssessmentReport.MailFlag_Approved__c = false;
      }
    }
    if (rs12 && isServiceReport != null) {
      for (Instruct_report__c Instruct_report : Instruct_reportList) {
        Instruct_report.MailFlag_Approved__c = false;
      }
    }
    // 服务技师培训 2019/1/7 张玉山 start
    system.debug('AssessmentReportList:' + AssessmentReportList);
    system.debug('Instruct_reportList:' + Instruct_reportList);
    system.debug('campaignList:' + campaignList);
    if (AssessmentReportList.size() > 0 && isServiceReport != null ) update AssessmentReportList;
    if (Instruct_reportList.size() > 0 && isServiceReport != null ) update Instruct_reportList;
    //// 服务技师培训 2019/1/7 张玉山 end

    if (campaignList.size() > 0) update campaignList;
  }

  global void finish(Database.BatchableContext BC) {
    saveResult();
  }


  public void saveResult() {
    BatchIF_Log__c iflog = new BatchIF_Log__c();
    iflog.Type__c = 'PushNotification';
    string tempstr = '';
    if (isServiceReport != null ) {
      tempstr = ' isServiceReport ';
    } else if (isService) {
      tempstr = ' isService ';
    } else {
      tempstr = ' old ';
    }
    iflog.Log__c = 'CampaignSendMailBatch start' + tempstr
                   + '\n';
    if (result) {
      iflog.Is_Error__c = 0;
      iflog.ErrorLog__c = '';
      if (logstr.length() > 65000) {
        logstr = logstr.substring(0, 65000);
        logstr += ' ...have more lines...';
      }
      
      iflog.Log__c += '邮件成功发送\n';
      iflog.Log__c += logstr;
    } else {
      iflog.Is_Error__c = 1;
      if (Errorstr.length() > 65000) {
        Errorstr = Errorstr.substring(0, 65000);
        Errorstr += ' ...have more lines...';
      }
      if (logstr.length() > 65000) {
        logstr = logstr.substring(0, 65000);
        logstr += ' ...have more lines...';
      }
      iflog.Log__c += logstr;
      iflog.ErrorLog__c = Errorstr;

    }

    insert iflog;

  }
  // 服务技师培训 2019/1/7 张玉山 start



  // 每年提醒更新学员工作状态 TO所有FSE CC服务企划部窗口 所有职种为销售服务的副经理级及以上人员
  public boolean sendMailAllFSE() {
    boolean rs = true;

    String[] post = new String[] { '部长', '经理', '副部长', '副经理'};
    String[] position = new String[] {'销售服务'};

    map<string, user> userMailMap = new map<string, user>();
    map<string, user> userManagerMailMap = new map<string, user>();
    List<User> userMailList = [select id, Name, Email, Dept__c, Province__c , OCM_man_province__c, Post__c, Salesdepartment__c
                               from User
                               where IsActive = true
                                       and (Profileid = :system.label.ProfileId_2S5
                                               or Profileid = :system.label.ProfileId_2S3
                                           )];
    for (User tempUser : userMailList) {
      userMailMap.put(tempUser.Email, tempUser);
    }

    List<User> userManagerMailList = [select id, Name, Email, Dept__c, Province__c , OCM_man_province__c, Post__c, Salesdepartment__c
                                      from User
                                      where IsActive = true
                                              and Post__c = :post
                                                      and SFDCPosition_C__c = :position
                                                              and  Profileid != : system.label.ProfileId_SystemAdmin
                                                              and Alias != '经销商活动测试'
                                                              order by Dept__c, Province__c];
    list<User> ServiceUserList = [select id, Name, Email, Dept__c, Province__c , OCM_man_province__c, Post__c, Salesdepartment__c
                                  from User
                                  where IsActive = true and
                                          id = : System.Label.ServiceDesignDep_NC];
    for (User tempUser : userManagerMailList) {
      if (!userMailMap.containskey(tempUser.Email)) {
        userManagerMailMap.put(tempUser.Email, tempUser);
      }
    }
    for (User tempUser : ServiceUserList) {
      if (!userMailMap.containskey(tempUser.Email)) {
        userManagerMailMap.put(tempUser.Email, tempUser);
      }
    }

    List<Messaging.SingleEmailMessage> sendMails = new List<Messaging.SingleEmailMessage>();

    String title = '';
    String body = '';
    List<List<String>> toMailsList = new List<List<String>>();
    List<List<String>> ccMailsList = new List<List<String>>();
    List<String> toMails = new List<String>();
    List<String> ccMails = new List<String>();
    Integer cnt = 0;
    Integer ccCnt = 0;
    for (User userMail : userMailMap.values()) {
      cnt += 1;
      if (cnt <= 100) {
        toMails.add(userMail.Email);
      } else {
        toMailsList.add(toMails);
        toMails = new List<String>();
        toMails.add(userMail.Email);
        cnt = 1;
      }
    }
    toMailsList.add(toMails);


    for (User userMail : userManagerMailmap.values()) {
      ccCnt += 1;
      if (ccCnt <= 25) {
        ccMails.add(userMail.Email);
      } else {
        ccMailsList.add(ccMails);
        ccMails = new List<String>();
        ccMails.add(userMail.Email);
        ccCnt = 1;
      }
    }
    ccMailsList.add(ccMails);


    title =  '【信息收集】内镜临床工程师受训人员在岗与跟进情况收集';
    body +=   '各位领导、同事：';
    body += '<br/>';
    body += '<br/>';
    body += '您们好！感谢平日对内镜临床工程师培养项目的理解与支持！';
    body += '<br/>';
    body += '<br/>';
    body += '为明确既已培养完成内镜临床工程师的工作开展状态，从而更好的支持现场工作，还请协助更新并反馈以下链接中内镜临床工程师的工作状态，填写表格中“在岗状态”“跟进状态”“是否负责内镜工作”，并保存即可。';
    body += '<br/>';
    body += '<br/>';
    body += '<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/apex/BmeWorkPage'  + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/apex/BmeWorkPage' + '</a><br/>';
    body += '<br/>';
    body += '<br/>';
    body += '若有不明之处，还请随时联系服务企划部窗口。';
    body += '<br/>';
    body += '<br/>';
    body += '谢谢！';
    for (integer i = 0; i < toMailsList.size(); i++ ) {
      List<String> toMailList = toMailsList[i];
      List<String> ccMailList = new List<String>();
      if (ccMailsList.size() > i ) {
        ccMailList = ccMailsList[i];
      }
      Messaging.SingleEmailMessage messageNEW = new Messaging.SingleEmailMessage();
      messageNEW.subject = title;
      //messageNEW.plainTextBody = body;
      messageNEW.htmlBody = body;
      messageNEW.setCharset('UTF-8');
      messageNEW.toAddresses = toMailList;
      messageNEW.ccAddresses = ccMailList;

      sendMails.add(messageNEW);
    }

    if (sendMails.size() > 0) {
      Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
      for (Integer i = 0; i < results.size(); i++) {
        if (results[i].success == false) {
          system.debug('=====send mail error:' + results[i].errors[0].message);
          result = false;
          Errorstr += 'sendMailAllFSE:' + results[i].errors[0].message + '\n';
          rs = false;
        }
      }
      logstr +='sendMailAllFSE 发送结束';
    }


    return rs;

  }


  //带教报告
  public  boolean sendMailInstructReport(List<Instruct_report__c> Instruct_reportList) {
    boolean rs = true;
    Map<String, String> deptMap = new Map<String, String>();
    deptMap.put('1.华北', '医疗华北营业本部');
    deptMap.put('2.东北', '医疗东北营业本部');
    deptMap.put('3.西北', '医疗西北营业本部');
    deptMap.put('4.西南', '医疗西南营业本部');
    deptMap.put('5.华东', '医疗华东营业本部');
    deptMap.put('6.华南', '医疗华南营业本部');

    String[] post = new String[] { '部长', '经理', '副部长', '副经理'};
    String[] position = new String[] {'销售服务'};
    List<User> userMailList = [select id, Name, Email, Dept__c, Province__c , OCM_man_province__c, Post__c, Salesdepartment__c
                               from User
                               where IsActive = true
                                       and Post__c = :post
                                               and SFDCPosition_C__c = :position
                                                       and  Profileid != : system.label.ProfileId_SystemAdmin
                                                       and Alias != '经销商活动测试'
                                                       order by Dept__c, Province__c];

    List<Messaging.SingleEmailMessage> sendMails = new List<Messaging.SingleEmailMessage>();
    for (Instruct_report__c Instruct_report : Instruct_reportList) {
      // 存 2.用户所在省、.职种为销售服务的副经理和经理；3.用户所在本部、职种为销售服务的副部长和部长。
      List<User> targetList2 = new List<User>();
      for ( user tempUser : userMailList) {
        if ((tempUser.OCM_man_province__c != null &&
                Instruct_report.campaign__r.Province__c != null &&
                tempUser.OCM_man_province__c.equals(Instruct_report.campaign__r.Province__c) &&
                ( tempUser.Post__c.equals('经理') || tempUser.Post__c.equals('副经理')))
                ||
                (tempUser.Salesdepartment__c != null &&
                 Instruct_report.campaign__r.Salesdepartment__c != null &&
                 tempUser.Salesdepartment__c.equals(Instruct_report.campaign__r.Salesdepartment__c) &&
                 ( tempUser.Post__c.equals('部长') || tempUser.Post__c.equals('副部长')))
           ) {
          targetList2.add(tempUser);
        }
      }
      if (Instruct_report.campaign__r.ServiceDesignDep__r != null) {
        targetList2.add(Instruct_report.campaign__r.ServiceDesignDep__r);
      }
      String title = '';
      String body = '';
      List<List<String>> toMailsList = new List<List<String>>();
      List<String> toMails = new List<String>();
      List<String> ccMailList = new List<String>();
      Integer cnt = 0;
      Integer ccCnt = 0;
      for (User userMail : targetList2) {
        cnt += 1;
        if (cnt <= 100) {
          toMails.add(userMail.Email);
        } else {
          toMailsList.add(toMails);
          toMails = new List<String>();
          toMails.add(userMail.Email);
          cnt = 1;
        }
      }
      toMailsList.add(toMails);
      title =  Instruct_report.campaign__r.Name + '带教报告';
      body +=   '领导您好：';
      body += '<br/>';
      body += '<br/>';
      body += Instruct_report.campaign__r.Name + '担当' + Instruct_report.campaign__r.Owner.Name + '提交了带教报告，报告具体内容请参照以下链接：<br/>';
      body += '<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + Instruct_report.campaign__c + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + Instruct_report.campaign__c + '</a><br/>';
      body += '<br/>';
      body += '<br/>';
      body += '谢谢！';
      for (List<String> toMailList : toMailsList) {
        Messaging.SingleEmailMessage messageNEW = new Messaging.SingleEmailMessage();
        messageNEW.subject = title;
        //messageNEW.plainTextBody = body;
        messageNEW.htmlBody = body;
        messageNEW.setCharset('UTF-8');
        messageNEW.toAddresses = toMailList;
        messageNEW.ccAddresses = ccMailList;

        sendMails.add(messageNEW);
      }

      if (sendMails.size() > 40) {
        Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
        for (Integer i = 0; i < results.size(); i++) {
          if (results[i].success == false) {
            system.debug('=====send mail error:' + results[i].errors[0].message);
            result = false;
            Errorstr += 'sendMailInstructReport:' + results[i].errors[0].message + '\n';
            rs = false;
          }
        }

        sendMails = new List<Messaging.SingleEmailMessage>();
      }

    }
    system.debug('sendMailInstructReport:' + sendMails);
    if (sendMails.size() > 0) {
      Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
      for (Integer i = 0; i < results.size(); i++) {
        if (results[i].success == false) {
          system.debug('=====send mail error:' + results[i].errors[0].message);
          result = false;
          Errorstr += 'sendMailInstructReport:' + results[i].errors[0].message + '\n';
          rs = false;
        }
      }
    }
    return rs;
  }
  // 授课、考核报告
  public boolean sendMailAssessmentReport(List<AssessmentReport__c> AssessmentReportlist) {
    boolean rs = true;
    Map<String, String> deptMap = new Map<String, String>();
    deptMap.put('1.华北', '医疗华北营业本部');
    deptMap.put('2.东北', '医疗东北营业本部');
    deptMap.put('3.西北', '医疗西北营业本部');
    deptMap.put('4.西南', '医疗西南营业本部');
    deptMap.put('5.华东', '医疗华东营业本部');
    deptMap.put('6.华南', '医疗华南营业本部');

    String[] post = new String[] { '部长', '经理', '副部长', '副经理'};
    String[] position = new String[] {'销售服务'};
    List<User> userMailList = [select id, Name, Email, Dept__c, Province__c , OCM_man_province__c, Post__c, Salesdepartment__c
                               from User
                               where IsActive = true
                                       and Post__c = :post
                                               and SFDCPosition_C__c = :position
                                                       and  Profileid != : system.label.ProfileId_SystemAdmin
                                                       and Alias != '经销商活动测试'
                                                       order by Dept__c, Province__c];


    List<Messaging.SingleEmailMessage> sendMails = new List<Messaging.SingleEmailMessage>();
    for (AssessmentReport__c AssessmentReport : AssessmentReportlist) {
      // 存 2.用户所在省、.职种为销售服务的副经理和经理；3.用户所在本部、职种为销售服务的副部长和部长。
      List<User> targetList2 = new List<User>();
      for ( user tempUser : userMailList) {
        if ((tempUser.OCM_man_province__c != null &&
                AssessmentReport.campaign__r.Province__c != null &&
                tempUser.OCM_man_province__c.equals(AssessmentReport.campaign__r.Province__c) &&
                ( tempUser.Post__c.equals('经理') || tempUser.Post__c.equals('副经理')))
                ||
                (tempUser.Salesdepartment__c != null &&
                 AssessmentReport.campaign__r.Salesdepartment__c != null &&
                 tempUser.Salesdepartment__c.equals(AssessmentReport.campaign__r.Salesdepartment__c) &&
                 ( tempUser.Post__c.equals('部长') || tempUser.Post__c.equals('副部长')))
           ) {
          targetList2.add(tempUser);
        }
      }
      if (AssessmentReport.campaign__r.ServiceDesignDep__r != null) {
        targetList2.add(AssessmentReport.campaign__r.ServiceDesignDep__r);
      }
      String title = '';
      String body = '';
      List<List<String>> toMailsList = new List<List<String>>();
      List<String> toMails = new List<String>();
      List<String> ccMailList = new List<String>();
      Integer cnt = 0;
      Integer ccCnt = 0;

      if (AssessmentReport.Type__c != null  && AssessmentReport.Type__c != null
              && AssessmentReport.Type__c.equals('授课')) {
        for (User userMail : targetList2) {
          cnt += 1;
          if (cnt <= 100) {
            toMails.add(userMail.Email);
          } else {
            toMailsList.add(toMails);
            toMails = new List<String>();
            toMails.add(userMail.Email);
            cnt = 1;
          }
        }
        toMailsList.add(toMails);
        title =  AssessmentReport.campaign__r.Name + '活动报告';
        body +=   '领导您好：';
        body += '<br/>';
        body += '<br/>';
        body += AssessmentReport.campaign__r.Name + '担当' + AssessmentReport.campaign__r.Owner.Name
                + '提交了活动报告，报告具体内容请参照以下链接：<br/>';
        body += '<a href="' + URL.getSalesforceBaseUrl().toExternalForm() +
                '/' + AssessmentReport.campaign__c + '">'
                + URL.getSalesforceBaseUrl().toExternalForm() + '/'
                + AssessmentReport.campaign__c + '</a><br/>';
        body += '<br/>';
        body += '<br/>';
        body += '谢谢！';

      } else {
        if (AssessmentReport.Campaign__r.Owner != null) {
          toMails.add(AssessmentReport.Campaign__r.Owner.Email);
        }
        toMailsList.add(toMails);
        for (User tempUser : targetList2) {
          ccMailList.add(tempUser.email);
        }
        title =  AssessmentReport.Name + '的报告已审批通过，请计划并安排带教跟进工作。';
        body +=  AssessmentReport.campaign__r.owner.Name + '您好：';
        body += '<br/>';
        body += '<br/>';
        body += '恭喜您完成了' + AssessmentReport.Name + '的全部授课及考核工作，辛苦了！<br/>';
        body += '接下来，为了帮助学员们更好的学以致用，服务临床，还请面向学员们开展带教活动。<br/>';
        body += '建议带教频率为至少每月带教一次，为期半年。<br/>';
        body += '建议带教内容包括故障排查（包括内镜系统和周边设备）、辅助学员面向院内人员开展培训、数据分析、以及其它您或学员本人认为需要加强的内容。<br/>';
        body += '带教后，还请及时在系统中提交带教报告。<br/>';
        body += '若有不明之处，还请随时联系服务企划部窗口。<br/>';
        body += '<br/>';
        body += '<br/>';
        body += '谢谢！';
      }
      for (List<String> toMailList : toMailsList) {
        Messaging.SingleEmailMessage messageNEW = new Messaging.SingleEmailMessage();
        messageNEW.subject = title;
        //messageNEW.plainTextBody = body;
        messageNEW.htmlBody = body;
        messageNEW.setCharset('UTF-8');
        messageNEW.toAddresses = toMailList;
        messageNEW.ccAddresses = ccMailList;

        sendMails.add(messageNEW);
      }

      if (sendMails.size() > 40) {
        Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
        for (Integer i = 0; i < results.size(); i++) {
          if (results[i].success == false) {
            system.debug('=====send mail error:' + results[i].errors[0].message);
            result = false;
            Errorstr += 'sendMailAssessmentReport:' + results[i].errors[0].message + '\n';

            rs = false;
          }
        }

        sendMails = new List<Messaging.SingleEmailMessage>();
      }

    }
    system.debug('sendMailAssessmentReport:' + sendMails);
    if (sendMails.size() > 0) {
      Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
      for (Integer i = 0; i < results.size(); i++) {
        if (results[i].success == false) {
          system.debug('=====send mail error:' + results[i].errors[0].message);
          result = false;
          Errorstr += 'sendMailAssessmentReport:' + results[i].errors[0].message + '\n';

          rs = false;
        }
      }
    }
    return rs;
  }

  //sixMonthService:
  //after3Service:
  //ApprovalService:
  //before7Service:
  //CancelService:

  public static string getlessonName(Campaign temcampaign) {
    string temStr = '';
    if (temcampaign.Lesson1Date__c <=  Date.today().addDays(-3)) {
      temStr = '第1次授课';
    }
    if (temcampaign.Lesson2Date__c <=  Date.today().addDays(-3)) {
      temStr = '第2次授课';
    }
    if (temcampaign.Lesson3Date__c <=  Date.today().addDays(-3)) {
      temStr = '第3次授课';
    }
    if (temcampaign.Lesson4Date__c <=  Date.today().addDays(-3)) {
      temStr = '第4次授课';
    }
    if (temcampaign.Lesson5Date__c <=  Date.today().addDays(-3)) {
      temStr = '第5次授课';
    }
    if (temcampaign.Lesson6Date__c <=  Date.today().addDays(-3)) {
      temStr = '第6次授课';
    }
    if (temcampaign.Lesson7Date__c <=  Date.today().addDays(-3)) {
      temStr = '第7次授课';
    }
    if (temcampaign.Lesson8Date__c <=  Date.today().addDays(-3)) {
      temStr = '第8次授课';
    }
    return temstr;
  }

  public static string getlessonDate(Campaign temcampaign) {
    Date temDate;
    string temStr = '';
    if (temcampaign.FinalExamDate__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.FinalExamDate__c;
    }
    if (temcampaign.Lesson1Date__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.Lesson1Date__c;
    }
    if (temcampaign.Lesson2Date__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.Lesson2Date__c;
    }
    if (temcampaign.Lesson3Date__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.Lesson3Date__c;
    }
    if (temcampaign.Lesson4Date__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.Lesson4Date__c;
    }
    if (temcampaign.Lesson5Date__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.Lesson5Date__c;
    }
    if (temcampaign.Lesson6Date__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.Lesson6Date__c;
    }
    if (temcampaign.Lesson7Date__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.Lesson7Date__c;
    }
    if (temcampaign.Lesson8Date__c <=  Date.today().addDays(-3)) {
      temDate = temcampaign.Lesson8Date__c;
    }
    if (temDate != null) {
      temStr = temDate.format();
    }
    return temStr;
  }
  public boolean sendMailService(List<Campaign> campaigns, String mailType) {
    boolean rs = true;

    Map<String, String> deptMap = new Map<String, String>();
    deptMap.put('1.华北', '医疗华北营业本部');
    deptMap.put('2.东北', '医疗东北营业本部');
    deptMap.put('3.西北', '医疗西北营业本部');
    deptMap.put('4.西南', '医疗西南营业本部');
    deptMap.put('5.华东', '医疗华东营业本部');
    deptMap.put('6.华南', '医疗华南营业本部');

    String[] post = new String[] { '部长', '经理', '副部长', '副经理'};
    String[] position = new String[] {'销售服务'};
    List<User> userMailList = [select id, Name, Email, Dept__c,
                               Province__c, OCM_man_province__c, Post__c, Salesdepartment__c
                               from User
                               where IsActive = true
                                       and Post__c = :post
                                               and SFDCPosition_C__c = :position
                                                       and  Profileid != : system.label.ProfileId_SystemAdmin
                                                       and Alias != '经销商活动测试'
                                                       order by Dept__c, Province__c];

    List<Messaging.SingleEmailMessage> sendMails = new List<Messaging.SingleEmailMessage>();
    for (Campaign campaign : campaigns) {

      // 存主担当
      List<User> targetList = new List<User>();

      targetList.add(campaign.Owner);

      // 存服务企划部窗口
      List<User> targetList2 = new List<User>();
      if (campaign.ServiceDesignDep__r != null) {
        targetList2.add(campaign.ServiceDesignDep__r);
      }

      // 存 2.用户所在省、.职种为销售服务的副经理和经理；3.用户所在本部、职种为销售服务的副部长和部长。
      List<User> targetList3 = new List<User>();
      for ( user tempUser : userMailList) {
        if ((tempUser.Province__c != null &&
                campaign.Province__c != null &&
                tempUser.Province__c.equals(campaign.Province__c) &&
                ( tempUser.Post__c.equals('经理') || tempUser.Post__c.equals('副经理')))
                ||
                (tempUser.Salesdepartment__c != null &&
                 campaign.Salesdepartment__c != null &&
                 tempUser.Salesdepartment__c.equals(campaign.Salesdepartment__c) &&
                 ( tempUser.Post__c.equals('部长') || tempUser.Post__c.equals('副部长')))
           ) {
          targetList3.add(tempUser);
        }
      }
      system.debug('=====targetList:' + targetList.size());
      system.debug('=====targetList3:' + targetList3.size());

      String title = '';
      String body = '';
      List<List<String>> toMailsList = new List<List<String>>();
      List<String> toMails = new List<String>();
      List<String> ccMailList = new List<String>();
      Integer cnt = 0;
      Integer ccCnt = 0;
      // TO 主担当  CC服务企划部窗口
      if (mailType.equals('sixMonthService') || mailType.equals('after3Service') ) {
        for (User userMail : targetList) {
          toMails.add(userMail.Email);
        }
        toMailsList.add(toMails);
        for (User userMail : targetList2) {
          ccMailList.add(userMail.Email);
        }
      }
      // TO 主担当  CC服务企划部窗口—所在省销售服务（副）经理&所在本部销售服务（副）部长
      else if (mailType.equals('before7Service')) {
        for (User userMail : targetList) {
          toMails.add(userMail.Email);
        }
        toMailsList.add(toMails);
        for (User userMail : targetList2) {
          ccMailList.add(userMail.Email);
        }
        for (User userMail : targetList3) {
          ccMailList.add(userMail.Email);
        }
        // to服务企划部窗口&所在省销售服务（副）经理&所在本部销售服务（副）部长
      } else if (mailType.equals('ApprovalService') || mailType.equals('CancelService')) {
        for (User userMail : targetList2) {
          cnt += 1;
          toMails.add(userMail.Email);
        }
        for (User userMail : targetList3) {
          cnt += 1;
          if (cnt <= 100) {
            toMails.add(userMail.Email);
          } else {
            toMailsList.add(toMails);
            toMails = new List<String>();
            toMails.add(userMail.Email);
            cnt = 1;
          }
        }

        toMailsList.add(toMails);

      }
      // HWAG-BBH675 二 start
      if (mailType.equals('ApprovalService')) {
        ccMailList.add(System.Label.Campaign_Mail_CC_Label1);
      }
      // HWAG-BBH675 二 end
      Date sDate = campaign.StartDate__c;
      Date eDate =   campaign.EndDate__c;
      String year = '';
      if (sDate != null ) {
        year = String.valueOf(sDate.year());
      }
      String month = '';
      if (sDate != null ) {
        month = String.valueOf(sDate.month());
      }
      month = month.leftPad(2, '0');
      String day = '';
      if (sDate != null ) {
        day = String.valueOf(sDate.day());
      }
      day = day.leftPad(2, '0');
      String strSDate = '';
      if (sDate != null ) {
        strSDate = sDate.format();
      }
      String strEDate = '';
      if (eDate != null ) {
        strEDate = eDate.format();
      }
      if (mailType.equals('sixMonthService')) {
        title = '【提醒】' + campaign.Name + '带教跟进工作的开展';
        body +=  campaign.owner.Name + '您好：';
        body += '<br/>';
        body += '<br/>';
        body += '为了帮助学员们更好的学以致用，服务临床，还请面向学员们开展带教活动。<br/>';
        body += '建议带教频率为每月至少带教一次，建议带教内容包括故障排查（包括内镜系统和周边设备）、辅助学员面向院内人员开展培训、数据分析、以及其它您或学员本人认为需要加强的内容。<br/>';
        body += '请您合理安排工作，安排本月的带教内容。带教后，还请及时在系统中提交带教报告。<br/>';
        body += '若有不明之处，还请随时联系服务企划部窗口。<br/>';
        body += '<br/>';
        body += '<br/>';
        body += '谢谢！';
      } else if (mailType.equals('after3Service')) {
        //生成第X次授课或者最终考核
        string SKorKH = getlessonName(campaign) ;
        string Datestr = getlessonDate(campaign);
        title = campaign.Name + SKorKH + '已经结束请尽快提交报告书';
        body +=  campaign.owner.Name + '您好!';
        body += '<br/>';
        body += '<br/>';
        body += campaign.Name + SKorKH + '已经结束，请尽快提交相应报告。<br/>';
        body += '<br/>';
        body += '培训名称：' + campaign.Name + '<br/>';

        body +=  SKorKH + '日期：' + Datestr + '<br/>';
        body += '<br/>';
        body += '培训链接：<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
      } else if (mailType.equals('after3FinalService')) {

        string SKorKH = '最终考核' ;
        string Datestr = '';
        if (campaign.FinalExamDate__c != null) {
          Datestr = campaign.FinalExamDate__c.format();
        }
        title = campaign.Name + SKorKH + '已经结束请尽快提交报告书';
        body +=  campaign.owner.Name + '您好!';
        body += '<br/>';
        body += '<br/>';
        body += campaign.Name + SKorKH + '已经结束，请尽快提交相应报告。<br/>';
        body += '<br/>';
        body += '培训名称：' + campaign.Name + '<br/>';

        body +=  SKorKH + '日期：' + Datestr + '<br/>';
        body += '<br/>';
        body += '培训链接：<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
      } else if (mailType.equals('ApprovalService')) {
        title = campaign.Name + '的申请已审批成功。';
        body += '领导您好！<br/>';
        body += '<br/>';
        body += campaign.Name + '已审批通过，该培训班将于' + strSDate + '开班。<br/>';

        body += '具体情况请参照以下链接：<br/> <a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
        body += '<br/> 请做好相应准备，如有问题请联系服务企划部窗口人员。<br/><br/>谢谢！';

      } else if (mailType.equals('before7Service')) {
        title = campaign.Name + '还有7天召开';
        body += campaign.owner.Name + '您好:<br/>';
        body += '<br/>';
        body += '距离在' + strSDate + '的' + campaign.Name + '还有7天的时间。' +  '<br/>';
        body += ' <a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
        body += '请您合理安排工作，做好相应准备。<br/> ';
        body += '若有不明之处，还请随时联系服务企划部窗口。<br/> ';
        body += '<br/>谢谢！ ';

      } else if (mailType.equals('CancelService')) {
        title = campaign.Name + '已取消';
        body += '领导您好！<br/>';
        body += '<br/>';
        body += campaign.Name + '由于以下原因已取消，请您知悉。<br/> <br/>';
        body += ' 活动计划： <a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
        body += '取消原因： ' + campaign.CancleReason__c + ' <br/> ';
        body += '<br/>谢谢！ ';

      }





      for (List<String> toMailList : toMailsList) {
        Messaging.SingleEmailMessage messageNEW = new Messaging.SingleEmailMessage();
        messageNEW.subject = title;
        //messageNEW.plainTextBody = body;
        messageNEW.htmlBody = body;
        messageNEW.setCharset('UTF-8');
        messageNEW.toAddresses = toMailList;
        messageNEW.ccAddresses = ccMailList;

        sendMails.add(messageNEW);
      }

      if (sendMails.size() > 40) {
        Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
        for (Integer i = 0; i < results.size(); i++) {
          if (results[i].success == false) {
            system.debug('=====send mail error:' + results[i].errors[0].message);
            result = false;
            Errorstr += 'sendMailService:' + results[i].errors[0].message + '\n';

            rs = false;
          }
        }

        sendMails = new List<Messaging.SingleEmailMessage>();
      }

    }
    system.debug('sendMail ' + mailType + ' :' + sendMails);
    if (sendMails.size() > 0) {
      Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
      for (Integer i = 0; i < results.size(); i++) {
        if (results[i].success == false) {
          system.debug('=====send mail error:' + results[i].errors[0].message);
          result = false;
          Errorstr += 'sendMailService:' + results[i].errors[0].message + '\n';

          rs = false;
        }
      }
    }
    return rs;
  }

  // 服务技师培训 2019/1/7 张玉山 end


  public static boolean sendMail(List<Campaign> campaigns, String mailType) {
    boolean rs = true;

    Map<String, String> deptMap = new Map<String, String>();
    deptMap.put('1.华北', '医疗华北营业本部');
    deptMap.put('2.东北', '医疗东北营业本部');
    deptMap.put('3.西北', '医疗西北营业本部');
    deptMap.put('4.西南', '医疗西南营业本部');
    deptMap.put('5.华东', '医疗华东营业本部');
    deptMap.put('6.华南', '医疗华南营业本部');

    String[] post = new String[] {'总监', '部长', '经理', '副部长', '副经理'};
    String[] dept = new String[] {'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗西南营业本部', '医疗华东营业本部', '医疗华南营业本部'};
    String[] position = new String[] {'销售推广', '销售市场', '销售服务'};
    List<User> userMailList = [select id, Name, Email, Dept__c, Province__c
                               from User
                               where IsActive = true
                                       and Post__c = :post
                                               and Dept__c = :dept
                                                       and SFDCPosition_C__c = :position
                                                               order by Dept__c, Province__c];

    List<User> userMail2List = [select id, Name, Email, Dept__c, Province__c
                                from User
                                where IsActive = true
                                        and Dept__c = :dept
                                                and SFDCPosition_C__c = '行政助理'
                                                        order by Dept__c, Province__c];

    List<Messaging.SingleEmailMessage> sendMails = new List<Messaging.SingleEmailMessage>();
    for (Campaign campaign : campaigns) {
      String societyType = campaign.Society_Type__c;
      String openScope = campaign.Open_scope__c;
      String openScope2 = deptMap.get(openScope);

      List<User> targetList = new List<User>();
      targetList.add(campaign.Owner);
      if (campaign.JingliApprovalManager__c != null) targetList.add(campaign.JingliApprovalManager__r);
      if (campaign.BuchangApprovalManager__c != null) targetList.add(campaign.BuchangApprovalManager__r);
      for (User userMail : userMailList) {
        if (societyType == '全国') {
          targetList.add(userMail);
        } else if (societyType == '本部') {
          if (userMail.Dept__c == openScope || userMail.Dept__c == openScope2) {
            targetList.add(userMail);
          }
        } else if (societyType == '区域') {
          if (userMail.Province__c == openScope) {
            targetList.add(userMail);
          }
        }
      }

      List<User> target2List = new List<User>();
      target2List.add(campaign.Owner);
      if (campaign.JingliApprovalManager__c != null) target2List.add(campaign.JingliApprovalManager__r);
      String userDept = campaign.Owner.Dept__c;
      if (mailType == 'after45' && (
                  userDept == '医疗华北营业本部' ||
                  userDept == '医疗东北营业本部' ||
                  userDept == '医疗西北营业本部' ||
                  userDept == '医疗西南营业本部' ||
                  userDept == '医疗华东营业本部' ||
                  userDept == '医疗华南营业本部')) {
        for (User userMail2 : userMail2List) {
          if (userDept == userMail2.Dept__c) {
            target2List.add(userMail2);
          }
        }
      }

      List<User> target3List = new List<User>();
      target3List.add(campaign.Owner);
      if (campaign.JingliApprovalManager__c != null) target3List.add(campaign.JingliApprovalManager__r);
      if (campaign.BuchangApprovalManager__c != null) target3List.add(campaign.BuchangApprovalManager__r);

      system.debug('=====targetList:' + targetList.size());
      system.debug('=====target2List:' + target2List.size());
      system.debug('=====target3List:' + target3List.size());

      String title = '';
      String body = '';
      List<List<String>> toMailsList = new List<List<String>>();

      List<String> toMails = new List<String>();
      Integer cnt = 0;
      if (mailType == 'after45') {
        for (User userMail : target2List) {
          cnt += 1;
          if (cnt <= 100) {
            toMails.add(userMail.Email);
          } else {
            toMailsList.add(toMails);
            toMails = new List<String>();
            toMails.add(userMail.Email);
            cnt = 1;
          }
        }
        toMailsList.add(toMails);
      } else if (mailType == 'after3') {
        for (User userMail : target3List) {
          toMails.add(userMail.Email);
        }
        toMailsList.add(toMails);
      } else {
        for (User userMail : targetList) {
          cnt += 1;
          if (cnt <= 100) {
            toMails.add(userMail.Email);
          } else {
            toMailsList.add(toMails);
            toMails = new List<String>();
            toMails.add(userMail.Email);
            cnt = 1;
          }
        }
        toMailsList.add(toMails);
      }

      Date sDate = campaign.StartDate;
      Date eDate = campaign.EndDate;
      String year = String.valueOf(sDate.year());
      String month = String.valueOf(sDate.month());
      month = month.leftPad(2, '0');
      String day = String.valueOf(sDate.day());
      day = day.leftPad(2, '0');

      String strSDate = sDate.format();
      String strEDate = eDate.format();

      if (mailType == 'after45') {
        title = '您登录的' + year + '年' + month + '月' + day + '日召开的' + campaign.Name2__c + '会议计划请您确认并提交审批';
        body += '请您确认以下会议是否如期召开，如果召开请提交待审批，请您的领导确认并公开信息给会议区域的同事。<br/>';
        body += '<br/>';
        body += '如果会议召开日期变更请您修改，如果会议取消，请点击“取消”按钮。<br/>';
        body += '<br/>';
        body += '学会培训名称：' + campaign.Name2__c + '<br/>';
        body += '地点：' + campaign.WorkshopPlace__c + '<br/>';
        body += '学会.培训分类：' + campaign.Workshop_category__c + '<br/>';
        body += '开始日期：' + strSDate + '<br/>';
        body += '结束日期：' + strEDate + '<br/>';
        body += '<br/>';
        body += '会议链接：<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
      } else if (mailType == 'cancel') {
        title = year + '年' + month + '月' + day + '日召开的' + campaign.Name2__c + '会议取消召开';
        body += '如题的会议，因' + campaign.CancleReason__c + '的原因，取消召开了，请重新进行工作安排。<br/>';
        body += '<br/>';
        body += '学会培训名称：' + campaign.Name2__c + '<br/>';
        body += '地点：' + campaign.WorkshopPlace__c + '<br/>';
        body += '学会.培训分类：' + campaign.Workshop_category__c + '<br/>';
        body += '<br/>';
        body += '会议链接：<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
      } else if (mailType == 'before15') {
        title = year + '年' + month + '月' + day + '日召开的' + campaign.Name2__c + '会议还有15天召开';
        body += '您好！<br/>';
        body += '<br/>';
        body += year + '年' + month + '月' + day + '日召开的' + campaign.Name2__c + '会议还有15天召开，请您提前安排好工作按时参加，莅临展台请着深色正装。<br/>';
        body += '<br/>';
        body += '开展地点：' + campaign.WorkshopPlace__c + '<br/>';
        body += '<br/>';
        body += '谢谢！<br/>';
        body += '<br/>';
        body += '具体的会议信息请参考以下的链接：<br/>';
        body += '会议链接：<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
      } else if (mailType == 'before7') {
        title = year + '年' + month + '月' + day + '日召开的' + campaign.Name2__c + '会议还有7天召开';
        body += '您好！<br/>';
        body += '<br/>';
        body += year + '年' + month + '月' + day + '日召开的' + campaign.Name2__c + '会议还有7天召开，请您提前安排好工作按时参加，莅临展台请着深色正装。<br/>';
        body += '<br/>';
        body += '开展地点：' + campaign.WorkshopPlace__c + '<br/>';
        body += '<br/>';
        body += '谢谢！<br/>';
        body += '<br/>';
        body += '具体的会议信息请参考以下的链接：<br/>';
        body += '会议链接：<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
      } else if (mailType == 'after3') {
        title = campaign.Name2__c + '已经结束请尽快提交报告书';
        body += '您好！<br/>';
        body += '<br/>';
        body += campaign.Name2__c + '会议已经结束，请尽快提交会议报告。<br/>';
        body += '<br/>';
        body += '学会培训名称：' + campaign.Name2__c + '<br/>';
        body += '地点：' + campaign.WorkshopPlace__c + '<br/>';
        body += '学会.培训分类：' + campaign.Workshop_category__c + '<br/>';
        body += '开始日期：' + strSDate + '<br/>';
        body += '结束日期：' + strEDate + '<br/>';
        body += '<br/>';
        body += '会议链接：<a href="' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '">' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaign.Id + '</a><br/>';
      }

      List<String> ccMailList = new List<String>();
      //ccMailList.add('it_prectech@olympus.com.cn');
      //ccMailList.add('ling_zhu@olympus.com.cn');
      // 会议召开前15天提醒邮件增加如下规则发送
      if (mailType == 'before15') {
        if (campaign.Workshop_category__c == 'TTC' || campaign.Workshop_category__c == 'NTC' ||
                campaign.Workshop_category__c == '服务医工学会' || campaign.Workshop_category__c == '服务护理学会') {
          // TTC、NTC、服务医工学会、服务护理学会→王茗芳
          ccMailList.add(System.Label.Campaign_Mail_CC_Label1);
        } else if (campaign.Workshop_category__c == '经销商服务培训') {
          // 经销商服务培训→袁俊生
          ccMailList.add(System.Label.Campaign_Mail_CC_Label2);
        }
      }
      for (List<String> toMailList : toMailsList) {
        Messaging.SingleEmailMessage messageNEW = new Messaging.SingleEmailMessage();
        messageNEW.subject = title;
        //messageNEW.plainTextBody = body;
        messageNEW.htmlBody = body;
        messageNEW.setCharset('UTF-8');
        messageNEW.toAddresses = toMailList;
        messageNEW.ccAddresses = ccMailList;
        sendMails.add(messageNEW);
      }

      if (sendMails.size() > 40) {
        Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
        for (Integer i = 0; i < results.size(); i++) {
          if (results[i].success == false) {
            system.debug('=====send mail error:' + results[i].errors[0].message);
            rs = false;
          }
        }

        sendMails = new List<Messaging.SingleEmailMessage>();
      }
    }

    if (sendMails.size() > 0) {
      Messaging.SendEmailResult[] results = messaging.sendEmail(sendMails);
      for (Integer i = 0; i < results.size(); i++) {
        if (results[i].success == false) {
          system.debug('=====send mail error:' + results[i].errors[0].message);
          rs = false;
        }
      }
    }

    return rs;
  }

}