*** empty log message ***

This commit is contained in:
John Wiegley 2003-10-01 04:42:13 +00:00
parent 16cb024a82
commit f93341edfc
10 changed files with 151 additions and 48 deletions

View file

@ -2,7 +2,8 @@ define GNUCASH
true
endef
CODE = amount.cc ledger.cc parse.cc balance.cc register.cc main.cc
CODE = amount.cc ledger.cc parse.cc \
balance.cc register.cc equity.cc main.cc
ifdef GNUCASH
CODE := $(CODE) gnucash.cc
endif

View file

@ -51,6 +51,7 @@ class gmp_amount : public amount
virtual amount * copy() const;
virtual amount * value(amount *) const;
virtual amount * street() const;
virtual operator bool() const;
@ -216,6 +217,25 @@ amount * gmp_amount::value(amount * pr) const
}
}
amount * gmp_amount::street() const
{
amount * cost = NULL;
const amount * amt = this;
for (int cycles = 0; cycles < 10; cycles++) {
totals::iterator pi = main_ledger.prices.amounts.find(amt->comm_symbol());
if (pi == main_ledger.prices.amounts.end()) {
break;
} else {
amount * temp = cost;
amt = cost = amt->value((*pi).second);
if (temp)
delete temp;
}
}
return cost ? cost : copy();
}
gmp_amount::operator bool() const
{
mpz_t copy;

View file

@ -151,26 +151,7 @@ void report_balances(int argc, char **argv, std::ostream& out)
if (! do_credit)
continue;
amount * cost = (*x)->cost;
bool allocated = false;
for (int cycles = 0; cost && cycles < 10; cycles++) {
std::map<const std::string, amount *>::iterator pi
= main_ledger.prices.amounts.find(cost->comm_symbol());
if (pi == main_ledger.prices.amounts.end()) {
balance->credit(cost);
if (allocated)
delete cost;
break;
} else {
amount * temp = cost;
cost = temp->value((*pi).second);
if (allocated)
delete temp;
allocated = true;
}
}
balance->credit((*x)->cost->street());
}
}
}

73
equity.cc Normal file
View file

@ -0,0 +1,73 @@
#include "ledger.h"
namespace ledger {
static void equity_entry(std::ostream& out, const account * acct,
const std::list<mask>& regexps)
{
if (acct->balance &&
(regexps.empty() || matches(regexps, acct->as_str()))) {
entry opening;
opening.date = std::time(NULL);
opening.cleared = true;
opening.desc = "Opening Balance";
transaction * xact;
for (totals::const_iterator i = acct->balance.amounts.begin();
i != acct->balance.amounts.end();
i++) {
if (! *((*i).second)) // skip if zero balance for the commodity
continue;
xact = new transaction();
xact->acct = const_cast<account *>(acct);
xact->cost = (*i).second->street();
opening.xacts.push_back(xact);
xact = new transaction();
xact->acct = main_ledger.find_account("Equity:Opening Balances");
xact->cost = (*i).second->street();
xact->cost->negate();
opening.xacts.push_back(xact);
}
opening.print(out);
}
// Display balances for all child accounts
for (account::const_iterator i = acct->children.begin();
i != acct->children.end();
i++)
equity_entry(out, (*i).second, regexps);
}
//////////////////////////////////////////////////////////////////////
//
// Create an Equity file based on a ledger. This is used for
// archiving past years, and starting out a new year with compiled
// balances.
//
void equity_ledger(int argc, char **argv, std::ostream& out)
{
optind = 1;
// Compile the list of specified regular expressions, which can be
// specified on the command line, or using an include/exclude file
for (; optind < argc; optind++)
record_regexp(argv[optind], regexps);
// The account have their current totals already generated as a
// result of parsing. We just have to output those values.
// totals
for (accounts_iterator i = main_ledger.accounts.begin();
i != main_ledger.accounts.end();
i++)
equity_entry(out, (*i).second, regexps);
}
} // namespace ledger

View file

@ -133,14 +133,14 @@ void totals::print(std::ostream& out, int width) const
}
}
amount * totals::value(const std::string& commodity)
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 (iterator i = amounts.begin(); i != amounts.end(); i++)
for (const_iterator i = amounts.begin(); i != amounts.end(); i++)
*total += *((*i).second);
return total;

View file

@ -1,5 +1,5 @@
#ifndef _LEDGER_H
#define _LEDGER_H "$Revision: 1.8 $"
#define _LEDGER_H "$Revision: 1.9 $"
//////////////////////////////////////////////////////////////////////
//
@ -117,6 +117,7 @@ class amount
virtual const std::string& comm_symbol() const = 0;
virtual amount * copy() const = 0;
virtual amount * value(amount * pr = NULL) const = 0;
virtual amount * street() const = 0;
// Test if non-zero
@ -235,7 +236,7 @@ struct totals
void print(std::ostream& out, int width) const;
// Returns an allocated entity
amount * value(const std::string& comm);
amount * value(const std::string& comm) const;
amount * sum(const std::string& comm) {
return amounts[comm];
}

View file

@ -1,5 +1,5 @@
\input texinfo @c -*-texinfo-*-
@comment $Id: ledger.texi,v 1.3 2003/09/30 23:17:18 johnw Exp $
@comment $Id: ledger.texi,v 1.4 2003/10/01 04:42:13 johnw Exp $
@comment %**start of header
@setfilename ledger.info
@ -274,7 +274,7 @@ currently $357 per ounce, then each dollar is worth 1/357 AU:
$5000 would buy 14 ounces of gold, which becomes the new display
commodity since a conversion factor was provided.
Commodities conversions can also be chained, up to a depth of 15.
Commodities conversions can also be chained, up to a depth of 10.
Here is a sample prices database that uses chaining:
@example

53
main.cc
View file

@ -9,6 +9,7 @@ namespace ledger {
extern void report_balances(int argc, char **argv, std::ostream& out);
extern void print_register(int argc, char **argv, std::ostream& out);
extern void print_ledger(int argc, char *argv[], std::ostream& out);
extern void equity_ledger(int argc, char **argv, std::ostream& out);
bool show_cleared;
@ -39,6 +40,11 @@ void show_help(std::ostream& out)
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
std::istream * file = NULL;
@ -114,18 +120,34 @@ int main(int argc, char *argv[])
}
if (optind == argc) {
std::cerr << "usage: ledger [options] COMMAND [options] [ARGS]" << std::endl
<< std::endl
<< "ledger options:" << std::endl
<< " -f FILE specify pathname of ledger data file" << std::endl
<< std::endl
<< "commands:" << std::endl
<< " balance show balance totals" << std::endl
<< " print print all ledger entries" << std::endl
<< std::endl
<< "`balance' command options:" << std::endl
<< " -s show sub-accounts in balance totals" << std::endl
<< " -S show empty accounts in balance totals" << std::endl;
std::cerr
<< "usage: ledger [options] COMMAND [options] [REGEXPS]" << std::endl
<< std::endl
<< "ledger options:" << std::endl
<< " -C also show cleared transactions" << std::endl
<< " -b DATE specify a beginning date" << std::endl
<< " -c do not show future entries (same as -e TODAY)" << std::endl
<< " -e DATE specify an ending date" << std::endl
<< " -f FILE specify pathname of ledger data file" << std::endl
<< " -h display this help text" << std::endl
#ifdef HUQUQULLAH
<< " -H do not auto-compute Huququ'llah" << std::endl
#endif
<< " -i FILE read the list of inclusion regexps from FILE" << std::endl
<< " -p FILE read the list of prices from FILE" << std::endl
<< " -w print out warnings where applicable" << std::endl
<< std::endl
<< "commands:" << std::endl
<< " balance show balance totals" << std::endl
<< " register display a register for ACCOUNT" << std::endl
<< " print print all ledger entries" << std::endl
<< " equity generate equity ledger for all entries" << std::endl
<< std::endl
<< "`balance' options:" << std::endl
<< " -F print each account's full name" << std::endl
<< " -n do not generate totals for parent accounts" << std::endl
<< " -s show sub-accounts in balance totals" << std::endl
<< " -S show empty accounts in balance totals" << std::endl;
return 1;
}
@ -137,11 +159,6 @@ int main(int argc, char *argv[])
return 1;
}
// Global defaults
commodity * usd = new commodity("$", true, false, true, false, 2);
main_ledger.commodities.insert(commodities_entry("USD", usd));
// Read the command word
const std::string command = argv[optind];
@ -182,6 +199,8 @@ int main(int argc, char *argv[])
print_register(argc - optind, &argv[optind], std::cout);
else if (command == "print")
print_ledger(argc - optind, &argv[optind], std::cout);
else if (command == "equity")
equity_ledger(argc - optind, &argv[optind], std::cout);
}
// main.cc ends here.

View file

@ -185,14 +185,14 @@ bool parse_ledger(std::istream& in)
}
#ifdef HUQUQULLAH
bool exempt = false;
bool exempt_or_necessary = false;
if (compute_huquq) {
if (*p == '!') {
exempt = true;
exempt_or_necessary = true;
p++;
}
else if (matches(huquq_categories, p)) {
exempt = true;
exempt_or_necessary = true;
}
}
#endif
@ -203,23 +203,30 @@ bool parse_ledger(std::istream& in)
curr->xacts.push_back(xact);
#ifdef HUQUQULLAH
if (exempt) {
if (exempt_or_necessary) {
static amount * huquq = create_amount("H 1.00");
amount * temp;
// 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.
transaction * t = new transaction();
t->acct = main_ledger.find_account("Huququ'llah");
temp = xact->cost->value();
t->cost = temp->value(huquq);
delete temp;
t->acct->balance.credit(t->cost);
curr->xacts.push_back(t);
// Balance the above transaction by recording the inverse in
// Expenses:Huququ'llah.
t = new transaction();
t->acct = main_ledger.find_account("Expenses:Huququ'llah");
temp = xact->cost->value();
t->cost = temp->value(huquq);
delete temp;
t->cost->negate();
t->acct->balance.credit(t->cost);
curr->xacts.push_back(t);
}
#endif

1
report
View file

@ -16,4 +16,5 @@ case "$command" in
health supplies -insurance -vacation ;;
huquq) $line "$@" balance ^huquq ;;
gold) $line "$@" balance -G $1 ^huquq ;;
equity) $line "$@" equity -- -^Income -^Expenses -^Equity ;;
esac