/**********************************************************************
 产品 首营状态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<GeData> geDataList = (List<GeData>) JSON.deserialize(rowDataStr, List<GeData>.class);
        if (geDataList == null || geDataList.size() == 0) {
            return;
        }


        Savepoint sp = Database.setSavepoint();
        try {
            globaltransforDate = '';
            // 符合的明细
            Map<String, GeDataDetails> 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<String, GeDataDetails> satisfyGeDataDetailMap, BatchIF_Log__c iflog) {

        // 获取产品库存 Start
        Map<String, ProductInventory__c> productInventoryMap = new Map<String, ProductInventory__c>();
        List<ProductInventory__c> 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<String> productCodeList = new List<String>();
        Map<String, Product2> productMap = new Map<String, Product2>();

        for (String managementCode : satisfyGeDataDetailMap.keySet()) {
            GeDataDetails geDataDetails = satisfyGeDataDetailMap.get(managementCode);
            productCodeList.add(ZeroPadding(geDataDetails.ProductCode));
        }

        List<Product2> 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<ProductInventory__c> upsertProductInventoryList = new List<ProductInventory__c>();
        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<String, GeDataDetails> RequiredFieldValidator(List<GeData> geDataList, BatchIF_Log__c iflog) {
        Map<String, GeDataDetails> result = new Map<String, GeDataDetails>();
        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;
    }


}