public without sharing class AssetHandler extends Oly_TriggerHandler { public static Map> queueRaesdMap; private Map newMap; private Map oldMap; private List newList; private List oldList; @TestVisible private static Set testTargetDepts; @TestVisible private static Id Account_Asset_Id; public static Boolean disabled = false; public AssetHandler() { this.newMap = (Map) Trigger.newMap; this.oldMap = (Map) Trigger.oldMap; this.newList = (List) Trigger.new; this.oldList = (List) Trigger.old; } protected override void beforeInsert() { beforeSetValue(); //动态更新 Asset的 AccountId的 Logic beforeSetAccountId(); //第一次不加变更的时候不知道第一次是多少 updateChangeQuantityReason(); } protected override void beforeUpdate() { if(!disabled){ beforeSetValue(); //动态更新 Asset的 AccountId的 Logic beforeSetAccountId(); updateChangeQuantityReason(); // 虚拟维修保修合同保修开始结束日期更新 updateMaintenance_Contract_Asset(); updateRentalCount(); } } protected override void afterInsert() { //有新的Asset的时候 暂定分配 queueRedistribution(); } protected override void afterUpdate() { if(!disabled){ mainAssetUpdateed_OneToOneRecord(); // 已经改进 Must_Input_ChangeQuantityReason 的 valida before可以完成 ChangeQuantityReason__c = '' ////入力規則によってbeforeクリアできません, cleanChangeQuantityReason(); // 清理字段「待废弃数(丢失/盘亏)修改理由」 cleanGiveupReturnReason(); //当主体参照的Asset的Last断开的时候重新寻找暂定分配 queueRedistribution(); // before では数式項目がnullの場合があります formulaToTextCheck(); // check一对一link表 checkOneToOneLink(); // 虚拟维修保修合同保修开始结束日期更新 updateMaintenance_Contract_Asset(); } } // 借出明细更新借出_分配_数(Sys)和已借出数(Sys) private void updateRentalCount() { Set idSet = new Set(); for(Id assId : this.newMap.keySet()) { if(this.newMap.get(assId).AssetManageConfirm__c && this.newMap.get(assId).Account_Management_Code__c != System.Label.Account_Asset_FJZ ) { idSet.add(assId); this.newMap.get(assId).Out_of_wh_Sys__c = 0; this.newMap.get(assId).Rental_Count_Sys__c = 0; } } if(!idSet.isEmpty()) { for (Rental_Apply_Equipment_Set_Detail__c raesd : [ SELECT Id, Shippment_loaner_time2__c, Asset__c FROM Rental_Apply_Equipment_Set_Detail__c WHERE Detail_Finish__c = false AND Asset__c IN :idSet ]) { this.newMap.get(raesd.Asset__c).Out_of_wh_Sys__c += 1; if(raesd.Shippment_loaner_time2__c != null) { this.newMap.get(raesd.Asset__c).Rental_Count_Sys__c += 1; } idSet.remove(raesd.Asset__c); } if(!idSet.isEmpty()) { // 没有字段可以完全准确地区分备品设备与耗材设备,只好把备品里没出现过的设备当成耗材来查 for (Consum_Apply_Equipment_Set_Detail__c caesd : [ SELECT Id, Shippment_loaner_time2__c, Asset__c FROM Consum_Apply_Equipment_Set_Detail__c WHERE Detail_Finish__c = false AND Asset__c IN :idSet ]) { this.newMap.get(caesd.Asset__c).Out_of_wh_Sys__c += 1; if(caesd.Shippment_loaner_time2__c != null) { this.newMap.get(caesd.Asset__c).Rental_Count_Sys__c += 1; } } } } } //多年保修 start private void updateMaintenance_Contract_Asset(){ StaticParameter.EscapeMaintenanceContractAfterUpdateTrigger = true; Set AssetIDSet = new Set(); for(Asset tempAsset : newList){ if(String.isNotBlank(tempAsset.warrantyType__c)){ AssetIDSet.add(tempAsset.id); } } if(AssetIDSet.size() > 0 ){ list MCAList = [select id,startDateGurantee__c, startDateGurantee_Text__c,endDateGurantee__c, endDateGurantee_Text__c,Return_Flag__c,ChangeAcc_flag__c, Maintenance_Price_Amount__c,Maintenance_Price_Amount_text__c, GuaranteePrice_Amount__c,GuaranteePrice_Amount_text__c from Maintenance_Contract_Asset__c where Asset__c in : AssetIDSet and Maintenance_Contract__r.RecordType.DeveloperName = 'VM_Contract' ]; if(MCAList.size() > 0){ list UpdateMcaList = new list (); for(Maintenance_Contract_Asset__c tempMCA : MCAList ){ if(tempMCA.startDateGurantee__c != tempMCA.startDateGurantee_Text__c || tempMCA.endDateGurantee__c != tempMCA.endDateGurantee_Text__c || tempMCA.Maintenance_Price_Amount__c != tempMCA.Maintenance_Price_Amount_Text__c || tempMCA.GuaranteePrice_Amount__c != tempMCA.GuaranteePrice_Amount_text__c){ UpdateMcaList.add(tempMCA); } } Oly_TriggerHandler.bypass('SetContractEstimatePriceHandler'); update UpdateMcaList; Oly_TriggerHandler.clearBypass('SetContractEstimatePriceHandler'); } } } //多年保修 end private void beforeSetValue() { for (Asset nObj : newList) { // 有线下数据, 所以不需要下面的logic //if (nObj.Quantity == null) { // nObj.Quantity = 1; //} if (Trigger.isInsert) { nObj.Last_Reserve_RAES_Detail__c = null; nObj.Last_Reserve_TAES_Detail__c = null; nObj.Pre_Reserve_RAES_Detail__c = null; nObj.Pre_Reserve_TAES_Detail__c = null; nObj.Fixture_OneToOne_Link__c = null; } if (Trigger.isUpdate) { Asset oObj = oldMap.get(nObj.Id); if (oObj.Last_Reserve_RAES_Detail__c != null && nObj.Last_Reserve_RAES_Detail__c == null && oObj.Last_Reserve_RAES_Detail_Flag__c == true) { nObj.Pre_Reserve_RAES_Detail__c = oObj.Last_Reserve_RAES_Detail__c; } if (oObj.Last_Reserve_TAES_Detail__c != null && nObj.Last_Reserve_TAES_Detail__c == null // TODO 由于__r超20,字段建不出来 // && oObj.Last_Reserve_TAES_Detail_Flag__c == true ) { nObj.Pre_Reserve_TAES_Detail__c = oObj.Last_Reserve_TAES_Detail__c; } } // 必ず最後で置く nObj.Fixture_Status2_text__c = nObj.Fixture_Status2__c; nObj.Fixture_Status3_text__c = nObj.Fixture_Status3__c; nObj.BTreeIndexKey__c = nObj.Asset_Owner__c + ':' + nObj.Asset_loaner_category__c + ':' + String.valueOf(nobj.Freeze_sign_Abandoned_Flag__c) + ':' + String.valueOf(nObj.Delete_Flag__c) + ':' + String.valueOf(nObj.AssetManageConfirm__c); if (nObj.Status == FixtureUtil.assetStatusMap.get(FixtureUtil.AssetStatus.Dai_Fei_Qi.ordinal())) { nObj.Freeze_sign__c = false; } // CHAN-CCR6MW gzw 【委托】【保有设备】保有设备发货日逻辑 start if(nObj.Posting_Date__c == null){ nObj.Posting_Date__c = Date.today(); } // CHAN-CCR6MW gzw 【委托】【保有设备】保有设备发货日逻辑 end } } // かならず before private void updateChangeQuantityReason() { for (Asset nObj : newList) { Asset oObj; String oQuantity = ''; String oAbandoned_Inventory = ''; if (Trigger.isUpdate) { oObj = oldMap.get(nObj.Id); oQuantity = oObj.Quantity == null ? '' : String.valueOf(oObj.Quantity); oAbandoned_Inventory = oObj.Abandoned_Inventory__c == null ? '' : String.valueOf(oObj.Abandoned_Inventory__c); } String nQuantity = nObj.Quantity == null ? '' : String.valueOf(nObj.Quantity); String nAbandoned_Inventory = nObj.Abandoned_Inventory__c == null ? '' : String.valueOf(nObj.Abandoned_Inventory__c); if ((oQuantity != nQuantity && String.isNotBlank(nObj.ChangeQuantityReason__c)) || Trigger.isInsert) { String rs = nObj.ChangeQuantityReason__c; nObj.ChangeQuantityHistory__c = String.format(System.Label.ChangeQuantityHistory, new String[]{oQuantity, nQuantity, rs}); // before里面入立规则过不了改到 // 已经改进 Must_Input_ChangeQuantityReason 的 valida before可以完成 ChangeQuantityReason__c = '' // nObj.ChangeQuantityReason__c = ''; } if (oAbandoned_Inventory != nAbandoned_Inventory || Trigger.isInsert) { String rs = nObj.Giveup_Return__c; nObj.ChangeAbandoned_InventoryHistory__c = String.format(System.Label.ChangeAbandoned_InventoryHistory, new String[]{oAbandoned_Inventory, nAbandoned_Inventory, rs}); } } } //// かならず afterUpdate private void cleanChangeQuantityReason() { // TODO 更新自己table 原则需要Static的Class变量(因为会有复数的Method去更新自己的) List assList = new List(); for (Asset nObj : newList) { if (String.isBlank(nObj.ChangeQuantityReason__c) == false) { assList.add(new Asset(Id = nObj.Id, ChangeQuantityReason__c = '')); } } if (!assList.isEmpty()) { update assList; } } // afterUpdate // 清理字段「待废弃数(丢失/盘亏)修改理由」 private void cleanGiveupReturnReason() { List assList = new List(); for (Asset nObj : newList) { if (String.isBlank(nObj.Giveup_Return__c) == false) { assList.add(new Asset( Id = nObj.Id, Giveup_Return__c = '')); } } if (!assList.isEmpty()) { update assList; } } // かならず after, oObj.Id と nObj.Id を使うため // Last_Reserve_RAES_Detail__c (个体管理) のlink 変わった場合、 // Fixture_OneToOne_Link__c より Asset に積み上げしている数字も連動になる、Fixture_OneToOne_Link__c を空更新 // 更新項目Fixture_OneToOne_Link__c.In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun__c = Fixture_OneToOne_Link__c.In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun_F__c private void mainAssetUpdateed_OneToOneRecord() { Set aSetIdSet = new Set(); for (Integer i = 0; i < newList.size(); i++) { Asset nObj = newList[i]; Asset oObj = oldList[i]; if (oObj.Last_Reserve_RAES_Detail__c != nObj.Last_Reserve_RAES_Detail__c) { if (String.isNotBlank(oObj.Id)) { aSetIdSet.add(oObj.Id); } if (String.isNotBlank(nObj.Id)) { aSetIdSet.add(nObj.Id); } } } if (!aSetIdSet.isEmpty()) { List oneToOneList = [ SELECT Id FROM Fixture_OneToOne_Link__c WHERE Main_Asset__c IN :aSetIdSet]; if (!oneToOneList.isEmpty()) { update oneToOneList; } } } // * 不会有暂定分配后再拿去修理的备品走重新设置暂定分配的逻辑(queueRedistribution方法) // * 理由:明细暂定分配的时候创建修理的话会报以下错误 // * 借出_分配_数 不能大于 设备的总数 ------> Asset 入力规则 You_Xiao_Ku_Cun_chk // * 暂定分配-1 // * 修理-1 // * 数量1 // * 1-1-1 = -1 // * // * 如果暂定分配想修理的话分配暂定分配的那一条明细 // * 然后再出出库前检测的时候选择NG修理 // かならず after private void queueRedistribution() { if (queueRaesdMap == null) { queueRaesdMap = new Map>(); } Map> modelNoAssetIdMap = new Map>(); Set raesdIdSet = new Set(); // List updList = new List(); String whkey = ''; for (Asset nObj : newList) { //ToDo現在排队できるのは主体だけなので,今後个体管理の附属品も排队できるの場合があったらこのIFぶんを直す必要があります if (!(nObj.Loaner_accsessary__c == false && nObj.Asset_Owner__c == 'Olympus' && nObj.Equipment_Type__c != '检测用备品' && nObj.Delete_Flag__c == False && nObj.You_Xiao_Ku_Cun__c > 0 && nObj.Freeze_sign_Abandoned_Flag__c == False) ) { continue; } String key = nObj.Fixture_Model_No_F__c; //暂定分配不看存放地 OLY_OCM-722 恢复存放地的条件 if (String.isNotBlank(nObj.Internal_asset_location__c)) { key += nObj.Internal_asset_location__c; } if (String.isNotBlank(nObj.Salesdepartment__c)) { key += nObj.Salesdepartment__c; } if (String.isNotBlank(nObj.Equipment_Type__c)) { key += nObj.Equipment_Type__c; } if (String.isNotBlank(nObj.Product_category__c)) { key += nObj.Product_category__c; } System.debug(LoggingLevel.INFO, '*** key: ' + key); //有新的Asset的时候 暂定分配 // You_Xiao_Ku_Cun__c > 0 在上面已经做了判断 if (Trigger.isInsert && String.isBlank(nObj.Last_Reserve_RAES_Detail__c)) { if (String.isBlank(nObj.Fixture_Model_No_F__c) == false) { // modelNoAssetIdMap.put(nObj.Fixture_Model_No_F__c, nObj.Id); if (modelNoAssetIdMap.containsKey(key) == false) { modelNoAssetIdMap.put(key, new Set()); } modelNoAssetIdMap.get(key).add(nObj.Id); } } //当主体参照的Asset的Last断开的时候重新寻找暂定分配 //ToDo状況確認 /* || (nObj.Asset_Owner__c != oObj.Asset_Owner__c && nObj.Asset_Owner__c == 'Olympus') || (nObj.Equipment_Type__c != oObj.Equipment_Type__c && oObj.Equipment_Type__c == '检测用备品') || (nObj.Delete_Flag__c != oObj.Delete_Flag__c && nObj.Delete_Flag__c == false) || (nObj.Freeze_sign__c != oObj.Freeze_sign__c && nObj.Delete_Flag__c == false) */ // You_Xiao_Ku_Cun__c > 0 在上面已经做了判断 else { Asset oObj = oldMap.get(nObj.Id); if (nObj.Loaner_accsessary__c == false && String.isBlank(nObj.Last_Reserve_RAES_Detail__c) && (nObj.Last_Reserve_RAES_Detail__c != oObj.Last_Reserve_RAES_Detail__c || (nObj.Asset_Owner__c != oObj.Asset_Owner__c && nObj.Asset_Owner__c == 'Olympus') //备品存放地 OLY_OCM-722 恢复存放地的条件 || (nObj.Internal_asset_location__c != oObj.Internal_asset_location__c) //备品分类并且不是 检测用备品 || (nObj.Equipment_Type__c != oObj.Equipment_Type__c && nObj.Equipment_Type__c != '检测用备品') //销售本部 || (nObj.Salesdepartment__c != oObj.Salesdepartment__c) //产品分类(GI/SP) || (nObj.Product_category__c != oObj.Product_category__c) //备品配套明细型号 || (nObj.Fixture_Model_No_F__c != oObj.Fixture_Model_No_F__c) || (nObj.Delete_Flag__c != oObj.Delete_Flag__c && nObj.Delete_Flag__c == true) || (nObj.Freeze_sign_Abandoned_Flag__c != oObj.Freeze_sign_Abandoned_Flag__c && nObj.Freeze_sign_Abandoned_Flag__c == false) ) ) { if (String.isBlank(nObj.Fixture_Model_No_F__c) == false) { if (modelNoAssetIdMap.containsKey(key) == false) { modelNoAssetIdMap.put(key, new Set()); } modelNoAssetIdMap.get(key).add(nObj.Id); } if (String.isNotBlank(oObj.Last_Reserve_RAES_Detail__c)) { raesdIdSet.add(oObj.Last_Reserve_RAES_Detail__c); } } } } if (modelNoAssetIdMap.isEmpty()) { return; } System.debug(LoggingLevel.INFO, '*** raesdIdSet: ' + JSON.serialize(raesdIdSet)); //modified by denny 2021-11-17 List keyList = new List(); keyList.addAll(modelNoAssetIdMap.keySet()); System.debug(LoggingLevel.INFO, '*** keyList: ' + keyList); List targetSequence = [SELECT Id,Apply_Set_Detail__c, Apply_Set_Detail_ExternalKey__c, Demo_Purpose2__c, Equipment_Type__c, ExternalKey__c, Fixture_Model_No__c, Internal_asset_location__c, Invalid_Flag__c, Product_category__c, Rental_Apply__c,Series_No__c, Series_Unequal_Queue_Flag__c, Salesdepartment__c FROM Rental_Apply_Sequence__c WHERE Series_No__c > 0 AND Invalid_Flag__c =false AND Apply_Set_Detail__c NOT IN:raesdIdSet AND ExternalKey__c IN:keyList ORDER BY Series_No__c ]; System.debug(LoggingLevel.INFO, '*** targetSequence: ' + targetSequence); Map> sequenceMap = new Map>(); for(Rental_Apply_Sequence__c sequeuece:targetSequence){ if(!sequenceMap.containsKey(sequeuece.Externalkey__c)){ sequenceMap.put(sequeuece.Externalkey__c,new List()); } sequenceMap.get(sequeuece.Externalkey__c).add(sequeuece); } Map updateMap = new Map(); for(String key:sequenceMap.keySet()){ for(Rental_Apply_Sequence__c sequeuece:sequenceMap.get(key)){ if(!updateMap.containsKey(sequeuece.Apply_Set_Detail__c)){ System.debug(LoggingLevel.INFO, '*** modelNoAssetIdMap: ' + JSON.serialize(modelNoAssetIdMap)); if(modelNoAssetIdMap.containsKey(key)){ List assIdList = new List(); assIdList.addAll(modelNoAssetIdMap.get(key)); String assIdbk = assIdList.get(0); Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c(); raesd.Id = sequeuece.Apply_Set_Detail__c; raesd.Asset__c = assIdbk; System.debug('raesd.Asset__c' + raesd.Asset__c); raesd.Queue_Number__c = 0; // 暂定分配 updateMap.put(raesd.Id,raesd); modelNoAssetIdMap.get(key).remove(assIdbk); if (modelNoAssetIdMap.get(key).isEmpty()) { modelNoAssetIdMap.remove(key); } System.debug(LoggingLevel.INFO, '*** modelNoAssetIdMap: ' + JSON.serialize(modelNoAssetIdMap)); } } } } System.debug(LoggingLevel.INFO, '*** updateMap.values(): ' + JSON.serialize(updateMap.values())); update updateMap.values(); // Fixture_Model_No_F__c を見ることができない、データがおおいので。 // Fixture_Set_Detail__r.Fixture_Model_No_F__c をみるか Fixture_Model_No_text__c をみるか // whkey += ' ('; // whkey += ' ((Fixture_Set_Detail__c != null and Fixture_Set_Detail__r.Product2__r.Fixture_Model_No_T__c =\'' + String.escapeSingleQuotes(nObj.Fixture_Model_No_F__c) + '\')'; // whkey += ' OR Fixture_Model_No_text__c =\'' + String.escapeSingleQuotes(nObj.Fixture_Model_No_F__c) + '\''; // whkey += ' )'; // String wher = ''; // //暂定分配不看存放地 OLY_OCM-722 恢复存放地的条件 // if (String.isNotBlank(nObj.Internal_asset_location__c)) { // wher += ' and Internal_asset_location_before__c =\'' + String.escapeSingleQuotes(nObj.Internal_asset_location__c) + '\''; // } // if (String.isNotBlank(nObj.Salesdepartment__c)) { // wher += ' and Salesdepartment_before__c =\'' + String.escapeSingleQuotes(nObj.Salesdepartment__c) + '\''; // } // if (String.isNotBlank(nObj.Product_category__c)) { // wher += ' and Product_category_text__c =\'' + String.escapeSingleQuotes(nObj.Product_category__c) + '\''; // } // if (String.isNotBlank(nObj.Equipment_Type__c)) { // wher += ' and Equipment_Type_text__c =\'' + String.escapeSingleQuotes(nObj.Equipment_Type__c) + '\''; // } // whkey += wher + ' ) OR'; // } // if (String.isNotBlank(whkey)) { // whkey = '( ' + whkey.removeEnd('OR') + ')'; // } // String soql = 'SELECT Fixture_Model_No_F__c, Substitute_flag__c, Asset__c,' // + ' Queue_Number__c, Fixture_Model_No_text__c, Salesdepartment_before__c,' // + ' Product_category_text__c, Equipment_Type_text__c, Internal_asset_location_before__c' // + ' FROM Rental_Apply_Equipment_Set_Detail__c' // + ' where Id != :raesdIdSet and ' // + whkey // + ' and Queue_Number__c > 0' // + ' and Cancel_Select__c = false' // + ' order by Queue_Number__c ASC'; // System.debug('whkey' + whkey); // System.debug('soql' + soql); // List targetRaesd = Database.query(soql); // System.debug('targetRaesd' + targetRaesd); // for (Rental_Apply_Equipment_Set_Detail__c raesd : targetRaesd) { // // TODO Fixture_Set_Detail__c に チェック追加 Rental_Apply_Equipment_Set_Detail__c 新数据, 有 没有分配(分配时间) 的话, 不能 Delete Fixture_Set_Detail__c // String key = ''; // if (raesd.Substitute_flag__c) { // key = raesd.Fixture_Model_No_text__c; // } else { // key = raesd.Fixture_Model_No_F__c; // } // //暂定分配不看存放地 OLY_OCM-722 恢复存放地的条件 // if (String.isNotBlank(raesd.Internal_asset_location_before__c)) { // key += '_' + raesd.Internal_asset_location_before__c; // } // if (String.isNotBlank(raesd.Salesdepartment_before__c)) { // key += '_' + raesd.Salesdepartment_before__c; // } // if (String.isNotBlank(raesd.Product_category_text__c)) { // key += '_' + raesd.Product_category_text__c; // } // if (String.isNotBlank(raesd.Equipment_Type_text__c)) { // key += '_' + raesd.Equipment_Type_text__c; // } // if (queueRaesdMap.containsKey(key) == false) { // queueRaesdMap.put(key, new List()); // } // queueRaesdMap.get(key).add(raesd); // } // System.debug('queueRaesdMap' + queueRaesdMap); // System.debug('modelNoAssetIdMap' + modelNoAssetIdMap); // List uplist = new List(); // for (String raesdkey : queueRaesdMap.keySet()) { // for (Rental_Apply_Equipment_Set_Detail__c raesd : queueRaesdMap.get(raesdkey)) { // System.debug(raesdkey); // // 这里的queueRaesdMap在用完后没有清空,导致与最新查出的targetRaesd不一致 // // 担心直接清空会造成其它问题,所以加or来保证明细的Asset__c只会被更新一次 // if (modelNoAssetIdMap.containsKey(raesdkey) == false || String.isNotBlank(raesd.Asset__c)) { // // 基本発生しない、queueRaesdMap <= modelNoAssetIdMap // continue; // } // Id assIdbk; // for (Id assId : modelNoAssetIdMap.get(raesdkey)) { // assIdbk = assId; // raesd.Asset__c = assId; // System.debug('raesd.Asset__c' + raesd.Asset__c); // raesd.Queue_Number__c = 0; // 暂定分配 // uplist.add(raesd); // System.debug('raesd Idis' + raesd.Id); // break; // } // modelNoAssetIdMap.get(raesdkey).remove(assIdbk); // if (modelNoAssetIdMap.get(raesdkey).isEmpty()) { // modelNoAssetIdMap.remove(raesdkey); // } // } // } // //排队更新 // if (!uplist.isEmpty()) { // update uplist; // } } //before 数式の値がnullになる可能性がありますのでここでも一回チェックします private void formulaToTextCheck() { List assets = new List(); for (Asset nObj : newList) { if (nObj.Fixture_Status2_text__c != nObj.Fixture_Status2__c) { Asset ass = new Asset(Id = nObj.Id); ass.Fixture_Status2_text__c = nObj.Fixture_Status2__c; assets.add(ass); } } if (!assets.isEmpty()) { update assets; } } private void checkOneToOneLink() { Set otoIds = new Set(); // 待删除link的Id Set assetIds = new Set(); Set centers = new Set {'北京 备品中心', '上海 备品中心', '广州 备品中心'}; for (Asset nObj : newList) { //待废弃,废弃,和数量0的备品需要断开一对一link (目前只处理个体管理的) if ((nObj.Fixture_Status__c == FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Fei_Qi.ordinal()) || nObj.Fixture_Status__c == FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Dai_Fei_Qi.ordinal()) || nObj.Quantity == 0) && nObj.Manage_type__c == FixtureUtil.managetypeMap.get(FixtureUtil.Managetype.Ge_Ti_Guan_Li)){ //是一对一主体或者是一对一个体附属品 if (nObj.Main_OneToOne__c == true || nObj.Fixture_OneToOne_Link__c <> null) { if(centers.contains(nObj.Internal_asset_location__c)) { assetIds.add(nObj.Id); } } } } if (assetIds.size() > 0) { Map linkMap = new Map([ SELECT Id FROM Fixture_OneToOne_Link__c WHERE Main_Asset__c in :assetIds OR Accessory_Asset__c IN: assetIds ]); if(!linkMap.isEmpty()){ delete linkMap.values(); } } } /** * 动态设定 Asset.AccountId (备品共享_杭州_华东营业本部) * Condition: * - before insert, before update * - 确认字段变化 (保有设备的备品存放地(Internal_asset_location__c)+所在地区(本部)(Salesdepartment__c)) * - Salesdepartment__c IN ('1.华北营业本部','2.东北营业本部','3.西北营业本部','4.华东营业本部','5.华南营业本部','6.西南营业本部') * - Asset 是 办事处备品 * Execute: * - 找 Label: OCM_Management_Province_Mapping, 的 办事处, 设定 AccountId * - 没有找的话, 不更新AccountId, 自动做 Account, Group, ApexShare */ private void beforeSetAccountId() { Set targetDepts = new Set {'1.华北营业本部','2.东北营业本部','3.西北营业本部','4.华东营业本部','5.华南营业本部','6.西南营业本部'}; Set targetCenters = new Set {'北京 备品中心', '上海 备品中心', '广州 备品中心'}; if (Test.isRunningTest() && testTargetDepts != null) { targetDepts = testTargetDepts; } // 存放地 → 省 的 Map Map targetProvs = AssetWebService.getOcmMgtProvMap(); // 收集对象 Asset Map assetAccShareNameMap = new Map(); Datetime execNow = System.now(); for (Asset nObj : newList) { Asset oObj = (null == this.oldMap) ? null : this.oldMap.get(nObj.Id); // 作成, 确认字段有没有变化 if (Trigger.isInsert || (oObj != null && (oObj.RecordTypeId != nObj.RecordTypeId || oObj.Asset_loaner_category__c != nObj.Asset_loaner_category__c || oObj.AssetManageConfirm__c != nObj.AssetManageConfirm__c || oObj.Internal_asset_location__c != nObj.Internal_asset_location__c || oObj.Salesdepartment__c != nObj.Salesdepartment__c || oObj.OlympusAccShareName__c != nObj.OlympusAccShareName__c ) && (targetCenters.contains(nObj.Internal_asset_location__c) || targetProvs.containsKey(nObj.Internal_asset_location__c) ) && !nObj.TransferToOther__c ) ) { // 是不是备品的确认 if (System.Label.Asset_RecordType == nObj.RecordTypeId && true == nObj.AssetManageConfirm__c && nObj.Asset_loaner_category__c != '耗材' ) { // 办事处备品 → 动态设定 Asset.AccountId 的対象 if (targetProvs.containsKey(nObj.Internal_asset_location__c) && targetDepts.contains(nObj.Salesdepartment__c) ) { String accShareName = '备品共享_' + targetProvs.get(nObj.Internal_asset_location__c) + '_' + nObj.Salesdepartment__c.right(6); nObj.OlympusAccShareName__c = accShareName; assetAccShareNameMap.put(nObj, accShareName); } else { if (AssetHandler.Account_Asset_Id == null) { // Static 只会执行一遍 AssetHandler.Account_Asset_Id = [SELECT Id FROM Account WHERE AgentCode_Ext__c =: System.Label.Account_Asset].Id; } nObj.OlympusAccShareName__c = ''; nObj.AccountId = AssetHandler.Account_Asset_Id; } } else { // 更新成 不是备品 的时候, 更新的程序里 要 care AccountId nObj.OlympusAccShareName__c = ''; } } } // check 是不是 accShareName 都有 Set insertAccShareNameSet = new Set(); if (assetAccShareNameMap.size() > 0) { Map accShareId = new Map(); for (Account accShare : [SELECT Id , Department_Name__c FROM Account WHERE RecordTypeId =: System.Label.Department_OTH AND Department_Name__c IN: assetAccShareNameMap.values()]) { accShareId.put(accShare.Department_Name__c, accShare.Id); } // assetAccShareNameMap 的 Key会有变化 // 这个 for loop后 就不能使用 assetAccShareNameMap.get(XXXX) 了 for (Asset nObj : assetAccShareNameMap.keySet()) { String accShareName = assetAccShareNameMap.get(nObj); if (accShareId.containsKey(accShareName)) { // 找到 Account 设定 AccountId, "Olympus社内 其他 备品" => "Olympus社内 其他 备品共享_XXX" nObj.AccountId = accShareId.get(accShareName); } else { // 找不到 AccountId, 新建 Account, Group, ApexShare insertAccShareNameSet.add(accShareName); } } } if (insertAccShareNameSet.size() > 0) { // AssetHandler.futureInsertAccShare(JSON.serialize(insertAccShareNameSet), execNow); System.enqueueJob(new MyQueueableClass(JSON.serialize(insertAccShareNameSet), execNow)); } } /** * 新建 备品共享_XXX 客户数据 * @param insertAccShareNameJson Json String of List ["备品共享_XXX", "备品共享_YYY"] */ private static void insertAccShare(String insertAccShareNameJson, Datetime execNow) { Set insertAccShareNameSet = (Set) JSON.deserialize(insertAccShareNameJson, Set.class); if (insertAccShareNameSet.isEmpty()) { return; } // Olympus社内 其他 List olympusAccount_OtherDC; try { olympusAccount_OtherDC = [SELECT Id, ParentId FROM Account WHERE Parent.AgentCode_Ext__c = '9999999' AND Department_Class_Name__c = '其他' FOR Update]; } catch (Exception e) { System.enqueueJob(new MyQueueableClass(insertAccShareNameJson, execNow)); return; } List isInsertedList = [SELECT Id, Department_Name__c FROM Account WHERE ParentId =: olympusAccount_OtherDC[0].Id AND Department_Name__c IN: insertAccShareNameSet]; if (isInsertedList.size() > 0) { Map insertedAccount = new Map(); for (Account insertedAcc : isInsertedList) { insertedAccount.put(insertedAcc.Department_Name__c, insertedAcc); insertAccShareNameSet.remove(insertedAcc.Department_Name__c); } // Update Asset.AccountId AssetHandler.updateAssetAccount(insertedAccount, execNow); } if (insertAccShareNameSet.size() > 0) { Map insertAccount = new Map(); for (String accShareName : insertAccShareNameSet) { insertAccount.put(accShareName, new Account( Name = '*', Hospital__c = olympusAccount_OtherDC[0].ParentId, ParentId = olympusAccount_OtherDC[0].Id, Department_Class__c = olympusAccount_OtherDC[0].Id, Other_dept_category__c = '其他科室', Department_Name__c = accShareName, OwnerId = System.Label.Batch_User_Id, RecordTypeId = System.Label.Department_OTH )); } AssetHandler.insertAccGrantShare(insertAccount, execNow); } } private static void insertAccGrantShare(Map insertAccountMap, Datetime execNow) { if (insertAccountMap.isEmpty()) { return; } Set accShareNameSet = insertAccountMap.keySet(); // insert Account的时候, 跳过 NFM001 // OLY_OCM-1230 需要执行NFM001Trigger // ControllerUtil.EscapeNFM001Trigger = true; insert insertAccountMap.values(); Map insertGroup = new Map(); Map groupNameMap = new Map(); for (String accShareName : accShareNameSet) { insertGroup.put(accShareName, new Group( Name = accShareName )); } // Check 有没有 Group for (Group grp : [SELECT Id, Name FROM Group WHERE Type = 'Regular' AND Name IN: accShareNameSet]) { // 已经有Group 的话 不用 insert insertGroup.remove(grp.Name); groupNameMap.put(grp.Name, grp); } if (insertGroup.size() > 0) { insert insertGroup.values(); // groupNameMap 含 所有 accShareNameSet 的 Group, 并且 都有 Id groupNameMap.putAll(insertGroup); } // 赋 Account 共享权限 List insertShareList = new List(); for (String accShareName : accShareNameSet) { insertShareList.add(new AccountShare( UserOrGroupId = groupNameMap.get(accShareName).Id, AccountId = insertAccountMap.get(accShareName).Id, AccountAccessLevel = 'Edit', OpportunityAccessLevel = 'None' )); } insert insertShareList; // Update Asset.AccountId AssetHandler.updateAssetAccount(insertAccountMap, execNow); } private static void updateAssetAccount(Map accShareNameAccountMap, Datetime execNow) { if (accShareNameAccountMap.isEmpty()) { return; } Set accShareNameSet = accShareNameAccountMap.keySet(); List updAssetAccount = new List(); for (Asset nObj : [SELECT Id, OlympusAccShareName__c, AccountId FROM Asset WHERE OlympusAccShareSameFlag__c = '0' AND OlympusAccShareName__c IN: accShareNameSet AND LastModifiedDate >=: execNow]) { nObj.AccountId = accShareNameAccountMap.get(nObj.OlympusAccShareName__c).Id; updAssetAccount.add(nObj); } update updAssetAccount; } @TestVisible class MyQueueableClass implements Queueable { String insertAccShareNameJson; Datetime execNow; public MyQueueableClass(String insertAccShareNameJson, Datetime execNow) { this.insertAccShareNameJson = insertAccShareNameJson; this.execNow = execNow; } public void execute(QueueableContext context) { AssetHandler.insertAccShare(insertAccShareNameJson, execNow); } } }