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        // Stopper Id=0 when generating work ad hoc
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        // Finds the path for generating the download file
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        // Finds the name of the download
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        // Loads the types of the fields to download into a vector
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        // Gets the SQL sentence for the download
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        // Retrieve the downloaded accounts
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      // TODO:  Add custom implementation.
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