public with sharing class ConsumAssignCancelController extends CreateRelationListPagingCtrlBase {
    public override Integer getSearchNumMax() {
        //各ページに制御あれば、最大件数を指定する
        searchNumMax = Integer.valueOf(Label.Product_Select_Limit);
        searchNumMax = 20;
        return searchNumMax;
    }

    /* 選択されたデータ取得用Soql　Fromから*/
    public override String getSelectedDataSql() {
        // オブジェクトAPI名
        selectedDataSql = ' From Consum_Apply_Equipment_Set__c';
        selectedDataSql += ' where Consum_Apply__c = \'' + String.escapeSingleQuotes(parentId) + '\'';
        selectedDataSql += ' AND RetalFSetDetail_Cnt__c > 0 ';
        selectedDataSql += ' AND Cancel_Select__c = false ';
        selectedDataSql += ' order by Name ASC nulls last';   // order by Fixture_Set_Detail__r.SortInt__c
        myComponentController.columnRightRW.put('Model_No__c', 'r');
        return selectedDataSql;
    }

    public override String getOriginObjName() {
        // オブジェクトAPI名
        originObjName = 'Asset';
        return originObjName;
    }
    public override String getOriginObjColumns() {
        // 項目セット
        originObjColumns = 'Id';
        return originObjColumns;
    }

    public override String getObjName() {
        // オブジェクトAPI名
        objName = 'Consum_Apply_Equipment_Set__c';
        return objName;
    }
    public override String getColumnLeftFieldSetName() {
        // 左の項目セット
        columnLeftFieldSetName = '';
        return columnLeftFieldSetName;
    }
    public override String getColumnRightFieldSetName() {
        // 右の項目セット
        columnRightFieldSetName = 'ConsumAssignCancel_List';
        return columnRightFieldSetName;
    }

    public override List<String> getColumnFieldList() {
        // strColumus 里加 field
        // FixtureUtil#raesdGroupBy()の項目も必要
        return new List<String>{'Cancel_Reason__c', 'VF_Cancel_Detail_Count__c'};
    }
    // 画面里直接可以输入的項目 List
    public override List<String> getWritableColumnFieldList() {
        return new List<String>{'Cancel_Reason__c', 'VF_Cancel_Detail_Count__c'};
    }
    // getObjName 连 getOriginObjName 的 FK
    public override String getFKColumnField() {
        return '';
    }

    public override String getRecordTypeId() {
        //ページレイアウトを収得するのレコードタイプ
        recordTypeId = '';
        return recordTypeId;
    }

    // ページコントローラに検索処理は、WhereSoql作成のみ、パラメータとして、コンポーネントに渡される
    public override String getSqlWhereStr() {
        sqlWhereStr = '';
        return sqlWhereStr;
    }

    public override Boolean getIsNeedRunSearch() {
        return false;
    }

    public Consum_Apply__c parentObj { get; set; }
    public Consum_Apply_Equipment_Set__c pageCaes {get; set;}
    private String savetype;

    public ConsumAssignCancelController() {
        parentId = ApexPages.currentPage().getParameters().get('pt_recid');
        savetype = ApexPages.currentPage().getParameters().get('savetype');
        pageCaes = new Consum_Apply_Equipment_Set__c();
        if (!String.isBlank(this.parentId)) {
            List<Consum_Apply__c> parentObjs = [
                    SELECT Id
                         , Name
                         , Person_In_Charge__c
                         , Salesdept__c
                         , WorkPlace__c
                         , Internal_asset_location_F__c
                         , demo_purpose2__c
                         , Request_shipping_day__c
                         , Asset_loaner_start_date__c
                         , Request_demo_day__c
                      FROM Consum_Apply__c
                     WHERE Id = :parentId
                    ];
            if(parentObjs.size()>0){
                parentObj = parentObjs.get(0);
            }
        }
    }

    public void init() {
        isNeedCheckEvent = true;
        searchOppSetParam();
        getSqlWhereStr();
    }

    private void searchOppSetParam() {

    }

    public PageReference searchOpp() {
        searchOppSetParam();
        // 選択済みの製品を取得
        myComponentController.getSelectedDataInfo();
        getSqlWhereStr();
        // コンポーネントにSoqlを発行して、ページングする
        myComponentController.searchAndPaging();
        return null;
    }

    public PageReference save() {
        Map<Id, Consum_Apply_Equipment_Set__c> caesMap = new Map<Id, Consum_Apply_Equipment_Set__c>();
        Savepoint sp = Database.setSavepoint();
        try{
            for(WrapperInfo info : viewList){
                Consum_Apply_Equipment_Set__c caes = (Consum_Apply_Equipment_Set__c) info.sobj;
                Boolean isChanged = info.check || caes.VF_Cancel_Detail_Count__c != null || String.isNotBlank(caes.Cancel_Reason__c);
                if(info.check){
                    if(caes.VF_Cancel_Detail_Count__c == null || caes.VF_Cancel_Detail_Count__c == 0) {
                        String msgStr = '第' + (info.lineNo+1) + '行 【取消明细申请件数】 不可为空!';
                        throw new ControllerUtil.myException(msgStr);
                    }
                    else if(caes.VF_Cancel_Detail_Count__c > caes.RetalFSetDetail_Cnt__c){
                        String msgStr = '第' + (info.lineNo+1) + '行 【取消明细申请件数】 不可超过 【申请件数】!';
                        throw new ControllerUtil.myException(msgStr);
                    }
                    if(String.isBlank(caes.Cancel_Reason__c)){
                        String msgStr = '第' + (info.lineNo+1) + '行 【取消理由】 不可为空';
                        throw new ControllerUtil.myException(msgStr);
                    }
                    if(String.isBlank(caes.Loaner_cancel_Remarks__c)){
                        String msgStr = '第' + (info.lineNo+1) + '行 【取消理由备注】 不可为空';
                        throw new ControllerUtil.myException(msgStr);
                    }
                    caesMap.put(caes.Id, caes);
                }
            }
            if(caesMap.isEmpty()){
                String msgStr = '没有需要取消的明细';
                throw new ControllerUtil.myException(msgStr);
            }
            List<Consum_Apply__c> parentObjs = [
                    SELECT Id
                         , Name
                         , Person_In_Charge__c
                         , Salesdept__c
                         , WorkPlace__c
                         , Internal_asset_location_F__c
                         , demo_purpose2__c
                         , Request_shipping_day__c
                         , Asset_loaner_start_date__c
                         , Request_demo_time__c
                      FROM Consum_Apply__c
                     WHERE Id = :parentId
                       FOR UPDATE
                    ];
            if(parentObjs.size()>0){
                parentObj = parentObjs.get(0);
            }
            List<Consum_Apply_Equipment_Set_Detail__c> csaesdList = [
                    SELECT Id
                         , Consum_Apply_Equipment_Set__c
                         , Asset__c
                         , Cancel_Select__c
                         , Cancel_Date__c
                         , Cancel_Time__c
                         , Cancel_Reason__c
                         , Select_Time__c
                         , Shipment_request__c
                         , Shipment_request_time2__c

                      FROM Consum_Apply_Equipment_Set_Detail__c
                     WHERE Consum_Apply_Equipment_Set__c IN :caesMap.keySet()
                       AND Cancel_Select__c = false
                     ORDER BY Consum_Apply_Equipment_Set__c, Degree_Of_Importance__c DESC, Asset__c NULLS FIRST
                ];
            if(csaesdList.isEmpty()){
                String msgStr = '没有可以取消的明细';
                throw new ControllerUtil.myException(msgStr);
            }
            Map<Id, Consum_Apply_Equipment_Set_Detail__c> csaesdUpdateMap = new Map<Id, Consum_Apply_Equipment_Set_Detail__c>();
            Set<Id> assetIdSet = new Set<Id>();
            for(Consum_Apply_Equipment_Set_Detail__c csaesd : csaesdList){
                // 当caesMap为空时表示所有取消操作已完成，不需要再遍历
                if(caesMap.isEmpty()){
                    break;
                }
                Id csaesId = csaesd.Consum_Apply_Equipment_Set__c;
                // caesMap不含csaesId时，表示csaesId一览下的明细已完成取消，跳过
                if(!caesMap.containsKey(csaesId)) {
                    continue;
                }

                Consum_Apply_Equipment_Set__c csaes = caesMap.get(csaesId);

                if(csaes.VF_Cancel_Detail_Count__c > 0){
                    assetIdSet.add(csaesd.Asset__c);
                    // 取消
                    csaesd.Cancel_Select__c = true;
                    // 取消理由
                    csaesd.Cancel_Reason__c = csaes.Cancel_Reason__c;
                    // 取消理由备注
                    csaesd.Loaner_cancel_Remarks__c = csaes.Loaner_cancel_Remarks__c;
                    // 以下字段在trigger里清
                    //// 取消日期
                    //csaesd.Cancel_Date__c = Datetime.now().date();
                    //// 取消日期
                    //csaesd.Cancel_Time__c = Datetime.now().time();
                    //// 保有设备link
                    //csaesd.Asset__c = null;
                    //// TODO 暂定分配时间
                    //// 分配时间
                    //csaesd.Select_Time__c = null;
                    //// 已做出库指示
                    //csaesd.Shipment_request__c = false;
                    //// 出库指示时间
                    //csaesd.Shipment_request_time2__c = null;

                    csaesdUpdateMap.put(csaesd.Id, csaesd);
                    // 取消的明细达到数量时，将一览从caesMap移除
                    if (csaes.VF_Cancel_Detail_Count__c - 1 == 0){
                        caesMap.remove(csaesId);
                    }
                    else{
                        csaes.VF_Cancel_Detail_Count__c -= 1;
                        caesMap.put(csaesId, csaes);
                    }
                }
            }
            if (csaesdUpdateMap.size() > 0) {
                List<Asset> lockAssetList = [
                        SELECT Id
                          FROM Asset
                         WHERE Id IN : assetIdSet
                           FOR UPDATE
                    ];
                List<Consum_Apply_Equipment_Set_Detail__c> lockCaesdList = [
                        SELECT Id
                          FROM Consum_Apply_Equipment_Set_Detail__c
                         WHERE Id IN : csaesdUpdateMap.keySet()
                           FOR UPDATE
                    ];

                if (parentObj.Request_demo_time__c != null) {
                    FixtureUtil.withoutUpdate(csaesdUpdateMap.values());
                }
                else {
                    FixtureUtil.withoutDelete(csaesdUpdateMap.values());
                }
                PageReference page = new PageReference('/apex/ConsumAssignCancel?pt_recid=' + parentId + '&savetype=1');
                page.setRedirect(true);
                return page;
            }
        }
        catch (Exception e){
            ApexPages.addMessages(e);
            Database.rollback(sp);
            return null;
        }
        return null;
    }

    public override void setViewList(List<sObject> queryList) {
        viewList = new List<WrapperInfo>();

        if (savetype == '1') {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.CONFIRM , '取消成功'));
        }

        if (selectedData.size() == 0) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.WARNING , '没有可以取消申请的一览明细'));
            return ;
        }

        if (String.isBlank(pageCaes.Id)) {
            pageCaes.Id = selectedData[0].Id;
        }

        if (selectedData.size() > 0) {
            for (Integer i = 0; i < selectedData.size(); i++) {
                Consum_Apply_Equipment_Set__c caes = (Consum_Apply_Equipment_Set__c) selectedData[i];
                WrapperInfo newWrapperInfo = new WrapperInfo(caes, myComponentController);
                newWrapperInfo.lineNo = i;
                newWrapperInfo.check = false;
                newWrapperInfo.oldCheck = false;
                viewList.add(newWrapperInfo);
            }
        }
    }

}