mirror of
https://github.com/ysoftdevs/Theatrical-Players-Refactoring-Kata.git
synced 2026-02-20 09:07:41 +01:00
Add C++ implementation
This commit is contained in:
95
cpp/statement.cpp
Normal file
95
cpp/statement.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "statement.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
// https://stackoverflow.com/a/7277333/104370
|
||||
class comma_numpunct : public std::numpunct<char>
|
||||
{
|
||||
protected:
|
||||
virtual char do_thousands_sep() const override
|
||||
{
|
||||
return ',';
|
||||
}
|
||||
|
||||
virtual std::string do_grouping() const override
|
||||
{
|
||||
return "\03";
|
||||
}
|
||||
};
|
||||
|
||||
std::string format_as_dollars(float amount)
|
||||
{
|
||||
// this creates a new locale based on the current application default
|
||||
// (which is either the one given on startup, but can be overriden with
|
||||
// std::locale::global) - then extends it with an extra facet that
|
||||
// controls numeric output.
|
||||
const std::locale comma_locale(std::locale(), new comma_numpunct());
|
||||
|
||||
std::ostringstream out;
|
||||
// tell stream to use our new locale.
|
||||
out.imbue(comma_locale);
|
||||
out.precision(2);
|
||||
out << "$" << std::fixed << amount;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string statement(
|
||||
const nlohmann::json& invoice,
|
||||
const nlohmann::json& plays)
|
||||
{
|
||||
float total_amount = 0;
|
||||
int volume_credits = 0;
|
||||
|
||||
std::stringstream result;
|
||||
result << "Statement for " << invoice["customer"].get<std::string>() << '\n';
|
||||
|
||||
for( const auto& perf : invoice["performances"])
|
||||
{
|
||||
float this_amount = 0;
|
||||
auto play = plays[perf["playID"].get<std::string>()];
|
||||
if (play["type"] == "tragedy")
|
||||
{
|
||||
this_amount = 40000;
|
||||
if (perf["audience"] > 30)
|
||||
{
|
||||
this_amount += 1000 * (perf["audience"].get<int>() - 30);
|
||||
}
|
||||
}
|
||||
|
||||
else if (play["type"] == "comedy")
|
||||
{
|
||||
this_amount = 30000;
|
||||
if (perf["audience"] > 20)
|
||||
{
|
||||
this_amount += 10000 + 500 * (perf["audience"].get<int>() - 20);
|
||||
}
|
||||
|
||||
this_amount += 300 * perf["audience"].get<int>();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
throw std::domain_error("unknown type: " + play["type"].get<std::string>());
|
||||
}
|
||||
|
||||
// add volume credits
|
||||
volume_credits += std::max(perf["audience"].get<int>() - 30, 0);
|
||||
|
||||
// add extra credit for every ten comedy attendees
|
||||
if ("comedy" == play["type"])
|
||||
{
|
||||
volume_credits += perf["audience"].get<int>() / 5;
|
||||
}
|
||||
|
||||
// print line for this order
|
||||
result << " " << play["name"].get<std::string>() << ": " << format_as_dollars(this_amount/100) <<
|
||||
" (" << perf["audience"] << " seats)\n";
|
||||
total_amount += this_amount;
|
||||
}
|
||||
|
||||
result << "Amount owed is " << format_as_dollars(total_amount/100.0f) << "\n";
|
||||
result << "You earned " << volume_credits << " credits";
|
||||
return result.str();
|
||||
}
|
||||
Reference in New Issue
Block a user