Mercurial > hgweb.cgi > drn
changeset 900:5c3c58aa9448
IN 32: Moved the survey completion logic out of the container of surveys and into the object itself where it belongs.
Added an upsert member function to the container of surveys.
author | John Schneiderman <JohnMS@member.fsf.org> |
---|---|
date | Wed, 05 Oct 2022 18:05:26 +0200 |
parents | 563ef254bc3a |
children | 4501ccdb0cfc |
files | src/file-storage/internal/XmlBudgetFile.cpp src/file-storage/unit-tests/BudgetFileContents.cpp src/navigation/internal/BudgetBankLedgers.cpp src/surveying/external/surveying/ReconciledSurvey.cpp src/surveying/external/surveying/ReconciledSurvey.h src/surveying/unit-tests/ReconciledSurvey-unit-tests.cpp |
diffstat | 6 files changed, 101 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/src/file-storage/internal/XmlBudgetFile.cpp Mon Oct 03 19:37:42 2022 +0200 +++ b/src/file-storage/internal/XmlBudgetFile.cpp Wed Oct 05 18:05:26 2022 +0200 @@ -643,7 +643,8 @@ }, reconciliationElement.date_ }, - {} // TODO: distribution amounts and validity value + {}, // TODO: distribution amounts + {} // TODO: validity value } ); }
--- a/src/file-storage/unit-tests/BudgetFileContents.cpp Mon Oct 03 19:37:42 2022 +0200 +++ b/src/file-storage/unit-tests/BudgetFileContents.cpp Wed Oct 05 18:05:26 2022 +0200 @@ -687,12 +687,13 @@ Money{1234, 5600u, Iso4217Codes::PLN}, QDate{2022, 8, 31} }, + {}, {} } }, { c1stSavings, - ReconciledSurvey{ReconciledBankAccount{c1stSavings, Iso4217Codes::PLN}, {}} + ReconciledSurvey{c1stSavings, Iso4217Codes::PLN} } } };
--- a/src/navigation/internal/BudgetBankLedgers.cpp Mon Oct 03 19:37:42 2022 +0200 +++ b/src/navigation/internal/BudgetBankLedgers.cpp Wed Oct 05 18:05:26 2022 +0200 @@ -928,13 +928,9 @@ try { - this->surveys_.completed( - ReconciledSurvey{ - ReconciledBankAccount{ba, reconciledBalance, completedOn}, - unusedBudget - }, - reconciledBalance - ); + auto survey{previousSurvey.valueOr(ReconciledSurvey{ba, ledger.account_.balance().code()})}; + survey.completed(completedOn, reconciledBalance, unusedBudget); + this->surveys_.upsert(survey); } catch (const exception&) {
--- a/src/surveying/external/surveying/ReconciledSurvey.cpp Mon Oct 03 19:37:42 2022 +0200 +++ b/src/surveying/external/surveying/ReconciledSurvey.cpp Wed Oct 05 18:05:26 2022 +0200 @@ -29,6 +29,8 @@ using drn::surveying::ReconciledSurvey; using drn::surveying::ReconciledSurveys; +#include <pecunia/Codes.h> +using pecunia::currency::Iso4217Codes; #include <pecunia/Math.h> using pecunia::math::sum; #include <QCryptographicHash> @@ -65,15 +67,17 @@ { QString calculateValidity( - ReconciledBankAccount reconciled, - map<BudgetItemIdentifier, Money> distribution + const BankAccount& ba, + const Money& balance, + const Optional<QDate>& reconciledOn, + const map<BudgetItemIdentifier, Money>& distribution ) { - QString value{presentationText(reconciled.bankAccount())}; - value = value % presentationText(reconciled.balance(), false, true); + QString value{presentationText(ba)}; + value = value % presentationText(balance, false, true); - if (reconciled.reconciledOn().hasValue()) - value = value % reconciled.reconciledOn()->toString(DateFormat::ISODate); + if (reconciledOn.hasValue()) + value = value % reconciledOn->toString(DateFormat::ISODate); for (const auto& itemAmount : distribution) value = value % presentationText(itemAmount.first) @@ -85,6 +89,10 @@ //{ ReconciledSurvey +ReconciledSurvey::ReconciledSurvey(BankAccount ba, const Iso4217Codes& currency) : + ReconciledSurvey{ReconciledBankAccount{ba, currency}, {}, {}} +{} + ReconciledSurvey::ReconciledSurvey( ReconciledBankAccount reconciled, map<BudgetItemIdentifier, Money> distribution, @@ -96,7 +104,14 @@ { if (this->validity_.hasValue()) { - const auto validityCheck{calculateValidity(this->reconciled_, this->distribution_)}; + const auto validityCheck{ + calculateValidity( + this->reconciled_.bankAccount(), + this->reconciled_.balance(), + this->reconciled_.reconciledOn(), + this->distribution_ + ) + }; if (this->validity_ != validityCheck) throw Error{ @@ -123,6 +138,32 @@ return this->validity_; } +void ReconciledSurvey::completed( + const QDate& completedOn, + const Money& reconciledBalance, + const map<BudgetItemIdentifier, Money>& distribution +) +{ + const auto distributionBalance{sum(this->reconciled_.balance().code(), distribution)}; + const auto ba{this->reconciled_.bankAccount()}; + + if (reconciledBalance != distributionBalance) + throw BankError{ + ba.bank_, + QObject::tr("The surveyed balance %1 does not match the unused %2 balance.") + .arg(presentationText(reconciledBalance)) + .arg(presentationText(distributionBalance)) + }; +// this->validity_ = calculateValidity( +// this->reconciled_.bankAccount(), +// reconciledBalance, +// completedOn, +// distribution +// ); + this->reconciled_.reconcile(completedOn, reconciledBalance); + this->distribution_ = move(distribution); +} + bool drn::surveying::operator==(const ReconciledSurvey& lhs, const ReconciledSurvey& rhs) { return tie(lhs.reconciled(), lhs.distribution()) == tie(rhs.reconciled(), rhs.distribution()); @@ -188,24 +229,14 @@ return account->second; } -void ReconciledSurveys::completed(ReconciledSurvey survey, const Money& reconciledBalance) +void ReconciledSurveys::upsert(ReconciledSurvey survey) { - const auto expectedBalance{sum(survey.reconciled().balance().code(), survey.distribution())}; const auto ba{survey.reconciled().bankAccount()}; - if (reconciledBalance != expectedBalance) - throw BankError{ - ba.bank_, - QObject::tr("The surveyed balance %1 does not match the expected %2.") - .arg(presentationText(reconciledBalance)) - .arg(presentationText(expectedBalance)) - }; - // TODO: survey.verification_ = calculateVerification(); - if (this->count(ba) == 0) { const auto emplaced{(*this).emplace(ba, move(survey))}; - assert(emplaced.second && "The new survey should always be inserted."); + assert(emplaced.second && "A new survey should always be inserted."); } else (*this)[ba] = move(survey);
--- a/src/surveying/external/surveying/ReconciledSurvey.h Mon Oct 03 19:37:42 2022 +0200 +++ b/src/surveying/external/surveying/ReconciledSurvey.h Wed Oct 05 18:05:26 2022 +0200 @@ -56,16 +56,22 @@ public: ReconciledSurvey() = default; /** - * @brief Full and partial initialisation constructor. + * @brief Partial initialisation constructor for creating a new survey. + * + * @param ba The bank account that is reconciled. + * @param currency The currency held within the bank account. + */ + ReconciledSurvey(banking::BankAccount ba, const pecunia::currency::Iso4217Codes& currency); + /** + * @brief Full initialisation constructor. * * @exception Error When a supplied validity value does not match the calculated value. * * @param reconciled The bank account that was reconciled. * @param distribution The distribution of the balance in the account. - * @param validity When supplied, the value that represents an object whose values were verified - * after having completed a survey. This is in lieu of verifying the balances upon object - * creation since exchange rates change over time. If not supplied, no verification is - * performed, i.e. the object is partially initialised. + * @param validity The value that represents an object whose values were verified after having + * completed a survey. This is in lieu of verifying the balances upon object creation since + * exchange rates change over time preventing verification in the future. */ ReconciledSurvey( banking::ReconciledBankAccount reconciled, @@ -73,7 +79,7 @@ budgeting::BudgetItemIdentifier, pecunia::currency::Money > distribution, - foundation::Optional<::QString> validity = {} + foundation::Optional<::QString> validity ); const banking::ReconciledBankAccount& reconciled() const noexcept; const std::map< @@ -84,6 +90,23 @@ * @brief The value that represents a valid object after having completed a survey. */ const foundation::Optional<::QString>& validity() const noexcept; + /** + * @brief Updates the survey with the completed values. + * + * @exception BankError When the reconciled bank balance does not match the amount of + * distributed unused funds. + * + * @param completedOn The date the balance was confirmed. + * @param reconciledBalance The balance as reported in the bank account. + * @param distribution The distribution of unused funds (bank balance) in the bank account. + * + * @post Upon successful survey completion, the validity value is computed and stored in the object. + */ + void completed( + const ::QDate& completedOn, + const pecunia::currency::Money& reconciledBalance, + const std::map<budgeting::BudgetItemIdentifier, pecunia::currency::Money>& distribution + ); }; class DRN_SURVEYING_EXPORT ReconciledSurveys : std::map<banking::BankAccount, ReconciledSurvey> @@ -100,13 +123,12 @@ using std::map<banking::BankAccount, ReconciledSurvey>::count; using std::map<banking::BankAccount, ReconciledSurvey>::at; using std::map<banking::BankAccount, ReconciledSurvey>::size; - foundation::Optional<ReconciledSurvey> find(const banking::BankAccount& ba) const; foundation::Optional<ReconciledSurvey> find( const banking::BankName& bn, const accounting::AccountNumber& an ) const; - void completed(ReconciledSurvey survey, const pecunia::currency::Money& reconciledBalance); + void upsert(ReconciledSurvey survey); }; DRN_SURVEYING_EXPORT bool operator==(
--- a/src/surveying/unit-tests/ReconciledSurvey-unit-tests.cpp Mon Oct 03 19:37:42 2022 +0200 +++ b/src/surveying/unit-tests/ReconciledSurvey-unit-tests.cpp Wed Oct 05 18:05:26 2022 +0200 @@ -111,9 +111,20 @@ void constructor_PartialInit_ShouldSet() { - const ReconciledSurvey survey{this->reconciled_, this->distribution_}; - QVERIFY_THAT(survey.distribution(), equals(this->distribution_)); - QVERIFY_THAT(survey.reconciled(), equals(this->reconciled_)); + const ReconciledSurvey survey{ + this->reconciled_.bankAccount(), + this->reconciled_.balance().code() + }; + QVERIFY_THAT( + survey.reconciled(), + equals( + ReconciledBankAccount{ + this->reconciled_.bankAccount(), + this->reconciled_.balance().code() + } + ) + ); + QVERIFY_TRUE(survey.distribution().empty()); QVERIFY_FALSE(survey.validity().hasValue()); }