/***************************************************************************
 *   Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>  *
 ***************************************************************************/
/** @file
 * This file is Skrooge plugin for operation management.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgoperationplugin.h"
#include "skgoperationpluginwidget.h"
#include "skgoperationboardwidget.h"
#include "skgbookmarkboardwidget.h"
#include "skgtraces.h"
#include "skgoperationobject.h"
#include "skgaccountobject.h"
#include "skgtrackerobject.h"
#include "skgbudgetobject.h"
#include "skgsuboperationobject.h"
#include "skgrecurrentoperationobject.h"
#include "skgcategoryobject.h"
#include "skgpayeeobject.h"
#include "skgtransactionmng.h"
#include "skgmainpanel.h"
#include "skgtableview.h"
#include "skgruleobject.h"
#include "skgoperation_settings.h"
#include "skgdocumentbank.h"

#include <kactioncollection.h>
#include <kstandardaction.h>
#include <kaboutdata.h>

#include <QDomDocument>

/**
 * This plugin factory.
 */
K_PLUGIN_FACTORY(SKGOperationPluginFactory, registerPlugin<SKGOperationPlugin>();)
/**
 * This plugin export.
 */
K_EXPORT_PLUGIN(SKGOperationPluginFactory("skrooge_operation", "skrooge_operation"))

SKGOperationPlugin::SKGOperationPlugin(QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent)
{
    SKGTRACEIN(10, "SKGOperationPlugin::SKGOperationPlugin");
}

SKGOperationPlugin::~SKGOperationPlugin()
{
    SKGTRACEIN(10, "SKGOperationPlugin::~SKGOperationPlugin");
    m_currentBankDocument = NULL;
    m_duplicateAction = NULL;
    m_switchToPointedAction = NULL;
    m_openHighLights = NULL;
    m_openLastModified = NULL;
    m_groupOperation = NULL;
    m_ungroupOperation = NULL;
    m_createTemplateAction = NULL;
    m_openSuboperations = NULL;
    m_openDuplicate = NULL;
    m_mergeOperationAction = NULL;
    m_open = NULL;
}

bool SKGOperationPlugin::setupActions(SKGDocument* iDocument, const QStringList& iArgument)
{
    SKGTRACEIN(10, "SKGOperationPlugin::setupActions");
    Q_UNUSED(iArgument);
    m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
    if (m_currentBankDocument == NULL) return false;

    m_currentBankDocument->setComputeBalances(skgoperation_settings::computeBalances());

    setComponentData(KGlobal::mainComponent());
    setXMLFile("../skrooge_operation/skrooge_operation.rc");

    //Menu
    //------------
    m_duplicateAction = new KAction(KIcon("skrooge_duplicate"), i18nc("Verb, duplicate an object",  "Duplicate"), this);
    connect(m_duplicateAction, SIGNAL(triggered(bool)), this, SLOT(actionDuplicate()));
    actionCollection()->addAction(QLatin1String("edit_duplicate_operation"), m_duplicateAction);
    m_duplicateAction->setShortcut(Qt::CTRL + Qt::Key_D);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("edit_duplicate_operation", m_duplicateAction);

    //------------
    m_createTemplateAction = new KAction(KIcon("skrooge_template"), i18nc("Verb", "Create template"), this);
    connect(m_createTemplateAction, SIGNAL(triggered(bool)), this, SLOT(actionCreateTemplate()));
    actionCollection()->addAction(QLatin1String("edit_template_operation"), m_createTemplateAction);
    m_createTemplateAction->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_T);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("edit_template_operation", m_createTemplateAction);

    //------------
    m_switchToPointedAction = new KAction(KIcon("dialog-ok"), i18nc("Verb, mark an object", "Point"), this);
    connect(m_switchToPointedAction, SIGNAL(triggered(bool)), this, SLOT(actionSwitchToPointed()));
    actionCollection()->addAction(QLatin1String("edit_point_selected_operation"), m_switchToPointedAction);
    m_switchToPointedAction->setShortcut(Qt::CTRL + Qt::Key_R);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("edit_point_selected_operation", m_switchToPointedAction);

    //------------
    KAction* fastEditionAction = new KAction(KIcon("games-solve"), i18nc("Verb", "Fast edit"), this);
    actionCollection()->addAction(QLatin1String("fast_edition"), fastEditionAction);
    fastEditionAction->setEnabled(false);
    fastEditionAction->setShortcut(Qt::Key_F10);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("fast_edition", fastEditionAction);

    //------------
    QStringList overlayopen;
    overlayopen.push_back("skg_open");
    m_open = new KAction(KIcon(icon(), NULL, overlayopen), i18nc("Verb", "Open operations..."), this);
    connect(m_open, SIGNAL(triggered(bool)), this, SLOT(actionOpenOperations()));
    actionCollection()->addAction(QLatin1String("open"), m_open);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("open", m_open);

    m_openHighLights = new KAction(KIcon("bookmarks", NULL, overlayopen), i18nc("Verb", "Open highlights..."), this);
    connect(m_openHighLights, SIGNAL(triggered(bool)), this, SLOT(actionOpenHighLights()));
    actionCollection()->addAction(QLatin1String("view_open_highlight"), m_openHighLights);
    m_openHighLights->setShortcut(Qt::META + Qt::Key_H);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("view_open_highlight", m_openHighLights);

    //------------
    m_openLastModified = new KAction(KIcon("view-refresh", NULL, overlayopen), i18nc("Verb", "Open last modified..."), this);
    connect(m_openLastModified, SIGNAL(triggered(bool)), this, SLOT(actionOpenLastModified()));
    actionCollection()->addAction(QLatin1String("view_open_last_modified"), m_openLastModified);
    m_openLastModified->setShortcut(Qt::META + Qt::Key_L);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("view_open_last_modified", m_openLastModified);

    //------------
    m_openSuboperations = new KAction(KIcon("split", NULL, overlayopen), i18nc("Verb", "Open sub operations..."), this);
    connect(m_openSuboperations, SIGNAL(triggered(bool)), this, SLOT(actionOpenSubOperations()));
    actionCollection()->addAction(QLatin1String("view_open_suboperations"), m_openSuboperations);
    m_openSuboperations->setShortcut(Qt::META + Qt::Key_S);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("view_open_suboperations", m_openSuboperations);

    //------------
    m_openDuplicate = new KAction(KIcon("skrooge_duplicate", NULL, overlayopen), i18nc("Verb", "Open potential duplicates..."), this);
    connect(m_openDuplicate, SIGNAL(triggered(bool)), this, SLOT(actionOpenDuplicate()));
    actionCollection()->addAction(QLatin1String("view_open_duplicates"), m_openDuplicate);
    m_openDuplicate->setShortcut(Qt::META + Qt::Key_D);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("view_open_duplicates", m_openDuplicate);

    //------------
    m_groupOperation = new KAction(KIcon("view-financial-transfer"), i18nc("Verb", "Group operations"), this);
    connect(m_groupOperation, SIGNAL(triggered(bool)), this, SLOT(actionGroupOperation()));
    actionCollection()->addAction(QLatin1String("edit_group_operation"), m_groupOperation);
    m_groupOperation->setShortcut(Qt::CTRL + Qt::Key_G);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("edit_group_operation", m_groupOperation);

    //------------
    QStringList overlay;
    overlay.push_back("edit-delete");
    m_ungroupOperation = new KAction(KIcon("view-financial-transfer", NULL, overlay), i18nc("Verb", "Ungroup operations"), this);
    connect(m_ungroupOperation, SIGNAL(triggered(bool)), this, SLOT(actionUngroupOperation()));
    actionCollection()->addAction(QLatin1String("edit_ungroup_operation"), m_ungroupOperation);
    m_ungroupOperation->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_G);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("edit_ungroup_operation", m_ungroupOperation);

    //------------
    m_mergeOperationAction = new KAction(KIcon("split"), i18nc("Verb, action to merge", "Merge sub operations"), this);
    connect(m_mergeOperationAction, SIGNAL(triggered(bool)), SLOT(actionMergeSubOperations()));
    actionCollection()->addAction(QLatin1String("merge_sub_operations"), m_mergeOperationAction);
    m_mergeOperationAction->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_M);

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("merge_sub_operations", m_mergeOperationAction);
    return true;
}

void SKGOperationPlugin::refresh()
{
    SKGTRACEIN(10, "SKGOperationPlugin::refresh");
    if (m_currentBankDocument && SKGMainPanel::getMainPanel()) {
        bool test = (m_currentBankDocument->getDatabase() != NULL);
        if (m_openHighLights) m_openHighLights->setEnabled(test);
        if (m_openSuboperations) m_openSuboperations->setEnabled(test);
        if (m_openDuplicate) m_openDuplicate->setEnabled(test);
        if (m_openLastModified) m_openLastModified->setEnabled(test && m_currentBankDocument->getNbTransaction() > 0);

        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
        int nb = selection.count();
        if (m_open) m_open->setEnabled(nb > 0);
        if (nb > 0) {
            bool onOperation = (selection.at(0).getRealTable() == "operation" &&  selection.at(0).getTable() != "v_operation_consolidated");
            if (m_duplicateAction) m_duplicateAction->setEnabled(onOperation);
            if (m_createTemplateAction) m_createTemplateAction->setEnabled(onOperation);
            if (m_switchToPointedAction) m_switchToPointedAction->setEnabled(onOperation);
            if (m_groupOperation) m_groupOperation->setEnabled(onOperation && selection.count() >= 2);
            if (m_ungroupOperation) m_ungroupOperation->setEnabled(onOperation);
            if (m_mergeOperationAction) m_mergeOperationAction->setEnabled(onOperation);
        } else {
            if (m_duplicateAction) m_duplicateAction->setEnabled(false);
            if (m_createTemplateAction) m_createTemplateAction->setEnabled(false);
            if (m_switchToPointedAction) m_switchToPointedAction->setEnabled(false);
            if (m_groupOperation) m_groupOperation->setEnabled(false);
            if (m_ungroupOperation) m_ungroupOperation->setEnabled(false);
            if (m_mergeOperationAction) m_mergeOperationAction->setEnabled(false);
        }
    }
}

int SKGOperationPlugin::getNbDashboardWidgets()
{
    return 2;
}

QString SKGOperationPlugin::getDashboardWidgetTitle(int iIndex)
{
    if (iIndex == 0) return i18nc("Noun, the title of a section", "Income && Expenditure");
    else if (iIndex == 1) return i18nc("Noun, the title of a section", "Highlighted operations");
    return "";
}

SKGWidget* SKGOperationPlugin::getDashboardWidget(int iIndex)
{
    if (iIndex == 0) return new SKGOperationBoardWidget(m_currentBankDocument);
    else if (iIndex == 1) return new SKGBookmarkBoardWidget(m_currentBankDocument);
    return NULL;
}

SKGTabPage* SKGOperationPlugin::getWidget()
{
    SKGTRACEIN(10, "SKGOperationPlugin::getWidget");
    return new SKGOperationPluginWidget(m_currentBankDocument);
}

QWidget* SKGOperationPlugin::getPreferenceWidget()
{
    SKGTRACEIN(10, "SKGOperationPlugin::getPreferenceWidget");
    QWidget* widget = new QWidget();
    ui.setupUi(widget);
    return widget;
}

KConfigSkeleton* SKGOperationPlugin::getPreferenceSkeleton()
{
    return skgoperation_settings::self();
}

SKGError SKGOperationPlugin::savePreferences() const
{
    m_currentBankDocument->setComputeBalances(skgoperation_settings::computeBalances());
    return SKGInterfacePlugin::savePreferences();
}

QString SKGOperationPlugin::title() const
{
    return i18nc("Noun", "Operations");
}

QString SKGOperationPlugin::icon() const
{
    return "view-financial-list";
}

QString SKGOperationPlugin::toolTip() const
{
    return i18nc("Noun", "Operation management");
}

int SKGOperationPlugin::getOrder() const
{
    return 15;
}

QStringList SKGOperationPlugin::tips() const
{
    QStringList output;
    output.push_back(i18nc("Description of a tips", "<p>... you can press <strong>+</strong>, <strong>-</strong>, <strong>CTRL +</strong> or <strong>CTRL -</strong> to quickly change dates.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can update many operations in one shot.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can double click on an operation to show or edit sub operations.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can duplicate an operation including complex operations (split, grouped, ...).</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can create template of operations.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can group and ungroup operations.</p>"));
    return output;
}

bool SKGOperationPlugin::isInPagesChooser() const
{
    return true;
}

void SKGOperationPlugin::actionGroupOperation()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGOperationPlugin::actionGroupOperation", err);
    //Get Selection
    if (SKGMainPanel::getMainPanel() && m_currentBankDocument) {
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
        int nb = selection.count();
        if (nb >= 2) {
            SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Group operations"), err, nb);
            SKGOperationObject main = selection.at(0);
            if (!err) err = m_currentBankDocument->stepForward(1);
            for (int i = 1; !err && i < nb; ++i) {
                SKGOperationObject operationObj = selection.at(i);
                if (!err) err = operationObj.setGroupOperation(main);
                if (!err) err = operationObj.save();

                if (!err) err = m_currentBankDocument->stepForward(i + 1);
            }
        }

        //status bar
        if (!err) err = SKGError(0, i18nc("Successful message after an user action", "Operations grouped."));
        else err.addError(ERR_FAIL, i18nc("Error message",  "Group creation failed"));

        //Display error
        SKGMainPanel::displayErrorMessage(err);
    }
}

void SKGOperationPlugin::actionUngroupOperation()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGOperationPlugin::actionUngroupOperation", err);
    //Get Selection
    if (SKGMainPanel::getMainPanel() && m_currentBankDocument) {
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
        int nb = selection.count();
        {
            SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Ungroup operation"), err, nb);
            for (int i = 0; !err && i < nb; ++i) {
                SKGOperationObject operationObj = selection.at(i);
                if (!err) err = operationObj.setGroupOperation(operationObj);
                if (!err) err = operationObj.save();

                if (!err) err = m_currentBankDocument->stepForward(i + 1);
            }
        }

        //status bar
        if (!err) err = SKGError(0, i18nc("Successful message after an user action", "Operation ungrouped."));
        else err.addError(ERR_FAIL, i18nc("Error message",  "Group deletion failed"));

        //Display error
        SKGMainPanel::displayErrorMessage(err);
    }
}

void SKGOperationPlugin::actionSwitchToPointed()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGOperationPlugin::actionSwitchToPointed", err);
    //Get Selection
    if (SKGMainPanel::getMainPanel() && m_currentBankDocument) {
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
        int nb = selection.count();
        {
            SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Switch to pointed"), err, nb);
            for (int i = 0; !err && i < nb; ++i) {
                SKGOperationObject operationObj = selection.at(i);
                if (!err) err = operationObj.setStatus(operationObj.getStatus() != SKGOperationObject::POINTED ? SKGOperationObject::POINTED : SKGOperationObject::NONE);
                if (!err) err = operationObj.save();

                if (!err) err = m_currentBankDocument->stepForward(i + 1);
            }
        }

        //status bar
        if (!err) err = SKGError(0, i18nc("Successful message after an user action", "Operation pointed."));
        else err.addError(ERR_FAIL, i18nc("Error message",  "Switch failed"));

        //Display error
        SKGMainPanel::displayErrorMessage(err);
    }
}

void SKGOperationPlugin::actionDuplicate()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGOperationPlugin::actionDuplicate", err);
    //Get Selection
    if (SKGMainPanel::getMainPanel() && m_currentBankDocument) {
        QStringList listUUID;
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
        int nb = selection.count();
        {
            SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Duplicate operation"), err, nb);
            for (int i = 0; !err && i < nb; ++i) {
                SKGOperationObject operationObj = selection.at(i);
                SKGOperationObject dup;
                if (!err) err = operationObj.duplicate(dup);
                if (!err) err = m_currentBankDocument->stepForward(i + 1);

                listUUID.push_back(dup.getUniqueID());
            }
        }

        //status bar
        if (!err) {
            err = SKGError(0, i18nc("Successful message after an user action", "Operation duplicated."));
            SKGOperationPluginWidget* w = qobject_cast<SKGOperationPluginWidget*>(SKGMainPanel::getMainPanel()->currentPage());
            if (w) w->getTableView()->selectObjects(listUUID, true);
        } else err.addError(ERR_FAIL, i18nc("Error message",  "Duplicate operation failed"));

        //Display error
        SKGMainPanel::displayErrorMessage(err);
    }
}

void SKGOperationPlugin::actionCreateTemplate()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGOperationPlugin::actionCreateTemplate", err);
    //Get Selection
    if (SKGMainPanel::getMainPanel() && m_currentBankDocument) {
        QStringList listUUID;
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
        int nb = selection.count();
        {
            SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Create template"), err, nb);
            for (int i = 0; !err && i < nb; ++i) {
                SKGOperationObject operationObj = selection.at(i);
                SKGOperationObject dup;
                if (!err) err = operationObj.duplicate(dup , QDate::currentDate(), true);
                if (!err) err = m_currentBankDocument->stepForward(i + 1);

                listUUID.push_back(dup.getUniqueID());
            }
        }

        //status bar
        if (!err) {
            err = SKGError(0, i18nc("Successful message after an user action", "Template created."));
            SKGOperationPluginWidget* w = qobject_cast<SKGOperationPluginWidget*>(SKGMainPanel::getMainPanel()->currentPage());
            if (w) {
                w->setTemplateMode(true);
                w->getTableView()->selectObjects(listUUID, true);
            }
        } else err.addError(ERR_FAIL, i18nc("Error message",  "Creation template failed"));

        //Display error
        SKGMainPanel::displayErrorMessage(err);
    }
}

void SKGOperationPlugin::actionOpenHighLights()
{
    openHighLights();
}

void SKGOperationPlugin::actionOpenOperations()
{
    SKGTRACEIN(10, "SKGBankPluginWidget::onDoubleClickedAccount");
    if (SKGMainPanel::getMainPanel()) {
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();

        int nb = selection.count();
        if (nb > 0) {
            QString wc;
            QString title;
            QString icon;
            QString table = selection.at(0).getRealTable();
            QString view;
            QString account;
            if (table == "account") {
                if (nb == 1) {
                    SKGAccountObject tmp = selection.at(0);
                    account = tmp.getName();
                } else {
                    //Build whereclause and title
                    wc = "rd_account_id in (";
                    title = i18nc("Noun, a list of items", "Operations of account:");

                    for (int i = 0; i < nb; ++i) {
                        SKGAccountObject tmp = selection.at(i);
                        if (i) {
                            wc += ',';
                            title += ',';
                        }
                        wc += SKGServices::intToString(tmp.getID());
                        title += i18n("'%1'", tmp.getDisplayName());
                    }
                    wc += ')';
                    //Set icon
                    icon = "view-bank-account";
                }
            } else if (table == "unit") {
                //Build whereclause and title
                wc = "rc_unit_id in (";
                title = i18nc("Noun, a list of items", "Operations with unit:");

                for (int i = 0; i < nb; ++i) {
                    SKGUnitObject tmp = selection.at(i);
                    if (i) {
                        wc += ',';
                        title += ',';
                    }
                    wc += SKGServices::intToString(tmp.getID());
                    title += i18n("'%1'", tmp.getDisplayName());
                }
                wc += ')';

                //Set icon
                icon = "view-currency-list";
            } else if (table == "category") {
                title = i18nc("Noun, a list of items", "Sub operations with category:");

                for (int i = 0; i < nb; ++i) {
                    SKGCategoryObject tmp = selection.at(i);
                    if (i) {
                        wc += " OR ";
                        title += ',';
                    }

                    QString name = tmp.getFullName();

                    wc += "(t_REALCATEGORY";
                    if (name.isEmpty()) wc += " IS NULL OR t_REALCATEGORY='')";
                    else wc += " = '" % SKGServices::stringToSqlString(name) % "' OR t_REALCATEGORY like '" % SKGServices::stringToSqlString(name) % OBJECTSEPARATOR % "%')";

                    title += i18n("'%1'", tmp.getDisplayName());
                }

                //Set icon
                icon = "skrooge_category";
                view = "v_operation_consolidated";
            } else if (table == "refund") {
                //Build whereclause and title
                wc = "t_REALREFUND in (";
                title = i18nc("Noun, a list of items", "Sub operations followed by tracker:");

                for (int i = 0; i < nb; ++i) {
                    SKGTrackerObject tmp = selection.at(i);
                    if (i) {
                        wc += ',';
                        title += ',';
                    }
                    wc += '\'' % SKGServices::stringToSqlString(tmp.getName()) % '\'';
                    title += i18n("'%1'", tmp.getDisplayName());
                }
                wc += ')';

                //Set icon
                icon = "skrooge_tracker";
                view = "v_operation_consolidated";
            } else if (table == "payee") {
                //Build whereclause and title
                wc = "r_payee_id in (";
                title = i18nc("Noun, a list of items", "Operations assigned to payee:");

                for (int i = 0; i < nb; ++i) {
                    SKGPayeeObject tmp = selection.at(i);
                    if (i) {
                        wc += ',';
                        title += ',';
                    }
                    wc += SKGServices::intToString(tmp.getID());
                    title += i18n("'%1'", tmp.getDisplayName());
                }
                wc += ')';

                //Set icon
                icon = "skrooge_payee";
            } else if (table == "budget") {
                title = i18nc("Noun, a list of items", "Operations assigned to budget:");

                for (int i = 0; i < nb; ++i) {
                    SKGBudgetObject tmp = selection.at(i);
                    if (i) {
                        wc += " OR ";
                        title += ',';
                    }

                    QString y = SKGServices::intToString(tmp.getYear());
                    QString m = SKGServices::intToString(tmp.getMonth());
                    if (m.length() == 1) m = '0' % m;

                    wc += "(i_IDCATEGORY IN (SELECT bc.id_category FROM budgetcategory bc WHERE bc.id=" % SKGServices::intToString(tmp.getID()) % ") AND "
                          "STRFTIME('%Y', d_date)='" % y % '\'';
                    if (m != "00") wc += " AND STRFTIME('%m', d_date)='" % m % '\'';
                    wc += ')';
                    title += i18n("'%1'", tmp.getDisplayName());
                }

                //Set icon
                icon = "view-income-categories";
                view = "v_operation_consolidated";
            } else if (table == "recurrentoperation") {
                title = i18nc("Noun, a list of items", "Scheduled operations:");

                for (int i = 0; i < nb; ++i) {
                    SKGRecurrentOperationObject tmp = selection.at(i);
                    if (i) {
                        wc += " OR ";
                        title += ',';
                    }

                    wc += "(EXISTS(SELECT 1 FROM recurrentoperation s WHERE s.rd_operation_id=v_operation_display.id and s.id=" % SKGServices::intToString(tmp.getID()) % ") OR r_recurrentoperation_id=" % SKGServices::intToString(tmp.getID()) + ')';
                    title += i18n("'%1'", tmp.getDisplayName());
                }

                //Set icon
                icon = "chronometer";
                view = "v_operation_display";
            } else if (table == "rule") {
                title = i18nc("Noun, a list of items", "Sub operations corresponding to rule:");

                for (int i = 0; i < nb; ++i) {
                    SKGRuleObject tmp = selection.at(i);
                    if (i) {
                        wc += " OR ";
                        title += ',';
                    }

                    wc += "i_SUBOPID in (SELECT i_SUBOPID FROM v_operation_prop WHERE " % tmp.getSelectSqlOrder() % ')';
                    title += i18n("'%1'", tmp.getDisplayName());
                }

                //Set icon
                icon = "edit-find";
                view = "v_operation_consolidated";
            } else if (table == "operation") {
                //Build whereclause and title
                if (selection.at(0).getTable() != "v_operation_consolidated") {
                    title = i18nc("Noun, a list of items", "Sub operations grouped or split of:");
                    view = "v_operation_consolidated";
                } else {
                    title = i18nc("Noun, a list of items", "Operations grouped with:");
                    view = "v_operation_display_all";
                }

                for (int i = 0; i < nb; ++i) {
                    SKGOperationObject tmp = selection.at(i);
                    if (i) {
                        wc += ',';
                        title += ',';
                    }

                    int opid = tmp.getID();
                    wc += "(id=" % SKGServices::intToString(opid);

                    opid = SKGServices::stringToInt(tmp.getAttribute("i_group_id"));
                    if (opid != 0) wc += " or i_group_id=" % SKGServices::intToString(opid);
                    wc += ')';

                    title += i18n("'%1'", tmp.getDisplayName());
                }

                //Set icon
                icon = "view-financial-list";
            }

            //Open
            if (QApplication::keyboardModifiers() &Qt::ControlModifier && QApplication::keyboardModifiers() &Qt::ShiftModifier) {
                //Call debug plugin
                QDomDocument doc("SKGML");
                QDomElement root = doc.createElement("parameters");
                doc.appendChild(root);
                root.setAttribute("sqlOrder", "SELECT * from " % (view.isEmpty() ? "v_operation_display" : view) % " WHERE " % wc);

                SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Debug plugin"), -1, doc.toString());
            } else {
                QDomDocument doc("SKGML");
                doc.setContent(SKGMainPanel::getMainPanel()->getDocument()->getParameter(view != "v_operation_consolidated" ? "SKGOPERATION_DEFAULT_PARAMETERS" : "SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS"));
                QDomElement root = doc.documentElement();
                if (root.isNull()) {
                    root = doc.createElement("parameters");
                    doc.appendChild(root);
                }

                if (!view.isEmpty()) root.setAttribute("operationTable", view);
                if (!wc.isEmpty()) root.setAttribute("operationWhereClause", wc);
                if (!title.isEmpty()) root.setAttribute("title", title);
                if (!icon.isEmpty()) root.setAttribute("title_icon", icon);
                if (!account.isEmpty()) root.setAttribute("account", account);
                else root.setAttribute("currentPage", "-1");

                SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
            }
        }
    }
}

void SKGOperationPlugin::openHighLights()
{
    SKGTRACEIN(10, "SKGOperationPlugin::openHighLights");
    QString wc = "t_bookmarked='Y'";
    QString title = i18nc("Noun, a list of items", "Highlighted operations");


    //Call operation plugin
    QDomDocument doc("SKGML");
    doc.setContent(SKGMainPanel::getMainPanel()->getDocument()->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
    QDomElement root = doc.documentElement();
    if (root.isNull()) {
        root = doc.createElement("parameters");
        doc.appendChild(root);
    }

    root.setAttribute("operationWhereClause", wc);
    root.setAttribute("title", title);
    root.setAttribute("title_icon", "bookmarks");

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
}

void SKGOperationPlugin::actionOpenDuplicate()
{
    SKGTRACEIN(10, "SKGOperationPlugin::actionOpenDuplicate");
    QString wc = "id in (SELECT o1.id FROM v_operation o1 WHERE EXISTS (SELECT 1 FROM v_operation o2 WHERE o1.id<>o2.id AND o1.t_template='N' AND o2.t_template='N' AND o1.d_date=o2.d_date  AND o1.f_CURRENTAMOUNT=o2.f_CURRENTAMOUNT AND o1.rd_account_id=o2.rd_account_id AND o1.rc_unit_id=o2.rc_unit_id AND (o1.t_status='N' OR o2.t_status='N')))";
    QString title = i18nc("Noun, a list of items", "Operations potentially duplicated");

    //Call operation plugin
    QDomDocument doc("SKGML");
    if (m_currentBankDocument) doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
    QDomElement root = doc.documentElement();
    if (root.isNull()) {
        root = doc.createElement("parameters");
        doc.appendChild(root);
    }

    root.setAttribute("operationWhereClause", wc);
    root.setAttribute("title", title);
    root.setAttribute("title_icon", "skrooge_duplicate");

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
}

void SKGOperationPlugin::actionOpenLastModified()
{
    SKGTRACEIN(10, "SKGOperationPlugin::actionOpenLastModified");
    QString wc = "id in (SELECT i_object_id FROM doctransactionitem di, doctransaction dt WHERE dt.t_mode='U' AND dt.id=di.rd_doctransaction_id AND di.t_object_table='operation'AND NOT EXISTS(select 1 from doctransaction B where B.i_parent=dt.id))";
    QString title = i18nc("Noun, a list of items", "Operations modified or created during last action");

    //Call operation plugin
    QDomDocument doc("SKGML");
    if (m_currentBankDocument) doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
    QDomElement root = doc.documentElement();
    if (root.isNull()) {
        root = doc.createElement("parameters");
        doc.appendChild(root);
    }

    root.setAttribute("operationWhereClause", wc);
    root.setAttribute("title", title);
    root.setAttribute("title_icon", "view-refresh");

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
}

void SKGOperationPlugin::actionOpenSubOperations()
{
    SKGTRACEIN(10, "SKGOperationPlugin::actionOpenSubOperations");
    //Call operation plugin
    QDomDocument doc("SKGML");
    if (m_currentBankDocument) doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS"));
    QDomElement root = doc.documentElement();
    if (root.isNull()) {
        root = doc.createElement("parameters");
        doc.appendChild(root);
    }

    root.setAttribute("operationTable", "v_operation_consolidated");
    root.setAttribute("operationWhereClause", "");
    root.setAttribute("title", i18nc("Noun, a list of items", "Sub operations"));
    root.setAttribute("title_icon", "split");

    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
}

SKGAdviceList SKGOperationPlugin::advices() const
{
    SKGTRACEIN(10, "SKGOperationPlugin::advices");
    SKGAdviceList output;

    //Search duplicate number on operation
    SKGStringListList result;
    m_currentBankDocument->executeSelectSqliteOrder("SELECT count(1), t_ACCOUNT, i_number FROM v_operation_display WHERE i_number!=0 GROUP BY t_ACCOUNT, i_number HAVING count(1)>1 ORDER BY count(1) DESC", result);
    int nb = result.count();
    for (int i = 1; i < nb; ++i) { //Ignore header
        //Get parameters
        QStringList line = result.at(i);
        QString account = line.at(1);
        QString number = line.at(2);

        SKGAdvice ad;
        ad.setUUID("skgoperationplugin_duplicate|" % number % ';' % account);
        ad.setPriority(7);
        ad.setShortMessage(i18nc("Advice on making the best (short)", "Duplicate number %1 in account '%2'", number, account));
        ad.setLongMessage(i18nc("Advice on making the best (long)", "Your account '%1' contains more than one operation with number %2.The operation number should be unique (check number, transaction reference...)", account, number));
        QStringList autoCorrections;
        autoCorrections.push_back(i18nc("Advice on making the best (action)", "Edit operations with duplicate number"));
        ad.setAutoCorrections(autoCorrections);
        output.push_back(ad);
    }

    //Check operations not reconciliated
    m_currentBankDocument->executeSelectSqliteOrder("SELECT count(1), t_ACCOUNT FROM v_operation_display WHERE t_status='N' GROUP BY t_ACCOUNT HAVING count(1)>100 ORDER BY count(1) DESC", result);
    nb = result.count();
    for (int i = 1; i < nb; ++i) { //Ignore header
        //Get parameters
        QStringList line = result.at(i);
        QString account = line.at(1);

        SKGAdvice ad;
        ad.setUUID("skgoperationplugin_notreconciliated|" % account);
        ad.setPriority(9);
        ad.setShortMessage(i18nc("Advice on making the best (short)", "Many operations of '%1' not reconciliated", account));
        ad.setLongMessage(i18nc("Advice on making the best (long)", "Don't forget to reconciliate your accounts. By doing so, you acknowledge that your bank has indeed processed these operations on your account. This is how you enforce compliance with your bank's statements. See online help for more details"));
        QStringList autoCorrections;
        autoCorrections.push_back(i18nc("Advice on making the best (action)", "Open account '%1' for reconciliation", account));
        ad.setAutoCorrections(autoCorrections);
        output.push_back(ad);
    }

    //Check operations without category
    bool exist = false;
    m_currentBankDocument->existObjects("v_operation_display", "t_TRANSFER='N' AND EXISTS (SELECT 1 FROM suboperation WHERE rd_operation_id=v_operation_display.id AND r_category_id=0)", exist);
    if (exist) {
        SKGAdvice ad;
        ad.setUUID("skgoperationplugin_nocategory");
        ad.setPriority(5);
        ad.setShortMessage(i18nc("Advice on making the best (short)", "Many operations don't have category"));
        ad.setLongMessage(i18nc("Advice on making the best (long)", "Don't forget to associate a category for each operation. This will allow you to generate better reports."));
        QStringList autoCorrections;
        autoCorrections.push_back(i18nc("Advice on making the best (action)", "Open operations without category"));
        ad.setAutoCorrections(autoCorrections);
        output.push_back(ad);
    }

    m_currentBankDocument->existObjects("v_operation_display", "t_TRANSFER='Y' AND EXISTS (SELECT 1 FROM suboperation WHERE rd_operation_id=v_operation_display.id AND r_category_id=0)", exist);
    if (exist) {
        SKGAdvice ad;
        ad.setUUID("skgoperationplugin_transfer_nocategory");
        ad.setPriority(3);
        ad.setShortMessage(i18nc("Advice on making the best (short)", "Many transfers don't have category"));
        ad.setLongMessage(i18nc("Advice on making the best (long)", "Don't forget to associate a category for each transfer."));
        QStringList autoCorrections;
        autoCorrections.push_back(i18nc("Advice on making the best (action)", "Open transfers without category"));
        ad.setAutoCorrections(autoCorrections);
        output.push_back(ad);
    }

    //Check operations without payee
    m_currentBankDocument->existObjects("v_operation_display", "t_TRANSFER='N' AND r_payee_id=0", exist);
    if (exist) {
        SKGAdvice ad;
        ad.setUUID("skgoperationplugin_nopayee");
        ad.setPriority(5);
        ad.setShortMessage(i18nc("Advice on making the best (short)", "Many operations don't have payee"));
        ad.setLongMessage(i18nc("Advice on making the best (long)", "Don't forget to associate a payee for each operation. This will allow you to generate better reports."));
        QStringList autoCorrections;
        autoCorrections.push_back(i18nc("Advice on making the best (action)", "Open operations without payee"));
        ad.setAutoCorrections(autoCorrections);
        output.push_back(ad);
    }

    m_currentBankDocument->existObjects("v_operation_display", "t_TRANSFER='Y' AND r_payee_id=0", exist);
    if (exist) {
        SKGAdvice ad;
        ad.setUUID("skgoperationplugin_transfer_nopayee");
        ad.setPriority(3);
        ad.setShortMessage(i18nc("Advice on making the best (short)", "Many transfers don't have payee"));
        ad.setLongMessage(i18nc("Advice on making the best (long)", "Don't forget to associate a payee for each transfer."));
        QStringList autoCorrections;
        autoCorrections.push_back(i18nc("Advice on making the best (action)", "Open transfers without payee"));
        ad.setAutoCorrections(autoCorrections);
        output.push_back(ad);
    }

    //Check operations in group of only one transaction
    m_currentBankDocument->existObjects("v_operation_display", "i_group_id<>0 AND (SELECT COUNT(1) FROM operation o WHERE o.i_group_id=v_operation_display.i_group_id)<2", exist);
    if (exist) {
        SKGAdvice ad;
        ad.setUUID("skgoperationplugin_groupofone");
        ad.setPriority(4);
        ad.setShortMessage(i18nc("Advice on making the best (short)", "Some operations are in groups with only one operation"));
        ad.setLongMessage(i18nc("Advice on making the best (long)", "When a transfer is created and when only one part of this transfer is removed, the second part is in a group of only one operation. This makes no sense."));
        QStringList autoCorrections;
        autoCorrections.push_back(i18nc("Advice on making the best (action)", "Open operations in groups with only one operation"));
        autoCorrections.push_back(i18nc("Advice on making the best (action)", "Remove groups with only one operation"));
        ad.setAutoCorrections(autoCorrections);
        output.push_back(ad);
    }

    //Too many money on a current account
    m_currentBankDocument->executeSelectSqliteOrder("SELECT t_name, f_RATE FROM v_account_display WHERE t_close='N' AND f_RATE>0 ORDER BY f_RATE DESC", result);
    nb = result.count();
    if (nb > 1) {
        //Get better interest account
        QString target = result.at(1).at(0);
        QString rate = result.at(1).at(1);

        //Get accounts with too much money
        m_currentBankDocument->executeSelectSqliteOrder("SELECT t_name FROM v_account_display WHERE f_RATE<" % rate % " AND t_type='C' AND t_close='N' AND f_CURRENTAMOUNT>-2*(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_operation_display s WHERE s.rd_account_id=v_account_display.id AND s.t_TYPEEXPENSE='-' AND s.d_DATEMONTH = strftime('%Y-%m',date('now','start of month', '-1 MONTH')))", result);
        nb = result.count();
        for (int i = 1; i < nb; ++i) { //Ignore header
            //Get parameters
            QString account = result.at(i).at(0);

            SKGAdvice ad;
            ad.setUUID("skgoperationplugin_too_much_money|" % account);
            ad.setPriority(6);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "Too much money in your account '%1'", account));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "You could save money on an account with a better rate. Example: '%1' (%2%)", target, rate));
            output.push_back(ad);
        }
    }
    return output;
}

SKGError SKGOperationPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) const
{
    if (m_currentBankDocument && iAdviceIdentifier.startsWith(QLatin1String("skgoperationplugin_duplicate|"))) {
        //Get parameters
        QString parameters = iAdviceIdentifier.right(iAdviceIdentifier.length() - 29);
        int pos = parameters.indexOf(';');
        QString num = parameters.left(pos);
        QString account = parameters.right(parameters.length() - 1 - pos);

        //Call operation plugin
        QDomDocument doc("SKGML");
        doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
        QDomElement root = doc.documentElement();
        if (root.isNull()) {
            root = doc.createElement("parameters");
            doc.appendChild(root);
        }

        root.setAttribute("operationWhereClause", "i_number=" % SKGServices::stringToSqlString(num) % " AND t_ACCOUNT='" % SKGServices::stringToSqlString(account) % '\'');
        root.setAttribute("title", i18nc("Noun, a list of items", "Operations of '%1' with duplicate number %2", account, num));
        root.setAttribute("title_icon", "security-low");
        SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
        return SKGError();
    } else if (m_currentBankDocument && iAdviceIdentifier.startsWith(QLatin1String("skgoperationplugin_notreconciliated|"))) {
        //Get parameters
        QString account = iAdviceIdentifier.right(iAdviceIdentifier.length() - 36);

        //Call operation plugin
        QDomDocument doc("SKGML");
        doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
        QDomElement root = doc.documentElement();
        if (root.isNull()) {
            root = doc.createElement("parameters");
            doc.appendChild(root);
        }

        root.setAttribute("account", account);
        root.setAttribute("modeInfoZone", "1");
        root.setAttribute("currentPage", "-1");
        SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
        return SKGError();
    } else if (m_currentBankDocument && iAdviceIdentifier == "skgoperationplugin_nocategory") {
        //Call operation plugin
        QDomDocument doc("SKGML");
        doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
        QDomElement root = doc.documentElement();
        if (root.isNull()) {
            root = doc.createElement("parameters");
            doc.appendChild(root);
        }

        root.setAttribute("operationWhereClause", "t_TRANSFER='N' AND EXISTS (SELECT 1 FROM suboperation WHERE rd_operation_id=v_operation_display.id AND r_category_id=0)");
        root.setAttribute("title", i18nc("Noun, a list of items", "Operations without category"));
        root.setAttribute("title_icon", "skrooge_category");
        SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
        return SKGError();
    } else if (m_currentBankDocument && iAdviceIdentifier == "skgoperationplugin_transfer_nocategory") {
        //Call operation plugin
        QDomDocument doc("SKGML");
        doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
        QDomElement root = doc.documentElement();
        if (root.isNull()) {
            root = doc.createElement("parameters");
            doc.appendChild(root);
        }

        root.setAttribute("operationWhereClause", "t_TRANSFER='Y' AND EXISTS (SELECT 1 FROM suboperation WHERE rd_operation_id=v_operation_display.id AND r_category_id=0)");
        root.setAttribute("title", i18nc("Noun, a list of items", "Transfers without category"));
        root.setAttribute("title_icon", "skrooge_category");
        SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
        return SKGError();
    } else if (m_currentBankDocument && iAdviceIdentifier == "skgoperationplugin_groupofone") {
        if (iSolution == 0) {
            //Call operation plugin
            QDomDocument doc("SKGML");
            doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
            QDomElement root = doc.documentElement();
            if (root.isNull()) {
                root = doc.createElement("parameters");
                doc.appendChild(root);
            }

            root.setAttribute("operationWhereClause", "v_operation_display.i_group_id<>0 AND (SELECT COUNT(1) FROM operation o WHERE o.i_group_id=v_operation_display.i_group_id)<2");
            root.setAttribute("title", i18nc("Noun, a list of items", "Operations in groups with only one operation"));
            root.setAttribute("title_icon", "view-financial-transfer");
            SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
            return SKGError();
        } else {
            SKGError err;
            {
                SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Remove groups with only one operation"), err);
                err = m_currentBankDocument->executeSqliteOrder("DELETE FROM operation WHERE operation.i_group_id<>0 AND (SELECT COUNT(1) FROM operation o WHERE o.i_group_id=operation.i_group_id)<2");
            }

            //status bar
            if (!err) err = SKGError(0, i18nc("Message for successful user action", "Remove groups done."));
            else err.addError(ERR_FAIL, i18nc("Error message", "Remove groups failed"));

            //Display error
            SKGMainPanel::displayErrorMessage(err);
        }
    } else if (m_currentBankDocument && iAdviceIdentifier == "skgoperationplugin_nopayee") {
        //Call operation plugin
        QDomDocument doc("SKGML");
        doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
        QDomElement root = doc.documentElement();
        if (root.isNull()) {
            root = doc.createElement("parameters");
            doc.appendChild(root);
        }

        root.setAttribute("operationWhereClause", "t_TRANSFER='N' AND r_payee_id=0");
        root.setAttribute("title", i18nc("Noun, a list of items", "Operations without payee"));
        root.setAttribute("title_icon", "skrooge_payee");
        SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
        return SKGError();
    } else if (m_currentBankDocument && iAdviceIdentifier == "skgoperationplugin_transfer_nopayee") {
        //Call operation plugin
        QDomDocument doc("SKGML");
        doc.setContent(m_currentBankDocument->getParameter("SKGOPERATION_DEFAULT_PARAMETERS"));
        QDomElement root = doc.documentElement();
        if (root.isNull()) {
            root = doc.createElement("parameters");
            doc.appendChild(root);
        }

        root.setAttribute("operationWhereClause", "t_TRANSFER='Y' AND r_payee_id=0");
        root.setAttribute("title", i18nc("Noun, a list of items", "Transfers without payee"));
        root.setAttribute("title_icon", "skrooge_payee");
        SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName("Skrooge operation plugin"), -1, doc.toString());
        return SKGError();
    }

    return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}

void SKGOperationPlugin::actionMergeSubOperations()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGImportExportPlugin::mergeImportedOperation", err);

    if (SKGMainPanel::getMainPanel() && m_currentBankDocument) {
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
        int nb = selection.count();
        if (nb >= 2) {
            SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Merge sub operations"), err);
            SKGOperationObject op = selection.at(0);
            for (int i = 1; !err && i < nb; ++i) {
                SKGOperationObject op2 = selection.at(i);
                err = op.mergeSuboperations(op2);
            }
        }
    }

    //status bar
    if (!err) err = SKGError(0, i18nc("Successful message after an user action", "Operations merged."));
    else err.addError(ERR_FAIL, i18nc("Error message", "Merge failed"));

    //Display error
    SKGMainPanel::displayErrorMessage(err);
}

#include "skgoperationplugin.moc"
