AB_VALUE *AB_Value_fromInt(long int num, long int denom) { AB_VALUE *v; v=AB_Value_new(); mpq_set_si(v->value, num, denom); return v; }
AB_VALUE *AB_Value_dup(const AB_VALUE *ov) { AB_VALUE *v; assert(ov); v=AB_Value_new(); mpq_set(v->value, ov->value); if (ov->currency) v->currency=strdup(ov->currency); return v; }
AB_TRANSACTION *AB_ImExporterYN__ReadLNE_LNS(AB_IMEXPORTER *ie, AB_IMEXPORTER_ACCOUNTINFO *ai, GWEN_XMLNODE *node) { AB_TRANSACTION *t; GWEN_XMLNODE *nn; GWEN_DATE *da=NULL; AB_VALUE *val=NULL; t=AB_Transaction_new(); /* get date */ nn=GWEN_XMLNode_FindFirstTag(node, "DTM", 0, 0); if (nn) da=AB_ImExporterYN__ReadDate(ie, nn, 209); AB_Transaction_SetValutaDate(t, da); GWEN_Date_free(da); da=NULL; /* read amount */ nn=GWEN_XMLNode_FindFirstTag(node, "MOA", 0, 0); if (nn) { /* Gutschrift */ val=AB_ImExporterYN__ReadValue(ie, nn, 210); if (val) { if (AB_Value_IsZero(val)) { AB_Value_free(val); val=NULL; } } if (val==NULL) { val=AB_ImExporterYN__ReadValue(ie, nn, 211); if (val) AB_Value_Negate(val); } } if (val==NULL) val=AB_Value_new(); AB_Value_SetCurrency(val, AB_ImExporterAccountInfo_GetCurrency(ai)); AB_Transaction_SetValue(t, val); AB_Value_free(val); val=0; /* read purpose */ nn=GWEN_XMLNode_GetNodeByXPath(node, "FTX/C108", GWEN_PATH_FLAGS_NAMEMUSTEXIST); if (nn) { GWEN_XMLNODE *nnn; nnn=GWEN_XMLNode_FindFirstTag(nn, "D_4440", 0, 0); while (nnn) { GWEN_XMLNODE *nData; nData=GWEN_XMLNode_GetFirstData(nnn); if (nData) { const char *s; s=GWEN_XMLNode_GetData(nData); if (s) { GWEN_BUFFER *xbuf; xbuf=GWEN_Buffer_new(0, 256, 0, 1); AB_ImExporter_Iso8859_1ToUtf8(s, strlen(s), xbuf); AB_Transaction_AddPurposeLine(t, GWEN_Buffer_GetStart(xbuf)); GWEN_Buffer_free(xbuf); } } nnn=GWEN_XMLNode_FindNextTag(nnn, "D_4440", 0, 0); } } return t; }
int AHB_DTAUS__Export(GWEN_DBIO *dbio, GWEN_SYNCIO *sio, GWEN_DB_NODE *data, GWEN_DB_NODE *cfg, uint32_t flags){ AB_VALUE *sumEUR; AB_VALUE *sumDEM; AB_VALUE *sumBankCodes; AB_VALUE *sumAccountIds; unsigned int cSets; GWEN_BUFFER *dst; GWEN_DB_NODE *gr; int isDebitNote; //int isEuro; const uint8_t *p; uint32_t size; int rv; isDebitNote=(strcasecmp(GWEN_DB_GetCharValue(cfg, "type", 0, "transfer"), "debitnote")==0); //isEuro=(strcasecmp(GWEN_DB_GetCharValue(cfg, "currency", 0, "EUR"), // "EUR")==0); cSets=0; sumEUR=AB_Value_new(); sumDEM=AB_Value_new(); sumBankCodes=AB_Value_new(); sumAccountIds=AB_Value_new(); dst=GWEN_Buffer_new(0, 1024, 0, 1); GWEN_Buffer_SetHardLimit(dst, AHB_DTAUS_HARDLIMIT); /* create A set */ if (AHB_DTAUS__CreateSetA(dst, cfg)) { DBG_INFO(AQBANKING_LOGDOMAIN, "Error creating A set"); GWEN_Buffer_free(dst); AB_Value_free(sumAccountIds); AB_Value_free(sumBankCodes); AB_Value_free(sumDEM); AB_Value_free(sumEUR); return -1; } /* create C sets */ gr=GWEN_DB_GetFirstGroup(data); while(gr) { const char *gn; gn=GWEN_DB_GroupName(gr); if ((isDebitNote && strcasecmp(gn, "debitnote")==0) || (!isDebitNote && (strcasecmp(gn, "transfer")==0 || strcasecmp(gn, "transaction")==0))){ if (AHB_DTAUS__CreateSetC(dst, cfg, gr, sumEUR, sumDEM, sumBankCodes, sumAccountIds)) { DBG_ERROR(AQBANKING_LOGDOMAIN, "Error creating C set from this data:"); GWEN_DB_Dump(gr, 2); GWEN_Buffer_free(dst); AB_Value_free(sumAccountIds); AB_Value_free(sumBankCodes); AB_Value_free(sumDEM); AB_Value_free(sumEUR); return -1; } cSets++; } /* if group matches */ else { DBG_ERROR(AQBANKING_LOGDOMAIN, "Ignoring group [%s]", GWEN_DB_GroupName(gr)); } gr=GWEN_DB_GetNextGroup(gr); } /* while */ /* create E set */ if (AHB_DTAUS__CreateSetE(dst, cfg, cSets, sumEUR, sumDEM, sumBankCodes, sumAccountIds)) { DBG_INFO(AQBANKING_LOGDOMAIN, "Error creating E set"); GWEN_Buffer_free(dst); AB_Value_free(sumAccountIds); AB_Value_free(sumBankCodes); AB_Value_free(sumDEM); AB_Value_free(sumEUR); return -1; } AB_Value_free(sumAccountIds); AB_Value_free(sumBankCodes); AB_Value_free(sumDEM); AB_Value_free(sumEUR); /* DTAUS finished, write it */ p=(const uint8_t*)GWEN_Buffer_GetStart(dst); size=GWEN_Buffer_GetUsedBytes(dst); rv=GWEN_SyncIo_WriteForced(sio, p, size); if (rv<0) { DBG_ERROR(AQBANKING_LOGDOMAIN, "Broken pipe"); GWEN_Buffer_free(dst); return GWEN_ERROR_IO; } GWEN_Buffer_free(dst); return 0; }
AB_VALUE *AB_Value_fromString(const char *s) { AB_VALUE *v; const char *currency=NULL; int conversion_succeeded = 1; // assume conversion will succeed char *tmpString=NULL; char *p; char *t; char decimalComma; int isNeg=0; if( !s ) { DBG_ERROR(AQBANKING_LOGDOMAIN, "Attempt to convert a NULL value"); return NULL; } tmpString=strdup(s); p=tmpString; while(*p && *p<33) p++; if (*p=='-') { isNeg=1; p++; } else if (*p=='+') { p++; } t=strchr(p, ':'); if (t) { currency=t+1; *t=0; } /* remove thousand's comma */ decimalComma=AB_Value_determineDecimalComma(p); if (decimalComma) { char *s1, *d1; s1=p; d1=p; while(*s1) { register char c; c=*(s1++); if (isdigit(c) || c=='/') *(d1++)=c; else if (c==decimalComma) /* always use '.' as decimal comma */ *(d1++)='.'; } *d1=0; } v=AB_Value_new(); t=strchr(p, '.'); if (t) { // remove comma and calculate denominator unsigned long denominator = 1; char *next; do { next=t+1; *t=*next; if (*next != 0) denominator *= 10; t++; } while (*next); // set denominator to the calculated value mpz_set_ui(mpq_denref(v->value), denominator); // set numerator to the resulting integer string without comma if (mpz_set_str(mpq_numref(v->value), p, 10) == -1) { conversion_succeeded = 0; } } else { /*DBG_ERROR(0, "Scanning this value: %s\n", p);*/ conversion_succeeded = (gmp_sscanf(p, "%Qu", v->value) == 1); } /* set currency (if any) */ if (currency) v->currency=strdup(currency); /* temporary string no longer needed */ free(tmpString); if (!conversion_succeeded) { DBG_ERROR(AQBANKING_LOGDOMAIN, "[%s] is not a valid value", s); AB_Value_free(v); return NULL; } if (isNeg) mpq_neg(v->value, v->value); return v; }
int AH_ImExporterOFX_TransactionCallback_cb(const struct OfxTransactionData data, void *user_data) { AH_IMEXPORTER_OFX *ieh; DBG_INFO(AQBANKING_LOGDOMAIN, "Transaction callback"); ieh=(AH_IMEXPORTER_OFX *)user_data; if (!ieh->lastAccountInfo) { DBG_ERROR(AQBANKING_LOGDOMAIN, "Transaction but no account. Ignoring"); return -1; } else { AB_TRANSACTION *t; t=AB_Transaction_new(); if (data.account_id_valid) AB_Transaction_SetLocalAccountNumber(t, data.account_id); else AB_Transaction_SetLocalAccountNumber(t, "----"); if (data.date_posted_valid) { GWEN_TIME *ti; ti=GWEN_Time_fromSeconds(data.date_posted); AB_Transaction_SetValutaDate(t, ti); GWEN_Time_free(ti); } if (data.date_initiated_valid) { GWEN_TIME *ti; ti=GWEN_Time_fromSeconds(data.date_initiated); AB_Transaction_SetDate(t, ti); GWEN_Time_free(ti); } if (data.fi_id_valid) AB_Transaction_SetFiId(t, data.fi_id); if (data.name_valid) AB_Transaction_AddRemoteName(t, data.name, 0); if (data.memo_valid) AB_Transaction_AddPurpose(t, data.memo, 0); if (data.amount_valid) { AB_VALUE *val; const char *cur; cur=0; if (data.account_ptr) if (data.account_ptr->currency_valid) cur=data.account_ptr->currency; val=AB_Value_fromDouble(data.amount); assert(val); AB_Value_SetCurrency(val, cur); if (data.invtransactiontype_valid) /* negate for investment transaction type (hack, see KMyMoney) */ AB_Value_Negate(val); AB_Transaction_SetValue(t, val); AB_Value_free(val); } else { DBG_ERROR(AQBANKING_LOGDOMAIN, "No amount in transaction"); } if (data.transactiontype_valid) { switch (data.transactiontype) { case OFX_CHECK: AB_Transaction_SetTransactionKey(t, "CHK"); AB_Transaction_SetTransactionText(t, "Check"); break; case OFX_INT: AB_Transaction_SetTransactionKey(t, "INT"); AB_Transaction_SetTransactionText(t, "Interest"); break; case OFX_DIV: AB_Transaction_SetTransactionKey(t, "DIV"); AB_Transaction_SetTransactionText(t, "Dividend"); break; case OFX_SRVCHG: AB_Transaction_SetTransactionKey(t, "CHG"); AB_Transaction_SetTransactionText(t, "Service charge"); break; case OFX_FEE: AB_Transaction_SetTransactionKey(t, "BRF"); AB_Transaction_SetTransactionText(t, "Fee"); break; case OFX_DEP: AB_Transaction_SetTransactionKey(t, "LDP"); /* FIXME: not sure */ AB_Transaction_SetTransactionText(t, "Deposit"); break; case OFX_ATM: AB_Transaction_SetTransactionKey(t, "MSC"); /* misc */ AB_Transaction_SetTransactionText(t, "Cash dispenser"); break; case OFX_POS: AB_Transaction_SetTransactionKey(t, "MSC"); /* misc */ AB_Transaction_SetTransactionText(t, "Point of sale"); break; case OFX_XFER: AB_Transaction_SetTransactionKey(t, "TRF"); AB_Transaction_SetTransactionText(t, "Transfer"); break; case OFX_PAYMENT: AB_Transaction_SetTransactionKey(t, "TRF"); /* FIXME: not sure */ AB_Transaction_SetTransactionText(t, "Electronic payment"); break; case OFX_CASH: AB_Transaction_SetTransactionKey(t, "MSC"); /* FIXME: not sure */ AB_Transaction_SetTransactionText(t, "Cash"); break; case OFX_DIRECTDEP: AB_Transaction_SetTransactionKey(t, "LDP"); /* FIXME: not sure */ AB_Transaction_SetTransactionText(t, "Direct deposit"); break; case OFX_DIRECTDEBIT: AB_Transaction_SetTransactionKey(t, "MSC"); /* FIXME: not sure */ AB_Transaction_SetTransactionText(t, "Merchant initiated debit"); break; case OFX_REPEATPMT: AB_Transaction_SetTransactionKey(t, "STO"); AB_Transaction_SetTransactionText(t, "Standing order"); break; case OFX_DEBIT: case OFX_CREDIT: case OFX_OTHER: AB_Transaction_SetTransactionKey(t, "MSC"); /* FIXME: not sure */ break; } } /* if transaction type is valid */ else if (data.invtransactiontype_valid) { switch (data.invtransactiontype) { case OFX_BUYDEBT: case OFX_BUYMF: case OFX_BUYOPT: case OFX_BUYOTHER: case OFX_BUYSTOCK: AB_Transaction_SetTransactionKey(t, "BUY"); AB_Transaction_SetTransactionText(t, "Buy stocks or alike"); AB_Transaction_SetSubType(t, AB_Transaction_SubTypeBuy); break; case OFX_REINVEST: AB_Transaction_SetTransactionKey(t, "REINV"); AB_Transaction_SetTransactionText(t, "Reinvestment"); AB_Transaction_SetSubType(t, AB_Transaction_SubTypeReinvest); break; case OFX_SELLDEBT: case OFX_SELLMF: case OFX_SELLOPT: case OFX_SELLOTHER: case OFX_SELLSTOCK: AB_Transaction_SetTransactionKey(t, "BUY"); AB_Transaction_SetTransactionText(t, "Buy stocks or alike"); AB_Transaction_SetSubType(t, AB_Transaction_SubTypeSell); break; case OFX_INCOME: AB_Transaction_SetTransactionKey(t, "DIV"); AB_Transaction_SetTransactionText(t, "Dividend"); AB_Transaction_SetSubType(t, AB_Transaction_SubTypeDividend); break; /* rest is unhandled */ case OFX_CLOSUREOPT: AB_Transaction_SetTransactionText(t, "XCLOSUREOPT"); break; case OFX_INVEXPENSE: AB_Transaction_SetTransactionText(t, "XINVEXPENSE"); break; case OFX_JRNLFUND: AB_Transaction_SetTransactionText(t, "XJRNLFUND"); break; case OFX_MARGININTEREST: AB_Transaction_SetTransactionText(t, "XMARGININTEREST"); break; case OFX_RETOFCAP: AB_Transaction_SetTransactionText(t, "XRETOFCAP"); break; case OFX_SPLIT: AB_Transaction_SetTransactionText(t, "XSPLIT"); break; case OFX_TRANSFER: AB_Transaction_SetTransactionText(t, "XTRANSFER"); break; default: break; } #ifdef HAVE_OFX_0_8_PLUS if (data.fees_valid || data.commission_valid) { AB_VALUE *vFees; vFees=AB_Value_new(); if (data.fees_valid) { AB_VALUE *v; v=AB_Value_fromDouble(data.fees); AB_Value_AddValue(vFees, v); AB_Value_free(v); } if (data.commission_valid) { AB_VALUE *v; v=AB_Value_fromDouble(data.commission); AB_Value_AddValue(vFees, v); AB_Value_free(v); } AB_Transaction_SetFees(t, vFees); AB_Value_free(vFees); } #endif if (data.units_valid) AB_Transaction_SetUnits(t, data.units); #ifdef HAVE_OFX_0_8_PLUS if (data.unitprice_valid && data.fees_valid) { AB_VALUE *v; v=AB_Value_fromDouble(data.fees); /* TODO: add currency */ AB_Transaction_SetUnitPrice(t, v); AB_Value_free(v); } #endif } else { DBG_NOTICE(AQBANKING_LOGDOMAIN, "No transaction type"); } if (data.server_transaction_id_valid) AB_Transaction_SetBankReference(t, data.server_transaction_id); if (data.check_number_valid) AB_Transaction_SetCustomerReference(t, data.check_number); else if (data.reference_number_valid) AB_Transaction_SetCustomerReference(t, data.reference_number); DBG_INFO(0, "Adding transaction"); AB_ImExporterAccountInfo_AddTransaction(ieh->lastAccountInfo, t); } return 0; }