Welcome, Guest. Please login or register.
Did you miss your activation email?

Author Topic: Last Group Footer being printed twice  (Read 3237 times)

LCoetzer

  • Newbie
  • *
  • Posts: 9
    • View Profile
Last Group Footer being printed twice
« on: June 13, 2017, 11:54:09 am »
Hi

The last Group footer seems to get displayed twice, but with empty values the second time.
I'm using v 1.4.14

In void ReportRender::renderDataBand(BandDesignIntf *dataBand)

The first time it gets rendered from within renderGroupHeader on line 553
The second time it gets rendered by renderGroupFooter(dataBand) on line 560

...
            renderGroupHeader(dataBand, bandDatasource, false);
            if (dataBand->tryToKeepTogether()) closeDataGroup(dataBand);
            firstTime = false;
        }

        m_reprintableBands.removeOne(dataBand->bandHeader());

        renderGroupFooter(dataBand);
...

Commenting out renderGroupFooter(dataBand); on line 560, worked for me, but I don't know if it will cause issues for other scenarios.

Regards
    Louis


Arin Alex

  • Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 1005
    • View Profile
Re: Last Group Footer being printed twice
« Reply #1 on: June 13, 2017, 01:14:10 pm »
Thanks for your message i'll check it. Could you send me a sample?
« Last Edit: June 13, 2017, 01:20:50 pm by Arin Alex »

LCoetzer

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Last Group Footer being printed twice
« Reply #2 on: June 17, 2017, 10:11:49 am »
Hi

Thank you for updating with all my changes.

I attached my report and two report pdfs, one with the line commented out and one NOT.
I cannot post a data sample because I get the data from my objects in code.
This is my code: This is prototype code to test the reporting library, so it's not necessarily the best way to do it.

void ReportManager::limeReceiver(LimeReport::CallbackInfo info, QVariant &data)
{
    switch (info.dataType)
    {
        /*//For Traversal method
        case LimeReport::CallbackInfo::DataType::IsEmpty:
        {
            data = m_dataAttributes.isEmpty();
            m_curRowIndex = 0;
            break;
        }
        case LimeReport::CallbackInfo::DataType::HasNext:
        {
            data = m_curRowIndex < (m_dataAttributes.size() - 1);
            break;
        }*/
        case LimeReport::CallbackInfo::DataType::ColumnHeaderData:
        {
            data = m_headers.at(info.index);
            break;
        }
        case LimeReport::CallbackInfo::DataType::ColumnData:
        {
            int columnIndex = m_headers.indexOf(info.columnName);

            /*//For Traversal method
            if (m_curRowIndex < m_dataAttributes.size())
            {
                //Attribute * attribute = m_dataAttributes.at(m_curRowIndex).at(columnIndex); //Traversal method
                QVariant attribute = m_dataAttributes.at(m_curRowIndex).at(columnIndex); //Traversal method
                //if (attribute != nullptr)
                    data = attribute->getValueString();
            }*/

            //Specify row count method
            if ((columnIndex >= 0) && (info.index >= 0) && (info.index < m_dataAttributes.size()))
                data = m_dataAttributes.at(info.index).at(columnIndex);
            break;
        }
        case LimeReport::CallbackInfo::DataType::ColumnCount:
        {
            data = m_headers.size();
            break;
        }
        //For row count method
        case LimeReport::CallbackInfo::DataType::RowCount:
        {
            data = m_dataAttributes.size();
            break;
        }
        default: break;
    }
}

//For Traversal method
void ReportManager::limeTransversal(const LimeReport::CallbackInfo::ChangePosType &type, bool &result)
{
    switch (type)
    {
        case LimeReport::CallbackInfo::ChangePosType::First:
        {
            m_curRowIndex = 0;
            if (m_dataAttributes.size() > 0)
            {
                result = true;
            }
            else
                result = false;

            break;
        }
        case LimeReport::CallbackInfo::ChangePosType::Next:
        {
            m_curRowIndex++;
            if (m_curRowIndex < (m_dataAttributes.size()))
            {
                result = true;
            }
            else
            {
                //m_curRowIndex--;
                result = false;
            }

            break;
        }
    }
}

bool ReportManager::printTestReport_LimeReport(bool pdf)
{
    bool success = false;
    LimeReport::ReportEngine *limeReport = new LimeReport::ReportEngine(this);

//Load Template
    QString fileName = ":/Reports/VehicleRefueling_LimeReport.lrxml";

    //Connect signals
    LimeReport::ICallbackDatasource *limeDataCallback = limeReport->dataManager()->createCallbackDatasource(QString("limeData"));
    connect(limeDataCallback, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)), this, SLOT(limeReceiver(LimeReport::CallbackInfo,QVariant&)));
    //connect(limeDataCallback, SIGNAL(changePos(LimeReport::CallbackInfo::ChangePosType,bool&)), this, SLOT(limeTransversal(LimeReport::CallbackInfo::ChangePosType,bool&)));

    //Get Data
    loadData();
    limeReport->loadFromFile(fileName);

    //Print
    QString pdfFileName = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first() + QString("/LimeReport_Report.pdf");
    if (pdf)
    {
        success = limeReport->printToPDF(pdfFileName);
        QDesktopServices::openUrl(QUrl(pdfFileName));
    }
    else
        success = limeReport->printReport();


    //Disconnect Signals
    disconnect(limeDataCallback, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)), this, SLOT(limeReceiver(LimeReport::CallbackInfo,QVariant&)));
    //disconnect(limeDataCallback, SIGNAL(changePos(LimeReport::CallbackInfo::ChangePosType,bool&)), this, SLOT(limeTransversal(LimeReport::CallbackInfo::ChangePosType,bool&)));
    //delete limeDataCallback; Don't delete it here. The library allready deletes it in it's destructor

//Clean up and return
    delete limeReport;
    return success;
}

void ReportManager::loadData()
{
    Kind *fuelLogKind = KindManager::getSingleton()->get(QString("Fuel Log"));
    QList<Thing*> *fuelLogs = fuelLogKind->getThings();

    //Sort it
    struct {
        bool operator()(Thing* a, Thing* b) const
        {
            Thing *vehicleA = a->getAttribute("Vehicle")->getValueThing();
            Thing *vehicleB = b->getAttribute("Vehicle")->getValueThing();
            int comparisonResult = vehicleA->getValueDisplayString("Name").compare(vehicleB->getValueDisplayString("Name"));
            if (comparisonResult < 0)
                return true;
            else if (comparisonResult > 0)
                return false;
            else
            {
                QDateTime dateTimeA = a->getAttribute("Date Time")->getValueTimestamp();
                QDateTime dateTimeB = b->getAttribute("Date Time")->getValueTimestamp();
                return dateTimeA < dateTimeB;
            }
        }
    } customLess;
    std::sort(fuelLogs->begin(), fuelLogs->end(), customLess);

    m_curRowIndex = -1;
    m_headers.clear();
    m_headers << "vehicleName" << "Month" << "Amount" << "Cost" << "Economy" << "vehicleEconomy";

    m_dataAttributes.clear();
    int count = 0;
    int index = 0;
    QDecNumber prevOdometer;
    int vehicleLogCount = 0;
    QDecNumber vehicleEconomy = 0;
    int vehicleLogStart = 0;
    foreach (Thing* aThing, (*fuelLogs))
    {
        count++;
        QList<QVariant> record;

        Thing *vehicle = aThing->getAttribute("Vehicle")->getValueThing();
        record.append(vehicle->getValueDisplayString("Name"));
        if ((count > 1) && (m_dataAttributes.at(index - 1).at(0).toString().compare((record.at(0).toString())) != 0))
            count = 1;

        record.append(aThing->getValueDisplayString("Date Time"));
        record.append(aThing->getValueDisplayString("Quantity"));
        record.append(aThing->getValueDisplayString("Amount"));

        //Append economy
        QDecNumber distanceTravelled;
        if (count == 1)
        {
            record.append(QVariant());//aThing->getAttribute("Economy"));
            if (index > 0) //If just finished a vehicle
            {
                //Set the vehicle average economy for the previous vehicle
                if (vehicleLogCount > 0)
                {
                    QVariant newValue = QVariant(QString((vehicleEconomy / vehicleLogCount).toString()));
                    for (int i = vehicleLogStart; i < index; i++)
                    {
                        QList<QVariant> prevRecord = m_dataAttributes.at(i);
                        prevRecord.replace(5, newValue);
                        m_dataAttributes.replace(i, prevRecord);
                    }
                }
            }
            vehicleLogCount = 0;
            vehicleEconomy = 0;
            vehicleLogStart = index;
        }
        else
        {
            distanceTravelled = aThing->getAttribute("Odometer")->getValueDecimal() - prevOdometer;
            QString refuelType = aThing->getValueDisplayString("Refuel Type");
            if (refuelType.compare("Full") == 0)
            {
                QDecNumber economy = distanceTravelled / aThing->getAttribute("Quantity")->getValueDecimal();
                if (economy != QDecNumber(0))
                {
                    vehicleLogCount++;
                    vehicleEconomy += economy;
                }

                record.append(QVariant(QString(economy.toString()))); //QVariant::fromValue(getValueDecimal());
            }
            else if (refuelType.compare("Partial with Fuel Level"))
            {
                record.append(QVariant());//aThing->getAttribute("Economy"));
            }
            else
            {
                record.append(QVariant());//aThing->getAttribute("Economy"));
            }
        }
        record.append(QVariant());//vehicleEconomy;

        m_dataAttributes.append(record);

        prevOdometer = aThing->getAttribute("Odometer")->getValueDecimal();
        index++;
    }

    //Set the vehicle average economy for the last vehicle
    if (vehicleLogCount > 0)
    {
        QVariant newValue = QVariant(QString((vehicleEconomy / vehicleLogCount).toString()));
        for (int i = vehicleLogStart; i < index; i++)
        {
            QList<QVariant> prevRecord = m_dataAttributes.at(i);
            prevRecord.replace(5, newValue);
            m_dataAttributes.replace(i, prevRecord);
        }
    }
}



Thanks and Regards
    Louis Coetzer

Arin Alex

  • Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 1005
    • View Profile
Re: Last Group Footer being printed twice
« Reply #3 on: June 23, 2017, 09:19:56 am »
This issue also has been fixed in (ver 1.4.19)