/*  $Id: CreateRelationListPagingExtend.cls 2017-08-29 11:33:00Z ume $
 *  TextClass:FixtureUtilTest
              RentalFixtureManage1Test
              RentalFixtureManage3Test
              RentalFixtureManage4Test
              RentalFixtureManage5Test
              RentalFixtureManage7Test
              RentalFixtureManage8Test
              RentalFixtureManage12Test
              RentalFixtureManage13Test
 *
 *  共通拡張クラス
 *
 *  已借出         ....已完成
 *  有效库存       ....已完成
 *  附属品分配状态  ....已完成
 *  主体分配状态    ....已完成
 *  可以分配主体    ....已完成
 *  排队           ....已完成
 *  累计借出数      ....已完成
 *
 *  别本部库存      ....已完成
 *  别省库存        ....已完成
 *  别用途库存      ....已完成  TestClass
 *  代替品库存     ....表结构确认 ... いらない
 *
 */
global without sharing class FixtureUtil {

    @TestVisible
    private static Set<String> getCheckFields(List<SObject> os) {
        Set<String> result = new Set<String>();
        for (SObject o : os) {
            result.addAll(o.getPopulatedFieldsAsMap().keySet());
        }
        return result;
    }

    // 需要条件的本部
    public static Set<String> needSalesdepartment = new Set<String> {
        '9.MA本部',
        '11.医疗产品培训本部'
    };

    // OLY_OCM-659 bieBenBuOpsQuan中除了'9.MA本部'和'11.医疗产品培训本部'以外的本部 Start
    public static String otherBenbus = '(\'0.备品中心\', \'1.华北营业本部\', \'2.东北营业本部\', \'3.西北营业本部\', \'4.华东营业本部\', \'5.华南营业本部\', \'6.西南营业本部\', \'7.GIR市场本部\', \'8.SP市场本部\', \'10.服务本部\', \'12.能量事业本部\')';
    // OLY_OCM-659 bieBenBuOpsQuan中除了'9.MA本部'和'11.医疗产品培训本部'以外的本部 End

    // 申请书使用目的2 选择列表内容
    public static Map<String, String> raDemo_purpose2MAP = new Map<String, String> {
        'shiyongwuxunjia' => '试用（无询价）',
        'shiyongyouxunjia' => '试用（有询价）',
        'xinchanpinpingjia' => '新产品评价',
        'xuehuizhanhui' => '学会展会',
        'yigoudaihuo' => '已购待货',
        'suopeiQIS' => '索赔QIS',
        'zaixiuli' => '再修理',
        'baoxiuyonghu' => '保修用户',
        'shichangduonianbaoxiu' => '市场多年保修',
        'yibanyonghu' => '一般用户',
        'guzhangpaicha' => '故障排查',
        'qita' => '其他',
        'linchuangyanjiu' => '临床研究',
        'xieyijieyong' => '协议借用'
    };

    //是否是Set单位
    private static Boolean isSet = false;

    //From Asset Groupby 后 汇总结果的的字段
    public static Set<String> asFs = new Set<String> {
            'Yi_Jie_Chu_Jia__c',             //已借出
            'Jie_Chu_Fen_Pei_Jia__c',        //借出分配  占坑数(不包含排队，从分配到回库的件数，取消的不算)
            'You_Xiao_Kun_Cun_Jia__c',       //有效库存
            'Ke_Yi_Fen_Pei_Zhu_Ti_Jia__c',   //可以分配主体
            'Dai_Xiu_Li_Jia__c',             //待修理
            'Bie_Cun_Fang_Di_Ku_Cun_Jia__c', //存放地
            'Bie_Sheng_Ku_Cun_Jia__c',       //别省
            'Bie_Ben_Bu_Ku_Cun_Jia__c',      //别本部
            'Bie_Yong_Tu_Ku_Cun_Jia__c',     //别用途库存
            'Bie_Chan_Pin_Fen_Lei_Jia__c',   //别产品分类
            'Zhu_Ti_Fen_Pei_Jia__c',         //主体分配
            'Fu_Shu_Pin_Fen_Pei_Jia__c'      //附属品分配状态
    };

    //From 借出備品Set Groupby 后 汇总结果的的字段
    public static Set<String> raesFs = new Set<String> {
    };

    //From 借出历史明细字段 Groupby 后 汇总结果的的字段
    public static Set<String> raesdFs = new Set<String> {
            'Pai_Dui_Jia__c',           //排队 (where modelno)
            'Lei_Ji_Jie_Chu_Shu_Jia__c' //累计借出数 + 占坑的数
            //
    };

    //From 借出历史明细字段 Groupby 后 汇总结果的的字段 Asset
    public static Set<String> raesdAssetFs = new Set<String> {
            'Lei_Ji_Jie_Chu_Shu_Asset_Jia__c' //累计借出数 + 占坑的数 AssetId
    };


    //管理种类
    public enum Managetype {
            Shu_Liang_Guan_Li,
            Ge_Ti_Guan_Li
    }

    //借出备品配套一览状態
    public enum RaStatus {
            Qu_Xiao,
            Shan_Chu,
            Wan_Liao,
            Yi_Hui_Shou,
            Yi_Hui_Ji,
            Yi_Yuan_Yi_Zhuang_Ji_Que_Ren,
            Shen_Qing_Zhe_Yi_Shou_Huo,
            Yi_Chu_Ku,
            Chu_Ku_Qian_Yi_Jian_Ce,
            Yi_Xia_Jia,
            Yi_Chu_Ku_Zhi_Shi,
            Yi_Fen_Pei,
            Qian_Pin_Zhong,
            Cao_An_Zhong,
            Tian_Xie_Wan_Bi,
            Shen_Qing_Zhong,
            Yi_Pi_Zhun
            //申请状态没有待分配
            // Dai_Fen_Pei

    }

    //借出备品配套一览状態
    public enum RaesStatus {
            Cao_An_Zhong,
            Qu_Xiao,
            Yi_Hui_Ku,
            Hui_Shou_Hou_Yi_Jian_Ce,
            Hui_Shou_Hou_Jian_Ce_NG,
            Hui_Shou_Hou_Yi_CDS,
            Yi_Hui_Shou,
            Yi_Hui_Ji,
            Yi_Yuan_Yi_Zhuang_Ji_Que_Ren,
            Shen_Qing_Zhe_Yi_Shou_Huo,
            Shen_Qing_Zhe_Shou_Huo_NG,
            Yi_Chu_Ku,
            Chu_Ku_Qian_Yi_Jian_Ce,
            Yi_Xia_Jia,
            Yi_Chu_Ku_Zhi_Shi,
            Yi_Fen_Pei,
            Dai_Fen_Pei,
            Pai_Dui_Zhong,
            Zan_Ding_Fen_Pei,
            Qian_Pin_Zhong

    }

    //借出备品配套一览明细状態
    public enum HistoryStatus {
            Qu_Xiao,
            Fei_Qi,
            Yi_Hui_Ku,
            Dai_Shang_Jia,
            Hui_Shou_Hou_Yi_CDS,
            Yi_Hui_Shou,
            Yi_Hui_Ji,
            Yi_Yuan_Yi_Zhuang_Ji_Que_Ren,
            Shen_Qing_Zhe_Yi_Shou_Huo,
            Shen_Qing_Zhe_Shou_Huo_NG,
            Yi_Chu_Ku,
            Chu_Ku_Qian_Yi_Jian_Ce,
            Yi_Xia_Jia,
            Yi_Chu_Ku_Zhi_Shi,
            Yi_Fen_Pei,
            Dai_Fen_Pei,
            Qian_Pin_Zhong,
            Yi_Xiao_Hao,
            Diu_Shi,
            Dai_Fei_Qi,
            Yi_Zhi_Bao_Fei_Qu,
            Pai_Dui_Zhong,
            Zan_Ding_Fen_Pei,
            Dai_Xiu_Li,
            Xiu_Li_Zhong
    }

    //備品状態
    public enum AssetStatus {
            // Mei_You_Ku_Cun,
            // Ke_Yi_Fen_Pei,
            // Bu_Fen_Mei_You,
            // Yi_Fen_Pei,
            // Yi_Xiao_Hao,
            // Diu_Shi,
            Fei_Qi,
            Dai_Fei_Qi
    }

    //備品状態F
    public enum AssetFixtureStatus {
            Mei_You_Ku_Cun,
            Ke_Yi_Fen_Pei,
            Bu_Fen_Mei_You,
            Yi_Fen_Pei,
            Dai_Fei_Qi,
            Yi_Xiao_Hao,
            Fei_Qi,
            Diu_Shi,
            Xiu_Li_Zhong,
            Xiu_Li_Cao_An_Zhong,
            Dong_Jie,
            // BP3 功能②:盘点报告 新追加
            Yi_Guo_Qi,
            Wu_Bao_You,
            Zan_Ding_Fen_Pei,
            Yi_Chu_Ku_Zhi_Shi,
            Yi_Xia_Jia,
            Chu_Ku_Qian_Yi_Jian_Ce,
            Yi_Hui_Shou,
            Hui_Shou_Hou_Yi_CDS,
            Dai_Shang_Jia,
            Yi_Zhi_Bao_Fei_Qu,
            Yi_Chu_Ku,
            Shen_Qing_Zhe_Yi_Shou_Huo,
            Shen_Qing_Zhe_Shou_Huo_NG,
            Yi_Yuan_Yi_Zhuang_Ji_Que_Ren,
            Yi_Hui_Ji,
            Qian_Pin_Zhong,
            Dai_Xiu_Li
    }

    // 收货清单状态
    public enum RNStatus {
            Dai_Shu_Ju_Que_Ren,
            Yi_Shu_Ju_Que_Ren,
            Yi_Shou_Huo_Que_Ren,
            Yi_Qing_Dian,
            Yi_Yan_Shou,
            Dai_Ru_Ku_Zhi_Shi,
            Yi_Ru_Ku_Zhi_Shi,
            Yi_Ru_Ku,
            Yi_Jian_Ce
    }

    // 收货清单配套一览
    public enum RNSStatus {
            Dai_Shu_Ju_Que_Ren,
            Yi_Shu_Ju_Que_Ren,
            Yi_Shou_Huo_Que_Ren,
            Yi_Qing_Dian,
            Yi_Yan_Shou,
            Yi_Jian_Ce,
            Dai_Ru_Ku_Zhi_Shi,
            Yi_Ru_Ku_Zhi_Shi,
            Yi_Ru_Ku
    }

    // 收货清单配套一览明细
    public enum RNDStatus {
            Dai_Shu_Ju_Que_Ren,
            Yi_Shu_Ju_Que_Ren,
            Yi_Shou_Huo_Que_Ren,
            Yi_Qing_Dian,
            Yi_Yan_Shou,
            Dai_Ru_Ku_Zhi_Shi,
            Yi_Ru_Ku_Zhi_Shi,
            Yi_Ru_Ku,
            Jian_Ce_NG,
            Qing_Dian_NG,
            Yan_Shou_NG,
            Yi_Jian_Ce
    }

    public static Date today {get {return today == null ? Date.today() : today;} set;}

    public static DateTime now {get {return now == null ? DateTime.now() : now;} set;}

    //管理种类Map
    public static Map<Managetype, String> managetypeMap = new Map<Managetype, String> {
            Managetype.Shu_Liang_Guan_Li  => '数量管理',
            Managetype.Ge_Ti_Guan_Li      => '个体管理'
    };

    // 收货清单状态Map
    public static Map<Integer, String> RNStatusMap = new Map<Integer, String> {
        RNStatus.Dai_Shu_Ju_Que_Ren.ordinal()  => '待数据确认',
        RNStatus.Yi_Shu_Ju_Que_Ren.ordinal()   => '已数据确认',
        RNStatus.Yi_Shou_Huo_Que_Ren.ordinal() => '已收货确认',
        RNStatus.Yi_Qing_Dian.ordinal()        => '已清点',
        RNStatus.Yi_Yan_Shou.ordinal()         => '已验收',
        RNStatus.Yi_Jian_Ce.ordinal()          => '已检测',
        RNStatus.Dai_Ru_Ku_Zhi_Shi.ordinal()   => '待入库指示',
        RNStatus.Yi_Ru_Ku_Zhi_Shi.ordinal()    => '已入库指示',
        RNStatus.Yi_Ru_Ku.ordinal()            => '已入库'
    };

    // 收货清单配套一览状态Map
    public static Map<Integer, String> RNSStatusMap = new Map<Integer, String> {
        RNSStatus.Dai_Shu_Ju_Que_Ren.ordinal()  => '待数据确认',
        RNSStatus.Yi_Shu_Ju_Que_Ren.ordinal()   => '已数据确认',
        RNSStatus.Yi_Shou_Huo_Que_Ren.ordinal() => '已收货确认',
        RNSStatus.Yi_Qing_Dian.ordinal()        => '已清点',
        RNSStatus.Yi_Yan_Shou.ordinal()         => '已验收',
        RNSStatus.Yi_Jian_Ce.ordinal()          => '已检测',
        RNSStatus.Dai_Ru_Ku_Zhi_Shi.ordinal()   => '待入库指示',
        RNSStatus.Yi_Ru_Ku_Zhi_Shi.ordinal()    => '已入库指示',
        RNSStatus.Yi_Ru_Ku.ordinal()            => '已入库'
    };

    // 收货清单配套一览明细状态Map
    public static Map<Integer, String> RNDStatusMap = new Map<Integer, String> {
        RNDStatus.Dai_Shu_Ju_Que_Ren.ordinal()  => '待数据确认',
        RNDStatus.Yi_Shu_Ju_Que_Ren.ordinal()   => '已数据确认',
        RNDStatus.Yi_Shou_Huo_Que_Ren.ordinal() => '已收货确认',
        RNDStatus.Yi_Qing_Dian.ordinal()        => '已清点',
        RNDStatus.Yi_Yan_Shou.ordinal()         => '已验收',
        RNDStatus.Yi_Jian_Ce.ordinal()          => '已检测',
        RNDStatus.Dai_Ru_Ku_Zhi_Shi.ordinal()   => '待入库指示',
        RNDStatus.Yi_Ru_Ku_Zhi_Shi.ordinal()    => '已入库指示',
        RNDStatus.Yi_Ru_Ku.ordinal()            => '已入库',
        RNDStatus.Qing_Dian_NG.ordinal()        => '清点NG',
        RNDStatus.Yan_Shou_NG.ordinal()         => '验收NG'
    };

    //备品借出申请
    //RA_Status__c
    public static Map<Integer, String> raStatusMap = new Map<Integer, String> {
            RaStatus.Qu_Xiao.ordinal()                        => '取消',
            RaStatus.Shan_Chu.ordinal()                       => '删除',
            RaStatus.Wan_Liao.ordinal()                       => '完了', //全部已回库的意思
            RaStatus.Yi_Hui_Shou.ordinal()                    => '已回收',
            RaStatus.Yi_Hui_Ji.ordinal()                      => '已回寄', //old:'归还发送完了',
            RaStatus.Yi_Yuan_Yi_Zhuang_Ji_Que_Ren.ordinal()   => '医院已装机确认', //old:'医院收到确认完了',
            RaStatus.Shen_Qing_Zhe_Yi_Shou_Huo.ordinal()      => '申请者已收货', //old:'申请者收到确认完了',
            RaStatus.Yi_Chu_Ku.ordinal()                      => '已出库', //old:'出库完了',
            RaStatus.Chu_Ku_Qian_Yi_Jian_Ce.ordinal()         => '出库前已检测', //old:'出库前检查完了',
            RaStatus.Yi_Xia_Jia.ordinal()                     => '已下架', //old:'下架完了',
            RaStatus.Yi_Chu_Ku_Zhi_Shi.ordinal()              => '已出库指示', //old:'出库指示完了',
            RaStatus.Yi_Fen_Pei.ordinal()                     => '已分配',
            RaStatus.Qian_Pin_Zhong.ordinal()                 => '欠品中', //欠品确认中
            RaStatus.Cao_An_Zhong.ordinal()                   => '草案中',
            RaStatus.Tian_Xie_Wan_Bi.ordinal()                => '填写完毕',
            RaStatus.Shen_Qing_Zhong.ordinal()                => '申请中',
            RaStatus.Yi_Pi_Zhun.ordinal()                     => '已批准' //old:'批准完了',
            //申请状态没有待分配
            // RaStatus.Dai_Fen_Pei.ordinal()                   => '待分配'
    };

    //借出备品配套一览状態
    //RAES_Status__c
    public static Map<Integer, String> raesStatusMap = new Map<Integer, String> {
            RaesStatus.Cao_An_Zhong.ordinal()                 => '草案中',
            RaesStatus.Qu_Xiao.ordinal()                      => '取消',
            RaesStatus.Yi_Hui_Ku.ordinal()                    => '已回库', //old:'上架完了',
            RaesStatus.Hui_Shou_Hou_Yi_Jian_Ce.ordinal()      => '回收后已检测', //old:'归还后检查完了',
            RaesStatus.Hui_Shou_Hou_Jian_Ce_NG.ordinal()      => '回收后检测NG',   //old:'回收后检查NG'
            RaesStatus.Hui_Shou_Hou_Yi_CDS.ordinal()          => '回收后已CDS', //old:'归还后CDS完了',
            RaesStatus.Yi_Hui_Shou.ordinal()                  => '已回收',
            RaesStatus.Yi_Hui_Ji.ordinal()                    => '已回寄', //old:'归还发送完了',
            RaesStatus.Yi_Yuan_Yi_Zhuang_Ji_Que_Ren.ordinal() => '医院已装机确认', //old:'医院收到确认完了',
            RaesStatus.Shen_Qing_Zhe_Yi_Shou_Huo.ordinal()    => '申请者已收货', //old:'申请者收到确认完了',
            RaesStatus.Shen_Qing_Zhe_Shou_Huo_NG.ordinal()    => '申请者收货NG',
            RaesStatus.Yi_Chu_Ku.ordinal()                    => '已出库', //old:'出库完了',
            RaesStatus.Chu_Ku_Qian_Yi_Jian_Ce.ordinal()       => '出库前已检测', //old:'出库前检查完了',
            RaesStatus.Yi_Xia_Jia.ordinal()                   => '已下架', //old:'下架完了',
            RaesStatus.Yi_Chu_Ku_Zhi_Shi.ordinal()            => '已出库指示', //old:'出库指示完了',
            RaesStatus.Yi_Fen_Pei.ordinal()                   => '已分配',
            RaesStatus.Dai_Fen_Pei.ordinal()                  => '待分配',
            RaesStatus.Pai_Dui_Zhong.ordinal()                => '排队中',
            RaesStatus.Zan_Ding_Fen_Pei.ordinal()             => '暂定分配',
            RaesStatus.Qian_Pin_Zhong.ordinal()               => '欠品中'
    };

    //ヒストリ状態
    //RAESD_Status_F__c
    public static Map<Integer, String> raesdStatusMap = new Map<Integer, String> {
            HistoryStatus.Qu_Xiao.ordinal()                       => '取消',
            HistoryStatus.Fei_Qi.ordinal()                        => '废弃',
            HistoryStatus.Yi_Hui_Ku.ordinal()                     => '已回库', //old:'上架完了',
            HistoryStatus.Dai_Shang_Jia.ordinal()                 => '待上架',
            HistoryStatus.Hui_Shou_Hou_Yi_CDS.ordinal()           => '回收后已CDS', //old:'归还后CDS完了',
            HistoryStatus.Yi_Hui_Shou.ordinal()                   => '已回收',
            HistoryStatus.Yi_Hui_Ji.ordinal()                     => '已回寄', //old:'归还发送完了',
            HistoryStatus.Yi_Yuan_Yi_Zhuang_Ji_Que_Ren.ordinal()  => '医院已装机确认', //old:'医院收到确认完了',
            HistoryStatus.Shen_Qing_Zhe_Shou_Huo_NG.ordinal()     => '申请者收货NG',
            HistoryStatus.Shen_Qing_Zhe_Yi_Shou_Huo.ordinal()     => '申请者已收货', //old:'申请者收到确认完了',
            HistoryStatus.Yi_Chu_Ku.ordinal()                     => '已出库', //old:'出库完了',
            HistoryStatus.Chu_Ku_Qian_Yi_Jian_Ce.ordinal()        => '出库前已检测', //old:'出库前检查完了',
            HistoryStatus.Yi_Xia_Jia.ordinal()                    => '已下架', //old:'下架完了',
            HistoryStatus.Yi_Chu_Ku_Zhi_Shi.ordinal()             => '已出库指示', //old:'出库指示完了',
            HistoryStatus.Yi_Fen_Pei.ordinal()                    => '已分配',
            HistoryStatus.Dai_Fen_Pei.ordinal()                   => '待分配',
            HistoryStatus.Qian_Pin_Zhong.ordinal()                => '欠品中',
            HistoryStatus.Yi_Xiao_Hao.ordinal()                   => '已消耗',
            HistoryStatus.Diu_Shi.ordinal()                       => '丢失',
            HistoryStatus.Dai_Fei_Qi.ordinal()                    => '待废弃',
            HistoryStatus.Yi_Zhi_Bao_Fei_Qu.ordinal()             => '待移至报废区',
            HistoryStatus.Pai_Dui_Zhong.ordinal()                 => '排队中',
            HistoryStatus.Zan_Ding_Fen_Pei.ordinal()              => '暂定分配',
            HistoryStatus.Dai_Xiu_Li.ordinal()                    => '待修理',
            HistoryStatus.Xiu_Li_Zhong.ordinal()                  => '修理中'
    };

    //Asset 状態
    //OLY_OCM-56
    public static Map<Integer, String> assetStatusMap = new Map<Integer, String> {
           // AssetStatus.Mei_You_Ku_Cun.ordinal() => '无库存',
           // AssetStatus.Ke_Yi_Fen_Pei.ordinal()  => '可分配',
           // AssetStatus.Bu_Fen_Mei_You.ordinal() => '部分没有',
           // AssetStatus.Yi_Fen_Pei.ordinal()     => '已分配',
           // AssetStatus.Diu_Shi.ordinal()        => '丢失',
           // AssetStatus.Yi_Xiao_Hao.ordinal()    => '消耗',
            AssetStatus.Dai_Fei_Qi.ordinal()     => '待报废', // 因为怕印象本番所以不修改    new:待废弃
            AssetStatus.Fei_Qi.ordinal()         => '廃棄'  // 因为怕印象本番所以不修改    new:废弃
    };

    //Asset 状態
    //OLY_OCM-56
    public static Map<Integer, String> assetFixtureStatusMap = new Map<Integer, String> {
            AssetFixtureStatus.Mei_You_Ku_Cun.ordinal()        => '无库存',
            AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal()         => '可分配',
            AssetFixtureStatus.Bu_Fen_Mei_You.ordinal()        => '部分没有',
            AssetFixtureStatus.Yi_Fen_Pei.ordinal()            => '已分配',  //
            AssetFixtureStatus.Xiu_Li_Zhong.ordinal()          => '修理中',
            AssetFixtureStatus.Xiu_Li_Cao_An_Zhong.ordinal()   => '修理草案中',
            AssetFixtureStatus.Diu_Shi.ordinal()               => '丢失',
            AssetFixtureStatus.Yi_Xiao_Hao.ordinal()           => '消耗',
            AssetFixtureStatus.Dong_Jie.ordinal()              => '冻结',
            AssetFixtureStatus.Dai_Fei_Qi.ordinal()            => '待废弃', // 画面上显示内容
            AssetFixtureStatus.Fei_Qi.ordinal()                => '废弃',  // 画面上显示内容
            AssetFixtureStatus.Yi_Guo_Qi.ordinal()             => '已过期',
            AssetFixtureStatus.Wu_Bao_You.ordinal()            => '无保有',
            AssetFixtureStatus.Zan_Ding_Fen_Pei.ordinal()      => '暂定分配',
            AssetFixtureStatus.Yi_Chu_Ku_Zhi_Shi.ordinal()     => '已出库指示',
            AssetFixtureStatus.Yi_Xia_Jia.ordinal()            => '已下架',
            AssetFixtureStatus.Chu_Ku_Qian_Yi_Jian_Ce.ordinal()=> '出库前已检测',
            AssetFixtureStatus.Yi_Hui_Shou.ordinal()           => '已回收',
            AssetFixtureStatus.Hui_Shou_Hou_Yi_CDS.ordinal()   => '回收后已CDS',
            AssetFixtureStatus.Dai_Shang_Jia.ordinal()         => '待上架',
            AssetFixtureStatus.Yi_Zhi_Bao_Fei_Qu.ordinal()     => '待移至报废区',
            AssetFixtureStatus.Yi_Chu_Ku.ordinal()             => '已出库',
            AssetFixtureStatus.Shen_Qing_Zhe_Yi_Shou_Huo.ordinal()   => '申请者已收货',
            AssetFixtureStatus.Shen_Qing_Zhe_Shou_Huo_NG.ordinal()   => '申请者收货NG',
            AssetFixtureStatus.Yi_Yuan_Yi_Zhuang_Ji_Que_Ren.ordinal()=> '医院已装机确认',
            AssetFixtureStatus.Yi_Hui_Ji.ordinal()                   => '已回寄',
            AssetFixtureStatus.Qian_Pin_Zhong.ordinal()              => '欠品中',
            AssetFixtureStatus.Dai_Xiu_Li.ordinal()                  => '待修理'
    };

    //本部SelectOption
    private static List<SelectOption> bieBenBuOpsBeiJin = new List<SelectOption>{
            new SelectOption('', '--全部--'),
            new SelectOption('0.备品中心', '0.备品中心'),
            new SelectOption('1.华北营业本部', '1.华北营业本部'),
            new SelectOption('2.东北营业本部', '2.东北营业本部'),
            new SelectOption('3.西北营业本部', '3.西北营业本部'),
            new SelectOption('7.GIR市场本部', '7.GIR市场本部'),
            new SelectOption('9.MA本部', '9.MA本部'),
            // 20220107 ljh update start
            // new SelectOption('10.服务本部', '10.服务本部'),
            new SelectOption('10.服务本部', '10.服务本部')
            // new SelectOption('12.能量事业本部', '12.能量事业本部')
            // 20220107 ljh update end
    };

    private static List<SelectOption> bieBenBuOpsShangHai = new List<SelectOption>{
            new SelectOption('', '--全部--'),
            new SelectOption('0.备品中心', '0.备品中心'),
            new SelectOption('4.华东营业本部', '4.华东营业本部'),
            new SelectOption('8.SP市场本部', '8.SP市场本部'),
            new SelectOption('9.MA本部', '9.MA本部'),
            new SelectOption('10.服务本部', '10.服务本部'),
            new SelectOption('11.医疗产品培训本部', '11.医疗产品培训本部'),
            // new SelectOption('12.能量事业本部', '12.能量事业本部'),// 20220107 ljh update
            new SelectOption('16.Solution本部', '16.Solution本部')
            // new SelectOption('17.市场企划本部', '17.市场企划本部')
    };

    private static List<SelectOption> bieBenBuOpsGuangZhou = new List<SelectOption>{
            new SelectOption('', '--全部--'),
            new SelectOption('0.备品中心', '0.备品中心'),
            new SelectOption('5.华南营业本部', '5.华南营业本部'),
            new SelectOption('6.西南营业本部', '6.西南营业本部'),
            // 20220107 ljh update start
            // new SelectOption('10.服务本部', '10.服务本部'),
            new SelectOption('10.服务本部', '10.服务本部')
            // new SelectOption('12.能量事业本部', '12.能量事业本部')
            // 20220107 ljh update end
    };

    private static List<SelectOption> bieBenBuOpsQuan = new List<SelectOption>{
            new SelectOption('', '--全部--'),
            new SelectOption('0.备品中心', '0.备品中心'),
            new SelectOption('1.华北营业本部', '1.华北营业本部'),
            new SelectOption('2.东北营业本部', '2.东北营业本部'),
            new SelectOption('3.西北营业本部', '3.西北营业本部'),
            new SelectOption('4.华东营业本部', '4.华东营业本部'),
            new SelectOption('5.华南营业本部', '5.华南营业本部'),
            new SelectOption('6.西南营业本部', '6.西南营业本部'),
            new SelectOption('7.GIR市场本部', '7.GIR市场本部'),
            new SelectOption('8.SP市场本部', '8.SP市场本部'),
            new SelectOption('9.MA本部', '9.MA本部'),
            new SelectOption('10.服务本部', '10.服务本部'),
            new SelectOption('11.医疗产品培训本部', '11.医疗产品培训本部'),
            // new SelectOption('12.能量事业本部', '12.能量事业本部'),20220107 ljh update
            new SelectOption('16.Solution本部', '16.Solution本部')
            // new SelectOption('17.市场企划本部', '17.市场企划本部')
    };

    //本部SelectOptionMap
    public static Map<String, List<SelectOption>> bieBenBuOpsMap = new Map<String, List<SelectOption>> {
            '北京 备品中心' => bieBenBuOpsBeiJin,
            '广州 备品中心' => bieBenBuOpsGuangZhou,
            '上海 备品中心' => bieBenBuOpsShangHai,
            'All'        => bieBenBuOpsQuan
    };

    public static  Map<String,String> locationMap = new Map<String,String>{
            '北京 备品中心' => System.Label.BeijingEmail,
            '广州 备品中心' => System.Label.GuangzhouEmail,
            '上海 备品中心' => System.Label.ShanghaiEmai
    };


    //本部SelectOption
    private static List<SelectOption> bieCunFangDiOps1 = new List<SelectOption>{
            new SelectOption('All', '--全部--'),
            new SelectOption('北京 备品中心', '北京 备品中心'),
            new SelectOption('广州 备品中心', '广州 备品中心'),
            new SelectOption('上海 备品中心', '上海 备品中心')
    };

    //本部SelectOptionMap
    public static Map<String, List<SelectOption>> bieCunFangDiOpsMap = new Map<String, List<SelectOption>> {
            '备品管理中心' => bieCunFangDiOps1
    };

    //产品分类SelectOption
    private static List<SelectOption> bieChanPinFenLeiOps1 = new List<SelectOption>{
            new SelectOption('', '--全部--'),
            new SelectOption('GI', 'GI'),
            new SelectOption('SP', 'SP')
    };

    //产品分类SelectOptionMap
    public static Map<String, List<SelectOption>> bieChanPinFenLeiOpsMap = new Map<String, List<SelectOption>> {
            'GISP' => bieChanPinFenLeiOps1
    };

    //备品分类SelectOption
    private static List<SelectOption> bieBeiPinFenLeiOps1 = new List<SelectOption>{
            new SelectOption('', '--全部--'),
            //new SelectOption('动物试验用', '动物试验用'),
            // new SelectOption('产品试用', '产品试用'),
            new SelectOption('学会展会', '学会展会'),
            new SelectOption('产品试用', '产品试用'),
            new SelectOption('维修代用（保修合同）', '维修代用（保修合同）'),
            new SelectOption('维修代用（一般维修）', '维修代用（一般维修）'),
            new SelectOption('协议借用', '协议借用')
    };

     //备品分类SelectOptionMap
    public static Map<String, List<SelectOption>> bieBeiPinFenLeiOpsMap = new Map<String, List<SelectOption>> {
            '备品分类' => bieBeiPinFenLeiOps1
    };

    //集中管理对象部门
    //TODO OCSM_BP3-75 等待OCSM整理好的Mapping
    public static Map<String, List<String>> departmentMap = new Map<String, List<String>> {
            '试用（无询价）'          => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部', '消化·呼吸内镜事业本部', '外科事业本部', '消化·呼吸领域解决方案本部'},
            '试用（有询价）'     => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部', '消化·呼吸内镜事业本部', '外科事业本部', '消化·呼吸领域解决方案本部'},
            '新产品评价'       => new List<String>{'能量事业本部', '消化·呼吸内镜事业本部', '外科事业本部', '消化·呼吸领域解决方案本部'},
            '学会展会'           => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部', '消化·呼吸内镜事业本部', '外科事业本部', 'MA本部', '医疗产品培训本部', '消化·呼吸领域解决方案本部'},
            '已购待货'          => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部'},
            '索赔QIS'          => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部'},
            '再修理'             => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部'},
            '保修用户'         => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部'},
            '市场多年保修'     => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部'},
            '一般用户'         => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部'},
            '故障排查'     => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部'},
            '其他'         => new List<String>{'医疗华北营业本部', '医疗东北营业本部', '医疗西北营业本部', '医疗华东营业本部', '医疗华南营业本部', '医疗西南营业本部', '能量事业本部', '消化·呼吸内镜事业本部', '外科事业本部', 'MA本部', '医疗产品培训本部', '医疗服务本部', '医疗备品管理中心', '消化·呼吸领域解决方案本部'},
            '协议借用'         => new List<String>{'MA本部'}
    };

    //备品分类
    //Rental_Apply__c.Equipment_Type_F
    public static Map<String, List<String>> equipment_TypeMap = new Map<String, List<String>> {
            '试用（无询价）'          => new List<String>{'产品试用'},
            '试用（有询价）'     => new List<String>{'产品试用'},
            '新产品评价'       => new List<String>{'产品试用'},
            '学会展会'           => new List<String>{'产品试用', '学会展会'},
            '已购待货'          => new List<String>{'产品试用'},
            '索赔QIS'          => new List<String>{'维修代用（保修合同）'},
            '再修理'             => new List<String>{'维修代用（一般维修）'},
            '保修用户'         => new List<String>{'维修代用（保修合同）'},
            '市场多年保修'         => new List<String>{'维修代用（保修合同）'},
            '一般用户'         => new List<String>{'维修代用（一般维修）'},
            '故障排查'         => new List<String>{'维修代用（一般维修）'},
            '其他'         => new List<String>(),
            '协议借用'         => new List<String>{'协议借用'}
    };


    public static Map<String, String> rental_Apply_App_CCEmailMap = new Map<String, String>();
    public static Map<String, String> initRental_Apply_App_CCEmailMap() {
        if (0 == rental_Apply_App_CCEmailMap.size()) {
            for (Rental_Apply_App_CCEmail__mdt rental_Apply_App_CCEmail : [SELECT Category5_F__c
                       , CCEmail__c
                    FROM Rental_Apply_App_CCEmail__mdt]) {
                if (String.isNotBlank(rental_Apply_App_CCEmail.CCEmail__c)) {
                    rental_Apply_App_CCEmailMap.put(rental_Apply_App_CCEmail.Category5_F__c, rental_Apply_App_CCEmail.CCEmail__c);
                }
            }
        }
        return rental_Apply_App_CCEmailMap;
    }

    public static String getAssetSoqlBase() {
        String baseStr = 'AssetManageConfirm__c = true';
        if (System.Test.isRunningTest()) {
            baseStr = 'Id != null';
        }
        return baseStr;
    }

    public static String getSoqlString(String str) {
        if (String.isBlank(str)) {
            return 'null';
        }
        else {
            return '\'' + String.escapeSingleQuotes(str) + '\'';
        }
    }

    /*
        OLY_OCM-13 决定：不考虑预约，在借的时候，就已经占用了。
        @param raes 需要做处理的借出备品Set List<Rental_Apply_Equipment_Set_Detail__c> 需要字段：Id
        @param fieldList  画面上表示的FieldList
        ToDo 附属品参数
    */
    public static Map<Id, Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>>> raesGroupBy(
            List<Rental_Apply_Equipment_Set__c> raes, List<String> fieldList, String wher) {
        Map<Id, Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>>> rtn = new Map<Id, Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>>>();
        //借出备品配套一览明细をクエリ
        List<Rental_Apply_Equipment_Set_Detail__c> raesda = [select
                Id, Fixture_Model_No_F__c, Rental_Apply_Equipment_Set__c, Is_Body_F__c, Is_Body__c, Asset__c, Asset__r.Fixture_Status__c,
                Rental_Apply__r.Salesdepartment__c, Rental_Apply__r.Equipment_Type_F__c, SalesProvince__c, RAESD_Status__c,
                Rental_Apply__r.Salesdept__c, Rental_Apply__r.Internal_asset_location_F__c,Rental_Apply__r.Product_category__c
            From Rental_Apply_Equipment_Set_Detail__c
            Where Rental_Apply_Equipment_Set__c = :raes
             and Cancel_Select__c = False];
        //不是主体的明细
        List<Rental_Apply_Equipment_Set_Detail__c> raesd = new List<Rental_Apply_Equipment_Set_Detail__c>();
        //主体的明细
        List<Rental_Apply_Equipment_Set_Detail__c> raesdBody = new List<Rental_Apply_Equipment_Set_Detail__c>();
        //借出备品配套一览Id为Map的key   值为这个一览下的明细Id
        Map<Id, List<Rental_Apply_Equipment_Set_Detail__c>> raMap = new Map<Id, List<Rental_Apply_Equipment_Set_Detail__c>>();

        for (Rental_Apply_Equipment_Set_Detail__c rsd : raesda) {
            if (raMap.containsKey(rsd.Rental_Apply_Equipment_Set__c)) {
                raMap.get(rsd.Rental_Apply_Equipment_Set__c).add(rsd);
            }
            else {
                List<Rental_Apply_Equipment_Set_Detail__c> raesdIdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
                raesdIdList.add(rsd);
                raMap.put(rsd.Rental_Apply_Equipment_Set__c, raesdIdList);
            }
        }

        //是set
        isSet = true;

        Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>> resdMap = raesdGroupBy(raesda, fieldList, wher);

        for (Id i : raMap.keySet()) {
            Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>> rdMap = new Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>>();
            for (Rental_Apply_Equipment_Set_Detail__c rad : raMap.get(i)){
                rdMap.put(rad, resdMap.get(rad));
            }
            rtn.put(i, rdMap);
        }
        for (Rental_Apply_Equipment_Set__c rs : raes) {
            if(!rtn.containsKey(rs.Id)) {
                rtn.put(rs.Id, new Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>>());
            }
        }
        return rtn;
    }

    /*

        @param raesds 需要做处理的借出备品明细 List<Rental_Apply_Equipment_Set_Detail__c>  需要字段：Asset__c
        @param fieldList  画面上表示的FieldList
    */
    public static Map<Id, Map<String, groupBean>> raesdGroupByAssetId(List<Rental_Apply_Equipment_Set_Detail__c> raesds, List<String> fieldList) {

        Set<String> useFieldSet = new Set<String>();
        for (String f : fieldList) {
            useFieldSet.add(f);
            List<String> fss = f.split('\\.');
            if (fss.size() > 1) {
                String fi = fss[fss.size() - 1];
                if (raesdAssetFs.contains(fi)) {
                    useFieldSet.add(fi);
                }
            }
        }

        Set<Id> assIds = new Set<Id>();
        Set<String> modelNoSet = new Set<String>();
        Map<Id, String> modelMap = new Map<Id, String>();
        //出库没有cancel
        if (useFieldSet.contains('Lei_Ji_Jie_Chu_Shu_Asset_Jia__c')) {
            for (Rental_Apply_Equipment_Set_Detail__c rae : raesds) {
                if (String.isNotBlank(rae.Asset__c)) {
                    assIds.add(rae.Asset__c);
                    modelMap.put(rae.Asset__c, rae.Fixture_Model_No_F__c);
                    modelNoSet.add(rae.Fixture_Model_No_F__c);
                }
            }
        }

        Map<Id, Map<String, groupBean>> assetIdGroupByMap = getAssetIdGroupByMap(new List<Id>(assIds), useFieldSet);

        if (useFieldSet.contains('Lei_Ji_Jie_Chu_Shu_Asset_Jia__c')) {
            String rasoql = 'Select Count(Id) CountId, Asset__c ' +
                    ' From Rental_Apply_Equipment_Set_Detail__c ' +
                    ' Where Asset__c in:keylist AND Asset__c != null ' +
                    ' AND Shippment_loaner_time2__c != null ' +
                    ' Group By Asset__c';
            setGroupByAsset(assetIdGroupByMap, rasoql, 'Asset__c', 'Lei_Ji_Jie_Chu_Shu_Asset_Jia__c', 'CountId', assIds);
        }

        return assetIdGroupByMap;
    }

    /*
        OLY_OCM-14, 15, 16
        @param raesd 需要做处理的借出备品明细 List<Rental_Apply_Equipment_Set_Detail__c>  Fixture_Model_No_F__c, Is_Body_F__c, Asset__c
                                                                                       需要字段：别本部 Rental_Apply__r.Salesdepartment__c
                                                                                       别用途 Rental_Apply__r.Equipment_Type_F__c
                                                                                       用别存放 Rental_Apply__r.Internal_asset_location_F__c
                                                                                       别省 SalesProvince__c
                                                                                       You_Xiao_Kun_Cun_Jia__c和Jie_Chu_Fen_Pei_Jia__c是中间字段一定会返回的
        @param fieldList  画面上表示的FieldList
    */
    public static Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>> raesdGroupBy(
            List<Rental_Apply_Equipment_Set_Detail__c> raesds, List<String> fieldList,  String wher) {

        Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>> rtn = new Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, groupBean>>();
        if (raesds == null) {
            return rtn;
        }
        Rental_Apply_Equipment_Set_Detail__c raesd = raesds.size() > 0
                ? raesds[0] : new Rental_Apply_Equipment_Set_Detail__c();

        //获取modelNoList
        Set<String> modelNoSet = new Set<String>();
        //获取BodymodelNoList
        Set<String> modelBodyNoSet = new Set<String>();
        //记录每一列对应的Id
        Map<Rental_Apply_Equipment_Set_Detail__c, String> data = new Map<Rental_Apply_Equipment_Set_Detail__c, String>();
        for(Rental_Apply_Equipment_Set_Detail__c ra : raesds) {
            modelNoSet.add(ra.Fixture_Model_No_F__c);
            data.put(ra, ra.Fixture_Model_No_F__c);
            if (ra.Is_Body__c) {
                modelBodyNoSet.add(ra.Fixture_Model_No_F__c);
            }
        }

        if (modelNoSet.isEmpty()) {
            return rtn;
        }

        Set<String> fieldSet = new Set<String>();
        for (String f : fieldList) {
            fieldSet.add(f);
            List<String> fss = f.split('\\.');
            if (fss.size() > 1) {
                fieldSet.add(fss[1]);
            }
        }

        Set<Id> asset_Ids = new Set<Id>();
        //Lei_Ji_Jie_Chu_Shu_Asset_Jia__c 并且是Set单位
        if ((isSet == true && fieldSet.contains('Lei_Ji_Jie_Chu_Shu_Asset_Jia__c'))) {
            for (Rental_Apply_Equipment_Set_Detail__c ra : raesds) {
                asset_Ids.add(ra.Asset__c);
            }
        }

        //可以分配主体需要有效库存
        if ((fieldSet.contains('Zhu_Ti_Fen_Pei_Jia__c') || fieldSet.contains('Fu_Shu_Pin_Fen_Pei_Jia__c') || fieldSet.contains('Ke_Yi_Fen_Pei_Zhu_Ti_Jia__c'))
                && !fieldSet.contains('You_Xiao_Kun_Cun_Jia__c')) {
            fieldSet.add('You_Xiao_Kun_Cun_Jia__c');
        }
        fieldSet.add('Jie_Chu_Fen_Pei_Jia__c');
        //有效库存需要已借出
        //if (fieldSet.contains('You_Xiao_Kun_Cun_Jia__c') && !fieldSet.contains('Yi_Jie_Chu_Jia__c')) {
        //    fieldSet.add('Yi_Jie_Chu_Jia__c');
        //}

        List<String> modelNoList = new List<String>(modelNoSet);

        //Asset用項目Set
        Set<String> asF = new Set<String>();
        //備品申請用項目Set
        Set<String> raesF = new Set<String>();
        //備品明細項目Set
        Set<String> raesdF = new Set<String>();
        //全て項目
        Set<String> allf = new Set<String>();
        //从画面上显示的全部字段取出这次要集計的字段
        for (String f : fieldSet) {
            if (asFs.contains(f)) {
                asF.add(f);
            }
            else if (raesFs.contains(f)) {
                raesF.add(f);
            }
            else if (raesdFs.contains(f)){
                //Set单位的话没有Lei_Ji_Jie_Chu_Shu_Jia__c
                if (f == 'Lei_Ji_Jie_Chu_Shu_Jia__c' && isSet) continue;
                raesdF.add(f);
            }
            allf.add(f);
        }

        //画面Map
        Map<String, Map<String, groupBean>> modelNoGroupByMap = getMmap(modelNoList, allf);
        //Asset的集計字段
        if (!asF.isEmpty()) {
            setAsset(modelNoGroupByMap, modelNoSet, modelBodyNoSet, asf, raesds, wher);
        }

        //借出备品明细的状态
        if (!raesdF.isEmpty()) {
            setRaesd(modelNoGroupByMap, modelNoSet, raesdF, wher);
        }

        //Id单位的数据整理 -> 状態は有效库存 - 希望借出ここで値を設定
        for (Rental_Apply_Equipment_Set_Detail__c sd : data.keySet()) {
            Map<String, groupBean> gbMap = modelNoGroupByMap.get(data.get(sd));
            rtn.put(sd, gbMap);
        }
        return rtn;
    }

    /*
        对这次需要返回的实例变量做初始化 By AssetId
        @param assetIdList 需要做处理的assetId
        @param fs 需要初始化的API
        @return 初始化的实例  Map<Id -> AssetId   Map<String -> 字段字符串   groupBean>> -> 字段处理后的值
    */
    private static Map<Id, Map<String, groupBean>> getAssetIdGroupByMap(List<Id> assetIdList, Set<String> fs) {
        Map<Id, Map<String, groupBean>> modelNoGroupByMap = new Map<Id, Map<String, groupBean>>();
        for (Id mo : assetIdList) {
            Map<String, groupBean> m = new Map<String, groupBean>();
            for (String key : fs){
                m.put(key, new groupBean());
            }
            modelNoGroupByMap.put(mo, m);
        }
        return modelNoGroupByMap;
    }

    /*
        对这次需要返回的实例变量做初始化
        @param modelNoList 需要做处理的ModelNo
        @param fs 需要初始化的API
        @return 初始化的实例 Map<String -> ModelNo   Map<String -> 字段字符串   groupBean>> -> 字段处理后的值
    */
    private static Map<String, Map<String, groupBean>> getMmap(List<String> modelNoList, Set<String> fs) {
        Map<String, Map<String, groupBean>> modelNoGroupByMap = new Map<String, Map<String, groupBean>>();
        for (String mo : modelNoList) {
            Map<String, groupBean> m = new Map<String, groupBean>();
            for (String key : fs){
                m.put(key, new groupBean());
            }
            modelNoGroupByMap.put(mo, m);
        }
        return modelNoGroupByMap;
    }

    /*
        明細に関する集計

        @param modelNoGroupByMap 需要返回的所有数据Map
        @param modelNoList 需要做处理的ModelNo
        @param fs  需要做处理的字段
    */
    private static void setRaesd(Map<String, Map<String, groupBean>> modelNoGroupByMap, Set<String> molist, Set<String> fs, String wher) {
        // OLY_OCM-654 保有设备合并 删除需要合并的字段 因为有主体的计算。所以不注释 Start
        String whe = wher.replace('Product_category__c', 'Product_category_text__c');
        whe = whe.replace('Internal_asset_location__c', 'Internal_asset_location_before__c');
        whe = whe.replace('Salesdepartment__c', 'Salesdepartment_before__c');
        whe = whe.replace('Equipment_Type__c', 'Equipment_Type_text__c');
        // OLY_OCM-654 保有设备合并 删除需要合并的字段 因为有主体的计算。所以不注释 End
        whe = whe.replace('Is_Body__c', 'Loaner_accsessary__c !');

        whe = whe.replaceAll('AND', 'and');
        whe = whe.replaceAll('And', 'and');

        List<String> wheList = whe.split('and');

        System.debug('wher is' + wher);

        String wher1 = '';
        Boolean dontneed = false;
        Boolean dontneed2 = false;
        for (String str : wheList) {
            if (str.contains('Internal_asset_location_before__c') || String.isBlank(str)) {
                if (str.contains('((')) {
                    wher1 += ' and ((';
                    dontneed = true;
                }
                System.debug(str);
                if (str.contains('))')) {
                    dontneed2 = true;
                }
                continue;
            }
            wher1 += (dontneed == true ? '' : ' and ') + str;
            wher1 += dontneed2 == true ? '))' : '';
            dontneed = false;
            dontneed2 = false;
        }
        wher1 += dontneed2 == true ? '))' : '';
        System.debug('wher1 is' + wheList);
        System.debug('wher1 is' + wher1);

        //排队
        // is_body 才会排队！！！！
        // select 申請ID、Group by 申請ID、自分で for して、Set(申請Id) にして 重複 を外す
        if (fs.contains('Pai_Dui_Jia__c')) {
            String rasoql = 'Select Count(Id) CountId, Fixture_Model_No_text__c ' +
                    ' From Rental_Apply_Equipment_Set_Detail__c ' +
                    ' Where Fixture_Model_No_text__c = :keylist AND Queue_Number__c > 0 ' +
                    ' AND Cancel_Select__c = False ' + wher1 +
                    ' Group By Fixture_Model_No_text__c';
            System.debug(LoggingLevel.INFO, '*123434** rasoql: ' + rasoql);
            // System.debug('rasoql**123*',rasoql);
            // List<AggregateResult> g = Database.query(rasoql);
            // Map<String, Set<String>> rmap = new Map<String, Set<String>>();
            // for (AggregateResult a : g) {
            //     String mof = (String)a.get('Fixture_Model_No_text__c');
            //     if (rmap.containsKey(mof)) {
            //         rmap.get(mof).add((String)a.get('Rental_Apply__c'));
            //     }
            //     else {
            //         rmap.put(mof, new Set<String>{(String)a.get('Rental_Apply__c')});
            //     }
            // }
            // for (String key : rmap.keySet()) {
            //     Map<String, groupBean> ma = modelNoGroupByMap.get(key);
            //     if (ma == null) {
            //         continue;
            //     }
            //     groupBean gBean = ma.get('Pai_Dui_Jia__c');
            //     gBean.gnum = Integer.Valueof(rmap.get(key).size());
            //     ma.put('Pai_Dui_Jia__c', gBean);
            // }
            setGroupBy(modelNoGroupByMap, rasoql, 'Fixture_Model_No_text__c', 'Pai_Dui_Jia__c', 'CountId', molist);
        }

        //累计借出数
        if (fs.contains('Lei_Ji_Jie_Chu_Shu_Jia__c')) {
            String rasoql = 'Select Count(Id) CountId, Asset__r.Product2.Fixture_Model_No_T__c ' +
                    ' From Rental_Apply_Equipment_Set_Detail__c ' +
                    ' Where Asset__r.Product2.Fixture_Model_No_T__c = :keylist AND Asset__c != null AND Shippment_loaner_time2__c != null' +
                    ' AND Cancel_Select__c = False ' +
                    ' Group By Asset__r.Product2.Fixture_Model_No_T__c';
            setGroupBy(modelNoGroupByMap, rasoql, 'Fixture_Model_No_T__c', 'Lei_Ji_Jie_Chu_Shu_Jia__c', 'CountId', molist);
        }
    }

    /*
        Assetに関する集計
        @param modelNoGroupByMap 需要返回的所有数据Map
        @param modelNoList 需要做处理的ModelNo
        @param fs  需要做处理的字段
        @param bieCunfangdi  别存放地
        @param birYongTu  别用途
    */
    private static void setAsset(Map<String, Map<String, groupBean>> modelNoGroupByMap, Set<String> molist, Set<String> moBodyList, Set<String> fs, List<Rental_Apply_Equipment_Set_Detail__c> raesds,
                                String wher) {
        // OLY_OCM-654 保有设备合并 删除需要合并的字段 因为有主体的计算。所以不注释 Start
        String whe = wher.replace('Product_category__c', 'Product_category_text__c');
        whe = whe.replace('Internal_asset_location__c', 'Internal_asset_location_before__c');
        whe = whe.replace('Salesdepartment__c', 'Salesdepartment_before__c');
        whe = whe.replace('Equipment_Type__c', 'Equipment_Type_text__c');
        // OLY_OCM-654 保有设备合并 删除需要合并的字段 因为有主体的计算。所以不注释 End
        whe = whe.replace('Loaner_accsessary__c', 'Is_Body__c !'); // Loaner_accsessary__c = -> IsBody_F__c !=
        //已借出
        //回库确认 Arrival_in_wh__c
        //分配-回库 没有 cancel
        //ToDo借出分配数应该用AssetId
        if (fs.contains('Jie_Chu_Fen_Pei_Jia__c')) {
            //修理中状态的明细不被检索出来哦哦
            //关联字段 Asset Draft_Repair_Count__c 草案中修理   Repairing_Count__c 修理中件数
            String repairStrtus = ' Repair__r.Status__c !=\'1.受理完毕\''
                                + ' AND Repair__r.Status__c !=\'2.维修报价阶段\''
                                + ' AND Repair__r.Status__c !=\'3.维修阶段\''
                                + ' AND Repair__r.Status__c !=\'草案中\'';

            String rasoql = 'Select Count(Id) CountId, Asset__r.Product2.Fixture_Model_No_T__c ' +
                             ' From Rental_Apply_Equipment_Set_Detail__c ' +
                             ' Where Asset__r.Product2.Fixture_Model_No_T__c = :keylist AND Asset__c != null AND (Queue_Number__c = 0 OR Queue_Number__c = null)' +
                             ' AND (Asset__r.Consumable_Guaranteen_end__c = null or Asset__r.Consumable_Guaranteen_end__c >= :Ftoday) ' +
                             // 有修理单并且状态是修理中的会在检索Asset件数的时候剪掉所以这里修理中的明细不需要检索出来
                             ' AND (Repair__c = null OR (' + repairStrtus + '))' +
                             ' AND ((Asset__r.Fixture_OneToOne_Link__c = null AND Asset__r.Loaner_accsessary__c = TRUE)' + // setEffectiveinventory 检索可以分配的库存时,附属品Fixture_OneToOne_Link__c不为空的保有设备是没有检索出来的。所以检索备品借出明细的时候要统一
                              ' OR Asset__r.Loaner_accsessary__c = FALSE)' + // setEffectiveinventory 检索可以分配的库存时,主体没有特别限制
                             ' AND Select_Time__c != null AND Detail_Finish__c = false ' + whe +
                             ' Group By Asset__r.Product2.Fixture_Model_No_T__c';
            setGroupBy(modelNoGroupByMap, rasoql, 'Fixture_Model_No_T__c', 'Jie_Chu_Fen_Pei_Jia__c', 'CountId', molist);
        }

        //借出分配
        //占坑数(不包含排队，从分配到回库的件数，取消的不算)
        // if (fs.contains('Yi_Jie_Chu_Jia__c')) {
        //     String rasoql = 'Select Count(Id) CountId, Asset__r.Product2.Fixture_Model_No_T__c ' +
        //                      ' From Rental_Apply_Equipment_Set_Detail__c ' +
        //                      ' Where Asset__r.Product2.Fixture_Model_No_T__c = :keylist AND Asset__c != null AND (Queue_Number__c = 0 OR Queue_Number__c = null) ' +
        //                      ' AND (Asset__r.Consumable_Guaranteen_end__c = null or Asset__r.Consumable_Guaranteen_end__c >= TODAY) ' +
        //                      ' AND Arrival_in_wh__c = false' + whe +
        //                      ' AND Cancel_Select__c = False' +
        //                      ' Group By Asset__r.Product2.Fixture_Model_No_T__c';
        //     setGroupBy(modelNoGroupByMap, rasoql, 'Fixture_Model_No_T__c', 'Jie_Chu_Fen_Pei_Jia__c', 'CountId', molist);
        // }

        //ToDo别用途, 别本部などの返答待ち
        // String bieFstr = '';

        // if (bieField == false) {
        //     //ToDo字段确认
        //     if (String.isNotBlank(raesds[0].Rental_Apply__r.Internal_asset_location_F__c)) {
        //         //别存放地
        //         bieFstr += ' AND Internal_asset_location_F__c = \'' + raesds[0].Rental_Apply__r.Internal_asset_location_F__c + '\'';
        //     }

        //     if (String.isNotBlank(raesds[0].Rental_Apply__r.Salesdept__c)) {
        //         //别本部
        //         bieFstr += ' AND Internal_demo_incharge_demo__c = \'' + raesds[0].Rental_Apply__r.Salesdept__c + '\'';
        //     }

        //     if(String.isBlank(raesds[0].Rental_Apply__r.Equipment_Type_F__c)) {
        //         //别用途
        //         bieFstr += ' AND Equipment_Type__c = \'' + raesds[0].Rental_Apply__r.Equipment_Type_F__c + '\'';
        //     }

        //     if (isBody == true) {
        //         if (String.isNotBlank(raesds[0].Rental_Apply__r.Owner_province__c)) {
        //             //别省
        //             bieFstr += ' AND SalesProvince__c = \'' + raesds[0].Rental_Apply__r.Owner_province__c + '\'';
        //         }
        //     }
        // }

        //有效库存
        if (fs.contains('You_Xiao_Kun_Cun_Jia__c')) {
            //可以分配的库存
            setEffectiveinventory(modelNoGroupByMap, molist, fs, 'You_Xiao_Kun_Cun_Jia__c', wher);
        }


        // 'Bie_Cun_Fang_Di_Ku_Cun_Jia__c', //别存放地
        if (fs.contains('Bie_Cun_Fang_Di_Ku_Cun_Jia__c')) {
            String bieCstr = '';
            if (String.isNotBlank(raesds[0].Rental_Apply__r.Internal_asset_location_F__c)) {
                //别存放地
                bieCstr += ' AND Internal_asset_location__c != \'' + raesds[0].Rental_Apply__r.Internal_asset_location_F__c + '\'';
            }
            setEffectiveinventory(modelNoGroupByMap, moBodyList, fs, 'Bie_Cun_Fang_Di_Ku_Cun_Jia__c', bieCstr);
        }

        //别用途库存
        if (fs.contains('Bie_Yong_Tu_Ku_Cun_Jia__c')) {
            String bieYstr = '';
            if(String.isNotBlank(raesds[0].Rental_Apply__r.Equipment_Type_F__c)) {
                // OLY_OCM-654 保有设备合并 别字段不用修改 Start
                //别用途
                bieYstr += ' AND Equipment_Type__c != \'' + raesds[0].Rental_Apply__r.Equipment_Type_F__c + '\'';
                // OLY_OCM-654 End
            }
            setEffectiveinventory(modelNoGroupByMap, moBodyList, fs, 'Bie_Yong_Tu_Ku_Cun_Jia__c', bieYstr);
        }

        //别产品分类
        if (fs.contains('Bie_Chan_Pin_Fen_Lei_Jia__c')) {
            String bieYstr = '';
            if(String.isNotBlank(raesds[0].Rental_Apply__r.Product_category__c)) {
                // OLY_OCM-654 保有设备合并 别字段不用修改 Start
                //别用途
                bieYstr += ' AND Product_category__c != \'' + raesds[0].Rental_Apply__r.Product_category__c + '\'';
                // OLY_OCM-654 End
            }
            setEffectiveinventory(modelNoGroupByMap, moBodyList, fs, 'Bie_Chan_Pin_Fen_Lei_Jia__c', bieYstr);
        }

        //别省的库存
        // if (fs.contains('Bie_Sheng_Ku_Cun_Jia__c')) {
        //     String bieYstr = '';
        //     if(String.isBlank(raesds[0].Rental_Apply__r.Owner_province__c)) {
        //         //别省的库存
        //         bieYstr += ' AND SalesProvince__c != \'' + raesds[0].Rental_Apply__r.Owner_province__c + '\'';
        //         System.debug('Bie_Yong_Tu_Ku_Cun_Jia__cis' + bieYstr);
        //     }
        //     setEffectiveinventory(modelNoGroupByMap, molist, fs, 'Bie_Sheng_Ku_Cun_Jia__c', ' AND SalesProvince__c !=\'' + raesds[0].Rental_Apply__r.Owner_province__c + '\'');
        // }

        //别本部库存
        if (fs.contains('Bie_Ben_Bu_Ku_Cun_Jia__c')) {
            // OLY_OCM-654 保有设备合并 别字段不需要修改 Start
            setEffectiveinventory(modelNoGroupByMap, moBodyList, fs, 'Bie_Ben_Bu_Ku_Cun_Jia__c', 'AND Salesdepartment__c !=\'' + raesds[0].Rental_Apply__r.Salesdepartment__c + '\'');
            // OLY_OCM-654 End
        }


        //Id单位的数据整理 -> 状態は有效库存 - 希望借出ここで値を設定
        for (Rental_Apply_Equipment_Set_Detail__c sd : raesds) {
            Map<String, groupBean> gbMap = modelNoGroupByMap.get(sd.Fixture_Model_No_F__c);
            //设置附属品状态 并清空主体状态
            if (fs.contains('Fu_Shu_Pin_Fen_Pei_Jia__c') && sd.Is_Body_F__c == false) {
                if(gbMap.get('You_Xiao_Kun_Cun_Jia__c').gnum >= 1) {
                    gbMap.get('Fu_Shu_Pin_Fen_Pei_Jia__c').gnum = AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal();
                }
                else if (gbMap.get('You_Xiao_Kun_Cun_Jia__c').gnum < 1) {
                    gbMap.get('Fu_Shu_Pin_Fen_Pei_Jia__c').gnum = AssetFixtureStatus.Mei_You_Ku_Cun.ordinal();
                }
                if (fs.contains('Zhu_Ti_Fen_Pei_Jia__c')) {
                    gbMap.get('Zhu_Ti_Fen_Pei_Jia__c').gnum = null;
                }
            }

            //设置主体状态 并清空附属品状态
            if (fs.contains('Zhu_Ti_Fen_Pei_Jia__c') && sd.Is_Body_F__c == true) {
                if(gbMap.get('You_Xiao_Kun_Cun_Jia__c').gnum >= 1) {
                    gbMap.get('Zhu_Ti_Fen_Pei_Jia__c').gnum = AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal();
                }
                else if (gbMap.get('You_Xiao_Kun_Cun_Jia__c').gnum < 1) {
                    gbMap.get('Zhu_Ti_Fen_Pei_Jia__c').gnum = AssetFixtureStatus.Mei_You_Ku_Cun.ordinal();
                }
                if(fs.contains('Fu_Shu_Pin_Fen_Pei_Jia__c')) {
                    gbMap.get('Fu_Shu_Pin_Fen_Pei_Jia__c').gnum = null;
                }
            }

            //可以分配主体只有是主体的时候才去赋值
            if (fs.contains('Ke_Yi_Fen_Pei_Zhu_Ti_Jia__c')) {
                if (sd.Is_Body_F__c == true) {
                    gbMap.get('Ke_Yi_Fen_Pei_Zhu_Ti_Jia__c').gnum = gbMap.get('You_Xiao_Kun_Cun_Jia__c').gnum;
                }
            }
        }
    }

    /*
        Group Map By AssetId设定
        @param assetIdNoGroupByMap 需要返回的所有数据Map
        @param groupData group by 后的数据
        @param key  key的Api
        @param apiName 设置的API
        @param valueKey group后需要赋值的字段
        @param keylist クエリ使用のSet
    */
    private Static void setGroupByAsset(Map<Id, Map<String, groupBean>> assetIdNoGroupByMap,
        String groupSoql, String key, String apiName, String valueKey, Set<Id> keylist) {
        List<AggregateResult> g = Database.query(groupSoql);
        for (AggregateResult a : g) {
            Map<String, groupBean> ma = assetIdNoGroupByMap.get((String)a.get(key));
            groupBean gBean = ma.get(apiName);
            gBean.gnum = Integer.Valueof(a.get(valueKey));
            ma.put(apiName, gBean);
        }
    }

    /*
        Group Map设定
        @param modelNoGroupByMap 需要返回的所有数据Map
        @param groupData group by 后的数据
        @param key  key的Api
        @param apiName 设置的API
        @param valueKey group后需要赋值的字段
        @param keylist クエリ使用のSet
    */
    private Static void setGroupBy(Map<String, Map<String, groupBean>> modelNoGroupByMap,
        String groupSoql, String key, String apiName, String valueKey, Set<String> keylist) {
        System.debug(LoggingLevel.INFO, '*** keylist: ' + keylist);
        Date Ftoday = FixtureUtil.today;
        List<AggregateResult> g = Database.query(groupSoql);
        for (AggregateResult a : g) {
            Map<String, groupBean> ma = modelNoGroupByMap.get((String)a.get(key));
            groupBean gBean = ma.get(apiName);
            gBean.gnum = Integer.Valueof(a.get(valueKey));
            ma.put(apiName, gBean);
        }
    }


    /*
        有效库存, 别本部库存, 别用途库存 You_Xiao_Kun_Cun_Jia__c, Bie_Ben_Bu_Ku_Cun_Jia__c, Bie_Yong_Tu_Ku_Cun_Jia__c
        在计算有效库存之前是需要已借出假
        @param modelNoGroupByMap 需要返回的所有数据Map
        @param modelNoList 需要做处理的ModelNo
        @param fs  需要做处理的字段
        @param fieldName  这次处理的字段 ( 有效库存 或 可以分配主体)
    */
    private static void setEffectiveinventory(Map<String, Map<String, groupBean>> modelNoGroupByMap,
            Set<String> molist, Set<String> fs, String fieldName, String where2) {
        String rasoql = 'Select SUM(Quantity) Quantity, Product2.Fixture_Model_No_T__c, '
                + ' SUM(Repairing_Count__c) Repairing_Count__c, SUM(Draft_Repair_Count__c) Draft_Repair_Count__c,'
                + ' SUM(In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun_Sum__c) In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun_Sum__c,'
                + ' SUM(Abandoned_Inventory__c) Abandoned_Inventory__c,'
                + ' SUM(Abandoned_RealThing__c) Abandoned_RealThing__c,'
                + ' SUM(Frozen_Quantity__c) Frozen_Quantity__c,'
                + ' SUM(Repairing_Link_Detail_Count__c) Repairing_Link_Detail_Count__c'
                + ' From Asset '
                + ' Where Product2.Fixture_Model_No_T__c = :molist '
                //ToDo别暂时不算检索条件
                + where2 + ' AND ' + getAssetSoqlBase()
                + ' AND Asset_loaner_category__c != \'耗材\''
                + ' AND RecordTypeId = \'01210000000kOPR\''
                + ' AND Product2.Fixture_Model_No_T__c != null'
                + ' AND Equipment_Type__c != \'检测用备品\''
                + ' AND Freeze_sign_Abandoned_Flag__c = False '
                + ' AND Delete_Flag__c = False '
                + ' AND (Consumable_Guaranteen_end__c = null or Consumable_Guaranteen_end__c >= :Ftoday) '           // SUM(Quantity) なので、From Rental_Apply_Equipment_Set_Detail__c にも Guaranteen_end__c を見るべき
                + ' AND Asset_Owner__c  =' + '\'' + 'Olympus' + '\' '
                + ' AND ((Loaner_accsessary__c = True AND Fixture_OneToOne_Link__c = null)'  // 附属品一对一的个体管理不能检索出来
                + '     OR (Loaner_accsessary__c = False AND Draft_Repair_Count__c = 0 AND Repairing_Count__c = 0))' //个体管理(主体) 有修理的不检索出来
                + ' Group By Product2.Fixture_Model_No_T__c';
        System.debug(rasoql);
        Date Ftoday = FixtureUtil.today;
        List<AggregateResult> g = Database.query(rasoql);

        for (AggregateResult a : g) {
            Map<String, groupBean> ma = modelNoGroupByMap.get((String)a.get('Fixture_Model_No_T__c'));
            groupBean gBean = ma.get(fieldName);
            groupBean gBean1 = ma.get('Jie_Chu_Fen_Pei_Jia__c');
            //已借出
            Integer lnum = gBean1.gnum;
            Integer num = a.get('Quantity') == null ? 0 : Integer.Valueof(a.get('Quantity'));
            Integer Repairing_Count = Integer.Valueof(a.get('Repairing_Count__c'));
            Integer Draft_Repair_Count = Integer.Valueof(a.get('Draft_Repair_Count__c'));
            Integer In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun_Sum = Integer.Valueof(a.get('In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun_Sum__c'));
            Integer Abandoned_Inventory_Sum = a.get('Abandoned_Inventory__c') == null ? 0 : Integer.Valueof(a.get('Abandoned_Inventory__c')); // 待废弃数(丢失/盘亏)
            Integer Abandoned_RealThing_Sum = a.get('Abandoned_RealThing__c') == null ? 0 : Integer.Valueof(a.get('Abandoned_RealThing__c')); // 待废弃数(实物)
            Integer Frozen_Quantity_Sum = a.get('Frozen_Quantity__c') == null ? 0 : Integer.Valueof(a.get('Frozen_Quantity__c')); // 冻结数
            Integer Repairing_Link_Detail_Count_Sum = a.get('Repairing_Link_Detail_Count__c') == null ? 0 : Integer.Valueof(a.get('Repairing_Link_Detail_Count__c')); // 修理中的明细
            System.debug('lnum' + lnum + 'num' + num);
            System.debug('gBean' + gBean);
            gBean.gnum = num - lnum - (Repairing_Count + Draft_Repair_Count - Repairing_Link_Detail_Count_Sum) - In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun_Sum -
                        Abandoned_Inventory_Sum - Abandoned_RealThing_Sum - Frozen_Quantity_Sum;
            ma.put(fieldName, gBean);
        }
    }



    /**
     * @param mainRAESDMap required {RAESD.Id => RAESD}的Map
     * @param raesMap required FixtureUtil.raesGroupBy()的return值
     * @return RAES.Id => 主体分配
     * 之前会掉用方法raesGroupBy,并且把结果传进来,这个方法只是对Groupby的就过做处理
     * 只会设置Zhu_Ti_Fen_Pei_Jia__c的值Fu_Shu_Pin_Fen_Pei_Jia__c的字段在方法makeFu_Shu_Pin_Fen_Pei_Jia里面设置
     */
    public static Map<Id, String> makeZhu_Ti_Fen_Pei_Jia(Map<Id, Rental_Apply_Equipment_Set_Detail__c> mainRAESDMap,
            Map<Id, Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, FixtureUtil.groupBean>>> raesMap) {
        if (raesMap == null) {
            throw new ControllerUtil.myException('raesMap is required');
        }

        Map<Id, String> raesdMap = new Map<Id, String>();

        // Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, FixtureUtil.groupBean>> rmap = raesMap.get(RAES.Id);
        // 注意点、Key がRental_Apply_Equipment_Set_Detail__c なので rmap は 一般的なMapとして使えない
        // rmap を loop として使うだけ
        for (Id iid : raesMap.keySet()) {
            Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, FixtureUtil.groupBean>> rmap = raesMap.get(iid);
            for (Rental_Apply_Equipment_Set_Detail__c raesd : rmap.keySet()) {
                if (mainRAESDMap.containsKey(raesd.Id) && raesd.Is_Body__c == true) {
                    Rental_Apply_Equipment_Set_Detail__c raesd1 = mainRAESDMap.get(raesd.Id);
                    if (String.isNotBlank(raesd1.Asset__c)) {
                        raesdMap.put(iid, raesd1.RAESD_Status__c);
                        break;
                    }
                }
                if (raesd.Is_Body__c) {
                    Map<String, FixtureUtil.groupBean> fMap = rmap.get(raesd);
                    raesdMap.put(iid, FixtureUtil.assetFixtureStatusMap.get(fMap.get('Zhu_Ti_Fen_Pei_Jia__c').gnum));
                }
            }
        }
        return raesdMap;
    }

    /**
     * @param accessoryRAESDMap required {RAESD.Id => RAESD}的Map
     * @param raesMap required FixtureUtil.raesGroupBy()的return值
     * @return RAES.Id => 附属品分配
     * 之前会掉用方法raesGroupBy,并且把结果传进来,这个方法只是对Groupby的就过做处理
     * 只会设置Fu_Shu_Pin_Fen_Pei_Jia__c的值Zhu_Ti_Fen_Pei_Jia__c的字段在方法makeZhu_Ti_Fen_Pei_Jia里面设置
     */
    public static Map<Id, String> makeFu_Shu_Pin_Fen_Pei_Jia(Map<Id, Rental_Apply_Equipment_Set_Detail__c> accessoryRAESDMap,
            Map<Id, Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, FixtureUtil.groupBean>>> raesMap) {
        if (raesMap == null) {
            throw new ControllerUtil.myException('raesMap is required');
        }
        // Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, FixtureUtil.groupBean>> rmap = raesMap.get(RAES.Id);
        // 注意点、Key がRental_Apply_Equipment_Set_Detail__c なので rmap は 一般的なMapとして使えない
        // rmap を loop として使うだけ
        Map<Id, String> raesdMap = new Map<Id, String>();
        for (Id iid : raesMap.keySet()) {
            Boolean yifenpei = false;
            Boolean keyifenpei = false;
            Boolean wukucun = false;
            Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, FixtureUtil.groupBean>> rmap = raesMap.get(iid);
            Boolean haveAccessory = false;
            for (Rental_Apply_Equipment_Set_Detail__c raesd : rmap.keySet()) {
                if (accessoryRAESDMap.containsKey(raesd.Id) && raesd.Is_Body__c == false) {
                    haveAccessory = true;
                    Rental_Apply_Equipment_Set_Detail__c raesd1 = accessoryRAESDMap.get(raesd.Id);
                    if (String.isNotBlank(raesd1.Asset__c)) {
                        yifenpei = true;
                        continue;
                    }
                }
                Map<String, FixtureUtil.groupBean> fMap = rmap.get(raesd);
                if (fMap.get('Fu_Shu_Pin_Fen_Pei_Jia__c').gnum == FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal()) {
                    wukucun = true;
                } else if (fMap.get('Fu_Shu_Pin_Fen_Pei_Jia__c').gnum == FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal()) {
                    keyifenpei = true;
                }
            }
            if (haveAccessory == false) {
                continue;
            }
            if (yifenpei == true && wukucun == false && keyifenpei == false) {
                raesdMap.put(iid, FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Fen_Pei.ordinal()));
            } else if (wukucun == true && keyifenpei == true) {
                raesdMap.put(iid, FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Bu_Fen_Mei_You.ordinal()));
            } else if (wukucun == false && keyifenpei == true) {
                raesdMap.put(iid, FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal()));
            } else {
                raesdMap.put(iid, FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal()));
            }

        }
        return raesdMap;
    }

/************************* Fixture Pubic Method ******************************/
    //public SObject getNewSobject(String t) {
    //    Type st = Type.forName(t);
    //    Sobject s = (Sobject) st.newInstance();
    //    return s;
    //}

    public static List<SelectOption> getPlickList(String objApi, String fieldApi) {
        Schema.DescribeFieldResult fieldResult = Schema.getGlobalDescribe().get(objApi).getDescribe().fields.getMap().get(fieldApi).getDescribe();
        List<SelectOption> pickListValuesList= new List<SelectOption>();
        List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
        pickListValuesList.add(new SelectOption('', system.label.StartTrading_None));
        for( Schema.PicklistEntry pickListVal : ple){
            pickListValuesList.add(new SelectOption(pickListVal.getValue(), pickListVal.getLabel()));
        }
        return pickListValuesList;
    }

/************************* Fixture DML Method ******************************/
    public static void delFixtureSetDetailByIds(Fixture_Set__c fs, List<Id> delIds) {
        List<Fixture_Set_Detail__c> dels = [Select Id
                From Fixture_Set_Detail__c where Fixture_Set__c = :fs.Id and Id IN :delIds];
        if (dels.size() > 0) { delete dels; }
    }

    public static void delRAES_excludedUpserted(Rental_Apply__c ra, List<Rental_Apply_Equipment_Set__c> upserted) {
        List<Rental_Apply_Equipment_Set__c> dels = [select Id
                from Rental_Apply_Equipment_Set__c
               where Rental_Apply__c = :ra.Id
                 and Cancel_Select__c = False
                 and Id Not IN :upserted];
        if (!dels.isEmpty()) delete dels;
    }
    public static void delRAESD_excludedUpserted(List<Rental_Apply_Equipment_Set__c> pList, List<Rental_Apply_Equipment_Set_Detail__c> upserted) {
        // ToDo 削除時、一部データのkeyを削除対象から外す
        // 一部データとは = Not(申請中) のこと
        List<Rental_Apply_Equipment_Set_Detail__c> dels = [select Id
                from Rental_Apply_Equipment_Set_Detail__c
               where Rental_Apply_Equipment_Set__c IN :pList
                 and Cancel_Select__c = False
                 // Fixture_Set_Detail__c为空的当作就数据不删除
                 and Fixture_Set_Detail__c != null
                 and Id Not IN :upserted];
        if (!dels.isEmpty()) delete dels;
    }

    public static void delRND_excludedUpserted(List<ReceivingNoteSummary__c> pList, List<ReceivingNoteDetail__c> upserted, List<ReceivingNoteDetail__c> updated, Boolean isAcceptance) {
        // ToDo 削除時、一部データのkeyを削除対象から外す
        // 一部データとは = Not(申請中) のこと
        List<ReceivingNoteDetail__c> dels = [SELECT Id
                    , AcceptanceResult__c
                    , AcceptanceStaff__c
                    , AcceptanceComments__c
                    , AcceptanceTime__c
                    , Change_Point__c
                    , RNDAssert__c
                    , RNDAssert__r.Product2Id
                    , Fixture_Set_Detail__r.Product2__c
                    , Set_Arrival_Product__c
                    , Fixture_Arrival_Product__c
                    , Fixture_Arrival_Process__c
                    , Default_Fixture_Arrival_Product__c
                    , Product_Arrival_Product__c
                 FROM ReceivingNoteDetail__c
                WHERE ReceivingNoteSummary__c IN :pList
                 // and Cancel_Select__c = False
                 // Fixture_Set_Detail__c为空的当作就数据不删除
                  AND Fixture_Set_Detail__c != null
                  AND Id Not IN :upserted
                  AND Id Not IN : updated
                  AND Delete_Flag__c = false
                 ];
        if (isAcceptance == false) {
            if (!dels.isEmpty()) delete dels;
        }
        else {
            if (dels.size() > 0) {
                List<ReceivingNoteDetail__c> updaterndList = new List<ReceivingNoteDetail__c>();
                List<ReceivingNoteDetail__c> deleterndList = new List<ReceivingNoteDetail__c>();
                for (ReceivingNoteDetail__c de : dels) {
                    if (de.Change_Point__c == '增加'
                        || de.Change_Point__c == '新建') {
                        deleterndList.add(de);
                    }
                    else {
                        de.Change_Point__c = '删除';
                        de.AcceptanceResult__c = null;
                        de.AcceptanceStaff__c = null;
                        de.AcceptanceComments__c = null;
                        de.AcceptanceTime__c = null;
                        // 配套入库产品
                        de.Set_Arrival_Product__c = de.Fixture_Set_Detail__r.Product2__c;
                        if (null == de.Product_Arrival_Product__c) {
                            de.Product_Arrival_Product__c = de.Default_Fixture_Arrival_Product__c;
                        }
                        // 配套后，产品没变则清空
                        if (null != de.RNDAssert__c
                            && de.RNDAssert__r.Product2Id == de.Set_Arrival_Product__c
                        ) {
                            de.Fixture_Arrival_Product__c = null;
                            de.Fixture_Arrival_Process__c = null;
                        }
                        // 配套后，产品变了则设为变体
                        else if (null != de.RNDAssert__c
                            && de.RNDAssert__r.Product2Id != de.Set_Arrival_Product__c
                        ) {
                            de.Fixture_Arrival_Product__c = de.Set_Arrival_Product__c;
                            de.Fixture_Arrival_Process__c = '变体';
                        }
                        updaterndList.add(de);
                    }
                }
                if (deleterndList.size() > 0) {
                    delete deleterndList;
                }

                if (updaterndList.size() > 0) {
                    update updaterndList;
                }
            }
        }
    }

    public static void delOtOLinkData(List<Id> mainIds) {
        List<Fixture_OneToOne_Link__c> oto_del = [select Id
                 from Fixture_OneToOne_Link__c
                where Main_Asset__c in :mainIds];
        if (!oto_del.isEmpty()) {
            delete oto_del;
        }
    }

    public static List<Rental_Apply_Equipment_Set_Detail__c> queryTempList(String sqlStr, List<Rental_Apply_Equipment_Set_Detail__c> tempList) {
        return Database.query(sqlStr);
    }

    public static void withoutUpsertObjects(List<Sobject> sobjs) {
        if (!sobjs.isEmpty()) upsert sobjs;
    }

    public static void withoutUpdate(List<Sobject> sobj) {
        if (!sobj.isEmpty()) update sobj;
    }

    public static void withoutInsert(List<Sobject> sobj) {
        if (!sobj.isEmpty()) insert sobj;
    }

    public static void withoutDelete(List<Sobject> sobj) {
        if (!sobj.isEmpty()) delete sobj;
    }

    public static Database.UpsertResult[] withoutUpsert(List<Sobject> sobj, Boolean allOrNone) {
        return Database.upsert(sobj, allOrNone);
    }

    public static Database.SaveResult[] withoutUpdate(List<Sobject> sobj, Boolean allOrNone) {
        return Database.update(sobj, allOrNone);
    }

    public static Database.SaveResult[] withoutInsert(List<Sobject> sobj, Boolean allOrNone) {
        return Database.insert(sobj, allOrNone);
    }

    public static void withoutUpsertRaes(List<Rental_Apply_Equipment_Set__c> sobj) {
        if (!sobj.isEmpty()) upsert sobj UniqueKey__c;
    }

    public static void withoutUpsertIh(List<Inventory_Header__c> sobj) {
        if (!sobj.isEmpty()) upsert sobj UniqueKey__c;
    }
    // 20220224 ljh 113盘点 Copy  start
    public static void withoutUpsertIhCopy(List<Inventory_Header_Copy__c> sobj) {
        if (!sobj.isEmpty()) upsert sobj UniqueKey__c;
    }
    // 20220224 ljh 113盘点 Copy  end
    public static void withoutUpsertRaesd(List<Rental_Apply_Equipment_Set_Detail__c> sobj) {
        if (!sobj.isEmpty()) upsert sobj UniqueKey__c;
    }

    public static void withoutUpsertRnd(List<ReceivingNoteDetail__c> sobj) {
        if (!sobj.isEmpty()) upsert sobj UniqueKey__c;
    }

    // 主体专用
    public static void delRAESDByIds(Rental_Apply_Equipment_Set__c raes, List<Id> delIds) {
        List<Rental_Apply_Equipment_Set_Detail__c> dels = [
                select Id,
                       FSD_OneToOneAccessory_Cnt__c,
                       Is_Body__c
                from Rental_Apply_Equipment_Set_Detail__c
                where Rental_Apply_Equipment_Set__c = :raes.Id and Id IN :delIds];

        if (dels.size() > 0) {
            List<Rental_Apply_Equipment_Set_Detail__c> tempList = new List<Rental_Apply_Equipment_Set_Detail__c>();
            // あとでまとめて削除する
            tempList.addAll(dels);

            // raes.Id より、1对1判断
            if (dels.size() > 0) {
                // 以前保存数据时一对一的情况下, 保存的附属品也一并删除
                Boolean isDelete1to1Main = false;
                for (Rental_Apply_Equipment_Set_Detail__c delMain : dels) {
                    if (delMain.FSD_OneToOneAccessory_Cnt__c > 0
                            && delMain.Is_Body__c) {
                        // 一对一的対象です。
                        isDelete1to1Main = true;
                    }
                }

                if (isDelete1to1Main) {
                    List<Rental_Apply_Equipment_Set_Detail__c> accessoryRaesdList = [
                            select Id
                              from Rental_Apply_Equipment_Set_Detail__c
                             where Rental_Apply_Equipment_Set__c = :raes.Id
                               and Cancel_Select__c = false
                               and Id NOT IN :delIds
                               and Is_Body__c != true];

                    if (accessoryRaesdList.size() > 0) {
                        tempList.addAll(accessoryRaesdList);
                    }
                }
            }

            delete tempList;
        }
    }

    /**
    * 一对一分配的附属品,当一对一主体排队或者分配及重新分配一对一主体时,一对一附属品清除分配信息,清除一对一link表的相关逻辑
    * 备注 1:返回要做一对一分配的明细
    *      2:只对需要清楚的明细做清楚操作
    * @param oldsRaes 旧的一览的Id
    * @param mfUpsert update操作的map,在外部调用的地方定义,有返回的功能
    * @param oldAssetId 旧的Asset.Id
    * @param fOtoMap 一对一link表update操作的map,在外部调用(之前的一对一分配数也需要一起清空)
    * @return 返回配套中所有的一对一附属品数据,对其中一对一一起分配的附属品相关的分配字段进行清除
    */
    public static List<Rental_Apply_Equipment_Set_Detail__c> clearOneToOneAccessory(Id oldsRaes
            , Map<String, Rental_Apply_Equipment_Set_Detail__c> mfUpsert
            , Id oldAssetId
            , Map<Id, Fixture_OneToOne_Link__c> fOtoMap) {

        // 需要考虑 oneToOneSelect 里用到的 newList 的字段
        String soql = '';
        soql += 'SELECT Id, UniqueKey__c, Asset__c, FSD_Fixture_Model_No__c, FSD_Name_CHN__c, Fixture_OneToOne_Link_Id__c,';
        soql += '       Select_Time__c, Shipment_request_time2__c, Shipment_request__c, OneToOne_Flag__c, StockDown__c, DeliverySlip__c';
        soql += '  from Rental_Apply_Equipment_Set_Detail__c';
        soql += ' where Rental_Apply_Equipment_Set__c = \'' + String.escapeSingleQuotes(oldsRaes) + '\'';
        soql += ' and Cancel_Select__c = false';
        soql += ' and FSD_Is_OneToOne__c = true';     // 一对一的附属品才是对象
        soql += ' and UniqueKey__c != null';          // 念のため
        soql += ' and Is_Body__c = false';
        soql += ' order by FSD_Fixture_Model_No__c';

        system.debug('====测试soql:' + soql);
        List<Rental_Apply_Equipment_Set_Detail__c> raesdList = Database.query(soql);

        if (!raesdList.isEmpty()) {
            for (Rental_Apply_Equipment_Set_Detail__c accessoryObj : raesdList) {
                // 已分配情况下,清除一对一一起分配的附属品
                if (accessoryObj.OneToOne_Flag__c) {
                    accessoryObj.Fixture_OneToOne_Link_Id__c = null;
                    accessoryObj.Asset__c = null;
                    accessoryObj.Select_Time__c = null;
                    accessoryObj.Shipment_request_time2__c = null;
                    accessoryObj.Shipment_request__c = false;

                    // 在此处先全部清空,在handler中会参照申请时逻辑重新设值
                    // 备品配套明细型号(借出时)
                    accessoryObj.Fixture_Model_No_text__c = accessoryObj.FSD_Fixture_Model_No__c;
                    // 机身编号（借出时）
                    accessoryObj.SerialNumber_text__c = null;
                    // 所在地区(省) 借出时
                    accessoryObj.SalesProvince_before__c = null;
                    // 所在地区(本部) 借出时
                    accessoryObj.Salesdepartment_before__c = null;
                    // 产品分类(GI/SP)(借出时)
                    accessoryObj.Product_category_text__c = null;
                    // 备品分类(借出时)
                    accessoryObj.Equipment_Type_text__c = null;
                    // 备品成本(借出时)
                    accessoryObj.Asset_cost_del_before__c = null;
                    // 备品存放地(借出时)
                    accessoryObj.Internal_asset_location_before__c = null;
                    //备品名称(借出时)
                    accessoryObj.Fixture_Name_text__c = accessoryObj.FSD_Name_CHN__c;
                    // OLY_OCM-243 追加字段对应 备品管理编码(借出时)
                    accessoryObj.EquipmentSet_Managment_Code_text__c = null;

                    mfUpsert.put(accessoryObj.UniqueKey__c, accessoryObj);
                }
            }
        }

        // 一对一的情况,主体备品和配套的附属品一起分配 之前的一对一分配数也需要一起清空
        List<Fixture_OneToOne_Link__c> fo2oList1 = [
                    SELECT Id, Main_Asset__c,
                           Accessory_Asset__c,
                           Accessory_Asset__r.Fixture_Model_No_F__c,
                           Quantity__c
                      FROM Fixture_OneToOne_Link__c
                     WHERE Accessory_Asset__c != null                   // 念のため
                       AND Main_Asset__c = :oldAssetId];
        for (Fixture_OneToOne_Link__c foto : fo2oList1) {
            foto.Select_Accessory_Asset_Cnt__c = 0;
            fOtoMap.put(foto.Id, foto);
        }

        return raesdList;
    }

/************************* Send Message ******************************/
    public static void sendMessage(String toAddress, List<String> ccAddress, String setSubject, String body) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        if (String.isNotBlank(toAddress)) {
            mail.setToAddresses(new String[]{toAddress});
            if (ccAddress != null) {
                if (!ccAddress.isEmpty()) {
                    mail.ccAddresses = ccAddress;
                }
            }
            mail.setCharset('UTF-8');
            mail.setSubject(setSubject);
            mail.setHtmlBody(body);
            //ToDo runtest
            Messaging.sendEmail(new List<Messaging.Email> { mail });
        }
    }

/************************* Inner Class ******************************/
    public class groupBean{
        //这里的gNum会保存数量或者状态
        public Integer gNum{get;set;}
        public Date gDate{get;set;}
        public groupBean() {
            gNum = 0;
        }
    }

    /**
    * 根据User和申请书目的可以选择不同的本部
    * @param purpose2 申请书目的2
    * @return 返回可以选择的部门
    */
    public static List<String> setAssetRAESSalesdepartment (String purpose2){
        List<String> departmentList = new List<String> ();
        if (departmentMap.containsKey(purpose2)){
            departmentList = departmentMap.get(purpose2);
        }
        return departmentList;
    }

    /**
    * 根据User和申请书目的可以选择不同的本部
    * @param purpose2 申请书目的2
    * @return 返回可以选择的备品分类
    */
    public static List<String> setAssetRAESEquipment_Type (String purpose2){
        List<String> equipment_TypeList = new List<String> ();
        if (equipment_TypeMap.containsKey(purpose2)){
            equipment_TypeList = equipment_TypeMap.get(purpose2);
        }
        return equipment_TypeList;
    }

    /**
    * 设置upsert错误信息
    * @param srList upsert结果
    * @param obj 数据类型
    * @param upsList upsert数据
    * @param messageList 错误信息List
    * @return 错误信息
    */
    public static List<String> setUpstError(List<Database.UpsertResult> srList, Schema.sObjectType obj
            , List<SObject> upsList, List<String> messageList) {
        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.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()) : '');
                    messageList.add(message);
                }
            }
        }
        return messageList;
    }

    /**
    * 设置save错误信息
    * @param srList save结果
    * @param obj 数据类型
    * @param upsList upsert数据
    * @param messageList 错误信息List
    * @return 错误信息
    */
    public static  List<String> setSaveError(List<Database.SaveResult> srList, Schema.sObjectType obj
            , List<SObject> upsList, List<String> messageList) {
        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()) : '');
                    messageList.add(message);
                }
            }
        }
        return messageList;
    }

    /**
    * 设置delete错误信息
    * @param srList upsert结果
    * @param obj 数据类型
    * @param upsList upsert数据
    * @param messageList 错误信息List
    * @return 错误信息
    */
    public static List<String> setDelError(List<Database.DeleteResult> srList, Schema.sObjectType obj
            , List<SObject> upsList, List<String> messageList) {
        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.DeleteResult 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()) : '');
                    messageList.add(message);
                }
            }
        }
        return messageList;
    }


    /**
    * 排队队列对象排序
    */
    global class SetDetailWrapper implements Comparable {

        public Rental_Apply_Equipment_Set_Detail__c detail;
        
        // Constructor
        public SetDetailWrapper(Rental_Apply_Equipment_Set_Detail__c setdetail) {
            detail = setdetail;
        }
        
        // Compare opportunities based on the opportunity amount.
        global Integer compareTo(Object compareTo) {
            // Cast argument to SetDetailWrapper
            SetDetailWrapper compareToDetail = (SetDetailWrapper)compareTo;
            
            // The return value of 0 indicates that both elements are equal.
            Integer returnValue = 0;
            if (detail.Rental_Apply_Equipment_Set__r.Name > compareToDetail.detail.Rental_Apply_Equipment_Set__r.Name) {
                // Set return value to a positive value.
                returnValue = 1;
            } else if (detail.Rental_Apply_Equipment_Set__r.Name < compareToDetail.detail.Rental_Apply_Equipment_Set__r.Name) {
                // Set return value to a negative value.
                returnValue = -1;
            }     
            return returnValue;       
        }
    }
    /**
    * 排队序列对象排序
    */
    global class SequenceWrapper implements Comparable {

        public Rental_Apply_Sequence__c sequence;
        
        // Constructor
        public SequenceWrapper(Rental_Apply_Sequence__c applySequence) {
            sequence = applySequence;
        }
        
        // Compare opportunities based on the opportunity amount.
        global Integer compareTo(Object compareTo) {
            // Cast argument to SequenceWrapper
            SequenceWrapper compareTosequence = (SequenceWrapper)compareTo;
            
            // The return value of 0 indicates that both elements are equal.
            Integer returnValue = 0;
            if (sequence.Series_No__c > compareTosequence.sequence.Series_No__c) {
                // Set return value to a positive value.
                returnValue = 1;
            } else if (sequence.Series_No__c < compareTosequence.sequence.Series_No__c) {
                // Set return value to a negative value.
                returnValue = -1;
            } else if ((sequence.Series_No__c == null) && (compareTosequence.sequence.Series_No__c != null)){
                // nulls-first implementation
                returnValue = -1;
            } else if ((sequence.Series_No__c != null) && (compareTosequence.sequence.Series_No__c == null)){
                // nulls-first implementation
                returnValue = 1;
            }        
            return returnValue;       
        }
    }

    @testVisible
    private void testI() {
        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++;
    }
}