// RowDataを残すため、@future execute にします
global class NFM008WebService {
    public static boolean isRunning = false;
    // Integer batchsize = 200;  考量する必要がないと思います。
    global class InstallationInformation {
        webservice NFMUtil.Monitoring Monitoring;
        webservice NFM008WebService.InstallationInfo[] InstallationInfo;
    }
    global class InstallationInfo {
        webservice NFM008WebService.InstallationInfoH InstallationInfoH;
        webservice NFM008WebService.InstallationInfoI[] InstallationInfoI;
    }
    global class InstallationInfoH {
        webservice String InquiryNo;
        webservice String InstallationDateH;               // 受信しない
        webservice String PostingDate;
        webservice String CompanyCode;
        webservice String DepartmentCode;
        webservice String PurposeOfAdvice;
    }
    global class InstallationInfoI {
        webservice String MaterialNo;
        webservice Double Quantity;                        // 受信しない
        webservice String SerialNo;
        webservice String InstallationDateI;
        webservice String ReturnExchangeReplenishMark;     // 返品区分、1の場合、レコード削除
        webservice String SLMark;
        webservice String GuaranteePeriod;
        webservice String Location;
        webservice String PurposeOfAdvice;
    }

    // 非同期を見せかけ、常にreturn void
    webservice static void NFM008(NFM008WebService.InstallationInformation InstallationInformation) {
        if (InstallationInformation == null) {
            return;
        }
        NFMUtil.Monitoring Monitoring = InstallationInformation.Monitoring;
        if (Monitoring == null) {
            return;
        }

        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM008', InstallationInformation.InstallationInfo);
        if (String.isBlank(rowData.Log__c) == false) executefuture(rowData.Id);
    }

    @future
    global static void executefuture(String rowData_Id) {
        execute(rowData_Id);
    }
    global static void execute(String rowData_Id) {
        // CHAN-BB9CX4 20190419 NFM008Webservice停用，以后使用NFM008Rest
//        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 = 'NFM008';
//        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
//        iflog.Log__c = logstr;
//        iflog.ErrorLog__c = '';
//        insert iflog;

//        String rowDataStr = NFMUtil.getRowDataStr(rowData);
//        List<InstallationInfo> installationInfoList = (List<InstallationInfo>) JSON.deserialize(rowDataStr, List<InstallationInfo>.class);
//        if (installationInfoList == null || installationInfoList.size() == 0) {
//            return;
//        }

//        NFM008WebService.isRunning = true;

//        Savepoint sp = Database.setSavepoint();
//        try {
//            // 更新対応配列とMapなどをセット
//            List<String> managementCodeList = new List<String>();
//            List<String> productCodeList = new List<String>();
//            List<String> productSerialNoList = new List<String>();
//            for (NFM008WebService.InstallationInfo InstallationInfo : installationInfoList) {
//                NFM008WebService.InstallationInfoH InstallationInfoH = InstallationInfo.InstallationInfoH;
//                if (InstallationInfoH == null) {
//                    continue;
//                }
//                if (InstallationInfo.InstallationInfoI == null || InstallationInfo.InstallationInfoI.size() == 0) {
//                    continue;
//                }
//                // InstallationInfoH より、病院と診療科の管理コード
//                InstallationInfoH.CompanyCode = NFMUtil.trimLeft(InstallationInfoH.CompanyCode, '0');
//                InstallationInfoH.DepartmentCode = NFMUtil.trimLeft(InstallationInfoH.DepartmentCode, '0');
//                if (InstallationInfoH.CompanyCode == null || InstallationInfoH.CompanyCode  == '' ||
//                    InstallationInfoH.DepartmentCode == null || InstallationInfoH.DepartmentCode == ''
//                ) {
//                    // 病院と診療科の管理コードがない場合、処理と飛ばす
//                    continue;
//                }
//                managementCodeList.add(InstallationInfoH.CompanyCode);
//                managementCodeList.add(InstallationInfoH.DepartmentCode);
//                for (NFM008WebService.InstallationInfoI InstallationInfoI : InstallationInfo.InstallationInfoI) {
//                    if (InstallationInfoI.MaterialNo == null || InstallationInfoI.MaterialNo == '' ||
//                        InstallationInfoI.SerialNo == null || InstallationInfoI.SerialNo == ''
//                    ) {
//                        // 商品コードがない場合、処理と飛ばす
//                        continue;
//                    }
//                    productCodeList.add(InstallationInfoI.MaterialNo);
//                    //MODIFY BY SUNLEI 20160808
//                    //productSerialNoList.add(InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo.trim());
//                    productSerialNoList.add(InstallationInfoI.SerialNo.trim());
//                }
//            }
//            // 診療科のみを取得
//            List<Account> accList = [select Id, Management_Code__c, Department_Class__c, Hospital__c, RecordType.DeveloperName
//                                       from Account
//                                      where Management_Code__c in :managementCodeList];
//            Map<String, Account> accsMap = new Map<String, Account>();
//            for (Account acc : accList) {
//                accsMap.put(acc.Management_Code__c, acc);
//            }
//            List<Product2> prdList = [select Id, Name, ProductCode, ProductCode_Ext__c, MDM_Model_No__c
//                                        from Product2
//                                       where ProductCode_Ext__c in :productCodeList];
//            Map<String, Product2> prdsMap = new Map<String, Product2>();
//            for (Product2 prd : prdList) {
//                prdsMap.put(prd.ProductCode_Ext__c, prd);
//            }
//            List<Asset> astList = [select Id, Name, Product2.ProductCode, SerialNumber, Product_Serial_No__c, Repair_Count__c,
//                                          Product2Id, AccountId, Account.Management_Code__c, Department_Class__c, Hospital__c,
//                                          Posting_Date__c, InstallDate, SLMark__c,
//                                          Guarantee_period_for_products__c, Installation_Site__c,OT_CODE__c, MDM_Model_No__c
//                                     from Asset
//                                    where SerialNumber in :productSerialNoList and Information_From__c <> '失单'];// and Delete_Flag__c = false];
//            Map<String, Asset> astsMap = new Map<String, Asset>();
//            Map<String, Integer> astcheckMap = new Map<String, Integer>();
//            for (Asset ast : astList) {
//                //astsMap.put(ast.Product_Serial_No__c, ast);
//                astsMap.put(ast.MDM_Model_No__c + ':' + ast.SerialNumber, ast);
//                // HHOA-AGN2EH start
//                if (astcheckMap.containsKey(ast.MDM_Model_No__c + ':' + ast.SerialNumber) == false) {
//                    astcheckMap.put(ast.MDM_Model_No__c + ':' + ast.SerialNumber, 1);
//                } else {
//                    astcheckMap.put(ast.MDM_Model_No__c + ':' + ast.SerialNumber, astcheckMap.get(ast.MDM_Model_No__c + ':' + ast.SerialNumber) + 1);
//                }
//                // HHOA-AGN2EH end
//            }
            
//            // 更新対応配列をセット
//            astList = new List<Asset>();
//            Map<String, Asset> astUpdateMap = new Map<String, Asset>();
//            List<Asset> astDelList = new List<Asset>();
//            Map<String, Asset> astDelMap = new Map<String, Asset>();
//            for (NFM008WebService.InstallationInfo InstallationInfo : installationInfoList) {
//                NFM008WebService.InstallationInfoH InstallationInfoH = InstallationInfo.InstallationInfoH;
//                if (InstallationInfoH == null) {
//                    iflog.ErrorLog__c += 'Error! InstallationInfoH is required. This inquiry is skipped.\n';
//                    continue;
//                }
//                if (InstallationInfo.InstallationInfoI == null || InstallationInfo.InstallationInfoI.size() == 0) {
//                    iflog.ErrorLog__c += 'Error! InstallationInfoI is required. This inquiry is skipped.\n';
//                    continue;
//                }
//// InstallationInfoH.PurposeOfAdvice を見ない
////                if (InstallationInfoH.PurposeOfAdvice == '1') {
////                    // deleteを無視
////                    logstr += 'InstallationInfoH.PurposeOfAdvice==1 ';
////                    continue;
////                }
//                // InstallationInfoH より、病院と診療科の管理コード
//                if (InstallationInfoH.CompanyCode == null || InstallationInfoH.CompanyCode == '') {
//                    // 必須項目がない場合、処理と飛ばす
//                    iflog.ErrorLog__c += 'Error! CompanyCode is required. This inquiry is skipped.\n';
//                    continue;
//                }
//                if (InstallationInfoH.DepartmentCode == null || InstallationInfoH.DepartmentCode == '') {
//                    // 必須項目がない場合、処理と飛ばす
//                    iflog.ErrorLog__c += 'Error! DepartmentCode is required. This inquiry is skipped.\n';
//                    continue;
//                }
//                if (accsMap.get(InstallationInfoH.CompanyCode) == null) {
//                    iflog.ErrorLog__c += 'Error! Company[' + InstallationInfoH.CompanyCode + ']NotExist. This inquiry is skipped.\n';
//                    continue;
//                } else if (accsMap.get(InstallationInfoH.CompanyCode).RecordType.DeveloperName != 'HP'
//                        && accsMap.get(InstallationInfoH.CompanyCode).RecordType.DeveloperName != 'Agency') {
//                    iflog.ErrorLog__c += 'Error! Company[' + InstallationInfoH.CompanyCode + ']Is Not HP(Agency). This inquiry is skipped.\n';
//                    continue;
//                }
//                if (accsMap.get(InstallationInfoH.DepartmentCode) == null) {
//                    iflog.ErrorLog__c += 'Error! Department[' + InstallationInfoH.DepartmentCode + ']NotExist. This inquiry is skipped.\n';
//                    continue;
//                }
//                for (NFM008WebService.InstallationInfoI InstallationInfoI : InstallationInfo.InstallationInfoI) {
//                    if (InstallationInfoI.MaterialNo == null || InstallationInfoI.MaterialNo == '') {
//                        // 必須項目がない場合、処理と飛ばす
//                        iflog.ErrorLog__c += 'Error! MaterialNo is required. This asset is skipped.\n';
//                        continue;
//                    }
//                    if (InstallationInfoI.SerialNo == null || InstallationInfoI.SerialNo == '') {
//                        // 必須項目がない場合、処理と飛ばす
//                        iflog.ErrorLog__c += 'Error! Product[' + InstallationInfoI.MaterialNo + '] SerialNo is required. This asset is skipped.\n';
//                        continue;
//                    }
//                    Product2 prd = prdsMap.get(InstallationInfoI.MaterialNo);
//                    if (prd == null) {
//                        iflog.ErrorLog__c += 'Error! [' + InstallationInfoI.SerialNo + ']Product[' + InstallationInfoI.MaterialNo + ']NotExist. This asset is skipped.\n';
//                        continue;
//                    }
//                    // HHOA-AGN2EH start
//                    if (astcheckMap.containsKey(prd.MDM_Model_No__c + ':' + InstallationInfoI.SerialNo.trim()) == true && astcheckMap.get(prd.MDM_Model_No__c + ':' + InstallationInfoI.SerialNo.trim()) > 1) {
//                        iflog.ErrorLog__c += 'Error! [' + InstallationInfoI.SerialNo + ']Product[' + InstallationInfoI.MaterialNo + '] Exist more than one. This asset is skipped.\n';
//                        continue;
//                    }
//                    // HHOA-AGN2EH end
//                    Asset ast = astsMap.get(prd.MDM_Model_No__c + ':' + InstallationInfoI.SerialNo.trim());
//                    if (ast == null) {
//                        // 保有設備存在しないのに、delete 受信の場合
//                        //if (InstallationInfoI.ReturnExchangeReplenishMark == '1' || InstallationInfoI.PurposeOfAdvice == '1') {
//                            // HHOA-AGN2EH start
//                            //iflog.ErrorLog__c += 'Warning! Delete Asset[' + InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo + ']NotExist\n';
//                            // HHOA-AGN2EH end
//                        //    continue;
//                        //}
//                        //iflog.ErrorLog__c += '194[prd.MDM_Model_No__c:' + prd.MDM_Model_No__c + ']SUNLEI TEST[InstallationInfoI.SerialNo' + InstallationInfoI.SerialNo + '] DEUG\n';
//                        //iflog.ErrorLog__c += '195[prd.MDM_Model_No__c:' + prd.MDM_Model_No__c + ']SUNLEI TEST[InstallationInfoI.SerialNo' + InstallationInfoI.SerialNo + '] DEUG\n';
//                         //add by sunlei 20160810 保有設備存在しない新規の場合、何もしない
//                        ast = new Asset();
//                        ast.SerialNumber                     = InstallationInfoI.SerialNo.trim();
//                        //continue;

//                    } else {
//                        if (InstallationInfoI.ReturnExchangeReplenishMark == '1' || InstallationInfoI.PurposeOfAdvice == '1') {
//                            // 物理削除用
//                            if (astDelMap.get(ast.Product_Serial_No__c) == null) {
//                                astDelList.add(ast);
//                                astDelMap.put(ast.Product_Serial_No__c, ast);
//                            }
//                            logstr += InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo + '(delete) ';
//                            // 修理がある場合、Warning! を出す
//                            if (ast.Repair_Count__c > 0) {
//                                // HHOA-AGN2EH start
//                                //iflog.ErrorLog__c += 'Warning! Delete Asset[' + InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo + '] with repair.\n';
//                                // HHOA-AGN2EH end
//                            }
//                            continue;
//                        }

//                        // HHOA-AGN2EH start
//                        if (ast.Hospital__c != accsMap.get(InstallationInfoH.CompanyCode).Id){
//                            iflog.ErrorLog__c += 'Warning! CompanyCode:' + '[' + InstallationInfoH.CompanyCode + '] is not match with the Asset[' + ast.OT_CODE__c +':'+ast.SerialNumber+']. This asset is skipped.\n';
//                            continue;
//                        }
//                        // HHOA-AGN2EH end

//                        //Modify by sunlei 20160804 更新的情况下 判断科室是否一致
//                        if (ast.AccountId != accsMap.get(InstallationInfoH.DepartmentCode).Id){
//                        // interface科室 <>保有设备的科室、処理と飛ばす
//                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + ast.OT_CODE__c + ':' + ast.SerialNumber  + '] DepartmentCode:' + ast.Account.Management_Code__c + ' is updated to '+ InstallationInfoH.DepartmentCode + '.\n';
//                            // HHOA-AGN2EH start
//                            //continue;
//                            // HHOA-AGN2EH end
//                        }
//                    }
//                    if (InstallationInfoI.InstallationDateI == null || InstallationInfoI.InstallationDateI == '') {
//                        // 必須項目がない場合、処理と飛ばす
//                        iflog.ErrorLog__c += 'Error! [' + InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo + ']InstallationDateI is required. This asset is skipped.\n';
//                        continue;
//                    }
//                    if (InstallationInfoI.SLMark == null || InstallationInfoI.SLMark == '') {
//                        // 必須項目がない場合、処理と飛ばす
//                        iflog.ErrorLog__c += 'Error! [' + InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo + ']SLMark is required. This asset is skipped.\n';
//                        continue;
//                    }

//                    //Add by sunlei 20160804 更新的情况下[保有设备]的OT-CODE和机身编号一致进行更新
//                    if (ast.SerialNumber == InstallationInfoI.SerialNo.trim() &&
//                        ast.MDM_Model_No__c == prdsMap.get(InstallationInfoI.MaterialNo).MDM_Model_No__c &&
//                        ast.OT_CODE__c != InstallationInfoI.MaterialNo  ){
//                        iflog.ErrorLog__c += 'Warning! Asset' + '[' + ast.OT_CODE__c + ':' + ast.SerialNumber  + '] is updated to [' + InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo + ']\n';
//                        //iflog.ErrorLog__c += '241Warning! Asset' + '[' + ast.OT_CODE__c + ':' + ast.SerialNumber  + '] is sunleitest to [' + InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo + ']\n';
//                        //continue;
//                    }

//                    // upsert用、項目転送
//                    ast.Product_Serial_No__c = InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo.trim();
//                    if (astUpdateMap.get(ast.Product_Serial_No__c) == null) {
//                        astList.add(ast);
//                        astUpdateMap.put(ast.Product_Serial_No__c, ast);
//                        logstr += InstallationInfoI.MaterialNo + ':' + InstallationInfoI.SerialNo.trim() + ' ';
//                    } else {
//                        ast = astUpdateMap.get(ast.Product_Serial_No__c);
//                    }
//                    ast.Name                             = prd.Name;
//                    ast.Order_No__c                      = InstallationInfoH.InquiryNo;
//                    ast.Posting_Date__c                  = NFMUtil.parseStr2Date(InstallationInfoH.PostingDate);
//                    ast.AccountId                        = accsMap.get(InstallationInfoH.DepartmentCode).Id;
//                    ast.Department_Class__c              = accsMap.get(InstallationInfoH.DepartmentCode).Department_Class__c;
//                    // HHOA-AGN2EH start
//                    //ast.Hospital__c                      = accsMap.get(InstallationInfoH.CompanyCode).Id;
//                    // HHOA-AGN2EH end
//                    ast.Product2Id                       = prdsMap.get(InstallationInfoI.MaterialNo).Id;
//                    // HHOA-AGN2EH start
//                    //ast.SerialNumber                     = InstallationInfoI.SerialNo.trim();
//                    // HHOA-AGN2EH end
//                    ast.InstallDate                      = NFMUtil.parseStr2Date(InstallationInfoI.InstallationDateI);
//                    ast.SLMark__c                        = InstallationInfoI.SLMark;
//                    // CHAN-AVC54T start
//                    //ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(InstallationInfoI.GuaranteePeriod);
//                    Date gp = NFMUtil.parseStr2Date(InstallationInfoI.GuaranteePeriod);
//                    if (gp != null) {
//                        ast.Guarantee_period_for_products__c = gp;
//                    }
//                    // CHAN-AVC54T end
//                    //if (InstallationInfoI.Location != null) {
//                    //    ast.Installation_Site__c         = InstallationInfoI.Location;
//                    //}
//                    ast.IF_Information_From__c           = true;
//                }
//            }
//            System.debug('astList +++++' + astList);
//            if (astList.size() > 0) {
//                upsert astList;
//            }
//            if (astDelList.size() > 0) {
//                //delete astDelList;
//                // TODO 今後 返品設備の科室に移動する可能性がある
//                // HHOA-AGN2EH start
//                //for (Asset ast : astDelList) {
//                //    ast.Return_Flag__c = true;
//                //}
//                //update astDelList;
//                // HHOA-AGN2EH end
//            }
//            logstr += '\nend';
//            rowData.retry_cnt__c=0;
//        } catch(Exception ex) {
//            // エラーが発生した場合
//            Database.rollback(sp);
//            System.debug(Logginglevel.ERROR, 'NFM008_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
//            System.debug(Logginglevel.ERROR, 'NFM008_' + 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;
    }
}