/**
     * [SetFrameNumManageBatch 进口单证上传后查找字段batch更新]
     * @Author   lijinhuan
     * @DateTime 2022-11-04T18:31:03+0800
     * 测试类：FrameNumUploadControllerTest
*/
global  without sharing  class SetFrameNumManageBatch implements Database.Batchable<sObject>, Database.Stateful{
    public String query;
    public String Id;

    //邮件信息
    List<String> emailMessages = new List<String>();

    //报错的进口单证Id
    String logStr = '进口单证 : ';
    //报错信息
    String errorStr = '';
    //总件数
    Integer totalCount = 0;
    // 失败件数
    Integer failedCount = 0;

    global SetFrameNumManageBatch() {
        this.query = query;
    }

    global SetFrameNumManageBatch(String Id) {
        this.query = query;
        this.Id = Id;
    }

    global Database.QueryLocator start(Database.BatchableContext bc) {
        query = 'select Id,ManagementCode__c,InspectionCard__c,InspectionCard_Select__c,ApplyList__c,ApplyList_Select__c,';
        // query += 'Statu_Achievements_DN_details__c,signInForm__c,Asset__c,ManagementCode__c,IsChange__c ';
        query += 'signInForm__c,Statu_Achievements_DN_details__c,Asset__c,ScanDate__c,ScanDate_select__c,IsChange__c, DeliveryDate__c, DeliveryDate_select__c ';
        // query += 'IsChange__c ';
        query += ' from FrameNumManage__c where createddate >= LAST_N_MONTHS:6 and ';
        if(String.isNotBlank(Id)){
            query += ' id = :Id';
        }else{
            // query += ' (signInForm__c = null  ';
            // query += ' OR Statu_Achievements_DN_details__c = null ';
             
            query += '(((signInForm__c = null OR Statu_Achievements_DN_details__c = null) AND AssertRecordType__c != \'Shipment\') ';
            query += ' OR Asset__c = null ';
            // 
            // query += ' Asset__c = null ';
            query += ' OR (InspectionCard_Select__c = null AND InspectionCard__c != null AND InspectionCard__c !=\'不要\')';
            // query += ' (InspectionCard_Select__c = null AND InspectionCard__c != null AND InspectionCard__c != \'\' AND InspectionCard__c !=\'不要\')';
            query += ' OR (InspectionCard_Select__c != null AND (InspectionCard__c =\'不要\' OR InspectionCard__c = null OR InspectionCard__c = \'\'))';// 清空
            query += ' OR (ApplyList_Select__c = null AND ApplyList__c != null AND ApplyList__c != \'\')';
            query += ' OR (ApplyList_Select__c != null AND (ApplyList__c = null OR ApplyList__c =\'\'))';// 清空
            query += ' OR (ScanDate__c !=  null AND ScanDate_select__c = null)';
            query += ' OR IsChange__c = true)';
        }
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, list<FrameNumManage__c> fnmList) {
        Map<String,String> InspectionCardMap = new Map<String,String>();
        Map<String,String> ApplyListMap = new Map<String,String>();
        Map<String,Id> InspectionCardIdMap = new Map<String,Id>();
        Map<String,Id> ApplyListIdMap = new Map<String,Id>();
        Set<String> TracingCodeSet = new Set<String>();
        Set<String> TracingCodeAssetSet = new Set<String>();
        Map<Id,String> clearMap = new Map<Id,String>();
        Set<Date> ScanDateSet = new Set<Date>();
        Map<Id,FrameNumManage__c> oldMap = new Map<Id,FrameNumManage__c>();
        try{
        for(FrameNumManage__c fnm:fnmList){
            // 清空
            // 0 all 1:ApplyList_Select__c 2:InspectionCard_Select__c 
            if(
                ((String.isBlank(fnm.ApplyList__c) ||(!String.isBlank(fnm.ApplyList__c) && fnm.ApplyList__c == '不要')) &&!String.isBlank(fnm.ApplyList_Select__c))
                && ((String.isBlank(fnm.InspectionCard__c) ||(!String.isBlank(fnm.InspectionCard__c) && fnm.InspectionCard__c == '不要')) &&!String.isBlank(fnm.InspectionCard_Select__c))
            ){
                clearMap.put(fnm.Id,'0');
            }else if((String.isBlank(fnm.ApplyList__c) ||(!String.isBlank(fnm.ApplyList__c) && fnm.ApplyList__c == '不要')) &&!String.isBlank(fnm.ApplyList_Select__c)){
                clearMap.put(fnm.Id,'1');
            }else if((String.isBlank(fnm.InspectionCard__c) ||(!String.isBlank(fnm.InspectionCard__c) && fnm.InspectionCard__c == '不要')) &&!String.isBlank(fnm.InspectionCard_Select__c)){
                clearMap.put(fnm.Id,'2');
            }                
            //赋值
            if(String.isBlank(fnm.signInForm__c) || String.isBlank(fnm.Statu_Achievements_DN_details__c)){
                System.debug('fnm ' + fnm.ManagementCode__c);
                TracingCodeSet.add(fnm.ManagementCode__c); //签收单 发货DN明细用
            }
            // System.debug('zheli03:'+String.isBlank(fnm.Asset__c));
            if(String.isBlank(fnm.Asset__c)){
                TracingCodeAssetSet.add(fnm.ManagementCode__c);// 保有设备用
            }
            
            // System.debug('zheli02:'+TracingCodeAssetSet);
            InspectionCardMap.put(fnm.ManagementCode__c,fnm.InspectionCard__c);
            ApplyListMap.put(fnm.ManagementCode__c,fnm.ApplyList__c);
            if(fnm.ScanDate__c != null){
                ScanDateSet.add(fnm.ScanDate__c);
            }
            oldMap.put(fnm.Id,fnm);
        }
        // 发货DN明细
        Map<String,Id> DNdetailMap = new Map<String,Id>();
        Map<String,String> DNMap  = new Map<String,String>();
        // Map<String,Id> AssetMap = new Map<String,Id>();
        for(Statu_Achievements_DN_details__c dn:[SELECT Id,TracingCode_Raw__c,Statu_Achievements_DN__c,Statu_Achievements_DN__r.Name,asset__c FROM Statu_Achievements_DN_details__c WHERE TracingCode_Raw__c IN: TracingCodeSet]){
            DNdetailMap.put(dn.TracingCode_Raw__c,dn.Id);
            // AssetMap.put(dn.TracingCode_Raw__c,dn.asset__c);
            DNMap.put(dn.TracingCode_Raw__c,dn.Statu_Achievements_DN__r.Name);
        }
        // 签收单
        Map<String,Id> eSignFormMap = new Map<String,Id>();
        for(eSignForm__c es:[SELECT Id,DNName__c FROM eSignForm__c WHERE DNName__c IN: DNMap.values()]){
            for(String key:DNMap.keySet()){
                if(DNMap.get(key) == es.DNName__c){
                    eSignFormMap.put(key,es.Id);
                }
            } 
        }
        System.debug('zheli01:'+TracingCodeAssetSet);
        // 保有设备
        Map<String,Id> AssetMap = new Map<String,Id>();
        Map<String, Asset> AssetDatas = new Map<String, Asset>();
        // 进口单证 增加发货日设置 start
        for(Asset ass:[SELECT Id,TracingCode__c,Posting_Date__c FROM Asset WHERE TracingCode__c IN: TracingCodeAssetSet]){
            if(!AssetMap.containsKey(ass.TracingCode__c)){
                AssetMap.put(ass.TracingCode__c,ass.Id);
                AssetDatas.put(ass.TracingCode__c,ass);
            }
            if (ass.Posting_Date__c != null) {
                ScanDateSet.add(ass.Posting_Date__c);
            }
            // AssetMap.put(ass.TracingCode__c,ass.Id);
        }
        // 进口单证 增加发货日设置 end
        // System.debug('zheli00:'+AssetMap);
        // 商检证   InspectionCard_Select__c 报关单   ApplyList_Select__c
        Set<String> FilesNameSet = new Set<String>();
        FilesNameSet.addAll(InspectionCardMap.values());
        FilesNameSet.addAll(ApplyListMap.values());
        for(FileAddress__c fa:[SELECT Id,OnlyFileName__c FROM FileAddress__c WHERE ParentRecordId__c = 'FrameNumManage' AND OnlyFileName__c IN: FilesNameSet]){
            for(String key:InspectionCardMap.keySet()){
                if(InspectionCardMap.get(key) == fa.OnlyFileName__c){
                    InspectionCardIdMap.put(key,fa.Id);
                }
                if(ApplyListMap.get(key) == fa.OnlyFileName__c){
                    ApplyListIdMap.put(key,fa.Id);
                }
            }
        }
        // 扫描日期
        Map<Date,Id> ScanDateMap = new Map<Date,Id>();
        for(OlympusCalendar__c oc:[SELECT Id,Date__c FROM OlympusCalendar__c WHERE Date__c IN: ScanDateSet]){
            ScanDateMap.put(oc.Date__c,oc.Id);
        }
        // 最后整合
        List<FrameNumManage__c> upFnmList = new List<FrameNumManage__c>();
        for(FrameNumManage__c fnm:fnmList){
            FrameNumManage__c temp = new FrameNumManage__c();
            temp.Id = fnm.Id;
            if(DNdetailMap.size() > 0 && DNdetailMap.containsKey(fnm.ManagementCode__c)){
                temp.Statu_Achievements_DN_details__c = DNdetailMap.get(fnm.ManagementCode__c);
            }
            if(eSignFormMap.size() > 0 && eSignFormMap.containsKey(fnm.ManagementCode__c)){
                temp.signInForm__c  = eSignFormMap.get(fnm.ManagementCode__c);
            }
            if(AssetMap.size() > 0 && AssetMap.containsKey(fnm.ManagementCode__c)){
                temp.Asset__c = AssetMap.get(fnm.ManagementCode__c);
                // 进口单证 增加发货日设置 start
                if(String.isNotBlank(temp.Asset__c) && AssetDatas.get(fnm.ManagementCode__c) != null && AssetDatas.get(fnm.ManagementCode__c).Posting_Date__c != null){
                    temp.DeliveryDate__c = AssetDatas.get(fnm.ManagementCode__c).Posting_Date__c;
                    temp.DeliveryDate_select__c = ScanDateMap.get(AssetDatas.get(fnm.ManagementCode__c).Posting_Date__c);
                }
                // 进口单证 增加发货日设置 end
            }
            if(ScanDateMap.size() > 0 && ScanDateMap.containsKey(fnm.ScanDate__c)){
                temp.ScanDate_Select__c = ScanDateMap.get(fnm.ScanDate__c);
            }
            if(clearMap.containsKey(fnm.Id)){
                if(clearMap.get(fnm.Id) == '0'){
                    temp.ApplyList_Select__c = null;
                    temp.InspectionCard_Select__c = null;
                }else if(clearMap.get(fnm.Id) == '1'){
                    temp.ApplyList_Select__c = null;
                }else if(clearMap.get(fnm.Id) == '2'){
                    temp.InspectionCard_Select__c = null;
                }
            }else{
                temp.InspectionCard_Select__c = InspectionCardIdMap.get(fnm.ManagementCode__c);
                temp.ApplyList_Select__c = ApplyListIdMap.get(fnm.ManagementCode__c);
            }
            temp.IsChange__c = false;
            // 有变化才更新
            // if(!(temp.Statu_Achievements_DN_details__c == oldMap.get(temp.Id).Statu_Achievements_DN_details__c 
            // && temp.signInForm__c == oldMap.get(temp.Id).signInForm__c 
            // && temp.Asset__c == oldMap.get(temp.Id).Asset__c
            // && temp.ApplyList_Select__c == oldMap.get(temp.Id).ApplyList_Select__c
            // && temp.InspectionCard_Select__c == oldMap.get(temp.Id).InspectionCard_Select__c
            // && temp.IsChange__c == oldMap.get(temp.Id).IsChange__c
            // )){
            // if(!(temp.ApplyList_Select__c == oldMap.get(temp.Id).ApplyList_Select__c
            // && temp.InspectionCard_Select__c == oldMap.get(temp.Id).InspectionCard_Select__c
            // && temp.IsChange__c == oldMap.get(temp.Id).IsChange__c
            // )){
            if(!(temp.ApplyList_Select__c == oldMap.get(temp.Id).ApplyList_Select__c
            && temp.InspectionCard_Select__c == oldMap.get(temp.Id).InspectionCard_Select__c
            && temp.IsChange__c == oldMap.get(temp.Id).IsChange__c
            && temp.Asset__c == oldMap.get(temp.Id).Asset__c
            && temp.ScanDate_Select__c == oldMap.get(temp.Id).ScanDate_Select__c
            )){
                // System.debug('zheli99');
                upFnmList.add(temp);
            }            
        }
        // System.debug('zhelieupFnmList:'+upFnmList.size());
        if(upFnmList.size() > 0){
            // update upFnmList;
            List<Database.SaveResult> saveResults = Database.update(upFnmList,false);
            //总数
            totalCount += saveResults.size();
            for(Integer i = 0;i<saveResults.size();i++) {
                if(!saveResults.get(i).isSuccess() ){
                    logStr += upFnmList.get(i).id +' ,';
                    errorStr += '失败进口单证 :'+upFnmList.get(i).id+'  失败原因:'+ String.ValueOf(saveResults.get(i).getErrors()[0]).split(';')[2].split('=')[1] 
                    +' : '+String.ValueOf(saveResults.get(i).getErrors()[0]).split(';')[1].split('=')[1] + '\r\n';
                    failedCount++ ;
                }
            }
        }
                
        }catch(Exception ex){
            errorStr += 'Batch执行过程中出现错误: ' + ex.getStackTraceString();
        }
        
    }

    global void finish(Database.BatchableContext BC) {
        BatchIF_Log__c IfLog = new BatchIF_Log__c();
        IfLog.Type__c = 'SetFrameNumManageBatchErrorLog';

        if (logStr.length() > 60000) {
            logStr = logStr.substring(0, 60000);
        }
        IfLog.Log__c = logStr;
        IfLog.Log__c += '\n end';
        if (errorStr.length() > 60000) {
            IfLog.ErrorLog__c = errorStr.substring(0, 60000);
        } else {
            IfLog.ErrorLog__c = errorStr.substring(0, errorStr.length());
        }

        insert IfLog;

        emailMessages.add('失败日志ID为：' + IfLog.Id + '\r\n失败信息:\r\n'+errorStr);

        //发送邮件
        sendFieldEmail();
    }
    // 发送提醒邮件
    private void sendFieldEmail() {
        PretechBatchEmailUtil be = new PretechBatchEmailUtil();
        String[] toList = new String[] {UserInfo.getUserEmail()};
        String title = '进口单证数据关联更新失败';
        String[] ccList = new String[]{};
        String ccEmail = System.Label.EmailAlert;
        if(ccEmail.length() > 0){
            for(String email : ccEmail.split(',')){
                ccList.add(email);
            }
        }
        if (System.Test.isRunningTest()) {
            be.successMail('', 1);
        }
        if (emailMessages.size() > 0 && failedCount > 0) {
            be.failedMail(toList, ccList, title, this.emailMessages.get(0)+'\n',
                            totalCount, totalCount - failedCount, failedCount,'',false);
            if(!Test.isRunningTest()){
                be.send();
            }
        }      
    }
}