Mercurial > hgweb.cgi > drn
changeset 903:a5377eca373b
IN 32: Adds the distribution to the ReconciledSurvey of the budget file.
Adds a toWeak mapping for the BudgetItemTypes (useful when translation is not desired).
author | John Schneiderman <JohnMS@member.fsf.org> |
---|---|
date | Thu, 06 Oct 2022 20:08:49 +0200 |
parents | 56c171f78d39 |
children | ab20e0cc063d |
files | src/budgeting/external/budgeting/BudgetItemTypes.cpp src/budgeting/external/budgeting/BudgetItemTypes.h src/file-storage/internal/BudgetElements.cpp src/file-storage/internal/BudgetElements.h src/file-storage/internal/XmlBudgetFile.cpp src/file-storage/unit-tests/BudgetFileContents.cpp src/file-storage/unit-tests/XmlBudgetFile-unit-tests.cpp src/navigation/internal/BudgetBankLedgers.h |
diffstat | 8 files changed, 377 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/src/budgeting/external/budgeting/BudgetItemTypes.cpp Thu Oct 06 17:05:23 2022 +0200 +++ b/src/budgeting/external/budgeting/BudgetItemTypes.cpp Thu Oct 06 20:08:49 2022 +0200 @@ -53,6 +53,18 @@ return o << "Value ("<< presentationText(bit).toStdString() << ')'; } +QString drn::budgeting::toWeak(const BudgetItemTypes& bit) +{ + BEGIN_ENUMERATION_TO_OTHER(bit); + MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Unknown, "Unknown"); + MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Bill, "Bill"); + MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Debt, "Debt"); + MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Goal, "Goal"); + MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Nontrack, "Nontrack"); + MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Wage, "Wage"); + END_ENUMERATION_TO_OTHER(bit, BudgetItemTypes); +} + QString drn::budgeting::presentationText(const BudgetItemTypes& bit) { BEGIN_ENUMERATION_TO_OTHER(bit);
--- a/src/budgeting/external/budgeting/BudgetItemTypes.h Thu Oct 06 17:05:23 2022 +0200 +++ b/src/budgeting/external/budgeting/BudgetItemTypes.h Thu Oct 06 20:08:49 2022 +0200 @@ -47,6 +47,7 @@ }; DRN_BUDGETING_EXPORT std::ostream& operator<<(std::ostream& o, const BudgetItemTypes& bit); +DRN_BUDGETING_EXPORT ::QString toWeak(const BudgetItemTypes& bit); DRN_BUDGETING_EXPORT ::QString presentationText(const BudgetItemTypes& bit); DRN_BUDGETING_EXPORT BudgetItemTypes toBudgetItemTypes(const ::QString& raw); DRN_BUDGETING_EXPORT BudgetItemTypes toBudgetItemTypes(const std::type_index& type);
--- a/src/file-storage/internal/BudgetElements.cpp Thu Oct 06 17:05:23 2022 +0200 +++ b/src/file-storage/internal/BudgetElements.cpp Thu Oct 06 20:08:49 2022 +0200 @@ -35,10 +35,11 @@ using drn::file_storage::internal::BanksElement; using drn::file_storage::internal::BillElement; using drn::file_storage::internal::BillsElement; +using drn::file_storage::internal::DebtElement; +using drn::file_storage::internal::DebtsElement; using drn::file_storage::internal::DiscretionariesElement; using drn::file_storage::internal::DiscretionaryElement; -using drn::file_storage::internal::DebtElement; -using drn::file_storage::internal::DebtsElement; +using drn::file_storage::internal::DistributionElement; using drn::file_storage::internal::GoalElement; using drn::file_storage::internal::GoalsElement; using drn::file_storage::internal::IndexedElement; @@ -1633,6 +1634,116 @@ //} +//{ DistributionElement + +const QLatin1String DistributionElement::typeAttribute_{"type"}; +const QLatin1String DistributionElement::budgetItemIdAttribute_{"id"}; +const QLatin1String DistributionElement::majorAttribute_{"major"}; +const QLatin1String DistributionElement::minorAttribute_{"minor"}; +const QLatin1String DistributionElement::currencyAttribute_{"currency"}; + +DistributionElement::DistributionElement() : + BasicElement{}, + type_{}, + budgetItemId_{}, + major_{}, + minor_{}, + currency_{} +{} + +DistributionElement::DistributionElement( + QString type, + const IndexedElement::IdType& budgetItemId, + MajorType major, + MinorType minor, + QString currency +) : + BasicElement{}, + type_{move(type)}, + budgetItemId_{budgetItemId}, + major_{move(major)}, + minor_{move(minor)}, + currency_{move(currency)} +{} + +const QLatin1String& DistributionElement::tag() const +{ + static const QLatin1String tag{"distribution"}; + return tag; +} + +void DistributionElement::read(QXmlStreamReader& xml) +{ + qDebug() << "Reading Element:" << this->tag(); + + if ( ! xml.isStartElement()) + throw BudgetFileError{ + xml.errorString(), + xml.lineNumber(), + xml.columnNumber(), + QObject::tr( + "The XML element, %1, is not the starting element of %2." + ).arg(xml.name()).arg(this->tag()) + }; + + if (xml.name() != this->tag()) + throw BudgetFileError{ + xml.errorString(), + xml.lineNumber(), + xml.columnNumber(), + QObject::tr( + "The XML element tag, %1, is not valid under the current element %2." + ).arg(xml.name()).arg(this->tag()) + }; + + if (xml.attributes().hasAttribute(DistributionElement::typeAttribute_)) + this->type_ = readAttributeString(xml, DistributionElement::typeAttribute_); + const auto budgetItemId{ + readAttributeUnsigned<quint32>(xml, DistributionElement::budgetItemIdAttribute_) + }; + + if (budgetItemId == IndexedElement::invalidId_) + throw BudgetFileError{ + xml.errorString(), + xml.lineNumber(), + xml.columnNumber(), + QObject::tr("The budget item ID for a distribution element cannot be invalid.") + }; + this->budgetItemId_ = budgetItemId; + + if (xml.attributes().hasAttribute(DistributionElement::majorAttribute_)) + this->major_ = readAttributeSigned<DistributionElement::MajorType>( + xml, + DistributionElement::majorAttribute_ + ); + + if (xml.attributes().hasAttribute(DistributionElement::minorAttribute_)) + this->minor_ = readAttributeUnsigned<DistributionElement::MinorType>( + xml, + DistributionElement::minorAttribute_ + ); + + if (xml.attributes().hasAttribute(DistributionElement::currencyAttribute_)) + this->currency_ = readAttributeString(xml, DistributionElement::currencyAttribute_); + xml.skipCurrentElement(); // Finished reading element. +} + +void DistributionElement::write(QXmlStreamWriter& xml) const +{ + xml.writeStartElement(this->tag()); + xml.writeAttribute(DistributionElement::typeAttribute_, this->type_); + xml.writeAttribute( + DistributionElement::budgetItemIdAttribute_, + QString::number(this->budgetItemId_) + ); + xml.writeAttribute(DistributionElement::majorAttribute_, QString::number(this->major_)); + xml.writeAttribute(DistributionElement::minorAttribute_, QString::number(this->minor_)); + xml.writeAttribute(DistributionElement::currencyAttribute_, this->currency_); + xml.writeEndElement(); +} + +//} + //{ ReconciliationElement const QLatin1String ReconciliationElement::accountIdAttribute_{"account"}; @@ -1652,7 +1763,7 @@ {} ReconciliationElement::ReconciliationElement(const IndexedElement::IdType& accountId) : - ReconciliationElement{accountId, {}, {}, {}, {}, {}} + ReconciliationElement{accountId, {}, {}, {}, {}, {}, {}} {} ReconciliationElement::ReconciliationElement( @@ -1661,7 +1772,8 @@ MinorType minor, QString currency, Optional<QDate> date, - Optional<QString> checksum + Optional<QString> checksum, + vector<DistributionElement> distributions ) : BasicElement{}, accountId_{accountId}, @@ -1669,7 +1781,8 @@ minor_{move(minor)}, currency_{move(currency)}, date_{move(date)}, - checksum_{move(checksum)} + checksum_{move(checksum)}, + distributions_{move(distributions)} { if (this->accountId_ == IndexedElement::invalidId_) throw BudgetFileError{ @@ -1742,7 +1855,19 @@ if (xml.attributes().hasAttribute(ReconciliationElement::checksumAttribute_)) this->checksum_ = readAttributeString(xml, ReconciliationElement::checksumAttribute_); - xml.skipCurrentElement(); // Finished reading element. + + while (xml.readNextStartElement()) + { + DistributionElement distribution{}; + + if (xml.name() == distribution.tag()) + { + distribution.read(xml); + this->distributions_.emplace_back(move(distribution)); + } + else + break; + }; } void ReconciliationElement::write(QXmlStreamWriter& xml) const @@ -1766,6 +1891,9 @@ if (this->checksum_.hasValue()) xml.writeAttribute(ReconciliationElement::checksumAttribute_, *this->checksum_); + + for (const auto& distribution : this->distributions_) + distribution.write(xml); xml.writeEndElement(); }
--- a/src/file-storage/internal/BudgetElements.h Thu Oct 06 17:05:23 2022 +0200 +++ b/src/file-storage/internal/BudgetElements.h Thu Oct 06 20:08:49 2022 +0200 @@ -465,6 +465,35 @@ std::vector<BankElement> banks_; }; +struct DistributionElement : BasicElement +{ + using MajorType = pecunia::UnitStorage; + using MinorType = pecunia::MinorUnit; + + DistributionElement(); + DistributionElement( + ::QString type, + const IndexedElement::IdType& budgetItemId, + MajorType major, + MinorType minor, + ::QString currency + ); + const ::QLatin1String& tag() const override; + void read(::QXmlStreamReader& xml) override; + void write(::QXmlStreamWriter& xml) const override; + + static const ::QLatin1String typeAttribute_; + ::QString type_; + static const ::QLatin1String budgetItemIdAttribute_; + IndexedElement::IdType budgetItemId_; + static const ::QLatin1String majorAttribute_; + MajorType major_; + static const ::QLatin1String minorAttribute_; + MinorType minor_; + static const ::QLatin1String currencyAttribute_; + ::QString currency_; +}; + struct ReconciliationElement : BasicElement { using MajorType = pecunia::UnitStorage; @@ -478,7 +507,8 @@ MinorType minor, ::QString currency, foundation::Optional<::QDate> date, - foundation::Optional<::QString> checksum + foundation::Optional<::QString> checksum, + std::vector<DistributionElement> distributions ); const ::QLatin1String& tag() const override; void read(::QXmlStreamReader& xml) override; @@ -496,6 +526,7 @@ foundation::Optional<::QDate> date_; static const ::QLatin1String checksumAttribute_; foundation::Optional<::QString> checksum_; + std::vector<DistributionElement> distributions_; }; struct ReconciliationsElement : BasicElement
--- a/src/file-storage/internal/XmlBudgetFile.cpp Thu Oct 06 17:05:23 2022 +0200 +++ b/src/file-storage/internal/XmlBudgetFile.cpp Thu Oct 06 20:08:49 2022 +0200 @@ -107,6 +107,11 @@ using drn::file_storage::internal::WagesElement; #include <budgeting/Budget.h> using drn::budgeting::Budget; +#include <budgeting/BudgetItemTypes.h> +using drn::budgeting::BudgetItemIdentifier; +using drn::budgeting::BudgetItemTypes; +using drn::budgeting::toBudgetItemTypes; +using drn::budgeting::toWeak; #include <budgeting/BudgetSource.h> using drn::budgeting::BudgetSource; #include <budgeting/Nontrack.h> @@ -139,6 +144,82 @@ using drn::surveying::ReconciledSurveys; +namespace +{ + +class BudgetItemIdentifierIndexer +{ + std::map<BudgetItemTypes, map<IndexedElement::IdType, BudgetSource>> budgetIds_; + +public: + void addMapping( + const BudgetItemTypes& type, + const IndexedElement::IdType& id, + const BudgetSource& source + ) + { + this->budgetIds_[type][id] = source; + } + + const BudgetSource& lookUp(const BudgetItemTypes& type, const IndexedElement::IdType& id) + try + { + return this->budgetIds_.at(type).at(id); + } + catch (const exception& error) + { + throw BudgetFileError{ + {}, + {}, + {}, + QObject::tr( + "The budget file contains a malformed budget item ID mapping. There is not an " + "identifier of %1 of the type %2." + ) + .arg(id) + .arg(presentationText(type)), + error + }; + } + + const IndexedElement::IdType& lookUpId(const BudgetItemTypes& type, const BudgetSource& source) + try + { + const auto& types{this->budgetIds_.at(type)}; + const auto idSource{ + find_if( + types.cbegin(), + types.cend(), + [&source] (const auto& IdSourceFromType) + { + return IdSourceFromType.second == source; + } + ) + }; + + if (idSource == types.cend()) + throw Error{QObject::tr("Failed to find budget source.")}; + return idSource->first; + } + catch (const exception& error) + { + throw BudgetFileError{ + {}, + {}, + {}, + QObject::tr( + "The budget file contains a malformed budget item ID mapping. There is not a " + "budget source '%1' of the type %2." + ) + .arg(presentationText(source)) + .arg(presentationText(type)), + error + }; + } +}; + +} + tuple< GeneralLedger, Budget, @@ -253,14 +334,16 @@ xml.columnNumber(), QObject::tr("An unexpected error appeared in the file.") }; + BudgetItemIdentifierIndexer budgetIndexer{}; Budget b{}; for (const auto& wageElement : wagesElement.wages_) try { + const BudgetSource source{wageElement.sourceName_}; b.wages_.add( Wage{ - BudgetSource{wageElement.sourceName_}, + source, Money{ wageElement.major_, wageElement.minor_, @@ -270,6 +353,7 @@ wageElement.nextOccurOn_ } ); + budgetIndexer.addMapping(BudgetItemTypes::Wage, wageElement.id_, source); } catch (const exception& error) { @@ -282,21 +366,23 @@ }; } - for (const auto& billsElement : billsElements.bills_) + for (const auto& billElement : billsElements.bills_) try { + const BudgetSource source{billElement.sourceName_}; b.bills_.add( Bill{ - BudgetSource{billsElement.sourceName_}, + source, Money{ - billsElement.major_, - billsElement.minor_, - toIso4217Code(billsElement.currency_.toStdString()) + billElement.major_, + billElement.minor_, + toIso4217Code(billElement.currency_.toStdString()) }, - toEventFrequency(billsElement.period_), - billsElement.nextOccurOn_ + toEventFrequency(billElement.period_), + billElement.nextOccurOn_ } ); + budgetIndexer.addMapping(BudgetItemTypes::Bill, billElement.id_, source); } catch (const exception& error) { @@ -312,9 +398,10 @@ for (const auto& debtElement : debtsElements.debts_) try { + const BudgetSource source{debtElement.sourceName_}; b.debts_.add( Debt{ - BudgetSource{debtElement.sourceName_}, + source, Money{ debtElement.minimumMajor_, debtElement.minimumMinor_, @@ -330,6 +417,7 @@ Percentage{debtElement.interest_} } ); + budgetIndexer.addMapping(BudgetItemTypes::Debt, debtElement.id_, source); } catch (const exception& error) { @@ -342,26 +430,28 @@ }; } - for (const auto& goalsElement : goalsElements.goals_) + for (const auto& goalElement : goalsElements.goals_) try { + const BudgetSource source{goalElement.sourceName_}; b.goals_.add( Goal{ - BudgetSource{goalsElement.sourceName_}, + source, Money{ - goalsElement.major_, - goalsElement.minor_, - toIso4217Code(goalsElement.currency_.toStdString()) + goalElement.major_, + goalElement.minor_, + toIso4217Code(goalElement.currency_.toStdString()) }, - toEventFrequency(goalsElement.period_), - goalsElement.nextOccurOn_, + toEventFrequency(goalElement.period_), + goalElement.nextOccurOn_, Money{ - goalsElement.finalMajor_, - goalsElement.finalMinor_, - toIso4217Code(goalsElement.currency_.toStdString()) + goalElement.finalMajor_, + goalElement.finalMinor_, + toIso4217Code(goalElement.currency_.toStdString()) } } ); + budgetIndexer.addMapping(BudgetItemTypes::Goal, goalElement.id_, source); } catch (const exception& error) { @@ -374,21 +464,23 @@ }; } - for (const auto& discretionaryElement : nontracksElement.discretionaries_) + for (const auto& nontrackElement : nontracksElement.discretionaries_) try { + const BudgetSource source{nontrackElement.sourceName_}; b.nontracks_.add( Nontrack{ - BudgetSource{discretionaryElement.sourceName_}, + source, Money{ - discretionaryElement.major_, - discretionaryElement.minor_, - toIso4217Code(discretionaryElement.currency_.toStdString()) + nontrackElement.major_, + nontrackElement.minor_, + toIso4217Code(nontrackElement.currency_.toStdString()) }, - toEventFrequency(discretionaryElement.period_), - discretionaryElement.nextOccurOn_ + toEventFrequency(nontrackElement.period_), + nontrackElement.nextOccurOn_ } ); + budgetIndexer.addMapping(BudgetItemTypes::Nontrack, nontrackElement.id_, source); } catch (const exception& error) { @@ -541,7 +633,9 @@ { AccountNumber number{account.accountId_}; numbers.emplace(number); - bankAccountTypes[name][move(number)] = toSupportedAccountTypes(account.type_); + bankAccountTypes[name][move(number)] = toSupportedAccountTypes( + account.type_ + ); } rawBanks[name] = Bank{name, move(numbers), bankElement.isClosed_}; } @@ -628,6 +722,20 @@ bankInfo->second.at(accountNumber) } }; + map<BudgetItemIdentifier, Money> distributions{}; + + for (const auto& distribution : reconciliationElement.distributions_) + { + const auto type{toBudgetItemTypes(distribution.type_)}; + distributions.emplace( + BudgetItemIdentifier{type, budgetIndexer.lookUp(type, distribution.budgetItemId_)}, + Money{ + distribution.major_, + distribution.minor_, + toIso4217Code(distribution.currency_.toStdString()) + } + ); + } surveys.emplace( ba, ReconciledSurvey{ @@ -640,7 +748,7 @@ }, reconciliationElement.date_ }, - {}, // TODO: distribution amounts + move(distributions), reconciliationElement.checksum_ } ); @@ -679,9 +787,10 @@ qDebug() << "Filling application element"; const ApplicationElement applicationElement{}; + BudgetItemIdentifierIndexer budgetIndexer{}; qDebug() << "Filling wage elements"; const WagesElement wageElements{ - [&b, &budgetCodes] () + [&b, &budgetCodes, &budgetIndexer] () { WagesElement we; auto id{static_cast<IndexedElement::IdType>(IndexedElement::invalidId_ + 1)}; @@ -698,6 +807,7 @@ wage.second.nextOccurOn(), budgetCodes.value<Wage>(wage.second.source()).number().integer() ); + budgetIndexer.addMapping(BudgetItemTypes::Wage, id, wage.first); ++id; } return we; @@ -705,7 +815,7 @@ }; qDebug() << "Filling bill elements"; const BillsElement billElements{ - [&b, &budgetCodes] () + [&b, &budgetCodes, &budgetIndexer] () { BillsElement ee; auto id{static_cast<IndexedElement::IdType>(IndexedElement::invalidId_ + 1)}; @@ -722,6 +832,7 @@ bill.second.nextOccurOn(), budgetCodes.value<Bill>(bill.second.source()).number().integer() ); + budgetIndexer.addMapping(BudgetItemTypes::Bill, id, bill.first); ++id; } return ee; @@ -729,7 +840,7 @@ }; qDebug() << "Filling debt elements"; const DebtsElement debtsElements{ - [&b, &budgetCodes] () + [&b, &budgetCodes, &budgetIndexer] () { DebtsElement le; auto id{static_cast<IndexedElement::IdType>(IndexedElement::invalidId_ + 1)}; @@ -749,6 +860,7 @@ debt.second.nextOccurOn(), budgetCodes.value<Debt>(debt.second.source()).number().integer() ); + budgetIndexer.addMapping(BudgetItemTypes::Debt, id, debt.first); ++id; } return le; @@ -756,7 +868,7 @@ }; qDebug() << "Filling goal elements"; const GoalsElement goalElements{ - [&b, &budgetCodes] () + [&b, &budgetCodes, &budgetIndexer] () { GoalsElement ge; auto id{static_cast<IndexedElement::IdType>(IndexedElement::invalidId_ + 1)}; @@ -775,6 +887,7 @@ goal.second.nextOccurOn(), budgetCodes.value<Goal>(goal.second.source()).number().integer() ); + budgetIndexer.addMapping(BudgetItemTypes::Goal, id, goal.first); ++id; } return ge; @@ -782,7 +895,7 @@ }; qDebug() << "Filling discretionary elements"; const DiscretionariesElement nontrackElements{ - [&b, &budgetCodes] () + [&b, &budgetCodes, &budgetIndexer] () { DiscretionariesElement des; auto id{static_cast<IndexedElement::IdType>(IndexedElement::invalidId_ + 1)}; @@ -799,6 +912,7 @@ nontrack.second.nextOccurOn(), budgetCodes.value<Nontrack>(nontrack.second.source()).number().integer() ); + budgetIndexer.addMapping(BudgetItemTypes::Nontrack, id, nontrack.first); ++id; } return des; @@ -883,7 +997,7 @@ }; qDebug() << "Filling reconciled bank accounts elements"; const ReconciliationsElement reconciliationsElement{ - [&surveys] () + [&surveys, &budgetIndexer] () { ReconciliationsElement elements{}; @@ -891,6 +1005,16 @@ { const auto& bankAccount{bankAccountReconciledSurvey.first}; const auto& reconciledSurvey{bankAccountReconciledSurvey.second}; + vector<DistributionElement> distributions{}; + + for (const auto& unused : reconciledSurvey.distribution()) + distributions.emplace_back( + toWeak(unused.first.type_), + budgetIndexer.lookUpId(unused.first.type_, unused.first.source_), + unused.second.major(), + unused.second.minor(), + QString::fromStdString(toStdString(unused.second.code())) + ); elements.reconciliations_.emplace_back( bankAccount.account_.code_.number().integer(), reconciledSurvey.reconciled().balance().major(), @@ -899,7 +1023,8 @@ toStdString(reconciledSurvey.reconciled().balance().code()) ), reconciledSurvey.reconciled().reconciledOn(), - reconciledSurvey.validity() + reconciledSurvey.validity(), + move(distributions) ); } return elements;
--- a/src/file-storage/unit-tests/BudgetFileContents.cpp Thu Oct 06 17:05:23 2022 +0200 +++ b/src/file-storage/unit-tests/BudgetFileContents.cpp Thu Oct 06 20:08:49 2022 +0200 @@ -64,6 +64,10 @@ using drn::banking::ReconciledBankAccount; #include <budgeting/Budget.h> using drn::budgeting::Budget; +#include <budgeting/BudgetItemIdentifier.h> +using drn::budgeting::BudgetItemIdentifier; +#include <budgeting/BudgetItemTypes.h> +using drn::budgeting::BudgetItemTypes; #include <budgeting/BudgetSource.h> using drn::budgeting::BudgetSource; #include <budgeting/Nontrack.h> @@ -167,7 +171,11 @@ </banks> <reconciliations> <reconciliation account="1010" major="0" minor="0" currency="PLN"/> - <reconciliation account="1020" major="1234" minor="5600" currency="PLN" date="2022-08-31" checksum="LWaIuzOUeNn/eXPBDC7VSNYh5xuBRUCjUpCJs8dZgjc="/> + <reconciliation account="1020" major="1234" minor="5600" currency="PLN" date="2022-08-31" checksum="b1ZfLVuVIYKVMVJ0/QQLRNMtIXjtcbbm0BUmJ37gQKQ="> + <distribution type="Bill" id="1" major="411" minor="5200" currency="PLN"/> + <distribution type="Goal" id="1" major="411" minor="5200" currency="PLN"/> + <distribution type="Goal" id="3" major="411" minor="5200" currency="PLN"/> + </reconciliation> </reconciliations> </DuxReiNummariae>)~"}; return budgetContents; @@ -669,14 +677,14 @@ static BankAccount homeFederalChequeing{ BankName{"Home Federal"}, BankAccountType{ - AccountCode{AccountNumber{1020}}, + validGeneralLedger().ledger(AccountNumber{1020}).account_.code(), SupportedAccountTypes::Chequeing } }; static BankAccount c1stSavings{ BankName{"Community 1st Credit Union"}, BankAccountType{ - AccountCode{AccountNumber{1010}}, + validGeneralLedger().ledger(AccountNumber{1010}).account_.code(), SupportedAccountTypes::Savings } }; @@ -690,8 +698,32 @@ Money{1234, 5600u, Iso4217Codes::PLN}, QDate{2022, 8, 31} }, - {}, - {inPlace, QStringLiteral("c4k+LysGJesR5edD/SMfWCJWZDwu7003I7fzbglyVQg=")} + { + { + { + BudgetItemIdentifier{ + BudgetItemTypes::Bill, + BudgetSource{"Club Dues"} + }, + Money{411, 5200u, Iso4217Codes::PLN} + }, + { + BudgetItemIdentifier{ + BudgetItemTypes::Goal, + BudgetSource{"Computer"} + }, + Money{411, 5200u, Iso4217Codes::PLN} + }, + { + BudgetItemIdentifier{ + BudgetItemTypes::Goal, + BudgetSource{"Vacation"} + }, + Money{411, 5200u, Iso4217Codes::PLN} + } + } + }, + {inPlace, QStringLiteral("b1ZfLVuVIYKVMVJ0/QQLRNMtIXjtcbbm0BUmJ37gQKQ=")} } }, {
--- a/src/file-storage/unit-tests/XmlBudgetFile-unit-tests.cpp Thu Oct 06 17:05:23 2022 +0200 +++ b/src/file-storage/unit-tests/XmlBudgetFile-unit-tests.cpp Thu Oct 06 20:08:49 2022 +0200 @@ -167,7 +167,6 @@ ); const string actual{budgetFileContents.constData()}; const string expected{validContents()}; - QSKIP("Expected to fail due to the survey distribution missing."); // TODO: Remove when distribution is added. QVERIFY_THAT(actual, equals(expected)); }
--- a/src/navigation/internal/BudgetBankLedgers.h Thu Oct 06 17:05:23 2022 +0200 +++ b/src/navigation/internal/BudgetBankLedgers.h Thu Oct 06 20:08:49 2022 +0200 @@ -295,7 +295,7 @@ void update( BudgetItemType item, const foundation::Optional<banking::BankAccount>& ba = {} - ); + ); // TODO: Need to handle when the change in source for budget item in the survey checksum. void removeWage(const budgeting::BudgetSource& source); void removeBill(const budgeting::BudgetSource& source); void removeDebt(const budgeting::BudgetSource& source);