Changeset View
Changeset View
Standalone View
Standalone View
kmymoney/plugins/xmlhelper/xmlstoragehelper.cpp
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * Copyright 2004-2006 Ace Jones <acejones@users.sourceforge.net> | ||||
3 | * Copyright 2006 Darren Gould <darren_gould@gmx.de> | ||||
4 | * Copyright 2007-2010 Alvaro Soliverez <asoliverez@gmail.com> | ||||
5 | * Copyright 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> | ||||
6 | * | ||||
7 | * This program is free software; you can redistribute it and/or | ||||
8 | * modify it under the terms of the GNU General Public License as | ||||
9 | * published by the Free Software Foundation; either version 2 of | ||||
10 | * the License, or (at your option) any later version. | ||||
11 | * | ||||
12 | * This program is distributed in the hope that it will be useful, | ||||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
15 | * GNU General Public License for more details. | ||||
16 | * | ||||
17 | * You should have received a copy of the GNU General Public License | ||||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | */ | ||||
20 | | ||||
21 | #include "xmlstoragehelper.h" | ||||
22 | | ||||
23 | // ---------------------------------------------------------------------------- | ||||
24 | // QT Includes | ||||
25 | | ||||
26 | #include <QDomElement> | ||||
27 | #include <QDomDocument> | ||||
28 | #include <QDate> | ||||
29 | #include <QMap> | ||||
30 | | ||||
31 | // ---------------------------------------------------------------------------- | ||||
32 | // KDE Includes | ||||
33 | | ||||
34 | // ---------------------------------------------------------------------------- | ||||
35 | // Project Includes | ||||
36 | | ||||
37 | #include "mymoneymoney.h" | ||||
38 | #include "mymoneybudget.h" | ||||
39 | #include "mymoneyreport.h" | ||||
40 | #include "mymoneytransactionfilter.h" | ||||
41 | #include "mymoneyenums.h" | ||||
42 | #include "mymoneyexception.h" | ||||
43 | | ||||
44 | namespace Element { | ||||
45 | | ||||
46 | enum class Report { | ||||
47 | Payee, | ||||
48 | Tag, | ||||
49 | Account, | ||||
50 | Text, | ||||
51 | Type, | ||||
52 | State, | ||||
53 | Number, | ||||
54 | Amount, | ||||
55 | Dates, | ||||
56 | Category, | ||||
57 | AccountGroup | ||||
58 | }; | ||||
59 | | ||||
60 | enum class Budget { | ||||
61 | Budget = 0, | ||||
62 | Account, | ||||
63 | Period | ||||
64 | }; | ||||
65 | } | ||||
66 | | ||||
67 | namespace Attribute { | ||||
68 | | ||||
69 | enum class Report { | ||||
70 | ID = 0, Group, Type, Name, Comment, ConvertCurrency, Favorite, | ||||
71 | SkipZero, DateLock, DataLock, MovingAverageDays, | ||||
72 | IncludesActuals, IncludesForecast, IncludesPrice, | ||||
73 | IncludesAveragePrice, IncludesMovingAverage, | ||||
74 | IncludesSchedules, IncludesTransfers, IncludesUnused, | ||||
75 | MixedTime, Investments, Budget, | ||||
76 | ShowRowTotals, ShowColumnTotals, Detail, | ||||
77 | ColumnsAreDays, ChartType, | ||||
78 | ChartCHGridLines, ChartSVGridLines, | ||||
79 | ChartDataLabels, ChartByDefault, | ||||
80 | LogYAxis, ChartLineWidth, ColumnType, RowType, | ||||
81 | DataRangeStart, DataRangeEnd, | ||||
82 | DataMajorTick, DataMinorTick, | ||||
83 | YLabelsPrecision, QueryColumns, | ||||
84 | Tax, Loans, HideTransactions, InvestmentSum, | ||||
85 | SettlementPeriod, ShowSTLTCapitalGains, TermsSeparator, | ||||
86 | Pattern, CaseSensitive, RegEx, InvertText, State, | ||||
87 | From, To, | ||||
88 | // insert new entries above this line | ||||
89 | LastAttribute | ||||
90 | }; | ||||
91 | | ||||
92 | enum class Budget { | ||||
93 | ID = 0, | ||||
94 | Name, | ||||
95 | Start, | ||||
96 | Version, | ||||
97 | BudgetLevel, | ||||
98 | BudgetSubAccounts, | ||||
99 | Amount, | ||||
100 | // insert new entries above this line | ||||
101 | LastAttribute | ||||
102 | }; | ||||
103 | | ||||
104 | } | ||||
105 | | ||||
106 | namespace MyMoneyXmlContentHandler2 { | ||||
107 | | ||||
108 | enum class Node { | ||||
109 | Report, | ||||
110 | Budget | ||||
111 | }; | ||||
112 | | ||||
113 | QString nodeName(Node nodeID) | ||||
114 | { | ||||
115 | static const QHash<Node, QString> nodeNames { | ||||
116 | {Node::Report, QStringLiteral("REPORT")}, | ||||
117 | {Node::Budget, QStringLiteral("BUDGET")} | ||||
118 | }; | ||||
119 | return nodeNames.value(nodeID); | ||||
120 | } | ||||
121 | | ||||
122 | uint qHash(const Node key, uint seed) { return ::qHash(static_cast<uint>(key), seed); } | ||||
123 | | ||||
124 | QString elementName(Element::Report elementID) | ||||
125 | { | ||||
126 | static const QMap<Element::Report, QString> elementNames { | ||||
127 | {Element::Report::Payee, QStringLiteral("PAYEE")}, | ||||
128 | {Element::Report::Tag, QStringLiteral("TAG")}, | ||||
129 | {Element::Report::Account, QStringLiteral("ACCOUNT")}, | ||||
130 | {Element::Report::Text, QStringLiteral("TEXT")}, | ||||
131 | {Element::Report::Type, QStringLiteral("TYPE")}, | ||||
132 | {Element::Report::State, QStringLiteral("STATE")}, | ||||
133 | {Element::Report::Number, QStringLiteral("NUMBER")}, | ||||
134 | {Element::Report::Amount, QStringLiteral("AMOUNT")}, | ||||
135 | {Element::Report::Dates, QStringLiteral("DATES")}, | ||||
136 | {Element::Report::Category, QStringLiteral("CATEGORY")}, | ||||
137 | {Element::Report::AccountGroup, QStringLiteral("ACCOUNTGROUP")} | ||||
138 | }; | ||||
139 | return elementNames.value(elementID); | ||||
140 | } | ||||
141 | | ||||
142 | QString attributeName(Attribute::Report attributeID) | ||||
143 | { | ||||
144 | static const QMap<Attribute::Report, QString> attributeNames { | ||||
145 | {Attribute::Report::ID, QStringLiteral("id")}, | ||||
146 | {Attribute::Report::Group, QStringLiteral("group")}, | ||||
147 | {Attribute::Report::Type, QStringLiteral("type")}, | ||||
148 | {Attribute::Report::Name, QStringLiteral("name")}, | ||||
149 | {Attribute::Report::Comment, QStringLiteral("comment")}, | ||||
150 | {Attribute::Report::ConvertCurrency, QStringLiteral("convertcurrency")}, | ||||
151 | {Attribute::Report::Favorite, QStringLiteral("favorite")}, | ||||
152 | {Attribute::Report::SkipZero, QStringLiteral("skipZero")}, | ||||
153 | {Attribute::Report::DateLock, QStringLiteral("datelock")}, | ||||
154 | {Attribute::Report::DataLock, QStringLiteral("datalock")}, | ||||
155 | {Attribute::Report::MovingAverageDays, QStringLiteral("movingaveragedays")}, | ||||
156 | {Attribute::Report::IncludesActuals, QStringLiteral("includesactuals")}, | ||||
157 | {Attribute::Report::IncludesForecast, QStringLiteral("includesforecast")}, | ||||
158 | {Attribute::Report::IncludesPrice, QStringLiteral("includesprice")}, | ||||
159 | {Attribute::Report::IncludesAveragePrice, QStringLiteral("includesaverageprice")}, | ||||
160 | {Attribute::Report::IncludesMovingAverage, QStringLiteral("includesmovingaverage")}, | ||||
161 | {Attribute::Report::IncludesSchedules, QStringLiteral("includeschedules")}, | ||||
162 | {Attribute::Report::IncludesTransfers, QStringLiteral("includestransfers")}, | ||||
163 | {Attribute::Report::IncludesUnused, QStringLiteral("includeunused")}, | ||||
164 | {Attribute::Report::MixedTime, QStringLiteral("mixedtime")}, | ||||
165 | {Attribute::Report::Investments, QStringLiteral("investments")}, | ||||
166 | {Attribute::Report::Budget, QStringLiteral("budget")}, | ||||
167 | {Attribute::Report::ShowRowTotals, QStringLiteral("showrowtotals")}, | ||||
168 | {Attribute::Report::ShowColumnTotals, QStringLiteral("showcolumntotals")}, | ||||
169 | {Attribute::Report::Detail, QStringLiteral("detail")}, | ||||
170 | {Attribute::Report::ColumnsAreDays, QStringLiteral("columnsaredays")}, | ||||
171 | {Attribute::Report::ChartType, QStringLiteral("charttype")}, | ||||
172 | {Attribute::Report::ChartCHGridLines, QStringLiteral("chartchgridlines")}, | ||||
173 | {Attribute::Report::ChartSVGridLines, QStringLiteral("chartsvgridlines")}, | ||||
174 | {Attribute::Report::ChartDataLabels, QStringLiteral("chartdatalabels")}, | ||||
175 | {Attribute::Report::ChartByDefault, QStringLiteral("chartbydefault")}, | ||||
176 | {Attribute::Report::LogYAxis, QStringLiteral("logYaxis")}, | ||||
177 | {Attribute::Report::ChartLineWidth, QStringLiteral("chartlinewidth")}, | ||||
178 | {Attribute::Report::ColumnType, QStringLiteral("columntype")}, | ||||
179 | {Attribute::Report::RowType, QStringLiteral("rowtype")}, | ||||
180 | {Attribute::Report::DataRangeStart, QStringLiteral("dataRangeStart")}, | ||||
181 | {Attribute::Report::DataRangeEnd, QStringLiteral("dataRangeEnd")}, | ||||
182 | {Attribute::Report::DataMajorTick, QStringLiteral("dataMajorTick")}, | ||||
183 | {Attribute::Report::DataMinorTick, QStringLiteral("dataMinorTick")}, | ||||
184 | {Attribute::Report::YLabelsPrecision, QStringLiteral("yLabelsPrecision")}, | ||||
185 | {Attribute::Report::QueryColumns, QStringLiteral("querycolumns")}, | ||||
186 | {Attribute::Report::Tax, QStringLiteral("tax")}, | ||||
187 | {Attribute::Report::Loans, QStringLiteral("loans")}, | ||||
188 | {Attribute::Report::HideTransactions, QStringLiteral("hidetransactions")}, | ||||
189 | {Attribute::Report::InvestmentSum, QStringLiteral("investmentsum")}, | ||||
190 | {Attribute::Report::SettlementPeriod, QStringLiteral("settlementperiod")}, | ||||
191 | {Attribute::Report::ShowSTLTCapitalGains, QStringLiteral("showSTLTCapitalGains")}, | ||||
192 | {Attribute::Report::TermsSeparator, QStringLiteral("tseparator")}, | ||||
193 | {Attribute::Report::Pattern, QStringLiteral("pattern")}, | ||||
194 | {Attribute::Report::CaseSensitive, QStringLiteral("casesensitive")}, | ||||
195 | {Attribute::Report::RegEx, QStringLiteral("regex")}, | ||||
196 | {Attribute::Report::InvertText, QStringLiteral("inverttext")}, | ||||
197 | {Attribute::Report::State, QStringLiteral("state")}, | ||||
198 | {Attribute::Report::From, QStringLiteral("from")}, | ||||
199 | {Attribute::Report::To, QStringLiteral("to")} | ||||
200 | }; | ||||
201 | return attributeNames.value(attributeID); | ||||
202 | } | ||||
203 | | ||||
204 | QString elementName(Element::Budget elementID) | ||||
205 | { | ||||
206 | static const QMap<Element::Budget, QString> elementNames { | ||||
207 | {Element::Budget::Budget, QStringLiteral("BUDGET")}, | ||||
208 | {Element::Budget::Account, QStringLiteral("ACCOUNT")}, | ||||
209 | {Element::Budget::Period, QStringLiteral("PERIOD")} | ||||
210 | }; | ||||
211 | return elementNames.value(elementID); | ||||
212 | } | ||||
213 | | ||||
214 | QString attributeName(Attribute::Budget attributeID) | ||||
215 | { | ||||
216 | static const QMap<Attribute::Budget, QString> attributeNames { | ||||
217 | {Attribute::Budget::ID, QStringLiteral("id")}, | ||||
218 | {Attribute::Budget::Name, QStringLiteral("name")}, | ||||
219 | {Attribute::Budget::Start, QStringLiteral("start")}, | ||||
220 | {Attribute::Budget::Version, QStringLiteral("version")}, | ||||
221 | {Attribute::Budget::BudgetLevel, QStringLiteral("budgetlevel")}, | ||||
222 | {Attribute::Budget::BudgetSubAccounts, QStringLiteral("budgetsubaccounts")}, | ||||
223 | {Attribute::Budget::Amount, QStringLiteral("amount")} | ||||
224 | }; | ||||
225 | return attributeNames.value(attributeID); | ||||
226 | } | ||||
227 | | ||||
228 | QHash<eMyMoney::Report::RowType, QString> rowTypesLUT() | ||||
229 | { | ||||
230 | static const QHash<eMyMoney::Report::RowType, QString> lut { | ||||
231 | {eMyMoney::Report::RowType::NoRows, QStringLiteral("none")}, | ||||
232 | {eMyMoney::Report::RowType::AssetLiability, QStringLiteral("assetliability")}, | ||||
233 | {eMyMoney::Report::RowType::ExpenseIncome, QStringLiteral("expenseincome")}, | ||||
234 | {eMyMoney::Report::RowType::Category, QStringLiteral("category")}, | ||||
235 | {eMyMoney::Report::RowType::TopCategory, QStringLiteral("topcategory")}, | ||||
236 | {eMyMoney::Report::RowType::Account, QStringLiteral("account")}, | ||||
237 | {eMyMoney::Report::RowType::Tag, QStringLiteral("tag")}, | ||||
238 | {eMyMoney::Report::RowType::Payee, QStringLiteral("payee")}, | ||||
239 | {eMyMoney::Report::RowType::Month, QStringLiteral("month")}, | ||||
240 | {eMyMoney::Report::RowType::Week, QStringLiteral("week")}, | ||||
241 | {eMyMoney::Report::RowType::TopAccount, QStringLiteral("topaccount")}, | ||||
242 | {eMyMoney::Report::RowType::AccountByTopAccount, QStringLiteral("topaccount-account")}, | ||||
243 | {eMyMoney::Report::RowType::EquityType, QStringLiteral("equitytype")}, | ||||
244 | {eMyMoney::Report::RowType::AccountType, QStringLiteral("accounttype")}, | ||||
245 | {eMyMoney::Report::RowType::Institution, QStringLiteral("institution")}, | ||||
246 | {eMyMoney::Report::RowType::Budget, QStringLiteral("budget")}, | ||||
247 | {eMyMoney::Report::RowType::BudgetActual, QStringLiteral("budgetactual")}, | ||||
248 | {eMyMoney::Report::RowType::Schedule, QStringLiteral("schedule")}, | ||||
249 | {eMyMoney::Report::RowType::AccountInfo, QStringLiteral("accountinfo")}, | ||||
250 | {eMyMoney::Report::RowType::AccountLoanInfo, QStringLiteral("accountloaninfo")}, | ||||
251 | {eMyMoney::Report::RowType::AccountReconcile, QStringLiteral("accountreconcile")}, | ||||
252 | {eMyMoney::Report::RowType::CashFlow, QStringLiteral("cashflow")}, | ||||
253 | }; | ||||
254 | return lut; | ||||
255 | } | ||||
256 | | ||||
257 | QString reportNames(eMyMoney::Report::RowType textID) | ||||
258 | { | ||||
259 | return rowTypesLUT().value(textID); | ||||
260 | } | ||||
261 | | ||||
262 | eMyMoney::Report::RowType stringToRowType(const QString &text) | ||||
263 | { | ||||
264 | return rowTypesLUT().key(text, eMyMoney::Report::RowType::Invalid); | ||||
265 | } | ||||
266 | | ||||
267 | QHash<eMyMoney::Report::ColumnType, QString> columTypesLUT() | ||||
268 | { | ||||
269 | static const QHash<eMyMoney::Report::ColumnType, QString> lut { | ||||
270 | {eMyMoney::Report::ColumnType::NoColumns, QStringLiteral("none")}, | ||||
271 | {eMyMoney::Report::ColumnType::Months, QStringLiteral("months")}, | ||||
272 | {eMyMoney::Report::ColumnType::BiMonths, QStringLiteral("bimonths")}, | ||||
273 | {eMyMoney::Report::ColumnType::Quarters, QStringLiteral("quarters")}, | ||||
274 | // {eMyMoney::Report::ColumnType::, QStringLiteral("4")} | ||||
275 | // {eMyMoney::Report::ColumnType::, QStringLiteral("5")} | ||||
276 | // {eMyMoney::Report::ColumnType::, QStringLiteral("6")} | ||||
277 | {eMyMoney::Report::ColumnType::Weeks, QStringLiteral("weeks")}, | ||||
278 | // {eMyMoney::Report::ColumnType::, QStringLiteral("8")} | ||||
279 | // {eMyMoney::Report::ColumnType::, QStringLiteral("9")} | ||||
280 | // {eMyMoney::Report::ColumnType::, QStringLiteral("10")} | ||||
281 | // {eMyMoney::Report::ColumnType::, QStringLiteral("11")} | ||||
282 | {eMyMoney::Report::ColumnType::Years, QStringLiteral("years")} | ||||
283 | }; | ||||
284 | return lut; | ||||
285 | } | ||||
286 | | ||||
287 | QString reportNames(eMyMoney::Report::ColumnType textID) | ||||
288 | { | ||||
289 | return columTypesLUT().value(textID); | ||||
290 | } | ||||
291 | | ||||
292 | eMyMoney::Report::ColumnType stringToColumnType(const QString &text) | ||||
293 | { | ||||
294 | return columTypesLUT().key(text, eMyMoney::Report::ColumnType::Invalid); | ||||
295 | } | ||||
296 | | ||||
297 | QHash<eMyMoney::Report::QueryColumn, QString> queryColumnsLUT() | ||||
298 | { | ||||
299 | static const QHash<eMyMoney::Report::QueryColumn, QString> lut { | ||||
300 | {eMyMoney::Report::QueryColumn::None, QStringLiteral("none")}, | ||||
301 | {eMyMoney::Report::QueryColumn::Number, QStringLiteral("number")}, | ||||
302 | {eMyMoney::Report::QueryColumn::Payee, QStringLiteral("payee")}, | ||||
303 | {eMyMoney::Report::QueryColumn::Category, QStringLiteral("category")}, | ||||
304 | {eMyMoney::Report::QueryColumn::Tag, QStringLiteral("tag")}, | ||||
305 | {eMyMoney::Report::QueryColumn::Memo, QStringLiteral("memo")}, | ||||
306 | {eMyMoney::Report::QueryColumn::Account, QStringLiteral("account")}, | ||||
307 | {eMyMoney::Report::QueryColumn::Reconciled, QStringLiteral("reconcileflag")}, | ||||
308 | {eMyMoney::Report::QueryColumn::Action, QStringLiteral("action")}, | ||||
309 | {eMyMoney::Report::QueryColumn::Shares, QStringLiteral("shares")}, | ||||
310 | {eMyMoney::Report::QueryColumn::Price, QStringLiteral("price")}, | ||||
311 | {eMyMoney::Report::QueryColumn::Performance, QStringLiteral("performance")}, | ||||
312 | {eMyMoney::Report::QueryColumn::Loan, QStringLiteral("loan")}, | ||||
313 | {eMyMoney::Report::QueryColumn::Balance, QStringLiteral("balance")}, | ||||
314 | {eMyMoney::Report::QueryColumn::CapitalGain, QStringLiteral("capitalgain")} | ||||
315 | }; | ||||
316 | return lut; | ||||
317 | } | ||||
318 | | ||||
319 | QString reportNamesForQC(eMyMoney::Report::QueryColumn textID) | ||||
320 | { | ||||
321 | return queryColumnsLUT().value(textID); | ||||
322 | } | ||||
323 | | ||||
324 | eMyMoney::Report::QueryColumn stringToQueryColumn(const QString &text) | ||||
325 | { | ||||
326 | return queryColumnsLUT().key(text, eMyMoney::Report::QueryColumn::End); | ||||
327 | } | ||||
328 | | ||||
329 | QHash<eMyMoney::Report::DetailLevel, QString> detailLevelLUT() | ||||
330 | { | ||||
331 | static const QHash<eMyMoney::Report::DetailLevel, QString> lut { | ||||
332 | {eMyMoney::Report::DetailLevel::None, QStringLiteral("none")}, | ||||
333 | {eMyMoney::Report::DetailLevel::All, QStringLiteral("all")}, | ||||
334 | {eMyMoney::Report::DetailLevel::Top, QStringLiteral("top")}, | ||||
335 | {eMyMoney::Report::DetailLevel::Group, QStringLiteral("group")}, | ||||
336 | {eMyMoney::Report::DetailLevel::Total, QStringLiteral("total")}, | ||||
337 | {eMyMoney::Report::DetailLevel::End, QStringLiteral("invalid")} | ||||
338 | }; | ||||
339 | return lut; | ||||
340 | } | ||||
341 | | ||||
342 | QString reportNames(eMyMoney::Report::DetailLevel textID) | ||||
343 | { | ||||
344 | return detailLevelLUT().value(textID); | ||||
345 | } | ||||
346 | | ||||
347 | eMyMoney::Report::DetailLevel stringToDetailLevel(const QString &text) | ||||
348 | { | ||||
349 | return detailLevelLUT().key(text, eMyMoney::Report::DetailLevel::End); | ||||
350 | } | ||||
351 | | ||||
352 | QHash<eMyMoney::Report::ChartType, QString> chartTypeLUT() | ||||
353 | { | ||||
354 | static const QHash<eMyMoney::Report::ChartType, QString> lut { | ||||
355 | {eMyMoney::Report::ChartType::None, QStringLiteral("none")}, | ||||
356 | {eMyMoney::Report::ChartType::Line, QStringLiteral("line")}, | ||||
357 | {eMyMoney::Report::ChartType::Bar, QStringLiteral("bar")}, | ||||
358 | {eMyMoney::Report::ChartType::Pie, QStringLiteral("pie")}, | ||||
359 | {eMyMoney::Report::ChartType::Ring, QStringLiteral("ring")}, | ||||
360 | {eMyMoney::Report::ChartType::StackedBar, QStringLiteral("stackedbar")} | ||||
361 | }; | ||||
362 | return lut; | ||||
363 | } | ||||
364 | | ||||
365 | QString reportNames(eMyMoney::Report::ChartType textID) | ||||
366 | { | ||||
367 | return chartTypeLUT().value(textID); | ||||
368 | } | ||||
369 | | ||||
370 | eMyMoney::Report::ChartType stringToChartType(const QString &text) | ||||
371 | { | ||||
372 | return chartTypeLUT().key(text, eMyMoney::Report::ChartType::End); | ||||
373 | } | ||||
374 | | ||||
375 | QHash<int, QString> typeAttributeLUT() | ||||
376 | { | ||||
377 | static const QHash<int, QString> lut { | ||||
378 | {0, QStringLiteral("all")}, | ||||
379 | {1, QStringLiteral("payments")}, | ||||
380 | {2, QStringLiteral("deposits")}, | ||||
381 | {3, QStringLiteral("transfers")}, | ||||
382 | {4, QStringLiteral("none")}, | ||||
383 | }; | ||||
384 | return lut; | ||||
385 | } | ||||
386 | | ||||
387 | QString typeAttributeToString(int textID) | ||||
388 | { | ||||
389 | return typeAttributeLUT().value(textID); | ||||
390 | } | ||||
391 | | ||||
392 | int stringToTypeAttribute(const QString &text) | ||||
393 | { | ||||
394 | return typeAttributeLUT().key(text, 4); | ||||
395 | } | ||||
396 | | ||||
397 | QHash<int, QString> stateAttributeLUT() | ||||
398 | { | ||||
399 | static const QHash<int, QString> lut { | ||||
400 | {0, QStringLiteral("all")}, | ||||
401 | {1, QStringLiteral("notreconciled")}, | ||||
402 | {2, QStringLiteral("cleared")}, | ||||
403 | {3, QStringLiteral("reconciled")}, | ||||
404 | {4, QStringLiteral("frozen")}, | ||||
405 | {5, QStringLiteral("none")} | ||||
406 | }; | ||||
407 | return lut; | ||||
408 | } | ||||
409 | | ||||
410 | QString stateAttributeToString(int textID) | ||||
411 | { | ||||
412 | return stateAttributeLUT().value(textID); | ||||
413 | } | ||||
414 | | ||||
415 | int stringToStateAttribute(const QString &text) | ||||
416 | { | ||||
417 | return stateAttributeLUT().key(text, 5); | ||||
418 | } | ||||
419 | | ||||
420 | QHash<int, QString> dateLockLUT() | ||||
421 | { | ||||
422 | static const QHash<int, QString> lut { | ||||
423 | {0, QStringLiteral("alldates")}, | ||||
424 | {1, QStringLiteral("untiltoday")}, | ||||
425 | {2, QStringLiteral("currentmonth")}, | ||||
426 | {3, QStringLiteral("currentyear")}, | ||||
427 | {4, QStringLiteral("monthtodate")}, | ||||
428 | {5, QStringLiteral("yeartodate")}, | ||||
429 | {6, QStringLiteral("yeartomonth")}, | ||||
430 | {7, QStringLiteral("lastmonth")}, | ||||
431 | {8, QStringLiteral("lastyear")}, | ||||
432 | {9, QStringLiteral("last7days")}, | ||||
433 | {10, QStringLiteral("last30days")}, | ||||
434 | {11, QStringLiteral("last3months")}, | ||||
435 | {12, QStringLiteral("last6months")}, | ||||
436 | {13, QStringLiteral("last12months")}, | ||||
437 | {14, QStringLiteral("next7days")}, | ||||
438 | {15, QStringLiteral("next30days")}, | ||||
439 | {16, QStringLiteral("next3months")}, | ||||
440 | {17, QStringLiteral("next6months")}, | ||||
441 | {18, QStringLiteral("next12months")}, | ||||
442 | {19, QStringLiteral("userdefined")}, | ||||
443 | {20, QStringLiteral("last3tonext3months")}, | ||||
444 | {21, QStringLiteral("last11Months")}, | ||||
445 | {22, QStringLiteral("currentQuarter")}, | ||||
446 | {23, QStringLiteral("lastQuarter")}, | ||||
447 | {24, QStringLiteral("nextQuarter")}, | ||||
448 | {25, QStringLiteral("currentFiscalYear")}, | ||||
449 | {26, QStringLiteral("lastFiscalYear")}, | ||||
450 | {27, QStringLiteral("today")}, | ||||
451 | {28, QStringLiteral("next18months")} | ||||
452 | }; | ||||
453 | return lut; | ||||
454 | } | ||||
455 | | ||||
456 | QString dateLockAttributeToString(int textID) | ||||
457 | { | ||||
458 | return dateLockLUT().value(textID); | ||||
459 | } | ||||
460 | | ||||
461 | int stringToDateLockAttribute(const QString &text) | ||||
462 | { | ||||
463 | return dateLockLUT().key(text, 0); | ||||
464 | } | ||||
465 | | ||||
466 | QHash<eMyMoney::Report::DataLock, QString> dataLockLUT() | ||||
467 | { | ||||
468 | static const QHash<eMyMoney::Report::DataLock, QString> lut { | ||||
469 | {eMyMoney::Report::DataLock::Automatic, QStringLiteral("automatic")}, | ||||
470 | {eMyMoney::Report::DataLock::UserDefined, QStringLiteral("userdefined")} | ||||
471 | }; | ||||
472 | return lut; | ||||
473 | } | ||||
474 | | ||||
475 | QString reportNames(eMyMoney::Report::DataLock textID) | ||||
476 | { | ||||
477 | return dataLockLUT().value(textID); | ||||
478 | } | ||||
479 | | ||||
480 | eMyMoney::Report::DataLock stringToDataLockAttribute(const QString &text) | ||||
481 | { | ||||
482 | return dataLockLUT().key(text, eMyMoney::Report::DataLock::DataOptionCount); | ||||
483 | } | ||||
484 | | ||||
485 | QHash<int, QString> accountTypeAttributeLUT() | ||||
486 | { | ||||
487 | static const QHash<int, QString> lut { | ||||
488 | {0, QStringLiteral("unknown")}, | ||||
489 | {1, QStringLiteral("checkings")}, | ||||
490 | {2, QStringLiteral("savings")}, | ||||
491 | {3, QStringLiteral("cash")}, | ||||
492 | {4, QStringLiteral("creditcard")}, | ||||
493 | {5, QStringLiteral("loan")}, | ||||
494 | {6, QStringLiteral("certificatedep")}, | ||||
495 | {7, QStringLiteral("investment")}, | ||||
496 | {8, QStringLiteral("moneymarket")}, | ||||
497 | {10, QStringLiteral("asset")}, | ||||
498 | {11, QStringLiteral("liability")}, | ||||
499 | {12, QStringLiteral("currency")}, | ||||
500 | {13, QStringLiteral("income")}, | ||||
501 | {14, QStringLiteral("expense")}, | ||||
502 | {15, QStringLiteral("assetloan")}, | ||||
503 | {16, QStringLiteral("stock")}, | ||||
504 | {17, QStringLiteral("equity")}, | ||||
505 | {18, QStringLiteral("invalid")} | ||||
506 | }; | ||||
507 | return lut; | ||||
508 | } | ||||
509 | | ||||
510 | QString accountTypeAttributeToString(int textID) | ||||
511 | { | ||||
512 | return accountTypeAttributeLUT().value(textID); | ||||
513 | } | ||||
514 | | ||||
515 | int stringToAccountTypeAttribute(const QString &text) | ||||
516 | { | ||||
517 | return accountTypeAttributeLUT().key(text, 0); | ||||
518 | } | ||||
519 | | ||||
520 | eMyMoney::Report::ReportType rowTypeToReportType(eMyMoney::Report::RowType rowType) | ||||
521 | { | ||||
522 | static const QHash<eMyMoney::Report::RowType, eMyMoney::Report::ReportType> reportTypes { | ||||
523 | {eMyMoney::Report::RowType::NoRows, eMyMoney::Report::ReportType::NoReport}, | ||||
524 | {eMyMoney::Report::RowType::AssetLiability, eMyMoney::Report::ReportType::PivotTable}, | ||||
525 | {eMyMoney::Report::RowType::ExpenseIncome, eMyMoney::Report::ReportType::PivotTable}, | ||||
526 | {eMyMoney::Report::RowType::Category, eMyMoney::Report::ReportType::QueryTable}, | ||||
527 | {eMyMoney::Report::RowType::TopCategory, eMyMoney::Report::ReportType::QueryTable}, | ||||
528 | {eMyMoney::Report::RowType::Account, eMyMoney::Report::ReportType::QueryTable}, | ||||
529 | {eMyMoney::Report::RowType::Tag, eMyMoney::Report::ReportType::QueryTable}, | ||||
530 | {eMyMoney::Report::RowType::Payee, eMyMoney::Report::ReportType::QueryTable}, | ||||
531 | {eMyMoney::Report::RowType::Month, eMyMoney::Report::ReportType::QueryTable}, | ||||
532 | {eMyMoney::Report::RowType::Week, eMyMoney::Report::ReportType::QueryTable}, | ||||
533 | {eMyMoney::Report::RowType::TopAccount, eMyMoney::Report::ReportType::QueryTable}, | ||||
534 | {eMyMoney::Report::RowType::AccountByTopAccount, eMyMoney::Report::ReportType::QueryTable}, | ||||
535 | {eMyMoney::Report::RowType::EquityType, eMyMoney::Report::ReportType::QueryTable}, | ||||
536 | {eMyMoney::Report::RowType::AccountType, eMyMoney::Report::ReportType::QueryTable}, | ||||
537 | {eMyMoney::Report::RowType::Institution, eMyMoney::Report::ReportType::QueryTable}, | ||||
538 | {eMyMoney::Report::RowType::Budget, eMyMoney::Report::ReportType::PivotTable}, | ||||
539 | {eMyMoney::Report::RowType::BudgetActual, eMyMoney::Report::ReportType::PivotTable}, | ||||
540 | {eMyMoney::Report::RowType::Schedule, eMyMoney::Report::ReportType::InfoTable}, | ||||
541 | {eMyMoney::Report::RowType::AccountInfo, eMyMoney::Report::ReportType::InfoTable}, | ||||
542 | {eMyMoney::Report::RowType::AccountLoanInfo, eMyMoney::Report::ReportType::InfoTable}, | ||||
543 | {eMyMoney::Report::RowType::AccountReconcile, eMyMoney::Report::ReportType::QueryTable}, | ||||
544 | {eMyMoney::Report::RowType::CashFlow, eMyMoney::Report::ReportType::QueryTable}, | ||||
545 | }; | ||||
546 | return reportTypes.value(rowType, eMyMoney::Report::ReportType::Invalid); | ||||
547 | } | ||||
548 | | ||||
549 | QHash<eMyMoney::Budget::Level, QString> budgetLevelLUT() | ||||
550 | { | ||||
551 | static const QHash<eMyMoney::Budget::Level, QString> lut { | ||||
552 | {eMyMoney::Budget::Level::None, QStringLiteral("none")}, | ||||
553 | {eMyMoney::Budget::Level::Monthly, QStringLiteral("monthly")}, | ||||
554 | {eMyMoney::Budget::Level::MonthByMonth, QStringLiteral("monthbymonth")}, | ||||
555 | {eMyMoney::Budget::Level::Yearly, QStringLiteral("yearly")}, | ||||
556 | {eMyMoney::Budget::Level::Max, QStringLiteral("invalid")}, | ||||
557 | }; | ||||
558 | return lut; | ||||
559 | } | ||||
560 | | ||||
561 | QString budgetNames(eMyMoney::Budget::Level textID) | ||||
562 | { | ||||
563 | return budgetLevelLUT().value(textID); | ||||
564 | } | ||||
565 | | ||||
566 | eMyMoney::Budget::Level stringToBudgetLevel(const QString &text) | ||||
567 | { | ||||
568 | return budgetLevelLUT().key(text, eMyMoney::Budget::Level::Max); | ||||
569 | } | ||||
570 | | ||||
571 | QHash<eMyMoney::Budget::Level, QString> budgetLevelsLUT() | ||||
572 | { | ||||
573 | static const QHash<eMyMoney::Budget::Level, QString> lut { | ||||
574 | {eMyMoney::Budget::Level::None, QStringLiteral("none")}, | ||||
575 | {eMyMoney::Budget::Level::Monthly, QStringLiteral("monthly")}, | ||||
576 | {eMyMoney::Budget::Level::MonthByMonth, QStringLiteral("monthbymonth")}, | ||||
577 | {eMyMoney::Budget::Level::Yearly, QStringLiteral("yearly")}, | ||||
578 | {eMyMoney::Budget::Level::Max, QStringLiteral("invalid")}, | ||||
579 | }; | ||||
580 | return lut; | ||||
581 | } | ||||
582 | | ||||
583 | QString budgetLevels(eMyMoney::Budget::Level textID) | ||||
584 | { | ||||
585 | return budgetLevelsLUT().value(textID); | ||||
586 | } | ||||
587 | | ||||
588 | void writeBaseXML(const QString &id, QDomDocument &document, QDomElement &el) | ||||
589 | { | ||||
590 | Q_UNUSED(document); | ||||
591 | | ||||
592 | el.setAttribute(QStringLiteral("id"), id); | ||||
593 | } | ||||
594 | | ||||
595 | MyMoneyReport readReport(const QDomElement &node) | ||||
596 | { | ||||
597 | if (nodeName(Node::Report) != node.tagName()) | ||||
598 | throw MYMONEYEXCEPTION_CSTRING("Node was not REPORT"); | ||||
599 | | ||||
600 | MyMoneyReport report(node.attribute(attributeName(Attribute::Report::ID))); | ||||
601 | | ||||
602 | // The goal of this reading method is 100% backward AND 100% forward | ||||
603 | // compatibility. Any report ever created with any version of KMyMoney | ||||
604 | // should be able to be loaded by this method (as long as it's one of the | ||||
605 | // report types supported in this version, of course) | ||||
606 | | ||||
607 | | ||||
608 | // read report's internals | ||||
609 | QString type = node.attribute(attributeName(Attribute::Report::Type)); | ||||
610 | if (type.startsWith(QLatin1String("pivottable"))) | ||||
611 | report.setReportType(eMyMoney::Report::ReportType::PivotTable); | ||||
612 | else if (type.startsWith(QLatin1String("querytable"))) | ||||
613 | report.setReportType(eMyMoney::Report::ReportType::QueryTable); | ||||
614 | else if (type.startsWith(QLatin1String("infotable"))) | ||||
615 | report.setReportType(eMyMoney::Report::ReportType::InfoTable); | ||||
616 | else | ||||
617 | throw MYMONEYEXCEPTION_CSTRING("Unknown report type"); | ||||
618 | | ||||
619 | report.setGroup(node.attribute(attributeName(Attribute::Report::Group))); | ||||
620 | | ||||
621 | report.clearTransactionFilter(); | ||||
622 | | ||||
623 | // read date tab | ||||
624 | QString datelockstr = node.attribute(attributeName(Attribute::Report::DateLock), "userdefined"); | ||||
625 | // Handle the pivot 1.2/query 1.1 case where the values were saved as | ||||
626 | // numbers | ||||
627 | bool ok = false; | ||||
628 | int i = datelockstr.toUInt(&ok); | ||||
629 | if (!ok) { | ||||
630 | i = stringToDateLockAttribute(datelockstr); | ||||
631 | if (i == -1) | ||||
632 | i = (int)eMyMoney::TransactionFilter::Date::UserDefined; | ||||
633 | } | ||||
634 | report.setDateFilter(static_cast<eMyMoney::TransactionFilter::Date>(i)); | ||||
635 | | ||||
636 | // read general tab | ||||
637 | report.setName(node.attribute(attributeName(Attribute::Report::Name))); | ||||
638 | report.setComment(node.attribute(attributeName(Attribute::Report::Comment), "Extremely old report")); | ||||
639 | report.setConvertCurrency(node.attribute(attributeName(Attribute::Report::ConvertCurrency), "1").toUInt()); | ||||
640 | report.setFavorite(node.attribute(attributeName(Attribute::Report::Favorite), "0").toUInt()); | ||||
641 | report.setSkipZero(node.attribute(attributeName(Attribute::Report::SkipZero), "0").toUInt()); | ||||
642 | | ||||
643 | if (report.reportType() == eMyMoney::Report::ReportType::PivotTable) { | ||||
644 | // read report's internals | ||||
645 | report.setIncludingBudgetActuals(node.attribute(attributeName(Attribute::Report::IncludesActuals), "0").toUInt()); | ||||
646 | report.setIncludingForecast(node.attribute(attributeName(Attribute::Report::IncludesForecast), "0").toUInt()); | ||||
647 | report.setIncludingPrice(node.attribute(attributeName(Attribute::Report::IncludesPrice), "0").toUInt()); | ||||
648 | report.setIncludingAveragePrice(node.attribute(attributeName(Attribute::Report::IncludesAveragePrice), "0").toUInt()); | ||||
649 | report.setMixedTime(node.attribute(attributeName(Attribute::Report::MixedTime), "0").toUInt()); | ||||
650 | report.setInvestmentsOnly(node.attribute(attributeName(Attribute::Report::Investments), "0").toUInt()); | ||||
651 | | ||||
652 | // read rows/columns tab | ||||
653 | if (node.hasAttribute(attributeName(Attribute::Report::Budget))) | ||||
654 | report.setBudget(node.attribute(attributeName(Attribute::Report::Budget))); | ||||
655 | | ||||
656 | const auto rowTypeFromXML = stringToRowType(node.attribute(attributeName(Attribute::Report::RowType))); | ||||
657 | if (rowTypeFromXML != eMyMoney::Report::RowType::Invalid) | ||||
658 | report.setRowType(rowTypeFromXML); | ||||
659 | else | ||||
660 | report.setRowType(eMyMoney::Report::RowType::ExpenseIncome); | ||||
661 | | ||||
662 | if (node.hasAttribute(attributeName(Attribute::Report::ShowRowTotals))) | ||||
663 | report.setShowingRowTotals(node.attribute(attributeName(Attribute::Report::ShowRowTotals)).toUInt()); | ||||
664 | else if (report.rowType() == eMyMoney::Report::RowType::ExpenseIncome) // for backward compatibility | ||||
665 | report.setShowingRowTotals(true); | ||||
666 | report.setShowingColumnTotals(node.attribute(attributeName(Attribute::Report::ShowColumnTotals), "1").toUInt()); | ||||
667 | | ||||
668 | //check for reports with older settings which didn't have the detail attribute | ||||
669 | const auto detailLevelFromXML = stringToDetailLevel(node.attribute(attributeName(Attribute::Report::Detail))); | ||||
670 | if (detailLevelFromXML != eMyMoney::Report::DetailLevel::End) | ||||
671 | report.setDetailLevel(detailLevelFromXML); | ||||
672 | else | ||||
673 | report.setDetailLevel(eMyMoney::Report::DetailLevel::All); | ||||
674 | | ||||
675 | report.setIncludingMovingAverage(node.attribute(attributeName(Attribute::Report::IncludesMovingAverage), "0").toUInt()); | ||||
676 | if (report.isIncludingMovingAverage()) | ||||
677 | report.setMovingAverageDays(node.attribute(attributeName(Attribute::Report::MovingAverageDays), "1").toUInt()); | ||||
678 | report.setIncludingSchedules(node.attribute(attributeName(Attribute::Report::IncludesSchedules), "0").toUInt()); | ||||
679 | report.setIncludingTransfers(node.attribute(attributeName(Attribute::Report::IncludesTransfers), "0").toUInt()); | ||||
680 | report.setIncludingUnusedAccounts(node.attribute(attributeName(Attribute::Report::IncludesUnused), "0").toUInt()); | ||||
681 | report.setColumnsAreDays(node.attribute(attributeName(Attribute::Report::ColumnsAreDays), "0").toUInt()); | ||||
682 | | ||||
683 | // read chart tab | ||||
684 | const auto chartTypeFromXML = stringToChartType(node.attribute(attributeName(Attribute::Report::ChartType))); | ||||
685 | if (chartTypeFromXML != eMyMoney::Report::ChartType::End) | ||||
686 | report.setChartType(chartTypeFromXML); | ||||
687 | else | ||||
688 | report.setChartType(eMyMoney::Report::ChartType::None); | ||||
689 | | ||||
690 | report.setChartCHGridLines(node.attribute(attributeName(Attribute::Report::ChartCHGridLines), "1").toUInt()); | ||||
691 | report.setChartSVGridLines(node.attribute(attributeName(Attribute::Report::ChartSVGridLines), "1").toUInt()); | ||||
692 | report.setChartDataLabels(node.attribute(attributeName(Attribute::Report::ChartDataLabels), "1").toUInt()); | ||||
693 | report.setChartByDefault(node.attribute(attributeName(Attribute::Report::ChartByDefault), "0").toUInt()); | ||||
694 | report.setLogYAxis(node.attribute(attributeName(Attribute::Report::LogYAxis), "0").toUInt()); | ||||
695 | report.setChartLineWidth(node.attribute(attributeName(Attribute::Report::ChartLineWidth), QString(MyMoneyReport::m_lineWidth)).toUInt()); | ||||
696 | | ||||
697 | // read range tab | ||||
698 | const auto columnTypeFromXML = stringToColumnType(node.attribute(attributeName(Attribute::Report::ColumnType))); | ||||
699 | if (columnTypeFromXML != eMyMoney::Report::ColumnType::Invalid) | ||||
700 | report.setColumnType(columnTypeFromXML); | ||||
701 | else | ||||
702 | report.setColumnType(eMyMoney::Report::ColumnType::Months); | ||||
703 | | ||||
704 | const auto dataLockFromXML = stringToDataLockAttribute(node.attribute(attributeName(Attribute::Report::DataLock))); | ||||
705 | if (dataLockFromXML != eMyMoney::Report::DataLock::DataOptionCount) | ||||
706 | report.setDataFilter(dataLockFromXML); | ||||
707 | else | ||||
708 | report.setDataFilter(eMyMoney::Report::DataLock::Automatic); | ||||
709 | | ||||
710 | report.setDataRangeStart(node.attribute(attributeName(Attribute::Report::DataRangeStart), "0")); | ||||
711 | report.setDataRangeEnd(node.attribute(attributeName(Attribute::Report::DataRangeEnd), "0")); | ||||
712 | report.setDataMajorTick(node.attribute(attributeName(Attribute::Report::DataMajorTick), "0")); | ||||
713 | report.setDataMinorTick(node.attribute(attributeName(Attribute::Report::DataMinorTick), "0")); | ||||
714 | report.setYLabelsPrecision(node.attribute(attributeName(Attribute::Report::YLabelsPrecision), "2").toUInt()); | ||||
715 | } else if (report.reportType() == eMyMoney::Report::ReportType::QueryTable) { | ||||
716 | // read rows/columns tab | ||||
717 | const auto rowTypeFromXML = stringToRowType(node.attribute(attributeName(Attribute::Report::RowType))); | ||||
718 | if (rowTypeFromXML != eMyMoney::Report::RowType::Invalid) | ||||
719 | report.setRowType(rowTypeFromXML); | ||||
720 | else | ||||
721 | report.setRowType(eMyMoney::Report::RowType::Account); | ||||
722 | | ||||
723 | unsigned qc = 0; | ||||
724 | QStringList columns = node.attribute(attributeName(Attribute::Report::QueryColumns), "none").split(','); | ||||
725 | foreach (const auto column, columns) { | ||||
726 | const int queryColumnFromXML = stringToQueryColumn(column); | ||||
727 | i = stringToQueryColumn(column); | ||||
728 | if (queryColumnFromXML != eMyMoney::Report::QueryColumn::End) | ||||
729 | qc |= queryColumnFromXML; | ||||
730 | } | ||||
731 | report.setQueryColumns(static_cast<eMyMoney::Report::QueryColumn>(qc)); | ||||
732 | | ||||
733 | report.setTax(node.attribute(attributeName(Attribute::Report::Tax), "0").toUInt()); | ||||
734 | report.setInvestmentsOnly(node.attribute(attributeName(Attribute::Report::Investments), "0").toUInt()); | ||||
735 | report.setLoansOnly(node.attribute(attributeName(Attribute::Report::Loans), "0").toUInt()); | ||||
736 | report.setHideTransactions(node.attribute(attributeName(Attribute::Report::HideTransactions), "0").toUInt()); | ||||
737 | report.setShowingColumnTotals(node.attribute(attributeName(Attribute::Report::ShowColumnTotals), "1").toUInt()); | ||||
738 | const auto detailLevelFromXML = stringToDetailLevel(node.attribute(attributeName(Attribute::Report::Detail), "none")); | ||||
739 | if (detailLevelFromXML == eMyMoney::Report::DetailLevel::All) | ||||
740 | report.setDetailLevel(detailLevelFromXML); | ||||
741 | else | ||||
742 | report.setDetailLevel(eMyMoney::Report::DetailLevel::None); | ||||
743 | | ||||
744 | // read performance or capital gains tab | ||||
745 | if (report.queryColumns() & eMyMoney::Report::QueryColumn::Performance) | ||||
746 | report.setInvestmentSum(static_cast<eMyMoney::Report::InvestmentSum>(node.attribute(attributeName(Attribute::Report::InvestmentSum), QString::number(static_cast<int>(eMyMoney::Report::InvestmentSum::Period))).toInt())); | ||||
747 | | ||||
748 | // read capital gains tab | ||||
749 | if (report.queryColumns() & eMyMoney::Report::QueryColumn::CapitalGain) { | ||||
750 | report.setInvestmentSum(static_cast<eMyMoney::Report::InvestmentSum>(node.attribute(attributeName(Attribute::Report::InvestmentSum), QString::number(static_cast<int>(eMyMoney::Report::InvestmentSum::Sold))).toInt())); | ||||
751 | if (report.investmentSum() == eMyMoney::Report::InvestmentSum::Sold) { | ||||
752 | report.setShowSTLTCapitalGains(node.attribute(attributeName(Attribute::Report::ShowSTLTCapitalGains), "0").toUInt()); | ||||
753 | report.setSettlementPeriod(node.attribute(attributeName(Attribute::Report::SettlementPeriod), "3").toUInt()); | ||||
754 | report.setTermSeparator(QDate::fromString(node.attribute(attributeName(Attribute::Report::TermsSeparator), QDate::currentDate().addYears(-1).toString(Qt::ISODate)),Qt::ISODate)); | ||||
755 | } | ||||
756 | } | ||||
757 | } else if (report.reportType() == eMyMoney::Report::ReportType::InfoTable) { | ||||
758 | if (node.hasAttribute(attributeName(Attribute::Report::ShowRowTotals))) | ||||
759 | report.setShowingRowTotals(node.attribute(attributeName(Attribute::Report::ShowRowTotals)).toUInt()); | ||||
760 | else | ||||
761 | report.setShowingRowTotals(true); | ||||
762 | } | ||||
763 | | ||||
764 | QDomNode child = node.firstChild(); | ||||
765 | while (!child.isNull() && child.isElement()) { | ||||
766 | QDomElement c = child.toElement(); | ||||
767 | if (elementName(Element::Report::Text) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::Pattern))) { | ||||
768 | report.setTextFilter(QRegExp(c.attribute(attributeName(Attribute::Report::Pattern)), | ||||
769 | c.attribute(attributeName(Attribute::Report::CaseSensitive), "1").toUInt() | ||||
770 | ? Qt::CaseSensitive : Qt::CaseInsensitive, | ||||
771 | c.attribute(attributeName(Attribute::Report::RegEx), "1").toUInt() | ||||
772 | ? QRegExp::Wildcard : QRegExp::RegExp), | ||||
773 | c.attribute(attributeName(Attribute::Report::InvertText), "0").toUInt()); | ||||
774 | } | ||||
775 | if (elementName(Element::Report::Type) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::Type))) { | ||||
776 | i = stringToTypeAttribute(c.attribute(attributeName(Attribute::Report::Type))); | ||||
777 | if (i != -1) | ||||
778 | report.addType(i); | ||||
779 | } | ||||
780 | if (elementName(Element::Report::State) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::State))) { | ||||
781 | i = stringToStateAttribute(c.attribute(attributeName(Attribute::Report::State))); | ||||
782 | if (i != -1) | ||||
783 | report.addState(i); | ||||
784 | } | ||||
785 | if (elementName(Element::Report::Number) == c.tagName()) | ||||
786 | report.setNumberFilter(c.attribute(attributeName(Attribute::Report::From)), c.attribute(attributeName(Attribute::Report::To))); | ||||
787 | if (elementName(Element::Report::Amount) == c.tagName()) | ||||
788 | report.setAmountFilter(MyMoneyMoney(c.attribute(attributeName(Attribute::Report::From), "0/100")), MyMoneyMoney(c.attribute(attributeName(Attribute::Report::To), "0/100"))); | ||||
789 | if (elementName(Element::Report::Dates) == c.tagName()) { | ||||
790 | QDate from, to; | ||||
791 | if (c.hasAttribute(attributeName(Attribute::Report::From))) | ||||
792 | from = QDate::fromString(c.attribute(attributeName(Attribute::Report::From)), Qt::ISODate); | ||||
793 | if (c.hasAttribute(attributeName(Attribute::Report::To))) | ||||
794 | to = QDate::fromString(c.attribute(attributeName(Attribute::Report::To)), Qt::ISODate); | ||||
795 | report.setDateFilter(from, to); | ||||
796 | } | ||||
797 | if (elementName(Element::Report::Payee) == c.tagName()) | ||||
798 | report.addPayee(c.attribute(attributeName(Attribute::Report::ID))); | ||||
799 | if (elementName(Element::Report::Tag) == c.tagName()) | ||||
800 | report.addTag(c.attribute(attributeName(Attribute::Report::ID))); | ||||
801 | if (elementName(Element::Report::Category) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::ID))) | ||||
802 | report.addCategory(c.attribute(attributeName(Attribute::Report::ID))); | ||||
803 | if (elementName(Element::Report::Account) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::ID))) | ||||
804 | report.addAccount(c.attribute(attributeName(Attribute::Report::ID))); | ||||
805 | if (elementName(Element::Report::AccountGroup) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::Group))) { | ||||
806 | i = stringToAccountTypeAttribute(c.attribute(attributeName(Attribute::Report::Group))); | ||||
807 | if (i != -1) | ||||
808 | report.addAccountGroup(static_cast<eMyMoney::Account::Type>(i)); | ||||
809 | } | ||||
810 | child = child.nextSibling(); | ||||
811 | } | ||||
812 | | ||||
813 | return report; | ||||
814 | } | ||||
815 | | ||||
816 | void writeReport(const MyMoneyReport &report, QDomDocument &document, QDomElement &parent) | ||||
817 | { | ||||
818 | auto el = document.createElement(nodeName(Node::Report)); | ||||
819 | | ||||
820 | // No matter what changes, be sure to have a 'type' attribute. Only change | ||||
821 | // the major type if it becomes impossible to maintain compatibility with | ||||
822 | // older versions of the program as new features are added to the reports. | ||||
823 | // Feel free to change the minor type every time a change is made here. | ||||
824 | | ||||
825 | // write report's internals | ||||
826 | if (report.reportType() == eMyMoney::Report::ReportType::PivotTable) | ||||
827 | el.setAttribute(attributeName(Attribute::Report::Type), "pivottable 1.15"); | ||||
828 | else if (report.reportType() == eMyMoney::Report::ReportType::QueryTable) | ||||
829 | el.setAttribute(attributeName(Attribute::Report::Type), "querytable 1.14"); | ||||
830 | else if (report.reportType() == eMyMoney::Report::ReportType::InfoTable) | ||||
831 | el.setAttribute(attributeName(Attribute::Report::Type), "infotable 1.0"); | ||||
832 | | ||||
833 | el.setAttribute(attributeName(Attribute::Report::Group), report.group()); | ||||
834 | el.setAttribute(attributeName(Attribute::Report::ID), report.id()); | ||||
835 | | ||||
836 | // write general tab | ||||
837 | auto anonymous = false; | ||||
838 | if (anonymous) { | ||||
839 | el.setAttribute(attributeName(Attribute::Report::Name), report.id()); | ||||
840 | el.setAttribute(attributeName(Attribute::Report::Comment), QString(report.comment()).fill('x')); | ||||
841 | } else { | ||||
842 | el.setAttribute(attributeName(Attribute::Report::Name), report.name()); | ||||
843 | el.setAttribute(attributeName(Attribute::Report::Comment), report.comment()); | ||||
844 | } | ||||
845 | el.setAttribute(attributeName(Attribute::Report::ConvertCurrency), report.isConvertCurrency()); | ||||
846 | el.setAttribute(attributeName(Attribute::Report::Favorite), report.isFavorite()); | ||||
847 | el.setAttribute(attributeName(Attribute::Report::SkipZero), report.isSkippingZero()); | ||||
848 | | ||||
849 | el.setAttribute(attributeName(Attribute::Report::DateLock), dateLockAttributeToString(static_cast<int>(report.dateRange()))); | ||||
850 | | ||||
851 | if (report.reportType() == eMyMoney::Report::ReportType::PivotTable) { | ||||
852 | // write report's internals | ||||
853 | el.setAttribute(attributeName(Attribute::Report::IncludesActuals), report.isIncludingBudgetActuals()); | ||||
854 | el.setAttribute(attributeName(Attribute::Report::IncludesForecast), report.isIncludingForecast()); | ||||
855 | el.setAttribute(attributeName(Attribute::Report::IncludesPrice), report.isIncludingPrice()); | ||||
856 | el.setAttribute(attributeName(Attribute::Report::IncludesAveragePrice), report.isIncludingAveragePrice()); | ||||
857 | el.setAttribute(attributeName(Attribute::Report::MixedTime), report.isMixedTime()); | ||||
858 | el.setAttribute(attributeName(Attribute::Report::Investments), report.isInvestmentsOnly()); // it's setable in rows/columns tab of querytable, but here it is internal setting | ||||
859 | | ||||
860 | // write rows/columns tab | ||||
861 | if (!report.budget().isEmpty()) | ||||
862 | el.setAttribute(attributeName(Attribute::Report::Budget), report.budget()); | ||||
863 | | ||||
864 | el.setAttribute(attributeName(Attribute::Report::RowType), reportNames(report.rowType())); | ||||
865 | el.setAttribute(attributeName(Attribute::Report::ShowRowTotals), report.isShowingRowTotals()); | ||||
866 | el.setAttribute(attributeName(Attribute::Report::ShowColumnTotals), report.isShowingColumnTotals()); | ||||
867 | el.setAttribute(attributeName(Attribute::Report::Detail), reportNames(report.detailLevel())); | ||||
868 | | ||||
869 | el.setAttribute(attributeName(Attribute::Report::IncludesMovingAverage), report.isIncludingMovingAverage()); | ||||
870 | if (report.isIncludingMovingAverage()) | ||||
871 | el.setAttribute(attributeName(Attribute::Report::MovingAverageDays), report.movingAverageDays()); | ||||
872 | | ||||
873 | el.setAttribute(attributeName(Attribute::Report::IncludesSchedules), report.isIncludingSchedules()); | ||||
874 | el.setAttribute(attributeName(Attribute::Report::IncludesTransfers), report.isIncludingTransfers()); | ||||
875 | el.setAttribute(attributeName(Attribute::Report::IncludesUnused), report.isIncludingUnusedAccounts()); | ||||
876 | el.setAttribute(attributeName(Attribute::Report::ColumnsAreDays), report.isColumnsAreDays()); | ||||
877 | el.setAttribute(attributeName(Attribute::Report::ChartType), reportNames(report.chartType())); | ||||
878 | el.setAttribute(attributeName(Attribute::Report::ChartCHGridLines), report.isChartCHGridLines()); | ||||
879 | el.setAttribute(attributeName(Attribute::Report::ChartSVGridLines), report.isChartSVGridLines()); | ||||
880 | el.setAttribute(attributeName(Attribute::Report::ChartDataLabels), report.isChartDataLabels()); | ||||
881 | el.setAttribute(attributeName(Attribute::Report::ChartByDefault), report.isChartByDefault()); | ||||
882 | el.setAttribute(attributeName(Attribute::Report::LogYAxis), report.isLogYAxis()); | ||||
883 | el.setAttribute(attributeName(Attribute::Report::ChartLineWidth), report.chartLineWidth()); | ||||
884 | el.setAttribute(attributeName(Attribute::Report::ColumnType), reportNames(report.columnType())); | ||||
885 | el.setAttribute(attributeName(Attribute::Report::DataLock), reportNames(report.dataFilter())); | ||||
886 | el.setAttribute(attributeName(Attribute::Report::DataRangeStart), report.dataRangeStart()); | ||||
887 | el.setAttribute(attributeName(Attribute::Report::DataRangeEnd), report.dataRangeEnd()); | ||||
888 | el.setAttribute(attributeName(Attribute::Report::DataMajorTick), report.dataMajorTick()); | ||||
889 | el.setAttribute(attributeName(Attribute::Report::DataMinorTick), report.dataMinorTick()); | ||||
890 | el.setAttribute(attributeName(Attribute::Report::YLabelsPrecision), report.yLabelsPrecision()); | ||||
891 | } else if (report.reportType() == eMyMoney::Report::ReportType::QueryTable) { | ||||
892 | // write rows/columns tab | ||||
893 | el.setAttribute(attributeName(Attribute::Report::RowType), reportNames(report.rowType())); | ||||
894 | QStringList columns; | ||||
895 | unsigned qc = report.queryColumns(); | ||||
896 | unsigned it_qc = eMyMoney::Report::QueryColumn::Begin; | ||||
897 | unsigned index = 1; | ||||
898 | while (it_qc != eMyMoney::Report::QueryColumn::End) { | ||||
899 | if (qc & it_qc) | ||||
900 | columns += reportNamesForQC(static_cast<eMyMoney::Report::QueryColumn>(it_qc)); | ||||
901 | it_qc *= 2; | ||||
902 | index++; | ||||
903 | } | ||||
904 | el.setAttribute(attributeName(Attribute::Report::QueryColumns), columns.join(",")); | ||||
905 | | ||||
906 | el.setAttribute(attributeName(Attribute::Report::Tax), report.isTax()); | ||||
907 | el.setAttribute(attributeName(Attribute::Report::Investments), report.isInvestmentsOnly()); | ||||
908 | el.setAttribute(attributeName(Attribute::Report::Loans), report.isLoansOnly()); | ||||
909 | el.setAttribute(attributeName(Attribute::Report::HideTransactions), report.isHideTransactions()); | ||||
910 | el.setAttribute(attributeName(Attribute::Report::ShowColumnTotals), report.isShowingColumnTotals()); | ||||
911 | el.setAttribute(attributeName(Attribute::Report::Detail), reportNames(report.detailLevel())); | ||||
912 | | ||||
913 | // write performance tab | ||||
914 | if (report.queryColumns() & eMyMoney::Report::QueryColumn::Performance || report.queryColumns() & eMyMoney::Report::QueryColumn::CapitalGain) | ||||
915 | el.setAttribute(attributeName(Attribute::Report::InvestmentSum), static_cast<int>(report.investmentSum())); | ||||
916 | | ||||
917 | // write capital gains tab | ||||
918 | if (report.queryColumns() & eMyMoney::Report::QueryColumn::CapitalGain) { | ||||
919 | if (report.investmentSum() == eMyMoney::Report::InvestmentSum::Sold) { | ||||
920 | el.setAttribute(attributeName(Attribute::Report::SettlementPeriod), report.settlementPeriod()); | ||||
921 | el.setAttribute(attributeName(Attribute::Report::ShowSTLTCapitalGains), report.isShowingSTLTCapitalGains()); | ||||
922 | el.setAttribute(attributeName(Attribute::Report::TermsSeparator), report.termSeparator().toString(Qt::ISODate)); | ||||
923 | } | ||||
924 | } | ||||
925 | } else if (report.reportType() == eMyMoney::Report::ReportType::InfoTable) | ||||
926 | el.setAttribute(attributeName(Attribute::Report::ShowRowTotals), report.isShowingRowTotals()); | ||||
927 | | ||||
928 | // | ||||
929 | // Text Filter | ||||
930 | // | ||||
931 | | ||||
932 | QRegExp textfilter; | ||||
933 | if (report.textFilter(textfilter)) { | ||||
934 | QDomElement f = document.createElement(elementName(Element::Report::Text)); | ||||
935 | f.setAttribute(attributeName(Attribute::Report::Pattern), textfilter.pattern()); | ||||
936 | f.setAttribute(attributeName(Attribute::Report::CaseSensitive), (textfilter.caseSensitivity() == Qt::CaseSensitive) ? 1 : 0); | ||||
937 | f.setAttribute(attributeName(Attribute::Report::RegEx), (textfilter.patternSyntax() == QRegExp::Wildcard) ? 1 : 0); | ||||
938 | f.setAttribute(attributeName(Attribute::Report::InvertText), report.MyMoneyTransactionFilter::isInvertingText()); | ||||
939 | el.appendChild(f); | ||||
940 | } | ||||
941 | | ||||
942 | // | ||||
943 | // Type & State Filters | ||||
944 | // | ||||
945 | QList<int> typelist; | ||||
946 | if (report.types(typelist) && ! typelist.empty()) { | ||||
947 | // iterate over payees, and add each one | ||||
948 | QList<int>::const_iterator it_type = typelist.constBegin(); | ||||
949 | while (it_type != typelist.constEnd()) { | ||||
950 | QDomElement p = document.createElement(elementName(Element::Report::Type)); | ||||
951 | p.setAttribute(attributeName(Attribute::Report::Type), typeAttributeToString(*it_type)); | ||||
952 | el.appendChild(p); | ||||
953 | | ||||
954 | ++it_type; | ||||
955 | } | ||||
956 | } | ||||
957 | | ||||
958 | QList<int> statelist; | ||||
959 | if (report.states(statelist) && ! statelist.empty()) { | ||||
960 | // iterate over payees, and add each one | ||||
961 | QList<int>::const_iterator it_state = statelist.constBegin(); | ||||
962 | while (it_state != statelist.constEnd()) { | ||||
963 | QDomElement p = document.createElement(elementName(Element::Report::State)); | ||||
964 | p.setAttribute(attributeName(Attribute::Report::State), stateAttributeToString(*it_state)); | ||||
965 | el.appendChild(p); | ||||
966 | | ||||
967 | ++it_state; | ||||
968 | } | ||||
969 | } | ||||
970 | // | ||||
971 | // Number Filter | ||||
972 | // | ||||
973 | | ||||
974 | QString nrFrom, nrTo; | ||||
975 | if (report.numberFilter(nrFrom, nrTo)) { | ||||
976 | QDomElement f = document.createElement(elementName(Element::Report::Number)); | ||||
977 | f.setAttribute(attributeName(Attribute::Report::From), nrFrom); | ||||
978 | f.setAttribute(attributeName(Attribute::Report::To), nrTo); | ||||
979 | el.appendChild(f); | ||||
980 | } | ||||
981 | | ||||
982 | // | ||||
983 | // Amount Filter | ||||
984 | // | ||||
985 | | ||||
986 | MyMoneyMoney from, to; | ||||
987 | if (report.amountFilter(from, to)) { // bool getAmountFilter(MyMoneyMoney&,MyMoneyMoney&); | ||||
988 | QDomElement f = document.createElement(elementName(Element::Report::Amount)); | ||||
989 | f.setAttribute(attributeName(Attribute::Report::From), from.toString()); | ||||
990 | f.setAttribute(attributeName(Attribute::Report::To), to.toString()); | ||||
991 | el.appendChild(f); | ||||
992 | } | ||||
993 | | ||||
994 | // | ||||
995 | // Payees Filter | ||||
996 | // | ||||
997 | | ||||
998 | QStringList payeelist; | ||||
999 | if (report.payees(payeelist)) { | ||||
1000 | if (payeelist.empty()) { | ||||
1001 | QDomElement p = document.createElement(elementName(Element::Report::Payee)); | ||||
1002 | el.appendChild(p); | ||||
1003 | } else { | ||||
1004 | // iterate over payees, and add each one | ||||
1005 | QStringList::const_iterator it_payee = payeelist.constBegin(); | ||||
1006 | while (it_payee != payeelist.constEnd()) { | ||||
1007 | QDomElement p = document.createElement(elementName(Element::Report::Payee)); | ||||
1008 | p.setAttribute(attributeName(Attribute::Report::ID), *it_payee); | ||||
1009 | el.appendChild(p); | ||||
1010 | | ||||
1011 | ++it_payee; | ||||
1012 | } | ||||
1013 | } | ||||
1014 | } | ||||
1015 | | ||||
1016 | // | ||||
1017 | // Tags Filter | ||||
1018 | // | ||||
1019 | | ||||
1020 | QStringList taglist; | ||||
1021 | if (report.tags(taglist)) { | ||||
1022 | if (taglist.empty()) { | ||||
1023 | QDomElement p = document.createElement(elementName(Element::Report::Tag)); | ||||
1024 | el.appendChild(p); | ||||
1025 | } else { | ||||
1026 | // iterate over tags, and add each one | ||||
1027 | QStringList::const_iterator it_tag = taglist.constBegin(); | ||||
1028 | while (it_tag != taglist.constEnd()) { | ||||
1029 | QDomElement p = document.createElement(elementName(Element::Report::Tag)); | ||||
1030 | p.setAttribute(attributeName(Attribute::Report::ID), *it_tag); | ||||
1031 | el.appendChild(p); | ||||
1032 | | ||||
1033 | ++it_tag; | ||||
1034 | } | ||||
1035 | } | ||||
1036 | } | ||||
1037 | | ||||
1038 | // | ||||
1039 | // Account Groups Filter | ||||
1040 | // | ||||
1041 | | ||||
1042 | QList<eMyMoney::Account::Type> accountgrouplist; | ||||
1043 | if (report.accountGroups(accountgrouplist)) { | ||||
1044 | // iterate over accounts, and add each one | ||||
1045 | QList<eMyMoney::Account::Type>::const_iterator it_group = accountgrouplist.constBegin(); | ||||
1046 | while (it_group != accountgrouplist.constEnd()) { | ||||
1047 | QDomElement p = document.createElement(elementName(Element::Report::AccountGroup)); | ||||
1048 | p.setAttribute(attributeName(Attribute::Report::Group), accountTypeAttributeToString(static_cast<int>(*it_group))); | ||||
1049 | el.appendChild(p); | ||||
1050 | | ||||
1051 | ++it_group; | ||||
1052 | } | ||||
1053 | } | ||||
1054 | | ||||
1055 | // | ||||
1056 | // Accounts Filter | ||||
1057 | // | ||||
1058 | | ||||
1059 | QStringList accountlist; | ||||
1060 | if (report.accounts(accountlist)) { | ||||
1061 | // iterate over accounts, and add each one | ||||
1062 | QStringList::const_iterator it_account = accountlist.constBegin(); | ||||
1063 | while (it_account != accountlist.constEnd()) { | ||||
1064 | QDomElement p = document.createElement(elementName(Element::Report::Account)); | ||||
1065 | p.setAttribute(attributeName(Attribute::Report::ID), *it_account); | ||||
1066 | el.appendChild(p); | ||||
1067 | | ||||
1068 | ++it_account; | ||||
1069 | } | ||||
1070 | } | ||||
1071 | | ||||
1072 | // | ||||
1073 | // Categories Filter | ||||
1074 | // | ||||
1075 | | ||||
1076 | accountlist.clear(); | ||||
1077 | if (report.categories(accountlist)) { | ||||
1078 | // iterate over accounts, and add each one | ||||
1079 | QStringList::const_iterator it_account = accountlist.constBegin(); | ||||
1080 | while (it_account != accountlist.constEnd()) { | ||||
1081 | QDomElement p = document.createElement(elementName(Element::Report::Category)); | ||||
1082 | p.setAttribute(attributeName(Attribute::Report::ID), *it_account); | ||||
1083 | el.appendChild(p); | ||||
1084 | | ||||
1085 | ++it_account; | ||||
1086 | } | ||||
1087 | } | ||||
1088 | | ||||
1089 | // | ||||
1090 | // Date Filter | ||||
1091 | // | ||||
1092 | | ||||
1093 | if (report.dateRange() == eMyMoney::TransactionFilter::Date::UserDefined) { | ||||
1094 | QDate dateFrom, dateTo; | ||||
1095 | if (report.dateFilter(dateFrom, dateTo)) { | ||||
1096 | QDomElement f = document.createElement(elementName(Element::Report::Dates)); | ||||
1097 | if (dateFrom.isValid()) | ||||
1098 | f.setAttribute(attributeName(Attribute::Report::From), dateFrom.toString(Qt::ISODate)); | ||||
1099 | if (dateTo.isValid()) | ||||
1100 | f.setAttribute(attributeName(Attribute::Report::To), dateTo.toString(Qt::ISODate)); | ||||
1101 | el.appendChild(f); | ||||
1102 | } | ||||
1103 | } | ||||
1104 | | ||||
1105 | | ||||
1106 | parent.appendChild(el); | ||||
1107 | } | ||||
1108 | | ||||
1109 | MyMoneyBudget readBudget(const QDomElement &node) | ||||
1110 | { | ||||
1111 | if (nodeName(Node::Budget) != node.tagName()) | ||||
1112 | throw MYMONEYEXCEPTION_CSTRING("Node was not BUDGET"); | ||||
1113 | | ||||
1114 | MyMoneyBudget budget(node.attribute(QStringLiteral("id"))); | ||||
1115 | // The goal of this reading method is 100% backward AND 100% forward | ||||
1116 | // compatibility. Any Budget ever created with any version of KMyMoney | ||||
1117 | // should be able to be loaded by this method (as long as it's one of the | ||||
1118 | // Budget types supported in this version, of course) | ||||
1119 | | ||||
1120 | budget.setName(node.attribute(attributeName(Attribute::Budget::Name))); | ||||
1121 | budget.setBudgetStart(QDate::fromString(node.attribute(attributeName(Attribute::Budget::Start)), Qt::ISODate)); | ||||
1122 | | ||||
1123 | QDomNode child = node.firstChild(); | ||||
1124 | while (!child.isNull() && child.isElement()) { | ||||
1125 | QDomElement c = child.toElement(); | ||||
1126 | | ||||
1127 | MyMoneyBudget::AccountGroup account; | ||||
1128 | | ||||
1129 | if (elementName(Element::Budget::Account) == c.tagName()) { | ||||
1130 | if (c.hasAttribute(attributeName(Attribute::Budget::ID))) | ||||
1131 | account.setId(c.attribute(attributeName(Attribute::Budget::ID))); | ||||
1132 | | ||||
1133 | if (c.hasAttribute(attributeName(Attribute::Budget::BudgetLevel))) | ||||
1134 | account.setBudgetLevel(stringToBudgetLevel(c.attribute(attributeName(Attribute::Budget::BudgetLevel)))); | ||||
1135 | | ||||
1136 | if (c.hasAttribute(attributeName(Attribute::Budget::BudgetSubAccounts))) | ||||
1137 | account.setBudgetSubaccounts(c.attribute(attributeName(Attribute::Budget::BudgetSubAccounts)).toUInt()); | ||||
1138 | } | ||||
1139 | | ||||
1140 | QDomNode period = c.firstChild(); | ||||
1141 | while (!period.isNull() && period.isElement()) { | ||||
1142 | QDomElement per = period.toElement(); | ||||
1143 | MyMoneyBudget::PeriodGroup pGroup; | ||||
1144 | | ||||
1145 | if (elementName(Element::Budget::Period) == per.tagName() && per.hasAttribute(attributeName(Attribute::Budget::Amount)) && per.hasAttribute(attributeName(Attribute::Budget::Start))) { | ||||
1146 | pGroup.setAmount(MyMoneyMoney(per.attribute(attributeName(Attribute::Budget::Amount)))); | ||||
1147 | pGroup.setStartDate(QDate::fromString(per.attribute(attributeName(Attribute::Budget::Start)), Qt::ISODate)); | ||||
1148 | account.addPeriod(pGroup.startDate(), pGroup); | ||||
1149 | } | ||||
1150 | | ||||
1151 | period = period.nextSibling(); | ||||
1152 | } | ||||
1153 | budget.setAccount(account, account.id()); | ||||
1154 | | ||||
1155 | child = child.nextSibling(); | ||||
1156 | } | ||||
1157 | | ||||
1158 | | ||||
1159 | return budget; | ||||
1160 | } | ||||
1161 | | ||||
1162 | const int BUDGET_VERSION = 2; | ||||
1163 | | ||||
1164 | void writeBudget(const MyMoneyBudget &budget, QDomDocument &document, QDomElement &parent) | ||||
1165 | { | ||||
1166 | auto el = document.createElement(nodeName(Node::Budget)); | ||||
1167 | | ||||
1168 | writeBaseXML(budget.id(), document, el); | ||||
1169 | | ||||
1170 | el.setAttribute(attributeName(Attribute::Budget::Name), budget.name()); | ||||
1171 | el.setAttribute(attributeName(Attribute::Budget::Start), budget.budgetStart().toString(Qt::ISODate)); | ||||
1172 | el.setAttribute(attributeName(Attribute::Budget::Version), BUDGET_VERSION); | ||||
1173 | | ||||
1174 | QMap<QString, MyMoneyBudget::AccountGroup>::const_iterator it; | ||||
1175 | auto accounts = budget.accountsMap(); | ||||
1176 | for (it = accounts.cbegin(); it != accounts.cend(); ++it) { | ||||
1177 | // only add the account if there is a budget entered | ||||
1178 | // or it covers some sub accounts | ||||
1179 | if (!(*it).balance().isZero() || (*it).budgetSubaccounts()) { | ||||
1180 | QDomElement domAccount = document.createElement(elementName(Element::Budget::Account)); | ||||
1181 | domAccount.setAttribute(attributeName(Attribute::Budget::ID), it.key()); | ||||
1182 | domAccount.setAttribute(attributeName(Attribute::Budget::BudgetLevel), budgetLevels(it.value().budgetLevel())); | ||||
1183 | domAccount.setAttribute(attributeName(Attribute::Budget::BudgetSubAccounts), it.value().budgetSubaccounts()); | ||||
1184 | | ||||
1185 | const QMap<QDate, MyMoneyBudget::PeriodGroup> periods = it.value().getPeriods(); | ||||
1186 | QMap<QDate, MyMoneyBudget::PeriodGroup>::const_iterator it_per; | ||||
1187 | for (it_per = periods.begin(); it_per != periods.end(); ++it_per) { | ||||
1188 | if (!(*it_per).amount().isZero()) { | ||||
1189 | QDomElement domPeriod = document.createElement(elementName(Element::Budget::Period)); | ||||
1190 | | ||||
1191 | domPeriod.setAttribute(attributeName(Attribute::Budget::Amount), (*it_per).amount().toString()); | ||||
1192 | domPeriod.setAttribute(attributeName(Attribute::Budget::Start), (*it_per).startDate().toString(Qt::ISODate)); | ||||
1193 | domAccount.appendChild(domPeriod); | ||||
1194 | } | ||||
1195 | } | ||||
1196 | | ||||
1197 | el.appendChild(domAccount); | ||||
1198 | } | ||||
1199 | } | ||||
1200 | | ||||
1201 | parent.appendChild(el); | ||||
1202 | } | ||||
1203 | } | ||||
1204 | |