public with sharing class DigCasesNumberController {
    public List<AccountInfo> oppRecords { get; set; }
    // ページレイアウトの情報を取得
    private Map<String, Map<String, String>> editLayoutItemRWMap = null;
    private Map<String, Map<String, String>> editLayoutItemRWMapRt = null;


    /*****************検索用******************/
    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 List<SelectOption> accTypeOpts { get; private set; }
    public List<SelectOption> ocmYearOpts { get; private set; }
    public List<SelectOption> DepartmentOpts { get; private set; }  //20211208
    public List<SelectOption> textOpts4 { get; private set; }
    public List<SelectOption> equalOpts4 { 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; }

    public String text4 { get; set; }
    public String condition4 { get; set; }
    public String value4 { get; set; }

    public String accType { get; set; }

    public String limits { get; set; }

    public Boolean sltv { get; set; }
    public Boolean sltvM { get; set; }
    public Boolean sltvL { get; set; }
    public Boolean customerTarget { get; set; }

    public String ocmYear { get; set; }
    public String Department { get; set; }    //20211208

    /*****************画面表示Bean******************/
    public Integer oppCount { get; set; }
    public String saveType { get; 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[] {'Id', 'RecordType.DeveloperName', 'ParentId', 'Parent.RecordType.DeveloperName', 'Parent.ParentId', 'Parent.Parent.RecordType.DeveloperName'};
    public String[] selColumus = null;
    public Set<String> columusSet = new Set<String> {'Id', 'RecordType.DeveloperName', 'ParentId', 'Parent.RecordType.DeveloperName', 'Parent.ParentId', 'Parent.Parent.RecordType.DeveloperName'};

    // 项目set 字段标签
    public List<String> titleLeft { get; private set; }
    public List<String> titleRight { get; private set; }
    // 项目set 字段名
    public List<List<String>> columnsLeftApi { get; private set; }         // 参照項目用
    public List<List<String>> columnsRightApi { get; private set; }        // 参照項目用
    public List<String> columnLeftCss { get; private set; }               // css 用
    public List<String> columnRightCss { get; private set; }              // css 用
    public Map<String, String> columnLeftRW { get; private set; }              // r,w,wm用
    public Map<String, String> columnRightRW { get; private set; }             // r,w,wm用
    private String strColumus;
    private String strRtColumus;

        /*****************ソート時再検索条件（画面からの入力条件を無視するため）******************/
    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;
    @TestVisible private String accTypeForSort = null;
    private Boolean sltvForSort = true;
    private Boolean sltvMForSort = true;
    private Boolean sltvLForSort = false;
    private Boolean customerTargetForSort = false;
    private String textForSort4 = null;
    private String conditionForSort4 = null;
    private String valueForSort4 = null;

    private static Integer oppLimit = 500;
    private Boolean isForMoneyFlg = false;

    public DigCasesNumberController() {
        editLayoutItemRWMap = SoapApi.getEditRWByRecordType('Account', null);
        editLayoutItemRWMapRt = SoapApi.getEditRWByRecordType('Account_Number_of_case__c', null);

        oppRecords = new List<AccountInfo>();

        // 日付検索条件のCalendar用
        con1 = new Contact();
        con2 = new Contact();

        dateOpts = new List<SelectOption>();
        dateOpts.add(new SelectOption('', '--无--'));
        dateOpts.add(new SelectOption('Registration_Day__c', '登录日'));
        dateOpts.add(new SelectOption('Ban_On_Use_Date__c', '禁用日期'));

        textOpts = new List<SelectOption>();
        textOpts.add(new SelectOption('', '--无--'));
        //textOpts.add(new SelectOption('S:Name','客户名'));
        //textOpts.add(new SelectOption('S:Management_Code__c','管理编码'));
        textOpts.add(new SelectOption('S:Salesdepartment_HP__c', '销售本部'));
        textOpts.add(new SelectOption('S:State_Master__r.Name', '省'));
        textOpts.add(new SelectOption('S:City_Master__r.Name', '市'));
        // TODO OCM科室等级？OCM分类？
        textOpts.add(new SelectOption('S:Segment__c', 'OCSM科室等级'));

        textOpts2 = textOpts;
        textOpts3 = textOpts;

        textOpts4 = new List<SelectOption>();
        textOpts4.add(new SelectOption('', '--无--'));
        textOpts4.add(new SelectOption('S:GI_Main__r.Alias', '消化科主担当'));
        textOpts4.add(new SelectOption('S:BF_owner__r.Alias', '呼吸科主担当'));
        textOpts4.add(new SelectOption('S:ET_owner__r.Alias', 'ET科主担当'));
        textOpts4.add(new SelectOption('S:SP_Main__r.Alias', '普外科主担当'));
        textOpts4.add(new SelectOption('S:URO_owner_ID__r.Alias', '泌尿科主担当'));
        textOpts4.add(new SelectOption('S:GYN_owner__r.Alias', '妇科主担当'));
        textOpts4.add(new SelectOption('S:ENT_owner_ID__r.Alias', '耳鼻喉科主担当'));
        //textOpts4.add(new SelectOption('S:FSE_SP_Main_Leader__c','FSE-SP主担当'));
        //textOpts4.add(new SelectOption('S:FSE_GI_Main_Leader__c','FSE-GI主担当'));

        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;
        equalOpts4 = 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('' + (oppLimit + 1), '全部'));

        accTypeOpts = new List<SelectOption>();
        // accTypeOpts.add(new SelectOption('01210000000QemG', '医院'));
        accTypeOpts.add(new SelectOption('01210000000QemL', '消化科'));
        accTypeOpts.add(new SelectOption('01210000000QezZ', '呼吸科'));
        accTypeOpts.add(new SelectOption('01210000000Qeze', '普外科'));
        accTypeOpts.add(new SelectOption('01210000000Qezj', '泌尿科'));
        accTypeOpts.add(new SelectOption('01210000000Qezo', '妇科'));
        accTypeOpts.add(new SelectOption('01210000000Qezt', '耳鼻喉科'));
        // accTypeOpts.add(new SelectOption('01210000000QemQ', 'ET'));
        // accTypeOpts.add(new SelectOption('01210000000Qezy', '其他'));
        
        //20211208
        DepartmentOpts = new List<SelectOption>();
        DepartmentOpts.add(new SelectOption('', '--无--'));
        DepartmentOpts.add(new SelectOption('国家级', '国家级'));
        DepartmentOpts.add(new SelectOption('省级', '省级'));
        DepartmentOpts.add(new SelectOption('地市级', '地市级'));
        DepartmentOpts.add(new SelectOption('区县级', '区县级'));
        DepartmentOpts.add(new SelectOption('私立', '私立'));
        //20211208

        ocmYearOpts = new List<SelectOption>();
        ocmYearOpts.add(new SelectOption('2012年度', '2012年度'));   //145P
        ocmYearOpts.add(new SelectOption('2013年度', '2013年度'));   //146P
        ocmYearOpts.add(new SelectOption('2014年度', '2014年度'));   //147P
        ocmYearOpts.add(new SelectOption('2015年度', '2015年度'));   //148P
        ocmYearOpts.add(new SelectOption('2016年度', '2016年度'));   //149P
        ocmYearOpts.add(new SelectOption('2017年度', '2017年度'));   //150P
        ocmYearOpts.add(new SelectOption('2018年度', '2018年度'));   //151P
        ocmYearOpts.add(new SelectOption('2019年度', '2019年度'));   //152P
        ocmYearOpts.add(new SelectOption('2020年度', '2020年度'));   //153P
        ocmYearOpts.add(new SelectOption('2021年度', '2021年度'));   //154P
        ocmYearOpts.add(new SelectOption('2022年度', '2022年度'));   //155P
        ocmYearOpts.add(new SelectOption('2023年度', '2023年度'));
        ocmYearOpts.add(new SelectOption('2024年度', '2024年度'));
        ocmYearOpts.add(new SelectOption('2025年度', '2025年度'));
        ocmYearOpts.add(new SelectOption('2026年度', '2026年度'));

        limits = '50';
    }

    public PageReference init() {
        String rdTypeId = System.currentPageReference().getParameters().get('accType');
        if (rdTypeId != null) {
            this.setUrlStr();
        } else {
            accType = '01210000000QemL';   //消化科
            sltv = true;
            sltvM = true;
            sltvL = false;
            // SWAG-BC832V start
            //customerTarget = true;
            Date dateToday = Date.today();
            Integer year = dateToday.year();
            // Integer month = dateToday.month();
            // if (month < 4) {
            //     year -= 1;
            // }
            // 今年度以降のデータを探す
            //String thisYearOCMPeriod = String.valueOf(year - 1867 + 'P');
            String thisYearOCMPeriod = String.valueOf(year - 1 + '年度');
            ocmYear = thisYearOCMPeriod;

            Department = '';

            // SWAG-BC832V end
            //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;
            }
            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;
                }
            }
            //20140822　追加 by katsu end
        }

        searchOppSetParam();
        setLayoutRWInfo();
        searchOppInner();
        return null;
    }

    private void searchOppSetParam() {
        if (accTypeForSort != accType) {
            this.sortOrder = null;
        }
        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;
        accTypeForSort = accType;
        sltvForSort = sltv;
        sltvMForSort = sltvM;
        sltvLForSort = sltvL;
        //customerTargetForSort = customerTarget;
        textForSort4 = text4;
        conditionForSort4 = condition4;
        valueForSort4 = value4;
    }

    private String getUrlStr() {
        String urlStr = 'accType=' + accType + '&accSearch=' + getBlankValue(accSearch) + '&ownerSearch=' + getBlankValue(ownerSearch);
        urlStr += '&text=' + getBlankValue(text) + '&condition=' + getBlankValue(condition) + '&value=' + getBlankValue(value);
        urlStr += '&text2=' + getBlankValue(text2) + '&condition2=' + getBlankValue(condition2) + '&value2=' + getBlankValue(value2);
        urlStr += '&text3=' + getBlankValue(text3) + '&condition3=' + getBlankValue(condition3) + '&value3=' + getBlankValue(value3);
        urlStr += '&text4=' + getBlankValue(text4) + '&condition4=' + getBlankValue(condition4) + '&value4=' + getBlankValue(value4);
        urlStr += '&limits=' + limits + '&sltv=' + (sltv ? '1' : '0') + '&sltvM=' + (sltvM ? '1' : '0');
        urlStr += '&sltvL=' + (sltvL ? '1' : '0') + '&ocmYear=' + ocmYear + '&Department=' + getBlankValue(Department);
        return urlStr;
    }

    @TestVisible private void setUrlStr() {
        accSearch = System.currentPageReference().getParameters().get('accSearch');
        ownerSearch = System.currentPageReference().getParameters().get('ownerSearch');
        text = System.currentPageReference().getParameters().get('text');
        condition = System.currentPageReference().getParameters().get('condition');
        value = System.currentPageReference().getParameters().get('value');
        text2 = System.currentPageReference().getParameters().get('text2');
        condition2 = System.currentPageReference().getParameters().get('condition2');
        value2 = System.currentPageReference().getParameters().get('value2');
        text3 = System.currentPageReference().getParameters().get('text3');
        condition3 = System.currentPageReference().getParameters().get('condition3');
        value3 = System.currentPageReference().getParameters().get('value3');
        limits = System.currentPageReference().getParameters().get('limits');
        accType = System.currentPageReference().getParameters().get('accType');
        sltv = System.currentPageReference().getParameters().get('sltv') == '1' ? true : false;
        sltvM = System.currentPageReference().getParameters().get('sltvM') == '1' ? true : false;
        sltvL = System.currentPageReference().getParameters().get('sltvL') == '1' ? true : false;
        //customerTarget = System.currentPageReference().getParameters().get('customerTarget') == '1' ? true : false;
        text4 = System.currentPageReference().getParameters().get('text4');
        condition4 = System.currentPageReference().getParameters().get('condition4');
        value4 = System.currentPageReference().getParameters().get('value4');
        ocmYear = System.currentPageReference().getParameters().get('ocmYear');
        Department = System.currentPageReference().getParameters().get('Department');
    }

    private String getBlankValue(String str) {
        if (str == null || str == '') {
            return '';
        } else {
            return str;
        }
    }

    @TestVisible private void setLayoutRWInfo() {
        if (this.sortOrder == null) {
            selColumus = new String[] {};
            strColumus = '';
            ID accRecordTypeId = accTypeForSort;

            //lt  20211129
            Map<String, String> DESC_RW = editLayoutItemRWMap.get(accRecordTypeId);
                Map<String, Schema.FieldSet> fsMap = Schema.getGlobalDescribe().get('Account').getDescribe().fieldSets.getMap();
                // 左 固定
                Schema.FieldSet fs = fsMap.get('Weekly_L_' + accTypeForSort);
                // 获得项目set中的所有项目
                List<FieldSetMember> fsmList = fs.getFields();
                // 获得字段标签和字段名
                titleLeft = new List<String>();
                List<String> columnLeft = new List<String>();
                columnLeftCss = new List<String>();
                columnsLeftApi = new List<List<String>>();
                columnLeftRW = new Map<String, String>();
                for (FieldSetMember fsm : fsmList) {
                    titleLeft.add(fsm.getLabel());
                    columnLeft.add(fsm.getFieldPath());
                    List<String> splitFieldPath = fsm.getFieldPath().split('\\.');
                    columnsLeftApi.add(splitFieldPath);
                    if (DESC_RW == null) {
                        columnLeftRW.put(fsm.getFieldPath(), 'r');
                    } else if (splitFieldPath.size() == 1) {
                        String rw = DESC_RW.get(fsm.getFieldPath());
                        if (rw != null) {
                            // SWAG-B4R3WA 2018-09-20 省设为可读 start
                            if ('所有人 ID'.equals(fsm.getLabel())) {
                                columnLeftRW.put(fsm.getFieldPath(), 'r');
                            } else {
                                columnLeftRW.put(fsm.getFieldPath(), rw);
                            }
                            // SWAG-B4R3WA 2018-09-20 省设为可读 start

                        } else {
                            columnLeftRW.put(fsm.getFieldPath(), 'r');
                        }
                    } else {
                        columnLeftRW.put(fsm.getFieldPath(), 'r');
                    }
                }
                for (String s : columnLeft) {
                    if (columusSet.contains(s) == false) {
                        columus.add(s);
                        columusSet.add(s);
                    }
                    if (selColumus.contains(s) == false) {
                        selColumus.add(s);
                    }
                    columnLeftCss.add(s.replace('.', '_'));
                }

                // 右 固定 客户-目标客户没有记录类型，key值固定
                DESC_RW = editLayoutItemRWMapRt.get('012000000000000AAA');
                strRtColumus = '';
                // 获得项目set
                Map<String, Schema.FieldSet> fsMapRt = Schema.getGlobalDescribe().get('Account_Number_of_case__c').getDescribe().fieldSets.getMap();
                Schema.FieldSet fsRt = fsMapRt.get('Weekly1_' + accTypeForSort);
                // Schema.FieldSet fsRt = fsMapRt.get('Weekly1_01210000000QemL');
                // 获得项目set中的所有项目
                List<FieldSetMember> fsmListRt = fsRt.getFields();
                // 获得字段标签和字段名
                titleRight = new List<String>();
                List<String> columnRight = new List<String>();
                columnRightCss = new List<String>();
                columnsRightApi = new List<List<String>>();
                columnRightRW = new Map<String, String>();

                for (FieldSetMember fsm : fsmListRt) {
                    titleRight.add(fsm.getLabel());
                    columnRight.add(fsm.getFieldPath());
                    List<String> splitFieldPath = fsm.getFieldPath().split('\\.');
                    columnsRightApi.add(splitFieldPath);
                    if (DESC_RW == null) {
                        columnRightRW.put(fsm.getFieldPath(), 'r');
                    } else if (splitFieldPath.size() == 1) {
                        String rw = DESC_RW.get(fsm.getFieldPath());
                        if (rw != null) {
                            columnRightRW.put(fsm.getFieldPath(), rw);
                        } else {
                            columnRightRW.put(fsm.getFieldPath(), 'r');
                        }
                    } else {
                        columnRightRW.put(fsm.getFieldPath(), 'r');
                    }
                }
                for (String s : columnRight) {
                    if (selColumus.contains(s) == false) {
                        selColumus.add(s);
                    }
                    if (strRtColumus == '') {
                        strRtColumus = s;
                    } else {
                        strRtColumus = strRtColumus + ',' + s;
                    }
                    columnRightCss.add(s.replace('.', '_'));
                }
                //lt 20211129

            // // 获得项目set
            // if (accTypeForSort.equals('01210000000QemG') || accTypeForSort.equals('01210000000QemQ') || accTypeForSort.equals('01210000000Qezy')) {
            //     Map<String, String> DESC_RW = editLayoutItemRWMap.get(accRecordTypeId);
            //     Map<String, Schema.FieldSet> fsMap = Schema.getGlobalDescribe().get('Account').getDescribe().fieldSets.getMap();
            //     // 左 固定
            //     Schema.FieldSet fs = fsMap.get('Weekly_L_' + accTypeForSort);
            //     // 获得项目set中的所有项目
            //     List<FieldSetMember> fsmList = fs.getFields();
            //     // 获得字段标签和字段名
            //     titleLeft = new List<String>();
            //     List<String> columnLeft = new List<String>();
            //     columnLeftCss = new List<String>();
            //     columnsLeftApi = new List<List<String>>();
            //     columnLeftRW = new Map<String, String>();
            //     for (FieldSetMember fsm : fsmList) {
            //         titleLeft.add(fsm.getLabel());
            //         columnLeft.add(fsm.getFieldPath());
            //         List<String> splitFieldPath = fsm.getFieldPath().split('\\.');
            //         columnsLeftApi.add(splitFieldPath);
            //         if (DESC_RW == null) {
            //             columnLeftRW.put(fsm.getFieldPath(), 'r');
            //         } else if (splitFieldPath.size() == 1) {
            //             String rw = DESC_RW.get(fsm.getFieldPath());
            //             if (rw != null) {
            //                 // SWAG-B4R3WA 2018-09-20 省设为可读 start
            //                 if ('省'.equals(fsm.getLabel())) {
            //                     columnLeftRW.put(fsm.getFieldPath(), 'r');
            //                 } else {
            //                     columnLeftRW.put(fsm.getFieldPath(), rw);
            //                 }
            //                 // SWAG-B4R3WA 2018-09-20 省设为可读 start
            //             } else {
            //                 columnLeftRW.put(fsm.getFieldPath(), 'r');
            //             }
            //         } else {
            //             columnLeftRW.put(fsm.getFieldPath(), 'r');
            //         }
            //     }
            //     for (String s : columnLeft) {
            //         if (columusSet.contains(s) == false) {
            //             columus.add(s);
            //             columusSet.add(s);
            //         }
            //         if (selColumus.contains(s) == false) {
            //             selColumus.add(s);
            //         }
            //         columnLeftCss.add(s.replace('.', '_'));
            //     }
            //     fs = fsMap.get('Weekly_' + accTypeForSort);
            //     // 获得项目set中的所有项目
            //     fsmList = fs.getFields();
            //     // 获得字段标签和字段名
            //     titleRight = new List<String>();
            //     List<String> columnRight = new List<String>();
            //     columnRightCss = new List<String>();
            //     columnsRightApi = new List<List<String>>();
            //     columnRightRW = new Map<String, String>();
            //     for (FieldSetMember fsm : fsmList) {
            //         titleRight.add(fsm.getLabel());
            //         columnRight.add(fsm.getFieldPath());
            //         List<String> splitFieldPath = fsm.getFieldPath().split('\\.');
            //         columnsRightApi.add(splitFieldPath);
            //         if (DESC_RW == null) {
            //             columnRightRW.put(fsm.getFieldPath(), 'r');
            //         } else if (splitFieldPath.size() == 1) {
            //             String rw = DESC_RW.get(fsm.getFieldPath());
            //             if (rw != null) {
            //                 // SWAG-B4R3WA 2018-09-20 市设为可读 start
            //                 if ('市'.equals(fsm.getLabel())) {
            //                     columnRightRW.put(fsm.getFieldPath(), 'r');
            //                 } else {
            //                     columnRightRW.put(fsm.getFieldPath(), rw);
            //                 }
            //                 // SWAG-B4R3WA 2018-09-20 市设为可读 start
            //             } else {
            //                 columnRightRW.put(fsm.getFieldPath(), 'r');
            //             }
            //         } else {
            //             columnRightRW.put(fsm.getFieldPath(), 'r');
            //         }
            //     }
            //     for (String s : columnRight) {
            //         if (columusSet.contains(s) == false) {
            //             columus.add(s);
            //             columusSet.add(s);
            //         }
            //         if (selColumus.contains(s) == false) {
            //             selColumus.add(s);
            //         }
            //         columnRightCss.add(s.replace('.', '_'));
            //     }


            // } else {
                
            // }
            strColumus = String.join(columus, ',');
            this.sortOrderAsc = true;
            //this.sortOrder = new String[columus.size()];
            this.sortOrder = new String[selColumus.size()];
            for (Integer i = 0; i < selColumus.size(); i++) this.sortOrder[i] = '　';
        }
    }

    private void searchOppInner() {
        oppRecords = new List<AccountInfo>();

        //lt 20211129
        String soql = this.makeSoql('1', false, accTypeForSort, hpForSort, ownerForSort,
                                        datefieldForSort, fromdForSort, todForSort, textForSort, conditionForSort, valueForSort,
                                        textForSort2, conditionForSort2, valueForSort2,
                                        textForSort3, conditionForSort3, valueForSort3, sltvForSort, sltvMForSort, sltvLForSort,
                                        textForSort4, conditionForSort4, valueForSort4);
            //SWAG-B4R3WA 2018-09-20 有效战略科室才能被搜索 start
            String targetSql = 'select Id, Account__r.Id, Account__r.Dep_Level__c,' + strRtColumus + ' from Account_Number_of_case__c where ' +
                               'Account__r.Is_Active_Formula__c = \'有效\' and ' + 'OCM_Year__c = \'' + ocmYear + '\'' ;
            //SWAG-B4R3WA 2018-09-20 有效战略科室才能被搜索 end
            targetSql += soql;
            if (String.isnotBlank(Department)) {
                targetSql += 'and Account__r.Dep_Level__c = \'' + Department + '\'';
            } 
            // else {
            //     //targetSql += ' and Submit_Customer_target_new__c =false';
            // }
            if (String.isBlank(this.sortKey)) {
                targetSql += ' order by Account__r.LastModifiedDate desc limit ' + Integer.valueOf(limits);
            } else {
                if (Integer.valueOf(this.sortKey) < titleLeft.size()) {
                    targetSql += ' order by Account__r.' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
                } else {
                    targetSql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
                }
            }
            List<Account_Number_of_case__c> targetQueryList = Database.query(targetSql);

            System.debug('lt123sql'+targetSql);
            System.debug('lt123list'+targetQueryList);

            if (targetQueryList != null && targetQueryList.size() > 0) {
                String ids = '';
                Map<Id, Account_Number_of_case__c> anotcMap = new Map<Id, Account_Number_of_case__c>();
                for (Account_Number_of_case__c obj : targetQueryList) {
                    anotcMap.put(obj.Account__r.Id, obj);
                    if (ids == '') {
                        ids = '\'' + obj.Account__r.Id + '\'';
                    } else {
                        ids += ',\'' + obj.Account__r.Id + '\'';
                    }
                }
                String accSql = 'select ' + strColumus + ' from Account where Id In (' + ids + ')';
                List<Account> queryList = Database.query(accSql);
                Map<Id, Account> accMap = new Map<Id, Account>();
                for (Account acc : queryList) {
                    accMap.put(acc.Id, acc);
                }
                // Account 按目标顺序排序
                List<Account> sortList = new List<Account>();
                for (Account_Number_of_case__c anot : targetQueryList) {
                    sortList.add(accMap.get(anot.Account__r.Id));
                }
                this.makeOppRecordsForView(sortList);
                for (AccountInfo ai : oppRecords) {
                    ai.anotc = anotcMap.get(ai.acc.Id);
                }
            }
        //lt 20211129

        // if (accTypeForSort.equals('01210000000QemG') || accTypeForSort.equals('01210000000QemQ') || accTypeForSort.equals('01210000000Qezy')) {
        //     String soql = this.makeSoql('0', false, accTypeForSort, hpForSort, ownerForSort, //deptForSort, rankForSort, conForSort,
        //                                 datefieldForSort, fromdForSort, todForSort, textForSort, conditionForSort, valueForSort,
        //                                 textForSort2, conditionForSort2, valueForSort2,
        //                                 textForSort3, conditionForSort3, valueForSort3, sltvForSort, sltvMForSort, sltvLForSort,
        //                                 textForSort4, conditionForSort4, valueForSort4);
        //     if (String.isBlank(this.sortKey)) {
        //         soql += ' order by LastModifiedDate desc limit ' + Integer.valueOf(limits);
        //     } else {
        //         soql += ' order by ' + this.columus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
        //     }
        //     List<Account> queryList = Database.query(soql);

        //     this.makeOppRecordsForView(queryList);
        // } else {
            

        // }

        oppCount = oppRecords.size();

        if (String.isBlank(this.sortKey)) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + oppCount + ' 条数据'));
        } else {
            if (oppCount > oppLimit) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '数据超过' + oppLimit + '件，只显示前' + oppLimit + '件'));
            } else {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + oppCount + ' 条数据'));
            }
        }
    }

    public PageReference searchOpp() {
        String url = this.getUrlStr();
        PageReference ref = new PageReference('/apex/DigCasesNumber?' + url);
        ref.setRedirect(true);
        return ref;

    }

    public PageReference sortTable() {
        oppRecords = new List<AccountInfo>();

        if (this.sortKey == this.preSortKey) {
            if (String.isBlank(this.sortKey) == false) {
                // 方向が変わるのみ
                this.sortOrderAsc = !this.sortOrderAsc;
                this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
            }
        } else {
            this.sortOrderAsc = true;
            if (String.isBlank(this.preSortKey) == false) {
                this.sortOrder[Integer.valueOf(this.preSortKey)] = '　';
            }
            this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
        }
        this.preSortKey = this.sortKey;

        setLayoutRWInfo();
        searchOppInner();
        return null;
    }

    public PageReference save() {
        try {
            List<Account> updOpps = new List<Account>();
            List<Account_Number_of_case__c> updTarget = new List<Account_Number_of_case__c>();

            for (AccountInfo oi : oppRecords) {
                // 変更チェック
                if (oi.changeFlg == '1') {
                    oi.changeFlg = '0';
                    updOpps.add(oi.acc);
                }
                // if (oi.changeFlgRt == '1') {
                //     oi.changeFlgRt = '0';
                //     updTarget.add(oi.anotc);
                // }

                //20211125 lt start
                if (accTypeForSort.equals('01210000000QemL')){
                    //ESD
                    if( oi.anotc.ESD_UpNumber__c != null && oi.anotc.ESD_DownNumber__c != null){
                        oi.anotc.ESD_Number__c = oi.anotc.ESD_UpNumber__c + oi.anotc.ESD_DownNumber__c;
                    }else if(oi.anotc.ESD_UpNumber__c == null && oi.anotc.ESD_DownNumber__c == null){
                        oi.anotc.ESD_Number__c = 0;
                    }else if( oi.anotc.ESD_UpNumber__c != null && oi.anotc.ESD_DownNumber__c == null){
                        oi.anotc.ESD_Number__c = oi.anotc.ESD_UpNumber__c;
                    }else if( oi.anotc.ESD_UpNumber__c == null && oi.anotc.ESD_DownNumber__c != null){
                        oi.anotc.ESD_Number__c = oi.anotc.ESD_DownNumber__c;
                    }
                    //EUS
                    if( oi.anotc.EUS_UpNumber__c != null && oi.anotc.EUS_DownNumber__c != null){
                        oi.anotc.EUS_Number__c = oi.anotc.EUS_UpNumber__c + oi.anotc.EUS_DownNumber__c;
                    }else if(oi.anotc.EUS_UpNumber__c == null && oi.anotc.EUS_DownNumber__c == null){
                        oi.anotc.EUS_Number__c = 0;
                    }else if( oi.anotc.EUS_UpNumber__c != null && oi.anotc.EUS_DownNumber__c == null){
                        oi.anotc.EUS_Number__c = oi.anotc.EUS_UpNumber__c;
                    }else if( oi.anotc.EUS_UpNumber__c == null && oi.anotc.EUS_DownNumber__c != null){
                        oi.anotc.EUS_Number__c = oi.anotc.EUS_DownNumber__c;
                    }
                    //ERCP
                    if( oi.anotc.ERCP_UpNumber__c != null && oi.anotc.ERCP_DownNumber__c != null){
                        oi.anotc.ERCP_Number__c = oi.anotc.ERCP_UpNumber__c + oi.anotc.ERCP_DownNumber__c;
                    }else if(oi.anotc.ERCP_UpNumber__c == null && oi.anotc.ERCP_DownNumber__c == null){
                        oi.anotc.ERCP_Number__c = 0;
                    }else if( oi.anotc.ERCP_UpNumber__c != null && oi.anotc.ERCP_DownNumber__c == null){
                        oi.anotc.ERCP_Number__c = oi.anotc.ERCP_UpNumber__c;
                    }else if( oi.anotc.ERCP_UpNumber__c == null && oi.anotc.ERCP_DownNumber__c != null){
                        oi.anotc.ERCP_Number__c = oi.anotc.ERCP_DownNumber__c;
                    }
                    system.debug('lt123ESD上消'+oi.anotc.ESD_UpNumber__c);
                }

                //20211125 lt end
                
                updTarget.add(oi.anotc);
            }

            system.debug('lt123oppRecords'+oppRecords);
            system.debug('lt123updTarget'+updTarget);
            

            if (updOpps.size() > 0) update updOpps;
            if (updTarget.size() > 0) update updTarget;

            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '保存完了'));
        } 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');
    }

    private String makeSoql(String sqlFlg, Boolean isforMoneyFlg, String accTypeStr, 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, Boolean sltvFlg, Boolean sltvMFlg, Boolean sltvLFlg,
                            String txt4, String con4, String val4) {
        String soql = '';
        String targetSql = '';
        if (isforMoneyFlg == false) {
            //SWAG-B4R3WA 2018-09-20 有效医院才能被搜索 start
            soql += 'select ' + strColumus
                    + ' from Account where Is_Active_Formula__c = \'有效\' and (RecordType.DeveloperName = \'HP\' or Parent.RecordType.DeveloperName = \'HP\' or Parent.Parent.RecordType.DeveloperName = \'HP\')';
            //SWAG-B4R3WA 2018-09-20 有效医院才能被搜索 end
        } else {
          
        }
        if (!String.isBlank(accTypeStr)) {
            soql += ' and RecordTypeId = \'' + String.escapeSingleQuotes(accTypeStr) + '\'';
            targetSql += ' and Account__r.RecordTypeId = \'' + String.escapeSingleQuotes(accTypeStr) + '\'';
        }
        //if (sltvFlg) {
        //    soql += ' and (HP_146POCM_Category_From_Dept__c = \'H0\' or HP_146POCM_Category_From_Dept__c = \'H1\')';
        //}
        if (sltvFlg || sltvMFlg || sltvLFlg) {
            String sqlStr = '';
            String sqlStr2 = '';
            if (sltvFlg) {
                sqlStr += ' HP_146POCM_Category_From_Dept__c = \'H0\' or HP_146POCM_Category_From_Dept__c = \'H1\' ';
                sqlStr2 += ' Account__r.HP_146POCM_Category_From_Dept__c = \'H0\' or Account__r.HP_146POCM_Category_From_Dept__c = \'H1\' ';
            }
            if (sltvMFlg) {
                if (sqlStr == '') {
                    sqlStr += ' HP_146POCM_Category_From_Dept__c = \'M0\' or HP_146POCM_Category_From_Dept__c = \'M1\' ';
                    sqlStr2 += ' Account__r.HP_146POCM_Category_From_Dept__c = \'M0\' or Account__r.HP_146POCM_Category_From_Dept__c = \'M1\' ';
                } else {
                    sqlStr += ' or HP_146POCM_Category_From_Dept__c = \'M0\' or HP_146POCM_Category_From_Dept__c = \'M1\' ';
                    sqlStr2 += ' or Account__r.HP_146POCM_Category_From_Dept__c = \'M0\' or Account__r.HP_146POCM_Category_From_Dept__c = \'M1\' ';
                }
            }
            if (sltvLFlg) {
                if (sqlStr == '') {
                    sqlStr += ' HP_146POCM_Category_From_Dept__c = \'L\' ';
                    sqlStr2 += ' Account__r.HP_146POCM_Category_From_Dept__c = \'L\' ';
                } else {
                    sqlStr += ' or HP_146POCM_Category_From_Dept__c = \'L\' ';
                    sqlStr2 += ' or Account__r.HP_146POCM_Category_From_Dept__c = \'L\' ';
                }
            }
            soql += ' and (' + sqlStr + ') ';
            targetSql += ' and (' + sqlStr2 + ') ';
        }
        if (!String.isBlank(accStr)) {
            //soql += ' and Hospital__c = \'' + accStr + '\'';
            String[] vals = accStr.split(' ');
            // 病院
            if (String.isBlank(accTypeStr) || accTypeStr == '01210000000QemG') {
                for (String v : vals) {
                    soql += ' and Name like \'%' + String.escapeSingleQuotes(v.replaceAll('%', '\\%')) + '%\'';
                }
            }
            // 戦略科室
            else {
                for (String v : vals) {
                    soql += ' and Parent.Name like \'%' + String.escapeSingleQuotes(v.replaceAll('%', '\\%')) + '%\'';
                    targetSql += ' and Account__r.Parent.Name like \'%' + String.escapeSingleQuotes(v.replaceAll('%', '\\%')) + '%\'';
                }
            }

        }
        if (!String.isBlank(ownerStr)) {
            //soql += ' and OwnerId = \'' + ownerStr + '\'';
            String[] vals = ownerStr.split(' ');
            for (String v : vals) {
                soql += ' and CreatedBy.Name like \'%' + String.escapeSingleQuotes(v.replaceAll('%', '\\%')) + '%\'';
                targetSql += ' and Account__r.CreatedBy.Name like \'%' + String.escapeSingleQuotes(v.replaceAll('%', '\\%')) + '%\'';
            }
        }

        if (!String.isBlank(datefield)) {
            if (fromd != null) {
                soql += ' and ' +  datefield + ' >= ' + String.valueOf(fromd).substring(0, 10);
                targetSql += ' and Account__r.' +  datefield + ' >= ' + String.valueOf(fromd).substring(0, 10);
            }
            if (tod != null) {
                soql += ' and (' +  datefield + ' <= ' + String.valueOf(tod).substring(0, 10) + ' OR ' + datefield + ' = null)';
                targetSql += ' and (Account__r.' +  datefield + ' <= ' + String.valueOf(tod).substring(0, 10) + ' OR Account__r.' + datefield + ' = null)';
            }
        }

        // xudan 20140507 検索ロジック修正
        String selCon = '';
        selCon += this.makeTextSql(sqlFlg, txt, con, val);
        selCon += this.makeTextSql(sqlFlg, txt2, con2, val2);
        selCon += this.makeTextSql(sqlFlg, txt3, con3, val3);
        // if (!String.isBlank(txt4)) {
        //     String str = txt4.substring(2);
        //     if (sqlFlg == '1' || accTypeForSort != '01210000000QemG') {
        //         txt4 = 'S:Parent.' + str;
        //     }
        // }
        selCon += this.makeTextSql(sqlFlg, txt4, con4, val4);
        soql += selCon;
        targetSql += selCon;
        if (sqlFlg == '1') {
            return targetSql;
        } else {
            return soql;
        }
    }

    public void makeOppRecordsForView(List<Account> queryList) {
        Savepoint sp = Database.setSavepoint();
        // TODO queryList について、最初のoppLimitだけ更新すればOKです。
        Database.SaveResult[] results = Database.update(queryList, false);
        // 強制ロールバック
        Database.rollback(sp);

        // 戦略科室データを作成
        Map<String, List<Account>> deptMap = new Map<String, List<Account>>();
        for (Account dept : [select Id, Name, Department_Class_Label__c, ParentId from Account where ParentId in :queryList]) {
            List<Account> tmpList = new List<Account>();
            if (deptMap.containsKey(dept.ParentId)) {
                tmpList = deptMap.get(dept.ParentId);
            }

            tmpList.add(dept);
            deptMap.put(dept.ParentId, tmpList);
        }

        for (Integer i = 0; i < queryList.size(); i++) {
            // limitを超えた場合前limit件のみを出す
            if (i == oppLimit + 1) {
                // TODO メッセージ表示
                continue;
            }
            oppRecords.add(new AccountInfo(queryList[i], deptMap.get(queryList[i].Id)));
            oppRecords[oppRecords.size() - 1].lineNo = oppRecords.size() - 1;
            if (!results[i].isSuccess()) {
                oppRecords[oppRecords.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') {
                        oppRecords[oppRecords.size() - 1].hasError = true;
                        // xudan 20140624 更新権限エラーとほかのエラーを区別
                    } else {
                        oppRecords[oppRecords.size() - 1].hasFieldError = true;
                    }
                }
            }
        }
    }

    private String makeTextSql(String sqlFlg, 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(sqlFlg, 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 、最初の２文字がタイプです
                    if (sqlFlg == '1') {
                        txt = 'Account__r.' + txt;
                    }
                    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(sqlFlg, txt1, con, val);
                if (con != 'notcontains') {
                    soql += this.makeTextSqlStr(sqlFlg, txt1, con, val);
                } else {
                    // notcontains
                    cSql = cSql.substring(5);       // ' and ' の5文字を外す
                    soql += ' and (NOT ' + cSql + ') ';
                }
            }
        }
        return soql;
    }

    /**
     * 文字列検索文を作成
     */
    private String makeTextSqlStr(String sqlFlg, String txt1, String con, String val) {
        String soql = '';
        if (!String.isBlank(txt1)) {
            String txt = txt1.substring(2);
            if (sqlFlg == '1') {
                txt = 'Account__r.' + txt;
            }
            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 \'%' + String.escapeSingleQuotes(tmpVal.replaceAll('%', '\\%')) + '%\'';
                } else if (con == 'starts with') {
                    soql += ' like \'' + String.escapeSingleQuotes(tmpVal.replaceAll('%', '\\%')) + '%\'';
                } else {
                    if (colType == 'S:') {
                        soql += ' ' + con + '\'' + tmpVal + '\'';
                    } else {
                        soql += ' ' + con + ' ' + tmpVal + ' ';
                    }
                }
            }
        }
        return soql;
    }

    class AccountInfo {
        public Account acc { 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 String changeFlgRt { get; set; }
        //public String accType { get; private set; }
        public Account_Number_of_case__c anotc { get; set; }

        public String nameGI { get; private set; }
        public String nameGS { get; private set; }
        public String nameURO { get; private set; }
        public String nameENT { get; private set; }
        public String nameGYN { get; private set; }
        public String nameBF { get; private set; }
        public String nameOTH { get; private set; }
        public String nameET { get; private set; }

        public String idGI { get; private set; }
        public String idGS { get; private set; }
        public String idURO { get; private set; }
        public String idENT { get; private set; }
        public String idGYN { get; private set; }
        public String idBF { get; private set; }
        public String idOTH { get; private set; }
        public String idET { get; private set; }

        public AccountInfo(Account record, List<Account> deptList) {
            acc = record;
            canEdit = true;
            hasError = false;
            hasFieldError = false;
            lineNo = 0;
            changeFlg = '0';
            changeFlgRt = '0';

            if (deptList != null) {
                for (Account dept : deptList) {
                    if (dept.Department_Class_Label__c == '消化科') {
                        nameGI = dept.Department_Class_Label__c;
                        idGI = dept.Id;
                    }
                    // if (dept.Department_Class_Label__c == '耳鼻喉科') {
                    //     nameENT = dept.Department_Class_Label__c;
                    //     idENT = dept.Id;
                    // }
                    // if (dept.Department_Class_Label__c == '泌尿科') {
                    //     nameURO = dept.Department_Class_Label__c;
                    //     idURO = dept.Id;
                    // }
                    // if (dept.Department_Class_Label__c == '普外科') {
                    //     nameGS = dept.Department_Class_Label__c;
                    //     idGS = dept.Id;
                    // }
                    // if (dept.Department_Class_Label__c == '妇科') {
                    //     nameGYN = dept.Department_Class_Label__c;
                    //     idGYN = dept.Id;
                    // }
                    // if (dept.Department_Class_Label__c == '呼吸科') {
                    //     nameBF = dept.Department_Class_Label__c;
                    //     idBF = dept.Id;
                    // }
                    // if (dept.Department_Class_Label__c == '其他') {
                    //     nameOTH = dept.Department_Class_Label__c;
                    //     idOTH = dept.Id;
                    // }
                    // if (dept.Department_Class_Label__c == 'ET') {
                    //     nameET = dept.Department_Class_Label__c;
                    //     idET = dept.Id;
                    // }
                }
            }
        }
    }
}