public without sharing class ConsumableAssetHander extends Oly_TriggerHandler {
    public static boolean isRunning = false;
    private Map<Id, Consumable_order_details2__c> newMap;
    private Map<Id, Consumable_order_details2__c> oldMap;
    private List<Consumable_order_details2__c> newList;
    private List<Consumable_order_details2__c> oldList;
    
    public ConsumableAssetHander() {
        this.newMap = (Map<Id, Consumable_order_details2__c>) Trigger.newMap;
        this.oldMap = (Map<Id, Consumable_order_details2__c>) Trigger.oldMap;
        this.newList = (List<Consumable_order_details2__c>) Trigger.new;
        this.oldList = (List<Consumable_order_details2__c>) Trigger.old;
    }

    protected override void afterUpdate() {
        shipmentOrSaleAsset();
        returnAsset();
        arrChangeBarcode();
    }
    protected override void afterInsert() {
        returnAsset();
    }

    //// 出库时，如果存在消耗品对应的Asset，则移动到出库医院下面，如果没有新建Asset。
    //// 出库时，如果互相调货，从被调货经销商，转移到调货经销商，如果没有新建Asset。
    private void shipmentOrSaleAsset() {
        if(isRunning) return;
        Account ocm = [select Id from Account where AgentCode_Ext__c = '9999900'];
        List<String> barcodeList = new List<String>();
        List<String> hospItalCodeList = new List<String>();
        List<String> dealerNameList = new List<String>();
        List<String> productCodeList = new List<String>();
        List<Consumable_order_details2__c> saleList = new List<Consumable_order_details2__c>();
        List<Asset> assUplist = new List<Asset>();
        //获取Barcode和医院编码
        for (Consumable_order_details2__c nObj : newList) {
            Consumable_order_details2__c oObj = oldMap.get(nObj.Id);
            if (((oObj.Dealer_Saled__c != nObj.Dealer_Saled__c && nObj.Dealer_Saled__c == true)
                    || (oObj.Dealer_Shipment__c != nObj.Dealer_Shipment__c && nObj.Dealer_Shipment__c == true))
                    && String.isNotBlank(nObj.Bar_Code__c) && nObj.Box_Piece__c == '盒') {
                // 耗材
                barcodeList.add(nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')');
                // 主机
                barcodeList.add(nObj.SerialLotNo__c);
                saleList.add(nObj);
                productCodeList.add(nObj.Consumable_product__c);
                if(String.isNotBlank(nObj.HospItal_Code__c)){
                    hospItalCodeList.add(nObj.HospItal_Code__c);
                }
                if(nObj.SummonsForDirction_det__c == '互相调货'){
                    dealerNameList.add(nObj.ShipmentAccount__c);
                }
                System.debug('ShipmentAccount-------' + nObj.ShipmentAccount__c);
            }
        }
        System.debug('SS-------1' + barcodeList);
        System.debug('dealerName-------' + dealerNameList);
        if(barcodeList.size() > 0){
            List<Asset> asslist = [select Id,Hospital__r.Name,SerialNumber,AssetMark__c
                                        from asset
                                        where SerialNumber in: barcodeList
                                        and SerialNumber != null];
            List<Account> acclist = [select Id,Name,Management_Code__c from Account where Management_Code__c in: hospItalCodeList];
            // 互相调货 经销商信息
            List<Account> changeacclist = [select Id,Name,Management_Code__c from Account where Name in: dealerNameList];
            // 互相调货 取契约信息
            List<Account> agencyContractlist = [select Id,Name,Management_Code__c,Parent.Name,
                                                        ENG_Dealer__c,ET_SP_Dealer__c
                                                    from Account
                                                    where Parent.Name in: dealerNameList
                                                    and RecordType.DeveloperName ='AgencyContract'
                                                    and (ENG_Dealer__c = true or ET_SP_Dealer__c = true)
                                                    order by Is_Active_Formula__c asc ];
            
            List<Account> departmentClasslist = [select Id,Name,parent.Management_Code__c,RecordType.DeveloperName from Account 
                                                  where parent.Management_Code__c in: hospItalCodeList
                                                  and (RecordType.DeveloperName = 'Department_Class_ET'
                                                      or RecordType.DeveloperName = 'Department_Class_GS')];
            Map<String,Asset> assMap = new Map<String,Asset>();
            Map<String,Account> changeassMap = new Map<String,Account>();
            Map<String,Account> cagencyContractMap = new Map<String,Account>();
            //存在的保有设备信息
            System.debug('SS-------2' + asslist);
            System.debug('changeacclist-------' + changeacclist.size());
            for(Asset ass : asslist){
                if(assMap.containsKey(ass.Hospital__r.Name + ass.SerialNumber)){
                    continue;
                }else{
                    assMap.put(ass.Hospital__r.Name + ass.SerialNumber, ass);
                }
            }
            for(Account ass : changeacclist){
                if(changeassMap.containsKey(ass.Name)){
                    continue;
                }else{
                    changeassMap.put(ass.Name, ass);
                }
            }

            for(Account ass : agencyContractlist){
                if(ass.ENG_Dealer__c && !cagencyContractMap.containsKey(ass.Parent.Name + 'ENG')){
                    cagencyContractMap.put(ass.Parent.Name + 'ENG', ass);
                }else if(ass.ET_SP_Dealer__c && !cagencyContractMap.containsKey(ass.Parent.Name + 'ET')){
                    cagencyContractMap.put(ass.Parent.Name + 'ET', ass);
                }
                //if(cagencyContractMap.containsKey(ass.Name)){
                //    continue;
                //}else{
                //    cagencyContractMap.put(ass.Name, ass);
                //}
            }
            //System.debug('SS-------3++ ' + assMap);
            //医院信息
            Map<String,Account> accMap = new Map<String,Account>();
            for(Account acc : acclist){
                accMap.put(acc.Management_Code__c, acc);
            }
            //科室信息
            Map<String,Account> depClassMap = new Map<String,Account>();
            for(Account dep : departmentClasslist){
                if(dep.RecordType.DeveloperName == 'Department_Class_ET'){
                    depClassMap.put(dep.parent.Management_Code__c + 'ET', dep);
                }else if(dep.RecordType.DeveloperName == 'Department_Class_GS'){
                    depClassMap.put(dep.parent.Management_Code__c + 'ENG', dep);
                }
                //depClassMap.put(dep.parent.Management_Code__c, dep);
            }
            Map<String, Product2__c> prdsMap = new Map<String, Product2__c>([select Id,Name,Product2__c,Product2__r.Name,OT_CODE_Text__c  from Product2__c where Id in:productCodeList]);
            for (Consumable_order_details2__c nObj : saleList) {
                asset ast = assMap.get(nObj.Dealer_Info_text__c + nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')');
                // 判段是否是及主机
                if(ast == null){
                    if(assMap.containsKey(nObj.Dealer_Info_text__c + nObj.SerialLotNo__c) && assMap.get(nObj.Dealer_Info_text__c + nObj.SerialLotNo__c).AssetMark__c == '主机'){
                        ast = assMap.get(nObj.Dealer_Info_text__c + nObj.SerialLotNo__c);
                    }
                }
                if(ast == null){
                    ast = new asset();
                    //ast.Order_No__c  = 
                    //ast.Posting_Date__c = Date.today();
                    ast.Name                             = prdsMap.get(nObj.Consumable_product__c).Product2__r.Name;
                    ast.Product2Id                       = prdsMap.get(nObj.Consumable_product__c).Product2__c;
                    //ast.Quantity                         = nObj.Intra_Trade_List_RMB__c;
                    ast.SerialNumber                     = nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')';
                    ast.SLMark__c                        = 'Serial Number';         // 固定 dnInfo.SorLMark;
                    //HWAG-B9AAD9 当保有设备 的 保有设备标记 =耗材时，保修期限 =发货日
                    //ast.Guarantee_period_for_products__c = nObj.Product_OutDate__c;
                    //ast.Guarantee_period_for_products__c = nObj.Guarantee_period_for_products__c;
                    ast.Posting_Date__c                  = nObj.Used_date__c == null ? nObj.Send_Date__c : nObj.Used_date__c;
                    ast.TracingCode__c                   = nObj.TracingCode__c;
                    ast.Guaranteen_end__c                = nObj.Sterilization_limit__c;
                    ast.Barcode__c                       = nObj.Bar_Code__c;
                    ast.Product_Serial_No__c             = prdsMap.get(nObj.Consumable_product__c).OT_CODE_Text__c + ':' + nObj.SerialLotNo__c  + '(' + nObj.TracingCode__c + ')';
                }
                //HHOA-BA34M9 经销商出库/销售时创建或更新保有设备的逻辑修改 最新
                ast.Guarantee_period_for_products__c = nObj.Product_OutDate__c;
                ast.Posting_Date__c                  = nObj.Product_OutDate__c;
                ast.Tracing_Information_From__c      = true;
                //ast.Posting_Date__c                      = nObj.Used_date__c == null ? nObj.Send_Date__c : nObj.Used_date__c;
                if(nObj.SummonsForDirction_det__c == '互相调货'){
                    //ast.AccountId                        = ocm.Id;
                    /*if(String.isNotBlank(nObj.Used_account__c)){
                        ast.Department_Class__c              = nObj.Used_account__c;
                    }else{
                        ast.Department_Class__c              = accMap.get(nObj.Dealer_Info_text__c).Id;
                    }*/
                    ast.Asset_Owner__c                   = '经销商资产';
                    // CHAN-BCK52H 修改资产客户时对应 调货时客户取到经销商契约
                    if(cagencyContractMap.containsKey(nObj.ShipmentAccount__c + nObj.Product_Type__c)){
                        ast.AccountId                        = cagencyContractMap.get(nObj.ShipmentAccount__c + nObj.Product_Type__c).Id;
                        ast.Department_Class__c              = cagencyContractMap.get(nObj.ShipmentAccount__c + nObj.Product_Type__c).Id;
                    }else{
                        ast.AccountId                        = changeassMap.get(nObj.ShipmentAccount__c).Id;
                        ast.Department_Class__c              = changeassMap.get(nObj.ShipmentAccount__c).Id;
                    }
                    ast.Asset_owner_delaer_name__c       = changeassMap.get(nObj.ShipmentAccount__c).Id;
                    ast.Hospital__c                      = changeassMap.get(nObj.ShipmentAccount__c).Id;

                }else{
                    //医院信息
                    ast.Asset_Owner__c                   = '病院資産';
                    
                    ast.AccountId                        = depClassMap.get(nObj.HospItal_Code__c + nObj.Product_Type__c).Id;
                    ast.Department_Class__c              = depClassMap.get(nObj.HospItal_Code__c + nObj.Product_Type__c).Id;
                    ast.Hospital__c                      = accMap.get(nObj.HospItal_Code__c).Id;
                    //ast.SerialNumber                     = nObj.SerialLotNo__c +  + '(' + nObj.TracingCode__c + ')';
                    //ast.Asset_owner_delaer_name__c       = accMap.get(nObj.HospItal_Code__c).Id;
                    ast.Asset_owner_delaer_name__c       = null;
                }
                assUplist.add(ast);
            }
            //System.debug('SS-------4+ ' + assUplist);
            if(assUplist.size() > 0){
                //assUplist[0].addError('error');
                upsert assUplist;
                isRunning = true;
            }
        }
        
    }

    //// 返品时，如果存在消耗品对应的Asset，则移动到返品经销商下面，如果没有新建Asset。
    private void returnAsset() {
        if(isRunning) return;
        Account ocm = [select Id from Account where AgentCode_Ext__c = '9999900'];
        List<String> barcodeList = new List<String>();
        List<String> dealerNameList = new List<String>();
        List<String> productCodeList = new List<String>();
        List<Consumable_order_details2__c> codReturnList = new List<Consumable_order_details2__c>();
        Map<String,Asset> assUpMap = new Map<String,Asset>();
        //获取Barcode和医院编码
        System.debug('SS-------1' + newList);
        for (Consumable_order_details2__c nObj : newList) {
            if(Trigger.isInsert){
                if (nObj.Dealer_Returned__c == true && String.isNotBlank(nObj.Bar_Code__c)) {
                    barcodeList.add(nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')');
                    codReturnList.add(nObj);
                    productCodeList.add(nObj.Consumable_product__c);
                    if(String.isNotBlank(nObj.Dealer_Info_text__c)){
                        dealerNameList.add(nObj.Dealer_Info_text__c);
                    }
                }
            }else if(Trigger.isUpdate){
                Consumable_order_details2__c oObj = oldMap.get(nObj.Id);
                if ((oObj.Dealer_Returned__c != nObj.Dealer_Returned__c && nObj.Dealer_Returned__c == true)
                        && String.isNotBlank(nObj.Bar_Code__c)) {
                    // 耗材
                    barcodeList.add(nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')');
                    // 主机
                    barcodeList.add(nObj.SerialLotNo__c);
                    codReturnList.add(nObj);
                    productCodeList.add(nObj.Consumable_product__c);
                    if(String.isNotBlank(nObj.Dealer_Info_text__c)){
                        dealerNameList.add(nObj.Dealer_Info_text__c);
                    }
                }
            }
        }
        System.debug('SS-------3+ ' + barcodeList.size() + barcodeList);
        if(barcodeList.size() > 0){
            List<Asset> asslist = [select Id,Hospital__r.Name,SerialNumber,Product_Serial_No__c,AssetMark__c from asset where SerialNumber in: barcodeList];
            List<Account> acclist = [select Id,Name,Management_Code__c from Account where Name in: dealerNameList];
            Map<String,Asset> assMap = new Map<String,Asset>();
            //存在的保有设备信息  医院
            for(Asset ass : asslist){
                if(assMap.containsKey(ass.Hospital__r.Name + ass.SerialNumber)){
                    continue;
                }else{
                    assMap.put(ass.Hospital__r.Name + ass.SerialNumber, ass);
                }
            }
            //System.debug('SS-------3++ ' + assMap.size() +  assMap);
            //经销商信息
            Map<String,Account> accMap = new Map<String,Account>();
            for(Account acc : acclist){
                accMap.put(acc.Name, acc);
            }

            Map<String, Product2__c> prdsMap = new Map<String, Product2__c>([select Id,Name,Product2__c,Product2__r.Name,OT_CODE_Text__c  from Product2__c where Id in:productCodeList]);
            //System.debug('SS-------31+++ ' + codReturnList.size() + codReturnList);
            for (Consumable_order_details2__c nObj : codReturnList) {
                if(nObj.SummonsForDirction_det__c == '互相调货') continue;
                if(assMap.containsKey(nObj.Dealer_Info_text__c + nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')')) continue;
                //System.debug('SS-------31++ ' + nObj.HospItal_Name__c + nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')');
                asset ast = assMap.get(nObj.HospItal_Name__c + nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')');
                //System.debug('SS-------31++  ast ' + ast);
                // 判段是否是及主机
                if(ast == null){
                    if(assMap.containsKey(nObj.HospItal_Name__c + nObj.SerialLotNo__c) && assMap.get(nObj.HospItal_Name__c + nObj.SerialLotNo__c).AssetMark__c == '主机'){
                        ast = assMap.get(nObj.HospItal_Name__c + nObj.SerialLotNo__c);
                    }
                }
                if(ast == null){
                    ast = new asset();
                    //ast.Order_No__c  = 
                    //ast.Posting_Date__c = Date.today();

                    ast.Name                             = prdsMap.get(nObj.Consumable_product__c).Product2__r.Name;
                    ast.Product2Id                       = prdsMap.get(nObj.Consumable_product__c).Product2__c;
                    //ast.Quantity                         = nObj.Intra_Trade_List_RMB__c;
                    ast.SerialNumber                     = nObj.SerialLotNo__c  + '(' + nObj.TracingCode__c + ')';
                    ast.SLMark__c                        = 'Serial Number';         // 固定 dnInfo.SorLMark;
                    //HWAG-B9AAD9 当保有设备 的 保有设备标记 =耗材时，保修期限 =发货日
                    ast.Guarantee_period_for_products__c = nObj.Deliver_date__c;
                    //ast.Guarantee_period_for_products__c = nObj.Guarantee_period_for_products__c;
                    ast.TracingCode__c                   = nObj.TracingCode__c;
                    ast.Guaranteen_end__c                = nObj.Sterilization_limit__c;
                    ast.Barcode__c                       = nObj.Bar_Code__c;
                    ast.Product_Serial_No__c             = prdsMap.get(nObj.Consumable_product__c).OT_CODE_Text__c + ':' + nObj.SerialLotNo__c  + '(' + nObj.TracingCode__c + ')';
                }
                //医院信息
                ast.Tracing_Information_From__c          = true;
                ast.Asset_Owner__c                       = '经销商资产';
                ast.AccountId                            = ocm.Id;
                if(String.isNotBlank(nObj.Used_account__c)){
                    ast.AccountId                        = nObj.Used_account__c;
                    ast.Department_Class__c              = nObj.Used_account__c;
                }else{
                    ast.AccountId                        = accMap.get(nObj.Dealer_Info_text__c).Id;
                    ast.Department_Class__c              = accMap.get(nObj.Dealer_Info_text__c).Id;
                }
                ast.Asset_owner_delaer_name__c           = accMap.get(nObj.Dealer_Info_text__c).Id;
                ast.Hospital__c                          = accMap.get(nObj.Dealer_Info_text__c).Id;

                //ast.SerialNumber                         = nObj.SerialLotNo__c +  + '(' + nObj.TracingCode__c + ')';
                //assUplist.add(ast);
                assUpMap.put(ast.Product_Serial_No__c, ast);
            }
        }
        System.debug('SS-------3+++ ' + assUpMap.size() + assUpMap.values());
        if(assUpMap.size() > 0){
            upsert assUpMap.values();
            isRunning = true;
        }
    }

    //// 出库时，如果存在消耗品对应的Asset，则移动到出库医院下面，如果没有新建Asset。
    //// 出库时，如果互相调货，从被调货经销商，转移到调货经销商，如果没有新建Asset。
    private void arrChangeBarcode() {
        if(isRunning) return;
        List<String> barcodeList = new List<String>();
        List<Consumable_order_details2__c> saleList = new List<Consumable_order_details2__c>();
        List<Asset> assUplist = new List<Asset>();
        //获取Barcode和医院编码
        for (Consumable_order_details2__c nObj : newList) {
            Consumable_order_details2__c oObj = oldMap.get(nObj.Id);
            if ((oObj.Dealer_Arrive__c != nObj.Dealer_Arrive__c && nObj.Dealer_Arrive__c == true)
                    && oObj.Bar_Code__c != nObj.Bar_Code__c) {
                barcodeList.add(nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')');
                saleList.add(nObj);
            }
        }
        //System.debug('SS-------1' + barcodeList);
        if(barcodeList.size() > 0){
            List<Asset> asslist = [select Id,Hospital__r.Name,SerialNumber from asset where SerialNumber in: barcodeList and SerialNumber != null];
            Map<String,Asset> assMap = new Map<String,Asset>();
            //存在的保有设备信息
            //System.debug('SS-------2' + asslist);
            for(Asset ass : asslist){
                if(assMap.containsKey(ass.Hospital__r.Name + ass.SerialNumber)){
                    continue;
                }else{
                    assMap.put(ass.Hospital__r.Name + ass.SerialNumber, ass);
                }
            }
            for (Consumable_order_details2__c nObj : saleList) {
                asset ast = assMap.get(nObj.Dealer_Info_text__c + nObj.SerialLotNo__c + '(' + nObj.TracingCode__c + ')');
                //System.debug('SS-------4 ' + nObj.HospItal_Name__c + nObj.Bar_Code__c);
                if(ast != null){
                    ast.Barcode__c                       = nObj.Bar_Code__c;
                    assUplist.add(ast);
                }
            }
            //System.debug('SS-------4+ ' + assUplist);
            if(assUplist.size() > 0){
                upsert assUplist;
                isRunning = true;
            }
        }
        
    }
}