summaryrefslogtreecommitdiff
path: root/src/convert.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/convert.cc')
-rw-r--r--src/convert.cc101
1 files changed, 42 insertions, 59 deletions
diff --git a/src/convert.cc b/src/convert.cc
index 493fbb7a..e8ca241e 100644
--- a/src/convert.cc
+++ b/src/convert.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2010, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2012, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -56,75 +56,50 @@ value_t convert_command(call_scope_t& args)
account_t * bucket = journal.master->find_account(bucket_name);
account_t * unknown = journal.master->find_account(_("Expenses:Unknown"));
- // Make an amounts mapping for the account under consideration
-
- typedef std::map<value_t, std::list<post_t *> > post_map_t;
- post_map_t post_map;
-
- xacts_iterator journal_iter(journal);
- while (xact_t * xact = *journal_iter++) {
- post_t * post = NULL;
- xact_posts_iterator xact_iter(*xact);
- while ((post = *xact_iter++) != NULL) {
- if (post->account == bucket)
- break;
- }
- if (post) {
- post_map_t::iterator i = post_map.find(post->amount);
- if (i == post_map.end()) {
- std::list<post_t *> post_list;
- post_list.push_back(post);
- post_map.insert(post_map_t::value_type(post->amount, post_list));
- } else {
- (*i).second.push_back(post);
- }
- }
- }
-
// Create a flat list
xacts_list current_xacts(journal.xacts_begin(), journal.xacts_end());
// Read in the series of transactions from the CSV file
print_xacts formatter(report);
- ifstream data(path(args.get<string>(0)));
- csv_reader reader(data);
+ path csv_file_path(args.get<string>(0));
- while (xact_t * xact = reader.read_xact(journal, bucket)) {
- if (report.HANDLED(invert)) {
- foreach (post_t * post, xact->posts)
- post->amount.in_place_negate();
- }
+ report.session.parsing_context.push(csv_file_path);
+ parse_context_t& context(report.session.parsing_context.get_current());
+ context.journal = &journal;
+ context.master = bucket;
- bool matched = false;
- if (! xact->posts.front()->amount.is_null()) {
- post_map_t::iterator i = post_map.find(- xact->posts.front()->amount);
- if (i != post_map.end()) {
- std::list<post_t *>& post_list((*i).second);
- foreach (post_t * post, post_list) {
- if (xact->code && post->xact->code &&
- *xact->code == *post->xact->code) {
- matched = true;
- break;
- }
- else if (xact->actual_date() == post->actual_date()) {
- matched = true;
- break;
- }
- }
+ csv_reader reader(context);
+
+ try {
+ while (xact_t * xact = reader.read_xact(report.HANDLED(rich_data))) {
+ if (report.HANDLED(invert)) {
+ foreach (post_t * post, xact->posts)
+ post->amount.in_place_negate();
}
- }
- if (matched) {
- DEBUG("convert.csv", "Ignored xact with code: " << *xact->code);
- checked_delete(xact); // ignore it
- }
- else {
+ string ref = (xact->has_tag(_("UUID")) ?
+ xact->get_tag(_("UUID"))->to_string() :
+ sha1sum(reader.get_last_line()));
+
+ checksum_map_t::const_iterator entry = journal.checksum_map.find(ref);
+ if (entry != journal.checksum_map.end()) {
+ INFO(file_context(reader.get_pathname(),
+ reader.get_linenum())
+ << "Ignoring known UUID " << ref);
+ checked_delete(xact); // ignore it
+ continue;
+ }
+
+ if (report.HANDLED(rich_data) && ! xact->has_tag(_("UUID")))
+ xact->set_tag(_("UUID"), string_value(ref));
+
if (xact->posts.front()->account == NULL) {
- // jww (2010-03-07): Bind this logic to an option: --auto-match
if (account_t * acct =
- lookup_probable_account(xact->payee, current_xacts.rbegin(),
- current_xacts.rend(), bucket).second)
+ (report.HANDLED(auto_match) ?
+ lookup_probable_account(xact->payee, current_xacts.rbegin(),
+ current_xacts.rend(), bucket).second :
+ NULL))
xact->posts.front()->account = acct;
else
xact->posts.front()->account = unknown;
@@ -141,8 +116,16 @@ value_t convert_command(call_scope_t& args)
formatter(*post);
}
}
+ formatter.flush();
+ }
+ catch (const std::exception&) {
+ add_error_context(_("While parsing file %1")
+ << file_context(reader.get_pathname(),
+ reader.get_linenum()));
+ add_error_context(_("While parsing CSV line:"));
+ add_error_context(line_context(reader.get_last_line()));
+ throw;
}
- formatter.flush();
// If not, transform the payee according to regexps