Example #1
0
static
AB_ACCOUNT_STATUS *_getLastAccountStatus(AB_IMEXPORTER_ACCOUNTINFO *iea) {
  AB_ACCOUNT_STATUS *lastAst=0;
  const GWEN_TIME *lastTi=0;
  AB_ACCOUNT_STATUS *ast=0;

  ast=AB_ImExporterAccountInfo_GetFirstAccountStatus(iea);
  while(ast) {
    const GWEN_TIME *ti;

    if (lastAst && lastTi && (ti=AB_AccountStatus_GetTime(ast))) {
      if (GWEN_Time_Diff(ti, lastTi)>0) {
	lastAst=ast;
        lastTi=ti;
      }
    }
    else {
      lastAst=ast;
      lastTi=AB_AccountStatus_GetTime(ast);
    }
    ast=AB_ImExporterAccountInfo_GetNextAccountStatus(iea);
  }

  return lastAst;
}
Example #2
0
static AB_IMEXPORTER_ACCOUNTINFO *
bal_accountinfo_cb(AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
{
    GncABImExContextImport *data = user_data;
    Account *gnc_acc;
    AB_ACCOUNT_STATUS *item, *best = NULL;
    const GWEN_TIME *best_time = NULL;
    const AB_BALANCE *booked_bal, *noted_bal;
    const AB_VALUE *booked_val = NULL, *noted_val = NULL;
    gdouble booked_value, noted_value;
    gnc_numeric value;
    time64 booked_tt = 0;
    GtkWidget *dialog;
    gboolean show_recn_window = FALSE;

    g_return_val_if_fail(element && data, NULL);

    if (data->awaiting & IGNORE_BALANCES)
        /* Ignore them */
        return NULL;

    if (!AB_ImExporterAccountInfo_GetFirstAccountStatus(element))
        /* No balance found */
        return NULL;
    else
        data->awaiting |= FOUND_BALANCES;

    /* Lookup the most recent ACCOUNT_STATUS available */
    item = AB_ImExporterAccountInfo_GetFirstAccountStatus(element);
    while (item)
    {
        const GWEN_TIME *item_time = AB_AccountStatus_GetTime(item);
        if (!best || GWEN_Time_Diff(best_time, item_time) < 0.0)
        {
            best = item;
            best_time = item_time;
        }
        item = AB_ImExporterAccountInfo_GetNextAccountStatus(element);
    }

    booked_bal = AB_AccountStatus_GetBookedBalance(best);
    if (!(data->awaiting & AWAIT_BALANCES))
    {
        /* Ignore zero balances if we don't await a balance */
        if (!booked_bal || AB_Value_IsZero(AB_Balance_GetValue(booked_bal)))
            return NULL;

        /* Ask the user whether to import unawaited non-zero balance */
        if (gnc_verify_dialog(data->parent, TRUE, "%s",
                              _("The bank has sent balance information "
                                "in its response."
                                "\n"
                                "Do you want to import it?")))
        {
            data->awaiting |= AWAIT_BALANCES;
        }
        else
        {
            data->awaiting |= IGNORE_BALANCES;
            return NULL;
        }
    }

    /* Lookup the corresponding gnucash account */
    gnc_acc = gnc_ab_accinfo_to_gnc_acc(element);
    if (!gnc_acc) return NULL;
    data->gnc_acc = gnc_acc;

    /* Lookup booked balance and time */
    if (booked_bal)
    {
        const GWEN_TIME *ti = AB_Balance_GetTime(booked_bal);
        if (ti)
        {
            booked_tt =  GWEN_Time_toTime_t(ti);
        }
        else
        {
            /* No time found? Use today because the HBCI query asked for today's
             * balance. */
            booked_tt = gnc_time64_get_day_start(gnc_time(NULL));
        }
        booked_val = AB_Balance_GetValue(booked_bal);
        if (booked_val)
        {
            booked_value = AB_Value_GetValueAsDouble(booked_val);
        }
        else
        {
            g_warning("bal_accountinfo_cb: booked_val == NULL.  Assuming 0");
            booked_value = 0.0;
        }
    }
    else
    {
        g_warning("bal_accountinfo_cb: booked_bal == NULL.  Assuming 0");
        booked_tt = 0;
        booked_value = 0.0;
    }

    /* Lookup noted balance */
    noted_bal = AB_AccountStatus_GetNotedBalance(best);
    if (noted_bal)
    {
        noted_val = AB_Balance_GetValue(noted_bal);
        if (noted_val)
            noted_value = AB_Value_GetValueAsDouble(noted_val);
        else
        {
            g_warning("bal_accountinfo_cb: noted_val == NULL.  Assuming 0");
            noted_value = 0.0;
        }
    }
    else
    {
        g_warning("bal_accountinfo_cb: noted_bal == NULL.  Assuming 0");
        noted_value = 0.0;
    }

    value = double_to_gnc_numeric(booked_value,
                                  xaccAccountGetCommoditySCU(gnc_acc),
                                  GNC_HOW_RND_ROUND_HALF_UP);
    if (noted_value == 0.0 && booked_value == 0.0)
    {
        dialog = gtk_message_dialog_new(
                     GTK_WINDOW(data->parent),
                     GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                     GTK_MESSAGE_INFO,
                     GTK_BUTTONS_OK,
                     "%s",
                     /* Translators: Strings from this file are needed only in
                      * countries that have one of aqbanking's Online Banking
                      * techniques available. This is 'OFX DirectConnect'
                      * (U.S. and others), 'HBCI' (in Germany), or 'YellowNet'
                      * (Switzerland). If none of these techniques are available
                      * in your country, you may safely ignore strings from the
                      * import-export/hbci subdirectory. */
                     _("The downloaded Online Banking Balance was zero.\n\n"
                       "Either this is the correct balance, or your bank does not "
                       "support Balance download in this Online Banking version. "
                       "In the latter case you should choose a different "
                       "Online Banking version number in the Online Banking "
                       "(AqBanking or HBCI) Setup. After that, try again to "
                       "download the Online Banking Balance."));
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);

    }
    else
    {
        gnc_numeric reconc_balance = xaccAccountGetReconciledBalance(gnc_acc);

        gchar *booked_str = gnc_AB_VALUE_to_readable_string(booked_val);
        gchar *message1 = g_strdup_printf(
                              _("Result of Online Banking job: \n"
                                "Account booked balance is %s"),
                              booked_str);
        gchar *message2 =
            (noted_value == 0.0) ?
            g_strdup("") :
            g_strdup_printf(_("For your information: This account also "
                              "has a noted balance of %s\n"),
                            gnc_AB_VALUE_to_readable_string(noted_val));

        if (gnc_numeric_equal(value, reconc_balance))
        {
            const gchar *message3 =
                _("The booked balance is identical to the current "
                  "reconciled balance of the account.");
            dialog = gtk_message_dialog_new(
                         GTK_WINDOW(data->parent),
                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                         GTK_MESSAGE_INFO,
                         GTK_BUTTONS_OK,
                         "%s\n%s\n%s",
                         message1, message2, message3);
            gtk_dialog_run(GTK_DIALOG(dialog));
            gtk_widget_destroy(GTK_WIDGET(dialog));

        }
        else
        {
            const char *message3 = _("Reconcile account now?");

            show_recn_window = gnc_verify_dialog(data->parent, TRUE, "%s\n%s\n%s",
                                                 message1, message2, message3);
        }
        g_free(booked_str);
        g_free(message1);
        g_free(message2);
    }

    /* Show reconciliation window */
    if (show_recn_window)
        recnWindowWithBalance(data->parent, gnc_acc, value, booked_tt);

    return NULL;
}
Example #3
0
static
int listBal(AB_BANKING *ab,
            GWEN_DB_NODE *dbArgs,
            int argc,
            char **argv) {
  GWEN_DB_NODE *db;
  int rv;
  const char *ctxFile;
  const char *outFile;
  AB_IMEXPORTER_CONTEXT *ctx=0;
  AB_IMEXPORTER_ACCOUNTINFO *iea=0;
  const char *bankId;
  const char *accountId;
  const char *bankName;
  const char *accountName;
  FILE *f;
  const GWEN_ARGS args[]={
  {
    GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
    GWEN_ArgsType_Char,            /* type */
    "bankId",                     /* name */
    0,                            /* minnum */
    1,                            /* maxnum */
    "b",                          /* short option */
    "bank",                       /* long option */
    "Specify the bank code",      /* short description */
    "Specify the bank code"       /* long description */
  },
  {
    GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
    GWEN_ArgsType_Char,            /* type */
    "accountId",                  /* name */
    0,                            /* minnum */
    1,                            /* maxnum */
    "a",                          /* short option */
    "account",                    /* long option */
    "Specify the account number",     /* short description */
    "Specify the account number"      /* long description */
  },
  {
    GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
    GWEN_ArgsType_Char,            /* type */
    "bankName",                   /* name */
    0,                            /* minnum */
    1,                            /* maxnum */
    "N",                          /* short option */
    "bankname",                   /* long option */
    "Specify the bank name",      /* short description */
    "Specify the bank name"       /* long description */
  },
  {
    GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
    GWEN_ArgsType_Char,            /* type */
    "accountName",                /* name */
    0,                            /* minnum */
    1,                            /* maxnum */
    "n",                          /* short option */
    "accountname",                    /* long option */
    "Specify the account name",     /* short description */
    "Specify the account name"      /* long description */
  },
  {
    GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
    GWEN_ArgsType_Char,            /* type */
    "ctxFile",                    /* name */
    0,                            /* minnum */
    1,                            /* maxnum */
    "c",                          /* short option */
    "ctxfile",                    /* long option */
    "Specify the file to store the context in",   /* short description */
    "Specify the file to store the context in"      /* long description */
  },
  {
    GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
    GWEN_ArgsType_Char,            /* type */
    "outFile",                    /* name */
    0,                            /* minnum */
    1,                            /* maxnum */
    "o",                          /* short option */
    "outfile",                    /* long option */
    "Specify the file to store the data in",   /* short description */
    "Specify the file to store the data in"      /* long description */
  },
  {
    GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
    GWEN_ArgsType_Int,             /* type */
    "help",                       /* name */
    0,                            /* minnum */
    0,                            /* maxnum */
    "h",                          /* short option */
    "help",                       /* long option */
    "Show this help screen",      /* short description */
    "Show this help screen"       /* long description */
  }
  };

  db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
  rv=GWEN_Args_Check(argc, argv, 1,
                     0 /*GWEN_ARGS_MODE_ALLOW_FREEPARAM*/,
                     args,
                     db);
  if (rv==GWEN_ARGS_RESULT_ERROR) {
    fprintf(stderr, "ERROR: Could not parse arguments\n");
    return 1;
  }
  else if (rv==GWEN_ARGS_RESULT_HELP) {
    GWEN_BUFFER *ubuf;

    ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
    if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
      fprintf(stderr, "ERROR: Could not create help string\n");
      return 1;
    }
    fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
    GWEN_Buffer_free(ubuf);
    return 0;
  }

  bankId=GWEN_DB_GetCharValue(db, "bankId", 0, 0);
  bankName=GWEN_DB_GetCharValue(db, "bankName", 0, 0);
  accountId=GWEN_DB_GetCharValue(db, "accountId", 0, 0);
  accountName=GWEN_DB_GetCharValue(db, "accountName", 0, 0);

  rv=AB_Banking_Init(ab);
  if (rv) {
    DBG_ERROR(0, "Error on init (%d)", rv);
    return 2;
  }

  ctxFile=GWEN_DB_GetCharValue(db, "ctxfile", 0, 0);
  rv=readContext(ctxFile, &ctx, 1);
  if (rv<0) {
    DBG_ERROR(0, "Error reading context (%d)", rv);
    return 4;
  }

  /* open output stream */
  outFile=GWEN_DB_GetCharValue(db, "outFile", 0, 0);
  if (outFile==0)
    f=stdout;
  else
    f=fopen(outFile, "w+");
  if (f==0) {
    DBG_ERROR(0, "Error selecting output file: %s",
	      strerror(errno));
    return 4;
  }

  iea=AB_ImExporterContext_GetFirstAccountInfo(ctx);
  while(iea) {
    int matches=1;
    const char *s;

    if (matches && bankId) {
      s=AB_ImExporterAccountInfo_GetBankCode(iea);
      if (!s || !*s || -1==GWEN_Text_ComparePattern(s, bankId, 0))
        matches=0;
    }

    if (matches && bankName) {
      s=AB_ImExporterAccountInfo_GetBankName(iea);
      if (!s || !*s)
        s=AB_ImExporterAccountInfo_GetBankName(iea);
      if (!s || !*s || -1==GWEN_Text_ComparePattern(s, bankName, 0))
        matches=0;
    }

    if (matches && accountId) {
      s=AB_ImExporterAccountInfo_GetAccountNumber(iea);
      if (!s || !*s || -1==GWEN_Text_ComparePattern(s, accountId, 0))
        matches=0;
    }
    if (matches && accountName) {
      s=AB_ImExporterAccountInfo_GetAccountName(iea);
      if (!s || !*s)
        s=AB_ImExporterAccountInfo_GetAccountName(iea);
      if (!s || !*s || -1==GWEN_Text_ComparePattern(s, accountName, 0))
        matches=0;
    }

    if (matches) {
      AB_ACCOUNT_STATUS *ast;

      ast=_getLastAccountStatus(iea);
      if (ast) {
	const GWEN_TIME *ti;
        const char *s;

	fprintf(f, "Account\t");
	s=AB_ImExporterAccountInfo_GetBankCode(iea);
	if (!s)
	  s="";
	fprintf(f, "%s\t", s);
	s=AB_ImExporterAccountInfo_GetAccountNumber(iea);
	if (!s)
	  s="";
	fprintf(f, "%s\t", s);
	s=AB_ImExporterAccountInfo_GetBankName(iea);
	if (!s)
	  s="";
	fprintf(f, "%s\t", s);
	s=AB_ImExporterAccountInfo_GetAccountName(iea);
	if (!s)
	  s="";
	fprintf(f, "%s\t", s);

	ti=AB_AccountStatus_GetTime(ast);
	_dumpBal(AB_AccountStatus_GetBookedBalance(ast), ti, f);
	_dumpBal(AB_AccountStatus_GetNotedBalance(ast), ti, f);

        fprintf(f, "\n");
      }
    } /* if matches */
    iea=AB_ImExporterContext_GetNextAccountInfo(ctx);
  } /* while */

  if (outFile) {
    if (fclose(f)) {
      DBG_ERROR(0, "Error closing output file: %s",
		strerror(errno));
      return 4;
    }
  }

  rv=AB_Banking_Fini(ab);
  if (rv) {
    fprintf(stderr, "ERROR: Error on deinit (%d)\n", rv);
    return 5;
  }

  return 0;
}
Example #4
0
/* --------------------------------------------------------------- FUNCTION */
int AH_Job_GetBalance_Process(AH_JOB *j, AB_IMEXPORTER_CONTEXT *ctx){
  AH_JOB_GETBALANCE *aj;
  GWEN_DB_NODE *dbResponses;
  GWEN_DB_NODE *dbCurr;
  int rv;

  DBG_INFO(AQHBCI_LOGDOMAIN, "Processing JobGetBalance");

  assert(j);
  aj=GWEN_INHERIT_GETDATA(AH_JOB, AH_JOB_GETBALANCE, j);
  assert(aj);

  dbResponses=AH_Job_GetResponses(j);
  assert(dbResponses);

  /* search for "Balance" */
  dbCurr=GWEN_DB_GetFirstGroup(dbResponses);
  while(dbCurr) {
    GWEN_DB_NODE *dbBalance;

    rv=AH_Job_CheckEncryption(j, dbCurr);
    if (rv) {
      DBG_INFO(AQHBCI_LOGDOMAIN, "Compromised security (encryption)");
      AH_Job_SetStatus(j, AH_JobStatusError);
      return rv;
    }
    rv=AH_Job_CheckSignature(j, dbCurr);
    if (rv) {
      DBG_INFO(AQHBCI_LOGDOMAIN, "Compromised security (signature)");
      AH_Job_SetStatus(j, AH_JobStatusError);
      return rv;
    }

    dbBalance=GWEN_DB_GetGroup(dbCurr, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
                               "data/balance");
    if (!dbBalance)
      dbBalance=GWEN_DB_GetGroup(dbCurr, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
                                         "data/balancecreditcard");
    if (dbBalance) {
      AB_ACCOUNT_STATUS *acst;
      GWEN_DB_NODE *dbT;
      AB_ACCOUNT *a;
      AB_IMEXPORTER_ACCOUNTINFO *ai;

      DBG_NOTICE(AQHBCI_LOGDOMAIN, "Got a balance");
      if (GWEN_Logger_GetLevel(0)>=GWEN_LoggerLevel_Debug)
        GWEN_DB_Dump(dbBalance, 2);

      acst=AB_AccountStatus_new();

      /* read booked balance */
      dbT=GWEN_DB_GetGroup(dbBalance, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
                           "booked");
      if (dbT) {
        AB_BALANCE *bal;

        bal=AH_Job_GetBalance__ReadBalance(dbT);
        if (bal) {
	  AB_AccountStatus_SetBookedBalance(acst, bal);
	  AB_AccountStatus_SetTime(acst, AB_Balance_GetTime(bal));
          AB_Balance_free(bal);
        }
      }

      /* read noted balance */
      dbT=GWEN_DB_GetGroup(dbBalance, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
                           "noted");
      if (dbT) {
        AB_BALANCE *bal;

        bal=AH_Job_GetBalance__ReadBalance(dbT);
        if (bal) {
	  AB_AccountStatus_SetNotedBalance(acst, bal);
	  if (AB_AccountStatus_GetTime(acst)==NULL)
	    AB_AccountStatus_SetTime(acst, AB_Balance_GetTime(bal));
          AB_Balance_free(bal);
        }
      }

      /* read credit Line */
      dbT=GWEN_DB_GetGroup(dbBalance, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
                           "creditLine");
      if (dbT) {
        AB_VALUE *v;

        v=AB_Value_fromDb(dbT);
        if (!v) {
          DBG_ERROR(AQHBCI_LOGDOMAIN, "Error parsing value from DB");
        }
        else {
          AB_AccountStatus_SetBankLine(acst, v);
        }
        AB_Value_free(v);
      }

      a=AH_AccountJob_GetAccount(j);
      assert(a);
      ai=AB_ImExporterContext_GetAccountInfo(ctx,
                                             AB_Account_GetBankCode(a),
                                             AB_Account_GetAccountNumber(a));
      assert(ai);

      /* add new account status */
      AB_ImExporterAccountInfo_AddAccountStatus(ai, acst);
      break; /* break loop, we found the balance */
    } /* if "Balance" */
    dbCurr=GWEN_DB_GetNextGroup(dbCurr);
  }

  return 0;
}