/**
 * 仪表板用询价关系对象每日增量写入数据用Batch
 * Author：shashiming 2024-03-06
 * Ver 1.0 Schedule重复执行Batch，对象作为传入参数，由于需要写入的对象比较多，这种方式可能导致启动不了，需要修改。
 * Ver 1.1 (待彤彤修改)修改Start方法，从辅助表里取对象(新增type)，预计挂在招标项目的定时任务里，凌晨6:00-7:00间执行
 */
global class ReportOppLinkFromOppBatch implements Database.Batchable<sObject> {
    
    // 检索对象
    public String insertObject;
    // 创建日开始时间
    public string inputdate;

    // 带参的构造函数
    global ReportOppLinkFromOppBatch(String insertObject, String inputdate) {
        this.insertObject = String.isNotBlank(insertObject) ? insertObject : null;
        this.inputdate = String.isNotBlank(inputdate) ? inputdate : null;
    }

    global Database.QueryLocator start(Database.BatchableContext bc) {
        String query = 'SELECT id FROM ';
        query += String.isNotBlank(this.insertObject) ? this.insertObject : 'Opportunity';
        query += ' WHERE CreatedDate >= ';
        query += String.isNotBlank(this.inputdate) ? (this.inputdate + 'T00:00:00.000+0800') : 'LAST_N_DAYS:0';
        query += ' ORDER BY CreatedDate';

        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, list<Sobject> scope) {
        // 写入日志
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = 'ReportOppLinkFromOppInsert';
        iflog.Log__c  = 'ReportOppLinkFromOppBatch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;

        try {
            // 先确认对象
            Id objid = scope != null && scope.size() > 0 ? scope.get(0).Id : null;
            if (objid == null) {
                iflog.Log__c += 'There is no data query from database\n';
                update iflog;
                return;
            }
            SObjectType objType = objid.getSObjectType();
            String objTypeStr = objType.getDescribe().getName();
            iflog.Log__c += 'Insert object type is ' + objTypeStr;
            // 获取所有id
            List<String> ids = new List<String>();
            for (Sobject obj: scope) {
                ids.add(obj.Id);
            }
            // 获得已存在的数据
            List<Report_Opp_Link__c> links = null;
            if (objTypeStr == 'Opportunity'){
                links = [select Id, Opportunity__c, Product_inquiry_sheet__c, task__c, Lead__c, Tender_Information__c, Statu_Achievements__c, AgencyOpportunity__c from Report_Opp_Link__c where Opportunity__c in :ids];
            } else if (objTypeStr == 'Inquiry_form__c') {
                links = [select Id, Opportunity__c, Product_inquiry_sheet__c, task__c, Lead__c, Tender_Information__c, Statu_Achievements__c, AgencyOpportunity__c from Report_Opp_Link__c where Product_inquiry_sheet__c in :ids];
            } else if (objTypeStr == 'task__c') {
                links = [select Id, Opportunity__c, Product_inquiry_sheet__c, task__c, Lead__c, Tender_Information__c, Statu_Achievements__c, AgencyOpportunity__c from Report_Opp_Link__c where task__c in :ids];
            } else if (objTypeStr == 'Lead') {
                links = [select Id, Opportunity__c, Product_inquiry_sheet__c, task__c, Lead__c, Tender_Information__c, Statu_Achievements__c, AgencyOpportunity__c from Report_Opp_Link__c where Lead__c in :ids];
            } else if (objTypeStr == 'Tender_Information__c') {
                links = [select Id, Opportunity__c, Product_inquiry_sheet__c, task__c, Lead__c, Tender_Information__c, Statu_Achievements__c, AgencyOpportunity__c from Report_Opp_Link__c where Tender_Information__c in :ids];
            } else if (objTypeStr == 'Statu_Achievements__c') {
                links = [select Id, Opportunity__c, Product_inquiry_sheet__c, task__c, Lead__c, Tender_Information__c, Statu_Achievements__c, AgencyOpportunity__c from Report_Opp_Link__c where Statu_Achievements__c in :ids];
            } else if (objTypeStr == 'Agency_Opportunity__c') {
                links = [select Id, Opportunity__c, Product_inquiry_sheet__c, task__c, Lead__c, Tender_Information__c, Statu_Achievements__c, AgencyOpportunity__c from Report_Opp_Link__c where AgencyOpportunity__c in :ids];
            }
            List<Report_Opp_Link__c> waitToInsert = new List<Report_Opp_Link__c>();
            for (String oid : ids) {
                Boolean insertFlag = true;
                if (links != null && links.size() > 0) {
                    for(Report_Opp_Link__c l : links) {
                        if (l.Opportunity__c == oid || 
                        l.Product_inquiry_sheet__c == oid || 
                        l.Lead__c == oid || 
                        l.Tender_Information__c == oid || 
                        l.Statu_Achievements__c == oid || 
                        l.AgencyOpportunity__c == oid ) {
                            insertFlag = false;
                            break;
                        }
                    }
                }
                if (insertFlag) {
                    Report_Opp_Link__c link = new Report_Opp_Link__c();
                    if (objTypeStr == 'Opportunity'){
                        link.Opportunity__c = oid;
                    } else if (objTypeStr == 'Inquiry_form__c') {
                        link.Product_inquiry_sheet__c = oid;
                    } else if (objTypeStr == 'task__c') {
                        link.task__c = oid;
                    } else if (objTypeStr == 'Lead') {
                        link.Lead__c = oid;
                    } else if (objTypeStr == 'Tender_Information__c') {
                        link.Tender_Information__c = oid;
                    } else if (objTypeStr == 'Statu_Achievements__c') {
                        link.Statu_Achievements__c = oid;
                    } else if (objTypeStr == 'Agency_Opportunity__c') {
                        link.AgencyOpportunity__c = oid;
                    } else {
                        continue;
                    }
                    waitToInsert.add(link);
                }
            }
            if (waitToInsert != null && waitToInsert.size() > 0) {
                insert waitToInsert;
            }
            iflog.Log__c += waitToInsert.size() + ' datas insert';
            update iflog;
        } catch (Exception ex) {
            iflog.ErrorLog__c += ex.getMessage();
            update iflog;
        } 
    }

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