diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/sie.c | 46 |
1 files changed, 37 insertions, 9 deletions
@@ -9,6 +9,7 @@ #include <time.h> #include "ledger.h" +#include "log.h" #include "util.h" #include "version.h" @@ -266,7 +267,7 @@ static int tokenize(char *line, char *toks[], int max, int *out_n) int n = 0; char *p = line; while (*p) { - while (*p == ' ' || *p == '\t') + while (*p == ' ' || *p == '\t' || *p == '\r') p++; if (!*p) break; @@ -298,7 +299,7 @@ static int tokenize(char *line, char *toks[], int max, int *out_n) } } else { toks[n++] = p; - while (*p && *p != ' ' && *p != '\t') + while (*p && *p != ' ' && *p != '\t' && *p != '\r') p++; if (*p) *p++ = '\0'; @@ -603,15 +604,17 @@ int sie_import_content(sqlite3 *db, int64_t org_id, int64_t user_id, continue; } if (toks[0][0] != '#') { - if (in_ver && strcmp(toks[0], "}") == 0) + if (in_ver && toks[0][0] == '}') in_ver = 0; line = strtok_r(NULL, "\n", &save); continue; } if (strcmp(toks[0], "#RAR") == 0 && n >= 4) { - if (sie_date(toks[2], fy_start) != 0 || - sie_date(toks[3], fy_end) != 0) - FAIL("SIE line %d: bad #RAR dates", line_no); + if (strcmp(toks[1], "0") == 0) { + if (sie_date(toks[2], fy_start) != 0 || + sie_date(toks[3], fy_end) != 0) + FAIL("SIE line %d: bad #RAR dates", line_no); + } } else if (strcmp(toks[0], "#KONTO") == 0 && n >= 2) { const char *name = n >= 3 ? toks[2] : ""; if (konto_n == konto_cap) { @@ -747,7 +750,25 @@ int sie_import_content(sqlite3 *db, int64_t org_id, int64_t user_id, FAIL("could not create account %s", ib_rows[i].account); } + /* The #IB balances are the previous year's closing balances. When this + org already has earlier non-IB vouchers, those carry the opening + balances and a synthetic IB voucher would double count them. */ + int64_t prior_history = 0; if (ib_n > 0 && !has_ib_ver) { + if (sqlite3_prepare_v2( + db, + "SELECT count(*) FROM vouchers WHERE org_id=?1" + " AND series <> 'IB' AND date < ?2", + -1, &st, NULL) != SQLITE_OK) + FAIL("database error"); + sqlite3_bind_int64(st, 1, org_id); + sqlite3_bind_text(st, 2, fy_start, -1, SQLITE_TRANSIENT); + if (sqlite3_step(st) == SQLITE_ROW) + prior_history = sqlite3_column_int64(st, 0); + sqlite3_finalize(st); + } + + if (ib_n > 0 && !has_ib_ver && prior_history == 0) { struct import_ver ibver; memset(&ibver, 0, sizeof ibver); snprintf(ibver.series, sizeof ibver.series, "IB"); @@ -766,6 +787,9 @@ int sie_import_content(sqlite3 *db, int64_t org_id, int64_t user_id, update_sequence(db, org_id, fy_id, "IB", 1); free(ibver.rows); vouchers++; + } else if (ib_n > 0 && prior_history > 0) { + log_info("SIE: #IB skipped; %lld earlier vouchers carry the balances", + (long long)prior_history); } /* re-walk the text to post vouchers (rows were kept only per block) */ @@ -811,12 +835,16 @@ int sie_import_content(sqlite3 *db, int64_t org_id, int64_t user_id, } else if (m > 0 && strcmp(t2[0], "#TRANS") == 0 && in_ver && m >= 3) { int64_t amt = 0; + int got = 0; for (int i = 2; i < m; i++) { - if (parse_amount(t2[i], &amt) == 0) + if (parse_amount(t2[i], &amt) == 0) { + got = 1; break; + } } - ver_add_row(&ver, t2[1], amt > 0 ? amt : 0, - amt < 0 ? -amt : 0, ""); + if (got && amt != 0) + ver_add_row(&ver, t2[1], amt > 0 ? amt : 0, + amt < 0 ? -amt : 0, ""); } } l2 = strtok_r(NULL, "\n", &save2); |
