File indexing completed on 2024-05-26 05:10:32

0001 /***************************************************************************
0002  * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr
0003  * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  ***************************************************************************/
0006 /** @file
0007  * This file is Skrooge plugin for MMB import / export.
0008  *
0009  * @author Stephane MANKOWSKI / Guillaume DE BURE
0010  */
0011 #include "skgimportpluginmmb.h"
0012 
0013 #include <qfile.h>
0014 #include <qsqldatabase.h>
0015 #include <qsqlerror.h>
0016 
0017 #include <klocalizedstring.h>
0018 #include <kpluginfactory.h>
0019 
0020 #include "skgbankincludes.h"
0021 #include "skgimportexportmanager.h"
0022 #include "skgobjectbase.h"
0023 #include "skgservices.h"
0024 #include "skgtraces.h"
0025 
0026 /**
0027  * This plugin factory.
0028  */
0029 K_PLUGIN_CLASS_WITH_JSON(SKGImportPluginMmb, "metadata.json")
0030 
0031 SKGImportPluginMmb::SKGImportPluginMmb(QObject* iImporter, const QVariantList& iArg)
0032     : SKGImportPlugin(iImporter)
0033 {
0034     SKGTRACEINFUNC(10)
0035     Q_UNUSED(iArg)
0036 }
0037 
0038 SKGImportPluginMmb::~SKGImportPluginMmb()
0039     = default;
0040 
0041 bool SKGImportPluginMmb::isImportPossible()
0042 {
0043     SKGTRACEINFUNC(10)
0044     return (m_importer->getDocument() == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("MMB"));
0045 }
0046 
0047 SKGError SKGImportPluginMmb::importFile()
0048 {
0049     if (m_importer->getDocument() == nullptr) {
0050         return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
0051     }
0052     SKGError err;
0053     SKGTRACEINFUNCRC(2, err)
0054 
0055     {
0056         QSqlDatabase originalDocument(QSqlDatabase::addDatabase(QStringLiteral("SKGSQLCIPHER"), QStringLiteral("originalDocument")));
0057         originalDocument.setDatabaseName(m_importer->getLocalFileName());
0058         if (!originalDocument.open()) {
0059             // Set error message
0060             QSqlError sqlErr = originalDocument.lastError();
0061             err = SKGError(SQLLITEERROR + sqlErr.nativeErrorCode().toInt(), sqlErr.text());
0062         }
0063         IFOK(err) {
0064             QMap<QString, SKGUnitObject> mapUnit;
0065             err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "MMB"), 9);
0066 
0067             // Step 1 - units
0068             IFOK(err) {
0069                 SKGStringListList listUnits;
0070                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT CURRENCYID, CURRENCYNAME, PFX_SYMBOL, SFX_SYMBOL, DECIMAL_POINT, GROUP_SEPARATOR, UNIT_NAME, CENT_NAME, SCALE, BASECONVRATE, CURRENCY_SYMBOL, "
0071                         "(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);
0072                 IFOK(err) {
0073                     int nb = listUnits.count() - 1;
0074                     err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
0075                     for (int i = 0; !err && i < nb; ++i) {
0076                         const QStringList& attributes = listUnits.at(i + 1);
0077 
0078                         SKGUnitObject unit(m_importer->getDocument());
0079                         err = unit.setName(attributes.at(1));
0080                         IFOK(err) {
0081                             QString symbol = attributes.at(2);
0082                             if (symbol.isEmpty()) {
0083                                 symbol = attributes.at(3);
0084                             }
0085                             err = unit.setSymbol(symbol);
0086                         }
0087                         if (!err && attributes.at(11) == QStringLiteral("Y")) {
0088                             err = unit.setType(SKGUnitObject::PRIMARY);
0089                         }
0090                         IFOKDO(err, unit.save())
0091 
0092                         mapUnit[attributes.at(0)] = unit;
0093 
0094                         IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0095                     }
0096 
0097                     SKGENDTRANSACTION(m_importer->getDocument(),  err)
0098                 }
0099             }
0100             IFOKDO(err, m_importer->getDocument()->stepForward(1))
0101 
0102             // Step 2 - bank and accounts
0103             QMap<QString, SKGAccountObject> mapAccount;
0104             IFOK(err) {
0105                 SKGStringListList listAccounts;
0106                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT ACCOUNTID, ACCOUNTNAME, ACCOUNTTYPE, ACCOUNTNUM, STATUS, NOTES, HELDAT, WEBSITE, CONTACTINFO, ACCESSINFO, INITIALBAL, FAVORITEACCT, CURRENCYID FROM ACCOUNTLIST_V1"), listAccounts);
0107                 IFOK(err) {
0108                     int nb = listAccounts.count() - 1;
0109                     IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import banks and accounts"), nb))
0110                     for (int i = 0; !err && i < nb; ++i) {
0111                         const QStringList& attributes = listAccounts.at(i + 1);
0112 
0113                         // Create bank
0114                         SKGBankObject bank(m_importer->getDocument());
0115                         IFOK(err) {
0116                             QString bankName = attributes.at(6);
0117                             if (bankName.isEmpty()) {
0118                                 bankName = QStringLiteral("MMEX");
0119                             }
0120                             err = bank.setName(bankName);
0121                         }
0122                         IFOKDO(err, bank.save())
0123 
0124                         // Create account
0125                         SKGAccountObject account;
0126                         err = bank.addAccount(account);
0127                         IFOKDO(err, account.setName(attributes.at(1)))
0128                         IFOKDO(err, account.setType(attributes.at(2) == QStringLiteral("Checking") ? SKGAccountObject::CURRENT : SKGAccountObject::INVESTMENT))
0129                         IFOKDO(err, account.setNumber(attributes.at(3)))
0130                         IFOKDO(err, account.setComment(attributes.at(5)))
0131                         IFOKDO(err, account.setAgencyAddress(attributes.at(8)))
0132                         IFOKDO(err, account.bookmark(attributes.at(11) == QStringLiteral("TRUE")))
0133                         IFOKDO(err, account.setClosed(attributes.at(4) != QStringLiteral("Open")))
0134                         IFOKDO(err, account.save())
0135                         IFOKDO(err, account.setInitialBalance(SKGServices::stringToDouble(attributes.at(10)), mapUnit[attributes.at(12)]))
0136                         IFOKDO(err, account.save())
0137 
0138                         mapAccount[attributes.at(0)] = account;
0139 
0140                         IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0141                     }
0142 
0143                     SKGENDTRANSACTION(m_importer->getDocument(),  err)
0144                 }
0145             }
0146             IFOKDO(err, m_importer->getDocument()->stepForward(2))
0147 
0148             // Step 3 - categories
0149             QMap<QString, SKGCategoryObject> mapCategory;
0150             IFOK(err) {
0151                 SKGStringListList listCategories;
0152                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT CATEGID, CATEGNAME FROM CATEGORY_V1"), listCategories);
0153                 IFOK(err) {
0154                     int nb = listCategories.count() - 1;
0155                     err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
0156                     for (int i = 0; !err && i < nb; ++i) {
0157                         const QStringList& attributes = listCategories.at(i + 1);
0158 
0159                         SKGCategoryObject cat(m_importer->getDocument());
0160                         err = cat.setName(attributes.at(1));
0161                         IFOKDO(err, cat.save())
0162 
0163                         mapCategory[attributes.at(0)] = cat;
0164 
0165                         IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0166                     }
0167 
0168                     SKGENDTRANSACTION(m_importer->getDocument(),  err)
0169                 }
0170             }
0171             IFOKDO(err, m_importer->getDocument()->stepForward(3))
0172 
0173             // Step 4 - sub categories
0174             QMap<QString, SKGCategoryObject> mapSubCategory;
0175             IFOK(err) {
0176                 SKGStringListList listCategories;
0177                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT SUBCATEGID, SUBCATEGNAME, CATEGID FROM SUBCATEGORY_V1"), listCategories);
0178                 IFOK(err) {
0179                     int nb = listCategories.count() - 1;
0180                     err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
0181                     for (int i = 0; !err && i < nb; ++i) {
0182                         const QStringList& attributes = listCategories.at(i + 1);
0183 
0184                         SKGCategoryObject cat(m_importer->getDocument());
0185                         err = cat.setName(attributes.at(1));
0186                         IFOKDO(err, cat.setParentCategory(mapCategory[attributes.at(2)]))
0187                         IFOKDO(err, cat.save())
0188 
0189                         mapSubCategory[attributes.at(0)] = cat;
0190 
0191                         IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0192                     }
0193 
0194                     SKGENDTRANSACTION(m_importer->getDocument(),  err)
0195                 }
0196             }
0197             IFOKDO(err, m_importer->getDocument()->stepForward(4))
0198 
0199             // Step 5 - payee
0200             QMap<QString, SKGPayeeObject> mapPayee;
0201             IFOK(err) {
0202                 SKGStringListList listPayee;
0203                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT PAYEEID, PAYEENAME FROM PAYEE_V1"), listPayee);
0204                 IFOK(err) {
0205                     int nb = listPayee.count() - 1;
0206                     err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payees"), nb);
0207                     for (int i = 0; !err && i < nb; ++i) {
0208                         const QStringList& attributes = listPayee.at(i + 1);
0209 
0210                         SKGPayeeObject payee(m_importer->getDocument());
0211                         err = payee.setName(attributes.at(1));
0212                         IFOKDO(err, payee.save())
0213 
0214                         mapPayee[attributes.at(0)] = payee;
0215 
0216                         IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0217                     }
0218 
0219                     SKGENDTRANSACTION(m_importer->getDocument(),  err)
0220                 }
0221             }
0222             IFOKDO(err, m_importer->getDocument()->stepForward(5))
0223 
0224             // Step 6 - transactions
0225             QMap<QString, SKGOperationObject> mapOperation;
0226             IFOK(err) {
0227                 SKGStringListList listOperations;
0228                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT * FROM ("
0229                         "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 "
0230                         "SELECT BDID,    ACCOUNTID, TOACCOUNTID, PAYEEID, TRANSCODE, TRANSAMOUNT, STATUS, TRANSACTIONNUMBER, NOTES, CATEGID, SUBCATEGID, TRANSDATE, FOLLOWUPID, TOTRANSAMOUNT, REPEATS, NEXTOCCURRENCEDATE, NUMOCCURRENCES FROM BILLSDEPOSITS_V1)"), listOperations);
0231                 IFOK(err) {
0232                     int nb = listOperations.count() - 1;
0233                     err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import transactions"), nb);
0234                     for (int i = 0; !err && i < nb; ++i) {
0235                         const QStringList& attributes = listOperations.at(i + 1);
0236                         if (attributes.at(6) != QStringLiteral("V")) {  // Void
0237                             bool recurrent = (attributes.at(14) != QStringLiteral("N/A"));
0238                             const QString& idTarget = attributes.at(2);
0239                             SKGAccountObject acc = mapAccount[attributes.at(1)];
0240                             SKGUnitObject unit;
0241                             IFOKDO(err, acc.getUnit(unit))
0242 
0243                             SKGOperationObject op;
0244                             IFOKDO(err, acc.addOperation(op, true))
0245                             IFOK(err) {
0246                                 const QString& id = attributes.at(3);
0247                                 if (id != QStringLiteral("-1")) {
0248                                     err = op.setPayee(mapPayee[id]);
0249                                 }
0250                             }
0251                             IFOKDO(err, op.setNumber(attributes.at(7)))
0252                             IFOKDO(err, op.setComment(attributes.at(8)))
0253                             IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(11)).date()))
0254                             IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
0255                             IFOKDO(err, op.setImportID("MMEX-" % attributes.at(0)))
0256                             IFOKDO(err, op.setUnit(unit))
0257                             IFOKDO(err, op.bookmark(attributes.at(6) == QStringLiteral("F")))
0258                             IFOKDO(err, op.setTemplate(recurrent))
0259                             IFOKDO(err, op.setStatus(attributes.at(6) == QStringLiteral("R") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE))
0260                             IFOKDO(err, op.save())
0261 
0262                             // Get splits
0263                             IFOK(err) {
0264                                 SKGStringListList listSubOperations;
0265                                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT SPLITTRANSID, CATEGID, SUBCATEGID, SPLITTRANSAMOUNT FROM ") % (recurrent ? "BUDGET" : "") % "SPLITTRANSACTIONS_V1 WHERE TRANSID=" % attributes.at(0), listSubOperations);
0266                                 IFOK(err) {
0267                                     int nb2 = listSubOperations.count() - 1;
0268                                     if (nb2 <= 0) {
0269                                         // No split
0270                                         SKGSubOperationObject subop;
0271                                         IFOKDO(err, op.addSubOperation(subop))
0272                                         IFOK(err) {
0273                                             QString id = attributes.at(10);
0274                                             if (id == QStringLiteral("-1")) {
0275                                                 id = attributes.at(9);
0276                                                 if (id != QStringLiteral("-1")) {
0277                                                     err = subop.setCategory(mapSubCategory[id]);
0278                                                 }
0279                                             } else {
0280                                                 err = subop.setCategory(mapCategory[id]);
0281                                             }
0282                                         }
0283                                         IFOK(err) {
0284                                             double q = SKGServices::stringToDouble(attributes.at(5));
0285                                             if (attributes.at(4) == QStringLiteral("Withdrawal") || idTarget != QStringLiteral("-1")) {
0286                                                 q = -q;
0287                                             }
0288                                             err = subop.setQuantity(q);
0289                                         }
0290                                         IFOKDO(err, subop.save())
0291                                     } else {
0292                                         // Has splits
0293                                         for (int j = 0; !err && j < nb2; ++j) {
0294                                             const QStringList& attributesSubOp = listSubOperations.at(j + 1);
0295 
0296                                             SKGSubOperationObject subop;
0297                                             IFOKDO(err, op.addSubOperation(subop))
0298                                             IFOK(err) {
0299                                                 QString id = attributesSubOp.at(2);
0300                                                 if (id == QStringLiteral("-1")) {
0301                                                     id = attributesSubOp.at(1);
0302                                                     if (id != QStringLiteral("-1")) {
0303                                                         err = subop.setCategory(mapCategory[id]);
0304                                                     }
0305                                                 } else {
0306                                                     err = subop.setCategory(mapSubCategory[id]);
0307                                                 }
0308                                             }
0309                                             IFOK(err) {
0310                                                 double q = SKGServices::stringToDouble(attributesSubOp.at(3));
0311                                                 if (attributes.at(4) == QStringLiteral("Withdrawal") || idTarget != QStringLiteral("-1")) {
0312                                                     q = -q;
0313                                                 }
0314                                                 err = subop.setQuantity(q);
0315                                             }
0316                                             IFOKDO(err, subop.save())
0317                                         }
0318                                     }
0319                                 }
0320                             }
0321 
0322                             // Case Transfer
0323                             if (!err && idTarget != QStringLiteral("-1")) {
0324                                 SKGOperationObject op2;
0325                                 err = op.duplicate(op2, op.getDate());
0326                                 IFOKDO(err, op2.setStatus(op.getStatus()))
0327                                 IFOKDO(err, op2.bookmark(op.isBookmarked()))
0328                                 IFOKDO(err, op2.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
0329                                 IFOKDO(err, op2.setImportID("MMEX-" % attributes.at(0) % "_TR"))
0330                                 IFOKDO(err, op2.save())
0331 
0332                                 SKGObjectBase::SKGListSKGObjectBase subops;
0333                                 IFOKDO(err, op.getSubOperations(subops))
0334                                 if (!err && !subops.isEmpty()) {
0335                                     SKGSubOperationObject subop2(subops.at(0));
0336                                     err = subop2.setQuantity(-subop2.getQuantity());
0337                                     IFOKDO(err, subop2.save())
0338                                 }
0339                                 IFOKDO(err, op.setParentAccount(mapAccount[idTarget]))
0340                                 IFOKDO(err, op.setGroupOperation(op2))
0341                                 IFOKDO(err, op.save())
0342                             }
0343 
0344                             // Create recurrent transaction
0345                             if (recurrent) {
0346                                 SKGRecurrentOperationObject recu;
0347                                 IFOKDO(err, op.addRecurrentOperation(recu))
0348                                 IFOKDO(err, recu.setDate(SKGServices::stringToTime(attributes.at(15)).date()))
0349                                 int nbTimes = SKGServices::stringToInt(attributes.at(16));
0350                                 if (!err && nbTimes != -1) {
0351                                     err = recu.setTimeLimit(nbTimes);
0352                                     IFOKDO(err, recu.timeLimit(true))
0353                                 }
0354                                 int repeats = SKGServices::stringToInt(attributes.at(14));
0355                                 IFOK(err) {
0356                                     switch (repeats) {
0357                                     case 1:
0358                                         // Weekly
0359                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
0360                                         IFOKDO(err, recu.setPeriodIncrement(1))
0361                                         break;
0362                                     case 2:
0363                                         // Bi-Weekly
0364                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
0365                                         IFOKDO(err, recu.setPeriodIncrement(2))
0366                                         break;
0367                                     case 3:
0368                                         // Monthly
0369                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
0370                                         IFOKDO(err, recu.setPeriodIncrement(1))
0371                                         break;
0372                                     case 4:
0373                                         // Bi-Monthly
0374                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
0375                                         IFOKDO(err, recu.setPeriodIncrement(2))
0376                                         break;
0377                                     case 5:
0378                                         // Quarterly
0379                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
0380                                         IFOKDO(err, recu.setPeriodIncrement(3))
0381                                         break;
0382                                     case 6:
0383                                         // Half yearly
0384                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
0385                                         IFOKDO(err, recu.setPeriodIncrement(6))
0386                                         break;
0387                                     case 7:
0388                                         // Yearly
0389                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::YEAR);
0390                                         IFOKDO(err, recu.setPeriodIncrement(1))
0391                                         break;
0392                                     case 8:
0393                                         // Four months
0394                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
0395                                         IFOKDO(err, recu.setPeriodIncrement(4))
0396                                         break;
0397                                     case 9:
0398                                         // Four weeks
0399                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
0400                                         IFOKDO(err, recu.setPeriodIncrement(4))
0401                                         break;
0402                                     case 10:
0403                                         // Daily
0404                                         err = recu.setPeriodUnit(SKGRecurrentOperationObject::DAY);
0405                                         IFOKDO(err, recu.setPeriodIncrement(1))
0406                                         break;
0407 
0408                                     default:
0409                                         break;
0410                                     }
0411                                 }
0412                                 IFOKDO(err, recu.save(true, false))
0413                             }
0414                             mapOperation[attributes.at(0)] = op;
0415                         }
0416 
0417                         IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0418                     }
0419 
0420                     SKGENDTRANSACTION(m_importer->getDocument(),  err)
0421                 }
0422             }
0423             IFOKDO(err, m_importer->getDocument()->stepForward(6))
0424 
0425             // Step 7 - stock
0426             IFOK(err) {
0427                 SKGStringListList listStock;
0428                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT STOCKID, HELDAT, PURCHASEDATE, STOCKNAME, SYMBOL, NUMSHARES, PURCHASEPRICE, NOTES, CURRENTPRICE, VALUE, COMMISSION FROM STOCK_V1"), listStock);
0429                 IFOK(err) {
0430                     int nb = listStock.count() - 1;
0431                     err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import stocks"), nb);
0432                     for (int i = 0; !err && i < nb; ++i) {
0433                         const QStringList& attributes = listStock.at(i + 1);
0434 
0435                         // Create unit
0436                         SKGUnitObject unit(m_importer->getDocument());
0437                         err = unit.setName(attributes.at(3));
0438                         IFOKDO(err, unit.setSymbol(attributes.at(4)))
0439                         IFOKDO(err, unit.setType(SKGUnitObject::SHARE))
0440                         IFOKDO(err, unit.save())
0441 
0442                         SKGUnitValueObject unitValue;
0443                         IFOKDO(err, unit.addUnitValue(unitValue))
0444                         IFOKDO(err, unitValue.setDate(SKGServices::stringToTime(attributes.at(2)).date()))
0445                         IFOKDO(err, unitValue.setQuantity(SKGServices::stringToDouble(attributes.at(6))))
0446                         IFOKDO(err, unitValue.save(true, false))
0447 
0448                         SKGUnitValueObject unitValue2;
0449                         IFOKDO(err, unit.addUnitValue(unitValue2))
0450                         IFOKDO(err, unitValue2.setDate(QDate::currentDate()))
0451                         IFOKDO(err, unitValue2.setQuantity(SKGServices::stringToDouble(attributes.at(8))))
0452                         IFOKDO(err, unitValue2.save(true, false))
0453 
0454                         // Create operation
0455                         SKGAccountObject acc = mapAccount[attributes.at(1)];
0456                         SKGUnitObject unitCurrency;
0457                         IFOKDO(err, acc.getUnit(unitCurrency))
0458 
0459                         SKGOperationObject op;
0460                         IFOKDO(err, acc.addOperation(op, true))
0461                         IFOKDO(err, op.setComment(attributes.at(7)))
0462                         IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(2)).date()))
0463                         IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
0464                         IFOKDO(err, op.setImportID("MMEX-STOCK-" % attributes.at(0)))
0465                         IFOKDO(err, op.setUnit(unit))
0466                         IFOKDO(err, op.save())
0467 
0468                         SKGSubOperationObject subop;
0469                         IFOKDO(err, op.addSubOperation(subop))
0470                         IFOKDO(err, subop.setQuantity(SKGServices::stringToDouble(attributes.at(5))))
0471                         IFOKDO(err, subop.save(true, false))
0472 
0473                         /*SKGOperationObject op2;
0474                         if(!err) err = acc.addOperation(op2, true);
0475                         if(!err) err = op2.setComment(attributes.at(7));
0476                         if(!err) err = op2.setDate(SKGServices::stringToTime(attributes.at(2)).date());
0477                         if(!err) err = op2.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T"));
0478                         if(!err) err = op2.setImportID("MMEX-STOCK-" % attributes.at(0)% "_TR");
0479                         if(!err) err = op2.setUnit(unitCurrency);
0480                         if(!err) err = op2.save();
0481 
0482                         SKGSubOperationObject subop2;
0483                         if(!err) err = op2.addSubOperation(subop2);
0484                         if(!err) err = subop2.setQuantity(-SKGServices::stringToDouble(attributes.at(5))*SKGServices::stringToDouble(attributes.at(6)));
0485                         if(!err) err = subop2.save();
0486 
0487                         if(!err) err = op.setGroupOperation(op2);
0488                         if(!err) err = op.save();*/
0489 
0490                         IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0491                     }
0492 
0493                     SKGENDTRANSACTION(m_importer->getDocument(),  err)
0494                 }
0495             }
0496             IFOKDO(err, m_importer->getDocument()->stepForward(7))
0497 
0498             // Step 8 - asset
0499             IFOK(err) {
0500                 SKGStringListList listAssets;
0501                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT ASSETID, STARTDATE, ASSETNAME, VALUE, VALUECHANGE, NOTES, VALUECHANGERATE, ASSETTYPE FROM ASSETS_V1"), listAssets);
0502                 IFOK(err) {
0503                     int nb = listAssets.count() - 1;
0504                     if (nb != 0) {
0505                         // Create account
0506                         // Create bank
0507                         SKGBankObject bank(m_importer->getDocument());
0508                         IFOKDO(err, bank.setName(QStringLiteral("MMEX")))
0509                         IFOKDO(err, bank.save())
0510 
0511                         // Create account
0512                         SKGAccountObject account;
0513                         err = bank.addAccount(account);
0514                         IFOKDO(err, account.setName(i18nc("Noun, a type of account", "Assets")))
0515                         IFOKDO(err, account.setType(SKGAccountObject::ASSETS))
0516                         IFOKDO(err, account.save())
0517 
0518                         err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import assets"), nb);
0519                         for (int i = 0; !err && i < nb; ++i) {
0520                             const QStringList& attributes = listAssets.at(i + 1);
0521 
0522                             // Create unit
0523                             SKGUnitObject unit(m_importer->getDocument());
0524                             err = unit.setName(attributes.at(2));
0525                             IFOKDO(err, unit.setSymbol(attributes.at(2)))
0526                             IFOKDO(err, unit.setType(SKGUnitObject::OBJECT))
0527                             IFOKDO(err, unit.setInternetCode(QStringLiteral("=") % (attributes.at(4) == QStringLiteral("Depreciates") ? QStringLiteral("-") : QStringLiteral("+")) % attributes.at(6)))
0528                             IFOKDO(err, unit.save())
0529 
0530                             SKGUnitValueObject unitValue;
0531                             IFOKDO(err, unit.addUnitValue(unitValue))
0532                             IFOKDO(err, unitValue.setDate(SKGServices::stringToTime(attributes.at(1)).date()))
0533                             IFOKDO(err, unitValue.setQuantity(SKGServices::stringToDouble(attributes.at(3))))
0534                             IFOKDO(err, unitValue.save(true, false))
0535 
0536                             // Create operation
0537                             SKGOperationObject op;
0538                             IFOKDO(err, account.addOperation(op, true))
0539                             IFOKDO(err, op.setComment(attributes.at(5)))
0540                             IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(1)).date()))
0541                             IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
0542                             IFOKDO(err, op.setImportID("MMEX-ASSET-" % attributes.at(0)))
0543                             IFOKDO(err, op.setUnit(unit))
0544                             IFOKDO(err, op.save())
0545 
0546                             SKGSubOperationObject subop;
0547                             IFOKDO(err, op.addSubOperation(subop))
0548                             IFOKDO(err, subop.setQuantity(1.0))
0549                             IFOKDO(err, subop.save(true, false))
0550 
0551                             IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0552                         }
0553 
0554                         SKGENDTRANSACTION(m_importer->getDocument(),  err)
0555                     }
0556                 }
0557             }
0558             IFOKDO(err, m_importer->getDocument()->stepForward(8))
0559 
0560             // Step 9 - budgets
0561             IFOK(err) {
0562                 SKGStringListList listBudgets;
0563                 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT BUDGETENTRYID, (SELECT Y.BUDGETYEARNAME FROM BUDGETYEAR_V1 Y WHERE Y.BUDGETYEARID=BUDGETTABLE_V1.BUDGETYEARID), CATEGID, SUBCATEGID, PERIOD, AMOUNT FROM BUDGETTABLE_V1"), listBudgets);
0564                 IFOK(err) {
0565                     int nb = listBudgets.count() - 1;
0566                     err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import budgets"), nb);
0567                     for (int i = 0; !err && i < nb; ++i) {
0568                         const QStringList& attributes = listBudgets.at(i + 1);
0569 
0570                         const QString& period = attributes.at(4);
0571 
0572                         int step = 0;
0573                         double coef = 0;
0574                         if (period == QStringLiteral("Weekly")) {
0575                             coef = 52.0 / 12.0;
0576                             step = 1;
0577                         } else if (period == QStringLiteral("Monthly")) {
0578                             coef = 1;
0579                             step = 1;
0580                         } else if (period == QStringLiteral("Bi-Weekly")) {
0581                             coef = 52.0 / 12.0 / 2.0;
0582                             step = 1;
0583                         } else if (period == QStringLiteral("Bi-Monthly")) {
0584                             coef = 1;
0585                             step = 2;
0586                         } else if (period == QStringLiteral("Quarterly")) {
0587                             coef = 1;
0588                             step = 4;
0589                         } else if (period == QStringLiteral("Half-Yearly")) {
0590                             coef = 1;
0591                             step = 6;
0592                         } else if (period == QStringLiteral("Yearly")) {
0593                             coef = 1;
0594                             step = 12;
0595                         }
0596 
0597                         if (step != 0) {
0598                             for (int j = 0; !err && j < 12; j = j + step) {
0599                                 SKGBudgetObject bug(m_importer->getDocument());
0600                                 err = bug.setYear(SKGServices::stringToInt(attributes.at(1)));
0601                                 IFOKDO(err, bug.setMonth(step == 12 ? 0 : j + 1))
0602                                 IFOK(err) {
0603                                     QString id = attributes.at(3);
0604                                     if (id == QStringLiteral("-1")) {
0605                                         id = attributes.at(2);
0606                                         if (id != QStringLiteral("-1")) {
0607                                             err = bug.setCategory(mapCategory[id]);
0608                                         }
0609                                     } else {
0610                                         err = bug.setCategory(mapSubCategory[id]);
0611                                     }
0612                                 }
0613                                 IFOKDO(err, bug.setBudgetedAmount(coef * SKGServices::stringToDouble(attributes.at(5))))
0614                                 IFOKDO(err, bug.save())
0615                             }
0616                         }
0617 
0618                         IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
0619                     }
0620 
0621                     SKGENDTRANSACTION(m_importer->getDocument(),  err)
0622                 }
0623             }
0624             IFOKDO(err, m_importer->getDocument()->stepForward(9))
0625 
0626             SKGENDTRANSACTION(m_importer->getDocument(),  err)
0627 
0628             IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE")))
0629         }
0630         originalDocument.close();
0631     }
0632     QSqlDatabase::removeDatabase(QStringLiteral("originalDocument"));
0633     return err;
0634 }
0635 
0636 QString SKGImportPluginMmb::getMimeTypeFilter() const
0637 {
0638     return "*.mmb|" % i18nc("A file format", "Money Manager Ex document");
0639 }
0640 
0641 #include <skgimportpluginmmb.moc>