*** empty log message ***
This commit is contained in:
parent
16cb024a82
commit
f93341edfc
10 changed files with 151 additions and 48 deletions
3
Makefile
3
Makefile
|
|
@ -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
|
||||
|
|
|
|||
20
amount.cc
20
amount.cc
|
|
@ -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;
|
||||
|
|
|
|||
21
balance.cc
21
balance.cc
|
|
@ -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
73
equity.cc
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
5
ledger.h
5
ledger.h
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
53
main.cc
|
|
@ -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.
|
||||
|
|
|
|||
15
parse.cc
15
parse.cc
|
|
@ -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
1
report
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue