Salesforce Apex - лучший способ достижения вывода вложенных таблиц - PullRequest
0 голосов
/ 26 октября 2018
public pageReference getData(){
    date sd = date.parse(sDate).toStartOfWeek();
    date ed = date.parse(eDate);
    hList = new list<Hours__c>([SELECT Name,Employee__r.Id,Date_worked__c,Employee__r.Offshore__c,Employee__r.Name,Employee__r.Department__c,Employee_Name__c,hours__c,Minutes__c,Hours_Decimal__c FROM Hours__c WHERE Type_of_Hours__c = 'Work' AND Date_worked__c >= :sd AND Date_worked__c <= :ed AND Employee__r.Department__c IN :selected ORDER BY Employee__r.Department__c,Date_worked__c,Employee__r.Name LIMIT 3000]);
    wrap = new list<wrapper>();
    string tempDepartment;
    string tempEmpName;
    date tempWorkDate;
    date tempStart = sd;
    decimal offshore = 0;
    decimal onshore = 0;
    decimal totalOffshore = 0;
    decimal totalOnShore = 0;
    decimal dateCount = 0;
    decimal aggreagteTotal = 0;
    integer hitLimit = 3000;
    integer rpwp = 0;
    integer compareRPWP = 0;
    boolean fired = false;
    boolean dateChanged = false;
    boolean dateCountis13 = false;
    map<date,integer> mapDateCount = new map<date,integer>();
    if(hList.size() > 0 && hList.size() < hitLimit){
        noResults = false;
        for(Hours__c h: hList){
            //initiate a new wrapper for each department as a primary header
            if( (h.Employee__r.Department__c != null && ((tempDepartment != null && tempDepartment != h.Employee__r.Department__c) || ( tempDepartment == null)) ) ){
                fired = true;
                tempDepartment = h.Employee__r.Department__c;
                wrap.add(new wrapper(null,null,null,null,null,tempDepartment,'','','',null,'',''));
            }else{
                fired = false;
            }
            if(fired || dateCountis13){
                dateCountis13 = false;
                dateCount = 0;
                totalOffshore = 0;
                totalOnShore = 0;
            }
            //initiate a new wrapper for each new week period, total employee hours for each week period for each department
            if(fired || (h.Date_worked__c != null && ((tempWorkDate != null && tempWorkDate != h.Date_worked__c) || ( tempWorkDate == null)) ) || (h.Employee__r.Department__c != null && ((tempDepartment != null && tempDepartment != h.Employee__r.Department__c) || ( tempDepartment == null)) ) ){
                dateChanged = true;
                tempWorkDate = h.Date_worked__c;
                offshore = 0;
                onshore = 0;
                rpwp = 0;
                dateCount++;
                for(Hours__c h1: hList){
                    //get count of each record that is inside a given week period
                    if(h1.Date_worked__c == tempWorkDate && h1.Employee__r.Department__c == tempDepartment){
                        rpwp++;
                    }
                    //logic for totaling offshore hours by date and department
                    if(h1.Date_worked__c == tempWorkDate && h1.Employee__r.Offshore__c && h1.Employee__r.Department__c == tempDepartment){
                        offshore += h1.Hours_Decimal__c != null ? h1.Hours_Decimal__c : 0;
                    }
                    //logic for totaling onshore hours by date and department
                    if(h1.Date_worked__c == tempWorkDate && h1.Employee__r.Offshore__c == false && h1.Employee__r.Department__c == tempDepartment){
                        onshore += h1.Hours_Decimal__c != null ? h1.Hours_Decimal__c : 0;
                    }
                }
                system.debug('rpwp: ' + rpwp);
                wrap.add(new wrapper(h.Date_worked__c.toStartOfWeek(),h.Date_worked__c,onshore,offshore,null,'total','','','',null,'',''));
                totalOffshore += offshore;
                totalOnShore += onshore;
                system.debug('OffShore: ' +  offshore + '  ' + tempWorkDate.format());
                system.debug('OnShore: ' + onshore + '  ' + tempWorkDate.format());
            }else{
                dateChanged = false;
            }
            //initiate a new wrapper for each record and give the ability to open and collapse all records under a given total week period
            // functionality now does an aggregate total of employee's that have multiple hour entrees for each week period.
            if( dateChanged || (h.Employee__r.Name != null && ((tempEmpName != null && tempEmpName != h.Employee__r.Name) || ( tempEmpName == null)) ) ){
                tempEmpName = h.Employee__r.Name;
                aggreagteTotal = 0;
                for(Hours__c h2: hList){
                    if(tempEmpName == h2.Employee__r.Name && tempWorkDate == h2.Date_worked__c){
                        aggreagteTotal += h2.Hours_Decimal__c;
                    }
                }
                if(h.Employee__r.Offshore__c){
                    wrap.add(new wrapper(h.Date_worked__c.toStartOfWeek(),h.Date_worked__c,0,h.hours__c,aggreagteTotal,'collapse',h.Employee__r.Name,h.Employee__r.Id,h.Name,h.Employee__r.Offshore__c,h.Employee__r.Department__c,h.Date_worked__c.format() ));
                }else{
                    wrap.add(new wrapper(h.Date_worked__c.toStartOfWeek(),h.Date_worked__c,h.hours__c,0,aggreagteTotal,'collapse',h.Employee__r.Name,h.Employee__r.Id,h.Name,h.Employee__r.Offshore__c,h.Employee__r.Department__c,h.Date_worked__c.format() ));
                }
            }
            //compare record count on the outside loop to record count on the inner loop and set compare iterator to 0 if the date changes
            if(dateChanged){
                compareRPWP = 0;
            }
            compareRPWP++;
            system.debug('compareRPWP: ' +  compareRPWP );
            //if on the 13th week -- initiate a new wrapper and get quarterly totals -- compare record count so that inner loop matches outer loop
            if( (dateCount == 13 && compareRPWP == rpwp) ){
                system.debug('totalOffshore: ' +  totalOffshore );
                system.debug('totalOnShore: ' + totalOnShore );
                dateCountis13 = true;
                wrap.add(new wrapper(null,null,totalOnShore,totalOffshore,null,'quarter',tempDepartment,'','',null,'',''));
            }
        }
    }else if(hList.size() <= 0){
        noResults = true;
        bannerMessage = 'Oops! No record found.';
    }else if(hList.size() >= hitLimit){
        noResults = true;
        bannerMessage = 'Oops! 3000 Record limit hit.';
    }else{
        noResults = true;
        bannerMessage = 'Oops! 50000 record limit hit.';
    }

    system.debug('wrap: ' + wrap);
    system.debug('hList: ' + hList);
    return null;
}

Вот мой метод работы в моем классе. По сути, я делаю запрос к пользовательскому объекту Hours__c. То, что я хочу сделать, - это чтобы результаты на столе были сначала вложены каждым сотрудником отдела. Затем вкладывается в каждый рабочий период со всеми часами, отработанными этим отделом для каждого рабочего периода. По сути, я добился этого с самого начала, упорядочив запрос таким образом. Теперь речь шла о том, как заставить логику схватить ее в нужное время. Но также необходимо агрегировать общее количество часов, если у сотрудников было более одного часа в неделю. Я также, наконец, через каждые 13 недель выводил общее количество часов за этот квартал.

Вот скринкаст моего пользовательского отчета, если вам интересно посмотреть, чего я достиг на фронтэнде, но чего я хочу добиться на бэкенде и более эффективным способом. Проблема с моей логикой, пока она работает, если запрашивается много данных. Эта логика довольно медленная. Потому что сначала он зацикливает результаты запроса один раз. но внутри первого цикла for я повторяю один и тот же запрос 2 раза ... :: slaps head :: ... Я знаю, что это ужасно.

Итак, я хочу посмотреть, может быть, есть ли более эффективный способ достичь этого с помощью потенциально карты или другого класса-обертки? Потому что это тоже все в одном классе-обёртке. Я использую логику переднего плана, чтобы отсортировать таблицу на основе результатов в классе-оболочке. Я просто прячусь и показываю строки. Как я уже сказал, это работает не так эффективно, как хотелось бы, чтобы моя логика работала.

вот скриншот:

https://screencast -o-matic.com / часы / cF60cwYAiB

1 Ответ

0 голосов
/ 27 октября 2018

Моя первая идея заключается в подготовке новой карты Map<Date, List<Hour__c>> dateWorkedToHoursMap в контроллере сразу после вашего SOQL. С помощью этой карты вы сможете быстро получить Hour__c записей по специфике Date (Date_worked__c) и проходить только через них в вашем сабле для петель.

public class Controller {

    // (...)
    Map<Date, List<Hour__c>> dateWorkedToHoursMap; // New map in controller
    // (...)

    // Updated "getData()" method which will prepare "dateWorkedToHoursMap" 
    // map just after SOQL and then will use in both sub for loops
    public pageReference getData() {
        // (...)
        // Your SOQL for Hour__c records
        // dateWorkedToHoursMap = prepareDateWorkedToHoursMap(hList);
        // (...)
        // main for through hList
        //      (...)
        //      1 sub for through list returned by: dateWorkedToHoursMap.get(h.Date_worked__c)
        //      (...)
        //      2 sub for through list returned by: dateWorkedToHoursMap.get(h.Date_worked__c)
        //      (...)
        // end of main for
    }

    // New "prepareDateWorkedToHoursMap()" method used to prepare "dateWorkedToHoursMap" map
    private void prepareDateWorkedToHoursMap(List<Hour__c> hours) {
        dateWorkedToHoursMap = new Map<Date, List<Hour__c>>();

        for(Hour__c hour : hours) {
            if(hour.Date_worked__c != null) {
                if(!dateWorkedToHoursMap.containsKey(hour.Date_worked__c)) {
                    dateWorkedToHoursMap.put(hour.Date_worked__c, new List<Hour__c>());
                }

                dateWorkedToHoursMap.get(hour.Date_worked__c).add(h);
            }
        }
    }
}

Если вы думаете, что это будет лучше, тогда вы можете попытаться подготовить карту как:

Map<String, Map<Date, List<Hour__c>>> departmentToDateWorkedToHoursMap

И тогда вы сможете быстро получить список Hour__c записей на основе DEPARTMENT и DATE WORKED.

...