Exemple #1
0
static PyObject *aqbanking_Account_transactions(aqbanking_Account* self, PyObject *args, PyObject *kwds)
{
	int rv;
	double tmpDateTime = 0;
	const char *bank_code;
	const char *account_no;
#if PY_VERSION_HEX >= 0x03030000
	bank_code = PyUnicode_AsUTF8(self->bank_code);
	account_no = PyUnicode_AsUTF8(self->no);
#else
	PyObject *s = _PyUnicode_AsDefaultEncodedString(self->bank_code, NULL);
	bank_code = PyBytes_AS_STRING(s);
	s = _PyUnicode_AsDefaultEncodedString(self->no, NULL);
	account_no = PyBytes_AS_STRING(s);
#endif
	GWEN_TIME *gwTime;
	const char *dateFrom=NULL, *dateTo=NULL;
	static char *kwlist[] = {"dateFrom", "dateTo", NULL};
	if (! PyArg_ParseTupleAndKeywords(args, kwds, "|ss", kwlist, &dateFrom, &dateTo))
	{
		return NULL;
	}

	AB_ACCOUNT *a;
	AB_JOB *job = 0;
	AB_JOB_LIST2 *jl = 0;
	AB_IMEXPORTER_CONTEXT *ctx = 0;
	AB_IMEXPORTER_ACCOUNTINFO *ai;
	/*aqbanking_Transaction *trans = NULL;*/
	PyObject *transList = PyList_New(0);

	// Valid data set?
	if (self->no == NULL)
	{
		PyErr_SetString(PyExc_AttributeError, "no");
	}
	if (self->bank_code == NULL)
	{
		PyErr_SetString(PyExc_AttributeError, "bank_code");
	}

	// Initialize aqbanking.
	rv = AB_create(self);
	if (rv > 0)
	{
		Py_DECREF(transList);
		return NULL;
	}

	// Let us find the account!
	a = AB_Banking_GetAccountByCodeAndNumber(self->ab, bank_code, account_no);
	if (!a)
	{
		PyErr_SetString(AccountNotFound, "Could not find the given account! ");
		Py_DECREF(transList);
		return NULL;
	}

	// Create job and execute it.
	job = AB_JobGetTransactions_new(a);
	if (dateFrom != NULL)
	{
		gwTime = GWEN_Time_fromString(dateFrom, "YYYYMMDD");
		AB_JobGetTransactions_SetFromTime(job, gwTime);
	}
	if (dateTo != NULL)
	{
		gwTime = GWEN_Time_fromString(dateTo, "YYYYMMDD");
		AB_JobGetTransactions_SetToTime(job, gwTime);
	}
	// Check for availability
	rv = AB_Job_CheckAvailability(job);
	if (rv) {
		PyErr_SetString(ExecutionFailed, "Transaction retrieval is not supported!");
		Py_DECREF(transList);
		return NULL;
	}

	jl = AB_Job_List2_new();
	AB_Job_List2_PushBack(jl, job);
	ctx = AB_ImExporterContext_new();
	rv = AB_Banking_ExecuteJobs(self->ab, jl, ctx);

	if (rv)
	{
		PyErr_SetString(ExecutionFailed, "Could not retrieve transactions!");
		Py_DECREF(transList);
		return NULL;
	}

	// With success. No process the result.
	ai = AB_ImExporterContext_GetFirstAccountInfo (ctx);
	while(ai)
	{
		const AB_TRANSACTION *t;
		
		t = AB_ImExporterAccountInfo_GetFirstTransaction(ai);
		while(t) {
			const AB_VALUE *v;
			AB_TRANSACTION_STATUS state;

			v=AB_Transaction_GetValue(t);
			if (v) {
				const GWEN_STRINGLIST *sl;
				const GWEN_TIME *tdtime;
				const char *purpose;
				const char *remoteName;
				aqbanking_Transaction *trans = (aqbanking_Transaction*) PyObject_CallObject((PyObject *) &aqbanking_TransactionType, NULL);

				/* The purpose (memo field) might contain multiple lines.
				 * Therefore AqBanking stores the purpose in a string list
				 * of which the first entry is used in this tutorial */
				sl = AB_Transaction_GetPurpose(t);
				if (sl)
				{
					purpose = GWEN_StringList_FirstString(sl);
					if (purpose == NULL) {
						purpose = "";
					}
				}
				else
				{
					purpose = "";
				}

#ifdef DEBUGSTDERR
				fprintf(stderr, "[%-10d]: [%-10s/%-10s][%-10s/%-10s] %-32s (%.2f %s)\n",
						AB_Transaction_GetUniqueId(t),
						AB_Transaction_GetRemoteIban(t),
						AB_Transaction_GetRemoteBic(t),
						AB_Transaction_GetRemoteAccountNumber(t),
						AB_Transaction_GetRemoteBankCode(t),
						purpose,
						AB_Value_GetValueAsDouble(v),
						AB_Value_GetCurrency(v)
				);
#endif

				tdtime = AB_Transaction_GetDate(t);
				tmpDateTime = PyLong_AsDouble(PyLong_FromSize_t(GWEN_Time_Seconds(tdtime)));
				trans->date = PyDate_FromTimestamp(Py_BuildValue("(O)", PyFloat_FromDouble(tmpDateTime)));
				tdtime = AB_Transaction_GetValutaDate(t);
				tmpDateTime = PyLong_AsDouble(PyLong_FromSize_t(GWEN_Time_Seconds(tdtime)));
				trans->valutaDate = PyDate_FromTimestamp(Py_BuildValue("(O)", PyFloat_FromDouble(tmpDateTime)));
				trans->purpose = PyUnicode_FromString(purpose);

				// Local user
				if (AB_Transaction_GetLocalAccountNumber(t) == NULL) {
					trans->localAccount = Py_None;
					Py_INCREF(Py_None);
				} else {
					trans->localAccount = PyUnicode_FromString(AB_Transaction_GetLocalAccountNumber(t));
				}
				if (AB_Transaction_GetLocalBankCode(t) == NULL) {
					trans->localBank = Py_None;
					Py_INCREF(Py_None);
				} else {
					trans->localBank = PyUnicode_FromString(AB_Transaction_GetLocalBankCode(t));
				}
				if (AB_Transaction_GetLocalIban(t) == NULL) {
					trans->localIban = Py_None;
					Py_INCREF(Py_None);
				} else {
					trans->localIban = PyUnicode_FromString(AB_Transaction_GetLocalIban(t));
				}
				if (AB_Transaction_GetLocalBic(t) == NULL) {
					trans->localBic = Py_None;
					Py_INCREF(Py_None);
				} else {
					trans->localBic = PyUnicode_FromString(AB_Transaction_GetLocalBic(t));
				}
				if (AB_Transaction_GetLocalName(t) == NULL) {
					trans->localName = Py_None;
					Py_INCREF(Py_None);
				} else {
				        trans->localName = PyUnicode_FromString(AB_Transaction_GetLocalName(t));
				}

				// Remote user
				if (AB_Transaction_GetRemoteAccountNumber(t) == NULL) {
					trans->remoteAccount = Py_None;
					Py_INCREF(Py_None);
				} else {
					trans->remoteAccount = PyUnicode_FromString(AB_Transaction_GetRemoteAccountNumber(t));
				}
				if (AB_Transaction_GetRemoteBankCode(t) == NULL) {
					trans->remoteBank = Py_None;
					Py_INCREF(Py_None);
				} else {
					trans->remoteBank = PyUnicode_FromString(AB_Transaction_GetRemoteBankCode(t));
				}
				if (AB_Transaction_GetRemoteIban(t) == NULL) {
					trans->remoteIban = Py_None;
					Py_INCREF(Py_None);
				} else {
					trans->remoteIban = PyUnicode_FromString(AB_Transaction_GetRemoteIban(t));
				}
				if (AB_Transaction_GetRemoteBic(t) == NULL) {
					trans->remoteBic = Py_None;
					Py_INCREF(Py_None);
				} else {
					trans->remoteBic = PyUnicode_FromString(AB_Transaction_GetRemoteBic(t));
				}
				if (AB_Transaction_GetRemoteName(t) == NULL) {
					trans->remoteName = Py_None;
					Py_INCREF(Py_None);
				} else {
					sl = AB_Transaction_GetRemoteName(t);
					remoteName = GWEN_StringList_FirstString(sl);
					if (remoteName == NULL) {
						trans->remoteName = Py_None;
					} else {
						trans->remoteName = PyUnicode_FromString(remoteName);
					}
				}

				trans->value = PyFloat_FromDouble(AB_Value_GetValueAsDouble(v));
				trans->currency = PyUnicode_FromString("EUR");
				trans->uniqueId = PyLong_FromLong(AB_Transaction_GetUniqueId(t));
				if (AB_Transaction_GetTransactionText(t) == NULL) {
					trans->transactionText = PyUnicode_FromString("");
				} else {
					trans->transactionText = PyUnicode_FromString(AB_Transaction_GetTransactionText(t));
				}
				trans->transactionCode = PyLong_FromLong(AB_Transaction_GetTransactionCode(t));
				trans->textKey = PyLong_FromLong(AB_Transaction_GetTextKey(t));
				trans->textKeyExt = PyLong_FromLong(AB_Transaction_GetTextKeyExt(t));
				if (AB_Transaction_GetMandateId(t) == NULL) {
					trans->sepaMandateId = Py_None;
				} else {
					trans->sepaMandateId = PyUnicode_FromString(AB_Transaction_GetMandateId(t));
				}
				if (AB_Transaction_GetCustomerReference(t) == NULL) {
					trans->customerReference = PyUnicode_FromString("");
				} else {
					trans->customerReference = PyUnicode_FromString(AB_Transaction_GetCustomerReference(t));
				}
				if (AB_Transaction_GetBankReference(t) == NULL) {
					trans->bankReference = PyUnicode_FromString("");
				} else {
					trans->bankReference = PyUnicode_FromString(AB_Transaction_GetBankReference(t));
				}
				if (AB_Transaction_GetEndToEndReference(t) == NULL) {
					trans->endToEndReference = PyUnicode_FromString("");
				} else {
					trans->endToEndReference = PyUnicode_FromString(AB_Transaction_GetEndToEndReference(t));
				}
				trans->state = 0;
				state = AB_Transaction_GetStatus(t);
				switch(state)
				{
					case AB_Transaction_StatusUnknown:
						trans->state = -1;
						break;
					case AB_Transaction_StatusNone:
						trans->state = 0;
						break;
					case AB_Transaction_StatusAccepted:
						trans->state = 1;
						break;
					case AB_Transaction_StatusRejected:
						trans->state = 2;
						break;
					case AB_Transaction_StatusPending:
						trans->state = 4;
						break;
					case AB_Transaction_StatusSending:
						trans->state = 8;
						break;
					case AB_Transaction_StatusAutoReconciled:
						trans->state = 16;
						break;
					case AB_Transaction_StatusManuallyReconciled:
						trans->state = 32;
						break;
					case AB_Transaction_StatusRevoked:
						trans->state = 64;
						break;
					case AB_Transaction_StatusAborted:
						trans->state = 128;
						break;
				}

				PyList_Append(transList, (PyObject *)trans);
				Py_DECREF(trans);
			}
			t = AB_ImExporterAccountInfo_GetNextTransaction(ai);
		} 
		ai = AB_ImExporterContext_GetNextAccountInfo(ctx);
	}

	// Free jobs.
	AB_Job_free(job);
	AB_Job_List2_free(jl);
	AB_ImExporterContext_free(ctx);

	// Exit aqbanking.
	rv = AB_free(self);
	if (rv > 0)
	{
		//Py_XDECREF(trans);
		Py_DECREF(transList);
		return NULL;
	}

	return transList;
}
Transaction *
gnc_ab_trans_to_gnc(const AB_TRANSACTION *ab_trans, Account *gnc_acc)
{
    QofBook *book;
    Transaction *gnc_trans;
    const gchar *fitid;
    const GWEN_TIME *valuta_date;
    time64 current_time;
    const char *custref;
    gchar *description;
    Split *split;
    gchar *memo;

    g_return_val_if_fail(ab_trans && gnc_acc, NULL);

    /* Create new GnuCash transaction for the given AqBanking one */
    book = gnc_account_get_book(gnc_acc);
    gnc_trans = xaccMallocTransaction(book);
    xaccTransBeginEdit(gnc_trans);

    /* Date / Time */
    valuta_date = AB_Transaction_GetValutaDate(ab_trans);
    if (!valuta_date)
    {
        const GWEN_TIME *normal_date = AB_Transaction_GetDate(ab_trans);
        if (normal_date)
            valuta_date = normal_date;
    }
    if (valuta_date)
        xaccTransSetDatePostedSecsNormalized(gnc_trans, GWEN_Time_toTime_t(valuta_date));
    else
        g_warning("transaction_cb: Oops, date 'valuta_date' was NULL");

    xaccTransSetDateEnteredSecs(gnc_trans, gnc_time (NULL));

    /* Currency.  We take simply the default currency of the gnucash account */
    xaccTransSetCurrency(gnc_trans, xaccAccountGetCommodity(gnc_acc));

    /* Trans-Num or Split-Action set with gnc_set_num_action below per book
     * option */

    /* Description */
    description = gnc_ab_description_to_gnc(ab_trans);
    xaccTransSetDescription(gnc_trans, description);
    g_free(description);

    /* Notes. */
    /* xaccTransSetNotes(gnc_trans, g_notes); */
    /* But Nobody ever uses the Notes field? */

    /* Add one split */
    split = xaccMallocSplit(book);
    xaccSplitSetParent(split, gnc_trans);
    xaccSplitSetAccount(split, gnc_acc);

    /* Set the transaction number or split action field based on book option.
     * We use the "customer reference", if there is one. */
    custref = AB_Transaction_GetCustomerReference(ab_trans);
    if (custref && *custref
            && g_ascii_strncasecmp(custref, "NONREF", 6) != 0)
        gnc_set_num_action (gnc_trans, split, custref, NULL);

    /* Set OFX unique transaction ID */
    fitid = AB_Transaction_GetFiId(ab_trans);
    if (fitid && *fitid)
        gnc_import_set_split_online_id(split, fitid);

    {
        /* Amount into the split */
        const AB_VALUE *ab_value = AB_Transaction_GetValue(ab_trans);
        double d_value = ab_value ? AB_Value_GetValueAsDouble (ab_value) : 0.0;
        AB_TRANSACTION_TYPE ab_type = AB_Transaction_GetType (ab_trans);
        gnc_numeric gnc_amount;

        /*printf("Transaction with value %f has type %d\n", d_value, ab_type);*/
        /* If the value is positive, but the transaction type says the
           money is transferred away from our account (Transfer instead of
           DebitNote), we switch the value to negative. */
        if (d_value > 0.0 && ab_type == AB_Transaction_TypeTransfer)
            d_value = -d_value;

        gnc_amount = double_to_gnc_numeric(
                         d_value,
                         xaccAccountGetCommoditySCU(gnc_acc),
                         GNC_HOW_RND_ROUND_HALF_UP);
        if (!ab_value)
            g_warning("transaction_cb: Oops, value was NULL.  Using 0");
        xaccSplitSetBaseValue(split, gnc_amount, xaccAccountGetCommodity(gnc_acc));
    }

    /* Memo in the Split. */
    memo = gnc_ab_memo_to_gnc(ab_trans);
    xaccSplitSetMemo(split, memo);
    g_free(memo);

    return gnc_trans;
}