1 /*
2 * Copyright 2002-2019 Thomas Baumgart <tbaumgart@kde.org>
3 * Copyright 2003 Michael Edwardes <mte@users.sourceforge.net>
4 * Copyright 2004-2006 Ace Jones <acejones@users.sourceforge.net>
5 * Copyright 2004 Kevin Tambascio <ktambascio@users.sourceforge.net>
6 * Copyright 2009-2014 Cristian Oneț <onet.cristian@gmail.com>
7 * Copyright 2012 Alessandro Russo <axela74@yahoo.it>
8 * Copyright 2016 Christian Dávid <christian-david@web.de>
9 * Copyright 2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "mymoneyxmlcontenthandler-test.h"
26
27 #include <QtTest>
28 #include "../mymoneystoragexml.cpp"
29 #include "mymoneyobject_p.h"
30 #include "mymoneyobject.h"
31 #include "mymoneyexception.h"
32
33 QTEST_GUILESS_MAIN(MyMoneyXmlContentHandlerTest)
34
35 class TestMyMoneyObjectPrivate : public MyMoneyObjectPrivate
36 {
37 };
38
39 class TestMyMoneyObject : public MyMoneyObject
40 {
41 Q_DECLARE_PRIVATE(TestMyMoneyObject)
42
43 public:
TestMyMoneyObject()44 TestMyMoneyObject() : MyMoneyObject(*new MyMoneyObjectPrivate) {}
TestMyMoneyObject(const QString & id)45 TestMyMoneyObject(const QString &id) :
46 MyMoneyObject(*new MyMoneyObjectPrivate, id)
47 {
48 }
49
TestMyMoneyObject(const TestMyMoneyObject & other)50 TestMyMoneyObject(const TestMyMoneyObject &other) :
51 MyMoneyObject(*new MyMoneyObjectPrivate(*other.d_func()), other.id())
52 {
53 }
54
TestMyMoneyObject(TestMyMoneyObject && other)55 TestMyMoneyObject(TestMyMoneyObject &&other) : TestMyMoneyObject()
56 {
57 swap(*this, other);
58 }
59
60 TestMyMoneyObject & operator=(TestMyMoneyObject other);
61 friend void swap(TestMyMoneyObject& first, TestMyMoneyObject& second);
~TestMyMoneyObject()62 ~TestMyMoneyObject() final override
63 {
64 }
65
hasReferenceTo(const QString &) const66 bool hasReferenceTo(const QString&) const final override
67 {
68 return false;
69 }
70
readBaseXML(const QDomElement & node,bool forceId=true)71 static TestMyMoneyObject readBaseXML(const QDomElement &node, bool forceId = true)
72 {
73 TestMyMoneyObject obj(node.attribute(QStringLiteral("id")));
74 if (obj.id().isEmpty() && forceId)
75 throw MYMONEYEXCEPTION_CSTRING("Node has no ID");
76 return obj;
77 }
78 };
79
swap(TestMyMoneyObject & first,TestMyMoneyObject & second)80 void swap(TestMyMoneyObject& first, TestMyMoneyObject& second)
81 {
82 using std::swap;
83 swap(first.d_ptr, second.d_ptr);
84 }
85
operator =(TestMyMoneyObject other)86 TestMyMoneyObject & TestMyMoneyObject::operator=(TestMyMoneyObject other)
87 {
88 swap(*this, other);
89 return *this;
90 }
91
92
readMyMoneyObject()93 void MyMoneyXmlContentHandlerTest::readMyMoneyObject()
94 {
95 TestMyMoneyObject t;
96
97 QString ref_ok = QString(
98 "<!DOCTYPE TEST>\n"
99 "<TRANSACTION-CONTAINER>\n"
100 " <MYMONEYOBJECT id=\"T000000000000000001\" >\n"
101 " </MYMONEYOBJECT>\n"
102 "</TRANSACTION-CONTAINER>\n"
103 );
104
105 QString ref_false1 = QString(
106 "<!DOCTYPE TEST>\n"
107 "<TRANSACTION-CONTAINER>\n"
108 " <MYMONEYOBJECT id=\"\" >\n"
109 " </MYMONEYOBJECT>\n"
110 "</TRANSACTION-CONTAINER>\n"
111 );
112
113 QString ref_false2 = QString(
114 "<!DOCTYPE TEST>\n"
115 "<TRANSACTION-CONTAINER>\n"
116 " <MYMONEYOBJECT >\n"
117 " </MYMONEYOBJECT>\n"
118 "</TRANSACTION-CONTAINER>\n"
119 );
120
121 QDomDocument doc;
122 QDomElement node;
123
124 // id="" but required
125 doc.setContent(ref_false1);
126 node = doc.documentElement().firstChild().toElement();
127
128 try {
129 t = TestMyMoneyObject::readBaseXML(node);
130 QFAIL("Missing expected exception");
131 } catch (const MyMoneyException &) {
132 }
133
134 // id attribute missing but required
135 doc.setContent(ref_false2);
136 node = doc.documentElement().firstChild().toElement();
137
138 try {
139 t = TestMyMoneyObject::readBaseXML(node);
140 QFAIL("Missing expected exception");
141 } catch (const MyMoneyException &) {
142 }
143
144 // id present
145 doc.setContent(ref_ok);
146 node = doc.documentElement().firstChild().toElement();
147
148 try {
149 t = TestMyMoneyObject::readBaseXML(node);
150 QVERIFY(t.id() == "T000000000000000001");
151 } catch (const MyMoneyException &) {
152 QFAIL("Unexpected exception");
153 }
154
155 // id="" but not required
156 doc.setContent(ref_false1);
157 node = doc.documentElement().firstChild().toElement();
158
159 try {
160 t = TestMyMoneyObject::readBaseXML(node, false);
161 QVERIFY(t.id().isEmpty());
162 } catch (const MyMoneyException &) {
163 QFAIL("Unexpected exception");
164 }
165 }
166
readKeyValueContainer()167 void MyMoneyXmlContentHandlerTest::readKeyValueContainer()
168 {
169 MyMoneyKeyValueContainer kvp;
170 kvp.setValue("Key", "Value");
171 kvp.setValue("key", "value");
172
173 QString ref_ok(
174 "<!DOCTYPE TEST>\n"
175 "<KVP-CONTAINER>\n"
176 " <KEYVALUEPAIRS>\n"
177 " <PAIR key=\"key\" value=\"Value\" />\n"
178 " <PAIR key=\"Key\" value=\"value\" />\n"
179 " </KEYVALUEPAIRS>\n"
180 "</KVP-CONTAINER>\n");
181
182 QString ref_false(
183 "<!DOCTYPE TEST>\n"
184 "<KVP-CONTAINER>\n"
185 " <KEYVALUE-PAIRS>\n"
186 " <PAIR key=\"key\" value=\"Value\" />\n"
187 " <PAIR key=\"Key\" value=\"value\" />\n"
188 " </KEYVALUE-PAIRS>\n"
189 "</KVP-CONTAINER>\n");
190
191
192 QDomDocument doc;
193 QDomElement node;
194 doc.setContent(ref_false);
195 node = doc.documentElement().firstChild().toElement();
196
197 // make sure, an empty node does not trigger an exception
198 try {
199 QDomElement e;
200 MyMoneyKeyValueContainer k;
201 MyMoneyXmlContentHandler::addToKeyValueContainer(k, e);
202 } catch (const MyMoneyException &) {
203 QFAIL("Unexpected exception");
204 }
205
206 try {
207 MyMoneyKeyValueContainer k;
208 MyMoneyXmlContentHandler::addToKeyValueContainer(k, node);
209 QFAIL("Missing expected exception");
210 } catch (const MyMoneyException &) {
211 }
212
213 doc.setContent(ref_ok);
214 node = doc.documentElement().firstChild().toElement();
215 try {
216 MyMoneyKeyValueContainer k;
217 MyMoneyXmlContentHandler::addToKeyValueContainer(k, node);
218 // QVERIFY(k.d_func()->m_kvp.count() == 2); to be enabled soon
219 QVERIFY(k.value("key") == "Value");
220 QVERIFY(k.value("Key") == "value");
221 } catch (const MyMoneyException &) {
222 QFAIL("Unexpected exception");
223 }
224 }
225
writeKeyValueContainer()226 void MyMoneyXmlContentHandlerTest::writeKeyValueContainer()
227 {
228 MyMoneyKeyValueContainer kvp;
229 kvp.setValue("Key", "Value");
230 kvp.setValue("key", "value");
231
232 QDomDocument doc("TEST");
233 QDomElement el = doc.createElement("KVP-CONTAINER");
234 doc.appendChild(el);
235 MyMoneyXmlContentHandler::writeKeyValueContainer(kvp, doc, el);
236
237 QCOMPARE(doc.doctype().name(), QLatin1String("TEST"));
238 QDomElement kvpContainer = doc.documentElement();
239 QCOMPARE(kvpContainer.tagName(), QLatin1String("KVP-CONTAINER"));
240 QCOMPARE(kvpContainer.childNodes().size(), 1);
241
242 QVERIFY(kvpContainer.childNodes().at(0).isElement());
243 QDomElement keyValuePairs = kvpContainer.childNodes().at(0).toElement();
244 QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS"));
245 QCOMPARE(keyValuePairs.childNodes().size(), 2);
246
247 QVERIFY(keyValuePairs.childNodes().at(0).isElement());
248 QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement();
249 QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR"));
250 QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("Key"));
251 QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("Value"));
252 QCOMPARE(keyValuePair1.childNodes().size(), 0);
253
254 QVERIFY(keyValuePairs.childNodes().at(1).isElement());
255 QDomElement keyValuePair2 = keyValuePairs.childNodes().at(1).toElement();
256 QCOMPARE(keyValuePair2.tagName(), QLatin1String("PAIR"));
257 QCOMPARE(keyValuePair2.attribute("key"), QLatin1String("key"));
258 QCOMPARE(keyValuePair2.attribute("value"), QLatin1String("value"));
259 QCOMPARE(keyValuePair2.childNodes().size(), 0);
260 }
261
readTransaction()262 void MyMoneyXmlContentHandlerTest::readTransaction()
263 {
264 MyMoneyTransaction t;
265
266 QString ref_ok = QString(
267 "<!DOCTYPE TEST>\n"
268 "<TRANSACTION-CONTAINER>\n"
269 " <TRANSACTION postdate=\"2001-12-28\" memo=\"Wohnung:Miete\" id=\"T000000000000000001\" commodity=\"EUR\" entrydate=\"2003-09-29\" >\n"
270 " <SPLITS>\n"
271 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"Withdrawal\" bankid=\"SPID\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" account=\"A000076\" />\n"
272 " <TAG id=\"G000001\"/>\n"
273 " </SPLITS>\n"
274 " <KEYVALUEPAIRS>\n"
275 " <PAIR key=\"key\" value=\"value\" />\n"
276 " </KEYVALUEPAIRS>\n"
277 " </TRANSACTION>\n"
278 "</TRANSACTION-CONTAINER>\n"
279 );
280
281 QString ref_false = QString(
282 "<!DOCTYPE TEST>\n"
283 "<TRANSACTION-CONTAINER>\n"
284 " <TRANS-ACTION postdate=\"2001-12-28\" memo=\"Wohnung:Miete\" id=\"T000000000000000001\" commodity=\"EUR\" entrydate=\"2003-09-29\" >\n"
285 " <SPLITS>\n"
286 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"Withdrawal\" bankid=\"SPID\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" account=\"A000076\" />\n"
287 " </SPLITS>\n"
288 " <KEYVALUEPAIRS>\n"
289 " <PAIR key=\"key\" value=\"value\" />\n"
290 " </KEYVALUEPAIRS>\n"
291 " </TRANS-ACTION>\n"
292 "</TRANSACTION-CONTAINER>\n"
293 );
294
295 QDomDocument doc;
296 QDomElement node;
297 doc.setContent(ref_false);
298 node = doc.documentElement().firstChild().toElement();
299
300 try {
301 t = MyMoneyXmlContentHandler::readTransaction(node);
302 QFAIL("Missing expected exception");
303 } catch (const MyMoneyException &) {
304 }
305
306 doc.setContent(ref_ok);
307 node = doc.documentElement().firstChild().toElement();
308
309 t.setValue("key", "VALUE");
310 try {
311 t = MyMoneyXmlContentHandler::readTransaction(node);
312 QVERIFY(t.postDate() == QDate(2001, 12, 28));
313 QVERIFY(t.entryDate() == QDate(2003, 9, 29));
314 QVERIFY(t.id() == "T000000000000000001");
315 QVERIFY(t.memo() == "Wohnung:Miete");
316 QVERIFY(t.commodity() == "EUR");
317 QVERIFY(t.pairs().count() == 1);
318 QVERIFY(t.value("key") == "value");
319 QVERIFY(t.splits().count() == 1);
320 } catch (const MyMoneyException &) {
321 QFAIL("Unexpected exception");
322 }
323 }
324
readTransactionEx()325 void MyMoneyXmlContentHandlerTest::readTransactionEx()
326 {
327 MyMoneyTransaction t;
328
329 QString ref_ok = QString(
330 "<!DOCTYPE TEST>\n"
331 "<TRANSACTION-CONTAINER>\n"
332 "<TRANSACTION postdate=\"2010-03-05\" memo=\"\" id=\"T000000000000004189\" commodity=\"EUR\" entrydate=\"2010-03-08\" >\n"
333 " <SPLITS>\n"
334 " <SPLIT payee=\"P000010\" reconciledate=\"\" shares=\"-125000/100\" action=\"Transfer\" bankid=\"A000076-2010-03-05-b6850c0-1\" number=\"\" reconcileflag=\"1\" memo=\"UMBUCHUNG\" value=\"-125000/100\" id=\"S0001\" account=\"A000076\" >\n"
335 " <KEYVALUEPAIRS>\n"
336 " <PAIR key=\"kmm-match-split\" value=\"S0002\" />\n"
337 " <PAIR key=\"kmm-matched-tx\" value=\"<!DOCTYPE MATCH>\n"
338 " <CONTAINER>\n"
339 " <TRANSACTION postdate="2010-03-05" memo="UMBUCHUNG" id="" commodity="EUR" entrydate="2010-03-08" >\n"
340 " <SPLITS>\n"
341 " <SPLIT payee="P000010" reconciledate="" shares="125000/100" action="Transfer" bankid="" number="" reconcileflag="0" memo="UMBUCHUNG" value="125000/100" id="S0001" account="A000087" />\n"
342 " <SPLIT payee="P000010" reconciledate="" shares="-125000/100" action="" bankid="A000076-2010-03-05-b6850c0-1" number="" reconcileflag="0" memo="UMBUCHUNG" value="-125000/100" id="S0002" account="A000076" />\n"
343 " </SPLITS>\n"
344 " <KEYVALUEPAIRS>\n"
345 " <PAIR key="Imported" value="true" />\n"
346 " </KEYVALUEPAIRS>\n"
347 " </TRANSACTION>\n"
348 " </CONTAINER>\n"
349 "\" />\n"
350 " <PAIR key=\"kmm-orig-memo\" value=\"\" />\n"
351 " </KEYVALUEPAIRS>\n"
352 " </SPLIT>\n"
353 " <SPLIT payee=\"P000010\" reconciledate=\"\" shares=\"125000/100\" action=\"Transfer\" bankid=\"\" number=\"\" reconcileflag=\"0\" memo=\"\" value=\"125000/100\" id=\"S0002\" account=\"A000087\" />\n"
354 " </SPLITS>\n"
355 "</TRANSACTION>\n"
356 "</TRANSACTION-CONTAINER>\n"
357 );
358 QDomDocument doc;
359 QDomElement node;
360 doc.setContent(ref_ok);
361 node = doc.documentElement().firstChild().toElement();
362
363 try {
364 t = MyMoneyXmlContentHandler::readTransaction(node);
365 QVERIFY(t.pairs().count() == 0);
366 QVERIFY(t.splits().size() == 2);
367 QVERIFY(t.splits()[0].pairs().count() == 3);
368 QVERIFY(t.splits()[1].pairs().count() == 0);
369 QVERIFY(t.splits()[0].isMatched());
370
371 MyMoneyTransaction ti = t.splits()[0].matchedTransaction();
372 QVERIFY(ti.pairs().count() == 1);
373 QVERIFY(ti.isImported());
374 QVERIFY(ti.splits().count() == 2);
375 } catch (const MyMoneyException &) {
376 QFAIL("Unexpected exception");
377 }
378 }
379
writeTransaction()380 void MyMoneyXmlContentHandlerTest::writeTransaction()
381 {
382 MyMoneyTransaction t("T000000000000000001");
383 t.setPostDate(QDate(2001, 12, 28));
384 t.setEntryDate(QDate(2003, 9, 29));
385 t.setMemo("Wohnung:Miete");
386 t.setCommodity("EUR");
387 t.setValue("key", "value");
388
389 MyMoneyTransaction matchedTx;
390 matchedTx.setMemo(QLatin1String("TEST <TEST"));
391 MyMoneySplit matchedSplit;
392 matchedSplit.setMemo(matchedTx.memo());
393 matchedSplit.setAccountId("A000076");
394 matchedTx.addSplit(matchedSplit);
395
396 MyMoneySplit s;
397 s.setPayeeId("P000001");
398 QList<QString> tagIdList;
399 tagIdList << "G000001";
400 s.setTagIdList(tagIdList);
401 s.setShares(MyMoneyMoney(96379, 100));
402 s.setValue(MyMoneyMoney(96379, 100));
403 s.setAction(MyMoneySplit::actionName(eMyMoney::Split::Action::Withdrawal));
404 s.setAccountId("A000076");
405 s.setReconcileFlag(eMyMoney::Split::State::Reconciled);
406 s.setBankID("SPID");
407 s.addMatch(matchedTx);
408 QVERIFY(s.matchedTransaction() == matchedTx);
409 t.addSplit(s);
410
411 QDomDocument doc("TEST");
412 QDomElement el = doc.createElement("TRANSACTION-CONTAINER");
413 doc.appendChild(el);
414 MyMoneyXmlContentHandler::writeTransaction(t, doc, el);
415
416 QCOMPARE(doc.doctype().name(), QLatin1String("TEST"));
417 QDomElement transactionContainer = doc.documentElement();
418 QVERIFY(transactionContainer.isElement());
419 QCOMPARE(transactionContainer.tagName(), QLatin1String("TRANSACTION-CONTAINER"));
420 QVERIFY(transactionContainer.childNodes().size() == 1);
421 QVERIFY(transactionContainer.childNodes().at(0).isElement());
422
423 QDomElement transaction = transactionContainer.childNodes().at(0).toElement();
424 QCOMPARE(transaction.tagName(), QLatin1String("TRANSACTION"));
425 QCOMPARE(transaction.attribute("id"), QLatin1String("T000000000000000001"));
426 QCOMPARE(transaction.attribute("postdate"), QLatin1String("2001-12-28"));
427 QCOMPARE(transaction.attribute("commodity"), QLatin1String("EUR"));
428 QCOMPARE(transaction.attribute("memo"), QLatin1String("Wohnung:Miete"));
429 QCOMPARE(transaction.attribute("entrydate"), QLatin1String("2003-09-29"));
430 QCOMPARE(transaction.childNodes().size(), 2);
431
432 QVERIFY(transaction.childNodes().at(0).isElement());
433 QDomElement splits = transaction.childNodes().at(0).toElement();
434 QCOMPARE(splits.tagName(), QLatin1String("SPLITS"));
435 QCOMPARE(splits.childNodes().size(), 1);
436 QVERIFY(splits.childNodes().at(0).isElement());
437 QDomElement split = splits.childNodes().at(0).toElement();
438 QCOMPARE(split.tagName(), QLatin1String("SPLIT"));
439 QCOMPARE(split.attribute("id"), QLatin1String("S0001"));
440 QCOMPARE(split.attribute("payee"), QLatin1String("P000001"));
441 QCOMPARE(split.attribute("reconcileflag"), QLatin1String("2"));
442 QCOMPARE(split.attribute("shares"), QLatin1String("96379/100"));
443 QCOMPARE(split.attribute("reconciledate"), QString());
444 QCOMPARE(split.attribute("action"), QLatin1String("Withdrawal"));
445 QCOMPARE(split.attribute("bankid"), QLatin1String("SPID"));
446 QCOMPARE(split.attribute("account"), QLatin1String("A000076"));
447 QCOMPARE(split.attribute("number"), QString());
448 QCOMPARE(split.attribute("value"), QLatin1String("96379/100"));
449 QCOMPARE(split.attribute("memo"), QString());
450 QCOMPARE(split.childNodes().size(), 2);
451
452 QVERIFY(split.childNodes().at(0).isElement());
453 QDomElement tag = split.childNodes().at(0).toElement();
454 QCOMPARE(tag.tagName(), QLatin1String("TAG"));
455 QCOMPARE(tag.attribute("id"), QLatin1String("G000001"));
456 QCOMPARE(tag.childNodes().size(), 0);
457
458 QDomElement keyValuePairs = transaction.childNodes().at(1).toElement();
459 QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS"));
460 QCOMPARE(keyValuePairs.childNodes().size(), 1);
461
462 QVERIFY(keyValuePairs.childNodes().at(0).isElement());
463 QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement();
464 QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR"));
465 QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("key"));
466 QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value"));
467 QCOMPARE(keyValuePair1.childNodes().size(), 0);
468
469 auto tread = MyMoneyXmlContentHandler::readTransaction(transaction);
470 QCOMPARE(tread.postDate(), t.postDate());
471 QCOMPARE(tread.memo(), t.memo());
472 QCOMPARE(tread.splits().count(), t.splits().count());
473 // now check the parts that are important in the matched transaction
474 tread = tread.splits().at(0).matchedTransaction();
475 QCOMPARE(tread.postDate(), matchedTx.postDate());
476 QCOMPARE(tread.memo(), matchedTx.memo());
477 QCOMPARE(tread.splits().count(), matchedTx.splits().count());
478 QCOMPARE(tread.splits().count(), 1);
479 QCOMPARE(tread.splits().at(0).memo(), matchedSplit.memo());
480 }
481
readSplit()482 void MyMoneyXmlContentHandlerTest::readSplit()
483 {
484 MyMoneySplit s;
485 QString ref_ok = QString(
486 "<!DOCTYPE TEST>\n"
487 "<SPLIT-CONTAINER>\n"
488 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"Deposit\" bankid=\"SPID\" number=\"124\" reconcileflag=\"2\" memo=\"MyMemo\" value=\"96379/1000\" account=\"A000076\" costcenter=\"C000005\">\n"
489 " <TAG id=\"G000001\"/>\n"
490 " </SPLIT>\n"
491 "</SPLIT-CONTAINER>\n");
492
493 QString ref_false = QString(
494 "<!DOCTYPE TEST>\n"
495 "<SPLIT-CONTAINER>\n"
496 " <SPLITS payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"Deposit\" bankid=\"SPID\" number=\"124\" reconcileflag=\"2\" memo=\"\" value=\"96379/1000\" account=\"A000076\" />\n"
497 " <TAG id=\"G000001\"/>\n"
498 "</SPLIT-CONTAINER>\n");
499
500 QDomDocument doc;
501 QDomElement node;
502 doc.setContent(ref_false);
503 node = doc.documentElement().firstChild().toElement();
504
505 try {
506 s = MyMoneyXmlContentHandler::readSplit(node);
507 QFAIL("Missing expected exception");
508 } catch (const MyMoneyException &) {
509 }
510
511 doc.setContent(ref_ok);
512 node = doc.documentElement().firstChild().toElement();
513
514 try {
515 s = MyMoneyXmlContentHandler::readSplit(node);
516 QCOMPARE(s.id().isEmpty(), true);
517 QCOMPARE(s.payeeId(), QLatin1String("P000001"));
518 QList<QString> tagIdList;
519 tagIdList << QLatin1String("G000001");
520 QCOMPARE(s.tagIdList(), tagIdList);
521 QCOMPARE(s.reconcileDate(), QDate());
522 QCOMPARE(s.shares(), MyMoneyMoney(96379, 100));
523 QCOMPARE(s.value(), MyMoneyMoney(96379, 1000));
524 QCOMPARE(s.number(), QLatin1String("124"));
525 QCOMPARE(s.bankID(), QLatin1String("SPID"));
526 QCOMPARE(s.reconcileFlag(), eMyMoney::Split::State::Reconciled);
527 QCOMPARE(s.action(), MyMoneySplit::actionName(eMyMoney::Split::Action::Deposit));
528 QCOMPARE(s.accountId(), QLatin1String("A000076"));
529 QCOMPARE(s.costCenterId(), QLatin1String("C000005"));
530 QCOMPARE(s.memo(), QLatin1String("MyMemo"));
531 } catch (const MyMoneyException &) {
532 }
533
534 }
535
writeSplit()536 void MyMoneyXmlContentHandlerTest::writeSplit()
537 {
538 MyMoneySplit s;
539
540 s.setPayeeId("P000001");
541 QList<QString> tagIdList;
542 tagIdList << "G000001";
543 s.setTagIdList(tagIdList);
544 s.setShares(MyMoneyMoney(96379, 100));
545 s.setValue(MyMoneyMoney(96379, 1000));
546 s.setAccountId("A000076");
547 s.setCostCenterId("C000005");
548 s.setNumber("124");
549 s.setBankID("SPID");
550 s.setAction(MyMoneySplit::actionName(eMyMoney::Split::Action::Deposit));
551 s.setReconcileFlag(eMyMoney::Split::State::Reconciled);
552
553 QDomDocument doc("TEST");
554 QDomElement el = doc.createElement("SPLIT-CONTAINER");
555 doc.appendChild(el);
556 MyMoneyXmlContentHandler::writeSplit(s, doc, el);
557
558 QCOMPARE(doc.doctype().name(), QLatin1String("TEST"));
559 QDomElement splitContainer = doc.documentElement();
560 QCOMPARE(splitContainer.tagName(), QLatin1String("SPLIT-CONTAINER"));
561 QCOMPARE(splitContainer.childNodes().size(), 1);
562
563 QCOMPARE(splitContainer.childNodes().at(0).isElement(), true);
564 QDomElement split = splitContainer.childNodes().at(0).toElement();
565 QCOMPARE(split.tagName(), QLatin1String("SPLIT"));
566 QCOMPARE(split.attribute("payee"), QLatin1String("P000001"));
567 QCOMPARE(split.attribute("reconcileflag"), QLatin1String("2"));
568 QCOMPARE(split.attribute("shares"), QLatin1String("96379/100"));
569 QCOMPARE(split.attribute("reconciledate"), QString());
570 QCOMPARE(split.attribute("action"), QLatin1String("Deposit"));
571 QCOMPARE(split.attribute("bankid"), QLatin1String("SPID"));
572 QCOMPARE(split.attribute("account"), QLatin1String("A000076"));
573 QCOMPARE(split.attribute("costcenter"), QLatin1String("C000005"));
574 QCOMPARE(split.attribute("number"), QLatin1String("124"));
575 QCOMPARE(split.attribute("value"), QLatin1String("96379/1000"));
576 QCOMPARE(split.attribute("memo"), QString());
577 QCOMPARE(split.attribute("id"), QString());
578 QCOMPARE(split.childNodes().size(), 1);
579
580 QCOMPARE(split.childNodes().at(0).isElement(), true);
581 QDomElement tag = split.childNodes().at(0).toElement();
582 QCOMPARE(tag.tagName(), QLatin1String("TAG"));
583 QCOMPARE(tag.attribute("id"), QLatin1String("G000001"));
584 QCOMPARE(tag.childNodes().size(), 0);
585
586 QString ref = QString(
587 "<!DOCTYPE TEST>\n"
588 "<SPLIT-CONTAINER>\n"
589 " <SPLIT payee=\"P000001\" reconcileflag=\"2\" shares=\"96379/100\" reconciledate=\"\" action=\"Deposit\" bankid=\"SPID\" account=\"A000076\" number=\"124\" value=\"96379/1000\" memo=\"\" id=\"\">\n"
590 " <TAG id=\"G000001\"/>\n"
591 " </SPLIT>\n"
592 "</SPLIT-CONTAINER>\n");
593 }
594
testReplaceIDinSplit()595 void MyMoneyXmlContentHandlerTest::testReplaceIDinSplit()
596 {
597 MyMoneySplit s;
598 bool changed;
599
600 s.setPayeeId("P000001");
601 s.setAccountId("A000076");
602 s.setCostCenterId("C000005");
603
604 changed = s.replaceId("X0001", "Y00001");
605 QCOMPARE(changed, false);
606 QCOMPARE(s.payeeId(), QLatin1String("P000001"));
607 QCOMPARE(s.accountId(), QLatin1String("A000076"));
608 QCOMPARE(s.costCenterId(), QLatin1String("C000005"));
609
610 changed = s.replaceId("P000002", "P000001");
611 QCOMPARE(changed, true);
612 QCOMPARE(s.payeeId(), QLatin1String("P000002"));
613 QCOMPARE(s.accountId(), QLatin1String("A000076"));
614 QCOMPARE(s.costCenterId(), QLatin1String("C000005"));
615
616 changed = s.replaceId("A000079", "A000076");
617 QCOMPARE(changed, true);
618 QCOMPARE(s.payeeId(), QLatin1String("P000002"));
619 QCOMPARE(s.accountId(), QLatin1String("A000079"));
620 QCOMPARE(s.costCenterId(), QLatin1String("C000005"));
621
622 changed = s.replaceId("C000006", "C000005");
623 QCOMPARE(changed, true);
624 QCOMPARE(s.payeeId(), QLatin1String("P000002"));
625 QCOMPARE(s.accountId(), QLatin1String("A000079"));
626 QCOMPARE(s.costCenterId(), QLatin1String("C000006"));
627
628 QString ref_ok = QString(
629 "<!DOCTYPE TEST>\n"
630 "<SPLIT-CONTAINER>\n"
631 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"-125000/100\" action=\"Transfer\" bankid=\"A000076-2010-03-05-b6850c0-1\" number=\"\" reconcileflag=\"1\" memo=\"UMBUCHUNG\" value=\"-125000/100\" id=\"S0001\" account=\"A000076\" >\n"
632 " <KEYVALUEPAIRS>\n"
633 " <PAIR key=\"kmm-match-split\" value=\"S0002\" />\n"
634 " <PAIR key=\"kmm-matched-tx\" value=\"<!DOCTYPE MATCH>\n"
635 " <CONTAINER>\n"
636 " <TRANSACTION postdate="2010-03-05" memo="UMBUCHUNG" id="" commodity="EUR" entrydate="2010-03-08" >\n"
637 " <SPLITS>\n"
638 " <SPLIT payee="P000010" reconciledate="" shares="125000/100" action="Transfer" bankid="" number="" reconcileflag="0" memo="UMBUCHUNG" value="125000/100" id="S0001" account="A000087" />\n"
639 " <SPLIT payee="P000011" reconciledate="" shares="-125000/100" action="" bankid="A000076-2010-03-05-b6850c0-1" number="" reconcileflag="0" memo="UMBUCHUNG" value="-125000/100" id="S0002" account="A000076" />\n"
640 " </SPLITS>\n"
641 " <KEYVALUEPAIRS>\n"
642 " <PAIR key="Imported" value="true" />\n"
643 " </KEYVALUEPAIRS>\n"
644 " </TRANSACTION>\n"
645 " </CONTAINER>\n"
646 "\" />\n"
647 " <PAIR key=\"kmm-orig-memo\" value=\"\" />\n"
648 " </KEYVALUEPAIRS>\n"
649 " </SPLIT>\n"
650 "</SPLIT-CONTAINER>\n"
651 );
652 QDomDocument doc;
653 QDomElement node;
654 doc.setContent(ref_ok);
655 node = doc.documentElement().firstChild().toElement();
656
657 try {
658 s = MyMoneyXmlContentHandler::readSplit(node);
659 QCOMPARE(s.payeeId(), QLatin1String("P000001"));
660 QCOMPARE(s.replaceId("P2", "P1"), false);
661 QCOMPARE(s.matchedTransaction().splits()[0].payeeId(), QLatin1String("P000010"));
662 QCOMPARE(s.matchedTransaction().splits()[1].payeeId(), QLatin1String("P000011"));
663 QCOMPARE(s.replaceId("P0010", "P000010"), true);
664 QCOMPARE(s.matchedTransaction().splits()[0].payeeId(), QLatin1String("P0010"));
665 QCOMPARE(s.matchedTransaction().splits()[1].payeeId(), QLatin1String("P000011"));
666 QCOMPARE(s.replaceId("P0011", "P000011"), true);
667 QCOMPARE(s.matchedTransaction().splits()[0].payeeId(), QLatin1String("P0010"));
668 QCOMPARE(s.matchedTransaction().splits()[1].payeeId(), QLatin1String("P0011"));
669
670 } catch (const MyMoneyException &) {
671 QFAIL("Unexpected exception");
672 }
673 }
674
readAccount()675 void MyMoneyXmlContentHandlerTest::readAccount()
676 {
677 MyMoneyAccount a;
678 QString ref_ok = QString(
679 "<!DOCTYPE TEST>\n"
680 "<ACCOUNT-CONTAINER>\n"
681 " <ACCOUNT parentaccount=\"Parent\" lastmodified=\"%1\" lastreconciled=\"\" institution=\"B000001\" number=\"465500\" opened=\"%2\" type=\"9\" id=\"A000001\" name=\"AccountName\" description=\"Desc\" >\n"
682 " <SUBACCOUNTS>\n"
683 " <SUBACCOUNT id=\"A000002\" />\n"
684 " <SUBACCOUNT id=\"A000003\" />\n"
685 " </SUBACCOUNTS>\n"
686 " <KEYVALUEPAIRS>\n"
687 " <PAIR key=\"key\" value=\"value\" />\n"
688 " <PAIR key=\"Key\" value=\"Value\" />\n"
689 " <PAIR key=\"reconciliationHistory\" value=\"2011-01-01:123/100;2011-02-01:114/25\"/>\n"
690 " <PAIR key=\"lastStatementDate\" value=\"2011-01-01\"/>\n"
691 " </KEYVALUEPAIRS>\n"
692 " </ACCOUNT>\n"
693 "</ACCOUNT-CONTAINER>\n").
694 arg(QDate::currentDate().toString(Qt::ISODate)).arg(QDate::currentDate().toString(Qt::ISODate));
695
696 QString ref_false = QString(
697 "<!DOCTYPE TEST>\n"
698 "<ACCOUNT-CONTAINER>\n"
699 " <KACCOUNT parentaccount=\"Parent\" lastmodified=\"%1\" lastreconciled=\"\" institution=\"B000001\" number=\"465500\" opened=\"%2\" type=\"9\" id=\"A000001\" name=\"AccountName\" description=\"Desc\" >\n"
700 " <SUBACCOUNTS>\n"
701 " <SUBACCOUNT id=\"A000002\" />\n"
702 " <SUBACCOUNT id=\"A000003\" />\n"
703 " </SUBACCOUNTS>\n"
704 " <KEYVALUEPAIRS>\n"
705 " <PAIR key=\"key\" value=\"value\" />\n"
706 " <PAIR key=\"Key\" value=\"Value\" />\n"
707 " </KEYVALUEPAIRS>\n"
708 " </KACCOUNT>\n"
709 "</ACCOUNT-CONTAINER>\n").
710 arg(QDate::currentDate().toString(Qt::ISODate)).arg(QDate::currentDate().toString(Qt::ISODate));
711
712 QDomDocument doc;
713 QDomElement node;
714 doc.setContent(ref_false);
715 node = doc.documentElement().firstChild().toElement();
716
717 try {
718 a = MyMoneyXmlContentHandler::readAccount(node);
719 QFAIL("Missing expected exception");
720 } catch (const MyMoneyException &) {
721 }
722
723 doc.setContent(ref_ok);
724 node = doc.documentElement().firstChild().toElement();
725
726 a.addAccountId("TEST");
727 a.setValue("KEY", "VALUE");
728
729 try {
730 a = MyMoneyXmlContentHandler::readAccount(node);
731 QCOMPARE(a.id(), QStringLiteral("A000001"));
732 QCOMPARE(a.name(), QStringLiteral("AccountName"));
733 QCOMPARE(a.parentAccountId(), QStringLiteral("Parent"));
734 QCOMPARE(a.lastModified(), QDate::currentDate());
735 QCOMPARE(a.lastReconciliationDate(), QDate());
736 QCOMPARE(a.institutionId(), QStringLiteral("B000001"));
737 QCOMPARE(a.number(), QStringLiteral("465500"));
738 QCOMPARE(a.openingDate(), QDate::currentDate());
739 QCOMPARE(a.accountType(), eMyMoney::Account::Type::Asset);
740 QCOMPARE(a.description(), QStringLiteral("Desc"));
741 QCOMPARE(a.accountList().count(), 2);
742 QCOMPARE(a.accountList()[0], QStringLiteral("A000002"));
743 QCOMPARE(a.accountList()[1], QStringLiteral("A000003"));
744 QCOMPARE(a.pairs().count(), 3);
745 QCOMPARE(a.value("key"), QStringLiteral("value"));
746 QCOMPARE(a.value("Key"), QStringLiteral("Value"));
747 QCOMPARE(a.pairs().contains("lastStatementDate"), false);
748 QCOMPARE(a.reconciliationHistory().count(), 2);
749 QCOMPARE(a.reconciliationHistory()[QDate(2011, 1, 1)].toString(), MyMoneyMoney(123, 100).toString());
750 QCOMPARE(a.reconciliationHistory()[QDate(2011, 2, 1)].toString(), MyMoneyMoney(456, 100).toString());
751 } catch (const MyMoneyException &) {
752 QFAIL("Unexpected exception");
753 }
754 }
755
writeAccount()756 void MyMoneyXmlContentHandlerTest::writeAccount()
757 {
758 QString id = "A000001";
759 QString institutionid = "B000001";
760 QString parent = "Parent";
761
762 MyMoneyAccount r;
763 r.setAccountType(eMyMoney::Account::Type::Asset);
764 r.setOpeningDate(QDate::currentDate());
765 r.setLastModified(QDate::currentDate());
766 r.setDescription("Desc");
767 r.setName("AccountName");
768 r.setNumber("465500");
769 r.setParentAccountId(parent);
770 r.setInstitutionId(institutionid);
771 r.setValue(QString("key"), "value");
772 r.addAccountId("A000002");
773 r.addReconciliation(QDate(2011, 1, 1), MyMoneyMoney(123, 100));
774 r.addReconciliation(QDate(2011, 2, 1), MyMoneyMoney(456, 100));
775
776 QCOMPARE(r.pairs().count(), 2);
777 QCOMPARE(r.value("key"), QLatin1String("value"));
778 QCOMPARE(r.value("reconciliationHistory"), QLatin1String("2011-01-01:123/100;2011-02-01:114/25"));
779
780 MyMoneyAccount a(id, r);
781
782 QDomDocument doc("TEST");
783 QDomElement el = doc.createElement("ACCOUNT-CONTAINER");
784 doc.appendChild(el);
785 MyMoneyXmlContentHandler::writeAccount(a, doc, el);
786
787 QCOMPARE(doc.doctype().name(), QLatin1String("TEST"));
788 QDomElement accountContainer = doc.documentElement();
789 QVERIFY(accountContainer.isElement());
790 QCOMPARE(accountContainer.tagName(), QLatin1String("ACCOUNT-CONTAINER"));
791 QVERIFY(accountContainer.childNodes().size() == 1);
792 QVERIFY(accountContainer.childNodes().at(0).isElement());
793
794 QDomElement account = accountContainer.childNodes().at(0).toElement();
795 QCOMPARE(account.tagName(), QLatin1String("ACCOUNT"));
796 QCOMPARE(account.attribute("id"), QLatin1String("A000001"));
797 QCOMPARE(account.attribute("lastreconciled"), QString());
798 QCOMPARE(account.attribute("institution"), QLatin1String("B000001"));
799 QCOMPARE(account.attribute("name"), QLatin1String("AccountName"));
800 QCOMPARE(account.attribute("number"), QLatin1String("465500"));
801 QCOMPARE(account.attribute("description"), QLatin1String("Desc"));
802 QCOMPARE(account.attribute("parentaccount"), QLatin1String("Parent"));
803 QCOMPARE(account.attribute("opened"), QDate::currentDate().toString(Qt::ISODate));
804 QCOMPARE(account.attribute("type"), QLatin1String("9"));
805 QCOMPARE(account.attribute("lastmodified"), QDate::currentDate().toString(Qt::ISODate));
806 QCOMPARE(account.attribute("id"), QLatin1String("A000001"));
807 QCOMPARE(account.childNodes().size(), 2);
808
809 QVERIFY(account.childNodes().at(0).isElement());
810 QDomElement subAccounts = account.childNodes().at(0).toElement();
811 QCOMPARE(subAccounts.tagName(), QLatin1String("SUBACCOUNTS"));
812 QCOMPARE(subAccounts.childNodes().size(), 1);
813 QVERIFY(subAccounts.childNodes().at(0).isElement());
814 QDomElement subAccount = subAccounts.childNodes().at(0).toElement();
815 QCOMPARE(subAccount.tagName(), QLatin1String("SUBACCOUNT"));
816 QCOMPARE(subAccount.attribute("id"), QLatin1String("A000002"));
817 QCOMPARE(subAccount.childNodes().size(), 0);
818
819 QDomElement keyValuePairs = account.childNodes().at(1).toElement();
820 QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS"));
821 QCOMPARE(keyValuePairs.childNodes().size(), 2);
822
823 QVERIFY(keyValuePairs.childNodes().at(0).isElement());
824 QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement();
825 QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR"));
826 QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("key"));
827 QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value"));
828 QCOMPARE(keyValuePair1.childNodes().size(), 0);
829
830 QVERIFY(keyValuePairs.childNodes().at(1).isElement());
831 QDomElement keyValuePair2 = keyValuePairs.childNodes().at(1).toElement();
832 QCOMPARE(keyValuePair2.tagName(), QLatin1String("PAIR"));
833 QCOMPARE(keyValuePair2.attribute("key"), QLatin1String("reconciliationHistory"));
834 QCOMPARE(keyValuePair2.attribute("value"), QLatin1String("2011-01-01:123/100;2011-02-01:114/25"));
835 QCOMPARE(keyValuePair2.childNodes().size(), 0);
836 }
837
readWritePayee()838 void MyMoneyXmlContentHandlerTest::readWritePayee()
839 {
840 QDomDocument doc;
841 QDomElement parent = doc.createElement("Test");
842 doc.appendChild(parent);
843 MyMoneyPayee payee1("some random id"); //if the ID isn't set, w ethrow an exception
844 MyMoneyXmlContentHandler::writePayee(payee1, doc, parent);
845 QString temp1 = "Account1";
846 payee1.setDefaultAccountId(temp1);
847 MyMoneyXmlContentHandler::writePayee(payee1, doc, parent);
848 QString temp2 = "Account2";
849 payee1.setDefaultAccountId(temp2);
850 MyMoneyXmlContentHandler::writePayee(payee1, doc, parent);
851 payee1.setDefaultAccountId();
852 MyMoneyXmlContentHandler::writePayee(payee1, doc, parent);
853 QDomElement el = parent.firstChild().toElement();
854 QVERIFY(!el.isNull());
855 auto payee2 = MyMoneyXmlContentHandler::readPayee(el);
856 QVERIFY(payee2.defaultAccountId().isEmpty());
857 el = el.nextSibling().toElement();
858 QVERIFY(!el.isNull());
859 auto payee3 = MyMoneyXmlContentHandler::readPayee(el);
860 QVERIFY(!payee3.defaultAccountId().isEmpty());
861 QVERIFY(payee3.defaultAccountId() == temp1);
862 el = el.nextSibling().toElement();
863 QVERIFY(!el.isNull());
864 auto payee4 = MyMoneyXmlContentHandler::readPayee(el);
865 QVERIFY(!payee4.defaultAccountId().isEmpty());
866 QVERIFY(payee4.defaultAccountId() == temp2);
867 el = el.nextSibling().toElement();
868 QVERIFY(!el.isNull());
869 auto payee5 = MyMoneyXmlContentHandler::readPayee(el);
870 QVERIFY(payee5.defaultAccountId().isEmpty());
871 }
872
readWriteTag()873 void MyMoneyXmlContentHandlerTest::readWriteTag()
874 {
875 QDomDocument doc;
876 QDomElement parent = doc.createElement("Test");
877 doc.appendChild(parent);
878 MyMoneyTag tag1("some random id"); //if the ID isn't set, w ethrow an exception
879 tag1.setName(QStringLiteral("MyTagName"));
880 tag1.setNamedTagColor(QStringLiteral("red"));
881 tag1.setNotes(QStringLiteral("Notes for a tag"));
882
883 MyMoneyXmlContentHandler::writeTag(tag1, doc, parent);
884 QDomElement el = parent.firstChild().toElement();
885 QVERIFY(!el.isNull());
886 auto tag2 = MyMoneyXmlContentHandler::readTag(el);
887 QCOMPARE(tag1.name(), tag2.name());
888 QCOMPARE(tag1.notes(), tag2.notes());
889 QCOMPARE(tag1.tagColor(), tag2.tagColor());
890 }
891
readInstitution()892 void MyMoneyXmlContentHandlerTest::readInstitution()
893 {
894 MyMoneyInstitution i;
895 QString ref_ok = QString(
896 "<!DOCTYPE TEST>\n"
897 "<INSTITUTION-CONTAINER>\n"
898 " <INSTITUTION sortcode=\"sortcode\" id=\"I00001\" manager=\"manager\" name=\"name\" >\n"
899 " <ADDRESS street=\"street\" zip=\"postcode\" city=\"town\" telephone=\"telephone\" />\n"
900 " <ACCOUNTIDS>\n"
901 " <ACCOUNTID id=\"A000001\" />\n"
902 " <ACCOUNTID id=\"A000003\" />\n"
903 " </ACCOUNTIDS>\n"
904 " <KEYVALUEPAIRS>\n"
905 " <PAIR key=\"key\" value=\"value\" />\n"
906 " </KEYVALUEPAIRS>\n"
907 " </INSTITUTION>\n"
908 "</INSTITUTION-CONTAINER>\n");
909
910 QString ref_false = QString(
911 "<!DOCTYPE TEST>\n"
912 "<INSTITUTION-CONTAINER>\n"
913 " <KINSTITUTION sortcode=\"sortcode\" id=\"I00001\" manager=\"manager\" name=\"name\" >\n"
914 " <ADDRESS street=\"street\" zip=\"postcode\" city=\"town\" telephone=\"telephone\" />\n"
915 " <ACCOUNTIDS>\n"
916 " <ACCOUNTID id=\"A000001\" />\n"
917 " <ACCOUNTID id=\"A000003\" />\n"
918 " </ACCOUNTIDS>\n"
919 " </KINSTITUTION>\n"
920 "</INSTITUTION-CONTAINER>\n");
921
922 QDomDocument doc;
923 QDomElement node;
924
925 doc.setContent(ref_false);
926 node = doc.documentElement().firstChild().toElement();
927 try {
928 i = MyMoneyXmlContentHandler::readInstitution(node);
929 QFAIL("Missing expected exception");
930 } catch (const MyMoneyException &) {
931 }
932
933 i.addAccountId("TEST");
934
935 doc.setContent(ref_ok);
936 node = doc.documentElement().firstChild().toElement();
937 try {
938 QStringList alist;
939 alist << "A000001" << "A000003";
940 i = MyMoneyXmlContentHandler::readInstitution(node);
941
942 QVERIFY(i.sortcode() == "sortcode");
943 QVERIFY(i.id() == "I00001");
944 QVERIFY(i.manager() == "manager");
945 QVERIFY(i.name() == "name");
946 QVERIFY(i.street() == "street");
947 QVERIFY(i.postcode() == "postcode");
948 QVERIFY(i.city() == "town");
949 QVERIFY(i.telephone() == "telephone");
950 QVERIFY(i.accountList() == alist);
951 QVERIFY(i.value(QString("key")) == "value");
952
953 } catch (const MyMoneyException &) {
954 QFAIL("Unexpected exception");
955 }
956 }
957
writeInstitution()958 void MyMoneyXmlContentHandlerTest::writeInstitution()
959 {
960 MyMoneyInstitution n("name", "town", "street", "postcode",
961 "telephone", "manager", "sortcode");;
962
963 n.addAccountId("A000001");
964 n.addAccountId("A000003");
965 n.setValue(QString("key"), "value");
966
967 QDomDocument doc("TEST");
968 QDomElement el = doc.createElement("INSTITUTION-CONTAINER");
969 doc.appendChild(el);
970
971 MyMoneyInstitution i("I00001", n);
972 MyMoneyXmlContentHandler::writeInstitution(i, doc, el);
973
974 QCOMPARE(doc.doctype().name(), QLatin1String("TEST"));
975 QDomElement institutionContainer = doc.documentElement();
976 QVERIFY(institutionContainer.isElement());
977 QCOMPARE(institutionContainer.tagName(), QLatin1String("INSTITUTION-CONTAINER"));
978 QVERIFY(institutionContainer.childNodes().size() == 1);
979 QVERIFY(institutionContainer.elementsByTagName("INSTITUTION").at(0).isElement());
980
981 QDomElement institution = institutionContainer.elementsByTagName("INSTITUTION").at(0).toElement();
982 QCOMPARE(institution.tagName(), QLatin1String("INSTITUTION"));
983 QCOMPARE(institution.attribute("id"), QLatin1String("I00001"));
984 QCOMPARE(institution.attribute("manager"), QLatin1String("manager"));
985 QCOMPARE(institution.attribute("name"), QLatin1String("name"));
986 QCOMPARE(institution.attribute("sortcode"), QLatin1String("sortcode"));
987 QCOMPARE(institution.childNodes().size(), 3);
988
989 QVERIFY(institution.childNodes().at(0).isElement());
990 QDomElement address = institution.childNodes().at(0).toElement();
991 QCOMPARE(address.tagName(), QLatin1String("ADDRESS"));
992 QCOMPARE(address.attribute("street"), QLatin1String("street"));
993 QCOMPARE(address.attribute("telephone"), QLatin1String("telephone"));
994 QCOMPARE(address.attribute("zip"), QLatin1String("postcode"));
995 QCOMPARE(address.attribute("city"), QLatin1String("town"));
996 QCOMPARE(address.childNodes().size(), 0);
997
998 QVERIFY(institution.childNodes().at(1).isElement());
999 QDomElement accountIds = institution.childNodes().at(1).toElement();
1000 QCOMPARE(accountIds.tagName(), QLatin1String("ACCOUNTIDS"));
1001 QCOMPARE(accountIds.childNodes().size(), 2);
1002
1003 QVERIFY(accountIds.childNodes().at(0).isElement());
1004 QDomElement account1 = accountIds.childNodes().at(0).toElement();
1005 QCOMPARE(account1.tagName(), QLatin1String("ACCOUNTID"));
1006 QCOMPARE(account1.attribute("id"), QLatin1String("A000001"));
1007 QCOMPARE(account1.childNodes().size(), 0);
1008
1009 QVERIFY(accountIds.childNodes().at(1).isElement());
1010 QDomElement account2 = accountIds.childNodes().at(1).toElement();
1011 QCOMPARE(account2.tagName(), QLatin1String("ACCOUNTID"));
1012 QCOMPARE(account2.attribute("id"), QLatin1String("A000003"));
1013 QCOMPARE(account2.childNodes().size(), 0);
1014
1015 QVERIFY(institution.childNodes().at(2).isElement());
1016 QDomElement keyValuePairs = institution.childNodes().at(2).toElement();
1017 QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS"));
1018 QCOMPARE(keyValuePairs.childNodes().size(), 1);
1019
1020 QVERIFY(keyValuePairs.childNodes().at(0).isElement());
1021 QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement();
1022 QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR"));
1023 QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("key"));
1024 QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value"));
1025 QCOMPARE(keyValuePair1.childNodes().size(), 0);
1026 }
1027
readSchedule()1028 void MyMoneyXmlContentHandlerTest::readSchedule()
1029 {
1030 MyMoneySchedule sch;
1031
1032 QString ref_ok1 = QString(
1033 "<!DOCTYPE TEST>\n"
1034 "<SCHEDULE-CONTAINER>\n"
1035 " <SCHEDULED_TX startDate=\"%1\" autoEnter=\"1\" weekendOption=\"2\" lastPayment=\"%2\" paymentType=\"1\" endDate=\"\" type=\"1\" id=\"SCH0002\" name=\"A Name\" fixed=\"1\" occurenceMultiplier=\"1\" occurence=\"4\" >\n" // krazy:exclude=spelling
1036 " <PAYMENTS>\n"
1037 " <PAYMENT date=\"%3\" />\n"
1038 " </PAYMENTS>\n"
1039 " <TRANSACTION postdate=\"2001-12-28\" memo=\"Wohnung:Miete\" id=\"\" commodity=\"EUR\" entrydate=\"2003-09-29\" >\n"
1040 " <SPLITS>\n"
1041 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"\" bankid=\"SPID1\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" account=\"A000076\" />\n"
1042 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"-96379/100\" action=\"\" bankid=\"SPID2\" number=\"\" reconcileflag=\"1\" memo=\"\" value=\"-96379/100\" account=\"A000276\" />\n"
1043 " </SPLITS>\n"
1044 " <KEYVALUEPAIRS>\n"
1045 " <PAIR key=\"key\" value=\"value\" />\n"
1046 " </KEYVALUEPAIRS>\n"
1047 " </TRANSACTION>\n"
1048 " </SCHEDULED_TX>\n"
1049 "</SCHEDULE-CONTAINER>\n"
1050 ).arg(QDate::currentDate().toString(Qt::ISODate))
1051 .arg(QDate::currentDate().toString(Qt::ISODate))
1052 .arg(QDate::currentDate().toString(Qt::ISODate));
1053
1054 // diff to ref_ok1 is that we now have an empty entrydate
1055 // in the transaction parameters
1056 QString ref_ok2 = QString(
1057 "<!DOCTYPE TEST>\n"
1058 "<SCHEDULE-CONTAINER>\n"
1059 " <SCHEDULED_TX startDate=\"%1\" autoEnter=\"1\" weekendOption=\"2\" lastPayment=\"%2\" paymentType=\"1\" endDate=\"\" type=\"1\" id=\"SCH0002\" name=\"A Name\" fixed=\"1\" occurenceMultiplier=\"1\" occurence=\"4\" >\n" // krazy:exclude=spelling
1060 " <PAYMENTS>\n"
1061 " <PAYMENT date=\"%3\" />\n"
1062 " </PAYMENTS>\n"
1063 " <TRANSACTION postdate=\"2001-12-28\" memo=\"Wohnung:Miete\" id=\"\" commodity=\"EUR\" entrydate=\"\" >\n"
1064 " <SPLITS>\n"
1065 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"\" bankid=\"SPID1\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" account=\"A000076\" />\n"
1066 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"-96379/100\" action=\"\" bankid=\"SPID2\" number=\"\" reconcileflag=\"1\" memo=\"\" value=\"-96379/100\" account=\"A000276\" />\n"
1067 " </SPLITS>\n"
1068 " <KEYVALUEPAIRS>\n"
1069 " <PAIR key=\"key\" value=\"value\" />\n"
1070 " </KEYVALUEPAIRS>\n"
1071 " </TRANSACTION>\n"
1072 " </SCHEDULED_TX>\n"
1073 "</SCHEDULE-CONTAINER>\n"
1074 ).arg(QDate::currentDate().toString(Qt::ISODate))
1075 .arg(QDate::currentDate().toString(Qt::ISODate))
1076 .arg(QDate::currentDate().toString(Qt::ISODate));
1077
1078 QString ref_false = QString(
1079 "<!DOCTYPE TEST>\n"
1080 "<SCHEDULE-CONTAINER>\n"
1081 " <SCHEDULE startDate=\"%1\" autoEnter=\"1\" weekendOption=\"2\" lastPayment=\"%2\" paymentType=\"1\" endDate=\"\" type=\"1\" id=\"SCH0002\" name=\"A Name\" fixed=\"1\" occurenceMultiplier=\"1\" occurence=\"4\" >\n" // krazy:exclude=spelling
1082 " <PAYMENTS count=\"1\" >\n"
1083 " <PAYMENT date=\"%3\" />\n"
1084 " </PAYMENTS>\n"
1085 " <TRANSACTION postdate=\"2001-12-28\" memo=\"Wohnung:Miete\" id=\"\" commodity=\"EUR\" entrydate=\"2003-09-29\" >\n"
1086 " <SPLITS>\n"
1087 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"\" bankid=\"SPID1\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" account=\"A000076\" />\n"
1088 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"-96379/100\" action=\"\" bankid=\"SPID2\" number=\"\" reconcileflag=\"1\" memo=\"\" value=\"-96379/100\" account=\"A000276\" />\n"
1089 " </SPLITS>\n"
1090 " <KEYVALUEPAIRS>\n"
1091 " <PAIR key=\"key\" value=\"value\" />\n"
1092 " </KEYVALUEPAIRS>\n"
1093 " </TRANSACTION>\n"
1094 " </SCHEDULED_TX>\n"
1095 "</SCHEDULE-CONTAINER>\n"
1096 ).arg(QDate::currentDate().toString(Qt::ISODate))
1097 .arg(QDate::currentDate().toString(Qt::ISODate))
1098 .arg(QDate::currentDate().toString(Qt::ISODate));
1099
1100 QDomDocument doc;
1101 QDomElement node;
1102 doc.setContent(ref_false);
1103 node = doc.documentElement().firstChild().toElement();
1104
1105 try {
1106 sch = MyMoneyXmlContentHandler::readSchedule(node);
1107 QFAIL("Missing expected exception");
1108 } catch (const MyMoneyException &) {
1109 }
1110
1111 doc.setContent(ref_ok1);
1112 node = doc.documentElement().firstChild().toElement();
1113
1114
1115 try {
1116 sch = MyMoneyXmlContentHandler::readSchedule(node);
1117 QCOMPARE(sch.id(), QLatin1String("SCH0002"));
1118 QCOMPARE(sch.nextDueDate(), QDate::currentDate().addDays(7));
1119 QCOMPARE(sch.startDate(), QDate::currentDate());
1120 QCOMPARE(sch.endDate(), QDate());
1121 QCOMPARE(sch.autoEnter(), true);
1122 QCOMPARE(sch.isFixed(), true);
1123 QCOMPARE(sch.weekendOption(), Schedule::WeekendOption::MoveNothing);
1124 QCOMPARE(sch.lastPayment(), QDate::currentDate());
1125 QCOMPARE(sch.paymentType(), Schedule::PaymentType::DirectDebit);
1126 QCOMPARE(sch.type(), Schedule::Type::Bill);
1127 QCOMPARE(sch.name(), QLatin1String("A Name"));
1128 QCOMPARE(sch.baseOccurrence(), Schedule::Occurrence::Weekly);
1129 QCOMPARE(sch.occurrenceMultiplier(), 1);
1130 QCOMPARE(sch.nextDueDate(), sch.lastPayment().addDays(7));
1131 QCOMPARE(sch.recordedPayments().count(), 1);
1132 QCOMPARE(sch.recordedPayments()[0], QDate::currentDate());
1133 } catch (const MyMoneyException &) {
1134 QFAIL("Unexpected exception");
1135 }
1136
1137 doc.setContent(ref_ok2);
1138 node = doc.documentElement().firstChild().toElement();
1139
1140
1141 try {
1142 sch = MyMoneyXmlContentHandler::readSchedule(node);
1143 QCOMPARE(sch.id(), QLatin1String("SCH0002"));
1144 QCOMPARE(sch.nextDueDate(), QDate::currentDate().addDays(7));
1145 QCOMPARE(sch.startDate(), QDate::currentDate());
1146 QCOMPARE(sch.endDate(), QDate());
1147 QCOMPARE(sch.autoEnter(), true);
1148 QCOMPARE(sch.isFixed(), true);
1149 QCOMPARE(sch.weekendOption(), Schedule::WeekendOption::MoveNothing);
1150 QCOMPARE(sch.lastPayment(), QDate::currentDate());
1151 QCOMPARE(sch.paymentType(), Schedule::PaymentType::DirectDebit);
1152 QCOMPARE(sch.type(), Schedule::Type::Bill);
1153 QCOMPARE(sch.name(), QLatin1String("A Name"));
1154 QCOMPARE(sch.baseOccurrence(), Schedule::Occurrence::Weekly);
1155 QCOMPARE(sch.occurrenceMultiplier(), 1);
1156 QCOMPARE(sch.nextDueDate(), sch.lastPayment().addDays(7));
1157 QCOMPARE(sch.recordedPayments().count(), 1);
1158 QCOMPARE(sch.recordedPayments()[0], QDate::currentDate());
1159 } catch (const MyMoneyException &) {
1160 QFAIL("Unexpected exception");
1161 }
1162 }
1163
writeSchedule()1164 void MyMoneyXmlContentHandlerTest::writeSchedule()
1165 {
1166 MyMoneySchedule tempSch("A Name",
1167 Schedule::Type::Bill,
1168 Schedule::Occurrence::Weekly, 123,
1169 Schedule::PaymentType::DirectDebit,
1170 QDate::currentDate(),
1171 QDate(),
1172 true,
1173 true);
1174
1175 MyMoneySchedule sch("SCH0001", tempSch);
1176 sch.setLastPayment(QDate::currentDate());
1177 sch.recordPayment(QDate::currentDate());
1178
1179 MyMoneyTransaction t("T000000000000000001");
1180 t.setPostDate(QDate(2001, 12, 28));
1181 t.setEntryDate(QDate(2003, 9, 29));
1182 t.setMemo("Wohnung:Miete");
1183 t.setCommodity("EUR");
1184 t.setValue("key", "value");
1185
1186 MyMoneySplit s;
1187 s.setPayeeId("P000001");
1188 s.setShares(MyMoneyMoney(96379, 100));
1189 s.setValue(MyMoneyMoney(96379, 100));
1190 s.setAccountId("A000076");
1191 s.setBankID("SPID1");
1192 s.setReconcileFlag(eMyMoney::Split::State::Reconciled);
1193 t.addSplit(s);
1194
1195 s.setPayeeId("P000001");
1196 s.setShares(MyMoneyMoney(-96379, 100));
1197 s.setValue(MyMoneyMoney(-96379, 100));
1198 s.setAccountId("A000276");
1199 s.setBankID("SPID2");
1200 s.setReconcileFlag(eMyMoney::Split::State::Cleared);
1201 s.clearId();
1202 t.addSplit(s);
1203
1204 sch.setTransaction(t);
1205
1206 QDomDocument doc("TEST");
1207 QDomElement el = doc.createElement("SCHEDULE-CONTAINER");
1208 doc.appendChild(el);
1209 MyMoneyXmlContentHandler::writeSchedule(sch, doc, el);
1210
1211 QCOMPARE(doc.doctype().name(), QLatin1String("TEST"));
1212 QDomElement scheduleContainer = doc.documentElement();
1213 QVERIFY(scheduleContainer.isElement());
1214 QCOMPARE(scheduleContainer.tagName(), QLatin1String("SCHEDULE-CONTAINER"));
1215 QCOMPARE(scheduleContainer.childNodes().size(), 1);
1216 QVERIFY(scheduleContainer.childNodes().at(0).isElement());
1217
1218 QDomElement schedule = scheduleContainer.childNodes().at(0).toElement();
1219 QCOMPARE(schedule.tagName(), QLatin1String("SCHEDULED_TX"));
1220 QCOMPARE(schedule.attribute("id"), QLatin1String("SCH0001"));
1221 QCOMPARE(schedule.attribute("paymentType"), QLatin1String("1"));
1222 QCOMPARE(schedule.attribute("autoEnter"), QLatin1String("1"));
1223 QCOMPARE(schedule.attribute("occurenceMultiplier"), QLatin1String("123")); // krazy:exclude=spelling
1224 QCOMPARE(schedule.attribute("startDate"), QDate::currentDate().toString(Qt::ISODate));
1225 QCOMPARE(schedule.attribute("lastPayment"), QDate::currentDate().toString(Qt::ISODate));
1226 QCOMPARE(schedule.attribute("occurenceMultiplier"), QLatin1String("123")); // krazy:exclude=spelling
1227 QCOMPARE(schedule.attribute("occurence"), QLatin1String("4")); // krazy:exclude=spelling
1228 QCOMPARE(schedule.attribute("type"), QLatin1String("1"));
1229 QCOMPARE(schedule.attribute("name"), QLatin1String("A Name"));
1230 QCOMPARE(schedule.attribute("fixed"), QLatin1String("1"));
1231 QCOMPARE(schedule.attribute("endDate"), QString());
1232 QCOMPARE(schedule.childNodes().size(), 2);
1233
1234 QVERIFY(schedule.childNodes().at(0).isElement());
1235 QDomElement payments = schedule.childNodes().at(0).toElement();
1236
1237 QVERIFY(schedule.childNodes().at(1).isElement());
1238 QDomElement transaction = schedule.childNodes().at(1).toElement();
1239 QCOMPARE(transaction.tagName(), QLatin1String("TRANSACTION"));
1240 QCOMPARE(transaction.attribute("id"), QString());
1241 QCOMPARE(transaction.attribute("postdate"), QLatin1String("2001-12-28"));
1242 QCOMPARE(transaction.attribute("commodity"), QLatin1String("EUR"));
1243 QCOMPARE(transaction.attribute("memo"), QLatin1String("Wohnung:Miete"));
1244 QCOMPARE(transaction.attribute("entrydate"), QLatin1String("2003-09-29"));
1245 QCOMPARE(transaction.childNodes().size(), 2);
1246
1247 QVERIFY(transaction.childNodes().at(0).isElement());
1248 QDomElement splits = transaction.childNodes().at(0).toElement();
1249 QCOMPARE(splits.tagName(), QLatin1String("SPLITS"));
1250 QCOMPARE(splits.childNodes().size(), 2);
1251 QVERIFY(splits.childNodes().at(0).isElement());
1252 QDomElement split1 = splits.childNodes().at(0).toElement();
1253 QCOMPARE(split1.tagName(), QLatin1String("SPLIT"));
1254 QCOMPARE(split1.attribute("id"), QLatin1String("S0001"));
1255 QCOMPARE(split1.attribute("payee"), QLatin1String("P000001"));
1256 QCOMPARE(split1.attribute("reconcileflag"), QLatin1String("2"));
1257 QCOMPARE(split1.attribute("shares"), QLatin1String("96379/100"));
1258 QCOMPARE(split1.attribute("reconciledate"), QString());
1259 QCOMPARE(split1.attribute("action"), QString());
1260 QCOMPARE(split1.attribute("bankid"), QString());
1261 QCOMPARE(split1.attribute("account"), QLatin1String("A000076"));
1262 QCOMPARE(split1.attribute("number"), QString());
1263 QCOMPARE(split1.attribute("value"), QLatin1String("96379/100"));
1264 QCOMPARE(split1.attribute("memo"), QString());
1265 QCOMPARE(split1.childNodes().size(), 0);
1266
1267 QVERIFY(splits.childNodes().at(1).isElement());
1268 QDomElement split2 = splits.childNodes().at(1).toElement();
1269 QCOMPARE(split2.tagName(), QLatin1String("SPLIT"));
1270 QCOMPARE(split2.attribute("id"), QLatin1String("S0002"));
1271 QCOMPARE(split2.attribute("payee"), QLatin1String("P000001"));
1272 QCOMPARE(split2.attribute("reconcileflag"), QLatin1String("1"));
1273 QCOMPARE(split2.attribute("shares"), QLatin1String("-96379/100"));
1274 QCOMPARE(split2.attribute("reconciledate"), QString());
1275 QCOMPARE(split2.attribute("action"), QString());
1276 QCOMPARE(split2.attribute("bankid"), QString());
1277 QCOMPARE(split2.attribute("account"), QLatin1String("A000276"));
1278 QCOMPARE(split2.attribute("number"), QString());
1279 QCOMPARE(split2.attribute("value"), QLatin1String("-96379/100"));
1280 QCOMPARE(split2.attribute("memo"), QString());
1281 QCOMPARE(split2.childNodes().size(), 0);
1282
1283 QDomElement keyValuePairs = transaction.childNodes().at(1).toElement();
1284 QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS"));
1285 QCOMPARE(keyValuePairs.childNodes().size(), 1);
1286
1287 QVERIFY(keyValuePairs.childNodes().at(0).isElement());
1288 QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement();
1289 QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR"));
1290 QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("key"));
1291 QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value"));
1292 QCOMPARE(keyValuePair1.childNodes().size(), 0);
1293 }
1294
testOverdue()1295 void MyMoneyXmlContentHandlerTest::testOverdue()
1296 {
1297 MyMoneySchedule sch_overdue;
1298 MyMoneySchedule sch_intime;
1299
1300 // the following checks only work correctly, if currentDate() is
1301 // between the 1st and 27th. If it is between 28th and 31st
1302 // we don't perform them. Note: this should be fixed.
1303 if (QDate::currentDate().day() > 27 || QDate::currentDate().day() == 1) {
1304 qDebug() << "testOverdue() skipped because current day is between 28th and 2nd";
1305 return;
1306 }
1307
1308 QDate startDate = QDate::currentDate().addDays(-1).addMonths(-23);
1309 QDate lastPaymentDate = QDate::currentDate().addDays(-1).addMonths(-1);
1310
1311 QString ref = QString(
1312 "<!DOCTYPE TEST>\n"
1313 "<SCHEDULE-CONTAINER>\n"
1314 " <SCHEDULED_TX startDate=\"%1\" autoEnter=\"0\" weekendOption=\"2\" lastPayment=\"%2\" paymentType=\"8\" endDate=\"\" type=\"5\" id=\"SCH0002\" name=\"A Name\" fixed=\"0\" occurenceMultiplier=\"1\" occurence=\"32\" >\n" // krazy:exclude=spelling
1315 " <PAYMENTS>\n"
1316 " <PAYMENT date=\"%3\" />\n"
1317 " </PAYMENTS>\n"
1318 " <TRANSACTION postdate=\"\" memo=\"Wohnung:Miete\" id=\"\" commodity=\"EUR\" entrydate=\"\" >\n"
1319 " <SPLITS>\n"
1320 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" account=\"A000076\" />\n"
1321 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"-96379/100\" action=\"\" number=\"\" reconcileflag=\"1\" memo=\"\" value=\"-96379/100\" account=\"A000276\" />\n"
1322 " </SPLITS>\n"
1323 " <KEYVALUEPAIRS>\n"
1324 " <PAIR key=\"key\" value=\"value\" />\n"
1325 " </KEYVALUEPAIRS>\n"
1326 " </TRANSACTION>\n"
1327 " </SCHEDULED_TX>\n"
1328 "</SCHEDULE-CONTAINER>\n");
1329 QString ref_overdue = ref.arg(startDate.toString(Qt::ISODate))
1330 .arg(lastPaymentDate.toString(Qt::ISODate))
1331 .arg(lastPaymentDate.toString(Qt::ISODate));
1332
1333 QString ref_intime = ref.arg(startDate.addDays(1).toString(Qt::ISODate))
1334 .arg(lastPaymentDate.addDays(1).toString(Qt::ISODate))
1335 .arg(lastPaymentDate.addDays(1).toString(Qt::ISODate));
1336
1337 QDomDocument doc;
1338 QDomElement node;
1339
1340 // std::cout << ref_intime << std::endl;
1341 try {
1342 doc.setContent(ref_overdue);
1343 node = doc.documentElement().firstChild().toElement();
1344 sch_overdue = MyMoneyXmlContentHandler::readSchedule(node);
1345 doc.setContent(ref_intime);
1346 node = doc.documentElement().firstChild().toElement();
1347 sch_intime = MyMoneyXmlContentHandler::readSchedule(node);
1348
1349 QCOMPARE(sch_overdue.isOverdue(), true);
1350 QCOMPARE(sch_intime.isOverdue(), false);
1351
1352 } catch (const MyMoneyException &) {
1353 QFAIL("Unexpected exception");
1354 }
1355 }
1356
testNextPayment()1357 void MyMoneyXmlContentHandlerTest::testNextPayment()
1358 /*
1359 * Test for a schedule where a payment hasn't yet been made.
1360 * First payment is in the future.
1361 */
1362 {
1363 MyMoneySchedule sch;
1364 QString future_sched = QString(
1365 "<!DOCTYPE TEST>\n"
1366 "<SCHEDULE-CONTAINER>\n"
1367 "<SCHEDULED_TX startDate=\"2007-02-17\" autoEnter=\"1\" weekendOption=\"2\" lastPayment=\"\" paymentType=\"1\" endDate=\"\" type=\"1\" id=\"SCH000058\" name=\"Car Tax\" fixed=\"1\" occurenceMultiplier=\"1\" occurence=\"16384\" >\n" // krazy:exclude=spelling
1368 " <PAYMENTS/>\n"
1369 " <TRANSACTION postdate=\"\" memo=\"\" id=\"\" commodity=\"GBP\" entrydate=\"\" >\n"
1370 " <SPLITS>\n"
1371 " <SPLIT payee=\"P000044\" reconciledate=\"\" shares=\"-15000/100\" action=\"Withdrawal\" bankid=\"\" number=\"\" reconcileflag=\"0\" memo=\"\" value=\"-15000/100\" account=\"A000155\" />\n"
1372 " <SPLIT payee=\"\" reconciledate=\"\" shares=\"15000/100\" action=\"Withdrawal\" bankid=\"\" number=\"\" reconcileflag=\"0\" memo=\"\" value=\"15000/100\" account=\"A000182\" />\n"
1373 " </SPLITS>\n"
1374 " <KEYVALUEPAIRS/>\n"
1375 " </TRANSACTION>\n"
1376 "</SCHEDULED_TX>\n"
1377 "</SCHEDULE-CONTAINER>\n"
1378 );
1379
1380 QDomDocument doc;
1381 QDomElement node;
1382 doc.setContent(future_sched);
1383 node = doc.documentElement().firstChild().toElement();
1384
1385 try {
1386 sch = MyMoneyXmlContentHandler::readSchedule(node);
1387 QCOMPARE(sch.nextPayment(QDate(2007, 2, 14)), QDate(2007, 2, 17));
1388 QCOMPARE(sch.nextPayment(QDate(2007, 2, 17)), QDate(2008, 2, 17));
1389 QCOMPARE(sch.nextPayment(QDate(2007, 2, 18)), QDate(2008, 2, 17));
1390
1391 } catch (const MyMoneyException &) {
1392 QFAIL("Unexpected exception");
1393 }
1394 }
1395
testNextPaymentOnLastDayOfMonth()1396 void MyMoneyXmlContentHandlerTest::testNextPaymentOnLastDayOfMonth()
1397 {
1398 MyMoneySchedule sch;
1399 QString future_sched = QString(
1400 "<!DOCTYPE TEST>\n"
1401 "<SCHEDULE-CONTAINER>\n"
1402 "<SCHEDULED_TX startDate=\"2014-10-31\" autoEnter=\"1\" weekendOption=\"2\" lastPayment=\"\" paymentType=\"1\" endDate=\"\" type=\"1\" id=\"SCH000058\" name=\"Car Tax\" fixed=\"1\" occurenceMultiplier=\"1\" occurence=\"32\" >\n" // krazy:exclude=spelling
1403 " <PAYMENTS/>\n"
1404 " <TRANSACTION postdate=\"\" memo=\"\" id=\"\" commodity=\"GBP\" entrydate=\"\" >\n"
1405 " <SPLITS>\n"
1406 " <SPLIT payee=\"P000044\" reconciledate=\"\" shares=\"-15000/100\" action=\"Withdrawal\" bankid=\"\" number=\"\" reconcileflag=\"0\" memo=\"\" value=\"-15000/100\" account=\"A000155\" />\n"
1407 " <SPLIT payee=\"\" reconciledate=\"\" shares=\"15000/100\" action=\"Withdrawal\" bankid=\"\" number=\"\" reconcileflag=\"0\" memo=\"\" value=\"15000/100\" account=\"A000182\" />\n"
1408 " </SPLITS>\n"
1409 " <KEYVALUEPAIRS/>\n"
1410 " </TRANSACTION>\n"
1411 "</SCHEDULED_TX>\n"
1412 "</SCHEDULE-CONTAINER>\n"
1413 );
1414
1415 QDomDocument doc;
1416 QDomElement node;
1417 doc.setContent(future_sched);
1418 node = doc.documentElement().firstChild().toElement();
1419
1420 try {
1421 sch = MyMoneyXmlContentHandler::readSchedule(node);
1422 QDate nextPayment;
1423
1424 // check for the first payment to happen
1425 nextPayment = sch.nextPayment(QDate(2014, 10, 1));
1426 QCOMPARE(nextPayment, QDate(2014, 10, 31));
1427 sch.setLastPayment(nextPayment);
1428
1429 QCOMPARE(sch.nextPayment(QDate(2014, 11, 1)), QDate(2014, 11, 30));
1430 QCOMPARE(sch.nextPayment(QDate(2014, 12, 1)), QDate(2014, 12, 31));
1431 QCOMPARE(sch.nextPayment(QDate(2015, 1, 1)), QDate(2015, 1, 31));
1432 QCOMPARE(sch.nextPayment(QDate(2015, 2, 1)), QDate(2015, 2, 28));
1433 QCOMPARE(sch.nextPayment(QDate(2015, 3, 1)), QDate(2015, 3, 31));
1434
1435 // now check that we also cover leap years
1436 QCOMPARE(sch.nextPayment(QDate(2016, 2, 1)), QDate(2016, 2, 29));
1437 QCOMPARE(sch.nextPayment(QDate(2016, 3, 1)), QDate(2016, 3, 31));
1438
1439 } catch (const MyMoneyException &) {
1440 QFAIL("Unexpected exception");
1441 }
1442 }
1443
testPaymentDates()1444 void MyMoneyXmlContentHandlerTest::testPaymentDates()
1445 {
1446 MyMoneySchedule sch;
1447 QString ref_ok = QString(
1448 "<!DOCTYPE TEST>\n"
1449 "<SCHEDULE-CONTAINER>\n"
1450
1451 "<SCHEDULED_TX startDate=\"2003-12-31\" autoEnter=\"1\" weekendOption=\"0\" lastPayment=\"2006-01-31\" paymentType=\"2\" endDate=\"\" type=\"2\" id=\"SCH000032\" name=\"DSL\" fixed=\"0\" occurenceMultiplier=\"1\" occurence=\"32\" >\n" // krazy:exclude=spelling
1452 " <PAYMENTS/>\n"
1453 " <TRANSACTION postdate=\"2006-02-28\" memo=\"\" id=\"\" commodity=\"EUR\" entrydate=\"\" >\n"
1454 " <SPLITS>\n"
1455 " <SPLIT payee=\"P000076\" reconciledate=\"\" shares=\"1200/100\" action=\"Deposit\" bankid=\"\" number=\"\" reconcileflag=\"0\" memo=\"\" value=\"1200/100\" account=\"A000076\" />\n"
1456 " <SPLIT payee=\"\" reconciledate=\"\" shares=\"-1200/100\" action=\"Deposit\" bankid=\"\" number=\"\" reconcileflag=\"0\" memo=\"\" value=\"-1200/100\" account=\"A000009\" />\n"
1457 " </SPLITS>\n"
1458 " <KEYVALUEPAIRS/>\n"
1459 " </TRANSACTION>\n"
1460 "</SCHEDULED_TX>\n"
1461
1462 "</SCHEDULE-CONTAINER>\n"
1463 );
1464
1465 QDomDocument doc;
1466 QDomElement node;
1467 doc.setContent(ref_ok);
1468 node = doc.documentElement().firstChild().toElement();
1469
1470 QDate startDate(2006, 1, 28);
1471 QDate endDate(2006, 5, 30);
1472
1473 try {
1474 sch = MyMoneyXmlContentHandler::readSchedule(node);
1475 QDate nextPayment = sch.nextPayment(startDate);
1476 QList<QDate> list = sch.paymentDates(nextPayment, endDate);
1477 QCOMPARE(list.count(), 3);
1478 QCOMPARE(list[0], QDate(2006, 2, 28));
1479 QCOMPARE(list[1], QDate(2006, 3, 31));
1480 // Would fall on a Sunday so gets moved back to 28th.
1481 QCOMPARE(list[2], QDate(2006, 4, 28));
1482
1483 // Add tests for each possible occurrence.
1484 // Check how paymentDates is meant to work
1485 // Build a list of expected dates and compare
1486 // Schedule::Occurrence::Once
1487 sch.setOccurrence(Schedule::Occurrence::Once);
1488 startDate.setDate(2009, 1, 1);
1489 endDate.setDate(2009, 12, 31);
1490 sch.setStartDate(startDate);
1491 sch.setNextDueDate(startDate);
1492 list = sch.paymentDates(startDate, endDate);
1493 QCOMPARE(list.count(), 1);
1494 QCOMPARE(list[0], QDate(2009, 1, 1));
1495 // Schedule::Occurrence::Daily
1496 sch.setOccurrence(Schedule::Occurrence::Daily);
1497 startDate.setDate(2009, 1, 1);
1498 endDate.setDate(2009, 1, 5);
1499 sch.setStartDate(startDate);
1500 sch.setNextDueDate(startDate);
1501 list = sch.paymentDates(startDate, endDate);
1502 QCOMPARE(list.count(), 5);
1503 QCOMPARE(list[0], QDate(2009, 1, 1));
1504 QCOMPARE(list[1], QDate(2009, 1, 2));
1505 // Would fall on Saturday so gets moved to 2nd.
1506 QCOMPARE(list[2], QDate(2009, 1, 2));
1507 // Would fall on Sunday so gets moved to 2nd.
1508 QCOMPARE(list[3], QDate(2009, 1, 2));
1509 QCOMPARE(list[4], QDate(2009, 1, 5));
1510 // Schedule::Occurrence::Daily with multiplier 2
1511 sch.setOccurrenceMultiplier(2);
1512 list = sch.paymentDates(startDate.addDays(1), endDate);
1513 QCOMPARE(list.count(), 2);
1514 // Would fall on Sunday so gets moved to 2nd.
1515 QCOMPARE(list[0], QDate(2009, 1, 2));
1516 QCOMPARE(list[1], QDate(2009, 1, 5));
1517 sch.setOccurrenceMultiplier(1);
1518 // Schedule::Occurrence::Weekly
1519 sch.setOccurrence(Schedule::Occurrence::Weekly);
1520 startDate.setDate(2009, 1, 6);
1521 endDate.setDate(2009, 2, 4);
1522 sch.setStartDate(startDate);
1523 sch.setNextDueDate(startDate);
1524 list = sch.paymentDates(startDate, endDate);
1525 QCOMPARE(list.count(), 5);
1526 QCOMPARE(list[0], QDate(2009, 1, 6));
1527 QCOMPARE(list[1], QDate(2009, 1, 13));
1528 QCOMPARE(list[2], QDate(2009, 1, 20));
1529 QCOMPARE(list[3], QDate(2009, 1, 27));
1530 QCOMPARE(list[4], QDate(2009, 2, 3));
1531 // Schedule::Occurrence::EveryOtherWeek
1532 sch.setOccurrence(Schedule::Occurrence::EveryOtherWeek);
1533 startDate.setDate(2009, 2, 5);
1534 endDate.setDate(2009, 4, 3);
1535 sch.setStartDate(startDate);
1536 sch.setNextDueDate(startDate);
1537 list = sch.paymentDates(startDate, endDate);
1538 QCOMPARE(list.count(), 5);
1539 QCOMPARE(list[0], QDate(2009, 2, 5));
1540 QCOMPARE(list[1], QDate(2009, 2, 19));
1541 QCOMPARE(list[2], QDate(2009, 3, 5));
1542 QCOMPARE(list[3], QDate(2009, 3, 19));
1543 QCOMPARE(list[4], QDate(2009, 4, 2));
1544 // Schedule::Occurrence::Fortnightly
1545 sch.setOccurrence(Schedule::Occurrence::Fortnightly);
1546 startDate.setDate(2009, 4, 4);
1547 endDate.setDate(2009, 5, 31);
1548 sch.setStartDate(startDate);
1549 sch.setNextDueDate(startDate);
1550 list = sch.paymentDates(startDate, endDate);
1551 QCOMPARE(list.count(), 4);
1552 // First one would fall on a Saturday and would get moved
1553 // to 3rd which is before start date so is not in list.
1554 // Would fall on a Saturday so gets moved to 17th.
1555 QCOMPARE(list[0], QDate(2009, 4, 17));
1556 // Would fall on a Saturday so gets moved to 1st.
1557 QCOMPARE(list[1], QDate(2009, 5, 1));
1558 // Would fall on a Saturday so gets moved to 15th.
1559 QCOMPARE(list[2], QDate(2009, 5, 15));
1560 // Would fall on a Saturday so gets moved to 29th.
1561 QCOMPARE(list[3], QDate(2009, 5, 29));
1562 // Schedule::Occurrence::EveryHalfMonth
1563 sch.setOccurrence(Schedule::Occurrence::EveryHalfMonth);
1564 startDate.setDate(2009, 6, 1);
1565 endDate.setDate(2009, 8, 11);
1566 sch.setStartDate(startDate);
1567 sch.setNextDueDate(startDate);
1568 list = sch.paymentDates(startDate, endDate);
1569 QCOMPARE(list.count(), 5);
1570 QCOMPARE(list[0], QDate(2009, 6, 1));
1571 QCOMPARE(list[1], QDate(2009, 6, 16));
1572 QCOMPARE(list[2], QDate(2009, 7, 1));
1573 QCOMPARE(list[3], QDate(2009, 7, 16));
1574 // Would fall on a Saturday so gets moved to 31st.
1575 QCOMPARE(list[4], QDate(2009, 7, 31));
1576 // Schedule::Occurrence::EveryThreeWeeks
1577 sch.setOccurrence(Schedule::Occurrence::EveryThreeWeeks);
1578 startDate.setDate(2009, 8, 12);
1579 endDate.setDate(2009, 11, 12);
1580 sch.setStartDate(startDate);
1581 sch.setNextDueDate(startDate);
1582 list = sch.paymentDates(startDate, endDate);
1583 QCOMPARE(list.count(), 5);
1584 QCOMPARE(list[0], QDate(2009, 8, 12));
1585 QCOMPARE(list[1], QDate(2009, 9, 2));
1586 QCOMPARE(list[2], QDate(2009, 9, 23));
1587 QCOMPARE(list[3], QDate(2009, 10, 14));
1588 QCOMPARE(list[4], QDate(2009, 11, 4));
1589 // Schedule::Occurrence::EveryFourWeeks
1590 sch.setOccurrence(Schedule::Occurrence::EveryFourWeeks);
1591 startDate.setDate(2009, 11, 13);
1592 endDate.setDate(2010, 3, 13);
1593 sch.setStartDate(startDate);
1594 sch.setNextDueDate(startDate);
1595 list = sch.paymentDates(startDate, endDate);
1596 QCOMPARE(list.count(), 5);
1597 QCOMPARE(list[0], QDate(2009, 11, 13));
1598 QCOMPARE(list[1], QDate(2009, 12, 11));
1599 QCOMPARE(list[2], QDate(2010, 1, 8));
1600 QCOMPARE(list[3], QDate(2010, 2, 5));
1601 QCOMPARE(list[4], QDate(2010, 3, 5));
1602 // Schedule::Occurrence::EveryThirtyDays
1603 sch.setOccurrence(Schedule::Occurrence::EveryThirtyDays);
1604 startDate.setDate(2010, 3, 19);
1605 endDate.setDate(2010, 7, 19);
1606 sch.setStartDate(startDate);
1607 sch.setNextDueDate(startDate);
1608 list = sch.paymentDates(startDate, endDate);
1609 QCOMPARE(list.count(), 5);
1610 QCOMPARE(list[0], QDate(2010, 3, 19));
1611 // Would fall on a Sunday so gets moved to 16th.
1612 QCOMPARE(list[1], QDate(2010, 4, 16));
1613 QCOMPARE(list[2], QDate(2010, 5, 18));
1614 QCOMPARE(list[3], QDate(2010, 6, 17));
1615 // Would fall on a Saturday so gets moved to 16th.
1616 QCOMPARE(list[4], QDate(2010, 7, 16));
1617 // Schedule::Occurrence::EveryEightWeeks
1618 sch.setOccurrence(Schedule::Occurrence::EveryEightWeeks);
1619 startDate.setDate(2010, 7, 26);
1620 endDate.setDate(2011, 3, 26);
1621 sch.setStartDate(startDate);
1622 sch.setNextDueDate(startDate);
1623 list = sch.paymentDates(startDate, endDate);
1624 QCOMPARE(list.count(), 5);
1625 QCOMPARE(list[0], QDate(2010, 7, 26));
1626 QCOMPARE(list[1], QDate(2010, 9, 20));
1627 QCOMPARE(list[2], QDate(2010, 11, 15));
1628 QCOMPARE(list[3], QDate(2011, 1, 10));
1629 QCOMPARE(list[4], QDate(2011, 3, 7));
1630 // Schedule::Occurrence::EveryOtherMonth
1631 sch.setOccurrence(Schedule::Occurrence::EveryOtherMonth);
1632 startDate.setDate(2011, 3, 14);
1633 endDate.setDate(2011, 11, 20);
1634 sch.setStartDate(startDate);
1635 sch.setNextDueDate(startDate);
1636 list = sch.paymentDates(startDate, endDate);
1637 QCOMPARE(list.count(), 5);
1638 QCOMPARE(list[0], QDate(2011, 3, 14));
1639 // Would fall on a Saturday so gets moved to 13th.
1640 QCOMPARE(list[1], QDate(2011, 5, 13));
1641 QCOMPARE(list[2], QDate(2011, 7, 14));
1642 QCOMPARE(list[3], QDate(2011, 9, 14));
1643 QCOMPARE(list[4], QDate(2011, 11, 14));
1644 // Schedule::Occurrence::EveryThreeMonths
1645 sch.setOccurrence(Schedule::Occurrence::EveryThreeMonths);
1646 startDate.setDate(2011, 11, 15);
1647 endDate.setDate(2012, 11, 19);
1648 sch.setStartDate(startDate);
1649 sch.setNextDueDate(startDate);
1650 list = sch.paymentDates(startDate, endDate);
1651 QCOMPARE(list.count(), 5);
1652 QCOMPARE(list[0], QDate(2011, 11, 15));
1653 QCOMPARE(list[1], QDate(2012, 2, 15));
1654 QCOMPARE(list[2], QDate(2012, 5, 15));
1655 QCOMPARE(list[3], QDate(2012, 8, 15));
1656 QCOMPARE(list[4], QDate(2012, 11, 15));
1657 // Schedule::Occurrence::Quarterly
1658 sch.setOccurrence(Schedule::Occurrence::Quarterly);
1659 startDate.setDate(2012, 11, 20);
1660 endDate.setDate(2013, 11, 23);
1661 sch.setStartDate(startDate);
1662 sch.setNextDueDate(startDate);
1663 list = sch.paymentDates(startDate, endDate);
1664 QCOMPARE(list.count(), 5);
1665 QCOMPARE(list[0], QDate(2012, 11, 20));
1666 QCOMPARE(list[1], QDate(2013, 2, 20));
1667 QCOMPARE(list[2], QDate(2013, 5, 20));
1668 QCOMPARE(list[3], QDate(2013, 8, 20));
1669 QCOMPARE(list[4], QDate(2013, 11, 20));
1670 // Schedule::Occurrence::EveryFourMonths
1671 sch.setOccurrence(Schedule::Occurrence::EveryFourMonths);
1672 startDate.setDate(2013, 11, 21);
1673 endDate.setDate(2015, 3, 23);
1674 sch.setStartDate(startDate);
1675 sch.setNextDueDate(startDate);
1676 list = sch.paymentDates(startDate, endDate);
1677 QCOMPARE(list.count(), 5);
1678 QCOMPARE(list[0], QDate(2013, 11, 21));
1679 QCOMPARE(list[1], QDate(2014, 3, 21));
1680 QCOMPARE(list[2], QDate(2014, 7, 21));
1681 QCOMPARE(list[3], QDate(2014, 11, 21));
1682 // Would fall on a Saturday so gets moved to 20th.
1683 QCOMPARE(list[4], QDate(2015, 3, 20));
1684 // Schedule::Occurrence::TwiceYearly
1685 sch.setOccurrence(Schedule::Occurrence::TwiceYearly);
1686 startDate.setDate(2015, 3, 22);
1687 endDate.setDate(2017, 3, 29);
1688 sch.setStartDate(startDate);
1689 sch.setNextDueDate(startDate);
1690 list = sch.paymentDates(startDate, endDate);
1691 QCOMPARE(list.count(), 4);
1692 // First date would fall on a Sunday which would get moved
1693 // to 20th which is before start date so not in list.
1694 QCOMPARE(list[0], QDate(2015, 9, 22));
1695 QCOMPARE(list[1], QDate(2016, 3, 22));
1696 QCOMPARE(list[2], QDate(2016, 9, 22));
1697 QCOMPARE(list[3], QDate(2017, 3, 22));
1698 // Schedule::Occurrence::Yearly
1699 sch.setOccurrence(Schedule::Occurrence::Yearly);
1700 startDate.setDate(2017, 3, 23);
1701 endDate.setDate(2021, 3, 29);
1702 sch.setStartDate(startDate);
1703 sch.setNextDueDate(startDate);
1704 list = sch.paymentDates(startDate, endDate);
1705 QCOMPARE(list.count(), 5);
1706 QCOMPARE(list[0], QDate(2017, 3, 23));
1707 QCOMPARE(list[1], QDate(2018, 3, 23));
1708 // Would fall on a Saturday so gets moved to 22nd.
1709 QCOMPARE(list[2], QDate(2019, 3, 22));
1710 QCOMPARE(list[3], QDate(2020, 3, 23));
1711 QCOMPARE(list[4], QDate(2021, 3, 23));
1712 // Schedule::Occurrence::EveryOtherYear
1713 sch.setOccurrence(Schedule::Occurrence::EveryOtherYear);
1714 startDate.setDate(2021, 3, 24);
1715 endDate.setDate(2029, 3, 30);
1716 sch.setStartDate(startDate);
1717 sch.setNextDueDate(startDate);
1718 list = sch.paymentDates(startDate, endDate);
1719 QCOMPARE(list.count(), 5);
1720 QCOMPARE(list[0], QDate(2021, 3, 24));
1721 QCOMPARE(list[1], QDate(2023, 3, 24));
1722 QCOMPARE(list[2], QDate(2025, 3, 24));
1723 QCOMPARE(list[3], QDate(2027, 3, 24));
1724 // Would fall on a Saturday so gets moved to 23rd.
1725 QCOMPARE(list[4], QDate(2029, 3, 23));
1726 } catch (const MyMoneyException &) {
1727 QFAIL("Unexpected exception");
1728 }
1729 }
1730
testHasReferenceTo()1731 void MyMoneyXmlContentHandlerTest::testHasReferenceTo()
1732 {
1733 MyMoneySchedule sch;
1734 QString ref_ok = QString(
1735 "<!DOCTYPE TEST>\n"
1736 "<SCHEDULE-CONTAINER>\n"
1737 " <SCHEDULED_TX startDate=\"%1\" autoEnter=\"1\" weekendOption=\"2\" lastPayment=\"%2\" paymentType=\"1\" endDate=\"\" type=\"1\" id=\"SCH0002\" name=\"A Name\" fixed=\"1\" occurenceMultiplier=\"1\" occurence=\"4\" >\n" // krazy:exclude=spelling
1738 " <PAYMENTS>\n"
1739 " <PAYMENT date=\"%3\" />\n"
1740 " </PAYMENTS>\n"
1741 " <TRANSACTION postdate=\"2001-12-28\" memo=\"Wohnung:Miete\" id=\"\" commodity=\"EUR\" entrydate=\"2003-09-29\" >\n"
1742 " <SPLITS>\n"
1743 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" account=\"A000076\" />\n"
1744 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"-96379/100\" action=\"\" number=\"\" reconcileflag=\"1\" memo=\"\" value=\"-96379/100\" account=\"A000276\" />\n"
1745 " </SPLITS>\n"
1746 " <KEYVALUEPAIRS>\n"
1747 " <PAIR key=\"key\" value=\"value\" />\n"
1748 " </KEYVALUEPAIRS>\n"
1749 " </TRANSACTION>\n"
1750 " </SCHEDULED_TX>\n"
1751 "</SCHEDULE-CONTAINER>\n"
1752 ).arg(QDate::currentDate().toString(Qt::ISODate))
1753 .arg(QDate::currentDate().toString(Qt::ISODate))
1754 .arg(QDate::currentDate().toString(Qt::ISODate));
1755
1756 QDomDocument doc;
1757 QDomElement node;
1758 doc.setContent(ref_ok);
1759 node = doc.documentElement().firstChild().toElement();
1760
1761 try {
1762 sch = MyMoneyXmlContentHandler::readSchedule(node);
1763
1764 } catch (const MyMoneyException &) {
1765 QFAIL("Unexpected exception");
1766 }
1767
1768 QCOMPARE(sch.hasReferenceTo(QLatin1String("P000001")), true);
1769 QCOMPARE(sch.hasReferenceTo(QLatin1String("A000276")), true);
1770 QCOMPARE(sch.hasReferenceTo(QLatin1String("A000076")), true);
1771 QCOMPARE(sch.hasReferenceTo(QLatin1String("EUR")), true);
1772 }
1773
testPaidEarlyOneTime()1774 void MyMoneyXmlContentHandlerTest::testPaidEarlyOneTime()
1775 {
1776 // this tries to figure out what's wrong with
1777 // https://bugs.kde.org/show_bug.cgi?id=231029
1778
1779 MyMoneySchedule sch;
1780 QDate paymentInFuture = QDate::currentDate().addDays(7);
1781
1782 QString ref_ok = QString(
1783 "<!DOCTYPE TEST>\n"
1784 "<SCHEDULE-CONTAINER>\n"
1785 " <SCHEDULED_TX startDate=\"%1\" autoEnter=\"0\" weekendOption=\"1\" lastPayment=\"%2\" paymentType=\"2\" endDate=\"%3\" type=\"4\" id=\"SCH0042\" name=\"A Name\" fixed=\"1\" occurenceMultiplier=\"1\" occurence=\"32\" >\n" // krazy:exclude=spelling
1786 " <PAYMENTS/>\n"
1787 " <TRANSACTION postdate=\"\" memo=\"\" id=\"\" commodity=\"GBP\" entrydate=\"\" >\n"
1788 " <SPLITS>\n"
1789 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"Transfer\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" id=\"S0001\" account=\"A000076\" />\n"
1790 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"-96379/100\" action=\"Transfer\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"-96379/100\" id=\"S0002\" account=\"A000276\" />\n"
1791 " </SPLITS>\n"
1792 " </TRANSACTION>\n"
1793 " </SCHEDULED_TX>\n"
1794 "</SCHEDULE-CONTAINER>\n"
1795 ).arg(paymentInFuture.toString(Qt::ISODate))
1796 .arg(paymentInFuture.toString(Qt::ISODate))
1797 .arg(paymentInFuture.toString(Qt::ISODate));
1798
1799 QDomDocument doc;
1800 QDomElement node;
1801 doc.setContent(ref_ok);
1802 node = doc.documentElement().firstChild().toElement();
1803
1804 try {
1805 sch = MyMoneyXmlContentHandler::readSchedule(node);
1806 QCOMPARE(sch.isFinished(), true);
1807 QCOMPARE(sch.occurrence(), Schedule::Occurrence::Monthly);
1808 QCOMPARE(sch.paymentDates(QDate::currentDate(), QDate::currentDate().addDays(21)).count(), 0);
1809 } catch (const MyMoneyException &) {
1810 QFAIL("Unexpected exception");
1811 }
1812 }
1813
testReplaceId()1814 void MyMoneyXmlContentHandlerTest::testReplaceId()
1815 {
1816 MyMoneySchedule sch;
1817 QDate paymentInFuture = QDate::currentDate().addDays(7);
1818
1819 QString ref_ok = QString(
1820 "<!DOCTYPE TEST>\n"
1821 "<SCHEDULE-CONTAINER>\n"
1822 " <SCHEDULED_TX startDate=\"%1\" autoEnter=\"0\" weekendOption=\"1\" lastPayment=\"%2\" paymentType=\"2\" endDate=\"%3\" type=\"4\" id=\"SCH0042\" name=\"A Name\" fixed=\"1\" occurenceMultiplier=\"1\" occurence=\"32\" >\n" // krazy:exclude=spelling
1823 " <PAYMENTS/>\n"
1824 " <TRANSACTION postdate=\"\" memo=\"\" id=\"\" commodity=\"GBP\" entrydate=\"\" >\n"
1825 " <SPLITS>\n"
1826 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"96379/100\" action=\"Transfer\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"96379/100\" id=\"S0001\" account=\"A000076\" />\n"
1827 " <SPLIT payee=\"P000001\" reconciledate=\"\" shares=\"-96379/100\" action=\"Transfer\" number=\"\" reconcileflag=\"2\" memo=\"\" value=\"-96379/100\" id=\"S0002\" account=\"A000276\" />\n"
1828 " </SPLITS>\n"
1829 " </TRANSACTION>\n"
1830 " </SCHEDULED_TX>\n"
1831 "</SCHEDULE-CONTAINER>\n"
1832 ).arg(paymentInFuture.toString(Qt::ISODate))
1833 .arg(paymentInFuture.toString(Qt::ISODate))
1834 .arg(paymentInFuture.toString(Qt::ISODate));
1835
1836 QDomDocument doc;
1837 QDomElement node;
1838 doc.setContent(ref_ok);
1839 node = doc.documentElement().firstChild().toElement();
1840
1841 try {
1842 sch = MyMoneyXmlContentHandler::readSchedule(node);
1843 QCOMPARE(sch.transaction().postDate().isValid(), false);
1844 QCOMPARE(sch.transaction().splits()[0].accountId(), QLatin1String("A000076"));
1845 QCOMPARE(sch.transaction().splits()[1].accountId(), QLatin1String("A000276"));
1846 QCOMPARE(sch.replaceId(QLatin1String("A000079"), QLatin1String("A000076")), true);
1847 QCOMPARE(sch.transaction().splits()[0].accountId(), QLatin1String("A000079"));
1848 QCOMPARE(sch.transaction().splits()[1].accountId(), QLatin1String("A000276"));
1849
1850 } catch (const MyMoneyException &) {
1851 QFAIL("Unexpected exception");
1852 }
1853
1854 }
1855