@isTest
private class SSOpportunityBatchTest {

    private static Product2 product = null;
    private static Id pricebookId = ControllerUtil.getStandardPricebook().Id;

    static {
        product = new Product2( Name='テスト商品');
        insert product;
    }

    private static PricebookEntry buildPB(String input) {
        PricebookEntry entry = new PricebookEntry(Pricebook2Id=pricebookId, Product2Id=product.Id);
        entry.UnitPrice = 0;
        entry.IsActive = true;
        entry.UseStandardPrice = false;
        entry.CurrencyIsoCode = input;
        insert entry;
        return entry;
    }

    @isTest(SeeAllData=true)
    static void makeSqlTest() {
        // データを作って、データ移行の項目をテスト
        // テストデータ insertSSTest と同じするする
        Opportunity opp1 = new Opportunity(Name='aiueo1', StageName='出荷', CurrencyIsoCode='USD', CloseDate=Date.today(),Trade__c = '外貿');
        Opportunity opp2 = new Opportunity(Name='aiueo2', StageName='出荷', CurrencyIsoCode='CNY', CloseDate=Date.today(),Trade__c = '内貿');
        insert new Opportunity[] {opp1, opp2};
//        PricebookEntry entryUSD = buildPB('USD');       // opp1用
        PricebookEntry entryCNY = buildPB('CNY');       // opp2用
        OpportunityLineItem oli21 = new OpportunityLineItem(OpportunityId=opp2.Id, Name__c='oli21', Quantity=21, UnitPrice=100, PricebookEntryId=entryCNY.Id);
        OpportunityLineItem oli22 = new OpportunityLineItem(OpportunityId=opp2.Id, Name__c='oli22', Quantity=22, UnitPrice=200, PricebookEntryId=entryCNY.Id);
        insert new OpportunityLineItem[] {oli21, oli22};
        Statu_Achievements__c sta11 = new Statu_Achievements__c(Opportunity__c=opp1.Id, ContractNO__c='sta11', DeliveryStatus__c = '未交付',ContractAmount__c = 11);
        Statu_Achievements__c sta12 = new Statu_Achievements__c(Opportunity__c=opp1.Id, ContractNO__c='sta12', DeliveryStatus__c = '部分交货',ContractAmount__c = 11);
        insert new Statu_Achievements__c[] {sta11, sta12};
        Id execBTId = Database.executeBatch(new SSOpportunityBatch(new Id[] {opp1.Id}), 1);
        execBTId = Database.executeBatch(new SSBackorderBatch(new Id[] {sta11.Id}), 1);
        // ExceptionがなければOK

        // 念のため、再度 select sql の確認
        SS_Batch_Column_Mapping__c setting = SS_Batch_Column_Mapping__c.getValues('Opportunity');
        //for (SS_Batch_Column_Mapping__c setting : settingList) {
            String soql = SSOpportunityBatch.makeSql(setting, new Set<String>());
            soql += ' limit 1';
            Database.query(soql);
            // ExceptionがなければOK
        //}
    }

    @isTest
    static void updateOppTest() {
        // カスタム設定を定義
        SS_Batch_Column_Mapping__c oppMapping = new SS_Batch_Column_Mapping__c(Name = 'Opportunity', SS_TableName__c='SS_Prospect_5days_list__c');
        oppMapping.From_Column_001__c = 'Id';
        oppMapping.SS_Column_001__c = 'Opportunity.Name';
        oppMapping.From_Column_002__c = 'Id';                           // 重複してもエラーにはならない
        oppMapping.SS_Column_002__c = 'Opportunity.Name';
        SS_Batch_Column_Mapping__c oliMapping = new SS_Batch_Column_Mapping__c(Name = 'OpportunityLineItem', SS_TableName__c='SS_Prospect_detail_product__c');
        SS_Batch_Column_Mapping__c staMapping = new SS_Batch_Column_Mapping__c(Name = 'Statu_Achievements__c', SS_TableName__c='SS_backorder_list__c');
        staMapping.From_Column_001__c = 'Id';
        staMapping.SS_Column_001__c = 'Statu_Achievements__c.Name';
        insert new SS_Batch_Column_Mapping__c[] {oppMapping, oliMapping, staMapping};
        // テストデータ
        Opportunity opp1 = new Opportunity(Name='aiueo1', StageName='引合', CloseDate=Date.today());
        Opportunity opp2 = new Opportunity(Name='aiueo2', StageName='引合', CloseDate=Date.today());
        insert new Opportunity[] {opp1, opp2};
        Statu_Achievements__c st1 = new Statu_Achievements__c(Name='st1', Opportunity__c=opp1.Id,ContractAmount__c = 11);
        Statu_Achievements__c st2 = new Statu_Achievements__c(Name='st2', Opportunity__c=opp2.Id,ContractAmount__c = 11);
        insert new Statu_Achievements__c[] {st1, st2};

        System.Test.StartTest();
        Id execBTId = Database.executeBatch(new SSOpportunityBatch(null), 5);
        execBTId = Database.executeBatch(new SSBackorderBatch(null), 5);
        System.Test.StopTest();
        
        opp1 = [Select Id, Name from Opportunity where Id = :opp1.Id];
        opp2 = [Select Id, Name from Opportunity where Id = :opp2.Id];
        System.assertEquals('::' + opp1.Id, opp1.Name);
        System.assertEquals('::' + opp2.Id, opp2.Name);
        st1 = [Select Id, Name from Statu_Achievements__c where Id = :st1.Id];
        st2 = [Select Id, Name from Statu_Achievements__c where Id = :st2.Id];
        System.assertEquals(st1.Id, st1.Name);
        System.assertEquals(st2.Id, st2.Name);
        
        // TODO 预测发货日必须大于预测OCM签约日 の テスト

        //wangweipeng 测试SSBackorderBatch的reuseUpdate方法    start
        SSBackorderBatch ssba = new SSBackorderBatch(null);
        List<Statu_Achievements__c> reuseUpdateList = new List<Statu_Achievements__c>();
        reuseUpdateList.add(new Statu_Achievements__c(Name='st1', Opportunity__c=opp1.Id,ContractAmount__c = 11));
        ssba.reuseUpdate(reuseUpdateList,1);
        //wangweipeng 测试SSBackorderBatch的reuseUpdate方法    end
    }

    @isTest
    static void insertSSTest() {
        // カスタム設定を定義
        SS_Batch_Column_Mapping__c oppMapping = new SS_Batch_Column_Mapping__c(Name = 'Opportunity', SS_TableName__c='SS_Prospect_5days_list__c');
        oppMapping.From_Column_001__c = 'Name';
        oppMapping.SS_Column_001__c = 'Opportunity_Name__c';
        oppMapping.From_Column_002__c = 'Owner.Alias';
        oppMapping.SS_Column_002__c = 'Account_Name__c';
        SS_Batch_Column_Mapping__c oliMapping = new SS_Batch_Column_Mapping__c(Name = 'OpportunityLineItem', SS_TableName__c='SS_Prospect_detail_product__c');
        oliMapping.From_Column_001__c = 'Name__c';
        oliMapping.SS_Column_001__c = 'Product_name__c';
        oliMapping.From_Column_002__c = 'Quantity';
        oliMapping.SS_Column_002__c = 'Number__c';
        SS_Batch_Column_Mapping__c staMapping = new SS_Batch_Column_Mapping__c(Name = 'Statu_Achievements__c', SS_TableName__c='SS_backorder_list__c');
        staMapping.From_Column_001__c = 'ContractNO__c';
        staMapping.From_Column_002__c = 'Id';
        staMapping.SS_Column_001__c = 'ContractNO__c';
        staMapping.SS_Column_002__c = 'BackorderID__c';
        insert new SS_Batch_Column_Mapping__c[] {oppMapping, oliMapping, staMapping};

        // テストデータ
        Opportunity opp1 = new Opportunity(Name='aiueo1', StageName='引合', CurrencyIsoCode='USD', CloseDate=Date.today());
        Opportunity opp2 = new Opportunity(Name='aiueo2', StageName='引合', CurrencyIsoCode='CNY', CloseDate=Date.today());
        insert new Opportunity[] {opp1, opp2};
//        PricebookEntry entryUSD = buildPB('USD');       // opp1用
        PricebookEntry entryCNY = buildPB('CNY');       // opp2用
        OpportunityLineItem oli21 = new OpportunityLineItem(OpportunityId=opp2.Id, Name__c='oli21', Quantity=21, UnitPrice=100, PricebookEntryId=entryCNY.Id);
        OpportunityLineItem oli22 = new OpportunityLineItem(OpportunityId=opp2.Id, Name__c='oli22', Quantity=22, UnitPrice=200, PricebookEntryId=entryCNY.Id);
        insert new OpportunityLineItem[] {oli21, oli22};
        Statu_Achievements__c sta11 = new Statu_Achievements__c(Opportunity__c=opp1.Id, ContractNO__c='sta11', DeliveryStatus__c = '未交付',ContractAmount__c = 11);
        Statu_Achievements__c sta12 = new Statu_Achievements__c(Opportunity__c=opp1.Id, ContractNO__c='sta12', DeliveryStatus__c = '部分交货',ContractAmount__c = 11);
        insert new Statu_Achievements__c[] {sta11, sta12};

        System.Test.StartTest();
        Id execBTId = Database.executeBatch(new SSOpportunityBatch(null), 5);
        execBTId = Database.executeBatch(new SSBackorderBatch(null), 5);
        System.Test.StopTest();
        
        // assert
        opp1 = [Select Id, Name from Opportunity where Id = :opp1.Id];
        opp2 = [Select Id, Name from Opportunity where Id = :opp2.Id];
        List<SS_Prospect_5days_list__c> ssOppList = [Select Id, Opportunity_Name__c from SS_Prospect_5days_list__c order by Name];
        System.assertEquals(2, ssOppList.size());
        System.assertEquals(opp1.Name, ssOppList[0].Opportunity_Name__c);
        System.assertEquals(opp2.Name, ssOppList[1].Opportunity_Name__c);
        List<SS_Prospect_detail_product__c> ssOliList = [Select Id, Product_name__c from SS_Prospect_detail_product__c order by number__c];
        System.assertEquals(2, ssOliList.size());
        System.assertEquals(oli21.Name__c, ssOliList[0].Product_name__c);
        System.assertEquals(oli22.Name__c, ssOliList[1].Product_name__c);
        List<SS_backorder_list__c> ssStaList = [Select Id, ContractNO__c from SS_backorder_list__c order by ContractNO__c];
        System.assertEquals(2, ssStaList.size());
        System.assertEquals(sta11.ContractNO__c, ssStaList[0].ContractNO__c);
        System.assertEquals(sta12.ContractNO__c, ssStaList[1].ContractNO__c);
        
        sta11 = [select SS_backorderID__c from Statu_Achievements__c where Id = :sta11.Id];
        System.assertEquals(ssStaList[0].Id, sta11.SS_backorderID__c);
        sta12 = [select SS_backorderID__c from Statu_Achievements__c where Id = :sta12.Id];
        System.assertEquals(ssStaList[1].Id, sta12.SS_backorderID__c);
    }
}