*** empty log message ***
This commit is contained in:
parent
c7e1cf34b3
commit
7ce12f8cfe
8 changed files with 184 additions and 150 deletions
2
Makefile
2
Makefile
|
|
@ -17,7 +17,7 @@ OBJS = $(patsubst %.cc,%.o,$(CODE))
|
||||||
|
|
||||||
CFLAGS = -Wall -ansi -pedantic
|
CFLAGS = -Wall -ansi -pedantic
|
||||||
#DFLAGS = -O3 -fomit-frame-pointer
|
#DFLAGS = -O3 -fomit-frame-pointer
|
||||||
DFLAGS = -g # -O2 # -pg
|
DFLAGS = -g -O2 # -pg
|
||||||
INCS = -I/usr/include/xmltok
|
INCS = -I/usr/include/xmltok
|
||||||
LIBS = -lgmpxx -lgmp -lpcre
|
LIBS = -lgmpxx -lgmp -lpcre
|
||||||
|
|
||||||
|
|
|
||||||
49
amount.cc
49
amount.cc
|
|
@ -59,13 +59,10 @@ class gmp_amount : public amount
|
||||||
|
|
||||||
virtual operator bool() const;
|
virtual operator bool() const;
|
||||||
|
|
||||||
virtual void credit(const amount * other) {
|
|
||||||
*this += *other;
|
|
||||||
}
|
|
||||||
virtual void negate() {
|
virtual void negate() {
|
||||||
mpz_ui_sub(quantity, 0, quantity);
|
mpz_ui_sub(quantity, 0, quantity);
|
||||||
}
|
}
|
||||||
virtual void operator+=(const amount& other);
|
virtual void credit(const amount * other);
|
||||||
|
|
||||||
virtual void parse(const char * num) {
|
virtual void parse(const char * num) {
|
||||||
*this = num;
|
*this = num;
|
||||||
|
|
@ -211,30 +208,32 @@ amount * gmp_amount::street() const
|
||||||
extern bool get_quotes;
|
extern bool get_quotes;
|
||||||
|
|
||||||
for (int cycles = 0; cycles < 10; cycles++) {
|
for (int cycles = 0; cycles < 10; cycles++) {
|
||||||
totals::iterator pi = main_ledger.prices.amounts.find(amt->comm_symbol());
|
totals::iterator pi =
|
||||||
|
main_ledger.prices.amounts.find(amt->comm_symbol());
|
||||||
if (pi == main_ledger.prices.amounts.end()) {
|
if (pi == main_ledger.prices.amounts.end()) {
|
||||||
if (get_quotes && amt->comm_symbol() != DEFAULT_COMMODITY) {
|
using namespace std;
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
char buf[256];
|
if (! get_quotes)
|
||||||
buf[0] = '\0';
|
break;
|
||||||
|
|
||||||
if (FILE * fp = popen((std::string("getquote ") +
|
char buf[256];
|
||||||
amt->comm_symbol()).c_str(), "r")) {
|
buf[0] = '\0';
|
||||||
if (feof(fp) || ! fgets(buf , 255, fp)) {
|
|
||||||
fclose(fp);
|
if (FILE * fp = popen((std::string("getquote ") +
|
||||||
break;
|
amt->comm_symbol()).c_str(), "r")) {
|
||||||
}
|
if (feof(fp) || ! fgets(buf , 255, fp)) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
if (buf[0]) {
|
if (buf[0]) {
|
||||||
char * p = strchr(buf, '\n');
|
char * p = strchr(buf, '\n');
|
||||||
if (p) *p = '\0';
|
if (p) *p = '\0';
|
||||||
|
|
||||||
main_ledger.record_price((amt->comm_symbol() + "=" + buf).c_str());
|
main_ledger.record_price((amt->comm_symbol() + "=" + buf).c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -598,11 +597,11 @@ amount& gmp_amount::operator=(const char * num)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gmp_amount::operator+=(const amount& _other)
|
void gmp_amount::credit(const amount * value)
|
||||||
{
|
{
|
||||||
const gmp_amount& other = dynamic_cast<const gmp_amount&>(_other);
|
const gmp_amount * val = dynamic_cast<const gmp_amount *>(value);
|
||||||
assert(quantity_comm == other.quantity_comm);
|
assert(quantity_comm == val->quantity_comm);
|
||||||
mpz_add(quantity, quantity, other.quantity);
|
mpz_add(quantity, quantity, val->quantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
13
balance.cc
13
balance.cc
|
|
@ -86,23 +86,12 @@ void report_balances(int argc, char **argv, std::ostream& out)
|
||||||
optind = 1;
|
optind = 1;
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
while (-1 != (c = getopt(argc, argv, "sSnFG:"))) {
|
while (-1 != (c = getopt(argc, argv, "sSnF"))) {
|
||||||
switch (char(c)) {
|
switch (char(c)) {
|
||||||
case 's': show_children = true; break;
|
case 's': show_children = true; break;
|
||||||
case 'S': show_empty = true; break;
|
case 'S': show_empty = true; break;
|
||||||
case 'n': no_subtotals = true; break;
|
case 'n': no_subtotals = true; break;
|
||||||
case 'F': full_names = true; break;
|
case 'F': full_names = true; break;
|
||||||
|
|
||||||
#ifdef HUQUQULLAH
|
|
||||||
case 'G': {
|
|
||||||
double gold = std::atof(optarg);
|
|
||||||
gold = 1 / gold;
|
|
||||||
char buf[256];
|
|
||||||
std::sprintf(buf, DEFAULT_COMMODITY "=%f troy", gold);
|
|
||||||
main_ledger.record_price(buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
25
ledger.cc
25
ledger.cc
|
|
@ -27,14 +27,20 @@ void entry::print(std::ostream& out, bool shortcut) const
|
||||||
|
|
||||||
if (shortcut &&
|
if (shortcut &&
|
||||||
(xacts.size() != 2 ||
|
(xacts.size() != 2 ||
|
||||||
xacts.front()->cost->comm() != xacts.back()->cost->comm())) {
|
xacts.front()->cost->comm() != xacts.back()->cost->comm()))
|
||||||
shortcut = false;
|
shortcut = false;
|
||||||
}
|
|
||||||
|
|
||||||
for (std::list<transaction *>::const_iterator x = xacts.begin();
|
for (std::list<transaction *>::const_iterator x = xacts.begin();
|
||||||
x != xacts.end();
|
x != xacts.end();
|
||||||
x++) {
|
x++) {
|
||||||
out << " ";
|
#ifdef HUQUQULLAH
|
||||||
|
if ((*x)->acct->exempt_or_necessary &&
|
||||||
|
(! shortcut || ! ledger::matches(main_ledger.huquq_categories,
|
||||||
|
(*x)->acct->as_str())))
|
||||||
|
out << " !";
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
out << " ";
|
||||||
|
|
||||||
out.width(30);
|
out.width(30);
|
||||||
out << std::left << (*x)->acct->as_str();
|
out << std::left << (*x)->acct->as_str();
|
||||||
|
|
@ -134,19 +140,6 @@ void totals::print(std::ostream& out, int width) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
amount * totals::value(const std::string& commodity) const
|
|
||||||
{
|
|
||||||
// Render all of the amounts into the given commodity. This
|
|
||||||
// requires known prices for each commodity.
|
|
||||||
|
|
||||||
amount * total = create_amount((commodity + " 0.00").c_str());
|
|
||||||
|
|
||||||
for (const_iterator i = amounts.begin(); i != amounts.end(); i++)
|
|
||||||
*total += *((*i).second);
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print out the entire ledger that was read in, sorted by date.
|
// Print out the entire ledger that was read in, sorted by date.
|
||||||
// This can be used to "wash" ugly ledger files.
|
// This can be used to "wash" ugly ledger files.
|
||||||
|
|
||||||
|
|
|
||||||
8
ledger.h
8
ledger.h
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef _LEDGER_H
|
#ifndef _LEDGER_H
|
||||||
#define _LEDGER_H "$Revision: 1.13 $"
|
#define _LEDGER_H "$Revision: 1.14 $"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|
@ -104,8 +104,8 @@ struct commodity
|
||||||
|
|
||||||
commodity() : prefix(false), separate(true),
|
commodity() : prefix(false), separate(true),
|
||||||
thousands(false), european(false) {}
|
thousands(false), european(false) {}
|
||||||
commodity(const std::string& sym, bool pre, bool sep,
|
commodity(const std::string& sym, bool pre = false, bool sep = true,
|
||||||
bool thou, bool euro, int prec);
|
bool thou = true, bool euro = false, int prec = 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<const std::string, commodity *> commodities_t;
|
typedef std::map<const std::string, commodity *> commodities_t;
|
||||||
|
|
@ -135,7 +135,6 @@ class amount
|
||||||
|
|
||||||
virtual void credit(const amount * other) = 0;
|
virtual void credit(const amount * other) = 0;
|
||||||
virtual void negate() = 0;
|
virtual void negate() = 0;
|
||||||
virtual void operator+=(const amount& other) = 0;
|
|
||||||
|
|
||||||
// String conversion routines
|
// String conversion routines
|
||||||
|
|
||||||
|
|
@ -263,7 +262,6 @@ struct totals
|
||||||
void print(std::ostream& out, int width) const;
|
void print(std::ostream& out, int width) const;
|
||||||
|
|
||||||
// Returns an allocated entity
|
// Returns an allocated entity
|
||||||
amount * value(const std::string& comm) const;
|
|
||||||
amount * sum(const std::string& comm) {
|
amount * sum(const std::string& comm) {
|
||||||
return amounts[comm];
|
return amounts[comm];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
43
ledger.texi
43
ledger.texi
|
|
@ -1,5 +1,5 @@
|
||||||
\input texinfo @c -*-texinfo-*-
|
\input texinfo @c -*-texinfo-*-
|
||||||
@comment $Id: ledger.texi,v 1.4 2003/10/01 04:42:13 johnw Exp $
|
@comment $Id: ledger.texi,v 1.5 2003/10/01 21:55:40 johnw Exp $
|
||||||
@comment %**start of header
|
@comment %**start of header
|
||||||
|
|
||||||
@setfilename ledger.info
|
@setfilename ledger.info
|
||||||
|
|
@ -287,6 +287,47 @@ Euro=DM 0.75
|
||||||
This is a roundabout way of reporting AAPL shares in their Deutsch
|
This is a roundabout way of reporting AAPL shares in their Deutsch
|
||||||
Mark equivalent.
|
Mark equivalent.
|
||||||
|
|
||||||
|
@section Accounts and Inventories
|
||||||
|
|
||||||
|
Since @code{ledger}'s accounts and commodity system is so flexible,
|
||||||
|
you can have accounts that don't really exist, and use commodities
|
||||||
|
that no one else recognizes. For example, let's say you are buying
|
||||||
|
and selling various items in EverQuest, and want to keep track of them
|
||||||
|
using a ledger. Just add items of whatever quantity you wish into
|
||||||
|
your EverQuest account:
|
||||||
|
|
||||||
|
@example
|
||||||
|
9/29 Get some stuff at the Inn
|
||||||
|
Places:Black's Tavern -3 Apples
|
||||||
|
Places:Black's Tavern -5 Steaks
|
||||||
|
EverQuest:Inventory
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Now your EverQuest:Inventory has 3 apples and 5 steaks in it. The
|
||||||
|
amounts are negative, because you are taking @emph{from} Black's
|
||||||
|
Tavern in order to credit your Inventory account. Note that you don't
|
||||||
|
have to use ``Places:Black's Tavern'' as the source account. You
|
||||||
|
could use ``EverQuest:System'' to represent the fact that you acquired
|
||||||
|
them online. The only purpose for choosing one kind of source account
|
||||||
|
over another is for generate more informative reports later on. The
|
||||||
|
more you know, the better analysis you can perform.
|
||||||
|
|
||||||
|
If you later sell some of these items to another player, the entry
|
||||||
|
would look like:
|
||||||
|
|
||||||
|
@example
|
||||||
|
10/2 Sturm Brightblade
|
||||||
|
EverQuest:Inventory -2 Steaks
|
||||||
|
EverQuest:Inventory 15 Gold
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Now you've turned 2 steaks into 15 gold, courtesy of your customer,
|
||||||
|
Sturm Brightblade.
|
||||||
|
|
||||||
|
Note that if you're playing on a system where ``Gold'' is the standard
|
||||||
|
currency, you should use the @samp{-D} flag to tell @code{ledger} that
|
||||||
|
that is the default commodity.
|
||||||
|
|
||||||
@chapter Using @code{ledger}
|
@chapter Using @code{ledger}
|
||||||
|
|
||||||
@chapter Computing Huqúqu'lláh
|
@chapter Computing Huqúqu'lláh
|
||||||
|
|
|
||||||
22
main.cc
22
main.cc
|
|
@ -112,11 +112,6 @@ static bool parse_date(const char * date_str, std::time_t * result)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Global defaults
|
|
||||||
|
|
||||||
commodity * usd = new commodity("$", true, false, true, false, 2);
|
|
||||||
main_ledger.commodities.insert(commodities_entry("USD", usd));
|
|
||||||
|
|
||||||
// Parse the command-line options
|
// Parse the command-line options
|
||||||
|
|
||||||
std::istream * file = NULL;
|
std::istream * file = NULL;
|
||||||
|
|
@ -129,7 +124,7 @@ int main(int argc, char *argv[])
|
||||||
show_cleared = false;
|
show_cleared = false;
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
while (-1 != (c = getopt(argc, argv, "+b:e:d:cChHwf:i:p:P"))) {
|
while (-1 != (c = getopt(argc, argv, "+b:e:d:D:cChHwf:i:p:P"))) {
|
||||||
switch (char(c)) {
|
switch (char(c)) {
|
||||||
case 'b':
|
case 'b':
|
||||||
case 'e': {
|
case 'e': {
|
||||||
|
|
@ -288,24 +283,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (compute_huquq) {
|
if (compute_huquq) {
|
||||||
main_ledger.compute_huquq = true;
|
main_ledger.compute_huquq = true;
|
||||||
main_ledger.huquq_commodity = new commodity("H", true, true,
|
|
||||||
true, false, 2);
|
|
||||||
|
|
||||||
// The allocation causes it to be inserted into the
|
|
||||||
// main_ledger.commodities mapping.
|
|
||||||
new commodity("mithqal", false, true, true, false, 1);
|
|
||||||
|
|
||||||
read_regexps(".huquq", main_ledger.huquq_categories);
|
read_regexps(".huquq", main_ledger.huquq_categories);
|
||||||
|
|
||||||
main_ledger.record_price("H=" DEFAULT_COMMODITY "0.19");
|
|
||||||
|
|
||||||
bool save_use_warnings = use_warnings;
|
|
||||||
use_warnings = false;
|
|
||||||
main_ledger.record_price("troy=8.5410148523 mithqal");
|
|
||||||
use_warnings = save_use_warnings;
|
|
||||||
|
|
||||||
main_ledger.huquq = create_amount("H 1.00");
|
|
||||||
|
|
||||||
main_ledger.huquq_account = main_ledger.find_account("Huququ'llah");
|
main_ledger.huquq_account = main_ledger.find_account("Huququ'llah");
|
||||||
main_ledger.huquq_expenses_account =
|
main_ledger.huquq_expenses_account =
|
||||||
main_ledger.find_account("Expenses:Huququ'llah");
|
main_ledger.find_account("Expenses:Huququ'llah");
|
||||||
|
|
|
||||||
172
parse.cc
172
parse.cc
|
|
@ -36,49 +36,119 @@ static void finalize_entry(entry * curr, bool compute_balances)
|
||||||
{
|
{
|
||||||
assert(curr);
|
assert(curr);
|
||||||
|
|
||||||
// Certain shorcuts are allowed in the case of exactly two
|
// If there were no transactions, it's definitely an error!
|
||||||
// transactions.
|
|
||||||
|
|
||||||
if (! curr->xacts.empty() && curr->xacts.size() == 2) {
|
if (curr->xacts.empty()) {
|
||||||
transaction * first = curr->xacts.front();
|
std::cerr << "Error, line " << (linenum - 1)
|
||||||
transaction * second = curr->xacts.back();
|
<< ": Entry has no transactions!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If one transaction gives no value at all, then its value is
|
// Scan through and compute the total balance for the entry.
|
||||||
// the inverse of the computed value of the other.
|
|
||||||
|
|
||||||
if (! first->cost && second->cost) {
|
totals balance;
|
||||||
first->cost = second->cost->value();
|
|
||||||
first->cost->negate();
|
|
||||||
|
|
||||||
if (compute_balances)
|
for (std::list<transaction *>::iterator x = curr->xacts.begin();
|
||||||
first->acct->balance.credit(first->cost);
|
x != curr->xacts.end();
|
||||||
}
|
x++)
|
||||||
else if (! second->cost && first->cost) {
|
if ((*x)->cost)
|
||||||
second->cost = first->cost->value();
|
balance.credit((*x)->cost->value());
|
||||||
second->cost->negate();
|
|
||||||
|
|
||||||
if (compute_balances)
|
// If one transaction is of a different commodity than the others,
|
||||||
second->acct->balance.credit(second->cost);
|
// and it has no per-unit price, determine its price by dividing
|
||||||
}
|
// the unit count into the value of the balance.
|
||||||
else if (first->cost && second->cost) {
|
//
|
||||||
// If one transaction is of a different commodity than the
|
// NOTE: We don't do this for prefix-style or joined-symbol
|
||||||
// other, and it has no per-unit price, and its not of the
|
// commodities. Also, do it for the last eligible commodity first,
|
||||||
// default commodity, then determine its price by dividing the
|
// if it meets the criteria.
|
||||||
// unit count into the total, to balance the transaction.
|
|
||||||
|
|
||||||
if (first->cost->comm() != second->cost->comm()) {
|
if (! balance.amounts.empty() && balance.amounts.size() == 2) {
|
||||||
if (! second->cost->has_price() &&
|
for (std::list<transaction *>::iterator x = curr->xacts.begin();
|
||||||
second->cost->comm_symbol() != DEFAULT_COMMODITY) {
|
x != curr->xacts.end();
|
||||||
second->cost->set_value(first->cost);
|
x++) {
|
||||||
}
|
if (! (*x)->cost->has_price() &&
|
||||||
else if (! first->cost->has_price() &&
|
! (*x)->cost->comm()->prefix &&
|
||||||
first->cost->comm_symbol() != DEFAULT_COMMODITY) {
|
(*x)->cost->comm()->separate) {
|
||||||
first->cost->set_value(second->cost);
|
for (totals::iterator i = balance.amounts.begin();
|
||||||
|
i != balance.amounts.end();
|
||||||
|
i++) {
|
||||||
|
if ((*i).second->comm() != (*x)->cost->comm()) {
|
||||||
|
(*x)->cost->set_value((*i).second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Walk through each of the transactions, fixing up any that we
|
||||||
|
// can, and performing any on-the-fly calculations.
|
||||||
|
|
||||||
|
bool empty_allowed = true;
|
||||||
|
|
||||||
|
for (std::list<transaction *>::iterator x = curr->xacts.begin();
|
||||||
|
x != curr->xacts.end();
|
||||||
|
x++) {
|
||||||
|
if (! (*x)->cost) {
|
||||||
|
if (empty_allowed && ! balance.amounts.empty() &&
|
||||||
|
balance.amounts.size() == 1) {
|
||||||
|
empty_allowed = false;
|
||||||
|
|
||||||
|
// If one transaction gives no value at all -- and all the
|
||||||
|
// rest are of the same commodity -- then its value is the
|
||||||
|
// inverse of the computed value of the others.
|
||||||
|
|
||||||
|
totals::iterator i = balance.amounts.begin();
|
||||||
|
(*x)->cost = (*i).second->value();
|
||||||
|
(*x)->cost->negate();
|
||||||
|
|
||||||
|
if (compute_balances)
|
||||||
|
(*x)->acct->balance.credit((*x)->cost);
|
||||||
|
} else {
|
||||||
|
std::cerr << "Error, line " << (linenum - 1)
|
||||||
|
<< ": Transaction entry is lacking an amount."
|
||||||
|
<< std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HUQUQULLAH
|
||||||
|
if (! main_ledger.compute_huquq || ! (*x)->exempt_or_necessary)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Reflect 19% of the exempt or necessary transaction in the
|
||||||
|
// Huququ'llah account.
|
||||||
|
|
||||||
|
amount * divisor = create_amount("0.19");
|
||||||
|
amount * temp = (*x)->cost->value();
|
||||||
|
|
||||||
|
transaction * t = new transaction(main_ledger.huquq_account,
|
||||||
|
temp->value(divisor));
|
||||||
|
curr->xacts.push_back(t);
|
||||||
|
|
||||||
|
if (compute_balances)
|
||||||
|
t->acct->balance.credit(t->cost);
|
||||||
|
|
||||||
|
// Balance the above transaction by recording the inverse in
|
||||||
|
// Expenses:Huququ'llah.
|
||||||
|
|
||||||
|
t = new transaction(main_ledger.huquq_expenses_account,
|
||||||
|
temp->value(divisor));
|
||||||
|
t->cost->negate();
|
||||||
|
curr->xacts.push_back(t);
|
||||||
|
|
||||||
|
if (compute_balances)
|
||||||
|
t->acct->balance.credit(t->cost);
|
||||||
|
|
||||||
|
delete temp;
|
||||||
|
delete divisor;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the balances again, just to make sure it all comes out
|
||||||
|
// right (i.e., to zero for every commodity).
|
||||||
|
|
||||||
if (! curr->validate()) {
|
if (! curr->validate()) {
|
||||||
std::cerr << "Error, line " << (linenum - 1)
|
std::cerr << "Error, line " << (linenum - 1)
|
||||||
<< ": Failed to balance the following transaction:"
|
<< ": Failed to balance the following transaction:"
|
||||||
|
|
@ -88,43 +158,7 @@ static void finalize_entry(entry * curr, bool compute_balances)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HUQUQULLAH
|
// If it's OK, add it to the general ledger's list of entries.
|
||||||
if (main_ledger.compute_huquq) {
|
|
||||||
for (std::list<transaction *>::iterator x = curr->xacts.begin();
|
|
||||||
x != curr->xacts.end();
|
|
||||||
x++) {
|
|
||||||
if (! (*x)->exempt_or_necessary || ! (*x)->cost)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Reflect the exempt or necessary transaction in the
|
|
||||||
// Huququ'llah account, using the H commodity, which is 19% of
|
|
||||||
// whichever DEFAULT_COMMODITY ledger was compiled with.
|
|
||||||
|
|
||||||
amount * temp = (*x)->cost->value();
|
|
||||||
|
|
||||||
transaction * t
|
|
||||||
= new transaction(main_ledger.huquq_account,
|
|
||||||
temp->value(main_ledger.huquq));
|
|
||||||
curr->xacts.push_back(t);
|
|
||||||
|
|
||||||
if (compute_balances)
|
|
||||||
t->acct->balance.credit(t->cost);
|
|
||||||
|
|
||||||
// Balance the above transaction by recording the inverse in
|
|
||||||
// Expenses:Huququ'llah.
|
|
||||||
|
|
||||||
t = new transaction(main_ledger.huquq_expenses_account,
|
|
||||||
temp->value(main_ledger.huquq));
|
|
||||||
t->cost->negate();
|
|
||||||
curr->xacts.push_back(t);
|
|
||||||
|
|
||||||
if (compute_balances)
|
|
||||||
t->acct->balance.credit(t->cost);
|
|
||||||
|
|
||||||
delete temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
main_ledger.entries.push_back(curr);
|
main_ledger.entries.push_back(curr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue