1 /***************************************************************************
2 * SPDX-FileCopyrightText: 2021 S. MANKOWSKI stephane@mankowski.fr
3 * SPDX-FileCopyrightText: 2021 G. DE BURE support@mankowski.fr
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 ***************************************************************************/
6 /** @file
7 * This file is Skrooge plugin for MMB import / export.
8 *
9 * @author Stephane MANKOWSKI / Guillaume DE BURE
10 */
11 #include "skgimportpluginmmb.h"
12
13 #include <qfile.h>
14 #include <qsqldatabase.h>
15 #include <qsqlerror.h>
16
17 #include <klocalizedstring.h>
18 #include <kpluginfactory.h>
19
20 #include "skgbankincludes.h"
21 #include "skgimportexportmanager.h"
22 #include "skgobjectbase.h"
23 #include "skgservices.h"
24 #include "skgtraces.h"
25
26 /**
27 * This plugin factory.
28 */
K_PLUGIN_FACTORY(SKGImportPluginMmbFactory,registerPlugin<SKGImportPluginMmb> ();)29 K_PLUGIN_FACTORY(SKGImportPluginMmbFactory, registerPlugin<SKGImportPluginMmb>();)
30
31 SKGImportPluginMmb::SKGImportPluginMmb(QObject* iImporter, const QVariantList& iArg)
32 : SKGImportPlugin(iImporter)
33 {
34 SKGTRACEINFUNC(10)
35 Q_UNUSED(iArg)
36 }
37
38 SKGImportPluginMmb::~SKGImportPluginMmb()
39 = default;
40
isImportPossible()41 bool SKGImportPluginMmb::isImportPossible()
42 {
43 SKGTRACEINFUNC(10)
44 return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("MMB"));
45 }
46
importFile()47 SKGError SKGImportPluginMmb::importFile()
48 {
49 if (m_importer == nullptr) {
50 return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
51 }
52 SKGError err;
53 SKGTRACEINFUNCRC(2, err)
54
55 {
56 QSqlDatabase originalDocument(QSqlDatabase::addDatabase(QStringLiteral("SKGSQLCIPHER"), QStringLiteral("originalDocument")));
57 originalDocument.setDatabaseName(m_importer->getLocalFileName());
58 if (!originalDocument.open()) {
59 // Set error message
60 QSqlError sqlErr = originalDocument.lastError();
61 err = SKGError(SQLLITEERROR + sqlErr.nativeErrorCode().toInt(), sqlErr.text());
62 }
63 IFOK(err) {
64 QMap<QString, SKGUnitObject> mapUnit;
65 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "MMB"), 9);
66
67 // Step 1 - units
68 IFOK(err) {
69 SKGStringListList listUnits;
70 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT CURRENCYID, CURRENCYNAME, PFX_SYMBOL, SFX_SYMBOL, DECIMAL_POINT, GROUP_SEPARATOR, UNIT_NAME, CENT_NAME, SCALE, BASECONVRATE, CURRENCY_SYMBOL, "
71 "(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);
72 IFOK(err) {
73 int nb = listUnits.count() - 1;
74 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
75 for (int i = 0; !err && i < nb; ++i) {
76 const QStringList& attributes = listUnits.at(i + 1);
77
78 SKGUnitObject unit(m_importer->getDocument());
79 err = unit.setName(attributes.at(1));
80 IFOK(err) {
81 QString symbol = attributes.at(2);
82 if (symbol.isEmpty()) {
83 symbol = attributes.at(3);
84 }
85 err = unit.setSymbol(symbol);
86 }
87 if (!err && attributes.at(11) == QStringLiteral("Y")) {
88 err = unit.setType(SKGUnitObject::PRIMARY);
89 }
90 IFOKDO(err, unit.save())
91
92 mapUnit[attributes.at(0)] = unit;
93
94 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
95 }
96
97 SKGENDTRANSACTION(m_importer->getDocument(), err)
98 }
99 }
100 IFOKDO(err, m_importer->getDocument()->stepForward(1))
101
102 // Step 2 - bank and accounts
103 QMap<QString, SKGAccountObject> mapAccount;
104 IFOK(err) {
105 SKGStringListList listAccounts;
106 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT ACCOUNTID, ACCOUNTNAME, ACCOUNTTYPE, ACCOUNTNUM, STATUS, NOTES, HELDAT, WEBSITE, CONTACTINFO, ACCESSINFO, INITIALBAL, FAVORITEACCT, CURRENCYID FROM ACCOUNTLIST_V1"), listAccounts);
107 IFOK(err) {
108 int nb = listAccounts.count() - 1;
109 IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import banks and accounts"), nb))
110 for (int i = 0; !err && i < nb; ++i) {
111 const QStringList& attributes = listAccounts.at(i + 1);
112
113 // Create bank
114 SKGBankObject bank(m_importer->getDocument());
115 IFOK(err) {
116 QString bankName = attributes.at(6);
117 if (bankName.isEmpty()) {
118 bankName = QStringLiteral("MMEX");
119 }
120 err = bank.setName(bankName);
121 }
122 IFOKDO(err, bank.save())
123
124 // Create account
125 SKGAccountObject account;
126 err = bank.addAccount(account);
127 IFOKDO(err, account.setName(attributes.at(1)))
128 IFOKDO(err, account.setType(attributes.at(2) == QStringLiteral("Checking") ? SKGAccountObject::CURRENT : SKGAccountObject::INVESTMENT))
129 IFOKDO(err, account.setNumber(attributes.at(3)))
130 IFOKDO(err, account.setComment(attributes.at(5)))
131 IFOKDO(err, account.setAgencyAddress(attributes.at(8)))
132 IFOKDO(err, account.bookmark(attributes.at(11) == QStringLiteral("TRUE")))
133 IFOKDO(err, account.setClosed(attributes.at(4) != QStringLiteral("Open")))
134 IFOKDO(err, account.save())
135 IFOKDO(err, account.setInitialBalance(SKGServices::stringToDouble(attributes.at(10)), mapUnit[attributes.at(12)]))
136 IFOKDO(err, account.save())
137
138 mapAccount[attributes.at(0)] = account;
139
140 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
141 }
142
143 SKGENDTRANSACTION(m_importer->getDocument(), err)
144 }
145 }
146 IFOKDO(err, m_importer->getDocument()->stepForward(2))
147
148 // Step 3 - categories
149 QMap<QString, SKGCategoryObject> mapCategory;
150 IFOK(err) {
151 SKGStringListList listCategories;
152 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT CATEGID, CATEGNAME FROM CATEGORY_V1"), listCategories);
153 IFOK(err) {
154 int nb = listCategories.count() - 1;
155 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
156 for (int i = 0; !err && i < nb; ++i) {
157 const QStringList& attributes = listCategories.at(i + 1);
158
159 SKGCategoryObject cat(m_importer->getDocument());
160 err = cat.setName(attributes.at(1));
161 IFOKDO(err, cat.save())
162
163 mapCategory[attributes.at(0)] = cat;
164
165 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
166 }
167
168 SKGENDTRANSACTION(m_importer->getDocument(), err)
169 }
170 }
171 IFOKDO(err, m_importer->getDocument()->stepForward(3))
172
173 // Step 4 - sub categories
174 QMap<QString, SKGCategoryObject> mapSubCategory;
175 IFOK(err) {
176 SKGStringListList listCategories;
177 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT SUBCATEGID, SUBCATEGNAME, CATEGID FROM SUBCATEGORY_V1"), listCategories);
178 IFOK(err) {
179 int nb = listCategories.count() - 1;
180 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
181 for (int i = 0; !err && i < nb; ++i) {
182 const QStringList& attributes = listCategories.at(i + 1);
183
184 SKGCategoryObject cat(m_importer->getDocument());
185 err = cat.setName(attributes.at(1));
186 IFOKDO(err, cat.setParentCategory(mapCategory[attributes.at(2)]))
187 IFOKDO(err, cat.save())
188
189 mapSubCategory[attributes.at(0)] = cat;
190
191 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
192 }
193
194 SKGENDTRANSACTION(m_importer->getDocument(), err)
195 }
196 }
197 IFOKDO(err, m_importer->getDocument()->stepForward(4))
198
199 // Step 5 - payee
200 QMap<QString, SKGPayeeObject> mapPayee;
201 IFOK(err) {
202 SKGStringListList listPayee;
203 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT PAYEEID, PAYEENAME FROM PAYEE_V1"), listPayee);
204 IFOK(err) {
205 int nb = listPayee.count() - 1;
206 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payees"), nb);
207 for (int i = 0; !err && i < nb; ++i) {
208 const QStringList& attributes = listPayee.at(i + 1);
209
210 SKGPayeeObject payee(m_importer->getDocument());
211 err = payee.setName(attributes.at(1));
212 IFOKDO(err, payee.save())
213
214 mapPayee[attributes.at(0)] = payee;
215
216 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
217 }
218
219 SKGENDTRANSACTION(m_importer->getDocument(), err)
220 }
221 }
222 IFOKDO(err, m_importer->getDocument()->stepForward(5))
223
224 // Step 6 - operations
225 QMap<QString, SKGOperationObject> mapOperation;
226 IFOK(err) {
227 SKGStringListList listOperations;
228 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT * FROM ("
229 "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 "
230 "SELECT BDID, ACCOUNTID, TOACCOUNTID, PAYEEID, TRANSCODE, TRANSAMOUNT, STATUS, TRANSACTIONNUMBER, NOTES, CATEGID, SUBCATEGID, TRANSDATE, FOLLOWUPID, TOTRANSAMOUNT, REPEATS, NEXTOCCURRENCEDATE, NUMOCCURRENCES FROM BILLSDEPOSITS_V1)"), listOperations);
231 IFOK(err) {
232 int nb = listOperations.count() - 1;
233 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
234 for (int i = 0; !err && i < nb; ++i) {
235 const QStringList& attributes = listOperations.at(i + 1);
236 if (attributes.at(6) != QStringLiteral("V")) { // Void
237 bool recurrent = (attributes.at(14) != QStringLiteral("N/A"));
238 const QString& idTarget = attributes.at(2);
239 SKGAccountObject acc = mapAccount[attributes.at(1)];
240 SKGUnitObject unit;
241 IFOKDO(err, acc.getUnit(unit))
242
243 SKGOperationObject op;
244 IFOKDO(err, acc.addOperation(op, true))
245 IFOK(err) {
246 const QString& id = attributes.at(3);
247 if (id != QStringLiteral("-1")) {
248 err = op.setPayee(mapPayee[id]);
249 }
250 }
251 IFOKDO(err, op.setNumber(attributes.at(7)))
252 IFOKDO(err, op.setComment(attributes.at(8)))
253 IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(11)).date()))
254 IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
255 IFOKDO(err, op.setImportID("MMEX-" % attributes.at(0)))
256 IFOKDO(err, op.setUnit(unit))
257 IFOKDO(err, op.bookmark(attributes.at(6) == QStringLiteral("F")))
258 IFOKDO(err, op.setTemplate(recurrent))
259 IFOKDO(err, op.setStatus(attributes.at(6) == QStringLiteral("R") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE))
260 IFOKDO(err, op.save())
261
262 // Get splits
263 IFOK(err) {
264 SKGStringListList listSubOperations;
265 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT SPLITTRANSID, CATEGID, SUBCATEGID, SPLITTRANSAMOUNT FROM ") % (recurrent ? "BUDGET" : "") % "SPLITTRANSACTIONS_V1 WHERE TRANSID=" % attributes.at(0), listSubOperations);
266 IFOK(err) {
267 int nb2 = listSubOperations.count() - 1;
268 if (nb2 <= 0) {
269 // No split
270 SKGSubOperationObject subop;
271 IFOKDO(err, op.addSubOperation(subop))
272 IFOK(err) {
273 QString id = attributes.at(10);
274 if (id == QStringLiteral("-1")) {
275 id = attributes.at(9);
276 if (id != QStringLiteral("-1")) {
277 err = subop.setCategory(mapSubCategory[id]);
278 }
279 } else {
280 err = subop.setCategory(mapCategory[id]);
281 }
282 }
283 IFOK(err) {
284 double q = SKGServices::stringToDouble(attributes.at(5));
285 if (attributes.at(4) == QStringLiteral("Withdrawal") || idTarget != QStringLiteral("-1")) {
286 q = -q;
287 }
288 err = subop.setQuantity(q);
289 }
290 IFOKDO(err, subop.save())
291 } else {
292 // Has splits
293 for (int j = 0; !err && j < nb2; ++j) {
294 const QStringList& attributesSubOp = listSubOperations.at(j + 1);
295
296 SKGSubOperationObject subop;
297 IFOKDO(err, op.addSubOperation(subop))
298 IFOK(err) {
299 QString id = attributesSubOp.at(2);
300 if (id == QStringLiteral("-1")) {
301 id = attributesSubOp.at(1);
302 if (id != QStringLiteral("-1")) {
303 err = subop.setCategory(mapCategory[id]);
304 }
305 } else {
306 err = subop.setCategory(mapSubCategory[id]);
307 }
308 }
309 IFOK(err) {
310 double q = SKGServices::stringToDouble(attributesSubOp.at(3));
311 if (attributes.at(4) == QStringLiteral("Withdrawal") || idTarget != QStringLiteral("-1")) {
312 q = -q;
313 }
314 err = subop.setQuantity(q);
315 }
316 IFOKDO(err, subop.save())
317 }
318 }
319 }
320 }
321
322 // Case Transfer
323 if (!err && idTarget != QStringLiteral("-1")) {
324 SKGOperationObject op2;
325 err = op.duplicate(op2, op.getDate());
326 IFOKDO(err, op2.setStatus(op.getStatus()))
327 IFOKDO(err, op2.bookmark(op.isBookmarked()))
328 IFOKDO(err, op2.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
329 IFOKDO(err, op2.setImportID("MMEX-" % attributes.at(0) % "_TR"))
330 IFOKDO(err, op2.save())
331
332 SKGObjectBase::SKGListSKGObjectBase subops;
333 IFOKDO(err, op.getSubOperations(subops))
334 if (!err && !subops.isEmpty()) {
335 SKGSubOperationObject subop2(subops.at(0));
336 err = subop2.setQuantity(-subop2.getQuantity());
337 IFOKDO(err, subop2.save())
338 }
339 IFOKDO(err, op.setParentAccount(mapAccount[idTarget]))
340 IFOKDO(err, op.setGroupOperation(op2))
341 IFOKDO(err, op.save())
342 }
343
344 // Create recurrent transaction
345 if (recurrent) {
346 SKGRecurrentOperationObject recu;
347 IFOKDO(err, op.addRecurrentOperation(recu))
348 IFOKDO(err, recu.setDate(SKGServices::stringToTime(attributes.at(15)).date()))
349 int nbTimes = SKGServices::stringToInt(attributes.at(16));
350 if (!err && nbTimes != -1) {
351 err = recu.setTimeLimit(nbTimes);
352 IFOKDO(err, recu.timeLimit(true))
353 }
354 int repeats = SKGServices::stringToInt(attributes.at(14));
355 IFOK(err) {
356 switch (repeats) {
357 case 1:
358 // Weekly
359 err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
360 IFOKDO(err, recu.setPeriodIncrement(1))
361 break;
362 case 2:
363 // Bi-Weekly
364 err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
365 IFOKDO(err, recu.setPeriodIncrement(2))
366 break;
367 case 3:
368 // Monthly
369 err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
370 IFOKDO(err, recu.setPeriodIncrement(1))
371 break;
372 case 4:
373 // Bi-Monthly
374 err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
375 IFOKDO(err, recu.setPeriodIncrement(2))
376 break;
377 case 5:
378 // Quarterly
379 err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
380 IFOKDO(err, recu.setPeriodIncrement(3))
381 break;
382 case 6:
383 // Half yearly
384 err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
385 IFOKDO(err, recu.setPeriodIncrement(6))
386 break;
387 case 7:
388 // Yearly
389 err = recu.setPeriodUnit(SKGRecurrentOperationObject::YEAR);
390 IFOKDO(err, recu.setPeriodIncrement(1))
391 break;
392 case 8:
393 // Four months
394 err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
395 IFOKDO(err, recu.setPeriodIncrement(4))
396 break;
397 case 9:
398 // Four weeks
399 err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
400 IFOKDO(err, recu.setPeriodIncrement(4))
401 break;
402 case 10:
403 // Daily
404 err = recu.setPeriodUnit(SKGRecurrentOperationObject::DAY);
405 IFOKDO(err, recu.setPeriodIncrement(1))
406 break;
407
408 default:
409 break;
410 }
411 }
412 IFOKDO(err, recu.save(true, false))
413 }
414 mapOperation[attributes.at(0)] = op;
415 }
416
417 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
418 }
419
420 SKGENDTRANSACTION(m_importer->getDocument(), err)
421 }
422 }
423 IFOKDO(err, m_importer->getDocument()->stepForward(6))
424
425 // Step 7 - stock
426 IFOK(err) {
427 SKGStringListList listStock;
428 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT STOCKID, HELDAT, PURCHASEDATE, STOCKNAME, SYMBOL, NUMSHARES, PURCHASEPRICE, NOTES, CURRENTPRICE, VALUE, COMMISSION FROM STOCK_V1"), listStock);
429 IFOK(err) {
430 int nb = listStock.count() - 1;
431 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import stocks"), nb);
432 for (int i = 0; !err && i < nb; ++i) {
433 const QStringList& attributes = listStock.at(i + 1);
434
435 // Create unit
436 SKGUnitObject unit(m_importer->getDocument());
437 err = unit.setName(attributes.at(3));
438 IFOKDO(err, unit.setSymbol(attributes.at(4)))
439 IFOKDO(err, unit.setType(SKGUnitObject::SHARE))
440 IFOKDO(err, unit.save())
441
442 SKGUnitValueObject unitValue;
443 IFOKDO(err, unit.addUnitValue(unitValue))
444 IFOKDO(err, unitValue.setDate(SKGServices::stringToTime(attributes.at(2)).date()))
445 IFOKDO(err, unitValue.setQuantity(SKGServices::stringToDouble(attributes.at(6))))
446 IFOKDO(err, unitValue.save(true, false))
447
448 SKGUnitValueObject unitValue2;
449 IFOKDO(err, unit.addUnitValue(unitValue2))
450 IFOKDO(err, unitValue2.setDate(QDate::currentDate()))
451 IFOKDO(err, unitValue2.setQuantity(SKGServices::stringToDouble(attributes.at(8))))
452 IFOKDO(err, unitValue2.save(true, false))
453
454 // Create operation
455 SKGAccountObject acc = mapAccount[attributes.at(1)];
456 SKGUnitObject unitCurrency;
457 IFOKDO(err, acc.getUnit(unitCurrency))
458
459 SKGOperationObject op;
460 IFOKDO(err, acc.addOperation(op, true))
461 IFOKDO(err, op.setComment(attributes.at(7)))
462 IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(2)).date()))
463 IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
464 IFOKDO(err, op.setImportID("MMEX-STOCK-" % attributes.at(0)))
465 IFOKDO(err, op.setUnit(unit))
466 IFOKDO(err, op.save())
467
468 SKGSubOperationObject subop;
469 IFOKDO(err, op.addSubOperation(subop))
470 IFOKDO(err, subop.setQuantity(SKGServices::stringToDouble(attributes.at(5))))
471 IFOKDO(err, subop.save(true, false))
472
473 /*SKGOperationObject op2;
474 if(!err) err = acc.addOperation(op2, true);
475 if(!err) err = op2.setComment(attributes.at(7));
476 if(!err) err = op2.setDate(SKGServices::stringToTime(attributes.at(2)).date());
477 if(!err) err = op2.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T"));
478 if(!err) err = op2.setImportID("MMEX-STOCK-" % attributes.at(0)% "_TR");
479 if(!err) err = op2.setUnit(unitCurrency);
480 if(!err) err = op2.save();
481
482 SKGSubOperationObject subop2;
483 if(!err) err = op2.addSubOperation(subop2);
484 if(!err) err = subop2.setQuantity(-SKGServices::stringToDouble(attributes.at(5))*SKGServices::stringToDouble(attributes.at(6)));
485 if(!err) err = subop2.save();
486
487 if(!err) err = op.setGroupOperation(op2);
488 if(!err) err = op.save();*/
489
490 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
491 }
492
493 SKGENDTRANSACTION(m_importer->getDocument(), err)
494 }
495 }
496 IFOKDO(err, m_importer->getDocument()->stepForward(7))
497
498 // Step 8 - asset
499 IFOK(err) {
500 SKGStringListList listAssets;
501 err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT ASSETID, STARTDATE, ASSETNAME, VALUE, VALUECHANGE, NOTES, VALUECHANGERATE, ASSETTYPE FROM ASSETS_V1"), listAssets);
502 IFOK(err) {
503 int nb = listAssets.count() - 1;
504 if (nb != 0) {
505 // Create account
506 // Create bank
507 SKGBankObject bank(m_importer->getDocument());
508 IFOKDO(err, bank.setName(QStringLiteral("MMEX")))
509 IFOKDO(err, bank.save())
510
511 // Create account
512 SKGAccountObject account;
513 err = bank.addAccount(account);
514 IFOKDO(err, account.setName(i18nc("Noun, a type of account", "Assets")))
515 IFOKDO(err, account.setType(SKGAccountObject::ASSETS))
516 IFOKDO(err, account.save())
517
518 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import assets"), nb);
519 for (int i = 0; !err && i < nb; ++i) {
520 const QStringList& attributes = listAssets.at(i + 1);
521
522 // Create unit
523 SKGUnitObject unit(m_importer->getDocument());
524 err = unit.setName(attributes.at(2));
525 IFOKDO(err, unit.setSymbol(attributes.at(2)))
526 IFOKDO(err, unit.setType(SKGUnitObject::OBJECT))
527 IFOKDO(err, unit.setInternetCode(QStringLiteral("=") % (attributes.at(4) == QStringLiteral("Depreciates") ? QStringLiteral("-") : QStringLiteral("+")) % attributes.at(6)))
528 IFOKDO(err, unit.save())
529
530 SKGUnitValueObject unitValue;
531 IFOKDO(err, unit.addUnitValue(unitValue))
532 IFOKDO(err, unitValue.setDate(SKGServices::stringToTime(attributes.at(1)).date()))
533 IFOKDO(err, unitValue.setQuantity(SKGServices::stringToDouble(attributes.at(3))))
534 IFOKDO(err, unitValue.save(true, false))
535
536 // Create operation
537 SKGOperationObject op;
538 IFOKDO(err, account.addOperation(op, true))
539 IFOKDO(err, op.setComment(attributes.at(5)))
540 IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(1)).date()))
541 IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
542 IFOKDO(err, op.setImportID("MMEX-ASSET-" % attributes.at(0)))
543 IFOKDO(err, op.setUnit(unit))
544 IFOKDO(err, op.save())
545
546 SKGSubOperationObject subop;
547 IFOKDO(err, op.addSubOperation(subop))
548 IFOKDO(err, subop.setQuantity(1.0))
549 IFOKDO(err, subop.save(true, false))
550
551 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
552 }
553
554 SKGENDTRANSACTION(m_importer->getDocument(), err)
555 }
556 }
557 }
558 IFOKDO(err, m_importer->getDocument()->stepForward(8))
559
560 // Step 9 - budgets
561 IFOK(err) {
562 SKGStringListList listBudgets;
563 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);
564 IFOK(err) {
565 int nb = listBudgets.count() - 1;
566 err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import budgets"), nb);
567 for (int i = 0; !err && i < nb; ++i) {
568 const QStringList& attributes = listBudgets.at(i + 1);
569
570 const QString& period = attributes.at(4);
571
572 int step = 0;
573 double coef = 0;
574 if (period == QStringLiteral("Weekly")) {
575 coef = 52.0 / 12.0;
576 step = 1;
577 } else if (period == QStringLiteral("Monthly")) {
578 coef = 1;
579 step = 1;
580 } else if (period == QStringLiteral("Bi-Weekly")) {
581 coef = 52.0 / 12.0 / 2.0;
582 step = 1;
583 } else if (period == QStringLiteral("Bi-Monthly")) {
584 coef = 1;
585 step = 2;
586 } else if (period == QStringLiteral("Quarterly")) {
587 coef = 1;
588 step = 4;
589 } else if (period == QStringLiteral("Half-Yearly")) {
590 coef = 1;
591 step = 6;
592 } else if (period == QStringLiteral("Yearly")) {
593 coef = 1;
594 step = 12;
595 }
596
597 if (step != 0) {
598 for (int j = 0; !err && j < 12; j = j + step) {
599 SKGBudgetObject bug(m_importer->getDocument());
600 err = bug.setYear(SKGServices::stringToInt(attributes.at(1)));
601 IFOKDO(err, bug.setMonth(step == 12 ? 0 : j + 1))
602 IFOK(err) {
603 QString id = attributes.at(3);
604 if (id == QStringLiteral("-1")) {
605 id = attributes.at(2);
606 if (id != QStringLiteral("-1")) {
607 err = bug.setCategory(mapCategory[id]);
608 }
609 } else {
610 err = bug.setCategory(mapSubCategory[id]);
611 }
612 }
613 IFOKDO(err, bug.setBudgetedAmount(coef * SKGServices::stringToDouble(attributes.at(5))))
614 IFOKDO(err, bug.save())
615 }
616 }
617
618 IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
619 }
620
621 SKGENDTRANSACTION(m_importer->getDocument(), err)
622 }
623 }
624 IFOKDO(err, m_importer->getDocument()->stepForward(9))
625
626 SKGENDTRANSACTION(m_importer->getDocument(), err)
627
628 IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE")))
629 }
630 originalDocument.close();
631 }
632 QSqlDatabase::removeDatabase(QStringLiteral("originalDocument"));
633 return err;
634 }
635
getMimeTypeFilter() const636 QString SKGImportPluginMmb::getMimeTypeFilter() const
637 {
638 return "*.mmb|" % i18nc("A file format", "Money Manager Ex document");
639 }
640
641 #include <skgimportpluginmmb.moc>
642