Began support for improved commodity handling.
This commit is contained in:
parent
96d6d62ad9
commit
2ebfddf401
12 changed files with 152 additions and 133 deletions
61
amount.cc
61
amount.cc
|
|
@ -1279,14 +1279,13 @@ void amount_t::annotate_commodity(const amount_t& price,
|
||||||
DEBUG_PRINT("amounts.commodities", " Annotated amount is " << *this);
|
DEBUG_PRINT("amounts.commodities", " Annotated amount is " << *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amount_t::reduce_commodity(const bool keep_price,
|
amount_t amount_t::reduce_commodity(const bool keep_price,
|
||||||
const bool keep_date,
|
const bool keep_date,
|
||||||
const bool keep_tag)
|
const bool keep_tag) const
|
||||||
{
|
{
|
||||||
if (! commodity().annotated)
|
if (! commodity().annotated ||
|
||||||
return;
|
(keep_price && keep_date && keep_tag))
|
||||||
if (keep_price && keep_date && keep_tag)
|
return *this;
|
||||||
return;
|
|
||||||
|
|
||||||
DEBUG_PRINT("amounts.commodities", "Reducing commodity for amount "
|
DEBUG_PRINT("amounts.commodities", "Reducing commodity for amount "
|
||||||
<< *this << std::endl
|
<< *this << std::endl
|
||||||
|
|
@ -1297,16 +1296,27 @@ void amount_t::reduce_commodity(const bool keep_price,
|
||||||
annotated_commodity_t&
|
annotated_commodity_t&
|
||||||
ann_comm(static_cast<annotated_commodity_t&>(commodity()));
|
ann_comm(static_cast<annotated_commodity_t&>(commodity()));
|
||||||
|
|
||||||
annotated_commodity_t * new_ann_comm =
|
commodity_t * new_comm;
|
||||||
annotated_commodity_t::find_or_create(*ann_comm.base,
|
|
||||||
keep_price ?
|
|
||||||
ann_comm.price : amount_t(),
|
|
||||||
keep_date ? ann_comm.date : 0,
|
|
||||||
keep_tag ? ann_comm.tag : "");
|
|
||||||
assert(new_ann_comm);
|
|
||||||
set_commodity(*new_ann_comm);
|
|
||||||
|
|
||||||
DEBUG_PRINT("amounts.commodities", " Reduced amount is " << *this);
|
if ((keep_price && ann_comm.price) ||
|
||||||
|
(keep_date && ann_comm.date) ||
|
||||||
|
(keep_tag && ! ann_comm.tag.empty()))
|
||||||
|
{
|
||||||
|
new_comm = annotated_commodity_t::find_or_create
|
||||||
|
(*ann_comm.base, keep_price ? ann_comm.price : amount_t(),
|
||||||
|
keep_date ? ann_comm.date : 0, keep_tag ? ann_comm.tag : "");
|
||||||
|
} else {
|
||||||
|
new_comm = commodity_t::find_or_create(ann_comm.base_symbol());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(new_comm);
|
||||||
|
|
||||||
|
amount_t temp(*this);
|
||||||
|
temp.set_commodity(*new_comm);
|
||||||
|
|
||||||
|
DEBUG_PRINT("amounts.commodities", " Reduced amount is " << temp);
|
||||||
|
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1347,6 +1357,22 @@ bool commodity_t::needs_quotes(const std::string& symbol)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool commodity_t::valid() const
|
||||||
|
{
|
||||||
|
if (symbol().empty() && this != null_commodity)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (annotated && ! base)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (precision() > 16)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
commodity_t * commodity_t::create(const std::string& symbol)
|
commodity_t * commodity_t::create(const std::string& symbol)
|
||||||
{
|
{
|
||||||
std::auto_ptr<commodity_t> commodity(new commodity_t);
|
std::auto_ptr<commodity_t> commodity(new commodity_t);
|
||||||
|
|
@ -1497,8 +1523,11 @@ annotated_commodity_t::create(const commodity_t& comm,
|
||||||
commodity->price = price;
|
commodity->price = price;
|
||||||
commodity->date = date;
|
commodity->date = date;
|
||||||
commodity->tag = tag;
|
commodity->tag = tag;
|
||||||
|
|
||||||
commodity->base = &comm;
|
commodity->base = &comm;
|
||||||
|
assert(commodity->base);
|
||||||
commodity->ptr = comm.ptr;
|
commodity->ptr = comm.ptr;
|
||||||
|
assert(commodity->ptr);
|
||||||
|
|
||||||
commodity->qualified_symbol = comm.symbol();
|
commodity->qualified_symbol = comm.symbol();
|
||||||
|
|
||||||
|
|
|
||||||
19
amount.h
19
amount.h
|
|
@ -75,9 +75,9 @@ class amount_t
|
||||||
void annotate_commodity(const amount_t& price,
|
void annotate_commodity(const amount_t& price,
|
||||||
const std::time_t date = 0,
|
const std::time_t date = 0,
|
||||||
const std::string& tag = "");
|
const std::string& tag = "");
|
||||||
void reduce_commodity(const bool keep_price = false,
|
amount_t reduce_commodity(const bool keep_price = false,
|
||||||
const bool keep_date = false,
|
const bool keep_date = false,
|
||||||
const bool keep_tag = false);
|
const bool keep_tag = false) const;
|
||||||
void clear_commodity() {
|
void clear_commodity() {
|
||||||
commodity_ = NULL;
|
commodity_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -282,9 +282,6 @@ inline amount_t abs(const amount_t& amt) {
|
||||||
return amt < 0 ? amt.negated() : amt;
|
return amt < 0 ? amt.negated() : amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define base_amount(amt) \
|
|
||||||
((! show_lots && amt.commodity().price) ? amt.base() : amt)
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const amount_t& amt);
|
std::ostream& operator<<(std::ostream& out, const amount_t& amt);
|
||||||
|
|
||||||
inline std::istream& operator>>(std::istream& in, amount_t& amt) {
|
inline std::istream& operator>>(std::istream& in, amount_t& amt) {
|
||||||
|
|
@ -499,15 +496,7 @@ class commodity_t
|
||||||
return ptr->value(moment);
|
return ptr->value(moment);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid() const {
|
bool valid() const;
|
||||||
if (symbol().empty() && this != null_commodity)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (precision() > 16)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class annotated_commodity_t : public commodity_t
|
class annotated_commodity_t : public commodity_t
|
||||||
|
|
|
||||||
31
balance.cc
31
balance.cc
|
|
@ -46,6 +46,19 @@ balance_t balance_t::price() const
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
balance_t balance_t::reduce(const bool keep_price, const bool keep_date,
|
||||||
|
const bool keep_tag) const
|
||||||
|
{
|
||||||
|
balance_t temp;
|
||||||
|
|
||||||
|
for (amounts_map::const_iterator i = amounts.begin();
|
||||||
|
i != amounts.end();
|
||||||
|
i++)
|
||||||
|
temp += (*i).second.reduce_commodity(keep_price, keep_date, keep_tag);
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
struct compare_amount_commodities {
|
struct compare_amount_commodities {
|
||||||
bool operator()(const amount_t * left, const amount_t * right) const {
|
bool operator()(const amount_t * left, const amount_t * right) const {
|
||||||
return left->commodity().symbol() < right->commodity().symbol();
|
return left->commodity().symbol() < right->commodity().symbol();
|
||||||
|
|
@ -160,14 +173,10 @@ balance_pair_t& balance_pair_t::operator/=(const balance_pair_t& bal_pair)
|
||||||
quantity /= bal_pair.quantity;
|
quantity /= bal_pair.quantity;
|
||||||
if (cost)
|
if (cost)
|
||||||
*cost /= bal_pair.cost ? *bal_pair.cost : bal_pair.quantity;
|
*cost /= bal_pair.cost ? *bal_pair.cost : bal_pair.quantity;
|
||||||
|
|
||||||
if (bal_pair.price && *bal_pair.price && price)
|
|
||||||
*price /= *bal_pair.price;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
balance_pair_t& balance_pair_t::add(const amount_t& amount,
|
balance_pair_t& balance_pair_t::add(const amount_t& amount,
|
||||||
const amount_t * a_price,
|
|
||||||
const amount_t * a_cost)
|
const amount_t * a_cost)
|
||||||
{
|
{
|
||||||
if (a_cost && ! cost)
|
if (a_cost && ! cost)
|
||||||
|
|
@ -175,13 +184,6 @@ balance_pair_t& balance_pair_t::add(const amount_t& amount,
|
||||||
quantity += amount;
|
quantity += amount;
|
||||||
if (cost)
|
if (cost)
|
||||||
*cost += a_cost ? *a_cost : amount;
|
*cost += a_cost ? *a_cost : amount;
|
||||||
|
|
||||||
if (a_price) {
|
|
||||||
if (! price)
|
|
||||||
price = new balance_t(*a_price);
|
|
||||||
else
|
|
||||||
*price += *a_price;
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,8 +292,10 @@ void export_balance()
|
||||||
.def("negate", &balance_t::negate)
|
.def("negate", &balance_t::negate)
|
||||||
.def("amount", &balance_t::amount)
|
.def("amount", &balance_t::amount)
|
||||||
.def("value", &balance_t::value)
|
.def("value", &balance_t::value)
|
||||||
|
.def("price", &balance_t::price)
|
||||||
|
.def("reduce", &balance_t::reduce)
|
||||||
.def("write", &balance_t::write)
|
.def("write", &balance_t::write)
|
||||||
.def("valid", &balance_t::valid)
|
.def("valid", &balance_t::valid)
|
||||||
;
|
;
|
||||||
|
|
||||||
class_< balance_pair_t > ("BalancePair")
|
class_< balance_pair_t > ("BalancePair")
|
||||||
|
|
@ -368,9 +372,6 @@ void export_balance()
|
||||||
.def("__len__", balance_pair_len)
|
.def("__len__", balance_pair_len)
|
||||||
.def("__getitem__", balance_pair_getitem)
|
.def("__getitem__", balance_pair_getitem)
|
||||||
|
|
||||||
.add_property("price",
|
|
||||||
make_getter(&balance_pair_t::price,
|
|
||||||
return_value_policy<reference_existing_object>()))
|
|
||||||
.add_property("cost",
|
.add_property("cost",
|
||||||
make_getter(&balance_pair_t::cost,
|
make_getter(&balance_pair_t::cost,
|
||||||
return_value_policy<reference_existing_object>()))
|
return_value_policy<reference_existing_object>()))
|
||||||
|
|
|
||||||
74
balance.h
74
balance.h
|
|
@ -411,6 +411,9 @@ class balance_t
|
||||||
amount_t amount(const commodity_t& commodity) const;
|
amount_t amount(const commodity_t& commodity) const;
|
||||||
balance_t value(const std::time_t moment) const;
|
balance_t value(const std::time_t moment) const;
|
||||||
balance_t price() const;
|
balance_t price() const;
|
||||||
|
balance_t reduce(const bool keep_price = false,
|
||||||
|
const bool keep_date = false,
|
||||||
|
const bool keep_tag = false) const;
|
||||||
|
|
||||||
void write(std::ostream& out, const int first_width,
|
void write(std::ostream& out, const int first_width,
|
||||||
const int latter_width = -1) const;
|
const int latter_width = -1) const;
|
||||||
|
|
@ -446,56 +449,42 @@ class balance_pair_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
balance_t quantity;
|
balance_t quantity;
|
||||||
balance_t * price;
|
|
||||||
balance_t * cost;
|
balance_t * cost;
|
||||||
|
|
||||||
// constructors
|
// constructors
|
||||||
balance_pair_t() : price(NULL), cost(NULL) {}
|
balance_pair_t() : cost(NULL) {}
|
||||||
balance_pair_t(const balance_pair_t& bal_pair)
|
balance_pair_t(const balance_pair_t& bal_pair)
|
||||||
: quantity(bal_pair.quantity), price(NULL), cost(NULL) {
|
: quantity(bal_pair.quantity), cost(NULL) {
|
||||||
if (bal_pair.price)
|
|
||||||
price = new balance_t(*bal_pair.price);
|
|
||||||
if (bal_pair.cost)
|
if (bal_pair.cost)
|
||||||
cost = new balance_t(*bal_pair.cost);
|
cost = new balance_t(*bal_pair.cost);
|
||||||
}
|
}
|
||||||
balance_pair_t(const balance_t& _quantity)
|
balance_pair_t(const balance_t& _quantity)
|
||||||
: quantity(_quantity), price(NULL), cost(NULL) {}
|
: quantity(_quantity), cost(NULL) {}
|
||||||
balance_pair_t(const amount_t& _quantity)
|
balance_pair_t(const amount_t& _quantity)
|
||||||
: quantity(_quantity), price(NULL), cost(NULL) {}
|
: quantity(_quantity), cost(NULL) {}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
balance_pair_t(T value) : quantity(value), price(NULL), cost(NULL) {}
|
balance_pair_t(T value) : quantity(value), cost(NULL) {}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
~balance_pair_t() {
|
~balance_pair_t() {
|
||||||
if (price) delete price;
|
if (cost) delete cost;
|
||||||
if (cost) delete cost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// assignment operator
|
// assignment operator
|
||||||
balance_pair_t& operator=(const balance_pair_t& bal_pair) {
|
balance_pair_t& operator=(const balance_pair_t& bal_pair) {
|
||||||
if (this != &bal_pair) {
|
if (this != &bal_pair) {
|
||||||
if (price) {
|
|
||||||
delete price;
|
|
||||||
price = NULL;
|
|
||||||
}
|
|
||||||
if (cost) {
|
if (cost) {
|
||||||
delete cost;
|
delete cost;
|
||||||
cost = NULL;
|
cost = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
quantity = bal_pair.quantity;
|
quantity = bal_pair.quantity;
|
||||||
if (bal_pair.price)
|
|
||||||
price = new balance_t(*bal_pair.price);
|
|
||||||
if (bal_pair.cost)
|
if (bal_pair.cost)
|
||||||
cost = new balance_t(*bal_pair.cost);
|
cost = new balance_t(*bal_pair.cost);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
balance_pair_t& operator=(const balance_t& bal) {
|
balance_pair_t& operator=(const balance_t& bal) {
|
||||||
if (price) {
|
|
||||||
delete price;
|
|
||||||
price = NULL;
|
|
||||||
}
|
|
||||||
if (cost) {
|
if (cost) {
|
||||||
delete cost;
|
delete cost;
|
||||||
cost = NULL;
|
cost = NULL;
|
||||||
|
|
@ -504,10 +493,6 @@ class balance_pair_t
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
balance_pair_t& operator=(const amount_t& amt) {
|
balance_pair_t& operator=(const amount_t& amt) {
|
||||||
if (price) {
|
|
||||||
delete price;
|
|
||||||
price = NULL;
|
|
||||||
}
|
|
||||||
if (cost) {
|
if (cost) {
|
||||||
delete cost;
|
delete cost;
|
||||||
cost = NULL;
|
cost = NULL;
|
||||||
|
|
@ -517,10 +502,6 @@ class balance_pair_t
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
balance_pair_t& operator=(T value) {
|
balance_pair_t& operator=(T value) {
|
||||||
if (price) {
|
|
||||||
delete price;
|
|
||||||
price = NULL;
|
|
||||||
}
|
|
||||||
if (cost) {
|
if (cost) {
|
||||||
delete cost;
|
delete cost;
|
||||||
cost = NULL;
|
cost = NULL;
|
||||||
|
|
@ -536,13 +517,6 @@ class balance_pair_t
|
||||||
quantity += bal_pair.quantity;
|
quantity += bal_pair.quantity;
|
||||||
if (cost)
|
if (cost)
|
||||||
*cost += bal_pair.cost ? *bal_pair.cost : bal_pair.quantity;
|
*cost += bal_pair.cost ? *bal_pair.cost : bal_pair.quantity;
|
||||||
|
|
||||||
if (bal_pair.price) {
|
|
||||||
if (! price)
|
|
||||||
price = new balance_t(*bal_pair.price);
|
|
||||||
else
|
|
||||||
*price += *bal_pair.price;
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
balance_pair_t& operator+=(const balance_t& bal) {
|
balance_pair_t& operator+=(const balance_t& bal) {
|
||||||
|
|
@ -568,15 +542,6 @@ class balance_pair_t
|
||||||
quantity -= bal_pair.quantity;
|
quantity -= bal_pair.quantity;
|
||||||
if (cost)
|
if (cost)
|
||||||
*cost -= bal_pair.cost ? *bal_pair.cost : bal_pair.quantity;
|
*cost -= bal_pair.cost ? *bal_pair.cost : bal_pair.quantity;
|
||||||
|
|
||||||
if (bal_pair.price) {
|
|
||||||
if (! price) {
|
|
||||||
price = new balance_t(*bal_pair.price);
|
|
||||||
price->negate();
|
|
||||||
} else {
|
|
||||||
*price -= *bal_pair.price;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
balance_pair_t& operator-=(const balance_t& bal) {
|
balance_pair_t& operator-=(const balance_t& bal) {
|
||||||
|
|
@ -648,15 +613,6 @@ class balance_pair_t
|
||||||
quantity *= bal_pair.quantity;
|
quantity *= bal_pair.quantity;
|
||||||
if (cost)
|
if (cost)
|
||||||
*cost *= bal_pair.cost ? *bal_pair.cost : bal_pair.quantity;
|
*cost *= bal_pair.cost ? *bal_pair.cost : bal_pair.quantity;
|
||||||
|
|
||||||
if (bal_pair.price && *bal_pair.price) {
|
|
||||||
if (price)
|
|
||||||
*price *= *bal_pair.price;
|
|
||||||
}
|
|
||||||
else if (price) {
|
|
||||||
delete price;
|
|
||||||
price = NULL;
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
balance_pair_t& operator*=(const balance_t& bal) {
|
balance_pair_t& operator*=(const balance_t& bal) {
|
||||||
|
|
@ -826,8 +782,7 @@ class balance_pair_t
|
||||||
// unary negation
|
// unary negation
|
||||||
void negate() {
|
void negate() {
|
||||||
quantity.negate();
|
quantity.negate();
|
||||||
if (price) price->negate();
|
if (cost) cost->negate();
|
||||||
if (cost) cost->negate();
|
|
||||||
}
|
}
|
||||||
balance_pair_t negated() const {
|
balance_pair_t negated() const {
|
||||||
balance_pair_t temp = *this;
|
balance_pair_t temp = *this;
|
||||||
|
|
@ -851,8 +806,7 @@ class balance_pair_t
|
||||||
|
|
||||||
void abs() {
|
void abs() {
|
||||||
quantity.abs();
|
quantity.abs();
|
||||||
if (price) price->abs();
|
if (cost) cost->abs();
|
||||||
if (cost) cost->abs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
amount_t amount(const commodity_t& commodity) const {
|
amount_t amount(const commodity_t& commodity) const {
|
||||||
|
|
@ -867,12 +821,10 @@ class balance_pair_t
|
||||||
}
|
}
|
||||||
|
|
||||||
balance_pair_t& add(const amount_t& amount,
|
balance_pair_t& add(const amount_t& amount,
|
||||||
const amount_t * a_price = NULL,
|
const amount_t * a_cost = NULL);
|
||||||
const amount_t * a_cost = NULL);
|
|
||||||
|
|
||||||
bool valid() {
|
bool valid() {
|
||||||
return (quantity.valid() &&
|
return quantity.valid() && (! cost || cost->valid());
|
||||||
(! price || price->valid()) && (! cost || cost->valid()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void round() {
|
void round() {
|
||||||
|
|
|
||||||
17
config.cc
17
config.cc
|
|
@ -780,9 +780,21 @@ OPT_BEGIN(actual, "L") {
|
||||||
} OPT_END(actual);
|
} OPT_END(actual);
|
||||||
|
|
||||||
OPT_BEGIN(lots, "") {
|
OPT_BEGIN(lots, "") {
|
||||||
show_lots = true;
|
keep_price = keep_date = keep_tag = true;
|
||||||
} OPT_END(lots);
|
} OPT_END(lots);
|
||||||
|
|
||||||
|
OPT_BEGIN(lot_prices, "") {
|
||||||
|
keep_price = true;
|
||||||
|
} OPT_END(lots_prices);
|
||||||
|
|
||||||
|
OPT_BEGIN(lot_dates, "") {
|
||||||
|
keep_date = true;
|
||||||
|
} OPT_END(lots_dates);
|
||||||
|
|
||||||
|
OPT_BEGIN(lot_tags, "") {
|
||||||
|
keep_tag = true;
|
||||||
|
} OPT_END(lots_tags);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Output customization
|
// Output customization
|
||||||
|
|
@ -1121,6 +1133,9 @@ option_t config_options[CONFIG_OPTIONS_SIZE] = {
|
||||||
{ "init-file", 'i', true, opt_init_file, false },
|
{ "init-file", 'i', true, opt_init_file, false },
|
||||||
{ "input-date-format", '\0', true, opt_input_date_format, false },
|
{ "input-date-format", '\0', true, opt_input_date_format, false },
|
||||||
{ "limit", 'l', true, opt_limit, false },
|
{ "limit", 'l', true, opt_limit, false },
|
||||||
|
{ "lot-dates", '\0', false, opt_lot_dates, false },
|
||||||
|
{ "lot-prices", '\0', false, opt_lot_prices, false },
|
||||||
|
{ "lot-tags", '\0', false, opt_lot_tags, false },
|
||||||
{ "lots", '\0', false, opt_lots, false },
|
{ "lots", '\0', false, opt_lots, false },
|
||||||
{ "market", 'V', false, opt_market, false },
|
{ "market", 'V', false, opt_market, false },
|
||||||
{ "monthly", 'M', false, opt_monthly, false },
|
{ "monthly", 'M', false, opt_monthly, false },
|
||||||
|
|
|
||||||
2
config.h
2
config.h
|
|
@ -99,7 +99,7 @@ class config_t
|
||||||
std::list<item_handler<transaction_t> *>& ptrs);
|
std::list<item_handler<transaction_t> *>& ptrs);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CONFIG_OPTIONS_SIZE 78
|
#define CONFIG_OPTIONS_SIZE 81
|
||||||
extern option_t config_options[CONFIG_OPTIONS_SIZE];
|
extern option_t config_options[CONFIG_OPTIONS_SIZE];
|
||||||
|
|
||||||
void option_help(std::ostream& out);
|
void option_help(std::ostream& out);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ std::auto_ptr<value_calc> total_expr;
|
||||||
std::auto_ptr<scope_t> global_scope;
|
std::auto_ptr<scope_t> global_scope;
|
||||||
std::time_t terminus;
|
std::time_t terminus;
|
||||||
|
|
||||||
|
bool keep_price = false;
|
||||||
|
bool keep_date = false;
|
||||||
|
bool keep_tag = false;
|
||||||
|
|
||||||
details_t::details_t(const transaction_t& _xact)
|
details_t::details_t(const transaction_t& _xact)
|
||||||
: entry(_xact.entry), xact(&_xact), account(xact_account(_xact))
|
: entry(_xact.entry), xact(&_xact), account(xact_account(_xact))
|
||||||
{
|
{
|
||||||
|
|
@ -643,6 +647,9 @@ void value_expr_t::compute(value_t& result, const details_t& details,
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! keep_price || ! keep_date || ! keep_tag)
|
||||||
|
result = result.reduce(keep_price, keep_date, keep_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void unexpected(char c, char wanted = '\0') {
|
static inline void unexpected(char c, char wanted = '\0') {
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,10 @@ extern std::auto_ptr<scope_t> global_scope;
|
||||||
extern std::time_t terminus;
|
extern std::time_t terminus;
|
||||||
extern bool initialized;
|
extern bool initialized;
|
||||||
|
|
||||||
|
extern bool keep_price;
|
||||||
|
extern bool keep_date;
|
||||||
|
extern bool keep_tag;
|
||||||
|
|
||||||
void init_value_expr();
|
void init_value_expr();
|
||||||
|
|
||||||
bool compute_amount(value_expr_t * expr, amount_t& amt,
|
bool compute_amount(value_expr_t * expr, amount_t& amt,
|
||||||
|
|
|
||||||
55
value.cc
55
value.cc
|
|
@ -728,16 +728,42 @@ value_t value_t::price() const
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
case AMOUNT:
|
|
||||||
case BALANCE:
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
case BALANCE_PAIR:
|
case AMOUNT:
|
||||||
if (((balance_pair_t *) data)->price)
|
return ((amount_t *) data)->price();
|
||||||
return *(((balance_pair_t *) data)->price);
|
|
||||||
else
|
|
||||||
return 0L;
|
|
||||||
|
|
||||||
|
case BALANCE:
|
||||||
|
return ((balance_t *) data)->price();
|
||||||
|
|
||||||
|
case BALANCE_PAIR:
|
||||||
|
return ((balance_pair_t *) data)->quantity.price();
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(0);
|
||||||
|
return value_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
value_t value_t::reduce(const bool keep_price, const bool keep_date,
|
||||||
|
const bool keep_tag) const
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case BOOLEAN:
|
||||||
|
case INTEGER:
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
case AMOUNT:
|
||||||
|
return ((amount_t *) data)->reduce_commodity(keep_price, keep_date,
|
||||||
|
keep_tag);
|
||||||
|
case BALANCE:
|
||||||
|
return ((balance_t *) data)->reduce(keep_price, keep_date, keep_tag);
|
||||||
|
|
||||||
|
case BALANCE_PAIR:
|
||||||
|
return ((balance_pair_t *) data)->quantity.reduce(keep_price, keep_date,
|
||||||
|
keep_tag);
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
|
@ -770,22 +796,21 @@ value_t value_t::cost() const
|
||||||
return value_t();
|
return value_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t& value_t::add(const amount_t& amount,
|
value_t& value_t::add(const amount_t& amount, const amount_t * cost)
|
||||||
const amount_t * price, const amount_t * cost)
|
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
if (price || cost) {
|
if (cost) {
|
||||||
cast(BALANCE_PAIR);
|
cast(BALANCE_PAIR);
|
||||||
return add(amount, price, cost);
|
return add(amount, cost);
|
||||||
}
|
}
|
||||||
else if ((type == AMOUNT &&
|
else if ((type == AMOUNT &&
|
||||||
((amount_t *) data)->commodity() != amount.commodity()) ||
|
((amount_t *) data)->commodity() != amount.commodity()) ||
|
||||||
(type != AMOUNT && amount.commodity())) {
|
(type != AMOUNT && amount.commodity())) {
|
||||||
cast(BALANCE);
|
cast(BALANCE);
|
||||||
return add(amount, price, cost);
|
return add(amount, cost);
|
||||||
}
|
}
|
||||||
else if (type != AMOUNT) {
|
else if (type != AMOUNT) {
|
||||||
cast(AMOUNT);
|
cast(AMOUNT);
|
||||||
|
|
@ -794,15 +819,15 @@ value_t& value_t::add(const amount_t& amount,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
if (price || cost) {
|
if (cost) {
|
||||||
cast(BALANCE_PAIR);
|
cast(BALANCE_PAIR);
|
||||||
return add(amount, price, cost);
|
return add(amount, cost);
|
||||||
}
|
}
|
||||||
*((balance_t *) data) += amount;
|
*((balance_t *) data) += amount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
((balance_pair_t *) data)->add(amount, price, cost);
|
((balance_pair_t *) data)->add(amount, cost);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
9
value.h
9
value.h
|
|
@ -145,7 +145,7 @@ class value_t
|
||||||
}
|
}
|
||||||
value_t& operator=(const balance_pair_t& value) {
|
value_t& operator=(const balance_pair_t& value) {
|
||||||
if ((balance_pair_t *) data != &value) {
|
if ((balance_pair_t *) data != &value) {
|
||||||
if (! value.price && ! value.cost) {
|
if (! value.cost) {
|
||||||
return *this = value.quantity;
|
return *this = value.quantity;
|
||||||
} else {
|
} else {
|
||||||
destroy();
|
destroy();
|
||||||
|
|
@ -267,9 +267,10 @@ class value_t
|
||||||
void cast(type_t cast_type);
|
void cast(type_t cast_type);
|
||||||
value_t cost() const;
|
value_t cost() const;
|
||||||
value_t price() const;
|
value_t price() const;
|
||||||
value_t& add(const amount_t& amount,
|
value_t reduce(const bool keep_price = false,
|
||||||
const amount_t * price = NULL,
|
const bool keep_date = false,
|
||||||
const amount_t * cost = NULL);
|
const bool keep_tag = false) const;
|
||||||
|
value_t& add(const amount_t& amount, const amount_t * cost = NULL);
|
||||||
|
|
||||||
value_t value(const std::time_t moment) const {
|
value_t value(const std::time_t moment) const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
|
||||||
4
walk.cc
4
walk.cc
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
bool show_lots = false;
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
bool compare_items<transaction_t>::operator()(const transaction_t * left,
|
bool compare_items<transaction_t>::operator()(const transaction_t * left,
|
||||||
const transaction_t * right)
|
const transaction_t * right)
|
||||||
|
|
@ -44,7 +42,7 @@ void add_transaction_to(const transaction_t& xact, value_t& value)
|
||||||
transaction_xdata_(xact).dflags & TRANSACTION_COMPOSITE) {
|
transaction_xdata_(xact).dflags & TRANSACTION_COMPOSITE) {
|
||||||
value += transaction_xdata_(xact).composite_amount;
|
value += transaction_xdata_(xact).composite_amount;
|
||||||
}
|
}
|
||||||
else if (xact.cost || xact.amount.commodity().annotated || value) {
|
else if (xact.cost || value) {
|
||||||
value.add(xact.amount, xact.cost);
|
value.add(xact.amount, xact.cost);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
2
walk.h
2
walk.h
|
|
@ -120,8 +120,6 @@ inline const account_t * xact_account(const transaction_t& xact) {
|
||||||
return xact_account(const_cast<transaction_t&>(xact));
|
return xact_account(const_cast<transaction_t&>(xact));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool show_lots;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline void walk_transactions(transactions_list::iterator begin,
|
inline void walk_transactions(transactions_list::iterator begin,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue