public without sharing class TransferApplyDetailHandler extends Oly_TriggerHandler {
    private Map<Id, TransferApplyDetail__c> newMap;
    private Map<Id, TransferApplyDetail__c> oldMap;
    private List<TransferApplyDetail__c> newList;
    private List<TransferApplyDetail__c> oldList;
    private static Map<Id, Asset> assMap = new Map<Id, Asset>(); // new Only
    private static Map<Id, Asset> assUpdMap = new Map<Id, Asset>(); // new と old，用于更新明细连着的Asset
    private static Map<String, Asset> newAssetMap = new Map<String, Asset>(); // ukey->Asset，明细没有连着的，调拨后需要更新或新建的Asset
    private static Map<String, List<Id>> uKeyMap = new Map<String, List<String>>(); // ukeyMap

    private static String userid = UserInfo.getUserId();
    private static DateTime now = System.now();
    public TransferApplyDetailHandler() {
        this.newMap = (Map<Id, TransferApplyDetail__c>) Trigger.newMap;
        this.oldMap = (Map<Id, TransferApplyDetail__c>) Trigger.oldMap;
        if(this.oldMap == null) {
            this.oldMap = new Map<Id, TransferApplyDetail__c>();
        }
        this.newList = (List<TransferApplyDetail__c>) Trigger.new;
        this.oldList = (List<TransferApplyDetail__c>) Trigger.old;
        if(this.oldList == null) {
            this.oldList = new List<TransferApplyDetail__c>();
        }
    }
    protected override void beforeInsert() {
        beforeSetValue();
    }
    protected override void beforeUpdate() {
        beforeSetValue();
    }
    protected override void afterInsert() {
        setFirstDetail();
        Set<Id> assIds = new Set<Id>();
        for (TransferApplyDetail__c raesd : newList) {
            if (String.isNotBlank(raesd.Asset__c)) {
                assIds.add(raesd.Asset__c);
            }
        }
        if (Trigger.isInsert && !assIds.isEmpty()) {
            assMap = getAsset(assIds);
        }
        changeAsset();
        changeAssetLast();
        if (!assUpdMap.isEmpty()) {
            update assUpdMap.values();
        }
        // 修改link里的调拨冻结数
        changeOneToOneLinkFronze();
        formulaToTextCheck();
    }
    protected override void afterUpdate() {
        setFirstDetail();
        Set<Id> assIds = new Set<Id>();
        for (TransferApplyDetail__c raesd : oldList) {
            if (String.isNotBlank(raesd.Asset__c)) {
                assIds.add(raesd.Asset__c);
            }
        }
        for (TransferApplyDetail__c raesd : newList) {
            if (String.isNotBlank(raesd.Asset__c)) {
                assIds.add(raesd.Asset__c);
            }
        }
        if (Trigger.isUpdate && !assIds.isEmpty()) {
            assMap = getAsset(assIds);
        }
        changeAsset();
        changeAssetLocation();
        clearLastReserveTAESD();
        Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
        if (!assUpdMap.isEmpty()) {
            update assUpdMap.values();
        }
        if(!newAssetMap.isEmpty()) {
            upsert newAssetMap.values();
        }
        Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());

        // 修改link里的调拨冻结数
        changeOneToOneLinkFronze();
        // 下架时删link
        deleteOneToOneLink();
        // 上架时建link
        createOneToOneLink();

        oneToOne4XX();
        formulaToTextCheck();
        receivedConfirmNGSetReturnDeliverySlipText();
        setToTa_BeforeOrReturnOrCancle_Text();//20201104 ljh add  OCSM_BP5-35

        if(!newAssetMap.isEmpty()) {
            List<TransferApplyDetail__c> tdList = new List<TransferApplyDetail__c>();
            for (String ukey : uKeyMap.keySet()) {
                Id assetId = newAssetMap.get(ukey).Id;
                for (Id noId : uKeyMap.get(ukey)) {
                    tdList.add(new TransferApplyDetail__c(Id = noId, Asset_After__c = assetId));
                }
            }
            newAssetMap.clear();
            if (tdList.size() > 0) {
                update tdList;
            }
        }
    }
    protected override void afterDelete() {
        deleteReFirst();
    }
    private Map<Id, Asset> getAsset(Set<Id> assIds) {
        return new Map<Id, Asset>([
                Select Id
                     , RecordTypeId
                     , Name
                     //, AccountId
                     , Quantity
                     , Status
                     , Manage_type__c
                     , Abandoned_Inventory__c
                     , Abandoned_RealThing__c
                     , CountForRepair__c
                     , Confirm_Lost_Count__c
                     , Consumable_Guaranteen_end__c
                     , Fixture_Model_No_F__c
                     , SerialNumber
                     , Asset_loaner_category__c
                     , Product2Id
                     , unknow_serial_NO_product__c
                     , Product_Serial_No__c
                     , AssetMark__c
                     , Internal_asset_location__c
                     , Salesdepartment__c
                     , SalesProvince__c
                     , Equipment_Type__c
                     , EquipmentSet_Managment_Code__c
                     , WH_location__c
                     , TransferFrozenQuantity__c
                     , TransferFrozenAbandon__c
                     , TransferFrozenRepair__c
                     , TransferFrozenLost__c
                     , Barcode__c
                     , Hospital__c
                     , Asset_Cutoff_Date__c
                     , Asset_Cutoff_FinalDate__c
                     , Assign_Agency_FirstDate__c
                     , Assign_Agency_FinalDate__c
                     , Internal_Asset_number_key__c
                From Asset
                Where Id =: assIds
                  and Asset_loaner_category__c != '耗材'
                  and RecordTypeId = '01210000000kOPR'
                  FOR UPDATE]);
    }

    private void setFirstDetail() {
        Map<Id, TransferApplySummary__c> tasMap = new Map<Id, TransferApplySummary__c>();
        for (TransferApplyDetail__c nObj : newList) {
            TransferApplyDetail__c oObj = null;
            if(oldMap.containsKey(nObj.Id)) {
                oObj = oldMap.get(nObj.Id);
            }
            if ((oObj == null && nObj.First_TAD_Id_F__c == null)
                || (oObj != null && oObj.Is_First_TAD_F__c && !oObj.Cancel_Select__c && nObj.Cancel_Select__c)) // 第一条明细被取消
            {
                TransferApplySummary__c tas = new TransferApplySummary__c(
                        Id = nObj.TransferApplySummary__c);
                tasMap.put(nObj.TransferApplySummary__c, tas);
            }
        }
        if (tasMap.isEmpty()) {
            return;
        }
        List<TransferApplyDetail__c> tadList = [Select Id, TransferApplySummary__c, Cancel_Select__c
            From TransferApplyDetail__c
            Where TransferApplySummary__c = :tasMap.keySet()
         ORDER BY TransferApplySummary__c, Main_OneToOne__c DESC, Cancel_Select__c, Name ASC nulls last
         ];
        Id raesId = null;
        for (TransferApplyDetail__c tad : tadList) {
            if (raesId != tad.TransferApplySummary__c) {
                TransferApplySummary__c tas = tasMap.get(tad.TransferApplySummary__c);
                if(tad.Cancel_Select__c) {
                    tas.Cancel_Select__c = true;
                    tas.Cancel_Reason__c = '主动取消';
                }
                else {
                    tas.First_TAD__c = tad.Id;
                }
                raesId = tad.TransferApplySummary__c;
            }
        }
        update tasMap.values();
    }
    private void formulaToTextCheck() {
        List<TransferApplyDetail__c> raesds = new List<TransferApplyDetail__c>();
        for (TransferApplyDetail__c nObj : newList) {
            //明细状态没有修理完毕所以修理完毕的时候不拷贝状态到Text字段
            if ((nObj.Repair_Status_Text__c != nObj.Repair_Status_F__c
                        && nObj.Repair_Status_F__c != '修理完毕')
                    || nObj.Return_Status_Text__c != nObj.Return_Status_F__c
                    || nObj.Shipment_Status_Text__c != nObj.Shipment_Status_F__c
                    || (nObj.ApplyPersonAppended__c != nObj.ApplyPersonAppended_F__c && Trigger.isInsert)
                    ) {
                TransferApplyDetail__c raesd = new TransferApplyDetail__c(Id = nObj.Id);
                //明细状态没有修理完毕所以修理完毕的时候不拷贝状态到Text字段
                if (nObj.Repair_Status_F__c != '修理完毕') {
                    raesd.Repair_Status_Text__c = nObj.Repair_Status_F__c;
                }
                raesd.Return_Status_Text__c = nObj.Return_Status_F__c;
                raesd.Shipment_Status_Text__c = nObj.Shipment_Status_F__c;
                if (Trigger.isInsert) {
                    raesd.ApplyPersonAppended__c = nObj.ApplyPersonAppended_F__c;
                }
                raesds.add(raesd);
            }
        }
        if (!raesds.isEmpty()) {
            update raesds;
        }
    }
    private void beforeSetValue() {
        //20201109 ljh add start
        Set<Id> tasSet = new Set<Id>();
        for (TransferApplyDetail__c nObj : newList) {
            tasSet.add(nObj.TransferApplySummary__c);
        }
        Map<Id, TransferApplySummary__c> tasMap = new Map<Id, TransferApplySummary__c>([Select Id, Name,Name_F__c,First_TAD_Model_No_F__c,IndexFromUniqueKey__c
                From TransferApplySummary__c
                Where Id =: tasSet]);
        //20201109 ljh add end
        for (TransferApplyDetail__c nObj : newList) {
            //因为是Insert时候设值  情况1，申请新建会设值  情况2，NG拷贝出来的时候会设值
            if (Trigger.isInsert) {
                // 272チケット
                // Create_State__c为空并且申请书的标准批准时间不为空的时候设置为1
                // 1 --- 追加附属品
                // 0 --- Cancel拷贝
                // null --- 普通新规
                if (nObj.Create_State__c == null && nObj.Transfer_Apply_Request_approval_time_F__c != null) {
                    nObj.Create_State__c = 1;
                }
                nObj.TransferCount__c = 1;
                nObj.Loaner_accsessary__c = nObj.Loaner_accsessary_F__c;
            }
            if (nObj.DeliverySlip__c != null && nObj.Shippment_loaner_time__c == null) {
                nObj.Shippment_loaner_time__c = nObj.Shippment_loaner_time_F__c;
            }
            nObj.RecordTypeDeNameText__c = nObj.RecordType_F__c;
            //nObj.DeliverySlip_Text__c = nObj.DeliverySlip__c;
            nObj.Return_DeliverySlip_Text__c = nObj.Return_DeliverySlip__c;
            //nObj.Received_Confirm_Text__c = nObj.Received_Confirm_F__c;
            nObj.Transfer_Apply_Request_approval_time__c  = nObj.ApplyPersonAppended_F__c?nObj.Add_Request_approval_time__c:nObj.Transfer_Apply_Request_approval_time_F__c;// 20210723 ljh add SFDC-C56D3K 处理历史数据
            TransferApplyDetail__c oObj = null;
            if (Trigger.isUpdate) {
                oObj = oldMap.get(nObj.Id);
                 if (oObj.ArrivalResult__c != nObj.ArrivalResult__c) {
                    //nObj.Lost_item_check_staff__c = null;
                    //nObj.Lost_item_check_time__c = null;
                    //nObj.Check_lost_Item__c = null;
                    nObj.ArrivalResult_User__c = userid;
                    nObj.ArrivalResult_DateTime__c = now;
                    nObj.Inspection_result_after_ng__c = null;
                    nObj.Inspection_staff_After__c = null;
                    nObj.Inspection_result_after__c = null;
                    nObj.After_Inspection_time__c = null;
                    //20210108 ljh update start
                    if(String.isNotBlank(oObj.Check_lost_Item__c) && oObj.Check_lost_Item__c == '欠品'){
                        if (nObj.ArrivalResult__c == '欠品') {
                            nObj.Check_lost_Item_Final__c = '欠品';
                        }
                        else if (nObj.ArrivalResult__c == 'OK') {
                            nObj.Check_lost_Item_Final__c = 'OK';
                        }
                        else if (nObj.ArrivalResult__c == 'NG') {
                            nObj.Check_lost_Item_Final__c = 'OK';
                            if(String.isNotBlank(nObj.Return_DeliverySlip__c)){
                               nObj.Inspection_result_after_Final__c = 'NG';
                            }
                        }
                    }else{
                         if (nObj.ArrivalResult__c == '欠品') {
                            nObj.Check_lost_Item__c = '欠品';
                        }
                        else if (nObj.ArrivalResult__c == 'OK') {
                            nObj.Check_lost_Item__c = 'OK';
                        }
                        else if (nObj.ArrivalResult__c == 'NG') {
                            nObj.Check_lost_Item__c = 'OK';
                            if(String.isNotBlank(nObj.Return_DeliverySlip__c)){
                               nObj.Inspection_result_after_Final__c = 'NG';
                            }
                        }
                    }
                    /*if (oObj.ArrivalResult__c != '欠品') {
                        if (nObj.ArrivalResult__c == '欠品') {
                            nObj.Check_lost_Item__c = '欠品';
                        }
                        else if (nObj.ArrivalResult__c == 'OK') {
                            nObj.Check_lost_Item__c = 'OK';
                        }
                        else if (nObj.ArrivalResult__c == 'NG') {
                            nObj.Check_lost_Item__c = 'OK';
                            // nObj.Inspection_result_after__c = 'NG';
                        }
                    }
                    else {
                        if (nObj.ArrivalResult__c == '欠品') {
                            nObj.Check_lost_Item_Final__c = '欠品';
                        }
                        else if (nObj.ArrivalResult__c == 'OK') {
                            nObj.Check_lost_Item_Final__c = 'OK';
                        }
                        else if (nObj.ArrivalResult__c == 'NG') {
                            nObj.Check_lost_Item_Final__c = 'OK';
                            nObj.Inspection_result_after_Final__c = 'NG';
                        }
                    }*/
                    //20210108 ljh update end
                }
                //出库前检查NGの場合キャンセルします
                if(oObj.Inspection_result__c != 'NG' && nObj.Inspection_result__c == 'NG') {
                    nObj.Cancel_Select__c = true;
                    nObj.Cancel_Mem__c = userid;
                    nObj.Cancel_Time__c = now;
                    nObj.Cancel_Reason__c = '出库前检查NG';
                    //nObj.Asset__c = null;
                }

                if (oObj.Inspection_result__c != nObj.Inspection_result__c && String.isNotBlank(nObj.Inspection_result__c)) {
                    nObj.Pre_inspection_time__c = now;
                    nObj.Inspection_staff__c = userid;
                }

                if (oObj.Asset_return_time__c == nObj.Asset_return_time__c) {

                    if (oObj.Check_lost_Item_Final__c != nObj.Check_lost_Item_Final__c && String.isNotBlank(nObj.Check_lost_Item_Final__c)) {
                        nObj.Lost_item_check_time_Final__c = now;
                        nObj.Lost_item_check_staff_Final__c = userid;
                        //nObj.Return_DeliverySlip__c = null;
                    }

                    if (oObj.Check_lost_Item__c != nObj.Check_lost_Item__c && String.isNotBlank(nObj.Check_lost_Item__c)) {
                        nObj.Lost_item_check_time__c = now;
                        nObj.Lost_item_check_staff__c = userid;
                    }

                    if (oObj.CDS_complete__c != nObj.CDS_complete__c && nObj.CDS_complete__c) {
                        nObj.CDS_complete_time__c = now;
                        nObj.CDS_staff__c = userid;
                    }

                    if (oObj.Inspection_result_after_Final__c != nObj.Inspection_result_after_Final__c && String.isNotBlank(nObj.Inspection_result_after_Final__c)) {
                        nObj.After_Inspection_time_Final__c = now;
                        nObj.Inspection_staff_After_Final__c = userid;
                    }

                    if (oObj.Inspection_result_after__c != nObj.Inspection_result_after__c && String.isNotBlank(nObj.Inspection_result_after__c)) {
                        nObj.After_Inspection_time__c = now;
                        nObj.Inspection_staff_After__c = userid;
                    }
                }

                if (nObj.Cancel_Select__c) {
                    if (nObj.StockDown__c && nObj.Inspection_result__c != 'NG'
                            && String.isBlank(nObj.DeliverySlip__c)) {
                        nObj.OnStock_By_Cancel__c = true;
                    }
                }

                if (Trigger.isInsert || oObj.Cancel_Select__c != nObj.Cancel_Select__c) {
                    if (nObj.Cancel_Select__c) {
                        nObj.Cancel_Time__c = now;
                        nObj.Cancel_Mem__c = userid;
                        // 未下架和办事处下架要清，其它下架后取消不清
                        if(!nObj.StockDown__c || nObj.RecordType_F__c == 'AgencyToCenter') {
                            nObj.Asset__c = null;
                            nObj.StockDown__c = false;
                            nObj.StockDown_time__c = null;
                            nObj.StockDown_staff__c = null;
                            nObj.Shipment_request_time2__c = null;
                        }
                        nObj.Shipment_request_time2__c = null;
                    }
                    else {
                        nObj.Cancel_Time__c = null;
                        nObj.Cancel_Mem__c = null;
                        nObj.Cancel_Reason__c = null;
                    }
                }
                // 归还后CDS
                if (Trigger.isInsert || oObj.CDS_complete__c != nObj.CDS_complete__c) {
                    if (nObj.CDS_complete__c) {
                        nObj.CDS_complete_time__c = now;
                        nObj.CDS_staff__c = userid;
                    } else {
                        nObj.CDS_complete_time__c = null;
                        nObj.CDS_staff__c = null;
                    }
                }

                if (Trigger.isUpdate
                    && ((oObj.Inspection_result_after_Final__c != 'NG'
                            && nObj.Inspection_result_after_Final__c == 'NG'
                            && nObj.Inspection_result_after_NG_Final__c == '维修')
                        || (oObj.Inspection_result_after__c != 'NG'
                            && nObj.Inspection_result_after__c == 'NG'
                            && nObj.Inspection_result_after_NG__c == '维修')
                    )
                ) {
                    nObj.Repair__c = null;
                }

                // OLY_OCM-531 Start 搬工作流规则
                if (nObj.Check_lost_Item_F__c == '欠品'
                        && nObj.Loaner_Giveup_Time__c == null
                        && nObj.Lost_item_giveup__c == true) {
                    nObj.Loaner_Giveup_Time__c = Datetime.now();
                }

                // OLY_OCM-531 End
                if (Trigger.isUpdate
                        &&oObj.Confirm_Lost_Date__c != null
                        && oObj.Check_lost_Item_F__c != nObj.Check_lost_Item_F__c
                        && oObj.Check_lost_Item_F__c == '欠品') {
                    nObj.Confirm_Lost_Date__c = null;
                }

                if (Trigger.isUpdate
                    && oObj.Arrival_in_wh__c == false
                    && nObj.Arrival_in_wh__c == true
                    && nObj.Manage_type_F__c == '个体管理') {
                    nObj.Asset_After__c = nObj.Asset__c;
                }
            }
            //20201109 ljh OCSM_BP5-44 调拨单设定对应_申请，一览，明细的命名规则 start
            TransferApplySummary__c tas = tasMap.get(nObj.TransferApplySummary__c);
            //IndexFromUniqueKey__c.format()会报错 要判不是Null
            if ( tas != null
                && tas.IndexFromUniqueKey__c != null
                && nObj.IndexFromUniqueKey__c != null
            ) {
                nObj.Name = tas.Name_F__c + ':'+tas.First_TAD_Model_No_F__c+':'+tas.IndexFromUniqueKey__c.format().leftpad(3, '0');
                nObj.Name += ':' + nObj.FSD_SortInt__c.format().leftpad(2, '0') + ':'+ nObj.IndexFromUniqueKey__c.format().leftpad(3, '0');
                //取消的时候名字加Canceled
                if (nObj.Cancel_Select__c) {
                    nObj.Name += ':Canceled';
                }
            }
            //20201109 ljh OCSM_BP5-44 调拨单设定对应_申请，一览，明细的命名规则 end
        }
    }
    private void changeAssetFrozen(TransferApplyDetail__c nObj, Asset ass, Integer cnt) {
        changeAssetFrozen(nObj, ass, cnt, false);
    }
    /**
    @description 修改保有设备里的各个调拨冻结数
    @param nObj 调拨明细
    @param ass 保有设备
    @param cnt +1或-1
    @param isFinish 是否要反映到有效库存
    */
    private void changeAssetFrozen(TransferApplyDetail__c nObj, Asset ass, Integer cnt, Boolean isFinish) {

        switch on nObj.TransferType__c {
            when '待废弃' {
                ass.TransferFrozenAbandon__c = intValueOf(ass.TransferFrozenAbandon__c) + cnt;
                if(isFinish) {
                    ass.Abandoned_RealThing__c = intValueOf(ass.Abandoned_RealThing__c ) + cnt;
                }
            }
            when '待修理' {
                ass.TransferFrozenRepair__c = intValueOf(ass.TransferFrozenRepair__c) + cnt;
                if(isFinish) {
                    ass.CountForRepair__c = intValueOf(ass.CountForRepair__c) + cnt;
                }
            }
            when '丢失找回' {
                ass.TransferFrozenLost__c = intValueOf(ass.TransferFrozenLost__c) + cnt;
                if(isFinish) {
                    ass.Abandoned_Inventory__c = intValueOf(ass.Abandoned_Inventory__c) + cnt;
                }
            }
            when else {
                ass.TransferFrozenQuantity__c = intValueOf(ass.TransferFrozenQuantity__c) + cnt;
            }
        }
    }
    private void changeAsset() {
        if (Trigger.isAfter) {
            if (assMap.isEmpty()) {
                return;
            }

            for (TransferApplyDetail__c nObj : newList) {
                TransferApplyDetail__c oObj = null;
                if (Trigger.isUpdate) {
                    oObj = oldMap.get(nObj.Id);
                }
                Asset ass = null;
                if (assMap.containsKey(nObj.Asset__c)) {
                    ass = assMap.get(nObj.Asset__c);
                }
                else if(oObj != null && assMap.containsKey(oObj.Asset__c)) {
                    ass = assMap.get(oObj.Asset__c);
                }
                if(ass == null) {
                    continue;
                }

                // Abandoned_Inventory__c  null -> 0
                if (ass.Abandoned_Inventory__c == null) {
                    ass.Abandoned_Inventory__c = 0;
                }
                // Abandoned_RealThing__c  null -> 0
                if (ass.Abandoned_RealThing__c == null) {
                    ass.Abandoned_RealThing__c = 0;
                }

                if (ass.Confirm_Lost_Count__c == null) {
                    ass.Confirm_Lost_Count__c = 0;
                }
                if (ass.TransferFrozenQuantity__c == null) {
                    ass.TransferFrozenQuantity__c = 0;
                }
                if (ass.CountForRepair__c == null) {
                    ass.CountForRepair__c = 0;
                }
                if(oObj == null) {
                    // 备品中心直接追加的明细
                    if(nObj.Approved_F__c) {
                        if(nObj.RecordType_F__c != 'InsideCenter') {
                            changeAssetFrozen(nObj, ass, 1);
                            assUpdMap.put(ass.Id, ass);
                        }
                    }
                    continue;
                }
                // 审批后下架前取消时，要解冻
                if (nObj.Approved_F__c && !nObj.StockDown__c && !oObj.Cancel_Select__c && nObj.Cancel_Select__c) {
                    changeAssetFrozen(nObj, ass, -1);
                    assUpdMap.put(ass.Id, ass);
                }
                // 首次提交审批
                else if(nObj.Create_State__c == null && oObj.Request_time__c != nObj.Request_time__c) {
                    // 提交时冻结数+1
                    if(nObj.Request_time__c != null) {
                        // 一对一附属品不用占调拨冻结数
                        if(nObj.RecordType_F__c != 'InsideCenter') {
                            changeAssetFrozen(nObj, ass, 1);
                            assUpdMap.put(ass.Id, ass);
                        }
                    }
                    // 驳回时冻结数-1
                    else {
                        if(nObj.RecordType_F__c != 'InsideCenter') {
                            changeAssetFrozen(nObj, ass, -1);
                            assUpdMap.put(ass.Id, ass);
                        }
                    }
                }
                // 提交追加审批
                else if(nObj.Create_State__c == 1 && oObj.Add_Request_demo_time__c != nObj.Add_Request_demo_time__c) {
                    // 提交时冻结数+1
                    if (nObj.Add_Request_demo_time__c != null) {
                        if(nObj.RecordType_F__c != 'InsideCenter') {
                            changeAssetFrozen(nObj, ass, 1);
                            assUpdMap.put(ass.Id, ass);
                        }
                    }
                    // 驳回时冻结数-1
                    else {
                        if(nObj.RecordType_F__c != 'InsideCenter') {
                            changeAssetFrozen(nObj, ass, -1);
                            assUpdMap.put(ass.Id, ass);
                        }
                    }
                }

                if (String.isBlank(oObj.Check_lost_Item_F__c) && nObj.Check_lost_Item_F__c == 'OK') {
                    //空->OK
                } else if (String.isBlank(oObj.Check_lost_Item_F__c) && nObj.Check_lost_Item_F__c == '欠品'
                        && nObj.Lost_item_giveup__c == false) {
                    //空->欠品
                } else if (String.isBlank(oObj.Check_lost_Item_F__c) && nObj.Check_lost_Item_F__c == '欠品'
                    && nObj.Lost_item_giveup__c == true) {
                    //空->欠品 and 放弃欠品回收（丢失）时，待废弃数(丢失/盘亏)加1，调拨冻结数-1
                    ass.Abandoned_Inventory__c += 1;
                    changeAssetFrozen(nObj, ass, -1, true);
                    if (oObj.Confirm_Lost_Date__c != null) {
                        ass.Confirm_Lost_Count__c -= 1;
                    }
                    assUpdMap.put(ass.Id, ass);
                } else if (String.isBlank(oObj.Check_lost_Item_F__c) && nObj.Check_lost_Item_F__c == '消耗') {
                    // 空->消耗，数量-1，调拨冻结数-1
                    ass.Quantity -= 1;
                    changeAssetFrozen(nObj, ass, -1, true);
                    ass.ChangeQuantityReason__c = '消耗';
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == 'OK' && String.isBlank(nObj.Check_lost_Item_F__c)) {
                    //OKから空白に変更時何もしません
                } else if (oObj.Check_lost_Item_F__c == 'OK' && nObj.Check_lost_Item_F__c == '欠品'
                        && nObj.Lost_item_giveup__c == false) {
                    //OKから欠品に変更時何もしません
                } else if (oObj.Check_lost_Item_F__c == 'OK' && nObj.Check_lost_Item_F__c == '欠品'
                        && nObj.Lost_item_giveup__c == true) {
                    //OK->欠品 and 放弃欠品回收（丢失）时，待废弃数(丢失/盘亏)加1，调拨冻结数-1
                    ass.Abandoned_Inventory__c += 1;
                    changeAssetFrozen(nObj, ass, -1, true);
                    if (oObj.Confirm_Lost_Date__c != null) {
                        ass.Confirm_Lost_Count__c -= 1;
                    }
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == 'OK' && nObj.Check_lost_Item_F__c == '消耗') {
                    //OK->消耗，数量-1，调拨冻结数-1
                    ass.Quantity -= 1;
                    changeAssetFrozen(nObj, ass, -1, true);
                    ass.ChangeQuantityReason__c = '消耗';
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '欠品' && String.isBlank(nObj.Check_lost_Item_F__c)
                        && oObj.Lost_item_giveup__c == false) {
                    if (oObj.Confirm_Lost_Date__c != null) {
                        ass.Confirm_Lost_Count__c -= 1;
                    }
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '欠品' && nObj.Check_lost_Item_F__c == 'OK'
                        && oObj.Lost_item_giveup__c == false) {
                    if (oObj.Confirm_Lost_Date__c != null) {
                        ass.Confirm_Lost_Count__c -= 1;
                    }
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '欠品' && nObj.Check_lost_Item_F__c == '欠品'
                        && oObj.Lost_item_giveup__c == false && nObj.Lost_item_giveup__c == true) {
                    //欠品 且 放弃欠品回收（丢失）时，待废弃数(丢失/盘亏)+1,调拨冻结数-1
                    ass.Abandoned_Inventory__c += 1;
                    changeAssetFrozen(nObj, ass, -1, true);
                    if (oObj.Confirm_Lost_Date__c != null) {
                        ass.Confirm_Lost_Count__c -= 1;
                    }
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '欠品' && nObj.Check_lost_Item_F__c == '消耗'
                        && oObj.Lost_item_giveup__c == false) {
                    //欠品->消耗,数量-1，调拨冻结数-1
                    ass.Quantity -= 1;
                    changeAssetFrozen(nObj, ass, -1, true);
                    ass.ChangeQuantityReason__c = '消耗';
                    if (oObj.Confirm_Lost_Date__c != null) {
                        ass.Confirm_Lost_Count__c -= 1;
                    }
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '欠品' && String.isBlank(nObj.Check_lost_Item_F__c) && oObj.Lost_item_giveup__c == true) {
                    //欠品放棄から空白に変更時 待废弃数(丢失/盘亏)减1
                    ass.Abandoned_Inventory__c -= 1;
                    changeAssetFrozen(nObj, ass, 1, true);
                    ass.ChangeQuantityReason__c = '欠品' + '->' + '';
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '欠品' && nObj.Check_lost_Item_F__c == 'OK' && oObj.Lost_item_giveup__c == true) {
                    //欠品放棄からOKに変更時 待废弃数(丢失/盘亏)减1
                    ass.Abandoned_Inventory__c -= 1;
                    changeAssetFrozen(nObj, ass, 1, true);
                    ass.ChangeQuantityReason__c = '欠品' + '->' + 'OK';
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '欠品' && nObj.Check_lost_Item_F__c == '欠品'
                        && oObj.Lost_item_giveup__c == true && nObj.Lost_item_giveup__c == false) {
                    //欠品放棄から欠品に変更時 待废弃数(丢失/盘亏)减1
                    ass.Abandoned_Inventory__c -= 1;
                    changeAssetFrozen(nObj, ass, 1, true);
                    ass.ChangeQuantityReason__c = '欠品放弃 -> ' + '欠品';
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '欠品' && nObj.Check_lost_Item_F__c == '消耗' && oObj.Lost_item_giveup__c == true) {
                    //欠品放棄から消耗に変更時 待废弃数(丢失/盘亏)减1 Quantityを-1
                    ass.Abandoned_Inventory__c -= 1;
                    ass.Quantity -= 1;
                } else if (oObj.Check_lost_Item_F__c == '消耗' && String.isBlank(nObj.Check_lost_Item_F__c)) {
                    //消耗から空白に変更時Quantityを+1
                    ass.Quantity += 1;
                    changeAssetFrozen(nObj, ass, 1, true);
                    ass.ChangeQuantityReason__c = '消耗 -> ' + '';
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '消耗' && nObj.Check_lost_Item_F__c == 'OK') {
                    //消耗から空白に変更時Quantityを+1
                    ass.Quantity += 1;
                    changeAssetFrozen(nObj, ass, 1, true);
                    ass.ChangeQuantityReason__c = '消耗 -> ' + 'OK';
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '消耗' && nObj.Check_lost_Item_F__c == '欠品'
                        && nObj.Lost_item_giveup__c == false) {
                    //消耗->欠品，数量+1，调拨冻结数+1
                    ass.Quantity += 1;
                    changeAssetFrozen(nObj, ass, 1, true);
                    ass.ChangeQuantityReason__c = '消耗 -> 欠品';
                    assUpdMap.put(ass.Id, ass);
                } else if (oObj.Check_lost_Item_F__c == '消耗' && nObj.Check_lost_Item_F__c == '欠品'
                        &&  nObj.Lost_item_giveup__c == true) {
                    //消耗->欠品 and 放棄, 待废弃数(丢失/盘亏)+1，数量+1
                    ass.Quantity += 1;
                    ass.Abandoned_Inventory__c += 1;
                    assUpdMap.put(ass.Id, ass);
                }

                //待废弃
                if (nObj.TAESD_Status__c == FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Dai_Fei_Qi.ordinal())
                        && oObj.TAESD_Status__c != nObj.TAESD_Status__c
                        && ass.Manage_type__c == '个体管理') {
                    ass.Status = FixtureUtil.assetStatusMap.get(FixtureUtil.AssetStatus.Dai_Fei_Qi.ordinal());
                    assUpdMap.put(ass.Id, ass);
                }
            }
        }
    }
    /*
     * 回库确认 OFF -> ON:
     * 取消分配 OFF -> ON:
     * 放弃欠品 OFF -> ON
     * 已消耗
     *
     *  清空Asset 最新备品申请借出明细 Last_Reserve_RAES_Detail__c
     *  (nObj.Asset__c 変更しないため、changeAssetLast()でクリアできないため、ここでクリア)
     *
     * クラスの assUpdMap を更新するだけ
     */
    private void clearLastReserveTAESD() {
        for (TransferApplyDetail__c nObj : newList) {
            TransferApplyDetail__c oObj = oldMap.get(nObj.Id);
            // 主体和附属品
            if (finishOrChangeAsset(Trigger.isDelete, oObj, nObj)) {
                Asset ass = null;
                if (assUpdMap.containsKey(oObj.Asset__c)) {
                    ass = assUpdMap.get(oObj.Asset__c);
                }
                // 这里 会出现 assUpdMap 有 但是 assMap 没有的情况
                if (ass == null
                        //分配备品有变化 (下架前)
                        && (oObj.Asset__c != null && oObj.Asset__c != nObj.Asset__c
                                && nObj.StockDown__c == false)) {
                    ass = new Asset(Id = oObj.Asset__c);
                }
                if (ass == null) {
                    continue;
                }
                // 暂时放在这里
                if (oObj.Manage_type_F__c == '个体管理') {
                    ass.Last_Reserve_TAES_Detail__c = null;
                    assUpdMap.put(ass.Id, ass);
                }
            }
        }
    }
    //nObj.Asset__cがある場合、変更した場合
    private void changeAssetLast() {
        for (TransferApplyDetail__c nObj : newList) {
            TransferApplyDetail__c oObj = null;
            if(Trigger.isUpdate){
                oObj = oldMap.get(nObj.Id);
            }
            Asset nass = assMap.get(nObj.Asset__c);
            if (assUpdMap.containsKey(nObj.Asset__c)) {
                nass = assUpdMap.get(nObj.Asset__c);
            } else if (String.isNotBlank(nObj.Asset__c)) {
                nass = new Asset(Id = nObj.Asset__c);
            }
            if(oObj != null) {
                Asset oass = assMap.get(oObj.Asset__c);
                if (assUpdMap.containsKey(oObj.Asset__c)) {
                    oass = assUpdMap.get(oObj.Asset__c);
                } else if (String.isNotBlank(oObj.Asset__c)) {
                    oass = new Asset(Id = oObj.Asset__c);
                }
                //nObj.Asset__cがある場合、変更した場合
                if (nObj.Asset__c != null && oObj.Asset__c != nObj.Asset__c
                        && (oObj.Manage_type_F__c == '个体管理' || nObj.Manage_type_F__c == '个体管理')) {
                    if (nObj.Manage_type_F__c == '个体管理') {
                        nass.Last_Reserve_TAES_Detail__c = nObj.Id;
                        assUpdMap.put(nass.Id, nass);
                    }
                    if (oObj.Manage_type_F__c == '个体管理') {
                        oass.Last_Reserve_TAES_Detail__c = null;
                        assUpdMap.put(oass.Id, oass);
                    }
                }
            }
            else if (nObj.Asset__c != null && nObj.Manage_type_F__c == '个体管理') {
                nass.Last_Reserve_TAES_Detail__c = nObj.Id;
                assUpdMap.put(nass.Id, nass);
            }
        }
    }
    private void setAssetDate(Asset ass, String recordTypeName, Date today) {
        switch on recordTypeName {
            when 'AgencyToCenter', 'CenterToCenter' {
                if(ass.Asset_Cutoff_Date__c == null) {
                    ass.Asset_Cutoff_Date__c = today;
                }
                else {
                    ass.Asset_Cutoff_FinalDate__c = today;
                }
            }
            when 'CenterToAgency' {
                if(ass.Assign_Agency_FirstDate__c == null) {
                    ass.Assign_Agency_FirstDate__c = today;
                }
                else {
                    ass.Assign_Agency_FinalDate__c = today;
                }
            }
        }
    }
    // 上架存放地变更数量修改，
    private void changeAssetLocation() {

        Map<String, Integer> newAssetCountMap = new Map<String, Integer>();                         // ukey -> 调拨后保有设备的数量
        Map<String, Integer> newAssetAbondonCountMap = new Map<String, Integer>();                  // ukey-> 调拨后保有设备的待废弃数
        Map<String, TransferApplyDetail__c> newTadMap = new Map<String, TransferApplyDetail__c>(); // ukey -> 调拨明细，这些明细需要新建保有设备

        Set<String> ukeySet = new Set<String>();
        Account accountFJZ = [select Id, Hospital__c from Account where AgentCode_Ext__c = :System.Label.Account_Asset_FJZ];
        Date today = System.today();
        for (TransferApplyDetail__c nObj : newList) {
            TransferApplyDetail__c oObj = oldMap.get(nObj.Id);
            if((oObj.Arrival_in_wh__c == false && nObj.Arrival_in_wh__c == true)
                || (nObj.RecordType_F__c == 'CenterToOther' && oObj.Shippment_loaner_time__c == null && nObj.Shippment_loaner_time__c != null)) {
                Asset ass = assMap.get(nObj.Asset__c);
                // 所有保有设备上架时都先在原设备上解冻
                changeAssetFrozen(nObj, ass, -1, true);
                // 个体管理，直接改
                if(ass.Manage_type__c == '个体管理') {
                    if(String.isNotBlank(nObj.WH_location__c)) {
                        ass.WH_location__c = nObj.WH_location__c;
                    }
                    // 调拨后待废弃上架
                    if( nObj.Arrival_wh_Abandoned_Flag_F__c) {
                        ass.ChangeQuantityReason__c = FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Dai_Fei_Qi.ordinal());
                        ass.WH_location__c = '废弃区';
                        ass.Abandoned_RealThing__c += 1;
                    }
                    if(nObj.DeliverySlip__c == null || nObj.Return_DeliverySlip__c != null) {
                        // 未发货，或发出后又寄回，上架时存放地等字段不用更新
                    }
                    // 移管给本部并且已发货才要改设备信息
                    else if(nObj.RecordType_F__c == 'CenterToOther' && oObj.Shippment_loaner_time__c == null && nObj.Shippment_loaner_time__c != null) {
                        ass.ChangeQuantityReason__c = '移管';
                        ass.AccountId = accountFJZ.Id;
                        ass.Quantity = 0;
                        ass.TransferToOther__c = true;
                        // 非固定资产
                        if(String.isBlank(ass.Internal_Asset_number_key__c)) {
                            ass.Status = '未使用';
                        }
                        // 固定资产
                        else {
                            ass.SalesProvince__c = null;
                            ass.Equipment_Type__c    = null;
                            ass.Product_category__c = null;
                            ass.Loaner_accsessary__c = false;
                            ass.EquipmentSet_Managment_Code__c = null;
                            ass.Manage_type__c = null;
                            ass.Consumable_Guaranteen_end__c = null;
                            ass.Asset_Cutoff_Date__c = null;
                            ass.Asset_Cutoff_FinalDate__c = null;
                            ass.Assign_Agency_FirstDate__c = null;
                            ass.Assign_Agency_FinalDate__c = null;
                            if(String.isNotBlank(nObj.Internal_asset_location_After__c)) {
                                ass.Internal_asset_location__c = nObj.Internal_asset_location_After__c;
                            }
                            if(String.isNotBlank(nObj.Salesdepartment_After__c)) {
                                ass.Salesdepartment__c = nObj.Salesdepartment_After__c;
                            }
                        }
                    }
                    else {
                        // 如果调拨后字段为空，则不更新
                        if(String.isNotBlank(nObj.Internal_asset_location_After__c)) {
                            ass.Internal_asset_location__c = nObj.Internal_asset_location_After__c;
                        }
                        if(String.isNotBlank(nObj.Salesdepartment_After__c)) {
                            ass.Salesdepartment__c = nObj.Salesdepartment_After__c;
                        }
                        if(String.isNotBlank(nObj.SalesProvince_After__c)) {
                            ass.SalesProvince__c = nObj.SalesProvince_After__c;
                        }
                        if(String.isNotBlank(nObj.Equipment_Type_After__c)) {
                            ass.Equipment_Type__c = nObj.Equipment_Type_After__c;
                        }
                        if(String.isNotBlank(nObj.EquipmentSet_Managment_Code_After__c)) {
                            ass.EquipmentSet_Managment_Code__c = nObj.EquipmentSet_Managment_Code_After__c;
                        }
                        ass.ChangeQuantityReason__c = '调拨';
                        setAssetDate(ass, nObj.RecordType_F__c, today) ;
                        ass.Status = '使用中';
                    }
                    ass.Last_Reserve_TAES_Detail__c = null;
                }
                // 数量管理要根据调拨后信息查找已有的Asset，如果有就按型号+存放地+本部做数量合并，如果没有就新建
                //20211109 ljh SFDC-C873GL update 
                // 数量管理要根据调拨后信息查找已有的Asset，如果有就按型号+存放地+本部+消耗品有效期至 做数量合并，如果没有就新建
                else {
                    String ukey =  ass.Fixture_Model_No_F__c // 型号;调拨后存放地;调拨后本部
                            + ';' + nObj.Internal_asset_location_After__c
                            + ';' + (String.isNotBlank(nObj.Salesdepartment_After__c) ? nObj.Salesdepartment_After__c : nObj.Salesdepartment__c);
                    // 20211109 ljh SFDC-C873GL add start
                    if(ass.Consumable_Guaranteen_end__c != null){
                        ukey += ';' + String.valueOf(ass.Consumable_Guaranteen_end__c);
                    }
                    // 20211109 ljh SFDC-C873GL add end         
                    if(nObj.DeliverySlip__c == null || nObj.Return_DeliverySlip__c != null) {
                        // 未发货，或发出后又寄回，在明细所连的保有设备上做数量修改
                        if( nObj.Arrival_wh_Abandoned_Flag_F__c) {
                            ass.ChangeQuantityReason__c = FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Dai_Fei_Qi.ordinal());
                            ass.Abandoned_RealThing__c += 1;
                        }
                    }
                    else {
                        // 发货后没有寄回，原保有设备数量减少
                        ass.Quantity -= 1;
                        if(nObj.RecordType_F__c == 'CenterToOther') {
                            ass.ChangeQuantityReason__c = '移管';
                        }
                        else {
                            ass.ChangeQuantityReason__c = '调拨';
                            // 准备调拨后的保有设备数量
                            Integer count = 0;
                            if (newAssetCountMap.containsKey(ukey)) {
                                count = newAssetCountMap.get(ukey);
                            }
                            newAssetCountMap.put(ukey, count + 1);
                            // 同型号数量管理附属品中有的明细有货架号，有的明细没有货架号，这时尽量用有货架号的明细新建设备
                            if (!newTadMap.containsKey(ukey) || String.isNotBlank(nObj.WH_location__c)) {
                                newTadMap.put(ukey, nObj);
                            }
                            if(nObj.Arrival_wh_Abandoned_Flag_F__c) {
                                count = 0;
                                if(newAssetAbondonCountMap.containsKey(ukey)) {
                                    count = newAssetAbondonCountMap.get(ukey);
                                }
                                newAssetAbondonCountMap.put(ukey, count + 1);
                            }
                            ukeySet.add(ukey);
                            if (uKeyMap.containsKey(ukey) == false) {
                                uKeyMap.put(ukey, new List<Id>());
                            }
                            uKeyMap.get(ukey).add(nObj.Id);
                        }
                    }
                }
                assUpdMap.put(ass.Id, ass);
            }
        }
        String sqlwhere = '';
        if(!ukeySet.isEmpty()) {
            for(String ukey: ukeySet) {
                // 20211109 ljh SFDC-C873GL update
                // 型号;存放地;本部
                // 型号;存放地;本部;消耗品有效期至
                List<String> fields = ukey.split(';');
                // 型号
                if (String.isNotBlank(fields[0]) && fields[0] != 'null') {
                    sqlwhere += ' (Fixture_Model_No_F__c =\'' + String.escapeSingleQuotes(fields[0]) + '\'';
                } else {
                    sqlwhere += ' (Fixture_Model_No_F__c = null';
                }
                // 备品存放地
                if (String.isNotBlank(fields[1]) && fields[1] != 'null') {
                    sqlwhere += ' AND Internal_asset_location__c =\'' + String.escapeSingleQuotes(fields[1]) + '\'';
                } else {
                    sqlwhere += ' AND Internal_asset_location__c = null';
                }
                // 本部
                if (String.isNotBlank(fields[2]) && fields[2] != 'null') {
                    sqlwhere += ' AND Salesdepartment__c =\'' + String.escapeSingleQuotes(fields[2]) + '\'';
                } else {
                    sqlwhere += ' AND Salesdepartment__c = null';
                }
                // 20211109 ljh SFDC-C873GL add start
                // 消耗品有效期至
                if (fields.size() == 4 && fields[3] != null) {
                    // DateTime temp = DateTime.valueOf(fields[3]);
                    // Date cGEDate = Date.valueOf(temp);
                    sqlwhere += ' AND Consumable_Guaranteen_end__c = ' + String.valueOf(fields[3]);
                }else {
                    sqlwhere += ' AND Consumable_Guaranteen_end__c = null';
                } 
                // 20211109 ljh SFDC-C873GL add end
                sqlwhere += ' ) OR';
            }
        }
        List<Asset> upsertList = new List<Asset>();
        if (newTadMap.size() > 0) {
            sqlwhere = sqlwhere.removeEnd('OR');
            sqlwhere = '(' + sqlwhere + ')';
            String sqlStr = 'SELECT Id, Asset_loaner_category__c, Salesdepartment__c, Quantity, Manage_type__c, ImageAsset__c, ImageSerial__c, '
                                + 'Fixture_Model_No_F__c, Product_category__c, Internal_asset_location__c, Consumable_Guaranteen_end__c, '
                                + 'SalesProvince__c, EquipmentSet_Managment_Code__c, Abandoned_RealThing__c, '
                                + 'Asset_Cutoff_Date__c, Assign_Agency_FirstDate__c, '
                                + 'Equipment_Type__c, SerialNumber FROM Asset Where ' + sqlwhere
                                + ' AND Delete_Flag__c = false '
                                + ' AND Asset_Owner__c = \'Olympus\''
                                + ' AND AssetManageConfirm__c = true'
                                + ' AND Quantity >= 0'
                                + ' AND (Freeze_sign_Abandoned_Flag__c = False OR Status =\'待报废\')'
                                + ' AND Manage_type__c = \'数量管理\''
                                + ' ORDER BY Fixture_Model_No_F__c, Quantity Desc';
            List<Asset> matchingAsset = Database.query(sqlStr);
            // 如果明细里想要的保有设备已经存在，就直接把数量和待废弃数更新进去
            for (Asset ast : matchingAsset) {
                String ukey = ast.Fixture_Model_No_F__c
                            + ';' + ast.Internal_asset_location__c
                            + ';' + ast.Salesdepartment__c;
                // 20211109 ljh SFDC-C873GL update start
                if (ast.Consumable_Guaranteen_end__c != null) {
                    ukey += ';' + String.valueOf(ast.Consumable_Guaranteen_end__c);
                } 
                // 20211109 ljh SFDC-C873GL update end
                if (newTadMap.containsKey(ukey)) {
                    ast.Quantity = ast.Quantity + newAssetCountMap.get(ukey);
                    ast.ChangeQuantityReason__c = '调拨';
                    setAssetDate(ast, newTadMap.get(ukey).RecordType_F__c, today) ;
                    if(newAssetAbondonCountMap.containsKey(ukey)) {
                        ast.Abandoned_RealThing__c += newAssetAbondonCountMap.get(ukey);
                    }
                    if(ast.Abandoned_RealThing__c == ast.Quantity) {
                        ast.Status = '待报废';
                    }
                    else {
                        ast.Status = '使用中';
                    }
                    newAssetMap.put(ukey, ast);
                    newTadMap.remove(ukey);
                }
            }
        }
        // 剩下的明细需要新建保有设备
        for (String ukey : newTadMap.keySet()) {
            TransferApplyDetail__c tad = newTadMap.get(ukey);
            Asset newAset = assMap.get(tad.Asset__c).clone(false);
            newAset.unknow_serial_NO_product__c = true;
            newAset.Assign_Agency_FirstDate__c = null;
            newAset.Assign_Agency_FinalDate__c = null;
            newAset.Asset_Cutoff_Date__c = null;
            newAset.Asset_Cutoff_FinalDate__c = null;
            newAset.Status = '使用中';
            newAset.SerialNumber = null;
            newAset.Product_Serial_No__c = null; // workflow会重新赋值
            newAset.Loaner_accsessary__c = true;
            newAset.AssetManageConfirm__c = true;
            newAset.Abandoned_RealThing__c = 0;
            newAset.Abandoned_Inventory__c = 0;
            newAset.Frozen_Quantity__c = 0;
            newAset.Out_of_wh__c = 0;
            newAset.Rental_Count__c = 0;
            newAset.MaintainCount_For_Processing__c = 0;
            newAset.CountForRepair__c = 0;
            newAset.Consumed_Count__c = 0;
            newAset.TransferFrozenQuantity__c = 0;
            newAset.TransferFrozenAbandon__c = 0;
            newAset.TransferFrozenLost__c = 0;
            newAset.TransferFrozenRepair__c = 0;
            newAset.Confirm_Lost_Count__c = 0;
            newAset.Inventory_Frozen_Quantity__c = 0;
            newAset.Appended_Inventory_Frozen_Quantity__c = 0;
            newAset.Inventory_Profit_Quantity__c = 0;
            newAset.Appended_Inventory_Profit_Quantity__c = 0;
            // 更新日期
            setAssetDate(newAset, tad.RecordType_F__c, today) ;
            // 按明细更新调拨后信息
            newAset.Internal_asset_location__c = tad.Internal_asset_location_After__c;
            if(String.isNotBlank(tad.Salesdepartment_After__c)) {
                newAset.Salesdepartment__c = tad.Salesdepartment_After__c;
            }
            if(String.isNotBlank(tad.SalesProvince_After__c)) {
                newAset.SalesProvince__c = tad.SalesProvince_After__c;
            }
            if(String.isNotBlank(tad.Equipment_Type_After__c)) {
                newAset.Equipment_Type__c = tad.Equipment_Type_After__c;
            }
            if(String.isNotBlank(tad.EquipmentSet_Managment_Code_After__c)) {
                newAset.EquipmentSet_Managment_Code__c = tad.EquipmentSet_Managment_Code_After__c;
            }

            newAset.WH_location__c = tad.WH_location__c;

            newAset.Quantity = newAssetCountMap.get(ukey);
            newAset.ChangeQuantityReason__c = '调拨';
            if(newAssetAbondonCountMap.containsKey(ukey)) {
                newAset.Abandoned_RealThing__c = newAssetAbondonCountMap.get(ukey);
            }
            newAssetMap.put(ukey, newAset);
        }
    }
    private void changeOneToOneLinkFronze() {
        Map<Id, Fixture_OneToOne_Link__c> linkMap = new Map<Id, Fixture_OneToOne_Link__c>();
        for(TransferApplyDetail__c nObj:newList) {
            // 只针对一对一附属品明细
            if(!nObj.OneToOneAccessory__c || nObj.Fixture_OneToOne_Link__c == null) {
                continue;
            }
            TransferApplyDetail__c oObj = null;
            if( oldMap.containsKey(nObj.Id)){
                oObj = oldMap.get(nObj.Id);
            }

            Boolean froze = false; // 冻结为true，解冻为false
            Boolean needUpdate = false;
            // 管理员追加的明细会自动批准
            if(oObj == null && nObj.Approved_F__c) {
                froze = true;
                needUpdate = true;
            }
            // 取消明细后
            else if(oObj != null && !oObj.Cancel_Select__c && nObj.Cancel_Select__c) {
                froze = false;
                needUpdate = true;
            }
            // 首次提交审批
            else if(nObj.Create_State__c == null && oObj != null && oObj.Request_time__c != nObj.Request_time__c) {
                froze = nObj.Request_time__c != null;
                needUpdate = true;
            }
            // 提交追加审批
            else if(nObj.Create_State__c == 1 && oObj != null && oObj.Add_Request_demo_time__c != nObj.Add_Request_demo_time__c) {
                froze = nObj.Add_Request_demo_time__c != null;
                needUpdate = true;
            }

            if(needUpdate) {
                Fixture_OneToOne_Link__c link = null;
                if(linkMap.containsKey(nObj.Fixture_OneToOne_Link__c)) {
                    link = linkMap.get(nObj.Fixture_OneToOne_Link__c);
                }
                else {
                    link = new Fixture_OneToOne_Link__c(Id=nObj.Fixture_OneToOne_Link__c,
                        TransferFrozenQuantity__c = 0,
                        CountForRepair__c = 0,
                        Abandoned_RealThing__c = 0
                        );
                }
                if(froze) {
                    // 冻结时待废弃，待修理，都移到调拨冻结数
                    link.TransferFrozenQuantity__c += 1;
                }
                else {
                    // 解冻时按明细的调拨分类恢复待废弃，待修理数
                    switch on nObj.TransferType__c {
                        when '待废弃' {
                            link.Abandoned_RealThing__c += 1;
                        }
                        when '待修理' {
                            link.CountForRepair__c += 1;
                        }
                    }
                }
                linkMap.put(link.Id, link);
            }
        }
        if(!linkMap.isEmpty()) {
            Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
            update linkMap.values();
            Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
        }
    }
    private Integer intValueOf(Decimal d) {
        if(d == null) {
            return 0;
        }
        return Integer.valueOf(d);
    }
    // 主体明细下架时删link
    private void deleteOneToOneLink() {
        Set<Id> assIdSet = new Set<Id>();
        for(TransferApplyDetail__c nObj:newList) {
            TransferApplyDetail__c oObj = oldMap.get(nObj.Id);
            if(nObj.Main_OneToOne__c && nObj.Asset__c != null) {
                if(nObj.RecordType_F__c == 'AgencyToCenter') {
                    if(oObj.Shippment_loaner_time_F__c == null && nObj.Shippment_loaner_time_F__c != null) {
                        assIdSet.add(nObj.Asset__c);
                    }
                }
                else if(!oObj.StockDown__c && nObj.StockDown__c) {
                    assIdSet.add(nObj.Asset__c);
                }
            }
        }
        if (!assIdSet.isEmpty()) {
            FixtureUtil.delOtOLinkData(new List<Id>(assIdSet));
        }
    }
    // 上架时新建link
    private void createOneToOneLink() {
        // 获取需要建link的明细
        Set<Id> otoDetailIdSet = new Set<Id>();
        for (TransferApplyDetail__c nObj : newList) {
            TransferApplyDetail__c oObj = oldMap.get(nObj.Id);
            if(!oObj.Arrival_in_wh__c && nObj.Arrival_in_wh__c
             && nObj.OneToOneAccessory__c && !nObj.SkipLink__c) {
                otoDetailIdSet.add(nObj.Id);
            }
        }

        if(otoDetailIdSet.isEmpty()) {
            return;
        }
        // 因为要用__r字段，不能直接用newList
        List<TransferApplyDetail__c> tadList = [
            SELECT Id
                 , TransferApplySummary__r.First_TAD__r.Asset__c
                 , TransferApplySummary__r.First_TAD__r.Arrival_in_wh__c
                 , Manage_type_F__c
                 , Internal_asset_location_After__c
                 , Salesdepartment_After__c
                 , SalesProvince_After__c
                 , Equipment_Type_After__c
                 , EquipmentSet_Managment_Code_After__c
                 , Internal_asset_location__c
                 , Salesdepartment__c
                 , SalesProvince__c
                 , Equipment_Type__c
                 , EquipmentSet_Managment_Code__c
                 , Fixture_Model_No_F__c
                 , Asset__r.Consumable_Guaranteen_end__c
                 , Arrival_wh_Flag_F__c
              FROM TransferApplyDetail__c
             WHERE Id IN: otoDetailIdSet
        ];

        Map<String, Integer> otoCntMap = new Map<String, Integer>(); // 主Id:附Id->数量
        for(TransferApplyDetail__c tad: tadList) {
            String otoKey = ''; //主Id:附Id
            if(tad.TransferApplySummary__r.First_TAD__r.Arrival_in_wh__c) { //
                if(tad.Manage_type_F__c == '个体管理') { // 个体管理的明细连的Asset不会变
                    otoKey = tad.TransferApplySummary__r.First_TAD__r.Asset__c + ':' + tad.Asset__c;
                }
                else if(tad.Manage_type_F__c == '数量管理') { // 数量管理的明细要去找新的Asset
                    String ukey = tad.Fixture_Model_No_F__c // 型号;存放地;本部
                            + ';' + tad.Internal_asset_location_After__c
                            + ';' + (String.isNotBlank(tad.Salesdepartment_After__c) ? tad.Salesdepartment_After__c : tad.Salesdepartment__c);
                    if(newAssetMap.containsKey(ukey)) {
                        otoKey = tad.TransferApplySummary__r.First_TAD__r.Asset__c + ':' + newAssetMap.get(ukey).Id;
                    }
                    else {
                        otoKey = tad.TransferApplySummary__r.First_TAD__r.Asset__c + ':' + tad.Asset__c;
                    }
                }
                if(String.isNotBlank(otoKey)) {
                    Integer cnt = 1;
                    if(otoCntMap.containsKey(otoKey)) {
                        cnt = otoCntMap.get(otoKey) + 1;
                    }
                    otoCntMap.put(otoKey, cnt);
                }
            }
        }


        // 找一下现有的link
        if(!otoCntMap.isEmpty()) {
            Map<String, Fixture_OneToOne_Link__c> linkMap = new Map<String, Fixture_OneToOne_Link__c>(); // 主Id:附Id->link对象
            String linkSql = 'SELECT Quantity__c, Main_Asset__c, Accessory_Asset__c FROM Fixture_OneToOne_Link__c WHERE ';
            for(String otoKey:otoCntMap.keySet()) {
                String mainId = otoKey.split(':')[0];
                String acceId = otoKey.split(':')[1];
                linkSql += '(Main_Asset__c = \'' + mainId + '\' AND Accessory_Asset__c = \''+acceId+'\') OR';
            }
            linkSql = linkSql.removeEnd('OR');
            List<Fixture_OneToOne_Link__c> matchingLinks = Database.query(linkSql);
            for(Fixture_OneToOne_Link__c link:matchingLinks) {
                linkMap.put(link.Main_Asset__c + ':' + link.Accessory_Asset__c, link);
            }
            for(String otoKey:otoCntMap.keySet()) {

                Fixture_OneToOne_Link__c link = new Fixture_OneToOne_Link__c();
                if(linkMap.containsKey(otoKey)) {
                    link = linkMap.get(otoKey);
                    link.Quantity__c += otoCntMap.get(otoKey);
                }
                else {
                    link.Main_Asset__c = otoKey.split(':')[0];
                    link.Accessory_Asset__c = otoKey.split(':')[1];
                    link.Quantity__c = otoCntMap.get(otoKey);
                }
                linkMap.put(otoKey, link);
            }
            if(!linkMap.isEmpty()) {
                Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                upsert linkMap.values();
                Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());

            }
        }

    }
    // 4-XX 下架后, 出库前检测的Action一对一分配的话, 和主体一起 Cancel
    private void oneToOne4XX() {
        //主体CnacelSet
        Set<Id> raesdBodyCnacelSet = new Set<Id>();
        Set<Id> raesdBodyNGSet = new Set<Id>();
        //暂时只考虑主体NG或者取消的时候
        Map<Id, String> raesdCancel_Remarks = new Map<Id, String>();
        //检测NG或者本来就Cancel的不需要再更新
        Set<Id> raesdIdSet = new Set<Id>();
        for (TransferApplyDetail__c nObj : newList) {
            TransferApplyDetail__c oObj = oldMap.get(nObj.Id);
            //Set没有cancel的话都需要拷贝
            //主体出库前检测NG 维修
            if (nObj.Main_OneToOne__c == true
                    && nObj.Inspection_result__c == 'NG'
                    && oObj.Inspection_result__c != nObj.Inspection_result__c
                    && nObj.Inspection_result_NG__c == '维修') {
                //需要重新分配一对一附属品的一览
                raesdBodyNGSet.add(nObj.TransferApplySummary__c);
                raesdCancel_Remarks.put(nObj.TransferApplySummary__c, nObj.Cancel_Reason__c);
                raesdIdSet.add(nObj.Id);
            }
            //主体出库前检测NG 废弃
            else if (nObj.Main_OneToOne__c == true
                    && nObj.Inspection_result__c == 'NG'
                    && oObj.Inspection_result__c != nObj.Inspection_result__c
                    && nObj.Inspection_result_NG__c == '废弃') {
                //需要重新分配一对一附属品的一览
                raesdBodyNGSet.add(nObj.TransferApplySummary__c);
                raesdCancel_Remarks.put(nObj.TransferApplySummary__c, nObj.Cancel_Reason__c);
                raesdIdSet.add(nObj.Id);
            }
            //附属品出库前检测NG 维修 并且是一对一分配
            else if (nObj.Main_OneToOne__c == false
                    && nObj.Inspection_result__c == 'NG'
                    && oObj.Inspection_result__c != nObj.Inspection_result__c
                    && nObj.Inspection_result_NG__c == '维修'
                    && nObj.OneToOneAccessory__c == true) {
                raesdIdSet.add(nObj.Id);
            }
            //附属品出库前检测NG 废弃 并且是一对一分配
            else if (nObj.Main_OneToOne__c == false
                    && nObj.Inspection_result__c == 'NG'
                    && oObj.Inspection_result__c != nObj.Inspection_result__c
                    && nObj.Inspection_result_NG__c == '废弃'
                    && nObj.OneToOneAccessory__c == true) {
                raesdIdSet.add(nObj.Id);
            }
            //OLY_OCM-152 下架后主体取消的话一对一附属品也要一起取消
            else if (String.isBlank(nObj.DeliverySlip__c)
                    && nObj.Main_OneToOne__c == true
                    && nObj.StockDown__c == true
                    && oObj.Cancel_Select__c == false
                    && nObj.Cancel_Select__c == true) {
                raesdIdSet.add(nObj.Id);
                raesdBodyCnacelSet.add(nObj.TransferApplySummary__c);
                raesdCancel_Remarks.put(nObj.TransferApplySummary__c, nObj.Cancel_Reason__c);
            }
        }
        if (raesdBodyNGSet.isEmpty() && raesdBodyCnacelSet.isEmpty()) {
            return;
        }
        List<TransferApplyDetail__c> raesds = [
                Select Id, TransferApplySummary__c,Cancel_Reason__c
                From TransferApplyDetail__c
                //主体出库前检测NG一览的所有一对一分配的明细
                Where (TransferApplySummary__c = :raesdBodyNGSet
                    //下架后主体取消一对一附属品也要一起取消
                       OR TransferApplySummary__c = :raesdBodyCnacelSet)
                    AND OneToOneAccessory__c = true
                    //和主体一起检测NG的不再更新
                    AND Id !=: raesdIdSet];
        List<TransferApplyDetail__c> raesdList = new List<TransferApplyDetail__c>();
        for (TransferApplyDetail__c raesd : raesds) {
            raesd.OnStock_By_Cancel__c = true;
            raesd.Cancel_Select__c = true;
            if(String.isNotBlank(raesd.Cancel_Reason__c) && raesd.Cancel_Reason__c != '出库前检查NG'){
                //主体出库前检查NG的话取消备注回自动设置为出库前检查NG
                raesd.Cancel_Reason__c = raesdCancel_Remarks.get(raesd.TransferApplySummary__c);
            }
            raesdList.add(raesd);
        }
        if (!raesdList.isEmpty()) {
            update raesdList;
        }
    }
    // afterdeleteのみ
    private void deleteReFirst() {
        Map<Id, TransferApplySummary__c> tasMap = new Map<Id, TransferApplySummary__c>();
        for (TransferApplyDetail__c oObj : oldList) {
            if (oObj.Is_First_TAD_F__c == true) {
                TransferApplySummary__c raes = new TransferApplySummary__c(
                        Id = oObj.TransferApplySummary__c,
                        First_TAD__c = null);
                tasMap.put(oObj.TransferApplySummary__c, raes);
            }
        }
        //修改一览的FirstMap
        if (tasMap.isEmpty()) {
            return;
        }

        List<TransferApplyDetail__c> raesList = [Select Id, TransferApplySummary__c
            From TransferApplyDetail__c
            Where TransferApplySummary__c = :tasMap.keySet()
         order by TransferApplySummary__c, Cancel_Select__c, IndexFromUniqueKey__c ASC nulls last];
        Id raesId = null;
        for (TransferApplyDetail__c tad : raesList) {
            if (raesId != tad.TransferApplySummary__c) {
                tasMap.get(tad.TransferApplySummary__c).First_TAD__c = tad.Id;
                raesId = tad.TransferApplySummary__c;
            }
        }
        Map<Id, TransferApplySummary__c> deleteTasMap = new Map<Id, TransferApplySummary__c>();
        Map<Id, TransferApplySummary__c> updateTasMap = new Map<Id, TransferApplySummary__c>();

        for(Id tasId:tasMap.keySet()) {
            TransferApplySummary__c tas = tasMap.get(tasId);
            if(tas.First_TAD__c == null) { //如果为空，说明一览下没有明细，直接删除
                deleteTasMap.put(tasId, tas);
            }
            else {
                updateTasMap.put(tasId, tas);
            }
        }
        //一览First更新
        if (!updateTasMap.isEmpty()) {
            update updateTasMap.values();
        }
        if(!deleteTasMap.isEmpty()) {
            delete deleteTasMap.values();
        }
    }
    // 最終状態及びAsset変更
    private Boolean finishOrChangeAsset(Boolean isDelete, TransferApplyDetail__c oObj, TransferApplyDetail__c nObj) {
        Boolean rtn = false;
        if (isDelete) {
            // oObj を確認する、oldで もともと finishのもの、falseを返す、
            rtn = !(
                //回库确认
                   (oObj.Arrival_in_wh__c)
                //取消分配, (下架后, 原则需要上架, 所以不能单纯的断开)
                || (oObj.Cancel_Select__c == true && oObj.StockDown__c == false)
                //下架前, 分配备品有变化 (变成别的配套, or 变 null)
                || (oObj.Asset__c == null && oObj.StockDown__c == false)
                //取消分配, (下架后, 原则需要上架, 所以不能单纯的断开)
                || (oObj.Cancel_Select__c == true && nObj.StockDown__c == false)
                //放弃欠品
                || (oObj.Lost_item_giveup__c == true)
                //已消耗
                || (oObj.Check_lost_Item_F__c == '消耗')
            );
        } else {
            rtn = (
                //回库确认
                   (!oObj.Arrival_in_wh__c && nObj.Arrival_in_wh__c)
                //取消分配, (下架后, 原则需要上架, 所以不能单纯的断开)
                || (oObj.Cancel_Select__c == false && nObj.Cancel_Select__c == true
                    && nObj.StockDown__c == false)
                //下架前, 分配备品有变化 (变成别的配套, or 变 null)
                || (oObj.Asset__c != null && oObj.Asset__c != nObj.Asset__c
                    && nObj.StockDown__c == false)
                //放弃欠品
                || (oObj.Lost_item_giveup__c == false && nObj.Lost_item_giveup__c == true
                    && oObj.Check_lost_Item_F__c != '消耗')
                //已消耗
                || (oObj.Check_lost_Item_F__c != '消耗' && nObj.Check_lost_Item_F__c == '消耗'
                    && oObj.Lost_item_giveup__c == false)
            );
        }
        return rtn;
    }
    //办事处收回NG后明细回寄时的邮件回寄单内容设置
    //只在Afterupdate里面调用
    private void receivedConfirmNGSetReturnDeliverySlipText() {
        //一览Id和对应的回寄发货单ID
        Map<Id, Id> raesRDSMap = new Map<Id, Id>();
        Map<Id, String> raesDateMap = new Map<Id, String>();
        for (TransferApplyDetail__c nObj : newList) {
            TransferApplyDetail__c oObj = oldMap.get(nObj.Id);
            //申请者收货NG的明细
            if (nObj.Received_Confirm_F__c == 'NG') {
                //回寄运输单赋值
                if (String.isBlank(oObj.Return_DeliverySlip__c) && String.isNotBlank(nObj.Return_DeliverySlip__c)) {
                    //因为是以为一览为单位，所以只有一条回寄单
                    //申请者收货NG的明细拆成两个回寄单回寄的情况暂时不考虑（应该没有这种情况）
                    if (!raesRDSMap.containsKey(nObj.TransferApplySummary__c)) {
                        raesRDSMap.put(nObj.TransferApplySummary__c, nObj.Return_DeliverySlip__c);
                        raesDateMap.put(nObj.TransferApplySummary__c, nObj.Asset_return_time__c.format());
                    }
                }
            }
        }
        if (raesRDSMap.isEmpty()) {
            return;
        }
        //NG_Return_DeliverySlip__c为空的一览才做邮件发送
        Map<Id, TransferApplySummary__c> raessMap = new Map<Id, TransferApplySummary__c>([Select Id From TransferApplySummary__c
                WHERE Id =: raesRDSMap.keySet()
                AND NG_Return_DeliverySlip__c = null]);
        Map<Id, FixtureDeliverySlip__c> fdss = new Map<Id, FixtureDeliverySlip__c>([Select Id, Name, Combine_Pack__c, Wh_Staff__c, DeliveryCompany__c, Shippment_loaner_time__c,
                Distributor_method__c, DeliveryCompany_SlipNo__c, DeliveryType__c
                From FixtureDeliverySlip__c
                Where Id =: raesRDSMap.values()]);
        List<TransferApplySummary__c> raess = new List<TransferApplySummary__c>();
        for (Id key: raesRDSMap.keySet()) {
            //当NG_Return_DeliverySlip__c不为空时不发邮件
            if (!raessMap.containsKey(key)) {
                continue;
            }
            FixtureDeliverySlip__c fds = fdss.get(raesRDSMap.get(key));
            String message = '发货-发货运输单号：'
                            + fds.Name + '<BR>'
                            + '发货-物流公司：'
                            + fds.DeliveryCompany__c + '<BR>'
                            + '发货-运输方式：'
                            + fds.Distributor_method__c + '<BR>'
                            + '物流提货时间：'
                            + raesDateMap.get(key) + '<BR>';
            raess.add(new TransferApplySummary__c(Id = key,
                    NG_Return_DeliverySlip_Information__c = message,
                    NG_Return_DeliverySlip__c = fds.Id));
        }
        if (!raess.isEmpty()) {
            update raess;
        }
    }
    //20201103 ljh 备品中心至办事处--收货NG回寄、欠品提醒 设置申请书的回寄通知文本 取消时间  OCSM_BP5-35
    //只在Afterupdate里面调用
    private void setToTa_BeforeOrReturnOrCancle_Text() {
        Set<Id> taReturnNGSet = new Set<Id>();//收货NG回寄
        Set<Id> taBeforeNGSet = new Set<Id>();//出库前NG
        Set<Id> taLoseSet = new Set<Id>();//欠品
        Map<Id,Datetime> cancleTimeMap = new Map<Id,Datetime>();//取消
        Map<Id,Datetime> waitPerfectMap = new Map<Id,Datetime>();//待受理完善备品信息
        Map<Id,Boolean> waitStockMap = new Map<Id,Boolean>();//已受理完善备品信息
        Set<Id> cancleTimeId = new Set<Id>();//取消
        Set<Id> waitPerfectid = new Set<Id>();//待受理完善备品信息
        Set<Id> waitStockId = new Set<Id>();//已受理完善备品信息
        for (TransferApplyDetail__c nObj : newList) {
            TransferApplyDetail__c oObj = oldMap.get(nObj.Id);
            //出库前NG
            if(oObj.Inspection_result__c != 'NG' && nObj.Inspection_result__c == 'NG') {
               taBeforeNGSet.add(nObj.Id);
            }
            //欠品
            if(oObj.Check_lost_Item_F__c != '欠品' && nObj.Check_lost_Item_F__c == '欠品') {
               taLoseSet.add(nObj.Id);
            }
            //收货NG回寄
            if (String.isBlank(oObj.Return_DeliverySlip__c)
                && String.isNotBlank(nObj.Return_DeliverySlip__c)
                && nObj.ArrivalResult__c == 'NG') {
                taReturnNGSet.add(nObj.Id);
            }
            //取消  Cancel_Select__c
            if(nObj.Cancel_Select__c == true && oObj.Cancel_Select__c == false && nObj.Inspection_result__c != 'NG'){
                if(!cancleTimeMap.containsKey(nObj.TransferApply__c)){
                    cancleTimeMap.put(nObj.TransferApply__c,nObj.Cancel_Time__c);
                }else{
                    if(cancleTimeMap.get(nObj.TransferApply__c) != nObj.Cancel_Time__c ){
                        cancleTimeMap.put(nObj.TransferApply__c,nObj.Cancel_Time__c);
                    }
                }
                cancleTimeId.add(nObj.Id);
            }
            //待受理完善备品信息
            if(nObj.Inspection_result_after_F__c != null && nObj.Inspection_result_after_F__c == 'OK' && oObj.Inspection_result_after_F__c != 'OK'){
                if(!waitPerfectMap.containsKey(nObj.TransferApply__c)){
                    waitPerfectMap.put(nObj.TransferApply__c,nObj.After_Inspection_time_F__c);
                }else{
                    if(waitPerfectMap.get(nObj.TransferApply__c) != nObj.After_Inspection_time_F__c ){
                        waitPerfectMap.put(nObj.TransferApply__c,nObj.After_Inspection_time_F__c);
                    }
                }
                waitPerfectid.add(nObj.Id);
            }
            //已受理完善备品信息 待上架
            if(nObj.IsPerfect__c == true && oObj.IsPerfect__c == false){
                if(!waitStockMap.containsKey(nObj.TransferApply__c)){
                    waitStockMap.put(nObj.TransferApply__c,nObj.IsPerfect__c);
                }
                waitStockId.add(nObj.Id);
            }

        }
        //出库前NG 欠品 收货NG回寄
        Set<Id> IdSet = new Set<Id>();
        IdSet.addAll(taBeforeNGSet);
        IdSet.addAll(taLoseSet);
        IdSet.addAll(taReturnNGSet);
        IdSet.addAll(cancleTimeId);
        IdSet.addAll(waitPerfectId);
        IdSet.addAll(waitStockId);
        Map<ID,List<TransferApplyDetail__c>> tadMap = new Map<ID,List<TransferApplyDetail__c>>();

        List<TransferApplyDetail__c> tadList =[ SELECT Id,TransferApply__c,Return_DeliverySlip__c,TransferApplySummary__c,Fixture_Model_No__c,NoItemReturn__c,
            TransferApply__r.Name,TransferApply__r.Id,
            Fixture_Set_Detail__r.Fixture_Set__c,Fixture_Set_Detail__c,Fixture_Model_No_F__c,
            Return_DeliverySlip__r.Id,Return_DeliverySlip__r.Name,Return_DeliverySlip__r.DeliveryCompany__c,Return_DeliverySlip__r.Distributor_method__c,Return_DeliverySlip__r.Shippment_loaner_time__c
             FROM TransferApplyDetail__c
             WHERE Id = :IdSet
             ORDER BY TransferApply__c, TransferApplySummary__c, Name
        ];
        Map<Id, FixtureDeliverySlip__c> return_DeliverySlipMap = new Map<Id, FixtureDeliverySlip__c>();
        for (TransferApplyDetail__c  tad:tadList) {
            if(!tadMap.containsKey(tad.TransferApply__c)) {
                List<TransferApplyDetail__c> tempL = new List<TransferApplyDetail__c>();
                tempL.add(tad);
                tadMap.put(tad.TransferApply__c,tempL);
            }else{
                List<TransferApplyDetail__c> oldL = tadMap.get(tad.TransferApply__c);
                oldL.add(tad);
                tadMap.put(tad.TransferApply__c,oldL);
            }
            /* --------- 设置运输单Map Start --------- */
            if (return_DeliverySlipMap.containsKey(tad.TransferApply__c) == false) {
                FixtureDeliverySlip__c fds = tad.Return_DeliverySlip__r;
                return_DeliverySlipMap.put(tad.TransferApply__c, fds);
            }
            /* --------- 设置运输单Map End --------- */
        }
        //出库前NG Before_NG_Detail_ForEmail__c  欠品Lose_Detail_ForEmail__c 收货NG回寄 Asset_return_Text__c
        if(taLoseSet.size()>0 || taBeforeNGSet.size()>0 || taReturnNGSet.size()>0
            || cancleTimeMap.size()>0 || waitPerfectMap.size()>0|| waitStockMap.size()>0){
            List<TransferApply__c> raList = new List<TransferApply__c>();
            List<TransferApply__c> raList2 = new List<TransferApply__c>();
            Map<String,Integer> mapBeforeNGMx = new Map<String,Integer>();
            Map<String,Integer> mapLoseMx = new Map<String,Integer>();
            Map<String,Integer> mapReturnNGMx = new Map<String,Integer>();
            List<TransferApplyDetail__c> tadBeforeNGList = new  List<TransferApplyDetail__c>();
            List<TransferApplyDetail__c> tadLoseList = new  List<TransferApplyDetail__c>();
            List<TransferApplyDetail__c> tadReturnNGList = new  List<TransferApplyDetail__c>();
            for (Id raId: tadMap.keySet()) {
                for (TransferApplyDetail__c tad : tadMap.get(raId)) {
                    //需要判断属于类型
                    //出库前NG
                    if(taBeforeNGSet.contains(tad.Id)){
                        tadBeforeNGList.add(tad);
                    }
                    //欠品
                    if(taLoseSet.contains(tad.Id)){
                        tadLoseList.add(tad);
                    }
                    //收货NG回寄
                    if(taReturnNGSet.contains(tad.Id)){
                        tadReturnNGList.add(tad);
                    }
                }
                String message1 = '' ;
                if(tadBeforeNGList.size()>0){
                    for(TransferApplyDetail__c tadBNg : tadBeforeNGList){
                       if(!mapBeforeNGMx.containsKey(tadBNg.Fixture_Model_No_F__c)){
                            mapBeforeNGMx.put(tadBNg.Fixture_Model_No_F__c,1);
                        }else{
                            Integer num = mapBeforeNGMx.get(tadBNg.Fixture_Model_No_F__c);
                            num++;
                            mapBeforeNGMx.put(tadBNg.Fixture_Model_No_F__c,num);
                        }
                    }
                    for(String key : mapBeforeNGMx.keySet()){
                        message1 += key+'&nbsp;*'+mapBeforeNGMx.get(key);
                        message1 += '<BR>';
                    }
                }
                String message2 = '' ;
                if(tadLoseList.size()>0){
                    for(TransferApplyDetail__c tadlose : tadLoseList){
                       if(!mapLoseMx.containsKey(tadLose.Fixture_Model_No_F__c)){
                            mapLoseMx.put(tadLose.Fixture_Model_No_F__c,1);
                        }else{
                            Integer num = mapLoseMx.get(tadLose.Fixture_Model_No_F__c);
                            num++;
                            mapLoseMx.put(tadLose.Fixture_Model_No_F__c,num);
                        }
                    }

                    for(String key : mapLoseMx.keySet()){
                        message2 += key+'&nbsp;*'+mapLoseMx.get(key);
                        message2 += '<BR>';
                    }
                }
                String message3 = '' ;
                if(tadReturnNGList.size()>0){
                    for(TransferApplyDetail__c tadRNG : tadReturnNGList){
                        if(!mapReturnNGMx.containsKey(tadRNG.Fixture_Model_No_F__c)){
                            mapReturnNGMx.put(tadRNG.Fixture_Model_No_F__c,1);
                        }else{
                            Integer num = mapReturnNGMx.get(tadRNG.Fixture_Model_No_F__c);
                            num++;
                            mapReturnNGMx.put(tadRNG.Fixture_Model_No_F__c,num);
                        }
                    }
                    for(String key : mapReturnNGMx.keySet()){
                        message3 += key+'&nbsp;*'+mapReturnNGMx.get(key);
                        message3 += '<BR>';
                    }
                    message3 += '<BR>';
                    FixtureDeliverySlip__c fds = new FixtureDeliverySlip__c();
                    if (return_DeliverySlipMap.containsKey(raId)) {
                        fds = return_DeliverySlipMap.get(raId);
                    }
                    message3 += '回寄-发货运输单号：' + (String.isBlank(fds.Name)? '' : fds.Name) + '<BR>';
                    message3 += '回寄-物流公司：' + (String.isBlank(fds.DeliveryCompany__c)? '' : fds.DeliveryCompany__c) + '<BR>';
                    message3 += '回寄-运输方式：' + (String.isBlank(fds.Distributor_method__c)? '' : fds.Distributor_method__c) + '<BR>';
                    String sdate = fds.Shippment_loaner_time__c == null ? '' : fds.Shippment_loaner_time__c.format();
                    message3 += '物流提货时间：' + sdate + '<BR>';
                }
                if (String.isNotBlank(message1) || String.isNotBlank(message2) || String.isNotBlank(message3) ||
                    cancleTimeMap.size()>0 || waitPerfectMap.size()>0|| waitStockMap.size()>0 ) {

                    TransferApply__c tempTa = new TransferApply__c();
                    TransferApply__c tempTa2 = new TransferApply__c();
                    tempTa.Id = raId;
                    tempTa2.Id = raId;
                    //出库前NG Before_NG_Detail_ForEmail__c
                    if(taBeforeNGSet.size()>0){
                        tempTa.Before_NG_Detail_ForEmail__c = message1;
                        tempTa2.Before_NG_Detail_ForEmail__c = null;
                    }
                    //欠品Lose_Detail_ForEmail__c
                    if(taLoseSet.size()>0){
                        tempTa.Lose_Detail_ForEmail__c = message2;
                        tempTa2.Lose_Detail_ForEmail__c = null;
                    }
                    //收货NG回寄 Asset_return_Text__c
                    if(taReturnNGSet.size()>0){
                        tempTa.Asset_return_Text__c = message3;
                        tempTa2.Asset_return_Text__c = null;
                    }
                    //取消 Cancel_Time_ForEmail__c
                    if(cancleTimeMap.size()>0){
                        if(cancleTimeMap.containsKey(raId)){
                            tempTa.Cancel_Time_ForEmail__c = cancleTimeMap.get(raId);
                            tempTa2.Cancel_Time_ForEmail__c = null;
                        }
                    }
                    //待受理完善备品信息 waitPerfectTime_ForEmail
                    if(waitPerfectMap.size()>0){
                        if(waitPerfectMap.containsKey(raId)){
                            tempTa.waitPerfectTime_ForEmail__c = waitPerfectMap.get(raId);
                            tempTa2.waitPerfectTime_ForEmail__c = null;
                        }
                    }
                    //已受理完善备品信息 待上架
                    if(waitStockMap.size()>0){
                        if(waitStockMap.containsKey(raId)){
                            tempTa.PerfectWaitStock__c = waitStockMap.get(raId);
                            tempTa2.PerfectWaitStock__c = false;
                        }
                    }
                    raList.add(tempTa);
                    raList2.add(tempTa2);
                }
            }
            if (raList.size() > 0) {
                FixtureUtil.withoutUpdate(raList2);
                FixtureUtil.withoutUpdate(raList);
            }
        }
    }
    //ljh  OCSM_BP5-35 end

}