public with sharing class OpportunityPCLController2 {
	public List<OppInfo> oppRecords { get; set; }
	// ページレイアウトの情報を取得
	private Map<String, String> DESC_RW = 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 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 チェック：询价、未チェック：全部（後藤要望）
	public Boolean onlyOpp { get; set; }
	//【委托】【重要】周会管理表修改  tcm start
	public Boolean OpptyWait { get; set; }
	//【委托】【重要】周会管理表修改  tcm end
	public String limits { get; set; }
	
	/*****************画面表示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'};
	public Set<String> columusSet = new Set<String> {'Id'};
	
	// 项目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 用
	//XLIU-CGF4TA 【委托】 【询价管理改善需求评估】询价中的进口论证判断 fy start 
	public List<String> columnRightCsscopy { get; private set; }
	public List<String> titleRightcopy { get; private set; }
	public List<List<String> > columnsRightApicopy { get; private set; } 
	//XLIU-CGF4TA 【委托】 【询价管理改善需求评估】询价中的进口论证判断 fy end 
	public Map<String, String> columnLeftRW { get; private set; }              // r,w,wm用
	public Map<String, String> columnRightRW { get; private set; }             // r,w,wm用
	public List<String> columnMark { get; private set; }                  // Mark用
	private String strColumus;                                            // soql用項目
	private String strColumusForMoney;                                    // 金額集計soql用項目
	public Map<String, Decimal> columnMoneyMap { get; private set; }
	public Map<String, Boolean> columnMoneyFlgMap { get; private set; }
	
	public Integer ratingStartIdx { get; private set; }  // Rating表示ラベルの開始Idx
	
	/*****************ソート時再検索条件（画面からの入力条件を無視するため）******************/
	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;
	//【委托】【重要】周会管理表修改  tcm start
	private Boolean OpptyWaitForSort = false;
	//【委托】【重要】周会管理表修改  tcm end
	private static Integer oppLimit = 1000;
	private Boolean isForMoneyFlg = false;
	//XLIU-CGF4TA 【委托】 【询价管理改善需求评估】询价中的进口论证判断 fy start 
	public Boolean HideForecastOCSMflag { get; set; }
	//XLIU-CGF4TA 【委托】 【询价管理改善需求评估】询价中的进口论证判断 fy end
	public OpportunityPCLController2() {
	  //Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
	  DESC_RW = SoapApi.getEditLayoutItemRW('Opportunity', new String[] {'01210000000QekKAAS'}).get('01210000000QekKAAS');
	  oppRecords = new List<OppInfo>();
	
	  // 日付検索条件のCalendar用
	  con1 = new Contact();
	  con2 = new Contact();
	
	  dateOpts = new List<SelectOption>();
	  dateOpts.add(new SelectOption('', '--无--'));
	  dateOpts.add(new SelectOption('Bid_Planned_Date__c', '预测招标日'));
	  dateOpts.add(new SelectOption('Bid_Date__c', '招标日'));
	  dateOpts.add(new SelectOption('Closing_Bid_Date__c', '中标日'));
	  //【委托】【重要】周会管理表修改  tcm start
	  dateOpts.add(new SelectOption('  TenderBeginDate__c', '招标日（招标项目）'));
	  dateOpts.add(new SelectOption('Closing_Bid_Date_Bid__c', '中标日（招投标）'));
	  //【委托】【重要】周会管理表修改  tcm end
	  dateOpts.add(new SelectOption('Close_Forecasted_Date__c', '预测OCSM签约日(KPI)')); //20220506 lt update
	
	  //SWAG-C9NC23 【委托】[重要，优先！]周会询价管理表修改   lt   20211217  start
	  dateOpts.add(new SelectOption('Close_Forecasted_Assume_Date__c', '预测OCSM签约日(担当)'));
	  //SWAG-C9NC23 【委托】[重要，优先！]周会询价管理表修改   lt   20211217  end
	
	  dateOpts.add(new SelectOption('CloseDate', '预测发货日'));  //20220506 lt update
	  dateOpts.add( new SelectOption('Created_Day__c', '创建日'));
	  dateOpts.add(new SelectOption('Last_Follow_Up_Date__c', '最后跟进日'));//***********************
	  // 日付検索に標準のLastModifiedDate（日時項目）は使えない、数式項目を利用
	  //dateOpts.add(new SelectOption('LastModified_Day__c', '最后更新日'));//**************************
	  //syu 2014/6/25 追加した
	  dateOpts.add( new SelectOption('Last_opd_date__c', '最后OPD实施日'));
	  dateOpts.add( new SelectOption('Key_tipics_last_update_day__c', '重要字段更新日'));
	  dateOpts.add( new SelectOption('Forecast_amount_last_update_day__c', '最后更新日-预测成交金额(含税)'));
	  dateOpts.add( new SelectOption('Stage2_last_update_day__c', '最后更新日-状态2'));
	  dateOpts.add( new SelectOption('OPP_rank_Last_update_day__c', '最后更新日-询价等级'));
	  dateOpts.add( new SelectOption('Tender_data_last_update_day__c', '最后更新日-预测招标日'));
	  dateOpts.add( new SelectOption('Bid_date_last_update_day__c', Schema.SObjectType.Opportunity.fields.Bid_date_last_update_day__c.label));
	  dateOpts.add( new SelectOption('Closing_Bid_date_last_update_day__c', '最后更新日-中标日'));
	  dateOpts.add( new SelectOption('Opp_forecast_day_last_update_day__c', '最后更新日-预测OCSM签约日'));
	  dateOpts.add( new SelectOption('Agent_Hospital_Contract_day_last_update__c', '最后更新日-经销商-医院(签)'));
	  dateOpts.add( new SelectOption('Agency_Contract_Date_last_update__c', '最后更新日-OCSM-经销商(签)'));
	  dateOpts.add( new SelectOption('Forecast_shipping_day_last_update__c', '最后更新日-预测发货日'));
	  dateOpts.add( new SelectOption('Situation_last_update_day__c', '最后更新日-询价跟进情况'));
	  dateOpts.add( new SelectOption('Manager_feedback_last_update__c', '最后更新日-经理反馈'));
	  dateOpts.add( new SelectOption('Follow_up_plan_last_update__c', '最后更新日-推进计划'));
	  //进口论证 fy start
	  dateOpts.add( new SelectOption('ImportDemonstration_Filing_date__c', '进口论证申请日'));
	  dateOpts.add( new SelectOption('ImportDemonstration_Approval_date__c', '进口论证批准日'));
	  dateOpts.add( new SelectOption('ImportDemonstration_Rejection_date__c', '进口论证驳回日'));
	  //进口论证 fy end
	
	  textOpts = new List<SelectOption>();
	  textOpts.add(new SelectOption('','--无--'));
	  textOpts.add(new SelectOption('S:Name','询价名称'));
	  textOpts.add(new SelectOption('S:Opportunity_No__c',Schema.SObjectType.Opportunity.fields.Opportunity_No__c.label));
	  textOpts.add(new SelectOption('S:HP_Name__c','医院名'));
	  textOpts.add(new SelectOption('S:Owner_Category__c','课'));// 20220907 XLIU-CHY4JL you
	  
	  // TODO xudan 20140626 状态1をチェックボックスに、ここ要らない？
	  textOpts.add(new SelectOption('S:Owner.Salesdepartment__c','本部'));
	  textOpts.add(new SelectOption('S:Owner.Province__c','省'));
	  textOpts.add(new SelectOption('S:Owner.Group__c','组'));
	  textOpts.add(new SelectOption('S:StageName__c','状态1'));
	  textOpts.add(new SelectOption('S:Owner.Name','担当人'));
	  textOpts.add(new SelectOption('S:OCM__c','OCSM分类'));
	  textOpts.add(new SelectOption('S:Department_Name__c','科室名'));
	  textOpts.add(new SelectOption('S:Opportunity_Category__c','询价科室分类'));
	  //textOpts.add(new SelectOption('N:Estimation_List_Price__c','标准定价总额'));
	  //textOpts.add(new SelectOption('N:Wholesale_Price_F__c','预测成交金额(含税)'));
	  //textOpts.add(new SelectOption('N:Amount_Without_Tax_F__c','预测成交金额(不含税)'));
	  textOpts.add(new SelectOption('S:Agency1__r.Name','经销商1'));
	  //textOpts.add(new SelectOption('S:Status_Formula__c','状态2'));
	  textOpts.add(new SelectOption('S:Competitor__c','询价等级'));
	  //textOpts.add(new SelectOption('S:OPD_SIS_collect_evaluation_sight__r.Name',Schema.SObjectType.Opportunity.fields.OPD_SIS_collect_evaluation_sight__c.label));
	  textOpts.add(new SelectOption('S:Forecast_this_month__c','本月预测'));
	  //进口论证 fy start
	  textOpts.add(new SelectOption('t:if_NeedImportDemonstration__c','需要进口论证'));
	  //进口论证 fy end
	  //textOpts.add(new SelectOption('N:Lapsed_Days__c',Schema.SObjectType.Opportunity.fields.Lapsed_Days__c.label));
	  //textOpts.add(new SelectOption('S:Rating01__c','1月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating02__c','2月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating03__c','3月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating04__c','4月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating05__c','5月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating06__c','6月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating07__c','7月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating08__c','8月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating09__c','9月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating10__c','10月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating11__c','11月末询价状态'));
	  //textOpts.add(new SelectOption('S:Rating12__c','12月末询价状态'));
	
	  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('' + (oppLimit + 1), '全部'));
	
	  limits = '50';
	
	  ratingStartIdx = -1;
	}
	
	public PageReference init() {
	  System.debug('lt123 --- init start --- : ' + System.currentTimeMillis());
	  // xudan 20140626 状态1をチェックボックスに
	  onlyOpp = true;
	  //【委托】【重要】周会管理表修改  tcm start
	  OpptyWait = false;
	  //【委托】【重要】周会管理表修改  tcm end
	  //20140822　追加 by katsu start
	  System.debug('lt123 --- 查user开始 --- : ' + System.currentTimeMillis());
	  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;
	  }
	  System.debug('lt123 --- 查user结束 --- : ' + System.currentTimeMillis());
	  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;
	  }
	  }
	  System.debug('lt123 --- 调用searchOppSetParam()前 --- : ' + System.currentTimeMillis());
	  //20140822　追加 by katsu end
	
	  searchOppSetParam();
	  System.debug('lt123 --- 调用searchOppSetParam()后,setLayoutRWInfo()前 --- : ' + System.currentTimeMillis());
	  setLayoutRWInfo();
	  System.debug('lt123 --- 调用setLayoutRWInfo()后 --- : ' + System.currentTimeMillis());
	  this.sortOrderAsc = true;
	  this.sortOrder = new String[columus.size()];
	  for (Integer i = 0; i < columus.size(); i++) this.sortOrder[i] = '　';
	  System.debug('lt123 --- 调用searchOppInner()前 --- : ' + System.currentTimeMillis());
	  searchOppInner();
	  System.debug('lt123 --- 调用searchOppInner()后 --- : ' + System.currentTimeMillis());
	  System.debug('columnMoneyFlgMapvalue:'+columnMoneyFlgMap);
	  System.debug('columnMoneyMapvalue:'+columnMoneyMap);
	  System.debug('columnRightCss:'+columnRightCss);
	  columnRightCsscopy =columnRightCss;
	  titleRightcopy = titleRight;
	  columnsRightApicopy = columnsRightApi;
	  System.debug('lt123 --- init end --- : ' + System.currentTimeMillis());
	  return null;
	}
	
	private void searchOppSetParam() {
	  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;
	  //【委托】【重要】周会管理表修改  tcm start
	  OpptyWaitForSort=OpptyWait;
	  //【委托】【重要】周会管理表修改  tcm end
	}
	
	private void setLayoutRWInfo() {
	  if (this.sortOrder == null) {
	
	  List<String> columnsForMoney = new List<String>();
	  Set<String> currencyFields = new Set<String>();
	
	  // 获得项目set
	  Map<String, Schema.FieldSet> fsMap = Schema.getGlobalDescribe().get('Opportunity').getDescribe().fieldSets.getMap();
	
	  // 合計金額計算用
	  Schema.FieldSet fs = fsMap.get('Opportunity_PCL_Sum');
	  List<FieldSetMember> fsmList = fs.getFields();
	  columnMoneyMap = new Map<String, Decimal>();
	  columnMoneyFlgMap = new Map<String, Boolean>();
	  for (FieldSetMember fsm : fsmList) {
		columnMoneyMap.put(fsm.getFieldPath(), 0);
	  }
	
	  // 左 固定
	  fs = fsMap.get('Opportunity_PCL_L');
	  // 获得项目set中的所有项目
	  fsmList = fs.getFields();
	  // 获得字段标签和字段名
	  titleLeft = new List<String>();
	  List<String> columnLeft = new List<String>();
	
	  columnLeftCss = new List<String>();
	  columnLeftRW = new Map<String, String>();
	  columnsLeftApi = new List<List<String> >();
	  for (FieldSetMember fsm : fsmList) {
		titleLeft.add(fsm.getLabel());
		columnLeft.add(fsm.getFieldPath());
		List<String> splitFieldPath = fsm.getFieldPath().split('\\.');
		columnsLeftApi.add(splitFieldPath);
	
		if (String.valueOf(fsm.getType()) == 'CURRENCY') {
		currencyFields.add(fsm.getFieldPath());
		}
		system.debug('splitFieldPath等于'+splitFieldPath.size());
		if (DESC_RW == null) {
		columnLeftRW.put(fsm.getFieldPath(), 'r');
		} else if (splitFieldPath.size() == 1) {
		String rw = DESC_RW.get(fsm.getFieldPath());
		if (rw != null) {
		  columnLeftRW.put(fsm.getFieldPath(), rw);
		} else {
		  columnLeftRW.put(fsm.getFieldPath(), 'r');
		}
		} else {
		columnLeftRW.put(fsm.getFieldPath(), 'r');
		}
	  }
	  for (String s : columnLeft) {
		if (columusSet.contains(s) == false) {
		columus.add(s);
		if (currencyFields.contains(s)) {
		  columnsForMoney.add('convertCurrency(' + s + ')');
		} else {
		  columnsForMoney.add(s);
		}
		columusSet.add(s);
		}
		if (columnMoneyMap.containsKey(s)) {
		columnMoneyFlgMap.put(s.replace('.','_'), true);
		} else {
		columnMoneyFlgMap.put(s.replace('.','_'), false);
		}
		columnLeftCss.add(s.replace('.','_'));
	  }
	  fs = fsMap.get('Opportunity_PCL');
	  // 获得项目set中的所有项目
	  fsmList = fs.getFields();
	  // 获得字段标签和字段名
	  titleRight = new List<String>();
	  List<String> tmpColRight = new List<String>();
	
	  columnRightCss = new List<String>();
	  columnRightRW = new Map<String, String>();
	  columnsRightApi = new List<List<String> >();
	
	  Integer cnt = 0;
	  for (FieldSetMember fsm : fsmList) {
		titleRight.add(fsm.getLabel());
		List<String> splitFieldPath = fsm.getFieldPath().split('\\.');
		columnsRightApi.add(splitFieldPath);
	
		if (String.valueOf(fsm.getType()) == 'CURRENCY') {
		currencyFields.add(fsm.getFieldPath());
		}
		// 「1月末」を設定したら、12ヶ月分を設定と見なす
		// 設定の順番や、欠番などを考慮せず
		System.debug('splitFieldPath:'+splitFieldPath);
		System.debug('splitFieldPath[0]:'+splitFieldPath[0]);
		if (splitFieldPath.size() == 1 && splitFieldPath[0] == 'Rating01__c') {
		ratingStartIdx = cnt;
		}
	
		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');
		}
		tmpColRight.add(fsm.getFieldPath());
		cnt++;
	  }
	  //SWAG-CFN8JP 【委托】 【委托】【FY23询价改善】-询价预测时间改善 fy start 
	  if(columnRightRW.containsKey('Close_Forecasted_Assume_Date__c')){
		columnRightRW.put('Close_Forecasted_Assume_Date__c', 'r');
	  }
	  if(columnRightRW.containsKey('Close_Forecasted_Date__c')){
		columnRightRW.put('Close_Forecasted_Date__c', 'r');
	  }
	  //SWAG-CFN8JP 【委托】 【委托】【FY23询价改善】-询价预测时间改善 fy end 
	  for (String s : tmpColRight) {
		if (columusSet.contains(s) == false) {
		columus.add(s);
		if (currencyFields.contains(s)) {
		  columnsForMoney.add('convertCurrency(' + s + ')');
		} else {
		  columnsForMoney.add(s);
		}
		columusSet.add(s);
	
		}
		if (columnMoneyMap.containsKey(s)) {
		columnMoneyFlgMap.put(s.replace('.','_'), true);
		} else {
		columnMoneyFlgMap.put(s.replace('.','_'), false);
		}
		columnRightCss.add(s.replace('.','_'));
	  }
	
	  for (Integer i = 0; i < columnRightCss.size(); i++) {
		system.debug('columnRightCsssize等于'+columnRightCss.size());
		system.debug('ratingStartIdx等于'+ratingStartIdx);
		if (i == ratingStartIdx) {
		// 12ヶ月の旧Css
		Map<Integer, String> oldCssMap = new Map<Integer, String>();
		// 12ヶ月の旧ラベル
		Map<Integer, String> oldLabelMap = new Map<Integer, String>();
		for (Integer m = 1; m <= 12; m++) {
		  oldCssMap.put(m, columnRightCss[i + m - 1]);
		  oldLabelMap.put(m, titleRight[i + m - 1]);
		}
		// 12ヶ月
		for (Integer m = 1; m <= 12; m++) {
		  Integer newM = makeRatingLabel(m);
		  // ラベル
		  titleRight[i + m - 1] = oldLabelMap.get(newM);
		  // CSS
		  columnRightCss[i + m - 1] = oldCssMap.get(newM);
		  // Read/Write
		  columnRightRW.put(columnRightCss[i + m - 1], 'r');
		  // API
		  columnsRightApi[i + m - 1] = new String[] { makeRatingAPI(m, Date.today().month()) };
		  columus[columnLeftCss.size() + 1 + i + m - 1] = makeRatingAPI(m, Date.today().month());
		}
		break;
		}
	  }
	
	  // ソート用
	  this.sortOrderAsc = true;
	  this.sortOrder = new String[columus.size()];
	  for (Integer i = 0; i < columus.size(); i++) this.sortOrder[i] = '　';
	
	  // Mark
	  fs = fsMap.get('Opportunity_PCL_Mark');
	  // 获得项目set中的所有项目
	  fsmList = fs.getFields();
	  columnMark = new List<String>();
	  for (FieldSetMember fsm : fsmList) {
		columnMark.add(fsm.getFieldPath());
	  }
	  for (String s : columnMark) {
		if (columusSet.contains(s) == false) {
		columus.add(s);
		columusSet.add(s);
		}
	  }
	
	  strColumus = String.join(columus, ',');
	  strColumusForMoney = String.join(columnsForMoney, ',');
	  system.debug('=====strColumus:' + strColumus);
	  }
	}
	
	private void searchOppInner() {
	  oppRecords = new List<OppInfo>();
	
	  String soql = this.makeSoql(false, hpForSort, ownerForSort,
					datefieldForSort, fromdForSort, todForSort, textForSort, conditionForSort, valueForSort,
					textForSort2, conditionForSort2, valueForSort2,
					textForSort3, conditionForSort3, valueForSort3,OpptyWaitForSort);
	  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);
	  }
	
	  String soqlForMoney = this.makeSoql(true, hpForSort, ownerForSort,
						datefieldForSort, fromdForSort, todForSort, textForSort, conditionForSort, valueForSort,
						textForSort2, conditionForSort2, valueForSort2,
						textForSort3, conditionForSort3, valueForSort3,OpptyWaitForSort);
	  if (String.isBlank(this.sortKey)) {
	  soqlForMoney += ' order by LastModifiedDate desc limit ' + Integer.valueOf(System.Label.TotalLimit);
	  } else {
	  soqlForMoney += ' 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('soql:' + soql);
	  List<Opportunity> queryList = Database.query(soql);
	  List<Opportunity> queryListForMoney = Database.query(soqlForMoney);
	
	  this.makeOppRecordsForView(queryList, queryListForMoney);
	
	  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() {
	  searchOppSetParam();
	  setLayoutRWInfo();
	  searchOppInner();
	  return null;
	}
	
	public PageReference sortTable() {
	  oppRecords = new List<OppInfo>();
	
	  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;
	}
  
	//XLIU-CGF4TA 【委托】 【询价管理改善需求评估】询价中的进口论证判断 增加保存的修改，只保存可以修改的字段 start
	private Opportunity makeUpdateOpp(Opportunity oppinline) {
	  Opportunity ret = new Opportunity();
	  ret.Id = oppinline.Id;
	  for (String leftkey : columnLeftRW.keySet()) {
		if (!'r'.equals(columnLeftRW.get(leftkey))) {
		  ret.put(leftkey, oppinline.get(leftkey));
		}
	  }
	  for (String rightkey : columnRightRW.keySet()) {
		if (!'r'.equals(columnRightRW.get(rightkey))) {
		  ret.put(rightkey, oppinline.get(rightkey));
		}
	  }
	  return ret;
	}
	//XLIU-CGF4TA 【委托】 【询价管理改善需求评估】询价中的进口论证判断 增加保存的修改，只保存可以修改的字段 end 
	
	public PageReference save() {
	  try {
	  List<Opportunity> updOpps = new List<Opportunity>();
	
	  // List<String> oppidList = new List<String>();
	  // Map<String, String> oppidMap = new Map<String, String>();
	  // for (OppInfo oi : oppRecords) {
	  //   if (oi.changeFlg == '1') {
	  //   if (oppidMap.containsKey(oi.rec.Id) == false) {
	  //     oppidList.add(oi.rec.Id);
	  //   }
	  //   }
	  // }
	
	  // Map<String, Opportunity> oppMap = new Map<String, Opportunity>();
	  // List<Opportunity> oppList = [select Id, Competitor__c from Opportunity where Id = :oppidList];
	  // for (Opportunity opp : oppList) {
	  //   oppMap.put(opp.Id, opp);
	  // }
	
	  for (OppInfo oi : oppRecords) {
		// 変更チェック
		if (oi.changeFlg == '1') {
		oi.changeFlg = '0';
		// oi.rec.Competitor__c = oppMap.get(oi.rec.Id).Competitor__c;
		// updOpps.add(oi.rec);
		Opportunity up_opp = makeUpdateOpp(oi.rec);
		// up_opp.Competitor__c = oppMap.get(oi.rec.Id).Competitor__c;
		System.debug('up_opp: ' + up_opp);
		updOpps.add(up_opp);
		}
	  }
	
	  if (updOpps.size() > 0) update updOpps;
	  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 {
		  //进口论证 fy start
		  searchOpp();
		  //进口论证 fy end
	  }
	  return null;
	}
	
	public PageReference cancel() {
	  return new PageReference('/home/home.jsp');
	}
	
	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,Boolean OpptyWait) {
	  //进口论证 fy start
	//   if(txt=='if_NeedImportDemonstration__c'){
	// 	if(val=='是'){
	// 		val = 'true';
	// 	}else if(val=='否'){
	// 		val = 'false';
	// 	}
	//   }
	//   if(txt2=='if_NeedImportDemonstration__c'){
	// 	if(val2=='是'){
	// 		val2 = 'true';
	// 	}else if(val2=='否'){
	// 		val2 = 'false';
	// 	}
	//   }
	//   if(txt3=='if_NeedImportDemonstration__c'){
	// 	if(val3=='是'){
	// 		val3 = 'true';
	// 	}else if(val3=='否'){
	// 		val3 = 'false';
	// 	}
	//   }
	  //进口论证 fy end
	  String soql ='';
	  if (isforMoneyFlg == false) {
	  soql += 'select ' + strColumus + ' from Opportunity where (RecordType.DeveloperName = \'Opportunity\' or RecordType.DeveloperName = \'SI_Oppor\')';
	/*            soql += 'select Id, Name, Hospital__r.Name, Hospital__c, StageName__c, Status_Formula__c,'
	+ ' Opportunity_No__c, AccountId, Account.Name, OwnerId, Owner.Name, Opportunity_Category__c,'
	+ ' Estimation_List_Price__c, Estimation_Id__c, Estimation_No__c, Last_Shipping_Scheduled_Date__c,  Last_Shipping_Date__c,'
	+ ' Last_Follow_Up_Date__c, CreatedDate, LastModified_Day__c, Closing_Bid_Date__c, Important_Rroduct_Flg__c,'//Owner.Brief_Name__c,
	+ ' Rating01__c, Rating02__c, Rating03__c, Rating04__c, Rating05__c, Rating06__c,'
	+ ' Rating07__c, Rating08__c, Rating09__c, Rating10__c, Rating11__c, Rating12__c,Owner_Category__c,'
	+ ' HP_Name__c, Sales_incharge__c, Wholesale_Price_F__c, Agency1__c, '//Estimation_List_Price_Formula__c, OCM_Agent1_Price_Formula__c,
	+ ' Segment__c, Opp_Code__c, Open_Quotation__c, Competitor__c, Bid_Planned_Date__c,'
	+ ' Close_Forecasted_Date__c, CloseDate, Follow_up_comment__c, Department_Name__c,'
	+ ' Next_Action__c, Create_Activity__c, Nunber_of_visit__c, Number_of_OPD__c, Rating__c, '//Quotation_Number_SAP__c,,  Discount_Rate__c
	+ ' OCM__c, Amount_Without_Tax_F__c, Key_tipics_last_update_day__c, Update_situation__c , Last_opd_date__c,'
	+ ' Stage2_last_update_day__c, Follow_up_plan_last_update__c, Closing_Bid_date_last_update_day__c, OPP_rank_Last_update_day__c, Situation_last_update_day__c, '
	+ ' Opp_forecast_day_last_update_day__c, Tender_data_last_update_day__c, Forecast_amount_last_update_day__c, Forecast_shipping_day_last_update__c, Created_Day__c, '
	+ ' Agency_Contract_Date1__c, Sales_Shop_Hospital_Contract__c, Manager_feedback__c, Forecast_this_month__c,'
	+ ' Manager_feedback_last_update__c, Agency_Contract_Date_last_update__c, Agent_Hospital_Contract_day_last_update__c,'
	+ ' Bid_Date__c, Bid_date_last_update_day__c, Collect_Customer_sign__c, Lapsed_Days__c, OPD_SIS_collect_evaluation_sight__c,'
	+ ' Owner.Salesdepartment__c, Owner.Province__c, Owner.Group__c'
	+ ' from Opportunity where (RecordType.DeveloperName = \'Opportunity\')';// and (stageName = \'引合\')';*/
	  } else {
	  soql += 'select ' + strColumusForMoney + ' from Opportunity where (RecordType.DeveloperName = \'Opportunity\' or RecordType.DeveloperName = \'SI_Oppor\')';
	/*            soql += 'select Id, Name, Hospital__r.Name, Hospital__c, StageName__c, Status_Formula__c,'
	+ ' Opportunity_No__c, AccountId, Account.Name, OwnerId, Owner.Name, Opportunity_Category__c,'
	+ ' convertCurrency(Estimation_List_Price__c), Estimation_Id__c, Estimation_No__c, Last_Shipping_Scheduled_Date__c,  Last_Shipping_Date__c,'
	+ ' Last_Follow_Up_Date__c, CreatedDate, LastModified_Day__c, Closing_Bid_Date__c, Important_Rroduct_Flg__c,'//Owner.Brief_Name__c,
	+ ' Rating01__c, Rating02__c, Rating03__c, Rating04__c, Rating05__c, Rating06__c,'
	+ ' Rating07__c, Rating08__c, Rating09__c, Rating10__c, Rating11__c, Rating12__c,Owner_Category__c,'
	+ ' HP_Name__c, Sales_incharge__c, convertCurrency(Wholesale_Price_F__c), Agency1__c, '//Estimation_List_Price_Formula__c, OCM_Agent1_Price_Formula__c,
	+ ' Segment__c, Opp_Code__c, Open_Quotation__c, Competitor__c, Bid_Planned_Date__c,'
	+ ' Close_Forecasted_Date__c, CloseDate, Follow_up_comment__c, Department_Name__c, '
	+ ' Next_Action__c, Create_Activity__c, Nunber_of_visit__c, Number_of_OPD__c, Rating__c, '//Quotation_Number_SAP__c,,  Discount_Rate__c
	+ ' OCM__c, convertCurrency(Amount_Without_Tax_F__c), Key_tipics_last_update_day__c, Update_situation__c , Last_opd_date__c,'
	+ ' Stage2_last_update_day__c, Follow_up_plan_last_update__c, Closing_Bid_date_last_update_day__c, OPP_rank_Last_update_day__c, Situation_last_update_day__c, '
	+ ' Opp_forecast_day_last_update_day__c, Tender_data_last_update_day__c, Forecast_amount_last_update_day__c, Forecast_shipping_day_last_update__c, Created_Day__c, '
	+ ' Agency_Contract_Date1__c, Sales_Shop_Hospital_Contract__c, Manager_feedback__c, Forecast_this_month__c,'
	+ ' Manager_feedback_last_update__c, Agency_Contract_Date_last_update__c, Agent_Hospital_Contract_day_last_update__c,'
	+ ' Bid_Date__c, Bid_date_last_update_day__c, Collect_Customer_sign__c, Lapsed_Days__c, OPD_SIS_collect_evaluation_sight__c,'
	+ ' Owner.Salesdepartment__c, Owner.Province__c, Owner.Group__c'
	+ ' from Opportunity where (RecordType.DeveloperName = \'Opportunity\')';// and (stageName = \'引合\')';*/
	  }
	  // xudan 20140626 状态1をチェックボックスに
	  if (onlyOpp) {
	  soql += ' and StageName__c = \'询价\'';
	  }
	  if (!String.isBlank(accStr)) {
	  //soql += ' and Hospital__c = \'' + accStr + '\'';
	  String[] vals = accStr.split(' ');
	  for (String v : vals) {
		soql += ' and Hospital__r.Name like \'%' + String.escapeSingleQuotes(v.replaceAll('%', '\\%')) + '%\'';
	  }
	  }
	  if (!String.isBlank(ownerStr)) {
	  //soql += ' and OwnerId = \'' + ownerStr + '\'';
	  String[] vals = ownerStr.split(' ');
	  for (String v : vals) {
		soql += ' and Owner.Name like \'%' + String.escapeSingleQuotes(v.replaceAll('%', '\\%')) + '%\'';
	  }
	  }
	
	  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)';
	  }
	  }
	  //【委托】【重要】周会管理表修改  tcm start
	  if (OpptyWait) {
	  soql+=' and StageName__c =\'询价\' and SAP_Send_OK__c =false and Bool_Create_Day__c=true and Update_situation__c like \'%没更新%\' and Close_Forecasted_Date__c <= 2022-03-31';
	  }
	  //【委托】【重要】周会管理表修改  tcm end
	
	  // 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<Opportunity> queryList, List<Opportunity> queryListForMoney) {
	  Savepoint sp = Database.setSavepoint();
	  // TODO queryList について、最初のoppLimitだけ更新すればOKです。
	  Database.SaveResult[] results = Database.update(queryList, false);
	  // 強制ロールバック
	  Database.rollback(sp);
	  // 合计值清空
	  for (String key : columnMoneyMap.keySet()) {
	  columnMoneyMap.put(key, 0);
	  }
	
	  for (Integer i = 0; i < queryListForMoney.size(); i++) {
	  if(i<queryList.size()) {
		// limitを超えた場合前limit件のみを出す
		if (i == oppLimit + 1) {
		// TODO メッセージ表示
		continue;
		}
		oppRecords.add(new OppInfo(queryList[i]));
		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;
		  }
		}
		}
	  }
	
	  for (String key : columnMoneyMap.keySet()) {
		Decimal d = columnMoneyMap.get(key);
		d += queryListForMoney[i].get(key) == null ? 0 : Decimal.valueOf(String.valueOf(queryListForMoney[i].get(key)));
		columnMoneyMap.put(key, d);
	  }
	  }
	}
	
	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;
	  //进口论证 fy start
	  if(txt=='if_NeedImportDemonstration__c'){
			if(tmpVal=='是'){
				tmpVal = 'true';
			}else if(tmpVal=='否'){
				tmpVal = 'false';
			}else {
				return soql;
			}
	  }
	  //进口论证 fy end
	  // 空白の場合''にする
	  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;
	}
	
	/**
	 * 現在の月にて、表示すべきラベル名を作成
	 */
	private Integer makeRatingLabel(Integer idx) {
	  Integer m = Date.today().month();
	
	  Integer val = idx - 1 + m;
	  if (val > 12) {
	  val = val - 12;
	  }
	  return val;
	}
	
	/**
	 * 現在の月にて、Ratingのソート番号を作成
	 */
	//【委托】【重要】周会管理表修改  tcm start
	// private Integer makeRatingSortIdx(Integer idx) {
	//   Integer m = Date.today().month();
	
	//   Integer val = idx - 1 + m;
	//   if (val > 29) {
	//     val = val - 12;
	//   }
	//   return val;
	// }
	//【委托】【重要】周会管理表修改  tcm end
	
	/**
	 * 現在の月にて、取得すべきAPI名を作成
	 */
	private String makeRatingAPI(Integer idx, Integer m) {
	  String rtn = '';
	
	  Integer val = idx - 1 + m;
	  if (val > 12) {
	  val = val - 12;
	  }
	  if (val < 10) {
	  rtn = '0' + val;
	  } else {
	  rtn = '' + val;
	  }
	
	  return 'Rating' + rtn + '__c';
	}
	//XLIU-CGF4TA 【委托】 【询价管理改善需求评估】询价中的进口论证判断 fy start 
	// public PageReference HideForecastOCSMSigningDate() {
	//   if(HideForecastOCSMflag){
	//     List<String> HidecolumnRightCss = new List<String>();
	//     List<String> HidetitleRight = new List<String>();
	//     List<List<String> > HidecolumnsRightApiList = new List<List<String> >();
	//     for(List<String> colrightapiList: columnsRightApicopy){
	//       List<String> HidecolumnsRightApi = new List<String>();
	//       for(String colrightapi :colrightapiList){
	//         if(colrightapi != 'Close_Forecasted_Date__c'&&colrightapi != 'Close_Forecasted_Assume_Date__c'&&colrightapi != 'CloseDate'){
	//           HidecolumnsRightApi.add(colrightapi);
	//         }
	//       }
	//       if(HidecolumnsRightApi.size()>0){
	//         HidecolumnsRightApiList.add(HidecolumnsRightApi);
	//       }
	//     }
	//     for(String colright: columnRightCsscopy){
	//       if(colright != 'Close_Forecasted_Date__c'&&colright != 'Close_Forecasted_Assume_Date__c'&&colright != 'CloseDate'){
	//         HidecolumnRightCss.add(colright);
	//       }
	//     }
	//     for(String titlr: titleRightcopy){
	//       if(titlr != '预测OCSM签约日(KPI)'&&titlr != '预测OCSM签约日(担当)'&&titlr != '预测发货日'){
	//         HidetitleRight.add(titlr);
	//       }
	//     }
	//     columnsRightApi=HidecolumnsRightApiList;
	//     columnRightCss=HidecolumnRightCss;
	//     titleRight=HidetitleRight;
	//   }else{
	//     system.debug('测试1'+titleRightcopy);
	//     system.debug('测试2'+columnsRightApicopy);
	//     system.debug('测试3'+columnRightCsscopy);
	//     titleRight=titleRightcopy;
	//     columnsRightApi=columnsRightApicopy;
	//     columnRightCss=columnRightCsscopy;
	//   }
  
	//   return null;
	// }
	//SWAG-CGG7UK 【委托】 【询价管理改善需求评估】询价中的进口论证判断 fy end 
	class OppInfo {
	  public Opportunity 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 OppInfo(Opportunity record) {
	  rec = record;
	  canEdit = true;
	  hasError = false;
	  hasFieldError = false;
	  lineNo = 0;
	  changeFlg = '0';
	  }
	}
	}