/********************************************************************** 产品 首营状态Z5 修改了LogAutoSendBatch 新增:产品库存对象 给 OT-GPI简档权限 *************************************************************************/ @RestResource(urlMapping = '/SBG018/*') global with sharing class SBG018Rest { public transient static String globaltransforDate; global class GeDatasRest { public GeDatas GeDatas; } global class GeDatas { public NFMUtil.Monitoring Monitoring; public GeData[] GeData; } global class GeData { public GeDataDetails[] GeDataDetails; public String Status; //首营状态 public String TransforDate; //传输日期 } global class GeDataDetails { public String ProductCode;//物料 public String Plant;//工厂 public String Department;//分野 public String FGSP;//整机/零件(FG=整机,SP=零件) public String Qty;//可分配库存数量 public String TradeType;//内/外贸(Tax Exemption=外贸,Taxation=内贸) } @HttpPost global static void execute() { // 取得接口传输内容 String strData = RestContext.request.requestBody.toString(); GeDatasRest ges = (GeDatasRest) JSON.deserializeStrict(strData, GeDatasRest.class); if (ges == null ) { return; } NFMUtil.Monitoring Monitoring = ges.GeDatas.Monitoring; if (Monitoring == null) { return; } BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'SBG018', ges.GeDatas.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 = 'SBG018'; 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; } Savepoint sp = Database.setSavepoint(); try { globaltransforDate = ''; // 符合的明细 Map satisfyGeDataDetailMap = RequiredFieldValidator(geDataList, iflog); if (satisfyGeDataDetailMap != null && satisfyGeDataDetailMap.size() > 0) { upsertProductInventory(satisfyGeDataDetailMap, iflog); } logstr += '\nend'; rowData.retry_cnt__c = 0; } catch (Exception ex) { Database.rollback(sp); System.debug(Logginglevel.ERROR, 'SBG018_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage()); System.debug(Logginglevel.ERROR, 'SBG018_' + 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; } // 保存产品库存 public static void upsertProductInventory(Map satisfyGeDataDetailMap, BatchIF_Log__c iflog) { // 获取产品库存 Start Map productInventoryMap = new Map(); List getProductInventoryList = [SELECT Id, Name,TransforDate__c, ProductCode__c, Plant__c, ProductSegment__c, ProductType__c, InventoryQuantity__c, ManagementCode__c,InventoryCode__c,TradeType__c FROM ProductInventory__c WHERE InventoryCode__c IN :satisfyGeDataDetailMap.keySet()]; if (getProductInventoryList.size() > 0) { for (ProductInventory__c productInventory : getProductInventoryList) { productInventoryMap.put(productInventory.InventoryCode__c, productInventory); } } // 获取产品库存 End // 获取产品 Start List productCodeList = new List(); Map productMap = new Map(); for (String managementCode : satisfyGeDataDetailMap.keySet()) { GeDataDetails geDataDetails = satisfyGeDataDetailMap.get(managementCode); productCodeList.add(ZeroPadding(geDataDetails.ProductCode)); } List getProductList = [SELECT Id, Name, ProductCode FROM Product2 WHERE ProductCode IN:productCodeList ]; if (getProductList.size() > 0) { for (Product2 product : getProductList) { productMap.put(product.ProductCode, product); } } // 获取产品 End // 保存 产品库存Start List upsertProductInventoryList = new List(); for (String inventoryCode : satisfyGeDataDetailMap.keySet()) { GeDataDetails geDataDetails = satisfyGeDataDetailMap.get(inventoryCode); String productCode = ZeroPadding(geDataDetails.ProductCode); String productId = ''; if (productMap.containsKey(productCode)) { productId = productMap.get(productCode).Id; } else { iflog.ErrorLog__c += 'productCode [ ' + productCode + ' ] is Nonexistent,This data is skipped.\n'; continue; } Date transforDate = NFMUtil.parseStr2Date(globaltransforDate, false); Boolean continueFlag = false; ProductInventory__c productInventory = new ProductInventory__c(); if (productInventoryMap.containsKey(inventoryCode)) { productInventory = productInventoryMap.get(inventoryCode); // 若传输日期小于等于当前库存日期,数据跳过不执行 if (transforDate < productInventory.TransforDate__c) { continueFlag = true; } else if(transforDate == productInventory.TransforDate__c) { // 接口数据大于库存数量,数据跳过(防止一天两次执行接口、对系统数据的覆盖) if ( Decimal.valueOf(geDataDetails.Qty) > productInventory.InventoryQuantity__c) { continueFlag = true; } } } else { // 产品库存的key(产品编码_分野_整机/零件_工厂_内/外贸) productInventory.InventoryCode__c = inventoryCode; String managementCode = ZeroPadding(geDataDetails.ProductCode) + '_' + geDataDetails.Department + '_' + geDataDetails.FGSP; // 产品库存验证的key(产品编码_分野_整机/零件) productInventory.ManagementCode__c = managementCode; productInventory.Name = inventoryCode; } if (continueFlag) { iflog.ErrorLog__c += '产品库存 [ ' + inventoryCode + ' ] not the latest data,This data is skipped.\n'; continue; } productInventory.TransforDate__c = transforDate ; productInventory.ProductCode__c = productId; productInventory.Plant__c = geDataDetails.Plant ; productInventory.ProductSegment__c = geDataDetails.Department ; productInventory.ProductType__c = geDataDetails.FGSP ; productInventory.InventoryQuantity__c = Decimal.valueOf(geDataDetails.Qty); productInventory.TradeType__c = geDataDetails.TradeType; upsertProductInventoryList.add(productInventory); } if (upsertProductInventoryList.size() > 0) { upsert upsertProductInventoryList; } // 保存 产品库存End } // 字段验证 public static Map RequiredFieldValidator(List geDataList, BatchIF_Log__c iflog) { Map result = new Map(); for (GeData gda : geDataList) { // 传输日期 if (String.isBlank(gda.TransforDate)) { iflog.ErrorLog__c += 'TransforDate is required,This data is skipped.\n'; continue; } globaltransforDate = gda.TransforDate; for (GeDataDetails geDataDetail : gda.GeDataDetails) { // 产品OTCode if (String.isBlank(geDataDetail.ProductCode)) { iflog.ErrorLog__c += 'ProductCode is required,This data is skipped.\n'; continue; } // 分野 if (String.isBlank(geDataDetail.Department)) { iflog.ErrorLog__c += 'ProductCode[ ' + geDataDetail.ProductCode + ' ] of Department is required,This data is skipped.\n'; continue; } // 工厂 if (String.isBlank(geDataDetail.Plant)) { iflog.ErrorLog__c += 'ProductCode[ ' + geDataDetail.ProductCode + ' ] of Plant is required,This data is skipped.\n'; continue; } // 整机/零件 if (String.isBlank(geDataDetail.FGSP)) { iflog.ErrorLog__c += 'ProductCode[ ' + geDataDetail.ProductCode + ' ] of FGSP is required,This data is skipped.\n'; continue; } // 内/外贸 if (String.isBlank(geDataDetail.TradeType)) { iflog.ErrorLog__c += 'ProductCode[ ' + geDataDetail.ProductCode + ' ] of TradeType is required,This data is skipped.\n'; continue; } if ('Tax Exemption'.equals(geDataDetail.TradeType)) { iflog.Log2__c += 'Tax Exemption, [ ProductCode:' + geDataDetail.ProductCode +',工厂:'+geDataDetail.Plant+',分野:'+geDataDetail.Department+', 数量:'+geDataDetail.Qty+ ' ].\n'; } // 库存数量 Boolean isContinue = false; if (String.isBlank(geDataDetail.Qty)) { iflog.ErrorLog__c += 'ProductCode[ ' + geDataDetail.ProductCode + ' ] of Qty is required,This data is skipped.\n'; continue; } else { Pattern pattern = Pattern.compile('^[0-9]\\d{0,13}(\\.\\d{0,4})?$'); Matcher isNum = pattern.matcher(geDataDetail.Qty); if (!isNum.matches()) { //内/外贸(Tax Exemption=外贸,Taxation=内贸) if ('Tax Exemption'.equals(geDataDetail.TradeType)) { // 外贸库存出现负数,默认存为0库存 geDataDetail.Qty = '0.000'; } else if ('Taxation'.equals(geDataDetail.TradeType)) { // 报错并发送邮件通知给系统管理员 iflog.ErrorLog__c += '[ ProductCode:' + geDataDetail.ProductCode +',工厂:'+geDataDetail.Plant+',分野:'+geDataDetail.Department+', 数量:'+geDataDetail.Qty+ ' ] has to be a Nonnegative number,This data is skipped.\n'; isContinue = true; } } } if (isContinue) { continue; } // 产品编码_分野_整机/零件_工厂_内/外贸 String inventoryCode = ZeroPadding(geDataDetail.ProductCode) + '_' + geDataDetail.Department + '_' + geDataDetail.FGSP + '_'+geDataDetail.Plant + '_'+geDataDetail.TradeType; result.put(inventoryCode, geDataDetail); } } return result; } // 纯数字产品编码进行补零 public static String ZeroPadding(String productCode) { Pattern pattern = Pattern.compile('^[0-9]*$'); Matcher isNum = pattern.matcher(productCode); if (isNum.matches()) { productCode = productCode.leftPad(18, '0'); } return productCode; } }