global class EquipmentDraftOnceYearBatch  implements Database.Batchable<sObject>, Database.Stateful {
/**
20211015 you 创建
历史数据：草案中的备品申请超过一定时间给自动取消；
         每年的4月1日执行；
         比如2022-04-01 执行的是2021-04-01之前的数据
一年一次
**/
    private static final Integer MAXERRORCNT = 20; // 邮件表单位最大错误信息显示数量
    private static final Boolean ALLORNONE = false; // 全部保存
    private ErrorBean eb = new ErrorBean(); // 邮件发送ERRORBEAN
    id Rentalid;
    //获取当前时间
    Date dateToday = Date.today();
    //获取当前年
    Integer year = dateToday.year();
    Integer month = dateToday.month();
    String todayStr = String.valueOf(dateToday);
    String toyear = year +'-04-01';
    Boolean flago = todayStr==toyear ? true:false;//判断今天是否是4.1，如果是则执行此batch

    global EquipmentDraftOnceYearBatch(id Rentalid) {
        this.Rentalid = Rentalid;
    }
    global EquipmentDraftOnceYearBatch() {
        
    }
    global Database.QueryLocator start(Database.BatchableContext BC) {
        String query;
        if (month < 4) {
            year -= 2;
        }else{
            year -= 1;
        }  
        Date startDate = date.newInstance(year, 4, 1);
        query = 'select id,name from Rental_Apply__c where Status__c = \'草案中\'';
        if(!Test.isRunningTest()){
            query = query + ' and CreatedDate < :startDate'; 
        }
        if(Rentalid!=null){
            query = query + ' and id = \'' + Rentalid +'\'';
        }
            query = query + ' order by CreatedDate desc';

        //system.debug('==today=='+today+'==='+todayStr+'=='+flago);
        return Database.getQueryLocator(query);
    }
    global void execute(Database.BatchableContext BC, List<Rental_Apply__c> RaList) {
        for (Integer i = 0; i < RaList.size(); i ++) {
            Rental_Apply__c ra = RaList[i];
            ra.Cancel_Reason__c = '主动取消';
            ra.Loaner_cancel_reason__c  ='';
            ra.Loaner_cancel_request__c ='草案中备品申请取消';
            ra.Status__c = '取消';
        }
        if (!RaList.isEmpty()) {
            // update RaList;
            // 备品申请更新Error
            Database.SaveResult[] saveRes = Database.update(RaList, ALLORNONE);
            eb.setError(saveRes, MAXERRORCNT, Rental_Apply__c.sObjectType);
        }

    }
    global void finish(Database.BatchableContext BC) {
        Boolean haveError = false;
        String body = '';
        for (Id objId : eb.messageMap.keySet()) {
            haveError = true;
            body += eb.messageMap.get(objId) + '<br/>';
        }
        if (eb.overMax) {
            body += ':Over ' + MAXERRORCNT + 'Record<br/>';
        }
        if (haveError == true) {
            String batchUserId = System.Label.Batch_User_Id; //batch用户
            List<User> us = [Select Id,NAme,Email From User Where Id =: batchUserId];
            if (!us.isEmpty()) {
                User use = us[0];
                if (String.isNotBlank(use.Email)) {
                    List<String> MailCc;
                    if (System.Label.Batch_Error_Send_To_CC != 'null') {//精琢用户
                        MailCc = System.Label.Batch_Error_Send_To_CC.split(',');
                    }
                    FixtureUtil.sendMessage(batchUserId,
                                            MailCc,
                                            'EquipmentDraftOnceYearBatch Error',
                                             body
                                            );
                }
            }
        }
    }
    /************************* Inner Class ******************************/
    public class ErrorBean{
        public Map<Id, String> messageMap;
        public Boolean overMax;
        public ErrorBean() {
          messageMap = new Map<Id, String>();
          overMax = false;
        }
        public void setError (Database.SaveResult[] saveRes, Integer maxCut, Schema.sObjectType obj) {
            if (messageMap.keySet().size() <= maxCut && overMax == false) {
                String objectName = obj.getDescribe().getName();
                String objectLabel = obj.getDescribe().getLabel();
                for (Database.SaveResult saveRe : saveRes) {
                    if (!saveRe.isSuccess()) {
                        if (!messageMap.containsKey(saveRe.getId())) {
                            if (messageMap.keySet().size() >= maxCut) {
                                overMax = true;
                                break;
                            }
                            for (Database.Error err : saveRe.getErrors()) {

                                String message = objectName + ':'
                                               + objectLabel + ':'
                                               + err.getStatusCode() + ':'
                                               + err.getFields() + ':'
                                               + err.getMessage();
                                messageMap.put(saveRe.getId(), message);
                                // 数据里面有复数错误信息的话只获取第一条
                                break;
                            }
                        }
                    }
                }
            }
        }
    }  
    @TestVisible private static void test() {
        Integer i = 0;
        
    } 
}