public with sharing class CreateOpportunityTaskBatch implements Database.Batchable<SObject>, Database.Stateful {
    
    public final List<Id> TEST_ID = null;
    
    // 报错的询价ID
    public String logstr = '';

    // 报错信息
    public String errorstr = '';

    public List<String> emailMessages = new List<String>();

    public Integer totalCount = 0; // 总件数
    public Integer failedCount = 0; // 失败件数
    //Boolean isExecuteOPD = false; //20210203 zh SWAG-BXQDHZ 是否执行OPD,自动执行时为true     mzy  update SWAG-C4V6GU   询价任务派送时间更改
    Boolean  isNeedExecute = false; // mzy update  2021-07-13  SFDC-Batch合并

    public CreateOpportunityTaskBatch() {
    }
    //20210203 zh SWAG-BXQDHZ start
    public CreateOpportunityTaskBatch(Boolean tempOPD) {
        isNeedExecute = tempOPD; 
    }
    //20210203 zh SWAG-BXQDHZ end
    public CreateOpportunityTaskBatch(List<Id> testId) {
        TEST_ID = testId;
    }

    public Database.QueryLocator start(Database.BatchableContext BC) {
        // System.debug('CreateOpportunityTaskBatch start');
        
        // 销售本部（预测用）包含1，2，3，4，5，6；
        List<String> areas = new List<String>();
        areas.add('1.华北'); 
        areas.add('2.东北'); 
        areas.add('3.西北'); 
        areas.add('4.西南'); 
        areas.add('5.华东'); 
        areas.add('6.华南'); 
        String oppSql = 'select id,name,StageName,ForecastAccuracyObject__c,SalesdepartmentForecast__c,Account.Name,';
        oppSql += ' OwnerId,Owner.IsActive,Department_Name__c,AccountId,IsNextMonthOfVisit__c,OCM__c,Opportunity_Category__c,OCSMRMB_Without_Tax__c';
        //2021-08-10  mzy  update   SWAG-C5R6GW   询价任务新增字段  start
        oppSql += ',Competitor__c,Close_Forecasted_Date__c,Created_Day__c,StageName__c,Bid_Date__c,Closing_Bid_Date__c ';
        //2021-08-10  mzy  update  SWAG-C5R6GW   询价任务新增字段  end
        oppSql += ' from Opportunity ';

        // 询价科室分类（Opportunity_Category__c） 是GI
        List<String> opportunityCategoryGI = new List<String>();
        opportunityCategoryGI.add('GI');
        opportunityCategoryGI.add('BF');
        opportunityCategoryGI.add('ET');
        // 询价科室分类（Opportunity_Category__c） 是SP
        List<String> opportunityCategorySP = new List<String>();
        opportunityCategorySP.add('GS');
        opportunityCategorySP.add('URO');
        opportunityCategorySP.add('GYN');
        opportunityCategorySP.add('OTH');
        opportunityCategorySP.add('ENT');

        if (TEST_ID != null && TEST_ID.size() > 0) {
            oppSql += ' where id in :TEST_ID';
        }else{
            oppSql += ' where StageName = \'引合\' and ForecastAccuracyObject__c = true';
            oppSql += ' and Competitor__c in (\'A\',\'B\',\'C\',\'D\',\'E\') '; //2021-11-22 yjk 增加判断条件 询价等级
            oppSql += ' and IsNextMonthOfVisit__c = false and SalesdepartmentForecast__c in :areas';
            // 5）客户为H层客户的询价
            // oppSql += ' and (OCM__c = \'H0\' or OCM__c = \'H1\')';
            // 6）预测合同金额超过设定值的询价（GI：200万以上，SP：100万以上）
            // oppSql += ' and ((Opportunity_Category__c in :opportunityCategoryGI and Wholesale_Price__c >= 2000000) or (Opportunity_Category__c in :opportunityCategorySP and Wholesale_Price__c >= 1000000))';
            // 7）未来两个月内预测成交的询价
            // 20210104 zh 询价被动任务修复 start

            //SWAG-C3J4U5 20210602 start rentx(注释掉了62,64行代码) （1and2and3）and(4 OR 5) 4是(H0 || H1)
            /*1.预测精度对象2.下月无拜访计划3.未来两个月内订货（预测OCSM签约日在未来两个内）4.H层客户询价5.大订单（GI 200万以上，SP 100万以上）*/
            //oppSql += ' and (OCM__c = \'H0\' or OCM__c = \'H1\' OR (Opportunity_Category__c in :opportunityCategoryGI and Wholesale_Price__c >= 2000000) OR (Opportunity_Category__c in :opportunityCategorySP and Wholesale_Price__c >= 1000000))';
            
            //SWAG-C3J4U5 20210602 end rentx

            // Integer nextMonth = Date.today().month()+1;
            // Integer nnextMonth = nextMonth+1;
            // oppSql += ' and (CALENDAR_MONTH(Close_Forecasted_Date__c) = :nextMonth or CALENDAR_MONTH(Close_Forecasted_Date__c) = :nnextMonth)';
            
            Date today  = date.today();
            //下月第一天
            Date nextMonthFirstDay = today.addMonths(2).toStartOfMonth();
            //下下月最后一天
            Date nnexMonthLastDay = today.addMonths(3).toStartOfMonth().addDays(-1);
            //半年后最后一天
            Date halfYearLastDay = today.addMonths(7).toStartOfMonth().addDays(-1);

            oppSql += ' and (((OCM__c = \'H0\' or OCM__c = \'H1\' )';
            oppSql += ' and (Close_Forecasted_Date__c >= :nextMonthFirstDay AND Close_Forecasted_Date__c <= :nnexMonthLastDay))';

            oppSql += ' or (((Opportunity_Category__c in :opportunityCategoryGI and OCSMRMB_Without_Tax__c >= 2000000) OR (Opportunity_Category__c in :opportunityCategorySP and OCSMRMB_Without_Tax__c >= 1000000))';
            oppSql += ' and (Close_Forecasted_Date__c >= :nextMonthFirstDay AND Close_Forecasted_Date__c <= :halfYearLastDay)))';
            // 20210104 zh 询价被动任务修复 end

            oppSql += ' and Bidding_Project_Name_Bid__r.subInfoType__c not in (\'3-3：开标公示\',\'3-4：候选人公示\',\'3-5：中标通知\',\'3-6：合同公告\')';
            
        }
        //2021-07-13  mzy  SWAG-C4V6GU   询价任务派送时间更改  改为  每月最后一天的  19:00   start
        //每月最后一天
        Date ThisMonthLastDay = Date.today().addMonths(1).toStartOfMonth().addDays(-1);
        //20210203 zh SWAG-BXQDHZ start   
        if (Date.today() != ThisMonthLastDay && isNeedExecute == true) {
            oppSql = 'select id from Opportunity where Name=\'\' and Name!=\'\' ';
        }
        //20210203 zh SWAG-BXQDHZ end
        //2021-07-13  mzy  SWAG-C4V6GU   询价任务派送时间更改  改为  每月最后一天的  19:00   end
        System.debug('oppSql'+oppSql);

        
        return Database.getQueryLocator(oppSql);
    }


    public void execute(Database.BatchableContext BC, List<Opportunity> oppList) {
        List<task__c>  insertTasks = new List<task__c>();

        Date today  = date.today();
        Date nextMonthFirstDay = today.addMonths(2).toStartOfMonth();
        //下下月最后一天
        Date nnexMonthLastDay = today.addMonths(3).toStartOfMonth().addDays(-1);
                // 询价科室分类（Opportunity_Category__c） 是GI
        List<String> opportunityCategoryGI = new List<String>();
        opportunityCategoryGI.add('GI');
        opportunityCategoryGI.add('BF');
        opportunityCategoryGI.add('ET');
        // 询价科室分类（Opportunity_Category__c） 是SP
        List<String> opportunityCategorySP = new List<String>();
        opportunityCategorySP.add('GS');
        opportunityCategorySP.add('URO');
        opportunityCategorySP.add('GYN');
        opportunityCategorySP.add('OTH');
        opportunityCategorySP.add('ENT');

        for (Opportunity opp : oppList){
            if(opp.Owner.IsActive){//2021-08-30 yjk 增加判断任务对应的用户必须为IsActive
                task__c newTask = new task__c();
                newTask.assignee__c = opp.OwnerId;
                newTask.OwnerId = opp.OwnerId;
                newTask.RecordTypeId = Schema.SObjectType.task__c.getRecordTypeInfosByDeveloperName().get('OpportunityFollow').getRecordTypeId();
                newTask.taskDifferent__c = '被动任务';
                newTask.Name = '用户拜访:' + opp.Account.Name; 
                newTask.account__c = opp.AccountId;
                newTask.OpportunityId__c = opp.Id;
                newTask.taskStatus__c = '01 分配';
                //2021-08-10  mzy  update   SWAG-C5R6GW   询价任务新增字段  start
                //询价等级（分配）：记录分配时点的询价等级
                //预测OCSM签约日（分配）：记录分配时点的预测签约日
                //询价状态 (分配) : 记录分配时点的询价状态
                //询价创建日 (分配) : 记录分配时点的询价创建日
                //询价招标日 (分配) : 记录分配时点的询价招标日
                //询价中标日 (分配) : 记录分配时点的询价中标日
                newTask.OppCompetitorDbt__c = opp.Competitor__c;
                newTask.CloseForecastedDateDbt__c = opp.Close_Forecasted_Date__c;
                newTask.OpportunityStatusDbt__c = opp.StageName__c;
                newTask.OppCreateDateDbt__c =opp.Created_Day__c;
                newTask.Bid_DateDbt__c =opp.Bid_Date__c;
                newTask.Closing_Bid_DateDbt__c =opp.Closing_Bid_Date__c;
                //2021-08-10  mzy  update   SWAG-C5R6GW   询价任务新增字段  end

                //2021-11-26 yjk 询价任务增加派发原因字段


                if(opp.Close_Forecasted_Date__c >= nextMonthFirstDay && opp.Close_Forecasted_Date__c<= nnexMonthLastDay){
                    if(
                        (opp.OCM__c == 'H0' || opp.OCM__c == 'H1') && 
                        (
                            (opportunityCategoryGI.contains(opp.Opportunity_Category__c)  && opp.OCSMRMB_Without_Tax__c >= 2000000) 
                            ||
                            (opportunityCategorySP.contains(opp.Opportunity_Category__c) && opp.OCSMRMB_Without_Tax__c >= 1000000)
                            )){
                        newTask.distributeReason__c = 'H层次月预测大合同';
                    }else if(opp.OCM__c == 'H0' || opp.OCM__c == 'H1'){
                        newTask.distributeReason__c = 'H层次月预测';
                    }else{
                        newTask.distributeReason__c = '非H层次月预测大合同';
                    }
                    
                }else{
                    newTask.distributeReason__c = '半年大合同';
                }
                insertTasks.add(newTask);
            }
        }
        if (insertTasks.size() > 0) {
            Database.SaveResult[] saveResults = Database.insert(insertTasks,false);
            totalCount = + saveResults.size();
            for (Integer i = 0; i < saveResults.size(); i++) {
                if (!saveResults.get(i).isSuccess()) {
                    logstr += '询价:' + insertTasks.get(i).OpportunityId__c + ' ,';
                    errorstr += saveResults.get(i).getErrors() + '\n';
                    failedCount ++;
                }
            }
        }
        // insert insertTasks;
    }

    public void finish(Database.BatchableContext BC) {
        BatchIF_Log__c batchIfLog = new BatchIF_Log__c();
        batchIfLog.Type__c = 'CreateOpportunityTaskBatch';
        if (logstr.length() > 60000) {
            logstr = logstr.substring(0, 60000);
        }
        batchIfLog.Log__c = logstr;
        logstr += '\nBatchCreateOpportunityTaskEnd';
        if (errorstr.length() > 60000) {
            batchIfLog.ErrorLog__c = errorstr.substring(0, 60000);
        } else {
            batchIfLog.ErrorLog__c = errorstr.substring(0, errorstr.length());
        }
        insert batchIfLog;
        emailMessages.add('失败日志ID为：' + batchIfLog.Id);
        sendFieldEmail();
        //2021-07-13  mzy  SFDC-Batch合并  end
        //因为 询价任务派送时间 变为 每月最后一天的 19:00 故剔除Batch链     mzy  update
        //20210203 zh SWAG-BXQDHZ start
        //if(!test.isRunningTest() && isExecuteOPD == true){
        //    Database.executebatch(new CreatePassiveTaskBatch(true), 10);
        //}
        if(!Test.isRunningTest() &&IsNeedExecute==true){
          //batch里调用下一个batch时，希望跟原有的Schedule里面传的条数保持一致
           Id execBTId = Database.executebatch(new SubAuthorizedBatch(true),10);
        }
        //20210203 zh SWAG-BXQDHZ end
        //2021-07-13  mzy  SFDC-Batch合并  end
    }

    // 发送提醒邮件
    private void sendFieldEmail() {
        PretechBatchEmailUtil be = new PretechBatchEmailUtil();
        String[] toList = new String[] {UserInfo.getUserEmail()};
        String title = '创建询价对应的task失败';
        String[] ccList = new String[] {};
        if (System.Test.isRunningTest()) {
            be.successMail('', 1);
        }
        if (emailMessages.size() > 0 && failedCount > 0) {
            be.failedMail(toList, ccList, title,
                            String.join(this.emailMessages, '\n'),
                            totalCount, totalCount - failedCount, failedCount,'',true);
            if(!Test.isRunningTest())
                be.send();
        }
    }
}