16. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 11/14/2017 6:57:19 AM Central Standard Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

16.1 Files compared

# Location File Last Modified
1 cbs.zip\cbs\cbs\src\main\java\gov\va\cpss\jasper PdfPatientStatementFactoryService.java Thu Nov 9 14:19:42 2017 UTC
2 cbs.zip\cbs\cbs\src\main\java\gov\va\cpss\jasper PdfPatientStatementFactoryService.java Tue Nov 14 12:34:04 2017 UTC

16.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 1730
Changed 1 2
Inserted 0 0
Removed 0 0

16.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

16.4 Active regular expressions

No regular expressions were active.

16.5 Comparison detail

  1   package go v.va.cpss. jasper;
  2  
  3   import jav a.awt.Imag e;
  4   import jav a.io.IOExc eption;
  5   import jav a.io.Input Stream;
  6   import jav a.text.Sim pleDateFor mat;
  7   import jav a.util.Arr ayList;
  8   import jav a.util.Arr ays;
  9   import jav a.util.Dat e;
  10   import jav a.util.Has hMap;
  11   import jav a.util.Lin kedHashMap ;
  12   import jav a.util.Lis t;
  13   import jav a.util.Map ;
  14  
  15   import jav ax.imageio .ImageIO;
  16  
  17   import org .apache.lo g4j.Logger ;
  18  
  19   import com .ibm.icu.u til.Calend ar;
  20  
  21   import gov .va.cpss.c obol.Money ;
  22   import gov .va.cpss.d ao.CBSSite StmtDAO;
  23   import gov .va.cpss.d ao.CBSSite TransDAO;
  24   import gov .va.cpss.d ao.CBSStmt DAO;
  25   import gov .va.cpss.j ob.sendcbs .SendCBSRu ntimeState Impl;
  26   import gov .va.cpss.j ob.sendcbs .SendCBSWr itePSRecor dSource;
  27   import gov .va.cpss.m odel.cbs.C BSSiteStmt ;
  28   import gov .va.cpss.m odel.cbs.C BSSiteTran s;
  29   import gov .va.cpss.m odel.cbs.C BSStmt;
  30   import gov .va.cpss.m odel.fps.P SDetails;
  31   import gov .va.cpss.m odel.fps.P SPatient;
  32   import gov .va.cpss.m odel.fps.P SRecord;
  33   import gov .va.cpss.m odel.fps.P SSite;
  34   import gov .va.cpss.m odel.fps.P SSiteStmt;
  35   import gov .va.cpss.m odel.updat estation.A ddress;
  36   import gov .va.cpss.m odel.updat estation.S tationInfo ;
  37   import gov .va.cpss.s ervice.Sta tionInfoUt il;
  38   import net .sf.jasper reports.en gine.JRExc eption;
  39   import net .sf.jasper reports.en gine.Jaspe rCompileMa nager;
  40   import net .sf.jasper reports.en gine.Jaspe rExportMan ager;
  41   import net .sf.jasper reports.en gine.Jaspe rFillManag er;
  42   import net .sf.jasper reports.en gine.Jaspe rPrint;
  43   import net .sf.jasper reports.en gine.Jaspe rReport;
  44   import net .sf.jasper reports.en gine.data. JRBeanColl ectionData Source;
  45  
  46   /**
  47    * Service  class to  create a P DF for a C BSStmt rec ord.
  48    * 
  49    * @author   DN S      BROWNL
  50    */
  51   public cla ss PdfPati entStateme ntFactoryS ervice {
  52  
  53           pr ivate stat ic final L ogger logg er = Logge r.getLogge r(PdfPatie ntStatemen tFactorySe rvice.clas s.getCanon icalName() );
  54           
  55           pr ivate Clas sLoader cl assLoader  = PdfPatie ntStatemen tFactorySe rvice.clas s.getClass Loader();
  56  
  57           //  AITC temp late speci fies that  the first  page shoul d not have  more than
  58           //  this many  lines.
  59           pr ivate stat ic final i nt MAX_LEN GTH_FIRST_ PAGE = 22;
  60           
  61           pr ivate stat ic final i nt MAX_LEN GTH_EXTENS ION_PAGE =  38;
  62  
  63           //  The accou nt number  is split o n the repo rt.
  64           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_1 = 0;
  65           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _1 = 3;
  66  
  67           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_2 = 3;
  68           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _2 = 3;
  69  
  70           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_3 = 6;
  71           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _3 = 3;
  72  
  73           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_4 = 9;
  74           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _4 = 4;
  75  
  76           //  The lengt h of this  is optiona l, dependi ng on the  length of  last name.
  77           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_5 = 13;
  78  
  79           //  Dates on  report are  formatted  MM/dd/yyy y
  80           pr ivate stat ic final S tring REPO RT_DATE_FO RMAT = "MM /dd/yyyy";
  81           
  82           //  Number of  days to a dd to stat ement date  to get th e full pay ment date.
  83           pr ivate stat ic final i nt FULL_PA YMENT_DAY_ NUMBER_DEL TA = 25;
  84           
  85           //  Credit va lues have  trailing C R
  86           pr ivate stat ic final S tring CRED IT_SUFFIX  = "CR";
  87  
  88           pr ivate CBSS tmtDAO cbs StmtDAO;
  89  
  90           pr ivate CBSS iteStmtDAO  cbsSiteSt mtDAO;
  91  
  92           pr ivate CBSS iteTransDA O cbsSiteT ransDAO;
  93           
  94   //      pr ivate Stat ionInfoUti l stationI nfoService ;
  95           
  96           pr ivate Jasp erReport m ainReport;
  97           pr ivate Jasp erReport d etailSubre port;
  98           pr ivate Jasp erReport s iteTitleSu breport;
  99           pr ivate Jasp erReport s iteTotalSu breport;
  100           pr ivate Jasp erReport s iteDelimit erSubrepor t;
  101           pr ivate Jasp erReport s iteTrailin gSpaceSubr eport;
  102           pr ivate Jasp erReport s iteFillerS paceSubrep ort;
  103           pr ivate Jasp erReport d etailEntry Subreport;
  104           pr ivate Jasp erReport s iteLateStm tSubreport ;
  105           
  106           pr ivate Imag e vaLogo;
  107           pr ivate Imag e checkbox ;
  108  
  109           pu blic CBSSt mtDAO getC bsStmtDAO( ) {
  110                    retu rn cbsStmt DAO;
  111           }
  112  
  113           pu blic void  setCbsStmt DAO(CBSStm tDAO cbsSt mtDAO) {
  114                    this .cbsStmtDA O = cbsStm tDAO;
  115           }
  116  
  117           pu blic CBSSi teStmtDAO  getCbsSite StmtDAO()  {
  118                    retu rn cbsSite StmtDAO;
  119           }
  120  
  121           pu blic void  setCbsSite StmtDAO(CB SSiteStmtD AO cbsSite StmtDAO) {
  122                    this .cbsSiteSt mtDAO = cb sSiteStmtD AO;
  123           }
  124  
  125           pu blic CBSSi teTransDAO  getCbsSit eTransDAO( ) {
  126                    retu rn cbsSite TransDAO;
  127           }
  128  
  129           pu blic void  setCbsSite TransDAO(C BSSiteTran sDAO cbsSi teTransDAO ) {
  130                    this .cbsSiteTr ansDAO = c bsSiteTran sDAO;
  131           }
  132  
  133   //      pu blic Stati onInfoServ ice getSta tionInfoSe rvice() {
  134   //               retu rn station InfoServic e;
  135   //      }
  136   //
  137   //      pu blic void  setStation InfoServic e(StationI nfoService  stationIn foService)  {
  138   //               this .stationIn foService  = stationI nfoService ;
  139   //      }
  140           
  141           pu blic void  initJasper Report(){
  142                    try{
  143                             logger .info("Com piling Jas per Report s");
  144                             String  mainRepor tJasper =  "Consolida tedPatient Statement. jrxml";
  145                             String  detailSub reportJasp er = "CpsS iteSubrepo rt.jrxml";
  146                             String  siteTitle SubreportJ asper = "C psSiteTitl eSubreport .jrxml";
  147                             String  siteTotal SubreportJ asper = "C psSiteTota lSubreport .jrxml";
  148                             String  siteDelim iterSubrep ortJasper  = "CpsSite DelimiterS ubreport.j rxml";
  149                             String  siteTrail ingSpaceSu breportJas per = "Cps SiteTraili ngSpaceSub report.jrx ml";
  150                             String  siteFille rSpaceSubr eportJaspe r = "CpsSi teFillerSp aceSubrepo rt.jrxml";
  151                             String  detailEnt rySubrepor tJasper =  "CpsSiteEn trySubrepo rt.jrxml";
  152                             String  siteLateS tmtJasper  = "CpsSite LateStmtSu breport.jr xml";
  153                             
  154                             InputS tream main ReportIS = classLoade r.getResou rceAsStrea m(mainRepo rtJasper);
  155                             InputS tream deta ilSubrepor tIS =class Loader.get ResourceAs Stream(det ailSubrepo rtJasper);
  156                             InputS tream site TitleSubre portIS =cl assLoader. getResourc eAsStream( siteTitleS ubreportJa sper);
  157                             InputS tream site TotalSubre portIS =cl assLoader. getResourc eAsStream( siteTotalS ubreportJa sper);
  158                             InputS tream site DelimiterS ubreportIS  =classLoa der.getRes ourceAsStr eam(siteDe limiterSub reportJasp er);
  159                             InputS tream site TrailingSp aceSubrepo rtIS =clas sLoader.ge tResourceA sStream(si teTrailing SpaceSubre portJasper );
  160                             InputS tream site FillerSpac eSubreport IS =classL oader.getR esourceAsS tream(site FillerSpac eSubreport Jasper);
  161                             InputS tream deta ilEntrySub reportIS = classLoade r.getResou rceAsStrea m(detailEn trySubrepo rtJasper);
  162                             InputS tream site LateStmtIS  = classLo ader.getRe sourceAsSt ream(siteL ateStmtJas per);
  163                             
  164                             InputS tream vaLo goIs =clas sLoader.ge tResourceA sStream("7 _VA_1COLOR _HORIZONT_ 12C9F6.jpg ");
  165                             InputS tream chec kboxIs =cl assLoader. getResourc eAsStream( "checkbox. png");
  166                             vaLogo  = ImageIO .read(vaLo goIs);
  167                             checkb ox = Image IO.read(ch eckboxIs);
  168                             
  169                             // Com pile the m ain report  file to a n object t o populate
  170                             // dyn amically.
  171                             mainRe port = Jas perCompile Manager.co mpileRepor t(mainRepo rtIS);
  172                             detail Subreport  = JasperCo mpileManag er.compile Report(det ailSubrepo rtIS);
  173                             siteTi tleSubrepo rt = Jaspe rCompileMa nager.comp ileReport( siteTitleS ubreportIS );
  174                             siteTo talSubrepo rt = Jaspe rCompileMa nager.comp ileReport( siteTotalS ubreportIS );
  175                             siteDe limiterSub report = J asperCompi leManager. compileRep ort(siteDe limiterSub reportIS);
  176                             siteTr ailingSpac eSubreport  = JasperC ompileMana ger.compil eReport(si teTrailing SpaceSubre portIS);
  177                             siteFi llerSpaceS ubreport =  JasperCom pileManage r.compileR eport(site FillerSpac eSubreport IS);
  178                             detail EntrySubre port = Jas perCompile Manager.co mpileRepor t(detailEn trySubrepo rtIS);
  179                             siteLa teStmtSubr eport = Ja sperCompil eManager.c ompileRepo rt(siteLat eStmtIS);
  180  
  181                    } ca tch (Numbe rFormatExc eption e)  {
  182                             // Sca n Line may  throw thi s.
  183                             logger .error("Nu mber Forma t Exceptio n: "+e.get Message()) ;
  184  
  185                    } ca tch (JRExc eption e)  {
  186                             // Jas per may th row this.
  187                             logger .error("JR  Exception : "+e.getM essage());
  188  
  189                    } ca tch (IOExc eption e)  {
  190                             // TOD O Auto-gen erated cat ch block
  191                             logger .error(e.g etMessage( ));
  192                    }
  193           }
  194           /* *
  195            *  Generate  a PDF stat ement for  the specif ied CBSStm t ID
  196            *  
  197            *  @param cb sStmtId
  198            *              The CBSS tmt ID.
  199            *  @return p df
  200            *                         The gene rated pdf  as a byte  array
  201            * /
  202           pu blic byte[ ] generate StatementP dfStream(f inal long  cbsStmtId)  {
  203  
  204                    Jasp erPrint ja sperPrint  = generate StatementP dfPrint(cb sStmtId);
  205                    byte  [] pdf=nu ll;
  206                    if ( jasperPrin t != null)  {
  207                             System .out.print ln("AFTER  Generation ");
  208  
  209                             // Exp ort the dy namically  filled rep ort to dis k.
  210                             try {
  211                                      
  212                                      // Expor t the dyna mically fi lled repor t to strea m.
  213                                      pdf = Ja sperExport Manager.ex portReport ToPdf(jasp erPrint);
  214                                      
  215  
  216                             } catc h (JRExcep tion e) {
  217                                      logger.e rror(e.get Message()) ;
  218                             }
  219  
  220                    } el se {
  221                             logger .error("ja sperPrint  is null");
  222                    }
  223                    retu rn pdf;
  224           }
  225  
  226           /* *
  227            *  Generate  a PDF stat ement for  the specif ied CBSStm t ID outpu t on the
  228            *  provided  stream.
  229            *  
  230            *  @param cb sStmtId
  231            *              The CBSS tmt ID.
  232            *  @param ou tputFile
  233            *              The file name for w hich to ou tput the P DF.
  234            * /
  235           pu blic void  generateSt atementPdf File(final  long cbsS tmtId, fin al String  outputFile ) {
  236  
  237                    Jasp erPrint ja sperPrint  = generate StatementP dfPrint(cb sStmtId);
  238  
  239                    if ( jasperPrin t != null)  {
  240                             logger .info("AFT ER Generat ion: " + o utputFile) ;
  241  
  242                             // Exp ort the dy namically  filled rep ort to dis k.
  243                             try {
  244  
  245                                      JasperEx portManage r.exportRe portToPdfF ile(jasper Print, out putFile);
  246                             } catc h (JRExcep tion e) {
  247                                      // TODO  Auto-gener ated catch  block
  248                                      logger.e rror(e.get Message()) ;
  249                             }
  250  
  251                    } el se {
  252                             // TOD O, log err or
  253                             logger .error("Cb s Stmt ID  not found:  " + cbsSt mtId);
  254                    }
  255           }
  256  
  257           /* *
  258            *  Generate  a Jasper P rint objec t for the  specified  CBSStmt ID .
  259            *  
  260            *  @param cb sStmtId
  261            *              The CBSS tmt ID.
  262            *  @return T he Jasper  Print obje ct.
  263            * /
  264           pu blic Jaspe rPrint gen erateState mentPdfPri nt(final l ong cbsStm tId) {
  265  
  266                    try  {
  267  
  268                             // Con vert from  CBSStmt
  269                             final  SendCBSWri tePSRecord Source psR ecordSourc e = buildR ecordSourc e(cbsStmtI d);
  270                             final  PdfConsoli datedState mentDataBe an dataBea n = buildS tatementDa taBean(psR ecordSourc e, cbsStmt Id);
  271  
  272                             // TOD O, if abov e are null  or empty  then retur n null!?!?
  273                             
  274                             // Get  reference s.
  275                             Map<St ring, Obje ct> mainRe portValueP arametersM  = dataBea n.getMainR eportValue Parameters M();
  276                             List<P dfSiteStat ementColle ctionBean>  siteState mentCollec tionBeanL  = dataBean
  277                                               .getPdfSit eStatement Collection BeanL();
  278  
  279                             // Cre ate a data  source to  use as in puts to po pulate the  site
  280                             // sta tement sub  report po rtion of t he PDF.
  281                             JRBean Collection DataSource  siteState mentCollec tionDataSo urce = new  JRBeanCol lectionDat aSource(
  282                                               siteStatem entCollect ionBeanL);
  283                                                       
  284                             // Cre ate a para meter map  to use as  inputs to  populate t he global
  285                             // por tion of th e PDF.
  286  
  287                             // Add  the subre ports as p arameters.
  288                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteSu breportPar ameter", d etailSubre port);
  289                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteTi tleSubrepo rtParamete r",
  290                                               siteTitleS ubreport);
  291                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteTo talSubrepo rtParamete r",
  292                                               siteTotalS ubreport);
  293                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteDe limiterSub reportPara meter",
  294                                               siteDelimi terSubrepo rt);
  295                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteTr ailingSpac eSubreport Parameter"
  296                                               siteTraili ngSpaceSub report);
  297                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteFi llerSpaceS ubreportPa rameter",
  298                                               siteFiller SpaceSubre port);
  299                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteEn trySubrepo rtParamete r",
  300                                               detailEntr ySubreport );
  301                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteLa teStmtSubr eportParam eter",
  302                                               siteLateSt mtSubrepor t);
  303                             mainRe portValueP arametersM .put("vaLo go",vaLogo );
  304                             mainRe portValueP arametersM .put("chec kbox",chec kbox);
  305                             
  306                             // Dyn amically f ill the re port with  the parame ter map an d sub repo rt
  307                             // col lection da ta source.
  308                             Jasper Print jasp erPrint =  JasperFill Manager.fi llReport(m ainReport,  mainRepor tValuePara metersM,
  309                                               siteStatem entCollect ionDataSou rce);
  310  
  311                             return  jasperPri nt;
  312  
  313                    } ca tch (Numbe rFormatExc eption e)  {
  314  
  315                             // Sca n Line may  throw thi s.
  316                             logger .error(e.g etMessage( ));
  317  
  318                    } ca tch (JRExc eption e)  {
  319  
  320                             // Jas per may th row this.
  321                             logger .error(e.g etMessage( ));
  322  
  323                    } ca tch (Index OutOfBound sException  e) {
  324  
  325                             // Sca n Line may  throw thi s.
  326                             logger .error(e.g etMessage( ));
  327                    }
  328  
  329                    retu rn null;
  330           }
  331  
  332           /* *
  333            *  Build a S endCBSWrit ePSRecordS ource obje ct for the  specified  CBSStmt.  The
  334            *  returned  object is  used to po pulate a J asper Data  Source.
  335            *  
  336            *  @param cb sStmtId
  337            *              The CBSS tmt ID.
  338            *  @return T he SendCBS WritePSRec ordSource.
  339            * /
  340           pr ivate Send CBSWritePS RecordSour ce buildRe cordSource (final lon g cbsStmtI d) {
  341  
  342                    fina l SendCBSW ritePSReco rdSource p sRecordSou rce = new  SendCBSWri tePSRecord Source();
  343                    
  344                    fina l SendCBSR untimeStat eImpl runt imeState =  new SendC BSRuntimeS tateImpl() ;
  345           ps RecordSour ce.setSend CBSRuntime State(runt imeState);
  346           
  347           fi nal CBSStm t cbsStmt  = cbsStmtD AO.get(cbs StmtId);
  348           
  349           fi nal List<C BSSiteStmt > siteStmt L = cbsSit eStmtDAO.g etAllByCBS StmtID(cbs StmtId, tr ue);
  350           
  351           fi nal List<C BSSiteTran s> siteTra nsL = cbsS iteTransDA O.getAllBy CBSSiteStm tID(cbsStm tId);
  352  
  353           fo r(CBSSiteS tmt siteSt mt : siteS tmtL) {
  354               siteStmt. setSiteTra nsL(new Ar rayList<CB SSiteTrans >());
  355           }
  356           
  357           fo r(CBSSiteT rans trans  : siteTra nsL){
  358               for(CBSSi teStmt sit eStmt : si teStmtL) {
  359                       i f(trans.ge tSiteStmtI d() == sit eStmt.getI d()){
  360                                sit eStmt.getS iteTransL( ).add(tran s);
  361                       }
  362               }
  363           }
  364           
  365           cb sStmt.setS iteStmtL(s iteStmtL);
  366           
  367           fi nal List<P SSite> psS itesList =  runtimeSt ate.getPSS itesList() ;
  368           ps SitesList. add(create PSSite(PSR ecord.Data Type.PH, 1 , 1, siteS tmtL.get(0 ), 1, cbsS tmt.getNew Balance(). getDouble( )));
  369           
  370           fi nal List<C BSStmt> cb sStmtL2 =  new ArrayL ist<CBSStm t>(1);
  371           cb sStmtL2.ad d(cbsStmt) ;
  372           
  373           fi nal Map<St ring, List <CBSStmt>>  cbsListsB ySite = ru ntimeState .getCBSLis tsBySite() ;
  374           cb sListsBySi te.put(cbs Stmt.getPr imarySiteS tmt().getS tationNum( ), cbsStmt L2);
  375           
  376           ps RecordSour ce.setPsSi tesList(ps SitesList) ;
  377           ps RecordSour ce.setCbsL istsBySite (cbsListsB ySite);
  378                    
  379           
  380           re turn psRec ordSource;
  381           }
  382  
  383           /* *
  384            *  Build a P SSite obje ct from da ta retriev ed from th e database .
  385            *  
  386            *  @param st atementTyp e
  387            *  @param ps SeqNum
  388            *  @param ps TotSeqNum
  389            *  @param pr imarySite
  390            *  @param ps TotStateme nt
  391            *  @param ps StatementV al
  392            *  @return T he PSSite  object.
  393            * /
  394           pr ivate PSSi te createP SSite(fina l PSRecord .DataType  statementT ype, final  int psSeq Num, final  int psTot SeqNum,
  395                             final  CBSSiteStm t primaryS ite, final  int psTot Statement,  final dou ble psStat ementVal)  {
  396                    PSSi te psSite  = new PSSi te();
  397                    psSi te.setType (PSRecord. DataType.P S);
  398                    psSi te.setStat ementType( statementT ype);
  399  
  400                    psSi te.setSeqN um(psSeqNu m);
  401                    psSi te.setTotS eqNum(psTo tSeqNum);
  402                    psSi te.setFaci lityNum(pr imarySite. getStation Num());
  403                    psSi te.setFaci lityPhoneN um(primary Site.getSt ationPhone Num());
  404                    psSi te.setStat ementDate( primarySit e.getState mentDate() );
  405                    psSi te.setProc essDate(pr imarySite. getProcess Date());
  406                    psSi te.setTotS tatement(p sTotStatem ent);
  407                    psSi te.setStat ementVal(n ew Money(p sStatement Val, 11));
  408  
  409                    retu rn psSite;
  410           }
  411  
  412           /* *
  413            *  Create a  PdfConsoli datedState mentDataBe an of para meters to  populate t he
  414            *  PDF repor t from a S endCBSWrit ePSRecordS ource obje ct.
  415            *  
  416            *  @param ps RecordSour ce
  417            *              The Send CBSWritePS RecordSour ce object  containing  the reque sted
  418            *              CBSStmt  data.
  419            *  @param cb sStmtId 
  420            *  @return T he PdfCons olidatedSt atementDat aBean for  the Jasper  Report.
  421            * /
  422           pr ivate PdfC onsolidate dStatement DataBean b uildStatem entDataBea n(final Se ndCBSWrite PSRecordSo urce psRec ordSource,  long cbsS tmtId) {
  423  
  424                    bool ean valid  = true;
  425  
  426                    // B uild the r eport valu e map.
  427                    Map< String, Ob ject> main ReportValu eParameter sM = new H ashMap<>() ;
  428  
  429                    // D eclare the  report da ta source.
  430                    List <PdfSiteSt atementCol lectionBea n> siteSta tementColl ectionBean L;
  431  
  432                    // S ite statem ent Map<PS SiteStmt,  List<PSDet ails>>
  433                    Map< PSSiteStmt , List<PSD etails>> s iteStateme ntM = new  LinkedHash Map<>();
  434  
  435                    // P S
  436                    Stri ng facilit yNum = "";
  437                    PSRe cord psRec ord = psRe cordSource .nextPSRec ord(true);
  438                    PSSi teStmt pv  = null;
  439                    whil e (psRecor d != null)  {
  440                             if (ps Record ins tanceof PS Site) {
  441                                      logger.i nfo("PS");
  442                                      facility Num = ((PS Site) psRe cord).getF acilityNum ();
  443                                      appendPS Map(mainRe portValueP arametersM , (PSSite)  psRecord) ;
  444                             } else  if (psRec ord instan ceof PSPat ient) {
  445                                      logger.i nfo("PH");
  446                                      appendPH Map(mainRe portValueP arametersM , (PSPatie nt) psReco rd);
  447                                      appendSc anLine(mai nReportVal ueParamete rsM, facil ityNum);
  448                             } else  if (psRec ord instan ceof PSSit eStmt) {
  449                                      logger.i nfo("PV");
  450                                      pv = (PS SiteStmt)  psRecord;
  451                                      List<PSD etails> si teDetailL  = new Arra yList<>();
  452                                      siteStat ementM.put (pv, siteD etailL);
  453                             } else  if (psRec ord instan ceof PSDet ails) {
  454                                      logger.i nfo("PD");
  455                                      siteStat ementM.get (pv).add(( PSDetails)  psRecord) ;
  456                             } else  {
  457                                      valid =  false;
  458                                      logger.e rror("Unkn own PS Rec ord Type") ;
  459                             }
  460  
  461                             if (va lid) {
  462                                      psRecord  = psRecor dSource.ne xtPSRecord (true);
  463                             } else  {
  464                                      break;
  465                             }
  466                    }
  467  
  468                    // T ODO, If no t valid lo g error?
  469                    if ( valid) {
  470                             siteSt atementCol lectionBea nL = build SiteStatem entCollect ionBean(si teStatemen tM, cbsStm tId);                       popu latePseudo StaticData (mainRepor tValuePara metersM, f acilityNum );
  471  
  472                             return  new PdfCo nsolidated StatementD ataBean(ma inReportVa lueParamet ersM, site StatementC ollectionB eanL);
  473                    }
  474  
  475                    // T ODO, ensur e whatever  calls thi s doesn't  crash with  null.
  476                    retu rn null;
  477           }
  478  
  479           /* *
  480            *  Populate  parameter  value map  for the PD F with PSS ite attrib utes.
  481            *  
  482            *  @param re portValueM
  483            *              The para meter map  to populat e.
  484            *  @param si te
  485            *              The PSSi te object  containing  the data  for the si te.
  486            * /
  487           pr ivate void  appendPSM ap(Map<Str ing, Objec t> reportV alueM, fin al PSSite  site) {
  488  
  489                    fina l Date sta tementDate  = site.ge tStatement Date();
  490                    fina l SimpleDa teFormat s tatementDa teFormat =  new Simpl eDateForma t(REPORT_D ATE_FORMAT );
  491                    repo rtValueM.p ut("Statem entDate",  statementD ateFormat. format(sta tementDate ));
  492  
  493                    // T he balance  determine s payment  date.
  494                    fina l double b alance = s ite.getSta tementVal( ).getDoubl e();
  495  
  496                    // T ODO, When  is this?
  497                    fina l Date pro cessDate =  site.getP rocessDate ();
  498                    fina l SimpleDa teFormat p rocessDate Format = n ew SimpleD ateFormat( REPORT_DAT E_FORMAT);
  499                    repo rtValueM.p ut("Paymen tDate", pr ocessDateF ormat.form at(process Date));
  500  
  501                    // B uild the p ayment par ameters.
  502                    if ( balance >  0) {
  503  
  504                             // Pay ment Due D ate is the  statement Date plus  FULL_PAYME NT_DAY_NUM BER_DELTA.
  505                             // TOD O, test th is with ro llover fro m december  to januar y.
  506                             final  SimpleDate Format pay mentDueDat eFormat =  new Simple DateFormat (REPORT_DA TE_FORMAT) ;
  507                             Calend ar c = Cal endar.getI nstance();
  508                             c.setT ime(statem entDate);
  509                             c.add( Calendar.D ATE, FULL_ PAYMENT_DA Y_NUMBER_D ELTA);
  510                             final  Date payme ntDueDate  = c.getTim e();
  511                             //Adde d 8/29
  512                             report ValueM.put ("PaymentD ueDate", p aymentDueD ateFormat. format(pay mentDueDat e));
  513  
  514                             //repo rtValueM.p ut("Paymen tDueMessag e", "TO AV OID LATE<b r/>CHARGES  PAY BALAN CE<br/>BY  "
  515                             //                + paymentD ueDateForm at.format( paymentDue Date));
  516                             report ValueM.put ("PaymentD ueMessage" , " ");
  517  
  518                             //repo rtValueM.p ut("Balanc e", site.g etStatemen tVal().get DoubleAsAb soluteStri ng());
  519                             report ValueM.put ("Balance" , " ");
  520                             report ValueM.put ("AmountDu e", site.g etStatemen tVal().get DoubleAsAb soluteStri ng());
  521  
  522                    } el se {
  523  
  524                             final  String pay mentDueDat e = "NO PA YMENT DUE" ;
  525                             //Adde d 8/25/201 7
  526                             report ValueM.put ("PaymentD ueDate", p aymentDueD ate);
  527                             //repo rtValueM.p ut("Paymen tDueMessag e", paymen tDueDate);
  528                             report ValueM.put ("PaymentD ueMessage" , " ");
  529  
  530                             //repo rtValueM.p ut("Balanc e", identi fyValueAsC redit(site .getStatem entVal().g etDoubleAs AbsoluteSt ring()));
  531                             report ValueM.put ("Balance" , " ");
  532                             report ValueM.put ("AmountDu e", "0.00" );
  533                    }
  534           }
  535  
  536           /* *
  537            *  Populate  parameter  value map  for the PD F with PSP atient att ributes.
  538            *  
  539            *  @param re portValueM
  540            *              The para meter map  to populat e.
  541            *  @param pa tient
  542            *              The PSPa tient obje ct contain ing the da ta for the  site.
  543            * /
  544           pr ivate void  appendPHM ap(Map<Str ing, Objec t> reportV alueM, fin al PSPatie nt patient ) {
  545  
  546                    // B uild the p atient nam e and whil e doing so  do not in clude any  empty or
  547                    // n ull names.
  548                    Stri ngBuilder  patientNam e = new St ringBuilde r();
  549                    if ( (patient.g etPatientF irstName()  != null)  && !patien t.getPatie ntFirstNam e().trim() .isEmpty() ) {
  550                             patien tName.appe nd(patient .getPatien tFirstName ().trim()) ;
  551                    }
  552                    if ( (patient.g etPatientM iddleName( ) != null)  && !patie nt.getPati entMiddleN ame().trim ().isEmpty ()) {
  553                             patien tName.appe nd(" ");
  554                             patien tName.appe nd(patient .getPatien tMiddleNam e().trim() );
  555                    }
  556                    if ( (patient.g etPatientL astName()  != null) & & !patient .getPatien tLastName( ).trim().i sEmpty())  {
  557                             patien tName.appe nd(" ");
  558                             patien tName.appe nd(patient .getPatien tLastName( ).trim());
  559                    }
  560                    repo rtValueM.p ut("Patien tName", pa tientName. toString() );
  561  
  562                    // T his is the  patient a ddress in  the title  and coupon  band.
  563                    Stri ngBuilder  address =  new String Builder();
  564                    if ( (patient.g etAddress1 () != null ) && !pati ent.getAdd ress1().is Empty()) {
  565                             addres s.append(p atient.get Address1() );
  566                    }
  567                    if ( (patient.g etAddress2 () != null ) && !pati ent.getAdd ress2().is Empty()) {
  568                             addres s.append(" <br/>");
  569                             addres s.append(p atient.get Address2() );
  570                    }
  571                    if ( (patient.g etAddress3 () != null ) && !pati ent.getAdd ress3().is Empty()) {
  572                             addres s.append(" <br/>");
  573                             addres s.append(p atient.get Address3() );
  574                    }
  575                    fina l String p atientCity StateZip =  patient.g etCity() +  " " + pat ient.getSt ate() + "  " + patien t.getZipCo de();
  576                    addr ess.append ("<br/>");
  577                    addr ess.append (patientCi tyStateZip );
  578                    repo rtValueM.p ut("Patien tAddress",  address.t oString()) ;
  579  
  580                    // B uild the p ayment par ameters.
  581                    if ( patient.ge tPrevBalan ce().getDo uble() > 0 ) {
  582                             report ValueM.put ("Previous Balance",  patient.ge tPrevBalan ce().getDo ubleAsAbso luteString ());
  583                    } el se {
  584                             report ValueM.put ("Previous Balance",  identifyVa lueAsCredi t(patient. getPrevBal ance().get DoubleAsAb soluteStri ng()));
  585                    }
  586                    repo rtValueM.p ut("NewCha rges", pat ient.getTo talCharges ().getDoub leAsAbsolu teString() );
  587                    repo rtValueM.p ut("Paymen tsReceived ", patient .getTotalC redits().g etDoubleWi thSignSuff ixAsString ());
  588  
  589                    // S ave the ra w account  number for  later use  by the Sc an Line.
  590                    // T he formate d account  number is  the one us ed in the  actual for m.
  591                    repo rtValueM.p ut("Accoun tNumberRaw ", patient .getAcntNu mDisp().tr im());
  592                    repo rtValueM.p ut("Accoun tNumber",  formatAcco untNumber( patient.ge tAcntNumDi sp().trim( )));
  593  
  594                    // T ODO, Figur e out if t his is lat e statemen t message  or special  notes
  595                    // o r both?
  596                    // A DDED 8/25/ 2017
  597                    Stri ngBuilder  localMessa ge = new S tringBuild er();
  598                    loca lMessage.a ppend("&nb sp;Local V A'S MESSAG E");
  599                    loca lMessage.a ppend("<br />");
  600                    loca lMessage.a ppend("&nb sp;&nbsp;*  CONSOLIDA TED STATEM ENT GENERA TED");
  601                    loca lMessage.a ppend("<br />");
  602                    loca lMessage.a ppend("&nb sp;&nbsp;*  REVIEW TE AR-OFF COU PON FOR AM OUNT DUE") ;
  603                    repo rtValueM.p ut("LocalM essage", l ocalMessag e.toString ());
  604                    //re portValueM .put("Loca lMessage",  " Local V A'S MESSAG E");
  605           }
  606  
  607           /* *
  608            *  Create a  scan line  and append  to the pa rameter ma p.
  609            *  
  610            *  @param re portValueM
  611            *              The para meter map  to populat e.
  612            *  @param fa cilityNum
  613            *              The prim ary site/f acility fo r the repo rt.
  614            * /
  615           pr ivate void  appendSca nLine(Map< String, Ob ject> repo rtValueM,  final Stri ng facilit yNum) {
  616  
  617                    fina l String a ccountNumb er = (Stri ng) report ValueM.get ("AccountN umberRaw") ;
  618                    fina l String a mountDue =  (String)  reportValu eM.get("Am ountDue");
  619  
  620                    fina l ScanLine  scanLine  = new Scan Line(facil ityNum, ac countNumbe r, amountD ue);
  621  
  622                    // A ppend thes e values.
  623                    repo rtValueM.p ut("Mailin gLabel", s canLine.ge tCalculate dScanLine( ));
  624           }
  625  
  626           /* *
  627            *  Populate  pseudo sta tic data i n the para meter map.
  628            *  
  629            *  @param re portValueM
  630            *              The para meter map  to populat e.
  631            *  @param fa cilityNum
  632            *              The prim ary site f or which t o use as l ookup key  for the ps eudo
  633            *              static d ata.
  634            * /
  635           pr ivate void  populateP seudoStati cData(Map< String, Ob ject> repo rtValueM,  final Stri ng facilit yNum) {
  636  
  637                    Stat ionInfo st ation = St ationInfoU til.getSta tion(facil ityNum);
  638                    Syst em.out.pri ntln(stati on.getFaci lityDesc() );
  639                    repo rtValueM.p ut("SiteLo cationName ", station .getFacili tyDesc());
  640                    
  641                    // T his is the  address a t the top  of the rep ort header  and is th e VAMC's a ddress.
  642                    Addr ess statio nAddress =  station.g etAddress( );
  643                    Stri ngBuilder  address =  new String Builder();
  644                    if ( (stationAd dress.getA ddress1()  != null) & & !station Address.ge tAddress1( ).isEmpty( )) {
  645                             addres s.append(s tationAddr ess.getAdd ress1());
  646                    }
  647                    if ( (stationAd dress.getA ddress2()  != null) & & !station Address.ge tAddress2( ).isEmpty( )) {
  648                             addres s.append(" <br/>");
  649                             addres s.append(s tationAddr ess.getAdd ress2());
  650                    }
  651                    if ( (stationAd dress.getA ddress3()  != null) & & !station Address.ge tAddress3( ).isEmpty( )) {
  652                             addres s.append(" <br/>");
  653                             addres s.append(s tationAddr ess.getAdd ress3());
  654                    }
  655                    fina l String p atientCity StateZip =  station.g etCity() +  " " + sta tion.getSt ate() + "  " + statio n.getZipCo de();
  656                    addr ess.append ("<br/>");
  657                    addr ess.append (patientCi tyStateZip );
  658                    
  659                    repo rtValueM.p ut("SiteAd dress", ad dress.toSt ring());
  660                    repo rtValueM.p ut("SiteCi tyStateZip ",
  661                                      String.f ormat("%s,  %s %s", s tation.get City(), st ation.getS tate(), st ation.getZ ipCode().g etZipCode1 ()));
  662  
  663                    // T his is the  phone num ber of the  HRC Call  Center (pe r VISN).
  664                    repo rtValueM.p ut("Questi onsPhone",  station.g etTelephon eNum1());
  665  
  666                    // F or some re ason this  is hard co ded on the  form.
  667                    // S o it is ha rd coded h ere for ea sier updat e.
  668                    repo rtValueM.p ut("PayByP hone", "1- 888-827-48 17");
  669                    repo rtValueM.p ut("PayHou rs", "Mon  - Fri 8am  - 5pm EST" );
  670                    
  671                    // T ODO, MAIL  TO: mailin g address.
  672                    // O ne address  per CPAC.
  673                    // T ODO, chang e this to  html field  type and  concatenat e a single  field.
  674                    repo rtValueM.p ut("MailTo Address",  "DEPARTMEN T OF VETER ANS AFFAIR S<br/>PO B OX 530269< br/>ATLANT A GA 30353 -0269");
  675           }
  676  
  677           /* *
  678            *  Build a P dfSiteStat ementColle ctionBean  from the s ite statem ent map to  be
  679            *  used as a  Jasper da ta source.
  680            *  
  681            *  @param si teStatemen tM
  682            *              The site  statement  map.
  683            *  @param cb sStmtId 
  684            *  @return L ist of Pdf SiteStatem entCollect ionBean. N ote that t he list is
  685            *          s ize of one  because t he Jasper  data sourc e that is  constructe d
  686            *          r equires a  list.
  687            * /
  688           pr ivate List <PdfSiteSt atementCol lectionBea n> buildSi teStatemen tCollectio nBean(
  689                             Map<PS SiteStmt,  List<PSDet ails>> sit eStatement M, long cb sStmtId) {
  690  
  691                    PdfS iteStateme ntCollecti onBean sit eStatement Collection  = new Pdf SiteStatem entCollect ionBean();
  692  
  693                    List <PdfSiteSt atementBea n> siteSta tementBean L = new Ar rayList<>( );
  694  
  695                    for  (Map.Entry <PSSiteStm t, List<PS Details>>  siteEntry  : siteStat ementM.ent rySet()) {
  696  
  697                             PdfSit eStatement Bean site  = new PdfS iteStateme ntBean();
  698  
  699                             final  String fac ilityTitle  = Station InfoUtil.g etStation( siteEntry. getKey().g etFacility Num()).get FacilityDe sc();
  700                             site.s etFacility (facilityT itle + " #  " + siteE ntry.getKe y().getFac ilityNum() );
  701  
  702                             //set  late state ment flag  for site i f statemen t is marke d late
  703                             final  CBSStmt cb sStmt = cb sStmtDAO.g et(cbsStmt Id);
  704                             if(cbs Stmt.getLa teStmtMsg( )){
  705                                      site.set LateStmtFl ag(true);
  706                             }
  707                             
  708                             List<P dfSiteStat ementEntry Bean> pdfS iteStateme ntEntryBea nL = new A rrayList<> ();
  709                             for (P SDetails d etails : s iteEntry.g etValue())  {
  710                                      // TODO,  split the  detail in to multipl e lines.
  711                                      // This  is necessa ry so line  calculati on is corr ect for po pulating t he form wi th the spe cified num ber of lin es.
  712                                      // TODO,  check tra ns desc an d wrap wit h [] for s uspended c harges
  713                                      
  714                                      PdfSiteS tatementEn tryBean de tailEntry  = new PdfS iteStateme ntEntryBea n(formatDe tailDescri ption(deta ils.getTra nsDesc()),
  715                                                       de tails.getT ransAmount ().getDoub leWithSign SuffixAsSt ring(), de tails.getR eferenceNu m());
  716                                      pdfSiteS tatementEn tryBeanL.a dd(detailE ntry);
  717                             }
  718                             site.s etRecords( pdfSiteSta tementEntr yBeanL);
  719  
  720                             site.s etTotalLab el("FACILI TY #" + si teEntry.ge tKey().get FacilityNu m() + " TO TAL");
  721                             site.s etTotal(si teEntry.ge tKey().get StationTot alAmount() .getDouble AsString() );
  722  
  723                             siteSt atementBea nL.add(sit e);
  724                    }
  725  
  726                    site StatementC ollection. setSiteSta tementL(si teStatemen tBeanL);
  727  
  728                    // S plit the s ite statem ent collec tion bean.
  729                    site StatementC ollection. split(MAX_ LENGTH_FIR ST_PAGE);
  730                    
  731                    // A dd filler  space to e xtend box  to footer  of page
  732                    site StatementC ollection. addFillerS pace(MAX_L ENGTH_FIRS T_PAGE, MA X_LENGTH_E XTENSION_P AGE);
  733  
  734                    retu rn Arrays. asList(sit eStatement Collection );
  735           }
  736  
  737           /* *
  738            *  Format th e descript ion text a s shown on  the examp les
  739            *  provided  by AITC.
  740            *  
  741            *  @param de tailDesc
  742            *              ----The  original d escription  text.
  743            *  @return T he formatt ed descrip tion.
  744            * /
  745           St ring forma tDetailDes cription ( String det ailDesc){
  746                    Stri ng parsedD esc = deta ilDesc;
  747                    pars edDesc = p arsedDesc. replace("  FD:", " Fi ll Date:") ;
  748                    pars edDesc = p arsedDesc. replace("  RX:", " RX #");
  749                    pars edDesc = p arsedDesc. replace("( NSC)", "") ;
  750                    pars edDesc = p arsedDesc. replace("P AYMENT", " PAYMENT PO STED ON");
  751                    retu rn parsedD esc;
  752           }
  753           /* *
  754            *  Format th e account  number for  easier re adability  as shown o n the exam ples
  755            *  provided  by AITC.
  756            *  
  757            *  @param ac countNumbe r
  758            *              The acco unt number .
  759            *  @return T he formatt ed account  number.
  760            *  @throws I ndexOutOfB oundsExcep tion
  761            *               If an e rror durin g formatti ng an exce ption is t hrown.
  762            * /
  763           pu blic stati c String f ormatAccou ntNumber(f inal Strin g accountN umber) thr ows IndexO utOfBounds Exception  {
  764  
  765                    // T he format  of the acc ount numbe r displaye d on the r eport appe ars to
  766                    // b e:
  767                    // 3  character  site numb er + space  + 3 chara cter + spa ce + 3 cha racter +
  768                    // s pace + 4 c haracter +  space + r emaining c haracter
  769                    Stri ngBuilder  formattedA ccountNumb er = new S tringBuild er();
  770  
  771                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_1,
  772                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 1, true));
  773  
  774                    form attedAccou ntNumber.a ppend(" ") ;
  775                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_2,
  776                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 2, true));
  777  
  778                    form attedAccou ntNumber.a ppend(" ") ;
  779                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_3,
  780                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 3, true));
  781  
  782                    form attedAccou ntNumber.a ppend(" ") ;
  783                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_4,
  784                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 4, true));
  785  
  786                    form attedAccou ntNumber.a ppend(" ") ;
  787                    form attedAccou ntNumber.a ppend(subs tringByPos ition(acco untNumber,  ACCOUNT_N UMBER_SPLI T_POSITION _5));
  788  
  789                    retu rn formatt edAccountN umber.toSt ring();
  790           }
  791  
  792           /* *
  793            *  Get a sub string of  the input  string by  the specif ied positi on.
  794            *  
  795            *  @param in put
  796            *              The inpu t string.
  797            *  @param po sition
  798            *              The star t position  for the s ubstring.
  799            *  @return T he substri ng.
  800            *  @throws I ndexOutOfB oundsExcep tion
  801            *               If an e rror durin g formatti ng an exce ption is t hrown.
  802            * /
  803           pr ivate stat ic String  substringB yPosition( final Stri ng input,  final int  position)  throws Ind exOutOfBou ndsExcepti on {
  804  
  805                    // V erify the  position i s valid fo r the inpu t.
  806                    if ( (input.len gth() - 1)  < positio n) {
  807                             throw  new IndexO utOfBounds Exception( "Input ("  + input +  ") with po sition ("  + position  + ") is i nvalid");
  808                    }
  809  
  810                    // G et the sub string.
  811                    fina l String s s = input. substring( position);
  812  
  813                    retu rn ss;
  814           }
  815  
  816           /* *
  817            *  Get a sub string of  the input  string by  the specif ied positi on and the
  818            *  desired l ength.
  819            *  
  820            *  @param in put
  821            *              The inpu t string.
  822            *  @param po sition
  823            *              The star t position  for the s ubstring
  824            *  @param le ngth
  825            *              The leng th of the  substring.
  826            *  @param ch eckLength
  827            *              Flag to  indicate i f the resu lt should  be checked  for an er ror.
  828            *  @return T he substri ng.
  829            *  @throws I ndexOutOfB oundsExcep tion
  830            *               If an e rror durin g formatti ng an exce ption is t hrown.
  831            * /
  832           pr ivate stat ic String  substringB yPositionL ength(fina l String i nput, fina l int posi tion, fina l int leng th,
  833                             final  boolean ch eckLength)  throws In dexOutOfBo undsExcept ion {
  834  
  835                    // V erify the  position i s valid fo r the inpu t.
  836                    if ( (input.len gth() - 1)  < positio n) {
  837                             throw  new IndexO utOfBounds Exception( "Input ("  + input +  ") with po sition ("  + position  + ") is i nvalid");
  838                    }
  839  
  840                    // O ptionally,  verify th e input wi ll support  the subst ring.
  841                    if ( checkLengt h && ((pos ition + le ngth) > in put.length ())) {
  842                             throw  new IndexO utOfBounds Exception( "Input ("  + input +  ") will no t support  specified  position ( " + positi on
  843                                               + ") and l ength (" +  length +  ") substri ng");
  844                    }
  845  
  846                    // G et the sub string.
  847                    fina l String s s = input. substring( position,  Math.min(p osition +  length, in put.length ()));
  848  
  849                    // I f necessar y, check t he length  and if not  the expec ted length  it is
  850                    // i nvalid.
  851                    if ( checkLengt h && (ss.l ength() !=  length))  {
  852                             throw  new IndexO utOfBounds Exception( "Expected  output ("  + ss + ")  with lengt h (" + len gth + ")") ;
  853                    }
  854  
  855                    retu rn ss;
  856           }
  857  
  858           /* *
  859            *  Create a  string tha t makes th e value re presented  as a credi t.
  860            *  @param va lue The va lue to con vert.
  861            *  @return T he credit  representa tion of th e value.
  862            * /
  863           pr ivate stat ic String  identifyVa lueAsCredi t(final St ring value ) {
  864                    retu rn value +  CREDIT_SU FFIX;
  865           }
  866   }