public with sharing class AssetTableController { public List oppRecords { get; set; } // ページレイアウトの情報を取得 /*****************検索用******************/ public Contact con1 { get; set; } public Contact con2 { get; set; } public String accSearch { get; set; } public List dateOpts { get; private set; } public List textOpts { get; private set; } public List equalOpts { get; private set; } public List textOpts2 { get; private set; } public List equalOpts2 { get; private set; } public List textOpts3 { get; private set; } public List equalOpts3 { get; private set; } public List 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; } public String limits { get; set; } /*****************画面表示Bean******************/ public Integer oppCount { 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 columusSet = new Set {'Id'}; // 项目set 字段标签 public List titleLeft { get; private set; } public List titleRight { get; private set; } // 项目set 字段名 public List> columnsLeftApi { get; private set; } // 参照項目用 public List> columnsRightApi { get; private set; } // 参照項目用 public List columnLeftCss { get; private set; } // css 用 public List columnRightCss { get; private set; } // css 用 private String strColumus; /*****************ソート時再検索条件(画面からの入力条件を無視するため)******************/ private String hpForSort = 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 static Integer oppLimit = 999; private Boolean isForMoneyFlg = false; public AssetTableController() { oppRecords = new List(); // 日付検索条件のCalendar用 con1 = new Contact(); con2 = new Contact(); dateOpts = new List(); dateOpts.add(new SelectOption('', '--无--')); dateOpts.add(new SelectOption('Posting_Date__c', '发货日')); dateOpts.add(new SelectOption('InstallDate', '安装日期')); dateOpts.add(new SelectOption('Final_Examination_Date__c', '最后点检日')); textOpts = new List(); textOpts.add(new SelectOption('','--无--')); textOpts.add(new SelectOption('S:OwnershipMachine_No__c','OCSM内部产品型号')); textOpts.add(new SelectOption('S:SerialNumber','机身编号')); textOpts.add(new SelectOption('S:Department_Name__c','科室')); textOpts.add(new SelectOption('S:Order_No__c','订单编码')); textOpts2 = textOpts; textOpts3 = textOpts; equalOpts = new List(); 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(); 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'; } public PageReference init() { searchOppSetParam(); setLayoutRWInfo(); this.sortOrderAsc = true; this.sortOrder = new String[columus.size()]; for (Integer i = 0; i < columus.size(); i++) this.sortOrder[i] = ' '; searchOppInner(); return null; } private void searchOppSetParam() { hpForSort = accSearch; 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; } private void setLayoutRWInfo() { if (this.sortOrder == null) { // 获得项目set Map fsMap = Schema.getGlobalDescribe().get('Asset').getDescribe().fieldSets.getMap(); // 左 固定 Schema.FieldSet fs = fsMap.get('AssetTableLeftFixation'); // 获得项目set中的所有项目 List fsmList = fs.getFields(); // 获得字段标签和字段名 titleLeft = new List(); List columnLeft = new List(); columnLeftCss = new List(); columnsLeftApi = new List>(); for (FieldSetMember fsm : fsmList) { titleLeft.add(fsm.getLabel()); columnLeft.add(fsm.getFieldPath()); List splitFieldPath = fsm.getFieldPath().split('\\.'); columnsLeftApi.add(splitFieldPath); } for (String s : columnLeft) { if (columusSet.contains(s) == false) { columus.add(s); columusSet.add(s); } columnLeftCss.add(s.replace('.','_')); } fs = fsMap.get('AssetTableRightMovement'); // 获得项目set中的所有项目 fsmList = fs.getFields(); // 获得字段标签和字段名 titleRight = new List(); List columnRight = new List(); columnRightCss = new List(); columnsRightApi = new List>(); for (FieldSetMember fsm : fsmList) { titleRight.add(fsm.getLabel()); columnRight.add(fsm.getFieldPath()); List splitFieldPath = fsm.getFieldPath().split('\\.'); columnsRightApi.add(splitFieldPath); } for (String s : columnRight) { if (columusSet.contains(s) == false) { columus.add(s); columusSet.add(s); } columnRightCss.add(s.replace('.','_')); } strColumus = String.join(columus, ','); this.sortOrderAsc = true; this.sortOrder = new String[columus.size()]; for (Integer i = 0; i < columus.size(); i++) this.sortOrder[i] = ' '; system.debug('=====strColumus:' + strColumus); } } private void searchOppInner() { oppRecords = new List(); String soql = this.makeSoql(false, hpForSort, datefieldForSort, fromdForSort, todForSort, textForSort, conditionForSort, valueForSort, textForSort2, conditionForSort2, valueForSort2, textForSort3, conditionForSort3, valueForSort3); if (String.isBlank(this.sortKey)) { soql += ' order by Id 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 queryList = Database.query(soql); this.makeOppRecordsForView(queryList); 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(); 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; } private String makeSoql(Boolean isforMoneyFlg, String accStr, String datefield, Date fromd, Date tod, String txt, String con, String val, String txt2, String con2, String val2, String txt3, String con3, String val3) { String soql =''; if (isforMoneyFlg == false) { soql += 'select Hospital__r.Name, ' + strColumus + ' from Asset where RecordTypeId = \''+System.label.Asset_table+'\' and Asset_Owner__c = \'病院資産\' '; //niwu 01210000000kOPM } if (!String.isBlank(accStr)) { //soql += ' and Hospital__r.Name = \'' + accStr +'\''; soql += ' and Hospital__r.Name like \'%' + String.escapeSingleQuotes(accStr.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)'; } } soql += this.makeTextSql(txt, con, val); soql += this.makeTextSql(txt2, con2, val2); soql += this.makeTextSql(txt3, con3, val3); return soql; } private void makeOppRecordsForView(List queryList) { for (Integer i = 0; i < queryList.size(); i++) { // limitを超えた場合前limit件のみを出す if (i == oppLimit + 1) { // TODO メッセージ表示 continue; } oppRecords.add(new RepairInfo(queryList[i])); } } 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 、最初の2文字がタイプです soql += ' and ( '; for (String v : vals) { if (con == 'equals') { soql += txt + ' = \'' + v + '\' or '; } else { // notequals soql += txt + ' <> \'' + v + '\' and '; } } soql = soql.substring(0, soql.length() - 4); soql += ')'; } } else { String cSql = this.makeTextSqlStr(txt1, con, val); if (con != 'notcontains') { soql += this.makeTextSqlStr(txt1, con, val); } else { // notcontains cSql = cSql.substring(5); // ' and ' の5文字を外す soql += ' and (NOT ' + cSql + ') '; } } } return soql; } /** * 文字列検索文を作成 */ private String makeTextSqlStr(String txt1, String con, String val) { String soql = ''; if (!String.isBlank(txt1)) { String txt = txt1.substring(2); String colType = txt1.substring(0, 2); String tmpVal = val; // 空白の場合''にする if (String.isBlank(tmpVal)) { if (con == 'equals') { //soql += ' and ' + txt + ' = ' + tmpVal; soql += ' and ' + txt + ' = null'; } else if (con == 'notequals') { soql += ' and ' + txt + ' <> null'; } else { // 空白の場合、contains, notcontains と starts withは無視 } } else { soql += ' and ' + txt; if (con == 'equals') { if (colType == 'S:') { soql += ' = \'' + tmpVal + '\''; } else { soql += ' = ' + tmpVal + ' '; } } else if (con == 'notequals') { if (colType == 'S:') { soql += ' <> \'' + tmpVal + '\''; } else { soql += ' <> ' + tmpVal + ' '; } } else if (con == 'contains' || con == 'notcontains') { soql += ' like \'%' + 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 RepairInfo { public Asset asset { 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 RepairInfo(Asset record) { asset = record; canEdit = true; hasError = false; hasFieldError = false; lineNo = 0; changeFlg = '0'; } } }