public without sharing class TransferShippmentReceived6Controller {
    public List<EsdInfo> esdList { get; set; }

    public Boolean saveBtnDisabled { get; private set; }
    public boolean done_flg {get;set;}
    public String SR_status { get; private set; }
    public String Step_status { get; private set; }
    public String open_type { get; private set; }
    public Boolean forceSave { get; set; }
    public String AccessoryId {get;set;}
    public String AccessorySetId {get;set;}
    public String UnCheckedId {get;set;}
    public Map<Id, String> assetLocationMap {get;set;} //  一览上架地
    private Boolean isStartUser; // 是否是调拨前地区的用户
    private Boolean isDestUser; // 是否是调拨后地区的用户
    private Boolean is2B3; // 是否是2B3_照片
    private String Id;
    private Set<Id> esIds;

    public Integer getEsdListSize() {
        return esdList.size();
    }

    public TransferShippmentReceived6Controller() {
        Id = ApexPages.currentPage().getParameters().get('id');
        if (SR_status == null) {
            SR_status = ApexPages.currentPage().getParameters().get('type');
        }
        if (Step_status == null) {
            Step_status = ApexPages.currentPage().getParameters().get('step');
        }
        if (open_type == null) {
            open_type = ApexPages.currentPage().getParameters().get('open');
        }
        esIds = new Set<Id>();
        assetLocationMap = new Map<Id, String>();
    }
    /**
    @description 用户角色与地区地否匹配
    @param roleName 角色Name
    @param center 备品中心
    */
    private Boolean isMatch(String roleName, String center) {
        switch on center {
            when '北京 备品中心' {
                return roleName == '备品中心北方管理成员';
            }
            when '上海 备品中心' {
                return roleName == '备品中心华东管理成员';
            }
            when '广州 备品中心' {
                return roleName == '备品中心南方管理成员';
            }
        }
        return false;
    }
    // 画面初始化
    public PageReference init() {
        forceSave = false;
        done_flg = false;
        esdList = new List<EsdInfo>();
        saveBtnDisabled = false;
        if (Id != null) {
            List<String> ids = Id.split(',');
            // 当前User
            String userid = Userinfo.getUserId();
            User user = [select Id,Name,UserRole.Name from User where Id = :userid];
            // 备品set
            List<TransferApplySummary__c> esList = [
                select Id
                     , Name
                     , TransferApply__r.From_Location__c
                     , TransferApply__r.Destination_location__c
                     , First_Tad__r.DeliverySlip__c
                     , First_Tad__r.Return_DeliverySlip__c
                     , TransferApply__c
                     , TAS_Status__c
                     , Shippment_loaner_time2__c
                from TransferApplySummary__c
               where (TransferApply__r.Name in :ids or Id in :ids)
                 ];

            if (esList.size() > 0) {
                for (TransferApplySummary__c raes : esList) {
                    esIds.add(raes.Id);
                    if(raes.First_Tad__r.DeliverySlip__c == null || raes.First_Tad__r.Return_DeliverySlip__c != null) {
                        assetLocationMap.put(raes.Id, raes.TransferApply__r.From_Location__c);
                    }
                    else {
                        assetLocationMap.put(raes.Id, raes.TransferApply__r.Destination_location__c);
                    }
                }
                User user1 = [SELECT UserRole.Name, Profile.Name FROM User WHERE Id=:UserInfo.getUserId()];
                isStartUser = isMatch(user1.UserRole.Name, esList[0].TransferApply__r.From_Location__c);
                isDestUser = isMatch(user1.UserRole.Name, esList[0].TransferApply__r.Destination_location__c);
                //20210519 you WLIG-C2J9AA start
                //is2B3 = user1.Profile.Name == '2B3_备品中心管理者(照片)';
                is2B3 = false;
                if(user1.Profile.Name == '2B3_备品中心管理者(照片)' || user1.UserRole.Name == '备品运营部'){
                   is2B3 = true;
                }
                //20210519 you WLIG-C2J9AA end

            } else {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '备品不存在'));
                saveBtnDisabled = true;
                return null;
            }
        }

        // 备品set明细
        List<TransferApplyDetail__c> eList = getDetails();
        Map<Id,List<TransferApplyDetail__c>> raesMap = new Map<Id,List<TransferApplyDetail__c>>(); // 一览Id->一览下明细list
        for (TransferApplyDetail__c esd : eList) {
            List<TransferApplyDetail__c> raesdList;
            if (raesMap.containsKey(esd.TransferApplySummary__c)) {
                raesdList = raesMap.get(esd.TransferApplySummary__c);
            } else {
                raesdList = new List<TransferApplyDetail__c>();
            }
            raesdList.add(esd);
            raesMap.put(esd.TransferApplySummary__c, raesdList);
        }
        Set<Id> otomainSet = new Set<Id>();
        for (Id raesId : raesMap.keySet()) {
            for (TransferApplyDetail__c esd : raesMap.get(raesId)) {
                EsdInfo ei = new EsdInfo(esd, isStartUser, isDestUser, is2B3);
                esdList.add(ei);
            }
        }

        if (esdList.size() <= 0) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '没有备品set明细'));
            saveBtnDisabled = true;
            return null;
        }
        Step_status = '上架';
        SR_status = 'Shippment';
        system.debug('=====' + Step_status);
        system.debug('=====' + open_type);

        return null;
    }
    private List<TransferApplyDetail__c> getDetails() {
        List<TransferApplyDetail__c> eList = [
                select Cancel_Select__c
                     , TransferApplySummary__c
                     , AssetName__c
                     , Asset__r.Product2Id
                     , SerialNumber_F__c
                     , Arrival_wh_Flag_F__c
                     , Arrival_wh_Abandoned_Flag_F__c
                     , Fixture_Set_Detail__r.Is_OneToOne__c
                     , Main_OneToOne__c
                     , Fixture_Model_No_F__c
                     , Internal_asset_location_After__c
                     , Salesdepartment_After__c
                     , RecordType_F__c
                     , TransferApplySummary__r.Fixture_Set__r.Name
                     , FSD_OneToOneAccessory_Cnt_F__c
                     , WH_location__c
                     , Asset__r.WH_location__c
                     , OneToOneAccessory__c
                     , Fixture_QRCode_F__c
                     , TransferApplySummary__r.Name
                     , Id
                     , Name
                     , Asset__c
                     , Inspection_result_after_F__c
                     , Arrival_in_wh__c
                     , Inspection_result_after_ng_F__c
                     , IsPerfect__c
                     , Return_DeliverySlip__c
                     , Salesdepartment__c
                     // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230801 by lc Start
                     , Asset__r.Storage_Conditions__c 
                     , Asset__r.Temperature_And_Humidity_Zone__c
                     , Asset__r.Storage_Conditions_Met_Status__c
                     , Asset__r.Product2.ProductCode
                     , Asset__r.Product2.SFDA_Approbation_No__c
                    // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230801 by lc End
                  from TransferApplyDetail__c
                 where TransferApplySummary__c in :esIds and ((Shipment_request_time2__c <> null and Cancel_Select__c = False ) or Arrival_wh_Flag_F__c = true or Arrival_wh_Abandoned_Flag_F__c = true)
                 //order by TransferApplySummary__r.Name, TransferApplySummary__c, Name
                 order by TransferApplySummary__r.Name, TransferApplySummary__c, Name
        ];
        return eList;
    }
    private Map<Id, TransferApplyDetail__c> getDetailMap() {
        List<TransferApplyDetail__c> tadList = getDetails();
        Map<Id, TransferApplyDetail__c> tadMap = new Map<Id, TransferApplyDetail__c>();
        for(TransferApplyDetail__c tad:tadList) {
            tadMap.put(tad.Id, tad);
        }
        return tadMap;
    }
    public PageReference deleteDetail() {
        if (UnCheckedId != null) {
            integer index = 0;
            for (EsdInfo esd : esdList) {
                if (esd.accessoryFlg && UnCheckedId == esd.rec2.Id) {
                    break;
                }
                index++;
            }
            esdList.remove(index);
        }
        UnCheckedId = null;
        return null;
    }

    public PageReference addAccessory() {
        system.debug(AccessorySetId);
        if (AccessoryId != null) {
            List<Asset> assList = [
                    select Id, Name, SerialNumber, Product2Id,WH_location__c, Internal_asset_location__c
                     from Asset
                    where Fixture_QRCode__c = :AccessoryId
                      and Ji_Zhong_Guan_Li_Ku_Cun__c > 0
                      and Asset_loaner_category__c != '耗材'
                      and RecordTypeId =:System.label.access_1];
            system.debug(assList);
            if (assList.size() > 0) {
                if( assetLocationMap.containsKey(AccessorySetId)
                    && asslist[0].Internal_asset_location__c != assetLocationMap.get(AccessorySetId)) {
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '扫描附属品的备品存放地与主体上架地区不一致！'));
                }
                else {
                    // 上架时现场追加的临时明细
                    EsdInfo accInfo = new EsdInfo();
                    accInfo.accessoryFlg = true;
                    accInfo.rec2 = asslist[0];
                    accInfo.accessorySetId = AccessorySetId;

                    Integer index = 1;
                    Integer insert_index = 0;
                    for (EsdInfo esd : esdList) {
                        if (esd.rec.TransferApplySummary__c == AccessorySetId) insert_index = index;
                        index++;
                    }
                    if (esdList.size() == insert_index) {
                        esdList.add(accInfo);
                    } else {
                        esdList.add(insert_index, accInfo);
                    }
                }
            }
            else {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '扫描的附属品不可追加！'));
            }
        }
        AccessoryId = null;
        return null;
    }
    // 处理通过【扫一扫附属品】按钮建立的link
    private void createOtoLinkFromScan(List<EsdInfo> mainEsdList, Map<Id, List<EsdInfo>> scanOtoAccessoryMap) {
        Map<String, Integer> otoCntMap = new Map<String, Integer>(); //主AssetId:附AssetId->link数量
        for(EsdInfo info: mainEsdList) {
            Id mainId = info.rec.Asset__c;
            if(scanOtoAccessoryMap.containsKey(info.rec.TransferApplySummary__c)) {
                for(EsdInfo acsEsd:scanOtoAccessoryMap.get(info.rec.TransferApplySummary__c)) {
                    Integer cnt = 0;
                    String otoKey = mainId + ':' +acsEsd.rec2.Id;
                    if(otoCntMap.containsKey(otoKey)) {
                        cnt = otoCntMap.get(otoKey);
                    }
                    otoCntMap.put(otoKey, cnt + 1);
                }
            }
        }
        System.debug(otoCntMap);
        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()) {
                System.debug(linkMap);
                FixtureUtil.withoutUpsertObjects(linkMap.values());
            }
        }
    }
    // 保存按钮
    public PageReference save() {
        done_flg = false;
        String userid = Userinfo.getUserId();
        List<TransferApplyDetail__c> eList = new List<TransferApplyDetail__c>();
        List<EsdInfo> otoCheckList_main = new List<EsdInfo>();
        List<EsdInfo> otoAccessoryList = new List<EsdInfo>(); // 存所有的一对一附属品，包括明细里的和现场扫的
        Map<Id, List<EsdInfo>> scanOtoAccessoryMap = new Map<Id, List<EsdInfo>>(); // 一览Id->仅存现场扫的假明细列表
        Set<Id> assetForLock = new Set<Id>();
        Set<String> ukeySet = new Set<String>();
        // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230804 by lc Start
        List<Asset> assUpdList = new List<Asset>();
        //数量管理的保有设备，需要做去重处理
        Map<Id, String> assIdMap = new Map<Id, String>();
        // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230804 by lc End

        for (EsdInfo esdInfo : esdList) {
            esdInfo.errorInfo = null;
            if (esdInfo.accessoryFlg) {
                otoAccessoryList.add(esdInfo);
                List<EsdInfo> tempList = new List<EsdInfo>();
                if(scanOtoAccessoryMap.containsKey(esdInfo.accessorySetId)) {
                    tempList = scanOtoAccessoryMap.get(esdInfo.accessorySetId);
                }
                tempList.add(esdInfo);
                scanOtoAccessoryMap.put(esdInfo.accessorySetId, tempList);
            } else {
                if (!esdInfo.editable) continue;
                TransferApplyDetail__c esd = esdInfo.rec;
                eList.add(esd);
                if (esd.Arrival_in_wh__c) {
                    esd.WH_location__c = esdInfo.wh_location;
                    if (esd.Main_OneToOne__c && (esd.Inspection_result_after_F__c == 'OK' || (!esd.Arrival_wh_Abandoned_Flag_F__c && esd.Arrival_wh_Flag_F__c))) {
                        otoCheckList_main.add(esdInfo);
                    } else if ((esd.Inspection_result_after_F__c == 'OK' || (!esd.Arrival_wh_Abandoned_Flag_F__c && esd.Arrival_wh_Flag_F__c)) && esd.OneToOneAccessory__c) {
                        otoAccessoryList.add(esdInfo);
                    }
                    String ukey =  esd.Fixture_Model_No_F__c // 型号;存放地;本部
                            + ';' + esd.Internal_asset_location_After__c
                            + ';' + (String.isNotBlank(esd.Salesdepartment_After__c)?esd.Salesdepartment_After__c:esd.Salesdepartment__c);
                    ukeySet.add(ukey);
                }
            }
            if (esdInfo.editable) {
                assetForLock.add(esdInfo.rec.Asset__c);

                // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230804 by lc Start
                if (assIdMap.isEmpty() || !assIdMap.containsKey(esdInfo.rec.Asset__c)) {
                    String checkFlag = null;
                    // 选择的温湿度区分
                    String thZone = esdInfo.rec.Asset__r.Temperature_And_Humidity_Zone__c;
                    // 储存条件 5~40℃，10~95%
                    String storageCon = esdInfo.rec.Asset__r.Storage_Conditions__c;
                    if (String.isBlank(thZone)) {
                        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '请选择温湿度分区!'));
                        return null;
                    }
                    if (esdInfo.rec.Asset__r.Product2.ProductCode.StartsWith('BP')) {
                        checkFlag = 'OK';
                    } else if (esdInfo.rec.Asset__r.Product2.SFDA_Approbation_No__c == 'FYL') {
                        checkFlag = 'OK';
                    } else {
                        if (String.isBlank(storageCon)) {
                            checkFlag = 'OK';
                        } else {
                            checkFlag = FixtureUtil.compareTemperatureAndHumidity(thZone, storageCon);
                        }
                    }
                    Asset ast = new Asset();
                    ast.Id = esdInfo.rec.Asset__c;
                    // 不满足则标记上储存条件不符合
                    ast.Storage_Conditions_Met_Status__c = checkFlag;
                    ast.Temperature_And_Humidity_Zone__c = thZone;
                    assUpdList.add(ast);
                    assIdMap.put(esdInfo.rec.Asset__c, '1');
                }
                // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230804 by lc End
            }
        }

        Map<String, Map<Id, List<Id>>> assProductCountMapAll = new Map<String, Map<Id, List<Id>>>(); // 一览Id->明细的产品Id->保有设备Id列表
        for (EsdInfo ei : otoAccessoryList) {
            Map<Id, List<Id>> assProductCountMap;
            if (assProductCountMapAll.containsKey(ei.accessorySetId)) {
                assProductCountMap = assProductCountMapAll.get(ei.accessorySetId);
            } else {
                assProductCountMap = new Map<Id, List<Id>>();
            }
            Id recId;
            Id product2Id;
            if (ei.rec2 != null) {
                recId = ei.rec2.Id;
                product2Id = ei.rec2.Product2Id;
            } else {
                recId = ei.rec.Asset__c;
                product2Id = ei.rec.Asset__r.Product2Id;
            }
            List<Id> count;
            if (assProductCountMap.containsKey(product2Id)) {
                count = assProductCountMap.get(product2Id);
            } else {
                count = new List<Id>();
            }
            count.add(recId);
            assProductCountMap.put(product2Id, count);
            assProductCountMapAll.put(ei.accessorySetId, assProductCountMap);
        }

        Boolean needSaveSet = false;
        Boolean needSaveDetail = false;
        Boolean needSaveAsset = false;

        //List<Fixture_OneToOne_Link__c> otolinkList = new List<Fixture_OneToOne_Link__c>();
        boolean err = false;
        //Map<String, Integer> otoMap = new Map<String, Integer>(); // 主设备Id:附设备Id->link数量
        Set<Id> otoDetailId = new Set<Id> (); // 需要建link的明细
        for (EsdInfo main : otoCheckList_main) {
            List<TransferApplyDetail__c> tadList;
            //没有cancel的看最新一套明细的fsd数量
            //已经cancel的看最早一套明细的一对一分配数量
            //理论上出库前上架的数据不会有非cancel的情况，所以直接用Cancel_Select__c判断
            system.debug(main.rec);
            if (main.rec.Cancel_Select__c == false) {
                tadList = [select Asset__r.Product2.Name, Asset__c, Asset__r.Product2Id , OneToOneAccessory__c
                                , Inspection_result_after_F__c, Arrival_wh_Abandoned_Flag_F__c, Arrival_wh_Flag_F__c
                            from TransferApplyDetail__c
                           where TransferApplySummary__c = :main.rec.TransferApplySummary__c
                                 and OneToOneAccessory__c = true
                                 and Cancel_Select__c = false //找最新的一套明细
                                 //and Canceled_Id__c = null //找最初的一套明细
                                 and Asset__c <> null //过滤未分配的数据。
                                 //and Arrival_in_wh__c = false
                                 order by TransferApplySummary__r.Name, TransferApplySummary__c, FSD_SortInt__c, Arrival_wh_Flag_F__c DESC
                                 //order by OneToOneAccessory__c desc
                                 ];
            } else {
                tadList = [select Asset__r.Product2.Name, Asset__c, Asset__r.Product2Id , OneToOneAccessory__c
                                , Inspection_result_after_F__c, Arrival_wh_Abandoned_Flag_F__c, Arrival_wh_Flag_F__c
                            from TransferApplyDetail__c
                           where TransferApplySummary__c = :main.rec.TransferApplySummary__c
                                 and OneToOneAccessory__c = true
                                 //and Canceled_Id__c = null
                                 and Asset__c <> null
                                 //and Arrival_in_wh__c = false
                                 order by TransferApplySummary__r.Name, TransferApplySummary__c, FSD_SortInt__c, Arrival_wh_Flag_F__c DESC
                                 //order by OneToOneAccessory__c desc
                                 ];
            }
            system.debug(tadList);
            Map<Id, List<Id>> assProductCountMap = new Map<Id, List<Id>>();
            if (assProductCountMapAll.containsKey(main.rec.TransferApplySummary__c)) {
                assProductCountMap = assProductCountMapAll.get(main.rec.TransferApplySummary__c);
            }

            for (TransferApplyDetail__c tad : tadList) {
                if (assProductCountMap.containsKey(tad.Asset__r.Product2Id) && assProductCountMap.get(tad.Asset__r.Product2Id).size() > 0) {

                    List<Id> count = assProductCountMap.get(tad.Asset__r.Product2Id);
                    String assetId = (String)count[0];
                    count.remove(0);
                    assProductCountMap.put(tad.Asset__r.Product2Id, count);
                    assProductCountMapAll.put(main.rec.TransferApplySummary__c, assProductCountMap);

                    //String key = (String)main.rec.Asset__c + ':' + assetId;
                    //Integer otoCnt;
                    //if (otoMap.containsKey(key)) {
                    //    otoCnt = otoMap.get(key);
                    //} else {
                    //    otoCnt = 0;
                    //}
                    //otoMap.put(key, otoCnt + 1);

                    // 这里检查的是 正常上架+现场扫的 在型号和数量上与 原配套 是否相同
                    // 和主体同时上架且正常上架的，要用trigger建link
                    // 明细中不和主体一同上架，或待废弃上架的，不建link
                    // 现场扫出来的，用本文件里的createOtoLinkFromScan()建，不用trigger建
                    if(tad.Inspection_result_after_F__c == 'OK' || (!tad.Arrival_wh_Abandoned_Flag_F__c && tad.Arrival_wh_Flag_F__c)) {
                        otoDetailId.add(tad.Id);
                    }
                } else {
                    if (!forceSave && (main.rec.Cancel_Select__c == false || (main.rec.Cancel_Select__c == true && tad.OneToOneAccessory__c))) {
                        main.errorInfo = '未补全附属品(部分上架请勾选复选框):'+tad.Asset__r.Product2.Name;
                        err = true;
                        break;
                    }
                }
            }
        }


        if (err) return null;

        //for (String oto : otoMap.keySet()) {
        //    List<String> keys = oto.split(':');
        //    Fixture_OneToOne_Link__c otolink = new Fixture_OneToOne_Link__c();
        //    otolink.Main_Asset__c = keys[0];
        //    otolink.Accessory_Asset__c = keys[1];
        //    otolink.Quantity__c = otoMap.get(oto);
        //    otolinkList.add(otolink);
        //}
        Datetime now = System.now();
        for (TransferApplyDetail__c esd : eList) {
            if (esd.Arrival_in_wh__c) {
                esd.Arrival_wh_time__c = now;
                esd.Return_wh_chenk_staff__c = userid;
                // 不和主体同时上架，或待废弃上架，不建link
                if(!otoDetailId.contains(esd.Id)) {
                    esd.SkipLink__c = true;
                }
            } else {
                esd.Arrival_wh_time__c = null;
                esd.Return_wh_chenk_staff__c = null;
            }
        }
        for (EsdInfo esdInfo : esdList) {
            if (esdInfo.accessoryFlg) continue;
            TransferApplyDetail__c esd = esdInfo.rec;
            if (esd.Arrival_in_wh__c && esd.FSD_OneToOneAccessory_Cnt_F__c > 0 && esd.Main_OneToOne__c && esd.Arrival_wh_Abandoned_Flag_F__c) {
                otoCheckList_main.add(esdInfo);
            }
        }
        String sqlStr = 'SELECT Id FROM Asset WHERE Id IN:assetForLock ';
        String sqlWhere = '';
        if(! ukeySet.isEmpty()) {
            for(String ukey: ukeySet) {
                // 型号;存放地;本部
                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)';
                }

                sqlWhere += ' OR';
            }
            sqlWhere = sqlWhere.removeEnd('OR');
            sqlWhere = '((' + sqlWhere + ')';
            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'
                    + ' AND Manage_type__c = \'数量管理\')';
            sqlStr += ' OR ' + sqlWhere ;
        }
        sqlStr += ' FOR UPDATE';
        List<Asset> astLock = Database.query(sqlStr);
        Savepoint sp = Database.setSavepoint();
        try {
            // 强制删废弃主体的一对一link
            if (otoCheckList_main.size() > 0) {
                List<Id> mainIds = new List<Id>();
                for (EsdInfo oto : otoCheckList_main) {
                    if (String.isNotBlank(oto.rec.Asset__c)) {
                        // Asset__c 念のための確認
                        mainIds.add(oto.rec.Asset__c);
                    }
                }
                FixtureUtil.delOtOLinkData(mainIds);
            }

            // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230804 by lc Start
            if (!assUpdList.isEmpty() && assUpdList.size() > 0) {
                Oly_TriggerHandler.bypass('AssetHandler');
                Oly_TriggerHandler.bypass('AssetHandlerCheck');
                FixtureUtil.withoutUpdate(assUpdList);
                Oly_TriggerHandler.clearBypass('AssetHandler');
                Oly_TriggerHandler.clearBypass('AssetHandlerCheck');
            }
            // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230804 by lc End

            // 这里只更新明细，保有设备和link都放到trigger里更新
            FixtureUtil.withoutUpsertObjects(eList);

            if (scanOtoAccessoryMap.size() > 0) { // 只有现场追加的
                createOtoLinkFromScan(otoCheckList_main, scanOtoAccessoryMap);
            }

            List<EsdInfo> esdL = new List<EsdInfo>();
            for (EsdInfo esd : esdList) {
                if (!esd.accessoryFlg) {
                    esdL.add(esd);
                }
            }
            init();
            done_flg = true;
            //Set<Id> a = new Set<Id>();
            //for(TransferApplyDetail__c t: [SELECT Asset__c, Asset_After__c FROM TransferApplyDetail__c WHERE Id=:eList]){
            //    a.add(t.Asset_After__c);
            //    a.add(t.Asset__c);
            //}

            //print('更新后设备',[SELECT Name, Account.Name, WH_location__c  FROM Asset WHERE Id IN:a]);
            //print('更新后link',[SELECT Quantity__c,Main_Asset__c,Accessory_Asset__c FROM Fixture_OneToOne_Link__c WHERE Main_Asset__c=:astLock]);
            //Database.rollback(sp);
        } catch (Exception ex) {
            system.debug('=====' + ex.getMessage());
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, ex.getMessage()));
            Database.rollback(sp);
            done_flg = false;
        }

        return null;
    }
    //// 调试用
    //private void print(String title, Map<String, Object> m) {
    //    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Info, title));
    //    for(String a:m.keyset()) {
    //        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Info, '' + m.get(a)));
    //    }
    //}
    //// 调试用
    //private void print(String title, Map<Id, Object> m) {
    //    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Info, title));
    //    for(Id a:m.keyset()) {
    //        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Info, '' + m.get(a)));
    //    }
    //}
    //// 调试用
    //private void print(String title, List<Object> l) {
    //    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Info, title));
    //    for(Object o:l) {
    //        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Info, '' + o));
    //    }
    //}
    public class EsdInfo {
        public TransferApplyDetail__c rec { get; set; }
        public Asset rec2 { get; set; }
        public String errorInfo { get; set; }
        public boolean accessoryFlg { get; set; }
        public String accessorySetId { get; set; }
        public Boolean discardFlg { get; set; }
        public boolean editable { get; set; }
        public String fsName {get;set;}
        public String wh_location {get;set;}

        public EsdInfo() {
            this.discardFlg = false;
            this.editable = false;
        }

        public EsdInfo(TransferApplyDetail__c rec, Boolean isStartUser, Boolean isDestUser, Boolean is2B3) {
            this.rec = rec;
            this.accessoryFlg = false;
            this.discardFlg = false;
            this.editable = false;
            this.fsName = rec.TransferApplySummary__r.Name;
            this.wh_location = rec.Asset__r.WH_location__c;

            if(String.isNotBlank(rec.TransferApplySummary__r.Fixture_Set__r.Name)){
                this.fsName += ':' + rec.TransferApplySummary__r.Fixture_Set__r.Name;
            }
            if (!rec.Arrival_in_wh__c && (rec.Arrival_wh_Flag_F__c || rec.Arrival_wh_Abandoned_Flag_F__c)) {
                this.editable = rec.RecordType_F__c != 'AgencyToCenter' || rec.IsPerfect__c;
            }

            // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230804 by lc Start
            if (rec.Asset__c != null) {
                if (String.isBlank(rec.Asset__r.Temperature_And_Humidity_Zone__c)) {
                    // 初始默认为A区
                    rec.Asset__r.Temperature_And_Humidity_Zone__c = 'A区';
                }
            }
            // 【FY24大及巨大课题】北京新法规项目对应 DB202307428742 20230804 by lc End

            if(is2B3) {
                // 2B3_照片不需要其它判断
            }
            // 取消或寄回，由调拨前中心操作
            else if(isStartUser) {
                this.editable = this.editable && (rec.Return_DeliverySlip__c != null || rec.Cancel_Select__c);
            }
            // 未取消且未寄回，由调拨后中心操作
            else if(isDestUser) {
                this.editable = this.editable && rec.Return_DeliverySlip__c == null && !rec.Cancel_Select__c;
            }
            else {
                this.editable = false;
            }
            this.discardFlg = rec.Arrival_wh_Abandoned_Flag_F__c;
            this.accessorySetId = rec.TransferApplySummary__c;
        }
    }
}