@isTest
private class NFM104RestTest {
	

    public static Integer count = 0;

    // 使用testSetup定义初始化函数
    @testSetup 
    static void setup() {
      //   StaticParameter.EventOpportunityPileUpExeFlg = true;
      // // EventC⇒Event処理後、逆更新をスルー用
      // StaticParameter.NotUpdEventCFlg = true;
      // // 積み上げ処理後、トリガをスルー用
      // StaticParameter.EscapeNFM001Trigger = true;
      // 
      // StaticParameter.EscapeNFM001AgencyContractTrigger = true;
      // StaticParameter.EscapeNFM001AgencyContractTrigger2 = true;
      // StaticParameter.EscapeNFM007Trigger = true;
      // StaticParameter.EscapeOpportunityBefUpdTrigger = true;
      // StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true;
      // StaticParameter.EscapeSyncOpportunityTrigger = true;
      // StaticParameter.EscapeMaintenanceContractAfterUpdateTrigger = true;
      // StaticParameter.EscapeSyncProduct2Trigger = true;
      // // trueのとき、リードのトリガーをスルーする
      // StaticParameter.EscapeLeadTrigger = true;
      // StaticParameter.EscapeAccountTrigger = true;

      // StaticParameter.EscapeConsumableOrderDetail2Trigger = true;

      // StaticParameter.EscapeNFM010UpsertStatuAchievementsTrigger = true;
      // // 直销耗材不直销 ConsumableAssetHander
      // StaticParameter.ConsumableAssetHanderTrigger = true;

      // // 跳过不涉及备品借出的逻辑
      // StaticParameter.rentalApplyIsRunning = true;

      // // accountdailyUpdate 跳过 更新询价
      // StaticParameter.EscapeOpportunityownerUpdate  = true;

        
        List<RecordType> rects   = [select Id, Name from RecordType where IsActive = true and SobjectType = 'Account'];
        List<RecordType> rectCo  = new List<RecordType>();
        List<RecordType> rectSct = new List<RecordType>();
        List<RecordType> rectDpt = new List<RecordType>();
        List<RecordType> rectAg  = new List<RecordType>();
        for(RecordType rect : rects){
            if('病院'.equals(rect.Name)){
                rectCo.add(rect);
            }
            if('戦略科室分類 消化科'.equals(rect.Name)){
                rectSct.add(rect);
            }
            if('診療科 消化科'.equals(rect.Name)){
                rectDpt.add(rect);
            }
            if('販売店'.equals(rect.Name)){
                rectAg.add(rect);
            }
        }
        if (rectCo.size() == 0) {
            return;
        }
        if (rectSct.size() == 0) {
            return;
        }
        if (rectDpt.size() == 0) {
            return;
        }
       if (rectAg.size() == 0) {
            return;
        }        
        // テストデータ
        Account company = new Account();
        company.RecordTypeId = rectCo[0].Id;
        company.Name         = 'NFM104TestCompany';
        upsert company;

        Account section = new Account();
        // section.RecordTypeId = rectSct[0].Id;
        // section.Name         = 'NFM104TestSection';
        // section.ParentId     = company.Id;
        // upsert section;
        list<Account> sections = [Select Management_Code__c, Management_Code_Auto__c, Name, Id from Account where ParentId = :company.Id and RecordTypeId = :rectSct[0].Id];
        section = sections[0];
        
        Account depart = new Account();
        depart.RecordTypeId        = rectDpt[0].Id;
        depart.Name                = '*';
        depart.Department_Name__c  = 'NFM104TestDepart';
        depart.ParentId            = section.Id;
        depart.Department_Class__c = section.Id;
        depart.Hospital__c         = company.Id;
        upsert depart;
        Account agency1 = new Account(name='Testhosp001',AgentCode_Ext__c = '0000021598', Dealer_discount__c =10,RecordTypeId = rectCo[0].Id);
        upsert agency1;
        // 再取得
        List<Account> accList = new List<Account>();
        company = [select Management_Code__c, Management_Code_Auto__c, Name, Id from Account where Id = :company.Id];
        accList.add(company);
        accList.add(section);
        depart = [select Management_Code__c, Management_Code_Auto__c, Name, Id from Account where Id = :depart.Id];
        accList.add(depart);

        List<Product2> prdList = new List<Product2>();
        Product2 prd1 = new Product2();
        prd1.ProductCode_Ext__c     = 'NFM104Prd1';
        prd1.ProductCode            = 'NFM104Prd1';
        prd1.Repair_Product_Code__c = 'NFM104Prd1_RP';
        prd1.Name                   = 'NFM104Prd1';
        prd1.Manual_Entry__c        = false;
        prdList.add(prd1);
        Product2 prd2 = new Product2();
        prd2.ProductCode_Ext__c     = 'NFM104Prd2';
        prd2.ProductCode            = 'NFM104Prd2';
        prd2.Repair_Product_Code__c = 'NFM104Prd2_RP';
        prd2.Name                   = 'NFM104Prd2';
        prd2.Manual_Entry__c        = false;
        prdList.add(prd2);
        insert prdList;
        System.Test.startTest();
        Asset ast = new Asset();
        ast.Name                             = 'NFM104Ast1';
        ast.AccountId                        = depart.Id;
        ast.Department_Class__c              = section.Id;
        ast.Hospital__c                      = company.Id;
        ast.Product2Id                       = prd1.Id;
        ast.SerialNumber                     = 'NFM104SerialNumber';
        ast.Guarantee_period_for_products__c = Date.today();
        ast.InstallDate                      = Date.today();
        insert ast;
        /*ast = [select Id, Name, Product_Serial_No__c, AccountId, Department_Class__c, Department_Class__r.Management_Code_Auto__c, Hospital__c, Product2Id, Product2.ProductCode, Product2.Repair_Product_Code__c, SerialNumber
                                 from Asset
                                where Id = :ast.Id];
        */
        Repair__c rpr = new Repair__c();
        rpr.SAPRepairNo__c         = 'NFM104Rpr1';
        rpr.Account__c             = depart.Id;
        rpr.Department_Class__c    = section.Id;
        rpr.Hospital__c            = company.Id;
        rpr.Delivered_Product__c   = ast.Id;
        rpr.SalesOfficeCode_selection__c = '北京';
        // rpr.Status__c              = '1.受理完毕';
        rpr.Status__c              = '草案中';
        rpr.Incharge_Staff__c = Userinfo.getUserId();
        rpr.Repair_Detail__c = 'test';
        insert rpr;

        System.Test.stopTest();   
    }

    static testMethod void testNFM104() {
        StaticParameter.EventOpportunityPileUpExeFlg = true;
      // EventC⇒Event処理後、逆更新をスルー用
      StaticParameter.NotUpdEventCFlg = true;
      // 積み上げ処理後、トリガをスルー用
      StaticParameter.EscapeNFM001Trigger = true;
      StaticParameter.EscapeNFM001AgencyContractTrigger = true;
      StaticParameter.EscapeNFM001AgencyContractTrigger2 = true;
      StaticParameter.EscapeNFM007Trigger = true;
      StaticParameter.EscapeOpportunityBefUpdTrigger = true;
      StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true;
      StaticParameter.EscapeSyncOpportunityTrigger = true;
      StaticParameter.EscapeMaintenanceContractAfterUpdateTrigger = true;
      StaticParameter.EscapeSyncProduct2Trigger = true;
      // trueのとき、リードのトリガーをスルーする
      StaticParameter.EscapeLeadTrigger = true;
      StaticParameter.EscapeAccountTrigger = true;

      StaticParameter.EscapeConsumableOrderDetail2Trigger = true;

      StaticParameter.EscapeNFM010UpsertStatuAchievementsTrigger = true;
      // 直销耗材不直销 ConsumableAssetHander
      StaticParameter.ConsumableAssetHanderTrigger = true;

      // 跳过不涉及备品借出的逻辑
      StaticParameter.rentalApplyIsRunning = true;

      // accountdailyUpdate 跳过 更新询价
      StaticParameter.EscapeOpportunityownerUpdate  = true;
        Repair__c rpr = [select Id, Name, Account__c,Department_Class__c,
            Delivered_Product__c,Hospital__c,SalesOfficeCode_selection__c,
             SAPRepairNo__c,Status__c,Incharge_Staff__c,Repair_Detail__c 
             from Repair__c];

        Repair_Quotation__c rq = new Repair_Quotation__c();
        rq.Name                  = 'testNFM104';
        rq.Repair__c             = rpr.Id;
        rq.MessageGroupNumber__c = '1';
        insert rq;
        // そのままreturn
        System.Test.startTest();
        NFM104RestTest.testNFM104_void();
       
        
        //TODO insert
        NFM104RestTest.testNFM104_insert(rpr);
        //TODO upsert
        //NFM104WebServiceTest.testNFM104_upsert();
        System.Test.stopTest();
    }

    static testMethod void test_method_two() {
        StaticParameter.EventOpportunityPileUpExeFlg = true;
      // EventC⇒Event処理後、逆更新をスルー用
      StaticParameter.NotUpdEventCFlg = true;
      // 積み上げ処理後、トリガをスルー用
      StaticParameter.EscapeNFM001Trigger = true;
      StaticParameter.EscapeNFM001AgencyContractTrigger = true;
      StaticParameter.EscapeNFM001AgencyContractTrigger2 = true;
      StaticParameter.EscapeNFM007Trigger = true;
      StaticParameter.EscapeOpportunityBefUpdTrigger = true;
      StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true;
      StaticParameter.EscapeSyncOpportunityTrigger = true;
      StaticParameter.EscapeMaintenanceContractAfterUpdateTrigger = true;
      StaticParameter.EscapeSyncProduct2Trigger = true;
      // trueのとき、リードのトリガーをスルーする
      StaticParameter.EscapeLeadTrigger = true;
      StaticParameter.EscapeAccountTrigger = true;

      StaticParameter.EscapeConsumableOrderDetail2Trigger = true;

      StaticParameter.EscapeNFM010UpsertStatuAchievementsTrigger = true;
      // 直销耗材不直销 ConsumableAssetHander
      StaticParameter.ConsumableAssetHanderTrigger = true;

      // 跳过不涉及备品借出的逻辑
      StaticParameter.rentalApplyIsRunning = true;

      // accountdailyUpdate 跳过 更新询价
      StaticParameter.EscapeOpportunityownerUpdate  = true;
        Test.startTest();
        
        RestRequest req = new RestRequest();
        RestResponse res = new RestResponse();

        String JsonMsg = '{"RepairQuotation": {"Monitoring":{"TransmissionDateTime":"201812201320","Text":"","Tag":"MSGH","Sender":"SFDC","Receiver":"SPO","NumberOfRecord":"1","MessageType":"NFM104","MessageGroupNumber":"20180001722190"},"QuotationHeaderInformation":null}}';
        req.requestURI = 'services/apexrest/NFM104/execute';
        req.httpMethod = 'POST';
        req.requestBody = Blob.valueof(JsonMsg);
        RestContext.request = req;
        RestContext.response= res;

        NFM104Rest.execute();

        Test.stopTest();
    }

    static void testNFM104_void() {
        StaticParameter.EventOpportunityPileUpExeFlg = true;
      // EventC⇒Event処理後、逆更新をスルー用
      StaticParameter.NotUpdEventCFlg = true;
      // 積み上げ処理後、トリガをスルー用
      StaticParameter.EscapeNFM001Trigger = true;
      StaticParameter.EscapeNFM001AgencyContractTrigger = true;
      StaticParameter.EscapeNFM001AgencyContractTrigger2 = true;
      StaticParameter.EscapeNFM007Trigger = true;
      StaticParameter.EscapeOpportunityBefUpdTrigger = true;
      StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true;
      StaticParameter.EscapeSyncOpportunityTrigger = true;
      StaticParameter.EscapeMaintenanceContractAfterUpdateTrigger = true;
      StaticParameter.EscapeSyncProduct2Trigger = true;
      // trueのとき、リードのトリガーをスルーする
      StaticParameter.EscapeLeadTrigger = true;
      StaticParameter.EscapeAccountTrigger = true;

      StaticParameter.EscapeConsumableOrderDetail2Trigger = true;

      StaticParameter.EscapeNFM010UpsertStatuAchievementsTrigger = true;
      // 直销耗材不直销 ConsumableAssetHander
      StaticParameter.ConsumableAssetHanderTrigger = true;

      // 跳过不涉及备品借出的逻辑
      StaticParameter.rentalApplyIsRunning = true;

      // accountdailyUpdate 跳过 更新询价
      StaticParameter.EscapeOpportunityownerUpdate  = true;
        // null
        //NFM104Rest.NFM104(null);
        //NFM104Rest.execute();
        NFM104Rest.RepairQuotation RepairQuotation                         = new NFM104Rest.RepairQuotation();
        NFM104Rest.QuotationHeaderInformation QuotationHeaderInformation   = new NFM104Rest.QuotationHeaderInformation();
        NFM104Rest.DiscountInformation DiscountInformation                 = new NFM104Rest.DiscountInformation();
        NFM104Rest.InspectionResultInformation InspectionResultInformation = new NFM104Rest.InspectionResultInformation();
        NFM104Rest.FailureInformation FailureInformation                   = new NFM104Rest.FailureInformation();
        NFM104Rest.ActivityInformation ActivityInformation                 = new NFM104Rest.ActivityInformation();

        QuotationHeaderInformation.DiscountInformation         = new NFM104Rest.DiscountInformation[] { DiscountInformation };
        QuotationHeaderInformation.InspectionResultInformation = new NFM104Rest.InspectionResultInformation[] { InspectionResultInformation };
        QuotationHeaderInformation.FailureInformation          = new NFM104Rest.FailureInformation[] { FailureInformation };
        QuotationHeaderInformation.ActivityInformation         = new NFM104Rest.ActivityInformation[] { ActivityInformation };
        RepairQuotation.QuotationHeaderInformation             = new NFM104Rest.QuotationHeaderInformation[] { QuotationHeaderInformation };

        // Monitoringをセットしない
        //BatchIF_Log__c rowData1 = NFMUtil.saveRowData(RepairQuotation.Monitoring, 'NFM104', RepairQuotation.QuotationHeaderInformation);
        //NFM104Rest.executefuture(rowData1.Id);

        Datetime nowDT = Datetime.now();
        String nowStr  = nowDT.format('yyyyMMddHHmm');
        RepairQuotation.Monitoring = new NFMUtil.Monitoring();
        RepairQuotation.Monitoring.MessageGroupNumber = nowStr + count + '1';
        // 必須項目をセットしない
        BatchIF_Log__c rowData2 = NFMUtil.saveRowData(RepairQuotation.Monitoring, 'NFM104', RepairQuotation.QuotationHeaderInformation);
        NFM104Rest.main(rowData2.Id);

        // 商品コードが存在しない
        RepairQuotation.Monitoring.MessageGroupNumber = nowStr + count + '2';
        count++;
        QuotationHeaderInformation.SAPQuotationNo = 'NFM104X';
        BatchIF_Log__c rowData3 = NFMUtil.saveRowData(RepairQuotation.Monitoring, 'NFM104', RepairQuotation.QuotationHeaderInformation);
        NFM104Rest.main(rowData3.Id);

        Repair_Quotation__c[] rslts = [select Id from Repair_Quotation__c where Name = :QuotationHeaderInformation.SAPQuotationNo];
        System.assertEquals(0, rslts.size());
    }

    static void testNFM104_insert(Repair__c rpr) {
      StaticParameter.EventOpportunityPileUpExeFlg = true;
      // EventC⇒Event処理後、逆更新をスルー用
      StaticParameter.NotUpdEventCFlg = true;
      // 積み上げ処理後、トリガをスルー用
      StaticParameter.EscapeNFM001Trigger = true;
      StaticParameter.EscapeNFM001AgencyContractTrigger = true;
      StaticParameter.EscapeNFM001AgencyContractTrigger2 = true;
      StaticParameter.EscapeNFM007Trigger = true;
      StaticParameter.EscapeOpportunityBefUpdTrigger = true;
      StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true;
      StaticParameter.EscapeSyncOpportunityTrigger = true;
      StaticParameter.EscapeMaintenanceContractAfterUpdateTrigger = true;
      StaticParameter.EscapeSyncProduct2Trigger = true;
      // trueのとき、リードのトリガーをスルーする
      StaticParameter.EscapeLeadTrigger = true;
      StaticParameter.EscapeAccountTrigger = true;

      StaticParameter.EscapeConsumableOrderDetail2Trigger = true;

      StaticParameter.EscapeNFM010UpsertStatuAchievementsTrigger = true;
      // 直销耗材不直销 ConsumableAssetHander
      StaticParameter.ConsumableAssetHanderTrigger = true;

      // 跳过不涉及备品借出的逻辑
      StaticParameter.rentalApplyIsRunning = true;

      // accountdailyUpdate 跳过 更新询价
      StaticParameter.EscapeOpportunityownerUpdate  = true;
        NFM104Rest.RepairQuotation RepairQuotation                         = new NFM104Rest.RepairQuotation();
        NFM104Rest.QuotationHeaderInformation QuotationHeaderInformation   = new NFM104Rest.QuotationHeaderInformation();
        NFM104Rest.DiscountInformation DiscountInformation                 = new NFM104Rest.DiscountInformation();
        NFM104Rest.InspectionResultInformation InspectionResultInformation = new NFM104Rest.InspectionResultInformation();
        NFM104Rest.FailureInformation FailureInformation                   = new NFM104Rest.FailureInformation();
        NFM104Rest.FailureInformation FailureInformation2                  = new NFM104Rest.FailureInformation();
        NFM104Rest.ActivityInformation ActivityInformation                 = new NFM104Rest.ActivityInformation();

        QuotationHeaderInformation.DiscountInformation         = new NFM104Rest.DiscountInformation[] { DiscountInformation };
        QuotationHeaderInformation.InspectionResultInformation = new NFM104Rest.InspectionResultInformation[] { InspectionResultInformation };
        QuotationHeaderInformation.FailureInformation          = new NFM104Rest.FailureInformation[] { FailureInformation };
        QuotationHeaderInformation.ActivityInformation         = new NFM104Rest.ActivityInformation[] { ActivityInformation };
        RepairQuotation.QuotationHeaderInformation             = new NFM104Rest.QuotationHeaderInformation[] { QuotationHeaderInformation };

        // Monitoringの設定
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        RepairQuotation.Monitoring = new NFMUtil.Monitoring();
        RepairQuotation.Monitoring.MessageGroupNumber = nowStr + count + '1';
        // insert
        QuotationHeaderInformation.SFDCRepairNo          = rpr.Name;
        QuotationHeaderInformation.SAPRepairNo           = rpr.SAPRepairNo__c;
        QuotationHeaderInformation.SAPQuotationNo        = 'NFM104I';
        QuotationHeaderInformation.FirstQuotationDate    = '20140101';
        QuotationHeaderInformation.LatestQuotationDate   = '20140101';
        QuotationHeaderInformation.TotalPrice            = '64300.34';
        QuotationHeaderInformation.RepairRank            = 'A';
        QuotationHeaderInformation.CafeteriaFlag         = '0000021598';

        DiscountInformation.DiscountType                 = '11';
        DiscountInformation.DiscountAmount               = '32000.12';

        InspectionResultInformation.InspectionResultFlag = '0000021598';
        InspectionResultInformation.InspectionComment    = 'CCD线长度: 248MM  把手、S盖脱漆、磨损，旋纽划痕，吸引口、水气口、1号外皮轻磨损。';
        InspectionResultInformation.FailureCause         = '先端部金属磨损严重，插入部发黄结晶，角度不足，钳子口磨损，2、3号外皮变色，水气不畅，CCD玻璃缺损大于1/10，涂胶后无阴影。B级不修理故障：CCD玻璃缺损大于1/10';

        FailureInformation.LocationGroupName             = '内镜连接座部';
        FailureInformation.LocationName                  = 'LG导光杆部';
        FailureInformation.PhenomenonName                = 'IG导光束异常（红裂缝、折损、彩虹斑）';
        FailureInformation.CauseName                     = '劣化, 老化';
        FailureInformation.DescriptionName               = '由于送气･送水圆筒的刮痕导致气囊送水量不能达到规格值。';

        ActivityInformation.ActivityDescription          = '插入部护套更换';

        //NFM104WebService.NFM104(RepairQuotation);
        BatchIF_Log__c rowData = NFMUtil.saveRowData(RepairQuotation.Monitoring, 'NFM104', RepairQuotation.QuotationHeaderInformation);
        if (String.isBlank(rowData.Log__c) == false) 
            NFM104Rest.main(rowData.Id);
        rpr = [select Id, Name, Delivered_Product__c, Repair_Quotation_Id__c, SAPRepairNo__c from Repair__c]; 
        List<Repair_Quotation__c> quotationList = [select Id, Name, Repair_Rank__c, Repair__c
                                                          , InspectionComment__c, InspectionResultFlag__c
                                                          , InspectionFailureCause__c
                                                          , LatestQuotationDate__c
                                                          , FirstQuotationDate__c, TotalPrice__c
                                                          , sales_discount__c, maintenance_pj__c
                                                          , CafeteriaFlag__c, MessageGroupNumber__c
                                                     from Repair_Quotation__c
                                                    where MessageGroupNumber__c =: RepairQuotation.Monitoring.MessageGroupNumber
                                                      and Name = :QuotationHeaderInformation.SAPQuotationNo ];
        count++;
        // System.assertEquals(0, quotationList.size());
        if (quotationList.size() == 1) {
            System.assertEquals(QuotationHeaderInformation.SAPQuotationNo, quotationList[0].Name);
            System.assertEquals(NFMUtil.parseStr2Date(QuotationHeaderInformation.FirstQuotationDate), quotationList[0].FirstQuotationDate__c);
            System.assertEquals(NFMUtil.parseStr2Date(QuotationHeaderInformation.LatestQuotationDate),quotationList[0].LatestQuotationDate__c);
            System.assertEquals(QuotationHeaderInformation.RepairRank, quotationList[0].Repair_Rank__c);
            System.assertEquals(null, quotationList[0].maintenance_pj__c);
            System.assertEquals(InspectionResultInformation.InspectionResultFlag == 'X' ? 'OK' : 'NG', quotationList[0].InspectionResultFlag__c);
            System.assertEquals(InspectionResultInformation.InspectionComment, quotationList[0].InspectionComment__c);
            System.assertEquals(InspectionResultInformation.FailureCause, quotationList[0].InspectionFailureCause__c);
            System.assertEquals(RepairQuotation.Monitoring.MessageGroupNumber, quotationList[0].MessageGroupNumber__c);
            System.assertEquals(rpr.Id, quotationList[0].Repair__c);
            System.assertEquals(rpr.Repair_Quotation_Id__c, quotationList[0].Id);
            System.assertEquals(rpr.SAPRepairNo__c, QuotationHeaderInformation.SAPRepairNo);
            
            List<Repair_quotation_reason__c> qrsnList = [select ActivityDescription__c, Repair_quotation__c, LocationGroupName__c, LocationName__c, PhenomenonName__c, CauseName__c, DescriptionName__c from Repair_quotation_reason__c];
            System.assertEquals(2, qrsnList.size());
            System.assertEquals(quotationList[0].Id, qrsnList[0].Repair_quotation__c);
            System.assertEquals(ActivityInformation.ActivityDescription, qrsnList[0].ActivityDescription__c);
            System.assertEquals(quotationList[0].Id, qrsnList[1].Repair_quotation__c);
            //System.assertEquals(FailureInformation.LocationGroupName, qrsnList[1].LocationGroupName__c);
            System.assertEquals(FailureInformation.LocationName, qrsnList[1].LocationName__c);
            System.assertEquals(FailureInformation.PhenomenonName, qrsnList[1].PhenomenonName__c);
            System.assertEquals(FailureInformation.CauseName, qrsnList[1].CauseName__c);
            System.assertEquals(FailureInformation.DescriptionName, qrsnList[1].DescriptionName__c);

            List<Repair_reason__c> rrsnList = [select Repair__c, Repair_quotation__c, LocationGroupName__c, LocationName__c, PhenomenonName__c, CauseName__c, DescriptionName__c from Repair_reason__c];
            System.assertEquals(0, rrsnList.size());
        }
    }
}