1 package com.instantbank.collections.collectionsQueuing.ejb;
2
3 import java.io.FileOutputStream;
4 import java.io.PrintStream;
5 import java.sql.CallableStatement;
6 import java.sql.Connection;
7 import java.sql.PreparedStatement;
8 import java.sql.ResultSet;
9 import java.sql.Statement;
10 import java.sql.Types;
11 import java.text.SimpleDateFormat;
12 import java.util.Vector;
13 import javax.ejb.CreateException;
14 import javax.ejb.EJBContext;
15 import javax.ejb.SessionBean;
16 import javax.ejb.SessionContext;
17 import com.instantbank.collections.commonQueuing.ejb.QueueServices;
18 import com.instantbank.collections.commonQueuing.ejb.QueueServicesHome;
19 import com.instantbank.collections.util.DataAccess;
20 import com.instantbank.collections.util.DateUtils;
21 import com.instantbank.collections.util.InstantbankException;
22 import com.instantbank.collections.util.ServiceLocator;
23 import com.instantbank.collections.util.StringFormat;
24 import com.instantbank.collections.util.XMLDataAccess;
25 import com.instantbank.collections.util.XMLUtils;
26
27 public class CollectionsQueuingServicesBean
28 implements SessionBean {
29 private EJBContext context;
30
31
32 public CollectionsQueuingServicesBean() { }
33
34
35 public Long assertStopperQueue(Long companyId) throws InstantbankException {
36 boolean amountRuleFound;
37 DataAccess da = null;
38 boolean daysRuleFound;
39 boolean bRecoveryCode = false;
40 String fieldName;
41 ResultSet rs = null;
42 int sequence;
43 QueueServices services;
44 String sql;
45 Statement st = null;
46 Long stopperId;
47
48 try {
49 QueueServicesHome home = (QueueServicesHome)ServiceLocator.instance().createEJB("QueueServicesHome", QueueServicesHome.class, false);
50 services = home.create();
51 stopperId = services.getStopper(companyId, "A");
52
53 if(stopperId.longValue() != 0) {
54 da = new DataAccess();
55 da.connect();
56 st = da.getConnection().createStatement();
57 sql = "SELECT QPWR_SEQUENCE,QPWR_FIELD_NAME FROM QUEUE_PLANS_WHERE_RULES WHERE ";
58 sql += "(QPWR_QPLAN_ID=" + stopperId + ") ORDER BY QPWR_SEQUENCE";
59 rs = st.executeQuery(sql);
60 amountRuleFound = false;
61 daysRuleFound = false;
62 bRecoveryCode = false;
63
64 while(rs.next()) {
65 sequence = rs.getInt(1);
66 fieldName = rs.getString(2);
67 if(fieldName.equals("AGRM_AMOUNT_PAST_DUE")) {
68 amountRuleFound = true;
69 }
70 else if(fieldName.equals("AGRM_CURR_DEL_DAYS")) {
71 daysRuleFound = true;
72 }
73 else if(fieldName.equals("AGRM_RECOVERY_CODE")) {
74 bRecoveryCode = true;
75 }
76 else {
77 sql = "DELETE FROM QUEUE_PLANS_WHERE_RULES WHERE ";
78 sql += "(QPWR_QPLAN_ID=" + stopperId + ") AND ";
79 sql += "(QPWR_SEQUENCE=" + sequence + ")";
80 da.makeDelete(sql);
81 }
82 }
83
84 if(!amountRuleFound || !daysRuleFound) {
85 sql = "DELETE FROM QUEUE_PLANS_WHERE_RULES WHERE QPWR_QPLAN_ID=" + stopperId;
86 da.makeDelete(sql);
87
88 sql = "INSERT INTO QUEUE_PLANS_WHERE_RULES (";
89 sql += "QPWR_QPLAN_ID,";
90 sql += "QPWR_SEQUENCE,";
91 sql += "QPWR_TEST,";
92 sql += "QPWR_TABLE_NAME,";
93 sql += "QPWR_TABLE_ALIAS,";
94 sql += "QPWR_FIELD_NAME,";
95 sql += "QPWR_FIELD_TYPE,";
96 sql += "QPWR_OPERATOR,";
97 sql += "QPWR_VALUE,";
98 sql += "QPWR_VALUE_TYPE,";
99 sql += "QPWR_CONNECTOR ";
100 sql += ") VALUES (";
101 sql += stopperId + ",";
102 sql += "1,";
103 sql += "1,";
104 sql += "'AGREEMENTS',";
105 sql += "'AGREEMENTS',";
106 sql += "'AGRM_CURR_DEL_DAYS',";
107 sql += "'N',";
108 sql += "'>=',";
109 sql += "1,";
110 sql += "'K',";
111 sql += "'AND'";
112 sql += ")";
113 da.makeInsert(sql);
114
115 sql = "INSERT INTO QUEUE_PLANS_WHERE_RULES (";
116 sql += "QPWR_QPLAN_ID,";
117 sql += "QPWR_SEQUENCE,";
118 sql += "QPWR_TEST,";
119 sql += "QPWR_TABLE_NAME,";
120 sql += "QPWR_TABLE_ALIAS,";
121 sql += "QPWR_FIELD_NAME,";
122 sql += "QPWR_FIELD_TYPE,";
123 sql += "QPWR_OPERATOR,";
124 sql += "QPWR_VALUE,";
125 sql += "QPWR_VALUE_TYPE,";
126 sql += "QPWR_CONNECTOR ";
127 sql += ") VALUES (";
128 sql += stopperId + ",";
129 sql += "2,";
130 sql += "1,";
131 sql += "'AGREEMENTS',";
132 sql += "'AGREEMENTS',";
133 sql += "'AGRM_AMOUNT_PAST_DUE',";
134 sql += "'N',";
135 sql += "'>=',";
136 sql += "1,";
137 sql += "'K',";
138 sql += "'OR'";
139 sql += ")";
140 da.makeInsert(sql);
141
142 sql = "INSERT INTO QUEUE_PLANS_WHERE_RULES (";
143 sql += "QPWR_QPLAN_ID,";
144 sql += "QPWR_SEQUENCE,";
145 sql += "QPWR_TEST,";
146 sql += "QPWR_TABLE_NAME,";
147 sql += "QPWR_TABLE_ALIAS,";
148 sql += "QPWR_FIELD_NAME,";
149 sql += "QPWR_FIELD_TYPE,";
150 sql += "QPWR_OPERATOR,";
151 sql += "QPWR_VALUE,";
152 sql += "QPWR_VALUE_TYPE ";
153 sql += ") VALUES (";
154 sql += stopperId + ",";
155 sql += "3,";
156 sql += "1,";
157 sql += "'AGREEMENTS',";
158 sql += "'AGREEMENTS',";
159 sql += "'AGRM_RECOVERY_CODE',";
160 sql += "'S',";
161 sql += "'<>',";
162 sql += "0,";
163 sql += "'K'";
164 sql += ")";
165 da.makeInsert(sql);
166 }
167 }
168 return stopperId;
169 }
170 catch(Exception e) {
171 throw new InstantbankException(e, "511001", "Failed to read stopper queue");
172 }
173 finally {
174 try {
175 if(rs != null) {
176 rs.close();
177 }
178 if(st != null) {
179 st.close();
180 }
181 if(da != null) {
182 da.disconnect();
183 }
184 }
185 catch(Exception e) {
186 }
187 }
188 }
189
190
191 public String distributeDownload(Long downloadId, Long companyId) throws InstantbankException {
192 String xml;
193
194 xml = XMLUtils.setAnswer("OK", "1", "Download Distributed Successfully", "");
195 return xml;
196 }
197
198
199 public String distributeWork(Long queueId, Long companyId) throws InstantbankException {
200 Connection conn;
201 DataAccess da = null;
202 long records;
203 ResultSet rs = null;
204 SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
205 CallableStatement sp;
206 String sql;
207 Statement st = null;
208 java.util.Date today;
209 String xml;
210
211 try {
212 da = new DataAccess();
213 da.connect();
214 st = da.getConnection().createStatement();
215 today = DateUtils.today();
216 conn = da.getConnection();
217
218 sql = "begin GENERATE_WORK.DISTRIBUTE_WORK_AD_HOC(" + companyId + "," + queueId + ",TO_DATE('" + sdf.format(today) + "','mm-dd-yyyy')); end;";
219 sp = conn.prepareCall(sql);
220 sp.execute();
221 sql = "SELECT count(*) FROM WORK_ITEMS WHERE wrki_qplan_id=" + queueId;
222 rs = st.executeQuery(sql);
223 rs.next();
224 records = rs.getLong(1);
225 StringBuffer sb = new StringBuffer();
226 sb.append(XMLUtils.xmlHeader());
227 sb.append("<Answer>");
228 sb.append("<Status>OK</Status>");
229 sb.append("<Code>1</Code>");
230 sb.append("<Message>Work distributed sucessfully</Message>");
231 sb.append("<Description></Description>");
232 sb.append("<Records>" + records + "</Records>");
233 sb.append("</Answer>");
234 xml = sb.toString();
235 return xml;
236 }
237 catch(Exception e) {
238 setRollbackOnly();
239 throw new InstantbankException(e, "511002", "Failed to distribute the work for the queue");
240 }
241 finally {
242 try {
243 if(rs != null) {
244 rs.close();
245 }
246 if(st != null) {
247 st.close();
248 }
249 if(da != null) {
250 da.disconnect();
251 }
252 }
253 catch(Exception e) {
254 }
255 }
256 }
257
258
259 public String generateDownload(Long downloadId, Long companyId) throws InstantbankException {
260 Connection conn;
261 DataAccess da = null;
262 String fieldType;
263 String fileName;
264 int i;
265 int j;
266 String line;
267 int numFields;
268 String path;
269 ResultSet rs = null;
270 SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
271 CallableStatement sp;
272 String sql;
273 Statement st = null;
274 java.sql.Date valueDate;
275 String valueString;
276 Vector vector;
277 String xml;
278
279 try {
280 da = new DataAccess();
281 da.connect();
282 st = da.getConnection().createStatement();
283
284
285 rs = st.executeQuery("SELECT CCFG_DOWNLOAD_PATH FROM COLLECTIONS_CONFIG WHERE CCFG_CMP_ID=" + companyId);
286 if(!rs.next()) {
287 throw new InstantbankException("XXXXXX", "Missing Collections configuration for the company");
288 }
289 path = rs.getString(1);
290
291
292 rs = st.executeQuery("SELECT DOWN_NAME FROM DOWNLOADS WHERE DOWN_ID=" + downloadId);
293 if(!rs.next()) {
294 throw new InstantbankException("XXXXXX", "Failed to retrieve the download");
295 }
296 fileName = rs.getString(1);
297
298
299 rs = st.executeQuery("SELECT DOWNF_FIELD_TYPE FROM DOWNLOAD_FIELDS WHERE DOWNF_DOWN_ID=" + downloadId + " ORDER BY DOWNF_SEQUENCE");
300 vector = new Vector();
301 for(numFields = 0; true; ++numFields) {
302 if(!rs.next()) {
303 break;
304 }
305 fieldType = rs.getString(1);
306 vector.addElement(fieldType);
307 }
308
309
310 conn = da.getConnection();
311 sp = conn.prepareCall("begin GENERATE_WORK.GET_DOWNLOAD_SENTENCE(" + companyId + "," + downloadId + ",?); end;");
312 sp.registerOutParameter(1, Types.VARCHAR);
313 sp.execute();
314 sql = sp.getString(1);
315
316 PrintStream ps = new PrintStream(new FileOutputStream(path + fileName));
317 rs = st.executeQuery(sql);
318 for(i = 0; true; i++) {
319 if(!rs.next()) {
320 break;
321 }
322 line = "";
323 for(j = 0; j < vector.size(); j++) {
324 fieldType = (String)vector.get(j);
325 if(fieldType.equals("S")) {
326 valueString = rs.getString(j + 1);
327 line += "\"" + StringFormat.toSafeJavaString(valueString) + "\"";
328 }
329 else if(fieldType.equals("D")) {
330 valueDate = rs.getDate(j + 1);
331 line += "\"" + sdf.format(valueDate) + "\"";
332 }
333 else if(fieldType.equals("N")) {
334 valueString = rs.getString(j + 1);
335 line += valueString;
336 }
337 if(j < vector.size() - 1) {
338 line += ",";
339 }
340 }
341 ps.println(line);
342 }
343 ps.close();
344
345 StringBuffer sb = new StringBuffer();
346 sb.append(XMLUtils.xmlHeader());
347 sb.append("<Answer>");
348 sb.append("<Status>OK</Status>");
349 sb.append("<Code>1</Code>");
350 sb.append("<Message>Download generated sucessfully</Message>");
351 sb.append("<Description>File generated at '" + path + fileName + "'</Description>");
352 sb.append("<Records>" + i + "</Records>");
353 sb.append("</Answer>");
354 xml = sb.toString();
355 }
356 catch(Exception e) {
357 xml = XMLUtils.setAnswer("ERROR", "-1", e.getClass().getName(), e.getMessage());
358 }
359 finally {
360 try {
361 if(rs != null) {
362 rs.close();
363 }
364 if(st != null) {
365 st.close();
366 }
367 if(da != null) {
368 da.disconnect();
369 }
370 }
371 catch(Exception e) {
372 }
373 }
374 return xml;
375 }
376
377
378 public String generateWork(Long queueId, Long companyId) throws InstantbankException {
379 DataAccess da = null;
380 Connection conn = null;
381 long records;
382 ResultSet rs = null;
383 CallableStatement sp;
384 String sql = "";
385 String sqlQueue = "";
386 Statement st = null;
387 String xml = "";
388
389 try {
390 da = new DataAccess();
391 da.connect();
392 st = da.getConnection().createStatement();
393 conn = da.getConnection();
394 sp = conn.prepareCall("begin GENERATE_WORK.GENERATE_WORK_AD_HOC(" + companyId + "," + queueId + ",TO_DATE(SYSDATE)); end;");
395 sp.registerOutParameter(1, Types.VARCHAR);
396 sp.execute();
397 sqlQueue = sp.getString(1);
398 sql = "SELECT ";
399 sql += "COUNT(*) ";
400 sql += "FROM ";
401 sql += "TMP_WRKI_" + queueId + " ";
402 rs = st.executeQuery(sql);
403 rs.next();
404 records = rs.getLong(1);
405
406 StringBuffer sb = new StringBuffer();
407 sb.append(XMLUtils.xmlHeader());
408 sb.append("<Answer>");
409 sb.append("<Status>OK</Status>");
410 sb.append("<Code>1</Code>");
411 sb.append("<Message>Work generated sucessfully</Message>");
412 sb.append("<Description></Description>");
413 sb.append("<Records>" + records + "</Records>");
414 sb.append("</Answer>");
415 xml = sb.toString();
416
417 return xml;
418 }
419 catch(Exception e) {
420 setRollbackOnly();
421 throw new InstantbankException(e, "511003", "Failed to generate work for the queue");
422 }
423 finally {
424 try {
425 if(rs != null) {
426 rs.close();
427 }
428 if(st != null) {
429 st.close();
430 }
431 if(da != null) {
432 da.disconnect();
433 }
434 }
435 catch(Exception e) {
436 }
437 }
438 }
439
440
441 public String getDownloadAccounts(Long downloadId, Long companyId) throws InstantbankException {
442 XMLDataAccess da = null;
443 Connection conn = null;
444 CallableStatement sp;
445 String sql = "";
446 String xml = "";
447
448 try {
449 da = new XMLDataAccess("");
450 da.connect();
451 conn = da.getDataAccess().getConnection();
452 sp = conn.prepareCall("begin GENERATE_WORK.GET_DOWNLOAD_SENTENCE(" + companyId + "," + downloadId + ",?); end;");
453 sp.registerOutParameter(1, Types.VARCHAR);
454 sp.execute();
455 sql = sp.getString(1);
456 xml = da.getXml(sql, "Accounts", "Account");
457 return xml;
458 }
459 catch(Exception e) {
460 this.context.setRollbackOnly();
461 throw new InstantbankException(e, "511004", "Failed to get the accounts for the download");
462 }
463 finally {
464
465 }
466 }
467
468
469 public Long getRowsQueueAccounts(Long queueId, Long companyId) throws InstantbankException {
470 XMLDataAccess da = null;
471 Connection conn = null;
472 CallableStatement sp;
473 String sql = "";
474 String sqlQueue = "";
475 String xml = "";
476 ResultSet rs = null;
477 PreparedStatement ps = null;
478 Long maxRows = null;
479
480 try {
481 da = new XMLDataAccess("");
482 da.connect();
483 conn = da.getDataAccess().getConnection();
484 sp = conn.prepareCall("begin GENERATE_WORK.PREVIEW_WORK(" + companyId + "," + queueId + ",TO_DATE(SYSDATE),?); end;");
485 sp.registerOutParameter(1, Types.VARCHAR);
486 sp.execute();
487 sqlQueue = sp.getString(1);
488 sql = "SELECT Count(*)";
489 sql += "FROM ";
490 sql += "(" + sqlQueue + ")";
491 ps = conn.prepareStatement(sql);
492 rs = ps.executeQuery();
493 if(rs.next()) {
494 maxRows = new Long(rs.getLong(1));
495 }
496 else {
497 maxRows = new Long("0");
498 }
499
500 return maxRows;
501 }
502 catch(Exception e) {
503 return new Long("0");
504 }
505 }
506
507
508 public String getQueueAccounts(Long queueId, Long companyId, Long rowNum) throws InstantbankException {
509 XMLDataAccess da = null;
510 Connection conn = null;
511 CallableStatement sp;
512 String sql = "";
513 String sqlQueue = "";
514 String xml = "";
515 Long maxRows;
516
517 try {
518 da = new XMLDataAccess("");
519 da.connect();
520 maxRows = new Long("19");
521 conn = da.getDataAccess().getConnection();
522 sp = conn.prepareCall("begin GENERATE_WORK.PREVIEW_WORK(" + companyId + "," + queueId + ",TO_DATE(SYSDATE),?); end;");
523 sp.registerOutParameter(1, Types.VARCHAR);
524 sp.execute();
525 sqlQueue = sp.getString(1);
526 sql = "SELECT ";
527 sql += "AGRM2.AGRM_ID id,";
528 sql += "AGRM2.AGRM_CODE code,";
529 sql += "AGRM2.AGRM_CURR_DEL_DAYS delinquentdays,";
530 sql += "AGRM2.AGRM_AMOUNT_PAST_DUE delinquentamount,";
531 sql += "AGRM2.AGRM_BALANCE balance,";
532 sql += "CUST_FIRST_NAME || ' ' || CUST_LAST_NAME name,";
533 sql += "CUST_SSN ssn ";
534 sql += "FROM ";
535 sql += "(" + sqlQueue + ") Query,";
536 sql += "AGREEMENTS AGRM2,";
537 sql += "AGREEMENTS_CUST_LINKS,";
538 sql += "CUSTOMERS ";
539 sql += "WHERE ";
540 sql += "(AGRM2.AGRM_ID = QUERY.AGRM_ID) AND ";
541 sql += "(ACL_AGRM_ID = AGRM2.AGRM_ID) AND ";
542 sql += "(ACL_CSR_CODE = 'PR') AND ";
543 sql += "(CUST_ID = ACL_CUST_ID) AND";
544 sql += "(agrm_order between " + rowNum.toString() + " AND " + new Long(rowNum.longValue() + maxRows.longValue()).toString() + ")";
545 xml = da.getXml(sql, "Accounts", "Account");
546 return xml;
547 }
548 catch(Exception e) {
549 return "<Accounts></Accounts>";
550 }
551 }
552
553
554 public String getStopperQueue(Long companyId) throws InstantbankException {
555 String queue;
556 QueueServices services;
557 Long stopperId;
558
559 try {
560 QueueServicesHome home = (QueueServicesHome)ServiceLocator.instance().createEJB("QueueServicesHome", QueueServicesHome.class, false);
561 services = home.create();
562 stopperId = assertStopperQueue(companyId);
563
564 if(stopperId.longValue() != 0) {
565 queue = services.getQueue(stopperId, companyId);
566 }
567 else {
568 queue = newStopperQueue();
569 }
570 return queue;
571 }
572 catch(Exception e) {
573 throw new InstantbankException(e, "511006", "Failed to read stopper queue");
574 }
575 }
576
577
578 public String newStopperQueue() throws InstantbankException {
579 SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
580 java.util.Date today = new java.util.Date();
581 String xml;
582
583 try {
584 xml = XMLUtils.xmlHeader();
585 xml += "<Queue>";
586 xml += "<QueueFields>";
587 xml += "<id>0</id>";
588 xml += "<startdate>" + sdf.format(today) + "</startdate>";
589 xml += "<lastchangeddate>" + sdf.format(today) + "</lastchangeddate>";
590 xml += "<status>A</status>";
591 xml += "</QueueFields>";
592 xml += "<RulesList>";
593 xml += "<Rule>";
594 xml += "<test>1</test>";
595 xml += "<tablename>AGREEMENTS</tablename>";
596 xml += "<tablealias>AGREEMENTS</tablealias>";
597 xml += "<fieldname>AGRM_CURR_DEL_DAYS</fieldname>";
598 xml += "<fieldtype>N</fieldtype>";
599 xml += "<operator>>=</operator>";
600 xml += "<value>1</value>";
601 xml += "<valuetype>K</valuetype>";
602 xml += "<connector>AND</connector>";
603 xml += "</Rule>";
604
605 xml += "<Rule>";
606 xml += "<test>1</test>";
607 xml += "<tablename>AGREEMENTS</tablename>";
608 xml += "<tablealias>AGREEMENTS</tablealias>";
609 xml += "<fieldname>AGRM_AMOUNT_PAST_DUE</fieldname>";
610 xml += "<fieldtype>N</fieldtype>";
611 xml += "<operator>>=</operator>";
612 xml += "<value>1</value>";
613 xml += "<valuetype>K</valuetype>";
614 xml += "<connector></connector>";
615 xml += "</Rule>";
616 xml += "</RulesList>";
617 xml += "<SortList/>";
618 xml += "<DistributionList/>";
619 xml += "</Queue>";
620 }
621 catch(Exception e) {
622 setRollbackOnly();
623 throw new InstantbankException(e, "511007", "Failed to create a new queue");
624 }
625 return xml;
626 }
627
628
629 public void ejbCreate() throws CreateException {
630
631 }
632
633
634 public void ejbActivate() { }
635
636
637 public void ejbPassivate() { }
638
639
640 public void ejbRemove() { }
641
642
643 private void setRollbackOnly() {
644 try {
645 this.context.setRollbackOnly();
646 }
647 catch(Exception e) {
648 }
649 }
650
651
652 public void setSessionContext(SessionContext ctx) {
653 this.context = ctx;
654 }
655 }
656
657