/***************************************************************************
 *   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 for MMB import / export.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgimportpluginmmb.h"
#include "skgtraces.h"
#include "skgservices.h"
#include "skgbankincludes.h"
#include "skgobjectbase.h"
#include "skgimportexportmanager.h"

#include <kio/netaccess.h>
#include <kgenericfactory.h>

#include <QFile>
#include <QSqlDatabase>
#include <QSqlError>
#include <qfileinfo.h>

#include <klocale.h>

/**
 * This plugin factory.
 */
K_PLUGIN_FACTORY(SKGImportPluginMmbFactory, registerPlugin<SKGImportPluginMmb>();)
/**
 * This plugin export.
 */
K_EXPORT_PLUGIN(SKGImportPluginMmbFactory("skrooge_import_mmb", "skrooge_import_mmb"))

SKGImportPluginMmb::SKGImportPluginMmb(QObject* iImporter, const QVariantList& iArg)
    : SKGImportPlugin(iImporter)
{
    SKGTRACEIN(10, "SKGImportPluginMmb::SKGImportPluginMmb");
    Q_UNUSED(iArg);
}

SKGImportPluginMmb::~SKGImportPluginMmb()
{
}

bool SKGImportPluginMmb::isImportPossible()
{
    SKGTRACEIN(10, "SKGImportPluginMmb::isImportPossible");
    return (!m_importer ? true : m_importer->getFileNameExtension() == "MMB");
}

SKGError SKGImportPluginMmb::importFile()
{
    if (!m_importer) return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
    SKGError err;
    SKGTRACEINRC(2, "SKGImportMmb::importFile", err);

    {
        QSqlDatabase originalDocument(QSqlDatabase::addDatabase("QSQLITE", "originalDocument"));
        originalDocument.setDatabaseName(m_importer->getLocalFileName());
        if (!originalDocument.open()) {
            //Set error message
            QSqlError sqlErr = originalDocument.lastError();
            err = SKGError(SQLLITEERROR + sqlErr.number(), sqlErr.text());
        }
        if (!err) {
            QMap<QString, SKGUnitObject> mapUnit;
            err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "MMB"), 9);

            //Step 1 - units
            if (!err) {
                SKGStringListList listUnits;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT CURRENCYID, CURRENCYNAME, PFX_SYMBOL, SFX_SYMBOL, DECIMAL_POINT, GROUP_SEPARATOR, UNIT_NAME, CENT_NAME, SCALE, BASECONVRATE, CURRENCY_SYMBOL, "
                        "(CASE WHEN EXISTS (SELECT 1 FROM INFOTABLE_V1 WHERE INFONAME='BASECURRENCYID' AND INFOVALUE=CURRENCYID) THEN 'Y' ELSE 'N' END) AS PRIMARYUNIT FROM CURRENCYFORMATS_V1", listUnits);
                if (!err) {
                    int nb = listUnits.count() - 1;
                    err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
                    for (int i = 0; !err && i < nb; ++i) {
                        QStringList attributes = listUnits.at(i + 1);

                        SKGUnitObject unit(m_importer->getDocument());
                        err = unit.setName(attributes.at(1));
                        if (!err) {
                            QString symbol = attributes.at(2);
                            if (symbol.isEmpty()) symbol = attributes.at(3);
                            err = unit.setSymbol(symbol);
                        }
                        if (!err && attributes.at(11) == "Y") err = unit.setType(SKGUnitObject::PRIMARY);
                        if (!err) err = unit.save();

                        mapUnit[attributes.at(0)] = unit;

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

                    if (!err) err = m_importer->getDocument()->endTransaction(true);
                    else  m_importer->getDocument()->endTransaction(false);
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(1);

            //Step 2 - bank and accounts
            QMap<QString, SKGAccountObject> mapAccount;
            if (!err) {
                SKGStringListList listAccounts;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT ACCOUNTID, ACCOUNTNAME, ACCOUNTTYPE, ACCOUNTNUM, STATUS, NOTES, HELDAT, WEBSITE, CONTACTINFO, ACCESSINFO, INITIALBAL, FAVORITEACCT, CURRENCYID FROM ACCOUNTLIST_V1", listAccounts);
                if (!err) {
                    int nb = listAccounts.count() - 1;
                    if (!err) err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import banks and accounts"), nb);
                    for (int i = 0; !err && i < nb; ++i) {
                        QStringList attributes = listAccounts.at(i + 1);

                        //Create bank
                        SKGBankObject bank(m_importer->getDocument());
                        if (!err) {
                            QString bankName = attributes.at(6);
                            if (bankName.isEmpty()) bankName = "MMEX";
                            err = bank.setName(bankName);
                        }
                        if (!err) err = bank.save();

                        //Create account
                        SKGAccountObject account;
                        err = bank.addAccount(account);
                        if (!err) err = account.setName(attributes.at(1));
                        if (!err) err = account.setType(attributes.at(2) == "Checking" ? SKGAccountObject::CURRENT : SKGAccountObject::INVESTMENT);
                        if (!err) err = account.setNumber(attributes.at(3));
                        if (!err) err = account.setComment(attributes.at(5));
                        if (!err) err = account.setAgencyAddress(attributes.at(8));
                        if (!err) err = account.bookmark(attributes.at(11) == "TRUE");
                        if (!err) err = account.setClosed(attributes.at(4) != "Open");
                        if (!err) err = account.save();
                        if (!err) err = account.setInitialBalance(SKGServices::stringToDouble(attributes.at(10)), mapUnit[attributes.at(12)]);
                        if (!err) err = account.save();

                        mapAccount[attributes.at(0)] = account;

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

                    if (!err) err = m_importer->getDocument()->endTransaction(true);
                    else  m_importer->getDocument()->endTransaction(false);
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(2);

            //Step 3 - categories
            QMap<QString, SKGCategoryObject> mapCategory;
            if (!err) {
                SKGStringListList listCategories;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT CATEGID, CATEGNAME FROM CATEGORY_V1", listCategories);
                if (!err) {
                    int nb = listCategories.count() - 1;
                    err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
                    for (int i = 0; !err && i < nb; ++i) {
                        QStringList attributes = listCategories.at(i + 1);

                        SKGCategoryObject cat(m_importer->getDocument());
                        err = cat.setName(attributes.at(1));
                        if (!err) err = cat.save();

                        mapCategory[attributes.at(0)] = cat;

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

                    if (!err) err = m_importer->getDocument()->endTransaction(true);
                    else  m_importer->getDocument()->endTransaction(false);
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(3);

            //Step 4 - sub categories
            QMap<QString, SKGCategoryObject> mapSubCategory;
            if (!err) {
                SKGStringListList listCategories;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT SUBCATEGID, SUBCATEGNAME, CATEGID FROM SUBCATEGORY_V1", listCategories);
                if (!err) {
                    int nb = listCategories.count() - 1;
                    err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
                    for (int i = 0; !err && i < nb; ++i) {
                        QStringList attributes = listCategories.at(i + 1);

                        SKGCategoryObject cat(m_importer->getDocument());
                        err = cat.setName(attributes.at(1));
                        if (!err) err = cat.setParentCategory(mapCategory[attributes.at(2)]);
                        if (!err) err = cat.save();

                        mapSubCategory[attributes.at(0)] = cat;

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

                    if (!err) err = m_importer->getDocument()->endTransaction(true);
                    else  m_importer->getDocument()->endTransaction(false);
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(4);

            //Step 5 - payee
            QMap<QString, SKGPayeeObject> mapPayee;
            if (!err) {
                SKGStringListList listPayee;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT PAYEEID, PAYEENAME FROM PAYEE_V1", listPayee);
                if (!err) {
                    int nb = listPayee.count() - 1;
                    err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payees"), nb);
                    for (int i = 0; !err && i < nb; ++i) {
                        QStringList attributes = listPayee.at(i + 1);

                        SKGPayeeObject payee(m_importer->getDocument());
                        err = payee.setName(attributes.at(1));
                        if (!err) err = payee.save();

                        mapPayee[attributes.at(0)] = payee;

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

                    if (!err) err = m_importer->getDocument()->endTransaction(true);
                    else  m_importer->getDocument()->endTransaction(false);
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(5);

            //Step 6 - operations
            QMap<QString, SKGOperationObject> mapOperation;
            if (!err) {
                SKGStringListList listOperations;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT * FROM ("
                        "SELECT TRANSID, ACCOUNTID, TOACCOUNTID, PAYEEID, TRANSCODE, TRANSAMOUNT, STATUS, TRANSACTIONNUMBER, NOTES, CATEGID, SUBCATEGID, TRANSDATE, FOLLOWUPID, TOTRANSAMOUNT, 'N/A'  , 'N/A', 'N/A' FROM CHECKINGACCOUNT_V1 UNION "
                        "SELECT BDID,    ACCOUNTID, TOACCOUNTID, PAYEEID, TRANSCODE, TRANSAMOUNT, STATUS, TRANSACTIONNUMBER, NOTES, CATEGID, SUBCATEGID, TRANSDATE, FOLLOWUPID, TOTRANSAMOUNT, REPEATS, NEXTOCCURRENCEDATE, NUMOCCURRENCES FROM BILLSDEPOSITS_V1)" , listOperations);
                if (!err) {
                    int nb = listOperations.count() - 1;
                    err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
                    for (int i = 0; !err && i < nb; ++i) {
                        QStringList attributes = listOperations.at(i + 1);
                        if (attributes.at(6) != "V") { //Void
                            bool recurrent = (attributes.at(14) != "N/A");
                            QString idTarget = attributes.at(2);
                            SKGAccountObject acc = mapAccount[attributes.at(1)];
                            SKGUnitObject unit;
                            if (!err)  err = acc.getUnit(unit);

                            SKGOperationObject op;
                            if (!err)  err = acc.addOperation(op);
                            if (!err) {
                                QString id = attributes.at(3);
                                if (id != "-1") err = op.setPayee(mapPayee[id]);
                            }
                            if (!err) err = op.setNumber(SKGServices::stringToInt(attributes.at(7)));
                            if (!err) err = op.setComment(attributes.at(8));
                            if (!err) err = op.setDate(SKGServices::stringToTime(attributes.at(11)).date());
                            if (!err) err = op.setAttribute("t_imported", "T");
                            if (!err) err = op.setImportID("MMEX-" % attributes.at(0));
                            if (!err) err = op.setUnit(unit);
                            if (!err) err = op.bookmark(attributes.at(6) == "F");
                            if (!err) err = op.setTemplate(recurrent);
                            if (!err) err = op.setStatus(attributes.at(6) == "R" ? SKGOperationObject::CHECKED : SKGOperationObject::NONE);
                            if (!err) err = op.save();

                            //Get splits
                            if (!err) {
                                SKGStringListList listSubOperations;
                                err = SKGServices::executeSelectSqliteOrder(&originalDocument, QString("SELECT SPLITTRANSID, CATEGID, SUBCATEGID, SPLITTRANSAMOUNT FROM ") % (recurrent ? "BUDGET" : "") % "SPLITTRANSACTIONS_V1 WHERE TRANSID=" % attributes.at(0), listSubOperations);
                                if (!err) {
                                    int nb2 = listSubOperations.count() - 1;
                                    if (nb2 <= 0) {
                                        //No split
                                        SKGSubOperationObject subop;
                                        if (!err) err = op.addSubOperation(subop);
                                        if (!err) {
                                            QString id = attributes.at(10);
                                            if (id == "-1") {
                                                id = attributes.at(9);
                                                if (id != "-1") err = subop.setCategory(mapSubCategory[id]);
                                            } else err = subop.setCategory(mapCategory[id]);
                                        }
                                        if (!err) {
                                            double q = SKGServices::stringToDouble(attributes.at(5));
                                            if (attributes.at(4) == "Withdrawal" || idTarget != "-1") q = -q;
                                            err = subop.setQuantity(q);
                                        }
                                        if (!err) err = subop.save();
                                    } else {
                                        //Has splits
                                        for (int j = 0; !err && j < nb2; ++j) {
                                            QStringList attributesSubOp = listSubOperations.at(j + 1);

                                            SKGSubOperationObject subop;
                                            if (!err) err = op.addSubOperation(subop);
                                            if (!err) {
                                                QString id = attributesSubOp.at(2);
                                                if (id == "-1") {
                                                    id = attributesSubOp.at(1);
                                                    if (id != "-1") err = subop.setCategory(mapCategory[id]);
                                                } else err = subop.setCategory(mapSubCategory[id]);
                                            }
                                            if (!err) {
                                                double q = SKGServices::stringToDouble(attributesSubOp.at(3));
                                                if (attributes.at(4) == "Withdrawal" || idTarget != "-1") q = -q;
                                                err = subop.setQuantity(q);
                                            }
                                            if (!err) err = subop.save();
                                        }
                                    }
                                }
                            }

                            //Case transfert
                            if (!err && idTarget != "-1") {
                                SKGOperationObject op2;
                                err = op.duplicate(op2, op.getDate());
                                if (!err) err = op2.setStatus(op.getStatus());
                                if (!err) err = op2.bookmark(op.isBookmarked());
                                if (!err) err = op2.setAttribute("t_imported", "T");
                                if (!err) err = op2.setImportID("MMEX-" % attributes.at(0) % "_TR");
                                if (!err) err = op2.save();

                                SKGObjectBase::SKGListSKGObjectBase subops;
                                if (!err) err = op.getSubOperations(subops);
                                if (!err && subops.count()) {
                                    SKGSubOperationObject subop2(subops.at(0));
                                    err = subop2.setQuantity(-subop2.getQuantity());
                                    if (!err) err = subop2.save();
                                }
                                if (!err) err = op.setParentAccount(mapAccount[idTarget]);
                                if (!err) err = op.setGroupOperation(op2);
                                if (!err) err = op.save();
                            }

                            //Create reccurent transaction
                            if (recurrent) {
                                SKGRecurrentOperationObject recu;
                                if (!err) err = op.addRecurrentOperation(recu);
                                if (!err) err = recu.setDate(SKGServices::stringToTime(attributes.at(15)).date());
                                int nbTimes = SKGServices::stringToInt(attributes.at(16));
                                if (!err && nbTimes != -1) {
                                    err = recu.setTimeLimit(nbTimes);
                                    if (!err) err = recu.timeLimit(true);
                                }
                                int repeats = SKGServices::stringToInt(attributes.at(14));
                                if (!err) {
                                    switch (repeats) {
                                    case 1:
                                        //Weekly
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
                                        if (!err) err = recu.setPeriodIncrement(1);
                                        break;
                                    case 2:
                                        //Bi-Weekly
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
                                        if (!err) err = recu.setPeriodIncrement(2);
                                        break;
                                    case 3:
                                        //Monthly
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
                                        if (!err) err = recu.setPeriodIncrement(1);
                                        break;
                                    case 4:
                                        //Bi-Monthly
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
                                        if (!err) err = recu.setPeriodIncrement(2);
                                        break;
                                    case 5:
                                        //Quarterly
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
                                        if (!err) err = recu.setPeriodIncrement(3);
                                        break;
                                    case 6:
                                        //Half yearly
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
                                        if (!err) err = recu.setPeriodIncrement(6);
                                        break;
                                    case 7:
                                        //Yearly
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::YEAR);
                                        if (!err) err = recu.setPeriodIncrement(1);
                                        break;
                                    case 8:
                                        //Four months
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
                                        if (!err) err = recu.setPeriodIncrement(4);
                                        break;
                                    case 9:
                                        //Four weeks
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
                                        if (!err) err = recu.setPeriodIncrement(4);
                                        break;
                                    case 10:
                                        //Daily
                                        err = recu.setPeriodUnit(SKGRecurrentOperationObject::DAY);
                                        if (!err) err = recu.setPeriodIncrement(1);
                                        break;

                                    default:
                                        break;
                                    }
                                }
                                if (!err) err = recu.save(true, false);
                            }
                            mapOperation[attributes.at(0)] = op;
                        }

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

                    if (!err) err = m_importer->getDocument()->endTransaction(true);
                    else  m_importer->getDocument()->endTransaction(false);
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(6);

            //Step 7 - stock
            if (!err) {
                SKGStringListList listStock;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT STOCKID, HELDAT, PURCHASEDATE, STOCKNAME, SYMBOL, NUMSHARES, PURCHASEPRICE, NOTES, CURRENTPRICE, VALUE, COMMISSION FROM STOCK_V1", listStock);
                if (!err) {
                    int nb = listStock.count() - 1;
                    err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import stocks"), nb);
                    for (int i = 0; !err && i < nb; ++i) {
                        QStringList attributes = listStock.at(i + 1);

                        //Create unit
                        SKGUnitObject unit(m_importer->getDocument());
                        err = unit.setName(attributes.at(3));
                        if (!err)  err = unit.setSymbol(attributes.at(4));
                        if (!err)  err = unit.setType(SKGUnitObject::SHARE);
                        if (!err) err = unit.save();

                        SKGUnitValueObject unitValue;
                        if (!err) err = unit.addUnitValue(unitValue);
                        if (!err) err = unitValue.setDate(SKGServices::stringToTime(attributes.at(2)).date());
                        if (!err) err = unitValue.setQuantity(SKGServices::stringToDouble(attributes.at(6)));
                        if (!err) err = unitValue.save(true, false);

                        SKGUnitValueObject unitValue2;
                        if (!err) err = unit.addUnitValue(unitValue2);
                        if (!err) err = unitValue2.setDate(QDate::currentDate());
                        if (!err) err = unitValue2.setQuantity(SKGServices::stringToDouble(attributes.at(8)));
                        if (!err) err = unitValue2.save(true, false);

                        //Create operation
                        SKGAccountObject acc = mapAccount[attributes.at(1)];
                        SKGUnitObject unitCurrency;
                        if (!err)  err = acc.getUnit(unitCurrency);

                        SKGOperationObject op;
                        if (!err) err = acc.addOperation(op);
                        if (!err) err = op.setComment(attributes.at(7));
                        if (!err) err = op.setDate(SKGServices::stringToTime(attributes.at(2)).date());
                        if (!err) err = op.setAttribute("t_imported", "T");
                        if (!err) err = op.setImportID("MMEX-STOCK-" % attributes.at(0));
                        if (!err) err = op.setUnit(unit);
                        if (!err) err = op.save();

                        SKGSubOperationObject subop;
                        if (!err) err = op.addSubOperation(subop);
                        if (!err) err = subop.setQuantity(SKGServices::stringToDouble(attributes.at(5)));
                        if (!err) err = subop.save(true, false);

                        /*SKGOperationObject op2;
                        if(!err) err = acc.addOperation(op2);
                        if(!err) err = op2.setComment(attributes.at(7));
                        if(!err) err = op2.setDate(SKGServices::stringToTime(attributes.at(2)).date());
                        if(!err) err = op2.setAttribute("t_imported", "T");
                        if(!err) err = op2.setImportID("MMEX-STOCK-" % attributes.at(0)% "_TR");
                        if(!err) err = op2.setUnit(unitCurrency);
                        if(!err) err = op2.save();

                        SKGSubOperationObject subop2;
                        if(!err) err = op2.addSubOperation(subop2);
                        if(!err) err = subop2.setQuantity(-SKGServices::stringToDouble(attributes.at(5))*SKGServices::stringToDouble(attributes.at(6)));
                        if(!err) err = subop2.save();

                        if(!err) err = op.setGroupOperation(op2);
                        if(!err) err = op.save();*/

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

                    if (!err) err = m_importer->getDocument()->endTransaction(true);
                    else  m_importer->getDocument()->endTransaction(false);
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(7);

            //Step 8 - asset
            if (!err) {
                SKGStringListList listAssets;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT ASSETID, STARTDATE, ASSETNAME, VALUE, VALUECHANGE, NOTES, VALUECHANGERATE, ASSETTYPE FROM ASSETS_V1", listAssets);
                if (!err) {
                    int nb = listAssets.count() - 1;
                    if (nb) {
                        //Create account
                        //Create bank
                        SKGBankObject bank(m_importer->getDocument());
                        if (!err) err = bank.setName("MMEX");
                        if (!err) err = bank.save();

                        //Create account
                        SKGAccountObject account;
                        err = bank.addAccount(account);
                        if (!err) err = account.setName(i18nc("Noun, a type of account", "Assets"));
                        if (!err) err = account.setType(SKGAccountObject::ASSETS);
                        if (!err) err = account.save();

                        err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import assets"), nb);
                        for (int i = 0; !err && i < nb; ++i) {
                            QStringList attributes = listAssets.at(i + 1);

                            //Create unit
                            SKGUnitObject unit(m_importer->getDocument());
                            err = unit.setName(attributes.at(2));
                            if (!err)  err = unit.setSymbol(attributes.at(2));
                            if (!err)  err = unit.setType(SKGUnitObject::OBJECT);
                            if (!err)  err = unit.setInternetCode(QString("=") % (attributes.at(4) == "Depreciates" ? "-" : "+") % attributes.at(6));
                            if (!err) err = unit.save();

                            SKGUnitValueObject unitValue;
                            if (!err) err = unit.addUnitValue(unitValue);
                            if (!err) err = unitValue.setDate(SKGServices::stringToTime(attributes.at(1)).date());
                            if (!err) err = unitValue.setQuantity(SKGServices::stringToDouble(attributes.at(3)));
                            if (!err) err = unitValue.save(true, false);

                            //Create operation
                            SKGOperationObject op;
                            if (!err) err = account.addOperation(op);
                            if (!err) err = op.setComment(attributes.at(5));
                            if (!err) err = op.setDate(SKGServices::stringToTime(attributes.at(1)).date());
                            if (!err) err = op.setAttribute("t_imported", "T");
                            if (!err) err = op.setImportID("MMEX-ASSET-" % attributes.at(0));
                            if (!err) err = op.setUnit(unit);
                            if (!err) err = op.save();

                            SKGSubOperationObject subop;
                            if (!err) err = op.addSubOperation(subop);
                            if (!err) err = subop.setQuantity(1.0);
                            if (!err) err = subop.save(true, false);

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

                        if (!err) err = m_importer->getDocument()->endTransaction(true);
                        else  m_importer->getDocument()->endTransaction(false);
                    }
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(8);

            //Step 9 - budgets
            if (!err) {
                SKGStringListList listBudgets;
                err = SKGServices::executeSelectSqliteOrder(&originalDocument, "SELECT BUDGETENTRYID, (SELECT Y.BUDGETYEARNAME FROM BUDGETYEAR_V1 Y WHERE Y.BUDGETYEARID=BUDGETTABLE_V1.BUDGETYEARID), CATEGID, SUBCATEGID, PERIOD, AMOUNT FROM BUDGETTABLE_V1", listBudgets);
                if (!err) {
                    int nb = listBudgets.count() - 1;
                    err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import budgets"), nb);
                    for (int i = 0; !err && i < nb; ++i) {
                        QStringList attributes = listBudgets.at(i + 1);

                        QString period = attributes.at(4);

                        int step = 0;
                        double coef = 0;
                        if (period == "Weekly") {
                            coef = 52.0 / 12.0;
                            step = 1;
                        } else if (period == "Monthly") {
                            coef = 1;
                            step = 1;
                        } else if (period == "Bi-Weekly") {
                            coef = 52.0 / 12.0 / 2.0;
                            step = 1;
                        } else if (period == "Bi-Monthly") {
                            coef = 1;
                            step = 2;
                        } else if (period == "Quarterly") {
                            coef = 1;
                            step = 4;
                        } else if (period == "Half-Yearly") {
                            coef = 1;
                            step = 6;
                        } else if (period == "Yearly") {
                            coef = 1;
                            step = 12;
                        }

                        if (step) {
                            for (int i = 0; !err && i < 12; i = i + step) {
                                SKGBudgetObject bug(m_importer->getDocument());
                                err = bug.setYear(SKGServices::stringToInt(attributes.at(1)));
                                if (!err) err = bug.setMonth(step == 12 ? 0 : i + 1);
                                if (!err) {
                                    QString id = attributes.at(3);
                                    if (id == "-1") {
                                        id = attributes.at(2);
                                        if (id != "-1") err = bug.setCategory(mapCategory[id]);
                                    } else err = bug.setCategory(mapSubCategory[id]);
                                }
                                if (!err) err = bug.setBudgetedAmount(coef * SKGServices::stringToDouble(attributes.at(5)));
                                if (!err) err = bug.save();
                            }
                        }

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

                    if (!err) err = m_importer->getDocument()->endTransaction(true);
                    else  m_importer->getDocument()->endTransaction(false);
                }
            }
            if (!err) err = m_importer->getDocument()->stepForward(9);

            if (!err) err = m_importer->getDocument()->endTransaction(true);
            else  m_importer->getDocument()->endTransaction(false);

            if (!err) err = m_importer->getDocument()->executeSqliteOrder("ANALYZE");
        }

    }
    QSqlDatabase::removeDatabase("originalDocument");
    return err;
}

QString SKGImportPluginMmb::getMimeTypeFilter() const
{
    return "*.mmb|" % i18nc("A file format", "Money Manager Ex document");
}

#include "skgimportpluginmmb.moc"
