1 /***************************************************************************
2     begin       : Wed Dec 26 2018
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 
EBC_Provider_SendCommands(AB_PROVIDER * pro,AB_PROVIDERQUEUE * pq,AB_IMEXPORTER_CONTEXT * ctx)12 int EBC_Provider_SendCommands(AB_PROVIDER *pro, AB_PROVIDERQUEUE *pq, AB_IMEXPORTER_CONTEXT *ctx)
13 {
14   EBC_PROVIDER *hp;
15   AB_USERQUEUE_LIST *uql;
16   AB_USERQUEUE *uq;
17   int rv;
18 
19   assert(pro);
20   hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
21   assert(hp);
22 
23   /* sort into user queue list */
24   uql=AB_UserQueue_List_new();
25   rv=AB_Provider_SortProviderQueueIntoUserQueueList(pro, pq, uql);
26   if (rv<0) {
27     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
28     AB_Provider_FreeUsersAndAccountsFromUserQueueList(pro, uql);
29     AB_UserQueue_List_free(uql);
30     return rv;
31   }
32 
33   uq=AB_UserQueue_List_First(uql);
34   while (uq) {
35     int rv;
36 
37     rv=EBC_Provider__SendUserQueue(pro, uq, ctx);
38     if (rv<0) {
39       DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
40     }
41     uq=AB_UserQueue_List_Next(uq);
42   }
43 
44   /* release accounts and users we loaded */
45   AB_Provider_FreeUsersAndAccountsFromUserQueueList(pro, uql);
46 
47   return 0;
48 }
49 
50 
51 
EBC_Provider__SendUserQueue(AB_PROVIDER * pro,AB_USERQUEUE * uq,AB_IMEXPORTER_CONTEXT * ctx)52 int EBC_Provider__SendUserQueue(AB_PROVIDER *pro, AB_USERQUEUE *uq, AB_IMEXPORTER_CONTEXT *ctx)
53 {
54   AB_ACCOUNTQUEUE_LIST *aql;
55   AB_USER *u;
56   GWEN_HTTP_SESSION *sess;
57   int rv;
58 
59   assert(uq);
60   u=AB_UserQueue_GetUser(uq);
61   assert(u);
62   DBG_ERROR(0, "Handling user \"%lu\"", (unsigned long int) AB_User_GetUniqueId(u));
63 
64   sess=EBC_Dialog_new(pro, u);
65   rv=GWEN_HttpSession_Init(sess);
66   if (rv<0) {
67     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
68     GWEN_HttpSession_free(sess);
69     return rv;
70   }
71 
72   aql=AB_UserQueue_GetAccountQueueList(uq);
73   if (aql) {
74     AB_ACCOUNTQUEUE *aq;
75     int rv;
76 
77     GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Info, I18N("Locking customer \"%lu\""), (unsigned long int) AB_User_GetUniqueId(u));
78     rv=AB_Provider_BeginExclUseUser(pro, u);
79     if (rv<0) {
80       DBG_INFO(AQEBICS_LOGDOMAIN, "Could not lock user [%lu] (%d)", (unsigned long int) AB_User_GetUniqueId(u), rv);
81       GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Error, I18N("Could not lock user \"%lu\""),
82                             (unsigned long int) AB_User_GetUniqueId(u));
83       AB_Provider_EndExclUseUser(pro, u, 1);  /* abandon */
84       GWEN_HttpSession_Fini(sess);
85       GWEN_HttpSession_free(sess);
86       return rv;
87     }
88 
89     aq=AB_AccountQueue_List_First(aql);
90     while (aq) {
91       int rv;
92 
93       rv=EBC_Provider__SendAccountQueue(pro, u, aq, sess, ctx);
94       if (rv<0) {
95         DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
96       }
97 
98       aq=AB_AccountQueue_List_Next(aq);
99     } /* while aq */
100 
101     GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Info, I18N("Unlocking customer \"%lu\""),
102                           (unsigned long int) AB_User_GetUniqueId(u));
103     rv=AB_Provider_EndExclUseUser(pro, u, 0);
104     if (rv<0) {
105       GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Error, I18N("Could not unlock user \"%lu\""),
106                             (unsigned long int) AB_User_GetUniqueId(u));
107       AB_Provider_EndExclUseUser(pro, u, 1); /* abandon */
108       GWEN_HttpSession_Fini(sess);
109       GWEN_HttpSession_free(sess);
110       return rv;
111     }
112   }
113 
114   /* close and destroy session */
115   GWEN_HttpSession_Fini(sess);
116   GWEN_HttpSession_free(sess);
117 
118   return 0;
119 }
120 
121 
122 
EBC_Provider__SendAccountQueue(AB_PROVIDER * pro,AB_USER * u,AB_ACCOUNTQUEUE * aq,GWEN_HTTP_SESSION * sess,AB_IMEXPORTER_CONTEXT * ctx)123 int EBC_Provider__SendAccountQueue(AB_PROVIDER *pro, AB_USER *u, AB_ACCOUNTQUEUE *aq,
124                                    GWEN_HTTP_SESSION *sess, AB_IMEXPORTER_CONTEXT *ctx)
125 {
126   AB_JOBQUEUE_LIST *jql;
127   AB_ACCOUNT *a;
128 
129   a=AB_AccountQueue_GetAccount(aq);
130   assert(a);
131 
132   EBC_Provider_SortTransactionsIntoJobQueues(pro, aq);
133 
134   jql=AB_AccountQueue_GetJobQueueList(aq);
135   if (jql) {
136     AB_JOBQUEUE *jq;
137 
138     jq=AB_JobQueue_List_First(jql);
139     while (jq) {
140       AB_TRANSACTION_COMMAND cmd;
141       int rv;
142 
143       cmd=AB_JobQueue_GetJobType(jq);
144       switch (cmd) {
145       case AB_Transaction_CommandGetTransactions:
146         rv=EBC_Provider_ExecContext_STA(pro, ctx, u, a, sess, jq);
147         break;
148       case AB_Transaction_CommandTransfer:
149       case AB_Transaction_CommandDebitNote:
150       default:
151         rv=GWEN_ERROR_NOT_SUPPORTED;
152         break;
153       }
154 
155       if (rv<0) {
156         DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
157       }
158       jq=AB_JobQueue_List_Next(jq);
159     }
160   }
161 
162   return 0;
163 }
164 
165 
166 
167 
168 
EBC_Provider_SortTransactionsIntoJobQueues(AB_PROVIDER * pro,AB_ACCOUNTQUEUE * aq)169 void EBC_Provider_SortTransactionsIntoJobQueues(AB_PROVIDER *pro, AB_ACCOUNTQUEUE *aq)
170 {
171   AB_TRANSACTION_LIST2 *tl;
172 
173   tl=AB_AccountQueue_GetTransactionList(aq);
174   if (tl) {
175     AB_TRANSACTION_LIST2_ITERATOR *it;
176 
177     it=AB_Transaction_List2_First(tl);
178     if (it) {
179       AB_TRANSACTION *t;
180 
181       t=AB_Transaction_List2Iterator_Data(it);
182       while (t) {
183         AB_JOBQUEUE *jq;
184         AB_TRANSACTION_COMMAND cmd;
185 
186         cmd=AB_Transaction_GetCommand(t);
187         jq=AB_AccountQueue_FindJobQueue(aq, cmd);
188         if (jq==NULL) {
189           jq=AB_JobQueue_new();
190           AB_JobQueue_SetJobType(jq, cmd);
191           AB_AccountQueue_AddJobQueue(aq, jq);
192         }
193         if (cmd==AB_Transaction_CommandGetTransactions) {
194           AB_TRANSACTION *tFirst;
195 
196           tFirst=AB_JobQueue_GetFirstTransaction(jq);
197           if (tFirst) {
198             /* don't add, just set reference id */
199             AB_Transaction_SetRefUniqueId(t, AB_Transaction_GetUniqueId(tFirst));
200           }
201           else {
202             /* add */
203             AB_JobQueue_AddTransaction(jq, t);
204           }
205         }
206         else
207           AB_JobQueue_AddTransaction(jq, t);
208 
209         t=AB_Transaction_List2Iterator_Next(it);
210       }
211       AB_Transaction_List2Iterator_free(it);
212     }
213   }
214 }
215 
216 
217 
EBC_Provider_ExecContext_STA(AB_PROVIDER * pro,AB_IMEXPORTER_CONTEXT * ctx,GWEN_UNUSED AB_USER * u,GWEN_UNUSED AB_ACCOUNT * a,GWEN_HTTP_SESSION * sess,AB_JOBQUEUE * jq)218 int EBC_Provider_ExecContext_STA(AB_PROVIDER *pro,
219                                  AB_IMEXPORTER_CONTEXT *ctx,
220                                  GWEN_UNUSED AB_USER *u,
221                                  GWEN_UNUSED AB_ACCOUNT *a,
222                                  GWEN_HTTP_SESSION *sess,
223                                  AB_JOBQUEUE *jq)
224 {
225   EBC_PROVIDER *dp;
226   AB_TRANSACTION_LIST2 *jl;
227 
228   assert(pro);
229   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
230   assert(dp);
231 
232   jl=AB_JobQueue_GetTransactionList(jq);
233   if (jl) {
234     AB_TRANSACTION_LIST2_ITERATOR *jit;
235 
236     jit=AB_Transaction_List2_First(jl);
237     if (jit) {
238       AB_TRANSACTION *uj;
239 
240       uj=AB_Transaction_List2Iterator_Data(jit);
241       assert(uj);
242       while (uj) {
243         int rv;
244 
245         rv=EBC_Provider_DownloadIntoContextWithSession(pro, sess, u,
246                                                        "STA",
247                                                        1 /* withReceipt */,
248                                                        AB_Transaction_GetFirstDate(uj),
249                                                        AB_Transaction_GetLastDate(uj),
250                                                        "swift",
251                                                        "SWIFT-MT940",
252                                                        ctx,
253                                                        0 /* don't lock */);
254         if (rv<0 || rv>=300) {
255           if (rv==GWEN_ERROR_NO_DATA)
256             AB_Transaction_SetStatus(uj, AB_Transaction_StatusAccepted);
257           else {
258             AB_Transaction_SetStatus(uj, AB_Transaction_StatusRejected);
259             if (rv==GWEN_ERROR_USER_ABORTED) {
260               DBG_INFO(AQEBICS_LOGDOMAIN, "User aborted");
261               AB_Transaction_List2Iterator_free(jit);
262               return rv;
263             }
264           }
265         }
266 
267         uj=AB_Transaction_List2Iterator_Next(jit);
268       } /* while */
269       AB_Transaction_List2Iterator_free(jit);
270     }
271   } /* if jl */
272 
273   return 0;
274 }
275 
276 
277 #if 0
278 int EBC_Provider_ExecContext__IZV(AB_PROVIDER *pro,
279                                   AB_IMEXPORTER_CONTEXT *ctx,
280                                   AB_USER *u,
281                                   AB_ACCOUNT *a,
282                                   GWEN_HTTP_SESSION *sess,
283                                   EBC_CONTEXT *ectx)
284 {
285   EBC_PROVIDER *dp;
286   AB_JOB_LIST2_ITERATOR *jit;
287   AB_JOB_STATUS js;
288   AB_IMEXPORTER_CONTEXT *exCtx;
289   AB_IMEXPORTER_ACCOUNTINFO *ai;
290   GWEN_BUFFER *bufDtaus;
291   GWEN_TIME *currentTime;
292   GWEN_BUFFER *logbuf;
293   int rv;
294   const char *profileName=NULL;
295   const char *s;
296   const char *rqType;
297   uint32_t groupId=0;
298 
299   assert(pro);
300   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
301   assert(dp);
302 
303   /* prepare CTX log */
304   logbuf=GWEN_Buffer_new(0, 256, 0, 1);
305   GWEN_Buffer_AppendString(logbuf, "BEGIN");
306   currentTime=GWEN_CurrentTime();
307   GWEN_Time_toString(currentTime, I18N("YYYY/MM/DD-hh:mm:ss"), logbuf);
308   GWEN_Time_free(currentTime);
309   GWEN_Buffer_AppendString(logbuf, "\t");
310   GWEN_Buffer_AppendString(logbuf, I18N("National Mass Transfer"));
311   GWEN_Buffer_AppendString(logbuf, "\n");
312   GWEN_Buffer_AppendString(logbuf, "\t");
313   GWEN_Buffer_AppendString(logbuf, I18N("Transfer type: "));
314   GWEN_Buffer_AppendString(logbuf, "\t");
315 
316   switch (EBC_Context_GetJobType(ectx)) {
317   case AB_Job_TypeTransfer:
318     if (!profileName)
319       profileName="transfer";
320     GWEN_Buffer_AppendString(logbuf, I18N("Transfer"));
321     break;
322   case AB_Job_TypeDebitNote:
323     if (!profileName)
324       profileName="debitnote";
325     GWEN_Buffer_AppendString(logbuf, I18N("Debit Note"));
326     break;
327   default:
328     GWEN_Buffer_AppendString(logbuf, I18N("unknown"));
329     break;
330   }
331   GWEN_Buffer_AppendString(logbuf, "\n");
332 
333   GWEN_Buffer_AppendString(logbuf, "\t");
334   GWEN_Buffer_AppendString(logbuf, I18N("Account: "));
335   GWEN_Buffer_AppendString(logbuf, "\t");
336   GWEN_Buffer_AppendString(logbuf, AB_Account_GetBankCode(a));
337   GWEN_Buffer_AppendString(logbuf, " / ");
338   GWEN_Buffer_AppendString(logbuf, AB_Account_GetAccountNumber(a));
339   GWEN_Buffer_AppendString(logbuf, "\n");
340   /* add a tab-less line to start a new table */
341   GWEN_Buffer_AppendString(logbuf, "Transactions\n");
342 
343   DBG_INFO(AQEBICS_LOGDOMAIN, "Sampling transactions from jobs");
344   exCtx=AB_ImExporterContext_new();
345   ai=AB_ImExporterAccountInfo_new();
346   AB_ImExporterAccountInfo_FillFromAccount(ai, a);
347 
348   jit=AB_Job_List2_First(EBC_Context_GetJobs(ectx));
349   if (jit) {
350     AB_JOB *uj;
351 
352     uj=AB_Job_List2Iterator_Data(jit);
353     assert(uj);
354     while (uj) {
355       AB_TRANSACTION *t;
356       const char *s;
357       const AB_VALUE *v;
358 
359       switch (EBC_Context_GetJobType(ectx)) {
360       case AB_Job_TypeTransfer:
361       case AB_Job_TypeDebitNote:
362         t=AB_Job_GetTransaction(uj);
363         break;
364       default:
365         t=NULL;
366       }
367       assert(t);
368 
369       if (groupId==0)
370         /* take id from first job of the created DTAUS doc */
371         groupId=AB_Job_GetJobId(uj);
372       AB_Transaction_SetGroupId(t, groupId);
373 
374       AB_ImExporterAccountInfo_AddTransaction(ai, AB_Transaction_dup(t));
375       s=AB_Transaction_GetRemoteName(t);
376       if (!s)
377         s=I18N("unknown");
378       GWEN_Buffer_AppendString(logbuf, s);
379       GWEN_Buffer_AppendString(logbuf, "\t");
380       s=AB_Transaction_GetRemoteBankCode(t);
381       if (!s)
382         s="????????";
383       GWEN_Buffer_AppendString(logbuf, s);
384       GWEN_Buffer_AppendString(logbuf, "\t");
385       s=AB_Transaction_GetRemoteAccountNumber(t);
386       if (!s)
387         s="??????????";
388       GWEN_Buffer_AppendString(logbuf, s);
389       GWEN_Buffer_AppendString(logbuf, "\t");
390       s=AB_Transaction_GetPurpose(t);
391       if (!s)
392         s="";
393       GWEN_Buffer_AppendString(logbuf, s);
394       GWEN_Buffer_AppendString(logbuf, "\t");
395       v=AB_Transaction_GetValue(t);
396       if (v)
397         AB_Value_toHumanReadableString(v, logbuf, 2);
398       else
399         GWEN_Buffer_AppendString(logbuf, "0,00 EUR");
400       GWEN_Buffer_AppendString(logbuf, "\n");
401 
402       uj=AB_Job_List2Iterator_Next(jit);
403     } /* while */
404     AB_Job_List2Iterator_free(jit);
405   }
406   AB_ImExporterContext_AddAccountInfo(exCtx, ai);
407 
408   GWEN_Buffer_AppendString(logbuf, I18N("Results:\n"));
409 
410   /* export as DTAUS to bufDtaus */
411   bufDtaus=GWEN_Buffer_new(0, 1024, 0, 1);
412 
413   DBG_INFO(AQEBICS_LOGDOMAIN, "Exporting transactions to DTAUS[default]");
414   rv=AB_Banking_ExportToBuffer(AB_Provider_GetBanking(pro),
415                                exCtx,
416                                "dtaus",
417                                profileName,
418                                bufDtaus);
419   if (rv<0) {
420     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
421     GWEN_Buffer_free(bufDtaus);
422     EBC_Provider_SetJobListStatus(EBC_Context_GetJobs(ectx),
423                                   AB_Job_StatusError);
424     GWEN_Buffer_AppendString(logbuf, "\t");
425     GWEN_Buffer_AppendString(logbuf, I18N("Error while exporting to DTAUS\n"));
426     GWEN_Buffer_AppendString(logbuf, "END\n");
427 
428     GWEN_Buffer_free(logbuf);
429     return rv;
430   }
431 
432   GWEN_Buffer_AppendString(logbuf, "\t");
433   GWEN_Buffer_AppendString(logbuf, I18N("Exporting to DTAUS: ok\n"));
434 
435   /* exchange upload request */
436   DBG_INFO(AQEBICS_LOGDOMAIN, "Uploading.");
437   AB_HttpSession_ClearLog(sess);
438 
439   if (EBC_Context_GetJobType(ectx)==AB_Job_TypeDebitNote) {
440     if (EBC_User_GetFlags(u) & EBC_USER_FLAGS_USE_IZL)
441       rqType="IZL";
442     else
443       rqType="IZV";
444   }
445   else
446     rqType="IZV";
447   rv=EBC_Provider_XchgUploadRequest(pro, sess, u, rqType,
448                                     (const uint8_t *)GWEN_Buffer_GetStart(bufDtaus),
449                                     GWEN_Buffer_GetUsedBytes(bufDtaus));
450   if (rv<0 || rv>=300)
451     js=AB_Job_StatusError;
452   else
453     js=AB_Job_StatusFinished;
454 
455   s=AB_HttpSession_GetLog(sess);
456   if (s)
457     GWEN_Buffer_AppendString(logbuf, s);
458   GWEN_Buffer_AppendString(logbuf, "END\n");
459 
460   GWEN_Buffer_free(logbuf);
461 
462   EBC_Provider_SetJobListStatus(EBC_Context_GetJobs(ectx), js);
463 
464   DBG_INFO(AQEBICS_LOGDOMAIN, "Done");
465   return 0;
466 }
467 
468 
469 
470 int EBC_Provider_ExecContext_IZV(AB_PROVIDER *pro,
471                                  AB_IMEXPORTER_CONTEXT *ctx,
472                                  AB_USER *u,
473                                  AB_ACCOUNT *a,
474                                  GWEN_HTTP_SESSION *sess,
475                                  EBC_CONTEXT *ectx)
476 {
477   EBC_PROVIDER *dp;
478   AB_JOB_LIST2_ITERATOR *jit;
479   int rv;
480 
481   assert(pro);
482   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
483   assert(dp);
484 
485   DBG_INFO(AQEBICS_LOGDOMAIN, "Executing IZV request");
486   rv=EBC_Provider_ExecContext__IZV(pro, ctx, u, a, sess, ectx);
487 
488   jit=AB_Job_List2_First(EBC_Context_GetJobs(ectx));
489   if (jit) {
490     AB_JOB *uj;
491 
492     uj=AB_Job_List2Iterator_Data(jit);
493     assert(uj);
494     while (uj) {
495       const AB_TRANSACTION *ot;
496 
497       switch (EBC_Context_GetJobType(ectx)) {
498       case AB_Job_TypeTransfer:
499       case AB_Job_TypeDebitNote:
500         ot=AB_Job_GetTransaction(uj);
501         break;
502       default:
503         ot=NULL;
504       }
505 
506       assert(ot);
507       if (ot) {
508         AB_TRANSACTION *t;
509         AB_TRANSACTION_STATUS tStatus;
510 
511         switch (AB_Job_GetStatus(uj)) {
512         case AB_Job_StatusFinished:
513           tStatus=AB_Transaction_StatusAccepted;
514           break;
515         case AB_Job_StatusPending:
516           tStatus=AB_Transaction_StatusPending;
517           break;
518         default:
519           tStatus=AB_Transaction_StatusRejected;
520           break;
521         }
522 
523         t=AB_Transaction_dup(ot);
524         AB_Transaction_SetStatus(t, tStatus);
525         AB_Transaction_SetUniqueAccountId(t, AB_Account_GetUniqueId(a));
526         if (AB_Transaction_GetType(t)<=AB_Transaction_TypeNone)
527           AB_Transaction_SetType(t, AB_Transaction_TypeTransfer);
528         AB_ImExporterContext_AddTransaction(ctx, t);
529       }
530 
531       uj=AB_Job_List2Iterator_Next(jit);
532     } /* while */
533     AB_Job_List2Iterator_free(jit);
534   }
535 
536   return rv;
537 }
538 #endif
539 
540 
541 
542