12#include <nlohmann/json.hpp>
16#include <unordered_set>
25void eraseAll(std::string& value,
char ch) {
26 value.erase(std::remove(value.begin(), value.end(), ch), value.end());
33 nlohmann::json config;
55 nlohmann::json properties = nlohmann::json::array();
57 const std::string value =
trim(propertyId);
59 properties.push_back(value);
63 std::move(properties);
65 nlohmann::json contractTypes = nlohmann::json::array();
68 if (!contractType.empty()) {
69 contractTypes.push_back(contractType);
73 std::move(contractTypes);
79 const std::string& dateField,
const std::string& dateMode,
80 const std::string& year,
const std::string& dateFrom,
81 const std::string& dateTo,
const std::vector<std::string>& propertyIds,
82 const std::vector<std::string>& contractTypes,
83 const std::string& allocatableMode) {
98 [](
const std::string& value) { return trim(value).empty(); }),
103 [](
const std::string& value) { return trim(value).empty(); }),
108std::vector<std::pair<std::string, double>>
110 std::vector<std::pair<std::string, double>> out;
111 if (adjustmentsJson.empty()) {
115 const auto parsed = nlohmann::json::parse(adjustmentsJson);
116 if (!parsed.is_object()) {
119 out.reserve(parsed.size());
120 for (
const auto& [key, value] : parsed.items()) {
121 if (value.is_number()) {
122 out.emplace_back(key, value.get<
double>());
125 }
catch (
const nlohmann::json::exception&) {
132 std::string normalized =
trim(text);
133 if (normalized.empty()) {
137 if (normalized.back() ==
'%') {
138 normalized.pop_back();
139 normalized =
trim(normalized);
141 eraseAll(normalized,
' ');
145 const double direct = std::stod(normalized, &consumed);
146 if (consumed == normalized.size() && std::isfinite(direct)) {
152 const auto lastComma = normalized.find_last_of(
',');
153 const auto lastDot = normalized.find_last_of(
'.');
154 if (lastComma != std::string::npos && lastDot != std::string::npos) {
155 if (lastComma > lastDot) {
156 eraseAll(normalized,
'.');
157 std::replace(normalized.begin(), normalized.end(),
',',
'.');
159 eraseAll(normalized,
',');
161 }
else if (lastComma != std::string::npos) {
162 std::replace(normalized.begin(), normalized.end(),
',',
'.');
167 const double parsed = std::stod(normalized, &consumed);
168 if (consumed == normalized.size() && std::isfinite(parsed)) {
177 const std::vector<AnalysisAdjustmentTransactionInput>& transactions,
178 const std::vector<std::string>& selectedTransactionIds,
double taxPercent) {
179 std::unordered_set<std::string> selected;
180 selected.reserve(selectedTransactionIds.size());
181 for (
const auto&
id : selectedTransactionIds) {
182 const std::string value =
trim(
id);
183 if (!value.empty()) {
184 selected.insert(value);
187 if (selected.empty()) {
188 return std::string(
"{}");
191 const double factor = 1.0 + (taxPercent / 100.0);
192 nlohmann::json adjustments = nlohmann::json::object();
193 for (
const auto& transaction : transactions) {
194 const std::string
id =
trim(transaction.id);
195 if (
id.empty() || !selected.contains(
id)) {
198 adjustments[id] = transaction.amount * factor;
200 return adjustments.dump();
205 const std::string& analysisId,
bool includeCalculationAdjustments,
206 const std::vector<std::pair<std::string, double>>& adjustments) {
207 const std::string targetId =
trim(analysisId);
208 const auto it = std::find_if(
210 [&](
const auto&
analysis) { return analysis.id == targetId; });
215 it->includeCalculationAdjustments = includeCalculationAdjustments;
216 for (
const auto& [key, value] : adjustments) {
217 const auto existing =
218 std::find_if(it->adjustments.begin(), it->adjustments.end(),
219 [&](
const auto& item) { return item.first == key; });
220 if (existing == it->adjustments.end()) {
221 it->adjustments.emplace_back(key, value);
223 existing->second = value;
230 std::unordered_set<std::string> seen;
231 std::vector<std::string> values;
232 for (
const auto& contract :
workspace.contracts) {
233 if (contract.type.empty() || seen.contains(contract.type)) {
236 seen.insert(contract.type);
237 values.push_back(contract.type);
239 std::sort(values.begin(), values.end());
Defines stable analysis type, configuration, filter, and result keys.
Declares analysis use-case request DTOs and filter-spec helpers.
Shared analysis request/config helpers for UI and application layers.
Declares private string helpers shared across core implementation files.
constexpr std::string_view kStrategyKey
constexpr std::string_view kPercentKey
constexpr std::string_view kStrategyTax
constexpr std::string_view kTotalAmount
constexpr std::string_view kPie
constexpr std::string_view kTypeCalculation
constexpr std::string_view kPlotTypeKey
constexpr std::string_view kPropertiesKey
constexpr std::string_view kPlotMeasureKey
constexpr std::string_view kContractTypesKey
std::vector< std::string > contractTypesFromSnapshot(const core::ports::workspace::WorkspaceSnapshot &workspace)
core::ports::analysis::AnalysisFilterSelection filterSelectionFromFields(const std::string &dateField, const std::string &dateMode, const std::string &year, const std::string &dateFrom, const std::string &dateTo, const std::vector< std::string > &propertyIds, const std::vector< std::string > &contractTypes, const std::string &allocatableMode)
std::string buildAnalysisAdjustmentsJson(const std::vector< AnalysisAdjustmentTransactionInput > &transactions, const std::vector< std::string > &selectedTransactionIds, double taxPercent)
std::optional< double > parseAnalysisPercentText(const std::string &text)
Parses a user-entered analysis percentage.
void applyAnalysisPreviewOverrides(core::ports::workspace::WorkspaceSnapshot &workspace, const std::string &analysisId, bool includeCalculationAdjustments, const std::vector< std::pair< std::string, double > > &adjustments)
std::string lowerAscii(std::string s)
Converts ASCII letters in a string to lowercase.
std::string trim(std::string s)
Removes leading and trailing ASCII whitespace from a string.
std::vector< std::pair< std::string, double > > parseAnalysisAdjustmentsJson(const std::string &adjustmentsJson)
std::string buildAnalysisConfigJson(const core::ports::analysis::AnalysisConfigInput &input)
std::string lowerAscii(std::string s)
Converts ASCII letters in a string to lowercase.
std::string trim(std::string s)
Removes leading and trailing ASCII whitespace from a string.
std::vector< std::string > contractTypes
std::vector< std::string > propertyIds
std::string allocatableMode