trigger TrainingTestResultTrigger on Training_test_Result__c (before insert, before update, after insert, after update, after delete) {
    // 更新对象 Contact 
    Map<Id, SObject> updateContact = new Map<Id, SObject>();
    if (trigger.isBefore) {
        Map<Id, Id> contactIdForUser = new Map<Id, Id>();
        for (Training_test_Result__c local : trigger.New) {
            if (local.employee__c != null
                    && (trigger.isInsert
                        || trigger.oldMap.get(local.Id).employee__c != local.employee__c
                    )
            ) {
                contactIdForUser.put(local.employee__c, local.employee__c);
            }
        }
        // OwnerIdの設定
        if (contactIdForUser.size() > 0) {
            Map<Id, Contact> contacMap = ControllerUtil.selectActiveUserFromContact(contactIdForUser.values());
            for (Training_test_Result__c local : trigger.New) {
                if (local.employee__c != null
                        && (trigger.isInsert
                            || trigger.oldMap.get(local.Id).employee__c != local.employee__c
                        )
                ) {
                    Contact employee = contacMap.get(local.employee__c);
                    if (employee == null) {
                        // local.employee__c.addError('请选择有效的用户');
                        local.OwnerId = '00510000000fSYI'; // 无效用户时，设batch用户，本番和测试环境id一致
                    } else {
                        local.OwnerId = employee.User__c;
                    }
                }
            }
        }
    }
    else if (trigger.isAfter) {
        if (trigger.isDelete) {
            for (Training_test_Result__c old : trigger.old) {
                if (old.RecordTypeId != null && old.employee__c != null) {
                    if (!updateContact.containsKey(old.employee__c)) {
                        SObject so = new Contact(Id = old.employee__c);
                        updateContact.put(old.employee__c, so);
                    }
                }
            }
        } else {
            for (Training_test_Result__c local : trigger.New) {
                // 记录受到插入和更新影响的学会
                if (local.RecordTypeId != null
                        && (trigger.isInsert
                            || trigger.oldMap.get(local.Id).RecordTypeId != local.RecordTypeId
                            || trigger.oldMap.get(local.Id).employee__c != local.employee__c
                        )
                ) {
                    if (local.employee__c != null
                            && !updateContact.containsKey(local.employee__c)) {
                        SObject so = new Contact(Id = local.employee__c);
                        updateContact.put(local.employee__c, so);
                    }
                    if (trigger.isUpdate && trigger.oldMap.get(local.Id).employee__c != null
                            && !updateContact.containsKey(trigger.oldMap.get(local.Id).employee__c)) {
                        SObject so = new Contact(Id = trigger.oldMap.get(local.Id).employee__c);
                        updateContact.put(trigger.oldMap.get(local.Id).employee__c, so);
                    }
                }
            }
        }
    }
    
    // 汇总社内培训考试结果件数
    if (updateContact.size() > 0) {
        Map<String, String> apiMap = new Map<String, String>();
        List<RecordType> rtList = ControllerUtil.recordTypeSelectForTrainingtestResult();
        for (RecordType rt : rtList) {
            // 根据RecordType拼接字段
            apiMap.put(rt.DeveloperName, 'Number_of_participant_for_' + rt.DeveloperName + '__c');
        }
        
        for (SObject so : updateContact.values()) {
            for (RecordType rt : rtList) {
                so.put(apiMap.get(rt.DeveloperName), 0);
            }
        }
        
        List<Training_test_Result__c> ttrList = ControllerUtil.trainingtestResultSelectByContactIds(updateContact.keySet());
        // 逐条汇总计算
        for (Training_test_Result__c ttr : ttrList) {
            SObject so = updateContact.get(ttr.employee__c);
            Integer cnt = Integer.valueof(so.get(apiMap.get(ttr.RecordType.DeveloperName))) + 1;
            so.put(apiMap.get(ttr.RecordType.DeveloperName), cnt);
        }
        
        ControllerUtil.updateSObjectContact(updateContact.values());
    }
}