Can you please revise this code and make it more cohesive and remove unnecessary methods. 

/// <summary>
///     Builds the matrix object for populating the viewers.
/// </summary>
class BudgetPlanAggregatedMatrixBuilder_WEW
{
    List columnLabels;
    Map dateColumnMap = new Map(Types::Integer, Types::Integer);
    Map matrixLineDefintionMap = new Map(Types::Integer, Types::Class);
    date displayDate, startDate;
    BudgetPlanTimeBucket_WEW bucket;
    boolean nextPageExists;
    List matrixLineDefinitions = new List(Types::Class);
    Query dataSourceQuery;
    QueryBuildDataSource qbdsBudget;
    int currentQuarter;
    int currentMonth;
    date currentYear;
    date beginOfPeriodDate, endOfPeriodDate;
    QueryBuildDataSource qbdsCustomerOverview;
    Query query;
    ItemId itemId;
    AccountNum accountNum;
    BudgetId_WEW budgetId;
    int maxColumns = 1;
    QueryBuildDataSource qbdsBIDateDimensionsView;
    QueryBuildDataSource qbdsBudgetPlanDetails; 


    public void new(Query _dataSourceQuery, ItemId _itemId, AccountNum _accountNum, BudgetId_WEW _budgetId, date _startDate = DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone()))
    {
        super();
        dataSourceQuery = _dataSourceQuery;
        startDate = _startDate;
        accountNum = _accountNum;
        budgetId = _budgetId;
        currentQuarter = date2Qtr(_startDate);
        currentMonth = mthOfYr(_startDate);
        currentYear = mkDate(1,1,year(_startDate));
        itemId = _itemId;

        // initialize in the current quarter
        BIDateDimensionsView dateView;
        select firstonly dateView
            where dateView.Date == startDate;
        displayDate = dateView.Month;

        this.initializeQuery();
        this.initializeCustomerQuery();
    }

    private void initializeQuery()
    {
        // add BIDateDimensionsView to source table
        qbdsBudget = dataSourceQuery.dataSourceTable(tableNum(BudgetPlanDetails_WEW)).addDataSource(tableNum(BIDateDimensionsView));

        // join datasources
        qbdsBudget.addLink(fieldNum(BudgetPlanDetails_WEW, BudgetPlanDate_WEW), fieldNum(BIDateDimensionsView, Date));
        qbdsBudget.joinMode(JoinMode::InnerJoin);

        // add default sorting
        qbdsBudget.addSortField(fieldNum(BudgetPlanDetails_WEW, BudgetPlanDate_WEW));
    }

    private void initializeCustomerQueryOLD()
    {
        // setup customer query
        query = new Query(); 
        qbdsBudgetPlanDetails = query.addDataSource(tableNum(BudgetPlanDetails_WEW));

        // add child data source
        //QueryBuildDataSource qbdsBIDateDimensionsView = qbdsBudgetPlanDetails.addDataSource(tableNum(BIDateDimensionsView));
        qbdsBIDateDimensionsView = qbdsBudgetPlanDetails.addDataSource(tableNum(BIDateDimensionsView));

        // setup join
        //qbdsBudgetPlanDetails.addLink(fieldNum(BudgetPlanDetails_WEW, BudgetPlanDate_WEW), fieldNum(BIDateDimensionsView, Date));
        qbdsBIDateDimensionsView.addLink(fieldNum(BudgetPlanDetails_WEW, BudgetPlanDate_WEW), fieldNum(BIDateDimensionsView, Date));
        //qbdsBudgetPlanDetails.joinMode(JoinMode::InnerJoin);
        qbdsBIDateDimensionsView.joinMode(JoinMode::InnerJoin);

        // Add gropuing on the parent data source
        qbdsBudgetPlanDetails.addGroupByField(fieldNum(BudgetPlanDetails_WEW, AccountNum));

        // Add gropuing on the child data source
        qbdsBIDateDimensionsView.addGroupByField(fieldNum(BIDateDimensionsView, Year));
        qbdsBIDateDimensionsView.addGroupByField(fieldNum(BIDateDimensionsView, Week_Of_Year));
        
        // Add SUM fields
        qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, BudgetQty), SelectionField::Sum);
        qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, BudgetPromotionQty), SelectionField::Sum);
        qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, ActualQty), SelectionField::Sum);
        qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, ActualpromotionQty), SelectionField::Sum);
        qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, RollingBudgetQty), SelectionField::Sum);
        qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, RollingBudgetPromotionQty), SelectionField::Sum);
        //qbdsBIDateDimensionsView.addSelectionField(fieldNum(BIDateDimensionsView, Week_Of_Year), SelectionField::Max);
        
        // Set the order mode to respect the GROUP BY
        qbdsBudgetPlanDetails.orderMode(OrderMode::GroupBy);
        
        // Add sorting
        //qbdsBudgetPlanDetails.addSortField(fieldNum(BudgetPlanDetails_WEW, AccountNum));
        //qbdsBIDateDimensionsView.addSortField(fieldNum(BIDateDimensionsView, Week));
    }

    private void initializeCustomerQuery()
    {
        /*
            - [ ] TODO: 
            - [ ] TODO: add range, to limit the records to the given ItemId or AccountNum
            - [ ] TODO: remove Group By Clause in Order so that a record is selected
        */
        // setup customer query
        query = new Query(); 
        qbdsBudgetPlanDetails = query.addDataSource(tableNum(BudgetPlanDetails_WEW));

        // add child data source
        qbdsBIDateDimensionsView = qbdsBudgetPlanDetails.addDataSource(tableNum(BIDateDimensionsView));

        // setup join
        qbdsBIDateDimensionsView.addLink(fieldNum(BudgetPlanDetails_WEW, BudgetPlanDate_WEW), fieldNum(BIDateDimensionsView, Date));
        qbdsBIDateDimensionsView.joinMode(JoinMode::InnerJoin);


    }

    private QueryRun getQueryRunObject(date _month, boolean _filterByCustomer = false)
    {

        date minCalendarWeek, maxCalendarWeek;
        BIDateDimensionsView biDateDimensionsView;

        select firstonly biDateDimensionsView
            where biDateDimensionsView.Month == _month
                && biDateDimensionsView.Day_Of_Week > 4;

        minCalendarWeek = biDateDimensionsView.Week;
        biDateDimensionsView.clear();

        select firstonly biDateDimensionsView
            order by biDateDimensionsView.Date desc
            where biDateDimensionsView.Month == _month
                && biDateDimensionsView.Day_Of_Week > 4;

        maxCalendarWeek = biDateDimensionsView.Week;

        // delete filter range of previous queryRun
        //qbdsBIDateDimensionsView.clearRange(fieldNum(BIDateDimensionsView, Month));


        qbdsBIDateDimensionsView.clearRange(fieldNum(BIDateDimensionsView, Week));

        // clear group by clause and restate all fields of BudgetPlanDetails_WEW
        query.clearGroupBy();

        // clear all field selections of the BudgetPlanDetails queryBuildDataSource object
        qbdsBudgetPlanDetails.fields().clearFieldList();
        qbdsBudgetPlanDetails.addAllFields(tableStr(BudgetPlanDetails_WEW));
        qbdsBudgetPlanDetails.clearRange(fieldNum(BudgetPlanDetails_WEW, ItemId));

        // clear BIDateDimensionsView queryBuildDataSource
        qbdsBIDateDimensionsView.fields().clearFieldList();
        qbdsBIDateDimensionsView.addAllFields(tableStr(BIDateDimensionsView));


        // only filter by the weeks which are within the week list

        // add new range for specific quarter
        //qbdsBIDateDimensionsView.addRange(fieldNum(BIDateDimensionsView, Month)).value(queryValue(_month));
        qbdsBIDateDimensionsView.addRange(fieldNum(BIDateDimensionsView, Week)).value(queryRange(minCalendarWeek, maxCalendarWeek));

        // dirty hack TODO: revert to structure based on calendar week/ year entries instead of full entries
        // alternatively check µ$s deaggregate function.
        qbdsBIDateDimensionsView.addRange(fieldNum(BIDateDimensionsView, Day_Of_Week)).value(queryValue(1));

        // delete itemId filter 
        if(!_filterByCustomer && itemId)
        {
            qbdsBudgetPlanDetails.addRange(fieldNum(BudgetPlanDetails_WEW, ItemId)).value(itemId);
        }
        else if (_filterByCustomer)
        {
            // Add gropuing on the child data source
            qbdsBIDateDimensionsView.addGroupByField(fieldNum(BIDateDimensionsView, Week_Of_Year));
            
            // Add grouping on the parent data source
            qbdsBudgetPlanDetails.addGroupByField(fieldNum(BudgetPlanDetails_WEW, AccountNum));
        
            // Add SUM fields
            qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, BudgetQty), SelectionField::Sum);
            qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, BudgetPromotionQty), SelectionField::Sum);
            qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, ActualQty), SelectionField::Sum);
            qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, ActualpromotionQty), SelectionField::Sum);
            qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, RollingBudgetQty), SelectionField::Sum);
            qbdsBudgetPlanDetails.addSelectionField(fieldNum(BudgetPlanDetails_WEW, RollingBudgetPromotionQty), SelectionField::Sum);

            // Set the order mode to respect the GROUP BY
            qbdsBudgetPlanDetails.orderMode(OrderMode::GroupBy);
        }

        return new QueryRun(query);
    }

    public ItemId parmItemId(ItemId _itemId = itemId)
    {
        itemId = _itemId;
        return itemId;
    }

    public AccountNum parmAccountNum(ItemId _accountNum = accountNum)
    {
        accountNum = _accountNum;
        return accountNum;
    }

    public BudgetId_WEW parmBudgetId(BudgetId_WEW _budgetId = budgetId)
    {
        budgetId = _budgetId; 
        return budgetId;
    }

    public List parmMatrixLineDefinitions(List _matrixLineDefinitions = matrixLineDefinitions)
    {
        matrixLineDefinitions = _matrixLineDefinitions;
        return matrixLineDefinitions;
    }

    public int parmCurrentQuarter(int _quarter = currentQuarter)
    {
        currentQuarter = _quarter;
        return currentQuarter;
    }

    public int parmCurrentMonth(int _month = currentMonth)
    {
        currentMonth = _month;
        return currentMonth;
    }

    public Map parmMatrixLineDefinitionMap(Map _matrixLineDefintionMap = matrixLineDefintionMap)
    {
        matrixLineDefintionMap = _matrixLineDefintionMap;
        return matrixLineDefintionMap;
    }

    public date parmCurrentYear(date _year = currentYear)
    {
        currentYear = _year;
        return currentYear;
    }

    public date parmStartDate(date _startDate = displayDate)
    {
        displayDate = _startDate;
        return displayDate;
    }

    public Query parmDataSourceQuery(Query _dataSourceQuery = dataSourceQuery)
    {
        dataSourceQuery = _dataSourceQuery;
        return dataSourceQuery;
    }

    public date parmDisplayDate(date _displayDate = displayDate)
    {
        displayDate = _displayDate;
        return displayDate;
    }

    public int parmMaxColumns(int _maxColumns = maxColumns)
    {
        maxColumns = _maxColumns; 
        return maxColumns;
    }

    public void createMatrixLineDefinitionMapFromList()
    {
        // TODO: check if matrixLineDefinitions is filled
        var lineDefinitionEnumerator = matrixLineDefinitions.getEnumerator();

        int rowCounter = 1;
        while(lineDefinitionEnumerator.moveNext())
        {
            var lineDefinition = lineDefinitionEnumerator.current();
            matrixLineDefintionMap.insert(rowCounter, lineDefinition);
            rowCounter++;
        }
         
    }

    //private QueryRun getQueryRunForQuarter(date _quarter)
    //{
    //    // delete filter range of previous queryRun
    //    qbdsBudget.clearRange(fieldNum(BIDateDimensionsView, Quarter));

    //    // add new range for specific quarter
    //    qbdsBudget.addRange(fieldNum(BIDateDimensionsView, Quarter)).value(queryValue(_quarter));

    //    return new QueryRun(dataSourceQuery);
    //}

    private QueryRun getQueryRunForMonth(date _month)
    {
        // delete filter range of previous queryRun
        qbdsBudget.clearRange(fieldNum(BIDateDimensionsView, Month));

        // add new range for specific quarter
        qbdsBudget.addRange(fieldNum(BIDateDimensionsView, Month)).value(queryValue(_month));

        return new QueryRun(dataSourceQuery);
    }

    //private QueryRun getQueryRunObjectOLD(date _month, boolean _filterByCustomer = false)
    //{
    //    // delete filter range of previous queryRun
    //    //qbdsCustomerOverview.clearRange(fieldNum(BIDateDimensionsView, Month));
    //    qbdsBIDateDimensionsView.clearRange(fieldNum(BIDateDimensionsView, Month));
    //    // add new range for specific quarter
    //    qbdsBIDateDimensionsView.addRange(fieldNum(BIDateDimensionsView, Month)).value(queryValue(_month));

    //    // delete itemId filter 
    //    if(!_filterByCustomer && itemId)
    //    {
    //        qbdsBudgetPlanDetails.addRange(fieldNum(BudgetPlanDetails_WEW, ItemId)).value(itemId);
    //    }
    //    else if (_filterByCustomer)
    //    {
    //        qbdsBudgetPlanDetails.addRange(fieldNum(BudgetPlanDetails_WEW, AccountNum)).value(accountNum);
    //    }

    //    return new QueryRun(query);
    //}

    private QueryRun getQueryRunForMonthCustomer(date _month, boolean _filterByCustomer = false)
    {
        // delete filter range of previous queryRun
        qbdsBudget.clearRange(fieldNum(BIDateDimensionsView, Month));
        // add new range for specific quarter
        qbdsBudget.addRange(fieldNum(BIDateDimensionsView, Month)).value(queryValue(_month));

        QueryRun qr = new QueryRun(dataSourceQuery);

        // delete itemId filter 
        if(_filterByCustomer)
        {
            qbdsBudget.clearRange(fieldNum(BudgetPlanDetails_WEW, ItemId));
            qbdsBudget.addSelectionField(fieldNum(BudgetPlanDetails_WEW, ActualQty), SelectionField::Sum);
            qbdsBudget.addSelectionField(fieldNum(BudgetPlanDetails_WEW, ActualPromotionQty), SelectionField::Sum);
            qbdsBudget.addSelectionField(fieldNum(BudgetPlanDetails_WEW, BudgetQty), SelectionField::Sum);
            qbdsBudget.addSelectionField(fieldNum(BudgetPlanDetails_WEW, BudgetPromotionQty), SelectionField::Sum);
            qbdsBudget.addSelectionField(fieldNum(BudgetPlanDetails_WEW, RollingBudgetQty), SelectionField::Sum);
            qbdsBudget.addSelectionField(fieldNum(BudgetPlanDetails_WEW, RollingBudgetPromotionQty), SelectionField::Sum);
        }

        return new QueryRun(dataSourceQuery);
    }

    /// <summary>
    ///     Sets the page/pagination related properties based on the page move direction.
    /// </summary>
    /// <param name = "_pageDirection">The enum indicating which way we are moving in pages.</param>
    public void setPageProperties(BudgetTablePageDirection_WEW _pageDirection)
    {
        switch (_pageDirection)
        {
            case BudgetTablePageDirection_WEW::Reset:
                this.resetPageProperties();
                break;
            case BudgetTablePageDirection_WEW::NextPage:
                //this.displayDate = nextQtr(this.displayDate);
                this.displayDate = nextMth(this.displayDate);
                break;
            case BudgetTablePageDirection_WEW::PreviousPage:
                //this.displayDate = prevQtr(this.displayDate);
                this.displayDate = prevMth(this.displayDate);
                break;
            case BudgetTablePageDirection_WEW::Current:
                break;
            default:
                throw error(Error::wrongUseOfFunction(funcName()));
        }
    }

    public void resetPageProperties()
    {
        this.currentQuarter = date2Qtr(this.displayDate);
        this.currentMonth = mthOfYr(this.displayDate);
        this.currentYear = mkDate(1,1,year(this.displayDate));
    }

    private void buildQuarterPeriods()
    {
        int periodCounter = 1; 
        dateColumnMap = new Map(Types::Integer, Types::Integer);
        columnLabels = new List(Types::String);

        BIDateDimensionsView dateView;
        while select dateView
            group by dateView.Week_of_Year
            where dateView.Quarter == this.displayDate
        {
            var timeBucket = dateView.Week_Of_Year;
            dateColumnMap.insert(timeBucket, periodCounter);
            columnLabels.addEnd(strFmt("@WEW:OST00153", timebucket));
            periodCounter++;
        }
        
        //this.startWeek = this.findMinKey(dateColumnMap);
        this.columnLabels = columnLabels;
        this.dateColumnMap = dateColumnMap;
    }

    private void buildWeekPeriods(date _displayDate)
    {
        int periodCounter = 1; 
        columnLabels = new List(Types::String);
        dateColumnMap = new Map(Types::Integer, Types::Integer);

        // OST TEST
        columnLabels.addEnd("@WEW:OST00165");
        dateColumnMap.insert(0, periodCounter);
        periodCounter++;
        // OST TEST
        BIDateDimensionsView dateView;
        while select dateView
            group by dateView.Week_of_Year
            where dateView.Quarter == _displayDate
        {
            var timeBucket = dateView.Week_Of_Year;
            dateColumnMap.insert(timeBucket, periodCounter);
            columnLabels.addEnd(strFmt("@WEW:OST00153", timebucket));
            periodCounter++;
        }
        //dateColumnMap.insert(,periodCounter);
        columnLabels.addEnd("@WEW:RSC09057");
        maxColumns = dateColumnMap.elements();
        
        //this.startWeek = this.findMinKey(dateColumnMap);
        this.columnLabels = columnLabels;
        this.dateColumnMap = dateColumnMap;
    }

    private void buildPeriodsPerMonth(date _displayDate)
    {
        int periodCounter = 1; 
        date currentMth = mkDate(1, mthOfYr(_displayDate), year(_displayDate));
        columnLabels = new List(Types::String);
        dateColumnMap = new Map(Types::Integer, Types::Integer);

        columnLabels.addEnd("@WEW:OST00165");
        dateColumnMap.insert(0, periodCounter);
        periodCounter++;

        BIDateDimensionsView dateView;
        while select dateView
            group by dateView.Week_of_Year
            where (dateView.Month == currentMth
                || dateView.Month == prevYr(currentMth))
                && dateView.Day_Of_Week > 4 // TEST OST: Only counts week, if it is Thursday
            //where dateView.Month == _displayDate
            //    || dateView.Month == prevYr(_displayDate)
        {
            var timeBucket = dateView.Week_of_Year;
            dateColumnMap.insert(timeBucket, periodCounter);
            columnLabels.addEnd(strFmt("@WEW:OST00153", timeBucket));
            periodCounter++;
        }
        columnLabels.addEnd("@WEW:RSC09057");
        maxColumns = dateColumnMap.elements();

        this.columnLabels = columnLabels;
        this.dateColumnMap = dateColumnMap;
    }

    private int tableCount(QueryRun _qr)
    {
        QueryRun qr;
        Query q = new Query(_qr.query());
        int dsN = _qr.query().dataSourceCount();
        int ds;
        for (ds = 2; ds <= dsN; ++ds)
        {
            if (q.dataSourceNo(ds).joinMode() == JoinMode::OuterJoin)
                q.dataSourceNo(ds).enabled(false);
            else if (q.dataSourceNo(ds).joinMode() == JoinMode::InnerJoin)
            {
                q.dataSourceNo(ds).joinMode(JoinMode::ExistsJoin);
                q.dataSourceNo(ds).fields().clearFieldList();
            }
        }
        q.dataSourceNo(1).fields().clearFieldList();
        q.dataSourceNo(1).addSelectionField(fieldNum(Common,RecId), SelectionField::Count);
        qr = new QueryRun(q);
        qr.next();
        return any2int(qr.getNo(1).RecId);
    }

    public BudgetPlanMatrix_WEW buildMatrixGeneric(
        BudgetTablePageDirection_WEW _pageDirection = BudgetTablePageDirection_WEW::Reset,
        boolean _perCustomer = false)
    {
        // updates the date by either either going back/forward one quarter
        this.setPageProperties(_pageDirection);
        //QueryRun queryRun = this.getQueryRunForQuarter(displayDate);
        QueryRun queryRun;
        //BudgetPlanMatrix_WEW budgetMatrix;
        var cellMatrix = new Map(Types::Container, Types::Class);
        var rowLabels = new List(Types::String);
        var rowNumberMap = new Map(Types::String, Types::Integer);
        //var lineDefinitionMap = new Map(Types::Integer, Types::Class);
        var rowNumber = 0;
        real budgetSum = 0;

        // first, loop over all LineDefintions
        var lineDefinitionEnumerator = matrixLineDefinitions.getEnumerator();
        var lineDefinitionNumber = 1;

        this.buildPeriodsPerMonth(displayDate);
        while (lineDefinitionEnumerator.moveNext())
        {
            var lineDefinition = lineDefinitionEnumerator.current();
            var rowNumberMapKey = any2Str(lineDefinitionNumber);
            date dateToBeDisplayed = lineDefinition.isCurrentYear() ? displayDate : prevYr(displayDate);

            // gets query for current observation range
            queryRun = this.getQueryRunObject(dateToBeDisplayed, _perCustomer);
            int queryCount= this.tableCount(queryRun);

            // checks, if the queryRun objects contains records, otherwise create new entries for the given date range
            if(queryCount == 0 && !_perCustomer)
            {
                BudgetPlanDetails_WEW::insertEmptyRecordsForMonth(itemId, accountNum, budgetId, dateToBeDisplayed);
            }
            if (!rowNumberMap.exists(rowNumberMapKey))
            {
                rowNumber++;
                if (rowNumber > matrixLineDefinitions.elements())
                {
                    break;
                }
                rowLabels.addEnd(lineDefinition.getRowLabel(Year(dateToBeDisplayed)));
                rowNumberMap.insert(rowNumberMapKey, rowNumber);
            }

            int cellRowNumber = rowNumberMap.lookup(rowNumberMapKey);
            //lineDefinitionMap.insert(cellRowNumber, lineDefinition);
            //budgetSum = lineDefinition.getSumPerYear(itemId, accountNum, year(dateToBeDisplayed));

            // insert sum row
            if (typeOf(lineDefinition.getSumPerYear(itemId, accountNum, year(dateToBeDisplayed),_perCustomer)) == Types::Real)
            {
                this.insertOrUpdateMatrixCell(
                    cellMatrix,
                    lineDefinitionNumber,
                    this.dateColumnMap.lookup(0),
                    lineDefinition.getSumPerYear(itemId, accountNum, year(dateToBeDisplayed), _perCustomer),
                    null,
                    true
                );
            }
            else if (typeOf(lineDefinition.getSumPerYear(itemId, accountNum, year(dateToBeDisplayed), _perCustomer)) == Types::String)
            {
                this.insertOrUpdateStringCell(
                    cellMatrix,
                    lineDefinitionNumber,
                    this.dateColumnMap.lookup(0),
                    lineDefinition.getSumPerYear(itemId, accountNum, Year(dateToBeDisplayed), _perCustomer),
                    null
                    );
 
            }

            if (this.columnLabels != null && columnLabels.elements() > 0)
            {
                while (queryRun.next())
                {
                    // get current record
                    BudgetPlanDetails_WEW aggregatedBudget = queryRun.get(tableNum(BudgetPlanDetails_WEW)) as BudgetPlanDetails_WEW;
                    BIDateDimensionsView biView = queryRun.get(tableNum(BIDateDimensionsView)) as BIDateDimensionsView;

                    var tmp = lineDefinition.getCellValue(aggregatedBudget);

                    if (typeOf(lineDefinition.getCellValue(aggregatedBudget)) == Types::Real)
                    {
                        // insert new data point in the matrix cell
                        this.insertOrUpdateMatrixCell(
                            cellMatrix,
                            cellRowNumber,
                            //this.dateColumnMap.lookup(cellColKey),
                            this.dateColumnMap.lookup(biView.Week_Of_Year),
                            lineDefinition.getCellValue(aggregatedBudget),
                            aggregatedBudget.data());
                    }
                    else if (typeOf(lineDefinition.getCellValue(aggregatedBudget)) == Types::String)
                    {
                        this.insertOrUpdateStringCell(
                            cellMatrix, 
                            cellRowNumber, 
                            this.dateColumnMap.lookup(biView.Week_Of_Year),
                            lineDefinition.getCellValue(aggregatedBudget),
                            aggregatedBudget.data());
                    }
                }
            }
            else
            {
                return null;
            }
            BudgetPlanComments_WEW budgetPlanComments = BudgetPlanComments_WEW::findOrCreate(
                accountNum, 
                itemId, 
                lineDefinition.commentLine()
            );
            this.insertOrUpdateStringCell(
                cellMatrix, 
                lineDefinitionNumber, 
                maxColumns + 1, 
                budgetPlanComments.BudgetPlanComment,
                budgetPlanComments, 
                true
            );
            lineDefinitionNumber++;
        }
        BudgetPlanMatrix_WEW outputMatrix = new BudgetPlanMatrix_WEW(rowLabels, this.columnLabels, cellMatrix);
        return outputMatrix;
    }

    public BudgetPlanMatrix_WEW buildMatrix(BudgetTablePageDirection_WEW _pageDirection = BudgetTablePageDirection_WEW::Reset)
    {
        // updates the date by either either going back/forward one quarter
        this.setPageProperties(_pageDirection);
        //QueryRun queryRun = this.getQueryRunForQuarter(displayDate);
        QueryRun queryRun;
        //BudgetPlanMatrix_WEW budgetMatrix;
        var cellMatrix = new Map(Types::Container, Types::Class);
        var rowLabels = new List(Types::String);
        var rowNumberMap = new Map(Types::String, Types::Integer);
        //var lineDefinitionMap = new Map(Types::Integer, Types::Class);
        var rowNumber = 0;
        real budgetSum = 0;
        //this.buildQuarterPeriods();

        // first, loop over all LineDefintions
        var lineDefinitionEnumerator = matrixLineDefinitions.getEnumerator();
        var lineDefinitionNumber = 1;

        this.buildPeriodsPerMonth(displayDate);
        while (lineDefinitionEnumerator.moveNext())
        {
            // tst ost
            var lineDefinition = lineDefinitionEnumerator.current();
            //var lineDefinitionTst = lineDefinitionEnumerator.current() as BudgetPlanMatrixLineDefinition_WEW;
            var rowNumberMapKey = any2Str(lineDefinitionNumber);
            date dateToBeDisplayed = lineDefinition.isCurrentYear() ? displayDate : prevYr(displayDate);

            // gets query for current observation range
            queryRun = this.getQueryRunForMonth(dateToBeDisplayed);
            int queryCount= this.tableCount(queryRun);

            // checks, if the queryRun objects contains records, otherwise create new entries for the given date range
            if(queryCount == 0)
            {
                BudgetPlanDetails_WEW::insertEmptyRecordsForMonth(itemId, accountNum, budgetId, dateToBeDisplayed);
            }
            if (!rowNumberMap.exists(rowNumberMapKey))
            {
                rowNumber++;
                if (rowNumber > matrixLineDefinitions.elements())
                {
                    break;
                }
                rowLabels.addEnd(lineDefinition.getRowLabel(Year(dateToBeDisplayed)));
                rowNumberMap.insert(rowNumberMapKey, rowNumber);
            }

            int cellRowNumber = rowNumberMap.lookup(rowNumberMapKey);
            //lineDefinitionMap.insert(cellRowNumber, lineDefinition);
            //budgetSum = lineDefinition.getSumPerYear(itemId, accountNum, year(dateToBeDisplayed));

            // insert sum row
            if (typeOf(lineDefinition.getSumPerYear(itemId, accountNum, year(dateToBeDisplayed))) == Types::Real)
            {
                this.insertOrUpdateMatrixCell(
                    cellMatrix,
                    lineDefinitionNumber,
                    this.dateColumnMap.lookup(0),
                    lineDefinition.getSumPerYear(itemId, accountNum, year(dateToBeDisplayed)),
                    null,
                    true
                );
            }
            else if (typeOf(lineDefinition.getSumPerYear(itemId, accountNum, year(dateToBeDisplayed))) == Types::String)
            {
                this.insertOrUpdateStringCell(
                    cellMatrix,
                    lineDefinitionNumber,
                    this.dateColumnMap.lookup(0),
                    lineDefinition.getSumPerYear(itemId, accountNum, Year(dateToBeDisplayed)),
                    null
                    );
 
            }

            if (this.columnLabels != null && columnLabels.elements() > 0)
            {
                while (queryRun.next())
                {
                    // get current record
                    BudgetPlanDetails_WEW aggregatedBudget = queryRun.get(tableNum(BudgetPlanDetails_WEW)) as BudgetPlanDetails_WEW;

                    // retrieve week of current date
                    BIDateDimensionsView weekDate;
                    select firstonly weekDate
                        order by weekDate.Date asc
                        where weekDate.Date == aggregatedBudget.BudgetPlanDate_WEW;
                    var cellColKey = weekDate.Week_Of_Year;


                    if (typeOf(lineDefinition.getCellValue(aggregatedBudget)) == Types::Real)
                    {
                        // insert new data point in the matrix cell
                        this.insertOrUpdateMatrixCell(
                            cellMatrix,
                            cellRowNumber,
                            this.dateColumnMap.lookup(cellColKey),
                            lineDefinition.getCellValue(aggregatedBudget),
                            aggregatedBudget.data());
                    }
                    else if (typeOf(lineDefinition.getCellValue(aggregatedBudget)) == Types::String)
                    {
                        this.insertOrUpdateStringCell(
                            cellMatrix, 
                            cellRowNumber, 
                            this.dateColumnMap.lookup(cellColKey),
                            lineDefinition.getCellValue(aggregatedBudget),
                            aggregatedBudget.data());
                    }
                }
            }
            else
            {
                return null;
            }
            BudgetPlanComments_WEW budgetPlanComments = BudgetPlanComments_WEW::findOrCreate(
                accountNum, 
                itemId, 
                lineDefinition.commentLine()
            );
            this.insertOrUpdateStringCell(
                cellMatrix, 
                lineDefinitionNumber, 
                maxColumns + 1, 
                budgetPlanComments.BudgetPlanComment,
                budgetPlanComments, 
                true
            );
            lineDefinitionNumber++;
        }
        return new BudgetPlanMatrix_WEW(rowLabels, this.columnLabels, cellMatrix);
    }

        private void insertOrUpdateMatrixCell(Map _matrixCellMap, int _rowNum, int _colNum, real _cellValue, BudgetPlanDetails_WEW _aggregation, boolean _enabled = true)
        {
            _matrixCellMap.insert([_rowNum, _colNum], new BudgetPlanMatrixCell_WEW(_aggregation, _cellValue, _enabled));
        }

        private void insertOrUpdateStringCell(Map _matrixCellMap, int _rowNum, int _colNum, str _cellValue, Common _comment, boolean _enabled = true)
        {
            _matrixCellMap.insert([_rowNum, _colNum], new BudgetPlanMatrixCell_WEW(_comment, _cellValue, _enabled));
        }

        /// <summary>
        /// Indicates whether next page exists.
        /// </summary>
        /// <returns><c>true</c> if next page exists; otherwise <c>false</c></returns>
        //public boolean existsNextPage()
        //{
        //    return nextPageExists;
        //}

    // TODO: ADAPT TO REFERENCE LINE DEFINITION LIST DIRECTLY
    // TODO: check difference between SET and LIST 
    public void updateMatrixCell(
        BudgetPlanMatrix_WEW _matrix, 
        BudgetPlanDetails_WEW _aggregatedBudget, 
        int _row, 
        int _col, 
        real _newQty)
    {
        var matrixCellMap = _matrix.parmCells(); 
        var matrixCellMapEnumerator = matrixCellMap.getEnumerator();
        var lineDefinitionMap = new Map(Types::Integer, Types::Class);
        var lineDefinitionMapEnumerator = matrixLineDefinitions.getEnumerator();

        while (matrixCellMapEnumerator.moveNext())
        {
            BudgetPlanMatrixCell_WEW cell = matrixCellMapEnumerator.currentValue();
            // check if it loops over all cells and only updates the one, which matches the recId
            // remember, this happens after the new value is set
            if (cell.record().RecId == _aggregatedBudget.RecId)
            {
                //rowNum = conPeek(matrixCellMapEnumerator.currentKey(), 1);
                int rowCounter = 1;
                while (lineDefinitionMapEnumerator.moveNext()) 
                {
                    var lineDefinition = lineDefinitionMapEnumerator.current() as BudgetPlanMatrixLineDefinition_WEW;    
                    if(rowCounter == _row)
                    {
                        lineDefinition.updateSourceTable(_aggregatedBudget, _newQty);
                    }

                    lineDefinitionMap.insert(rowCounter, lineDefinition);
                    this.insertOrUpdateMatrixCell(matrixCellMap, rowCounter, _col, _newQty, _aggregatedBudget);
                    rowCounter++;
                }
                //this.updateMatrixCells(_matrix, rowNum, colNum, _aggregatedForecast, _newQty);
                break;
            }
        }
        
    }

    public void updateCommentMatrixCell(
        BudgetPlanMatrix_WEW _matrix, 
        BudgetPlanComments_WEW _comment,
        int _row, 
        int _col, 
        str _newQty)
    {
        var matrixCellMap = _matrix.parmCells(); 
        var matrixCellMapEnumerator = matrixCellMap.getEnumerator();
        var lineDefinitionMap = new Map(Types::Integer, Types::Class);
        var lineDefinitionMapEnumerator = matrixLineDefinitions.getEnumerator();

        ttsbegin;
        _comment.selectForUpdate(true);
        _comment.BudgetPlanComment = _newQty;
        _comment.update();
        ttscommit;
    }

}