111#define BUDGET_NO_BUDGET 0x00
112#define BUDGET_BUDGETED 0x01
113#define BUDGET_UNBUDGETED 0x02
114#define BUDGET_WRAP_VALUES 0x04
142 return _(
"current report");
245 HANDLER(abbrev_len_).report(out);
248 HANDLER(add_budget).report(out);
249 HANDLER(align_intervals).report(out);
251 HANDLER(amount_data).report(out);
253 HANDLER(auto_match).report(out);
256 HANDLER(balance_format_).report(out);
261 HANDLER(budget_format_).report(out);
264 HANDLER(cleared_format_).report(out);
267 HANDLER(collapse_if_zero).report(out);
269 HANDLER(csv_format_).report(out);
273 HANDLER(date_format_).report(out);
274 HANDLER(datetime_format_).report(out);
277 HANDLER(deviation).report(out);
279 HANDLER(display_amount_).report(out);
280 HANDLER(display_total_).report(out);
286 HANDLER(exchange_).report(out);
288 HANDLER(force_color).report(out);
289 HANDLER(force_pager).report(out);
290 HANDLER(forecast_while_).report(out);
291 HANDLER(forecast_years_).report(out);
294 HANDLER(generated).report(out);
295 HANDLER(group_by_).report(out);
296 HANDLER(group_title_format_).report(out);
298 HANDLER(immediate).report(out);
302 HANDLER(lisp_date_format_).report(out);
303 HANDLER(lot_dates).report(out);
304 HANDLER(lot_prices).report(out);
306 HANDLER(lot_notes).report(out);
308 HANDLER(lots_actual).report(out);
313 HANDLER(no_rounding).report(out);
314 HANDLER(no_titles).report(out);
325 HANDLER(plot_amount_format_).report(out);
326 HANDLER(plot_total_format_).report(out);
327 HANDLER(prepend_format_).report(out);
328 HANDLER(prepend_width_).report(out);
330 HANDLER(prices_format_).report(out);
331 HANDLER(pricedb_format_).report(out);
332 HANDLER(primary_date).report(out);
334 HANDLER(quarterly).report(out);
337 HANDLER(register_format_).report(out);
339 HANDLER(related_all).report(out);
341 HANDLER(revalued_only).report(out);
342 HANDLER(revalued_total_).report(out);
343 HANDLER(rich_data).report(out);
346 HANDLER(sort_all_).report(out);
347 HANDLER(sort_xacts_).report(out);
348 HANDLER(start_of_week_).report(out);
351 HANDLER(time_report).report(out);
353 HANDLER(total_data).report(out);
354 HANDLER(truncate_).report(out);
355 HANDLER(unbudgeted).report(out);
356 HANDLER(uncleared).report(out);
357 HANDLER(unrealized).report(out);
358 HANDLER(unrealized_gains_).report(out);
359 HANDLER(unrealized_losses_).report(out);
364 HANDLER(meta_width_).report(out);
365 HANDLER(date_width_).report(out);
366 HANDLER(payee_width_).report(out);
367 HANDLER(account_width_).report(out);
368 HANDLER(amount_width_).report(out);
369 HANDLER(total_width_).report(out);
386 (report_t, abbrev_len_,
387 CTOR(report_t, abbrev_len_) {
394 OTHER(limit_).on(whence,
"actual");
415 OTHER(empty).on(whence);
416 OTHER(display_total_)
417 .on(whence,
"count>0?(display_total/count):0");
421 (report_t, balance_format_,
422 CTOR(report_t, balance_format_) {
425 " justify(scrub(display_total), max(int(amount_width),20),"
426 " max(int(amount_width),20) + int(prepend_width), true, color),"
427 " bold if should_bold))"
428 " %(!options.flat ? depth_spacer : \"\")"
430 " ansify_if(partial_account(options.flat), blue if color),"
431 " bold if should_bold))\n%/"
433 "%(prepend_width ? \" \" * int(prepend_width) : \"\")"
434 "%(\"-\" * max(int(amount_width),20))\n");
440 OTHER(revalued).on(whence);
441 OTHER(amount_).expr.set_base_expr(
"rounded(cost)");
446 if (optional<date_t> begin = interval.
begin()) {
447 string predicate =
"date>=[" + to_iso_extended_string(*begin) +
"]";
448 OTHER(limit_).on(whence, predicate);
450 throw_(std::invalid_argument,
451 _f(
"Could not determine beginning of period '%1%'") % str);
467 (report_t, budget_format_,
468 CTOR(report_t, budget_format_) {
470 "%(justify(scrub(get_at(display_total, 0)), int(amount_width), -1, true, color))"
471 " %(justify(-scrub(get_at(display_total, 1)), int(amount_width), "
472 " int(amount_width) + 1 + int(amount_width), true, color))"
473 " %(justify(scrub((get_at(display_total, 1) || 0) + "
474 " (get_at(display_total, 0) || 0)), int(amount_width), "
475 " int(amount_width) + 1 + int(amount_width) + 1 + int(amount_width), true, color))"
477 " justify((get_at(display_total, 1) ? "
478 " (100% * quantity(scrub(get_at(display_total, 0)))) / "
479 " -quantity(scrub(get_at(display_total, 1))) : 0), "
480 " 5, -1, true, false),"
481 " magenta if (color and get_at(display_total, 1) and "
482 " (abs(quantity(scrub(get_at(display_total, 0))) / "
483 " quantity(scrub(get_at(display_total, 1)))) >= 1))))"
484 " %(!options.flat ? depth_spacer : \"\")"
485 "%-(ansify_if(partial_account(options.flat), blue if color))\n"
486 "%/%$1 %$2 %$3 %$4\n%/"
487 "%(prepend_width ? \" \" * int(prepend_width) : \"\")"
488 "------------ ------------ ------------ -----\n");
494 OTHER(limit_).on(whence,
"cleared");
498 (report_t, cleared_format_,
499 CTOR(report_t, cleared_format_) {
501 "%(justify(scrub(get_at(display_total, 0)), 16, 16 + int(prepend_width), "
502 " true, color)) %(justify(scrub(get_at(display_total, 1)), 18, "
503 " 36 + int(prepend_width), true, color))"
504 " %(latest_cleared ? format_date(latest_cleared) : \" \")"
505 " %(!options.flat ? depth_spacer : \"\")"
506 "%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
508 "%(prepend_width ? \" \" * int(prepend_width) : \"\")"
509 "---------------- ---------------- ---------\n");
517 OTHER(display_).on(whence,
"post|depth<=1");
520 OPTION_(report_t, collapse_if_zero,
DO() {
521 OTHER(collapse).on(whence);
528 (report_t, csv_format_,
529 CTOR(report_t, csv_format_) {
534 "%(quoted(display_account)),"
535 "%(quoted(commodity(scrub(display_amount)))),"
536 "%(quoted(quantity(scrub(display_amount)))),"
537 "%(quoted(cleared ? \"*\" : (pending ? \"!\" : \"\"))),"
538 "%(quoted(join(note | xact.note)))\n");
542 OTHER(limit_).on(whence,
"date<=today");
546 OTHER(period_).on(whence,
"daily");
555 OTHER(amount_).expr.set_base_expr
556 (
"(amount > 0 ? amount : 0, amount < 0 ? amount : 0)");
558 OTHER(register_format_)
561 " ansify_if(justify(format_date(date), int(date_width)),"
562 " green if color and date > today),"
563 " bold if should_bold))"
565 " ansify_if(justify(truncated(payee, int(payee_width)), int(payee_width)), "
566 " bold if color and !cleared and actual),"
567 " bold if should_bold))"
569 " ansify_if(justify(truncated(display_account, int(account_width), "
570 " int(abbrev_len)), int(account_width)),"
572 " bold if should_bold))"
574 " justify(scrub(abs(get_at(display_amount, 0))), int(amount_width), "
575 " 3 + int(meta_width) + int(date_width) + int(payee_width)"
576 " + int(account_width) + int(amount_width) + int(prepend_width),"
578 " bold if should_bold))"
580 " justify(scrub(abs(get_at(display_amount, 1))), int(amount_width), "
581 " 4 + int(meta_width) + int(date_width) + int(payee_width)"
582 " + int(account_width) + int(amount_width) + int(amount_width) + int(prepend_width),"
584 " bold if should_bold))"
586 " justify(scrub(get_at(display_total, 0) + get_at(display_total, 1)), int(total_width), "
587 " 5 + int(meta_width) + int(date_width) + int(payee_width)"
588 " + int(account_width) + int(amount_width) + int(amount_width) + int(total_width)"
589 " + int(prepend_width), true, color),"
590 " bold if should_bold))\n%/"
591 "%(justify(\" \", int(date_width)))"
593 " justify(truncated(has_tag(\"Payee\") ? payee : \" \", "
594 " int(payee_width)), int(payee_width)),"
595 " bold if should_bold))"
596 " %$3 %$4 %$5 %$6\n");
598 OTHER(balance_format_)
601 " justify(scrub(abs(get_at(display_total, 0))), 14,"
602 " 14 + int(prepend_width), true, color),"
603 " bold if should_bold)) "
605 " justify(scrub(abs(get_at(display_total, 1))), 14,"
606 " 14 + 1 + int(prepend_width) + int(total_width), true, color),"
607 " bold if should_bold)) "
609 " justify(scrub(get_at(display_total, 0) + get_at(display_total, 1)), 14,"
610 " 14 + 2 + int(prepend_width) + int(total_width) + int(total_width), true, color),"
611 " bold if should_bold))"
612 " %(!options.flat ? depth_spacer : \"\")"
614 " ansify_if(partial_account(options.flat), blue if color),"
615 " bold if should_bold))\n%/"
617 "%(prepend_width ? \" \" * int(prepend_width) : \"\")"
618 "--------------------------------------------\n");
622 OTHER(display_).on(whence,
string(
"depth<=") + str);
626 OTHER(display_total_)
627 .on(whence,
"display_amount-display_total");
634 value =
string(
"(") + value +
")&(" + str +
")";
638 (report_t, display_amount_,
640 (
"display_amount",
"amount_expr")) {}
646 (report_t, display_total_,
648 (
"display_total",
"total_expr")) {}
662 if (optional<date_t> end = interval.
begin()) {
663 string predicate =
"date<[" + to_iso_extended_string(*end) +
"]";
664 OTHER(limit_).on(whence, predicate);
668 throw_(std::invalid_argument,
669 _f(
"Could not determine end of period '%1%'")
681 OTHER(market).on(whence);
692 OTHER(revalued).on(whence);
693 OTHER(amount_).expr.set_base_expr(
"(amount, cost)");
697 OTHER(display_amount_)
699 "use_direct_amount ? amount :"
700 " (is_seq(get_at(amount_expr, 0)) ?"
701 " get_at(get_at(amount_expr, 0), 0) :"
702 " market(get_at(amount_expr, 0), value_date, exchange)"
703 " - get_at(amount_expr, 1))");
704 OTHER(revalued_total_)
706 "(market(get_at(total_expr, 0), value_date, exchange), "
707 "get_at(total_expr, 1))");
708 OTHER(display_total_)
710 "use_direct_amount ? total_expr :"
711 " market(get_at(total_expr, 0), value_date, exchange)"
712 " - get_at(total_expr, 1)");
718 (report_t, group_by_,
725 (report_t, group_title_format_,
726 CTOR(report_t, group_title_format_) {
727 on(none,
"%(value)\n");
733 OTHER(market).on(whence);
735 .on(whence,
"nail_down(amount_expr, "
736 "market(amount_expr, value_date, exchange))");
743 OTHER(amount_).on(whence,
"-amount_expr");
750 value =
string(
"(") + value +
")&(" + str +
")";
756 OTHER(lot_prices).on(whence);
757 OTHER(display_amount_)
758 .on(whence,
"averaged_lots(display_amount)");
759 OTHER(display_total_)
760 .on(whence,
"averaged_lots(display_total)");
767 OTHER(revalued).on(whence);
769 OTHER(display_amount_)
770 .on(whence,
"market(display_amount, value_date, exchange)");
771 OTHER(display_total_)
772 .on(whence,
"market(display_total, value_date, exchange)");
778 OTHER(period_).on(whence,
"monthly");
786 OTHER(revalued).off();
795 if (optional<date_t> begin = interval.
begin()) {
798 throw_(std::invalid_argument,
799 _f(
"Could not determine beginning of period '%1%'")
808 value =
string(
"(") + value +
")&(" + str +
")";
814#if HAVE_ISATTY and !defined(_WIN32) and !defined(__CYGWIN__)
817 CTOR(report_t, pager_) {
818 if (isatty(STDOUT_FILENO)) {
819 if (! std::getenv(
"PAGER")) {
820 bool have_less =
false;
821 if (exists(
path(
"/opt/local/bin/less")) ||
822 exists(
path(
"/usr/local/bin/less")) ||
823 exists(
path(
"/usr/bin/less")))
828 setenv(
"LESS",
"-FRSX", 0);
831 on(none, std::getenv(
"PAGER"));
832 setenv(
"LESS",
"-FRSX", 0);
847 OTHER(limit_).on(whence,
"pending");
853 "((is_account&parent&parent.total)?"
854 " percent(scrub(total), scrub(parent.total)):0)");
861 value +=
string(
" ") + str;
867 (report_t, plot_amount_format_,
868 CTOR(report_t, plot_amount_format_) {
870 "%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_amount)))\n");
874 (report_t, plot_total_format_,
875 CTOR(report_t, plot_total_format_) {
877 "%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_total)))\n");
884 OTHER(amount_).expr.set_base_expr(
"price");
888 (report_t, prices_format_,
889 CTOR(report_t, prices_format_) {
891 "%(date) %-8(display_account) %(justify(scrub(display_amount), 12, "
892 " 2 + 9 + 8 + 12, true, color))\n");
896 (report_t, pricedb_format_,
897 CTOR(report_t, pricedb_format_) {
899 "P %(datetime) %(display_account) %(scrub(display_amount))\n");
905 OTHER(revalued).off();
907 OTHER(amount_).expr.set_base_expr(
"amount");
908 OTHER(total_).expr.set_base_expr(
"total");
912 OTHER(period_).on(whence,
"quarterly");
918 OTHER(limit_).on(whence,
"real");
922 (report_t, register_format_,
923 CTOR(report_t, register_format_) {
926 " ansify_if(justify(format_date(date), int(date_width)),"
927 " green if color and date > today),"
928 " bold if should_bold))"
930 " ansify_if(justify(truncated(payee, int(payee_width)), int(payee_width)), "
931 " bold if color and !cleared and actual),"
932 " bold if should_bold))"
934 " ansify_if(justify(truncated(display_account, int(account_width), "
935 " int(abbrev_len)), int(account_width)),"
937 " bold if should_bold))"
939 " justify(scrub(display_amount), int(amount_width), "
940 " 3 + int(meta_width) + int(date_width) + int(payee_width)"
941 " + int(account_width) + int(amount_width) + int(prepend_width),"
943 " bold if should_bold))"
945 " justify(scrub(display_total), int(total_width), "
946 " 4 + int(meta_width) + int(date_width) + int(payee_width)"
947 " + int(account_width) + int(amount_width) + int(total_width)"
948 " + int(prepend_width), true, color),"
949 " bold if should_bold))\n%/"
950 "%(justify(\" \", int(date_width)))"
952 " justify(truncated(has_tag(\"Payee\") ? payee : \" \", "
953 " int(payee_width)), int(payee_width)),"
954 " bold if should_bold))"
961 OTHER(related).on(whence);
968 (report_t, revalued_total_,
979 OTHER(sort_xacts_).off();
980 OTHER(sort_all_).off();
984 OTHER(sort_).on(whence, str);
985 OTHER(sort_xacts_).off();
989 OTHER(sort_).on(whence, str);
990 OTHER(sort_all_).off();
998 OTHER(balance_format_)
1000 "%(ansify_if(justify(earliest_checkin ? "
1001 " format_datetime(earliest_checkin) : \"\", 19, -1, true),"
1002 " bold if latest_checkout_cleared)) "
1003 "%(ansify_if(justify(latest_checkout ? "
1004 " format_datetime(latest_checkout) : \"\", 19, -1, true), "
1005 " bold if latest_checkout_cleared)) "
1006 "%(latest_checkout_cleared ? \"*\" : \" \") "
1008 " justify(scrub(display_total), 8,"
1009 " 8 + 4 + 19 * 2, true, color), bold if should_bold))"
1010 " %(!options.flat ? depth_spacer : \"\")"
1012 " ansify_if(partial_account(options.flat), blue if color),"
1013 " bold if should_bold))\n%/"
1015 "%(prepend_width ? \" \" * int(prepend_width) : \"\")"
1016 "--------------------------------------------------\n");
1029 if (style ==
"leading")
1031 else if (style ==
"middle")
1033 else if (style ==
"trailing")
1036 throw_(std::invalid_argument,
1037 _f(
"Unrecognized truncation style: '%1%'") % style);
1046 OTHER(limit_).on(whence,
"uncleared|pending");
1055 OTHER(amount_).on(whence,
"unrounded(amount_expr)");
1056 OTHER(total_).on(whence,
"unrounded(total_expr)");
1060 OTHER(period_).on(whence,
"weekly");
1064 OTHER(columns_).on(whence,
"132");
1068 OTHER(period_).on(whence,
"yearly");
1080template <
class Type =
post_t,
1082 void (report_t::*report_method)(handler_ptr) =
1086 shared_ptr<item_handler<Type> > handler;
1093 report_t& _report,
const string& _whence)
1094 : handler(_handler), report(_report), whence(_whence) {
1098 : handler(other.handler), report(other.report), whence(other.whence) {
1107 if (args.
size() > 0)
1108 report.parse_query_args(args.
value(), whence);
1110 (report.*report_method)(handler_ptr(handler));
Basic type and macros for handling command-line options.
#define DECL1(type, name, vartype, var, value)
#define OPTION(type, name)
#define OPTION_(type, name, body)
#define OPTION__(type, name, body)
#define BUDGET_UNBUDGETED
Types for annotating commodities.
A utility class for abstracting an output stream.
Types for handling commodities.
#define TRACE_CTOR(cls, args)
optional< datetime_t > epoch
balance_t average_lot_prices(const balance_t &bal)
shared_ptr< item_handler< post_t > > post_handler_ptr
boost::filesystem::path path
value_t scope_value(scope_t *val)
boost::posix_time::ptime datetime_t
shared_ptr< item_handler< account_t > > acct_handler_ptr
intrusive_ptr< op_t > ptr_op_t
static enum ledger::format_t::elision_style_t default_style
static bool default_style_changed
void on(const char *whence)
void commodities_report(post_handler_ptr handler)
value_t fn_lot_date(call_scope_t &scope)
virtual void define(const symbol_t::kind_t kind, const string &name, expr_t::ptr_op_t def)
value_t fn_amount_expr(call_scope_t &scope)
value_t fn_commodity_price(call_scope_t &scope)
value_t fn_rounded(call_scope_t &scope)
value_t fn_total_expr(call_scope_t &scope)
report_t(const report_t &report)
value_t fn_truncated(call_scope_t &scope)
value_t fn_to_balance(call_scope_t &scope)
keep_details_t what_to_keep()
value_t fn_quoted_rfc(call_scope_t &scope)
value_t fn_round(call_scope_t &scope)
value_t fn_get_at(call_scope_t &scope)
value_t fn_quoted(call_scope_t &scope)
value_t fn_to_amount(call_scope_t &scope)
value_t fn_to_mask(call_scope_t &scope)
value_t fn_to_sequence(call_scope_t &scope)
void report_options(std::ostream &out)
value_t fn_unround(call_scope_t &scope)
void xact_report(post_handler_ptr handler, xact_t &xact)
value_t fn_lot_tag(call_scope_t &scope)
value_t fn_to_string(call_scope_t &scope)
report_t(session_t &_session)
value_t echo_command(call_scope_t &scope)
value_t fn_unrounded(call_scope_t &scope)
void normalize_options(const string &verb)
value_t fn_is_seq(call_scope_t &scope)
value_t fn_format_datetime(call_scope_t &scope)
value_t fn_to_int(call_scope_t &scope)
value_t pricemap_command(call_scope_t &scope)
void accounts_report(acct_handler_ptr handler)
uint_least8_t budget_flags
value_t fn_commodity(call_scope_t &scope)
virtual string description()
value_t fn_ansify_if(call_scope_t &scope)
option_t< report_t > * lookup_option(const char *p)
value_t fn_now(call_scope_t &)
value_t fn_today(call_scope_t &)
value_t display_value(const value_t &val)
value_t fn_justify(call_scope_t &scope)
value_t fn_to_boolean(call_scope_t &scope)
value_t fn_to_date(call_scope_t &scope)
value_t fn_set_commodity_price(call_scope_t &scope)
value_t fn_abs(call_scope_t &scope)
value_t fn_display_amount(call_scope_t &scope)
value_t fn_trim(call_scope_t &scope)
value_t fn_display_total(call_scope_t &scope)
virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t kind, const string &name)
value_t fn_market(call_scope_t &scope)
value_t fn_to_datetime(call_scope_t &scope)
value_t fn_print(call_scope_t &scope)
value_t fn_averaged_lots(call_scope_t &scope)
value_t fn_lot_price(call_scope_t &scope)
value_t fn_quantity(call_scope_t &scope)
value_t fn_clear_commodity(call_scope_t &scope)
void generate_report(post_handler_ptr handler)
value_t fn_top_amount(call_scope_t &val)
value_t fn_floor(call_scope_t &scope)
value_t fn_options(call_scope_t &)
value_t fn_nail_down(call_scope_t &scope)
value_t fn_strip(call_scope_t &scope)
string report_format(option_t< report_t > &option)
value_t fn_format_date(call_scope_t &scope)
value_t fn_join(call_scope_t &scope)
void posts_report(post_handler_ptr handler)
value_t fn_format(call_scope_t &scope)
value_t fn_ceiling(call_scope_t &scope)
value_t fn_should_bold(call_scope_t &scope)
value_t reload_command(call_scope_t &)
value_t fn_roundto(call_scope_t &scope)
optional< string > maybe_format(option_t< report_t > &option)
output_stream_t output_stream
value_t fn_percent(call_scope_t &scope)
void parse_query_args(const value_t &args, const string &whence)
value_t fn_scrub(call_scope_t &scope)
reporter(const reporter &other)
value_t operator()(call_scope_t &args)
reporter(shared_ptr< item_handler< Type > > _handler, report_t &_report, const string &_whence)
optional< date_t > begin() const
Dynamic type representing various numeric types.