public with sharing class StatuAchievementsPCLController {
    public List<PCLInfo> pclInfos { get; set; }
    
    /*****************検索用******************/
    public Contact con1 { get; set; }
    public Contact con2 { get; set; }
    
    public String accSearch { get; set; }
    public String ownerSearch { get; set; }
    
    public List<SelectOption> dateOpts { get; private set; }
    public List<SelectOption> textOpts { get; private set; }
    public List<SelectOption> equalOpts { get; private set; }
    public List<SelectOption> textOpts2 { get; private set; }
    public List<SelectOption> equalOpts2 { get; private set; }
    public List<SelectOption> textOpts3 { get; private set; }
    public List<SelectOption> equalOpts3 { get; private set; }
    public List<SelectOption> limitOpts { get; private set; }
    
    public String dateField { get; set; }
    
    public String text { get; set; }
    public String condition { get; set; }
    public String value { get; set; }
    
    public String text2 { get; set; }
    public String condition2 { get; set; }
    public String value2 { get; set; }
    
    public String text3 { get; set; }
    public String condition3 { get; set; }
    public String value3 { get; set; }
    
    // TODO xudan 20140626 チェック：询价、未チェック：全部（後藤要望）
    // FIXME katsu 複数選択にする必要があります。 とりあえず Boolean で作る
    public Boolean onlyOpp { get; set; }
    
    public String limits { get; set; }
    
    /*****************画面表示Bean******************/
    public Integer pclCount { get; set; }
    public String saveType { get; set; }
    
    /*****************金額合計******************/
    public Decimal CAmountSum { get; private set; }
    public Decimal PAmountSum { get; private set; }
    public Decimal NPAmountSum { get; private set; }
    public Decimal USAmountSum { get; private set; }
    public Decimal USwtAmountSum { get; private set; }
    
    /*****************ソートキー******************/
    public String sortKey { get; set; }
    public String preSortKey { get; set; }
    public Boolean sortOrderAsc { get; set; }
    public String[] sortOrder { get; set; }
    public String[] columus = new String[]{'ContractNO__c', 'Opp_Hospital__c', 'Opportunity_Name__c', 'Agency1_Name_F__c', 'Opportunity_Salesdepartment_SAP__c'
                                          ,'SaleProvince_SAP__c', 'Team__c', 'Owner_Category__c', 'Owner__c', 'Order_no_without_0__c', 'Status_1__c'
                       /* 10 */           ,'Status_2_Formula__c', 'Book_stock__c', 'Opp_OCM__c', 'Opp_Department_Name__c', 'Opportunity_Category__c'
                                          ,'QuotationCode__c', 'ContractAmount_F__c', 'PaymentAmount_F__c', 'NOT_PaymentAmount_F__c', 'PaymentRate_F__c'
                       /* 20 */           ,'UnshippedAmount_F__c', 'UnshippedAmount_without_tax_Thousand_DN__c', 'X5weeks_ago__c', 'X4weeks_ago__c', 'X3Weeks_ago__c'
                                          ,'X2weeks_ago__c', 'Last_week__c', 'Current_status__c', 'OverviewStatus__c', 'End_User_contract__c'
                       /* 30 */           ,'PaymentStatus__c', 'AssignmentStatus__c', 'DeliveryStatus__c', 'Pacial_shipment__c', 'SoLatestDeliveryDate__c'
                                          ,'First_DeliveryDate__c', 'Current_shipping_date__c', 'EndUser_contract_submit_day__c', 'Payment_Scheduled_Date__c', 'Payment_All_Scheduled_Date__c'
                       /* 40 */           ,'Shipping_Scheduled_Date__c', 'Follow_up_comment__c', 'Reason_not_collect_money__c', 'Reason_not_ship__c', 'Manager_feedback__c'
                                          ,'Create_Activity__c', 'Create_task__c', 'Key_topic_last_update_date__c', 'Update_situation__c', 'FirstApproveDate__c'
                       /* 50 */           ,'Monthly_forecast_shipping__c', 'Forecast_ship_monthly_mannual__c','	Opp_Number__c','Opportunity__c'
                                          };
    // TODO katsu rl1 ~ rl12 rs1~rs12 はいらない
//    /***************** Rating表示ラベル（動的対応） ******************/
//    public Integer rl1 { get; private set; }
//    public Integer rl2 { get; private set; }
//    public Integer rl3 { get; private set; }
//    public Integer rl4 { get; private set; }
//    public Integer rl5 { get; private set; }
//    public Integer rl6 { get; private set; }
//    public Integer rl7 { get; private set; }
//    public Integer rl8 { get; private set; }
//    public Integer rl9 { get; private set; }
//    public Integer rl10 { get; private set; }
//    public Integer rl11 { get; private set; }
//    public Integer rl12 { get; private set; }
//    
//    /***************** Ratingソート番号（動的対応） ******************/
//    public Integer rs1 { get; private set; }
//    public Integer rs2 { get; private set; }
//    public Integer rs3 { get; private set; }
//    public Integer rs4 { get; private set; }
//    public Integer rs5 { get; private set; }
//    public Integer rs6 { get; private set; }
//    public Integer rs7 { get; private set; }
//    public Integer rs8 { get; private set; }
//    public Integer rs9 { get; private set; }
//    public Integer rs10 { get; private set; }
//    public Integer rs11 { get; private set; }
//    public Integer rs12 { get; private set; }
    
    /*****************ソート時再検索条件（画面からの入力条件を無視するため）******************/
    // TODO katsu sql ２つ を保持すればいいと思います。
    private String soqlWithoutSort = null;
    private String soqlForMoneyWithoutSort = null;
//    private String hpForSort = null;
//    private String ownerForSort = null;
//    private String datefieldForSort = null;
//    private Date fromdForSort = null;
//    private Date todForSort = null;
//    private String textForSort = null;
//    private String conditionForSort = null;
//    private String valueForSort = null;
//    private String textForSort2 = null;
//    private String conditionForSort2 = null;
//    private String valueForSort2 = null;
//    private String textForSort3 = null;
//    private String conditionForSort3 = null;
//    private String valueForSort3 = null;
//    private String limitForSort = null;
//    private Boolean onlyOppForSort = true;

    private static Integer searchLimit = 1000;
    
    public StatuAchievementsPCLController() {
        system.debug('test:12345');
        //Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
        pclInfos = new List<PCLInfo>();
        
        // 日付検索条件のCalendar用
        con1 = new Contact();
        con2 = new Contact();
        
        dateOpts = new List<SelectOption>();
        dateOpts.add(new SelectOption('', '--无--'));
        dateOpts.add(new SelectOption('SoLatestDeliveryDate__c', Schema.SObjectType.Statu_Achievements__c.fields.SoLatestDeliveryDate__c.label));
        dateOpts.add(new SelectOption('First_DeliveryDate__c', Schema.SObjectType.Statu_Achievements__c.fields.First_DeliveryDate__c.label));
        dateOpts.add(new SelectOption('Current_shipping_date__c', Schema.SObjectType.Statu_Achievements__c.fields.Current_shipping_date__c.label));
        dateOpts.add(new SelectOption('EndUser_contract_submit_day__c', Schema.SObjectType.Statu_Achievements__c.fields.EndUser_contract_submit_day__c.label));
        dateOpts.add(new SelectOption('Payment_Scheduled_Date__c', Schema.SObjectType.Statu_Achievements__c.fields.Payment_Scheduled_Date__c.label));
        dateOpts.add(new SelectOption('Payment_All_Scheduled_Date__c', Schema.SObjectType.Statu_Achievements__c.fields.Payment_All_Scheduled_Date__c.label));
        //dateOpts.add(new SelectOption('Shipping_Scheduled_Date__c', Schema.SObjectType.Statu_Achievements__c.fields.Shipping_Scheduled_Date__c.label));
        dateOpts.add(new SelectOption('Shipping_Scheduled_Date_For_Report__c', Schema.SObjectType.Statu_Achievements__c.fields.Shipping_Scheduled_Date_For_Report__c.label));
        dateOpts.add(new SelectOption('FirstApproveDate__c', Schema.SObjectType.Statu_Achievements__c.fields.FirstApproveDate__c.label));

        //syu 2014/6/25 追加した
        dateOpts.add(new SelectOption('Key_topic_last_update_date__c', '重要字段更新日'));
        dateOpts.add(new SelectOption('Last_update_UnshippedAmount_without_tax__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_UnshippedAmount_without_tax__c.label));
        dateOpts.add(new SelectOption('Last_update_OverviewStatus__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_OverviewStatus__c.label));
        dateOpts.add(new SelectOption('Last_update_PaymentStatus__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_PaymentStatus__c.label));
        dateOpts.add(new SelectOption('Last_update_AssignmentStatus__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_AssignmentStatus__c.label));
        dateOpts.add(new SelectOption('Last_update_shipping_status__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_shipping_status__c.label));
        dateOpts.add(new SelectOption('Last_update_EndUser_contract_submit_day__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_EndUser_contract_submit_day__c.label));
        dateOpts.add(new SelectOption('Last_update_Payment_Scheduled_Date__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_Payment_Scheduled_Date__c.label));
        dateOpts.add(new SelectOption('Last_update_Payment_All_Scheduled_Date__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_Payment_All_Scheduled_Date__c.label));
        dateOpts.add(new SelectOption('Last_update_forecast_shipping_date__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_forecast_shipping_date__c.label));
        dateOpts.add(new SelectOption('Last_update_followup_situation__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_followup_situation__c.label));
        dateOpts.add(new SelectOption('Last_update_Reason_not_collect_money__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_Reason_not_collect_money__c.label));
        dateOpts.add(new SelectOption('Last_update_Reason_not_ship__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_Reason_not_ship__c.label));
        dateOpts.add(new SelectOption('Last_update_manager_feedback__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_update_manager_feedback__c.label));

        textOpts = new List<SelectOption>();
        textOpts.add(new SelectOption('','--无--'));
        textOpts.add(new SelectOption('S:ContractNO__c', Schema.SObjectType.Statu_Achievements__c.fields.ContractNO__c.label));
        textOpts.add(new SelectOption('S:Opp_Hospital__c', Schema.SObjectType.Statu_Achievements__c.fields.Opp_Hospital__c.label));
        textOpts.add(new SelectOption('S:Owner_Category__c', Schema.SObjectType.Statu_Achievements__c.fields.Owner_Category__c.label));// 20220907 XLIU-CHY4JL you
        textOpts.add(new SelectOption('S:Opportunity_Name__c', Schema.SObjectType.Opportunity.fields.Name.label));
        textOpts.add(new SelectOption('S:Opportunity__r.Opportunity_sub_owner__r.name', Schema.SObjectType.Opportunity.fields.Opportunity_sub_owner__c.label));
        textOpts.add(new SelectOption('S:Agency1_Name_F__c', Schema.SObjectType.Statu_Achievements__c.fields.Agency1_Name_F__c.label));
        textOpts.add(new SelectOption('S:Opportunity_Salesdepartment_SAP__c', Schema.SObjectType.Opportunity.fields.Salesdepartment_SAP__c.label));
        textOpts.add(new SelectOption('S:SaleProvince_SAP__c', Schema.SObjectType.Statu_Achievements__c.fields.SaleProvince_SAP__c.label));
        textOpts.add(new SelectOption('S:Team__c', Schema.SObjectType.Statu_Achievements__c.fields.Team__c.label));
        textOpts.add(new SelectOption('S:Owner__c', Schema.SObjectType.Statu_Achievements__c.fields.Owner__c.label));
        textOpts.add(new SelectOption('S:Order_no_without_0__c', Schema.SObjectType.Statu_Achievements__c.fields.Order_no_without_0__c.label));
        textOpts.add(new SelectOption('S:Status_1__c', Schema.SObjectType.Statu_Achievements__c.fields.Status_1__c.label));
        //textOpts.add(new SelectOption('S:Status_2_Formula__c', Schema.SObjectType.Statu_Achievements__c.fields.Status_2_Formula__c.label));
        //textOpts.add(new SelectOption('S:Book_stock__c', Schema.SObjectType.Statu_Achievements__c.fields.Book_stock__c.label));
        //textOpts.add(new SelectOption('S:Opp_OCM__c', Schema.SObjectType.Statu_Achievements__c.fields.Opp_OCM__c.label));
        textOpts.add(new SelectOption('S:Opp_Department_Name__c', Schema.SObjectType.Statu_Achievements__c.fields.Opp_Department_Name__c.label));
        textOpts.add(new SelectOption('S:Opportunity_Category__c', Schema.SObjectType.Statu_Achievements__c.fields.Opportunity_Category__c.label));
        //textOpts.add(new SelectOption('S:QuotationCode__c', Schema.SObjectType.Statu_Achievements__c.fields.QuotationCode__c.label));
        //textOpts.add(new SelectOption('N:ContractAmount_F__c', Schema.SObjectType.Statu_Achievements__c.fields.ContractAmount_F__c.label));
        //textOpts.add(new SelectOption('N:PaymentAmount_F__c', Schema.SObjectType.Statu_Achievements__c.fields.PaymentAmount_F__c.label));
        //textOpts.add(new SelectOption('N:NOT_PaymentAmount_F__c', Schema.SObjectType.Statu_Achievements__c.fields.NOT_PaymentAmount_F__c.label));
        textOpts.add(new SelectOption('S:PaymentRate_F__c', Schema.SObjectType.Statu_Achievements__c.fields.PaymentRate_F__c.label));
        //textOpts.add(new SelectOption('N:UnshippedAmount_F__c', Schema.SObjectType.Statu_Achievements__c.fields.UnshippedAmount_F__c.label));
        //textOpts.add(new SelectOption('N:UnshippedAmount_without_tax_F__c', Schema.SObjectType.Statu_Achievements__c.fields.UnshippedAmount_without_tax_F__c.label));
        //textOpts.add(new SelectOption('S:X5weeks_ago__c', Schema.SObjectType.Statu_Achievements__c.fields.X5weeks_ago__c.label));
        //textOpts.add(new SelectOption('S:X4weeks_ago__c', Schema.SObjectType.Statu_Achievements__c.fields.X4weeks_ago__c.label));
        //textOpts.add(new SelectOption('S:X3Weeks_ago__c', Schema.SObjectType.Statu_Achievements__c.fields.X3Weeks_ago__c.label));
        //textOpts.add(new SelectOption('S:X2weeks_ago__c', Schema.SObjectType.Statu_Achievements__c.fields.X2weeks_ago__c.label));
        //textOpts.add(new SelectOption('S:Last_week__c', Schema.SObjectType.Statu_Achievements__c.fields.Last_week__c.label));
        textOpts.add(new SelectOption('S:Current_status__c', Schema.SObjectType.Statu_Achievements__c.fields.Current_status__c.label));
        textOpts.add(new SelectOption('S:OverviewStatus__c', Schema.SObjectType.Statu_Achievements__c.fields.OverviewStatus__c.label));
        textOpts.add(new SelectOption('S:End_User_contract__c', Schema.SObjectType.Statu_Achievements__c.fields.End_User_contract__c.label));
        //textOpts.add(new SelectOption('S:PaymentStatus__c', Schema.SObjectType.Statu_Achievements__c.fields.PaymentStatus__c.label));
        //textOpts.add(new SelectOption('S:AssignmentStatus__c', Schema.SObjectType.Statu_Achievements__c.fields.AssignmentStatus__c.label));
        //textOpts.add(new SelectOption('S:DeliveryStatus__c', Schema.SObjectType.Statu_Achievements__c.fields.DeliveryStatus__c.label));
        //textOpts.add(new SelectOption('N:Pacial_shipment__c', Schema.SObjectType.Statu_Achievements__c.fields.Pacial_shipment__c.label));
        //textOpts.add(new SelectOption('S:Forecast_ship_monthly_mannual__c', Schema.SObjectType.Statu_Achievements__c.fields.Forecast_ship_monthly_mannual__c.label));
        //textOpts.add(new SelectOption('S:Follow_up_comment__c', Schema.SObjectType.Statu_Achievements__c.fields.Follow_up_comment__c.label));
        //textOpts.add(new SelectOption('S:Reason_not_collect_money__c', Schema.SObjectType.Statu_Achievements__c.fields.Reason_not_collect_money__c.label));
        //textOpts.add(new SelectOption('S:Reason_not_ship__c', Schema.SObjectType.Statu_Achievements__c.fields.Reason_not_ship__c.label));
        //textOpts.add(new SelectOption('S:Manager_feedback__c', Schema.SObjectType.Statu_Achievements__c.fields.Manager_feedback__c.label));
        //textOpts.add(new SelectOption('S:Create_Activity__c', Schema.SObjectType.Statu_Achievements__c.fields.Create_Activity__c.label));
        //textOpts.add(new SelectOption('S:Create_task__c', Schema.SObjectType.Statu_Achievements__c.fields.Create_task__c.label));
        //textOpts.add(new SelectOption('S:Update_situation__c', Schema.SObjectType.Statu_Achievements__c.fields.Update_situation__c.label));
        textOpts.add(new SelectOption('S:Monthly_forecast_shipping__c',Schema.SObjectType.Statu_Achievements__c.fields.Monthly_forecast_shipping__c.label));
        textOpts2 = textOpts;
        textOpts3 = textOpts;
        
        equalOpts = new List<SelectOption>();
        equalOpts.add(new SelectOption('equals','等于'));
        equalOpts.add(new SelectOption('notequals','不等于'));
        equalOpts.add(new SelectOption('<','<'));
        equalOpts.add(new SelectOption('>','>'));
        equalOpts.add(new SelectOption('<=','<='));
        equalOpts.add(new SelectOption('>=','>='));
        equalOpts.add(new SelectOption('contains','包含'));
        equalOpts.add(new SelectOption('notcontains','不包含'));
        equalOpts.add(new SelectOption('starts with','起始字符'));
        
        equalOpts2 = equalOpts;
        equalOpts3 = equalOpts;
        
        limitOpts = new List<SelectOption>();
        limitOpts.add(new SelectOption('20','20'));
        limitOpts.add(new SelectOption('50','50'));
        limitOpts.add(new SelectOption('100','100'));
        limitOpts.add(new SelectOption('200','200'));
        limitOpts.add(new SelectOption('500','500'));
        limitOpts.add(new SelectOption('' + (searchLimit + 1), '全部'));
        
        limits = '50';
        
//        rl1 = this.makeRatingLabel(1);
//        rl2 = this.makeRatingLabel(2);
//        rl3 = this.makeRatingLabel(3);
//        rl4 = this.makeRatingLabel(4);
//        rl5 = this.makeRatingLabel(5);
//        rl6 = this.makeRatingLabel(6);
//        rl7 = this.makeRatingLabel(7);
//        rl8 = this.makeRatingLabel(8);
//        rl9 = this.makeRatingLabel(9);
//        rl10 = this.makeRatingLabel(10);
//        rl11 = this.makeRatingLabel(11);
//        rl12 = this.makeRatingLabel(12);
//        
//        // Ratingのソート順番は18～29、固定
//        rs1 = this.makeRatingSortIdx(18);
//        rs2 = this.makeRatingSortIdx(19);
//        rs3 = this.makeRatingSortIdx(20);
//        rs4 = this.makeRatingSortIdx(21);
//        rs5 = this.makeRatingSortIdx(22);
//        rs6 = this.makeRatingSortIdx(23);
//        rs7 = this.makeRatingSortIdx(24);
//        rs8 = this.makeRatingSortIdx(25);
//        rs9 = this.makeRatingSortIdx(26);
//        rs10 = this.makeRatingSortIdx(27);
//        rs11 = this.makeRatingSortIdx(28);
//        rs12 = this.makeRatingSortIdx(29);
    }
    
    public PageReference init() {
        system.debug('test:12345');
        CAmountSum = 0.0;
        PAmountSum = 0.0;
        NPAmountSum = 0.0;
        USAmountSum = 0.0;
        USwtAmountSum = 0.0;

        //20140331追加。郁
        //text='S:DeliveryStatus__c';
        //condition='notequals';
        //value = '已完全交付';
        //text2='S:Status_2_Formula__c';
        //condition2='notequals';
        //value2 = '无效';

        // xudan 20140626 状态1をチェックボックスに
        // [委托]【周会-注残管理表】请确认周会注残管理表显示逻辑 by vivek start
        // onlyOpp = true;
        onlyOpp = false;
        // [委托]【周会-注残管理表】请确认周会注残管理表显示逻辑 by vivek start
        //20140822　追加 by katsu start
        String uidParam = System.currentPageReference().getParameters().get('uid');
        if (uidParam != null){
            User u = [select Id, FirstName, LastName from User where Id = :uidParam];
            ownerSearch = u.LastName + ' ' + u.FirstName;
//            ownerForSort = ownerSearch;
        }
        String hpidParam = System.currentPageReference().getParameters().get('hpid');
        if(hpidParam != null){
            List<Account> hpAcc = ControllerUtil.selectAccountForTrigger(new String[] {hpidParam});
            if (hpAcc.size() > 0) {
                accSearch = hpAcc[0].name;
//                hpForSort = accSearch;
            }
        }
        //20140822　追加 by katsu end
        soqlWithoutSort = this.makeSoql(false, accSearch, ownerSearch, //opp.Opportunity_Category__c, opp.Consumable__c,
                                    dateField, con1.Birthdate, con2.Birthdate, text, condition, value, text2, condition2, value2, text3, condition3, value3);
        String soql = soqlWithoutSort + ' order by LastModifiedDate desc limit ' + Integer.valueOf(limits);
        
        soqlForMoneyWithoutSort = this.makeSoql(true, accSearch, ownerSearch, //opp.Opportunity_Category__c, opp.Consumable__c,
                                    dateField, con1.Birthdate, con2.Birthdate, text, condition, value, text2, condition2, value2, text3, condition3, value3);
        String soqlForMoney = soqlForMoneyWithoutSort + ' order by LastModifiedDate desc limit ' + Integer.valueOf(System.Label.TotalLimit);
        System.debug('soqlWithoutSort:' + soqlWithoutSort);
        List<Statu_Achievements__c> queryList = Database.query(soql);
        List<Statu_Achievements__c> queryListForMoney = Database.query(soqlForMoney);
        
        this.makeOppRecordsForView(queryList, queryListForMoney);
        
        this.sortKey = '0';
        this.preSortKey = '0';
        this.sortOrderAsc = true;
        this.sortOrder = new String[columus.size()];
        for (Integer i = 0; i < columus.size(); i++) this.sortOrder[i] = '　';
        
        pclCount = pclInfos.size();
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + pclCount + ' 条数据'));
        
        return null;
    }
    
    public PageReference searchOpp() {
        pclInfos = new List<PCLInfo>();
        
        String soql = this.makeSoql(false, accSearch, ownerSearch, //opp.Opportunity_Category__c, opp.Rating_manual__c, opp.Consumable__c,
                                    dateField, con1.Birthdate, con2.Birthdate, text, condition, value, text2, condition2, value2, text3, condition3, value3);
        soql += ' order by ContractNO__c limit ' + Integer.valueOf(limits);
        
        String soqlForMoney = this.makeSoql(true, accSearch, ownerSearch, //opp.Opportunity_Category__c, opp.Rating_manual__c, opp.Consumable__c,
                                    dateField, con1.Birthdate, con2.Birthdate, text, condition, value, text2, condition2, value2, text3, condition3, value3);
        soqlForMoney += ' order by ContractNO__c limit ' + Integer.valueOf(System.Label.TotalLimit);
        this.sortOrder[0] = '↑';
        
        system.debug('soql：'+soql);
        system.debug('soqlForMoney：'+soqlForMoney);
        List<Statu_Achievements__c> queryList = Database.query(soql);
        List<Statu_Achievements__c> queryListForMoney = Database.query(soqlForMoney);
        
        CAmountSum = 0.0;
        PAmountSum = 0.0;
        NPAmountSum = 0.0;
        USAmountSum = 0.0;
        USwtAmountSum = 0.0;
        
        this.makeOppRecordsForView(queryList, queryListForMoney);
        
//        hpForSort = accSearch;
//        ownerForSort = ownerSearch;
//        datefieldForSort = dateField;
//        fromdForSort = con1.Birthdate;
//        todForSort = con2.Birthdate;
//        textForSort = text;
//        conditionForSort = condition;
//        valueForSort = value;
//        textForSort2 = text2;
//        conditionForSort2 = condition2;
//        valueForSort2 = value2;
//        textForSort3 = text3;
//        conditionForSort3 = condition3;
//        valueForSort3 = value3;
//        limitForSort = limits;
//        onlyOppForSort = onlyOpp;
        
        pclCount = pclInfos.size();
        if (pclCount > searchLimit) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'The search returned more than the maximum number of rows (' + searchLimit + ')'));
        } else {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + pclCount + ' 条数据'));
        }
        return null;
    }
    
    public PageReference sortTable() {
        pclInfos = new List<PCLInfo>();
        
        if (this.sortKey == this.preSortKey) {
            // 方向が変わるのみ
            this.sortOrderAsc = !this.sortOrderAsc;
            this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
        } else {
            this.sortOrderAsc = true;
            this.sortOrder[Integer.valueOf(this.preSortKey)] = '　';
            this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
        }
        this.preSortKey = this.sortKey;
        
        String soql = soqlWithoutSort
                + ' order by ' + this.columus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
system.debug('sort:::::'+ soql);
        List<Statu_Achievements__c> queryList = Database.query(soql);
        String soqlForMoney = soqlForMoneyWithoutSort 
                + ' order by ' + this.columus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last')+ ' limit ' + Integer.valueOf(System.Label.TotalLimit) ;
system.debug('sort:::::'+ soqlForMoney);
        List<Statu_Achievements__c> queryListForMoney = Database.query(soqlForMoney);
        
        CAmountSum = 0.0;
        PAmountSum = 0.0;
        NPAmountSum = 0.0;
        USAmountSum = 0.0;
        USwtAmountSum = 0.0;
        
        this.makeOppRecordsForView(queryList, queryListForMoney);
        
        pclCount = pclInfos.size();
        if (pclCount > searchLimit) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'The search returned more than the maximum number of rows (' + searchLimit + ')'));
        } else {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + pclCount + ' 条数据'));
        }
        return null;
    }
    
    public PageReference save() {
        try {
            List<Statu_Achievements__c> updSAs = new List<Statu_Achievements__c>();
            
            for (PCLInfo oi : pclInfos) {
                // 変更チェック
                if (oi.changeFlg == '1') {
                    oi.changeFlg = '0';
                    updSAs.add(oi.rec);
                }
            }
            
            if (updSAs.size() > 0) update updSAs;
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'Save Completed'));
        } catch (Exception ex) {
            ApexPages.addMessages(ex);
            return null;
        }
        
        if (saveType == '1') {
            searchOpp();
            saveType = '';
        } else if (saveType == '2') {
            sortTable();
            saveType = '';
        } else {
        }
        return null;
    }
    
    public PageReference cancel() {
        return new PageReference('/home/home.jsp');
    }
    
    // TODO katsu 出す項目の整理
    private String makeSoql(Boolean isforMoneyFlg, String accStr, String ownerStr, //String dept, String rank, Boolean consumable,
                            String datefield, Date fromd, Date tod, String txt, String con, String val,
                            String txt2, String con2, String val2,
                            String txt3, String con3, String val3) {
        String soql ='';
        if (isforMoneyFlg == false) {
            
            // [委托]【周会-注残管理表】请确认周会注残管理表显示逻辑 修改之前的where条件：where Id != null  and DeliveryStatus__c <> \'已完全交付\' and Status_2_Formula__c <> \'无效\'   修改之后的where条件：where Id != null  and Status_2_Formula__c <> \'无效\' and Status_1__c not in (\'取消\',\'完毕\',\'冻结\') and UnshippedAmount_without_tax_Thousand_F__c > 1'; by vivek start
            //【委托】【重要】周会管理表修改 (添加字段：Opportunity__c) by tcm  20211029 start
            soql += 'select Id, Opportunity__c,	Opp_Number__c, ContractNO__c, Opp_Hospital__c, QuotationCode__c, DeliveryStatus__c,'
                + ' Last_update_PaymentStatus__c, Last_update_AssignmentStatus__c, Last_update_Reason_not_collect_money__c, Last_update_UnshippedAmount_without_tax__c,'
                + ' Last_update_Reason_not_ship__c, Last_update_followup_situation__c, Last_update_shipping_status__c, Last_update_OverviewStatus__c, Last_update_manager_feedback__c,'
                + ' Last_update_Payment_All_Scheduled_Date__c, Last_update_Payment_Scheduled_Date__c, Last_update_forecast_shipping_date__c, Last_update_EndUser_contract_submit_day__c,'
                + ' ContractNO_link__c, Hospital_link__c, Opportunity_Name__c, Agency1_Name_F__c, Opportunity_Salesdepartment_SAP__c,'
                + ' SaleProvince_SAP__c, Team__c, Owner_Category__c, Owner__c, Order_no_without_0__c, Status_1__c,Opportunity__r.Opportunity_sub_owner__c,'
                + ' Status_2_Formula__c, Book_stock__c, Opp_OCM__c, Opp_Department_Name__c, Opportunity_Category__c,'
                + ' Open_Quotation__c, ContractAmount_F__c, PaymentAmount_F__c, NOT_PaymentAmount_F__c, PaymentRate_F__c,'
                + ' UnshippedAmount_F__c, UnshippedAmount_without_tax_Thousand_DN__c, X5weeks_ago__c, X4weeks_ago__c, X3Weeks_ago__c,'
                + ' X2weeks_ago__c, Last_week__c, Current_status__c, OverviewStatus__c, End_User_contract__c,'
                + ' PaymentStatus__c, AssignmentStatus__c, Parcial_ship_link__c, Pacial_shipment__c, SoLatestDeliveryDate__c,'
                + ' First_DeliveryDate__c, Current_shipping_date__c, EndUser_contract_submit_day__c, Payment_Scheduled_Date__c, Payment_All_Scheduled_Date__c,'
                + ' Shipping_Scheduled_Date__c, Follow_up_comment__c, Reason_not_collect_money__c, Reason_not_ship__c, Manager_feedback__c,'
                + ' Create_Activity__c, Create_task__c, Key_topic_last_update_date__c, Update_situation__c, FirstApproveDate__c,'
                + ' Monthly_forecast_shipping__c, Forecast_ship_monthly_mannual__c'
                + ' from Statu_Achievements__c where Id != null  and Status_2_Formula__c <> \'无效\' and Status_1__c not in (\'取消\',\'完毕\',\'冻结\') and Forecast_Amount_F__c > 1';
        } else {
            soql += 'select Id, Opportunity__c,ContractNO__c,Opp_Number__c, Opp_Hospital__c, QuotationCode__c, DeliveryStatus__c,'
                + ' Last_update_PaymentStatus__c, Last_update_AssignmentStatus__c, Last_update_Reason_not_collect_money__c, Last_update_UnshippedAmount_without_tax__c,'
                + ' Last_update_Reason_not_ship__c, Last_update_followup_situation__c, Last_update_shipping_status__c, Last_update_OverviewStatus__c, Last_update_manager_feedback__c,'
                + ' Last_update_Payment_All_Scheduled_Date__c, Last_update_Payment_Scheduled_Date__c, Last_update_forecast_shipping_date__c, Last_update_EndUser_contract_submit_day__c,'
                + ' ContractNO_link__c, Hospital_link__c, Opportunity_Name__c, Agency1_Name_F__c, Opportunity_Salesdepartment_SAP__c,'
                + ' SaleProvince_SAP__c, Team__c, Owner_Category__c, Owner__c, Order_no_without_0__c, Status_1__c,Opportunity__r.Opportunity_sub_owner__c,'
                + ' Status_2_Formula__c, Book_stock__c, Opp_OCM__c, Opp_Department_Name__c, Opportunity_Category__c,'
                + ' Open_Quotation__c, convertCurrency(ContractAmount_F__c), convertCurrency(PaymentAmount_F__c), convertCurrency(NOT_PaymentAmount_F__c), PaymentRate_F__c,'
                + ' convertCurrency(UnshippedAmount_F__c), UnshippedAmount_without_tax_Thousand_DN__c, X5weeks_ago__c, X4weeks_ago__c, X3Weeks_ago__c,'
                + ' X2weeks_ago__c, Last_week__c, Current_status__c, OverviewStatus__c, End_User_contract__c,'
                + ' PaymentStatus__c, AssignmentStatus__c, Parcial_ship_link__c, Pacial_shipment__c, SoLatestDeliveryDate__c,'
                + ' First_DeliveryDate__c, Current_shipping_date__c, EndUser_contract_submit_day__c, Payment_Scheduled_Date__c, Payment_All_Scheduled_Date__c,'
                + ' Shipping_Scheduled_Date__c, Follow_up_comment__c, Reason_not_collect_money__c, Reason_not_ship__c, Manager_feedback__c,'
                + ' Create_Activity__c, Create_task__c, Key_topic_last_update_date__c, Update_situation__c, FirstApproveDate__c,'
                + ' Monthly_forecast_shipping__c, Forecast_ship_monthly_mannual__c'
                + ' from Statu_Achievements__c where Id != null  and Status_2_Formula__c <> \'无效\' and Status_1__c not in (\'取消\',\'完毕\',\'冻结\') and Forecast_Amount_F__c > 1';
        }
            //【委托】【重要】周会管理表修改 (添加字段：Opportunity__c) by tcm  20211029 end
        // [委托]【周会-注残管理表】请确认周会注残管理表显示逻辑 by vivek end
        // xudan 20140626 状态1をチェックボックスに

        if (onlyOpp) {
            // [委托]【周会-注残管理表】请确认周会注残管理表显示逻辑 by vivek start
            // soql += ' and (Opportunity__r.StageName__c = \'注残\' or Opportunity__r.StageName__c = \'发货\') ';
            soql += ' and (Opportunity__r.StageName__c = \'注残\' or Opportunity__r.StageName__c = \'发货\') and DeliveryStatus__c = \'部分交付\'';
            // [委托]【周会-注残管理表】请确认周会注残管理表显示逻辑 by vivek end
        }
        // [委托]【周会-注残管理表】请确认周会注残管理表显示逻辑 by vivek start
        // if(!onlyOpp){
        //     soql += 'and DeliveryStatus__c <> \'已完全交付\'';
        // }
        // [委托]【周会-注残管理表】请确认周会注残管理表显示逻辑 by vivek end

        if (!String.isBlank(accStr)) {
            //soql += ' and Hospital__c = \'' + accStr + '\'';
            String[] vals = accStr.split(' ');
            for (String v : vals) {
                soql += ' and Opp_Hospital__c like \'%' + v + '%\'';
            }
        }
        if (!String.isBlank(ownerStr)) {
            //soql += ' and OwnerId = \'' + ownerStr + '\'';
            String[] vals = ownerStr.split(' ');
            for (String v : vals) {
                soql += ' and Opportunity__r.Owner.Name like \'%' + v + '%\'';
            }
        }
        
        if (!String.isBlank(datefield)) {
            if (fromd != null) {
                soql += ' and ' +  datefield + ' >= ' + String.valueOf(fromd).substring(0, 10);
            }
            if (tod != null) {
                soql += ' and (' +  datefield + ' <= ' + String.valueOf(tod).substring(0, 10) + ' OR ' + datefield + ' = null)';
            }
        }
        
        // xudan 20140507 検索ロジック修正
        soql += this.makeTextSql(txt, con, val);
        soql += this.makeTextSql(txt2, con2, val2);
        soql += this.makeTextSql(txt3, con3, val3);
        
        system.debug(soql);
        return soql;
    }
    
    private void makeOppRecordsForView(List<Statu_Achievements__c> queryList, List<Statu_Achievements__c> queryListForMoney) {
        Savepoint sp = Database.setSavepoint();
        // TODO queryList について、最初のoppLimitだけ更新すればOKです。
        Database.SaveResult[] results = Database.update(queryList, false);
        // 強制ロールバック
        Database.rollback(sp);
        
        for (Integer i = 0; i < queryListForMoney.size(); i++) {
            if(i<queryList.size()){
                // limitを超えた場合前limit件のみを出す
                if (i == searchLimit + 1) {
                    // FIXME メッセージ表示
                    continue;
                }
                pclInfos.add(new PCLInfo(queryList[i]));
                pclInfos[pclInfos.size() - 1].lineNo = pclInfos.size() - 1;
                if (!results[i].isSuccess()) {
                    pclInfos[pclInfos.size() - 1].canEdit = false;
                    // 空更新失敗の場合、編集できないとみなす
                    // xudan 20140624 更新権限のエラーのみロック
                    if (results[i].getErrors()[0].getStatusCode() != null) {
                        if (String.valueOf(results[i].getErrors()[0].getStatusCode()) == 'INSUFFICIENT_ACCESS_OR_READONLY') {
                            pclInfos[pclInfos.size() - 1].hasError = true;
                        // xudan 20140624 更新権限エラーとほかのエラーを区別
                        } else {
                            pclInfos[pclInfos.size() - 1].hasFieldError = true;
                        }
                    }
                }
            }
            if (queryListForMoney[i].ContractAmount_F__c != null) CAmountSum += queryListForMoney[i].ContractAmount_F__c;
            if (queryListForMoney[i].PaymentAmount_F__c != null) PAmountSum += queryListForMoney[i].PaymentAmount_F__c;
            if (queryListForMoney[i].NOT_PaymentAmount_F__c != null) NPAmountSum += queryListForMoney[i].NOT_PaymentAmount_F__c;
            if (queryListForMoney[i].UnshippedAmount_F__c != null) USAmountSum += queryListForMoney[i].UnshippedAmount_F__c;
            // LHJ 20200618 Start
            // if (queryListForMoney[i].UnshippedAmount_without_tax_F__c != null) USwtAmountSum += queryListForMoney[i].UnshippedAmount_without_tax_F__c;
            if (queryListForMoney[i].UnshippedAmount_without_tax_Thousand_DN__c != null) USwtAmountSum += queryListForMoney[i].UnshippedAmount_without_tax_Thousand_DN__c;
            // LHJ 20200618 End
        }
    }
    
    private String makeTextSql(String txt1, String con, String val) {
        String soql = '';
        // containsの場合、日報画面の病院検索を真似し、spaceで分けて、and検索
        // equalsの場合、SF標準の検索を真似し、「,」で分けて、or検索
        if (!String.isBlank(txt1)) {
            if ((con == 'contains' || con == 'notcontains') && val.contains(' ')) {
                String[] vals = val.split(' ');
                String cSql = '';
                for (String v : vals) {
                    cSql += this.makeTextSqlStr(txt1, con, v);
                }
                if (con == 'contains') {
                    soql += cSql;
                } else {
                    // notcontains
                    cSql = cSql.replaceAll(' and ', ') and (NOT ');
                    soql += cSql.substring(1) + ') ';
                }
            } else if ((con == 'equals' || con == 'notequals') && val.contains(',')) {
                String[] vals = val.split(',');
                if (vals.size() > 0) {
                    String txt = txt1.substring(2);     // S:Name 、最初の２文字がタイプです
                    soql += ' and ( ';
                    for (String v : vals) {
                        if (con == 'equals') {
                            soql += txt + ' = \'' + v + '\' or ';
                        } else {
                            // notequals
                            soql += txt + ' <> \'' + v + '\' and ';
                        }
                    }
                    soql = soql.substring(0, soql.length() - 4);
                    soql += ')';
                }
            } else {
                String cSql = this.makeTextSqlStr(txt1, con, val);
                if (con != 'notcontains') {
                    soql += this.makeTextSqlStr(txt1, con, val);
                } else {
                    // notcontains
                    cSql = cSql.substring(5);       // ' and ' の5文字を外す
                    soql += ' and (NOT ' + cSql + ') ';
                }
            }
        }
        return soql;
    }
    
    /**
     * 文字列検索文を作成
     */ 
    private String makeTextSqlStr(String txt1, String con, String val) {
        String soql = '';
        if (!String.isBlank(txt1)) {
            String txt = txt1.substring(2);
            String colType = txt1.substring(0, 2);
            String tmpVal = val;
            // 空白の場合''にする
            if (String.isBlank(tmpVal)) {
                if (con == 'equals') {
                    //soql += ' and ' + txt + ' = ' + tmpVal;
                    soql += ' and ' + txt + ' = null';
                } else if (con == 'notequals') {
                    soql += ' and ' + txt + ' <> null';
                } else {
                    // 空白の場合、contains, notcontains と starts withは無視
                }
            } else {
                soql += ' and ' + txt;
                if (con == 'equals') {
                    if (colType == 'S:') {
                        soql += ' = \'' + tmpVal + '\'';
                    } else {
                        soql += ' = ' + tmpVal + ' ';
                    }
                } else if (con == 'notequals') {
                    if (colType == 'S:') {
                        soql += ' <> \'' + tmpVal + '\'';
                    } else {
                        soql += ' <> ' + tmpVal + ' ';
                    }
                } else if (con == 'contains' || con == 'notcontains') {
                    soql += ' like \'%' + tmpVal + '%\'';
                } else if (con == 'starts with') {
                    soql += ' like \'' + tmpVal + '%\'';
                } else {
                    if (colType == 'S:') {
                        soql += ' ' + con + '\'' + tmpVal + '\'';
                    } else {
                        soql += ' ' + con + ' ' + tmpVal + ' ';
                    }
                }
            }
        }
        return soql;
    }
    
//    /**
//     * 現在の月にて、表示すべきラベル名を作成
//     */
//    private Integer makeRatingLabel(Integer idx) {
//        Integer m = Date.today().month();
//        
//        Integer val = idx - 1 + m;
//        if (val > 12) {
//            val = val - 12;
//        }
//        return val;
//    }
//    
//    /**
//     * 現在の月にて、Ratingのソート番号を作成
//     */
//    private Integer makeRatingSortIdx(Integer idx) {
//        Integer m = Date.today().month();
//        
//        Integer val = idx - 1 + m;
//        if (val > 29) {
//            val = val - 12;
//        }
//        return val;
//    }
    
    class PCLInfo {
        public Statu_Achievements__c rec { get; set; }
        public Boolean canEdit { get; private set; }
        public Boolean hasError { get; private set; }
        public Boolean hasFieldError { get; private set; }
        public Integer lineNo { get; private set; }
        public String changeFlg { get; set; }
        
        public PCLInfo(Statu_Achievements__c record) {
            rec = record;
            canEdit = true;
            hasError = false;
            hasFieldError = false;
            lineNo = 0;
            changeFlg = '0';
        }
    }

    
}