global class InventoryStartAssetSnapshotBatch implements Database.Batchable<sObject>, Database.Stateful {

    private String cunFangDi { get; set; }     //存放地, 肯定有值 不为null
    private Datetime lastInventoryTime {get;set;} // 上次盘点时间
    private Inventory_Header__c ih_new = new Inventory_Header__c();
    private Map<String, List<String>> statusMap = new Map<String, List<String>>();
    private Map<String, List<String>> TAstatusMap = new Map<String, List<String>>();//20210520 you 1650 
    private Map<String, List<String>> AngecyTAstatusMap = new Map<String, List<String>>();//20210625 you 1650   办事处单独
    private Map<String, String> assetFieldMap = new Map<String, String>();
    private Map<String, String> raesdFieldMap = new Map<String, String>();
    private Map<String, String> repairFieldMap = new Map<String, String>();
    private Map<String, String> TasdFieldMap = new Map<String, String>();//20210520 you 1650
    private Set<String> availableMain = new Set<String>();
    private Set<String> availableMainOnStock = new Set<String>();
    private Set<String> defaultAssetField;
    private Set<String> defaultRaesdField;
    private Set<String> defaultRepairField;
    private Set<String> defaultTasdField;//20210520 you 1650
    private String assetId { get; set; } 
    public static Integer FIELDMAX = 30;

    global List<String> emailMessages;
    global Integer totalCount = 0; // 总件数 (Asset)
    global Integer executedCount = 0;
    global Integer failedCount = 0;


    @TestVisible
    private static List<String> messagesForTest;

    global InventoryStartAssetSnapshotBatch(String cunFangDi, Inventory_Header__c ih_new){
        this.cunFangDi = cunFangDi;
        this.ih_new = ih_new;
        this.emailMessages = new List<String>();
    }
    /**
    String aa='a3H1m0000002DAE';//盘点表头id  自己做测试添加得
    List<Inventory_Header__c> ihList = [select Id, Inventory_Status__c, Name, Internal_asset_location__c, Inventory_Start_Date__c from Inventory_Header__c where id =:aa];
    system.debug('==='+ihList.size());
    Database.executeBatch(new InventoryStartAssetSnapshotBatch('沈阳',ihList[0],'02i10000004HYl6AAG'), 1);  //保有设备id
  
    global InventoryStartAssetSnapshotBatch(String cunFangDi, Inventory_Header__c ih_new, String assetId){
        this.cunFangDi = cunFangDi;
        this.ih_new = ih_new;
        this.assetId = assetId;
        this.emailMessages = new List<String>();
    }
  **/
  
    global Database.QueryLocator start(Database.BatchableContext bc) {
        System.debug('enter InventoryStartAssetSnapshotBatch start');
        List<Inventory_Header__c> lastInventory = [SELECT CreatedDate
                                               FROM Inventory_Header__c
                                              WHERE Fixture_Header__c = null
                                                AND Id !=:ih_new.Id
                                                AND Internal_asset_location__c = :cunFangDi
                                              ORDER BY CreatedDate DESC
                                              LIMIT 1
                                              ];
        if(lastInventory.isEmpty()){
            lastInventoryTime = Datetime.newInstanceGMT(1970, 1, 1, 0, 0, 0);
        }
        else{
            lastInventoryTime = lastInventory[0].CreatedDate;
        }

        List<Inventory_Header__c> ihList = [select Id, Name, Inventory_Status__c, Internal_asset_location__c, InventorySubmit_PIC__c, InventoryCheck_PIC__c,InventoryCheck_PIC__r.Email
                from Inventory_Header__c where Id = :ih_new.Id];
        
        if (ihList.size() == 0 ||  ihList[0].Inventory_Status__c != '处理中') {
            if (ihList[0].Inventory_Status__c == null) {
                Inventory_Header__c ih = new Inventory_Header__c();
                ih.Internal_asset_location__c = ihList[0].Internal_asset_location__c;
                ih.Inventory_Status__c = '处理中';
                ih.InventoryPIC__c = UserInfo.getUserId();
                ih.Inventory_Start_Date__c = Date.today();
                ih.InventorySubmit_PIC__c = ihList[0].InventorySubmit_PIC__c;
                ih.InventoryCheck_PIC__c = ihList[0].InventoryCheck_PIC__c; 
                ih.UniqueKey__c = ihList[0].Internal_asset_location__c+':'+Date.today().toStartOfMonth();

                // 删备品表头前先删掉备品表头下的耗材表头
                List<Inventory_Header__c> consumIh = [select Id from Inventory_Header__c where Fixture_Header__c = :ih_new.Id];
                delete consumIh;
                delete ih_new;
                insert ih; 
                this.ih_new = ih;
            } else {
                // emailMessages ihList[0].Name 的状态是 ihList[0].Inventory_Status__c 不能盘点
                this.emailMessages.add(ihList[0].Name +'的状态是' + ihList[0].Inventory_Status__c + ' ,不能盘点。');
                return Database.getQueryLocator([SELECT Id FROM Asset LIMIT 0]);
            }
        }

        List<Asset> errorList = [select Id,Inventory_Frozen_Quantity__c
                from Asset where (Inventory_Frozen_Quantity__c>0
                             or Appended_Inventory_Frozen_Quantity__c>0
                             or Inventory_Profit_Quantity__c>0
                             or Appended_Inventory_Profit_Quantity__c>0)
                             and Asset_loaner_category__c != '耗材'
                             and Internal_asset_location__c = :cunFangDi];
        if (errorList.size()>0) {
            this.emailMessages.add(ihList[0].Name +' 备品资产中存在未清空的冻结数, 不能盘点。');
            return Database.getQueryLocator([SELECT Id FROM Asset LIMIT 0]);
        }

        defaultAssetField = new Set<String> {'Id','Last_Reserve_RAES_Detail__r.RAESD_Status__c','Last_Reserve_RAES_Detail__r.Is_Body__c','Last_Reserve_TAES_Detail__r.TAESD_Status__c','Last_Reserve_TAES_Detail__r.Is_Body__c','Fixture_OneToOne_Link__r.Main_Asset__r.WH_location__c','Fixture_Model_No_F__c','Internal_asset_location__c','WH_location__c','Ji_Zhong_Guan_Li_Ku_Cun__c','You_Xiao_Ku_Cun__c','Out_of_wh__c','Main_OneToOne__c','Repairing_Link_Detail_Count__c','Manage_type__c','Fixture_Status__c','Fixture_OneToOne_Link__c','Fixture_OneToOne_Link__r.Main_Asset__c','Abandoned_Inventory__c','Abandoned_RealThing__c','Repairing_Count__c','Draft_Repair_Count__c','Frozen_Quantity__c','Quantity'};
        defaultRaesdField = new Set<String> {'Id','Loaner_Giveup_Time__c', 'Rental_Apply_Equipment_Set__r.First_RAESD__r.Asset__r.WH_location__c','Asset__c','RAESD_Status__c','OneToOne_Flag__c','Rental_Apply_Equipment_Set__r.First_RAESD__r.Asset__c','Lost_item_giveup__c'};
        defaultRepairField = new Set<String> {'Id','Delivered_Product__c'};
        //20210520 you 1650 
        defaultTasdField = new Set<String> {'Id','Loaner_Giveup_Time__c', 'TransferApplySummary__r.First_TAD__r.Asset__r.WH_location__c','Asset__c','TAESD_Status__c','OneToOneAccessory__c','TransferApplySummary__r.First_TAD__r.Asset__c','Lost_item_giveup__c'};
        //针对备品一览明细的借出备品明细状态
        statusMap.put('出借中', new List<String> {'已出库','申请者已收货','申请者收货NG','医院已装机确认','已回寄','欠品中'});
        statusMap.put('在库', new List<String> {'已下架','出库前已检测','待修理','已回收','回收后已CDS','待上架','待移至报废区'});
        //针对调拨一览明细的调拨明细状态 //20210520 you 1650 
        TAstatusMap.put('调拨中', new List<String> {'已出库','欠品中','收货NG','已收货','收货后已CDS','已回寄'});
        TAstatusMap.put('在库', new List<String> {'已下架','出库前已检测','待修理','已回收','回收后已CDS','待上架','待移至报废区'});
         
        //办事处的调拨和备品的不一样，为了区分
        AngecyTAstatusMap.put('调拨中', new List<String> {'已出库','欠品中','收货NG','已收货','收货后已CDS','已回寄','待修理','待上架','待移至报废区'});
        AngecyTAstatusMap.put('在库', new List<String> {'已下架','出库前已检测','已回收','回收后已CDS'});


        

        Inventory_Batch_Mapping__mdt columns = [select From_Columns__c, Inventory_Columns__c from Inventory_Batch_Mapping__mdt where DeveloperName = 'Asset'];
        List<String> keyList = columns.From_Columns__c.split(',');
        List<String> valueList = columns.Inventory_Columns__c.split(',');
        for (Integer i = 0; i < keyList.size(); i++) {
            assetFieldMap.put(keyList[i], valueList[i]);
            defaultAssetField.add(keyList[i]);
        }

        columns = [select From_Columns__c, Inventory_Columns__c from Inventory_Batch_Mapping__mdt where DeveloperName = 'Repair'];
        keyList = columns.From_Columns__c.split(',');
        valueList = columns.Inventory_Columns__c.split(',');
        for (Integer i = 0; i < keyList.size(); i++) {
            repairFieldMap.put(keyList[i], valueList[i]);
            defaultRepairField.add(keyList[i]);
        }

        columns = [select From_Columns__c, Inventory_Columns__c from Inventory_Batch_Mapping__mdt where DeveloperName = 'RAESD'];
        keyList = columns.From_Columns__c.split(',');
        valueList = columns.Inventory_Columns__c.split(',');
        for (Integer i = 0; i < keyList.size(); i++) {
            raesdFieldMap.put(keyList[i], valueList[i]);
            defaultRaesdField.add(keyList[i]);
        }
        //20210520 you 1650  start
        columns = [select From_Columns__c, Inventory_Columns__c from Inventory_Batch_Mapping__mdt where DeveloperName = 'TASD'];
        keyList = columns.From_Columns__c.split(',');
        valueList = columns.Inventory_Columns__c.split(',');
        for (Integer i = 0; i < keyList.size(); i++) {
            TasdFieldMap.put(keyList[i], valueList[i]);
            defaultTasdField.add(keyList[i]);
        }
        //20210729 办事处盘点看所在本部 邮件
         SS_Batch_Column_Mapping__c mpdMapping = SS_Batch_Column_Mapping__c.getValues('Agency_Inventory_Role');//办事处盘点保有设备得权限           
        Map<String,String> AgencyHeaderMap = new Map<String,String>();
        for (Integer i = 1; i <= FIELDMAX; i++) {
            String lpadI = ('00' + i).right(3);
            String fromColumn = 'From_Column_' + lpadI + '__c';
            String apiStr = String.valueOf(mpdMapping.get(fromColumn));
            if (String.isBlank(apiStr) == false) {
                String ssColumn = 'SS_Column_' + lpadI + '__c';
                String ssApiStr = String.valueOf(mpdMapping.get(ssColumn));
                AgencyHeaderMap.put(apiStr,ssApiStr);  
            }

        }
        //20210520 you 1650  end
        String querysql ='';
         if(String.isBlank(assetId)){
            querysql = 'select ' + String.join(new List<String>(defaultAssetField), ', ')
                + ' from Asset '
                + 'where Internal_asset_location__c = :cunFangDi'
                + '  and Fixture_Status__c not in (\'废弃\', \'无保有\')'
                + '  and Delete_Flag__c = False'
                + '  and Quantity > 0'
                + '  and Asset_Owner__c = \'Olympus\''
                + '  and ' + FixtureUtil.getAssetSoqlBase()
                + '  and Asset_loaner_category__c != \'耗材\'';
                if(AgencyHeaderMap.containsKey(cunFangDi)){
                    String Salesdepartment = AgencyHeaderMap.get(cunFangDi);
                    System.debug('Salesdepartment=='+Salesdepartment+'==cunFangDi='+cunFangDi);
                   querysql += '  and Salesdepartment__c = :Salesdepartment';
                }
                // 增加排序确保主体先处理
                querysql += '  order by Manage_type__c desc, Main_OneToOne__c desc, Last_Reserve_RAES_Detail__r.Is_Body__c desc,Last_Reserve_TAES_Detail__r.Is_Body__c desc';
        }else{//自己做测试加的保有设备得id
            querysql = 'select ' + String.join(new List<String>(defaultAssetField), ', ')
                + ' from Asset '
                + 'where Internal_asset_location__c = :cunFangDi'
                + '  and Fixture_Status__c not in (\'废弃\', \'无保有\')'
                + '  and Delete_Flag__c = False'
                + '  and Quantity > 0'
                + '  and Asset_Owner__c = \'Olympus\''
                + '  and id =: assetId'
                + '  and ' + FixtureUtil.getAssetSoqlBase()
                + '  and Asset_loaner_category__c != \'耗材\''
                // 增加排序确保主体先处理
                + '  order by Manage_type__c desc, Main_OneToOne__c desc, Last_Reserve_RAES_Detail__r.Is_Body__c desc,Last_Reserve_TAES_Detail__r.Is_Body__c desc';
        }
        
        system.debug('querysql1'+querysql);
        return Database.getQueryLocator(querysql);
    }

    global void execute(Database.BatchableContext BC, List<Asset> assetList) {
        // select ih_new, is batch executing, else return
        List<Inventory_Header__c> ihList = [select Id, Name, Inventory_Status__c
                from Inventory_Header__c where Id = :ih_new.Id];
        if (ihList.size() == 0 || ihList[0].Inventory_Status__c != '处理中') {
            // emailMessages ihList[0].Name 的状态是 ihList[0].Inventory_Status__c 不能盘点
            this.emailMessages.add(ihList[0].Name +'的状态是' + ihList[0].Inventory_Status__c + ' ,不能盘点。');
            return;
        }
    Savepoint sp = Database.setSavepoint();
    try {
        //总件数count
        totalCount += assetList.size();
        system.debug('保有设备总件数：'+assetList.size());
        // UniqueKey__c:Record
        Map<String, Inventory_Detail__c> upsertMap = new Map<String, Inventory_Detail__c>();
        Map<Id, Asset> assetMap = new Map<Id, Asset>();
        //办事处的调拨和备品的不一样，为了区分
        Boolean angecycun=false;
        if(cunFangDi=='上海 备品中心' || cunFangDi=='广州 备品中心' || cunFangDi=='北京 备品中心'){
           angecycun = true;
        }
        for (Asset ast : assetList) {
            assetMap.put(ast.Id, ast);
            // '在库' from Asset
            Inventory_Detail__c ihDetail = new Inventory_Detail__c();
            ihDetail.Asset__c = ast.Id;

            ihDetail.Amount__c = ast.Quantity;
            ihDetail.WH_location__c = ast.WH_location__c;
            //一对一主体  //20210520 you 1650 加上调拨一览明细的
            if (ast.Main_OneToOne__c 
                || (ast.Last_Reserve_RAES_Detail__r.Is_Body__c 
                    && statusMap.get('在库').contains(ast.Last_Reserve_RAES_Detail__r.RAESD_Status__c))
                || (angecycun && ast.Last_Reserve_TAES_Detail__r.Is_Body__c 
                    && TAstatusMap.get('在库').contains(ast.Last_Reserve_TAES_Detail__r.TAESD_Status__c))
                || (!angecycun && ast.Last_Reserve_TAES_Detail__r.Is_Body__c 
                    && AngecyTAstatusMap.get('在库').contains(ast.Last_Reserve_TAES_Detail__r.TAESD_Status__c))) {
                ihDetail.OneToOne_Body__c = true;
                ihDetail.Main_Asset__c = ast.Id;
            }
            //个体一对一附属品
            if (ast.Fixture_OneToOne_Link__c != null) {
                ihDetail.Main_Asset__c = ast.Fixture_OneToOne_Link__r.Main_Asset__c;
                ihDetail.OneToOne_Accsessary__c = true;
                ihDetail.Amount__c = 0;
                ihDetail.Fixture_OneToOne_Link__c = ast.Fixture_OneToOne_Link__c;
                //ihDetail.WH_location__c = ast.Fixture_OneToOne_Link__r.Main_Asset__r.WH_location__c;
            }

            Inventory_Detail__c ihDetail_add = new Inventory_Detail__c();
            ihDetail.Asset_Status__c = '在库';
            ihDetail.Sync_Asset_Record_Flag__c = true;
            ihDetail.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail.Asset_Status__c+':'+ihDetail.Main_Asset__c+':'+ast.Id;
            ihDetail.Inventory_Header__c = ih_new.Id;
            ihDetail.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
            ihDetail.Internal_asset_location__c = ast.Internal_asset_location__c;
            ihDetail.toAbandon_amount__c = ast.Abandoned_RealThing__c;

            // '丢失' from Asset
            if (ast.Abandoned_Inventory__c > 0) {
                Inventory_Detail__c ihDetail_abd = new Inventory_Detail__c();
                ihDetail_abd.Asset__c = ast.Id;
                //if (ast.Main_OneToOne__c) {
                //    ihDetail_abd.OneToOne_Body__c = true;
                //}
                //if (ast.Fixture_OneToOne_Link__c != null) {
                //    ihDetail_abd.Main_Asset__c = ast.Fixture_OneToOne_Link__r.Main_Asset__c;
                //}
                ihDetail_abd.Asset_Status__c = '丢失';
                ihDetail_abd.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail_abd.Asset_Status__c+':'+ihDetail_abd.Main_Asset__c+':'+ast.Id;
                ihDetail_abd.Inventory_Header__c = ih_new.Id;
                ihDetail_abd.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
                ihDetail_abd.WH_location__c = ast.WH_location__c;
                ihDetail_abd.Internal_asset_location__c = ast.Internal_asset_location__c;
                ihDetail_abd.Amount__c = ast.Abandoned_Inventory__c;
                ihDetail_abd.Abandoned_Inventory_Start__c = ast.Abandoned_Inventory__c;
                setMapObject(ihDetail_abd, ast, 'Asset');
                upsertMap.put(ihDetail_abd.UniqueKey__c, ihDetail_abd);
                ihDetail.Amount__c = ihDetail.Amount__c-ihDetail_abd.Amount__c;
            }
            // '修理中' from Asset
            //if (ast.Repairing_Count__c + ast.Draft_Repair_Count__c > 0) {
            //    Inventory_Detail__c ihDetail_rep = new Inventory_Detail__c();
            //    ihDetail_rep.Asset__c = ast.Id;
            //    if (ast.Main_OneToOne__c) {
            //        ihDetail_rep.OneToOne_Body__c = true;
            //    }
            //    if (ast.Fixture_OneToOne_Link__c != null) {
            //        ihDetail_rep.Main_Asset__c = ast.Fixture_OneToOne_Link__r.Main_Asset__c;
            //    }
            //    ihDetail_rep.Asset_Status__c = '维修中';
            //    ihDetail_rep.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail_rep.Asset_Status__c+':'+ihDetail_rep.Main_Asset__c+':'+ast.Id;
            //    ihDetail_rep.Inventory_Header__c = ih_new.Id;
            //    ihDetail_rep.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
            //    ihDetail_rep.WH_location__c = ast.WH_location__c;
            //    ihDetail_rep.Internal_asset_location__c = ast.Internal_asset_location__c;
            //    ihDetail_rep.Amount__c = ast.Repairing_Count__c + ast.Draft_Repair_Count__c;
            //    setMapObject(ihDetail_rep, ast, 'Asset');
            //    upsertMap.put(ihDetail_rep.UniqueKey__c, ihDetail_rep);
            //    ihDetail.Amount__c = ihDetail.Amount__c - ihDetail_rep.Amount__c;
            //}
            // '冻结' from Asset
            if (ast.Frozen_Quantity__c > 0) {
                Inventory_Detail__c ihDetail_frz = new Inventory_Detail__c();
                ihDetail_frz.Asset__c = ast.Id;
                //if (ast.Main_OneToOne__c) {
                //    ihDetail_frz.OneToOne_Body__c = true;
                //}
                //if (ast.Fixture_OneToOne_Link__c != null) {
                //    ihDetail_frz.Main_Asset__c = ast.Fixture_OneToOne_Link__r.Main_Asset__c;
                //}
                ihDetail_frz.Asset_Status__c = '冻结';
                ihDetail_frz.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail_frz.Asset_Status__c+':'+ihDetail_frz.Main_Asset__c+':'+ast.Id;
                ihDetail_frz.Inventory_Header__c = ih_new.Id;
                ihDetail_frz.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
                ihDetail_frz.WH_location__c = ast.WH_location__c;
                ihDetail_frz.Internal_asset_location__c = ast.Internal_asset_location__c;
                ihDetail_frz.Amount__c = ast.Frozen_Quantity__c;
                setMapObject(ihDetail_frz, ast, 'Asset');
                upsertMap.put(ihDetail_frz.UniqueKey__c, ihDetail_frz);
                ihDetail.Amount__c = ihDetail.Amount__c - ihDetail_frz.Amount__c;
            }
            //待废弃数
            if (ast.Fixture_Status__c == '待废弃') {
                ihDetail.toAbandon_amount__c = ihDetail.Amount__c;
            }
            setMapObject(ihDetail, ast, 'Asset');
            if (ast.Fixture_OneToOne_Link__c != null) {
                ihDetail.WH_location__c = ast.Fixture_OneToOne_Link__r.Main_Asset__r.WH_location__c;
            }
            system.debug('保有设备上的数据总计：'+ihDetail);
            upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
            
        }
        
        //修理id
        String querysql = 'select ' + String.join(new List<String>(defaultRepairField), ', ')
                // + ' from Repair__c where Delivered_Product__c IN :assetList and Status__c in (\'草案中\',\'1.受理完毕\',\'2.维修报价阶段\',\'3.维修阶段\')';
                + ' from Repair__c where Delivered_Product__c IN :assetList '
                + ' and (Status__c in (\'1.受理完毕\',\'2.维修报价阶段\',\'3.维修阶段\') or (Status__c in (\'4.修理品返送阶段\',\'0.取消\') and Repair_Returned_To_HP_Date__c=null))';
        system.debug('querysql2--修理'+querysql);
        List<Repair__c> repaireList = Database.query(querysql);
        system.debug('querysql2--修理'+querysql+'==修理条数：'+repaireList.size());
        for (Repair__c rp : repaireList) {
            Asset ast = assetMap.get(rp.Delivered_Product__c);
            Inventory_Detail__c ihDetail_rep = new Inventory_Detail__c();
            ihDetail_rep.Asset__c = ast.Id;
            //if (ast.Main_OneToOne__c) {
            //    ihDetail_rep.OneToOne_Body__c = true;
            //}
            //if (ast.Fixture_OneToOne_Link__c != null) {
            //    ihDetail_rep.Main_Asset__c = ast.Fixture_OneToOne_Link__r.Main_Asset__c;
            //}
            ihDetail_rep.Asset_Status__c = '维修中';
            ihDetail_rep.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail_rep.Asset_Status__c+':'+ihDetail_rep.Main_Asset__c+':'+ihDetail_rep.Asset__c+':'+rp.Id;
            ihDetail_rep.Inventory_Header__c = ih_new.Id;
            ihDetail_rep.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
            ihDetail_rep.WH_location__c = ast.WH_location__c;
            ihDetail_rep.Internal_asset_location__c = ast.Internal_asset_location__c;
            ihDetail_rep.Amount__c = 1;
            ihDetail_rep.Repair__c = rp.Id;
            ihDetail_rep.Repair_Id__c = rp.Id;
            setMapObject(ihDetail_rep, ast, 'Asset');
            setMapObject(ihDetail_rep, rp, 'Repair');
            upsertMap.put(ihDetail_rep.UniqueKey__c, ihDetail_rep);

            String uniKey = ih_new.Id+':'+ihDetail_rep.Fixture_Model_No__c+':'+'在库'+':'+ihDetail_rep.Main_Asset__c+':'+ihDetail_rep.Asset__c;
            Inventory_Detail__c ihDetail = upsertMap.get(uniKey);
            if (ihDetail != null) {
                ihDetail.Amount__c -= 1;
                upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
            }
        }

        //借出备品配套一览明细

        List<Rental_Apply_Equipment_Set_Detail__c> copy_raList = [select Rental_Apply__c 
                from Rental_Apply_Equipment_Set_Detail__c 
                where Asset__c IN :assetList 
                    and Rental_Apply__r.RA_Status__c ='完了' 
                    and Arrival_in_wh__c <> true 
                    and RAESD_Status__c not in ('取消', '已消耗')];
        system.debug('满足条件得备品明细：'+copy_raList.size());
        Set<Id> copy_raId = new Set<Id>();
        for (Rental_Apply_Equipment_Set_Detail__c copy_ra : copy_raList) {
            copy_raId.add(copy_ra.Rental_Apply__c);
        }

        querysql = 'select ' + String.join(new List<String>(defaultRaesdField), ', ')
                + ' from Rental_Apply_Equipment_Set_Detail__c '
                + ' where Asset__c IN :assetList '
                + ' and (Rental_Apply__r.RA_Status__c <> \'完了\' or Rental_Apply__c in :copy_raId)';
        
        List<Rental_Apply_Equipment_Set_Detail__c> detailList = Database.query(querysql);
        system.debug('querysql2--借出备品配套一览明细'+querysql+'==需要做操作得明细：'+detailList.size());
        for (Rental_Apply_Equipment_Set_Detail__c dl : detailList) {
            Asset ast = assetMap.get(dl.Asset__c);
            String main_Asset_Id = null;
            if (ast.Fixture_OneToOne_Link__c != null) {
                main_Asset_Id = ast.Fixture_OneToOne_Link__r.Main_Asset__c;
            } else if (ast.Last_Reserve_RAES_Detail__r.Is_Body__c && statusMap.get('在库').contains(ast.Last_Reserve_RAES_Detail__r.RAESD_Status__c)) {
                main_Asset_Id = ast.Id;
            }

            // 丢失借出明细 from 明细
            if (true == dl.Lost_item_giveup__c && dl.Loaner_Giveup_Time__c != null && dl.Loaner_Giveup_Time__c > lastInventoryTime) {
                Inventory_Detail__c ihDetail_lend = new Inventory_Detail__c();
                ihDetail_lend.Asset__c = ast.Id;
                ihDetail_lend.RAESD__c = dl.Id;
                ihDetail_lend.RAESD_Id__c = dl.Id;
                ihDetail_lend.Asset_Status__c = '丢失借出明细';
                ihDetail_lend.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail_lend.Asset_Status__c+':'+ihDetail_lend.Main_Asset__c+':'+ast.Id+':'+dl.Id;
                ihDetail_lend.Inventory_Header__c = ih_new.Id;
                ihDetail_lend.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
                ihDetail_lend.WH_location__c = ast.WH_location__c;
                ihDetail_lend.Internal_asset_location__c = ast.Internal_asset_location__c;
                ihDetail_lend.Amount__c = 1;
                system.debug('符合丢失借出明细：'+ihDetail_lend);
                setMapObject(ihDetail_lend, ast, 'Asset');
                setMapObject(ihDetail_lend, dl, 'Raesd');
                upsertMap.put(ihDetail_lend.UniqueKey__c, ihDetail_lend);
                
            }
            // 出借中 from 明细
            else if (statusMap.get('出借中').contains(dl.RAESD_Status__c)) {
                Inventory_Detail__c ihDetail_lend = new Inventory_Detail__c();
                ihDetail_lend.Asset__c = ast.Id;
                ihDetail_lend.RAESD__c = dl.Id;
                ihDetail_lend.RAESD_Id__c = dl.Id;
                ihDetail_lend.Asset_Status__c = '出借中';
                ihDetail_lend.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail_lend.Asset_Status__c+':'+ihDetail_lend.Main_Asset__c+':'+ast.Id+':'+dl.Id;
                ihDetail_lend.Inventory_Header__c = ih_new.Id;
                ihDetail_lend.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
                ihDetail_lend.WH_location__c = ast.WH_location__c;
                ihDetail_lend.Internal_asset_location__c = ast.Internal_asset_location__c;
                ihDetail_lend.Amount__c = 1;
                setMapObject(ihDetail_lend, ast, 'Asset');
                setMapObject(ihDetail_lend, dl, 'Raesd');
                upsertMap.put(ihDetail_lend.UniqueKey__c, ihDetail_lend);
                system.debug('符合出借中得明细：'+ihDetail_lend);
                
                String uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+main_Asset_Id+':'+ast.Id;
                system.debug('出借中的key：'+uniKey);
                Inventory_Detail__c ihDetail = upsertMap.get(uniKey);
                if (ihDetail != null) { 
                    ihDetail.Amount__c -= 1;
                    system.debug('有出借中的数据，那么asset的数量要减掉'+ihDetail.Amount__c);
                    upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                }
            }
            // 待移至报废区+设置虚拟货架号 from 明细
            else if (statusMap.get('在库').contains(dl.RAESD_Status__c)) {
                if(dl.OneToOne_Flag__c == false) {
                    
                    String uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+main_Asset_Id+':'+ast.Id;
                    system.debug('==非一对一=='+dl.id+'==uniKey=='+uniKey);
                    String vhwLocation = '待回库区';
                    if(dl.RAESD_Status__c == '已下架' || dl.RAESD_Status__c == '出库前已检测' ){
                        vhwLocation = '备货区';
                    }
                    //设置待报废数量
                    Inventory_Detail__c ihDetail = upsertMap.get(uniKey);
                    if (dl.RAESD_Status__c == '待移至报废区' ) {
                        if (ihDetail.toAbandon_amount__c == null) {
                            ihDetail.toAbandon_amount__c = 1;
                        } else {
                            ihDetail.toAbandon_amount__c += 1;
                        }
                    }

                    ihDetail.VWH_location__c = vhwLocation;
                    upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                }
                // 一对一
                else {
                    main_Asset_Id = dl.Rental_Apply_Equipment_Set__r.First_RAESD__r.Asset__c;
                    String uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+main_Asset_Id+':'+ast.Id;
                    system.debug('==一对一=='+dl.id+'==uniKey=='+uniKey);
                    String vhwLocation = '待回库区';
                    if(dl.RAESD_Status__c == '已下架' || dl.RAESD_Status__c == '出库前已检测' ){
                        vhwLocation = '备货区';
                    }
                    Inventory_Detail__c ihDetail = upsertMap.get(uniKey);
                    if (ihDetail == null) {
                        
                        ihDetail = new Inventory_Detail__c();
                        ihDetail.Asset__c = ast.Id;
                        ihDetail.OneToOne_Accsessary__c = true;
                        ihDetail.Main_Asset__c = main_Asset_Id;
                        ihDetail.Asset_Status__c = '在库';
                        ihDetail.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail.Asset_Status__c+':'+ihDetail.Main_Asset__c+':'+ast.Id;
                        ihDetail.Inventory_Header__c = ih_new.Id;
                        ihDetail.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
                        ihDetail.VWH_Location__c = vhwLocation;
                        ihDetail.Internal_asset_location__c = ast.Internal_asset_location__c;
                        ihDetail.Amount__c = 1;
                        setMapObject(ihDetail, ast, 'Asset');
                        ihDetail.WH_location__c = dl.Rental_Apply_Equipment_Set__r.First_RAESD__r.Asset__r.WH_location__c;
                        upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                        system.debug('==一对一 if=='+ihDetail.Amount__c);
                    } else {
                        ihDetail.Amount__c += 1;
                        //ihDetail.VWH_location__c = vhwLocation;
                        system.debug('==一对一 else=='+ihDetail.Amount__c);
                        upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                    }
                    uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+null+':'+ast.Id;
                    system.debug('==一对一 这里=='+uniKey);
                    if (upsertMap.containsKey(uniKey)) {
                        Inventory_Detail__c ihDetail_org = upsertMap.get(uniKey);
                        ihDetail_org.Amount__c -= 1;
                        system.debug('==在库有值 -1=='+ihDetail_org.Amount__c);
                        if (dl.RAESD_Status__c == '待移至报废区' ) {
                            if (ihDetail_org.toAbandon_amount__c == null) {
                                ihDetail_org.toAbandon_amount__c = 1;
                            } else {
                                ihDetail_org.toAbandon_amount__c += 1;
                            }
                        }
                        upsertMap.put(ihDetail_org.UniqueKey__c, ihDetail_org);
                    }
                }
            }
        }
        //调拨申请一览明细 //20210520 you 1650 
        List<TransferApplyDetail__c> copy_traList = [select TransferApply__c 
                from TransferApplyDetail__c 
                where Asset__c IN :assetList 
                    and TransferApply__r.TA_Status__c ='完了' 
                    and Arrival_in_wh__c <> true 
                    and TAESD_Status__c not in ('取消', '已消耗')];//调拨没有已消耗
  
        Set<Id> copy_taId = new Set<Id>();
        for (TransferApplyDetail__c copy_tra : copy_traList) {
            copy_taId.add(copy_tra.TransferApply__c);
        }

        querysql = 'select ' + String.join(new List<String>(defaultTasdField), ', ')
                + ' from TransferApplyDetail__c '
                + ' where Asset__c IN :assetList '
                + ' and (TransferApply__r.TA_Status__c <> \'完了\' or TransferApply__c in :copy_taId)';
        system.debug('querysql3--调拨申请一览明细'+querysql);
        List<TransferApplyDetail__c> tadetailList = Database.query(querysql);
        for (TransferApplyDetail__c ta : tadetailList) {
            Asset ast = assetMap.get(ta.Asset__c);
            String main_Asset_Id = null;
            if (ast.Fixture_OneToOne_Link__c != null) {
                main_Asset_Id = ast.Fixture_OneToOne_Link__r.Main_Asset__c;
            } else if (ast.Last_Reserve_TAES_Detail__r.Is_Body__c && ((angecycun && TAstatusMap.get('在库').contains(ast.Last_Reserve_TAES_Detail__r.TAESD_Status__c)) || (!angecycun && AngecyTAstatusMap.get('在库').contains(ast.Last_Reserve_TAES_Detail__r.TAESD_Status__c)) )) {
                main_Asset_Id = ast.Id;
            }

            // 丢失借出明细 from 明细
            if (true == ta.Lost_item_giveup__c && ta.Loaner_Giveup_Time__c != null && ta.Loaner_Giveup_Time__c > lastInventoryTime) {
                Inventory_Detail__c ihDetail_Tasd = new Inventory_Detail__c();
                ihDetail_Tasd.Asset__c = ast.Id;
                ihDetail_Tasd.TASD__c = ta.Id;
                ihDetail_Tasd.TASD_Id__c = ta.Id;
                ihDetail_Tasd.Asset_Status__c = '丢失调拨明细';
                ihDetail_Tasd.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail_Tasd.Asset_Status__c+':'+ihDetail_Tasd.Main_Asset__c+':'+ast.Id+':'+ta.Id;
                ihDetail_Tasd.Inventory_Header__c = ih_new.Id;
                ihDetail_Tasd.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
                ihDetail_Tasd.WH_location__c = ast.WH_location__c;
                ihDetail_Tasd.Internal_asset_location__c = ast.Internal_asset_location__c;
                ihDetail_Tasd.Amount__c = 1;
                setMapObject(ihDetail_Tasd, ast, 'Asset');
                setMapObject(ihDetail_Tasd, ta, 'TASD');
                upsertMap.put(ihDetail_Tasd.UniqueKey__c, ihDetail_Tasd);
            }
            // 出借中 from 明细
            //20210915 调拨的移管单 状态为“已出库”的就算完成了，不算调拨中的所以不用减数量 
            else if (ta.TransferApply__r.RecordType.Name != '备品中心移管至非集中管理部门'){
                if((angecycun && TAstatusMap.get('调拨中').contains(ta.TAESD_Status__c)) || (!angecycun && AngecyTAstatusMap.get('调拨中').contains(ta.TAESD_Status__c)) ) {
                    Inventory_Detail__c ihDetail_Tasd = new Inventory_Detail__c();
                    ihDetail_Tasd.Asset__c = ast.Id;
                    ihDetail_Tasd.TASD__c = ta.Id;
                    ihDetail_Tasd.TASD_Id__c = ta.Id;
                    ihDetail_Tasd.Asset_Status__c = '调拨中';
                    ihDetail_Tasd.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail_Tasd.Asset_Status__c+':'+ihDetail_Tasd.Main_Asset__c+':'+ast.Id+':'+ta.Id;
                    ihDetail_Tasd.Inventory_Header__c = ih_new.Id;
                    ihDetail_Tasd.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
                    ihDetail_Tasd.WH_location__c = ast.WH_location__c;
                    ihDetail_Tasd.Internal_asset_location__c = ast.Internal_asset_location__c;
                    ihDetail_Tasd.Amount__c = 1;
                    setMapObject(ihDetail_Tasd, ast, 'Asset');
                    setMapObject(ihDetail_Tasd, ta, 'TASD');
                    upsertMap.put(ihDetail_Tasd.UniqueKey__c, ihDetail_Tasd);

                    String uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+main_Asset_Id+':'+ast.Id;
                    Inventory_Detail__c ihDetail = upsertMap.get(uniKey);
                    
                    if (ihDetail != null) { 
                        ihDetail.Amount__c -= 1;
                        upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                    }
                }
            }
            // 待移至报废区+设置虚拟货架号 from 明细
            else if ((angecycun && TAstatusMap.get('在库').contains(ta.TAESD_Status__c))  || (!angecycun && AngecyTAstatusMap.get('在库').contains(ta.TAESD_Status__c))) {
                //if(ta.OneToOne_Flag__c == false) {
                if(ta.OneToOneAccessory__c == false){
                    String uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+main_Asset_Id+':'+ast.Id;
                    String vhwLocation = '待回库区';
                    if(ta.TAESD_Status__c == '已下架' || ta.TAESD_Status__c == '出库前检测' ){
                        vhwLocation = '备货区';
                    }
                    //设置待报废数量
                    Inventory_Detail__c ihDetail = upsertMap.get(uniKey);
                    if (ta.TAESD_Status__c == '待移至报废区' ) {
                        if (ihDetail.toAbandon_amount__c == null) {
                            ihDetail.toAbandon_amount__c = 1;
                        } else {
                            ihDetail.toAbandon_amount__c += 1;
                        }
                    }

                    ihDetail.VWH_location__c = vhwLocation;
                    upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                }
                // 一对一
                else {
                    main_Asset_Id = ta.TransferApplySummary__r.First_TAD__r.Asset__c;
                    String uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+main_Asset_Id+':'+ast.Id;
                    String vhwLocation = '待回库区';
                    if(ta.TAESD_Status__c == '已下架' || ta.TAESD_Status__c == '出库前已检测' ){
                        vhwLocation = '备货区';
                    }
                    Inventory_Detail__c ihDetail = upsertMap.get(uniKey);
                    if (ihDetail == null) {
                        ihDetail = new Inventory_Detail__c();
                        ihDetail.Asset__c = ast.Id;
                        ihDetail.OneToOne_Accsessary__c = true;
                        ihDetail.Main_Asset__c = main_Asset_Id;
                        ihDetail.Asset_Status__c = '在库';
                        ihDetail.UniqueKey__c = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+ihDetail.Asset_Status__c+':'+ihDetail.Main_Asset__c+':'+ast.Id;
                        ihDetail.Inventory_Header__c = ih_new.Id;
                        ihDetail.Fixture_Model_No__c = ast.Fixture_Model_No_F__c;
                        ihDetail.VWH_Location__c = vhwLocation;
                        ihDetail.Internal_asset_location__c = ast.Internal_asset_location__c;
                        ihDetail.Amount__c = 1;
                        setMapObject(ihDetail, ast, 'Asset');
                        ihDetail.WH_location__c = ta.TransferApplySummary__r.First_TAD__r.Asset__r.WH_location__c;
                        upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                    } else {
                        ihDetail.Amount__c += 1;
                        //ihDetail.VWH_location__c = vhwLocation;
                        upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                    }
                    uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+null+':'+ast.Id;
                    if (upsertMap.containsKey(uniKey)) {
                        Inventory_Detail__c ihDetail_org = upsertMap.get(uniKey);
                        ihDetail_org.Amount__c -= 1;
                        if (ta.TAESD_Status__c == '待移至报废区' ) {
                            if (ihDetail_org.toAbandon_amount__c == null) {
                                ihDetail_org.toAbandon_amount__c = 1;
                            } else {
                                ihDetail_org.toAbandon_amount__c += 1;
                            }
                        }
                        upsertMap.put(ihDetail_org.UniqueKey__c, ihDetail_org);
                    }
                }
            }
        }
        system.debug('==upsertMap=='+upsertMap);
        // link 一对一
        List<Fixture_OneToOne_Link__c> otoAccessoryList = 
            [select Accessory_Asset__r.Fixture_Model_No_F__c,
                    Accessory_Asset__r.Internal_asset_location__c,
                    Accessory_Asset__r.WH_location__c,
                    Main_Asset__r.WH_location__c,
                    Accessory_Asset__c,
                    Main_Asset__c,
                    Quantity__c
                from Fixture_OneToOne_Link__c
                where Accessory_Asset__r.Internal_asset_location__c=:cunFangDi
                 and Main_Asset_Status__c != '已下架'    //20210622 you 1650  备品中心已下架没有link表，办事处的已下架有link表，所以办事处的不查询这部分数据
                 and Accessory_Asset__c IN :assetList];
        system.debug('==一对一link表=='+otoAccessoryList.size());
        for (Fixture_OneToOne_Link__c odl : otoAccessoryList) {
            Asset ast = assetMap.get(odl.Accessory_Asset__c);
            String main_Asset_Id = odl.Main_Asset__c;
            String uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+main_Asset_Id+':'+ast.Id;
            Inventory_Detail__c ihDetail = upsertMap.get(uniKey);
            if (ihDetail == null) {
                ihDetail = new Inventory_Detail__c();
                ihDetail.Asset__c = ast.Id;
                ihDetail.Asset_Status__c = '在库';
                ihDetail.Inventory_Header__c = ih_new.Id;
                ihDetail.UniqueKey__c = uniKey;
                ihDetail.OneToOne_Accsessary__c = true;
                ihDetail.Main_Asset__c = main_Asset_Id;
                ihDetail.Fixture_Model_No__c = odl.Accessory_Asset__r.Fixture_Model_No_F__c;
                ihDetail.Internal_asset_location__c = odl.Accessory_Asset__r.Internal_asset_location__c;
                ihDetail.Amount__c = odl.Quantity__c;
                setMapObject(ihDetail, ast, 'Asset');
                ihDetail.WH_location__c = odl.Main_Asset__r.WH_location__c;
                ihDetail.Fixture_OneToOne_Link__c = odl.Id;
                upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
                system.debug('==没有创建在库=='+uniKey+'==在库数量-=='+ihDetail.Amount__c);
            } else {
                ihDetail.Amount__c += odl.Quantity__c;
                system.debug('有在库=='+uniKey+'==在库数量-=='+ihDetail.Amount__c);
                upsertMap.put(ihDetail.UniqueKey__c, ihDetail);
            }
            uniKey = ih_new.Id+':'+ast.Fixture_Model_No_F__c+':'+'在库'+':'+null+':'+ast.Id;
            if (upsertMap.containsKey(uniKey)) {//集中：跟主机在一起的附属品 剩下的是单独的附属品
                Inventory_Detail__c ihDetail_org = upsertMap.get(uniKey);
                ihDetail_org.Amount__c -= odl.Quantity__c;
                system.debug('有在库的要减掉'+ihDetail_org.Amount__c);
                upsertMap.put(ihDetail_org.UniqueKey__c, ihDetail_org);
            } 
        }
        system.debug('===目前upsertMap==='+upsertMap);
        //check amount
        Set<Id> asstIdSet = new Set<Id>();
        List<Inventory_Detail__c> upsertDetailList = new List<Inventory_Detail__c>();
        for (String uniKey: upsertMap.keySet()) {
            Inventory_Detail__c upsertDetail = upsertMap.get(uniKey);
            if (upsertDetail.Amount__c >= 0) {
                upsertDetailList.add(upsertDetail);
                // 收集所有在库的一对一主体Asset
                if (upsertDetail.OneToOne_Body__c && upsertDetail.Amount__c > 0 && upsertDetail.Asset_Status__c == '在库') {
                    availableMain.add(upsertDetail.Main_Asset__c);
                    if (String.isBlank(upsertDetail.VWH_location__c)) availableMainOnStock.add(upsertDetail.Main_Asset__c);
                }
            }
            if (upsertDetail.Amount__c < 0) {
                asstIdSet.add(upsertDetail.Asset__c);
                //error
                this.emailMessages.add('保有设备：'+upsertDetail.Fixture_Model_No__c + '(' + upsertDetail.Asset__c + ')的' + Inventory_Detail__c.Fields.Amount__c.getDescribe().getLabel() + ' < 0');
                //failedCount ++;
            }
        }
        system.debug('=upsertDetailList=='+upsertDetailList);
        system.debug('=availableMain=='+availableMain);
        system.debug('=availableMainOnStock=='+availableMainOnStock);
        // 处理找不到主体的一对一附属品
        for (Inventory_Detail__c idc : upsertDetailList) {
            system.debug('=idc.OneToOne_Accsessary__c=='+idc.OneToOne_Accsessary__c+'==idc.Main_Asset__c=='+idc.Main_Asset__c+'==idc.Fixture_OneToOne_Link__c=='+idc.Fixture_OneToOne_Link__c);
            if (idc.OneToOne_Accsessary__c) {
                // 一对一附属品，并且对应的主体不是在库状态。
                if (!availableMain.contains(idc.Main_Asset__c) ||
                        // 一对一附属品在借出明细里，主机单独上架了
                        (availableMainOnStock.contains(idc.Main_Asset__c) && String.isBlank(idc.Fixture_OneToOne_Link__c))) {

                    String uKey = idc.UniqueKey__c;
                system.debug('=一开始的uKey=='+uKey);
                    List<String> parts = uKey.split(':');
                    parts[3] = 'null';
                    uKey = String.join(parts, (':'));
                    // 把集中库存的的数量加回去
                    Inventory_Detail__c ihDetail_org = upsertMap.get(uKey);
                    if (ihDetail_org != null) {
                        ihDetail_org.Amount__c += idc.Amount__c;
                        system.debug(' 把集中库存的的数量加回去'+ihDetail_org.Amount__c+'=uKey=='+uKey);
                        upsertMap.put(ihDetail_org.UniqueKey__c, ihDetail_org);
                        upsertMap.put(idc.UniqueKey__c, null);
                    } else {
                        //个体一对一附属品的话，清除一对一状态。
                        if (idc.Manage_type__c == FixtureUtil.managetypeMap.get(FixtureUtil.Managetype.Ge_Ti_Guan_Li)) {
                            upsertMap.put(idc.UniqueKey__c, null);
                            idc.UniqueKey__c = uKey;
                            idc.OneToOne_Accsessary__c = false;
                            upsertMap.put(idc.UniqueKey__c, idc);
                        } else {
                            this.emailMessages.add('不整合一对一数据：UniqueKey(' + idc.UniqueKey__c + ')');
                        } 
                    }
                }
            }
        }

        // 重新做成upsertlist
        upsertDetailList = new List<Inventory_Detail__c>();
        for (String uniKey: upsertMap.keySet()) {
            Inventory_Detail__c upsertDetail = upsertMap.get(uniKey);
            if (upsertDetail != null && upsertDetail.Amount__c >= 0) {
                upsertDetailList.add(upsertDetail);
            }
        }

        List<Database.UpsertResult> upResult = Database.upsert(upsertDetailList, Inventory_Detail__c.Fields.UniqueKey__c, false);
        this.emailMessages = FixtureUtil.setUpstError(upResult, Inventory_Detail__c.sObjectType, upsertDetailList, this.emailMessages);
        for (Integer i = 0; i < upResult.size(); i++) {
            Database.UpsertResult sr = upResult[i];
            if (!sr.isSuccess()) {
                Inventory_Detail__c iobj = upsertDetailList[i];
                asstIdSet.add(iobj.Asset__c);
            }
        }
        //upsert upsertDetailList UniqueKey__c;

        failedCount += asstIdSet.size();
    } catch(Exception e) {
        Database.rollback(sp);
        System.debug(LoggingLevel.ERROR, + e.getMessage() + '\n' + e.getStackTraceString());
        this.emailMessages.add(ihList[0].Name  + ' 备品盘点开始处理 Exception:' + e.getMessage() + '\n' + e.getStackTraceString());
    }
        executedCount += assetList.size();
    }

    global void finish(Database.BatchableContext BC) {
        Inventory_Header__c iheader = [select Id, Inventory_Status__c, Name, Internal_asset_location__c, Inventory_Start_Date__c,InventoryCheck_PIC__r.Email,InventoryCheck_PIC__c,InventoryCheck_PIC__r.IsActive,Jingli_Equipment_Id__c,Jingli_Equipment__r.IsActive,Buzhang_Equipment_Id__c,Buzhang_Equipment__r.IsActive,InventorySubmit_PIC__c,Zongjian_Equipment__c,Zongjian_Equipment__r.IsActive from Inventory_Header__c where Id = :ih_new.Id];
        String text = '';
        try {
            if (this.emailMessages.size() == 0 && totalCount == executedCount) {
            
                text = '备品盘点报告书编号：' + iheader.Name + '  盘点地点：' + iheader.Internal_asset_location__c + '  盘点开始日：' + iheader.Inventory_Start_Date__c;
                if(cunFangDi == '上海 备品中心'){
                    text += '\n备品盘点batch已结束，请等待耗材盘点batch结束。';
                    ConsumInventoryStartAssetSnapshotBatch consumIstarter = new ConsumInventoryStartAssetSnapshotBatch(cunFangDi, iheader);
                    Database.executeBatch(consumIstarter, 100);
                }
                else{
                    iheader.Inventory_Status__c = '盘点中';
                    update iheader;
                    text += '\n可以开始备品盘点。';
                }
            } else {
                text = '备品盘点报告书编号：' + iheader.Name + '  盘点地点：' + iheader.Internal_asset_location__c + '  盘点开始日：' + iheader.Inventory_Start_Date__c;
                text += '\n开始盘点 处理失败。';
//                delete iheader;
            }
        } catch (Exception e) {
            system.debug('Exception=='+e);
            this.emailMessages.add(e.getMessage());
        }
        //20210628 1650 you 盘点表头共享给盘点报告确认人
        List<Inventory_Header__Share> shareList = new List<Inventory_Header__Share>();
        if(null!=iheader.InventoryCheck_PIC__c && iheader.InventoryCheck_PIC__c != iheader.InventorySubmit_PIC__c && iheader.InventoryCheck_PIC__r.IsActive==true){
             Inventory_Header__Share xmshare=new Inventory_Header__Share();
             xmshare.RowCause = 'Manual';
             xmshare.UserOrGroupId=iheader.InventoryCheck_PIC__c;
             xmshare.ParentId=iheader.Id;
             xmshare.AccessLevel='Edit'; 
             system.debug('zheli1'+iheader.id+'=='+xmshare); 
             shareList.add(xmshare);
        }
         
         if(null!=iheader.Jingli_Equipment_Id__c && iheader.Jingli_Equipment_Id__c != iheader.InventoryCheck_PIC__c && iheader.Jingli_Equipment__r.IsActive==true){
            Inventory_Header__Share xmshare1=new Inventory_Header__Share();
             xmshare1.RowCause = 'Manual';
             xmshare1.UserOrGroupId=iheader.Jingli_Equipment_Id__c;
             xmshare1.ParentId=iheader.Id;
             xmshare1.AccessLevel='Edit'; 
             system.debug('zheli2'+iheader.id+'=='+xmshare1); 
             shareList.add(xmshare1);
         } 
         system.debug('我在这里呀'+iheader.Buzhang_Equipment__r.IsActive +'===='+iheader.Jingli_Equipment__r.IsActive);
         if(null!=iheader.Buzhang_Equipment_Id__c && iheader.Buzhang_Equipment_Id__c != iheader.Jingli_Equipment_Id__c && iheader.Buzhang_Equipment__r.IsActive==true){
            Inventory_Header__Share xmshare2=new Inventory_Header__Share();
             xmshare2.RowCause = 'Manual';
             xmshare2.UserOrGroupId=iheader.Buzhang_Equipment_Id__c;
             xmshare2.ParentId=iheader.Id;
             xmshare2.AccessLevel='Edit'; 
             system.debug('zheli3'+iheader.id+'=='+xmshare2); 
             shareList.add(xmshare2);
         } 
         if(null!=iheader.Zongjian_Equipment__c && iheader.Zongjian_Equipment__c != iheader.Buzhang_Equipment_Id__c && iheader.Zongjian_Equipment__r.IsActive==true){
            Inventory_Header__Share xmshare3=new Inventory_Header__Share();
             xmshare3.RowCause = 'Manual';
             xmshare3.UserOrGroupId=iheader.Zongjian_Equipment__c;
             xmshare3.ParentId=iheader.Id;
             xmshare3.AccessLevel='Edit'; 
             system.debug('zheli4'+iheader.id+'=='+iheader.Zongjian_Equipment__c); 
             shareList.add(xmshare3);
         } 
         if(null !=shareList && shareList.size()>0  && (cunFangDi !='上海 备品中心' && cunFangDi !='广州 备品中心' && cunFangDi!='北京 备品中心')){
            insert shareList;
         }
         InventoryStartAssetSnapshotBatch.messagesForTest = this.emailMessages;
        // 发 mail
        String InventoryCheck_PIC_email = iheader.InventoryCheck_PIC__r.Email;
        BatchEmailUtil be = new BatchEmailUtil();
        String[] toList = new String[]{UserInfo.getUserEmail()};
        String title = '开始备品盘点';
        String[] ccList = new String[]{};
        for(String email : System.Label.Inventory_Result_Email.split(',')){
            ccList.add(email);
        } 
        system.debug('盘点报告确认人'+InventoryCheck_PIC_email);
        if(InventoryCheck_PIC_email != null){
           ccList.add(InventoryCheck_PIC_email); 
        }
         
        if(this.emailMessages.size() == 0 && totalCount == executedCount) {
            be.successMail(toList,ccList, title, totalCount, text);
        }else{
            String emailLabel = 'BatchNotify';
            for (OrgWideEmailAddress tmpEmailObj : [SELECT Id, Address, DisplayName 
                    FROM OrgWideEmailAddress
                    WHERE DisplayName like :emailLabel]) {
                ccList.add(tmpEmailObj.Address);
            }
            if (totalCount != executedCount) {
                this.emailMessages.add('有一部分Batch没有运行, 请确认系统管理员。');
            }
            be.failedMail(toList, ccList, title,
                    String.join(this.emailMessages, '\n'),
                    totalCount, executedCount, failedCount);
        }
        be.send();

    }

    private void setMapObject(Inventory_Detail__c idetail, sObject obj, String typeStr) {
        List<String> fromCol;
        List<String> toCol;
        if (typeStr == 'Asset') {
            fromCol = new List<String>(assetFieldMap.keySet());//原表字段API名
            toCol = assetFieldMap.values();//盘点表明细字段API名
        } else if (typeStr == 'Repair') {//维修
            fromCol = new List<String>(repairFieldMap.keySet());
            toCol = repairFieldMap.values();
        } else if (typeStr == 'TASD') {//调拨明细
            fromCol = new List<String>(TasdFieldMap.keySet());
            toCol = TasdFieldMap.values();
        } else {//申请明细
            fromCol = new List<String>(raesdFieldMap.keySet());
            toCol = raesdFieldMap.values();
        }

        for (Integer i = 0; i < fromCol.size(); i++) {
            List<String> cols = fromCol[i].split('\\.');//例如存在字段 Rental_Apply__r.Name
            idetail.put(toCol[i], CreateRelationListPagingCmpCtrl.getObjectValue(obj, cols));//盘点明细字段api，对应的数据
        }
    }

    //TODO error
    //@TestVisible
    //private Integer setUpstError(List<Database.UpsertResult> srList, Schema.sObjectType obj
    //        , List<SObject> upsList) {
    //    Integer errorCnt = 0;
    //    List<String> errMsgList = new List<String>();
    //    String objectName = obj.getDescribe().getName();
    //    String objectLabel = obj.getDescribe().getLabel();
    //    for (Integer i = 0; i < srList.size(); i++) {
    //        SObject eObj = upsList[i];
    //        Database.UpsertResult sr = srList[i];
    //        if (!sr.isSuccess()) {
    //            errorCnt++;
    //            for (Database.Error err : sr.getErrors()) {
    //                String message = objectLabel + ':'
    //                        + objectName + '=' + eObj.get('Name')
    //                        + ', ' + err.getStatusCode() + ':' + err.getMessage()
    //                        + ((err.getFields() != null && err.getFields().size() > 0) ? ', Field:' + String.valueOf(err.getFields()) : '');
    //                this.emailMessages.add(message);
    //            }
    //        }
    //    }
    //    return errorCnt;
    //}
    ////TODO error
    //@TestVisible
    //private Integer setSaveError(List<Database.SaveResult> srList, Schema.sObjectType obj
    //        , List<SObject> upsList) {
    //    Integer errorCnt = 0;
    //    String objectName = obj.getDescribe().getName();
    //    String objectLabel = obj.getDescribe().getLabel();
    //    for (Integer i = 0; i < srList.size(); i++) {
    //        SObject eObj = upsList[i];
    //        Database.SaveResult sr = srList[i];
    //        if (!sr.isSuccess()) {
    //            errorCnt++;
    //            for (Database.Error err : sr.getErrors()) {
    //                String message = objectLabel + ':'
    //                        + objectName + '=' + eObj.get('Name')
    //                        + ', ' + err.getStatusCode() + ':' + err.getMessage()
    //                        + ((err.getFields() != null && err.getFields().size() > 0) ? ', Field:' + String.valueOf(err.getFields()) : '');
    //                this.emailMessages.add(message);
    //            }
    //        } 
    //    }
    //    return errorCnt;
    //}
    @TestVisible private static void test() {
        Integer i = 0;
        i++;
        i++;
        i++;//可以多写点
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
         i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
               i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
      }
}