@RestResource(urlMapping = '/NFM204/*') global with sharing class NFM204Rest { global class GeDatas { public NFMUtil.Monitoring Monitoring; public GeData[] GeData; } global class GeData { public String MaterialGroup; //物料组 public String MaterialNo; //物料号 public String MaterialStatus; //物料状态 public String RegisterNo; //注册证号 public String RegisterNoClass_New; //注册证号经营范围编号(新) public String RegisterNoClass_Old; //注册证号经营范围编号(旧) public String RegisterNoStatus; //注册证号状态 public String ValidFrom; //注册证号效期从 public String ValidTo; //注册证号效期至 public String MedPrdClass; //医疗器械分类 public String BusinessScope; //经营范围 public String Model; //产品型号 public String ProductName; //产品名称(委托产品名称) public String PrdCompanyLicense; //生产企业许可证号/备案凭证号 public String PrdCompanyAddr; //生产企业地址 public String Unit; //单位(基本单位) public String StroageCondition; //储存条件 public String TransCondition; //运输条件 public String Z3PLAuthorized; //是否3PL委托产品 public String AuthorizedCompany; //委托方企业名称 public String Z3PLAuthorizedNo; //3PL业务委托协议号 public String ApprovedDate; //委托批准日期 public String PrdValidFrom; //委托产品效期从 public String PrdValidTo; //委托产品效期至 public String AuthorizedCompany_SH; public String ApprovedDate_SH; public String YXQX; public String MaterialStatusType; // 状态 1:只更新物料状态;2:只更新注册证状态;其它状态(全都更新) public String IsPrediscontinued; //是否预停产 MaterialStatusType==1&&IsPrediscontinued==1时更新PreDiscontinuedDatetime public String PreDiscontinuedDatetime;//预停产时间 public String Other1; public String Other2; public String Other3; // 20190219 Add public String APP_NAME_BJ; // 北京首营审核人 public String APP_DATE_BJ; // 北京审核日期 public String APP_RSLT_BJ; // 北京首营审核结果 public String APP_NAME_SH; // 上海首营审核人 public String APP_DATE_SH; // 上海审核日期 public String APP_RSLT_SH; // 上海首营审核结果 public String APP_NAME_GZ; // 广州首营审核人 public String APP_DATE_GZ; // 广州审核日期 public String APP_RSLT_GZ; // 广州首营审核结果 public String APP_NAME_OSH; // OSH首营审核人 public String APP_DATE_OSH; // OSH审核日期 public String APP_RSLT_OSH; // OSH首营审核结果 //2019/4/10 Add public String REG_Name; // 注册人名称 public String REG_ADD; // 注册人住所 public String PROD_ADD; // 生产地址 public String STRU_COM; // 结构及组成 public String ADOPT_RANGE; // 适用范围 //2019/11/28 Add public String ClinicalCode; //型号规格 //2019/11/28 End //20220329 WLIG-CCTA6G you public String CertificateNo;//3C证书编号 public String EffectiveFrom;//3C证书效期从 public String EffectiveTo;//3C证书效期至 } @HttpPost global static void execute() { // 取得接口传输内容 String strData = RestContext.request.requestBody.toString(); GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class); if (ges == null ) { return; } NFMUtil.Monitoring Monitoring = ges.Monitoring; if (Monitoring == null) { return; } BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM204', ges.GeData); if (String.isBlank(rowData.Log__c) == false) { executefuture(rowData.Id); } // JSONを戻す RestResponse res = RestContext.response; res.addHeader('Content-Type', 'application/json'); res.statusCode = 200; String jsonResponse = '{"status": "Success", "Message":""}'; res.responseBody = blob.valueOf(jsonResponse); return; } @future global static void executefuture(String rowData_Id) { main(rowData_Id); } global static void main (String rowData_Id) { Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt); BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c from BatchIF_Log__c where RowDataFlg__c = true and Id = :rowData_Id]; String logstr = rowData.MessageGroupNumber__c + ' start\n'; BatchIF_Log__c iflog = new BatchIF_Log__c(); iflog.Type__c = 'NFM204'; iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c; iflog.Log__c = logstr; iflog.ErrorLog__c = ''; insert iflog; String rowDataStr = NFMUtil.getRowDataStr(rowData); List GeDataList = (List) JSON.deserialize(rowDataStr, List.class); if (GeDataList == null || GeDataList.size() == 0) { return; } // BatchIF転送表 から、コード変換のMapを作成 Map transferMap = new Map(); List transferList = [select Table__c, Column__c, External_value__c, Internal_value__c from BatchIF_Transfer__c where Dropped_Flag__c = false and (Table__c = 'Product_Register__c' or Table__c = 'Product2')]; for (BatchIF_Transfer__c t : transferList) { transferMap.put(t.Column__c + t.External_value__c, t.Internal_value__c); } Savepoint sp = Database.setSavepoint(); try { List productNoList = new List(); //根据 产品注册证名称与有效期从 制作MD5编码 用于查询 List mD5KeyList = new List(); List mD5KeyDeleteList = new List(); // 设置 产品 Date startDate = Date.newInstance(1900, 1, 1); String ValidFrom = ''; String ValidTo = ''; String RegisterNo = ''; Boolean typeIs_Not_1 = false; Boolean typeIs_null = false; for (GeData data : GeDataList) { // 产品Code的List (只更新注册证状态时,不更新产品) if (data.MaterialStatusType != '2' && String.isNotBlank(data.MaterialNo)) { productNoList.add(data.MaterialNo); } // FYL产品注册证 无 注册证号效期从和 注册证号效期至 SFDC做特殊处理 if ('FYL'.equals(data.RegisterNo)) { data.ValidFrom = '19000101'; data.ValidTo = '40001231'; } // 注册证号List(只更新产品状态时,不更新注册证) if (data.MaterialStatusType != '1' && String.isNotBlank(data.RegisterNo) && String.isNotBlank(data.ValidFrom) && String.isNotBlank(data.ValidTo)) { typeIs_Not_1 = true; // mD5KeyList.add(MD5Encrypt(data.RegisterNo,data.ValidFrom,data.ValidTo)); } // 删除产品注册证关系 if (data.MaterialStatusType != '1' && data.MaterialStatusType != '2' && String.isNotBlank(data.RegisterNo) && String.isNotBlank(data.ValidFrom) && String.isNotBlank(data.ValidTo)) { typeIs_null = true; // mD5KeyDeleteList.add(MD5Encrypt(data.RegisterNo,data.ValidFrom,data.ValidTo)); } if (typeIs_Not_1 || typeIs_null) { Date startOfDay = NFMUtil.parseStr2Date(data.ValidFrom,false); // 取 产品注册证 最大的有效期从 if (startOfDay >= startDate) { startDate = startOfDay; ValidFrom = data.ValidFrom; ValidTo = data.ValidTo; RegisterNo = data.RegisterNo; } } } if (typeIs_Not_1) { mD5KeyList.add(MD5Encrypt(RegisterNo,ValidFrom,ValidTo)); } if (typeIs_null) { mD5KeyDeleteList.add(MD5Encrypt(RegisterNo,ValidFrom,ValidTo)); } Map productMap = new Map(); Map registerMap = new Map(); Map prlinkMap = new Map(); // 产品 List productList = [select id, ProductCode,ProduceCompany__c,ProduceCompany2__c,ProduceCompany3__c,M_BC_Stop_manufacure__c,CertificateNo__c,EffectiveFrom__c,EffectiveTo__c from Product2 where ProductCode = :productNoList]; for (Product2 product : productList) { productMap.put(product.ProductCode, product); } // 注册证 List registerList = [select id, Name,MD5EncryptionKey__c,PrdCompanyAddr__c,PrdCompanyAddr2__c,PrdCompanyAddr3__c from Product_Register__c where MD5EncryptionKey__c = :mD5KeyList]; for (Product_Register__c register : registerList) { registerMap.put(register.MD5EncryptionKey__c, register); } // Link List prlinkList = new List(); // 单独更新注册证和单独更新产品的场合,不更新link。 prlinkList = [select id, //If_Delete__c, Product2__c, Product2__r.ProductCode, Product_Register__c, Product_Register__r.RegisterNoStatus__c, Product_Register__r.Name, Product_Register__r.MD5EncryptionKey__c from Product_Register_Link__c where //Product2__r.ProductCode in :productNoList and Product_Register__r.MD5EncryptionKey__c in :mD5KeyDeleteList //and If_Delete__c = false ]; for (Product_Register_Link__c prlink : prlinkList) { prlinkMap.put(prlink.Product2__r.ProductCode + '_' + prlink.Product_Register__r.MD5EncryptionKey__c, prlink); } system.debug('=====productMap:' + productMap); system.debug('=====registerMap:' + registerMap); system.debug('=====prlinkMap:' + prlinkMap); Map upd_productMap = new Map(); Map ups_registerMap = new Map(); Map ins_linkMap = new Map(); for (GeData data : GeDataList) { Product2 prd = new Product2(); Product_Register__c pr = new Product_Register__c(); // 产品Code的List (只更新注册证状态时,不更新产品) if (data.MaterialStatusType != '2' && String.isNotBlank(data.MaterialNo)) { // 检查物料在系统中是否存在 prd = productMap.get(data.MaterialNo); if (productMap.containsKey(data.MaterialNo)) { prd = productMap.get(data.MaterialNo); } else { iflog.ErrorLog__c += 'OTCode[' + data.MaterialNo + ']不存在\n'; continue; } // XHL 20211008 Start 只更新 预计停止日期 // MaterialStatusType==1&&IsPrediscontinued==1时更新PreDiscontinuedDatetime(其余产品字段都不更新) if ('1'.equals(data.MaterialStatusType) && '1'.equals(data.IsPrediscontinued)) { String preDiscontinuedDatetime = data.PreDiscontinuedDatetime; if (String.isBlank(preDiscontinuedDatetime) || '00000000'.equals(preDiscontinuedDatetime)) { prd.M_BC_Stop_manufacure__c = null; } else { prd.M_BC_Stop_manufacure__c = NFMUtil.parseStr2Date(preDiscontinuedDatetime, false); // IdList.add(prd.Id); } upd_productMap.put(data.MaterialNo, prd); logstr += 'Product:' + data.MaterialNo; continue; } // XHL 20211008 End 只更新 预计停止日期 // 更新物料产品状态 prd.Product_Status__c = NFMUtil.getMapValue(transferMap, 'Product_Status__c', data.MaterialStatus, iflog); if (data.RegisterNo == 'FYL') { //CHAN-C4X63A 【委托】NFM204字段“生产企业地址”优化 XHL 20210716 Start String prdCompanyAddr = data.PrdCompanyAddr; prd.ProduceCompany__c = null; prd.ProduceCompany2__c = null; prd.ProduceCompany3__c = null; if (String.isNotBlank(prdCompanyAddr)){ if (prdCompanyAddr.length()<=765 && prdCompanyAddr.length() > 255 ) { Map resultMap = new Map(); resultMap = prdCompanyAddrSub(prdCompanyAddr,resultMap,1); prd = getProduceCompany(resultMap,prd); } else { prd.ProduceCompany__c = prdCompanyAddr; } } //CHAN-C4X63A 【委托】NFM204字段“生产企业地址”优化 XHL 20210716 End //20200804 ljh add start if (data.MaterialGroup != null) { prd.Is_DangerousChemicals__c = data.MaterialGroup.equals('DG') ? true : false; } //20200804 ljh add end } upd_productMap.put(data.MaterialNo, prd); logstr += 'Product:' + data.MaterialNo; } // 注册证号List(只更新产品状态时,不更新注册证) if (data.MaterialStatusType != '1' && String.isNotBlank(data.RegisterNo) && data.RegisterNo != 'FYL' && String.isNotBlank(data.ValidFrom) && String.isNotBlank(data.ValidTo)) { string md5key = MD5Encrypt(RegisterNo,ValidFrom,ValidTo); // 新建或更新注册证 if (registerMap.containsKey(md5key)) { pr = registerMap.get(md5key); } if (data.MaterialStatusType != '2') { //CHAN-C4X63A 【委托】NFM204字段“生产企业地址”优化 XHL 20210716 Start String prdCompanyAddr = data.PrdCompanyAddr; pr.PrdCompanyAddr__c = null; pr.PrdCompanyAddr2__c = null; pr.PrdCompanyAddr3__c = null; if (String.isNotBlank(prdCompanyAddr)){ if (prdCompanyAddr.length()<=765 && prdCompanyAddr.length() > 255 ) { Map resultMap = new Map(); resultMap = prdCompanyAddrSub(prdCompanyAddr,resultMap,1); pr = getPrdCompanyAddr(resultMap,pr); } else { pr.PrdCompanyAddr__c = prdCompanyAddr; } } //CHAN-C4X63A 【委托】NFM204字段“生产企业地址”优化 XHL 20210716 End pr.Name = RegisterNo; //注册证号 pr.IsFromSPO__c = true; pr.RegisterNoClass_New__c = data.RegisterNoClass_New; //注册证号分类编号(新) pr.RegisterNoClass_Old__c = data.RegisterNoClass_Old; //注册证号分类编号(旧) pr.ValidFrom__c = NFMUtil.parseStr2Date(ValidFrom); //注册证号效期从 pr.ValidTo__c = NFMUtil.parseStr2Date(ValidTo); //注册证号效期至 pr.MedPrdClass__c = data.MedPrdClass; //医疗器械分类 //pr.BusinessScope__c = data.BusinessScope; //经营范围 pr.PrdCompanyLicense__c = data.PrdCompanyLicense; //生产企业许可证号/备案凭证号 //pr.PrdCompanyAddr__c = data.PrdCompanyAddr; //生产企业地址 pr.MD5EncryptionKey__c = md5key; } // 2的场合 只更新注册证状态 pr.RegisterNoStatus__c = NFMUtil.getMapValue(transferMap, 'RegisterNoStatus__c', data.RegisterNoStatus, iflog); if (String.isNotBlank(pr.Name)) { ups_registerMap.put(md5key, pr); logstr += ' Register:' + data.RegisterNo + '\n'; } else { logstr += ' Register:' + data.RegisterNo + '不存在,请检查接口数据是否正确\n'; } } // 20220329 WLIG-CCTA6G you start //MaterialStatusType为空时,产品注册证和产品都更新 if(String.isBlank(data.MaterialStatusType) && upd_productMap.containsKey(data.MaterialNo)){ prd = upd_productMap.get(data.MaterialNo); prd.CertificateNo__c = data.CertificateNo; prd.EffectiveFrom__c = NFMUtil.parseStr2Date(data.EffectiveFrom, false); prd.EffectiveTo__c = NFMUtil.parseStr2Date(data.EffectiveTo, false); upd_productMap.put(data.MaterialNo, prd); } // 20220329 WLIG-CCTA6G you end } //logstr += ups_registerMap; system.debug('ups_registerMap--->'+ups_registerMap); if (upd_productMap.keySet().size() > 0) update upd_productMap.values(); if (ups_registerMap.keySet().size() > 0) upsert ups_registerMap.values(); // 删除注册证号下所有物料 List delList = new List(); for (Product_Register_Link__c prlc : prlinkList) { if (prlc.Product_Register__r.RegisterNoStatus__c != '不要') { // prlc.If_Delete__c = true; delList.add(prlc); } } if (delList.size() > 0 ) delete delList; // 取得所有注册证ID List registerList2 = [select id, Name,MD5EncryptionKey__c from Product_Register__c where MD5EncryptionKey__c = :mD5KeyList]; for (Product_Register__c register : registerList2) { registerMap.put(register.MD5EncryptionKey__c, register); } // 产品和注册证关系表 for (GeData data : GeDataList) { if (!productMap.containsKey(data.MaterialNo)) { // 产品不存在的场合 continue; } if (data.MaterialStatusType == '1' || data.MaterialStatusType == '2') { // 只更新物料状态或者产品注册证的场合 continue; } // FYL产品注册证 无 注册证号效期从和注册证号效期至 SFDC做特殊处理 if ('FYL'.equals(data.RegisterNo)) { data.ValidFrom = '19000101'; data.ValidTo = '40001231'; } if (String.isBlank(data.ValidFrom) || String.isBlank(data.ValidTo)) { continue; } // 非医疗不要注册证的场合 String md5key = MD5Encrypt(RegisterNo,ValidFrom,ValidTo); if ((data.RegisterNoStatus == '50') && (prlinkMap.get(data.MaterialNo + '_' + md5key) != null)) { continue; } String prlink = data.MaterialNo + '_' + data.RegisterNo; Product_Register_Link__c prl = new Product_Register_Link__c(); prl.Product2__c = productMap.get(data.MaterialNo).id; prl.Product_Register__c = registerMap.get(md5key).id; prl.If_Delete__c = false; ins_linkMap.put(prlink, prl); } if (ins_linkMap.keySet().size() > 0) insert ins_linkMap.values(); logstr += '\nend'; rowData.retry_cnt__c = 0; } catch (Exception ex) { // エラーが発生した場合 Database.rollback(sp); System.debug(Logginglevel.ERROR, 'NFM204_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage()); System.debug(Logginglevel.ERROR, 'NFM204_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString()); logstr += '\n' + ex.getMessage(); iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c; if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0; if (rowData.retry_cnt__c < batch_retry_max_cnt) { rowData.retry_cnt__c++; LogAutoSendSchedule.assignOneMinute(); } if (rowData.retry_cnt__c >= batch_retry_max_cnt) { rowData.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowData.ErrorLog__c + '错误次数已经超过自动收信设定的最大次数,请手动收信'; } } update rowData; iflog.Log__c = logstr; if (iflog.Log__c.length() > 131072) { iflog.Log__c = iflog.Log__c.subString(0, 131065) + ' ...'; } if (iflog.ErrorLog__c.length() > 32768) { iflog.ErrorLog__c = iflog.ErrorLog__c.subString(0, 32760) + ' ...'; } update iflog; } /** * 以产品注册证号+效期从+效期至 。进行MD5加密作为产品注册证的唯一标识 * @Author XHL * @DateTime 2021-06-28 * @param RegisterNo [注册证名称] * @param ValidFrom [注册证号效期从] * @param ValidTo [注册证号效期至] * @return [根据三个参数转成的MD5码] */ public static String MD5Encrypt(String RegisterNo,String ValidFrom,String ValidTo){ if (String.isBlank(RegisterNo) || String.isBlank(ValidFrom) || String.isBlank(ValidTo)) { return null; } String result = ''; //注册证号效期从 Date startOfDay = NFMUtil.parseStr2Date(ValidFrom,false); //注册证号效期至 Date endOfDay = NFMUtil.parseStr2Date(ValidTo,false); //时间戳 Long timestampStart = Datetime.newInstanceGmt(startOfDay.year(), startOfDay.Month(),startOfDay.Day(), 0, 0, 0).getTime(); Long timestampEnd = Datetime.newInstanceGmt(endOfDay.year(), endOfDay.Month(),endOfDay.Day(), 0, 0, 0).getTime(); //MD5转化 String md5key = RegisterNo + timestampStart + timestampEnd; String mD5EncryptionKey = EncodingUtil.convertToHex(Crypto.generateDigest('MD5', Blob.valueOf(md5key))).toUpperCase(); result = mD5EncryptionKey; system.debug('result---->'+result); return result; } /** * 截取生产企业地址 //CHAN-C4X63A 【委托】NFM204字段“生产企业地址”优化 XHL 20210716 * @Author XHL * @DateTime 2021-07-16 * @param prdCompanyAddr [生产企业地址] * @param resultMap [截取的地址] * @param mapKey [] * @return [description] */ public static Map prdCompanyAddrSub(String prdCompanyAddr,Map resultMap,Integer mapKey){ if (prdCompanyAddr.length() > 255) { String result = prdCompanyAddr.substring(0,255); resultMap.put(mapKey,result); prdCompanyAddr = prdCompanyAddr.substring(255,prdCompanyAddr.length()); mapKey++; resultMap = prdCompanyAddrSub(prdCompanyAddr,resultMap,mapKey); } else { if (prdCompanyAddr.length() > 0) { resultMap.put(mapKey,prdCompanyAddr); } } return resultMap; } /** * 产品注册证 生产企业地址字段赋值//CHAN-C4X63A 【委托】NFM204字段“生产企业地址”优化 XHL 20210716 * @Author XHL * @DateTime 2021-07-16 * @param resultMap [description] * @param pr [description] * @return [description] */ public static Product_Register__c getPrdCompanyAddr(Map resultMap,Product_Register__c pr){ for(Integer i :resultMap.keySet()){ String address = resultMap.get(i); switch on i { when 1 { pr.PrdCompanyAddr__c = address; } when 2 { pr.PrdCompanyAddr2__c = address; } when 3 { pr.PrdCompanyAddr3__c = address; } } } return pr; } /** * 产品 生产企业字段赋值 //CHAN-C4X63A 【委托】NFM204字段“生产企业地址”优化 XHL 20210716 * @Author liukai * @DateTime 2021-07-16 * @param resultMap [description] * @param prd [description] * @return [description] */ public static Product2 getProduceCompany(Map resultMap,Product2 prd){ for(Integer i :resultMap.keySet()){ String address = resultMap.get(i); switch on i { when 1 { prd.ProduceCompany__c = address; } when 2 { prd.ProduceCompany2__c = address; } when 3 { prd.ProduceCompany3__c = address; } } } return prd; } }