1 /***************************************************************************
2     begin       : Wed Jan 08 2014
3     copyright   : (C) 2018 by Martin Preuss
4     email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *          Please see toplevel file COPYING for license details           *
8  ***************************************************************************/
9 
10 
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14 
15 
16 #include "jobsepaxfermulti_p.h"
17 #include "jobtransferbase_l.h"
18 #include "aqhbci_l.h"
19 #include "accountjob_l.h"
20 #include "job_l.h"
21 #include "user_l.h"
22 #include "provider_l.h"
23 #include "hhd_l.h"
24 
25 #include <gwenhywfar/debug.h>
26 #include <gwenhywfar/misc.h>
27 #include <gwenhywfar/inherit.h>
28 #include <gwenhywfar/text.h>
29 
30 #include <assert.h>
31 #include <ctype.h>
32 
33 
34 
35 GWEN_INHERIT(AH_JOB, AH_JOB_SEPAXFERMULTI);
36 
37 
38 
39 
40 /* --------------------------------------------------------------- FUNCTION */
AH_Job_SepaTransferMulti_new(AB_PROVIDER * pro,AB_USER * u,AB_ACCOUNT * account)41 AH_JOB *AH_Job_SepaTransferMulti_new(AB_PROVIDER *pro, AB_USER *u, AB_ACCOUNT *account)
42 {
43   AH_JOB *j;
44   AH_JOB_SEPAXFERMULTI *aj;
45   GWEN_DB_NODE *dbParams;
46   const char *s;
47 
48   j=AH_Job_TransferBase_new("JobSepaTransferMulti",
49                             AB_Transaction_TypeTransfer,
50                             AB_Transaction_SubTypeStandard,
51                             pro, u, account);
52   if (!j)
53     return 0;
54 
55   AH_Job_SetChallengeClass(j, 13);
56 
57   GWEN_NEW_OBJECT(AH_JOB_SEPAXFERMULTI, aj);
58   GWEN_INHERIT_SETDATA(AH_JOB, AH_JOB_SEPAXFERMULTI, j, aj,
59                        AH_Job_SepaTransferMulti_FreeData);
60 
61   AH_Job_SetSupportedCommand(j, AB_Transaction_CommandSepaTransfer);
62 
63   /* overwrite some virtual functions */
64   AH_Job_SetPrepareFn(j, AH_Job_SepaTransferMulti_Prepare);
65   AH_Job_SetGetLimitsFn(j, AH_Job_TransferBase_GetLimits_SepaUndated);
66   AH_Job_SetHandleCommandFn(j, AH_Job_TransferBase_HandleCommand_SepaUndated);
67   AH_Job_SetAddChallengeParamsFn(j, AH_Job_SepaTransferMulti_AddChallengeParams);
68 
69   /* get params */
70   dbParams=AH_Job_GetParams(j);
71   assert(dbParams);
72 
73   AH_Job_SetMaxTransfers(j, GWEN_DB_GetIntValue(dbParams, "maxTransfers", 0, 0));
74 
75   s=GWEN_DB_GetCharValue(dbParams, "sumFieldNeeded", 0, "j");
76   if (s && toupper(*s)=='J')
77     aj->sumFieldNeeded=1;
78   else
79     aj->sumFieldNeeded=0;
80 
81   s=GWEN_DB_GetCharValue(dbParams, "singleBookingAllowed", 0, "j");
82   if (s && toupper(*s)=='J')
83     aj->singleBookingAllowed=1;
84   else
85     aj->singleBookingAllowed=0;
86 
87   return j;
88 }
89 
90 
91 
92 /* --------------------------------------------------------------- FUNCTION */
AH_Job_SepaTransferMulti_FreeData(void * bp,void * p)93 void GWENHYWFAR_CB AH_Job_SepaTransferMulti_FreeData(void *bp, void *p)
94 {
95   AH_JOB_SEPAXFERMULTI *aj;
96 
97   aj=(AH_JOB_SEPAXFERMULTI *)p;
98 
99   AB_Value_free(aj->sumValues);
100 
101   GWEN_FREE_OBJECT(aj);
102 }
103 
104 
105 
106 /* --------------------------------------------------------------- FUNCTION */
AH_Job_SepaTransferMulti_AddChallengeParams(AH_JOB * j,int hkTanVer,GWEN_DB_NODE * dbMethod)107 int AH_Job_SepaTransferMulti_AddChallengeParams(AH_JOB *j, int hkTanVer, GWEN_DB_NODE *dbMethod)
108 {
109   AH_JOB_SEPAXFERMULTI *aj;
110   const AB_TRANSACTION *t;
111   const char *s;
112   int tanVer=AH_JOB_TANVER_1_4;
113 
114   DBG_ERROR(AQHBCI_LOGDOMAIN, "AddChallengeParams function called");
115 
116   assert(j);
117   aj=GWEN_INHERIT_GETDATA(AH_JOB, AH_JOB_SEPAXFERMULTI, j);
118   assert(aj);
119 
120   /* get data from first transaction */
121   t=AH_Job_GetFirstTransfer(j);
122   if (t==NULL) {
123     DBG_ERROR(AQHBCI_LOGDOMAIN, "No validated transaction");
124     return GWEN_ERROR_INVALID;
125   }
126 
127   s=GWEN_DB_GetCharValue(dbMethod, "zkaTanVersion", 0, NULL);
128   if (s && *s && strncasecmp(s, "1.3", 3)==0) {
129     DBG_ERROR(AQHBCI_LOGDOMAIN, "TAN version is 1.3 (%s)", s);
130     tanVer=AH_JOB_TANVER_1_3;
131   }
132 
133   if (tanVer==AH_JOB_TANVER_1_4) {
134     int rv;
135 
136     DBG_ERROR(AQHBCI_LOGDOMAIN, "TAN version is 1.4.x");
137     rv=AH_HHD14_AddChallengeParams_13(j,
138                                       AH_Job_GetTransferCount(j),
139                                       aj->sumValues,
140                                       AB_Transaction_GetLocalIban(t));
141     if (rv<0) {
142       DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
143       return rv;
144     }
145   }
146   else {
147     DBG_ERROR(AQHBCI_LOGDOMAIN, "Unhandled tan version %d for now", tanVer);
148     return GWEN_ERROR_INTERNAL;
149   }
150   return 0;
151 }
152 
153 
154 
155 /* --------------------------------------------------------------- FUNCTION */
AH_Job_SepaTransferMulti_Prepare(AH_JOB * j)156 int AH_Job_SepaTransferMulti_Prepare(AH_JOB *j)
157 {
158   AH_JOB_SEPAXFERMULTI *aj;
159   GWEN_DB_NODE *dbArgs;
160   int rv;
161   AB_TRANSACTION *t;
162 
163   DBG_INFO(AQHBCI_LOGDOMAIN, "Preparing transfers");
164 
165   assert(j);
166   aj=GWEN_INHERIT_GETDATA(AH_JOB, AH_JOB_SEPAXFERMULTI, j);
167   assert(aj);
168 
169   dbArgs=AH_Job_GetArguments(j);
170 
171   /* calculate sum */
172   AB_Value_free(aj->sumValues);
173   aj->sumValues=AB_Value_new();
174   AB_Value_SetCurrency(aj->sumValues, "EUR");
175   t=AH_Job_GetFirstTransfer(j);
176   if (t==NULL) {
177     DBG_ERROR(AQHBCI_LOGDOMAIN, "No transaction in job");
178     return GWEN_ERROR_INTERNAL;
179   }
180   while (t) {
181     const AB_VALUE *v;
182 
183     v=AB_Transaction_GetValue(t);
184     if (v) {
185       const char *s;
186 
187       s=AB_Value_GetCurrency(v);
188       if (s && strcmp(s, "EUR")) {
189         DBG_ERROR(AQHBCI_LOGDOMAIN, "EUR required in SEPA transactions (%s)", s);
190         return GWEN_ERROR_BAD_DATA;
191       }
192       AB_Value_AddValue(aj->sumValues, v);
193     }
194     t=AB_Transaction_List_Next(t);
195   }
196 
197 
198   rv=AH_Job_TransferBase_SelectPainProfile(j, 1);
199   if (rv<0) {
200     DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
201     return rv;
202   }
203 
204 
205   /* set singleBookingWanted */
206   GWEN_DB_SetCharValue(dbArgs, GWEN_DB_FLAGS_OVERWRITE_VARS, "singleBookingWanted", (aj->singleBookingAllowed)?"J":"N");
207 
208   /* export transfers to SEPA */
209   rv=AH_Job_TransferBase_SepaExportTransactions(j);
210   if (rv<0) {
211     DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
212     return rv;
213   }
214 
215   /* store sum value */
216   if (1) {
217     GWEN_DB_NODE *dbV;
218     GWEN_BUFFER *nbuf;
219     const char *s;
220 
221     dbV=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_OVERWRITE_GROUPS, "totalSum");
222     assert(dbV);
223 
224     nbuf=GWEN_Buffer_new(0, 32, 0, 1);
225     AB_Value_toHbciString(aj->sumValues, nbuf);
226     if (GWEN_Buffer_GetUsedBytes(nbuf)<1) {
227       DBG_ERROR(AQHBCI_LOGDOMAIN, "Error in conversion");
228       GWEN_Buffer_free(nbuf);
229       return GWEN_ERROR_BAD_DATA;
230     }
231 
232     /* store value */
233     GWEN_DB_SetCharValue(dbV, GWEN_DB_FLAGS_OVERWRITE_VARS,
234                          "value",
235                          GWEN_Buffer_GetStart(nbuf));
236     GWEN_Buffer_free(nbuf);
237 
238     /* store currency */
239     s=AB_Value_GetCurrency(aj->sumValues);
240     assert(s);
241     GWEN_DB_SetCharValue(dbV, GWEN_DB_FLAGS_OVERWRITE_VARS, "currency", s);
242   }
243   return 0;
244 }
245 
246 
247 
248 
249 
250 
251 
252